Не печатает чек с СН ЕНВД Розница 2.2

Ну хоть ты тресни, но после выставления в настройках организации:

И установка что продажи по складу именно ЕНВД:

На чеке, при фискализации на ККТ всё равно вылезало СН : УСН Доходы. В результате копания кода 1С, в модуле Общиймодуль.ПодключаемоеОборудованиеРК, нашел функцию отвечающую за выдачу на ККТ систему налогообложения:

Функция ПолучитьСистемуНалогообложенияККТ(Организация, ВидНалога, ДатаДокумента = Неопределено) Экспорт
	
	Если НЕ ЗначениеЗаполнено(ДатаДокумента) Тогда
		ДатаДокумента = ТекущаяДатаСеанса();
	КонецЕсли;
	
	Если ВидНалога = Перечисления.ВидыНалогов.ЕНВД Тогда
		Возврат Перечисления.ТипыСистемНалогообложенияККТ.ЕНВД;
	ИначеЕсли ВидНалога = Перечисления.ВидыНалогов.ЕСХН Тогда
		Возврат Перечисления.ТипыСистемНалогообложенияККТ.ЕСН;
	ИначеЕсли ВидНалога = Перечисления.ВидыНалогов.ПСН Тогда
		Возврат Перечисления.ТипыСистемНалогообложенияККТ.Патент;
	КонецЕсли;
	
	Запрос = Новый Запрос;
	Запрос.Текст = "ВЫБРАТЬ
	|	СистемыНалогообложенияОрганизацийСрезПоследних.СистемаНалогообложения,
	|	СистемыНалогообложенияОрганизацийСрезПоследних.ОбъектНалогообложения
	|ИЗ
	|	РегистрСведений.СистемыНалогообложенияОрганизаций.СрезПоследних(&ДатаДокумента, Организация = &Организация) КАК СистемыНалогообложенияОрганизацийСрезПоследних";
	
	Запрос.УстановитьПараметр("ДатаДокумента", ДатаДокумента);
	Запрос.УстановитьПараметр("Организация"  , Организация);
	Результат = Запрос.Выполнить();
	Выборка = Результат.Выбрать();	
	Если Выборка.Следующий() Тогда		
		Если Выборка.СистемаНалогообложения = Перечисления.СистемыНалогообложения.Общая Тогда			
			Возврат Перечисления.ТипыСистемНалогообложенияККТ.ОСН;
		ИначеЕсли Выборка.ОбъектНалогообложения = Перечисления.ОбъектыНалогообложенияПоУСН.Доходы Тогда
			Возврат Перечисления.ТипыСистемНалогообложенияККТ.УСНДоход;
		Иначе			
			Возврат Перечисления.ТипыСистемНалогообложенияККТ.УСНДоходРасход
		КонецЕсли;
	Иначе
		Возврат Перечисления.ТипыСистемНалогообложенияККТ.ОСН;
	КонецЕсли;
	
	
КонецФункции

И что мы тут видим? Определение СН идет по выборке из регистра РегистрСведений.СистемыНалогообложенияОрганизаций. Четко видим что ЕНВД присутствует. Идём в форму заполнения этого регистра и видим:

Что за хрень ерунда? Видишь суслика? Нет. А он есть. 1С ники писали-писали, но что-то не дописали. Теоретически по моему предположению, в функции выше должна быть проверка не только СН у организации, но и по складу. Но они её засунули в другую обработку — при сборке позиций товара. И там эта «ЕНВД» в чеке уже никак не участвует. Точнее участвет, но не понятно как. Есть вероятность, что я конечно какую-то галочку очередную не нашел. А может и ошибка 1С. Может в следующих релизах поправят. А пока добавил «костыль»:

Если Выборка.Следующий() Тогда
		// грибов. Костыль чтоб печатался чек ЕНВД
		Если Выборка.СистемаНалогообложения = Перечисления.СистемыНалогообложения.Общая Тогда
			Возврат Перечисления.ТипыСистемНалогообложенияККТ.ЕНВД;
			//Возврат Перечисления.ТипыСистемНалогообложенияККТ.ОСН;
		ИначеЕсли Выборка.ОбъектНалогообложения = Перечисления.ОбъектыНалогообложенияПоУСН.Доходы Тогда
			Возврат Перечисления.ТипыСистемНалогообложенияККТ.ЕНВД;
			//Возврат Перечисления.ТипыСистемНалогообложенияККТ.УСНДоход;
		Иначе
			Возврат Перечисления.ТипыСистемНалогообложенияККТ.ЕНВД;
			//Возврат Перечисления.ТипыСистемНалогообложенияККТ.УСНДоходРасход
		КонецЕсли;
	Иначе
		Возврат Перечисления.ТипыСистемНалогообложенияККТ.ЕНВД;
		//Возврат Перечисления.ТипыСистемНалогообложенияККТ.ОСН;
	КонецЕсли;

 

Программный вызов отчета СКД с параметрами и отборами. Выгрузка в файл

Можно сделать примерно так:

таб1=новый ТабличныйДокумент();	   
	СКД=Отчеты.ОценкаВаловойПрибыли.ПолучитьМакет("ОсновнаяСхемаКомпоновкиДанных");
	
	Настройки=СКД.НастройкиПоУмолчанию;	
	ПераметрыСКД=Настройки.ПараметрыДанных.Элементы;	
	прскд=ПераметрыСКД.Найти("Период");	
		пер=Новый СтандартныйПериод;
		пер.ДатаНачала=НачалоМесяца(ТекущаяДата());
		пер.ДатаОкончания=КонецДня(ТекущаяДата());
	прскд=пер;
			ЭлементОтбора=Настройки.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
				ЭлементОтбора.ВидСравнения=ВидСравненияКомпоновкиДанных.Равно;
				ЭлементОтбора.ЛевоеЗначение=Новый ПолеКомпоновкиДанных("Магазин");//поле отбора
				ЭлементОтбора.ПравоеЗначение=Справочники.Магазины.НайтиПоНаименованию("Вологда Торговля");
				ЭлементОтбора.Использование=Истина;
				ЭлементОтбора.ИдентификаторПользовательскойНастройки=Новый УникальныйИдентификатор();//добавляет отбор  в состав пользовательских настроек
	
	
	 	Расшифровка = Новый ДанныеРасшифровкиКомпоновкиДанных;
		КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;    
		
	    //Передаем в макет компоновки схему, настройки и данные расшифровки
	    МакетКомпоновки = КомпоновщикМакета.Выполнить(СКД, Настройки, Расшифровка);    
	    ВнешниеПараметры = Новый Структура;    		
		
	    //Выполним компоновку с помощью процессора компоновки
	    ПроцессорКомпоновкиДанных = Новый ПроцессорКомпоновкиДанных;
	    ПроцессорКомпоновкиДанных.Инициализировать(МакетКомпоновки, ВнешниеПараметры, Расшифровка);    
		
	    //Выводим результат в табличный документ
	    ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
	    ПроцессорВывода.УстановитьДокумент(таб1);    
	    ПроцессорВывода.Вывести(ПроцессорКомпоновкиДанных, Истина);    	 
		
		таб1.Записать("c:\temp\выловая_прибыль.xls",ТипФайлаТабличногоДокумента.XLS);

Полезные функции для работы с IP адресами

Собрал в кучку полезные функции для работы с IP адресами, которые наиболее часто использую.

/**
 * Конвертируем ip/mask в диапазон IP
 * 127.0.0.1/24 -> массив [0] 127.0.0.1 [1] 127.0.255.255
 * @param type $net
 * @return type
 */
function cidrconv($net) {
    $start = strtok($net,"/");
    $n = 3 - substr_count($net, ".");
    if ($n > 0)
    {
        for ($i = $n;$i > 0; $i--)
            $start .= ".0";
    }
    $bits1 = str_pad(decbin(ip2long($start)), 32, "0", STR_PAD_LEFT);
    $net = (1 << (32 - substr(strstr($net, "/"), 1))) - 1;
    $bits2 = str_pad(decbin($net), 32, "0", STR_PAD_LEFT);
    $final = "";
    for ($i = 0; $i < 32; $i++)
    {
        if ($bits1[$i] == $bits2[$i]) $final .= $bits1[$i];
        if ($bits1[$i] == 1 and $bits2[$i] == 0) $final .= $bits1[$i];
        if ($bits1[$i] == 0 and $bits2[$i] == 1) $final .= $bits2[$i];
    }
    return array($start, long2ip(bindec($final)));
}
/**
 * Возвращает маску из IP вида 255.255.255.0 -> 24
 * @param type $ip
 * @return type
 */
function ip2mask($ip){
    $res=false;
    $intip=ip2long($ip);    
    if ($intip>0){
	$binstr=decbin($intip);	
	$res=  strpos($binstr,"0");		
    };
    return $res;
};

/**
 * Попадает ли ip в заданный диапазон 
 * true - да, false - нет
 * Например: (10.0.1.3,10.0.0.0/8) -> true
 * @param type $ip
 * @param type $mask
 */
function ip_in_range($ip,$mask){
  $res=false;
  $ipd=cidrconv($mask);     
  $ip=ip2long($ip);  
  $start=ip2long($ipd[0]);  
  $end=ip2long($ipd[1]);  
  if (($ip>=$start) and ($ip<=$end)){$res=true;};
  return $res;
};

/**
 * Возвращает true если IP  белый, false если серый
 * @param type $ip
 */
function WhiteIP($ip){
    $res=true;
    if (ip_in_range($ip,"10.0.0.0/8")==true){$res=false;};
    if (ip_in_range($ip,"172.16.0.0/12")==true){$res=false;};
    if (ip_in_range($ip,"192.168.0.0/16")==true){$res=false;};
    return $res;
};

Пример использования:

var_dump(cidrconv("10.0.0.0/8"));
var_dump(ip2mask("255.255.255.0"));
var_dump(ip_in_range("10.20.30.40","10.0.0.0/8"));
var_dump(WhiteIP("172.16.40.11"));
var_dump(WhiteIP("176.192.40.11"));

Результат:

array(2) {
  [0]=>
  string(8) "10.0.0.0"
  [1]=>
  string(14) "10.255.255.255"
}
int(24)
bool(true)
bool(false)
bool(true)

 

Автоматическое определение пути интерпретатора в скриптах Linux

Если не известно под какой версией дистрибутива запускается тот или иной скрипт, то можно воспользоваться утилитой env для поиска пути. В этом случае заголовок скрипта будет примерно такой:

#!/usr/bin/env php
<?php
 echo "Hello!";
?>