Лабораторная работа №4

This commit is contained in:
sofya_zubkova 2024-12-18 22:33:05 +04:00
parent 887fb94e2d
commit b0c084ba0c
19 changed files with 230 additions and 55 deletions

View File

@ -1,11 +1,19 @@
using ProjectPatientAccounting.Entities.Enums; using ProjectPatientAccounting.Entities.Enums;
using System.ComponentModel;
namespace ProjectPatientAccounting.Entities; namespace ProjectPatientAccounting.Entities;
public class Doctor public class Doctor
{ {
public int Id { get; private set; } public int Id { get; private set; }
public string FullName => $"{Name} {Surname}";
[DisplayName("Имя")]
public string Name { get; private set; } = string.Empty; public string Name { get; private set; } = string.Empty;
[DisplayName("Фамилия")]
public string Surname { get; private set; } = string.Empty; public string Surname { get; private set; } = string.Empty;
[DisplayName("Номер участка")]
public Area DoctorArea { get; private set; } public Area DoctorArea { get; private set; }
public static Doctor CreateEntity(int id, string name, string surname, Area doctorArea) public static Doctor CreateEntity(int id, string name, string surname, Area doctorArea)

View File

@ -1,11 +1,18 @@
using ProjectPatientAccounting.Entities.Enums; using ProjectPatientAccounting.Entities.Enums;
using System.ComponentModel;
namespace ProjectPatientAccounting.Entities; namespace ProjectPatientAccounting.Entities;
public class Medicament public class Medicament
{ {
public int Id { get; private set; } public int Id { get; private set; }
[DisplayName("Название")]
public string Name { get; private set; } = string.Empty; public string Name { get; private set; } = string.Empty;
[DisplayName("Описание")]
public string Description { get; private set; } = string.Empty; public string Description { get; private set; } = string.Empty;
[DisplayName("Тип медикамента")]
public TypeMedicament TypeMedicament { get; private set; } public TypeMedicament TypeMedicament { get; private set; }
public static Medicament CreateEntity(int id, string name, string description, TypeMedicament typeMedicament) public static Medicament CreateEntity(int id, string name, string description, TypeMedicament typeMedicament)

View File

@ -4,6 +4,7 @@ public class MedicamentReception
{ {
public int Id { get; private set; } public int Id { get; private set; }
public int MedicamentId { get; private set; } public int MedicamentId { get; private set; }
public string MedicamentName { get; private set; } = string.Empty;
public int Dosage { get; private set; } public int Dosage { get; private set; }
public static MedicamentReception CreateElement(int id, int medicamentId, int dosage) public static MedicamentReception CreateElement(int id, int medicamentId, int dosage)

View File

@ -1,11 +1,21 @@
namespace ProjectPatientAccounting.Entities; using System.ComponentModel;
namespace ProjectPatientAccounting.Entities;
public class Patient public class Patient
{ {
public int Id { get; private set; } public int Id { get; private set; }
public string FullName => $"{Name} {Surname}";
[DisplayName("Имя")]
public string Name { get; private set; } = string.Empty; public string Name { get; private set; } = string.Empty;
[DisplayName("Фамилия")]
public string Surname { get; private set; } = string.Empty; public string Surname { get; private set; } = string.Empty;
[DisplayName("Номер телефона")]
public string Telephone { get; private set; } = string.Empty; public string Telephone { get; private set; } = string.Empty;
[DisplayName("Номер мед.карты")]
public int NumMedCard { get; private set; } public int NumMedCard { get; private set; }
public static Patient CreateEntity(int id, string name, string surname, string telephone, int numMedCard) public static Patient CreateEntity(int id, string name, string surname, string telephone, int numMedCard)

View File

@ -1,11 +1,19 @@
using ProjectPatientAccounting.Entities.Enums; using ProjectPatientAccounting.Entities.Enums;
using System.ComponentModel;
namespace ProjectPatientAccounting.Entities; namespace ProjectPatientAccounting.Entities;
public class PatientDiagnosis public class PatientDiagnosis
{ {
public int Id { get; private set; } public int Id { get; private set; }
public string FullName => $"{Name} {DiagnosisCode}";
[DisplayName("Название")]
public string Name { get; private set; } = string.Empty; public string Name { get; private set; } = string.Empty;
[DisplayName("Код диагноза")]
public int DiagnosisCode { get; private set; } public int DiagnosisCode { get; private set; }
[DisplayName("Статус диагноза")]
public PatientDiagnosisStatus PatientDiagnosisStatus { get; private set; } public PatientDiagnosisStatus PatientDiagnosisStatus { get; private set; }
public static PatientDiagnosis CreateEntity(int id, string name, int diagnosisCode, PatientDiagnosisStatus patientDiagnosisStatus) public static PatientDiagnosis CreateEntity(int id, string name, int diagnosisCode, PatientDiagnosisStatus patientDiagnosisStatus)

View File

@ -1,13 +1,40 @@
namespace ProjectPatientAccounting.Entities; using System.ComponentModel;
namespace ProjectPatientAccounting.Entities;
public class Reception public class Reception
{ {
public int Id { get; private set; } public int Id { get; private set; }
[Browsable(false)]
public int PatientId { get; private set; } public int PatientId { get; private set; }
[Browsable(false)]
public int DoctorId { get; private set; } public int DoctorId { get; private set; }
[Browsable(false)]
public int DiagnosisId { get; private set; } public int DiagnosisId { get; private set; }
[DisplayName("Пациент")]
public string PatientName { get; private set; } = string.Empty;
[DisplayName("Диагноз")]
public string DiagnosisName { get; private set; } = string.Empty;
[DisplayName("Доктор")]
public string DoctorName { get; private set; } = string.Empty;
[DisplayName("Дата приема")]
public DateTime ReceptionDate { get; private set; } public DateTime ReceptionDate { get; private set; }
[DisplayName("Номер талона")]
public int NumTicket { get; private set; } public int NumTicket { get; private set; }
[DisplayName("Медикаменты")]
public string Medicament => MedicamentReceptions != null ?
string.Join(", ", MedicamentReceptions.Select(x => $"{x.MedicamentName} {x.Dosage}")) :
string.Empty;
[Browsable(false)]
public IEnumerable<MedicamentReception> MedicamentReceptions { get; private set; } = []; public IEnumerable<MedicamentReception> MedicamentReceptions { get; private set; } = [];
public static Reception CreateOperation(int id, int patientId, int doctorId, int diagnosisId, int numTicket, IEnumerable<MedicamentReception> medicamentReceptions) public static Reception CreateOperation(int id, int patientId, int doctorId, int diagnosisId, int numTicket, IEnumerable<MedicamentReception> medicamentReceptions)
@ -23,4 +50,11 @@ public class Reception
MedicamentReceptions = medicamentReceptions MedicamentReceptions = medicamentReceptions
}; };
} }
public void SetMedicamentReceptions(IEnumerable<MedicamentReception> medicamentReceptions)
{
if (medicamentReceptions != null && medicamentReceptions.Any())
{
MedicamentReceptions = medicamentReceptions;
}
}
} }

View File

@ -29,7 +29,12 @@ public partial class FormDoctors : Form
} }
} }
private void LoadList() => dataGridViewDoctors.DataSource = _doctorRepository.ReadDoctors(); private void LoadList()
{
dataGridViewDoctors.DataSource = _doctorRepository.ReadDoctors();
dataGridViewDoctors.Columns["Id"].Visible = false;
dataGridViewDoctors.Columns["FullName"].Visible = false;
}
private bool TryGetIdentifierFromSelectedRow(out int id) private bool TryGetIdentifierFromSelectedRow(out int id)
{ {

View File

@ -29,7 +29,11 @@ public partial class FormMedicaments : Form
} }
} }
private void LoadList() => dataGridViewMedicaments.DataSource = _medicamentRepository.ReadMedicaments(); private void LoadList()
{
dataGridViewMedicaments.DataSource = _medicamentRepository.ReadMedicaments();
dataGridViewMedicaments.Columns["Id"].Visible = false;
}
private bool TryGetIdentifierFromSelectedRow(out int id) private bool TryGetIdentifierFromSelectedRow(out int id)
{ {

View File

@ -30,8 +30,12 @@ public partial class FormPatientDiagnosises : Form
} }
} }
private void LoadList() => dataGridViewPatientDiagnosises.DataSource = private void LoadList()
_patientDiagnosisRepository.ReadDiagnosises(); {
dataGridViewPatientDiagnosises.DataSource = _patientDiagnosisRepository.ReadDiagnosises();
dataGridViewPatientDiagnosises.Columns["Id"].Visible = false;
dataGridViewPatientDiagnosises.Columns["FullName"].Visible = false;
}
private bool TryGetIdentifierFromSelectedRow(out int id) private bool TryGetIdentifierFromSelectedRow(out int id)
{ {

View File

@ -142,6 +142,7 @@
Controls.Add(dateTimePickerStartDate); Controls.Add(dateTimePickerStartDate);
Controls.Add(labelDoctor); Controls.Add(labelDoctor);
Name = "FormPatientReport"; Name = "FormPatientReport";
StartPosition = FormStartPosition.CenterParent;
Text = "Отчет по принятым пациентам"; Text = "Отчет по принятым пациентам";
ResumeLayout(false); ResumeLayout(false);
PerformLayout(); PerformLayout();

View File

@ -13,7 +13,7 @@ namespace ProjectPatientAccounting.Forms
_container = container ?? throw new ArgumentNullException(nameof(container)); _container = container ?? throw new ArgumentNullException(nameof(container));
comboBoxDoctor.DataSource = doctorRepository.ReadDoctors(); comboBoxDoctor.DataSource = doctorRepository.ReadDoctors();
comboBoxDoctor.DisplayMember = "Surname"; comboBoxDoctor.DisplayMember = "FullName";
comboBoxDoctor.ValueMember = "Id"; comboBoxDoctor.ValueMember = "Id";
} }

