diff --git a/HardwareShop/HardwareShopBusinessLogic/BusinessLogics/Worker/PurchaseLogic.cs b/HardwareShop/HardwareShopBusinessLogic/BusinessLogics/Worker/PurchaseLogic.cs index 59fb61b..085fbfc 100644 --- a/HardwareShop/HardwareShopBusinessLogic/BusinessLogics/Worker/PurchaseLogic.cs +++ b/HardwareShop/HardwareShopBusinessLogic/BusinessLogics/Worker/PurchaseLogic.cs @@ -75,7 +75,7 @@ namespace HardwareShopContracts.BusinessLogicsContracts model.PurchaseStatus = PurchaseStatus.Выдан; model.DatePurchase = DateTime.Now; CheckModel(model, false); - if (_purchaseStorage.Update(model) == null) + if (_purchaseStorage.Update(model, false) == null) { _logger.LogWarning("Change status operation failed"); return false; diff --git a/HardwareShop/HardwareShopBusinessLogic/BusinessLogics/Worker/WorkerReportLogic.cs b/HardwareShop/HardwareShopBusinessLogic/BusinessLogics/Worker/WorkerReportLogic.cs index f4931b7..9bcadf7 100644 --- a/HardwareShop/HardwareShopBusinessLogic/BusinessLogics/Worker/WorkerReportLogic.cs +++ b/HardwareShop/HardwareShopBusinessLogic/BusinessLogics/Worker/WorkerReportLogic.cs @@ -1,8 +1,15 @@  +using HardwareShopBusinessLogic.MailWorker; +using HardwareShopBusinessLogic.OfficePackage; +using HardwareShopBusinessLogic.OfficePackage.HelperModels; +using HardwareShopBusinessLogic.OfficePackage.Implements; 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 { @@ -11,10 +18,21 @@ namespace HardwareShopContracts.BusinessLogicsContracts private readonly IPurchaseStorage _purchaseStorage; - public WorkerReportLogic(IPurchaseStorage purchaseStorage) - { + private readonly AbstractSaveToExcel _saveToExcel; + private readonly AbstractSaveToWord _saveToWord; + + private readonly AbstractSaveToPdf _saveToPdf; + + private readonly AbstractMailWorker _mailKitWorker; + + public WorkerReportLogic(IPurchaseStorage purchaseStorage, AbstractMailWorker mailKitWorker, AbstractSaveToPdf saveToPdf, AbstractSaveToExcel saveToExcel, AbstractSaveToWord saveToWord) + { _purchaseStorage = purchaseStorage; + _saveToExcel = saveToExcel; + _saveToWord = saveToWord; + _saveToPdf = saveToPdf; + _mailKitWorker = mailKitWorker; } /// @@ -25,8 +43,10 @@ namespace HardwareShopContracts.BusinessLogicsContracts { var list = new List(); - foreach (var purchase in purchaseList) + foreach (var p in purchaseList) { + var purchase = _purchaseStorage.GetElement(new() { Id = p.Id })!; + var record = new ReportPurchaseComponentViewModel { Id = purchase.Id, @@ -57,32 +77,34 @@ 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 }); - - foreach (var purchase in purchases) + var purchases = _purchaseStorage.GetFilteredList(new PurchaseSearchModel { DateFrom = model.DateFrom, DateTo = model.DateTo, UserId = model.UserId }); + foreach (var p in purchases) { - 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; @@ -93,27 +115,59 @@ namespace HardwareShopContracts.BusinessLogicsContracts /// Сохранение компонент с указаеним покупок в файл-Word /// /// - public void SaveComponentsToWordFile(ReportBindingModel model) + public byte[] SavePurchasesToWordFile(ReportBindingModel model, List purchases) { - throw new NotImplementedException(); + _saveToWord.CreateBuildPurchaseReport(new WordInfo + { + FileName = model.FileName, + Title = "Список Компонентов", + PurchaseComponent = GetPurchaseComponent(purchases) + }); + + byte[] file = File.ReadAllBytes(model.FileName); + File.Delete(model.FileName); + return file; } /// /// Сохранение компонент с указаеним покупок в файл-Excel /// /// - public void SaveDishComponentToExcelFile(ReportBindingModel model) + public byte[] SavePurchasesToExcelFile(ReportBindingModel model, List purchases) { - throw new NotImplementedException(); + _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 void SendByMailPurchaseReport(ReportBindingModel model) { - throw new NotImplementedException(); + byte[] file = _saveToPdf.GetPurchaseReportFile(new() + { + FileName = model.FileName, + Title = "Отчет по покупкам", + DateFrom = model.DateFrom, + DateTo = model.DateTo, + ReportPurchases = GetPurchase(model) + }); + _mailKitWorker.MailSendAsync(new() + { + MailAddress = model.UserEmail, + Subject = "Отчет по покупкам", + Text = $"За период с {model.DateFrom.ToShortDateString()} " + + $"по {model.DateTo.ToShortDateString()}.", + File = file + }); } } } \ No newline at end of file diff --git a/HardwareShop/HardwareShopBusinessLogic/HardwareShopBusinessLogic.csproj b/HardwareShop/HardwareShopBusinessLogic/HardwareShopBusinessLogic.csproj index b313fbf..caa0fe4 100644 --- a/HardwareShop/HardwareShopBusinessLogic/HardwareShopBusinessLogic.csproj +++ b/HardwareShop/HardwareShopBusinessLogic/HardwareShopBusinessLogic.csproj @@ -10,6 +10,7 @@ + diff --git a/HardwareShop/HardwareShopBusinessLogic/MailWorker/MailKitWorker.cs b/HardwareShop/HardwareShopBusinessLogic/MailWorker/MailKitWorker.cs index 96a2d20..1951330 100644 --- a/HardwareShop/HardwareShopBusinessLogic/MailWorker/MailKitWorker.cs +++ b/HardwareShop/HardwareShopBusinessLogic/MailWorker/MailKitWorker.cs @@ -25,6 +25,8 @@ namespace HardwareShopBusinessLogic.MailWorker objMailMessage.Body = info.Text; objMailMessage.SubjectEncoding = Encoding.UTF8; objMailMessage.BodyEncoding = Encoding.UTF8; + MemoryStream ms = new(info.File); + objMailMessage.Attachments.Add(new Attachment(ms, "report.pdf", "application/pdf")); objSmtpClient.UseDefaultCredentials = false; objSmtpClient.EnableSsl = true; diff --git a/HardwareShop/HardwareShopBusinessLogic/OfficePackage/AbstractSaveToExcel.cs b/HardwareShop/HardwareShopBusinessLogic/OfficePackage/AbstractSaveToExcel.cs index 2a675cd..10da8a0 100644 --- a/HardwareShop/HardwareShopBusinessLogic/OfficePackage/AbstractSaveToExcel.cs +++ b/HardwareShop/HardwareShopBusinessLogic/OfficePackage/AbstractSaveToExcel.cs @@ -56,11 +56,90 @@ namespace HardwareShopBusinessLogic.OfficePackage SaveExcel(info); } - /// - /// Создание excel-файла - /// - /// - protected abstract void CreateExcel(ExcelInfo info); + /// + /// Создание отчета по сборкам в выбранных товарах + /// + /// + public void CreatePurchaseComponentReport(ExcelInfo info) + { + CreateExcel(info); + + InsertCellInWorksheet(new ExcelCellParameters + { + ColumnName = "A", + RowIndex = 1, + Text = info.Title, + StyleInfo = ExcelStyleInfoType.Title + }); + + MergeCells(new ExcelMergeParameters + { + CellFromName = "A1", + CellToName = "E1" + }); + + uint rowIndex = 2; + foreach (var bg in info.PurchaseComponent) + { + InsertCellInWorksheet(new ExcelCellParameters + { + ColumnName = "A", + RowIndex = rowIndex, + Text = bg.Id.ToString(), + StyleInfo = ExcelStyleInfoType.Text + }); + rowIndex++; + + foreach (var build in bg.Builds) + { + InsertCellInWorksheet(new ExcelCellParameters + { + ColumnName = "B", + RowIndex = rowIndex, + Text = build.Build, + StyleInfo = ExcelStyleInfoType.TextWithBroder + }); + InsertCellInWorksheet(new ExcelCellParameters + { + ColumnName = "C", + RowIndex = rowIndex, + Text = build.count.ToString(), + StyleInfo = ExcelStyleInfoType.TextWithBroder + }); + + rowIndex++; + foreach (var component in build.Item3) + { + InsertCellInWorksheet(new ExcelCellParameters + { + ColumnName = "D", + RowIndex = rowIndex, + Text = component.Component, + StyleInfo = ExcelStyleInfoType.TextWithBroder + }); + InsertCellInWorksheet(new ExcelCellParameters + { + ColumnName = "E", + RowIndex = rowIndex, + Text = component.count.ToString(), + StyleInfo = ExcelStyleInfoType.TextWithBroder + }); + + rowIndex++; + } + } + + rowIndex++; + } + + SaveExcel(info); + } + + /// + /// Создание excel-файла + /// + /// + protected abstract void CreateExcel(ExcelInfo info); /// /// Добавляем новую ячейку в лист diff --git a/HardwareShop/HardwareShopBusinessLogic/OfficePackage/AbstractSaveToPdf.cs b/HardwareShop/HardwareShopBusinessLogic/OfficePackage/AbstractSaveToPdf.cs new file mode 100644 index 0000000..f5fefac --- /dev/null +++ b/HardwareShop/HardwareShopBusinessLogic/OfficePackage/AbstractSaveToPdf.cs @@ -0,0 +1,119 @@ +using DocumentFormat.OpenXml.EMMA; +using HardwareShopBusinessLogic.OfficePackage.HelperEnums; +using HardwareShopBusinessLogic.OfficePackage.HelperModels; +using MigraDoc.Rendering; + +namespace HardwareShopBusinessLogic.OfficePackage +{ + public abstract class AbstractSaveToPdf + { + public byte[] GetPurchaseReportFile(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 { "5cm", "5cm", "5cm", "5cm", "5cm" }); + + CreateRow(new PdfRowParameters + { + Texts = new List { "Покупка", "Дата покупки", "Цена", "Комментарии", "Комплектующие" }, + Style = "NormalTitle", + ParagraphAlignment = PdfParagraphAlignmentType.Center + }); + + foreach (var record in info.ReportPurchases) + { + List comments = record.Comments; + List components = record.Components; + int recordHeight = Math.Max(comments.Count + 1, components.Count + 1); + for (int i = 0; i < recordHeight; i++) + { + List cellsData = new() { "", "", "", "", "" }; + if (i == 0) + { + cellsData[0] = record.Id.ToString(); + cellsData[1] = record.PurchaseDate.ToShortDateString(); + cellsData[2] = record.PurchaseSum.ToString("0.00") + " р."; + CreateRow(new PdfRowParameters + { + Texts = cellsData, + Style = "Normal", + ParagraphAlignment = PdfParagraphAlignmentType.Left + }); + continue; + } + int k = i - 1; + if (k < comments.Count) + { + cellsData[3] = comments[k]; + } + if (k < components.Count) + { + cellsData[4] = components[k]; + } + CreateRow(new PdfRowParameters + { + Texts = cellsData, + Style = "Normal", + ParagraphAlignment = PdfParagraphAlignmentType.Left + }); + } + } + + return GetFile(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); + + /// + /// Сохранение отправляем файл + /// + /// + protected abstract byte[] GetFile(PdfInfo info); + } +} diff --git a/HardwareShop/HardwareShopBusinessLogic/OfficePackage/AbstractSaveToWord.cs b/HardwareShop/HardwareShopBusinessLogic/OfficePackage/AbstractSaveToWord.cs index b7b704a..362d0ba 100644 --- a/HardwareShop/HardwareShopBusinessLogic/OfficePackage/AbstractSaveToWord.cs +++ b/HardwareShop/HardwareShopBusinessLogic/OfficePackage/AbstractSaveToWord.cs @@ -57,11 +57,86 @@ namespace HardwareShopBusinessLogic.OfficePackage SaveWord(info); } - /// + public void CreateBuildPurchaseReport(WordInfo info) + { + CreateWord(info); + + CreateParagraph(new WordParagraph + { + Texts = new List<(string, WordTextProperties)> { (info.Title, new WordTextProperties { Bold = true, Size = "24" }) }, + TextProperties = new WordTextProperties + { + Size = "24", + JustificationType = WordJustificationType.Center + } + }); + + List rows = new List(); + rows.Add(new WordRow + { + Rows = new List<(string, WordTextProperties)> { + ("Покупки", new WordTextProperties { Size = "24", Bold = true }), + ("Сборки", new WordTextProperties { Size = "24", Bold = true }), + ("Количество", new WordTextProperties { Size = "24", Bold = true }), + ("Компоненты", new WordTextProperties { Size = "24", Bold = true }), + ("Количество", new WordTextProperties { Size = "24", Bold = true }) + } + }); + + var reportRecords = info.PurchaseComponent; + foreach (var reportRecord in reportRecords) + { + rows.Add(new WordRow + { + Rows = new List<(string, WordTextProperties)> + { + (reportRecord.Id.ToString(), new WordTextProperties { }), + ("", new WordTextProperties { }), + ("", new WordTextProperties { }), + ("", new WordTextProperties { }), + ("", new WordTextProperties { }) + } + }); + for (int i = 0; i < reportRecord.Builds.Count; i++) + { + rows.Add(new WordRow + { + Rows = new List<(string, WordTextProperties)> + { + ("", new WordTextProperties { }), + (reportRecord.Builds[i].Build, new WordTextProperties { }), + (reportRecord.Builds[i].count.ToString(), new WordTextProperties { }), + ("", new WordTextProperties { }), + ("", new WordTextProperties { }) + } + }); + for(int j = 0; j < reportRecord.Builds[i].Item3.Count; j++) + { + rows.Add(new WordRow + { + Rows = new List<(string, WordTextProperties)> + { + ("", new WordTextProperties { }), + ("", new WordTextProperties { }), + ("", new WordTextProperties { }), + (reportRecord.Builds[i].Item3[j].Component, new WordTextProperties { }), + (reportRecord.Builds[i].Item3[j].count.ToString(), new WordTextProperties { }) + } + }); + } + } + } + + CreateTable(rows); + + SaveWord(info); + } + + /// /// Создание doc-файла /// /// - protected abstract void CreateWord(WordInfo info); + protected abstract void CreateWord(WordInfo 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/ExcelInfo.cs b/HardwareShop/HardwareShopBusinessLogic/OfficePackage/HelperModels/ExcelInfo.cs index b85af0c..9c7156d 100644 --- a/HardwareShop/HardwareShopBusinessLogic/OfficePackage/HelperModels/ExcelInfo.cs +++ b/HardwareShop/HardwareShopBusinessLogic/OfficePackage/HelperModels/ExcelInfo.cs @@ -9,5 +9,7 @@ namespace HardwareShopBusinessLogic.OfficePackage.HelperModels public string Title { get; set; } = string.Empty; public List BuildGood { get; set; } = new(); - } + + public List PurchaseComponent { get; set; } = new(); + } } \ 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/HelperModels/WordInfo.cs b/HardwareShop/HardwareShopBusinessLogic/OfficePackage/HelperModels/WordInfo.cs index 2640fa6..fc62c87 100644 --- a/HardwareShop/HardwareShopBusinessLogic/OfficePackage/HelperModels/WordInfo.cs +++ b/HardwareShop/HardwareShopBusinessLogic/OfficePackage/HelperModels/WordInfo.cs @@ -9,5 +9,7 @@ namespace HardwareShopBusinessLogic.OfficePackage.HelperModels public string Title { get; set; } = string.Empty; public List BuildGood { get; set; } = new(); - } + + public List PurchaseComponent { get; set; } = new(); + } } \ 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..8ab2ecf --- /dev/null +++ b/HardwareShop/HardwareShopBusinessLogic/OfficePackage/Implements/SaveToPdf.cs @@ -0,0 +1,122 @@ +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); + } + + protected override byte[] GetFile(PdfInfo info) + { + SavePdf(info); + byte[] file = File.ReadAllBytes(info.FileName); + File.Delete(info.FileName); + return file; + } + } +} \ No newline at end of file diff --git a/HardwareShop/HardwareShopBusinessLogic/OfficePackage/Implements/SaveToWord.cs b/HardwareShop/HardwareShopBusinessLogic/OfficePackage/Implements/SaveToWord.cs index b3a6874..921eeb0 100644 --- a/HardwareShop/HardwareShopBusinessLogic/OfficePackage/Implements/SaveToWord.cs +++ b/HardwareShop/HardwareShopBusinessLogic/OfficePackage/Implements/SaveToWord.cs @@ -111,7 +111,7 @@ namespace HardwareShopBusinessLogic.OfficePackage.Implements TableGrid tableGrid = new TableGrid(); for (int j = 0; j < data[0].Rows.Count; ++j) { - tableGrid.AppendChild(new GridColumn() { Width = "3200" }); + tableGrid.AppendChild(new GridColumn() { Width = "1600" }); } table.AppendChild(tableGrid); for (int i = 0; i < data.Count; ++i) diff --git a/HardwareShop/HardwareShopContracts/BindingModels/MailSendInfoBindingModel.cs b/HardwareShop/HardwareShopContracts/BindingModels/MailSendInfoBindingModel.cs index 11301ec..0054e7c 100644 --- a/HardwareShop/HardwareShopContracts/BindingModels/MailSendInfoBindingModel.cs +++ b/HardwareShop/HardwareShopContracts/BindingModels/MailSendInfoBindingModel.cs @@ -7,5 +7,7 @@ public string Subject { get; set; } = string.Empty; public string Text { get; set; } = string.Empty; + + public byte[] File { get; set; } = Array.Empty(); } } \ No newline at end of file diff --git a/HardwareShop/HardwareShopContracts/BindingModels/PurchaseBindingModel.cs b/HardwareShop/HardwareShopContracts/BindingModels/PurchaseBindingModel.cs index ad97e96..d359473 100644 --- a/HardwareShop/HardwareShopContracts/BindingModels/PurchaseBindingModel.cs +++ b/HardwareShop/HardwareShopContracts/BindingModels/PurchaseBindingModel.cs @@ -31,5 +31,11 @@ namespace HardwareShopContracts.BindingModels get; set; } = new(); + + public List Purchases + { + get; + set; + } = new(); } } diff --git a/HardwareShop/HardwareShopContracts/BindingModels/ReportBindingModel.cs b/HardwareShop/HardwareShopContracts/BindingModels/ReportBindingModel.cs index 08b8b88..ff2da2e 100644 --- a/HardwareShop/HardwareShopContracts/BindingModels/ReportBindingModel.cs +++ b/HardwareShop/HardwareShopContracts/BindingModels/ReportBindingModel.cs @@ -2,12 +2,14 @@ { public class ReportBindingModel { + public string UserEmail { get; set; } = string.Empty; + public string FileName { get; set; } = string.Empty; + public DateTime DateFrom { get; set; } + + public DateTime DateTo { get; set; } + public int UserId { get; set; } - - public DateTime? DateFrom { get; set; } - - public DateTime? DateTo { get; set; } } } diff --git a/HardwareShop/HardwareShopContracts/BusinessLogicsContracts/IWorkerReportLogic.cs b/HardwareShop/HardwareShopContracts/BusinessLogicsContracts/IWorkerReportLogic.cs index 40d4205..920c70e 100644 --- a/HardwareShop/HardwareShopContracts/BusinessLogicsContracts/IWorkerReportLogic.cs +++ b/HardwareShop/HardwareShopContracts/BusinessLogicsContracts/IWorkerReportLogic.cs @@ -17,24 +17,24 @@ namespace HardwareShopContracts.BusinessLogicsContracts /// /// /// - List GetPurchase(ReportBindingModel model, UserBindingModel userModel); + List GetPurchase(ReportBindingModel model); /// /// Сохранение компонент с указаеним покупок в файл-Word /// /// - void SaveComponentsToWordFile(ReportBindingModel model); + byte[] SavePurchasesToWordFile(ReportBindingModel model, List purchases); /// /// Сохранение компонент с указаеним покупок в файл-Excel /// /// - void SaveDishComponentToExcelFile(ReportBindingModel model); + byte[] SavePurchasesToExcelFile(ReportBindingModel model, List purchases); /// /// Сохранение отчёта по покупкам в файл-Pdf /// /// - void SaveOrdersToPdfFile(ReportBindingModel model); + void 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/StoragesContracts/IPurchaseStorage.cs b/HardwareShop/HardwareShopContracts/StoragesContracts/IPurchaseStorage.cs index b140577..47283c8 100644 --- a/HardwareShop/HardwareShopContracts/StoragesContracts/IPurchaseStorage.cs +++ b/HardwareShop/HardwareShopContracts/StoragesContracts/IPurchaseStorage.cs @@ -11,7 +11,7 @@ namespace HardwareShopContracts.StoragesContracts List GetReportFilteredList(PurchaseSearchModel model); PurchaseViewModel? GetElement(PurchaseSearchModel model); PurchaseViewModel? Insert(PurchaseBindingModel model); - PurchaseViewModel? Update(PurchaseBindingModel model); + PurchaseViewModel? Update(PurchaseBindingModel model, bool withParams = true); PurchaseViewModel? Delete(PurchaseBindingModel model); } } 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/BuildStorage.cs b/HardwareShop/HardwareShopDatabaseImplement/Implements/Worker/BuildStorage.cs index 522a159..c1f9e7f 100644 --- a/HardwareShop/HardwareShopDatabaseImplement/Implements/Worker/BuildStorage.cs +++ b/HardwareShop/HardwareShopDatabaseImplement/Implements/Worker/BuildStorage.cs @@ -53,13 +53,15 @@ namespace HardwareShopDatabaseImplement.Implements.Worker return null; } using var context = new HardwareShopDatabase(); - return context.Builds + var dadada = context.Builds .Include(x => x.Purchases) .ThenInclude(x => x.Purchase) .FirstOrDefault(x => (!string.IsNullOrEmpty(model.BuildName) && x.BuildName == model.BuildName) || (model.Id.HasValue && x.Id == model.Id)) ?.GetViewModel; - } + return dadada; + + } public BuildViewModel? Insert(BuildBindingModel model) { diff --git a/HardwareShop/HardwareShopDatabaseImplement/Implements/Worker/PurchaseStorage.cs b/HardwareShop/HardwareShopDatabaseImplement/Implements/Worker/PurchaseStorage.cs index 513349f..610a11d 100644 --- a/HardwareShop/HardwareShopDatabaseImplement/Implements/Worker/PurchaseStorage.cs +++ b/HardwareShop/HardwareShopDatabaseImplement/Implements/Worker/PurchaseStorage.cs @@ -80,6 +80,13 @@ namespace HardwareShopDatabaseImplement.Implements.Worker return context.Purchases .Include(x => x.Goods) .ThenInclude(x => x.Good) + .Include(x => x.Builds) + .ThenInclude(x => x.Build) + .ThenInclude(x => x.Components) + .ThenInclude(x => x.Component) + .Include(x => x.Builds) + .ThenInclude(x => x.Build) + .ThenInclude(x => x.Comments) .FirstOrDefault(x => model.Id.HasValue && x.Id == model.Id) ?.GetViewModel; } @@ -101,7 +108,7 @@ namespace HardwareShopDatabaseImplement.Implements.Worker ?.GetViewModel; } - public PurchaseViewModel? Update(PurchaseBindingModel model) + public PurchaseViewModel? Update(PurchaseBindingModel model, bool withParams = true) { using var context = new HardwareShopDatabase(); using var transaction = context.Database.BeginTransaction(); @@ -117,7 +124,11 @@ namespace HardwareShopDatabaseImplement.Implements.Worker } purchase.Update(model); context.SaveChanges(); - purchase.UpdateGoods(context, model); + if (!withParams) { + transaction.Commit(); + return purchase.GetViewModel; + } + purchase.UpdateGoods(context, model); transaction.Commit(); return purchase.GetViewModel; } diff --git a/HardwareShop/HardwareShopRestApi/Controllers/BuildController.cs b/HardwareShop/HardwareShopRestApi/Controllers/BuildController.cs index a2ef62f..f10fe82 100644 --- a/HardwareShop/HardwareShopRestApi/Controllers/BuildController.cs +++ b/HardwareShop/HardwareShopRestApi/Controllers/BuildController.cs @@ -3,7 +3,10 @@ using HardwareShopContracts.BindingModels; using HardwareShopContracts.BusinessLogicsContracts; using HardwareShopContracts.SearchModels; using HardwareShopContracts.ViewModels; +using HardwareShopDatabaseImplement.Models.ManyToMany; +using HardwareShopDatabaseImplement.Models.Storekeeper; using HardwareShopDatabaseImplement.Models.Worker; +using HardwareShopDataModels.Enums; using HardwareShopDataModels.Models; using Microsoft.AspNetCore.Mvc; using System.ComponentModel; @@ -16,12 +19,15 @@ namespace HardwareShopRestApi.Controllers { private readonly ILogger _logger; private readonly IBuildLogic _buildLogic; + private readonly IPurchaseLogic _purchaseLogic; - public BuildController(IBuildLogic buildLogic, ILogger logger) + public BuildController(IBuildLogic buildLogic, IPurchaseLogic purchaseLogic, ILogger logger) { _logger = logger; _buildLogic = buildLogic; - } + _purchaseLogic = purchaseLogic; + + } [HttpGet] public List? GetBuilds(int userId = 0) @@ -56,7 +62,33 @@ namespace HardwareShopRestApi.Controllers } } - [HttpPost] + [HttpGet] + public List>? GetBuildPurchase(int buildId) + { + try + { + var result = _buildLogic.ReadElement(new() { Id = buildId }); + List> listPurchase = new List>(); + foreach (var item in result.BuildPurchases) + { + listPurchase.Add(Tuple.Create(new PurchaseViewModel + { + Id = item.Value.Item1.Id, + Sum = item.Value.Item1.Sum, + PurchaseStatus = item.Value.Item1.PurchaseStatus, + }, item.Value.Item2)); + } + return listPurchase; + + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка сборки"); + throw; + } + } + + [HttpPost] public void Create(BuildBindingModel model) { try @@ -70,7 +102,8 @@ namespace HardwareShopRestApi.Controllers } } - [HttpPost] + + [HttpPost] public void Update(BuildBindingModel model) { try @@ -84,7 +117,138 @@ namespace HardwareShopRestApi.Controllers } } - [HttpPost] + [HttpGet] + public bool LinkPurchase(int buildId, int purchaseId, int count) + { + try + { + var build = GetBuild(buildId);//APIClient.GetRequest($"api/build/getBuild?buildId={buildId}"); + var purchase = _purchaseLogic.ReadElement(new() { Id = purchaseId }); + if (purchase.PurchaseStatus == PurchaseStatus.Выдан) return false; + if (build.BuildPurchases.ContainsKey(purchaseId)) + { + + build.BuildPurchases[purchaseId] = (purchase, build.BuildPurchases[purchaseId].Item2 + count); + } + else + { + build.BuildPurchases.Add(purchaseId, (purchase as IPurchaseModel, count)); + } + Update(new BuildBindingModel + { + Id = buildId, + Price = build.Price, + BuildName = build.BuildName, + BuildPurchases = build.BuildPurchases + }); + purchase.Sum = Calc(purchase.Id); + _purchaseLogic.Update(new PurchaseBindingModel + { + Id = purchase.Id, + Sum = purchase.Sum, + PurchaseStatus = purchase.PurchaseStatus, + PurchaseGoods = purchase.PurchaseGoods, + }); + return true; + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка обновления данных"); + throw; + } + } + private double Calc(int purchaseId) + { + var purchase = _purchaseLogic.ReadElement(new() { Id = purchaseId }); + double price = 0; + foreach (var elem in purchase.PurchaseBuilds) + { + price += ((elem.Value.Item1?.Price ?? 0) * elem.Value.Item2); + } + foreach (var elem in purchase.PurchaseGoods) + { + price += ((elem.Value.Item1?.Price ?? 0) * elem.Value.Item2); + } + return Math.Round(price * 1.1, 2); + } + + [HttpGet] + public bool DeleteLinkPurchase(int deleteBuildId, int deletePurchaseId) + { + try + { + var build = GetBuild(deleteBuildId);//APIClient.GetRequest($"api/build/getBuild?buildId={buildId}"); + var purchase = _purchaseLogic.ReadElement(new() { Id = deletePurchaseId }); + if (purchase.PurchaseStatus == PurchaseStatus.Выдан) return false; + build.BuildPurchases.Remove(deletePurchaseId);//Add(purchaseId, (purchase as IPurchaseModel, count)); + + Update(new BuildBindingModel + { + Id = deleteBuildId, + Price = build.Price, + BuildName = build.BuildName, + BuildPurchases = build.BuildPurchases + }); + purchase.Sum = Calc(purchase.Id); + _purchaseLogic.Update(new PurchaseBindingModel + { + Id = purchase.Id, + Sum = purchase.Sum, + PurchaseStatus = purchase.PurchaseStatus, + DatePurchase = purchase.DatePurchase, + PurchaseGoods = purchase.PurchaseGoods, + }); + return true; + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка обновления данных"); + throw; + } + } + + [HttpGet] + public bool UpdateLinkPurchase(int updateBuildId, int updatePurchaseId, int count) + { + try + { + var build = GetBuild(updateBuildId);//APIClient.GetRequest($"api/build/getBuild?buildId={buildId}"); + var purchase = _purchaseLogic.ReadElement(new() { Id = updatePurchaseId }); + if (purchase.PurchaseStatus == PurchaseStatus.Выдан) return false; + if (build.BuildPurchases.ContainsKey(updatePurchaseId)) + { + build.BuildPurchases[updatePurchaseId] = (build.BuildPurchases[updatePurchaseId].Item1, count); + } + else + { + return false; + } + Update(new BuildBindingModel + { + Id = updateBuildId, + Price = build.Price, + BuildName = build.BuildName, + BuildPurchases = build.BuildPurchases + }); + purchase.Sum = Calc(purchase.Id); + _purchaseLogic.Update(new PurchaseBindingModel + { + Id = purchase.Id, + Sum = purchase.Sum, + PurchaseStatus = purchase.PurchaseStatus, + DatePurchase = purchase.DatePurchase, + PurchaseGoods = purchase.PurchaseGoods, + }); + return true; + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка обновления данных"); + throw; + } + } + + [HttpPost] public void DeleteBuild(BuildBindingModel model) { try diff --git a/HardwareShop/HardwareShopRestApi/Controllers/PurchaseController.cs b/HardwareShop/HardwareShopRestApi/Controllers/PurchaseController.cs index b97f1fe..06d0d52 100644 --- a/HardwareShop/HardwareShopRestApi/Controllers/PurchaseController.cs +++ b/HardwareShop/HardwareShopRestApi/Controllers/PurchaseController.cs @@ -3,6 +3,7 @@ using HardwareShopContracts.BusinessLogicsContracts; using HardwareShopContracts.SearchModels; using HardwareShopContracts.ViewModels; using HardwareShopDatabaseImplement.Models.Storekeeper; +using HardwareShopDataModels.Enums; using HardwareShopDataModels.Models; using HardwareShopRestApi.Controllers; using Microsoft.AspNetCore.Mvc; @@ -24,6 +25,30 @@ namespace HardwareShopRestApi.Controllers _purchaseLogic = purchaseLogic; } + [HttpGet] + public Tuple>>? GetPurchaseUpdate(int purchaseId) + { + try + { + var purchase = _purchaseLogic.ReadElement(new() { Id = purchaseId }); + if (purchase == null) + return null; + var tuple = Tuple.Create(purchase, + purchase.PurchaseGoods.Select(x => Tuple.Create(new GoodViewModel + { + Id = x.Value.Item1.Id, + GoodName = x.Value.Item1.GoodName, + Price = x.Value.Item1.Price + }, x.Value.Item2)).ToList()); + return tuple; + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка получения покупки"); + throw; + } + } + [HttpGet] public List? GetPurchases(int userId) { @@ -39,11 +64,11 @@ namespace HardwareShopRestApi.Controllers } [HttpGet] - public PurchaseViewModel? GetPurchase(int id) + public PurchaseViewModel? GetPurchase(int purchaseId) { try { - return _purchaseLogic.ReadElement(new() { Id = id }); + return _purchaseLogic.ReadElement(new() { Id = purchaseId }); } catch (Exception ex) { @@ -59,8 +84,7 @@ namespace HardwareShopRestApi.Controllers { for (int i = 0; i < model.PurchaseGoodsCounts.Count; i++) { - model.PurchaseGoods.Add(model.ListPurchaseGoods[i].Id, - (model.ListPurchaseGoods[i] as IGoodModel, model.PurchaseGoodsCounts[i])); + model.PurchaseGoods.Add(model.ListPurchaseGoods[i].Id,(model.ListPurchaseGoods[i] as IGoodModel, model.PurchaseGoodsCounts[i])); } _purchaseLogic.Create(model); } @@ -72,11 +96,15 @@ namespace HardwareShopRestApi.Controllers } [HttpPost] - public void UpdatePurchase(PurchaseBindingModel model) + public void UpdateStatusPurchase(PurchaseBindingModel model) { try { - _purchaseLogic.Update(model); + var oldModel = _purchaseLogic.ReadElement(new() { + Id = model.Id, + }); + model.Sum = oldModel.Sum; + _purchaseLogic.DeliveryPurchase(model); } catch (Exception ex) { @@ -85,6 +113,40 @@ namespace HardwareShopRestApi.Controllers } } + [HttpPost] + public void Update(PurchaseBindingModel model) + { + try + { + for (int i = 0; i < model.PurchaseGoodsCounts.Count; i++) + { + model.PurchaseGoods.Add(model.ListPurchaseGoods[i].Id, (model.ListPurchaseGoods[i] as IGoodModel, model.PurchaseGoodsCounts[i])); + } + model.PurchaseBuilds = _purchaseLogic.ReadElement(new() { Id = model.Id }).PurchaseBuilds; + model.Sum = Calc(model); + _purchaseLogic.Update(model); + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка обновления данных товара"); + throw; + } + } + + private double Calc(PurchaseBindingModel purchase) + { + double price = 0; + foreach (var elem in purchase.PurchaseBuilds) + { + price += ((elem.Value.Item1?.Price ?? 0) * elem.Value.Item2); + } + foreach (var elem in purchase.PurchaseGoods) + { + price += ((elem.Value.Item1?.Price ?? 0) * elem.Value.Item2); + } + return Math.Round(price * 1.1, 2); + } + [HttpPost] public void DeletePurchase(PurchaseBindingModel model) { diff --git a/HardwareShop/HardwareShopRestApi/Controllers/ReportController.cs b/HardwareShop/HardwareShopRestApi/Controllers/ReportController.cs index e0f97a4..3ca9f8a 100644 --- a/HardwareShop/HardwareShopRestApi/Controllers/ReportController.cs +++ b/HardwareShop/HardwareShopRestApi/Controllers/ReportController.cs @@ -1,4 +1,5 @@ -using HardwareShopContracts.BindingModels; +using DocumentFormat.OpenXml.Drawing; +using HardwareShopContracts.BindingModels; using HardwareShopContracts.BusinessLogicsContracts; using HardwareShopContracts.ViewModels; using Microsoft.AspNetCore.Mvc; @@ -75,5 +76,55 @@ namespace HardwareShopRestApi.Controllers throw; } } + + + [HttpPost] + public byte[] BuildPurchaseReport(PurchaseBindingModel model, string format) + { + try + { + byte[] file; + switch (format) + { + case "docx": + file = _reportWorkerLogic.SavePurchasesToWordFile(new ReportBindingModel { FileName = "temp.docx" }, model.Purchases); + break; + case "xlsx": + file = _reportWorkerLogic.SavePurchasesToExcelFile(new ReportBindingModel { FileName = "temp.xlsx" }, model.Purchases); + break; + default: + throw new FormatException("Неправильный формат файла"); + } + return file; + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка сохранения списка сборок по выбранным товарам"); + throw; + } + } + + + [HttpPost] + public List? GetPurchaseReportData(ReportBindingModel model) + { + try + { + var report = _reportWorkerLogic.GetPurchase(model); + return report; + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка получения данных для отчёта"); + throw; + } + } + + [HttpPost] + public void SendByMailPurchaseReport(ReportBindingModel reportModel) + { + _reportWorkerLogic.SendByMailPurchaseReport(reportModel); + } } + } diff --git a/HardwareShop/HardwareShopRestApi/Program.cs b/HardwareShop/HardwareShopRestApi/Program.cs index 6a1f113..d6f6f40 100644 --- a/HardwareShop/HardwareShopRestApi/Program.cs +++ b/HardwareShop/HardwareShopRestApi/Program.cs @@ -38,6 +38,7 @@ builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient(); +builder.Services.AddTransient(); builder.Services.AddSingleton(); builder.Services.AddControllers(); diff --git a/HardwareShop/HardwareShopWorkerApp/APIClient.cs b/HardwareShop/HardwareShopWorkerApp/APIClient.cs index 99eb654..f84e17f 100644 --- a/HardwareShop/HardwareShopWorkerApp/APIClient.cs +++ b/HardwareShop/HardwareShopWorkerApp/APIClient.cs @@ -46,5 +46,23 @@ namespace HardwareShopWorkerApp throw new Exception(result); } } - } + + public static R? PostRequestWithResult(string requestUrl, T model) + { + var json = JsonConvert.SerializeObject(model); + var data = new StringContent(json, Encoding.UTF8, "application/json"); + + var response = _client.PostAsync(requestUrl, data); + + var result = response.Result.Content.ReadAsStringAsync().Result; + if (response.Result.IsSuccessStatusCode) + { + return JsonConvert.DeserializeObject(result); + } + else + { + return default; + } + } + } } \ No newline at end of file diff --git a/HardwareShop/HardwareShopWorkerApp/Controllers/HomeController.cs b/HardwareShop/HardwareShopWorkerApp/Controllers/HomeController.cs index 205dda3..484b7bf 100644 --- a/HardwareShop/HardwareShopWorkerApp/Controllers/HomeController.cs +++ b/HardwareShop/HardwareShopWorkerApp/Controllers/HomeController.cs @@ -2,10 +2,15 @@ using HardwareShopContracts.SearchModels; using HardwareShopContracts.ViewModels; using HardwareShopDatabaseImplement.Models; +using HardwareShopDatabaseImplement.Models.ManyToMany; +using HardwareShopDatabaseImplement.Models.Storekeeper; +using HardwareShopDatabaseImplement.Models.Worker; using HardwareShopDataModels.Enums; +using HardwareShopDataModels.Models; using HardwareShopWorkerApp.Models; using Microsoft.AspNetCore.Mvc; using System.Diagnostics; +using System.IO.Pipelines; using static System.Net.Mime.MediaTypeNames; namespace HardwareShopWorkerApp.Controllers @@ -143,7 +148,29 @@ namespace HardwareShopWorkerApp.Controllers Response.Redirect("Builds"); } - + [HttpGet] + public void LinkBuildPurchase(int buildId, int purchaseId, int count) + { + if (APIClient.User == null) + { + throw new Exception("Вы как суда попали? Суда вход только авторизованным"); + } + if (buildId <= 0) + { + throw new Exception($"Идентификтаор сборки не может быть ниже или равен 0"); + } + if (purchaseId <= 0) + { + throw new Exception($"Идентификтаор покупки не может быть ниже или равен 0"); + } + if (count <= 0) + { + throw new Exception($"Количество сборок в покупке не может быть ниже или равен 0"); + } + APIClient.GetRequest($"api/build/linkPurchase?buildId={buildId}&purchaseId={purchaseId}&count={count}"); + Response.Redirect($"LinkPurchase?buildId={buildId}"); + } + [HttpPost] public void DeleteBuild(int deleteBuildId) { @@ -262,11 +289,6 @@ namespace HardwareShopWorkerApp.Controllers Response.Redirect("Comments"); } - public IActionResult listComponents() - { - return View(); - } - [HttpGet] public IActionResult Purchases() { @@ -298,6 +320,49 @@ namespace HardwareShopWorkerApp.Controllers return result; } + [HttpGet] + public IActionResult ListComponents() + { + if (APIClient.User == null) + { + return Redirect("~/Home/Enter"); + } + ViewBag.Purchases = APIClient.GetRequest>($"api/purchase/getpurchases?userId={APIClient.User.Id}"); + return View(); + } + + [HttpPost] + public int[]? ListComponents([FromBody] PurchaseBindingModel purchaseModel, [FromQuery] string format) + { + if (APIClient.User == null) + { + throw new Exception("Вы как сюда попали? Сюда вход только авторизованным"); + } + if (string.IsNullOrEmpty(format)) + { + throw new FormatException($"Неправильный формат файла: {format}"); + } + 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) + { + if (APIClient.User == null) + { + throw new Exception("Вы как сюда попали? Сюда вход только авторизованным"); + } + var result = APIClient.GetRequest($"api/purchase/getpurchase?purchaseId={Id}"); + if (result == null) + { + return default; + } + return result; + } + [HttpGet] public IActionResult CreatePurchase() { @@ -324,11 +389,79 @@ namespace HardwareShopWorkerApp.Controllers APIClient.PostRequest("api/purchase/createpurchase", purchaseModel); } + [HttpPost] + public void UpdateStatusPurchase(int id, int status) + { + if (APIClient.User == null) + { + throw new Exception("Вы как сюда попали? Сюда вход только авторизованным"); + } + if (id <= 0) + { + throw new Exception("Некорректный идентификатор"); + } + if (status <= 0) + { + throw new Exception("Некорректный статус"); + } + APIClient.PostRequest("api/purchase/UpdateStatusPurchase", new PurchaseBindingModel + { + Id = id, + PurchaseStatus = (PurchaseStatus)status + }); + } + + [HttpPost] + public void DeletePurchase(int purchaseId) + { + if (APIClient.User == null) + { + throw new Exception("Вы как сюда попали? Сюда вход только авторизованным"); + } + if (purchaseId <= 0) + { + throw new Exception("Некорректный идентификатор"); + } + var purchase = APIClient.GetRequest($"api/purchase/getpurchase?purchaseId={purchaseId}"); + APIClient.PostRequest("api/purchase/DeletePurchase", new PurchaseBindingModel + { + Id = purchaseId, + PurchaseStatus = purchase.PurchaseStatus + }); + } + [HttpGet] - public IActionResult WorkerReport() - { - return View(); - } + public IActionResult UpdatePurchase(int purchaseId) + { + if (APIClient.User == null) + { + throw new Exception("Вы как сюда попали? Сюда вход только авторизованным"); + } + ViewBag.Goods = APIClient.GetRequest>($"api/good/GetAllGoods"); + return View(purchaseId); + } + + [HttpPost] + public void UpdatePurchase([FromBody] PurchaseBindingModel purchaseModel) + { + if (APIClient.User == null) + { + throw new Exception("Вы как сюда попали? Сюда вход только авторизованным"); + } + purchaseModel.UserId = APIClient.User.Id; + APIClient.PostRequest("api/purchase/update", purchaseModel); + } + + [HttpGet] + public Tuple>>? GetPurchaseUpdate(int purchaseId) + { + if (APIClient.User == null) + { + throw new Exception("Вы как сюда попали? Сюда вход только авторизованным"); + } + var result = APIClient.GetRequest>>?>($"api/purchase/getpurchaseupdate?purchaseId={purchaseId}"); + return result; + } [HttpGet] public IActionResult Builds() @@ -347,9 +480,90 @@ namespace HardwareShopWorkerApp.Controllers } [HttpGet] - public IActionResult LinkPurchase() + public IActionResult LinkPurchase(int buildId) { + if (APIClient.User == null) + { + return Redirect("~/Home/Enter"); + } + if (buildId <= 0) + { + throw new Exception($"Идентификтаор сборки не может быть ниже или равен 0"); + } + ViewBag.Purchase = APIClient.GetRequest>($"api/purchase/getpurchases?userId={APIClient.User.Id}"); + return View(APIClient.GetRequest>>($"api/build/GetBuildPurchase?buildId={buildId}")); + } + + + [HttpGet] + public void DeleteLinkPurchase(int deleteBuildId, int deletePurchaseId) + { + if (APIClient.User == null) + { + throw new Exception("Вы как суда попали? Суда вход только авторизованным"); + } + if (deleteBuildId <= 0) + { + throw new Exception($"Идентификтаор сборки не может быть ниже или равен 0"); + } + if (deletePurchaseId <= 0) + { + throw new Exception($"Идентификтаор покупки не может быть ниже или равен 0"); + } + APIClient.GetRequest($"api/build/deleteLinkPurchase?deleteBuildId={deleteBuildId}&deletePurchaseId={deletePurchaseId}"); + Response.Redirect($"LinkPurchase?buildId={deleteBuildId}"); + } + + [HttpGet] + public void UpdateLinkPurchase(int updateBuildId, int updatePurchaseId, int count) + { + if (APIClient.User == null) + { + throw new Exception("Вы как суда попали? Суда вход только авторизованным"); + } + if (updateBuildId <= 0) + { + throw new Exception($"Идентификтаор сборки не может быть ниже или равен 0"); + } + if (updatePurchaseId <= 0) + { + throw new Exception($"Идентификтаор покупки не может быть ниже или равен 0"); + } + 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; + } + + [HttpPost] + public void SendByMailPurchaseReport([FromBody] ReportBindingModel reportModel) + { + if (APIClient.User == null) + { + return; + } + reportModel.UserId = APIClient.User.Id; + reportModel.UserEmail = APIClient.User.Email; + APIClient.PostRequest("api/report/SendByMailPurchaseReport", reportModel); + } } } \ No newline at end of file diff --git a/HardwareShop/HardwareShopWorkerApp/Views/Home/Builds.cshtml b/HardwareShop/HardwareShopWorkerApp/Views/Home/Builds.cshtml index 2f2d175..631ed28 100644 --- a/HardwareShop/HardwareShopWorkerApp/Views/Home/Builds.cshtml +++ b/HardwareShop/HardwareShopWorkerApp/Views/Home/Builds.cshtml @@ -55,9 +55,7 @@ - + diff --git a/HardwareShop/HardwareShopWorkerApp/Views/Home/CreatePurchase.cshtml b/HardwareShop/HardwareShopWorkerApp/Views/Home/CreatePurchase.cshtml index a999da5..0cb7236 100644 --- a/HardwareShop/HardwareShopWorkerApp/Views/Home/CreatePurchase.cshtml +++ b/HardwareShop/HardwareShopWorkerApp/Views/Home/CreatePurchase.cshtml @@ -24,6 +24,7 @@ Товар Количество Цена + Действие @@ -93,12 +94,21 @@ saveBtn.addEventListener("click", () => { console.log('try to add purchase') + console.log(list) + if (list.length == 0) { + alert('failed add good. components are empty') + return + } let goods = [] let counts = [] list.forEach((x) => { goods.push(x.good); counts.push(parseInt(x.count)) }) + console.log(JSON.stringify({ + "Sum": parseFloat(totalSum.value), + "ListPurchaseGoods": goods, "PurchaseGoodsCounts": counts + })); $.ajax( { url: `/Home/CreatePurchase`, @@ -106,7 +116,7 @@ contentType: 'application/json', data: JSON.stringify({ "Sum": parseFloat(totalSum.value), - "ListPurchaseGoods": goods + "ListPurchaseGoods": goods, "PurchaseGoodsCounts": counts }) } ).done(() => window.location.href = '/Home/Purchases') @@ -115,12 +125,25 @@ function reloadTable() { resultTable.innerHTML = '' let price = 0; + let count = 0; list.forEach((elem) => { + resultTable.innerHTML += `${elem.good.goodName}${elem.count}${Math.round(elem.good.price * elem.count * 100) / 100} \ +
\ + \ +
` + count++; console.log(elem); - resultTable.innerHTML += `${elem.good.goodName}${elem.count}${Math.round(elem.good.price * elem.count * 100) / 100}` price += elem.good.price * elem.count }) - totalSum.value = Math.round(price * 100) / 100 + totalSum.value = Math.round(price * 110) / 100 + console.log(totalSum.value); + } + + function deleteGood(id) { + list = list.filter(value => value.good.goodName != resultTable.rows[id].cells[0].innerText) + reloadTable() } diff --git a/HardwareShop/HardwareShopWorkerApp/Views/Home/LinkPurchase.cshtml b/HardwareShop/HardwareShopWorkerApp/Views/Home/LinkPurchase.cshtml index 74db850..2c23262 100644 --- a/HardwareShop/HardwareShopWorkerApp/Views/Home/LinkPurchase.cshtml +++ b/HardwareShop/HardwareShopWorkerApp/Views/Home/LinkPurchase.cshtml @@ -1,4 +1,184 @@ - +@using HardwareShopContracts.ViewModels; + +@model List> +@{ + ViewData["Title"] = "Привязка сборок"; + Layout = "~/Views/Shared/_LayoutWorker.cshtml"; +} + +
+

Привязка сборок

+
+ +
+ @{ +

+ +

+ + + + + + + + + + + + @foreach (var item in Model) + { + + + + + + + + } + +
+ Идентификатор покупки + + Цена + + Статус + + Количество сборок в заказе + + Действия +
+ @Html.DisplayFor(modelItem => item.Item1.Id) + + @Html.DisplayFor(modelItem => item.Item1.Sum) + + @Html.DisplayFor(modelItem => item.Item1.PurchaseStatus) + + @Html.DisplayFor(modelItem => item.Item2) + +
+ + + +
+
+ } +
+ + + + + + + +@section Scripts +{ + +} +@* @{ ViewData["Title"] = "LinkPurchase"; @@ -78,4 +258,4 @@ - \ No newline at end of file +*@ \ No newline at end of file diff --git a/HardwareShop/HardwareShopWorkerApp/Views/Home/Purchases.cshtml b/HardwareShop/HardwareShopWorkerApp/Views/Home/Purchases.cshtml index 245cb59..e21e699 100644 --- a/HardwareShop/HardwareShopWorkerApp/Views/Home/Purchases.cshtml +++ b/HardwareShop/HardwareShopWorkerApp/Views/Home/Purchases.cshtml @@ -16,15 +16,14 @@

Покупки

- Добавить - - - + Добавить + +

-
- +
+
@@ -100,10 +99,8 @@ var table = document.getElementById("table"); var remove = document.getElementById("delete"); - var inwork = document.getElementById("inwork"); - var ready = document.getElementById("ready"); var done = document.getElementById("done"); - var order = 0; + var purchase = 0; for (var i = 1; i < table.rows.length; i++) { table.rows[i].onclick = function () { // remove the background from the previous selected row @@ -114,46 +111,30 @@ index = this.rowIndex; // add class selected to the row this.classList.toggle("selected"); - order = parseInt(this.cells[0].innerText); + purchase = parseInt(this.cells[0].innerText); remove.addEventListener("click", () => { - console.log('try to delete order') + console.log('try to delete purchase') $.ajax( { - url: `/Storekeeper/DeleteOrder`, + url: `/Home/DeletePurchase`, type: 'POST', - data: { id: order } + data: { purchaseId: purchase } } - ) - }) - inwork.addEventListener("click", () => { - console.log('try to delete order') - $.ajax( - { - url: `/Storekeeper/UpdateOrder`, - type: 'POST', - data: { id: order, status: 1 } - } - ) - }) - ready.addEventListener("click", () => { - console.log('try to delete order') - $.ajax( - { - url: `/Storekeeper/UpdateOrder`, - type: 'POST', - data: { id: order, status: 2 } - } - ) + ).done(() => window.location.href = '/Home/Purchases') }) done.addEventListener("click", () => { - console.log('try to delete order') + console.log('try to delete purchase') $.ajax( { - url: `/Storekeeper/UpdateOrder`, + url: `/Home/UpdateStatusPurchase`, type: 'POST', - data: { id: order, status: 3 } + data: { id: purchase, status: 1 } } - ) + ).done(() => window.location.href = '/Home/Purchases') + }) + update.addEventListener("click", () => { + console.log('try to update purchase') + window.location.href = '/Home/UpdatePurchase?purchaseId=' + purchase }) }; } diff --git a/HardwareShop/HardwareShopWorkerApp/Views/Home/UpdatePurchase.cshtml b/HardwareShop/HardwareShopWorkerApp/Views/Home/UpdatePurchase.cshtml new file mode 100644 index 0000000..c150829 --- /dev/null +++ b/HardwareShop/HardwareShopWorkerApp/Views/Home/UpdatePurchase.cshtml @@ -0,0 +1,242 @@ +@using HardwareShopContracts.ViewModels +@model int +@{ + ViewData["Title"] = "UpdatePurchase"; + Layout = "~/Views/Shared/_LayoutWorker.cshtml"; +} + +
+

Редактирование покупки

+
+ +
+
+ + +
+

Товары

+
+ + +
+ + + + + + + + + + + +
ТоварКоличествоЦенаДействие
+
+ +
+
+ + + +@section Scripts + { + +} + + +@*
+
+
+

Товары

+
+
+ + + + + + + + + + + +
+ Номер + + Название товара + + Цена + + Количество +
+
+
+
+ + + + + +
+ +
+*@ \ No newline at end of file diff --git a/HardwareShop/HardwareShopWorkerApp/Views/Home/WorkerReport.cshtml b/HardwareShop/HardwareShopWorkerApp/Views/Home/WorkerReport.cshtml index 45096fa..5c263c2 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 diff --git a/HardwareShop/HardwareShopWorkerApp/Views/Home/listComponents.cshtml b/HardwareShop/HardwareShopWorkerApp/Views/Home/listComponents.cshtml index 34055ca..ea4942c 100644 --- a/HardwareShop/HardwareShopWorkerApp/Views/Home/listComponents.cshtml +++ b/HardwareShop/HardwareShopWorkerApp/Views/Home/listComponents.cshtml @@ -1,65 +1,153 @@ -@{ - ViewData["Title"] = "ListComponents"; +@using HardwareShopContracts.ViewModels +@{ + ViewData["Title"] = "Получение списка"; Layout = "~/Views/Shared/_LayoutWorker.cshtml"; } -
-
-
-

Покупки

-
-
- - - - - - - - - - - -
- Номер - - Дата оплаты - - Сумма - - Статус -
-
-
-
- - - - - -
+
+

Получение списка покупок

+
-