<?php
namespace Models;

// Модель строк чека
class Receiptlines extends \DB\SQL\Mapper {
	public $db, $f3;
	public $marking_group=array(
		1=>array('title'=>'Предметы одежды, белье постельное, столовое, туалетное и кухонное', 'pg'=>'lp'),
		2=>array('title'=>'Обувные товары', 'pg'=>'shoes'),
		3=>array('title'=>'Табачные изделия', 'pg'=>'tobacco'),
		4=>array('title'=>'Духи и туалетная вода', 'pg'=>'perfumery'),
		5=>array('title'=>'Шины и покрышки пневматические резиновые новые', 'pg'=>'tires'),
		6=>array('title'=>'Фотокамеры (кроме кинокамер), фотовспышки и лампы-вспышки', 'pg'=>'electronics'),
		7=>array('title'=>'Лекарственные препараты для медицинского применения', 'pg'=>'pharma'),
		8=>array('title'=>'Молочная продукция', 'pg'=>'milk'),
		9=>array('title'=>'Велосипеды и велосипедные рамы', 'pg'=>'bicycle'),
		10=>array('title'=>'Кресла-коляски', 'pg'=>'wheelchairs'),
		11=>array('title'=>'Меховые изделия', 'pg'=>'furs'),
		12=>array('title'=>'Альтернативная табачная продукция', 'pg'=>'otp'),
		13=>array('title'=>'Питьевая вода', 'pg'=>'water')
	);

	public function __construct($db, $f3) {
		parent::__construct($db, 'receiptlines'); // подключаемся к таблице строк чека
		$this->db=$db;
		$this->f3=$f3;
	}

	// Проверяем повтор марки
	function check_double_mark($mark) {
		$mark=str_replace('', '\\u001d', $mark);
		$this->reset();
		$this->load(array('mark like ?', '%"'.$mark.'"%'), array('limit'=>1));
		if($this->dry()) {
			return array(
				'success'=>true,
				'txt'=>'double_mark_not_found'
			);
		}
		return array(
			'success'=>false,
			'txt'=>'double_mark_found'
		);
	}

	// Выбираем строки из базы
	function select_lines($query, $option=null) {
		$products=new \Models\Products($this->db, $this->f3);
		$categories=new \DB\SQL\Mapper($this->db, 'productcategories');
		$barcodes=new \DB\SQL\Mapper($this->db, 'barcodes');
		$partners=new \DB\SQL\Mapper($this->db, 'partners');
		$lines=array();
		$parent=array();
		$modifiers=array();
		$sort_lines=array();
		$this->load($query, $option);
		if(!$this->dry()) {
			$units=array_combine(array_column($products->units, 'number'), array_keys($products->units));
			do {
				$l=$this->cast();
				$l['pg']='';
				$l['unit_okei']=isset($units[$l['units_fr']])?$units[$l['units_fr']]:0;
				$products->reset();
				$products->load(array('id=?', $l['product_id']), array('limit'=>1));
				if(!$products->dry()) {
					$l['partner']=array();
					if($products->partner_id>0) {
						$partners->load(array('partner_id=?', $products->partner_id), array('limit'=>1));
						if(!$partners->dry()) {
							$l['partner']=$partners->cast();
						}
					}
					if($products->marking_group>0) {
						$l['pg']=$this->marking_group[$products->marking_group]['pg'];
					}
					$l['img']=json_decode($products->img, true);
					$l['max_discount']=$products->max_discount;
					$l['print_group']=$products->print_group;
					$l['quantity']=$products->quantity;
					$l['egais']=$products->egais;
					$l['category_id']=$products->category_id;
					$l['ppr']=$products->ppr;
					$l['print_group']=$products->print_group;
					$l['add_bonus']=$products->add_bonus;
					$l['stock']=$products->stock;
					$l['stop']=$products->stop;
					$l['sno']=$products->sno;
					$barcodes->reset();
					$barcodes->load(array('product_id=?', $products->id), array('limit'=>1));
					$l['barcode']=$barcodes->barcode;
				}
				else {
					$l['max_discount']=100;
					$l['print_group']=0;
					$l['egais']=0;
					$other_info=json_decode($l['other_info'], true);
					if($other_info) {
						$l['category_id']=$other_info['category_id'];
						$l['ppr']=$other_info['ppr'];
						$l['print_group']=$other_info['print_group'];
						$l['barcode']=$other_info['barcode'];
					}
				}
				if($l['category_id']) {
					$categories->reset();
					$categories->load(array('id=?', $l['category_id']), array('limit'=>1));
					if(!$categories->dry()) {
						$l['category_title']=$categories->title;
						$l['category_parent_id']=$categories->parent_id;
					}
				}

				if($l['parent_id']>0) {
					$l['print_group']=$parent[$l['parent_id']]['print_group'];
					$modifiers[$l['parent_id']][]=$l;
				}
				else {
					$parent[$l['id']]=$l;
					$lines[]=$l;
				}
			}
			while($this->skip());
		}
		$this->reset();
		$kop=array();
		if($lines) {
			foreach ($lines as $l) {
				if($l['price']<0) {
					$kop=$l;
					continue;
				}
				$sort_lines[]=$l;
				if(isset($modifiers[$l['id']])) {
					$modifiers[$l['id']][array_key_last($modifiers[$l['id']])]['last']=1;
					$sort_lines=array_merge($sort_lines, $modifiers[$l['id']]);
					unset($modifiers[$l['id']]);
				}
			}
		}
		if($modifiers) {
			foreach ($modifiers as $m) {
				$sort_lines=array_merge($sort_lines, $m);
			}
		}
		if($kop) {
			$sort_lines[]=$kop;
		}
		return $sort_lines;
	}

