<?xml version="1.0" encoding="windows-1251"?>
<registry>
	<node path="%root%\Объекты\Контроллеры\РеестрПоправок\ПоправкиКЗакону">
		<value type="7" name="ПрименитьЗаявки">//Макрос для применения поправок к данным заданного слоя
//Параметры: 
//      Слой: ILayer            - открытый слой с данными, к которым нужно применить поправки. 
//                                Необязательный: если не указан, то создается внутри макроса
//      Слой.Алиас: строка      - алиас слоя данных. Нужен, если параметр "Слой" не указан, чтобы
//                                создать слой и открыть данные. Необязательный.
//      Документ.ИД: целое      - ИД документа, поправки к которому нужно применить. Обязательный.
//
//      Поправка.ИД: целое      - ИД поправки, которую нужно в любом случае применить (независимо от состояния). Необязательный.
//
//      Поправки.Список: строка - дополнительное ограничение, позволяющее применить только указанный перечень поправок.
//                                Список содержит перечисление ИД необходимых поправок через запятую. Поправки применяются
//                                независимо от их принятия.                                        


включить "\библиотеки\libru.lib";
включить "\библиотеки\Layers.lib";
включить "\библиотеки\Reports.lib";
включить "\библиотеки\Base.lib";
включить "\библиотеки\Ops.lib";
включить "\Макросы\Слои\ПоддержкаСлойницы.abl";
включить "\Макросы\Слои\ВспомогательныеФункции.abl";
включить "\Макросы\Слои\ПоддержкаОпераций.abl";
включить "\Библиотеки\SharedParams.lib";
включить "\Макросы\Слои\ПоддержкаДинамическихПараметров.abl";
включить '\Библиотеки\Documents.lib';

ПрименитьЗаявки(Параметры: IVariables);

константы
  алиасПоправка           = "РеестрПоправок.ПоправкиКЗакону.Поправки";
  алиасЗаявки             = "РеестрПоправок.ПоправкиКЗакону.Заявки";  
  алиасНаполнениеПоправки = "РеестрПоправок.ПоправкиКЗакону.Операции";
  алиасДокументы          = "Закон.Данные.ПроектыЗаконов";
  кАлиас_Документы        = "Платформа.Состояния.СостоянияДокументов";  

функция ПолучитьЗначениеПараметраЧек2(Таб, Таб2: строка): целое;
переменные
  ОбщиеПараметры : ISharedParams;
  Параметр: ISPParam;
начало
  результат := нет;
  попытка
    ОбщиеПараметры := SharedParams;
    Параметр := ОбщиеПараметры.Param(Таб);
    результат := Параметр.Collection.Param(Таб2).Checked;
  неудача
  конец;      
конец;  

функция ПолучитьСостоянияЗаявок: ILayer;
переменные
  Парам: IVariables;
  Замена: ILayer;
  ДанныеЗамены: СтатическиеДанные;
  СхемаСостЗаявок: Строка;
начало
  Парам:= CreateVariables;
  результат := ПолучитьМенеджерСлоев.CreateLayerByAlias(кАлиас_Документы);

  Замена := ПолучитьМенеджерСлоев.CreateLayerByAlias('Платформа.ДескрипторыБлоков.ЗаменыКомпонентов');
  Замена.Open;
  ДанныеЗамены := Замена.LayerData;
  если ДанныеЗамены.Locate('ИмяЗамещаемого','РеестрПоправок.ПоправкиКЗакону.СхемаСостоянийЗаявок',0) тогда
    СхемаСостЗаявок := ДанныеЗамены.ПолеПоИмени('ИмяЗамещающего').КакСтрока
  иначе
    СхемаСостЗаявок := 'РеестрПоправок.ПоправкиКЗакону.СхемаСостоянийЗаявок';    
  Парам.Значение('$layer.НазваниеСхемы'):= СхемаСостЗаявок;
  результат.SelectData(Парам);
конец;

//Выборка заявок из базы с ограничением по ид поправки
функция ПолучитьЗаявки(ИДПоправки: Целое; ИДЗаявок: строка; ИДОбязательнойЗаявки: строка; ИДПоправок: Строка; ПараметрыОграничений: IVariables; СтрокаИДСостояний: строка): ILayer;
переменные
  колОграничения: IVariables;  
