<?php
namespace Models;

// Модель для работы с Фискальным регистратором
class Fr extends \DB\SQL\Mapper{
	public $db, $f3, $printer, $print_group_id, $sets, $fr, $ticket_type=array('1'=>0, '2'=>1, '128'=>128, '130'=>130), $api_data;

	public function __construct($db, $f3, $printer='kkm', $open=true, $print_group_id=0) {
		parent::__construct($db, 'fr_settings'); // подключаемся к таблице с настройками
		$this->f3=$f3;
		$this->db=$db;
		$this->receipt=array();
		$this->discount_sum=0;
		$this->printer=$printer;
		if(is_null($print_group_id)) {
			$print_group_id=0;
		}
		$this->print_group_id=$print_group_id;
		$this->api_data=$this->f3->get('api_data');
		$this->sets=$this->get_fr();
		if($this->sets['driver']=='') {
			$this->sets['active']=0;
		}
		if($this->sets['active']==1 && $this->sets['driver']!='' && $open===true) {
			if(file_exists($this->sets['driver'].'/server.py')) {
				$this->fr=new Fr_python($f3, $this->sets);
			}
			elseif(file_exists($this->sets['driver'].'/server.php')) {
				$class=explode('/', $this->sets['driver']);
				$class=array_reverse($class);
				$model='\Models\\'.$class[0].'_Fr_php';
				if(!class_exists($model, false)) {
					require_once($this->sets['driver'].'/server.php');
				}
				/*$file='/server.config';
				if($printer=='pre' || $printer=='kitchen' || $printer=='bar' || $printer=='pricetags') {
					if(file_exists($this->sets['driver'].'/'.$printer.'_'.$print_group_id.'_server.config')) {
						$file='/'.$printer.'_'.$print_group_id.'_server.config';
					}
					elseif(file_exists($this->sets['driver'].'/'.$printer.'_server.config')) {
						$file='/'.$printer.'_server.config';
					}
				}
				$config=parse_ini_file($this->sets['driver'].$file);*/
				$s=new \Models\Settings($this->f3, $this->db);
				$config=$s->get_driver_config($this->sets['driver'], $printer, $print_group_id);
				$config=$config['config'];
				$this->fr=new $model($f3, $this->sets, $config);
				$this->sets['vat_type']=$this->fr->config['vat_type'];
			}
			else {
				echo 'Ошибка';
			}
		}
		if(!$this->sets['vat_type'] || !is_array($this->sets['vat_type'])) {
			$this->sets['vat_type']=array(
				'vatNo'=>'4',
				'vat0'=>'1',
				'vat110'=>'5',
				'vat10'=>'2',
				'vat120'=>'6',
				'vat20'=>'3'
			);
		}
		if($this->sets['version']=='1.05') {
			$this->ticket_type['128']=0;
			$this->ticket_type['130']=1;
		}
	}

	function get_printers($query=null, $options=null) {
		if(!$query) {
			$query=array('active=1');
		}
		$printers=array();
		$this->reset();
		$this->load($query, $options);
		if($this->dry()) return $printers;
		$title=array(
			'kkm'=>'Принтер ККМ',
			'pre'=>'Принтер для пречеков',
			'bar'=>'Принтер для бара',
			'kitchen'=>'Принтер для кухни',
			'pricetags'=>'Принтер для ценников',
		);
		do {
			$p=$this->cast();
			$p['title']=$title[$p['printer']];
			$printers[]=$p;
		}
		while($this->skip());
		return $printers;
	}

	// Список драйверов
	function get_drivers() {
		$drivers=array();
		$printers_dir=$this->f3->get('printers_dir');
		$dirs=scandir($printers_dir); // Ищем все драйвера
		if($dirs) {
			foreach ($dirs as $d) {
				$folder=$printers_dir.$d;
				$file=$folder.'/driver.config';
				if(is_dir($folder) && file_exists($file)) {
					$config=parse_ini_file($file);
					if($config) {
						$drivers[$folder]=array(
							'title'=>$config['ServerName'],
							'path'=>$folder,
							'url'=>$config['KKMurl']['default']?$config['KKMurl']['default']:''
						);
					}
				}
			}

			foreach ($dirs as $d) {
				$folder=$printers_dir.$d;
				$file=$folder.'/server.config';
				if(is_dir($folder) && file_exists($file)) {
					$config=parse_ini_file($file);
					if($config && !isset($drivers[$folder])) {
						$drivers[$folder]=array(
							'title'=>$config['ServerName'],
							'path'=>$folder,
							'url'=>$config['KKMurl']?$config['KKMurl']:''
						);
					}
				}
			}
		}

		return $drivers;
	}

	// Настройки ФР
	function get_fr() {
		$this->reset();
		$this->load(array("printer=? AND rm=? AND print_group_id=?", array($this->printer, $this->api_data['rm_id'], $this->print_group_id)), array('limit'=>1));
		$sets=$this->cast();
		$sets['sno_types']=json_decode($sets['sno_types'], true);
		$sets['psr']=json_decode($sets['psr'], true);
		if(!is_array($sets['sno_types'])) {
			$sets['sno_types']=array($sets['sno']);
		}
		if(!in_array($sets['sno'], $sets['sno_types'])) {
			$sets['sno_types'][]=$sets['sno'];
		}
		$sets['pays_type']=json_decode($sets['pays_type'], true);
		if($sets['active']==0) $sets['version']='0';
		return $sets;
	}

	// Сохраняем настройки ФР
	function save_fr($post) {
		if($this->printer=='kkm') {
			$post['pays_type']=json_encode($post['pays']);
			unset($post['pays']);
		}
		else {
			$post['pays_type']='';
		}
		if($post['fix_user']) {
			$post['fix_user']=trim($post['fix_user']);
		}
		if($post['fix_inn']) {
			$post['fix_inn']=str_replace(' ', '', $post['fix_inn']);
		}
		if($post['free_title']) {
			$post['free_title']=trim($post['free_title']);
		}
		if(!$post['rm']) {
			$post['rm']=$this->api_data['rm_id'];
		}

		$this->reset();
		$sets=$this->get_fr();
		$post['printer']=$this->printer;

		if(!$post['sno_types']) {
			$post['sno_types']=array($sets['sno']);
		}
		$post['sno_types']=json_encode($post['sno_types']);

		if(!$post['psr']) {
			$post['psr']=array('4');
		}
		$post['psr']=json_encode($post['psr']);

		if(!$post['active'] && $post['print_group_id']>0) {
			if($this->erase()===false) {
				return array(
					'success'=>false,
					'txt'=>'db_error'
				);
			}
			return array(
				'success'=>true,
				'txt'=>'save_successful'
			);
		}

		$this->copyFrom($post);
		if($this->save()===false) {
			return array(
				'success'=>false,
				'txt'=>'db_error'
			);
		}
		return array(
			'success'=>true,
			'txt'=>'save_successful'
		);
	}