	// Добавляем строку в чек
	function add_line($receipt_id, $line, $count=1, $parent_id=0, $create_order=null, $complite_order=null, $issued_order=null) {
		if($count<0) {
			return array(
				'success'=>false,
				'txt'=>'quantity_error'
			);
		}
		$line['parent_id']=$parent_id;
		if(!$line['turn']) $line['turn']=1;
		if($parent_id>0) {
			$this->load(array('id=?', $parent_id), array('limit'=>1));
			if($this->dry()) {
				return array(
					'success'=>true,
					'txt'=>'not_found',
					'function'=>'$(".modifiers_'.$line['product_id'].'").addClass("modifiers_count_1");'
				);
			}
			$line['kitchen']=$this->kitchen;
			$line['bar']=$this->bar;
			$line['print_group_id']=$this->print_group_id;
			$line['turn']=$this->turn;
			$line['create_order']=$this->create_order;
			$line['complite_order']=$this->complite_order;
			$line['issued_order']=$this->issued_order;
		}
		if(!isset($line['units_fr'])) $line['units_fr']=255;
		$line['receipt_id']=$receipt_id;
		$count=str_replace(',', '.', $count);
		$line['count']=abs(round($count, 3));
		$line['product_id']=$line['id'];
		if(!$line['product_title']) {
			$line['product_title']=$line['short_title'];
			if(!$line['product_title']) {
				$line['product_title']=$line['title'];
			}
		}
		$line['price']=str_replace(',', '.', $line['price']);
		$line['price']=abs($line['price']);
		if(!isset($line['price0'])) {
			$line['price0']=$line['price'];
		}
		if(!isset($line['discount'])) {
			$line['discount']=0;
		}
		if(!$line['loyalty']) {
			$line['loyalty']=0;
		}
		if(!$line['turn']) {
			$line['turn']=1;
		}
		if($create_order) {
			$line['create_order']=$create_order;
		}
		if($complite_order) {
			$line['complite_order']=$complite_order;
		}
		if($issued_order) {
			$line['issued_order']=$issued_order;
		}
		unset($line['id']);
		$this->reset();
		if($parent_id>0) {
			$this->load(array('product_id=? AND parent_id=?', array($line['product_id'], $parent_id)), array('limit'=>1));
			if($count==0) {
				return $this->delete_line($this->id);
			}
		}
		if(!is_numeric($line['price']) || $count<0) {
			return array(
				'success'=>false,
				'txt'=>'incorrect_data',
				'function'=>'$(".modifiers_false_'.$line['product_id'].'").addClass("modifiers_count_-1");'
			);
		}

		if($line['product_id']==null)$line['product_id']=0;
		$line['product_title']=html_entity_decode(html_entity_decode($line['product_title']));
		if(is_array($line['barcodes'])) $line['barcodes']=json_encode(array_column($line['barcodes'], 'barcode'));
		$this->copyFrom($line);
		if($this->save()) {
			if($this->id) {
				$id=$this->id;
			}
			else {
				$id=$this->get('_id');
			}
			if($parent_id>0) {
				$scrollto='#line_'.$parent_id;
				$id=$parent_id;
				//$this->db->exec("UPDATE receiptlines SET bar=0, kitchen=0 WHERE id=? OR parent_id=?", array($parent_id, $parent_id));
			}
			else {
				$scrollto='#line_'.$id;
			}

			return array(
				'success'=>true,
				'txt'=>'save_successful',
				'line'=>$line,
				//'reload'=>array('.receiptlines', '#receipts_buttons', '.button_total'),
				'reload'=>array('.receiptlines'),
				'id'=>$id,
				'scroll'=>'.receiptlines_div',
				'scrollto'=>$scrollto,
				'close_all_window'=>true,
				'function'=>'$(".modifiers_'.$line['product_id'].'").addClass("modifiers_count_1"); $(".free_title").val(""); $("#add_product_'.$line['product_id'].'").addClass("success_complete");'
			);
		}
		else {
			return array(
				'success'=>false,
				'txt'=>'db_error',
				'function'=>'$(".modifiers_'.$line['product_id'].'").addClass("modifiers_count_-1");  $("#add_product_'.$line['product_id'].'").addClass("error_complete")'
			);
		}
	}