View File

@ -30,7 +30,12 @@ public partial class FormPatients : Form
} }
} }
private void LoadList() => dataGridViewPatients.DataSource = _patientRepository.ReadPatients(); private void LoadList()
{
dataGridViewPatients.DataSource = _patientRepository.ReadPatients();
dataGridViewPatients.Columns["Id"].Visible = false;
dataGridViewPatients.Columns["FullName"].Visible = false;
}
private bool TryGetIdentifierFromSelectedRow(out int id) private bool TryGetIdentifierFromSelectedRow(out int id)
{ {

View File

@ -15,15 +15,15 @@ namespace ProjectPatientAccounting.Forms
throw new ArgumentNullException(nameof(receptionRepository)); throw new ArgumentNullException(nameof(receptionRepository));
comboBoxPatient.DataSource = patientRepository.ReadPatients(); comboBoxPatient.DataSource = patientRepository.ReadPatients();
comboBoxPatient.DisplayMember = "Surname"; comboBoxPatient.DisplayMember = "FullName";
comboBoxPatient.ValueMember = "Id"; comboBoxPatient.ValueMember = "Id";
comboBoxDoctor.DataSource = doctorRepository.ReadDoctors(); comboBoxDoctor.DataSource = doctorRepository.ReadDoctors();
comboBoxDoctor.DisplayMember = "Surname"; comboBoxDoctor.DisplayMember = "FullName";
comboBoxDoctor.ValueMember = "Id"; comboBoxDoctor.ValueMember = "Id";
comboBoxDiagnosis.DataSource = patientDiagnosisRepository.ReadDiagnosises(); comboBoxDiagnosis.DataSource = patientDiagnosisRepository.ReadDiagnosises();
comboBoxDiagnosis.DisplayMember = "Name"; comboBoxDiagnosis.DisplayMember = "FullName";
comboBoxDiagnosis.ValueMember = "Id"; comboBoxDiagnosis.ValueMember = "Id";
ColumnType.DataSource = medicamentRepository.ReadMedicaments(); ColumnType.DataSource = medicamentRepository.ReadMedicaments();

View File

@ -91,6 +91,7 @@
Controls.Add(labelFileName); Controls.Add(labelFileName);
Controls.Add(buttonSelectFileName); Controls.Add(buttonSelectFileName);
Name = "FormReceptionDistributionDiagnosises"; Name = "FormReceptionDistributionDiagnosises";
StartPosition = FormStartPosition.CenterParent;
Text = "Распределение диагнозов"; Text = "Распределение диагнозов";
ResumeLayout(false); ResumeLayout(false);
PerformLayout(); PerformLayout();

View File

@ -28,9 +28,12 @@ public partial class FormReceptions : Form
MessageBoxButtons.OK, MessageBoxIcon.Error); MessageBoxButtons.OK, MessageBoxIcon.Error);
} }
} }
private void LoadList()
private void LoadList() => dataGridViewReceptions.DataSource = {
_receptionRepository.ReadReceptions(); dataGridViewReceptions.DataSource = _receptionRepository.ReadReceptions();
dataGridViewReceptions.Columns["Id"].Visible = false;
dataGridViewReceptions.Columns["ReceptionDate"].DefaultCellStyle.Format = "dd.MM.yyyy";
}
private bool TryGetIdentifierFromSelectedRow(out int id) private bool TryGetIdentifierFromSelectedRow(out int id)
{ {

View File

@ -22,7 +22,7 @@ namespace ProjectPatientAccounting.Reports
{ {
new PdfBuilder(filePath) new PdfBuilder(filePath)
.AddHeader("Статистика пациентов") .AddHeader("Статистика пациентов")
.AddPieChart("Поставленные диагнозы", GetData(dateTime)) .AddPieChart($"Поставленные диагнозы на {dateTime: dd MMMM yyyy}", GetData(dateTime))
.Build(); .Build();
return true; return true;
} }
@ -35,22 +35,13 @@ namespace ProjectPatientAccounting.Reports
private List<(string Caption, double Value)> GetData(DateTime dateTime) private List<(string Caption, double Value)> GetData(DateTime dateTime)
{ {
var receptions = _receptionRepository.ReadReceptions() return _receptionRepository.ReadReceptions(dateFrom: dateTime.Date, dateTo:dateTime.Date.AddDays(1))
.Where(x => x.ReceptionDate.Date == dateTime.Date) .GroupBy(x => x.DiagnosisName, (key, group) => new {
.ToList(); DiagnosisName = key, Count = group.Sum(x => x.DiagnosisId) })
.Select(x => (x.DiagnosisName, (double)x.Count))
var totalReceptions = receptions.Count;
return receptions
.GroupBy(x => x.DiagnosisId)
.Select(g => new
{
DiagnosisId = g.Key,
Count = g.Count()
})
.Select(x => (x.DiagnosisId.ToString(), (double)x.Count / totalReceptions * 100))
.ToList(); .ToList();
} }
} }
} }