	function ascii_str($str) {
		$alphabet=array(
			0=>array(" #### ","##  ##","##  ##","##  ##"," #### ", "      "),
			1=>array("   ##", " ####", "## ##", "   ##", "   ##", "     "),
			2=>array(" #### ","##  ##","   ## ","  ##  ","######", "      "),
			3=>array(" #### ","##  ##","   ## ","##  ##"," #### ", "      "),
			4=>array("##  ##","##  ##","######","    ##","    ##", "      "),
			5=>array("######","##    ","##### ","    ##","##### ", "      "),
			6=>array(" #####","##    ","##### ","##  ##"," #### ", "      "),
			7=>array("######","   ## ","  ##  "," ##   ","##    ", "      "),
			8=>array(" #### ","##  ##"," #### ","##  ##"," #### ", "      "),
			9=>array(" #####","##  ##"," #####","    ##"," #### ", "      "),
			'А'=>array("  ##  ", " #### ", "##  ##", "######", "##  ##", "      "),
			'Б'=>array("######", "##    ", "######", "##  ##", "######", "      "),
			'В'=>array("##### ", "##  ##", "##### ", "##  ##", "##### ", "      "),
			'Г'=>array("######", "##    ", "##    ", "##    ", "##    ", "      "),
			'Д'=>array("  ##### ", " ##  ## ", " ##  ## ", "########", "##    ##", "        "),
			'Е'=>array("######", "##    ", "##### ", "##    ", "######", "      "),
			'Ё'=>array(" #  # ", "######", "##    ", "##### ", "##    ", "######"),
			'Ж'=>array("## ## ##", "## ## ##", " ###### ", "## ## ##", "## ## ##", "        "),
			'З'=>array(" #### ", "##  ##", "   ## ", "##  ##", " #### ", "      "),
			'И'=>array("##  ##", "## ###", "######", "### ##", "##  ##", "      "),
			'Й'=>array("  --  ", "##  ##", "## ###", "######", "### ##", "##  ##"),
			'К'=>array("##  ##", "## ## ", "####  ", "## ## ", "##  ##", "      "),
			'Л'=>array("  ##  ", " #### ", "##  ##", "##  ##", "##  ##", "      "),
			'М'=>array("##     ##", "###   ###", "## ### ##", "##  #  ##", "##     ##", "         "),
			'Н'=>array("##  ##", "##  ##", "######", "##  ##", "##  ##", "      "),
			'О'=>array(" #### ", "##  ##", "##  ##", "##  ##", " #### ", "      "),
			'П'=>array("######", "##  ##", "##  ##", "##  ##", "##  ##", "      "),
			'Р'=>array("##### ", "##  ##", "##### ", "##    ", "##    ", "      "),
			'С'=>array(" #### ", "##  ##", "##    ", "##  ##", " #### ", "      "),
			'Т'=>array("######", "  ##  ", "  ##  ", "  ##  ", "  ##  ", "      "),
			'У'=>array("##   ##", " ## ## ", "  ###  ", " ##    ", "##     ", "       "),
			'Ф'=>array(" ###### ", "## ## ##", " ###### ", "   ##   ", "   ##   ", "        "),
			'Х'=>array("##   ##", " ## ## ", "  ###  ", " ## ## ", "##   ##", "       "),
			'Ц'=>array("##  ##  ", "##  ##  ", "##  ##  ", "##  ##  ", "########", "      ##"),
			'Ч'=>array("##  ##", "##  ##", " #####", "    ##", "    ##", "      "),
			'Ш'=>array("## ## ##", "## ## ##", "## ## ##", "## ## ##", "########", "        "),
			'Щ'=>array("## ## ##  ", "## ## ##  ", "## ## ##  ", "## ## ##  ", "##########", "        ##"),
			'Ъ'=>array("####    ", "  ##    ", "  ##### ", "  ##  ##", "  ##### ", "        "),
			'Ы'=>array("##     ##", "##     ##", "#####  ##", "##  ## ##", "#####  ##", "         "),
			'Ь'=>array("##    ", "##    ", "##### ", "##  ##", "##### ", "      "),
			'Э'=>array(" #### ", "##  ##", "   ###", "##  ##", " #### ", "      "),
			'Ю'=>array("##  #### ", "## ##  ##", "#####  ##", "## ##  ##", "##  #### ", "        "),
			'Я'=>array("  #####", " ##  ##", "  #####", " ##  ##", "##   ##", "       "),
			'A'=>array("  ##  ", " #### ", "##  ##", "######", "##  ##", "      "),
			'B'=>array("##### ", "##  ##", "##### ", "##  ##", "##### ", "      "),
			'C'=>array(" #### ", "##  ##", "##    ", "##  ##", " #### ", "      "),
			'D'=>array("##### ", "##  ##", "##   #", "##  ##", "##### ", "      "),
			'E'=>array("######", "##    ", "##### ", "##    ", "######", "      "),
			'F'=>array("######", "##    ", "##### ", "##    ", "##    ", "      "),
			'G'=>array(" #####", "##    ", "##  ##", "##   #", " #### ", "      "),
			'H'=>array("##  ##", "##  ##", "######", "##  ##", "##  ##", "      "),
			'I'=>array("####", " ## ", " ## ", " ## ", "####", "    "),
			'J'=>array("    ##", "    ##", "    ##", "##  ##", " #### ", "      "),
			'K'=>array("##  ##", "## ## ", "####  ", "## ## ", "##  ##", "      "),
			'L'=>array("##    ", "##    ", "##    ", "##    ", "######", "      "),
			'M'=>array("##     ##", "###   ###", "## ### ##", "##  #  ##", "##     ##", "         "),
			'N'=>array("##  ##", "### ##", "######", "## ###", "##  ##", "      "),
			'O'=>array(" #### ", "##  ##", "##  ##", "##  ##", " #### ", "      "),
			'P'=>array("##### ", "##  ##", "##### ", "##    ", "##    ", "      "),
			'Q'=>array(" #### ", "##  ##", "##  ##", "##  ##", " #####", "     #"),
			'R'=>array("##### ", "##  ##", "##### ", "## ## ", "##  ##", "      "),
			'S'=>array(" #####", "##    ", " #### ", "    ##", "##### ", "      "),
			'T'=>array("######", "  ##  ", "  ##  ", "  ##  ", "  ##  ", "      "),
			'U'=>array("##  ##", "##  ##", "##  ##", "##  ##", " #### ", "      "),
			'V'=>array("##    ##", "##    ##", " ##  ## ", "  ####  ", "   ##   ", "        "),
			'W'=>array("##     ##", "##  #  ##", "## ### ##", "###   ###", "##     ##", "         "),
			'X'=>array("##   ##", " ## ## ", "  ###  ", " ## ## ", "##   ##", "       "),
			'Y'=>array("##    ##", " ##  ## ", "   ##   ", "   ##   ", "   ##   ", "        "),
			'Z'=>array("######", "   ## ", "  ##  ", " ##   ", "######", "      ")
		);

		$p='';
		$symbols=array();
		$strlen=mb_strlen($str);
		for($sympos=0; $sympos<$strlen; $sympos++) {
			$symbols[]=$alphabet[mb_strtoupper(mb_substr($str, $sympos, 1))];
		}
		for($i=0; $i<6; $i++) {
			foreach($symbols as $n=>$s) {
				$p.=$s[$i];
				if($n<$strlen-1) {
					$p.=' ';
				}
			}
			$p.='#kkm_br#';
		}
		return $p;
	}

	function ascii_str2($str) {
		$alphabet=array(
			0=>array(" ████ ","██  ██","██  ██","██  ██"," ████ ", "      "),
			1=>array("   ██", " ████", "██ ██", "   ██", "   ██", "     "),
			2=>array(" ████ ","██  ██","   ██ ","  ██  ","██████", "      "),
			3=>array(" ████ ","██  ██","   ██ ","██  ██"," ████ ", "      "),
			4=>array("██  ██","██  ██","██████","    ██","    ██", "      "),
			5=>array("██████","██    ","█████ ","    ██","█████ ", "      "),
			6=>array(" █████","██    ","█████ ","██  ██"," ████ ", "      "),
			7=>array("██████","   ██ ","  ██  "," ██   ","██    ", "      "),
			8=>array(" ████ ","██  ██"," ████ ","██  ██"," ████ ", "      "),
			9=>array(" █████","██  ██"," █████","    ██"," ████ ", "      "),
			'А'=>array("  ██  ", " ████ ", "██  ██", "██████", "██  ██", "      "),
			'Б'=>array("██████", "██    ", "██████", "██  ██", "██████", "      "),
			'В'=>array("█████ ", "██  ██", "█████ ", "██  ██", "█████ ", "      "),
			'Г'=>array("██████", "██    ", "██    ", "██    ", "██    ", "      "),
			'Д'=>array("  █████ ", " ██  ██ ", " ██  ██ ", "████████", "██    ██", "        "),
			'Е'=>array("██████", "██    ", "█████ ", "██    ", "██████", "      "),
			'Ё'=>array(" █  █ ", "██████", "██    ", "█████ ", "██    ", "██████"),
			'Ж'=>array("██ ██ ██", "██ ██ ██", " ██████ ", "██ ██ ██", "██ ██ ██", "        "),
			'З'=>array(" ████ ", "██  ██", "   ██ ", "██  ██", " ████ ", "      "),
			'И'=>array("██  ██", "██ ███", "██████", "███ ██", "██  ██", "      "),
			'Й'=>array("  --  ", "██  ██", "██ ███", "██████", "███ ██", "██  ██"),
			'К'=>array("██  ██", "██ ██ ", "████  ", "██ ██ ", "██  ██", "      "),
			'Л'=>array("  ██  ", " ████ ", "██  ██", "██  ██", "██  ██", "      "),
			'М'=>array("██     ██", "███   ███", "██ ███ ██", "██  █  ██", "██     ██", "         "),
			'Н'=>array("██  ██", "██  ██", "██████", "██  ██", "██  ██", "      "),
			'О'=>array(" ████ ", "██  ██", "██  ██", "██  ██", " ████ ", "      "),
			'П'=>array("██████", "██  ██", "██  ██", "██  ██", "██  ██", "      "),
			'Р'=>array("█████ ", "██  ██", "█████ ", "██    ", "██    ", "      "),
			'С'=>array(" ████ ", "██  ██", "██    ", "██  ██", " ████ ", "      "),
			'Т'=>array("██████", "  ██  ", "  ██  ", "  ██  ", "  ██  ", "      "),
			'У'=>array("██   ██", " ██ ██ ", "  ███  ", " ██    ", "██     ", "       "),
			'Ф'=>array(" ██████ ", "██ ██ ██", " ██████ ", "   ██   ", "   ██   ", "        "),
			'Х'=>array("██   ██", " ██ ██ ", "  ███  ", " ██ ██ ", "██   ██", "       "),
			'Ц'=>array("██  ██  ", "██  ██  ", "██  ██  ", "██  ██  ", "████████", "      ██"),
			'Ч'=>array("██  ██", "██  ██", " █████", "    ██", "    ██", "      "),
			'Ш'=>array("██ ██ ██", "██ ██ ██", "██ ██ ██", "██ ██ ██", "████████", "        "),
			'Щ'=>array("██ ██ ██  ", "██ ██ ██  ", "██ ██ ██  ", "██ ██ ██  ", "██████████", "        ██"),
			'Ъ'=>array("████    ", "  ██    ", "  █████ ", "  ██  ██", "  █████ ", "        "),
			'Ы'=>array("██     ██", "██     ██", "█████  ██", "██  ██ ██", "█████  ██", "         "),
			'Ь'=>array("██    ", "██    ", "█████ ", "██  ██", "█████ ", "      "),
			'Э'=>array(" ████ ", "██  ██", "   ███", "██  ██", " ████ ", "      "),
			'Ю'=>array("██  ████ ", "██ ██  ██", "█████  ██", "██ ██  ██", "██  ████ ", "        "),
			'Я'=>array("  █████", " ██  ██", "  █████", " ██  ██", "██   ██", "       "),
			'A'=>array("  ██  ", " ████ ", "██  ██", "██████", "██  ██", "      "),
			'B'=>array("█████ ", "██  ██", "█████ ", "██  ██", "█████ ", "      "),
			'C'=>array(" ████ ", "██  ██", "██    ", "██  ██", " ████ ", "      "),
			'D'=>array("█████ ", "██  ██", "██   █", "██  ██", "█████ ", "      "),
			'E'=>array("██████", "██    ", "█████ ", "██    ", "██████", "      "),
			'F'=>array("██████", "██    ", "█████ ", "██    ", "██    ", "      "),
			'G'=>array(" █████", "██    ", "██  ██", "██   █", " ████ ", "      "),
			'H'=>array("██  ██", "██  ██", "██████", "██  ██", "██  ██", "      "),
			'I'=>array("████", " ██ ", " ██ ", " ██ ", "████", "    "),
			'J'=>array("    ██", "    ██", "    ██", "██  ██", " ████ ", "      "),
			'K'=>array("██  ██", "██ ██ ", "████  ", "██ ██ ", "██  ██", "      "),
			'L'=>array("██    ", "██    ", "██    ", "██    ", "██████", "      "),
			'M'=>array("██     ██", "███   ███", "██ ███ ██", "██  █  ██", "██     ██", "         "),
			'N'=>array("██  ██", "███ ██", "██████", "██ ███", "██  ██", "      "),
			'O'=>array(" ████ ", "██  ██", "██  ██", "██  ██", " ████ ", "      "),
			'P'=>array("█████ ", "██  ██", "█████ ", "██    ", "██    ", "      "),
			'Q'=>array(" ████ ", "██  ██", "██  ██", "██  ██", " █████", "     █"),
			'R'=>array("█████ ", "██  ██", "█████ ", "██ ██ ", "██  ██", "      "),
			'S'=>array(" █████", "██    ", " ████ ", "    ██", "█████ ", "      "),
			'T'=>array("██████", "  ██  ", "  ██  ", "  ██  ", "  ██  ", "      "),
			'U'=>array("██  ██", "██  ██", "██  ██", "██  ██", " ████ ", "      "),
			'V'=>array("██    ██", "██    ██", " ██  ██ ", "  ████  ", "   ██   ", "        "),
			'W'=>array("██     ██", "██  █  ██", "██ ███ ██", "███   ███", "██     ██", "         "),
			'X'=>array("██   ██", " ██ ██ ", "  ███  ", " ██ ██ ", "██   ██", "       "),
			'Y'=>array("██    ██", " ██  ██ ", "   ██   ", "   ██   ", "   ██   ", "        "),
			'Z'=>array("██████", "   ██ ", "  ██  ", " ██   ", "██████", "      ")
		);

		$p='';
		$symbols=array();
		$strlen=mb_strlen($str);
		for($sympos=0; $sympos<$strlen; $sympos++) {
			$symbols[]=$alphabet[mb_strtoupper(mb_substr($str, $sympos, 1))];
		}
		for($i=0; $i<6; $i++) {
			foreach($symbols as $n=>$s) {
				$p.=$s[$i];
				if($n<$strlen-1) {
					$p.=' ';
				}
			}
			$p.='#kkm_br#';
		}
		return $p;
	}

