<?php
namespace Models;

// Модель для смен
class Changes extends \DB\SQL\Mapper {
	public $db, $f3, $fr, $api_data;

	public function __construct($db, $f3) {
		parent::__construct($db, 'changes' ); // подключаемся к таблице смен
		$this->db=$db;
		$this->f3=$f3;
		$this->fr=new \Models\Fr($db, $f3);
		$this->api_data=$this->f3->get('api_data');
	}

	// Информация об открываемой странице
	function page_data($page='search') {
		$pages=array(
			'search'=>array(
				'title'=>'Поиск смен',
				'inc'=>'changes_search.htm'
			),
			'close_alert'=>array(
				'title'=>'Закрытие смены',
				'inc'=>'changes_close_alert.htm'
			)
		);
		$pages[$page]['page']=$page;
		return $pages[$page];
	}

	// Узнаем текущую смену
	function get_change($open=true, $open_fr=true, $ignore_openpay_tickets=false) {
		$this->reset();
		$change=array();
		// ищем открытую смену
		$this->load(array("time_end=0 AND rm=?", $this->api_data['rm_id']), array("limit"=>1, "order"=>"id DESC"));

		if($open && $open_fr) {
			$hold=$this->f3->get('hold');
			if($hold) {
				$this->f3->clear('hold');
			}

			// Ищем непроведенный документ закрытия этой
			$receipt=$this->db->exec("SELECT * FROM receipts WHERE time=0 AND changes=? AND rm=? AND type=? LIMIT 1", array($this->id, $this->api_data['rm_id'], $this->f3->get('receipt_change_close')));
			if($receipt) {
				$change=new \Controllers\Changes($this);
				$res=$change->z(false, true, true, $ignore_openpay_tickets);
				if(!$res['success']) {
					return $res;
				}
				$res=$change->open(false);
				if(!$res['success']) {
					return $res;
				}
			}

			// closed - закрыта
	        // opened - открыта
	        // expired - истекла
			$change_status=$this->fr->change_status();

			if($change_status=='expired') {
				if($this->dry()) {
					$this->fr->z(null, 1, false);
				}
				else {
					//$this->z($this->cast(), true);
					$change=new \Controllers\Changes($this);
					$res=$change->z(false, true, true, $ignore_openpay_tickets);
					if(!$res['success']) {
						return $res;
					}
					$change_status='closed';
					$this->reset();
				}
			}
			if($change_status=='closed') {
				$this->fr->open_session();
			}
			if(isset($hold)) {
				$this->f3->set('hold', $hold);
			}
		}

		if($this->dry()) { // если открытой смены нет, то открываем смену
			if($open) {
				$chz_error='';
				$chz_status='';
				$sets=$this->f3->get('base_settings');
				if($sets['token_chz']!='' && (int)$sets['chz_offline']==1 && $sets['piot_driver']=='') {
					$sets['service']=1;
					$chz=new \Models\Chz($this->db, $this->f3, $sets);
					$res=$chz->lm_status();
					if($res['success']===false) {
						$chz_error=$res['txt'];
					}
					if($res['status'] && $res['status']!='ready') {
						$chz_error='lm_chz_status_error';
						$chz_status=$res['status_title'];
					}
					if($chz_error!='') $this->f3->get('logs_model')->save_log($chz_error);
					
				}

				// Узнаем наличность в кассе на момент закрытия предыдущей смены
				$cash=0;
				$this->reset();
				$this->load(array('time_end>0 AND rm=?', $this->api_data['rm_id']), array('limit'=>1, 'order'=>'time_end DESC'));
				if(!$this->dry()) {
					$cash=$this->cash_end;
				}
				$this->reset();
				$change=array(
					'rm'=>$this->api_data['rm_id'],
					'time_start'=>time(),
					'time_end'=>0,
					'cash_start'=>$cash,
					'cash_end'=>0,
					'txt'=>'change_is_open',
					'chz_error'=>$chz_error,
					'chz_status'=>$chz_status
				);
				$this->copyFrom($change);
				if($this->insert()) {
					$change['id']=$this->get('_id');
					// Создаем чек открытия смены
					$r=new \Models\Receipts($this->db, $this->f3);
					$p=new \Models\Paymentmethods($this->db, $this->f3);
					$api=$this->f3->get('api_data');
					$paymentmethod=$p->select_method('cash=1')[0]['id'];
					$r->ticket_change($api, $change, $this->f3->get('receipt_change_open'), $paymentmethod, 0);
				}
				else {
					return false;
				}
			}
		}
		else {
			$change=$this->cast();
			$change['txt']='change_open';
			$this->reset();
		}
		return $change;
	}

