diff --git a/VetClinic/PharmacistApp/Controllers/HomeController.cs b/VetClinic/PharmacistApp/Controllers/HomeController.cs index 8c73825..fb3c334 100644 --- a/VetClinic/PharmacistApp/Controllers/HomeController.cs +++ b/VetClinic/PharmacistApp/Controllers/HomeController.cs @@ -2,10 +2,13 @@ using NPOI.SS.UserModel; using PharmacistApp.Models; using System.Diagnostics; +using System.Globalization; using System.Text; using VetClinicContracts.BindingModels; +using VetClinicContracts.BusinessLogicsContracts; using VetClinicContracts.SearchModels; using VetClinicContracts.ViewModels; +using VetClinicDataBaseImplement.Implements; using VetClinicDataBaseImplement.Models; using VetClinicDataModels.Models; @@ -27,8 +30,7 @@ namespace PharmacistApp.Controllers return Redirect("~/Home/Enter"); } return -View(APIPharmacist.GetRequest>($"api/medicine/getmedicines?pharmacistid={ - APIPharmacist.Pharmacist.Id}")); +View(APIPharmacist.GetRequest>($"api/medicine/getmedicines?pharmacistid={APIPharmacist.Pharmacist.Id}")); } @@ -143,7 +145,7 @@ View(APIPharmacist.GetRequest>($"api/medicine/getmedicin { _price = Convert.ToDouble(price); } - catch(Exception ex) + catch (Exception ex) { throw new Exception("Ошибка в введенных данных"); } @@ -157,7 +159,7 @@ View(APIPharmacist.GetRequest>($"api/medicine/getmedicin MedicineName = name, Price = Math.Round(_price, 2), PharmacistId = APIPharmacist.Pharmacist.Id - }) ; + }); Response.Redirect("Index"); } @@ -253,7 +255,7 @@ View(APIPharmacist.GetRequest>($"api/medicine/getmedicin throw new Exception("Вы как сюда попали? Сюда вход только авторизованным"); } StringBuilder st = new StringBuilder(price); - for(int i = 0; i < price.Length; i++) + for (int i = 0; i < price.Length; i++) { if (price[i] == '.') st[i] = ','; @@ -592,11 +594,150 @@ View(res); ViewBag.Services = APIPharmacist.GetRequest>($"api/service/getservices?pharmacistid={APIPharmacist.Pharmacist.Id}"); return View(); } + + [HttpPost] + public void AnimalListReport(List services, string type) + { + if (APIPharmacist.Pharmacist == null) + { + throw new Exception("Вы как суда попали? Суда вход только авторизованным"); + } + + if (services.Count <= 0) + { + throw new Exception("Количество должно быть больше 0"); + } + + if (string.IsNullOrEmpty(type)) + { + throw new Exception("Неверный тип отчета"); + } + + + + if (type == "docx") + { + APIPharmacist.PostRequest("api/report/createanimallistwordfile", new ListAnimalsBindingModel + { + Services = services, + FileName = "C:\\ReportsCourseWork\\wordfile.docx" + }); + Response.Redirect("GetWordFile"); + } + else + { + APIPharmacist.PostRequest("api/report/createanimallistexcelfile", new ListAnimalsBindingModel + { + Services = services, + FileName = "C:\\ReportsCourseWork\\excelfile.xlsx" + }); + Response.Redirect("GetExcelFile"); + } + } + + [HttpGet] + public IActionResult GetWordFile() + { + return new PhysicalFileResult("C:\\ReportsCourseWork\\wordfile.docx", "application/vnd.openxmlformats-officedocument.wordprocessingml.document"); + } + + public IActionResult GetExcelFile() + { + return new PhysicalFileResult("C:\\ReportsCourseWork\\excelfile.xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); + } [HttpGet] public IActionResult Report() { + ViewBag.Report = new List(); return View(); } - } + + [HttpGet] + public string GetAnimalsReport(DateTime dateFrom, DateTime dateTo) + { + if (APIPharmacist.Pharmacist == null) + { + throw new Exception("Вы как суда попали? Суда вход только авторизованным"); + } + List result; + try + { + string dateFromS = dateFrom.ToString("s", CultureInfo.InvariantCulture); + string dateToS = dateTo.ToString("s", CultureInfo.InvariantCulture); + result = APIPharmacist.GetRequest> + ($"api/report/getvisitsguidesreport?datefrom={dateFromS}&dateto={dateToS}&pharmacistid={APIPharmacist.Pharmacist.Id}")!; + + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка создания отчета"); + throw; + } + string table = ""; + table += "

Предварительный отчет

"; + table += "
"; + table += ""; + table += ""; + table += ""; + table += ""; + table += ""; + table += ""; + table += ""; + table += ""; + table += ""; + foreach (var medicine in result) + { + table += ""; + table += ""; + table += $""; + table += $""; + table += $""; + table += $""; + table += ""; + foreach(var guidance in medicine.Guidances) + { + table += ""; + table += $""; + table += $""; + table += $""; + table += $""; + table += ""; + } + foreach (var visit in medicine.Visits) + { + table += ""; + table += $""; + table += $""; + table += $""; + table += $""; + table += ""; + } + table += ""; + } + table += "
ДатаНазвание медикаментаУслуга рекомендацииНазвание визита
{medicine.MedicineName}
{guidance.Date}{guidance.ServiceName}
{visit.DateVisit}{visit.NameVisit}
"; + table += "
"; + return table; + } + + [HttpPost] + public void Report(DateTime dateFrom, DateTime dateTo) + { + if (APIPharmacist.Pharmacist == null) + { + throw new Exception("Вы как суда попали? Суда вход только авторизованным"); + } + APIPharmacist.PostRequest("api/report/sendvisitsguidesreporttoemail", new VisitsGuidesBindingModel + { + FileName = "C:\\ReportsCourseWork\\pdffile.pdf", + PharmacistId = APIPharmacist.Pharmacist.Id, + DateFrom = dateFrom, + DateTo = dateTo, + Email = APIPharmacist.Pharmacist.Email + + }); + Response.Redirect("Report"); + + } + } } diff --git a/VetClinic/PharmacistApp/Views/Home/AnimalListReport.cshtml b/VetClinic/PharmacistApp/Views/Home/AnimalListReport.cshtml index 2cec407..fc17311 100644 --- a/VetClinic/PharmacistApp/Views/Home/AnimalListReport.cshtml +++ b/VetClinic/PharmacistApp/Views/Home/AnimalListReport.cshtml @@ -19,9 +19,18 @@ -
-
-
-
+
+ +
+ + +
+
+ + +
+
+
+
diff --git a/VetClinic/PharmacistApp/Views/Home/Report.cshtml b/VetClinic/PharmacistApp/Views/Home/Report.cshtml index 3c90865..3ac7296 100644 --- a/VetClinic/PharmacistApp/Views/Home/Report.cshtml +++ b/VetClinic/PharmacistApp/Views/Home/Report.cshtml @@ -1,60 +1,67 @@  + @{ - ViewData["Title"] = "Report"; + ViewData["Title"] = "Report"; } -
-

Список медикаментов с расшифровкой по визитам и рекомендациям

+ +
+
+

Отчет по медикаментам за период

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

Будь добр, дружок, зайди!

- // return; - // } -
-
Начальная дата:
-
- -
-
-
-
Конечная дата:
-
- -
-
- - - - - - - - - - - - будет заполняться вьюшками отчета - -
- Номер - - Дата - - Медикамент - - Визит - - Рекомендация -
-
-
-
-
-
-
-
-
- } -
\ No newline at end of file + +@section Scripts { + +} \ No newline at end of file diff --git a/VetClinic/VetClinicBusinessLogic/BusinessLogics/ReportLogicPharmacist.cs b/VetClinic/VetClinicBusinessLogic/BusinessLogics/ReportLogicPharmacist.cs index 407b670..9ec9b53 100644 --- a/VetClinic/VetClinicBusinessLogic/BusinessLogics/ReportLogicPharmacist.cs +++ b/VetClinic/VetClinicBusinessLogic/BusinessLogics/ReportLogicPharmacist.cs @@ -10,6 +10,7 @@ using VetClinicContracts.BusinessLogicsContracts; using VetClinicContracts.SearchModels; using VetClinicContracts.StoragesContracts; using VetClinicContracts.ViewModels; +using VetClinicDataBaseImplement.Implements; namespace VetClinicBusinessLogic.BusinessLogics { @@ -19,13 +20,16 @@ namespace VetClinicBusinessLogic.BusinessLogics private readonly IMedicineStorage _medicineStorage; private readonly AbstractSaveToExcelPharmacist _saveToExcel; private readonly AbstractSaveToWordPharmacist _saveToWord; + private readonly AbstractSaveToPdfPharmacist _saveToPdf; public ReportLogicPharmacist(IServiceStorage serviceStorage, IMedicineStorage medicineStorage, - AbstractSaveToExcelPharmacist saveToExcel, AbstractSaveToWordPharmacist saveToWord) + AbstractSaveToExcelPharmacist saveToExcel, AbstractSaveToWordPharmacist saveToWord, + AbstractSaveToPdfPharmacist saveToPdf) { _serviceStorage = serviceStorage; _medicineStorage = medicineStorage; _saveToExcel = saveToExcel; _saveToWord = saveToWord; + _saveToPdf = saveToPdf; } public List GetServiceAnimals(List services) @@ -85,5 +89,57 @@ namespace VetClinicBusinessLogic.BusinessLogics ServicesAnimals = GetServiceAnimals(model.Services) }); } + + public List GetMedicineVisitsAndGuidances(VisitsGuidesBindingModel model) + { + List ans = new(); + List>>>> responseGuides = + _medicineStorage.GetGuidancesInfo(new VisitGuidesSearchModel { DateFrom = model.DateFrom!, DateTo = model.DateTo!, PharmacistId = model.PharmacistId!}); + List>>>> responseVisits = + _medicineStorage.GetVisitsInfo(new VisitGuidesSearchModel { DateFrom = model.DateFrom!, DateTo = model.DateTo!, PharmacistId = model.PharmacistId! }); + Dictionary dict = new(); + + foreach(var medicine in responseGuides) + { + dict.Add(medicine.Item1.Id, new()); + dict[medicine.Item1.Id].MedicineName = medicine.Item1.MedicineName; + foreach(var service in medicine.Item2) + { + foreach(var guidance in service.Item2) + { + dict[medicine.Item1.Id].Guidances.Add(guidance); + } + } + } + + foreach (var medicine in responseVisits) + { + HashSet used = new(); + foreach (var service in medicine.Item2) + { + foreach (var visit in service.Item2) + { + if (used.Contains(visit.Id)) + continue; + dict[medicine.Item1.Id].Visits.Add(visit); + } + } + ans.Add(dict[medicine.Item1.Id]); + } + return ans; + } + + public void SaveMedicinesToPdfFile(VisitsGuidesBindingModel model) + { + _saveToPdf.CreateDoc(new PdfInfo + { + FileName = model.FileName, + Title = "Список медикаментов", + DateFrom = model.DateFrom!, + DateTo = model.DateTo!, + Medicines = GetMedicineVisitsAndGuidances(model) + }); + + } } } diff --git a/VetClinic/VetClinicBusinessLogic/MailWorker/AbstractMailWorker.cs b/VetClinic/VetClinicBusinessLogic/MailWorker/AbstractMailWorker.cs new file mode 100644 index 0000000..e484fa6 --- /dev/null +++ b/VetClinic/VetClinicBusinessLogic/MailWorker/AbstractMailWorker.cs @@ -0,0 +1,64 @@ +using Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using VetClinicContracts.BindingModels; +using VetClinicContracts.BusinessLogicsContracts; + +namespace VetClinicBusinessLogic.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 IPharmacistLogic _pharmacistLogic; + private readonly ILogger _logger; + + public AbstractMailWorker(ILogger logger, IPharmacistLogic pharmacistLogic) + { + _logger = logger; + _pharmacistLogic = pharmacistLogic; + } + + 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); + } + + protected abstract Task SendMailAsync(MailSendInfoBindingModel info); + } +} diff --git a/VetClinic/VetClinicBusinessLogic/MailWorker/MailWorker.cs b/VetClinic/VetClinicBusinessLogic/MailWorker/MailWorker.cs new file mode 100644 index 0000000..77f50f5 --- /dev/null +++ b/VetClinic/VetClinicBusinessLogic/MailWorker/MailWorker.cs @@ -0,0 +1,50 @@ +using Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net.Mail; +using System.Net.Mime; +using System.Net; +using System.Text; +using System.Threading.Tasks; +using VetClinicContracts.BindingModels; +using VetClinicContracts.BusinessLogicsContracts; + +namespace VetClinicBusinessLogic.MailWorker +{ + public class MailKitWorker : AbstractMailWorker + { + public MailKitWorker(ILogger logger, IPharmacistLogic pharmacistLogic) : base(logger, pharmacistLogic) { } + + 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; + Attachment attachment = new Attachment("C:\\ReportsCourseWork\\pdffile.pdf", new ContentType(MediaTypeNames.Application.Pdf)); + objMailMessage.Attachments.Add(attachment); + + 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; + } + } + + + } +} diff --git a/VetClinic/VetClinicBusinessLogic/OfficePackage/AbstractSaveToPdfPharmacist.cs b/VetClinic/VetClinicBusinessLogic/OfficePackage/AbstractSaveToPdfPharmacist.cs new file mode 100644 index 0000000..bb3dee7 --- /dev/null +++ b/VetClinic/VetClinicBusinessLogic/OfficePackage/AbstractSaveToPdfPharmacist.cs @@ -0,0 +1,73 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using VetClinicBusinessLogic.OfficePackage.HelperEnums; +using VetClinicBusinessLogic.OfficePackage.HelperModels; +using VetClinicDataBaseImplement.Implements; + +namespace VetClinicBusinessLogic.OfficePackage +{ + public abstract class AbstractSaveToPdfPharmacist + { + 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 { "4cm", "4cm", "4cm", "4cm" }); + CreateRow(new PdfRowParameters + { + Texts = new List { "Дата", "Название медикамента", "Услуга рекомендации", +"Название визита" }, + Style = "NormalTitle", + ParagraphAlignment = PdfParagraphAlignmentType.Center + }); + foreach (var medicine in info.Medicines) + { + CreateRow(new PdfRowParameters + { + Texts = new List { "", medicine.MedicineName, "", "" }, + Style = "NormalTitle", + ParagraphAlignment = PdfParagraphAlignmentType.Center + }); + foreach(var visit in medicine.Visits) + { + CreateRow(new PdfRowParameters + { + Texts = new List { visit.DateVisit.ToString(), "", "", visit.NameVisit }, + Style = "Normal", + ParagraphAlignment = PdfParagraphAlignmentType.Center + }); + } + foreach (var guidance in medicine.Guidances) + { + CreateRow(new PdfRowParameters + { + Texts = new List { guidance.Date.ToString(), "", guidance.ServiceName, "" }, + Style = "Normal", + ParagraphAlignment = PdfParagraphAlignmentType.Center + }); + } + } + SavePdf(info); + } + protected abstract void CreatePdf(PdfInfo info); + protected abstract void CreateParagraph(PdfParagraph paragraph); + protected abstract void CreateTable(List columns); + protected abstract void CreateRow(PdfRowParameters rowParameters); + protected abstract void SavePdf(PdfInfo info); + } +} diff --git a/VetClinic/VetClinicBusinessLogic/OfficePackage/HelperEnums/PdfParagraphAlignmentType.cs b/VetClinic/VetClinicBusinessLogic/OfficePackage/HelperEnums/PdfParagraphAlignmentType.cs new file mode 100644 index 0000000..aa7a867 --- /dev/null +++ b/VetClinic/VetClinicBusinessLogic/OfficePackage/HelperEnums/PdfParagraphAlignmentType.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace VetClinicBusinessLogic.OfficePackage.HelperEnums +{ + public enum PdfParagraphAlignmentType + { + Center, + Left, + Rigth + } + +} diff --git a/VetClinic/VetClinicBusinessLogic/OfficePackage/HelperModels/PdfInfo.cs b/VetClinic/VetClinicBusinessLogic/OfficePackage/HelperModels/PdfInfo.cs new file mode 100644 index 0000000..8e21977 --- /dev/null +++ b/VetClinic/VetClinicBusinessLogic/OfficePackage/HelperModels/PdfInfo.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using VetClinicDataBaseImplement.Implements; + +namespace VetClinicBusinessLogic.OfficePackage.HelperModels +{ + public class PdfInfo + { + public string FileName { get; set; } = string.Empty; + public string Title { get; set; } = string.Empty; + public DateTime DateFrom { get; set; } + public DateTime DateTo { get; set; } + public List Medicines { get; set; } = new(); + } +} diff --git a/VetClinic/VetClinicBusinessLogic/OfficePackage/HelperModels/PdfParagraph.cs b/VetClinic/VetClinicBusinessLogic/OfficePackage/HelperModels/PdfParagraph.cs new file mode 100644 index 0000000..44d63f2 --- /dev/null +++ b/VetClinic/VetClinicBusinessLogic/OfficePackage/HelperModels/PdfParagraph.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using VetClinicBusinessLogic.OfficePackage.HelperEnums; + +namespace VetClinicBusinessLogic.OfficePackage.HelperModels +{ + public class PdfParagraph + { + public string Text { get; set; } = string.Empty; + public string Style { get; set; } = string.Empty; + public PdfParagraphAlignmentType ParagraphAlignment { get; set; } + + } +} diff --git a/VetClinic/VetClinicBusinessLogic/OfficePackage/HelperModels/PdfRowParameters.cs b/VetClinic/VetClinicBusinessLogic/OfficePackage/HelperModels/PdfRowParameters.cs new file mode 100644 index 0000000..93fadaa --- /dev/null +++ b/VetClinic/VetClinicBusinessLogic/OfficePackage/HelperModels/PdfRowParameters.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using VetClinicBusinessLogic.OfficePackage.HelperEnums; + +namespace VetClinicBusinessLogic.OfficePackage.HelperModels +{ + public class PdfRowParameters + { + public List Texts { get; set; } = new(); + public string Style { get; set; } = string.Empty; + public PdfParagraphAlignmentType ParagraphAlignment { get; set; } + + } +} diff --git a/VetClinic/VetClinicBusinessLogic/OfficePackage/Implements/SaveToPdfPharmacist.cs b/VetClinic/VetClinicBusinessLogic/OfficePackage/Implements/SaveToPdfPharmacist.cs new file mode 100644 index 0000000..7229c03 --- /dev/null +++ b/VetClinic/VetClinicBusinessLogic/OfficePackage/Implements/SaveToPdfPharmacist.cs @@ -0,0 +1,107 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using VetClinicBusinessLogic.OfficePackage.HelperEnums; +using VetClinicBusinessLogic.OfficePackage.HelperModels; +using MigraDoc.DocumentObjectModel; +using MigraDoc.DocumentObjectModel.Tables; +using MigraDoc.Rendering; + +namespace VetClinicBusinessLogic.OfficePackage.Implements +{ + public class SaveToPdfPharmacist : AbstractSaveToPdfPharmacist + { + private Document? _document; + private Section? _section; + private Table? _table; + private static ParagraphAlignment + GetParagraphAlignment(PdfParagraphAlignmentType type) + { + return type switch + { + PdfParagraphAlignmentType.Center => ParagraphAlignment.Center, + PdfParagraphAlignmentType.Left => ParagraphAlignment.Left, + PdfParagraphAlignmentType.Rigth => ParagraphAlignment.Right, + _ => ParagraphAlignment.Justify, + }; + } + /// + /// Создание стилей для документа + /// + /// + private static void DefineStyles(Document document) + { + var style = document.Styles["Normal"]; + style.Font.Name = "Times New Roman"; + style.Font.Size = 14; + style = document.Styles.AddStyle("NormalTitle", "Normal"); + style.Font.Bold = true; + } + protected override void CreatePdf(PdfInfo info) + { + _document = new Document(); + DefineStyles(_document); + _section = _document.AddSection(); + } + protected override void CreateParagraph(PdfParagraph pdfParagraph) + { + if (_section == null) + { + return; + } + var paragraph = _section.AddParagraph(pdfParagraph.Text); + paragraph.Format.SpaceAfter = "1cm"; + paragraph.Format.Alignment = + GetParagraphAlignment(pdfParagraph.ParagraphAlignment); + paragraph.Style = pdfParagraph.Style; + } + protected override void CreateTable(List columns) + { + if (_document == null) + { + return; + } + _table = _document.LastSection.AddTable(); + foreach (var elem in columns) + { + _table.AddColumn(elem); + } + } + protected override void CreateRow(PdfRowParameters rowParameters) + { + if (_table == null) + { + return; + } + var row = _table.AddRow(); + for (int i = 0; i < rowParameters.Texts.Count; ++i) + { + row.Cells[i].AddParagraph(rowParameters.Texts[i]); + if (!string.IsNullOrEmpty(rowParameters.Style)) + { + row.Cells[i].Style = rowParameters.Style; + } + Unit borderWidth = 0.5; + row.Cells[i].Borders.Left.Width = borderWidth; + row.Cells[i].Borders.Right.Width = borderWidth; + row.Cells[i].Borders.Top.Width = borderWidth; + row.Cells[i].Borders.Bottom.Width = borderWidth; + row.Cells[i].Format.Alignment = + GetParagraphAlignment(rowParameters.ParagraphAlignment); + row.Cells[i].VerticalAlignment = VerticalAlignment.Center; + } + } + protected override void SavePdf(PdfInfo info) + { + var renderer = new PdfDocumentRenderer(true) + { + Document = _document + }; + renderer.RenderDocument(); + renderer.PdfDocument.Save(info.FileName); + } + } + +} diff --git a/VetClinic/VetClinicBusinessLogic/VetClinicBusinessLogic.csproj b/VetClinic/VetClinicBusinessLogic/VetClinicBusinessLogic.csproj index 53d9c2b..237dc55 100644 --- a/VetClinic/VetClinicBusinessLogic/VetClinicBusinessLogic.csproj +++ b/VetClinic/VetClinicBusinessLogic/VetClinicBusinessLogic.csproj @@ -16,6 +16,7 @@ + diff --git a/VetClinic/VetClinicContracts/BindingModels/MailConfigBindingModel.cs b/VetClinic/VetClinicContracts/BindingModels/MailConfigBindingModel.cs new file mode 100644 index 0000000..b95217f --- /dev/null +++ b/VetClinic/VetClinicContracts/BindingModels/MailConfigBindingModel.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace VetClinicContracts.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/VetClinic/VetClinicContracts/BindingModels/MailSendInfoBindingModel.cs b/VetClinic/VetClinicContracts/BindingModels/MailSendInfoBindingModel.cs new file mode 100644 index 0000000..df45f6e --- /dev/null +++ b/VetClinic/VetClinicContracts/BindingModels/MailSendInfoBindingModel.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace VetClinicContracts.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/VetClinic/VetClinicContracts/BindingModels/VisitsGuidesBindingModel.cs b/VetClinic/VetClinicContracts/BindingModels/VisitsGuidesBindingModel.cs index 33d5ed9..2a605d1 100644 --- a/VetClinic/VetClinicContracts/BindingModels/VisitsGuidesBindingModel.cs +++ b/VetClinic/VetClinicContracts/BindingModels/VisitsGuidesBindingModel.cs @@ -9,8 +9,9 @@ namespace VetClinicContracts.BindingModels public class VisitsGuidesBindingModel { public string FileName { get; set; } = string.Empty; - public List Medicines { get; set; } = new(); - DateTime DateFrom { get; set; } = DateTime.Now; - DateTime DateTo { get; set; } = DateTime.Now; + public DateTime DateFrom { get; set; } = DateTime.Now; + public DateTime DateTo { get; set; } = DateTime.Now; + public int? PharmacistId { get; set; } + public string? Email { get; set; } } } diff --git a/VetClinic/VetClinicContracts/BusinessLogicsContracts/IReportLogicPharmacist.cs b/VetClinic/VetClinicContracts/BusinessLogicsContracts/IReportLogicPharmacist.cs index 46d6def..f6611d8 100644 --- a/VetClinic/VetClinicContracts/BusinessLogicsContracts/IReportLogicPharmacist.cs +++ b/VetClinic/VetClinicContracts/BusinessLogicsContracts/IReportLogicPharmacist.cs @@ -5,13 +5,16 @@ using System.Text; using System.Threading.Tasks; using VetClinicContracts.BindingModels; using VetClinicContracts.ViewModels; +using VetClinicDataBaseImplement.Implements; namespace VetClinicContracts.BusinessLogicsContracts { - public interface IReportLogicPharmacist //Будет дорабатываться + public interface IReportLogicPharmacist { List GetServiceAnimals(List services); void SaveAnimalsToWordFile(ListAnimalsBindingModel model); void SaveAnimalsToExcelFile(ListAnimalsBindingModel model); + List GetMedicineVisitsAndGuidances(VisitsGuidesBindingModel services); + void SaveMedicinesToPdfFile(VisitsGuidesBindingModel model); } } diff --git a/VetClinic/VetClinicContracts/SearchModels/VisitGuidesSearchModel.cs b/VetClinic/VetClinicContracts/SearchModels/VisitGuidesSearchModel.cs index c25ab26..d9e777d 100644 --- a/VetClinic/VetClinicContracts/SearchModels/VisitGuidesSearchModel.cs +++ b/VetClinic/VetClinicContracts/SearchModels/VisitGuidesSearchModel.cs @@ -11,5 +11,6 @@ namespace VetClinicContracts.SearchModels public List? medicinesIds { get; set; } public DateTime? DateFrom { get; set; } public DateTime? DateTo { get; set; } + public int? PharmacistId { get; set; } } } diff --git a/VetClinic/VetClinicContracts/ViewModels/VisitsGuidesViewModel.cs b/VetClinic/VetClinicContracts/ViewModels/VisitsGuidesViewModel.cs index f6235fb..230dbcb 100644 --- a/VetClinic/VetClinicContracts/ViewModels/VisitsGuidesViewModel.cs +++ b/VetClinic/VetClinicContracts/ViewModels/VisitsGuidesViewModel.cs @@ -12,7 +12,5 @@ namespace VetClinicDataBaseImplement.Implements public string MedicineName { get; set; } = string.Empty; public List Visits { get; set; } = new(); public List Guidances { get; set; } = new(); - public DateTime DateFrom { get; set; } = DateTime.Now; - public DateTime DateTo { get; set; } = DateTime.Now; } } diff --git a/VetClinic/VetClinicDataBaseImplement/Implements/MedicineStorage.cs b/VetClinic/VetClinicDataBaseImplement/Implements/MedicineStorage.cs index e5932ab..25abd25 100644 --- a/VetClinic/VetClinicDataBaseImplement/Implements/MedicineStorage.cs +++ b/VetClinic/VetClinicDataBaseImplement/Implements/MedicineStorage.cs @@ -35,13 +35,8 @@ namespace VetClinicDataBaseImplement.Implements } public List>>>> GetGuidancesInfo(VisitGuidesSearchModel model) { - if (model.medicinesIds == null) - { - return new(); - } using var context = new VetClinicDatabase(); - return context.Medicines - .Where(medicine => model.medicinesIds.Contains(medicine.Id)) + return context.Medicines.Where(medicine => medicine.PharmacistId == model.PharmacistId) .Select(medicine => new Tuple>>>(medicine.GetViewModel, context.ServiceMedicines.Include(service => service.Service) .Include(service => service.Medicine).Where(service => medicine.Id == service.MedicineId). @@ -52,14 +47,9 @@ namespace VetClinicDataBaseImplement.Implements } public List>>>> GetVisitsInfo(VisitGuidesSearchModel model) { - if (model.medicinesIds == null) - { - return new(); - } using var context = new VetClinicDatabase(); - return context.Medicines - .Where(medicine => model.medicinesIds.Contains(medicine.Id)) - .Select(medicine => new Tuple>>>(medicine.GetViewModel, + return context.Medicines.Where(medicine => medicine.PharmacistId == model.PharmacistId) + .Select(medicine => new Tuple>>>(medicine.GetViewModel, context.ServiceMedicines.Include(service => service.Service) .Include(service => service.Medicine).Where(service => medicine.Id == service.MedicineId). Select(service => new Tuple>(service.Service.GetViewModel, diff --git a/VetClinic/VetClinicDataBaseImplement/Implements/VisitsGuidesViewModel.cs b/VetClinic/VetClinicDataBaseImplement/Implements/VisitsGuidesViewModel.cs deleted file mode 100644 index 549f058..0000000 --- a/VetClinic/VetClinicDataBaseImplement/Implements/VisitsGuidesViewModel.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using VetClinicContracts.ViewModels; - -namespace VetClinicDataBaseImplement.Implements -{ - public class VisitsGuidesViewModel - { - string MedicineName { get; set; } = string.Empty; - List Visits { get; set; } = new(); - List Guidances { get; set; } = new(); - } -} diff --git a/VetClinic/VetClinicDataBaseImplement/Migrations/20240428120220_InitialCreate.Designer.cs b/VetClinic/VetClinicDataBaseImplement/Migrations/20240428120220_InitialCreate.Designer.cs index 986e936..a80c663 100644 --- a/VetClinic/VetClinicDataBaseImplement/Migrations/20240428120220_InitialCreate.Designer.cs +++ b/VetClinic/VetClinicDataBaseImplement/Migrations/20240428120220_InitialCreate.Designer.cs @@ -5,7 +5,7 @@ using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using VetClinicDataBaseImplement; +using VetClinicContracts.ViewModels; #nullable disable diff --git a/VetClinic/VetClinicDataBaseImplement/Migrations/VetClinicDatabaseModelSnapshot.cs b/VetClinic/VetClinicDataBaseImplement/Migrations/VetClinicDatabaseModelSnapshot.cs index ce5bfb5..0dfdfde 100644 --- a/VetClinic/VetClinicDataBaseImplement/Migrations/VetClinicDatabaseModelSnapshot.cs +++ b/VetClinic/VetClinicDataBaseImplement/Migrations/VetClinicDatabaseModelSnapshot.cs @@ -4,7 +4,7 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using VetClinicDataBaseImplement; +using VetClinicContracts.ViewModels; #nullable disable diff --git a/VetClinic/VetClinicDataBaseImplement/VetClinicDatabase .cs b/VetClinic/VetClinicDataBaseImplement/VetClinicDatabase .cs index 1d9e6df..3aa2bb9 100644 --- a/VetClinic/VetClinicDataBaseImplement/VetClinicDatabase .cs +++ b/VetClinic/VetClinicDataBaseImplement/VetClinicDatabase .cs @@ -11,7 +11,7 @@ namespace VetClinicDataBaseImplement { if (optionsBuilder.IsConfigured == false) { - optionsBuilder.UseSqlServer(@"Data Source=localhost\SQLEXPRESS02;Initial Catalog=VetClinicDatabase;Integrated Security=True;MultipleActiveResultSets=True;;TrustServerCertificate=True"); + optionsBuilder.UseSqlServer(@"Data Source=localhost\SQLEXPRESS;Initial Catalog=VetClinicDatabase;Integrated Security=True;MultipleActiveResultSets=True;;TrustServerCertificate=True"); } base.OnConfiguring(optionsBuilder); } diff --git a/VetClinic/VetClinicRestApi/Controllers/ReportController.cs b/VetClinic/VetClinicRestApi/Controllers/ReportController.cs new file mode 100644 index 0000000..2ecffa6 --- /dev/null +++ b/VetClinic/VetClinicRestApi/Controllers/ReportController.cs @@ -0,0 +1,87 @@ +using Microsoft.AspNetCore.Mvc; +using VetClinicBusinessLogic.BusinessLogics; +using VetClinicBusinessLogic.MailWorker; +using VetClinicContracts.BindingModels; +using VetClinicContracts.BusinessLogicsContracts; +using VetClinicDataBaseImplement.Implements; + +namespace VetClinicRestApi.Controllers +{ + [Route("api/[controller]/[action]")] + [ApiController] + public class ReportController : Controller + { + private readonly IReportLogicPharmacist _reportPharmacist; + private readonly AbstractMailWorker _mailWorker; + public ReportController(ILogger logger, IReportLogicPharmacist reportPharmacist,AbstractMailWorker mailWorker) + { + _reportPharmacist = reportPharmacist; + _mailWorker = mailWorker; + } + public IActionResult Index(ReportLogicPharmacist reportPharmacist) + { + return View(); + } + [HttpPost] + public void CreateAnimalListWordFile(ListAnimalsBindingModel model) + { + try + { + _reportPharmacist.SaveAnimalsToWordFile(model); + } + catch (Exception ex) + { + throw; + } + } + [HttpPost] + public void CreateAnimalListExcelFile(ListAnimalsBindingModel model) + { + try + { + _reportPharmacist.SaveAnimalsToExcelFile(model); + } + catch (Exception ex) + { + throw; + } + } + [HttpGet] + public List GetVisitsGuidesReport(string dateFrom, string dateTo, int pharmacistId) + { + try + { + DateTime DateFrom = DateTime.Parse(dateFrom); + DateTime DateTo = DateTime.Parse(dateTo); + VisitsGuidesBindingModel model = new(); + model.DateFrom = DateFrom; + model.DateTo = DateTo; + model.PharmacistId = pharmacistId; + return _reportPharmacist.GetMedicineVisitsAndGuidances(model); + } + catch (Exception ex) + { + throw; + } + } + + [HttpPost] + public void SendVisitsGuidesReportToEmail(VisitsGuidesBindingModel model) + { + try + { + _reportPharmacist.SaveMedicinesToPdfFile(model); + _mailWorker.MailSendAsync(new MailSendInfoBindingModel + { + MailAddress = model.Email!, + Subject = "Отчет по медикаментам", + Text = "Лови" + }); + } + catch (Exception ex) + { + throw; + } + } + } +} diff --git a/VetClinic/VetClinicRestApi/Program.cs b/VetClinic/VetClinicRestApi/Program.cs index ac29eb0..da7360b 100644 --- a/VetClinic/VetClinicRestApi/Program.cs +++ b/VetClinic/VetClinicRestApi/Program.cs @@ -4,6 +4,10 @@ using VetClinicContracts.StoragesContracts; using VetClinicDataBaseImplement.Implements; using Microsoft.OpenApi.Models; using VetClinicBaseImplement.Implements; +using VetClinicBusinessLogic.OfficePackage; +using VetClinicBusinessLogic.OfficePackage.Implements; +using VetClinicBusinessLogic.MailWorker; +using VetClinicContracts.BindingModels; var builder = WebApplication.CreateBuilder(args); @@ -30,6 +34,12 @@ builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient(); +builder.Services.AddTransient(); +builder.Services.AddTransient(); +builder.Services.AddTransient(); +builder.Services.AddTransient(); +builder.Services.AddSingleton(); + builder.Services.AddControllers(); // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle @@ -40,6 +50,24 @@ builder.Services.AddSwaggerGen(c => c.SwaggerDoc("v1", new OpenApiInfo { Title = "VetClinicRestApi", Version = "v1" }); }); var app = builder.Build(); +var mailSender = app.Services.GetService(); +mailSender?.MailConfig(new MailConfigBindingModel +{ + MailLogin = builder.Configuration?.GetSection("MailLogin")?.Value?.ToString() +?? string.Empty, + MailPassword = +builder.Configuration?.GetSection("MailPassword")?.Value?.ToString() ?? +string.Empty, + SmtpClientHost = +builder.Configuration?.GetSection("SmtpClientHost")?.Value?.ToString() ?? +string.Empty, + SmtpClientPort = +Convert.ToInt32(builder.Configuration?.GetSection("SmtpClientPort")?.Value?.ToString()), + PopHost = builder.Configuration?.GetSection("PopHost")?.Value?.ToString() ?? +string.Empty, + PopPort = Convert.ToInt32(builder.Configuration?.GetSection("PopPort")?.Value?.ToString()) +}); + // Configure the HTTP request pipeline. if (app.Environment.IsDevelopment()) diff --git a/VetClinic/VetClinicRestApi/VetClinicRestApi.csproj b/VetClinic/VetClinicRestApi/VetClinicRestApi.csproj index 51ac888..9c5ed23 100644 --- a/VetClinic/VetClinicRestApi/VetClinicRestApi.csproj +++ b/VetClinic/VetClinicRestApi/VetClinicRestApi.csproj @@ -1,4 +1,4 @@ - + net8.0 @@ -17,4 +17,8 @@ + + + + diff --git a/VetClinic/VetClinicRestApi/appsettings.json b/VetClinic/VetClinicRestApi/appsettings.json index 10f68b8..01ad592 100644 --- a/VetClinic/VetClinicRestApi/appsettings.json +++ b/VetClinic/VetClinicRestApi/appsettings.json @@ -5,5 +5,11 @@ "Microsoft.AspNetCore": "Warning" } }, - "AllowedHosts": "*" + "AllowedHosts": "*", + "SmtpClientHost": "smtp.gmail.com", + "SmtpClientPort": "587", + "PopHost": "pop.gmail.com", + "PopPort": "995", + "MailLogin": "sasda3183@gmail.com", + "MailPassword": "ozxp vjof uinv fcmj" }