	function ascii_str3($str) {
		$alphabet=array(
			0=>array("████","█  █","█  █","█  █","████", "    "),
			1=>array(" █", "██", " █", " █", " █", "  "),
			2=>array("████","█  █","  ██","██  ","████", "    "),
			3=>array("███","  █","███","  █","███", "   "),
			4=>array("█   ","█  █","████","   █","   █", "    "),
			5=>array("████","█   ","████","   █","████", "    "),
			6=>array("████","█   ","████","█  █","████", "    "),
			7=>array("████","█  █","  ██"," ██ ","██  ", "    "),
			8=>array("████","█  █","████","█  █","████", "    "),
			9=>array("████","█  █","████","   █","████", "    "),
			'А'=>array("████", "█  █", "████", "█  █", "█  █", "    "),
			'Б'=>array("████", "█   ", "████", "█  █", "████", "    "),
			'В'=>array("████ ", "█  ██", "████ ", "█  ██", "████ ", "     "),
			'Г'=>array("███", "█  ", "█  ", "█  ", "█  ", "   "),
			'Д'=>array(" ███ ", " █ █ ", " █ █ ", "█████", "█   █", "     "),
			'Е'=>array("███", "█  ", "███", "█  ", "███", "   "),
			'Ё'=>array("* *", "███", "█  ", "███", "█  ", "███"),
			'Ж'=>array("█ █ █", "█████", " ███ ", "█████", "█ █ █", "     "),
			'З'=>array("███", "  █", "███", "  █", "███", "   "),
			'И'=>array("█  █", "█  █", "█ ██", "██ █", "█  █", "    "),
			'Й'=>array(" ── ", "█  █", "█  █", "█ ██", "██ █", "█  █"),
			'К'=>array("█  █", "█ █ ", "██  ", "█ █ ", "█  █", "    "),
			'Л'=>array("  ██", " █ █", "█  █", "█  █", "█  █", "    "),
			'М'=>array("█   █", "██ ██", "█ █ █", "█   █", "█   █", "     "),
			'Н'=>array("█  █", "█  █", "████", "█  █", "█  █", "    "),
			'О'=>array("████", "█  █", "█  █", "█  █", "████", "    "),
			'П'=>array("████", "█  █", "█  █", "█  █", "█  █", "    "),
			'Р'=>array("████", "█  █", "████", "█   ", "█   ", "    "),
			'С'=>array("████", "█  █", "█   ", "█  █", "████", "    "),
			'Т'=>array("███", " █ ", " █ ", " █ ", " █ ", "   "),
			'У'=>array("█ █", "█ █", "███", "  █", "███", "   "),
			'Ф'=>array("█████", "█ █ █", "█ █ █", "█████", "  █  ", "     "),
			'Х'=>array("██ ██", " ███ ", "  █  ", " ███ ", "██ ██", "     "),
			'Ц'=>array("█  █ ", "█  █ ", "█  █ ", "█  █ ", "█████", "    █"),
			'Ч'=>array("█  █", "█  █", "████", "   █", "   █", "    "),
			'Ш'=>array("█   █", "█   █", "█ █ █", "█ █ █", "█████", "     "),
			'Щ'=>array("█   █ ", "█   █ ", "█ █ █ ", "█ █ █ ", "██████", "     █"),
			'Ъ'=>array("██   ", " █   ", " ████", " █  █", " ████", "     "),
			'Ы'=>array("█   █", "█   █", "███ █", "█ █ █", "███ █", "     "),
			'Ь'=>array("█   ", "█   ", "████", "█  █", "████", "    "),
			'Э'=>array("████", "█  █", "  ██", "█  █", "████", "    "),
			'Ю'=>array("█  ██ ", "█ █  █", "████ █", "█ █  █", "█  ██ ", "      "),
			'Я'=>array("████", "█  █", "████", " █ █", " █ █", "    "),
			'A'=>array("████", "█  █", "████", "█  █", "█  █", "    "),
			'B'=>array("████ ", "█  ██", "████ ", "█  ██", "████ ", "     "),
			'C'=>array("████", "█  █", "█   ", "█  █", "████", "    "),
			'D'=>array("████ ", "█  ██", "█  ██", "█  ██", "████ ", "     "),
			'E'=>array("███", "█  ", "███", "█  ", "███", "   "),
			'F'=>array("███", "█  ", "███", "█  ", "█  ", "   "),
			'G'=>array("████", "█   ", "█ ██", "█  █", "████", "    "),
			'H'=>array("█  █", "█  █", "████", "█  █", "█  █", "    "),
			'I'=>array("███", " █ ", " █ ", " █ ", "███", "   "),
			'J'=>array("  ██", "   █", "   █", "█  █", "████", "    "),
			'K'=>array("█  █", "█ █ ", "██  ", "█ █ ", "█  █", "    "),
			'L'=>array("█  ", "█  ", "█  ", "█  ", "███", "   "),
			'M'=>array("█   █", "██ ██", "█ █ █", "█   █", "█   █", "     "),
			'N'=>array("█  █", "██ █", "█ ██", "█  █", "█  █", "    "),
			'O'=>array("████", "█  █", "█  █", "█  █", "████", "    "),
			'P'=>array("████", "█  █", "████", "█   ", "█   ", "    "),
			'Q'=>array("████ ", "█  █ ", "█  █ ", "█  █ ", "█████", "    █"),
			'R'=>array("████", "█  █", "████", "█ █ ", "█ █ ", "    "),
			'S'=>array("███", "█  ", "███", "  █", "███", "   "),
			'T'=>array("███", " █ ", " █ ", " █ ", " █ ", "   "),
			'U'=>array("█ █", "█ █", "█ █", "█ █", "███", "   "),
			'V'=>array("█ █", "█ █", "█ █", "███", " █ ", "   "),
			'W'=>array("█   █", "█   █", "█ █ █", "█████", " █ █ ", "     "),
			'X'=>array("██ ██", " ███ ", "  █  ", " ███ ", "██ ██", "     "),
			'Y'=>array("█ █", "█ █", "███", "  █", "███", "   "),
			'Z'=>array("████", "  ██", " ██ ", "██  ", "████", "    ")
		);

		$p='';
		$symbols=array();
		$strlen=mb_strlen($str);
		for($sympos=0; $sympos<$strlen; $sympos++) {
			$symbols[]=$alphabet[mb_strtoupper(mb_substr($str, $sympos, 1))];
		}
		for($i=0; $i<6; $i++) {
			foreach($symbols as $n=>$s) {
				$p.=$s[$i];
				if($n<$strlen-1) {
					$p.=' ';
				}
			}
			$p.='#kkm_br#';
		}
		return $p;
	}		

	// Открытие смены
	function open_session($print=1) {
		$user=$this->f3->get('authorization_user.short_name');
		$user_inn=$this->f3->get('authorization_user.inn');
		if($this->sets['fix_user']) {
			$user=$this->sets['fix_user'];
			$user_inn=$this->sets['fix_inn'];
		}
		if($user_inn) {
			$user.='{{user_inn}}'.$user_inn;
		}
		$strs="preitem;\n";
		if($this->sets['header']) {
			$strs.=$this->sets['header']."\n";
		}
		$strs.="preitem_end;\n";
		if($this->sets['type']) {
			$strs.="open_session;".$print.";".$user.";\n";
		}
		if(!$this->sets['type'] && $print==1) {
			$strs.="p;ОТКРЫТИЕ СМЕНЫ#kkm_br#".date("d-m-Y H:i").";\n";
		}
		//$strs.="p;#kkm_br#Касса: ".$this->api_data['rm_id']."#kkm_br#";
		//$strs.="Кассир ".$this->f3->get('authorization_user.short_name').";\n";
		$strs.="postitem;\n";
		if($this->sets['footer'] && $print==1) {

			$strs.=$this->sets['footer']."\n";
		}
		$strs.="postitem_end;\n";
		
		$this->send_ajax($strs);

		$res=$this->check_fnstatus();
		if($res['success']) {
			$this->f3->set('COOKIE.ofd_n', $res['ofd_n']);
			$this->f3->set('COOKIE.fn_end', $res['fn_end']);
		}
	}

	function check_fnstatus() {
		if(!$this->sets['active'] || $this->sets['type']==0) {
			return array(
				'success'=>true,
				'ofd_n'=>0,
				'fn_end'=>0
			);
		}
		return $this->fr->check_fnstatus();
	}