	// Меняем строку в чеке
	function change_line($line_id, $count, $price, $discount=0, $description=false, $loyalty=false, $writeoff_bonus=0) {
		$this->reset();
		$this->load(array('id=?', $line_id), array('limit'=>1));
		if($this->dry()) {
			return array(
				'success'=>false,
				'txt'=>'not_found'
			);
		}
		if($this->parent_id==0 && ($this->kitchen>0 || $this->bar>0) && (isset($count) && $count!='' && $count!=$this->count)) {
			return array(
				'success'=>false,
				'txt'=>'position_is_already_in_progress'
			);
		}
		if($this->mark!='' && ($count && $count!=1) && $this->units_fr==0) {
			return array(
				'success'=>false,
				'txt'=>'quantity_marked_goods_may_not_exceed_1'
			);
		}
		$line=$this->cast();
		if($count) {
			$count=str_replace(',', '.', $count);
			$line['count']=round($count, 3);
		}

		if($line['count']<0) {
			return array(
				'success'=>false,
				'txt'=>'quantity_error'
			);
		}
		
		if(isset($price)) {
			$price=str_replace(',', '.', $price);
			if($line['vat_type']>0) {
				$price-=$price/(100+$line['vat'])*$line['vat'];
			}
			$line['price']=floatval($price);
		}
		$line['line_discount']=$discount;
		if(!$discount && $price && !$writeoff_bonus) {
			$line['price0']=$line['price'];
		}
		if($description!==false) {
			$line['description']=$description;
		}
		if($loyalty!==false) {
			$line['loyalty']=$loyalty;
		}
		$line['writeoff_bonus']=$writeoff_bonus;
		$this->copyFrom($line);
		if($this->update()) {
			if($line['parent_id']>0) {
				$val=array($line['parent_id'], $line['parent_id']);
			}
			else {
				$val=array($line['id'], $line['id']);
			}
			//$this->db->exec("UPDATE receiptlines SET bar=0, kitchen=0 WHERE id=? OR parent_id=?", $val);
			return array(
				'success'=>true,
				'txt'=>'save_successful',
				//'reload'=>array('.receiptlines', '#receipts_buttons', '.button_total'),
				'reload'=>array('.receiptlines'),
				'scroll'=>'.receiptlines_div',
				'scrollto'=>'#line_'.$line_id,
				'id'=>$line_id,
				'line'=>$line,
				'close_all_window'=>true
			);
		}
		else {
			return array(
				'success'=>false,
				'txt'=>'db_error'
			);
		}
	}

	// Удаляем строку из чека
	function delete_line($line_id, $receipt=null) {
		$this->reset();
		$return_bonus=0;
		if($line_id=='all') {
			if($receipt) {
				$receipt_id=$receipt['id'];
				if($receipt['partner_id']>0) {
					$res=$this->db->exec('SELECT SUM(writeoff_bonus) as return_bonus FROM receiptlines WHERE receipt_id=?', $receipt_id);
					if($res[0]['return_bonus']>0)$return_bonus=$res[0]['return_bonus'];
				}
			}
			else {
				$receipt_id=$this->f3->get('COOKIE.receipt_id');
			}
			$res=$this->db->exec("DELETE FROM `receiptlines` WHERE `receipt_id`=?", $receipt_id);
			if($res===false) {
				return array(
					'success'=>false,
					'txt'=>'db_error',
				);
			}
		}
		else {
			$this->load(array('id=?', $line_id), array('limit'=>1));
			if($this->dry()) {
				return array(
					'success'=>false,
					'txt'=>'not_found'
				);
			}
			$line=$this->cast();

			if($receipt['partner_id']>0) {
				$return_bonus=$line['writeoff_bonus'];
			}

			if($this->combo_id>0) {
				$combo_lines=$this->db->exec("SELECT id FROM receiptlines WHERE combo_id=?", $this->combo_id);
			}

			if($this->erase(array('id=? OR parent_id=? OR (combo_id>0 AND combo_id=?)', array($line_id, $line_id, $this->combo_id)))===false) {
				return array(
					'success'=>false,
					'txt'=>'db_error',
					'function'=>'$(".modifiers_'.$line['product_id'].'").addClass("modifiers_count_-1");'
				);
			}
		}
		if($combo_lines) {
			$this->erase(array('parent_id IN ('.implode(', ', array_column($combo_lines, 'id')).')'));
		}
		if($return_bonus>0) {
			$this->db->exec("UPDATE partners SET bonus=bonus+? WHERE partner_id=?", array($return_bonus, $receipt['partner_id']));
		}
		return array(
			'success'=>true,
			'txt'=>'save_successful',
			//'reload'=>array('.receiptlines', '#receipts_buttons', '.button_total'),
			'reload'=>array('.receiptlines'),
			'line'=>$line,
			'close_all_window'=>true
		);
	}

	// Узнаем сумму строк
	function get_sum($lines, $discount=0, $round_kop=0, $bonus_pay=0, $ignore_max_discount=0) {
		$sum=0;
		$sum0=0;
		$receipt_id=0;
		if(!$lines) {
			return 0;
		}
		if($bonus_pay>0) {
			$lines_bonus=$this->lines_price_bonus_pay($lines, $bonus_pay, $ignore_max_discount);
			$lines=$lines_bonus['lines'];
		}

		foreach ($lines as $key=>$l) {
			if($ignore_max_discount) {
				$l['max_discount']=100;
			}
			if($round_kop==1 && $l['loyalty']==3) continue;
			if($receipt_id==0) {
				$receipt_id=$l['receipt_id'];
			}
			$s=round($l['price']+($l['price']*(($l['vat']/100)*max(0, $l['vat_type']))), 2);
			if($l['discount']) {
				$s-=$s*($l['discount']/100);
			}
			else {
				if($discount && !$l['loyalty']) {
					if($discount<$l['max_discount']) {
						$s-=$s*($discount/100);
					}
					else {
						$s-=$s*($l['max_discount']/100);
					}
				}
			}
			$lines[$key]['discount_sum']=$lines[$key]['price']-$s;
			$lines[$key]['price']=$s;
			$s=round($s*$l['count'], 2);
			$sum+=$s;
		}

		$d_sum=$sum-floor($sum);
		if((int)$round_kop==1) {
			$this->delete_kop($receipt_id, $d_sum);
			$sum=floor($sum);
		}

		$sum=round($sum, 2);
		return array(
			'sum'=>$sum,
			'lines'=>$lines
		);
	}

