diff --git a/HardwareShop/HardwareShopBusinessLogic/BusinessLogics/Worker/WorkerReportLogic.cs b/HardwareShop/HardwareShopBusinessLogic/BusinessLogics/Worker/WorkerReportLogic.cs index 0cab5f4..83c7e98 100644 --- a/HardwareShop/HardwareShopBusinessLogic/BusinessLogics/Worker/WorkerReportLogic.cs +++ b/HardwareShop/HardwareShopBusinessLogic/BusinessLogics/Worker/WorkerReportLogic.cs @@ -6,25 +6,33 @@ using HardwareShopContracts.BindingModels; using HardwareShopContracts.SearchModels; using HardwareShopContracts.StoragesContracts; using HardwareShopContracts.ViewModels; +using HardwareShopDatabaseImplement.Implements.Worker; using HardwareShopDatabaseImplement.Models.Worker; +using System.Reflection.PortableExecutable; namespace HardwareShopContracts.BusinessLogicsContracts { public class WorkerReportLogic : IWorkerReportLogic { - private readonly IPurchaseStorage _purchaseStorage; + private readonly IPurchaseStorage _purchaseStorage; - private readonly AbstractSaveToExcel _saveToExcel; + private readonly IBuildStorage _buildStorage; - private readonly AbstractSaveToWord _saveToWord; + private readonly AbstractSaveToExcel _saveToExcel; - public WorkerReportLogic(IPurchaseStorage purchaseStorage, AbstractSaveToExcel saveToExcel, AbstractSaveToWord saveToWord) + private readonly AbstractSaveToWord _saveToWord; + + private readonly AbstractSaveToWord _saveToPdf; + + public WorkerReportLogic(IPurchaseStorage purchaseStorage, IBuildStorage buildStorage, AbstractSaveToWord saveToPdf, AbstractSaveToExcel saveToExcel, AbstractSaveToWord saveToWord) { _purchaseStorage = purchaseStorage; - _saveToExcel = saveToExcel; - _saveToWord = saveToWord; - } + _buildStorage = buildStorage; + _saveToExcel = saveToExcel; + _saveToWord = saveToWord; + _saveToPdf = saveToPdf; + } /// /// Получение списка компонент с указанием, в каких покупках используются @@ -38,7 +46,7 @@ namespace HardwareShopContracts.BusinessLogicsContracts { var purchase = _purchaseStorage.GetElement(new() { Id = p.Id })!; - var record = new ReportPurchaseComponentViewModel + var record = new ReportPurchaseComponentViewModel { Id = purchase.Id, Builds = new List<(string Build, int count, List<(string Component, int count)>)>(), @@ -68,43 +76,44 @@ namespace HardwareShopContracts.BusinessLogicsContracts /// /// /// - public List GetPurchase(ReportBindingModel model, UserBindingModel userModel) + public List GetPurchase(ReportBindingModel model) { var list = new List(); - var purchases = _purchaseStorage.GetFilteredList(new PurchaseSearchModel { DateFrom = model.DateFrom, DateTo = model.DateTo, UserId = userModel.Id }); - + var purchases = _purchaseStorage.GetFilteredList(new PurchaseSearchModel { DateFrom = model.DateFrom, DateTo = model.DateTo, UserId = model.UserId }); foreach (var p in purchases) { - var purchase = _purchaseStorage.GetElement(new() { Id = p.Id })!; - var record = new ReportPurchaseViewModel - { - Id = purchase.Id, - Builds = new List<(string Build, int count, List, List<(string Component, int count)>)>(), - }; + var purchase = _purchaseStorage.GetElement(new() { Id = p.Id })!; + List commentList = new List(); + List componentList = new List(); foreach (var build in purchase.PurchaseBuilds) { - List commentList = new List(); foreach (var comment in build.Value.Item1.BuildComments) { commentList.Add(new(comment.Value.Text)); } - List<(string Component, int count)> componentList = new List<(string Component, int count)>(); foreach (var component in build.Value.Item1.BuildComponents) { - componentList.Add(new(component.Value.Item1.ComponentName, component.Value.Item2)); + componentList.Add(component.Value.Item1.ComponentName); } - record.Builds.Add(new(build.Value.Item1.BuildName, build.Value.Item2, commentList, componentList)); } + var record = new ReportPurchaseViewModel + { + Id = purchase.Id, + PurchaseDate = (DateTime)p.DatePurchase, + PurchaseSum = p.Sum, + Comments = commentList, + Components = componentList.Distinct().ToList() + }; list.Add(record); } return list; } - /// - /// Сохранение компонент с указаеним покупок в файл-Word - /// - /// + /// + /// Сохранение компонент с указаеним покупок в файл-Word + /// + /// public byte[] SavePurchasesToWordFile(ReportBindingModel model, List purchases) { _saveToWord.CreateBuildPurchaseReport(new WordInfo @@ -114,35 +123,35 @@ namespace HardwareShopContracts.BusinessLogicsContracts PurchaseComponent = GetPurchaseComponent(purchases) }); - byte[] file = File.ReadAllBytes(model.FileName); - File.Delete(model.FileName); - return file; - } + byte[] file = File.ReadAllBytes(model.FileName); + File.Delete(model.FileName); + return file; + } - /// - /// Сохранение компонент с указаеним покупок в файл-Excel - /// - /// - public byte[] SavePurchasesToExcelFile(ReportBindingModel model, List purchases) - { - _saveToExcel.CreatePurchaseComponentReport(new ExcelInfo - { - FileName = model.FileName, - Title = "Список Компонентов", - PurchaseComponent = GetPurchaseComponent(purchases) - }); - byte[] file = File.ReadAllBytes(model.FileName); - File.Delete(model.FileName); - return file; - } + /// + /// Сохранение компонент с указаеним покупок в файл-Excel + /// + /// + public byte[] SavePurchasesToExcelFile(ReportBindingModel model, List purchases) + { + _saveToExcel.CreatePurchaseComponentReport(new ExcelInfo + { + FileName = model.FileName, + Title = "Список Компонентов", + PurchaseComponent = GetPurchaseComponent(purchases) + }); + byte[] file = File.ReadAllBytes(model.FileName); + File.Delete(model.FileName); + return file; + } /// /// Сохранение отчёта по покупкам в файл-Pdf /// /// - public void SaveOrdersToPdfFile(ReportBindingModel model) + public byte[] SendByMailPurchaseReport(ReportBindingModel model) { throw new NotImplementedException(); } - } + } } \ No newline at end of file diff --git a/HardwareShop/HardwareShopBusinessLogic/HardwareShopBusinessLogic.csproj b/HardwareShop/HardwareShopBusinessLogic/HardwareShopBusinessLogic.csproj index c92001f..44d3e9e 100644 --- a/HardwareShop/HardwareShopBusinessLogic/HardwareShopBusinessLogic.csproj +++ b/HardwareShop/HardwareShopBusinessLogic/HardwareShopBusinessLogic.csproj @@ -9,6 +9,7 @@ + diff --git a/HardwareShop/HardwareShopBusinessLogic/OfficePackage/AbstractSaveToPdf.cs b/HardwareShop/HardwareShopBusinessLogic/OfficePackage/AbstractSaveToPdf.cs new file mode 100644 index 0000000..46fc9c9 --- /dev/null +++ b/HardwareShop/HardwareShopBusinessLogic/OfficePackage/AbstractSaveToPdf.cs @@ -0,0 +1,96 @@ +using HardwareShopBusinessLogic.OfficePackage.HelperEnums; +using HardwareShopBusinessLogic.OfficePackage.HelperModels; + +namespace HardwareShopBusinessLogic.OfficePackage +{ + public abstract class AbstractSaveToPdf + { + //public void CreateDoc(PdfInfo info) + //{ + // CreatePdf(info); + // CreateParagraph(new PdfParagraph { Text = info.Title, Style = "NormalTitle", ParagraphAlignment = PdfParagraphAlignmentType.Center }); + // CreateParagraph(new PdfParagraph { Text = $"с {info.DateFrom.ToShortDateString()} по {info.DateTo.ToShortDateString()}", Style = "Normal", ParagraphAlignment = PdfParagraphAlignmentType.Center }); + + // CreateTable(new List { "2cm", "3cm", "6cm", "3cm", "3cm" }); + + // CreateRow(new PdfRowParameters + // { + // Texts = new List { "Номер", "Дата заказа", "Блюдо", "Сумма", "Статус" }, + // Style = "NormalTitle", + // ParagraphAlignment = PdfParagraphAlignmentType.Center + // }); + + // foreach (var order in info.Orders) + // { + // CreateRow(new PdfRowParameters + // { + // Texts = new List { order.Id.ToString(), order.DateCreate.ToShortDateString(), order.DishName, order.Sum.ToString(), order.OrderStatus }, + // Style = "Normal", + // ParagraphAlignment = PdfParagraphAlignmentType.Left + // }); + // } + // CreateParagraph(new PdfParagraph { Text = $"Итого: {info.Orders.Sum(x => x.Sum)}\t", Style = "Normal", ParagraphAlignment = PdfParagraphAlignmentType.Rigth }); + + // SavePdf(info); + //} + + //public void CreateOrdersGroupedByDateDoc(PdfInfo info) + //{ + // CreatePdf(info); + // CreateParagraph(new PdfParagraph { Text = info.Title, Style = "NormalTitle", ParagraphAlignment = PdfParagraphAlignmentType.Center }); + + // CreateTable(new List { "3cm", "3cm", "3cm" }); + + // CreateRow(new PdfRowParameters + // { + // Texts = new List { "Дата заказов", "Количество заказов", "Сумма" }, + // Style = "NormalTitle", + // ParagraphAlignment = PdfParagraphAlignmentType.Center + // }); + + // foreach (var order in info.OrdersGroupedByDate) + // { + // CreateRow(new PdfRowParameters + // { + // Texts = new List { order.DateCreate.ToShortDateString(), order.Count.ToString(), order.Sum.ToString() }, + // Style = "Normal", + // ParagraphAlignment = PdfParagraphAlignmentType.Left + // }); + // } + + // SavePdf(info); + //} + + /// + /// Создание doc-файла + /// + /// + protected abstract void CreatePdf(PdfInfo info); + + /// + /// Создание параграфа с текстом + /// + /// + /// + protected abstract void CreateParagraph(PdfParagraph paragraph); + + /// + /// Создание таблицы + /// + /// + /// + protected abstract void CreateTable(List columns); + + /// + /// Создание и заполнение строки + /// + /// + protected abstract void CreateRow(PdfRowParameters rowParameters); + + /// + /// Сохранение файла + /// + /// + protected abstract void SavePdf(PdfInfo info); + } +} diff --git a/HardwareShop/HardwareShopBusinessLogic/OfficePackage/HelperEnums/PdfParagraphAlignmentType.cs b/HardwareShop/HardwareShopBusinessLogic/OfficePackage/HelperEnums/PdfParagraphAlignmentType.cs new file mode 100644 index 0000000..5694a46 --- /dev/null +++ b/HardwareShop/HardwareShopBusinessLogic/OfficePackage/HelperEnums/PdfParagraphAlignmentType.cs @@ -0,0 +1,11 @@ +namespace HardwareShopBusinessLogic.OfficePackage.HelperEnums +{ + public enum PdfParagraphAlignmentType + { + Center, + + Left, + + Rigth + } +} \ No newline at end of file diff --git a/HardwareShop/HardwareShopBusinessLogic/OfficePackage/HelperModels/PdfInfo.cs b/HardwareShop/HardwareShopBusinessLogic/OfficePackage/HelperModels/PdfInfo.cs new file mode 100644 index 0000000..7950098 --- /dev/null +++ b/HardwareShop/HardwareShopBusinessLogic/OfficePackage/HelperModels/PdfInfo.cs @@ -0,0 +1,20 @@ + +using HardwareShopContracts.ViewModels; + +namespace HardwareShopBusinessLogic.OfficePackage.HelperModels +{ + public class PdfInfo + { + public string FileName { get; set; } = string.Empty; + + public string Title { get; set; } = string.Empty; + + public DateTime DateFrom { get; set; } + + public DateTime DateTo { get; set; } + + public List ReportComponents { get; set; } = new(); + + public List ReportPurchases { get; set; } = new(); + } +} \ No newline at end of file diff --git a/HardwareShop/HardwareShopBusinessLogic/OfficePackage/HelperModels/PdfParagraph.cs b/HardwareShop/HardwareShopBusinessLogic/OfficePackage/HelperModels/PdfParagraph.cs new file mode 100644 index 0000000..d17ab8b --- /dev/null +++ b/HardwareShop/HardwareShopBusinessLogic/OfficePackage/HelperModels/PdfParagraph.cs @@ -0,0 +1,13 @@ +using HardwareShopBusinessLogic.OfficePackage.HelperEnums; + +namespace HardwareShopBusinessLogic.OfficePackage.HelperModels +{ + public class PdfParagraph + { + public string Text { get; set; } = string.Empty; + + public string Style { get; set; } = string.Empty; + + public PdfParagraphAlignmentType ParagraphAlignment { get; set; } + } +} \ No newline at end of file diff --git a/HardwareShop/HardwareShopBusinessLogic/OfficePackage/HelperModels/PdfRowParameters.cs b/HardwareShop/HardwareShopBusinessLogic/OfficePackage/HelperModels/PdfRowParameters.cs new file mode 100644 index 0000000..a803d0f --- /dev/null +++ b/HardwareShop/HardwareShopBusinessLogic/OfficePackage/HelperModels/PdfRowParameters.cs @@ -0,0 +1,13 @@ +using HardwareShopBusinessLogic.OfficePackage.HelperEnums; + +namespace HardwareShopBusinessLogic.OfficePackage.HelperModels +{ + public class PdfRowParameters + { + public List Texts { get; set; } = new(); + + public string Style { get; set; } = string.Empty; + + public PdfParagraphAlignmentType ParagraphAlignment { get; set; } + } +} \ No newline at end of file diff --git a/HardwareShop/HardwareShopBusinessLogic/OfficePackage/Implements/SaveToPdf.cs b/HardwareShop/HardwareShopBusinessLogic/OfficePackage/Implements/SaveToPdf.cs new file mode 100644 index 0000000..9a36ede --- /dev/null +++ b/HardwareShop/HardwareShopBusinessLogic/OfficePackage/Implements/SaveToPdf.cs @@ -0,0 +1,114 @@ +using HardwareShopBusinessLogic.OfficePackage.HelperEnums; +using HardwareShopBusinessLogic.OfficePackage.HelperModels; +using MigraDoc.DocumentObjectModel; +using MigraDoc.DocumentObjectModel.Tables; +using MigraDoc.Rendering; + +namespace HardwareShopBusinessLogic.OfficePackage.Implements +{ + public class SaveToPdf : AbstractSaveToPdf + { + private Document? _document; + + private Section? _section; + + private Table? _table; + + private static ParagraphAlignment GetParagraphAlignment(PdfParagraphAlignmentType type) + { + return type switch + { + PdfParagraphAlignmentType.Center => ParagraphAlignment.Center, + PdfParagraphAlignmentType.Left => ParagraphAlignment.Left, + PdfParagraphAlignmentType.Rigth => ParagraphAlignment.Right, + _ => ParagraphAlignment.Justify, + }; + } + + /// + /// Создание стилей для документа + /// + /// + private static void DefineStyles(Document document) + { + var style = document.Styles["Normal"]; + style.Font.Name = "Times New Roman"; + style.Font.Size = 14; + + style = document.Styles.AddStyle("NormalTitle", "Normal"); + style.Font.Bold = true; + } + + protected override void CreatePdf(PdfInfo info) + { + _document = new Document(); + DefineStyles(_document); + + _section = _document.AddSection(); + } + + protected override void CreateParagraph(PdfParagraph pdfParagraph) + { + if (_section == null) + { + return; + } + var paragraph = _section.AddParagraph(pdfParagraph.Text); + paragraph.Format.SpaceAfter = "1cm"; + paragraph.Format.Alignment = GetParagraphAlignment(pdfParagraph.ParagraphAlignment); + paragraph.Style = pdfParagraph.Style; + } + + protected override void CreateTable(List columns) + { + if (_document == null) + { + return; + } + _table = _document.LastSection.AddTable(); + + foreach (var elem in columns) + { + _table.AddColumn(elem); + } + } + + protected override void CreateRow(PdfRowParameters rowParameters) + { + if (_table == null) + { + return; + } + var row = _table.AddRow(); + for (int i = 0; i < rowParameters.Texts.Count; ++i) + { + row.Cells[i].AddParagraph(rowParameters.Texts[i]); + + if (!string.IsNullOrEmpty(rowParameters.Style)) + { + row.Cells[i].Style = rowParameters.Style; + } + + Unit borderWidth = 0.5; + + row.Cells[i].Borders.Left.Width = borderWidth; + row.Cells[i].Borders.Right.Width = borderWidth; + row.Cells[i].Borders.Top.Width = borderWidth; + row.Cells[i].Borders.Bottom.Width = borderWidth; + + row.Cells[i].Format.Alignment = GetParagraphAlignment(rowParameters.ParagraphAlignment); + row.Cells[i].VerticalAlignment = VerticalAlignment.Center; + } + } + + protected override void SavePdf(PdfInfo info) + { + var renderer = new PdfDocumentRenderer(true) + { + Document = _document + }; + renderer.RenderDocument(); + renderer.PdfDocument.Save(info.FileName); + } + } +} \ No newline at end of file diff --git a/HardwareShop/HardwareShopContracts/BindingModels/ReportBindingModel.cs b/HardwareShop/HardwareShopContracts/BindingModels/ReportBindingModel.cs index 2b9f8d4..1bb0758 100644 --- a/HardwareShop/HardwareShopContracts/BindingModels/ReportBindingModel.cs +++ b/HardwareShop/HardwareShopContracts/BindingModels/ReportBindingModel.cs @@ -7,5 +7,7 @@ public DateTime? DateFrom { get; set; } public DateTime? DateTo { get; set; } + + public int UserId { get; set; } } } diff --git a/HardwareShop/HardwareShopContracts/BusinessLogicsContracts/IWorkerReportLogic.cs b/HardwareShop/HardwareShopContracts/BusinessLogicsContracts/IWorkerReportLogic.cs index 9eee930..4c66b07 100644 --- a/HardwareShop/HardwareShopContracts/BusinessLogicsContracts/IWorkerReportLogic.cs +++ b/HardwareShop/HardwareShopContracts/BusinessLogicsContracts/IWorkerReportLogic.cs @@ -17,7 +17,7 @@ namespace HardwareShopContracts.BusinessLogicsContracts /// /// /// - List GetPurchase(ReportBindingModel model, UserBindingModel userModel); + List GetPurchase(ReportBindingModel model); /// /// Сохранение компонент с указаеним покупок в файл-Word @@ -31,10 +31,10 @@ namespace HardwareShopContracts.BusinessLogicsContracts /// byte[] SavePurchasesToExcelFile(ReportBindingModel model, List purchases); - /// - /// Сохранение отчёта по покупкам в файл-Pdf - /// - /// - void SaveOrdersToPdfFile(ReportBindingModel model); + /// + /// Сохранение отчёта по покупкам в файл-Pdf + /// + /// + byte[] SendByMailPurchaseReport(ReportBindingModel model); } } \ No newline at end of file diff --git a/HardwareShop/HardwareShopContracts/SearchModels/BuildSearchModel.cs b/HardwareShop/HardwareShopContracts/SearchModels/BuildSearchModel.cs index e42cdaf..6999a46 100644 --- a/HardwareShop/HardwareShopContracts/SearchModels/BuildSearchModel.cs +++ b/HardwareShop/HardwareShopContracts/SearchModels/BuildSearchModel.cs @@ -4,6 +4,8 @@ { public int? Id { get; set; } + public int? PurchaseId { get; set; } + public string? BuildName { get; set; } = string.Empty; public int? UserId { get; set; } diff --git a/HardwareShop/HardwareShopContracts/ViewModels/ReportPurchaseViewModel.cs b/HardwareShop/HardwareShopContracts/ViewModels/ReportPurchaseViewModel.cs index b39605d..b0ee694 100644 --- a/HardwareShop/HardwareShopContracts/ViewModels/ReportPurchaseViewModel.cs +++ b/HardwareShop/HardwareShopContracts/ViewModels/ReportPurchaseViewModel.cs @@ -4,6 +4,12 @@ { public int Id { get; set; } - public List<(string Build, int count, List, List<(string Component, int count)>)> Builds { get; set; } = new(); + public DateTime PurchaseDate { get; set; } + + public double PurchaseSum { get; set; } + + public List Comments { get; set; } = new(); + + public List Components { get; set; } = new(); } } diff --git a/HardwareShop/HardwareShopDatabaseImplement/Implements/Worker/PurchaseStorage.cs b/HardwareShop/HardwareShopDatabaseImplement/Implements/Worker/PurchaseStorage.cs index 1c79500..610a11d 100644 --- a/HardwareShop/HardwareShopDatabaseImplement/Implements/Worker/PurchaseStorage.cs +++ b/HardwareShop/HardwareShopDatabaseImplement/Implements/Worker/PurchaseStorage.cs @@ -84,7 +84,10 @@ namespace HardwareShopDatabaseImplement.Implements.Worker .ThenInclude(x => x.Build) .ThenInclude(x => x.Components) .ThenInclude(x => x.Component) - .FirstOrDefault(x => model.Id.HasValue && x.Id == model.Id) + .Include(x => x.Builds) + .ThenInclude(x => x.Build) + .ThenInclude(x => x.Comments) + .FirstOrDefault(x => model.Id.HasValue && x.Id == model.Id) ?.GetViewModel; } diff --git a/HardwareShop/HardwareShopRestApi/Controllers/ReportController.cs b/HardwareShop/HardwareShopRestApi/Controllers/ReportController.cs index 2f19715..37b3603 100644 --- a/HardwareShop/HardwareShopRestApi/Controllers/ReportController.cs +++ b/HardwareShop/HardwareShopRestApi/Controllers/ReportController.cs @@ -1,5 +1,7 @@ -using HardwareShopContracts.BindingModels; +using DocumentFormat.OpenXml.Drawing; +using HardwareShopContracts.BindingModels; using HardwareShopContracts.BusinessLogicsContracts; +using HardwareShopContracts.ViewModels; using Microsoft.AspNetCore.Mvc; namespace HardwareShopRestApi.Controllers @@ -71,6 +73,22 @@ namespace HardwareShopRestApi.Controllers throw; } } + + + [HttpPost] + public List? GetPurchaseReportData(ReportBindingModel model) + { + try + { + var report = _reportWorkerLogic.GetPurchase(model); + return report; + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка получения данных для отчёта"); + throw; + } + } } } diff --git a/HardwareShop/HardwareShopWorkerApp/Controllers/HomeController.cs b/HardwareShop/HardwareShopWorkerApp/Controllers/HomeController.cs index 6a73699..1578ee0 100644 --- a/HardwareShop/HardwareShopWorkerApp/Controllers/HomeController.cs +++ b/HardwareShop/HardwareShopWorkerApp/Controllers/HomeController.cs @@ -345,10 +345,9 @@ namespace HardwareShopWorkerApp.Controllers byte[]? file = APIClient.PostRequestWithResult($"api/report/buildpurchasereport?format={format}", purchaseModel); var array = file!.Select(b => (int)b).ToArray(); return array; - - } + [HttpGet] public GoodViewModel? GetPurchase(int Id) { @@ -464,12 +463,6 @@ namespace HardwareShopWorkerApp.Controllers return result; } - [HttpGet] - public IActionResult WorkerReport() - { - return View(); - } - [HttpGet] public IActionResult Builds() { @@ -539,5 +532,26 @@ namespace HardwareShopWorkerApp.Controllers APIClient.GetRequest($"api/build/UpdateLinkPurchase?updateBuildId={updateBuildId}&updatePurchaseId={updatePurchaseId}&count={count}"); Response.Redirect($"LinkPurchase?buildId={updateBuildId}"); } - } + + public IActionResult WorkerReport() + { + if (APIClient.User == null) + { + return Redirect("~/Home/Enter"); + } + return View(); + } + + [HttpPost] + public List? WorkerReport([FromBody] ReportBindingModel reportModel) + { + if (APIClient.User == null) + { + return new(); + } + reportModel.UserId = APIClient.User.Id; + List? list = APIClient.PostRequestWithResult>("api/report/getpurchasereportdata", reportModel); + return list; + } + } } \ No newline at end of file diff --git a/HardwareShop/HardwareShopWorkerApp/Views/Home/WorkerReport.cshtml b/HardwareShop/HardwareShopWorkerApp/Views/Home/WorkerReport.cshtml index 45096fa..2e803d2 100644 --- a/HardwareShop/HardwareShopWorkerApp/Views/Home/WorkerReport.cshtml +++ b/HardwareShop/HardwareShopWorkerApp/Views/Home/WorkerReport.cshtml @@ -3,13 +3,198 @@ Layout = "~/Views/Shared/_LayoutWorker.cshtml"; } -
-
- - - - +

Отчет по покупкам

+ +
+
+

- - - \ No newline at end of file +
+ +
+
+

Дата начала:

+ +
+
+

Дата конца:

+ +
+ + +
+ +

+ За период с  + ... +  по  + ... +

+
+ + + + + + + + + + + + +
Номер покупкиДата покупкиСумма покупкиКомментарииКомплектующие
+
+ +@section Scripts + { + +} \ No newline at end of file