	// Закрытие смены
	function z($change, $print=1, $bt=true) {
		if($change['slip']!='') {
			$slip=str_replace('<br>', '#kkm_br#', nl2br($change['slip']));
			$slip=str_replace("\n", '', $slip);
			$slip=str_replace("\r", '', $slip);
			$this->send_ajax('p;'.$slip);
		}

		$user=$this->f3->get('authorization_user.short_name');
		$user_inn=$this->f3->get('authorization_user.inn');
		if($this->sets['fix_user']) {
			$user=$this->sets['fix_user'];
			$user_inn=$this->sets['fix_inn'];
		}
		if($user_inn) {
			$user.='{{user_inn}}'.$user_inn;
		}
		$strs="preitem;\n";
		if($print==1) {
			if($this->sets['header']) {
				$strs.=$this->sets['header']."\n";
			}
		}
		$strs.="preitem_end;\n";
		if($this->sets['type']) {
			$strs.="z;".$print.";".$user.";\n";
		}

		if(!$this->sets['type'] && $print==1) {
			$strs.=$this->report($change, 'z');
		}
		if((int)$this->sets['price_programm_z']==1) {
			$report=$this->report($change, 'z')."\n";
		}
		else {
			$report='';
		}
		$strs.=$report;
		$strs.="postitem;\n";
		if($this->sets['footer'] && $print==1) {
			$strs.=$this->sets['footer']."\n";
		}
		$strs.="postitem_end;\n";
		$receipt_slip=$change['slip'];
		$report=str_replace('#kkm_br#', '<br>', $report);
		$report=str_replace('p;', '', $report);
		$report=$this->replace_strs($report);
		if($receipt_slip=='') $receipt_slip=$report;
		$epay=new \Models\Epays($this->db, $this->f3);
		$epays=$epay->select_epays(array('active=1'));
		if($epays && $bt==true) {
			foreach($epays as $e) {
				$epay=new \Models\Epays($this->db, $this->f3, $e['id']);
				$res=$epay->z($change);
				if(!$res['success']) {
					$this->f3->get('logs_model')->save_log($res['txt'].' (Электронный метод оплаты "'.$e['title'].'")', 'error');
					$res['txt']=$e['title'].'#kkm_br#'.$res['txt'];
				}
				if($res['txt']) {
					$slip=str_replace("\n", '', $res['txt']);
					$slip=str_replace("\r", '', $slip);
					$slip='p;'.preg_replace('/\<br(\s*)?\/?\>/i', "#kkm_br#", $slip).";\n";
					if($receipt_slip!='') $receipt_slip.='<br>';
					$receipt_slip.=$res['slip'];
					$this->db->exec("UPDATE receipts SET slip=? WHERE id=?", array($receipt_slip, $change['receipt_id']));
					if($res['success']) {
						$res=$this->send_ajax($slip);
					}
					else {
						return $res;
					}
					sleep(3);
				}
			}
		}
		$res=$this->send_ajax($strs);
		if(!is_array($res)) {
			$res=array(
				'success'=>$res
			);
		}
		$res['slip']=$receipt_slip;
		return $res;
	}

	// X-отчет смены
	function x($change) {
		$strs="";
		if($this->sets['type']) {
			$strs="x;\n";
			$strs.=$this->report($change, 'x');
		}
		else {
			$strs.=$this->report($change, 'x');
			if($this->sets['footer']) {
				$strs.=$this->sets['footer']."\n";
			}
		}
		$epay=new \Models\Epays($this->db, $this->f3);
		$epays=$epay->select_epays(array('active=1'));
		if($epays) {
			foreach($epays as $e) {
				$epay=new \Models\Epays($this->db, $this->f3, $e['id']);
				$res=$epay->x($change);
				if(!$res['success']) {
					$this->f3->get('logs_model')->save_log($res['txt'].' (Электронный метод оплаты "'.$e['title'].'")', 'error');
					$res['txt']=$e['title'].'#kkm_br#'.$res['txt'];
				}
				if($res['txt']) {
					$slip=str_replace("\n", '', $res['txt']);
					$slip=str_replace("\r", '', $slip);
					$slip='p;'.preg_replace('/\<br(\s*)?\/?\>/i', "#kkm_br#", $slip).";\n";
					$receipt_slip=$res['slip'];
					$res=$this->send_ajax($slip);
					sleep(3);
				}
			}
		}
		$this->send_ajax($strs);
	}

	function report($change, $type) {
		$types=array('x'=>'НУЛЕВОЙ ОТЧЕТ', 'z'=>'ОТЧЕТ С ГАШЕНИЕМ');
		$strs='';
		if($this->sets['header']) {
			$strs.=$this->sets['header']."\n";
		}
		$strs.="p;".$types[$type]."#kkm_br#";

		if($change) {
			$receipts=new \Models\Receipts($this->db, $this->f3);
			$report=$receipts->change_statistic($change['id']);
			$p=new \Models\Paymentmethods($this->db, $this->f3);
			$paymentmethods=$p->select_method();
			foreach ($paymentmethods as $p) {
				$pays[$p['id']]=array('title'=>$p['title'], 'cash'=>$p['cash']);
			}
			$strs.=date("d/m/Y H:i")."#kkm_br#";
			$strs.="Смена ".$change['id']."#kkm_br#";
			$strs.="Начало смены ".date("d/m/Y H:i", $change['time_start'])."#kkm_br#";
			$epays=$this->db->exec("SELECT * FROM epays_settings");
			if($epays) {
				$epays=array_combine(array_column($epays, 'id'), $epays);
			}
		}

		if($type=='z') {
			$strs.="Конец смены ".date("d/m/Y H:i");
		}
		$strs.="#kkm_br#";
		$total=$change['cash_start'];
		if($change) {
			$types=array(
				$this->f3->get('receipt_sales')=>'Продажи',
				$this->f3->get('receipt_return')=>'Возвраты',
				$this->f3->get('receipt_cashin')=>'Внесение',
				$this->f3->get('receipt_cashout')=>'Изъятие'
			);
			foreach ($report as $type => $r) {
				if(!$types[$type]) continue;
				$strs.="#kkm_br#".$types[$type]." = ".$r['count']."#kkm_br#";
				foreach ($pays as $i => $p) {
					$strs.="  ".$p['title']." = ".number_format(abs($r['pay'][$i]), 2, '.', '')."#kkm_br#";
					if($p['cash']==1) {
						if($type==$this->f3->get('receipt_return'))$total-=$r['pay'][$i];
						else $total+=$r['pay'][$i];
					}
					if($r['epay'] && $p['cash']!=1) {
						foreach($r['epay'] as $eid=>$epay){
							$strs.=' - '.$epays[$eid]['title'].':#kkm_br##kkm_right#'.number_format($epay['sum'], 2, '.', '').'#kkm_br#';
						}
					}
				}
				$strs.="  Сумма = ".number_format(abs($r['sum']), 2, '.', '')."#kkm_br##kkm_br#";
			}
			$strs.="#kkm_br#Наличность в кассе = ".number_format($total, 2, '.', '');
			$strs.=";\n";
		}
		//$strs.="p;Касса: ".$this->api_data['rm_id']."#kkm_br#";
		//$strs.="Кассир ".$this->f3->get('authorization_user.short_name').";\n";
		if($this->sets['footer']) {
			$strs.=$this->sets['footer']."\n";
		}
		return $strs;
	}

