1<?php
2/* Copyright (C) 2012	   Regis Houssin       <regis.houssin@inodbox.com>
3 * Copyright (C) 2013-2015 Laurent Destailleur <eldy@users.sourceforge.net>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <https://www.gnu.org/licenses/>.
17 */
18
19/**
20 *  \file       htdocs/product/admin/product_tools.php
21 *  \ingroup    product
22 *  \brief      Setup page of product module
23 */
24
25// TODO We must add a confirmation on button because this will make a mass change
26// FIXME Should also change table product_price for price levels
27
28require '../../main.inc.php';
29require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
30require_once DOL_DOCUMENT_ROOT.'/core/lib/product.lib.php';
31require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
32require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.product.class.php';
33
34// Load translation files required by the page
35$langs->loadLangs(array('admin', 'products'));
36
37// Security check
38if (!$user->admin) accessforbidden();
39
40$action = GETPOST('action', 'aZ09');
41$oldvatrate = GETPOST('oldvatrate', 'alpha');
42$newvatrate = GETPOST('newvatrate', 'alpha');
43//$price_base_type=GETPOST('price_base_type');
44
45
46
47/*
48 * Actions
49 */
50
51if ($action == 'convert')
52{
53	$error = 0;
54
55	if ($oldvatrate == $newvatrate)
56	{
57		$langs->load("errors");
58		setEventMessages($langs->trans("ErrorNewValueCantMatchOldValue"), null, 'errors');
59		$error++;
60	}
61
62	if (!$error)
63	{
64		$country_id = $mysoc->country_id; // TODO Allow to choose country into form
65
66		$nbrecordsmodified = 0;
67
68		$db->begin();
69
70		// Clean vat code old
71		$vat_src_code_old = '';
72		if (preg_match('/\((.*)\)/', $oldvatrate, $reg))
73		{
74			$vat_src_code_old = $reg[1];
75			$oldvatrateclean = preg_replace('/\s*\(.*\)/', '', $oldvatrate); // Remove code into vatrate.
76		} else $oldvatrateclean = $oldvatrate;
77
78		// Clean vat code new
79		$vat_src_code_new = '';
80		if (preg_match('/\((.*)\)/', $newvatrate, $reg))
81		{
82			$vat_src_code_new = $reg[1];
83			$newvatrateclean = preg_replace('/\s*\(.*\)/', '', $newvatrate); // Remove code into vatrate.
84		} else $newvatrateclean = $newvatrate;
85
86		// If country to edit is my country, so we change customer prices
87		if ($country_id == $mysoc->country_id)
88		{
89			$sql = 'SELECT rowid';
90			$sql .= ' FROM '.MAIN_DB_PREFIX.'product';
91			$sql .= ' WHERE entity IN ('.getEntity('product').')';
92			$sql .= " AND tva_tx = '".$db->escape($oldvatrateclean)."'";
93			if ($vat_src_code_old) $sql .= " AND default_vat_code = '".$db->escape($vat_src_code_old)."'";
94			else " AND default_vat_code = IS NULL";
95
96			$resql = $db->query($sql);
97			if ($resql)
98			{
99				$num = $db->num_rows($resql);
100
101				$i = 0;
102				while ($i < $num)
103				{
104					$obj = $db->fetch_object($resql);
105
106					$objectstatic = new Product($db); // Object init must be into loop to avoid to get value of previous step
107					$ret = $objectstatic->fetch($obj->rowid);
108					if ($ret > 0)
109					{
110						$ret = 0; $retm = 0; $updatelevel1 = false;
111
112						// Update multiprice
113						$listofmulti = array_reverse($objectstatic->multiprices, true); // To finish with level 1
114						foreach ($listofmulti as $level => $multiprices)
115						{
116							$price_base_type = $objectstatic->multiprices_base_type[$level]; // Get price_base_type of product/service to keep the same for update
117							if (empty($price_base_type)) continue; // Discard not defined price levels
118
119							if ($price_base_type == 'TTC')
120							{
121								$newprice = price2num($objectstatic->multiprices_ttc[$level], 'MU'); // Second param must be MU (we want a unit price so 'MU'. If unit price was on 4 decimal, we must keep 4 decimals)
122								$newminprice = $objectstatic->multiprices_min_ttc[$level];
123							} else {
124								$newprice = price2num($objectstatic->multiprices[$level], 'MU'); // Second param must be MU (we want a unit price so 'MU'. If unit price was on 4 decimal, we must keep 4 decimals)
125								$newminprice = $objectstatic->multiprices_min[$level];
126							}
127							if ($newminprice > $newprice) $newminprice = $newprice;
128
129							$newvat = str_replace('*', '', $newvatrate);
130							$localtaxes_type = getLocalTaxesFromRate($newvat, 0, $mysoc, $mysoc);
131							$newnpr = $objectstatic->multiprices_recuperableonly[$level];
132							$newdefaultvatcode = $vat_src_code_new;
133							$newlevel = $level;
134
135							//print "$objectstatic->id $newprice, $price_base_type, $newvat, $newminprice, $newlevel, $newnpr<br>\n";
136							$retm = $objectstatic->updatePrice($newprice, $price_base_type, $user, $newvatrateclean, $newminprice, $newlevel, $newnpr, 0, 0, $localtaxes_type, $newdefaultvatcode);
137							if ($retm < 0)
138							{
139								$error++;
140								break;
141							}
142
143							if ($newlevel == 1) $updatelevel1 = true;
144						}
145
146						// Update single price
147						$price_base_type = $objectstatic->price_base_type; // Get price_base_type of product/service to keep the same for update
148						if ($price_base_type == 'TTC')
149						{
150							$newprice = price2num($objectstatic->price_ttc, 'MU'); // Second param must be MU (we want a unit price so 'MU'. If unit price was on 4 decimal, we must keep 4 decimals)
151							$newminprice = $objectstatic->price_min_ttc;
152						} else {
153							$newprice = price2num($objectstatic->price, 'MU'); // Second param must be MU (we want a unit price so 'MU'. If unit price was on 4 decimal, we must keep 4 decimals)
154							$newminprice = $objectstatic->price_min;
155						}
156						if ($newminprice > $newprice) $newminprice = $newprice;
157						$newvat = str_replace('*', '', $newvatrate);
158						$localtaxes_type = getLocalTaxesFromRate($newvat, 0, $mysoc, $mysoc);
159						$newnpr = $objectstatic->recuperableonly;
160						$newdefaultvatcode = $vat_src_code_new;
161						$newlevel = 0;
162						if (!empty($price_base_type) && !$updatelevel1)
163						{
164							//print "$objectstatic->id $newprice, $price_base_type, $newvat, $newminprice, $newlevel, $newnpr<br>\n";
165							$ret = $objectstatic->updatePrice($newprice, $price_base_type, $user, $newvatrateclean, $newminprice, $newlevel, $newnpr, 0, 0, $localtaxes_type, $newdefaultvatcode);
166						}
167
168						if ($ret < 0 || $retm < 0) $error++;
169						else $nbrecordsmodified++;
170					}
171					unset($objectstatic);
172
173					$i++;
174				}
175			} else dol_print_error($db);
176		}
177
178		$fourn = new Fournisseur($db);
179
180		// Change supplier prices
181		$sql = 'SELECT pfp.rowid, pfp.fk_soc, pfp.price as price, pfp.quantity as qty, pfp.fk_availability, pfp.ref_fourn';
182		$sql .= ' FROM '.MAIN_DB_PREFIX.'product_fournisseur_price as pfp, '.MAIN_DB_PREFIX.'societe as s';
183		$sql .= ' WHERE pfp.fk_soc = s.rowid AND pfp.entity IN ('.getEntity('product').')';
184		$sql .= " AND tva_tx = '".$db->escape($oldvatrate)."'";
185		if ($vat_src_code_old) $sql .= " AND default_vat_code = '".$db->escape($vat_src_code_old)."'";
186		else " AND default_vat_code = IS NULL";
187		$sql .= " AND s.fk_pays = ".((int) $country_id);
188		//print $sql;
189		$resql = $db->query($sql);
190		if ($resql)
191		{
192			$num = $db->num_rows($resql);
193
194			$i = 0;
195			while ($i < $num)
196			{
197				$obj = $db->fetch_object($resql);
198
199				$objectstatic2 = new ProductFournisseur($db); // Object init must be into loop to avoid to get value of previous step
200				$ret = $objectstatic2->fetch_product_fournisseur_price($obj->rowid);
201				if ($ret > 0)
202				{
203					$ret = 0; $retm = 0; $updatelevel1 = false;
204
205					$price_base_type = 'HT';
206					//$price_base_type = $objectstatic2->price_base_type;	// Get price_base_type of product/service to keep the same for update
207					//if ($price_base_type == 'TTC')
208					//{
209					//	$newprice=price2num($objectstatic2->price_ttc,'MU');    // Second param must be MU (we want a unit price so 'MU'. If unit price was on 4 decimal, we must keep 4 decimals)
210					//	$newminprice=$objectstatic2->price_min_ttc;
211					//}
212					//else
213					//{
214						$newprice = price2num($obj->price, 'MU'); // Second param must be MU (we want a unit price so 'MU'. If unit price was on 4 decimal, we must keep 4 decimals)
215						//$newminprice=$objectstatic2->fourn_price_min;
216					//}
217					//if ($newminprice > $newprice) $newminprice=$newprice;
218					$newvat = str_replace('*', '', $newvatrate);
219					$localtaxes_type = getLocalTaxesFromRate($newvat, 0, $mysoc, $mysoc);
220					//$newnpr=$objectstatic2->recuperableonly;
221					$newnpr = 0;
222					$newdefaultvatcode = $vat_src_code_new;
223
224					$newpercent = $objectstatic2->fourn_remise_percent;
225					$newdeliverydelay = $objectstatic2->delivery_time_days;
226					$newsupplierreputation = $objectstatic2->supplier_reputation;
227
228					$newlevel = 0;
229					if (!empty($price_base_type) && !$updatelevel1)
230					{
231						//print "$objectstatic2->id $newprice, $price_base_type, $newvat, $newminprice, $newlevel, $newnpr<br>\n";
232						$fourn->id = $obj->fk_soc;
233						$ret = $objectstatic2->update_buyprice($obj->qty, $newprice, $user, $price_base_type, $fourn, $obj->fk_availability, $obj->ref_fourn, $newvat, '', $newpercent, 0, $newnpr, $newdeliverydelay, $newsupplierreputation, $localtaxes_type, $newdefaultvatcode);
234					}
235
236					if ($ret < 0 || $retm < 0) $error++;
237					else $nbrecordsmodified++;
238				}
239				unset($objectstatic2);
240
241				$i++;
242			}
243		} else dol_print_error($db);
244
245		if (!$error)
246		{
247			$db->commit();
248		} else {
249			$db->rollback();
250		}
251
252		// Output result
253		if (!$error)
254		{
255			if ($nbrecordsmodified > 0) setEventMessages($langs->trans("RecordsModified", $nbrecordsmodified), null, 'mesgs');
256			else setEventMessages($langs->trans("NoRecordFound"), null, 'warnings');
257		} else {
258			setEventMessages($langs->trans("Error"), null, 'errors');
259		}
260	}
261}
262
263/*
264 * View
265 */
266
267$form = new Form($db);
268
269$title = $langs->trans('ProductVatMassChange');
270
271llxHeader('', $title);
272
273print load_fiche_titre($title, '', 'title_setup');
274
275print $langs->trans("ProductVatMassChangeDesc").'<br><br>';
276
277if (empty($mysoc->country_code))
278{
279	$langs->load("errors");
280	$warnpicto = img_error($langs->trans("WarningMandatorySetupNotComplete"));
281	print '<br><a href="'.DOL_URL_ROOT.'/admin/company.php?mainmenu=home">'.$warnpicto.' '.$langs->trans("WarningMandatorySetupNotComplete").'</a>';
282} else {
283	print '<form method="POST" action="'.$_SERVER['PHP_SELF'].'">';
284	print '<input type="hidden" name="token" value="'.newToken().'" />';
285	print '<input type="hidden" name="action" value="convert" />';
286
287	print '<table class="noborder centpercent">';
288	print '<tr class="liste_titre">';
289	print '<td>'.$langs->trans("Parameters").'</td>'."\n";
290	print '<td class="right" width="60">'.$langs->trans("Value").'</td>'."\n";
291	print '</tr>'."\n";
292
293
294	print '<tr class="oddeven">'."\n";
295	print '<td>'.$langs->trans("OldVATRates").'</td>'."\n";
296	print '<td width="60" class="right">'."\n";
297	print $form->load_tva('oldvatrate', $oldvatrate, $mysoc, null, 0, 0, '', false, 1);
298	print '</td>'."\n";
299	print '</tr>'."\n";
300
301
302	print '<tr class="oddeven">'."\n";
303	print '<td>'.$langs->trans("NewVATRates").'</td>'."\n";
304	print '<td width="60" class="right">'."\n";
305	print $form->load_tva('newvatrate', $newvatrate, $mysoc, null, 0, 0, '', false, 1);
306	print '</td>'."\n";
307	print '</tr>'."\n";
308
309	/*
310
311	print '<tr class="oddeven">'."\n";
312	print '<td>'.$langs->trans("PriceBaseTypeToChange").'</td>'."\n";
313	print '<td width="60" class="right">'."\n";
314	print $form->selectPriceBaseType($price_base_type);
315	print '</td>'."\n";
316	print '</tr>'."\n";
317	*/
318
319	print '</table>';
320
321	print '<br>';
322
323	// Buttons for actions
324
325	print '<div class="center">';
326	print '<input type="submit" id="convert_vatrate" name="convert_vatrate" value="'.$langs->trans("MassConvert").'" class="button" />';
327	print '</div>';
328
329	print '</form>';
330}
331
332// End of page
333llxFooter();
334$db->close();
335