начало
  колОграничения := CreateVariables;

  // Если не задано ограничение по дате принятия заявки,
  // то пытаемся ограничить по состоянию заявки
  Если не (СтрокаИДСостояний = "")  тогда
  начало;
    колОграничения.Values("$Layer.DocStateRef") := СтрокаИДСостояний;
    колОграничения.Values("$Layer.DocStateRef.Ограничение") := 'in';
  конец; 
 
  если ИДПоправки &lt;&gt; -1 тогда колОграничения.Values("$Layer.Поправка_ИД") := ИДПоправки;
  если ИДЗаявок &lt;&gt; "" тогда 
  начало
    колОграничения.Values("$Layer.ИД") := ИДЗаявок+","+ИДОбязательнойЗаявки;
    колОграничения.Values("$Layer.ИД.Ограничение") := "in"; 
  конец
  иначе
    Если ИДПоправок &lt;&gt; "" тогда
    начало
      Если ИДПоправки &lt;&gt; -1 тогда
        ИДПоправок := ИДПоправок + ',' + ЦелоеВСтроку(ИДПоправки);
      колОграничения.Values("$Layer.Поправка_ИД") := ИДПоправок;
      колОграничения.Values("$Layer.Поправка_ИД.Ограничение") := "in";
    конец;   
  результат := ПолучитьМенеджерСлоев.CreateLayerByAliasEx(алиасЗаявки, 1);
  Если колОграничения.Count &lt;&gt; 0 тогда
  начало
    Если ПараметрыОграничений &lt;&gt; nil тогда
      колОграничения.PumpData(ПараметрыОграничений);
    результат.SelectData(колОграничения);
  конец;  
конец; 

// Комментарий
функция ПолучитьСлойХраненияОперации(АлиасСлоя: Строка): Строка;
переменные
  ПривязкаКСлоям: Сущность;
начало
  ПривязкаКСлоям := Операционность.СписокПривязокКСлою.НайтиСущность('АлиасСлоя', АлиасСлоя);
  Если ПривязкаКСлоям &lt;&gt; nil тогда
    результат := ПривязкаКСлоям.Атрибут('СлойОписания')
  иначе
    результат := АлиасСлоя;
конец;


//Выборка операций над данными заданного слоя из заданных поправок 
функция ПолучитьНаполнениеЗаявки(ссЗаявки: СтатическиеДанные; АлиасСлоя: Строка; СостояниеЗаявок: целое): ILayer;
переменные
  колОграничения: IVariables;
  Наполнение: СтатическиеДанные;
  
начало
  колОграничения := CreateVariables;   
  колОграничения.Values("$Layer.Заявка_ИД") := ПолучитьСписокЗначенийПоля(ссЗаявки, "ИД", ',');
  колОграничения.Values("$Layer.Заявка_ИД.Ограничение") := 'in';
  колОграничения.Values("$Layer.Слой_Алиас") := ПолучитьСлойХраненияОперации(АлиасСлоя);
  колОграничения.Values("$FacialAccRights.Disable") := 1;
  если СостояниеЗаявок тогда
    колОграничения.Values("$Layer.Сотояние") := СостояниеЗаявок;   
  результат := ПолучитьМенеджерСлоев.CreateLayerByAliasEx(алиасНаполнениеПоправки, 1);
  
  // Для того, чтобы наполнение поправки сортировалось еще и по номеру поправки, добавляем поле
  Наполнение := результат.LayerData;
  Наполнение.ДобавитьЦелоеПоле("Поправка_Номер");
  
  результат.SelectData(колОграничения);
  //делаем разыменовку некоторых атрибутов по ссылке на поправку (т.к. мы выбрали данные без разыменовки для ускорения работы)  
  Наполнение.Группировать(ссЗаявки, "insert=false;default=false;keys=Заявка_ИД;Заявка_ИД=ИД;Заявка_Номер=Номер;Заявка_Приоритет=Приоритет;Поправка_Номер=Поправка_Номер");
конец; 

//Выборка данных слоя с ограничением по версии из указанной сборки
функция ПолучитьДанныеСлоя(АлиасСлоя: Строка; Сборка: Целое; ВыбратьТолькоЗаявки: Целое): ILayer;
переменные
  колОграничения: IVariables;