	// Добавляем чек
	function ticket($t, $lines, $sum=0, $discount=0, $sales_receipts=0, $print=1, $egais=null, $partner_bonus=0, $partner_bonus_sum=0, $bonus_pay=0, $return_epay=null, $ignore_max_discount=0, $sno=false) {
		$epay_bonus_pay=0;
		$create_receipt=0;
		$pays=json_decode($t['payment'], true);
		$receipt_slip='';
		if($this->f3->get('GET.continue_print')==1) {
			$this->f3->clear('GET.continue_print');
			$this->continue_print();
		}
		elseif(!$t['slip'] && $t['type']!=$this->f3->get('receipt_correct_return')) {
			$epay=new \Models\Epays($this->db, $this->f3, $t['epay']);
			if(isset($epay->epay->config['onlyThis']) && $epay->epay->config['onlyThis']==1 && count($pays)>1) {
				return array(
					'success'=>false,
					'txt'=>'onlyThis_epay_error'
				);
			}

			if(isset($epay->epay->config['bonusPay']) && $epay->epay->config['bonusPay']==1) {
				$partner=$this->db->exec("SELECT * FROM partners WHERE partner_id=? LIMIT 1", array($t['partner_id']??0));
				if(empty($partner)) {
					return array(
						'success'=>false,
						'ticket_reset'=>false,
						'txt'=>'partner_not_found'
					);
				}

				if((int)$epay->epay->config['checkMaxBonusPay']==1) {
					if($partner[0]['bonus_pay']!=100) {
						return array(
							'success'=>false,
							'ticket_reset'=>false,
							'txt'=>'max_bonus_pay_error'
						);
					}
				}

				$partner_bonus=0;
				$partner_bonus_sum=0;
				$bonus_pay=0;
				$epay_bonus_pay=$sum;
				if($partner[0]['bonus']<$sum) {
					return array(
						'success'=>false,
						'ticket_reset'=>false,
						'txt'=>'bonus_pay_sum_error'
					);
				}
			}
			$e_paymethod=(int)$this->f3->get('e_paymethod');
			foreach($pays as $pn=>$pay) {
				if($t['sum']>0 && ((float)$pay['sum']<=0 || $pay['sum']=='' || !is_numeric($pay['sum'])))  {
					return array(
						'success'=>false,
						'ticket_reset'=>false,
						'txt'=>'client_sum_error'
					);
				}
				if((int)$pay['method']==$e_paymethod && ($pay['sum']>0 || (isset($epay->epay->nofr) && $epay->epay->nofr==true))) {
					if($t['type']==$this->f3->get('receipt_sales') || $t['type']==$this->f3->get('receipt_correct_sales')) {
						$epay_type='sale';
					}
					elseif($t['changes']==$return_epay['changes'] && $t['sum']==$return_epay['sum0']) {
						$epay_type='cancel';
					}
					else {
						$epay_type='return';
					}
					$res=$epay->ticket($epay_type, $pay['sum'], $return_epay, $lines);
					if($res['nofr']===true) return $res;
					if(!$res['success']) {
						if($t['type']==$this->f3->get('receipt_correct_sales') || $t['type']==$this->f3->get('receipt_correct_return')) {
							$this->db->exec("DELETE FROM receipts WHERE id=?", array($t['id']));
						}
						echo $res['txt'];
						$this->f3->get('logs_model')->save_log($res['txt'].' Чек: '.$t['id'].'. Способ оплаты '.$t['epay'].' '.$epay->epay->config['ServerName'], 'error');
						exit();
					}
					elseif($res['show_qr']) {
						$this->db->exec("UPDATE receipts SET sbp_order_id=? WHERE id=?", array($res['sbp_order_id'], $t['id']));
						if($res['qr'] && $epay->epay->config['print']==1) {
							$this->send_ajax('qr;'.$res['qr'].";6;\n");
						}
						return $res;
					}
					elseif($res['txt']) {
						$slip=str_replace("\n", '', $res['txt']);
						$slip=str_replace("\r", '', $slip);
						$slip='p;'.preg_replace('/\<br(\s*)?\/?\>/i', "#kkm_br#", $slip).";\n";
						if(!$res['slip']) {
							$res['slip']=$slip;
						}
						$receipt_slip=$res['slip'];
						$this->db->exec("UPDATE receipts SET slip=?, pan=?, transid=?, authcode=? WHERE id=?", array($receipt_slip, $res['pan'], $res['transid'], $res['authcode'], $t['id']));
						if($print==1) $this->send_ajax($slip);
					}
					if(isset($res['fiscalization_type']) && $res['fiscalization_type']>=0) {
						$line_price=$res['fiscalization_type']/count($lines);
						$pays[$pn]['sum']=0;
						foreach($lines as $ln=>$l) {
							if($res['fiscalization_type']==2) {
								$lines[$ln]['psr']=1; // Полная предварительная оплата до момента передачи предмета расчета - ПРЕДОПЛАТА 100%
							}
							else {
								$lines[$ln]['price']=round($line_price/$l['count'], 2);
							}
							$pays[$pn]['sum']+=$lines[$ln]['price'];
							$sum=$pays[$pn]['sum'];
						}
						$t['payment']=json_encode($pays);
					}
					if(isset($res['create_receipt']) && $res['create_receipt']>0) {
						$create_receipt=$res['create_receipt'];
					}
				}
			}
		}
		// Защита от повторной фискализации одного и того же чека (например, при повторном
		// вызове Fr::ticket() из-за дублирующегося запроса) - если ФД/ФП уже были получены
		// от ККТ раньше, повторно ничего не печатаем, а возвращаем уже сохранённый результат.
		$existing_fd=$t['fd']?:($t['receipt']['fd']??null);
		$existing_fp=$t['fp']?:($t['receipt']['fp']??null);
		if($existing_fd && $existing_fp) {
			return array(
				'success'=>true,
				'fd'=>$existing_fd,
				'fp'=>$existing_fp,
				'kkm_time'=>$t['kkm_time']?:($t['receipt']['kkm_time']??null),
				'slip'=>$receipt_slip,
				'epay_bonus_pay'=>$epay_bonus_pay,
				'create_receipt'=>$create_receipt
			);
		}
		if(!$this->sets['type'] && !$print) return true;
		if($this->f3->get('hold')) return true;

		$user=$this->f3->get('authorization_user.short_name');
		$user_name=$user;
		$user_inn=$this->f3->get('authorization_user.inn');
		if($this->sets['fix_user']) {
			$user=$this->sets['fix_user'];
			$user_inn=$this->sets['fix_inn'];
		}
		if($user_inn) {
			$user.='{{user_inn}}'.$user_inn;
		}

		if(!$this->sets['type']) {
			$t['receipt']['sno']=$sno;
			$t['receipt']['changes']=$t['changes'];
			$t['receipt']['user']['short_name']=$user_name;
			$t['receipt']['time']=microtime();
			$t['receipt']['receiptlines']=$lines;
			$t['receipt']['pays']=json_decode($t['payment'], true);
			$p=new \Models\Paymentmethods($this->db, $this->f3);
			$paymentmethods=$p->select_method();
			foreach ($paymentmethods as $p) {
				$pays[$p['id']]=array('title'=>$p['title'], 'cash'=>$p['cash']);
			}
			foreach($t['receipt']['pays'] as $pn=>$pv) {
				$t['receipt']['pays'][$pn]['title']=$pays[$pv['method']]['title'];
			}

			$type_text=array(1=>"ПРИХОД", 2=>"ВОЗВРАТ ПРИХОДА", 128=>"КОРРЕКЦИЯ/ПРИХОД", 130=>"КОРРЕКЦИЯ/ВОЗВРАТ");
			$t['receipt']['title']=$type_text[(int)$t['type']];
			$res=$this->print($t['receipt']);
			$res['slip']=$receipt_slip;
			return $res;
		}


		$this->receipt=$t['receipt'];

		$vat_type=$this->f3->get('vat_type');
		$psr=4; // Признак способа расчета по умолчанию
		$ppr=1; // Признак предмета расчета по умолчанию
		$section=1; // Секция

		// Заголовок
		$strs="preitem;\n";
		if($this->sets['header'] && $print==1) {
			$strs.=$this->sets['header']."\n";
		}

		if($sales_receipts && $print==1) {
			$strs.="print_font;2;Товарный чек;\n";
		}
		$strs.="preitem_end;\n";

		$other_data=json_decode($t['other_data'], true);
		$ur=0;
		if($other_data['partner']) {
			if(is_numeric($other_data['partner']['inn']) && (($other_data['partner']['ie']==1 && mb_strlen($other_data['partner']['inn'])==12) || mb_strlen($other_data['partner']['inn'])==10)) {
				$ur=1;
				$other_data['partner']['ur']=1;
			}
		}

		// Товары
		$lines_str='';
		$discount_sum=0;
		$ticket_sum=0;
		$round_kop=0;
		$bonus_pay0=$bonus_pay;
		$partner_bonus_sum-=$bonus_pay;
		foreach ($lines as $l) {
			if($l['parent_id']>0 && $l['price']==0 && $l['mark']!='') continue;
			if($l['product_id']==0 && $l['parent_id']>0 && (int)$this->sets['hide_free_modifier']==1) continue;
			if(!isset($l['price0'])) {
				$l['price0']=$l['price'];
			}
			if($l['discount_sum']>0) {
				$discount_sum+=$l['discount_sum']*$l['count'];
			}
			else {
				$discount_sum+=($l['price0']-$l['price'])*$l['count'];
			}
			if(!isset($l['units_fr'])) $l['units_fr']=255;
			$price=$l['price']*100;
			$price=round($price);
			$vt=$vat_type;
			if(!isset($l['ppr'])) $l['ppr']=$ppr;
			if(!isset($l['psr'])) $l['psr']=$psr;
			if(isset($l['other_info'])) {
				$other_info=json_decode($l['other_info'], true);
				if(isset($other_info['ppr'])) $l['ppr']=$other_info['ppr'];
			}
			if($l['vat_type']==0) $vt=$this->sets['vat_type']['vatNo'];
			elseif($l['vat_type']!=0 && $l['vat']==0) $vt=$this->sets['vat_type']['vat0'];
			elseif($l['vat_type']==1 && $l['vat']>0 && $l['vat']<=5) $vt=$this->sets['vat_type']['vat105'];
			elseif($l['vat_type']==-1 && $l['vat']>0 && $l['vat']<=5) $vt=$this->sets['vat_type']['vat5'];
			elseif($l['vat_type']==1 && $l['vat']>5 && $l['vat']<=7) $vt=$this->sets['vat_type']['vat107'];
			elseif($l['vat_type']==-1 && $l['vat']>5 && $l['vat']<=7) $vt=$this->sets['vat_type']['vat7'];
			elseif($l['vat_type']==1 && $l['vat']>7 && $l['vat']<=10) $vt=$this->sets['vat_type']['vat110'];
			elseif($l['vat_type']==-1 && $l['vat']>7 && $l['vat']<=10) $vt=$this->sets['vat_type']['vat10'];
			elseif($l['vat_type']==1 && $l['vat']>10 && $l['vat']<=20) $vt=$this->sets['vat_type']['vat120'];
			elseif($l['vat_type']==-1 && $l['vat']>10 && $l['vat']<=20) $vt=$this->sets['vat_type']['vat20'];
			elseif($l['vat_type']==1 && $l['vat']>20) $vt=$this->sets['vat_type']['vat122'];
			elseif($l['vat_type']==-1 && $l['vat']>20) $vt=$this->sets['vat_type']['vat22'];
			$l['country_id']=(string)sprintf("%03d", $l['country_id']);
			if($l['mark']!='') {
				$mark=json_decode($l['mark'], true)[0];
				$i=1;
				if(!$l['pg'])$l['pg']='other';
				if($l['pg']!='furs') $l['ppr']=33; // ТМ
				$count=$l['count'];
				$smde=array(
					'title'=>str_replace(';', ',', $l['product_title']),
					'mark'=>str_replace(';', '{{U+003B}}', (string)$mark),
					'gp'=>$l['pg'],
					'egais'=>$l['egais'],
					'price'=>$price,
					'quantity'=>round($count*1000),
					'vat'=>$vt,
					'section'=>$section,
					'psr'=>$l['psr'],
					'ppr'=>$l['ppr'],
					'partner'=>$l['partner']?$l['partner']:array(),
					'ffd_version'=>$this->sets['version'],
					'units'=>$l['units_fr'],
					'barcode'=>$l['barcode'],
					'reqId'=>$l['reqId'],
					'reqTimestamp'=>$l['reqTimestamp'],
					'inst'=>$l['inst'],
					'version'=>$l['version']
				);
				if($ur==1 && $l['country_id']>0 && (string)$l['country_id']!='643') {
					$smde['country_id']=$l['country_id'];
					$smde['country_alpha2']=$l['country_alpha2'];
					$smde['gtd']=$l['gtd']??'';
				}
				$lines_str.='smde;'.json_encode($smde).";\n";
			}
			else {
				$smde=array(
					'title'=>str_replace(';', ',', $l['product_title']),
					'price'=>$price,
					'quantity'=>round($l['count']*1000),
					'vat'=>$vt,
					'section'=>$section,
					'psr'=>$l['psr'],
					'ppr'=>$l['ppr'],
					'partner'=>$l['partner']?$l['partner']:array(),
					'ffd_version'=>$this->sets['version'],
					'units'=>$l['units_fr'],
					'barcode'=>$l['barcode']
				);
				if($ur==1 && $l['country_id']>0 && (string)$l['country_id']!='643') {
					$smde['country_id']=$l['country_id'];
					$smde['country_alpha2']=$l['country_alpha2'];
					$smde['gtd']=$l['gtd']??'';
				}
				$lines_str.='smde;'.json_encode($smde).";\n";
			}
			$ticket_sum+=$price*$l['count'];
		}
		//
		if($sum>0) {	
			$ticket_sum=$sum*100;
		}
		if($round_kop==1) {
			$total_sum=floor($ticket_sum/100)*100;
		}
		else {
			$total_sum=$ticket_sum;
		}

		$strs.='b;'.($this->ticket_type[$t['type']]).';'.$user.";".$print.";".$total_sum.';'.$ticket_sum.";\n"; // Открываем чек
		if($t['client']) {
			$other_data['partner']['client']=$t['client'];
		}

		if($ur!=1) {
			$other_data['partner']=array(
				'client'=>$other_data['partner']['client']
			);
		}

		$strs.='partner;'.json_encode($other_data['partner']).";\n";

		if(isset($t['correct_type']) && ($t['correct_type']==0 || $t['correct_type']==1) && ($this->ticket_type[$t['type']]==128 || $this->ticket_type[$t['type']]==130)) {
			$strs.="set_tlv;1173;1;".$t['correct_type'].";\n";
		}
		if($t['osn_date'] && ($this->ticket_type[$t['type']]==128 || $this->ticket_type[$t['type']]==130)) {
			$dates=explode('.', $t['osn_date']);
			$strs.="set_tlv;1178;3;".(gmmktime(0, 0, 0, $dates[1], $dates[0], $dates[2])).";\n";
		}
		if($t['osn_number'] && $t['correct_type']==1 && ($this->ticket_type[$t['type']]==128 || $this->ticket_type[$t['type']]==130)) {
			$strs.="set_tlv;1179;5;".$t['osn_number'].";\n";
		}
		if($t['fpd']) {
			$strs.="set_tlv;1192;5;".$t['fpd'].";\n";
		}

		$strs.=$lines_str;

		// оплата
		$strs.='tmde;';

		foreach ($pays as $p) {
			$mpay[$this->sets['pays_type'][$p['method']]]=$p['sum'];
		}

		$pay_count=5;

		for($i=0; $i<$pay_count; $i++) {
			if(!$mpay[$i])$mpay[$i]=0;
			$strs.=max(round($mpay[$i]*100), 0).';';
		}

		$sno_types=$this->f3->get('sno');
		$strs.=$sno!=false && isset($sno_types[$sno])?(string)$sno:$this->sets['sno'].';';
		$strs.="\n";
		$strs.="postitem;\n";
		/*if($egais && isset($egais['url']) && isset($egais['sign'])) {
			$strs.="p;".$egais['sign'].";\n";
			$strs.="qr;".$egais['url'].";\n";
			$strs.="p;".$egais['url'].";\n";
		}*/

		if($print==1) {
			if($this->sets['type']==0) {
				$strs.="p;Позиций ".count($lines);
				if($discount_sum>0) {
					$strs.="#kkm_br#Скидка ".number_format($discount_sum, 2, '.', '');
				}
				$strs.="#kkm_br#";
				$strs.="Касса: ".$this->api_data['rm_id'];
				$strs.="#kkm_br#".date("d.m.Y H:i")." N ".$t['id']."#kkm_br#";
				$strs.="Кассир#kkm_br#".$user_name;
				if($user_inn) {
					$strs.="#kkm_br#ИНН кассира#kkm_br#".$user_inn;
				}
				$strs.=";\n";
			}
			if($partner_bonus!=0 || $partner_bonus_sum!=0) {
				$strs.="p;Оплачено баллами: ".$bonus_pay0."#kkm_br#Начисленно баллов: ".$partner_bonus."#kkm_br#Всего баллов: ".$partner_bonus_sum.";\n";
			}
			if($this->sets['footer']) {
				$strs.=$this->sets['footer']."\n";
			}
		}
		$strs.="postitem_end;\n";
		$this->discount_sum=$discount_sum;
		$res=$this->send_ajax($strs);
		if(!is_array($res)) {
			$res=array(
				'success'=>$res,
			);
		}
		$res['epay_bonus_pay']=$epay_bonus_pay;
		$res['create_receipt']=$create_receipt;
		$res['slip']=$receipt_slip;
		return $res;
	}