	// Отбрасываем копейки
	function delete_kop($receipt_id, $kop) {
		$this->reset();
		$this->load(array('receipt_id=? AND loyalty=3', $receipt_id), array('limit'=>1));
		if($kop==0) {
			$this->erase();
			return;
		}
		$data=array(
			'receipt_id'=>$receipt_id,
			'product_id'=>0,
			'product_title'=>'Отбрасывание копеек',
			'price'=>-$kop,
			'price0'=>-$kop,
			'discount'=>0,
			'line_discount'=>0,
			'vat'=>0,
			'vat_type'=>0,
			'count'=>1,
			'description'=>'Отбрасывание копеек',
			'loyalty'=>3,
		);
		$this->copyFrom($data);
		$this->save();
	}

	// Отмечаем, что позиция была напечатана на принтере кухни или бара
	function print_ok($line_id, $printer) {
		$this->reset();
		$this->load(array('id=?', $line_id), array('limit'=>1));
		if($this->dry()) {
			return false;
		}
		$data[$printer]=1;
		if($printer=='kitchen' || $printer=='bar') {
			$data['create_order']=microtime(true);
		}
		$this->copyFrom($data);
		if($this->update()===false) {
			return false;
		}
		return true;
	}

	// Выдаем то что не надо отправлять на кухню или бар
	function issued_receipt($receipt_id, $all=0) {
		$where_product='';
		if($all==0) {
			$where_product=' AND ((bar=0 AND kitchen=0) OR product_id<0) ';
		}
		$this->db->exec("UPDATE `receiptlines` SET `create_order`=(case create_order when 0 then ? else create_order end), `complite_order`=(case complite_order when 0 then ? else complite_order end), `issued_order`=(case issued_order when 0 then ? else issued_order end) WHERE `receipt_id`=? ".$where_product, array(microtime(true), microtime(true), microtime(true), $receipt_id));
	}

	// Сохраняем строки в базе данных
	function save_lines($receipt, $discount=0, $create_order=null, $complite_order=null, $issued_order=null) {
		if($create_order===null) $create_order=microtime(true);
		if($complite_order===null) $complite_order=microtime(true);
		if($issued_order===null) $issued_order=microtime(true);
		if(!$receipt['id']) {
			return array(
				'success'=>false,
				'txt'=>'not_enough_data'
			);
		}
		if($discount!=0) {
			$lines=$this->select_lines(array('receipt_id=? AND loyalty=0', $receipt['id']));
			if($lines) {
				foreach ($lines as $l) {
					if($l['max_discount']<$discount) {
						$d=$l['max_discount'];
					}
					else {
						$d=$discount;
					}
					if($receipt['partner']['ignore_max_discount']>0) {
						$d=$discount;
					}
					if($d) {
						if($receipt['client'] || $receipt['partner_id']) {
							$description='Скидка клиента';
						}
						else {
							$description='Скидка на чек';
						}
					}
					else {
						$description='';
					}
					$res=$this->db->exec("UPDATE `receiptlines` SET `discount`=?, `description`=? WHERE `id`=?", array($d, $description, $l['id']));
					if($res===false) break;
				}
			}
		}
		$res=$this->db->exec("UPDATE `receiptlines` SET `create_order`=(case create_order when 0 then ? else create_order end), `complite_order`=(case complite_order when 0 then ? else complite_order end), `issued_order`=(case issued_order when 0 then ? else issued_order end) WHERE `receipt_id`=?", array($create_order, $complite_order, $issued_order, $receipt['id']));
		if($res===false) {
			return array(
				'success'=>false,
				'txt'=>'db_error'
			);
		}
		return array(
			'success'=>true,
			'txt'=>'save_successful',
			//'reload'=>array('.receiptlines', '#receipts_buttons', '.button_total'),
			'reload'=>array('.receiptlines'),
			'reload_menu'=>true,
			'close_all_window'=>true
		);
	}

