diff --git a/ElectronicsShop/ElectronicsShopBusinessLogic/BusinessLogic/ReportLogic.cs b/ElectronicsShop/ElectronicsShopBusinessLogic/BusinessLogic/ReportLogic.cs new file mode 100644 index 0000000..dcc80c3 --- /dev/null +++ b/ElectronicsShop/ElectronicsShopBusinessLogic/BusinessLogic/ReportLogic.cs @@ -0,0 +1,88 @@ +using ElectronicsShopBusinessLogic.OfficePackage.HelperModels; +using ElectronicsShopBusinessLogic.OfficePackage; +using ElectronicsShopContracts.SearchModels; +using ElectronicsShopContracts.StorageContracts; +using ElectronicsShopContracts.ViewModels; +using ElectronicsShopContracts.BindingModels; +using ElectronicsShopContracts.BusinessLogicContracts; + + +namespace ElectronicsShopBusinessLogic.BusinessLogic +{ + public class ReportLogic : IReportLogic + { + + private readonly IProductStorage _productStorage; + + private readonly IOrderStorage _orderStorage; + + private readonly AbstractSaveToExcel _saveToExcel; + + private readonly AbstractSaveToWord _saveToWord; + + public ReportLogic(IProductStorage productStorage, IOrderStorage orderStorage, + AbstractSaveToExcel saveToExcel, AbstractSaveToWord saveToWord) + { + _productStorage = productStorage; + _orderStorage = orderStorage; + + _saveToExcel = saveToExcel; + _saveToWord = saveToWord; + } + + public List GetProduct() + { + var productsList = _productStorage.GetFullList(); + + var list = new List(); + + foreach (var product in productsList) + { + var record = new ReportProductsViewModel + { + CostItemID = product.CostItemID, + ProductName = product.ProductName, + Price = product.Price, + CostItemName = product.CostItemName, + }; + list.Add(record); + } + return list; + } + + public List GetOrders(ReportBindingModel model) + { + return _orderStorage.GetFilteredList(new OrderSearchModel { DateFrom = model.DateFrom, DateTo = model.DateTo }) + .Select(x => new ReportOrdersVeiwModel + { + ID = x.ID, + ClientID = x.ClientID, + DateCreate = x.DateCreate, + ProductList = x.ProductList, + Sum = x.Sum + }) + .ToList(); + } + + public void SaveListToWordFile(ReportBindingModel model) + { + _saveToWord.CreateDoc(new WordInfo + { + FileName = model.FileName, + Title = "Список продуктов", + ListProduct = _productStorage.GetFullList() + }); + } + + public void SaveProductToExcelFile(ReportBindingModel model) + { + _saveToExcel.CreateReport(new ExcelInfo + { + FileName = model.FileName, + Title = "Список Заказов", + Orders = GetOrders(model),// мейби нет + }); + } + } +} + diff --git a/ElectronicsShop/ElectronicsShopBusinessLogic/ElectronicsShopBusinessLogic.csproj b/ElectronicsShop/ElectronicsShopBusinessLogic/ElectronicsShopBusinessLogic.csproj index 39bc039..45686b4 100644 --- a/ElectronicsShop/ElectronicsShopBusinessLogic/ElectronicsShopBusinessLogic.csproj +++ b/ElectronicsShop/ElectronicsShopBusinessLogic/ElectronicsShopBusinessLogic.csproj @@ -7,7 +7,11 @@ + + + + diff --git a/ElectronicsShop/ElectronicsShopBusinessLogic/MailWorker/AbstractMailWorker.cs b/ElectronicsShop/ElectronicsShopBusinessLogic/MailWorker/AbstractMailWorker.cs new file mode 100644 index 0000000..277c91d --- /dev/null +++ b/ElectronicsShop/ElectronicsShopBusinessLogic/MailWorker/AbstractMailWorker.cs @@ -0,0 +1,100 @@ +using ElectronicsShopContracts.BindingModels; +using ElectronicsShopContracts.BusinessLogicContracts; +using Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ElectronicsShopBusinessLogic.MailWorker +{ + public abstract class AbstractMailWorker + { + protected string _mailLogin = string.Empty; + + protected string _mailPassword = string.Empty; + + protected string _smtpClientHost = string.Empty; + + protected int _smtpClientPort; + + protected string _popHost = string.Empty; + + protected int _popPort; + + private readonly IMessageInfoLogic _messageInfoLogic; + private readonly IClientLogic _clientLogic; + + private readonly ILogger _logger; + + public AbstractMailWorker(ILogger logger, IMessageInfoLogic messageInfoLogic, IClientLogic clientLogic) + { + _logger = logger; + _messageInfoLogic = messageInfoLogic; + _clientLogic = clientLogic; + } + + public void MailConfig(MailConfigBindingModel config) + { + _mailLogin = config.MailLogin; + _mailPassword = config.MailPassword; + _smtpClientHost = config.SmtpClientHost; + _smtpClientPort = config.SmtpClientPort; + _popHost = config.PopHost; + _popPort = config.PopPort; + _logger.LogDebug("Config: {login}, {password}, {clientHost}, {clientPOrt}, {popHost}, {popPort}", _mailLogin, _mailPassword, _smtpClientHost, _smtpClientPort, _popHost, _popPort); + } + + public async void MailSendAsync(MailSendInfoBindingModel info) + { + if (string.IsNullOrEmpty(_mailLogin) || string.IsNullOrEmpty(_mailPassword)) + { + return; + } + + if (string.IsNullOrEmpty(_smtpClientHost) || _smtpClientPort == 0) + { + return; + } + + if (string.IsNullOrEmpty(info.MailAddress) || string.IsNullOrEmpty(info.Subject) || string.IsNullOrEmpty(info.Text)) + { + return; + } + + _logger.LogDebug("Send Mail: {To}, {Subject}", info.MailAddress, info.Subject); + await SendMailAsync(info); + } + + public async void MailCheck() + { + if (string.IsNullOrEmpty(_mailLogin) || string.IsNullOrEmpty(_mailPassword)) + { + return; + } + + if (string.IsNullOrEmpty(_popHost) || _popPort == 0) + { + return; + } + + if (_messageInfoLogic == null) + { + return; + } + + var list = await ReceiveMailAsync(); + _logger.LogDebug("Check Mail: {Count} new mails", list.Count); + foreach (var mail in list) + { + mail.ClientID = _clientLogic.ReadElemet(new() { Email = mail.SenderName })?.ID; + _messageInfoLogic.Create(mail); + } + } + + protected abstract Task SendMailAsync(MailSendInfoBindingModel info); + + protected abstract Task> ReceiveMailAsync(); + } +} diff --git a/ElectronicsShop/ElectronicsShopBusinessLogic/MailWorker/MailKitWorker.cs b/ElectronicsShop/ElectronicsShopBusinessLogic/MailWorker/MailKitWorker.cs new file mode 100644 index 0000000..47760c5 --- /dev/null +++ b/ElectronicsShop/ElectronicsShopBusinessLogic/MailWorker/MailKitWorker.cs @@ -0,0 +1,84 @@ +using ElectronicsShopContracts.BusinessLogicContracts; +using Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net.Mail; +using System.Net; +using System.Text; +using System.Threading.Tasks; +using ElectronicsShopContracts.BindingModels; +using MailKit.Net.Pop3; +using MailKit.Security; + +namespace ElectronicsShopBusinessLogic.MailWorker +{ + public class MailKitWorker : AbstractMailWorker + { + public MailKitWorker(ILogger logger, IMessageInfoLogic messageInfoLogic, IClientLogic clientLogic) : base(logger, messageInfoLogic, clientLogic) { } + + protected override async Task SendMailAsync(MailSendInfoBindingModel info) + { + using var objMailMessage = new MailMessage(); + using var objSmtpClient = new SmtpClient(_smtpClientHost, _smtpClientPort); + try + { + objMailMessage.From = new MailAddress(_mailLogin); + objMailMessage.To.Add(new MailAddress(info.MailAddress)); + objMailMessage.Subject = info.Subject; + objMailMessage.Body = info.Text; + objMailMessage.SubjectEncoding = Encoding.UTF8; + objMailMessage.BodyEncoding = Encoding.UTF8; + + objSmtpClient.UseDefaultCredentials = false; + objSmtpClient.EnableSsl = true; + objSmtpClient.DeliveryMethod = SmtpDeliveryMethod.Network; + objSmtpClient.Credentials = new NetworkCredential(_mailLogin, _mailPassword); + + await Task.Run(() => objSmtpClient.Send(objMailMessage)); + } + catch (Exception) + { + throw; + } + } + + protected override async Task> ReceiveMailAsync() + { + var list = new List(); + using var client = new Pop3Client(); + await Task.Run(() => + { + try + { + client.Connect(_popHost, _popPort, SecureSocketOptions.SslOnConnect); + client.Authenticate(_mailLogin, _mailPassword); + for (int i = 0; i < client.Count; i++) + { + var message = client.GetMessage(i); + foreach (var mail in message.From.Mailboxes) + { + list.Add(new MessageInfoBindingModel + { + DateDelivery = message.Date.DateTime, + MessageID = message.MessageId, + SenderName = mail.Address, + Subject = message.Subject, + Body = message.TextBody + }); + } + } + } + catch (MailKit.Security.AuthenticationException) + { } + finally + { + client.Disconnect(true); + } + }); + return list; + } + + + } +} diff --git a/ElectronicsShop/ElectronicsShopBusinessLogic/OfficePackage/AbstractSaveToExcel.cs b/ElectronicsShop/ElectronicsShopBusinessLogic/OfficePackage/AbstractSaveToExcel.cs new file mode 100644 index 0000000..8d3dcca --- /dev/null +++ b/ElectronicsShop/ElectronicsShopBusinessLogic/OfficePackage/AbstractSaveToExcel.cs @@ -0,0 +1,104 @@ +using ElectronicsShopBusinessLogic.OfficePackage.HelperEnums; +using ElectronicsShopBusinessLogic.OfficePackage.HelperModels; + + +namespace ElectronicsShopBusinessLogic.OfficePackage +{ + public abstract class AbstractSaveToExcel + { + public void CreateReport(ExcelInfo 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 pc in info.Orders) + { + InsertCellInWorksheet(new ExcelCellParameters + { + ColumnName = "A", + RowIndex = rowIndex, + Text = pc.ProductList.ToString(), + StyleInfo = ExcelStyleInfoType.Text + }); + rowIndex++; + + foreach (var (product , Count) in pc.ProductList) + { + InsertCellInWorksheet(new ExcelCellParameters + { + ColumnName = "B", + RowIndex = rowIndex, + Text = product.ToString(), + 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 = pc.ClientID.ToString(),//Тут в исходние был счётчик, ClientID как заглушка от ошибки + StyleInfo = ExcelStyleInfoType.Text + }); + rowIndex++; + } + + SaveExcel(info); + } + + /// + /// Создание excel-файла + /// + /// + protected abstract void CreateExcel(ExcelInfo info); + + /// + /// Добавляем новую ячейку в лист + /// + /// + protected abstract void InsertCellInWorksheet(ExcelCellParameters excelParams); + + /// + /// Объединение ячеек + /// + /// + protected abstract void MergeCells(ExcelMergeParameters excelParams); + + /// + /// Сохранение файла + /// + /// + protected abstract void SaveExcel(ExcelInfo info); + } +} diff --git a/ElectronicsShop/ElectronicsShopBusinessLogic/OfficePackage/AbstractSaveToWord.cs b/ElectronicsShop/ElectronicsShopBusinessLogic/OfficePackage/AbstractSaveToWord.cs new file mode 100644 index 0000000..b0f7f94 --- /dev/null +++ b/ElectronicsShop/ElectronicsShopBusinessLogic/OfficePackage/AbstractSaveToWord.cs @@ -0,0 +1,65 @@ +using ElectronicsShopBusinessLogic.OfficePackage.HelperEnums; +using ElectronicsShopBusinessLogic.OfficePackage.HelperModels; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ElectronicsShopBusinessLogic.OfficePackage +{ + public abstract class AbstractSaveToWord + { + public void CreateDoc(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 + } + }); + + foreach (var product in info.ListProduct) + { + CreateParagraph(new WordParagraph + { + Texts = new List<(string, WordTextProperties)> { + (product.ProductName+' ', new WordTextProperties { Size = "24", Bold = true }), + (product.Price.ToString(), new WordTextProperties { Size = "24" }) + }, + TextProperties = new WordTextProperties + { + Size = "24", + JustificationType = WordJustificationType.Both + } + }); + } + + SaveWord(info); + } + + /// + /// Создание doc-файла + /// + /// + protected abstract void CreateWord(WordInfo info); + + /// + /// Создание абзаца с текстом + /// + /// + /// + protected abstract void CreateParagraph(WordParagraph paragraph); + + /// + /// Сохранение файла + /// + /// + protected abstract void SaveWord(WordInfo info); + } +} diff --git a/ElectronicsShop/ElectronicsShopBusinessLogic/OfficePackage/HelperEnums/ExcelStyleInfoType.cs b/ElectronicsShop/ElectronicsShopBusinessLogic/OfficePackage/HelperEnums/ExcelStyleInfoType.cs new file mode 100644 index 0000000..dc4ebc5 --- /dev/null +++ b/ElectronicsShop/ElectronicsShopBusinessLogic/OfficePackage/HelperEnums/ExcelStyleInfoType.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ElectronicsShopBusinessLogic.OfficePackage.HelperEnums +{ + public enum ExcelStyleInfoType + { + Title, + + Text, + + TextWithBroder + } +} diff --git a/ElectronicsShop/ElectronicsShopBusinessLogic/OfficePackage/HelperEnums/WordJustificationType.cs b/ElectronicsShop/ElectronicsShopBusinessLogic/OfficePackage/HelperEnums/WordJustificationType.cs new file mode 100644 index 0000000..3a25b84 --- /dev/null +++ b/ElectronicsShop/ElectronicsShopBusinessLogic/OfficePackage/HelperEnums/WordJustificationType.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ElectronicsShopBusinessLogic.OfficePackage.HelperEnums +{ + public enum WordJustificationType + { + Center, + + Both + } +} diff --git a/ElectronicsShop/ElectronicsShopBusinessLogic/OfficePackage/HelperModels/ExcelCellParameters.cs b/ElectronicsShop/ElectronicsShopBusinessLogic/OfficePackage/HelperModels/ExcelCellParameters.cs new file mode 100644 index 0000000..84397c7 --- /dev/null +++ b/ElectronicsShop/ElectronicsShopBusinessLogic/OfficePackage/HelperModels/ExcelCellParameters.cs @@ -0,0 +1,22 @@ +using ElectronicsShopBusinessLogic.OfficePackage.HelperEnums; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ElectronicsShopBusinessLogic.OfficePackage.HelperModels +{ + public class ExcelCellParameters + { + public string ColumnName { get; set; } = string.Empty; + + public uint RowIndex { get; set; } + + public string Text { get; set; } = string.Empty; + + public string CellReference => $"{ColumnName}{RowIndex}"; + + public ExcelStyleInfoType StyleInfo { get; set; } + } +} diff --git a/ElectronicsShop/ElectronicsShopBusinessLogic/OfficePackage/HelperModels/ExcelInfo.cs b/ElectronicsShop/ElectronicsShopBusinessLogic/OfficePackage/HelperModels/ExcelInfo.cs new file mode 100644 index 0000000..f83ed8b --- /dev/null +++ b/ElectronicsShop/ElectronicsShopBusinessLogic/OfficePackage/HelperModels/ExcelInfo.cs @@ -0,0 +1,13 @@ +using ElectronicsShopContracts.ViewModels; + +namespace ElectronicsShopBusinessLogic.OfficePackage.HelperModels +{ + public class ExcelInfo + { + public string FileName { get; set; } = string.Empty; + + public string Title { get; set; } = string.Empty; + + public List Orders { get; set; } = new(); + } +} diff --git a/ElectronicsShop/ElectronicsShopBusinessLogic/OfficePackage/HelperModels/ExcelMergeParameters.cs b/ElectronicsShop/ElectronicsShopBusinessLogic/OfficePackage/HelperModels/ExcelMergeParameters.cs new file mode 100644 index 0000000..2c3dcfc --- /dev/null +++ b/ElectronicsShop/ElectronicsShopBusinessLogic/OfficePackage/HelperModels/ExcelMergeParameters.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ElectronicsShopBusinessLogic.OfficePackage.HelperModels +{ + public class ExcelMergeParameters + { + public string CellFromName { get; set; } = string.Empty; + + public string CellToName { get; set; } = string.Empty; + + public string Merge => $"{CellFromName}:{CellToName}"; + } +} diff --git a/ElectronicsShop/ElectronicsShopBusinessLogic/OfficePackage/HelperModels/WordInfo.cs b/ElectronicsShop/ElectronicsShopBusinessLogic/OfficePackage/HelperModels/WordInfo.cs new file mode 100644 index 0000000..32309dc --- /dev/null +++ b/ElectronicsShop/ElectronicsShopBusinessLogic/OfficePackage/HelperModels/WordInfo.cs @@ -0,0 +1,14 @@ +using ElectronicsShopContracts.ViewModels; + + +namespace ElectronicsShopBusinessLogic.OfficePackage.HelperModels +{ + public class WordInfo + { + public string FileName { get; set; } = string.Empty; + + public string Title { get; set; } = string.Empty; + + public List ListProduct { get; set; } = new(); + } +} diff --git a/ElectronicsShop/ElectronicsShopBusinessLogic/OfficePackage/HelperModels/WordParagraph.cs b/ElectronicsShop/ElectronicsShopBusinessLogic/OfficePackage/HelperModels/WordParagraph.cs new file mode 100644 index 0000000..20195dd --- /dev/null +++ b/ElectronicsShop/ElectronicsShopBusinessLogic/OfficePackage/HelperModels/WordParagraph.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ElectronicsShopBusinessLogic.OfficePackage.HelperModels +{ + public class WordParagraph + { + public List<(string, WordTextProperties)> Texts { get; set; } = new(); + + public WordTextProperties? TextProperties { get; set; } + } +} diff --git a/ElectronicsShop/ElectronicsShopBusinessLogic/OfficePackage/HelperModels/WordTextProperties.cs b/ElectronicsShop/ElectronicsShopBusinessLogic/OfficePackage/HelperModels/WordTextProperties.cs new file mode 100644 index 0000000..1dcb036 --- /dev/null +++ b/ElectronicsShop/ElectronicsShopBusinessLogic/OfficePackage/HelperModels/WordTextProperties.cs @@ -0,0 +1,18 @@ +using ElectronicsShopBusinessLogic.OfficePackage.HelperEnums; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ElectronicsShopBusinessLogic.OfficePackage.HelperModels +{ + public class WordTextProperties + { + public string Size { get; set; } = string.Empty; + + public bool Bold { get; set; } + + public WordJustificationType JustificationType { get; set; } + } +} diff --git a/ElectronicsShop/ElectronicsShopBusinessLogic/OfficePackage/Implements/SaveToExcel.cs b/ElectronicsShop/ElectronicsShopBusinessLogic/OfficePackage/Implements/SaveToExcel.cs new file mode 100644 index 0000000..be76f31 --- /dev/null +++ b/ElectronicsShop/ElectronicsShopBusinessLogic/OfficePackage/Implements/SaveToExcel.cs @@ -0,0 +1,293 @@ +using DocumentFormat.OpenXml; +using DocumentFormat.OpenXml.Office2010.Excel; +using DocumentFormat.OpenXml.Office2013.Excel; +using DocumentFormat.OpenXml.Packaging; +using DocumentFormat.OpenXml.Spreadsheet; +using ElectronicsShopBusinessLogic.OfficePackage.HelperEnums; +using ElectronicsShopBusinessLogic.OfficePackage.HelperModels; + + +namespace ElectronicsShopBusinessLogic.OfficePackage.Implements +{ + public class SaveToExcel : AbstractSaveToExcel + { + 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 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 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 }); + + 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 }); + + 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 }); + + 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 }; + + 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 }; + + 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 stylesheetExtensionList = new StylesheetExtensionList(); + + 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}" }; + stylesheetExtension2.AddNamespaceDeclaration("x15", "http://schemas.microsoft.com/office/spreadsheetml/2010/11/main"); + stylesheetExtension2.Append(new TimelineStyles() { DefaultTimelineStyle = "TimeSlicerStyleLight1" }); + + stylesheetExtensionList.Append(stylesheetExtension1); + stylesheetExtensionList.Append(stylesheetExtension2); + + sp.Stylesheet.Append(fonts); + sp.Stylesheet.Append(fills); + sp.Stylesheet.Append(borders); + sp.Stylesheet.Append(cellStyleFormats); + sp.Stylesheet.Append(cellFormats); + sp.Stylesheet.Append(cellStyles); + sp.Stylesheet.Append(differentialFormats); + sp.Stylesheet.Append(tableStyles); + sp.Stylesheet.Append(stylesheetExtensionList); + } + + /// + /// Получение номера стиля из типа + /// + /// + /// + private static uint GetStyleValue(ExcelStyleInfoType styleInfo) + { + return styleInfo switch + { + ExcelStyleInfoType.Title => 2U, + ExcelStyleInfoType.TextWithBroder => 1U, + ExcelStyleInfoType.Text => 0U, + _ => 0U, + }; + } + + protected override void CreateExcel(ExcelInfo info) + { + _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(); + + // Создаем 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 sheet = new Sheet() + { + 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) + { + return; + } + var sheetData = _worksheet.GetFirstChild(); + if (sheetData == null) + { + return; + } + + // Ищем строку, либо добавляем ее + Row row; + if (sheetData.Elements().Where(r => r.RowIndex! == excelParams.RowIndex).Any()) + { + row = sheetData.Elements().Where(r => r.RowIndex! == excelParams.RowIndex).First(); + } + else + { + row = new Row() { RowIndex = excelParams.RowIndex }; + sheetData.Append(row); + } + + // Ищем нужную ячейку + Cell cell; + if (row.Elements().Where(c => c.CellReference!.Value == excelParams.CellReference).Any()) + { + cell = row.Elements().Where(c => c.CellReference!.Value == excelParams.CellReference).First(); + } + else + { + // Все ячейки должны быть последовательно друг за другом расположены + // нужно определить, после какой вставлять + Cell? refCell = null; + foreach (Cell rowCell in row.Elements()) + { + if (string.Compare(rowCell.CellReference!.Value, excelParams.CellReference, true) > 0) + { + refCell = rowCell; + break; + } + } + + 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) + { + return; + } + MergeCells mergeCells; + + if (_worksheet.Elements().Any()) + { + mergeCells = _worksheet.Elements().First(); + } + else + { + mergeCells = new MergeCells(); + + if (_worksheet.Elements().Any()) + { + _worksheet.InsertAfter(mergeCells, _worksheet.Elements().First()); + } + else + { + _worksheet.InsertAfter(mergeCells, _worksheet.Elements().First()); + } + } + + var mergeCell = new MergeCell() + { + Reference = new StringValue(excelParams.Merge) + }; + mergeCells.Append(mergeCell); + } + + protected override void SaveExcel(ExcelInfo info) + { + if (_spreadsheetDocument == null) + { + return; + } + _spreadsheetDocument.WorkbookPart!.Workbook.Save(); + _spreadsheetDocument.Dispose(); + } + } +} diff --git a/ElectronicsShop/ElectronicsShopBusinessLogic/OfficePackage/Implements/SaveToWord.cs b/ElectronicsShop/ElectronicsShopBusinessLogic/OfficePackage/Implements/SaveToWord.cs new file mode 100644 index 0000000..7e42b6a --- /dev/null +++ b/ElectronicsShop/ElectronicsShopBusinessLogic/OfficePackage/Implements/SaveToWord.cs @@ -0,0 +1,135 @@ +using DocumentFormat.OpenXml.Packaging; +using DocumentFormat.OpenXml.Wordprocessing; +using DocumentFormat.OpenXml; +using ElectronicsShopBusinessLogic.OfficePackage.HelperEnums; +using ElectronicsShopBusinessLogic.OfficePackage.HelperModels; + +namespace ElectronicsShopBusinessLogic.OfficePackage.Implements +{ + public class SaveToWord : AbstractSaveToWord + { + private WordprocessingDocument? _wordDocument; + + private Body? _docBody; + + /// + /// Получение типа выравнивания + /// + /// + /// + private static JustificationValues GetJustificationValues(WordJustificationType type) + { + return type switch + { + WordJustificationType.Both => JustificationValues.Both, + WordJustificationType.Center => JustificationValues.Center, + _ => 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 }); + } + properties.AppendChild(paragraphMarkRunProperties); + + return properties; + } + + protected override void CreateWord(WordInfo 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) + { + return; + } + 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) + { + properties.AppendChild(new Bold()); + } + docRun.AppendChild(properties); + + docRun.AppendChild(new Text { Text = run.Item1, Space = SpaceProcessingModeValues.Preserve }); + + docParagraph.AppendChild(docRun); + } + + _docBody.AppendChild(docParagraph); + } + + protected override void SaveWord(WordInfo info) + { + if (_docBody == null || _wordDocument == null) + { + return; + } + _docBody.AppendChild(CreateSectionProperties()); + + _wordDocument.MainDocumentPart!.Document.Save(); + + _wordDocument.Dispose(); + } + } +} diff --git a/ElectronicsShop/ElectronicsShopContracts/BindingModels/MailConfigBindingModel.cs b/ElectronicsShop/ElectronicsShopContracts/BindingModels/MailConfigBindingModel.cs new file mode 100644 index 0000000..426b3d6 --- /dev/null +++ b/ElectronicsShop/ElectronicsShopContracts/BindingModels/MailConfigBindingModel.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ElectronicsShopContracts.BindingModels +{ + public class MailConfigBindingModel + { + public string MailLogin { get; set; } = string.Empty; + public string MailPassword { get; set; } = string.Empty; + public string SmtpClientHost { get; set; } = string.Empty; + public int SmtpClientPort { get; set; } + public string PopHost { get; set; } = string.Empty; + public int PopPort { get; set; } + } +} diff --git a/ElectronicsShop/ElectronicsShopContracts/BindingModels/MailSendInfoBindingModel.cs b/ElectronicsShop/ElectronicsShopContracts/BindingModels/MailSendInfoBindingModel.cs new file mode 100644 index 0000000..16cc1da --- /dev/null +++ b/ElectronicsShop/ElectronicsShopContracts/BindingModels/MailSendInfoBindingModel.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ElectronicsShopContracts.BindingModels +{ + public class MailSendInfoBindingModel + { + public string MailAddress { get; set; } = string.Empty; + public string Subject { get; set; } = string.Empty; + public string Text { get; set; } = string.Empty; + } +} diff --git a/ElectronicsShop/ElectronicsShopContracts/BindingModels/MessageInfoBindingModel.cs b/ElectronicsShop/ElectronicsShopContracts/BindingModels/MessageInfoBindingModel.cs new file mode 100644 index 0000000..473aa4c --- /dev/null +++ b/ElectronicsShop/ElectronicsShopContracts/BindingModels/MessageInfoBindingModel.cs @@ -0,0 +1,19 @@ +using ElectronicsShopDataModels.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ElectronicsShopContracts.BindingModels +{ + public class MessageInfoBindingModel : IMessageInfoModel + { + public string MessageID { get; set; } = string.Empty; + public int? ClientID { get; set; } + public string SenderName { get; set; } = string.Empty; + public string Subject { get; set; } = string.Empty; + public string Body { get; set; } = string.Empty; + public DateTime DateDelivery { get; set; } + } +} diff --git a/ElectronicsShop/ElectronicsShopContracts/BindingModels/ReportBindingModel.cs b/ElectronicsShop/ElectronicsShopContracts/BindingModels/ReportBindingModel.cs new file mode 100644 index 0000000..f3609f4 --- /dev/null +++ b/ElectronicsShop/ElectronicsShopContracts/BindingModels/ReportBindingModel.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ElectronicsShopContracts.BindingModels +{ + public class ReportBindingModel + { + public string FileName { get; set; } = string.Empty; + + public DateTime? DateFrom { get; set; } + + public DateTime? DateTo { get; set; } + } +} diff --git a/ElectronicsShop/ElectronicsShopContracts/BusinessLogicContracts/IMessageInfoLogic.cs b/ElectronicsShop/ElectronicsShopContracts/BusinessLogicContracts/IMessageInfoLogic.cs new file mode 100644 index 0000000..4e1c2c6 --- /dev/null +++ b/ElectronicsShop/ElectronicsShopContracts/BusinessLogicContracts/IMessageInfoLogic.cs @@ -0,0 +1,17 @@ +using ElectronicsShopContracts.BindingModels; +using ElectronicsShopContracts.SearchModels; +using ElectronicsShopContracts.ViewModels; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ElectronicsShopContracts.BusinessLogicContracts +{ + public interface IMessageInfoLogic + { + List? ReadList(MessageInfoSearchModel? model); + bool Create(MessageInfoBindingModel model); + } +} diff --git a/ElectronicsShop/ElectronicsShopContracts/BusinessLogicContracts/IReportLogic.cs b/ElectronicsShop/ElectronicsShopContracts/BusinessLogicContracts/IReportLogic.cs new file mode 100644 index 0000000..7ea7086 --- /dev/null +++ b/ElectronicsShop/ElectronicsShopContracts/BusinessLogicContracts/IReportLogic.cs @@ -0,0 +1,18 @@ +using ElectronicsShopContracts.BindingModels; +using ElectronicsShopContracts.ViewModels; + + +namespace ElectronicsShopContracts.BusinessLogicContracts +{ + public interface IReportLogic + { + List GetProduct();//Это наш список продуктов + + List GetOrders(ReportBindingModel model);//это наш список заказов + + void SaveListToWordFile(ReportBindingModel model); + + void SaveProductToExcelFile(ReportBindingModel model); + + } +} diff --git a/ElectronicsShop/ElectronicsShopContracts/SearchModels/MessageInfoSearchModel.cs b/ElectronicsShop/ElectronicsShopContracts/SearchModels/MessageInfoSearchModel.cs new file mode 100644 index 0000000..fe50a21 --- /dev/null +++ b/ElectronicsShop/ElectronicsShopContracts/SearchModels/MessageInfoSearchModel.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ElectronicsShopContracts.SearchModels +{ + public class MessageInfoSearchModel + { + public int? ClientID { get; set; } + public string? MessageID { get; set; } + } +} diff --git a/ElectronicsShop/ElectronicsShopContracts/StorageContracts/IMessageInfoStorage.cs b/ElectronicsShop/ElectronicsShopContracts/StorageContracts/IMessageInfoStorage.cs new file mode 100644 index 0000000..3e0169f --- /dev/null +++ b/ElectronicsShop/ElectronicsShopContracts/StorageContracts/IMessageInfoStorage.cs @@ -0,0 +1,19 @@ +using ElectronicsShopContracts.BindingModels; +using ElectronicsShopContracts.SearchModels; +using ElectronicsShopContracts.ViewModels; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ElectronicsShopContracts.StorageContracts +{ + public interface IMessageInfoStorage + { + List GetFullList(); + List GetFilteredList(MessageInfoSearchModel model); + MessageInfoViewModel? GetElement(MessageInfoSearchModel model); + MessageInfoViewModel? Insert(MessageInfoBindingModel model); + } +} diff --git a/ElectronicsShop/ElectronicsShopContracts/ViewModels/MessageInfoViewModel.cs b/ElectronicsShop/ElectronicsShopContracts/ViewModels/MessageInfoViewModel.cs new file mode 100644 index 0000000..8b634e3 --- /dev/null +++ b/ElectronicsShop/ElectronicsShopContracts/ViewModels/MessageInfoViewModel.cs @@ -0,0 +1,30 @@ +using ElectronicsShopDataModels.Models; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ElectronicsShopContracts.ViewModels +{ + public class MessageInfoViewModel: IMessageInfoModel + { + public string MessageID { get; set; } = string.Empty; + + public int? ClientID { get; set; } + + [DisplayName("Отправитель")] + public string SenderName { get; set; } = string.Empty; + + [DisplayName("Дата письма")] + public DateTime DateDelivery { get; set; } + + [DisplayName("Заголовок")] + public string Subject { get; set; } = string.Empty; + + [DisplayName("Текст")] + public string Body { get; set; } = string.Empty; + } +} + diff --git a/ElectronicsShop/ElectronicsShopContracts/ViewModels/ReportOrdersVeiwModel.cs b/ElectronicsShop/ElectronicsShopContracts/ViewModels/ReportOrdersVeiwModel.cs new file mode 100644 index 0000000..21b891f --- /dev/null +++ b/ElectronicsShop/ElectronicsShopContracts/ViewModels/ReportOrdersVeiwModel.cs @@ -0,0 +1,22 @@ +using ElectronicsShopDataModels.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ElectronicsShopContracts.ViewModels +{ + public class ReportOrdersVeiwModel + { + public int ID { get; set; } + + public int ClientID { get; set; } + + public DateTime DateCreate { get; set; } + + public Dictionary ProductList { get; set; } = new(); + + public double Sum { get; set; } + } +} diff --git a/ElectronicsShop/ElectronicsShopContracts/ViewModels/ReportProductsViewModel.cs b/ElectronicsShop/ElectronicsShopContracts/ViewModels/ReportProductsViewModel.cs new file mode 100644 index 0000000..50f7ecf --- /dev/null +++ b/ElectronicsShop/ElectronicsShopContracts/ViewModels/ReportProductsViewModel.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ElectronicsShopContracts.ViewModels +{ + public class ReportProductsViewModel + { + public int CostItemID { get; set; } + + public string ProductName { get; set; } = string.Empty; + + public double Price { get; set; } + + public string CostItemName { get; set; } = string.Empty; + } +} diff --git a/ElectronicsShop/ElectronicsShopDataBaseImplement/DataBase.cs b/ElectronicsShop/ElectronicsShopDataBaseImplement/DataBase.cs index 23bfaec..2830f99 100644 --- a/ElectronicsShop/ElectronicsShopDataBaseImplement/DataBase.cs +++ b/ElectronicsShop/ElectronicsShopDataBaseImplement/DataBase.cs @@ -23,5 +23,6 @@ namespace ElectronicsShopDataBaseImplement public virtual DbSet Employees { set; get; } public virtual DbSet CostItems { set; get; } public virtual DbSet Paymeants { get; set; } - } + public virtual DbSet Messages { set; get; } + } } diff --git a/ElectronicsShop/ElectronicsShopDataBaseImplement/Implements/MessageInfoStorage.cs b/ElectronicsShop/ElectronicsShopDataBaseImplement/Implements/MessageInfoStorage.cs new file mode 100644 index 0000000..3f805bd --- /dev/null +++ b/ElectronicsShop/ElectronicsShopDataBaseImplement/Implements/MessageInfoStorage.cs @@ -0,0 +1,53 @@ +using ElectronicsShopContracts.BindingModels; +using ElectronicsShopContracts.SearchModels; +using ElectronicsShopContracts.StorageContracts; +using ElectronicsShopContracts.ViewModels; +using ElectronicsShopDataBaseImplement.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ElectronicsShopDataBaseImplement.Implements +{ + public class MessageInfoStorage : IMessageInfoStorage + { + + public MessageInfoViewModel? GetElement(MessageInfoSearchModel model) + { + using var context = new Database(); + if (model.MessageID != null) + { + return context.Messages.FirstOrDefault(x => x.MessageID == model.MessageID)?.GetViewModel; + } + return null; + } + + public List GetFilteredList(MessageInfoSearchModel model) + { + using var context = new Database(); + return context.Messages + .Where(x => x.MessageID == model.MessageID).Select(x => x.GetViewModel).ToList(); + } + + public List GetFullList() + { + using var context = new Database(); + return context.Messages.Select(x => x.GetViewModel).ToList(); + } + + public MessageInfoViewModel? Insert(MessageInfoBindingModel model) + { + using var context = new Database(); + var newMessage = MessageInfo.Create(model); + if (newMessage == null || context.Messages.Any(x => x.MessageID.Equals(model.MessageID))) + { + return null; + } + context.Messages.Add(newMessage); + context.SaveChanges(); + return newMessage.GetViewModel; + } + } +} diff --git a/ElectronicsShop/ElectronicsShopDataBaseImplement/Migrations/20240530150159_AddMessages.Designer.cs b/ElectronicsShop/ElectronicsShopDataBaseImplement/Migrations/20240530150159_AddMessages.Designer.cs new file mode 100644 index 0000000..daf6f22 --- /dev/null +++ b/ElectronicsShop/ElectronicsShopDataBaseImplement/Migrations/20240530150159_AddMessages.Designer.cs @@ -0,0 +1,322 @@ +// +using System; +using ElectronicsShopDataBaseImplement; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace ElectronicsShopDataBaseImplement.Migrations +{ + [DbContext(typeof(Database))] + [Migration("20240530150159_AddMessages")] + partial class AddMessages + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.4") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("ElectronicsShopDataBaseImplement.Models.Client", b => + { + b.Property("ID") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("ID")); + + b.Property("ClientFIO") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Email") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Password") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("ID"); + + b.ToTable("Clients"); + }); + + modelBuilder.Entity("ElectronicsShopDataBaseImplement.Models.CostItem", b => + { + b.Property("ID") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("ID")); + + b.Property("CostNum") + .HasColumnType("int"); + + b.Property("EmployeeID") + .HasColumnType("int"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Price") + .HasColumnType("float"); + + b.HasKey("ID"); + + b.HasIndex("EmployeeID"); + + b.ToTable("CostItems"); + }); + + modelBuilder.Entity("ElectronicsShopDataBaseImplement.Models.Employee", b => + { + b.Property("ID") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("ID")); + + b.Property("EmployeeFIO") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Login") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Password") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("ID"); + + b.ToTable("Employees"); + }); + + modelBuilder.Entity("ElectronicsShopDataBaseImplement.Models.MessageInfo", b => + { + b.Property("MessageID") + .HasColumnType("nvarchar(450)"); + + b.Property("Body") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("ClientID") + .HasColumnType("int"); + + b.Property("DateDelivery") + .HasColumnType("datetime2"); + + b.Property("SenderName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Subject") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("MessageID"); + + b.HasIndex("ClientID"); + + b.ToTable("Messages"); + }); + + modelBuilder.Entity("ElectronicsShopDataBaseImplement.Models.Order", b => + { + b.Property("ID") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("ID")); + + b.Property("ClientID") + .HasColumnType("int"); + + b.Property("DateCreate") + .HasColumnType("datetime2"); + + b.Property("Sum") + .HasColumnType("float"); + + b.HasKey("ID"); + + b.HasIndex("ClientID"); + + b.ToTable("Orders"); + }); + + modelBuilder.Entity("ElectronicsShopDataBaseImplement.Models.OrderProduct", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Count") + .HasColumnType("int"); + + b.Property("OrderID") + .HasColumnType("int"); + + b.Property("ProductID") + .HasColumnType("int"); + + b.Property("_productID") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("ProductID"); + + b.HasIndex("_productID"); + + b.ToTable("OrderProducts"); + }); + + modelBuilder.Entity("ElectronicsShopDataBaseImplement.Models.Paymeant", b => + { + b.Property("ID") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("ID")); + + b.Property("OrderID") + .HasColumnType("int"); + + b.Property("PayOption") + .HasColumnType("int"); + + b.Property("PaymentID") + .HasColumnType("int"); + + b.Property("ProductID") + .HasColumnType("int"); + + b.Property("SumPayment") + .HasColumnType("float"); + + b.HasKey("ID"); + + b.HasIndex("PaymentID"); + + b.ToTable("Paymeants"); + }); + + modelBuilder.Entity("ElectronicsShopDataBaseImplement.Models.Product", b => + { + b.Property("ID") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("ID")); + + b.Property("CostItemID") + .HasColumnType("int"); + + b.Property("Price") + .HasColumnType("float"); + + b.Property("ProductName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("ID"); + + b.HasIndex("CostItemID"); + + b.ToTable("Products"); + }); + + modelBuilder.Entity("ElectronicsShopDataBaseImplement.Models.CostItem", b => + { + b.HasOne("ElectronicsShopDataBaseImplement.Models.Employee", "Employee") + .WithMany() + .HasForeignKey("EmployeeID") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Employee"); + }); + + modelBuilder.Entity("ElectronicsShopDataBaseImplement.Models.MessageInfo", b => + { + b.HasOne("ElectronicsShopDataBaseImplement.Models.Client", "Client") + .WithMany() + .HasForeignKey("ClientID"); + + b.Navigation("Client"); + }); + + modelBuilder.Entity("ElectronicsShopDataBaseImplement.Models.Order", b => + { + b.HasOne("ElectronicsShopDataBaseImplement.Models.Client", null) + .WithMany("Orders") + .HasForeignKey("ClientID") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ElectronicsShopDataBaseImplement.Models.OrderProduct", b => + { + b.HasOne("ElectronicsShopDataBaseImplement.Models.Order", "_order") + .WithMany("Products") + .HasForeignKey("ProductID") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("ElectronicsShopDataBaseImplement.Models.Product", "_product") + .WithMany() + .HasForeignKey("_productID"); + + b.Navigation("_order"); + + b.Navigation("_product"); + }); + + modelBuilder.Entity("ElectronicsShopDataBaseImplement.Models.Paymeant", b => + { + b.HasOne("ElectronicsShopDataBaseImplement.Models.Order", null) + .WithMany("Payments") + .HasForeignKey("PaymentID"); + }); + + modelBuilder.Entity("ElectronicsShopDataBaseImplement.Models.Product", b => + { + b.HasOne("ElectronicsShopDataBaseImplement.Models.CostItem", "CostItem") + .WithMany() + .HasForeignKey("CostItemID") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("CostItem"); + }); + + modelBuilder.Entity("ElectronicsShopDataBaseImplement.Models.Client", b => + { + b.Navigation("Orders"); + }); + + modelBuilder.Entity("ElectronicsShopDataBaseImplement.Models.Order", b => + { + b.Navigation("Payments"); + + b.Navigation("Products"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/ElectronicsShop/ElectronicsShopDataBaseImplement/Migrations/20240530150159_AddMessages.cs b/ElectronicsShop/ElectronicsShopDataBaseImplement/Migrations/20240530150159_AddMessages.cs new file mode 100644 index 0000000..8284989 --- /dev/null +++ b/ElectronicsShop/ElectronicsShopDataBaseImplement/Migrations/20240530150159_AddMessages.cs @@ -0,0 +1,48 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace ElectronicsShopDataBaseImplement.Migrations +{ + /// + public partial class AddMessages : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "Messages", + columns: table => new + { + MessageID = table.Column(type: "nvarchar(450)", nullable: false), + ClientID = table.Column(type: "int", nullable: true), + SenderName = table.Column(type: "nvarchar(max)", nullable: false), + DateDelivery = table.Column(type: "datetime2", nullable: false), + Subject = table.Column(type: "nvarchar(max)", nullable: false), + Body = table.Column(type: "nvarchar(max)", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Messages", x => x.MessageID); + table.ForeignKey( + name: "FK_Messages_Clients_ClientID", + column: x => x.ClientID, + principalTable: "Clients", + principalColumn: "ID"); + }); + + migrationBuilder.CreateIndex( + name: "IX_Messages_ClientID", + table: "Messages", + column: "ClientID"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "Messages"); + } + } +} diff --git a/ElectronicsShop/ElectronicsShopDataBaseImplement/Migrations/DatabaseModelSnapshot.cs b/ElectronicsShop/ElectronicsShopDataBaseImplement/Migrations/DatabaseModelSnapshot.cs index 55e33e5..a578fb3 100644 --- a/ElectronicsShop/ElectronicsShopDataBaseImplement/Migrations/DatabaseModelSnapshot.cs +++ b/ElectronicsShop/ElectronicsShopDataBaseImplement/Migrations/DatabaseModelSnapshot.cs @@ -100,6 +100,36 @@ namespace ElectronicsShopDataBaseImplement.Migrations b.ToTable("Employees"); }); + modelBuilder.Entity("ElectronicsShopDataBaseImplement.Models.MessageInfo", b => + { + b.Property("MessageID") + .HasColumnType("nvarchar(450)"); + + b.Property("Body") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("ClientID") + .HasColumnType("int"); + + b.Property("DateDelivery") + .HasColumnType("datetime2"); + + b.Property("SenderName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Subject") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("MessageID"); + + b.HasIndex("ClientID"); + + b.ToTable("Messages"); + }); + modelBuilder.Entity("ElectronicsShopDataBaseImplement.Models.Order", b => { b.Property("ID") @@ -219,6 +249,15 @@ namespace ElectronicsShopDataBaseImplement.Migrations b.Navigation("Employee"); }); + modelBuilder.Entity("ElectronicsShopDataBaseImplement.Models.MessageInfo", b => + { + b.HasOne("ElectronicsShopDataBaseImplement.Models.Client", "Client") + .WithMany() + .HasForeignKey("ClientID"); + + b.Navigation("Client"); + }); + modelBuilder.Entity("ElectronicsShopDataBaseImplement.Models.Order", b => { b.HasOne("ElectronicsShopDataBaseImplement.Models.Client", null) diff --git a/ElectronicsShop/ElectronicsShopDataBaseImplement/Models/MessageInfo.cs b/ElectronicsShop/ElectronicsShopDataBaseImplement/Models/MessageInfo.cs new file mode 100644 index 0000000..dda8193 --- /dev/null +++ b/ElectronicsShop/ElectronicsShopDataBaseImplement/Models/MessageInfo.cs @@ -0,0 +1,58 @@ +using ElectronicsShopContracts.BindingModels; +using ElectronicsShopContracts.ViewModels; +using ElectronicsShopDataModels.Models; +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ElectronicsShopDataBaseImplement.Models +{ + public class MessageInfo : IMessageInfoModel + { + [Key] + public string MessageID { get; private set; } = string.Empty; + + public int? ClientID { get; private set; } + + public string SenderName { get; private set; } = string.Empty; + + public DateTime DateDelivery { get; private set; } = DateTime.Now; + + public string Subject { get; private set; } = string.Empty; + + public string Body { get; private set; } = string.Empty; + + public Client? Client { get; private set; } + + public static MessageInfo? Create(MessageInfoBindingModel model) + { + if (model == null) + { + return null; + } + return new() + { + Body = model.Body, + Subject = model.Subject, + ClientID = model.ClientID, + MessageID = model.MessageID, + SenderName = model.SenderName, + DateDelivery = model.DateDelivery, + }; + } + + public MessageInfoViewModel GetViewModel => new() + { + Body = Body, + Subject = Subject, + ClientID = ClientID, + MessageID = MessageID, + SenderName = SenderName, + DateDelivery = DateDelivery, + }; + + } +} diff --git a/ElectronicsShop/ElectronicsShopDataModels/Models/IMessageInfoModel.cs b/ElectronicsShop/ElectronicsShopDataModels/Models/IMessageInfoModel.cs new file mode 100644 index 0000000..2baae7e --- /dev/null +++ b/ElectronicsShop/ElectronicsShopDataModels/Models/IMessageInfoModel.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ElectronicsShopDataModels.Models +{ + public interface IMessageInfoModel + { + string MessageID { get; } + + int? ClientID { get; } + + string SenderName { get; } + + DateTime DateDelivery { get; } + + string Subject { get; } + + string Body { get; } + } +} diff --git a/ElectronicsShop/ElectronicsShopRestAPI/Controllers/MainController.cs b/ElectronicsShop/ElectronicsShopRestAPI/Controllers/MainController.cs index d35ad5f..00fb832 100644 --- a/ElectronicsShop/ElectronicsShopRestAPI/Controllers/MainController.cs +++ b/ElectronicsShop/ElectronicsShopRestAPI/Controllers/MainController.cs @@ -15,8 +15,8 @@ namespace ElectronicsShopRestAPI.Controllers { private readonly ILogger _logger; private readonly IProductLogic _product; private readonly IOrderLogic _order; - private Dictionary _ProductList; - private int? _ID; + private readonly IMessageInfoLogic _message; + public MainController(ILogger logger, IProductLogic product, IOrderLogic orderLogic) { @@ -58,7 +58,7 @@ namespace ElectronicsShopRestAPI.Controllers { { return _order.ReadList(new OrderSearchModel { - ID = _clientID + ClientID = _clientID }); } catch (Exception ex) @@ -80,22 +80,23 @@ namespace ElectronicsShopRestAPI.Controllers { } - [HttpPost] - public void CreateOrder(OrderBindingModel model) { - try - { - _order.CreateOrder(model); - } - catch (Exception ex) - { - _logger.LogError(ex, "Ошибка создания заказа"); - throw; - } - } - - [HttpPost] - public void SaveOrder(Dictionary list) { - - } + [HttpPost] + public void AddProduct(OrderBindingModel model) + { + try + { + var order=_order.ReadElement(new OrderSearchModel { ID = model.ID });//возвращает null + if (model != null&& order!=null) + { + order.ProductList = model.ProductList; + order.Sum += model.Sum; + } + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка создания заказа"); + throw; + } + } } } diff --git a/ElectronicsShop/ElectronicsShopRestAPI/appsettings.json b/ElectronicsShop/ElectronicsShopRestAPI/appsettings.json index 10f68b8..b54a8bc 100644 --- a/ElectronicsShop/ElectronicsShopRestAPI/appsettings.json +++ b/ElectronicsShop/ElectronicsShopRestAPI/appsettings.json @@ -5,5 +5,11 @@ "Microsoft.AspNetCore": "Warning" } }, - "AllowedHosts": "*" + "AllowedHosts": "*", + "SmtpClientHost": "smtp.gmail.com", + "SmtpClientPort": "587", + "PopHost": "pop.gmail.com", + "PopPort": "995", + "MailLogin": "electronicsshop437@gmail.com", + "MailPassword": "ntlt xijz ckup zglg" } diff --git a/ElectronicsShop/ElectronicsShopShopClientApp/Controllers/HomeController.cs b/ElectronicsShop/ElectronicsShopShopClientApp/Controllers/HomeController.cs index 70834d7..c0fcf5e 100644 --- a/ElectronicsShop/ElectronicsShopShopClientApp/Controllers/HomeController.cs +++ b/ElectronicsShop/ElectronicsShopShopClientApp/Controllers/HomeController.cs @@ -15,9 +15,9 @@ namespace ElectronicsShopUserApp.Controllers { private Dictionary _productList; //private readonly IOrderLogic _order; - public HomeController(ILogger logger/*, IOrderLogic orderLogic*/) { + public HomeController(ILogger logger/*, IOrderLogic orderLogic*/) { _logger = logger; - _productList = new Dictionary(); + //_order = orderLogic; } public IActionResult Index() { @@ -160,5 +160,25 @@ namespace ElectronicsShopUserApp.Controllers { var prod = APIClient.GetRequset($"api/main/getproduct?_productid={product}"); return count * (prod?.Price ?? 1); } + [HttpGet] + public IActionResult AddProduct() + { + ViewBag.Products = APIClient.GetRequset>("api/main/getproducts"); + return View(); + } + [HttpPost] + public void AddProduct(int count/*, int product*/) + { + if (APIClient.Client == null) + { + throw new Exception(" ? "); + } + if (count <= 0) + { + throw new Exception(" 0"); + } + + Response.Redirect("CreateOrder"); + } } } diff --git a/ElectronicsShop/ElectronicsShopShopClientApp/Views/Home/Message.cshtml b/ElectronicsShop/ElectronicsShopShopClientApp/Views/Home/Message.cshtml new file mode 100644 index 0000000..95e88cc --- /dev/null +++ b/ElectronicsShop/ElectronicsShopShopClientApp/Views/Home/Message.cshtml @@ -0,0 +1,49 @@ +@using ElectronicsShopContracts.ViewModels + +@model List +@{ + ViewData["Title"] = "Message"; +} + +
+

Отчёты

+ Создать товар +
+
+ @{ + + + + + + + + + + @if (Model != null) + { + @foreach (var item in Model) + { + + + + + } + } + +
+ Заголовок + + Тело письма + + Дата письма +
+ + @Html.DisplayFor(modelItem => item.Subject) + + @Html.DisplayFor(modelItem => item.Body) + + @Html.DisplayFor(modelItem => item.DateDelivery) +
+ } +
\ No newline at end of file diff --git a/ElectronicsShop/ElectronicsShopShopClientApp/Views/Shared/_Layout.cshtml b/ElectronicsShop/ElectronicsShopShopClientApp/Views/Shared/_Layout.cshtml index 1a63db2..c4396f5 100644 --- a/ElectronicsShop/ElectronicsShopShopClientApp/Views/Shared/_Layout.cshtml +++ b/ElectronicsShop/ElectronicsShopShopClientApp/Views/Shared/_Layout.cshtml @@ -34,6 +34,9 @@ +