<?php
/*
 * draftupdate.php
 *
 * Copyright 2020-2021 Christophe Battarel <christophe.battarel@altairis.fr>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 * MA 02110-1301, USA.
 *
 *
 */
if (! defined('NOTOKENRENEWAL')) define('NOTOKENRENEWAL', '1'); // Disables token renewal

$res=@include("../../main.inc.php");					// For root directory
if (! $res) $res=@include("../../../main.inc.php");		// For "custom" directory

$param = base64_decode($_POST["param64"]);

parse_str($param, $_POST);//print_r($_POST);die;

$id = GETPOST("id", 'int');
$element = GETPOST("element", 'alpha');
$draftupdate = GETPOST("draftupdate", 'int');

$langs->load('drafteditable@dolitools');

$errors = array();

if (($element == 'propal' || $element == 'commande' || $element == 'facture') && $user->rights->{$element}->creer)
{
	switch($element)
	{
		case 'commande' :
			require_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php';
			break;
		case 'propal':
			require_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propal.class.php';
			break;
		case 'facture':
			require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
			break;
	}

	$object = new $element($db);
	if ($object->fetch($id) > 0)
	{

		$object->fetch_thirdparty();

		// update lines first because they might be changed later by triggers
		update_lines();

		// reload lines
		$object->fetch_lines();

		// project
		if (GETPOST('projectid')) $object->setProject(GETPOST('projectid', 'int'));

		// customer reference
		$result = $object->set_ref_client($user, GETPOST('ref_client'));
		if ($result < 0)
		{
			$errors = array_merge($errors, $object->errors);
		}

		// object date
		if ($object->element == 'propal') $date = dol_mktime(0, 0, 0, GETPOST('remonth'), GETPOST('reday'), GETPOST('reyear'));
		elseif ($object->element == 'commande') $date = dol_mktime(0, 0, 0, GETPOST('order_month'), GETPOST('order_day'), GETPOST('order_year'));

		$result = $object->set_date($user, $date);
		if ($result < 0)
		{
			$errors = array_merge($errors, $object->errors);
		}

		// validity date
		if ($object->element == 'propal') {
			$date = dol_mktime(0, 0, 0, GETPOST('echmonth'), GETPOST('echday'), GETPOST('echyear'));
			$result = $object->set_echeance($user, $date);
			if ($result < 0)
			{
				$errors = array_merge($errors, $object->errors);
			}
		}

		// delivery date
		if ($object->element == 'propal') $datelivraison = dol_mktime(0, 0, 0, GETPOST('date_livraisonmonth'), GETPOST('date_livraisonday'), GETPOST('date_livraisonyear'));
		elseif ($object->element == 'commande') $datelivraison = dol_mktime(0, 0, 0, GETPOST('liv_month'), GETPOST('liv_day'), GETPOST('liv_year'));

		$result = $object->set_date_livraison($user, $datelivraison);
		if ($result < 0)
		{
			$errors = array_merge($errors, $object->errors);
		}

		// payment method
		$result = $object->setPaymentMethods(GETPOST('mode_reglement_id', 'int'));
		if ($result < 0)
		{
			$errors = array_merge($errors, $object->errors);
		}

		// multicurrency
		if ( ! empty($conf->multicurrency->enabled) )
		{
			// Multicurrency Code
			$result = $object->setMulticurrencyCode(GETPOST('multicurrency_code', 'alpha'));
			if ($result < 0)
			{
				$errors = array_merge($errors, $object->errors);
			}

			// Multicurrency rate
			$result = $object->setMulticurrencyRate(price2num(GETPOST('multicurrency_tx')));
			if ($result < 0)
			{
				$errors = array_merge($errors, $object->errors);
			}
		}

		$result = $object->availability(GETPOST('availability_id'));
		if ($result < 0)
		{
			$errors = array_merge($errors, $object->errors);
		}

		$result = $object->demand_reason(GETPOST('demand_reason_id'));
		if ($result < 0)
		{
			$errors = array_merge($errors, $object->errors);
		}

		$result = $object->setPaymentTerms(GETPOST('cond_reglement_id', 'int'));
		if ($result < 0)
		{
			$errors = array_merge($errors, $object->errors);
		}

		// Set incoterm
		if (GETPOST('incoterm_id', 'int'))
		{
			$result = $object->setIncoterms(GETPOST('incoterm_id', 'int'), GETPOST('location_incoterms', 'alpha'));
			if ($result < 0)
			{
				$errors = array_merge($errors, $object->errors);
			}
		}

		// bank account
		if ($element == 'commande' && ! empty($conf->global->BANK_ASK_PAYMENT_BANK_DURING_ORDER) && ! empty($conf->banque->enabled))
		{
			$result=$object->setBankAccount(GETPOST('fk_account', 'int'));
			if ($result < 0)
			{
				$errors = array_merge($errors, $object->errors);
			}
		}

		// shipping method
		$result = $object->setShippingMethod(GETPOST('shipping_method_id', 'int'));
		if ($result < 0)
		{
			$errors = array_merge($errors, $object->errors);
		}

		// warehouse
		if ($element == 'commande' && ! empty($conf->expedition->enabled) && ! empty($conf->global->WAREHOUSE_ASK_WAREHOUSE_DURING_ORDER))
		{
			$result = $object->setWarehouse(GETPOST('warehouse_id', 'int'));
			if ($result < 0)
			{
				$errors = array_merge($errors, $object->errors);
			}
		}

		// extrafields
		$object->oldarray_options = $object->array_options;
		$extrafields = new ExtraFields($db);
		// fetch optionals attributes and labels
		$extrafields->fetch_name_optionals_label($object->table_element);

		$result = $extrafields->setOptionalsFromPost($extralabels, $object);
		if ($result < 0)
		{
			$errors = array_merge($errors, $extrafields->errors);
		}
		else
		{
			switch($element)
			{
				case 'propal' :
					$trigger = 'PROPAL_MODIFY';
					break;
				case 'commande' :
					$trigger = 'ORDER_MODIFY';
					break;
				case 'facture' :
					$trigger = 'BILL_MODIFY';
					break;
				default :
					$trigger = null;
			}
			$ret = $object->insertExtraFields($trigger);
			if ($ret < 0) $errors = array_merge($errors, $object->errors);
		}

		// génération pdf si pas d'erreur
		if (empty($errors))
		{
			if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) {
				// Define output language
				$outputlangs = $langs;
				$newlang = GETPOST('lang_id', 'alpha');
				if ($conf->global->MAIN_MULTILANGS && empty($newlang))
					$newlang = $object->thirdparty->default_lang;
				if (! empty($newlang)) {
					$outputlangs = new Translate("", $conf);
					$outputlangs->setDefaultLang($newlang);
				}

				$ret = $object->fetch($object->id); // Reload to get new records
				$object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
			}
		}

	}
	else
	{
		$errors[] = $langs->trans("ObjectNotFound");
	}
}
else
{
	$errors[] = $langs->trans("NotAuthorized");
}