	// Применение программ лояльности
	function apply_loyalty($receipt, $product, $loyalty) {
		$res=$this->db->exec("SELECT SUM(count) AS count FROM `receiptlines` WHERE receipt_id=? AND product_id=? AND loyalty!=2", array($receipt['id'], $product['id']));
		$count=$res[0]['count']; // Общее кол-во товара
		//var_dump($count); exit();
		// Выбираем все строки с товаром, и не измененной ценой
		$lines=$this->select_lines(array('receipt_id=? AND product_id=? AND loyalty=0', array($receipt['id'], $product['id'])), array('order'=>'count'));
		$selected=array(); // Выбранная программа
		// Если программ несколько, то перебираем программы лояльности, что бы узнать самую выгодную
		$new_price=false;
		foreach ($loyalty as $n => $l) {
			$items=json_decode($l['data'], true);
			// Находим параметры программы лояльности для товара
			$l_data=array();

			if($l['action_type']>0) {

				if(isset($items['product'][$product['id']])) { // Если параметры указаны для товара
					$l_data=$items['product'][$product['id']];
				}
				else { // Если параметры указаны для категории
					if(isset($items['category'][$product['category_id']])) {
						$l_data=$items['category'][$product['category_id']];
					}
				}
			}
			elseif($l['action_type']<0 && (is_array($items['product']) || is_array($items['category']))) {
				if(!isset($items['product'][$product['id']]) && !isset($items['category'][$product['category_id']])) { // Если параметры указаны для товара
					$l_data=$items['product'][array_key_first($items['product'])];
				}
				else { // Если параметры указаны для категории
					if(!isset($items['category'][$product['category_id']])) {
						$l_data=$items['category'][array_key_first($items['category'])];
					}
				}
			}
			// Если параметры нашлись, вычисляем новую цену
			if($l_data) {
				if($l_data['quantity']=='')$l_data['quantity']=0;
				// Если кол-во товара соответствует необходимому
				if(($l_data['quantity_type']=='>' && $count>$l_data['quantity']) || ($l_data['quantity_type']=='=' && $count>=$l_data['quantity'])) {
					// Цена с учетом НДС, но без учета скидки
					$price=$product['price']+($product['price']/100*$product['vat'])*max(0, $product['vat_type']);
					// Вычисляем цену со скидкой, с учетом типа скидки
					if($l_data['discount_type']=='%') {
						$l_discount=$l_data['discount'];
						if($l_discount>$product['max_discount'] && (int)$l['ignor_maxdiscount']===0) {
							$l_discount=$product['max_discount'];
						}
						$price-=($price/100*$l_discount);
					}
					elseif($l_data['discount_type']=='='){
						$price=$l_data['discount'];
					}
					else {
						$price-=$l_data['discount'];
					}
					// Если нашли более выгодную программу
					if($new_price===false || $new_price>$price) {
						$new_price=$price;
						$selected=$l;
						$selected['data']=$l_data;
					}
				}
			}
		}

		// Применяем программу лояльности
		if($selected['data']['discount_type']=='%') {
			$discount=$selected['data']['discount'];
		}
		else {
			$discount=0;
		}

		if($discount>$product['max_discount'] && (int)$l['ignor_maxdiscount']===0) {
			$discount=$product['max_discount'];
		}


		$not_discount=$selected['data']['quantity']; // Кол-во к которому не надо применять скидку
		if($selected['data']['quantity_type']=='=') { // Если скидка на определенное кол-во
			$not_discount=$count%$not_discount;
		}

		// Если нужно применить не ко всему кол-ву
		if($not_discount>0) {
			// Ищем строку у которой указано кол-во, к которому не нужно применять скидку, а вдруг такая есть
			$l_key=array_search($not_discount, array_column($lines, 'count'));
			if($l_key!==false) {
				// если такая строка нашлась, то удаляем ее, и применем скидку к оставшимся строкам
				unset($lines[$l_key]);
			}
			else {
				// Если такой строки нет, то надо работать с тем, что есть
				foreach ($lines as $n=>$l) {
					if($l['count']<=$not_discount) {
						$not_discount-=$l['count'];
						unset($lines[$n]);
					}
					else {
						// Если кол-во больше необходимого, то придется кол-во разделить на 2 строки
						// Оставляем в строке то кол-во, к которому будет применена скидку
						$lines[$n]['count']-=$not_discount;
						// Создаем новую строку с тем кол-вом, к которому не надо применять скидку
						$line=array(
							'id'=>$l['product_id'],
							'title'=>$l['product_title'],
							'price'=>$product['price'],
							'price0'=>$product['price'],
							'vat'=>$l['vat'],
							'vat_type'=>$l['vat_type']
						);
						$this->add_line($receipt['id'], $line, $not_discount);
						break;
					}
				}
			}
		}
		// Применяем скидку
		if($lines && $selected) {
			foreach ($lines as $l) {
				$this->change_line($l['id'], $l['count'], $new_price, $discount, 'Акция: '.$selected['title'], 1);
			}
		}
	}