View File

@ -1,7 +1,7 @@
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using ProjectPatientAccounting.Entities.Enums; using ProjectPatientAccounting.Entities.Enums;
using ProjectPatientAccounting.Repositories; using ProjectPatientAccounting.Repositories;
using System.Diagnostics;
namespace ProjectPatientAccounting.Reports; namespace ProjectPatientAccounting.Reports;
internal class TableReport internal class TableReport
@ -29,7 +29,7 @@ internal class TableReport
{ {
new ExcelBuilder(filePath) new ExcelBuilder(filePath)
.AddHeader("Сводка по движению пациентов", 0, 4) .AddHeader("Сводка по движению пациентов", 0, 4)
.AddParagraph("за период", 0) .AddParagraph($"за период c {startDate: dd.MM.yyyy} по {endDate:dd.MM.yyyy}", 0)
.AddTable([15, 20, 25, 25], GetData(doctorId, startDate, endDate)) .AddTable([15, 20, 25, 25], GetData(doctorId, startDate, endDate))
.Build(); .Build();
return true; return true;
@ -43,11 +43,11 @@ internal class TableReport
private List<string[]> GetData(int doctorId, DateTime startDate, DateTime endDate) private List<string[]> GetData(int doctorId, DateTime startDate, DateTime endDate)
{ {
var receptions = _receptionRepository.ReadReceptions(dateFrom:startDate, dateTo:endDate, doctorId).ToList(); var receptions = _receptionRepository.ReadReceptions(dateFrom:startDate, dateTo:endDate, doctorId: doctorId).ToList();
var patients = _patientRepository.ReadPatients(); var patients = _patientRepository.ReadPatients();
var doctorNames = _doctorRepository.ReadDoctors().ToDictionary(d => d.Id, d => d.Surname); var doctorNames = _doctorRepository.ReadDoctors().ToDictionary(d => d.Id, d => d.FullName);
var diagnosisStatuses = _patientDiagnosisRepository.ReadDiagnosises().ToDictionary(d => d.Id, d => d.PatientDiagnosisStatus); var diagnosisStatuses = _patientDiagnosisRepository.ReadDiagnosises().ToDictionary(d => d.Id, d => d.PatientDiagnosisStatus);
Debug.WriteLine(receptions.Count);
var data = receptions var data = receptions
.Join(patients, r => r.PatientId, p => p.Id, (r, p) => new .Join(patients, r => r.PatientId, p => p.Id, (r, p) => new
{ {
@ -55,12 +55,12 @@ internal class TableReport
DoctorId = r.DoctorId, DoctorId = r.DoctorId,
DiagnosisId = r.DiagnosisId DiagnosisId = r.DiagnosisId
}) })
.Where(x => x.DoctorId == doctorId)
.OrderBy(x => x.Date) .OrderBy(x => x.Date)
.GroupBy(x => x.Date) .GroupBy(x => new { x.Date, x.DoctorId })
.Select(g => new .Select(g => new
{ {
Date = g.Key, Date = g.Key.Date,
DoctorId = g.Key.DoctorId,
TotalPatients = g.Count(), TotalPatients = g.Count(),
RecoveredPatients = g.Count(x => diagnosisStatuses[x.DiagnosisId] == PatientDiagnosisStatus.Closed) RecoveredPatients = g.Count(x => diagnosisStatuses[x.DiagnosisId] == PatientDiagnosisStatus.Closed)
}); });
@ -68,6 +68,7 @@ internal class TableReport
var result = new List<string[]> { item }; var result = new List<string[]> { item };
foreach (var entry in data) foreach (var entry in data)
{ {
result.Add(new string[] result.Add(new string[]
{ {
entry.Date.ToString("dd.MM.yyyy"), entry.Date.ToString("dd.MM.yyyy"),
@ -86,6 +87,7 @@ internal class TableReport
totalPatients.ToString("N0"), totalPatients.ToString("N0"),
recoveredPatients.ToString("N0") recoveredPatients.ToString("N0")
}); });
return result; return result;
} }
} }

View File

@ -0,0 +1,31 @@
using System.Text;
namespace ProjectPatientAccounting.Repositories.Implementations;
internal class QueryBuilder
{
private readonly StringBuilder _builder;
public QueryBuilder()
{
_builder = new();
}
public QueryBuilder AddCondition(string condition)
{
if (_builder.Length > 0)
{
_builder.Append(" AND ");
}
_builder.Append(condition);
return this;
}
public string Build()
{
if (_builder.Length == 0)
{
return string.Empty;
}
return $"WHERE {_builder}";
}
}

View File

@ -85,13 +85,73 @@ public class ReceptionRepository : IReceptionRepository
try try
{ {
using var connection = new NpgsqlConnection(_connectionString.ConnectionString); using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var querySelect = @"SELECT * FROM Receptions"; var builder = new QueryBuilder();
var receptions = if (dateFrom.HasValue)
connection.Query<Reception>(querySelect); {
_logger.LogDebug("Полученные объекты: {json}", builder.AddCondition("r.ReceptionDate >= @dateFrom");
JsonConvert.SerializeObject(receptions));
return receptions;
} }
if (dateTo.HasValue)
{
builder.AddCondition("r.ReceptionDate <= @dateTo");
}
if (patientId.HasValue)
{
builder.AddCondition("r.PatientId = @patientId");
}
if (diagnosisId.HasValue)
{
builder.AddCondition("r.DiagnosisId = @diagnosisId");
}
if (doctorId.HasValue)
{
builder.AddCondition("r.DoctorId = @doctorId");
}
var querySelect = $@"
SELECT
r.*,
CONCAT(p.Name, ' ', p.Surname) AS PatientName,
CONCAT(pd.Name, ' ', pd.DiagnosisCode) AS DiagnosisName,
CONCAT(d.Name, ' ', d.Surname) AS DoctorName,
mr.MedicamentId,
m.Name AS MedicamentName,
mr.Dosage
FROM Receptions r
LEFT JOIN Patients p ON p.Id = r.PatientId
LEFT JOIN PatientDiagnosises pd ON pd.Id = r.DiagnosisId
LEFT JOIN Doctors d ON d.Id = r.DoctorId
INNER JOIN MedicamentReceptions mr ON mr.ReceptionId = r.Id
LEFT JOIN Medicaments m ON m.Id = mr.MedicamentId
{builder.Build()}";
var receptionDict = new Dictionary<int, List<MedicamentReception>>();
var receptions = connection.Query<Reception, MedicamentReception, Reception>(querySelect,
(reception, medicamentReceptions) =>
{
if (!receptionDict.TryGetValue(reception.Id, out var mr))
{
mr = [];
receptionDict.Add(reception.Id, mr);
}
mr.Add(medicamentReceptions);
return reception;
},
splitOn: "MedicamentId", param: new { dateFrom, dateTo, patientId, diagnosisId, doctorId });
_logger.LogDebug("Полученные объекты: {json}", JsonConvert.SerializeObject(receptions));
return receptionDict.Select(x =>
{
var r = receptions.First(y => y.Id == x.Key);
r.SetMedicamentReceptions(x.Value);
return r;
}).ToArray();
}
catch (Exception ex) catch (Exception ex)
{ {
_logger.LogError(ex, "Ошибка при чтении объектов"); _logger.LogError(ex, "Ошибка при чтении объектов");