	// Открыть смену на ФР
	function open_fr() {
		if($this->fr->sets['active']) {
			$this->fr->open_session();
			return array(
				'success'=>true,
				'txt'=>'change_is_open'
			);
		}
		else {
			return array(
				'success'=>false,
				'txt'=>'kkm_is_not_activity'
			);
		}
	}

	// Закрыть смену на ФР
	function close_fr() {
		if($this->fr->sets['active']) {
			$this->fr->z(null, 1, false);
			return array(
				'success'=>true,
				'txt'=>'change_is_close'
			);
		}
		else {
			return array(
				'success'=>false,
				'txt'=>'kkm_is_not_activity'
			);
		}
	}

	// Открыть смену на Кассе
	function open_db() {
		$res=$this->get_change(false);
		if($res) {
			return array(
				'success'=>false,
				'txt'=>'change_open'
			);
		}
		$this->reset();
		$change=array(
			'rm'=>$this->api_data['rm_id'],
			'time_start'=>time(),
			'time_end'=>0
		);
		$this->copyFrom($change);
		if($this->insert()) {
			return array(
				'success'=>true,
				'txt'=>'change_is_open'
			);
		}
		else {
			return array(
				'success'=>false,
				'txt'=>'db_error'
			);
		}
	}

	// Закрываем смену
	function z($change, $fr=true, $bt=true) {
		$this->reset();
		$this->load(array('id=?', $change['id']));
		if($this->dry()) {
			return array(
				'success'=>false,
				'txt'=>'change_not_open'
			);
		}
		if($fr && $this->fr->change_status()!='closed') {
			$fr_result=$this->fr->z($change, 1, $bt);
			if(!$fr_result['success']) {
				return $fr_result;
			}
		}
		$change['time_end']=time();
		$change['time']=microtime(true);
		$this->time_end=$change['time_end'];
		$this->cash_end=$change['cash_end'];
		$slip='';
		if(isset($fr_result['slip']) && $fr_result['slip']!='') {
			$slip=$fr_result['slip'];
		}
		if($this->update()) {
			$this->db->exec("UPDATE receiptlines SET create_order=(case create_order when 0 then ?+('0.' || substr(receipt_id, -3, 3)) else create_order end), complite_order=(case complite_order when 0 then ?+('0.' || substr(receipt_id, -3, 3)) else complite_order end), issued_order=(case issued_order when 0 then ?+('0.' || substr(receipt_id, -3, 3)) else issued_order end) WHERE create_order=0 OR complite_order=0 OR issued_order=0", array($change['time'], $change['time'], $change['time']));
			return array(
				'success'=>true,
				'txt'=>'change_is_close',
				'change'=>$change,
				'slip'=>$slip
			);
		}
		else {
			return array(
				'success'=>false,
				'txt'=>'db_error'
			);
		}
	}

	// X-отчет
	function x() {
		// ищем открытую смену
		$change=$this->get_change(false);
		if(!$change) {
			return array(
				'success'=>false,
				'txt'=>'change_not_open'
			);
		}

		$this->fr->x($change);
		return array(
			'success'=>true,
			'txt'=>'x-report_is_ready'
		);
	}

	// Выбор из базы
	function select_changes($query=null, $options=null) {
		if($query==null) {
			$query=array('rm=?', $this->api_data['rm_id']);
		}
		else {
			$query[1][]=$this->api_data['rm_id'];
			$query=array('('.$query[0].') AND rm=?', $query[1]);
		}
		$this->reset();
		$changes=array();
		$this->load($query, $options);
		if($this->dry()) {
			return $changes;
		}
		do {
			$changes[]=$this->cast();
		}
		while($this->skip());
		$this->reset();
		return $changes;
	}

	// Поиск смен
	function search($dates, $start=0, $limit=0) {
		$sql="id>?";
		$val[]=0;
		if($dates[0]) {
			if($sql!='')$sql.=' AND ';
			$sql.='time_start>=?';
			$val[]=$dates[0];
		}
		if($dates[1]) {
			if($sql!='')$sql.=' AND ';
			$sql.='time_start<=?';
			$val[]=$dates[1];
		}

		$options=array('order'=>'time_start DESC');
		if($start>0) {
			$options['offset']=$start;
		}
		if($limit>0) {
			$options['limit']=$limit;
		}
		$changes=$this->select_changes(array($sql, $val), $options);
		$count=$this->count(array($sql, $val));
		return array(
			'changes'=>$changes,
			'count'=>$count
		);
	}
}