	function linesmerge($line_id) {
		$this->reset();
		$this->load(array('id=?', $line_id), array('limit'=>1));
		if($this->dry()) {
			return array(
				'success'=>false,
				'txt'=>'not_found'
			);
		}

		$lines=$this->db->exec("SELECT * FROM receiptlines WHERE receipt_id=? AND product_id=? AND vat=? AND vat_type=? AND price=? AND price0=? AND discount=? AND (mark='' OR  mark IS NULL) AND units_fr>=0 AND id!=? AND kitchen=0 AND bar=0", array($this->receipt_id, $this->product_id, $this->vat, $this->vat_type, $this->price, $this->price0, $this->discount, $line_id));
		if(!$lines) {
			return array(
				'success'=>true,
				'txt'=>'save_successful'
			);
		}
		$count=array_sum(array_column($lines, 'count'));

		$this->count+=$count;
		if($this->update()) {
			$this->db->exec("DELETE FROM receiptlines WHERE id IN (".implode(',', array_column($lines, 'id')).")");
			return array(
				'success'=>true,
				'txt'=>'save_successful'
			);
		}

		return array(
			'success'=>false,
			'txt'=>'db_error'
		);
	}

	// Отмена акций
	function cancel_loyalty($receipt, $product) {
		$sql="UPDATE `receiptlines` SET `price`=?, `loyalty`=0, `line_discount`=0, `description`='' WHERE `receipt_id`=? AND `product_id`=? AND `loyalty`=1";
		$val=array(
			$product['price'],
			$receipt['id'],
			$product['id']
		);
		$this->db->exec($sql, $val);
	}