echo base64_encode(json_encode($errors));

exit;

// mise à jour des lignes
function update_lines()
{
	global $object, $conf, $langs, $db, $mysoc, $errors, $user, $draftupdate;

	$subtotal_lines = array();

	// lignes
	foreach($_POST as $key => $val)
	{
		if (substr($key, 0, 11) == 'lineid_new_')
		{
			$lineid = substr($key, 7);

			if (isset($_POST['qty_'.$lineid])) // otherwise line was created then deleted
			{
				// new line
				$langs->load('errors');
				$error = 0;

				// Set if we used free entry or predefined product
				$product_desc = (posted($lineid,'dp_desc') ?posted($lineid,'dp_desc') : '');
				$price_ht = posted($lineid,'price_ht');
				$price_ht_devise = posted($lineid,'multicurrency_price_ht');
				$prod_entry_mode = posted($lineid,'prod_entry_mode');
				if ($prod_entry_mode == 'free')
				{
					$idprod = 0;
					$tva_tx = (posted($lineid,'tva_tx') ? posted($lineid,'tva_tx') : 0);
				}
				else
				{
					$idprod = posted($lineid,'productid', 'int');
					$tva_tx = '';
				}

				$qty = posted($lineid,'qty');
				$remise_percent = (posted($lineid,'remise_percent') != '' ? posted($lineid,'remise_percent') : 0);

				// Extrafields
				$extrafields = new ExtraFields($db);
				$extralabelsline = $extrafields->fetch_name_optionals_label($object->table_element_line);
				$array_options = $extrafields->getOptionalsFromPost($object->table_element_line, '_'.$lineid);

				if (empty($idprod) && ($price_ht < 0) && ($qty < 0)) {
					$errors = array_merge($errors, $langs->trans('ErrorBothFieldCantBeNegative', $langs->transnoentitiesnoconv('UnitPriceHT'), $langs->transnoentitiesnoconv('Qty')));
					$error++;
				}
				if ($prod_entry_mode == 'free' && empty($idprod) && posted($lineid,'type') < 0) {
					$errors = array_merge($errors, $langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Type')));
					$error++;
				}
				if ($prod_entry_mode == 'free' && empty($idprod) && $price_ht == '' && $price_ht_devise == '') 	// Unit price can be 0 but not ''. Also price can be negative for order.
				{
					$errors = array_merge($errors, $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("UnitPriceHT")));
					$error++;
				}
				if ($qty == '') {
					$errors = array_merge($errors, $langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Qty')));
					$error++;
				}
				if ($prod_entry_mode == 'free' && empty($idprod) && empty($product_desc)) {
					$errors = array_merge($errors, $langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Description')));
					$error++;
				}

				if (!$error && !empty($conf->variants->enabled) && $prod_entry_mode != 'free') {
					if ($combinations = posted($lineid,'combinations', 'array')) {
						//Check if there is a product with the given combination
						$prodcomb = new ProductCombination($db);

						if ($res = $prodcomb->fetchByProductCombination2ValuePairs($idprod, $combinations)) {
							$idprod = $res->fk_product_child;
						}
						else
						{
							$errors = array_merge($errors, $langs->trans('ErrorProductCombinationNotFound'));
							$error++;
						}
					}
				}

				if (!$error && ($qty >= 0) && (!empty($product_desc) || !empty($idprod))) {
					// Clean parameters
					$date_start = dol_mktime(posted($lineid,'date_start'.'hour'), posted($lineid,'date_start'.'min'), posted($lineid,'date_start'.'sec'), posted($lineid,'date_start'.'month'), posted($lineid,'date_start'.'day'), posted($lineid,'date_start'.'year'));
					$date_end = dol_mktime(posted($lineid,'date_end'.'hour'), posted($lineid,'date_end'.'min'), posted($lineid,'date_end'.'sec'), posted($lineid,'date_end'.'month'), posted($lineid,'date_end'.'day'), posted($lineid,'date_end'.'year'));
					$price_base_type = (posted($lineid,'price_base_type', 'alpha') ?posted($lineid,'price_base_type', 'alpha') : 'HT');

					// Ecrase $pu par celui du produit
					// Ecrase $desc par celui du produit
					// Ecrase $tva_tx par celui du produit
					// Ecrase $base_price_type par celui du produit
					if (!empty($idprod)) {
						$prod = new Product($db);
						$prod->fetch($idprod);

						$label = ((posted($lineid,'product_label') && posted($lineid,'product_label') != $prod->label) ? posted($lineid,'product_label') : '');

						// Update if prices fields are defined
						$tva_tx = get_default_tva($mysoc, $object->thirdparty, $prod->id);
						$tva_npr = get_default_npr($mysoc, $object->thirdparty, $prod->id);
						if (empty($tva_tx)) $tva_npr = 0;

						$pu_ht = $prod->price;
						$pu_ttc = $prod->price_ttc;
						$price_min = $prod->price_min;
						$price_base_type = $prod->price_base_type;

						// If price per segment
						if (!empty($conf->global->PRODUIT_MULTIPRICES) && !empty($object->thirdparty->price_level))
						{
							$pu_ht = $prod->multiprices[$object->thirdparty->price_level];
							$pu_ttc = $prod->multiprices_ttc[$object->thirdparty->price_level];
							$price_min = $prod->multiprices_min[$object->thirdparty->price_level];
							$price_base_type = $prod->multiprices_base_type[$object->thirdparty->price_level];
							if (!empty($conf->global->PRODUIT_MULTIPRICES_USE_VAT_PER_LEVEL))  // using this option is a bug. kept for backward compatibility
							{
								if (isset($prod->multiprices_tva_tx[$object->thirdparty->price_level])) $tva_tx = $prod->multiprices_tva_tx[$object->thirdparty->price_level];
								if (isset($prod->multiprices_recuperableonly[$object->thirdparty->price_level])) $tva_npr = $prod->multiprices_recuperableonly[$object->thirdparty->price_level];
							}
						}
						// If price per customer
						elseif (!empty($conf->global->PRODUIT_CUSTOMER_PRICES))
						{
							require_once DOL_DOCUMENT_ROOT.'/product/class/productcustomerprice.class.php';

							$prodcustprice = new Productcustomerprice($db);

							$filter = array('t.fk_product' => $prod->id, 't.fk_soc' => $object->thirdparty->id);

							$result = $prodcustprice->fetch_all('', '', 0, 0, $filter);
							if ($result >= 0)
							{
								if (count($prodcustprice->lines) > 0)
								{
									$pu_ht = price($prodcustprice->lines[0]->price);
									$pu_ttc = price($prodcustprice->lines[0]->price_ttc);
									$price_base_type = $prodcustprice->lines[0]->price_base_type;
									$tva_tx = $prodcustprice->lines[0]->tva_tx;
									if ($prodcustprice->lines[0]->default_vat_code && !preg_match('/\(.*\)/', $tva_tx)) $tva_tx .= ' ('.$prodcustprice->lines[0]->default_vat_code.')';
									$tva_npr = $prodcustprice->lines[0]->recuperableonly;
									if (empty($tva_tx)) $tva_npr = 0;
								}
							}
							else
							{
								$errors = array_merge($errors, $prodcustprice->error, $prodcustprice->errors, 'errors');
							}
						}
						// If price per quantity
						elseif (!empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY))
						{
							if ($prod->prices_by_qty[0])	// yes, this product has some prices per quantity
							{
								// Search the correct price into loaded array product_price_by_qty using id of array retrieved into POST['pqp'].
								$pqp = posted($lineid,'pbq', 'int');

								// Search price into product_price_by_qty from $prod->id
								foreach ($prod->prices_by_qty_list[0] as $priceforthequantityarray)
								{
									if ($priceforthequantityarray['rowid'] != $pqp) continue;
									// We found the price
									if ($priceforthequantityarray['price_base_type'] == 'HT')
									{
										$pu_ht = $priceforthequantityarray['unitprice'];
									}
									else
									{
										$pu_ttc = $priceforthequantityarray['unitprice'];
									}
									// Note: the remise_percent or price by qty is used to set data on form, so we will use value from POST.
									break;
								}
							}
						}
						// If price per quantity and customer
						elseif (!empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES))
						{
							if ($prod->prices_by_qty[$object->thirdparty->price_level])	// yes, this product has some prices per quantity
							{
								// Search the correct price into loaded array product_price_by_qty using id of array retrieved into POST['pqp'].
								$pqp = posted($lineid,'pbq', 'int');
								// Search price into product_price_by_qty from $prod->id
								foreach ($prod->prices_by_qty_list[$object->thirdparty->price_level] as $priceforthequantityarray)
								{
									if ($priceforthequantityarray['rowid'] != $pqp) continue;
									// We found the price
									if ($priceforthequantityarray['price_base_type'] == 'HT')
									{
										$pu_ht = $priceforthequantityarray['unitprice'];
									}
									else
									{
										$pu_ttc = $priceforthequantityarray['unitprice'];
									}
									// Note: the remise_percent or price by qty is used to set data on form, so we will use value from POST.
									break;
								}
							}
						}

						$tmpvat = price2num(preg_replace('/\s*\(.*\)/', '', $tva_tx));
						$tmpprodvat = price2num(preg_replace('/\s*\(.*\)/', '', $prod->tva_tx));

						// if price ht is forced (ie: calculated by margin rate and cost price). TODO Why this ?
						if (!empty($price_ht)) {
							$pu_ht = price2num($price_ht, 'MU');
							$pu_ttc = price2num($pu_ht * (1 + ($tmpvat / 100)), 'MU');
						}
						// On reevalue prix selon taux tva car taux tva transaction peut etre different
						// de ceux du produit par defaut (par exemple si pays different entre vendeur et acheteur).
						elseif ($tmpvat != $tmpprodvat) {
							if ($price_base_type != 'HT') {
								$pu_ht = price2num($pu_ttc / (1 + ($tmpvat / 100)), 'MU');
							} else {
								$pu_ttc = price2num($pu_ht * (1 + ($tmpvat / 100)), 'MU');
							}
						}

						$desc = '';

						// Define output language
						if (!empty($conf->global->MAIN_MULTILANGS) && !empty($conf->global->PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE)) {
							$outputlangs = $langs;
							$newlang = '';
							if (empty($newlang) && posted($lineid,'lang_id', 'aZ09'))
								$newlang = posted($lineid,'lang_id', 'aZ09');
							if (empty($newlang))
								$newlang = $object->thirdparty->default_lang;
							if (!empty($newlang)) {
								$outputlangs = new Translate("", $conf);
								$outputlangs->setDefaultLang($newlang);
							}

							$desc = (!empty($prod->multilangs [$outputlangs->defaultlang] ["description"])) ? $prod->multilangs [$outputlangs->defaultlang] ["description"] : $prod->description;
						} else {
							$desc = $prod->description;
						}

						if (!empty($product_desc) && !empty($conf->global->MAIN_NO_CONCAT_DESCRIPTION)) $desc = $product_desc;
						else $desc = dol_concatdesc($desc, $product_desc, '', !empty($conf->global->MAIN_CHANGE_ORDER_CONCAT_DESCRIPTION));

						// Add custom code and origin country into description
						if (empty($conf->global->MAIN_PRODUCT_DISABLE_CUSTOMCOUNTRYCODE) && (!empty($prod->customcode) || !empty($prod->country_code))) {
							$tmptxt = '(';
							// Define output language
							if (!empty($conf->global->MAIN_MULTILANGS) && !empty($conf->global->PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE)) {
								$outputlangs = $langs;
								$newlang = '';
								if (empty($newlang) && posted($lineid,'lang_id', 'alpha'))
									$newlang = posted($lineid,'lang_id', 'alpha');
								if (empty($newlang))
									$newlang = $object->thirdparty->default_lang;
								if (!empty($newlang)) {
									$outputlangs = new Translate("", $conf);
									$outputlangs->setDefaultLang($newlang);
									$outputlangs->load('products');
								}
								if (!empty($prod->customcode))
									$tmptxt .= $outputlangs->transnoentitiesnoconv("CustomCode").': '.$prod->customcode;
								if (!empty($prod->customcode) && !empty($prod->country_code))
									$tmptxt .= ' - ';
								if (!empty($prod->country_code))
									$tmptxt .= $outputlangs->transnoentitiesnoconv("CountryOrigin").': '.getCountry($prod->country_code, 0, $db, $outputlangs, 0);
							} else {
								if (!empty($prod->customcode))
									$tmptxt .= $langs->transnoentitiesnoconv("CustomCode").': '.$prod->customcode;
								if (!empty($prod->customcode) && !empty($prod->country_code))
									$tmptxt .= ' - ';
								if (!empty($prod->country_code))
									$tmptxt .= $langs->transnoentitiesnoconv("CountryOrigin").': '.getCountry($prod->country_code, 0, $db, $langs, 0);
							}
							$tmptxt .= ')';
							$desc = dol_concatdesc($desc, $tmptxt);
						}

						$type = $prod->type;
						$fk_unit = $prod->fk_unit;
					} else {
						$pu_ht = price2num($price_ht, 'MU');
						$pu_ttc = price2num(posted($lineid,'price_ttc'), 'MU');
						$tva_npr = (preg_match('/\*/', $tva_tx) ? 1 : 0);
						$tva_tx = str_replace('*', '', $tva_tx);
						$label = (posted($lineid,'product_label') ? posted($lineid,'product_label') : '');
						$desc = $product_desc;
						$type = posted($lineid,'type');
						$fk_unit = posted($lineid,'units', 'alpha');
						$pu_ht_devise = price2num($price_ht_devise, 'MU');
					}

					// Margin
					$fournprice = price2num(posted($lineid,'fournprice') ? posted($lineid,'fournprice') : '');
					$buyingprice = price2num(posted($lineid,'buying_price') != '' ? posted($lineid,'buying_price') : ''); // If buying_price is '0', we muste keep this value

					// Local Taxes
					$localtax1_tx = get_localtax($tva_tx, 1, $object->thirdparty);
					$localtax2_tx = get_localtax($tva_tx, 2, $object->thirdparty);

					$desc = dol_htmlcleanlastbr($desc);

					$info_bits = 0;
					if ($tva_npr)
						$info_bits |= 0x01;

					if (((!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->produit->ignore_price_min_advance)) || empty($conf->global->MAIN_USE_ADVANCED_PERMS)) && (!empty($price_min) && (price2num($pu_ht) * (1 - price2num($remise_percent) / 100) < price2num($price_min)))) {
						$mesg = $langs->trans("CantBeLessThanMinPrice", price(price2num($price_min, 'MU'), 0, $langs, 0, 0, - 1, $conf->currency));
						$errors = array_merge($errors, $mesg);
					} else {
						// Insert line
						if ($object->element == 'commande') $result = $object->addline($desc, $pu_ht, $qty, $tva_tx, $localtax1_tx, $localtax2_tx, $idprod, $remise_percent, $info_bits, 0, $price_base_type, $pu_ttc, $date_start, $date_end, $type, posted($lineid,'rank'), 0, posted($lineid,'fk_parent_line'), $fournprice, $buyingprice, $label, $array_options, $fk_unit, '', 0, $pu_ht_devise);

						elseif ($object->element == 'propal') $result = $object->addline($desc, $pu_ht, $qty, $tva_tx, $localtax1_tx, $localtax2_tx, $idprod, $remise_percent, $price_base_type, $pu_ttc, $info_bits, $type, posted($lineid,'rank'), 0, posted($lineid,'fk_parent_line'), $fournprice, $buyingprice, $label, $date_start, $date_end, $array_options, $fk_unit, '', 0, $pu_ht_devise);

						if (result < 0) $errors = array_merge($errors, $object->errors);
					}
				}
			}
		}
		elseif (substr($key, 0, 7) == 'lineid_')
		{
			$lineid = substr($key, 7);
			$special_code = posted($lineid,'special_code');
			$rang = posted($lineid,'rank');

			// lignes sous-total

			if ($conf->subtotal->enabled)
			{
				dol_include_once('/subtotal/class/subtotal.class.php');
			}

			if ($conf->subtotal->enabled && $special_code == TSubtotal::$module_number && posted($lineid, 'product_type') == 9 )
			{
				// memorize subtotal lines to parse them after the others
				$subtotal_lines[] = $lineid;
			}

			elseif (isset($_POST['qty_'.$lineid]))
			{
				// update line

				// Clean parameters
				$date_start = '';
				$date_end = '';
				$date_start = dol_mktime(posted($lineid,'date_starthour'), posted($lineid,'date_startmin'), posted($lineid,'date_startsec'), posted($lineid,'date_startmonth'), posted($lineid,'date_startday'), posted($lineid,'date_startyear'));
				$date_end = dol_mktime(posted($lineid,'date_endhour'), posted($lineid,'date_endmin'), posted($lineid,'date_endsec'), posted($lineid,'date_endmonth'), posted($lineid,'date_endday'), posted($lineid,'date_endyear'));
				$description = dol_htmlcleanlastbr(posted($lineid,'product_desc', 'none'));
				$pu_ht = posted($lineid,'price_ht');
				$vat_rate = (posted($lineid,'tva_tx') ?posted($lineid,'tva_tx') : 0);
				$pu_ht_devise = posted($lineid,'multicurrency_subprice');

				// Define info_bits
				$info_bits = 0;
				if (preg_match('/\*/', $vat_rate))
					$info_bits |= 0x01;

				// Define vat_rate
				$vat_rate = str_replace('*', '', $vat_rate);
				$localtax1_rate = get_localtax($vat_rate, 1, $object->thirdparty, $mysoc);
				$localtax2_rate = get_localtax($vat_rate, 2, $object->thirdparty, $mysoc);

				// Add buying price
				$fournprice = price2num(posted($lineid,'fournprice') ? posted($lineid,'fournprice') : '');
				$buyingprice = price2num(posted($lineid,'buying_price') != '' ? posted($lineid,'buying_price') : ''); // If buying_price is '0', we muste keep this value

				// Extrafields Lines
				$extrafields = new ExtraFields($db);
				$extralabelsline = $extrafields->fetch_name_optionals_label($object->table_element_line);
				$array_options = $extrafields->getOptionalsFromPost($object->table_element_line, '_'.$lineid);

				// Define special_code for special lines
				if (!posted($lineid,'qty')) $special_code = 3;

				// Check minimum price
				$productid = posted($lineid,'productid', 'int');
				if (!empty($productid)) {
					$product = new Product($db);
					$product->fetch($productid);

					$type = $product->type;

					$price_min = $product->price_min;
					if ((!empty($conf->global->PRODUIT_MULTIPRICES) || !empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES)) && !empty($object->thirdparty->price_level))
						$price_min = $product->multiprices_min[$object->thirdparty->price_level];

					$label = ((posted($lineid,'update_label') && posted($lineid,'product_label')) ? posted($lineid,'product_label') : '');

					if (((!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->produit->ignore_price_min_advance)) || empty($conf->global->MAIN_USE_ADVANCED_PERMS)) && ($price_min && (price2num($pu_ht) * (1 - price2num(posted($lineid,'remise_percent')) / 100) < price2num($price_min)))) {
						$errors = array_merge($errors, $langs->trans("CantBeLessThanMinPrice", price(price2num($price_min, 'MU'), 0, $langs, 0, 0, - 1, $conf->currency)));
						$error++;
					}
				} else {
					$type = posted($lineid,'type');
					$label = (posted($lineid,'product_label') ? posted($lineid,'product_label') : '');

					// Check parameters
					if (posted($lineid,'type') < 0) {
						$errors = array_merge($errors, $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Type")));
						$error++;
					}
				}

				if (!$error) {
					if (empty($user->rights->margins->creer))
					{
						$fournprice = $line->fk_fournprice;
						$buyingprice = $line->pa_ht;
					}

					if ($object->element == 'commande') $result = $object->updateline(posted($lineid,'lineid'), $description, $pu_ht, posted($lineid,'qty'), posted($lineid,'remise_percent'), $vat_rate, $localtax1_rate, $localtax2_rate, 'HT', $info_bits, $date_start, $date_end, $type, posted($lineid,'fk_parent_line'), 0, $fournprice, $buyingprice, $label, $special_code, $array_options, posted($lineid,'units'), $pu_ht_devise);

					elseif ($object->element == 'propal') $result = $object->updateline(posted($lineid,'lineid'), $pu_ht, posted($lineid,'qty'), posted($lineid,'remise_percent'), $vat_rate, $localtax1_rate, $localtax2_rate, $description, 'HT', $info_bits, $special_code, posted($lineid,'fk_parent_line'), 0, $fournprice, $buyingprice, $label, $type, $date_start, $date_end, $array_options, posted($lineid,'units'), $pu_ht_devise);

					if ($result < 0) $errors = array_merge($errors, $object->errors);
				}
				else
				{
					$errors = array_merge($errors, $object->errors);
				}
			}
			else
			{
				// delete line
				$object->deleteline($user, $lineid);
			}
		}
	}

	// subtotal lines
	$save_mesgs = $_SESSION['dol_events'];

	foreach ($subtotal_lines as $lineid)
	{
		//Commented by Christophe Battarel$object->updateRangOfLine($lineid, $rang);

		dol_include_once('/subtotal/lib/subtotal.lib.php');

		if ($object->element == 'commande') $line = new $object->class_element_line($db);
		elseif($object->element == 'propal') $line = new PropaleLigne($db);

		$line->fetch($lineid);

		$_POST['line-title'] = posted($lineid, 'line-title');
		$_POST['line-description'] = posted($lineid, 'line-description');
		$_POST['line-qty'] = posted($lineid, 'line-qty');
		$_POST['line-pagebreak'] = posted($lineid, 'subtotal-pagebreak'); // original name was line-pagebreak and id was subtotal-pagebreak
		$_POST['line-showTotalHT'] = posted($lineid, 'subtotal-showTotalHT'); // original name was line-showTotalHT and id was subtotal-pagebreak
		$_POST['line-showReduc'] = posted($lineid, 'subtotal-showReduc'); // original name was line-showReduc and id was subtotal-pagebreak
		$_POST['subtotal_level'] = posted($lineid, 'subtotal_level');
		$_POST['subtotal_tva_tx'] = posted($lineid, 'subtotal_tva_tx');
		$_POST['subtotal_progress'] = posted($lineid, 'subtotal_progress');
		$showBlockExtrafields = posted($lineid, 'showBlockExtrafields');

		if(TSubtotal::isTitle($line) && !empty($showBlockExtrafields))
		{
			$extrafieldsline = new ExtraFields($db);
			$extralabelsline = $extrafieldsline->fetch_name_optionals_label($object->table_element_line);
			$extrafieldsline->setOptionalsFromPost($extralabelsline, $line);
		}

		$label = GETPOST('line-title', 'none');
		$description = ($line->qty>90) ? '' : GETPOST('line-description', 'restricthtml');
		$pagebreak = GETPOST('line-pagebreak', 'int');
		$showTotalHT = GETPOST('line-showTotalHT', 'int');
		$showReduc = GETPOST('line-showReduc', 'int');

		$level = GETPOST('subtotal_level', 'int');
		if (!empty($level))
		{
			if ($line->qty > 90) $line->qty = 100 - $level; // Si on edit une ligne sous-total
			else $line->qty = $level;
		}
		$line->array_options['options_show_total_ht'] = $showTotalHT;
		$line->array_options['options_show_reduc'] = $showReduc;

		$res = TSubtotal::doUpdateLine($object, $line->id, $description, 0, $line->qty, 0, '', '', 0, 9, 0, 0, 'HT', $pagebreak, 0, 1, null, 0, $label, TSubtotal::$module_number, $line->array_options);

		if ($res < 0) $errors = array_merge($errors, $object->errors);
		else
		{
			$result = _updateSubtotalBloc($object, $line);
			if ($result < 0) $errors = array_merge($errors, $object->errors);
		}
	}

	$_SESSION['dol_events'] = $save_mesgs;
}

function posted($lineid, $var, $type=null)
{
	return GETPOST($var.'_'.$lineid, $type);
	//Commented by Christophe Battarelreturn $_POST[$var.'_'.$lineid];
}
?>