	// Внесение в кассу
	function cashin($change, $sum, $print_type=null) {
		if($this->f3->get('GET.continue_print')==1) {
			$this->f3->clear('GET.continue_print');
			$this->continue_print();
		}
		if($this->f3->get('hold')) return true;
		$user=$this->f3->get('authorization_user.short_name');
		$user_inn=$this->f3->get('authorization_user.inn');
		if($this->sets['fix_user']) {
			$user=$this->sets['fix_user'];
			$user_inn=$this->sets['fix_inn'];
		}
		if($user_inn) {
			$user.='{{user_inn}}'.$user_inn;
		}
		$strs="preitem;\n";
		if($this->sets['header']) {
			$strs.=$this->sets['header']."\n";
		}
		$strs.="preitem_end;\n";
		if($print_type!==0 && $this->sets['type']) {
			$strs.="imde;".($sum*100).";".$user.";\n";
		}
		if(!$this->sets['type'] || $print_type===0) { 
			// Заголовок
			if($sum>=0) {
				$strs.="p;ВНЕСЕНИЕ В КАССУ";
			}
			else {
				$strs.="p;ИЗЪЯТИЕ ИЗ КАССЫ";
			}
			$strs.="#kkm_br#";
			$strs.="Сумма = ".number_format(abs($sum), 2, '.', '')."#kkm_br#";
			//$strs.="Касса: ".$this->api_data['rm_id']."#kkm_br#";
			//$strs.="Кассир ".$this->f3->get('authorization_user.short_name')."#kkm_br#";
			$strs.="Смена ".$change.";\n";
			//$strs.=date("d-m-Y H:i").";\n";
		}
		/*else {
			$strs.="p;Касса: ".$this->api_data['rm_id']."#kkm_br#";
			$strs.="Кассир ".$this->f3->get('authorization_user.short_name').";\n";
		}*/
		// подвал
		$strs.="postitem;\n";
		if($this->sets['footer']) {
			$strs.=$this->sets['footer']."\n";
		}
		$strs.="postitem_end;\n";
		
		$this->send_ajax($strs);
	}

	// Обнуление не пробитого чека
	function reset_ticket() {
		$strs="g;";
		$this->send_ajax($strs);
		return array(
			'success'=>true,
			'txt'=>'ticket_reset'
		);
	}

	// Запрос полного статуса ККМ
	function status_kkm() {
		$strs="d;";
		$this->fr->send_ajax($strs, null, true);
	}

	// Продолжить печать, после аварийной остановки
	function continue_print() {
		$strs="continue_print;";
		$this->send_ajax($strs);
		return array(
			'success'=>true,
			'txt'=>'print_continue'
		);
	}

	// Отчет по секциям
	function rep_sections() {
		$strs="rep_sections;";
		$this->send_ajax($strs);
	}

	// Печать копии последнего чека
	function c() {
		$strs='';
		// Заголовок
		if($this->sets['header']) {
			$strs.=$this->sets['header']."\n";
		}
		$strs.="c;\n";
		// Подвал
		if($this->sets['footer']) {
			$strs.=$this->sets['footer']."\n";
		}
		//$strs.="p;Касса: ".$this->api_data['rm_id']."#kkm_br#";
		//$strs.="Кассир ".$this->f3->get('authorization_user.short_name').";\n";
		
		$this->send_ajax($strs);
	}

	// Печать ценника
	function pricetags($product) {
		if($product['vat_type']>0) {
			$vat_price=$product['price']/100*$product['vat'];
			$price=$product['price']+$vat_price;
		}
		else {
			$price=$product['price'];
			$vat_price=0;
		}
		$strs="";
		if($this->sets['header']) {
			$strs.=$this->sets['header']."\n";
		}
		$strs.="print_bold;".str_replace(';', ',', $product['title'])."#kkm_br#";
		if($product['quantity']!=1) {
			$strs.="#kkm_center#".number_format($price, 2, '.', '').'x'.number_format($product['quantity'], 3, '.', '')."=".number_format($price*$product['quantity'], 2, '.', '')." руб.#kkm_br#";
		}
		else {
			$strs.="#kkm_center#".number_format($price, 2, '.', '')." руб.#kkm_br#";
		}
		//$strs.="#kkm_bold#Цена:#kkm_br##kkm_right##kkm_bold#".number_format($price*$product['quantity'], 2, '.', '')." руб.#kkm_br#";
		if($product['vat_type']!=0) {
			$strs.="В т. ч НДС ".number_format($vat_price, 2, '.', '')." руб.#kkm_br#;\n";
		}
		$strs.="\n";
		if(is_array($product['barcodes'][0]['barcode'])) {
			$product['barcodes'][0]['barcode']=$product['barcodes'][0]['barcode']['barcode'];
		}

		if($product['barcodes'][0]['barcode']!='') {
			$barcode=ltrim((string)$product['barcodes'][0]['barcode'], '0');
			$barcode=mb_substr($barcode, 0, 13);
			$strs.="barcode;".$barcode.";\n";
			//$strs.="p;#kkm_center#".$barcode.";\n";
		}
		if($this->sets['footer']) {
			$strs.=$this->sets['footer']."\n";
		}

		return $this->send_ajax($strs);
	}

	// Печать пречека или товарного чека
	function print($receipt) {
		if(!$this->sets['active']) {
			return array(
				'success'=>true
			);
		}
		$this->receipt=$receipt;
		$strs='';
		// Заголовок
		$strs="preitem;\n";
		if($this->sets['header']) {
			$strs.=$this->sets['header']."\n";
		}
		$strs.="preitem_end;\n";

		if($this->printer!='kitchen' && $this->printer!='bar') {
			$strs.='p;';
			if($receipt['title']) {
				$strs.='#kkm_center#'.$receipt['title'].'#kkm_br#';
			}
			// Товарный чек или пречек
			elseif($receipt['time']>0) {
				$strs.='#kkm_center#ТОВАРНЫЙ ЧЕК#kkm_br#';
			}
			else {
				$strs.='#kkm_center#ПРЕДВАРИТЕЛЬНЫЙ ЧЕК#kkm_br#';
			}
			//$strs.=";\n";
		}
		else {
			$strs.='print_bold;';
		}

		$sum=0;
		$discount_sum=0;
		$turn=0;
		// Позиции в чеке
		$print_lines=0;
		$strs.='#kkm_br#';
		$width=$this->fr->get_paper_width();
		if($width==0) $width=30;
		//$title_w=floor($width/2);
		$ticket_width_table_tmp=$this->f3->get('ticket_width_table_tmp');
		$count_w=max(7, floor($width/6));
		$price_w=max(10, $count_w);
		$summ_w=max(10, $price_w);
		$title_w=$width-$summ_w-$price_w-$count_w;
		$width_part=floor($width/4);
		if($this->printer!='kitchen' && $this->printer!='bar' && $width>$ticket_width_table_tmp) {
			$strs.='Номенклатура'.str_repeat(' ', max(0, $title_w-12));
			$strs.=str_repeat(' ', max(0, $count_w-6)).'Кол-во';
			$strs.=str_repeat(' ', max(0, $price_w-4)).'Цена';
			$strs.=str_repeat(' ', max(0, $summ_w-5)).'Сумма';
		}
		$turn=0;
		foreach ($receipt['receiptlines'] as $n=>$l) {
			if(($this->printer=='kitchen' || $this->printer=='bar') && (int)$l['print_group_id']!=(int)$this->print_group_id) continue;
			// Цена
			$print_lines+=1;
			if($l['loyalty']==0 && !$l['discount']) {
				$l['discount']=$receipt['discount'];
			}
			if($l['discount']>$l['max_discount']) {
				$l['discount']=$l['max_discount'];
			}
			$price=$l['price']+($l['price']*($l['vat']/100))*max(0, $l['vat_type']);
			$price=round($price, 2);

			$d_sum=$l['price0']*($l['discount']/100);
			//$price-=$d_sum;
			if($l['line_discount']>0) {
				$price0=$l['price0']+($l['price0']*($l['vat']/100))*max(0, $l['vat_type']);
				$d_sum=(float) $price0*((float) $l['line_discount']/100);
			}
			$discount_sum+=$d_sum*$l['count'];
			$sum+=$price*$l['count']; // Сумма чека
			$l['product_title']=str_replace(';', ',', $l['product_title']);
			if($l['parent_id']>0) {
				$l['product_title']=' -'.$l['product_title'];
			}
			if($this->printer=='kitchen' || $this->printer=='bar') {
				if($l['turn']!=$turn) {
					$strs.='#kkm_br##kkm_center#--- Очередь '.$l['turn'].' ---#kkm_br#';
				}
				$turn=$l['turn'];

				$strs.='#kkm_br#';

				if($this->sets['line_by_line']!=1) {
					if($l['parent_id']==0 && $n>0)$strs.='#kkm_br##kkm_center#----------#kkm_br#';
				}

				$title=mb_str_split($l['product_title'], $title_w+$price_w+$summ_w);
				$title[0]=trim($title[0]);
				$strs.=$title[0].str_repeat(' ', max(0, $title_w+$price_w+$summ_w-mb_strlen($title[0])));
				$strs.=sprintf("%' ".($count_w)."s", numberformat($l['count'], 3, '.', ''));
				$title_n=count($title);
				if($title_n>1) {
					for($i=1; $i<=$title_n; $i++) {
						if($title[$i]!='') $strs.='#kkm_br#'.trim($title[$i]);
					}
				}
			}
			else {
				if($width>$ticket_width_table_tmp) $w=$title_w;
				else $w=$width;
				$strs.='#kkm_br#';
				$title=mb_str_split($l['product_title'], $w);
				$title[0]=trim($title[0]);
				$strs.=$title[0].str_repeat(' ', max(0, $w-mb_strlen($title[0])));
				if($width>$ticket_width_table_tmp) {
					$strs.=sprintf("%' ".($count_w-mb_strlen($l['unit_short_title']))."s", numberformat($l['count'], 3, '.', '')).$l['unit_short_title'];
					$strs.=sprintf("%' ".$price_w."s", number_format($price, 2, '.', ''));
					$strs.=sprintf("%' ".$summ_w."s", number_format($price*$l['count'], 2, '.', ''));
				}
				$title_n=count($title);
				if($title_n>1) {
					for($i=1; $i<=$title_n; $i++) {
						if($title[$i]!='') $strs.='#kkm_br#'.trim($title[$i]);
					}
				}
				if($width<=$ticket_width_table_tmp) {
					$count_txt=numberformat($l['count'], 3, '.', '').$l['unit_short_title'];
					$strs.='#kkm_br#'.$count_txt.str_repeat(' ', max(0, $width_part-2-mb_strlen($count_txt))).' X';
					$strs.=sprintf("%' ".$width_part."s", number_format($price, 2, '.', ''));
					$strs.=str_repeat(' ', max(0, $width_part-1)).'=';
					$strs.=sprintf("%' ".($width-$width_part*3)."s", number_format($price*$l['count'], 2, '.', ''));
				}
			}

			// НДС товара
			if($l['vat_type']!=0) {
				$vp=(($l['price']/(100+$l['vat']*abs(min(0, $l['vat_type']))))*$l['vat'])*$l['count'];
				$vp=round($vp, 2);
				$vat[$l['vat']]+=$vp; // Сумма НДС по чеку
				if($this->printer!='kitchen' && $this->printer!='bar') {
					$strs.='#kkm_br#НДС'.str_repeat(' ', max(0, $title_w-3));
					$strs.=sprintf("%' ".($count_w+$price_w)."s", numberformat($l['vat'], 3, '.', '').'%');
					$strs.=sprintf("%' ".$summ_w."s", number_format($vp, 2, '.', ''));
				}
			}
			
		}

		if($this->printer!='kitchen' && $this->printer!='bar') {
			$strs.='#kkm_br#'.sprintf("%'-".$width."s", '-').'#kkm_br#';
			$strs.='ИТОГ'.str_repeat(' ', max(0, $title_w-4));
			$strs.=sprintf("%' ".($width-$title_w)."s", number_format($sum, 2, '.', ''));
			$strs.='#kkm_br#'.sprintf("%'-".$width."s", '-').'#kkm_br#';
		}

		// Если чек пробит
		if($this->printer!='kitchen' && $this->printer!='bar' && $receipt['time']>0 && $receipt['pays']) {
			$cash=0;
			// Оплата
			$strs.='#kkm_br#';
			$strs.='#kkm_center#ОПЛАТА#kkm_br#';
			foreach ($receipt['pays'] as $p) {
				$strs.=$p['title'].str_repeat(' ', max(0, $title_w-mb_strlen($p['title'])));
				$strs.=sprintf("%' ".($width-$title_w)."s", number_format(round($p['sum'], 2), 2, '.', ''));
				$cash+=$p['sum'];
			}
			$strs.='#kkm_br#';

			// Сдача
			$strs.='Сдача'.str_repeat(' ', max(0, $title_w-5));
			$strs.=sprintf("%' ".($width-$title_w)."s", number_format($cash-$sum, 2, '.', ''));
			$strs.='#kkm_br#';
			$sno=$this->f3->get('sno');
			// СНО
			$strs.='СНО';
			$strs.=str_repeat(' ', max(0, $width-mb_strlen($sno[$receipt['sno']])-3)).$sno[$receipt['sno']];
			$strs.='#kkm_br#';

			// НДС по чеку
			if($vat) {
				$strs.='#kkm_center#НДС#kkm_br#';
				foreach ($vat as $p=>$v) {
					$strs.=sprintf("%-' ".$title_w."s", number_format($p, 2, '.', '').'%');
					$strs.=sprintf("%' ".($width-$title_w)."s", number_format($v, 2, '.', ''));
				}
				$strs.='#kkm_br#';
			}
			// Кассир и смена
			$strs.='Кассир';
			$user=$receipt['user']['short_name'];
			if($this->sets['fix_user']) {
				$user=$this->sets['fix_user'];
			}
			$strs.=str_repeat(' ', max(0, $width-mb_strlen($user)-6)).$user;
			$strs.='#kkm_br#';
			$strs.='Смена';
			$strs.=str_repeat(' ', max(0, $width-mb_strlen($receipt['changes'])-5)).$receipt['changes'];
			$strs.='#kkm_br#';
		}

		if($this->printer!='kitchen' && $this->printer!='bar') {
			$strs.='Позиций';
			$strs.=str_repeat(' ', max(0, $width-mb_strlen(count($receipt['receiptlines']))-7)).count($receipt['receiptlines']);
			$strs.='#kkm_br#';

			if($discount_sum>0) {
				$strs.='Скидка';
				$strs.=str_repeat(' ', max(0, $width-mb_strlen(number_format($discount_sum, 2, '.', ''))-6)).number_format($discount_sum, 2, '.', '');
				$strs.='#kkm_br#';
			}
			$strs.='ЧЕК';
			$strs.=str_repeat(' ', max(0, $width-mb_strlen($receipt['id'])-3)).$receipt['id'];
			$strs.='#kkm_br#';
		}

		/*if($receipt['time']>0) {
			$strs.=date('d-m-Y H:i', $receipt['time']);
		}*/

		if(($this->printer=='kitchen' || $this->printer=='bar') && $receipt['description']!='') {
			$strs.='#kkm_br#'.sprintf("%'-".$width."s", '-').'#kkm_br#';
			$strs.=$receipt['description'].'#kkm_br#';
		}

		$strs.=";\n";

		//$strs.="Касса: ".$this->api_data['rm_id']."#kkm_br#";
		//$strs.="Кассир ".$this->f3->get('authorization_user.short_name').";\n";

		// Подвал

		$strs.="postitem;\n";
		if($this->sets['footer']) {

			$strs.=$this->sets['footer']."\n";
		}
		$strs.="postitem_end;\n";
		if(($this->printer=='kitchen' || $this->printer=='bar') && $this->print_group_id==0) {
			$printers=$this->get_printers(array('printer=? AND print_group_id!=0', array($this->printer)));
			if($printers) {
				foreach($printers as $printer){
					$fr=new \Models\Fr($this->db, $this->f3, $this->printer, true, $printer['print_group_id']);
					$res=$fr->print($receipt);
				}
			}
		}
		if($print_lines==0) {
			return array(
				'success'=>true
			);
		}
		if(!$this->fr->config['repeat']) $this->fr->config['repeat']=1;
		for($i=0; $i<$this->fr->config['repeat']; $i++) {
			$copy='';
			if($i>0) {
				$copy="print_font;2;#kkm_center#КОПИЯ ".$i.";\n";
			}
			$res=$this->send_ajax($copy.$strs);
		}
		return $res;
	}