начало
  колОграничения := CreateVariables;
  колОграничения.Values("$Version.Сборка") := Сборка;
  результат := ПолучитьМенеджерСлоев.CreateLayerByAlias(АлиасСлоя);
  Если не ВыбратьТолькоЗаявки тогда
    результат.SelectData(колОграничения)
  иначе
    результат.OpenEmpty;
конец; 

//Получение кода сборки для заданного документа
функция ПолучитьКодСборкиДляДокумента(ИДДокумента: целое): целое;
переменные
  сДокумент            : ILayer;
  ссДокумент           : IStaticSet;
  колОграничения: IVariables;
начало
  колОграничения := CreateVariables;
  колОграничения.Values("$Layer.ИД") := ИДДокумента;
  сДокумент := ПолучитьМенеджерСлоев.CreateLayerByAliasEx(алиасДокументы, 1);
  сДокумент.SelectData(колОграничения);
  ссДокумент := сДокумент.LayerData;
  если ссДокумент.ЧислоЗаписей = 0 тогда 
    ВызватьОшибку("Документ не найден: ИД="+ЦелоеВСтроку(ИДДокумента));
  результат := ссДокумент.ПолеПоИмени("Сборка_Код").КакЦелое;  
конец;

//Получение кода сборки для заданного документа
функция ПолучитьИДДокументаДляПоправки(ИДПоправки: целое): целое;
переменные
  сДокумент            : ILayer;
  ссДокумент           : IStaticSet;
  колОграничения: IVariables;
начало
  колОграничения := CreateVariables;
  колОграничения.Values("$Layer.ИД") := ИДПоправки;
  сДокумент := ПолучитьМенеджерСлоев.CreateLayerByAliasEx(алиасПоправка, 1);
  сДокумент.SelectData(колОграничения);
  ссДокумент := сДокумент.LayerData;
  если ссДокумент.ЧислоЗаписей = 0 тогда 
    ВызватьОшибку("Документ не найден: ИД="+ЦелоеВСтроку(ИДПоправки));
  результат := ссДокумент.ПолеПоИмени("Проект_ИД").КакЦелое;  
конец;


функция ПеренестиДанныеПоПредыдущейПоправкеВБуфер(ссДанные, Буфер: СтатическиеДанные; ПредПоправка: строка; Слой: ILayer);
начало
  если Слой.IsCalculatedLayer тогда
  начало
    //Когда поправки применяются к вычислимым слоям, тогда в данных уже будут присутствовать данные различных поправок. 
    //Поэтому применять придется очень хитро: на каждом шаге удалять из исходных данных предыдущую версию данных  
    если ПредПоправка = "null" тогда  
      УстановитьФильтр(ссДанные, "UpdateGroupIndex is null", да)
    иначе
      УстановитьФильтр(ссДанные, "(UpdateGroupIndex is null) or (UpdateGroupIndex="+ПредПоправка+")", да);
    попытка  
      //!!! закомментировано, т.к. данных исходных может не быть, а поправками +/- могут добавляться записи
          //если ссДанные.ЧислоЗаписей = 0 тогда
      //  ВызватьОшибку("Ошибка в алгоритме применения поправок: для вычислимого слоя "+Слой.Description.Params("Alias")+" не получены данные источников по поправке "+ПредПоправка);  
      Буфер.Группировать(ссДанные, "keys=*;UpdateGroupIndex="+ПредПоправка);
      если ПредПоправка &lt;&gt; "null" тогда  
        УстановитьФильтр(ссДанные, "UpdateGroupIndex="+ПредПоправка, да);             
      ссДанные.Очистить;
    обязательно     
      УстановитьФильтр(ссДанные, "", нет);
    конец;  
  конец
  иначе
    Буфер.Группировать(ссДанные, "keys=*;UpdateGroupIndex="+ПредПоправка);  
конец;

// Преобразуем дату из формата 01.01.2010 в 20100101
функция ПреобразоватьДату(Дт: строка):строка;
начало
  результат := подстрока(дт,1,2);
  результат := подстрока(дт,4,2) + результат;
  результат := подстрока(дт,7,4) + результат;    
