private void GenerateBaseReport(List <ProductionWarehouseMovementReportDataBaseNode> dataBaseNodeList) { var nomenclatureResultList = new List <ProductionWarehouseMovementReportNomenclature>(); var nomenclatureIds = dataBaseNodeList.Select(x => x.NomenclatureId).Distinct(); foreach (var nomenclatureId in nomenclatureIds) { var nomenclatureDocuments = dataBaseNodeList.Where(x => x.NomenclatureId == nomenclatureId); var nomenclatureRangePrices = nomenclatureDocuments .FirstOrDefault() .PurchasePrices .Where(x => (x.StartDate <= _endDate) && (x.EndDate == null || x.EndDate >= _startDate)); foreach (var nomenclatureRangePrice in nomenclatureRangePrices) { var documentsInPriceRange = nomenclatureDocuments .Where(x => (nomenclatureRangePrice.StartDate <= x.MovementDocumentDate) && (nomenclatureRangePrice.EndDate == null || nomenclatureRangePrice.EndDate >= x.MovementDocumentDate)); var nomenclature = new ProductionWarehouseMovementReportNomenclature { PurchasePriceStartDate = nomenclatureRangePrice.StartDate, PurchasePriceEndDate = nomenclatureRangePrice.EndDate ?? _endDate, NomenclatureName = nomenclatureDocuments.FirstOrDefault().NomenclatureName, Amount = decimal.Round(documentsInPriceRange.Sum(a => a.Amount)), PurchasePrice = nomenclatureRangePrice.PurchasePrice, Sum = decimal.Round(documentsInPriceRange.Sum(a => a.Amount) * nomenclatureRangePrice.PurchasePrice, 2) }; nomenclatureResultList.Add(nomenclature); } var documentsNotInPriceRange = new List <ProductionWarehouseMovementReportDataBaseNode>(); foreach (var nomenclatureDocument in nomenclatureDocuments) { if (!nomenclatureDocument.PurchasePrices .Any(p => (p.StartDate <= nomenclatureDocument.MovementDocumentDate) && (p.EndDate == null || p.EndDate >= nomenclatureDocument.MovementDocumentDate))) { documentsNotInPriceRange.Add(nomenclatureDocument); } } var nomenclatureWithNullPrice = new ProductionWarehouseMovementReportNomenclature { NomenclatureName = nomenclatureDocuments.FirstOrDefault().NomenclatureName, Amount = decimal.Round(documentsNotInPriceRange.Sum(a => a.Amount)) }; if (nomenclatureWithNullPrice.Amount > 0) { nomenclatureResultList.Add(nomenclatureWithNullPrice); } } var totalRow = new ProductionWarehouseMovementReportNomenclature { NomenclatureName = "ИТОГО", Amount = decimal.Round(nomenclatureResultList.Sum(n => n.Amount)), Sum = nomenclatureResultList.Sum(n => n.Sum), IsTotal = true }; var reportNode = new ProductionWarehouseMovementReportNode { NomenclatureColumns = (nomenclatureResultList .OrderBy(x => x.NomenclatureName) .ThenBy(x => x.PurchasePriceStartDate) .ToList()) }; reportNode.NomenclatureColumns.Add(totalRow); ResultNodeList.Add(reportNode); }
public void Export(IFileDialogService fileDialogService, string fileName, bool isDetailed, Encoding encoding = null) { if (fileDialogService is null) { throw new ArgumentNullException(nameof(fileDialogService)); } var dialogSettings = new DialogSettings(); dialogSettings.Title = "Сохранить"; dialogSettings.DefaultFileExtention = ".csv"; dialogSettings.FileName = $"{fileName} {DateTime.Now:yyyy-MM-dd-HH-mm}.csv"; var result = fileDialogService.RunSaveFileDialog(dialogSettings); if (!result.Successful) { return; } var writer = new StreamWriter(result.Path, false, encoding ?? Encoding.GetEncoding(1251)); var csv = new CsvWriter(writer, CultureInfo.CurrentCulture); if (isDetailed) { var columnNames = Titles.Select(x => x.NomenclatureName).ToList(); var headers = new[] { "Дата", "ТМЦ" }.Concat(columnNames).ToList(); foreach (var header in headers) { csv.WriteField(header); } csv.NextRecord(); foreach (var row in ResultNodeList) { csv.WriteField(row.MovementDocumentDate > DateTime.MinValue ? row.MovementDocumentDate.ToShortDateString() : string.Empty); csv.WriteField(row.MovementDocumentName); foreach (var column in row.NomenclatureColumns) { csv.WriteField(column.IsTotal? $"{ column.Amount:F2}" : $"{ column.Amount:F0}"); } csv.NextRecord(); } } else { var headers = new[] { "ТМЦ", "Период", "Цена", "Количество", "Сумма" }; foreach (var header in headers) { csv.WriteField(header); } csv.NextRecord(); foreach (var row in ResultNodeList.SingleOrDefault().NomenclatureColumns) { csv.WriteField(row.NomenclatureName); csv.WriteField(row.DateRange); csv.WriteField(row.IsTotal ? "" : row.PurchasePrice.ToString()); csv.WriteField(row.Amount); csv.WriteField(row.Sum); csv.NextRecord(); } } writer.Close(); }
private void GenerateDetailedReport(List <ProductionWarehouseMovementReportDataBaseNode> dataBaseNodeList) { Titles = dataBaseNodeList .OrderBy(x => x.NomenclatureName) .GroupBy(x => x.NomenclatureId) .Select(x => new ProductionWarehouseMovementReportTitleNode { NomenclatureId = x.First().NomenclatureId, NomenclatureName = x.First().NomenclatureName }) .ToList(); var documentDates = dataBaseNodeList .Select(x => x.MovementDocumentDate) .OrderBy(x => x) .Distinct(); foreach (var documentDate in documentDates) { var documentsOnDate = dataBaseNodeList .Where(d => d.MovementDocumentDate == documentDate) .GroupBy(x => x.MovementDocumentId) .Select(x => new { Id = x.First().MovementDocumentId, Date = x.First().MovementDocumentDate }); var rowsOnDate = new List <ProductionWarehouseMovementReportNode>(); #region Формирование строк-документов с колонками-номенклатурами foreach (var documentOnDate in documentsOnDate) { var nomenclatures = dataBaseNodeList .Where(d => d.MovementDocumentId == documentOnDate.Id) .Select(x => { var nomenclature = new ProductionWarehouseMovementReportNomenclature { Id = x.NomenclatureId, NomenclatureName = x.NomenclatureName, Amount = decimal.Round(x.Amount, 2) }; nomenclature.PurchasePrice = x.PurchasePrices .FirstOrDefault(p => (p.StartDate <= documentOnDate.Date) && (p.EndDate == null || p.EndDate >= documentOnDate.Date)) ?.PurchasePrice ?? 0m; nomenclature.Sum = decimal.Round(nomenclature.PurchasePrice * nomenclature.Amount, 2); return(nomenclature); }); var filledByTitleNomenclatures = FillNomenclatureColumnsByTitles(nomenclatures); var filledRow = new ProductionWarehouseMovementReportNode { NomenclatureColumns = filledByTitleNomenclatures, MovementDocumentDate = documentOnDate.Date, MovementDocumentName = $"Документ №{documentOnDate.Id}" }; rowsOnDate.Add(filledRow); } ResultNodeList.AddRange(rowsOnDate); #endregion #region Формирование строки с итоговым количеством за дату var amountTotalNomenclatures = new List <ProductionWarehouseMovementReportNomenclature>(); foreach (var title in Titles) { var amountSum = rowsOnDate .SelectMany(x => x.NomenclatureColumns) .Where(x => x.Id == title.NomenclatureId) .Sum(x => x.Amount); amountTotalNomenclatures.Add(new ProductionWarehouseMovementReportNomenclature { Id = title.NomenclatureId, Amount = decimal.Round(amountSum, 2) }); } var amountTotalRow = new ProductionWarehouseMovementReportNode { MovementDocumentName = "Сумма шт:", NomenclatureColumns = amountTotalNomenclatures }; ResultNodeList.Add(amountTotalRow); #endregion #region Формирование строки с ценой закупки на дату var purchasePriceNomenclatures = new List <ProductionWarehouseMovementReportNomenclature>(); foreach (var title in Titles) { var purchasePrice = rowsOnDate .SelectMany(x => x.NomenclatureColumns) .Where(x => x.Id == title.NomenclatureId) .Max(x => x.PurchasePrice); purchasePriceNomenclatures.Add(new ProductionWarehouseMovementReportNomenclature { Id = title.NomenclatureId, Amount = purchasePrice, IsTotal = true }); } var purchasePriceTotalRow = new ProductionWarehouseMovementReportNode { MovementDocumentName = "Цена:", NomenclatureColumns = purchasePriceNomenclatures }; ResultNodeList.Add(purchasePriceTotalRow); #endregion #region Формирование строки с итоговой суммой за дату var sumTotalColumns = new List <ProductionWarehouseMovementReportNomenclature>(); for (int i = 0; i < Titles.Count; i++) { sumTotalColumns.Add(new ProductionWarehouseMovementReportNomenclature { Id = Titles[i].NomenclatureId, Amount = decimal.Round(amountTotalNomenclatures[i].Amount * purchasePriceNomenclatures[i].Amount), IsTotal = true }); } var sumTotalRow = new ProductionWarehouseMovementReportNode { MovementDocumentName = "Сумма р.:", NomenclatureColumns = sumTotalColumns }; ResultNodeList.Add(sumTotalRow); #endregion } }