From 911e9f8393615f76155aef10f533c972525a93b0 Mon Sep 17 00:00:00 2001 From: Bulat Date: Thu, 19 Dec 2024 15:13:00 +0400 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D0=B4=D0=B5=D0=BB=D0=B0=D0=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Entities/DrugMedicalHistory.cs | 7 +- .../Entities/MedicalHistory.cs | 15 +-- .../Forms/FormDrugReport.Designer.cs | 18 +-- .../Forms/FormDrugReport.cs | 21 ++-- .../Forms/FormMedicalHistory.cs | 4 +- .../Reports/ChartReport.cs | 40 ++++-- .../Reports/TableReport.cs | 118 +++++++++++++++--- .../MedicalHistoryRepository.cs | 14 ++- 8 files changed, 180 insertions(+), 57 deletions(-) diff --git a/RegistrationPatientsPolyclinic/RegistrationPatientsPolyclinic/Entities/DrugMedicalHistory.cs b/RegistrationPatientsPolyclinic/RegistrationPatientsPolyclinic/Entities/DrugMedicalHistory.cs index c0f0a42..caf9098 100644 --- a/RegistrationPatientsPolyclinic/RegistrationPatientsPolyclinic/Entities/DrugMedicalHistory.cs +++ b/RegistrationPatientsPolyclinic/RegistrationPatientsPolyclinic/Entities/DrugMedicalHistory.cs @@ -17,15 +17,16 @@ public class DrugMedicalHistory // Тоже самое что FeedFeedRepleshme public string Description { get; private set; } = string.Empty; + public int MedicalHistoryId { get; private set; } - - public static DrugMedicalHistory CreateEntity(int id, int drugId, string description) + public static DrugMedicalHistory CreateEntity(int id, int drugId, string description, int medicalHistoryId) { return new DrugMedicalHistory { Id = id, DrugId = drugId, - Description = description ?? string.Empty + Description = description ?? string.Empty, + MedicalHistoryId = medicalHistoryId }; } } diff --git a/RegistrationPatientsPolyclinic/RegistrationPatientsPolyclinic/Entities/MedicalHistory.cs b/RegistrationPatientsPolyclinic/RegistrationPatientsPolyclinic/Entities/MedicalHistory.cs index b84239d..f01decc 100644 --- a/RegistrationPatientsPolyclinic/RegistrationPatientsPolyclinic/Entities/MedicalHistory.cs +++ b/RegistrationPatientsPolyclinic/RegistrationPatientsPolyclinic/Entities/MedicalHistory.cs @@ -28,13 +28,14 @@ public class MedicalHistory // сущность пополнения, напо public DateTime VisitDate { get; private set; } - - public string Drug => DrugMedicalHistory != null ? - string.Join(", ", DrugMedicalHistory.Select(x => $"{x.Id} {x.Description}")) : - string.Empty; - [Browsable(false)] - public IEnumerable DrugMedicalHistory { get; set; } = []; + public IEnumerable DrugMedicalHistory { get; set; } = []; + + + [DisplayName("Назначенные лекарства")] + public string DrugsSummary => string.Join(", ", DrugMedicalHistory + .Select(d => $" {d.DrugId}, {d.Description}")); + public static MedicalHistory CreateEntity(int id, int patientId, int doctorId, IEnumerable drugMedicalHistory) @@ -61,7 +62,7 @@ public class MedicalHistory // сущность пополнения, напо }; } */ - public void SetProductMaterial(IEnumerable drugMedicalHistory) + public void SetDrugMedHistory(IEnumerable drugMedicalHistory) { if (drugMedicalHistory != null && drugMedicalHistory.Any()) { diff --git a/RegistrationPatientsPolyclinic/RegistrationPatientsPolyclinic/Forms/FormDrugReport.Designer.cs b/RegistrationPatientsPolyclinic/RegistrationPatientsPolyclinic/Forms/FormDrugReport.Designer.cs index b135844..e87e4f0 100644 --- a/RegistrationPatientsPolyclinic/RegistrationPatientsPolyclinic/Forms/FormDrugReport.Designer.cs +++ b/RegistrationPatientsPolyclinic/RegistrationPatientsPolyclinic/Forms/FormDrugReport.Designer.cs @@ -31,7 +31,7 @@ dateTimePickerStart = new DateTimePicker(); textBoxFilePath = new TextBox(); buttonSelectFilePath = new Button(); - comboBoxDrug = new ComboBox(); + comboBoxDoctor = new ComboBox(); dateTimePickerEnd = new DateTimePicker(); labelFilePath = new Label(); labelDrug = new Label(); @@ -65,13 +65,13 @@ buttonSelectFilePath.UseVisualStyleBackColor = true; buttonSelectFilePath.Click += buttonSelectFilePath_Click; // - // comboBoxDrug + // comboBoxDoctor // - comboBoxDrug.FormattingEnabled = true; - comboBoxDrug.Location = new Point(140, 143); - comboBoxDrug.Name = "comboBoxDrug"; - comboBoxDrug.Size = new Size(125, 28); - comboBoxDrug.TabIndex = 3; + comboBoxDoctor.FormattingEnabled = true; + comboBoxDoctor.Location = new Point(140, 143); + comboBoxDoctor.Name = "comboBoxDoctor"; + comboBoxDoctor.Size = new Size(125, 28); + comboBoxDoctor.TabIndex = 3; // // dateTimePickerEnd // @@ -137,7 +137,7 @@ Controls.Add(labelDrug); Controls.Add(labelFilePath); Controls.Add(dateTimePickerEnd); - Controls.Add(comboBoxDrug); + Controls.Add(comboBoxDoctor); Controls.Add(buttonSelectFilePath); Controls.Add(textBoxFilePath); Controls.Add(dateTimePickerStart); @@ -152,7 +152,7 @@ private DateTimePicker dateTimePickerStart; private TextBox textBoxFilePath; private Button buttonSelectFilePath; - private ComboBox comboBoxDrug; + private ComboBox comboBoxDoctor; private DateTimePicker dateTimePickerEnd; private Label labelFilePath; private Label labelDrug; diff --git a/RegistrationPatientsPolyclinic/RegistrationPatientsPolyclinic/Forms/FormDrugReport.cs b/RegistrationPatientsPolyclinic/RegistrationPatientsPolyclinic/Forms/FormDrugReport.cs index b30e10e..c84e8ec 100644 --- a/RegistrationPatientsPolyclinic/RegistrationPatientsPolyclinic/Forms/FormDrugReport.cs +++ b/RegistrationPatientsPolyclinic/RegistrationPatientsPolyclinic/Forms/FormDrugReport.cs @@ -17,15 +17,15 @@ namespace RegistrationPatientsPolyclinic.Forms { private readonly IUnityContainer _container; - public FormDrugReport(IUnityContainer container, IDrugRepository drugRepository) + public FormDrugReport(IUnityContainer container, IDrugRepository drugRepository, IDoctorRepository doctorRepository) { InitializeComponent(); _container = container ?? throw new ArgumentNullException(nameof(container)); - comboBoxDrug.DataSource = drugRepository.ReadDrug(); - comboBoxDrug.DisplayMember = "Name"; - comboBoxDrug.ValueMember = "Id"; + comboBoxDoctor.DataSource = doctorRepository.ReadDoctors(); + comboBoxDoctor.DisplayMember = "FullName"; + comboBoxDoctor.ValueMember = "Id"; } @@ -50,16 +50,21 @@ namespace RegistrationPatientsPolyclinic.Forms { throw new Exception("Отсутствует имя файла для отчета"); } - if (comboBoxDrug.SelectedIndex < 0) + if (comboBoxDoctor.SelectedIndex < 0) { - throw new Exception("Не выбран корм"); + throw new Exception("Не выбран врач"); } if (dateTimePickerEnd.Value <= dateTimePickerStart.Value) { throw new Exception("Дата начала должна быть раньше даты окончания"); } - if (_container.Resolve().CreateTable(textBoxFilePath.Text, (int)comboBoxDrug.SelectedValue!, - dateTimePickerStart.Value, dateTimePickerEnd.Value)) + + // Приведение дат к началу и концу месяца + var startDate = new DateTime(dateTimePickerStart.Value.Year, dateTimePickerStart.Value.Month, 1); + var endDate = new DateTime(dateTimePickerEnd.Value.Year, dateTimePickerEnd.Value.Month, 1).AddMonths(1).AddDays(-1); + + if (_container.Resolve().CreateTable(textBoxFilePath.Text, (int)comboBoxDoctor.SelectedValue!, + startDate, endDate)) { MessageBox.Show("Документ сформирован", "Формирование документа", MessageBoxButtons.OK, MessageBoxIcon.Information); } diff --git a/RegistrationPatientsPolyclinic/RegistrationPatientsPolyclinic/Forms/FormMedicalHistory.cs b/RegistrationPatientsPolyclinic/RegistrationPatientsPolyclinic/Forms/FormMedicalHistory.cs index 5fbb40b..657d9c9 100644 --- a/RegistrationPatientsPolyclinic/RegistrationPatientsPolyclinic/Forms/FormMedicalHistory.cs +++ b/RegistrationPatientsPolyclinic/RegistrationPatientsPolyclinic/Forms/FormMedicalHistory.cs @@ -91,10 +91,10 @@ _medicalHistoryRepository.ReadMedicalHistory(); { continue; } - list.Add(DrugMedicalHistory.CreateEntity(0, Convert.ToInt32(row.Cells["ColumnDrug"].Value), row.Cells["ColumnDescription"].Value?.ToString())); + list.Add(DrugMedicalHistory.CreateEntity(0, Convert.ToInt32(row.Cells["ColumnDrug"].Value), row.Cells["ColumnDescription"].Value?.ToString(), 0)); } return list.GroupBy(x => x.DrugId, x => x.Description, (id, description) => - DrugMedicalHistory.CreateEntity(0, id, string.Join(", ", description))).ToList(); + DrugMedicalHistory.CreateEntity(0, id, string.Join(", ", description), 0)).ToList(); } } diff --git a/RegistrationPatientsPolyclinic/RegistrationPatientsPolyclinic/Reports/ChartReport.cs b/RegistrationPatientsPolyclinic/RegistrationPatientsPolyclinic/Reports/ChartReport.cs index 2584078..bf87118 100644 --- a/RegistrationPatientsPolyclinic/RegistrationPatientsPolyclinic/Reports/ChartReport.cs +++ b/RegistrationPatientsPolyclinic/RegistrationPatientsPolyclinic/Reports/ChartReport.cs @@ -1,5 +1,6 @@ using Microsoft.Extensions.Logging; using RegistrationPatientsPolyclinic.Repositories; +using RegistrationPatientsPolyclinic.Repositories.Implementations; using System; using System.Collections.Generic; using System.Linq; @@ -14,10 +15,12 @@ internal class ChartReport private readonly IMedicalHistoryRepository _medicalHistoryRepository; private readonly ILogger _logger; - public ChartReport(IMedicalHistoryRepository medicalHistoryRepository, ILogger logger) + public ChartReport(IMedicalHistoryRepository medicalHistoryRepository, IDoctorPaymentsRepository doctorPaymentsRepository, ILogger logger) { _medicalHistoryRepository = medicalHistoryRepository ?? throw new ArgumentNullException(nameof(medicalHistoryRepository)); + _doctorPaymentsRepository = doctorPaymentsRepository ?? + throw new ArgumentNullException(nameof(doctorPaymentsRepository)); _logger = logger ?? throw new ArgumentNullException(nameof(logger)); } @@ -27,8 +30,8 @@ internal class ChartReport try { new PdfBuilder(filePath) - .AddHeader("Пополенение лекарства") - .AddPieChart("Виды лекарства", GetData(dateTime)) + .AddHeader($"Выписанные лекарства на {dateTime:dd.MM.yyyy}") + .AddPieChart("Соотношение выписанных лекарств по врачам", GetData(dateTime)) .Build(); return true; } @@ -41,12 +44,33 @@ internal class ChartReport private List<(string Caption, double Value)> GetData(DateTime dateTime) { // Получаем все медицинские истории за указанную дату - var medicalHistories = _medicalHistoryRepository.ReadMedicalHistory(dateTime, dateTime); + var medicalHistories = _medicalHistoryRepository.ReadMedicalHistory(null, null, null, null); - // Группируем по идентификатору пациента и считаем количество посещений - return medicalHistories - .GroupBy(mh => mh.PatientId) - .Select(g => (Caption: $"Patient {g.Key}", Value: (double)g.Count())) + // Фильтруем истории, где есть назначения лекарств + var filteredHistories = medicalHistories + .Where(mh => mh.VisitDate.Date == dateTime.Date) + .Where(mh => mh.DrugMedicalHistory != null && mh.DrugMedicalHistory.Any()) .ToList(); + + // Группируем по имени врача и считаем количество назначений лекарств + var groupedData = filteredHistories + .GroupBy( + mh => mh.DoctorName, + (doctorName, group) => new + { + DoctorName = doctorName, + TotalDrugAssignments = group + .SelectMany(mh => mh.DrugMedicalHistory) + .Count() // Считаем количество назначений лекарств + } + ) + .ToList(); + + // Преобразуем данные в формат, подходящий для диаграммы + var result = groupedData + .Select(x => (Caption: x.DoctorName, Value: (double)x.TotalDrugAssignments)) + .ToList(); + + return result; } } diff --git a/RegistrationPatientsPolyclinic/RegistrationPatientsPolyclinic/Reports/TableReport.cs b/RegistrationPatientsPolyclinic/RegistrationPatientsPolyclinic/Reports/TableReport.cs index 2a3438a..1b14c80 100644 --- a/RegistrationPatientsPolyclinic/RegistrationPatientsPolyclinic/Reports/TableReport.cs +++ b/RegistrationPatientsPolyclinic/RegistrationPatientsPolyclinic/Reports/TableReport.cs @@ -22,11 +22,13 @@ internal class TableReport private readonly IDrugRepository _drugRepository; + private readonly IDoctorRepository _doctorRepository; + private readonly ILogger _logger; - internal static readonly string[] item = ["Доктор", "Описание", "Количество пациентов"]; + internal static readonly string[] item = ["Id врача", "Количество пациентов", "Выплаты"]; - public TableReport(IMedicalHistoryRepository medicalHistoryRepository, IDoctorPaymentsRepository doctorPaymentsRepository, IDrugRepository drugRepository, ILogger logger) + public TableReport(IMedicalHistoryRepository medicalHistoryRepository, IDoctorPaymentsRepository doctorPaymentsRepository, IDoctorRepository doctorRepository, IDrugRepository drugRepository, ILogger logger) { _medicalHistoryRepository = medicalHistoryRepository ?? throw new ArgumentNullException(nameof(medicalHistoryRepository)); ; @@ -34,27 +36,35 @@ internal class TableReport throw new ArgumentNullException(nameof(doctorPaymentsRepository)); _drugRepository = drugRepository ?? throw new ArgumentNullException(nameof(drugRepository)); + _doctorRepository = doctorRepository ?? + throw new ArgumentNullException(nameof(IMedicalHistoryRepository)); _logger = logger ?? throw new ArgumentNullException(nameof(logger)); } - public bool CreateTable(string filePath, int drugId, DateTime startDate, DateTime endDate) + public bool CreateTable(string filePath, int doctorId, DateTime startDate, DateTime endDate) { try { - var data = GetData(drugId, startDate, endDate); - var columnsWidths = new int[] {10, 15, 15 }; + var startOfMonth = new DateTime(startDate.Year, startDate.Month, 1); + var endOfMonth = new DateTime(endDate.Year, endDate.Month, 1).AddMonths(1).AddDays(-1); - if (columnsWidths.Length != data.First().Length) - { - throw new InvalidOperationException("Количество ширин столбцов не соответствует количеству данных."); - } + // Получаем данные для таблицы и имя врача + var (tableData, doctorFullName) = GetData(doctorId, startOfMonth, endOfMonth); - new ExcelBuilder(filePath) - .AddHeader("Сводка по движению лекарство", 0, 3) - .AddParagraph("за период", 0) - .AddTable(columnsWidths, data) - .Build(); + var excelBuilder = new ExcelBuilder(filePath) + .AddHeader("Сводка по оплате", 0, 3) + .AddParagraph($"За период с {startOfMonth:MMMM yyyy} по {endOfMonth:MMMM yyyy}", 0) + .AddParagraph($"Врач: {doctorFullName}", 0) + .AddTable(new[] { 25, 25, 25 }, tableData); + + excelBuilder.AddParagraph("", 0); + + excelBuilder + .AddHeader("Назначенные лекарства", 0, 2) + .AddTable(new[] { 25, 25 }, GetDrugData(doctorId, startOfMonth, endOfMonth)); + + excelBuilder.Build(); return true; } catch (Exception ex) @@ -126,6 +136,8 @@ internal class TableReport */ + // ВНИЗУ САМЫЙ ПОСЛЕДНИЙ!!! + /* private List GetData(int drugId, DateTime startDate, DateTime endDate) { var data = _medicalHistoryRepository @@ -153,4 +165,82 @@ internal class TableReport new List() { new string[] { "Всего", string.Empty, data.Sum(x => x.CountOut ?? 0).ToString() } }) .ToList(); } + */ + + private (List, string) GetData(int doctorId, DateTime startOfMonth, DateTime endOfMonth) + { + var data = _doctorPaymentsRepository + .ReadDoctorPayments() + .Where(x => + { + var IdDoctorss = x.IdDoctor; + return IdDoctorss == doctorId; + }) + .Select(x => new + { + DoctorName = x.DoctorName, // Предполагается, что есть поле DoctorName + CountOfPatients = x.Count_Patient, + Payments = x.Payment + }) + .ToList(); + + var doctorName = data.FirstOrDefault()?.DoctorName ?? "Неизвестный врач"; + + var result = new List() + { + new[] { "Имя Врача", "Количество пациентов", "Выплаты" } + } + .Union( + data.Select(x => new string[] + { + x.DoctorName, + x.CountOfPatients.ToString(), + x.Payments.ToString() + }) + ) + .Union( + new[] + { + new string[] + { + "Всего", + data.Sum(x => x.CountOfPatients).ToString(), + data.Sum(x => x.Payments).ToString() + } + } + ) + .ToList(); + + return (result, doctorName); + } + + private List GetDrugData(int doctorId, DateTime startOfMonth, DateTime endOfMonth) + { + var medicalHistories = _medicalHistoryRepository + .ReadMedicalHistory(startOfMonth, endOfMonth, doctorId, null) // Исправлено + .Where(mh => mh.DrugMedicalHistory != null && mh.DrugMedicalHistory.Any()) + .ToList(); + + _logger.LogDebug("Полученные медицинские истории с лекарствами: {data}", JsonConvert.SerializeObject(medicalHistories)); + + var drugData = medicalHistories + .SelectMany(mh => mh.DrugMedicalHistory.Select(drug => new + { + Date = mh.VisitDate, + Count = drug.Description + })) + .OrderBy(x => x.Date) + .ToList(); + + var result = new List { new[] { "Дата", "Назначенные лекарства" } }; + + result.AddRange(drugData.Select(item => new string[] + { + item.Date.ToString("dd MMMM yyyy"), + item.Count.ToString() + })); + + + return result; + } } diff --git a/RegistrationPatientsPolyclinic/RegistrationPatientsPolyclinic/Repositories/Implementations/MedicalHistoryRepository.cs b/RegistrationPatientsPolyclinic/RegistrationPatientsPolyclinic/Repositories/Implementations/MedicalHistoryRepository.cs index 0695d4b..347617c 100644 --- a/RegistrationPatientsPolyclinic/RegistrationPatientsPolyclinic/Repositories/Implementations/MedicalHistoryRepository.cs +++ b/RegistrationPatientsPolyclinic/RegistrationPatientsPolyclinic/Repositories/Implementations/MedicalHistoryRepository.cs @@ -150,26 +150,28 @@ WHERE Id=@id"; var querySelect = $@"SELECT mh.*, CONCAT(p.Last_Name, ' ', p.First_Name) as PatientName, CONCAT(d.Last_Name, ' ', d.First_Name) as DoctorName, - dmh.Id AS Id, dmh.DrugId AS drugId, dmh.Description AS Description + dmh.Id AS Id, dmh.DrugId AS drugId,dmh.MedicalHistoryId AS MedicalHistoryId, dmh.Description FROM MedicalHistory mh LEFT JOIN DrugMedicalHistory dmh ON dmh.MedicalHistoryId = mh.Id LEFT JOIN Patient p ON p.Id = mh.PatientId LEFT JOIN doctor d ON d.Id = mh.DoctorId {builder.Build()}"; - + _logger.LogDebug("SQL запрос: {query}", querySelect); + _logger.LogDebug("Параметры: dateForm = {dateForm}, dateTo = {dateTo}, doctorId = {doctorId}, patientId = {patientId}", + dateForm, dateTo, DoctorId, PatientId); var historyDict = new Dictionary>(); var medicalHistory = connection.Query(querySelect, - (history, drugMedicalHistory) => + (history, drug) => { if (!historyDict.TryGetValue(history.Id, out var drugs)) { drugs = new List(); historyDict.Add(history.Id, drugs); } - if (drugMedicalHistory != null && drugMedicalHistory.Id > 0) + if (drug != null && drug.Id > 0) { - drugs.Add(DrugMedicalHistory.CreateEntity(drugMedicalHistory.Id, drugMedicalHistory.DrugId, drugMedicalHistory.Description)); + drugs.Add(DrugMedicalHistory.CreateEntity(drug.Id, drug.DrugId, drug.Description, drug.MedicalHistoryId)); } return history; }, splitOn: "Id", param: new { dateForm, dateTo, DoctorId, PatientId }); @@ -179,7 +181,7 @@ WHERE Id=@id"; return historyDict.Select(x => { var mh = medicalHistory.First(y => y.Id == x.Key); - mh.SetProductMaterial(x.Value); + mh.SetDrugMedHistory(x.Value); return mh; }).ToArray(); }