конец;


переменные
  ПолеТипОперации,ПолеИД: Поле;

//переменные
  сЗаявки              : ILayer;
  ссЗаявки             : IStaticSet;
  сНаполнениеЗаявки    : ILayer;
  сСлойДанных          : ILayer;
  ссДанные             : IStaticSet;
  ссНаполнениеЗаявки   : IStaticSet;
  АлиасСлоя            : Строка;
  ИДЗаявок             : Строка;
  ИДОбязательнойЗаявки : строка; 
  ИДПоправки           : Целое;
  ИДДокумента          : целое;
  КодСборки            : целое;
  ОперацииКВыполнению  : строка;  
  ТипОп                : Сущность;
  П                    : IVariables; 
  КонецГруппы          : целое;
  ПредТип              : целое;

  // По-умолчанию выбираем все, кроме отклоненных, так что всегда 0
  СостояниеЗаявок: целое;

  УбратьУдаленныеЗаписи: целое;
  СтарыйФильтр         : строка;
  ВыбратьТолькоЗаявки  : Целое;
  ИДПоправок           : Строка;

  // Параметры по заявкам
  ПоДатеПринятия: Целое;
  ДатаНачала, ДатаКонца, ИДСостояний: Строка;    
начало
//  если не Параметры.CheckParam("Документ.ИД") тогда
//    Выход;
  Если Параметры.CheckParam('ВыбратьТолькоЗаявки') тогда
   ВыбратьТолькоЗаявки := Параметры.Значение('ВыбратьТолькоЗаявки')    
  иначе
    ВыбратьТолькоЗаявки := нет;
  
  ИДПоправки := -1;
  // получаем ИД поправки
  Если Параметры.CheckParam("Поправка.ИД") тогда
    ИДПоправки := Параметры.Values("Поправка.ИД");
  Если Параметры.CheckParam("Заявка.ИД") тогда
    ИДОбязательнойЗаявки := Параметры.Values("Заявка.ИД")
  иначе
    ИДОбязательнойЗаявки := '';    
  ИДЗаявок := "";
  //Определяем сборку (либо по ИД документа, либо из параметров)
  Если Параметры.CheckParam("Документ.ИД") тогда
  начало
    //Определяем ИД документа  
    ИДДокумента := Параметры.Values("Документ.ИД");
    // получаем код сборки  
    КодСборки := ПолучитьКодСборкиДляДокумента(ИДДокумента);
  конец
  иначе
  начало
    // получаем Ид документа по ид поправки
    ИДДокумента := ПолучитьИДДокументаДляПоправки(ИДПоправки);
    // получаем код сборки  
    КодСборки := ПолучитьКодСборкиДляДокумента(ИДДокумента);
  конец;
    
  //получаем данные исходного слоя
  //если они не пришли в параметрах, то создаем этот слой и открываем его
  если Параметры.CheckParam("Слой") тогда
  начало
    сСлойДанных := Параметры.Values("Слой");
    АлиасСлоя := сСлойДанных.Description.Params("Alias");
  конец  
  иначе
  начало  
    //Слой не задан, значит должен быть задан алиас слоя
    если Параметры.CheckParam("Слой.Алиас") тогда
      АлиасСлоя := Параметры.Values("Слой.Алиас")
    иначе
      ВызватьОшибку("Не указан слой с исходными данными для применения поправок");  
    // если задан параметр Выбрать только заявки, то открываем пустой слой    
    сСлойДанных := ПолучитьДанныеСлоя(АлиасСлоя, КодСборки, ВыбратьТолькоЗаявки);
    Параметры.Значение('Слой') := сСлойДанных;
  конец;              
  ссДанные := сСлойДанных.LayerData;
         
  //Считываем параметр ограничения поправок по ИД
  если Параметры.CheckParam("Заявки.Список") тогда
    ИДЗаявок := Параметры.Values("Заявки.Список");
    
  Если Параметры.CheckParam("Поправки.Список") тогда
    ИДПоправок := Параметры.Values("Поправки.Список");
                        

  // Получаем параметр по состояниям заявок
  ИДСостояний := Параметры.Values("Заявки.ИДСостояний");  

  //Получаем все заявки для поправки с учетом ограничений по состоянию заявок
  Если Параметры.ПараметрСуществует('ПараметрыОграниченийЗаявок') тогда
    сЗаявки := ПолучитьЗаявки(ИДПоправки, ИДЗаявок, ИДОбязательнойЗаявки, ИДПоправок, Параметры.Значение('ПараметрыОграниченийЗаявок'), ИДСостояний)
  иначе
    сЗаявки := ПолучитьЗаявки(ИДПоправки, ИДЗаявок, ИДОбязательнойЗаявки, ИДПоправок, nil, ИДСостояний);                                                  
  ссЗаявки := сЗаявки.LayerData;
  
  если ссЗаявки.ЧислоЗаписей = 0 тогда Выход;
  
 //////////////////////////////////////////////////////////////////////////////
  // Необходимо наложить фильтр на заявки, который выберет только те заявки
  // дата принятия которых входит в промежуток от "с" - "по" в параметре ограничения
  // "Документ" при установленной галочке "дата принятия заявок". Если это ограничение не задано,
  // выбираем все заявки, кроме отклоненных.
  Если Параметры.ПараметрСуществует("Заявки.ПоДатеПринятия") тогда
  начало
    ПоДатеПринятия := Параметры.Values("Заявки.ПоДатеПринятия");
    // Если установлена галочка "дата принятия заявок", то
    Если ПоДатеПринятия тогда
    начало
      ДатаНачала := Параметры.Values("Заявки.ДатаНачала");
      ДатаКонца := Параметры.Values("Заявки.ДатаКонца");      

      // Проверим даты на пустоту и если есть пустые, то выставим по умолчанию
      Если ДатаНачала = "" тогда 
        ДатаНачала := "20100101"
      иначе
        ДатаНачала := ПреобразоватьДату(ДатаНачала);
      Если ДатаКонца = "" тогда ДатаКонца := ДатаВСтроку(ПолучитьТекущуюДату);
      ДатаКонца := ПреобразоватьДату(ДатаКонца);    
    
      если ИДОбязательнойЗаявки &lt;&gt; '' тогда
        ссЗаявки.Фильтр :="((AcceptDate between " + ДатаНачала + " and " + ДатаКонца + ")) or (ИД = "+ИДОбязательнойЗаявки+")" 
      иначе
        ссЗаявки.Фильтр := "(AcceptDate between " + ДатаНачала + " and " + ДатаКонца + ")";            
    конец
    иначе
    начало                          
      // Ограничение по-умолчанию: выбираем все заявки, кроме отклоненных, если не задано состояние  
      если ИДОбязательнойЗаявки = "" тогда
        ссЗаявки.Фильтр := "(RejectDate is null)"
      иначе
        ссЗаявки.Фильтр := "(RejectDate is null) or (ИД = "+ИДОбязательнойЗаявки+")";
      СостояниеЗаявок := нет;           
    конец;
  конец
  иначе
  начало
    если ИДОбязательнойЗаявки = "" тогда
    начало
      если ИДЗаявок="" тогда
        СостояниеЗаявок := 1
      иначе
        СостояниеЗаявок := 0;
    конец
    иначе
    начало
      ссЗаявки.Фильтр := "((AcceptDate is not null) and (RejectDate is null)) or (ИД = "+ИДОбязательнойЗаявки+")";
      СостояниеЗаявок := нет;
    конец;    
  конец;
  если Параметры.ПараметрСуществует("Заявки.Сотояние") тогда
    СостояниеЗаявок := Параметры.Значение("Заявки.Сотояние");
  
