Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections.Generic;
- using System.Data.Objects;
- using System.Data;
- using System.Data.EntityClient;
- using System.Linq;
- using System.IO;
- using GUTFIRK.Utils;
- using GUTFIRK.ForestManagement.Domain;
- using GUTFIRK.ForestManagement.Domain.ModelEntities;
- using GUTFIRK.ForestManagement.Domain.ReportServiceInterface;
- using GUTFIRK.ForestManagement.Domain.ReportServiceInterface.ReportsDescriptions.ForestFund;
- using GUTFIRK.ForestManagement.Domain.ReportServiceInterface.ReportsParams;
- using GUTFIRK.Utils.TemplateSystem;
- namespace GUTFIRK.ForestManagement.ReportService.ReportsCreators
- {
- /// <summary>
- /// Класс, формирующий отчет "Форма №2" по инструкциям ГУЛФ 1997 года.
- /// </summary>
- public sealed class Form2_ReportCreator : SelectOptionsAdapter
- {
- #region Скрытые поля
- // Количество граф в форме №2
- // Графы №№16 - 17 оставляем незаполненными.
- const int COLUMN_COUNT = 15;
- ForestResourcesReportParams _reportParams = null;
- static object _lockObject = new object();
- List<Form1Row> _form1RowList = new List<Form1Row>();
- List<Form2Row> _form2RowList = new List<Form2Row>();
- List<short> _distinctCuttingAgesList = new List<short>();
- List<short> _distinctStocksList = new List<short>();
- List<short> _distinctNormativeDataList = new List<short>();
- // Массив для хранения результатов расчета
- // Индекс 0 - код набора НСИ.
- // Индекс 1 - графа (столбец) формы №2
- // Индекс 2 - номер строки формы №1 (лист формы №2)
- // Индекс 3 - код породы
- // Индекс 4 - возраст рубки
- double[, , , ,] _array = null;
- #endregion
- /// <summary>
- /// Конструктор.
- /// </summary>
- public Form2_ReportCreator()
- {
- _description = new Form2_ReportDescription();
- }
- /// <summary>
- /// Распределяет значения площади и запасов по временному массиву.
- /// Новые значения суммируются со значениями элементов массива.
- /// </summary>
- /// <param name="ageDataItem">Возрастная характеристика главной породы.</param>
- /// <param name="area">Площадь, га.</param>
- /// <param name="volume">Запас, кбм.</param>
- /// <param name="form1Row">Строка формы учета №1</param>
- /// <param name="nsi_index">Индекс кода НСИ</param>
- private void DistributeValues(vw_QuarterAgeDataItem ageDataItem, double area, double volume, Form1Row form1Row, int nsi_index)
- {
- // Если строка формы учета №1 является "эксплуатируемой",
- // то распределение значений производим только в случае, если сам подвыдел является эксплуатируемым.
- //if (ageDataItem.IsExploitable == false && form1Row.IsExploitable)
- // return;
- double p = 0.0;
- int form1Row_index = _form1RowList.IndexOf(form1Row);
- int stock_index = _distinctStocksList.IndexOf(ageDataItem.MainStock_OID.Value);
- // достаем ноль из запасников в случае необходимости (если нет соответствия в CuttingAges)
- int cuttingAge_index = ageDataItem.CuttingAge.HasValue ? _distinctCuttingAgesList.IndexOf(ageDataItem.CuttingAge.Value) : _distinctCuttingAgesList.IndexOf(0);
- #region Распределение по графам
- for (int i = 0; i < COLUMN_COUNT; i++)
- {
- // FIXME (при добавлении расчета граф №№16 - 17)
- p = i <= 7 ? area : volume;
- try
- {
- #region switch
- switch (i)
- {
- // Всего
- case 0: // Area
- case 8: // Volume
- _array[nsi_index, i, form1Row_index, stock_index, cuttingAge_index] += p;
- break;
- // Молодняки первого класса возраста
- case 1: // Area
- case 9: // Volume
- if (ageDataItem.AgeGroup_OID == 1 && ageDataItem.AgeClass == 1)
- _array[nsi_index, i, form1Row_index, stock_index, cuttingAge_index] += p;
- break;
- // Молодняки второго класса возраста
- case 2: // Area
- case 10: // Volume
- if (ageDataItem.AgeGroup_OID == 1 && ageDataItem.AgeClass == 2)
- _array[nsi_index, i, form1Row_index, stock_index, cuttingAge_index] += p;
- break;
- // Средневозрастные
- case 3: // Area
- case 11: // Volume
- if (ageDataItem.AgeGroup_OID == 2)
- _array[nsi_index, i, form1Row_index, stock_index, cuttingAge_index] += p;
- break;
- // Средневозрастные, включенные в расчет
- case 4: // Area
- if (ageDataItem.AgeGroup_OID == 2 && ageDataItem.InCalc == true)
- _array[nsi_index, i, form1Row_index, stock_index, cuttingAge_index] += p;
- break;
- // Приспевающие
- case 5: // Area
- case 12: // Volume
- if (ageDataItem.AgeGroup_OID == 3)
- _array[nsi_index, i, form1Row_index, stock_index, cuttingAge_index] += p;
- break;
- // Спелые и перестойные
- case 6: // Area
- case 13: // Volume
- if (ageDataItem.AgeGroup_OID == 4 || ageDataItem.AgeGroup_OID == 5)
- _array[nsi_index, i, form1Row_index, stock_index, cuttingAge_index] += p;
- break;
- // Перестойные
- case 7: // Area
- case 14: // Volume
- if (ageDataItem.AgeGroup_OID == 5)
- _array[nsi_index, i, form1Row_index, stock_index, cuttingAge_index] += p;
- break;
- }
- #endregion
- }
- catch (IndexOutOfRangeException ex)
- {
- #if DEBUG
- Program.LogSystem.Error("DistributeValues error", ex);
- #endif
- throw;
- }
- }
- #endregion
- }
- private double GetSum(int nsi_index, int column_index, int form1Row_index)
- {
- double result = 0.0;
- for (int j = 0; j < _distinctStocksList.Count; j++)
- for (int k = 0; k < _distinctCuttingAgesList.Count; k++)
- result += _array[nsi_index, column_index, form1Row_index, j, k];
- return result;
- }
- private double GetSum(int column_index, int form1Row_index)
- {
- double result = 0.0;
- for (int i = 0; i < _distinctNormativeDataList.Count; i++)
- for (int j = 0; j < _distinctStocksList.Count; j++)
- for (int k = 0; k < _distinctCuttingAgesList.Count; k++)
- result += _array[i, column_index, form1Row_index, j, k];
- return result;
- }
- private double GetSum2(int column_index, int form1Row_index, int age_index, List<short> stocksList)
- {
- double result = 0.0;
- if (age_index >= 0)
- {
- for (int i = 0; i < _distinctNormativeDataList.Count; i++)
- for (int j = 0; j < _distinctStocksList.Count; j++)
- if (stocksList.Contains(_distinctStocksList[j]))
- result += _array[i, column_index, form1Row_index, j, age_index];
- }
- else
- {
- for (int i = 0; i < _distinctNormativeDataList.Count; i++)
- for (int j = 0; j < _distinctStocksList.Count; j++)
- {
- if (stocksList.Contains(_distinctStocksList[j]) == false)
- continue;
- for (int k = 0; k < _distinctCuttingAgesList.Count; k++)
- result += _array[i, column_index, form1Row_index, j, k];
- }
- }
- return result;
- }
- private List<short> GetCuttingAges(int form1row_index, int stock_index)
- {
- List<short> list = new List<short>();
- for (int nsi_index = 0; nsi_index < _distinctNormativeDataList.Count; nsi_index++)
- {
- for (int age_index = 0; age_index < _distinctCuttingAgesList.Count; age_index++)
- {
- if (_array[nsi_index, 0, form1row_index, stock_index, age_index] > 0 && list.Contains(_distinctCuttingAgesList[age_index]) == false)
- list.Add(_distinctCuttingAgesList[age_index]);
- }
- }
- list.Sort();
- return list;
- }
- /// <summary>
- /// В ходе выполнения этого метода инициируются и заполняются скрытые поля класса
- /// </summary>
- /// <param name="reportParams"></param>
- /// <param name="progressCallback"></param>
- public override object DoCalculations(IReportParams reportParams, Procedure<int> progressCallback)
- {
- CheckParams(reportParams);
- #region Переменные
- _reportParams = (ForestResourcesReportParams)reportParams;
- //_reportParams.Identifiers.Sort();
- var year = (short)_reportParams.SelectOptions.YearOfActualization;
- // Переменные для вызова callback-метода, отвечающего за вывод прогресса.
- int progress_counter = 0; // счетчик
- double progress_q = 0.0; // множитель
- // Список ассоциаций НСИ за указанный год.
- List<NormativeAssociation> na_list = null;
- // По этому справочнику будут определены подчиненные строки формы учета №1
- List<Form1Rows_CalculationOrder> calc_list1 = null;
- // По этому справочнику будут определены подчиненные строки формы учета №2
- List<Form2Rows_CalculationOrder> calc_list2 = null;
- // в списоке calcOrder_list1 порядок обработки подчиненных строк формы учета №1
- List<byte> calcOrder_list1 = new List<byte>();
- // в списоке calcOrder_list2 порядок обработки подчиненных строк формы учета №2
- List<byte> calcOrder_list2 = new List<byte>();
- // Здесь - соответствия между категориями защитности и строками формы №1
- IEnumerable<Form1Rows_To_ProtectionCategories> form1Rows_categoriesList = new List<Form1Rows_To_ProtectionCategories>();
- // Здесь - соответствия между породами и строками формы №2
- IEnumerable<Form2Rows_To_Stocks> form2Rows_stocksList = new List<Form2Rows_To_Stocks>();
- // В этот список помещаем все сущности Form1Columns с номерами граф 2 и 3, затрагиваемые наборами НСИ
- IEnumerable<Form1Columns> form1ColumnsList = new List<Form1Columns>();
- progress_counter = 0;
- progress_q = 0.0; //25.0 / reportParams.Identifiers.Count; // деление на ноль невозможно - отфильтровано в родителе BaseReport
- #endregion
- using (ModelContext context = new ModelContext())
- {
- #region Расчет
- #region Загрузка справочников
- // Инициируем скрытые поля.
- _form1RowList = context.Form1RowSet.OrderBy(a => a.PrintOrder).ToList();
- _form2RowList = context.Form2RowSet.OrderBy(a => a.PrintOrder).ToList();
- _distinctCuttingAgesList.Clear();
- // в список возрастов рубок намеренно добавляем ноль
- _distinctCuttingAgesList.Add(0);
- _distinctStocksList.Clear();
- _distinctNormativeDataList.Clear();
- foreach (Form2Row form2Row in _form2RowList)
- form2Row.InitStockList();
- // Загрузив данные из БД в список один раз, будем искать в нем соответствие между кварталом и набором НСИ.
- na_list = context.NormativeAssociationSet.Where("it.Year = @year", new ObjectParameter("year", year)).Include("NormativeData").Include("Forestry").ToList();
- if (na_list.Count == 0)
- throw new ReportException(reportParams, "Список нормативных ассоциаций пуст.");
- calc_list1 = context.Form1Rows_CalculationOrderSet.Include("Form1RowA").Include("Form1RowB").ToList<Form1Rows_CalculationOrder>();
- calc_list2 = context.Form2Rows_CalculationOrderSet.Include("Form2RowA").Include("Form2RowB").ToList<Form2Rows_CalculationOrder>();
- calcOrder_list1.Clear();
- foreach (Form1Rows_CalculationOrder item in calc_list1)
- {
- if (calcOrder_list1.Contains(item.CalcOrder) == false)
- calcOrder_list1.Add(item.CalcOrder);
- }
- calcOrder_list1.Sort();
- calcOrder_list2.Clear();
- foreach (Form2Rows_CalculationOrder item in calc_list2)
- {
- if (calcOrder_list2.Contains(item.CalcOrder) == false)
- calcOrder_list2.Add(item.CalcOrder);
- }
- calcOrder_list2.Sort();
- progressCallback(5);
- #endregion
- #region Получение списка кварталов из списка выделов
- var qIDs = GetQuarterIDs(_reportParams.SelectOptions);
- var fullQuarterIds = GetFullQuarterIDs(_reportParams.SelectOptions);
- progress_q = qIDs.Count > 0 ? 85.0 / qIDs.Count : 0.0;
- #endregion
- #region Первый обход кварталов
- // При первом обходе собираем различные возрасты рубок, идентификаторы пород и форм учета №1.
- // Заполняются списки _distinctCuttingAgesList, _distinctStocksList, _distinctNormativeDataList
- progress_counter = 0;
- progress_q = 40.0 / qIDs.Count;
- foreach (var quarterID in qIDs)
- {
- #region CallBack
- progress_counter++;
- progressCallback(this.GetProgress(5, progress_counter, progress_q));
- #endregion
- var quarter = context.QuarterSet.Include("DivisionalForestry.Forestry").FirstOrDefault(x => x.OID == quarterID);
- if (quarter == null)
- continue;
- List<int> sortedIdentifiers = null;
- if (fullQuarterIds.BinarySearch(quarterID) >= 0)
- {
- quarter.Stratums.Load();
- sortedIdentifiers = quarter.Stratums.Select(x => x.OID).ToList();
- }
- else
- {
- sortedIdentifiers = GetStratumIDsFromPartialQuarter(_reportParams.SelectOptions, quarterID);
- }
- sortedIdentifiers.Sort();
- #region Загрузка НСИ
- NormativeAssociation na = na_list.Where(a => a.Forestry.OID == quarter.GetForestry().OID).FirstOrDefault();
- // Ошибка может возникнуть в случае, если лесничеству не сопоставлен набор НСИ в указанный год.
- if (na == null)
- throw new ReportException(reportParams, String.Format("Отсутствует набор НСИ для квартала (OID = {0})", quarter.OID));
- // Подгружаем данные, если встретился новый набор НСИ.
- if (_distinctNormativeDataList.Contains(na.NormativeData.OID) == false)
- {
- _distinctNormativeDataList.Add(na.NormativeData.OID);
- ObjectParameter parameter = new ObjectParameter("oid", na.NormativeData.OID);
- List<Form2Rows_To_Stocks> list1 = context.Form2Rows_To_StocksSet.Where("it.NormativeData.OID = @oid", parameter).Include("Stock").Include("Form2Row").Include("NormativeData").ToList();
- form2Rows_stocksList = form2Rows_stocksList.Concat(list1);
- List<Form1Rows_To_ProtectionCategories> list2 = context.Form1Rows_To_ProtectionCategoriesSet.Where("it.NormativeData.OID = @oid", parameter).Include("ProtectionCategory").Include("NormativeData").Include("Form1Row").ToList();
- form1Rows_categoriesList = form1Rows_categoriesList.Concat(list2);
- List<Form1Columns> list3 = context.Form1ColumnsSet.Where("it.NormativeData.OID = @oid AND (it.ColumnNumber = 2 OR it.ColumnNumber = 3)", parameter).Include("LandCategory").Include("NormativeData").ToList();
- form1ColumnsList = form1ColumnsList.Concat(list3);
- }
- #endregion
- #region Выполнение хранимой процедуры и обработка ошибок
- // Получаем возрастные характеристики на квартал.
- List<vw_QuarterAgeDataItem> vw_AgeDataResult = null;
- //lock (_lockObject)
- //{
- int counter = 0;
- bool success = false;
- //Попытка выполнить хранимые процедуры
- while (!success)
- {
- try
- {
- counter++; // Увеличиваем значение счетчика
- // Получаем возрастные характеристики на квартал.
- vw_AgeDataResult = context.GetMainStockAgeDataOnQuarter(quarter.OID, na.NormativeData.OID, na.CuttingAgeKey, year).ToList();
- success = true; // Выполнение хранимой процедуры успешно
- }
- // В случае ошибки выполнения хранимой процедуры 10 раз подряд останавливаем формирование отчета
- catch
- {
- if (counter >= 10) break;
- }
- }
- if (!success) throw new ReportException(reportParams, "Ошибка доступа к хранимой процедуре");
- //}
- #endregion
- foreach (vw_QuarterAgeDataItem item in vw_AgeDataResult)
- {
- if (sortedIdentifiers.BinarySearch(item.Stratum_OID.Value) >= 0)
- {
- //if (item.ReturnCode.HasValue && item.ReturnCode == 0)
- //{
- if (item.MainStock_OID.HasValue && _distinctStocksList.Contains(item.MainStock_OID.Value) == false)
- _distinctStocksList.Add(item.MainStock_OID.Value);
- if (item.CuttingAge.HasValue && _distinctCuttingAgesList.Contains(item.CuttingAge.Value) == false)
- _distinctCuttingAgesList.Add(item.CuttingAge.Value);
- //}
- }
- }
- }
- #endregion
- #region Инициализация временного массива
- // Инициализация временного массива
- // Вторая размерность (графа формы) распределяется следующим образом:
- // 0-7 - распределение площадей
- // 8-15 - распределение запасов
- _array = new double[_distinctNormativeDataList.Count, COLUMN_COUNT, _form1RowList.Count, _distinctStocksList.Count, _distinctCuttingAgesList.Count];
- #if DEBUG
- Program.LogSystem.DebugFormat("array init: ndl={0}, col={1}, f1r={2}, st={3}, cta={4}", _distinctNormativeDataList.Count, COLUMN_COUNT, _form1RowList.Count, _distinctStocksList.Count, _distinctCuttingAgesList.Count);
- #endif
- #endregion
- #region Второй обход кварталов
- progress_counter = 0;
- foreach (var quarterID in qIDs)
- {
- #region CallBack
- progress_counter++;
- progressCallback(this.GetProgress(45, progress_counter, progress_q));
- #endregion
- var quarter = context.QuarterSet.Include("DivisionalForestry.Forestry").FirstOrDefault(x => x.OID == quarterID);
- if (quarter == null)
- continue;
- List<int> sortedIdentifiers = null;
- if (fullQuarterIds.BinarySearch(quarterID) >= 0)
- {
- quarter.Stratums.Load();
- sortedIdentifiers = quarter.Stratums.Select(x => x.OID).ToList();
- }
- else
- {
- sortedIdentifiers = GetStratumIDsFromPartialQuarter(_reportParams.SelectOptions, quarterID);
- }
- sortedIdentifiers.Sort();
- NormativeAssociation na = na_list.Where(a => a.Forestry.OID == quarter.GetForestry().OID).FirstOrDefault();
- if (na == null)
- {
- throw new ReportException(reportParams, "Нормативная ассоциация для квартала не найдена OID = " + quarter.OID.ToString());
- }
- int nsi_index = _distinctNormativeDataList.IndexOf(na.NormativeData.OID);
- #region Выполнение хранимой процедуры и обработка ошибок
- List<vw_QuarterAgeDataItem> vw_AgeDataResult = null;
- //lock (_lockObject)
- //{
- int counter = 0;
- bool success = false;
- //Попытка выполнить хранимые процедуры
- while (!success)
- {
- try
- {
- counter++; // Увеличиваем значение счетчика
- // Получаем возрастные характеристики на квартал.
- vw_AgeDataResult = context.GetMainStockAgeDataOnQuarter(quarter.OID, na.NormativeData.OID, na.CuttingAgeKey, year).ToList();
- success = true; // Выполнение хранимой процедуры успешно
- }
- // В случае ошибки выполнения хранимой процедуры 10 раз подряд останавливаем формирование отчета
- catch
- {
- if (counter >= 10) break;
- }
- }
- if (!success) throw new ReportException(reportParams, "Ошибка доступа к хранимой процедуре");
- //}
- #endregion
- List<CommonData> commonDataList = quarter.GetCommonDataList(context, year);
- #region Обход общих характеристик
- // Заполняем список form1RowsInQuarter, чтобы определить - какие строки формы учета необходимо просчитать.
- foreach (CommonData commonData in commonDataList)
- {
- if (commonData.LandCategoryReference.IsLoaded == false)
- commonData.LandCategoryReference.Load();
- if (commonData.SubStratumReference.IsLoaded == false)
- commonData.SubStratumReference.Load();
- if (commonData.SubStratum.StratumReference.IsLoaded == false)
- commonData.SubStratum.StratumReference.Load();
- // Отсекаем подвыделы, которые не относятся к графе №2 формы учета №1
- int count = form1ColumnsList.Count(a => a.LandCategory.OID == commonData.LandCategory.OID && a.NormativeData.OID == na.NormativeData.OID);
- if (count == 0)
- continue;
- vw_QuarterAgeDataItem item = vw_AgeDataResult.First(a => a.CommonData_OID == commonData.OID);
- if (sortedIdentifiers.BinarySearch(item.Stratum_OID.Value) >= 0)
- {
- //if (item.ReturnCode.HasValue && item.ReturnCode.Value == 0)
- //{
- if (commonData.ProtectionCategoryReference.IsLoaded == false)
- commonData.ProtectionCategoryReference.Load();
- if (commonData.ProtectionCategory.ForestGroupReference.IsLoaded == false)
- commonData.ProtectionCategory.ForestGroupReference.Load();
- // Строки, соответствующие текущей категории защитности.
- IEnumerable<Form1Rows_To_ProtectionCategories> list = form1Rows_categoriesList.Where(a => a.ProtectionCategory.OID == commonData.ProtectionCategory.OID && a.NormativeData.OID == na.NormativeData.OID);
- double volume = commonData.TotalVolume.GetValueOrDefault();
- foreach (Form1Rows_To_ProtectionCategories item1 in list)
- {
- // Обработка строки формы учета №1
- this.DistributeValues(item, commonData.Area, volume, item1.Form1Row, nsi_index);
- }
- // "Эксплуатируемые" строки
- if (item.IsExploitable.HasValue && item.IsExploitable.Value == true && item.ReturnCode.HasValue && item.ReturnCode == 0)
- {
- Form1Row row = _form1RowList.First(a => a.OID == commonData.ProtectionCategory.ForestGroup.ExploitableForm1RowOID);
- if (row == null)
- throw new ReportException(reportParams, String.Format("Отсутствует строка формы учета №1 (OID = {0})", commonData.ProtectionCategory.ForestGroup.ExploitableForm1RowOID));
- // Обработка строки формы учета №1
- DistributeValues(item, commonData.Area, volume, row, nsi_index);
- }
- //}
- }
- context.Detach(commonData);
- }
- #endregion
- foreach (vw_QuarterAgeDataItem ageDataItem in vw_AgeDataResult)
- context.Detach(ageDataItem);
- context.Detach(quarter);
- }
- #endregion
- #region Расчет подчиненных строк формы учета №1
- progress_q = 5.0 / calcOrder_list1.Count;
- progress_counter = 0;
- foreach (byte calcOrder in calcOrder_list1)
- {
- #region Callback
- progress_counter++;
- progressCallback(this.GetProgress(85, progress_counter, progress_q));
- #endregion
- IEnumerable<Form1Rows_CalculationOrder> list4 = calc_list1.Where(a => a.CalcOrder == calcOrder);
- foreach (Form1Rows_CalculationOrder item in list4)
- {
- int index_dest = _form1RowList.IndexOf(item.Form1RowA);
- int index_src = _form1RowList.IndexOf(item.Form1RowB);
- for (int n = 0; n < _distinctNormativeDataList.Count; n++)
- {
- for (int i = 0; i < COLUMN_COUNT; i++)
- {
- for (int j = 0; j < _distinctStocksList.Count; j++)
- {
- for (int k = 0; k < _distinctCuttingAgesList.Count; k++)
- {
- _array[n, i, index_dest, j, k] += _array[n, i, index_src, j, k];
- }
- }
- }
- }
- }
- }
- #endregion
- #endregion
- } // ModelContext
- //reportData.Year = reportParams.Year;
- //reportData.ReportName = reportParams.Name;
- //reportData.DistinctCuttingAgesList = _distinctCuttingAgesList;
- //reportData.Form1RowsList = _form1RowsList;
- //reportData.Form2RowsList = _form2RowsList;
- //reportData.DistinctStocksList = _distinctStocksList;
- //reportData.DistinctNormativeDataList = _distinctNormativeDataList;
- //reportData.Array = _array;
- //return reportData;
- return null;
- }
- public override void CreateDocument(object obj, string formatKey, Procedure<int> progressCallback, string templateFolder, System.IO.Stream outputStream)
- {
- #region Печать
- TemplateProcessor tprocessor = new TemplateProcessor();
- //Form2_ReportData rd = (Form2_ReportData)obj;
- //templateFolder += _description.Key + "\\" + formatKey + "\\";
- DateTime creationDateTime = DateTime.Now;
- bool nbspFlag = formatKey == Program.HTML_FORMAT_KEY; //? " " : String.Empty;
- #region Параметры шаблонов
- tprocessor.Parameters.Add(new TemplateParameter2("R_PROPERTY", tprocessor.ReadFile(templateFolder + "rproperty.tpl")));
- tprocessor.Parameters.Add(new TemplateParameter2("PAGE_BREAK", tprocessor.ProcessFile(templateFolder + "pagebreak.tpl")));
- tprocessor.Parameters.Add(new TemplateParameter2("R_PROPERTY_2", tprocessor.ReadFile(templateFolder + "rproperty2.tpl")));
- tprocessor.Parameters.Add(new TemplateParameter2("R_PROPERTY_2B", tprocessor.ReadFile(templateFolder + "rproperty2b.tpl")));
- tprocessor.Parameters.Add(new TemplateParameter2("R_PROPERTY_H", tprocessor.ReadFile(templateFolder + "rproperty_h.tpl")));
- tprocessor.Parameters.Add(new TemplateParameter2("DOCUMENT_CREATION_DATETIME", String.Format("{0}-{1:D2}-{2:D2}T{3:D2}:{4:D2}:{5:D2}Z", creationDateTime.Year, creationDateTime.Month, creationDateTime.Day, creationDateTime.Hour, creationDateTime.Minute, creationDateTime.Second)));
- tprocessor.Parameters.Add(new TemplateParameter2("ACTUALIZATION_DATE", String.Format("01.01.{0}", _reportParams.SelectOptions.YearOfActualization)));
- tprocessor.Parameters.Add(new TemplateParameter2("DOCUMENT_CREATION_DATE", creationDateTime.ToShortDateString()));
- tprocessor.Parameters.Add(new TemplateParameter2("SHEET_NUMBER"));
- tprocessor.Parameters.Add(new TemplateParameter2("ROWS_CONTENT"));
- tprocessor.Parameters.Add(new TemplateParameter2("BODY_CONTENT"));
- for (int p = 1; p <= 17; p++)
- tprocessor.Parameters.Add(new NumericTemplateParameter2("VALUE_S" + p.ToString(), 0, nbspFlag, (byte)2, DecimalSeparator.Comma));
- tprocessor.Parameters.Add(new HtmlEncodedTemplateParameter2("REPORT_NAME", _reportParams.Name, nbspFlag));
- tprocessor.Parameters.Add(new HtmlEncodedTemplateParameter2("GROUP_NUMBER", String.Empty, nbspFlag));
- tprocessor.Parameters.Add(new HtmlEncodedTemplateParameter2("FORM1ROW_NAME", String.Empty, nbspFlag));
- tprocessor.Parameters.Add(new HtmlEncodedTemplateParameter2("VALUE_A", String.Empty, nbspFlag));
- tprocessor.Parameters.Add(new HtmlEncodedTemplateParameter2("VALUE_B", String.Empty, nbspFlag));
- tprocessor.Parameters.Add(new HtmlEncodedTemplateParameter2("VALUE_C", String.Empty, nbspFlag));
- #endregion
- string header_template_1 = tprocessor.ReadFile(templateFolder + "header_1.tpl");
- string header_template_2 = tprocessor.ReadFile(templateFolder + "header_2.tpl");
- string row_template_1 = tprocessor.ReadFile(templateFolder + "row_1.tpl");
- string row_template_2 = tprocessor.ReadFile(templateFolder + "row_2.tpl");
- string boldrow_template_1 = tprocessor.ReadFile(templateFolder + "boldrow_1.tpl");
- string boldrow_template_2 = tprocessor.ReadFile(templateFolder + "boldrow_2.tpl");
- Dictionary<int, string> results = new Dictionary<int, string>();
- int maxResult_id = 0, result_id = 0;
- bool outputFlag = true;
- List<short> stocksForForm2RowList = new List<short>();
- // Индексы строк формы №1, которые будут выведены на печать
- List<int> form1RowsIndexesList = new List<int>();
- for (int i = 0; i < _form1RowList.Count; i++)
- {
- if (this.GetSum(0, i) > 0.0)
- form1RowsIndexesList.Add(i);
- }
- //foreach (Form1Row form1Row in _form1RowList)
- //{
- // int form1RowIndex = rd.Form1RowsList.IndexOf(form1Row);
- // if (this.GetSum(0, form1RowIndex, rd) > 0.0)
- // form1RowsIndexesList.Add(form1RowIndex);
- //}
- // Формирование фрагментов документа производим в две итерации.
- // 1-ая итерация: распределение площадей.
- // 2-ая итерация: распределение запасов.
- for (int iteration = 1; iteration <= 2; iteration++)
- {
- int sheetNumber = 0;
- for (int index = 0; index < form1RowsIndexesList.Count; index++)
- {
- int form1RowIndex = form1RowsIndexesList[index];
- Form1Row form1Row = _form1RowList[form1RowIndex];
- // В заголовке листа выводим наименование строки формы + идентификатор группы лесов.
- tprocessor.Parameters["GROUP_NUMBER"].Value = form1Row.Form2_ForestGroupValue;
- tprocessor.Parameters["FORM1ROW_NAME"].Value = form1Row.Name;
- System.Text.StringBuilder contentBuilder = new System.Text.StringBuilder();
- sheetNumber++;
- tprocessor.Parameters["SHEET_NUMBER"].Value = sheetNumber.ToString();
- #region Перебор строк формы №2
- for (int form2RowIndex = 0; form2RowIndex < _form2RowList.Count; form2RowIndex++)
- {
- // Будем выводить в документ только те строки формы учета №2,
- // для которых есть соответствующая порода в списке _distinctStocksList.
- List<Stock> stockList = _form2RowList[form2RowIndex].GetStocks();
- stocksForForm2RowList.Clear();
- foreach (Stock stock in stockList)
- if (_distinctStocksList.Contains(stock.OID))
- stocksForForm2RowList.Add(stock.OID);
- if (stocksForForm2RowList.Count == 0)
- continue;
- #region О свойстве PrintType...
- // Все строки формы учета №2 условно делим на 4 типа (свойство PrintType)
- // 1 - "Раздел"
- // Выводится жирным шрифтом.
- // Заполняется только графа "А" с наименованием строки
- // 2 - "Строка данных"
- // Заполняются все графы. Графа "В" (возраст рубки) заполняется,
- // только если признак вывода Form2_MinCuttingAgeFlag = true
- // 3 - "Итоговая строка с последующим выводом пустой строки"
- // Заполняются все графы кроме графы "В"
- // 4 - "Итоговая строка"
- // Заполняются все графы кроме графы "В"
- #endregion
- // Вывод наименования строки в первой графе.
- tprocessor.Parameters["VALUE_A"].Value = _form2RowList[form2RowIndex].Name;
- switch (_form2RowList[form2RowIndex].PrintType)
- {
- case 1:
- tprocessor.Parameters["VALUE_B"].Value = null;
- tprocessor.Parameters["VALUE_C"].Value = null;
- if (iteration == 1)
- contentBuilder.Append(tprocessor.ProcessString(boldrow_template_1));
- else
- contentBuilder.Append(tprocessor.ProcessString(boldrow_template_2));
- break;
- case 2:
- tprocessor.Parameters["VALUE_B"].Value = _form2RowList[form2RowIndex].External_ID;
- if (form1Row.Form2_MinCuttingAgeFlag == false)
- {
- outputFlag = this.SetTemplateParameters(tprocessor, iteration, form1RowIndex, stocksForForm2RowList, -1);
- switch (iteration)
- {
- case 1:
- if (outputFlag)
- contentBuilder.Append(tprocessor.ProcessString(row_template_1));
- break;
- case 2:
- if (outputFlag)
- contentBuilder.Append(tprocessor.ProcessString(row_template_2));
- break;
- }
- }
- else
- {
- // Необходимо сгруппировать строки данных по возрастам рубки.
- // Для строк данных (PrintType = 2) при правильном заполнении справочников
- // список stocksForForm2RowList будет содержать единственный идентификатор породы.
- if (stocksForForm2RowList.Count > 0)
- {
- int stock_index = _distinctStocksList.IndexOf(stocksForForm2RowList[0]);
- List<short> cuttingAgesList = this.GetCuttingAges(form1RowIndex, stock_index);
- foreach (short age in cuttingAgesList)
- {
- this.SetTemplateParameters(tprocessor, iteration, form1RowIndex, stocksForForm2RowList, _distinctCuttingAgesList.IndexOf(age));
- if (iteration == 1)
- contentBuilder.Append(tprocessor.ProcessString(row_template_1));
- else
- contentBuilder.Append(tprocessor.ProcessString(row_template_2));
- }
- }
- }
- break;
- case 3:
- case 4:
- tprocessor.Parameters["VALUE_B"].Value = _form2RowList[form2RowIndex].External_ID;
- tprocessor.Parameters["VALUE_C"].Value = null;
- outputFlag = this.SetTemplateParameters(tprocessor, iteration, form1RowIndex, stocksForForm2RowList, -1);
- switch (iteration)
- {
- case 1:
- if (outputFlag)
- contentBuilder.Append(tprocessor.ProcessString(row_template_1));
- break;
- case 2:
- if (outputFlag)
- contentBuilder.Append(tprocessor.ProcessString(row_template_2));
- break;
- }
- break;
- }
- // Вывод пустой строки.
- if (_form2RowList[form2RowIndex].PrintType == 3)
- {
- tprocessor.Parameters["VALUE_A"].Value = null;
- tprocessor.Parameters["VALUE_B"].Value = null;
- tprocessor.Parameters["VALUE_C"].Value = null;
- for (int p = 1; p <= 15; p++)
- tprocessor.Parameters["VALUE_S" + p.ToString()].Value = null;
- if (iteration == 1)
- contentBuilder.Append(tprocessor.ProcessString(row_template_1));
- else
- contentBuilder.Append(tprocessor.ProcessString(row_template_2));
- }
- }
- #endregion
- tprocessor.Parameters["ROWS_CONTENT"].Value = contentBuilder.ToString();
- string pageContent = String.Empty;
- if (iteration == 1)
- {
- pageContent = tprocessor.ProcessString(header_template_1);
- result_id = 2 * sheetNumber - 1;
- }
- else
- {
- pageContent = tprocessor.ProcessString(header_template_2);
- result_id = 2 * sheetNumber;
- // Для всех четных страниц кроме последней в конец добавляем разрыв страницы.
- if (index + 1 != form1RowsIndexesList.Count)
- pageContent += tprocessor.Parameters["PAGE_BREAK"].Value;
- }
- results.Add(result_id, pageContent);
- if (maxResult_id < result_id)
- maxResult_id = result_id;
- }
- } // iteration
- for (int id = 1; id <= maxResult_id; id++)
- {
- tprocessor.Parameters["BODY_CONTENT"].Value += results[id];
- }
- tprocessor.ProcessFileToStream(outputStream, templateFolder + "document.tpl");
- #endregion
- }
- private int GetProgress(int progressBase, int progress_counter, double progress_q)
- {
- return progressBase + (int)(progress_q * progress_counter);
- }
- /// <summary>
- /// Выполняет установку параметров шаблонизатора (TemplateProcessor), содержащих
- /// значения строки формы №2 (графы А, Б, В, значения площадей и запасов).
- /// Возвращает TRUE, если строку нужно вывести в результирующий документ и FALSE,
- /// если вывод не требуется.
- /// </summary>
- /// <param name="templateProcessor">Шаблонизатор.</param>
- /// <param name="iteration">Номер итерации (1 или 2)</param>
- /// <param name="form1Row_index">Индекс строки формы учета №1</param>
- /// <param name="stocks">Породы, соответствующие выводимой строке формы №2</param>
- /// <param name="age_index">Индекс возраста рубки.</param>
- /// <returns></returns>
- private bool SetTemplateParameters(TemplateProcessor templateProcessor, int iteration, int form1Row_index, List<short> stocks, int age_index)
- {
- int min_index = iteration == 1 ? 0 : 8;
- int max_index = iteration == 1 ? 7 : 14; // FIXME (графы №№16-17)
- bool result = true;
- if (age_index >= 0)
- {
- if (_distinctCuttingAgesList[age_index] == 0) // выводим прочерк напротив записей, для которых нет соответствия в CuttingAges
- templateProcessor.Parameters["VALUE_C"].Value = "-";
- else
- templateProcessor.Parameters["VALUE_C"].Value = _distinctCuttingAgesList[age_index].ToString();
- }
- else
- templateProcessor.Parameters["VALUE_C"].Value = null;
- for (int columnIndex = min_index; columnIndex <= max_index; columnIndex++)
- {
- double value = this.GetSum2(columnIndex, form1Row_index, age_index, stocks);
- // Параметры не заполняются и строка не выводится,
- // если общая площадь (для первой итерации) или общий запас (для второй итерации)
- // равны нулю.
- if (columnIndex == min_index && value == 0.0)
- {
- result = false;
- break;
- }
- if (iteration == 2)
- value /= 1000; // Вывод запасов в тыс. кбм.
- string param = String.Format("VALUE_S{0}", columnIndex + 1);
- if (value > 0)
- {
- templateProcessor.Parameters[param].Value = value;
- }
- else
- {
- templateProcessor.Parameters[param].Value = null;
- }
- }
- return result;
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement