diff --git a/.gitignore b/.gitignore index ca1c7a3..f56d961 100644 --- a/.gitignore +++ b/.gitignore @@ -13,6 +13,10 @@ # User-specific files (MonoDevelop/Xamarin Studio) *.userprefs +# dll файлы +*.dll + +/SushiBar/ImplementationExtensions # Mono auto generated files mono_crash.* diff --git a/SushiBar/SushiBarBusinessLogic_/ComponentLogic.cs b/SushiBar/SushiBarBusinessLogic_/BusinessLogics/ComponentLogic.cs similarity index 100% rename from SushiBar/SushiBarBusinessLogic_/ComponentLogic.cs rename to SushiBar/SushiBarBusinessLogic_/BusinessLogics/ComponentLogic.cs diff --git a/SushiBar/SushiBarBusinessLogic_/BusinessLogics/OrderLogic.cs b/SushiBar/SushiBarBusinessLogic_/BusinessLogics/OrderLogic.cs new file mode 100644 index 0000000..e99a7c9 --- /dev/null +++ b/SushiBar/SushiBarBusinessLogic_/BusinessLogics/OrderLogic.cs @@ -0,0 +1,194 @@ +using Microsoft.Extensions.Logging; +using SushiBarContracts.BindingModels; +using SushiBarContracts.BusinessLogicsContracts; +using SushiBarContracts.SearchModels; +using SushiBarContracts.StoragesContracts; +using SushiBarContracts.ViewModels; +using SushiBarDataModels.Enums; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SushiBarBusinessLogic.BusinessLogics +{ + public class OrderLogic : IOrderLogic + { + + private readonly ILogger _logger; + private readonly IOrderStorage _orderStorage; + static readonly object _locker = new object(); + private readonly IShopStorage _shopStorage; + + public OrderLogic(ILogger logger, IOrderStorage orderStorage, IShopStorage shopStorage) + { + _logger = logger; + _orderStorage = orderStorage; + _shopStorage = shopStorage; + } + + public OrderViewModel? ReadElement(OrderSearchModel model) + { + if (model == null) + { + throw new ArgumentNullException(nameof(model)); + } + _logger.LogInformation("ReadElement. ClientId:{ClientId}.Status:{Status}.ImplementerId:{ImplementerId}.DateFrom:{DateFrom}.DateTo:{DateTo}OrderId:{Id}", + model.ClientId, model.Status, model.ImplementerId, model.DateFrom, model.DateTo, model.Id); + var element = _orderStorage.GetElement(model); + if (element == null) + { + _logger.LogWarning("ReadElement element not found"); + return null; + } + _logger.LogInformation("ReadElement find. Id:{Id}", element.Id); + return element; + } + + public List? ReadList(OrderSearchModel? model) + { + _logger.LogInformation("ReadList. ClientId:{ClientId}.Status:{Status}.ImplementerId:{ImplementerId}.DateFrom:{DateFrom}.DateTo:{DateTo}OrderId:{Id}", + model?.ClientId, model?.Status, model?.ImplementerId, model?.DateFrom, model?.DateTo, model?.Id); + var list = model == null ? _orderStorage.GetFullList() : _orderStorage.GetFilteredList(model); + if (list == null) + { + _logger.LogWarning("ReadList return null list"); + return null; + } + _logger.LogInformation("ReadList. Count:{Count}", list.Count); + return list; + } + + public bool CreateOrder(OrderBindingModel model) + { + CheckModel(model); + if (model.Status != OrderStatus.Неизвестен) + return false; + model.Status = OrderStatus.Принят; + if (_orderStorage.Insert(model) == null) + { + _logger.LogWarning("Insert operation failed"); + return false; + } + return true; + } + + public bool TakeOrderInWork(OrderBindingModel model) + { + lock (_locker) + { + return ChangeStatus(model, OrderStatus.Выполняется); + } + } + + public bool FinishOrder(OrderBindingModel model) + { + return ChangeStatus(model, OrderStatus.Готов); + } + + public bool DeliveryOrder(OrderBindingModel model) + { + lock (_locker) + { + model = FillOrderBindingModel(model); + if (model.Status != OrderStatus.Готов && model.Status != OrderStatus.Ожидает) + { + _logger.LogWarning("Changing status operation faled: Current-{Status}:required-Выдан.", model.Status); + throw new InvalidOperationException($"Невозможно приствоить статус выдан заказу с текущим статусом {model.Status}"); + } + if (!_shopStorage.RestockingShops(new SupplyBindingModel + { + SushiId = model.SushiId, + Count = model.Count + })) + { + if (model.Status == OrderStatus.Готов || model.Status == OrderStatus.Ожидает) + { + model.Status = OrderStatus.Ожидает; + return UpdateOrder(model); + } + } + model.Status = OrderStatus.Выдан; + return UpdateOrder(model); + } + } + + private void CheckModel(OrderBindingModel model, bool withParams = true) + { + if (model == null) + { + throw new ArgumentNullException(nameof(model)); + } + if (!withParams) + { + return; + } + if (model.Count <= 0) + { + throw new ArgumentException("Колличество пиццы в заказе не может быть меньше 1", nameof(model.Count)); + } + if (model.Sum <= 0) + { + throw new ArgumentException("Стоимость заказа на может быть меньше 1", nameof(model.Sum)); + } + if (model.DateImplement.HasValue && model.DateImplement < model.DateCreate) + { + throw new ArithmeticException($"Дата выдачи заказа {model.DateImplement} не может быть раньше даты его создания {model.DateCreate}"); + } + _logger.LogInformation("Sushi. SushiId:{SushiId}.Count:{Count}.Sum:{Sum}Id:{Id}", + model.SushiId, model.Count, model.Sum, model.Id); + } + private bool ChangeStatus(OrderBindingModel model, OrderStatus requiredStatus) + { + model = FillOrderBindingModel(model); + + if (requiredStatus - model.Status == 1) + { + model.Status = requiredStatus; + if (model.Status == OrderStatus.Готов) + model.DateImplement = DateTime.Now; + return UpdateOrder(model); + } + _logger.LogWarning("Changing status operation faled: Current-{Status}:required-{requiredStatus}.", model.Status, requiredStatus); + throw new InvalidOperationException($"Невозможно приствоить статус {requiredStatus} заказу с текущим статусом {model.Status}"); + } + + private OrderBindingModel FillOrderBindingModel(OrderBindingModel model) + { + CheckModel(model, false); + var element = _orderStorage.GetElement(new OrderSearchModel() + { + Id = model.Id + }); + if (element == null) + { + throw new InvalidOperationException(nameof(element)); + } + model.Id = element.Id; + model.DateCreate = element.DateCreate; + model.SushiId = element.SushiId; + model.DateImplement = element.DateImplement; + model.ClientId = element.ClientId; + model.Status = element.Status; + model.Count = element.Count; + model.Sum = element.Sum; + if (!model.ImplementerId.HasValue) + { + model.ImplementerId = element.ImplementerId; + } + return model; + } + + private bool UpdateOrder(OrderBindingModel model) + { + if (_orderStorage.Update(model) == null) + { + _logger.LogWarning("Update operation failed"); + return false; + } + _logger.LogWarning("Update operation sucsess"); + return true; + } + } + } diff --git a/SushiBar/SushiBarBusinessLogic_/ReportLogic.cs b/SushiBar/SushiBarBusinessLogic_/BusinessLogics/ReportLogic.cs similarity index 61% rename from SushiBar/SushiBarBusinessLogic_/ReportLogic.cs rename to SushiBar/SushiBarBusinessLogic_/BusinessLogics/ReportLogic.cs index 81ae29c..9f795ff 100644 --- a/SushiBar/SushiBarBusinessLogic_/ReportLogic.cs +++ b/SushiBar/SushiBarBusinessLogic_/BusinessLogics/ReportLogic.cs @@ -11,24 +11,25 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -namespace SushiBarBusinessLogic +namespace SushiBarBusinessLogic.BusinessLogics { public class ReportLogic : IReportLogic { private readonly IComponentStorage _componentStorage; private readonly ISushiStorage _SushiStorage; private readonly IOrderStorage _orderStorage; + private readonly IShopStorage _shopStorage; private readonly AbstractSaveToExcel _saveToExcel; private readonly AbstractSaveToWord _saveToWord; private readonly AbstractSaveToPdf _saveToPdf; - public ReportLogic(ISushiStorage SushiStorage, IComponentStorage componentStorage, IOrderStorage orderStorage, + public ReportLogic(ISushiStorage SushiStorage, IComponentStorage componentStorage, IOrderStorage orderStorage, IShopStorage shopStorage, AbstractSaveToExcel saveToExcel, AbstractSaveToWord saveToWord, AbstractSaveToPdf saveToPdf) { _SushiStorage = SushiStorage; _componentStorage = componentStorage; _orderStorage = orderStorage; - + _shopStorage = shopStorage; _saveToExcel = saveToExcel; _saveToWord = saveToWord; _saveToPdf = saveToPdf; @@ -89,5 +90,55 @@ namespace SushiBarBusinessLogic Orders = GetOrders(model) }); } + + public List GetShops() + { + return _shopStorage.GetFullList().Select(x => new ReportShopsViewModel + { + ShopName = x.ShopName, + Sushis = x.ShopSushis.Select(x => (x.Value.Item1.SushiName, x.Value.Item2)).ToList(), + TotalCount = x.ShopSushis.Select(x => x.Value.Item2).Sum() + }).ToList(); + } + + public List GetGroupedOrders() + { + return _orderStorage.GetFullList().GroupBy(x => x.DateCreate.Date).Select(x => new ReportGroupOrdersViewModel + { + Date = x.Key, + OrdersCount = x.Count(), + OrdersSum = x.Select(y => y.Sum).Sum() + }).ToList(); + } + + public void SaveShopsToWordFile(ReportBindingModel model) + { + _saveToWord.CreateShopsDoc(new WordShopInfo + { + FileName = model.FileName, + Title = "Список магазинов", + Shops = _shopStorage.GetFullList() + }); + } + + public void SaveShopsToExcelFile(ReportBindingModel model) + { + _saveToExcel.CreateShopSushisReport(new ExcelShop + { + FileName = model.FileName, + Title = "Наполненость магазинов", + ShopSushis = GetShops() + }); + } + + public void SaveGroupedOrdersToPdfFile(ReportBindingModel model) + { + _saveToPdf.CreateGroupedOrdersDoc(new PdfGroupedOrdersInfo + { + FileName = model.FileName, + Title = "Список заказов сгруппированных по дате заказов", + GroupedOrders = GetGroupedOrders() + }); + } } } diff --git a/SushiBar/SushiBarBusinessLogic_/BusinessLogics/ShopLogic.cs b/SushiBar/SushiBarBusinessLogic_/BusinessLogics/ShopLogic.cs new file mode 100644 index 0000000..f14617f --- /dev/null +++ b/SushiBar/SushiBarBusinessLogic_/BusinessLogics/ShopLogic.cs @@ -0,0 +1,186 @@ +using Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using SushiBarContracts.BindingModels; +using SushiBarContracts.BusinessLogicsContracts; +using SushiBarContracts.SearchModels; +using SushiBarContracts.StoragesContracts; +using SushiBarContracts.ViewModels; + +namespace SushiBarBusinessLogic.BusinessLogics +{ + public class ShopLogic : IShopLogic + { + private readonly ILogger _logger; + private readonly IShopStorage _shopStorage; + private readonly ISushiStorage _sushiStorage; + + public ShopLogic(ILogger logger, IShopStorage shopStorage, ISushiStorage sushiStorage) + { + _logger = logger; + _shopStorage = shopStorage; + _sushiStorage = sushiStorage; + } + + public List? ReadList(ShopSearchModel? model) + { + _logger.LogInformation("ReadList. ShopName:{ShopName}.Id:{ Id}", model?.ShopName, model?.Id); + var list = model == null ? _shopStorage.GetFullList() : _shopStorage.GetFilteredList(model); + if (list == null) + { + _logger.LogWarning("ReadList return null list"); + return null; + } + _logger.LogInformation("ReadList. Count:{Count}", list.Count); + return list; + } + + public ShopViewModel? ReadElement(ShopSearchModel model) + { + if (model == null) + { + throw new ArgumentNullException(nameof(model)); + } + _logger.LogInformation("ReadElement. ShopName:{ShopName}.Id:{ Id}", model.ShopName, model.Id); + var element = _shopStorage.GetElement(model); + if (element == null) + { + _logger.LogWarning("ReadElement element not found"); + return null; + } + _logger.LogInformation("ReadElement find. Id:{Id}", element.Id); + return element; + } + + public bool Create(ShopBindingModel model) + { + CheckModel(model); + if (_shopStorage.Insert(model) == null) + { + _logger.LogWarning("Insert operation failed"); + return false; + } + return true; + } + + public bool Update(ShopBindingModel model) + { + CheckModel(model); + if (_shopStorage.Update(model) == null) + { + _logger.LogWarning("Update operation failed"); + return false; + } + return true; + } + + public bool Delete(ShopBindingModel model) + { + CheckModel(model, false); + _logger.LogInformation("Delete. Id:{Id}", model.Id); + if (_shopStorage.Delete(model) == null) + { + _logger.LogWarning("Delete operation failed"); + return false; + } + return true; + } + + public bool MakeSupply(SupplyBindingModel model) + { + if (model == null) + { + throw new ArgumentNullException(nameof(model)); + } + if (model.Count <= 0) + { + throw new ArgumentException("Количество изделий должно быть больше 0"); + } + var shop = _shopStorage.GetElement(new ShopSearchModel + { + Id = model.ShopId + }); + if (shop == null) + { + throw new ArgumentException("Магазина не существует"); + } + if (shop.ShopSushis.ContainsKey(model.SushiId)) + { + var oldValue = shop.ShopSushis[model.SushiId]; + oldValue.Item2 += model.Count; + shop.ShopSushis[model.SushiId] = oldValue; + } + else + { + var sushi = _sushiStorage.GetElement(new SushiSearchModel + { + Id = model.SushiId + }); + if (sushi == null) + { + throw new ArgumentException($"Поставка: Товар с id:{model.SushiId} не найденн"); + } + shop.ShopSushis.Add(model.SushiId, (sushi, model.Count)); + } + + _shopStorage.Update(new ShopBindingModel() + { + Id = shop.Id, + ShopName = shop.ShopName, + Adress = shop.Adress, + OpeningDate = shop.OpeningDate, + ShopSushis = shop.ShopSushis, + SushiMaxCount = shop.SushiMaxCount, + }); + return true; + } + + private void CheckModel(ShopBindingModel model, bool withParams = true) + { + if (model == null) + { + throw new ArgumentNullException(nameof(model)); + } + if (!withParams) + { + return; + } + if (string.IsNullOrEmpty(model.Adress)) + { + throw new ArgumentException("Адрес магазина длжен быть заполнен", nameof(model.Adress)); + } + if (string.IsNullOrEmpty(model.ShopName)) + { + throw new ArgumentException("Название магазина должно быть заполнено", nameof(model.ShopName)); + } + _logger.LogInformation("Shop. ShopName:{ShopName}.Adres:{Adres}.OpeningDate:{OpeningDate}.Id:{ Id}", model.ShopName, model.Adress, model.OpeningDate, model.Id); + var element = _shopStorage.GetElement(new ShopSearchModel + { + ShopName = model.ShopName + }); + if (element != null && element.Id != model.Id) + { + throw new InvalidOperationException("Магазин с таким названием уже есть"); + } + } + + public bool Sale(SupplySearchModel model) + { + if (!model.SushiId.HasValue || !model.Count.HasValue) + { + return false; + } + _logger.LogInformation("Check sushi count in all shops"); + if (_shopStorage.Sale(model)) + { + _logger.LogInformation("Selling sucsess"); + return true; + } + _logger.LogInformation("Selling failed"); + return false; + } + } +} diff --git a/SushiBar/SushiBarBusinessLogic_/SushiLogic.cs b/SushiBar/SushiBarBusinessLogic_/BusinessLogics/SushiLogic.cs similarity index 93% rename from SushiBar/SushiBarBusinessLogic_/SushiLogic.cs rename to SushiBar/SushiBarBusinessLogic_/BusinessLogics/SushiLogic.cs index 339a27a..e9b39fc 100644 --- a/SushiBar/SushiBarBusinessLogic_/SushiLogic.cs +++ b/SushiBar/SushiBarBusinessLogic_/BusinessLogics/SushiLogic.cs @@ -92,11 +92,11 @@ namespace SushiBarBusinessLogic.BusinessLogics } if (string.IsNullOrEmpty(model.SushiName)) { - throw new ArgumentNullException("Нет названия пиццы", nameof(model.SushiName)); + throw new ArgumentNullException("Нет названия суши", nameof(model.SushiName)); } if (model.Price <= 0) { - throw new ArgumentNullException("Цена пиццы должна быть больше 0", nameof(model.Price)); + throw new ArgumentNullException("Цена суши должна быть больше 0", nameof(model.Price)); } if (model.SushiComponents == null || model.SushiComponents.Count == 0) { @@ -109,7 +109,7 @@ namespace SushiBarBusinessLogic.BusinessLogics }); if (element != null && element.Id != model.Id) { - throw new InvalidOperationException("Пицца с таким названием уже есть"); + throw new InvalidOperationException("Суши с таким названием уже есть"); } } } diff --git a/SushiBar/SushiBarBusinessLogic_/OfficePackage/AbstractSaveToExcel.cs b/SushiBar/SushiBarBusinessLogic_/OfficePackage/AbstractSaveToExcel.cs index 7c71989..dfe03e7 100644 --- a/SushiBar/SushiBarBusinessLogic_/OfficePackage/AbstractSaveToExcel.cs +++ b/SushiBar/SushiBarBusinessLogic_/OfficePackage/AbstractSaveToExcel.cs @@ -13,6 +13,7 @@ namespace SushiBarBusinessLogic.OfficePackage public void CreateReport(ExcelInfo info) { CreateExcel(info); + InsertCellInWorksheet(new ExcelCellParameters { ColumnName = "A", @@ -20,40 +21,46 @@ namespace SushiBarBusinessLogic.OfficePackage Text = info.Title, StyleInfo = ExcelStyleInfoType.Title }); + MergeCells(new ExcelMergeParameters { CellFromName = "A1", CellToName = "C1" }); + uint rowIndex = 2; - foreach (var sc in info.SushiComponents) + foreach (var pc in info.SushiComponents) { InsertCellInWorksheet(new ExcelCellParameters { ColumnName = "A", RowIndex = rowIndex, - Text = sc.SushiName, + Text = pc.SushiName, StyleInfo = ExcelStyleInfoType.Text }); rowIndex++; - foreach (var component in sc.Components) + + foreach (var (Component, Count) in pc.Components) { InsertCellInWorksheet(new ExcelCellParameters { ColumnName = "B", RowIndex = rowIndex, - Text = component.Item1, + Text = Component, StyleInfo = ExcelStyleInfoType.TextWithBroder }); + InsertCellInWorksheet(new ExcelCellParameters { ColumnName = "C", RowIndex = rowIndex, - Text = component.Item2.ToString(), + Text = Count.ToString(), StyleInfo = ExcelStyleInfoType.TextWithBroder }); + rowIndex++; } + InsertCellInWorksheet(new ExcelCellParameters { ColumnName = "A", @@ -65,33 +72,90 @@ namespace SushiBarBusinessLogic.OfficePackage { ColumnName = "C", RowIndex = rowIndex, - Text = sc.TotalCount.ToString(), + Text = pc.TotalCount.ToString(), StyleInfo = ExcelStyleInfoType.Text }); rowIndex++; } + SaveExcel(info); } - /// - /// Создание excel-файла - /// - /// - protected abstract void CreateExcel(ExcelInfo info); - /// - /// Добавляем новую ячейку в лист - /// - /// - protected abstract void InsertCellInWorksheet(ExcelCellParameters - excelParams); - /// - /// Объединение ячеек - /// - /// + + public void CreateShopSushisReport(ExcelShop info) + { + CreateExcel(info); + + InsertCellInWorksheet(new ExcelCellParameters + { + ColumnName = "A", + RowIndex = 1, + Text = info.Title, + StyleInfo = ExcelStyleInfoType.Title + }); + + MergeCells(new ExcelMergeParameters + { + CellFromName = "A1", + CellToName = "C1" + }); + + uint rowIndex = 2; + foreach (var sr in info.ShopSushis) + { + InsertCellInWorksheet(new ExcelCellParameters + { + ColumnName = "A", + RowIndex = rowIndex, + Text = sr.ShopName, + StyleInfo = ExcelStyleInfoType.Text + }); + rowIndex++; + + foreach (var (Sushi, Count) in sr.Sushis) + { + InsertCellInWorksheet(new ExcelCellParameters + { + ColumnName = "B", + RowIndex = rowIndex, + Text = Sushi, + StyleInfo = ExcelStyleInfoType.TextWithBroder + }); + + + InsertCellInWorksheet(new ExcelCellParameters + { + ColumnName = "C", + RowIndex = rowIndex, + Text = Count.ToString(), + StyleInfo = ExcelStyleInfoType.TextWithBroder + }); + + rowIndex++; + } + + InsertCellInWorksheet(new ExcelCellParameters + { + ColumnName = "A", + RowIndex = rowIndex, + Text = "Итого", + StyleInfo = ExcelStyleInfoType.Text + }); + InsertCellInWorksheet(new ExcelCellParameters + { + ColumnName = "C", + RowIndex = rowIndex, + Text = sr.TotalCount.ToString(), + StyleInfo = ExcelStyleInfoType.Text + }); + rowIndex++; + } + + SaveExcel(info); + } + + protected abstract void CreateExcel(IDocument info); + protected abstract void InsertCellInWorksheet(ExcelCellParameters excelParams); protected abstract void MergeCells(ExcelMergeParameters excelParams); - /// - /// Сохранение файла - /// - /// - protected abstract void SaveExcel(ExcelInfo info); + protected abstract void SaveExcel(IDocument info); } } diff --git a/SushiBar/SushiBarBusinessLogic_/OfficePackage/AbstractSaveToPdf.cs b/SushiBar/SushiBarBusinessLogic_/OfficePackage/AbstractSaveToPdf.cs index b3f0d21..1795203 100644 --- a/SushiBar/SushiBarBusinessLogic_/OfficePackage/AbstractSaveToPdf.cs +++ b/SushiBar/SushiBarBusinessLogic_/OfficePackage/AbstractSaveToPdf.cs @@ -13,67 +13,65 @@ namespace SushiBarBusinessLogic.OfficePackage 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 { "1cm", "3cm", "4cm", "6cm", "3cm" }); + 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 { "Номер", "Дата заказа", "Статус", "Изделие", "Сумма" }, + 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.Status.ToString(), order.SushiName, order.Sum.ToString() }, + Texts = new List { order.Id.ToString(), order.DateCreate.ToShortDateString(), order.SushiName, order.Status.ToString(), order.Sum.ToString() }, Style = "Normal", ParagraphAlignment = PdfParagraphAlignmentType.Left }); } - CreateParagraph(new PdfParagraph - { - Text = $"Итого: {info.Orders.Sum(x => x.Sum)}\t", - Style = "Normal", - ParagraphAlignment = PdfParagraphAlignmentType.Rigth - }); + CreateParagraph(new PdfParagraph { Text = $"Итого: {info.Orders.Sum(x => x.Sum)}\t", Style = "Normal", ParagraphAlignment = PdfParagraphAlignmentType.Rigth }); + SavePdf(info); } - /// - /// Создание doc-файла - /// - /// - protected abstract void CreatePdf(PdfInfo info); - /// - /// Создание параграфа с текстом - /// - /// - /// + + public void CreateGroupedOrdersDoc(PdfGroupedOrdersInfo info) + { + CreatePdf(info); + CreateParagraph(new PdfParagraph { Text = info.Title, Style = "NormalTitle", ParagraphAlignment = PdfParagraphAlignmentType.Center }); + + CreateTable(new List { "4cm", "3cm", "2cm" }); + CreateRow(new PdfRowParameters + { + Texts = new List { "Дата заказа", "Кол-во", "Сумма" }, + Style = "NormalTitle", + ParagraphAlignment = PdfParagraphAlignmentType.Center + }); + + + foreach (var groupedOrder in info.GroupedOrders) + { + CreateRow(new PdfRowParameters + { + Texts = new List { groupedOrder.Date.ToShortDateString(), groupedOrder.OrdersCount.ToString(), groupedOrder.OrdersSum.ToString() }, + Style = "Normal", + ParagraphAlignment = PdfParagraphAlignmentType.Left + }); + } + + CreateParagraph(new PdfParagraph { Text = $"Итого: {info.GroupedOrders.Sum(x => x.OrdersSum)}\t", Style = "Normal", ParagraphAlignment = PdfParagraphAlignmentType.Center }); + + SavePdf(info); + } + + protected abstract void CreatePdf(IDocument 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 void SavePdf(IDocument info); } } diff --git a/SushiBar/SushiBarBusinessLogic_/OfficePackage/AbstractSaveToWord.cs b/SushiBar/SushiBarBusinessLogic_/OfficePackage/AbstractSaveToWord.cs index bd162a0..3e15d25 100644 --- a/SushiBar/SushiBarBusinessLogic_/OfficePackage/AbstractSaveToWord.cs +++ b/SushiBar/SushiBarBusinessLogic_/OfficePackage/AbstractSaveToWord.cs @@ -38,21 +38,52 @@ namespace SushiBarBusinessLogic.OfficePackage } SaveWord(info); } - /// - /// Создание doc-файла - /// - /// - protected abstract void CreateWord(WordInfo info); - /// - /// Создание абзаца с текстом - /// - /// - /// + + public void CreateShopsDoc(WordShopInfo 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 + } + }); + + CreateTable(new List { "3000", "3000", "3000" }); + CreateRow(new WordRowParameters + { + Texts = new List { "Название", "Адрес", "Дата открытия" }, + TextProperties = new WordTextProperties + { + Size = "24", + Bold = true, + JustificationType = WordJustificationType.Center + } + }); + + foreach (var shop in info.Shops) + { + CreateRow(new WordRowParameters + { + Texts = new List { shop.ShopName, shop.Adress, shop.OpeningDate.ToString() }, + TextProperties = new WordTextProperties + { + Size = "22", + JustificationType = WordJustificationType.Both + } + }); + } + + SaveWord(info); + } + + protected abstract void CreateWord(IDocument info); protected abstract void CreateParagraph(WordParagraph paragraph); - /// - /// Сохранение файла - /// - /// - protected abstract void SaveWord(WordInfo info); + protected abstract void SaveWord(IDocument info); + protected abstract void CreateTable(List colums); + protected abstract void CreateRow(WordRowParameters rowParameters); } } \ No newline at end of file diff --git a/SushiBar/SushiBarBusinessLogic_/OfficePackage/HelperModels/ExcelInfo.cs b/SushiBar/SushiBarBusinessLogic_/OfficePackage/HelperModels/ExcelInfo.cs index d9b69b4..f4ea133 100644 --- a/SushiBar/SushiBarBusinessLogic_/OfficePackage/HelperModels/ExcelInfo.cs +++ b/SushiBar/SushiBarBusinessLogic_/OfficePackage/HelperModels/ExcelInfo.cs @@ -2,7 +2,7 @@ namespace SushiBarBusinessLogic.OfficePackage.HelperModels { - public class ExcelInfo + public class ExcelInfo : IDocument { public string FileName { get; set; } = string.Empty; public string Title { get; set; } = string.Empty; diff --git a/SushiBar/SushiBarBusinessLogic_/OfficePackage/HelperModels/ExcelShop.cs b/SushiBar/SushiBarBusinessLogic_/OfficePackage/HelperModels/ExcelShop.cs new file mode 100644 index 0000000..680c521 --- /dev/null +++ b/SushiBar/SushiBarBusinessLogic_/OfficePackage/HelperModels/ExcelShop.cs @@ -0,0 +1,16 @@ +using SushiBarContracts.ViewModels; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SushiBarBusinessLogic.OfficePackage.HelperModels +{ + public class ExcelShop : IDocument + { + public string FileName { get; set; } = string.Empty; + public string Title { get; set; } = string.Empty; + public List ShopSushis { get; set; } = new(); + } +} diff --git a/SushiBar/SushiBarBusinessLogic_/OfficePackage/HelperModels/PdfGroupedOrdersInfo.cs b/SushiBar/SushiBarBusinessLogic_/OfficePackage/HelperModels/PdfGroupedOrdersInfo.cs new file mode 100644 index 0000000..fbcc93d --- /dev/null +++ b/SushiBar/SushiBarBusinessLogic_/OfficePackage/HelperModels/PdfGroupedOrdersInfo.cs @@ -0,0 +1,18 @@ +using SushiBarContracts.ViewModels; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SushiBarBusinessLogic.OfficePackage.HelperModels +{ + public class PdfGroupedOrdersInfo : IDocument + { + 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 GroupedOrders { get; set; } = new(); + } +} diff --git a/SushiBar/SushiBarBusinessLogic_/OfficePackage/HelperModels/PdfInfo.cs b/SushiBar/SushiBarBusinessLogic_/OfficePackage/HelperModels/PdfInfo.cs index bf4b058..189cdd8 100644 --- a/SushiBar/SushiBarBusinessLogic_/OfficePackage/HelperModels/PdfInfo.cs +++ b/SushiBar/SushiBarBusinessLogic_/OfficePackage/HelperModels/PdfInfo.cs @@ -8,7 +8,7 @@ using System.Threading.Tasks; namespace SushiBarBusinessLogic.OfficePackage.HelperModels { - public class PdfInfo + public class PdfInfo : IDocument { public string FileName { get; set; } = string.Empty; public string Title { get; set; } = string.Empty; diff --git a/SushiBar/SushiBarBusinessLogic_/OfficePackage/HelperModels/WordInfo.cs b/SushiBar/SushiBarBusinessLogic_/OfficePackage/HelperModels/WordInfo.cs index 472a5aa..8e36208 100644 --- a/SushiBar/SushiBarBusinessLogic_/OfficePackage/HelperModels/WordInfo.cs +++ b/SushiBar/SushiBarBusinessLogic_/OfficePackage/HelperModels/WordInfo.cs @@ -2,7 +2,7 @@ namespace SushiBarBusinessLogic.OfficePackage.HelperModels { - public class WordInfo + public class WordInfo : IDocument { public string FileName { get; set; } = string.Empty; public string Title { get; set; } = string.Empty; diff --git a/SushiBar/SushiBarBusinessLogic_/OfficePackage/HelperModels/WordRowParameters.cs b/SushiBar/SushiBarBusinessLogic_/OfficePackage/HelperModels/WordRowParameters.cs new file mode 100644 index 0000000..2df1cd9 --- /dev/null +++ b/SushiBar/SushiBarBusinessLogic_/OfficePackage/HelperModels/WordRowParameters.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SushiBarBusinessLogic.OfficePackage.HelperModels +{ + public class WordRowParameters + { + public List Texts { get; set; } = new(); + public WordTextProperties TextProperties { get; set; } = new(); + } +} diff --git a/SushiBar/SushiBarBusinessLogic_/OfficePackage/HelperModels/WordShopInfo.cs b/SushiBar/SushiBarBusinessLogic_/OfficePackage/HelperModels/WordShopInfo.cs new file mode 100644 index 0000000..75515bf --- /dev/null +++ b/SushiBar/SushiBarBusinessLogic_/OfficePackage/HelperModels/WordShopInfo.cs @@ -0,0 +1,16 @@ +using SushiBarContracts.ViewModels; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SushiBarBusinessLogic.OfficePackage.HelperModels +{ + public class WordShopInfo : IDocument + { + public string FileName { get; set; } = string.Empty; + public string Title { get; set; } = string.Empty; + public List Shops { get; set; } = new(); + } +} diff --git a/SushiBar/SushiBarBusinessLogic_/OfficePackage/IDocument.cs b/SushiBar/SushiBarBusinessLogic_/OfficePackage/IDocument.cs new file mode 100644 index 0000000..14e64b9 --- /dev/null +++ b/SushiBar/SushiBarBusinessLogic_/OfficePackage/IDocument.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SushiBarBusinessLogic.OfficePackage +{ + public interface IDocument + { + public string FileName { get; set; } + public string Title { get; set; } + } +} diff --git a/SushiBar/SushiBarBusinessLogic_/OfficePackage/Implements/SaveToExcel.cs b/SushiBar/SushiBarBusinessLogic_/OfficePackage/Implements/SaveToExcel.cs index 99c7ee3..05ef135 100644 --- a/SushiBar/SushiBarBusinessLogic_/OfficePackage/Implements/SaveToExcel.cs +++ b/SushiBar/SushiBarBusinessLogic_/OfficePackage/Implements/SaveToExcel.cs @@ -14,167 +14,110 @@ namespace SushiBarBusinessLogic.OfficePackage.Implements private SpreadsheetDocument? _spreadsheetDocument; private SharedStringTablePart? _shareStringPart; private Worksheet? _worksheet; - /// - /// Настройка стилей для файла - /// - /// + private static void CreateStyles(WorkbookPart workbookpart) { var sp = workbookpart.AddNewPart(); sp.Stylesheet = new Stylesheet(); + var fonts = new Fonts() { Count = 2U, KnownFonts = true }; + var fontUsual = new Font(); fontUsual.Append(new FontSize() { Val = 12D }); - fontUsual.Append(new DocumentFormat.OpenXml.Office2010.Excel.Color() - { Theme = 1U }); + fontUsual.Append(new DocumentFormat.OpenXml.Office2010.Excel.Color() { Theme = 1U }); fontUsual.Append(new FontName() { Val = "Times New Roman" }); fontUsual.Append(new FontFamilyNumbering() { Val = 2 }); fontUsual.Append(new FontScheme() { Val = FontSchemeValues.Minor }); + var fontTitle = new Font(); fontTitle.Append(new Bold()); fontTitle.Append(new FontSize() { Val = 14D }); - fontTitle.Append(new DocumentFormat.OpenXml.Office2010.Excel.Color() - { Theme = 1U }); + fontTitle.Append(new DocumentFormat.OpenXml.Office2010.Excel.Color() { Theme = 1U }); fontTitle.Append(new FontName() { Val = "Times New Roman" }); fontTitle.Append(new FontFamilyNumbering() { Val = 2 }); fontTitle.Append(new FontScheme() { Val = FontSchemeValues.Minor }); + fonts.Append(fontUsual); fonts.Append(fontTitle); + var fills = new Fills() { Count = 2U }; + var fill1 = new Fill(); fill1.Append(new PatternFill() { PatternType = PatternValues.None }); + var fill2 = new Fill(); - fill2.Append(new PatternFill() - { - PatternType = PatternValues.Gray125 - }); + fill2.Append(new PatternFill() { PatternType = PatternValues.Gray125 }); + fills.Append(fill1); fills.Append(fill2); + var borders = new Borders() { Count = 2U }; + var borderNoBorder = new Border(); borderNoBorder.Append(new LeftBorder()); borderNoBorder.Append(new RightBorder()); borderNoBorder.Append(new TopBorder()); borderNoBorder.Append(new BottomBorder()); borderNoBorder.Append(new DiagonalBorder()); + var borderThin = new Border(); + var leftBorder = new LeftBorder() { Style = BorderStyleValues.Thin }; - leftBorder.Append(new DocumentFormat.OpenXml.Office2010.Excel.Color() - { Indexed = 64U }); - var rightBorder = new RightBorder() - { - Style = BorderStyleValues.Thin - }; - rightBorder.Append(new - DocumentFormat.OpenXml.Office2010.Excel.Color() - { Indexed = 64U }); + leftBorder.Append(new DocumentFormat.OpenXml.Office2010.Excel.Color() { Indexed = 64U }); + + var rightBorder = new RightBorder() { Style = BorderStyleValues.Thin }; + rightBorder.Append(new DocumentFormat.OpenXml.Office2010.Excel.Color() { Indexed = 64U }); + var topBorder = new TopBorder() { Style = BorderStyleValues.Thin }; - topBorder.Append(new DocumentFormat.OpenXml.Office2010.Excel.Color() - { Indexed = 64U }); - var bottomBorder = new BottomBorder() - { - Style = - BorderStyleValues.Thin - }; - bottomBorder.Append(new - DocumentFormat.OpenXml.Office2010.Excel.Color() - { Indexed = 64U }); + topBorder.Append(new DocumentFormat.OpenXml.Office2010.Excel.Color() { Indexed = 64U }); + + var bottomBorder = new BottomBorder() { Style = BorderStyleValues.Thin }; + bottomBorder.Append(new DocumentFormat.OpenXml.Office2010.Excel.Color() { Indexed = 64U }); + borderThin.Append(leftBorder); borderThin.Append(rightBorder); borderThin.Append(topBorder); borderThin.Append(bottomBorder); borderThin.Append(new DiagonalBorder()); + borders.Append(borderNoBorder); borders.Append(borderThin); + var cellStyleFormats = new CellStyleFormats() { Count = 1U }; - var cellFormatStyle = new CellFormat() - { - NumberFormatId = 0U, - FontId - = 0U, - FillId = 0U, - BorderId = 0U - }; + var cellFormatStyle = new CellFormat() { NumberFormatId = 0U, FontId = 0U, FillId = 0U, BorderId = 0U }; + cellStyleFormats.Append(cellFormatStyle); + var cellFormats = new CellFormats() { Count = 3U }; - var cellFormatFont = new CellFormat() - { - NumberFormatId = 0U, - FontId = - 0U, - FillId = 0U, - BorderId = 0U, - FormatId = 0U, - ApplyFont = true - }; - var cellFormatFontAndBorder = new CellFormat() - { - NumberFormatId = 0U, - FontId = 0U, - FillId = 0U, - BorderId = 1U, - FormatId = 0U, - ApplyFont = true, - ApplyBorder = true - }; - var cellFormatTitle = new CellFormat() - { - NumberFormatId = 0U, - FontId - = 1U, - FillId = 0U, - BorderId = 0U, - FormatId = 0U, - Alignment = new Alignment() - { - Vertical = VerticalAlignmentValues.Center, - WrapText = true, - Horizontal = - HorizontalAlignmentValues.Center - }, - ApplyFont = true - }; + var cellFormatFont = new CellFormat() { NumberFormatId = 0U, FontId = 0U, FillId = 0U, BorderId = 0U, FormatId = 0U, ApplyFont = true }; + var cellFormatFontAndBorder = new CellFormat() { NumberFormatId = 0U, FontId = 0U, FillId = 0U, BorderId = 1U, FormatId = 0U, ApplyFont = true, ApplyBorder = true }; + var cellFormatTitle = new CellFormat() { NumberFormatId = 0U, FontId = 1U, FillId = 0U, BorderId = 0U, FormatId = 0U, Alignment = new Alignment() { Vertical = VerticalAlignmentValues.Center, WrapText = true, Horizontal = HorizontalAlignmentValues.Center }, ApplyFont = true }; + cellFormats.Append(cellFormatFont); cellFormats.Append(cellFormatFontAndBorder); cellFormats.Append(cellFormatTitle); - var cellStyles = new CellStyles() { Count = 1U }; - cellStyles.Append(new CellStyle() - { - Name = "Normal", - FormatId = 0U, - BuiltinId = 0U - }); - var differentialFormats = new - DocumentFormat.OpenXml.Office2013.Excel.DifferentialFormats() - { Count = 0U }; - var tableStyles = new TableStyles() - { - Count = 0U, - DefaultTableStyle = "TableStyleMedium2", - DefaultPivotStyle = "PivotStyleLight16" - }; + var cellStyles = new CellStyles() { Count = 1U }; + + cellStyles.Append(new CellStyle() { Name = "Normal", FormatId = 0U, BuiltinId = 0U }); + + var differentialFormats = new DocumentFormat.OpenXml.Office2013.Excel.DifferentialFormats() { Count = 0U }; + + var tableStyles = new TableStyles() { Count = 0U, DefaultTableStyle = "TableStyleMedium2", DefaultPivotStyle = "PivotStyleLight16" }; + var stylesheetExtensionList = new StylesheetExtensionList(); - var stylesheetExtension1 = new StylesheetExtension() - { - Uri = "{EB79DEF2-80B8-43e5-95BD-54CBDDF9020C}" - }; + + var stylesheetExtension1 = new StylesheetExtension() { Uri = "{EB79DEF2-80B8-43e5-95BD-54CBDDF9020C}" }; stylesheetExtension1.AddNamespaceDeclaration("x14", "http://schemas.microsoft.com/office/spreadsheetml/2009/9/main"); - stylesheetExtension1.Append(new SlicerStyles() - { - DefaultSlicerStyle = "SlicerStyleLight1" - }); - var stylesheetExtension2 = new StylesheetExtension() - { - Uri = "{9260A510-F301-46a8-8635-F512D64BE5F5}" - }; + stylesheetExtension1.Append(new SlicerStyles() { DefaultSlicerStyle = "SlicerStyleLight1" }); + + var stylesheetExtension2 = new StylesheetExtension() { Uri = "{9260A510-F301-46a8-8635-F512D64BE5F5}" }; stylesheetExtension2.AddNamespaceDeclaration("x15", "http://schemas.microsoft.com/office/spreadsheetml/2010/11/main"); - stylesheetExtension2.Append(new TimelineStyles() - { - DefaultTimelineStyle = "TimeSlicerStyleLight1" - }); + stylesheetExtension2.Append(new TimelineStyles() { DefaultTimelineStyle = "TimeSlicerStyleLight1" }); + stylesheetExtensionList.Append(stylesheetExtension1); stylesheetExtensionList.Append(stylesheetExtension2); + sp.Stylesheet.Append(fonts); sp.Stylesheet.Append(fills); sp.Stylesheet.Append(borders); @@ -185,11 +128,7 @@ namespace SushiBarBusinessLogic.OfficePackage.Implements sp.Stylesheet.Append(tableStyles); sp.Stylesheet.Append(stylesheetExtensionList); } - /// - /// Получение номера стиля из типа - /// - /// - /// + private static uint GetStyleValue(ExcelStyleInfoType styleInfo) { return styleInfo switch @@ -200,40 +139,44 @@ namespace SushiBarBusinessLogic.OfficePackage.Implements _ => 0U, }; } - protected override void CreateExcel(ExcelInfo info) + + protected override void CreateExcel(IDocument info) { - _spreadsheetDocument = SpreadsheetDocument.Create(info.FileName, - SpreadsheetDocumentType.Workbook); + _spreadsheetDocument = SpreadsheetDocument.Create(info.FileName, SpreadsheetDocumentType.Workbook); + // Создаем книгу (в ней хранятся листы) var workbookpart = _spreadsheetDocument.AddWorkbookPart(); workbookpart.Workbook = new Workbook(); + CreateStyles(workbookpart); - _shareStringPart = - _spreadsheetDocument.WorkbookPart!.GetPartsOfType().Any() - ? - _spreadsheetDocument.WorkbookPart.GetPartsOfType().First() - : - _spreadsheetDocument.WorkbookPart.AddNewPart(); + + // Получаем/создаем хранилище текстов для книги + _shareStringPart = _spreadsheetDocument.WorkbookPart!.GetPartsOfType().Any() + ? _spreadsheetDocument.WorkbookPart.GetPartsOfType().First() + : _spreadsheetDocument.WorkbookPart.AddNewPart(); + // Создаем SharedStringTable, если его нет if (_shareStringPart.SharedStringTable == null) { _shareStringPart.SharedStringTable = new SharedStringTable(); } + // Создаем лист в книгу var worksheetPart = workbookpart.AddNewPart(); worksheetPart.Worksheet = new Worksheet(new SheetData()); + // Добавляем лист в книгу - var sheets = - _spreadsheetDocument.WorkbookPart.Workbook.AppendChild(new Sheets()); + var sheets = _spreadsheetDocument.WorkbookPart.Workbook.AppendChild(new Sheets()); var sheet = new Sheet() { - Id = - _spreadsheetDocument.WorkbookPart.GetIdOfPart(worksheetPart), + Id = _spreadsheetDocument.WorkbookPart.GetIdOfPart(worksheetPart), SheetId = 1, Name = "Лист" }; sheets.Append(sheet); + _worksheet = worksheetPart.Worksheet; } + protected override void InsertCellInWorksheet(ExcelCellParameters excelParams) { if (_worksheet == null || _shareStringPart == null) @@ -245,6 +188,7 @@ namespace SushiBarBusinessLogic.OfficePackage.Implements { return; } + // Ищем строку, либо добавляем ее Row row; if (sheetData.Elements().Where(r => r.RowIndex! == excelParams.RowIndex).Any()) @@ -256,7 +200,8 @@ namespace SushiBarBusinessLogic.OfficePackage.Implements row = new Row() { RowIndex = excelParams.RowIndex }; sheetData.Append(row); } - // Ищем нужную ячейку + + // Ищем нужную ячейку Cell cell; if (row.Elements().Where(c => c.CellReference!.Value == excelParams.CellReference).Any()) { @@ -275,20 +220,22 @@ namespace SushiBarBusinessLogic.OfficePackage.Implements break; } } - var newCell = new Cell() - { - CellReference = excelParams.CellReference - }; + + var newCell = new Cell() { CellReference = excelParams.CellReference }; row.InsertBefore(newCell, refCell); + cell = newCell; } + // вставляем новый текст _shareStringPart.SharedStringTable.AppendChild(new SharedStringItem(new Text(excelParams.Text))); _shareStringPart.SharedStringTable.Save(); + cell.CellValue = new CellValue((_shareStringPart.SharedStringTable.Elements().Count() - 1).ToString()); cell.DataType = new EnumValue(CellValues.SharedString); cell.StyleIndex = GetStyleValue(excelParams.StyleInfo); } + protected override void MergeCells(ExcelMergeParameters excelParams) { if (_worksheet == null) @@ -296,6 +243,7 @@ namespace SushiBarBusinessLogic.OfficePackage.Implements return; } MergeCells mergeCells; + if (_worksheet.Elements().Any()) { mergeCells = _worksheet.Elements().First(); @@ -303,24 +251,25 @@ namespace SushiBarBusinessLogic.OfficePackage.Implements else { mergeCells = new MergeCells(); + if (_worksheet.Elements().Any()) { - _worksheet.InsertAfter(mergeCells, - _worksheet.Elements().First()); + _worksheet.InsertAfter(mergeCells, _worksheet.Elements().First()); } else { - _worksheet.InsertAfter(mergeCells, - _worksheet.Elements().First()); + _worksheet.InsertAfter(mergeCells, _worksheet.Elements().First()); } } + var mergeCell = new MergeCell() { Reference = new StringValue(excelParams.Merge) }; mergeCells.Append(mergeCell); } - protected override void SaveExcel(ExcelInfo info) + + protected override void SaveExcel(IDocument info) { if (_spreadsheetDocument == null) { diff --git a/SushiBar/SushiBarBusinessLogic_/OfficePackage/Implements/SaveToPdf.cs b/SushiBar/SushiBarBusinessLogic_/OfficePackage/Implements/SaveToPdf.cs index a5840f7..ed10be5 100644 --- a/SushiBar/SushiBarBusinessLogic_/OfficePackage/Implements/SaveToPdf.cs +++ b/SushiBar/SushiBarBusinessLogic_/OfficePackage/Implements/SaveToPdf.cs @@ -11,6 +11,7 @@ namespace SushiBarBusinessLogic.OfficePackage.Implements private Document? _document; private Section? _section; private Table? _table; + private static ParagraphAlignment GetParagraphAlignment(PdfParagraphAlignmentType type) { return type switch @@ -21,24 +22,25 @@ namespace SushiBarBusinessLogic.OfficePackage.Implements _ => 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) + + protected override void CreatePdf(IDocument info) { _document = new Document(); DefineStyles(_document); + _section = _document.AddSection(); } + protected override void CreateParagraph(PdfParagraph pdfParagraph) { if (_section == null) @@ -50,6 +52,7 @@ namespace SushiBarBusinessLogic.OfficePackage.Implements paragraph.Format.Alignment = GetParagraphAlignment(pdfParagraph.ParagraphAlignment); paragraph.Style = pdfParagraph.Style; } + protected override void CreateTable(List columns) { if (_document == null) @@ -57,11 +60,13 @@ namespace SushiBarBusinessLogic.OfficePackage.Implements return; } _table = _document.LastSection.AddTable(); + foreach (var elem in columns) { _table.AddColumn(elem); } } + protected override void CreateRow(PdfRowParameters rowParameters) { if (_table == null) @@ -72,20 +77,25 @@ namespace SushiBarBusinessLogic.OfficePackage.Implements 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) + + protected override void SavePdf(IDocument info) { var renderer = new PdfDocumentRenderer(true) { @@ -95,4 +105,4 @@ namespace SushiBarBusinessLogic.OfficePackage.Implements renderer.PdfDocument.Save(info.FileName); } } -} \ No newline at end of file +} \ No newline at end of file diff --git a/SushiBar/SushiBarBusinessLogic_/OfficePackage/Implements/SaveToWord.cs b/SushiBar/SushiBarBusinessLogic_/OfficePackage/Implements/SaveToWord.cs index 6c1fc93..0e5ffa3 100644 --- a/SushiBar/SushiBarBusinessLogic_/OfficePackage/Implements/SaveToWord.cs +++ b/SushiBar/SushiBarBusinessLogic_/OfficePackage/Implements/SaveToWord.cs @@ -11,13 +11,8 @@ namespace SushiBarBusinessLogic.OfficePackage.Implements { private WordprocessingDocument? _wordDocument; private Body? _docBody; - /// - /// Получение типа выравнивания - /// - /// - /// - private static JustificationValues - GetJustificationValues(WordJustificationType type) + + private static JustificationValues GetJustificationValues(WordJustificationType type) { return type switch { @@ -26,59 +21,60 @@ namespace SushiBarBusinessLogic.OfficePackage.Implements _ => JustificationValues.Left, }; } - /// - /// Настройки страницы - /// - /// + private static SectionProperties CreateSectionProperties() { var properties = new SectionProperties(); + var pageSize = new PageSize { Orient = PageOrientationValues.Portrait }; + properties.AppendChild(pageSize); + return properties; } - /// - /// Задание форматирования для абзаца - /// - /// - /// + private static ParagraphProperties? CreateParagraphProperties(WordTextProperties? paragraphProperties) { if (paragraphProperties == null) { return null; } + var properties = new ParagraphProperties(); + properties.AppendChild(new Justification() { Val = GetJustificationValues(paragraphProperties.JustificationType) }); + properties.AppendChild(new SpacingBetweenLines { LineRule = LineSpacingRuleValues.Auto }); + properties.AppendChild(new Indentation()); + var paragraphMarkRunProperties = new ParagraphMarkRunProperties(); if (!string.IsNullOrEmpty(paragraphProperties.Size)) { - paragraphMarkRunProperties.AppendChild(new FontSize - { - Val = paragraphProperties.Size - }); + paragraphMarkRunProperties.AppendChild(new FontSize { Val = paragraphProperties.Size }); } properties.AppendChild(paragraphMarkRunProperties); + return properties; } - protected override void CreateWord(WordInfo info) + + protected override void CreateWord(IDocument info) { _wordDocument = WordprocessingDocument.Create(info.FileName, WordprocessingDocumentType.Document); MainDocumentPart mainPart = _wordDocument.AddMainDocumentPart(); mainPart.Document = new Document(); _docBody = mainPart.Document.AppendChild(new Body()); } + protected override void CreateParagraph(WordParagraph paragraph) { if (_docBody == null || paragraph == null) @@ -88,9 +84,11 @@ namespace SushiBarBusinessLogic.OfficePackage.Implements var docParagraph = new Paragraph(); docParagraph.AppendChild(CreateParagraphProperties(paragraph.TextProperties)); + foreach (var run in paragraph.Texts) { var docRun = new Run(); + var properties = new RunProperties(); properties.AppendChild(new FontSize { Val = run.Item2.Size }); if (run.Item2.Bold) @@ -98,24 +96,97 @@ namespace SushiBarBusinessLogic.OfficePackage.Implements properties.AppendChild(new Bold()); } docRun.AppendChild(properties); - docRun.AppendChild(new Text - { - Text = run.Item1, - Space = SpaceProcessingModeValues.Preserve - }); + + docRun.AppendChild(new Text { Text = run.Item1, Space = SpaceProcessingModeValues.Preserve }); + docParagraph.AppendChild(docRun); } + _docBody.AppendChild(docParagraph); } - protected override void SaveWord(WordInfo info) + + protected override void SaveWord(IDocument info) { if (_docBody == null || _wordDocument == null) { return; } _docBody.AppendChild(CreateSectionProperties()); + _wordDocument.MainDocumentPart!.Document.Save(); _wordDocument.Dispose(); } + + private Table? _lastTable; + protected override void CreateTable(List columns) + { + if (_docBody == null) + return; + + _lastTable = new Table(); + + var tableProp = new TableProperties(); + tableProp.AppendChild(new TableLayout { Type = TableLayoutValues.Fixed }); + tableProp.AppendChild(new TableBorders( + new TopBorder() { Val = new EnumValue(BorderValues.Single), Size = 4 }, + new LeftBorder() { Val = new EnumValue(BorderValues.Single), Size = 4 }, + new RightBorder() { Val = new EnumValue(BorderValues.Single), Size = 4 }, + new BottomBorder() { Val = new EnumValue(BorderValues.Single), Size = 4 }, + new InsideHorizontalBorder() { Val = new EnumValue(BorderValues.Single), Size = 4 }, + new InsideVerticalBorder() { Val = new EnumValue(BorderValues.Single), Size = 4 } + )); + tableProp.AppendChild(new TableWidth { Type = TableWidthUnitValues.Auto }); + _lastTable.AppendChild(tableProp); + + TableGrid tableGrid = new TableGrid(); + foreach (var column in columns) + { + tableGrid.AppendChild(new GridColumn() { Width = column }); + } + _lastTable.AppendChild(tableGrid); + + _docBody.AppendChild(_lastTable); + } + + protected override void CreateRow(WordRowParameters rowParameters) + { + if (_docBody == null || _lastTable == null) + return; + + TableRow docRow = new TableRow(); + foreach (var column in rowParameters.Texts) + { + var docParagraph = new Paragraph(); + WordParagraph paragraph = new WordParagraph + { + Texts = new List<(string, WordTextProperties)> { (column, rowParameters.TextProperties) }, + TextProperties = rowParameters.TextProperties + }; + + docParagraph.AppendChild(CreateParagraphProperties(paragraph.TextProperties)); + + foreach (var run in paragraph.Texts) + { + var docRun = new Run(); + + var properties = new RunProperties(); + properties.AppendChild(new FontSize { Val = run.Item2.Size }); + if (run.Item2.Bold) + { + properties.AppendChild(new Bold()); + } + docRun.AppendChild(properties); + + docRun.AppendChild(new Text { Text = run.Item1, Space = SpaceProcessingModeValues.Preserve }); + + docParagraph.AppendChild(docRun); + } + + TableCell docCell = new TableCell(); + docCell.AppendChild(docParagraph); + docRow.AppendChild(docCell); + } + _lastTable.AppendChild(docRow); + } } } diff --git a/SushiBar/SushiBarBusinessLogic_/WorkModeling .cs b/SushiBar/SushiBarBusinessLogic_/WorkModeling .cs index 14802a4..39a5b00 100644 --- a/SushiBar/SushiBarBusinessLogic_/WorkModeling .cs +++ b/SushiBar/SushiBarBusinessLogic_/WorkModeling .cs @@ -36,7 +36,8 @@ namespace SushiBarBusinessLogic return; } var orders = _orderLogic.ReadList(new OrderSearchModel { Status = OrderStatus.Принят }); - if (orders == null || orders.Count == 0) + + if (orders == null ) { _logger.LogWarning("DoWork. Orders is null or empty"); return; @@ -54,7 +55,8 @@ namespace SushiBarBusinessLogic { return; } - await RunOrderInWork(implementer); + await DeliverWaitingOrder(implementer); + await RunOrderInWork(implementer); await Task.Run(() => { @@ -76,7 +78,8 @@ namespace SushiBarBusinessLogic { Id = order.Id }); - } + _orderLogic.DeliveryOrder(new OrderBindingModel { Id = order.Id }); + } // кто-то мог уже перехватить заказ, игнорируем ошибку catch (InvalidOperationException ex) { @@ -135,5 +138,47 @@ namespace SushiBarBusinessLogic throw; } } - } + + private async Task DeliverWaitingOrder(ImplementerViewModel implementer) + { + if (_orderLogic == null || implementer == null) + { + return; + } + var waitingOrders = await Task.Run(() => _orderLogic.ReadList(new OrderSearchModel + { + ImplementerId = implementer.Id, + Status = OrderStatus.Ожидает + })); + if (waitingOrders == null || waitingOrders.Count == 0) + { + return; + } + _logger.LogInformation("DeliverWaitingOrder. Find some waitig order for implementer:{id}.Count:{count}", implementer.Id, waitingOrders.Count); + foreach (var waitingOrder in waitingOrders) + { + try + { + _logger.LogInformation("DeliverWaitingOrder. Trying to deliver order id:{id}", waitingOrder.Id); + var res = _orderLogic.DeliveryOrder(new OrderBindingModel + { + Id = waitingOrder.Id + }); + } + catch (ArgumentException ex) + { + _logger.LogWarning(ex, "DeliverWaitingOrder. Fault"); + } + catch (InvalidOperationException ex) + { + _logger.LogWarning(ex, "Error try deliver order"); + } + catch (Exception ex) + { + _logger.LogError(ex, "Error while do work"); + throw; + } + } + } + } } diff --git a/SushiBar/SushiBarClientApp/APIClient.cs b/SushiBar/SushiBarClientApp/APIClient.cs index 83268e4..dbebe39 100644 --- a/SushiBar/SushiBarClientApp/APIClient.cs +++ b/SushiBar/SushiBarClientApp/APIClient.cs @@ -10,14 +10,16 @@ namespace SushiBarClientApp public class APIClient { private static readonly HttpClient _client = new(); - public static ClientViewModel? Client { get; set; } = null; + + public static string? Password { get; set; } + public static void Connect(IConfiguration configuration) { _client.BaseAddress = new Uri(configuration["IPAddress"]); _client.DefaultRequestHeaders.Accept.Clear(); - _client.DefaultRequestHeaders.Accept.Add(new - MediaTypeWithQualityHeaderValue("application/json")); + _client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); } + public static T? GetRequest(string requestUrl) { var response = _client.GetAsync(requestUrl); @@ -31,12 +33,24 @@ namespace SushiBarClientApp throw new Exception(result); } } + public static void PostRequest(string requestUrl, T model) { var json = JsonConvert.SerializeObject(model); - var data = new StringContent(json, Encoding.UTF8, - "application/json"); + 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) + { + throw new Exception(result); + } + } + + public static void DeleteRequest(string requestUrl) + { + var response = _client.DeleteAsync(requestUrl); var result = response.Result.Content.ReadAsStringAsync().Result; if (!response.Result.IsSuccessStatusCode) { @@ -44,5 +58,5 @@ namespace SushiBarClientApp } } } - } + diff --git a/SushiBar/SushiBarClientApp/Controllers/HomeController.cs b/SushiBar/SushiBarClientApp/Controllers/HomeController.cs index 35552d9..ab3ec11 100644 --- a/SushiBar/SushiBarClientApp/Controllers/HomeController.cs +++ b/SushiBar/SushiBarClientApp/Controllers/HomeController.cs @@ -11,6 +11,145 @@ namespace SushiBarClientApp.Controllers public class HomeController : Controller { private readonly ILogger _logger; + + public HomeController(ILogger logger) + { + _logger = logger; + } + + public IActionResult Index() + { + if (APIClient.Password == null) + { + return Redirect("~/Home/Enter"); + } + return View(APIClient.GetRequest>($"api/shop/getshoplist?password={APIClient.Password}")); + } + + [HttpGet] + public IActionResult Enter() + { + return View(); + } + + [HttpPost] + public void Enter(string password) + { + bool resout = APIClient.GetRequest($"/api/shop/authentication?password={password}"); + if (!resout) + { + Response.Redirect("../Home/Enter"); + return; + } + APIClient.Password = password; + Response.Redirect("Index"); + } + + [HttpGet] + public IActionResult Create() + { + if (APIClient.Password == null) + { + return Redirect("~/Home/Enter"); + } + return View("Shop"); + } + + [HttpPost] + public void Create(int id, string shopname, string adress, DateTime openingdate, int maxcount) + { + if (string.IsNullOrEmpty(shopname) || string.IsNullOrEmpty(adress)) + { + throw new Exception("Название или адрес не может быть пустым"); + } + if (openingdate == default(DateTime)) + { + throw new Exception("Дата открытия не может быть пустой"); + } + + APIClient.PostRequest($"api/shop/createshop?password={APIClient.Password}", new ShopBindingModel + { + Id = id, + ShopName = shopname, + Adress = adress, + OpeningDate = openingdate, + SushiMaxCount = maxcount + }); + Response.Redirect("Index"); + } + + [HttpGet] + public IActionResult Update(int Id) + { + if (APIClient.Password == null) + { + return Redirect("~/Home/Enter"); + } + return View("Shop", APIClient.GetRequest($"api/shop/getshop?shopId={Id}&password={APIClient.Password}")); + } + + [HttpPost] + public void Update(int id, string shopname, string adress, DateTime openingdate, int maxcount) + { + if (string.IsNullOrEmpty(shopname) || string.IsNullOrEmpty(adress)) + { + throw new Exception("Название или адрес не может быть пустым"); + } + if (openingdate == default(DateTime)) + { + throw new Exception("Дата открытия не может быть пустой"); + } + APIClient.PostRequest($"api/shop/updateshop?password={APIClient.Password}", new ShopBindingModel + { + Id = id, + ShopName = shopname, + Adress = adress, + OpeningDate = openingdate, + SushiMaxCount = maxcount + }); + Response.Redirect("../Index"); + } + + [HttpPost] + public void Delete(int Id) + { + APIClient.DeleteRequest($"api/shop/deleteshop?shopId={Id}&password={APIClient.Password}"); + Response.Redirect("../Index"); + } + + [HttpGet] + public IActionResult Supply() + { + if (APIClient.Password == null) + { + return Redirect("~/Home/Enter"); + } + + ViewBag.Shops = APIClient.GetRequest>($"api/shop/getshoplist?password={APIClient.Password}"); + ViewBag.Sushis = APIClient.GetRequest>($"api/main/getsushilist"); + return View(); + } + + [HttpPost] + public void Supply(int shop, int sushi, int count) + { + APIClient.PostRequest($"api/shop/makesypply?password={APIClient.Password}", new SupplyBindingModel + { + ShopId = shop, + SushiId = sushi, + Count = count + }); + Response.Redirect("Index"); + } + + [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] + public IActionResult Error() + { + return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier }); + } + } +} + private readonly ILogger _logger; public HomeController(ILogger logger) { _logger = logger; diff --git a/SushiBar/SushiBarClientApp/Views/Home/Index.cshtml b/SushiBar/SushiBarClientApp/Views/Home/Index.cshtml index 843135f..b669ca6 100644 --- a/SushiBar/SushiBarClientApp/Views/Home/Index.cshtml +++ b/SushiBar/SushiBarClientApp/Views/Home/Index.cshtml @@ -1,75 +1,68 @@ @using SushiBarContracts.ViewModels -@model List +@model List @{ ViewData["Title"] = "Home Page"; }
-