	// Проверка кода маркировки
	function check_mark_fr($mark, $unit=0) {
		$strs='check_mark;'.str_replace(';', '{{U+003B}}', $mark).";".$unit.';';
	}

	// Замена переменных
	function replace_strs($strs) {
		$strs=preg_replace('/\<br(\s*)?\/?\>/i', "#kkm_br#", $strs);
		$strs=str_replace('#kkm_rm#', $this->api_data['rm_id'], $strs);
		$strs=html_entity_decode($strs);
		$user=$this->f3->get('authorization_user.short_name');
		$print_user=$user;
		if($this->sets['fix_user']) {
			$user=$this->sets['fix_user'];
		}
		$strs=str_replace('#kkm_user#', $user, $strs);
		$strs=str_replace('#print_user#', $print_user, $strs);
		$strs=str_replace('#date#', date('d.m.Y'), $strs);
		$strs=str_replace('#time#', date('H:i:s'), $strs);
		if($this->receipt) {
			$strs=str_replace('#receipt_number#', $this->receipt['id'], $strs);
			$strs=str_replace('#order_number#', $this->receipt['order_number'], $strs);
			$strs=str_replace('#big_order_number#', $this->ascii_str($this->receipt['order_number']), $strs);
			$strs=str_replace('#big_order_number2#', $this->ascii_str2($this->receipt['order_number']), $strs);
			$strs=str_replace('#big_order_number3#', $this->ascii_str3($this->receipt['order_number']), $strs);
			$strs=str_replace('#table_number#', $this->receipt['table_id'], $strs);
			$strs=str_replace('#room_number#', $this->receipt['table']['room'], $strs);
			$strs=str_replace('#table#', $this->receipt['table']['title'], $strs);
			$strs=str_replace('#room#', $this->receipt['table']['room_title'], $strs);
			$strs=str_replace('#description#', $this->receipt['description'], $strs);
		}
		else {
			$strs=str_replace('#receipt_number#', '', $strs);
			$strs=str_replace('#table_number#', '', $strs);
			$strs=str_replace('#big_order_number#', '', $strs);
			$strs=str_replace('#big_order_number2#', '', $strs);
			$strs=str_replace('#big_order_number3#', '', $strs);
			$strs=str_replace('#order_number#', '', $strs);
			$strs=str_replace('#room_number#', '', $strs);
			$strs=str_replace('#table#', '', $strs);
			$strs=str_replace('#room#', '', $strs);
			$strs=str_replace('#description#', '', $strs);
		}
		if($this->discount_sum) {
			$strs=str_replace('#discount_sum#', number_format($this->discount_sum, 2, '.', ''), $strs);
		}
		else {
			$strs=str_replace('#discount_sum#', 0.00, $strs);
		}
		$s=explode("\n", $strs);
		$strs='';
		foreach($s as $str) {
			$str=trim($str);
			if($str!='') {
				$strs.=$str."\n";
			}
		}
		return $strs;
	}

	// Проверка маркированного товара
	function check_mark($mark, $count=1, $unit=0) {
		// Статус смены

		$mark=str_replace(' ', '+', $mark);
		$strs='check_mark;'.str_replace(';', '{{U+003B}}', $mark).";".$count.';'.$unit.";\n";
		return $this->send_ajax($strs);
	}

	function print_qr($qr) {
		$strs='qr;'.html_entity_decode($qr).";5;\nfeed;3;\n";
		return $this->send_ajax($strs);
	}

	function correction($data) {
		$data['user_name']=$this->f3->get('authorization_user.short_name');
		$data['user_inn']=$this->f3->get('authorization_user.inn');
		if($this->sets['fix_user']) {
			$data['user_name']=$this->sets['fix_user'];
			$data['user_inn']=$this->sets['fix_inn'];
		}
		$strs='correction;'.json_encode($data).";\n";
		return $this->send_ajax($strs);
	}

	function printdoc($fd) {
		$strs='printdoc;'.$fd.';';
		return $this->send_ajax($strs);
	}

	// Отправка запроса
	function send_ajax($strs) {
		$strs=$this->replace_strs($strs);
		if($this->f3->get('GET.continue_print')==1) {
			$this->f3->clear('GET.continue_print');
			$this->continue_print();
			return;
		}
		if(!$this->sets['active']) {
			return array(
				'success'=>true
			);
		}
		return $this->fr->send_ajax($strs);
	}

	// Состояние смены
	function change_status() {
		// closed - закрыта
        // opened - открыта
        // expired - истекла
		if(!$this->sets['active'] || !$this->sets['type']) return 'opened'; // Если ККМ не используется или используется чекопечатающий принтер
		$status=$this->fr->change_status();
		return $status;
	}

	function cancel_qr($data) {
		$epay=new \Models\Epays($this->db, $this->f3, $data['epay']);
		return $epay->cancel_qr($data);
	}

	function paycontrol_qr($data) {
		$epay=new \Models\Epays($this->db, $this->f3, $data['epay']);
		return $epay->paycontrol_qr($data);
	}

	function get_ofd() {
		return $this->fr->get_ofd();
	}

	function set_ofd($data) {
		return $this->fr->set_ofd($data);
	}

	function get_regdata() {
		return $this->fr->get_regdata();
	}

	function kkm_registration($data) {
		return $this->fr->kkm_registration($data);
	}

	function closefn() {
		return $this->fr->closefn();
	}

	function salesreport_print($lines) {
		$sum=0;
		$strs='p;#kkm_center#ОТЧЕТ ЗА СМЕНУ#kkm_br##kkm_br##kkm_center#ПРОДАЖИ#kkm_br##kkm_br#';
		$width=$this->fr->get_paper_width();
		if($width==0) $width=30;
		$title_w=floor($width/2);
		$count_w=floor(($width-$title_w)/2);
		$summ_w=$width-$title_w-$count_w;
		if($this->printer!='kitchen' && $this->printer!='bar') {
			$strs.='Номенклатура'.str_repeat(' ', max(0, $title_w-12));
			$strs.=str_repeat(' ', max(0, $count_w-6)).'Кол-во';
			$strs.=str_repeat(' ', max(0, $summ_w-5)).'Сумма';
		}
		foreach ($lines['sales'] as $l) {
			$strs.='#kkm_br#';
			$title=mb_str_split($l['product_title'], $title_w);
			$title[0]=trim($title[0]);
			$strs.=$title[0].str_repeat(' ', max(0, $title_w-mb_strlen($title[0])));
			$strs.=sprintf("%' ".$count_w."s", numberformat($l['total_count'], 3, '.', ''));
			$strs.=sprintf("%' ".$summ_w."s", number_format($l['sum'], 2, '.', ''));
			$title_n=count($title);
			if($title_n>1) {
				for($i=1; $i<=$title_n; $i++) {
					if($title[$i]!='') $strs.='#kkm_br#'.trim($title[$i]);
				}
			}
		}
		$strs.='#kkm_br##kkm_center#ВОЗВРАТЫ#kkm_br##kkm_br#';
		if($this->printer!='kitchen' && $this->printer!='bar') {
			$strs.='Номенклатура'.str_repeat(' ', max(0, $title_w-12));
			$strs.=str_repeat(' ', max(0, $count_w-6)).'Кол-во';
			$strs.=str_repeat(' ', max(0, $summ_w-5)).'Сумма';
		}
		foreach ($lines['returns'] as $l) {
			$strs.='#kkm_br#';
			$title=mb_str_split($l['product_title'], $title_w);
			$title[0]=trim($title[0]);
			$strs.=$title[0].str_repeat(' ', max(0, $title_w-mb_strlen($title[0])));
			$strs.=sprintf("%' ".$count_w."s", numberformat($l['total_count'], 3, '.', ''));
			$strs.=sprintf("%' ".$summ_w."s", number_format($l['sum'], 2, '.', ''));
			$title_n=count($title);
			if($title_n>1) {
				for($i=1; $i<=$title_n; $i++) {
					if($title[$i]!='') $strs.='#kkm_br#'.trim($title[$i]);
				}
			}
		}
		$strs.='#kkm_br##kkm_center#ИТОГИ#kkm_br##kkm_br#';
		if($this->printer!='kitchen' && $this->printer!='bar') {
			$strs.='Номенклатура'.str_repeat(' ', max(0, $title_w-12));
			$strs.=str_repeat(' ', max(0, $count_w-6)).'Кол-во';
			$strs.=str_repeat(' ', max(0, $summ_w-5)).'Сумма';
		}
		foreach ($lines['result'] as $l) {
			$strs.='#kkm_br#';
			$title=mb_str_split($l['product_title'], $title_w);
			$title[0]=trim($title[0]);
			$strs.=$title[0].str_repeat(' ', max(0, $title_w-mb_strlen($title[0])));
			$strs.=sprintf("%' ".$count_w."s", numberformat($l['total_count'], 3, '.', ''));
			$strs.=sprintf("%' ".$summ_w."s", number_format($l['sum'], 2, '.', ''));
			$title_n=count($title);
			if($title_n>1) {
				for($i=1; $i<=$title_n; $i++) {
					if($title[$i]!='') $strs.='#kkm_br#'.trim($title[$i]);
				}
			}
			$sum+=$l['sum'];
		}
		$strs.="#kkm_br##kkm_right#Итого ".numberformat($sum, 2, '.', '').";\n";
		$strs.="postitem;\n";
		if($this->sets['footer']) {

			$strs.=$this->sets['footer']."\n";
		}
		$strs.="postitem_end;\n";
		return $this->fr->send_ajax($strs);
	}
}