	function lines_price_bonus_pay($lines, $bonus_pay, $ignore_max_discount=0) {
		// Вычисляем цену с учетом оплаты баллами
		$bonus_pay0=$bonus_pay;
		while ($bonus_pay>0) {
			foreach ($lines as $key=>$l) {
				if($l['loyalty']>0) continue;
				if(!$l['max_b']) {
					if($ignore_max_discount==1) $l['max_discount']=100;
					$l['max_b']=floor($l['price0']/100*$l['max_discount']*100)/100;
				}
				if($bonus_pay>=1) {
					$b=floor(1/$l['count']*100)/100;
				}
				else {
					break(2);
				}
				if($l['bonus_pay_max']==1) {
					continue;
				}
				elseif($b>$l['price'] || $l['price0']-($l['price']-$b)>$l['max_b']) {
					$lines[$key]['bonus_pay_max']=1;
					continue;
				}
				$lines[$key]['price']-=$b;
				$b=$b*$l['count'];
				$lines[$key]['bonus_pay']+=$b;
				$bonus_pay=round($bonus_pay-$b, 2);
			}
			if($bonus_pay0!=$bonus_pay) {
				$bonus_pay0=$bonus_pay;
			}
			else {
				break;
			}
		}
		// Если остались копеечные бонусы, то надо разделить строки
		if($bonus_pay>0) {
			foreach($lines as $key=>$l) {
				if($l['count']>1 && $l['price']>$bonus_pay) {
					$bp=$l['bonus_pay']/$l['count'];
					$lines[$key]['count']-=1;
					$lines[$key]['bonus_pay']=$bp*$lines[$key]['count'];

					$new_line=$l;
					unset($new_line['id']);
					$new_line['count']=1;
					$new_line['price']-=$bonus_pay;
					$new_line['bonus_pay']=round($bp+$bonus_pay, 2);
					$lines[]=$new_line;
					$bonus_pay=0;
					break;
				}
			}
		}

		$total=0;
		foreach($lines as $l){
			$total+=$l['count']*$l['price'];
		}

		return array(
			'lines'=>$lines,
			'bonus_pay'=>$bonus_pay,
			'total'=>$total
		);
	}

	function lines_bonus_pay($lines, $bonus_pay, $ignore_max_discount=0) {
		$res=$this->lines_price_bonus_pay($lines, $bonus_pay, $ignore_max_discount);
		foreach ($res['lines'] as $l) {
			if($l['loyalty']>0) continue;
			$this->reset();
			if(isset($l['id'])) {
				$this->load(array('id=?', $l['id']), array('limit'=>1));
			}
			$l['description']='Оплачено баллами';
			$l['bonus_pay']=number_format($l['bonus_pay'], 2, '.', '');
			$l['writeoff_bonus']=$l['bonus_pay'];
			$this->copyFrom($l);
			$this->save();
		}
		return; 
	}

	function insert_line($line) {
		$this->reset();
		$this->copyFrom($line);
		if($this->insert()===false) {
			return array(
				'success'=>false,
				'txt'=>'db_error'
			);
		}
		return array(
			'success'=>true,
			'txt'=>'save_successful',
			'id'=>$this->get('_id')
		);
	}

	function max_bonus_pay($summ, $partner, $lines) {
		if(!$lines) return 0;
		$writeoff_bonus=array_sum(array_column($lines, 'writeoff_bonus'));
		$parent['bonus']-=$writeoff_bonus;
		$max_for_summ=min(floor($summ/100*$partner['bonus_pay']), $partner['bonus']);
		$bonus_pay=0;
		foreach ($lines as $l) {
			if($l['price']<=0 || $l['loyalty']>0) continue;
			$max_for_line=floor($l['price']*$l['count']/100*$l['max_discount']);
			if($max_for_line>$max_for_summ || (int)$partner['ignore_max_discount']==1) {
				$bonus_pay+=$max_for_summ;
				break;
			}
			else {
				$bonus_pay+=$max_for_line;
				$max_for_summ-=$max_for_line;
			}
		}
		return $bonus_pay;
	}

	function control_sno($lines, $sno_default) {
		if(!$lines) return true;
		$sno=array();
		foreach($lines as $l) {
			if($l['sno']=='0' || !$l['sno'])$l['sno']=$sno_default;
			$sno[(string)$l['sno']]=1;
		}
		if(count($sno)<=1) $status=true;
		else $status=false;
		return array(
			'status'=>$status,
			'sno'=>array_keys($sno)
		);
	}
}