//////////////////////////////////////////////////////////////////////////////  
 

  Если ссЗаявки.ЧислоЗаписей = 0 тогда
    выход;  
  //теперь выбираем наполнение этих поправок применительно к исходному слою
  сНаполнениеЗаявки := ПолучитьНаполнениеЗаявки(ссЗаявки, АлиасСлоя, СостояниеЗаявок);    
  ссНаполнениеЗаявки := сНаполнениеЗаявки.LayerData;  
  
  //сортируем по порядку применения операций
  ссНаполнениеЗаявки.IndexFieldNames := "Поправка_Номер;Заявка_Приоритет;Заявка_Номер;НомерОперации";
  ссЗаявки.IndexFieldNames := "Приоритет;Номер";

  УбратьУдаленныеЗаписи := нет;
  ссНаполнениеЗаявки.ВНачало;
  ПолеТипОперации := ссНаполнениеЗаявки.Поле("ТипОперации");
  ПолеИД := ссНаполнениеЗаявки.Поле("ИД"); 
  // отключим событие ибо оно тормозит работу многих операций
  сСлойДанных.DisableEvents('ВыборЗаписиИзСправочника');
  попытка 
    пока не ссНаполнениеЗаявки.ВКонце делать
    начало
      ТипОп := Операционность.СписокТиповОпераций.НайтиСущность("Код", МассивИз(ПолеТипОперации.КакЦелое));
      если ТипОп = nil тогда
        ВызватьОшибку(Формат("Не найдено описание типа операции: ТипОперации=%d", ПолеТипОперации.какЦелое));
      
      // Пропускаем информационные операции
      если не ТипОп.Атрибут("ИнформационнаяОперация") тогда
      начало
        // в наполнении поправки выделяет группу операций, которые можно выполнить за раз 
        // (инкрементные одного типа, идущие подряд)
        // после этого курсор ссНаполнениеПоправки находится на следующей операции
        если ТипОп.Атрибут("Инкрементность") тогда
        начало
          КонецГруппы := нет;
          ПредТип := ПолеТипОперации.какЦелое;
          ОперацииКВыполнению := ПолеИД.КакСтрока;
          пока не ссНаполнениеЗаявки.ВКонце и не КонецГруппы делать
          начало 
            ссНаполнениеЗаявки.Следующая;
            если не ссНаполнениеЗаявки.ВКонце тогда
            начало
              КонецГруппы := ПолеТипОперации.КакЦелое &lt;&gt; ПредТип; 
              если не КонецГруппы тогда
                ОперацииКВыполнению := ОперацииКВыполнению+","+ПолеИД.КакСтрока;
            конец;    
          конец;
        конец
        иначе
        начало
          ОперацииКВыполнению := ПолеИД.КакСтрока;
          ссНаполнениеЗаявки.Следующая;
        конец;
        
        //Изменения к тексту закона: могут быть удаленные записи
        если ТипОп.Атрибут("Код") = 3 тогда  
          УбратьУдаленныеЗаписи := да;
          
        П := CreateVariables;
        П.Values("Операция.ИсходныеДанные") := сСлойДанных; 
        П.Values("Операция.ИД") := ОперацииКВыполнению;
        П.Values("Операция.ТипОперации") := ТипОп;
        Если параметры.ПараметрСуществует('ВыполнитьРазыменовки') тогда
          П.Values('ВыполнитьРазыменовки') := Параметры.Значение('ВыполнитьРазыменовки');
        Если параметры.ПараметрСуществует('ПараметрыОграниченийОпераций') тогда
          П.Values('ПараметрыОграниченийОпераций') := целое(Параметры.Значение('ПараметрыОграниченийОпераций'));
        ВызватьКонтроллер(ТипОп.Атрибут("Обработчик"), П);
        
        Если параметры.ПараметрСуществует('ПараметрыОграниченийОпераций') тогда
          П.Values('ПараметрыОграниченийОпераций') := nil;
      конец;    
    конец;
  обязательно
    сСлойДанных.EnableEvents('ВыборЗаписиИзСправочника');          
  конец;
  если УбратьУдаленныеЗаписи тогда
  начало
    СтарыйФильтр := ссДанные.Фильтр;
    ссДанные.Фильтр := "UpdateStatus = 3";
    ссДанные.Очистить;
    ссДанные.Фильтр := СтарыйФильтр;
  конец;  
конец.
</value>
		<param value="ПрименитьЗаявки" type="1" name="AccessCount">9443</param>
		<param value="ПрименитьЗаявки" type="2" name="AccessDate">41869.7416813657</param>
		<param value="ПрименитьЗаявки" type="3" name="installversion">1.0</param>
		<param value="ПрименитьЗаявки" type="3" name="Export">SKVORTSOVV\skvortsov\18.08.2014 17:48:18</param>
	</node>
</registry>