Заказы

+

Магазины

-
- @{ - if (Model == null) - { -

Авторизируйтесь

- return; - } +
+

+ Создать магазин +

-

- Создать заказ -

- - - - - - - - - - - - - @foreach (var item in Model) - { - - - - - - - - - } - -
- Номер - - Суши - - Дата создания - - Количество - - Сумма - - Статус -
- @Html.DisplayFor(modelItem => item.Id) - - @Html.DisplayFor(modelItem => item.SushiName) - - @Html.DisplayFor(modelItem => item.DateCreate) - - @Html.DisplayFor(modelItem => item.Count) - - @Html.DisplayFor(modelItem => item.Sum) - - @Html.DisplayFor(modelItem => item.Status) -
- } + + + + + + + + + + + + + @foreach (var item in Model) + { + + + + + + + + + } + +
+ Номер + + Название + + Адрес + + Дата открытия + + Максимальная вместимость + + +
+ @Html.DisplayFor(modelItem => item.Id) + + @Html.DisplayFor(modelItem => item.ShopName) + + @Html.DisplayFor(modelItem => item.Adress) + + @Html.DisplayFor(modelItem => item.OpeningDate) + + @Html.DisplayFor(modelItem => item.SushiMaxCount) + + Изменить +
\ No newline at end of file diff --git a/SushiBar/SushiBarClientApp/Views/Home/Shop.cshtml b/SushiBar/SushiBarClientApp/Views/Home/Shop.cshtml new file mode 100644 index 0000000..3c7dca9 --- /dev/null +++ b/SushiBar/SushiBarClientApp/Views/Home/Shop.cshtml @@ -0,0 +1,74 @@ +@using SushiBarDataModels.Models; +@using SushiBarContracts.ViewModels; + @model ShopSushiViewModel + +@{ + ViewData["Title"] = "Shop"; +} + +
+ @{ + if (Model == null) + { +

Создание магазина

+ } + else + { +

Изменение магазина

+ } + } +
+ +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + @{ + if (Model != null && Model.Shop != null) + { + + } + } +
+
+@{ + if (Model != null && Model.Shop != null) + { +
+
Содержимое магазина
+
+ + + + + + + + + @foreach (var item in Model.ShopSushi) + { + + + + + } + + +
НазваниеКоличество
@Html.DisplayFor(modelItem => item.Value.Sushi.SushiName)@Html.DisplayFor(modelItem => item.Value.Count)
+ } +} \ No newline at end of file diff --git a/SushiBar/SushiBarClientApp/Views/Home/Supply.cshtml b/SushiBar/SushiBarClientApp/Views/Home/Supply.cshtml new file mode 100644 index 0000000..a5a73ae --- /dev/null +++ b/SushiBar/SushiBarClientApp/Views/Home/Supply.cshtml @@ -0,0 +1,22 @@ +@{ + ViewData["Title"] = "Supply"; +} +
+

Создание поставки

+
+
+
+ + +
+
+ + +
+
+ + +
+ + Отмена +
diff --git a/SushiBar/SushiBarClientApp/Views/Shared/_Layout.cshtml b/SushiBar/SushiBarClientApp/Views/Shared/_Layout.cshtml index d2b20db..33fa0a2 100644 --- a/SushiBar/SushiBarClientApp/Views/Shared/_Layout.cshtml +++ b/SushiBar/SushiBarClientApp/Views/Shared/_Layout.cshtml @@ -14,15 +14,15 @@