Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //#define DEBUG_LOG
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Data.Objects;
- using GUTFIRK.ForestManagement.Domain.ModelEntities;
- using GUTFIRK.ForestManagement.Domain;
- using GUTFIRK.Utils;
- 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>
- /// Класс, формирующий отчет "Форма №1" по инструкциям ГУЛФ 1997 года.
- /// </summary>
- public class Form1_ReportCreator : SelectOptionsAdapter
- {
- // Максимальное количество строк данных на одной странице
- //const int MAX_ROW_COUNT = 14;
- // Количество граф в форме + 1
- const int COLUMN_COUNT = 25;
- //object _lockObject = new object();
- ForestResourcesReportParams _reportParams = null;
- List<short> _distinctNormativeDataList = new List<short>();
- // Список строк формы учета.
- List<Form1Row> _form1RowsList = null;
- // Массив для хранения результатов расчета
- double[,] _s = null;
- // Площади горных и равнинных лесов
- double _sg1 = 0.0, _sg2 = 0.0;
- /// <summary>
- /// Конструктор.
- /// </summary>
- public Form1_ReportCreator()
- {
- _description = new Form1_ReportDescription();
- }
- /// <summary>
- /// Расчеты
- /// </summary>
- /// <param name="reportParams">Параметры отчета</param>
- /// <param name="progressCallback">Процедура, выполняющая обновление прогресса.</param>
- /// <returns>Результаты расчетов</returns>
- public override object DoCalculations(IReportParams reportParams, Procedure<int> progressCallback)
- {
- CheckParams(reportParams);
- #region Переменные
- //Form1ReportData reportData = new Form1ReportData();
- #if DEBUG_LOG
- Program.LogSystem.Info("F1_get_params");
- #endif
- _reportParams = (ForestResourcesReportParams)reportParams;
- var year = (short)_reportParams.SelectOptions.YearOfActualization;
- // Переменные для учета рельефа местности
- //double sg1 = 0.0; // горные леса
- //double sg2 = 0.0; // равнинные леса
- #if DEBUG_LOG
- Program.LogSystem.Info("F2_sort_identifiers");
- #endif
- _distinctNormativeDataList.Clear();
- // В этот список помещаем все сущности Form1Columns, затрагиваемые наборами НСИ
- IEnumerable<Form1Columns> form1ColumnsList = new List<Form1Columns>();
- // Здесь - соответствия между категориями защитности и строками формы №1
- IEnumerable<Form1Rows_To_ProtectionCategories> form1Rows_categoriesList = new List<Form1Rows_To_ProtectionCategories>();
- // Список ассоциаций НСИ за указанный год.
- List<NormativeAssociation> na_list = null;
- // По этому справочнику будут определены подчиненные строки формы учета.
- List<Form1Rows_CalculationOrder> calc_list = null;
- // в список calcOrder_list поместим различные номера действий. Отсортируем его по возрастанию номера действия.
- List<byte> calcOrder_list = new List<byte>();
- int progress_counter = 0;
- int progress = 0;
- double progress_q = 0.0;
- #endregion
- using (ModelContext context = new ModelContext())
- {
- #region Загрузка основных справочников и классификаторов
- //form1RowsList = context.Form1RowSet.Include("ExploitableForestGroup").OrderBy(a => a.PrintOrder).ToList<Form1Row>();
- #if DEBUG_LOG
- Program.LogSystem.Info("F3_load_references");
- #endif
- _form1RowsList = context.Form1RowSet.OrderBy(a => a.PrintOrder).ToList();
- //reportData.Form1RowList = form1RowsList;
- // Загрузив данные из БД в список один раз, будем искать в нем соответствие между кварталом и набором НСИ.
- na_list = context.NormativeAssociationSet.Where("it.Year = @year", new ObjectParameter("year", year)).Include("NormativeData").Include("Forestry").ToList<NormativeAssociation>();
- if (na_list.Count == 0)
- throw new ReportException(reportParams, "Список нормативных ассоциаций пуст.");
- calc_list = context.Form1Rows_CalculationOrderSet.Include("Form1RowA").Include("Form1RowB").ToList<Form1Rows_CalculationOrder>();
- calcOrder_list.Clear();
- foreach (Form1Rows_CalculationOrder item in calc_list)
- {
- if (calcOrder_list.Contains(item.CalcOrder) == false)
- calcOrder_list.Add(item.CalcOrder);
- }
- calcOrder_list.Sort();
- _s = new double[COLUMN_COUNT, _form1RowsList.Count];
- progressCallback(5);
- #endregion
- var qIDs = GetQuarterIDs(_reportParams.SelectOptions);
- var fullQuarterIds = GetFullQuarterIDs(_reportParams.SelectOptions);
- progress_q = qIDs.Count > 0 ? 85.0 / qIDs.Count : 0.0;
- foreach (int quarterID in qIDs)
- {
- #region Callback
- progress_counter++;
- progress = 5 + (int)(progress_q * progress_counter);
- progressCallback(progress);
- #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<Form1Columns> list1 = context.Form1ColumnsSet.Where("it.NormativeData.OID = @oid", parameter).Include("LandCategory").Include("NormativeData").ToList();
- form1ColumnsList = form1ColumnsList.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_To_ProtectionCategories>();
- form1Rows_categoriesList = form1Rows_categoriesList.Concat(list2);
- }
- #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
- #region Расчет строк, которые зависят только от категории защитности
- List<CommonData> commonDataList = quarter.GetCommonDataList(context, year);
- foreach (CommonData commonData in commonDataList)
- {
- vw_QuarterAgeDataItem ageDataItem = vw_AgeDataResult.First(a => a.CommonData_OID == commonData.OID);
- //if (ageDataItem.ReturnCode.HasValue && ageDataItem.ReturnCode.Value != 0)
- // continue;
- if (sortedIdentifiers.BinarySearch(ageDataItem.Stratum_OID.Value) >= 0)
- {
- //double k = forestResourcesReportParams.Identifiers.Where(x => x.Identifier == ageDataItem.Stratum_OID).Select(y => y.Area).First();
- // Учет рельефа местности.
- if (commonData.MountainFlag)
- _sg1 += commonData.Area;
- else
- _sg2 += commonData.Area;
- if (commonData.LandCategoryReference.IsLoaded == false)
- commonData.LandCategoryReference.Load();
- if (commonData.ProtectionCategoryReference.IsLoaded == false)
- commonData.ProtectionCategoryReference.Load();
- if (commonData.ProtectionCategory.ForestGroupReference.IsLoaded == false)
- commonData.ProtectionCategory.ForestGroupReference.Load();
- Form1Columns column = form1ColumnsList.First(a => a.LandCategory.OID == commonData.LandCategory.OID && a.NormativeData.OID == na.NormativeData.OID);
- if (column == null)
- throw new ReportException(reportParams, String.Format("Нет соответствующей графы для категории земель (OID = {0}). Квартал (OID = {1})", commonData.LandCategory.OID, quarter.OID));
- // Строки, соответствующие текущей категории защитности.
- IEnumerable<Form1Rows_To_ProtectionCategories> list3 = form1Rows_categoriesList.Where(a => a.ProtectionCategory.OID == commonData.ProtectionCategory.OID && a.NormativeData.OID == na.NormativeData.OID);
- // В column.ColumnNumber содержится номер графы, к которой нужно прибавить площадь
- foreach (Form1Rows_To_ProtectionCategories item in list3)
- {
- int index = _form1RowsList.IndexOf(item.Form1Row);
- _s[column.ColumnNumber, index] += commonData.Area;
- }
- // "Эксплуатируемые" строки (27, 32, 43)
- if (ageDataItem.IsExploitable.HasValue && ageDataItem.IsExploitable.Value == true && ageDataItem.ReturnCode.HasValue && ageDataItem.ReturnCode.Value == 0)
- {
- Form1Row row = _form1RowsList.FirstOrDefault(a => a.OID == commonData.ProtectionCategory.ForestGroup.ExploitableForm1RowOID);
- if (row == null)
- throw new ReportException(reportParams, String.Format("Отсутствует строка формы учета №1 (OID = {0})", commonData.ProtectionCategory.ForestGroup.ExploitableForm1RowOID));
- int index = _form1RowsList.IndexOf(row);
- _s[column.ColumnNumber, index] += commonData.Area;
- }
- }
- context.Detach(commonData);
- }
- #endregion
- foreach (vw_QuarterAgeDataItem ageDataResult in vw_AgeDataResult)
- context.Detach(ageDataResult);
- context.Detach(quarter);
- }
- }
- #region Расчет подчиненных строк
- foreach (byte calcOrder in calcOrder_list)
- {
- IEnumerable<Form1Rows_CalculationOrder> list4 = calc_list.Where(a => a.CalcOrder == calcOrder);
- foreach (Form1Rows_CalculationOrder item in list4)
- {
- int index_dest = _form1RowsList.IndexOf(item.Form1RowA);
- int index_src = _form1RowsList.IndexOf(item.Form1RowB);
- for (int i = 0; i < COLUMN_COUNT; i++)
- _s[i, index_dest] += _s[i, index_src];
- }
- }
- #endregion
- #region Суммирование площадей по графам
- for (int i = 0; i < _form1RowsList.Count; i++)
- {
- _s[2, i] = _s[2, i] + _s[3, i];
- _s[11, i] = _s[7, i] + _s[8, i] + _s[9, i] + _s[10, i];
- _s[12, i] = _s[2, i] + _s[4, i] + _s[5, i] + _s[6, i] + _s[11, i];
- _s[24, i] = _s[13, i] + _s[14, i] + _s[15, i] + _s[16, i] + _s[17, i] + _s[18, i] + _s[19, i] + _s[20, i] + _s[21, i] + _s[22, i] + _s[23, i];
- _s[1, i] = _s[12, i] + _s[24, i];
- if (_form1RowsList[i].IsExploitable)
- {
- for (int j = 2; j < COLUMN_COUNT; j++)
- _s[j, i] = 0.0;
- _s[2, i] = _s[1, i];
- _s[12, i] = _s[1, i];
- }
- }
- #endregion
- //reportData.s = s;
- //reportData.sg1 = sg1;
- //reportData.sg2 = sg2;
- //reportData.Year = forestResourcesReportParams.Year;
- //reportData.ReportName = forestResourcesReportParams.Name;
- return null;
- }
- public override void CreateDocument(object obj, string formatKey, Procedure<int> progressCallback, string templateFolder, System.IO.Stream outputStream)
- {
- #if DEBUG_LOG
- Program.LogSystem.Info("F15_begin_createDoc");
- #endif
- #region Создание документа
- //Form1ReportData rd = (Form1ReportData)obj;
- int progress_counter = 0;
- int progress = 0;
- double progress_q = 0.0;
- //ForestResourcesReportParams forestResourcesReportParams = reportParams as ForestResourcesReportParams;
- //templateFolder += _description.Key + "\\" + formatKey + "\\";
- TemplateProcessor tprocessor = new TemplateProcessor();
- Dictionary<int, string> results = new Dictionary<int, string>();
- DateTime creationDateTime = DateTime.Now;
- int MAX_ROW_COUNT = formatKey == Program.HTML_FORMAT_KEY ? 100 : 14;
- bool nbspFlag = formatKey == Program.HTML_FORMAT_KEY;
- //string emptyValue = 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("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("RELIEF_TYPE"));
- tprocessor.Parameters.Add(new TemplateParameter2("ROWS_CONTENT"));
- tprocessor.Parameters.Add(new TemplateParameter2("BODY_CONTENT"));
- for (int i = 1; i <= 24; i++)
- tprocessor.Parameters.Add(new NumericTemplateParameter2("VALUE_S" + i.ToString(), 0, nbspFlag, (byte)2, DecimalSeparator.Comma));
- // Для параметров, которые могут содержать спецсимволы.
- tprocessor.Parameters.Add(new HtmlEncodedTemplateParameter2("REPORT_NAME", _reportParams.Name, nbspFlag));
- tprocessor.Parameters.Add(new HtmlEncodedTemplateParameter2("VALUE_A", null, nbspFlag));
- tprocessor.Parameters.Add(new HtmlEncodedTemplateParameter2("VALUE_B", null, nbspFlag));
- #endregion
- string row_template_1 = tprocessor.ReadFile(templateFolder + "rowcontent_1.tpl");
- string row_template_2 = tprocessor.ReadFile(templateFolder + "rowcontent_2.tpl");
- string header_template_1 = tprocessor.ReadFile(templateFolder + "header_1.tpl");
- string header_template_2 = tprocessor.ReadFile(templateFolder + "header_2.tpl");
- tprocessor.Parameters["RELIEF_TYPE"].Value = _sg1 > _sg2 ? "горный" : "равнинный";
- progress_q = 2.0 / _form1RowsList.Count;
- // На первой итерации формируем результаты со строками №№1-12
- // На второй - результаты со строками №№13-24
- for (int iteration = 1; iteration <= 2; iteration++)
- {
- #region Переменные
- bool nextResult = true;
- string rowsTemplate = String.Empty;
- int resultId = 0;
- int rc = 0; // Количество созданных строк данных
- int result_count = 0;
- //progress_counter = 0;
- #endregion
- // Перебор всех строк формы учета
- for (int rowIndex = 0; rowIndex < _form1RowsList.Count; rowIndex++)
- {
- #region Callback
- progress_counter++;
- if (formatKey == Program.HTML_FORMAT_KEY)
- {
- progress = 95 + 2 * (iteration - 1) + (int)(progress_q * progress_counter);
- }
- else
- {
- progress = 90 + 2 * (iteration - 1) + (int)(progress_q * progress_counter);
- }
- progressCallback(progress);
- #endregion
- // Пропуск строк с общей площадью, равной нулю.
- if (_s[1, rowIndex] == 0.0)
- continue;
- if (nextResult)
- {
- nextResult = false;
- result_count++;
- rc = 0;
- switch (iteration)
- {
- case 1:
- resultId = 2 * result_count - 1;
- rowsTemplate = row_template_1;
- break;
- case 2:
- resultId = 2 * result_count;
- rowsTemplate = row_template_2;
- break;
- }
- results.Add(resultId, String.Empty);
- }
- tprocessor.Parameters["VALUE_A"].Value = _form1RowsList[rowIndex].Name;
- tprocessor.Parameters["VALUE_B"].Value = _form1RowsList[rowIndex].External_ID;
- for (int k = 1; k <= 12; k++)
- {
- int k0 = (iteration - 1) * 12 + k;
- if (_s[k0, rowIndex] == 0.0) tprocessor.Parameters["VALUE_S" + k0.ToString()].Value = null;
- else tprocessor.Parameters["VALUE_S" + k0.ToString()].Value = _s[k0, rowIndex];
- //tprocessor.Parameters["VALUE_S" + k0.ToString()].Value = rd.s[k0, rowIndex] == 0.0 ? null : rd.s[k0, rowIndex];
- }
- results[resultId] += tprocessor.ProcessString(rowsTemplate);
- rc++;
- // Если достигнуто предельное количество строк данных, то создаем новый результирующий набор
- if (rc == MAX_ROW_COUNT)
- {
- nextResult = true;
- }
- }
- } // iteration
- int[] keys = new int[results.Keys.Count];
- results.Keys.CopyTo(keys, 0);
- Array.Sort(keys);
- for (int i = 0; i < keys.Length; i++)
- {
- decimal d;
- string headerTemplateFile = String.Empty;
- if (keys[i] % 2 == 0)
- {
- headerTemplateFile = header_template_2;
- // В конец каждого второго кроме последнего ставим разрыв страницы.
- if (i != keys.Length - 1)
- //results[keys[i]] += vars["PAGE_BREAK"];
- results[keys[i]] += tprocessor.Parameters["PAGE_BREAK"].Value;
- d = keys[i] / 2;
- }
- else
- {
- headerTemplateFile = header_template_1;
- d = (keys[i] + 1) / 2;
- }
- tprocessor.Parameters["SHEET_NUMBER"].Value = Convert.ToString(Math.Floor(d));
- tprocessor.Parameters["ROWS_CONTENT"].Value = results[keys[i]];
- tprocessor.Parameters["BODY_CONTENT"].Value += tprocessor.ProcessString(headerTemplateFile);
- }
- tprocessor.ProcessFileToStream(outputStream, templateFolder + "document.tpl");
- //tprocessor.ProcessStringToStream(
- #endregion
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement