From c60a1d2120c83375d980ac4d0bf43e9512c3cc21 Mon Sep 17 00:00:00 2001 From: TikhonElli Date: Mon, 16 Dec 2024 21:20:09 +0400 Subject: [PATCH] =?UTF-8?q?=D0=9B=D0=B0=D0=B1=D0=BE=D1=80=D0=B0=D1=82?= =?UTF-8?q?=D0=BE=D1=80=D0=BD=D0=B0=D1=8F=20=D1=80=D0=B0=D0=B1=D0=BE=D1=82?= =?UTF-8?q?=D0=B0=20=E2=84=964?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Entities/Athlete.cs | 7 +++ .../Entities/AthleteAccommodation.cs | 15 ++++- .../Entities/Hotel.cs | 5 +- .../Entities/Room.cs | 7 +++ .../Entities/ServiceProvision.cs | 32 ++++++---- .../Entities/ServiceProvisionConnection.cs | 2 + .../TempServiceProvisionConnection.cs | 16 ----- .../Forms/FormAthleteAccommodation.cs | 4 +- .../Forms/FormAthleteReport.cs | 2 +- .../Forms/FormAthletes.cs | 7 ++- .../Forms/FormAthletesAccommodation.cs | 13 ++-- .../Forms/FormHotels.cs | 8 ++- .../Forms/FormRooms.cs | 6 +- .../Forms/FormServiceProvision.cs | 2 +- .../Forms/FormServicesProvision.cs | 8 ++- .../Reports/ChartReport.cs | 15 +++-- .../Reports/DocReport.cs | 22 +++---- .../Reports/PdfBuilder.cs | 1 - .../Reports/TableReport.cs | 20 +++--- .../AthleteAccommodationRepository.cs | 36 +++++++++-- .../Implementations/HotelRepository.cs | 1 + .../Implementations/QueryBuilder.cs | 34 ++++++++++ .../Implementations/RoomRepository.cs | 9 ++- .../ServiceProvisionRepository.cs | 62 ++++++++++++++++--- 24 files changed, 246 insertions(+), 88 deletions(-) delete mode 100644 ProjectAthletesAccommodation/ProjectAthletesAccommodation/Entities/TempServiceProvisionConnection.cs create mode 100644 ProjectAthletesAccommodation/ProjectAthletesAccommodation/Repositories/Implementations/QueryBuilder.cs diff --git a/ProjectAthletesAccommodation/ProjectAthletesAccommodation/Entities/Athlete.cs b/ProjectAthletesAccommodation/ProjectAthletesAccommodation/Entities/Athlete.cs index d6cfff8..b7720b8 100644 --- a/ProjectAthletesAccommodation/ProjectAthletesAccommodation/Entities/Athlete.cs +++ b/ProjectAthletesAccommodation/ProjectAthletesAccommodation/Entities/Athlete.cs @@ -1,4 +1,5 @@ using ProjectAthletesAccommodation.Entities.Enums; +using System.ComponentModel; namespace ProjectAthletesAccommodation.Entities; @@ -6,12 +7,18 @@ public class Athlete { public int Id { get; private set; } + [DisplayName("Имя")] public string Name { get; private set; } = string.Empty; + [DisplayName("Фамилия")] public string Surname { get; private set; } = string.Empty; + public string FullName => $"{Name} {Surname}"; + + [DisplayName("Вид спорта")] public KindOfSport KindOfSport { get; private set; } + [DisplayName("Классификация")] public AthleteClassification AthleteClassification { get; private set; } public static Athlete CreateEntity(int id, string name, string surname, diff --git a/ProjectAthletesAccommodation/ProjectAthletesAccommodation/Entities/AthleteAccommodation.cs b/ProjectAthletesAccommodation/ProjectAthletesAccommodation/Entities/AthleteAccommodation.cs index 342d2a9..434c607 100644 --- a/ProjectAthletesAccommodation/ProjectAthletesAccommodation/Entities/AthleteAccommodation.cs +++ b/ProjectAthletesAccommodation/ProjectAthletesAccommodation/Entities/AthleteAccommodation.cs @@ -1,17 +1,30 @@ -namespace ProjectAthletesAccommodation.Entities; +using System.ComponentModel; + +namespace ProjectAthletesAccommodation.Entities; public class AthleteAccommodation { public int Id { get; private set; } + [Browsable(false)] public int RoomId { get; private set; } + [Browsable(false)] public int AthleteId { get; private set; } + [DisplayName("Номер")] + public string RoomName { get; private set; } = string.Empty; + + [DisplayName("Спортсмен")] + public string AthleteName { get; private set; } = string.Empty; + + [DisplayName("Стоимость проживания")] public decimal Price { get; private set; } + [DisplayName("Дата заезда")] public DateTime DateStart { get; private set; } + [DisplayName("Дата выезда")] public DateTime DateEnd { get; private set; } public static AthleteAccommodation CreateOpeartion(int id, int roomId, int athleteId, decimal price) diff --git a/ProjectAthletesAccommodation/ProjectAthletesAccommodation/Entities/Hotel.cs b/ProjectAthletesAccommodation/ProjectAthletesAccommodation/Entities/Hotel.cs index 4e6763e..8764b87 100644 --- a/ProjectAthletesAccommodation/ProjectAthletesAccommodation/Entities/Hotel.cs +++ b/ProjectAthletesAccommodation/ProjectAthletesAccommodation/Entities/Hotel.cs @@ -1,9 +1,12 @@ -namespace ProjectAthletesAccommodation.Entities; +using System.ComponentModel; + +namespace ProjectAthletesAccommodation.Entities; public class Hotel { public int Id { get; private set; } + [DisplayName("Название")] public string Name { get; private set; } = string.Empty; public static Hotel CreateEntity(int id, string name) diff --git a/ProjectAthletesAccommodation/ProjectAthletesAccommodation/Entities/Room.cs b/ProjectAthletesAccommodation/ProjectAthletesAccommodation/Entities/Room.cs index a917408..6a6ed02 100644 --- a/ProjectAthletesAccommodation/ProjectAthletesAccommodation/Entities/Room.cs +++ b/ProjectAthletesAccommodation/ProjectAthletesAccommodation/Entities/Room.cs @@ -1,4 +1,5 @@ using ProjectAthletesAccommodation.Entities.Enums; +using System.ComponentModel; namespace ProjectAthletesAccommodation.Entities; @@ -6,10 +7,16 @@ public class Room { public int Id { get; private set; } + [Browsable(false)] public int HotelId { get; private set; } + [DisplayName("Гостиница")] + public string HotelName { get; private set; } = string.Empty; + + [DisplayName("Номер")] public string Name { get; private set; } = string.Empty; + [DisplayName("Тип номера")] public TypeOfRoom TypeOfRoom { get; private set; } public static Room CreateEntity(int id, int hotelId, string name, diff --git a/ProjectAthletesAccommodation/ProjectAthletesAccommodation/Entities/ServiceProvision.cs b/ProjectAthletesAccommodation/ProjectAthletesAccommodation/Entities/ServiceProvision.cs index b6507c8..5c2df8c 100644 --- a/ProjectAthletesAccommodation/ProjectAthletesAccommodation/Entities/ServiceProvision.cs +++ b/ProjectAthletesAccommodation/ProjectAthletesAccommodation/Entities/ServiceProvision.cs @@ -1,18 +1,32 @@ -namespace ProjectAthletesAccommodation.Entities; +using System.ComponentModel; + +namespace ProjectAthletesAccommodation.Entities; public class ServiceProvision { public int Id { get; private set; } + [Browsable(false)] public int HotelId { get; private set; } + [DisplayName("Гостиница")] + public string HotelName { get; private set; } = string.Empty; + + [DisplayName("Услуга")] public string Name { get; private set; } = string.Empty; + [DisplayName("Дата и время предоставления")] public DateTime Date { get; private set; } + [DisplayName("Спортсмены и стоимости услуг")] + public string Athlete => ServiceProvisionConnection != null ? + string.Join(", ", ServiceProvisionConnection.Select(x => $"{x.AthleteName} {x.Price}")) : + string.Empty; + + [Browsable(false)] public IEnumerable ServiceProvisionConnection { get; private set; } = []; - public static ServiceProvision CreateOpeartion(int id, int hotelId, string name, + public static ServiceProvision CreateOpeartion(int id, int hotelId, string name, IEnumerable serviceProvisionConnection) { return new ServiceProvision @@ -25,16 +39,12 @@ public class ServiceProvision }; } - public static ServiceProvision CreateOpeartion(TempServiceProvisionConnection tempServiceProvisionConnection, - IEnumerable serviceProvisionConnection) + public void SetServiceProvisionConnection(IEnumerable + serviceProvisionConnection) { - return new ServiceProvision + if (serviceProvisionConnection != null && serviceProvisionConnection.Any()) { - Id = tempServiceProvisionConnection.Id, - HotelId = tempServiceProvisionConnection.HotelId, - Name = tempServiceProvisionConnection.Name, - Date = tempServiceProvisionConnection.Date, - ServiceProvisionConnection = serviceProvisionConnection - }; + ServiceProvisionConnection = serviceProvisionConnection; + } } } \ No newline at end of file diff --git a/ProjectAthletesAccommodation/ProjectAthletesAccommodation/Entities/ServiceProvisionConnection.cs b/ProjectAthletesAccommodation/ProjectAthletesAccommodation/Entities/ServiceProvisionConnection.cs index 473e766..3890473 100644 --- a/ProjectAthletesAccommodation/ProjectAthletesAccommodation/Entities/ServiceProvisionConnection.cs +++ b/ProjectAthletesAccommodation/ProjectAthletesAccommodation/Entities/ServiceProvisionConnection.cs @@ -6,6 +6,8 @@ public class ServiceProvisionConnection public int AthleteId { get; private set; } + public string AthleteName { get; private set; } = string.Empty; + public decimal Price { get; private set; } public static ServiceProvisionConnection CreateElement(int id, int athleteId, decimal price) diff --git a/ProjectAthletesAccommodation/ProjectAthletesAccommodation/Entities/TempServiceProvisionConnection.cs b/ProjectAthletesAccommodation/ProjectAthletesAccommodation/Entities/TempServiceProvisionConnection.cs deleted file mode 100644 index 2482105..0000000 --- a/ProjectAthletesAccommodation/ProjectAthletesAccommodation/Entities/TempServiceProvisionConnection.cs +++ /dev/null @@ -1,16 +0,0 @@ -namespace ProjectAthletesAccommodation.Entities; - -public class TempServiceProvisionConnection -{ - public int Id { get; private set; } - - public int HotelId { get; private set; } - - public string Name { get; private set; } = string.Empty; - - public DateTime Date { get; private set; } - - public int AthleteId { get; private set; } - - public decimal Price { get; private set; } -} \ No newline at end of file diff --git a/ProjectAthletesAccommodation/ProjectAthletesAccommodation/Forms/FormAthleteAccommodation.cs b/ProjectAthletesAccommodation/ProjectAthletesAccommodation/Forms/FormAthleteAccommodation.cs index 2da20f6..585bf40 100644 --- a/ProjectAthletesAccommodation/ProjectAthletesAccommodation/Forms/FormAthleteAccommodation.cs +++ b/ProjectAthletesAccommodation/ProjectAthletesAccommodation/Forms/FormAthleteAccommodation.cs @@ -19,7 +19,7 @@ namespace ProjectAthletesAccommodation.Forms comboBoxRoom.ValueMember = "Id"; comboBoxAthlete.DataSource = athleteRepository.ReadAthletes(); - comboBoxAthlete.DisplayMember = "Name"; + comboBoxAthlete.DisplayMember = "FullName"; comboBoxAthlete.ValueMember = "Id"; } @@ -33,7 +33,7 @@ namespace ProjectAthletesAccommodation.Forms } _athleteAccommodationRepository.CreateAthleteAccommodation - (AthleteAccommodation.CreateOpeartion(0, (int)comboBoxRoom.SelectedValue!, + (AthleteAccommodation.CreateOpeartion(0, (int)comboBoxRoom.SelectedValue!, (int)comboBoxAthlete.SelectedValue!, Convert.ToDecimal(numericUpDownPrice.Value))); Close(); diff --git a/ProjectAthletesAccommodation/ProjectAthletesAccommodation/Forms/FormAthleteReport.cs b/ProjectAthletesAccommodation/ProjectAthletesAccommodation/Forms/FormAthleteReport.cs index e19230f..690a7c4 100644 --- a/ProjectAthletesAccommodation/ProjectAthletesAccommodation/Forms/FormAthleteReport.cs +++ b/ProjectAthletesAccommodation/ProjectAthletesAccommodation/Forms/FormAthleteReport.cs @@ -15,7 +15,7 @@ public partial class FormAthleteReport : Form throw new ArgumentNullException(nameof(container)); comboBoxAthlete.DataSource = athleteRepository.ReadAthletes(); - comboBoxAthlete.DisplayMember = "Name"; + comboBoxAthlete.DisplayMember = "FullName"; comboBoxAthlete.ValueMember = "Id"; } diff --git a/ProjectAthletesAccommodation/ProjectAthletesAccommodation/Forms/FormAthletes.cs b/ProjectAthletesAccommodation/ProjectAthletesAccommodation/Forms/FormAthletes.cs index f043def..227d968 100644 --- a/ProjectAthletesAccommodation/ProjectAthletesAccommodation/Forms/FormAthletes.cs +++ b/ProjectAthletesAccommodation/ProjectAthletesAccommodation/Forms/FormAthletes.cs @@ -89,7 +89,12 @@ namespace ProjectAthletesAccommodation.Forms } } - private void LoadList() => dataGridView.DataSource = _athleteRepository.ReadAthletes(); + private void LoadList() + { + dataGridView.DataSource = _athleteRepository.ReadAthletes(); + dataGridView.Columns["Id"].Visible = false; + dataGridView.Columns["FullName"].Visible = false; + } private bool TryGetIdentifierFromSelectedRow(out int id) { diff --git a/ProjectAthletesAccommodation/ProjectAthletesAccommodation/Forms/FormAthletesAccommodation.cs b/ProjectAthletesAccommodation/ProjectAthletesAccommodation/Forms/FormAthletesAccommodation.cs index 9302d64..648ac1e 100644 --- a/ProjectAthletesAccommodation/ProjectAthletesAccommodation/Forms/FormAthletesAccommodation.cs +++ b/ProjectAthletesAccommodation/ProjectAthletesAccommodation/Forms/FormAthletesAccommodation.cs @@ -9,12 +9,12 @@ namespace ProjectAthletesAccommodation.Forms private readonly IAthleteAccommodationRepository _athleteAccommodationRepository; - public FormAthletesAccommodation(IUnityContainer container, + public FormAthletesAccommodation(IUnityContainer container, IAthleteAccommodationRepository athleteAccommodationRepository) { InitializeComponent(); _container = container ?? throw new ArgumentNullException(nameof(container)); - _athleteAccommodationRepository = athleteAccommodationRepository + _athleteAccommodationRepository = athleteAccommodationRepository ?? throw new ArgumentNullException(nameof(athleteAccommodationRepository)); } @@ -70,8 +70,13 @@ namespace ProjectAthletesAccommodation.Forms } } - private void LoadList() => dataGridView.DataSource = - _athleteAccommodationRepository.ReadAthleteAccommodation(); + private void LoadList() + { + dataGridView.DataSource = _athleteAccommodationRepository.ReadAthleteAccommodation(); + dataGridView.Columns["Id"].Visible = false; + dataGridView.Columns["DateStart"].DefaultCellStyle.Format = "dd.MM.yyyy"; + dataGridView.Columns["DateEnd"].DefaultCellStyle.Format = "dd.MM.yyyy"; + } private bool TryGetIdentifierFromSelectedRow(out int id) { diff --git a/ProjectAthletesAccommodation/ProjectAthletesAccommodation/Forms/FormHotels.cs b/ProjectAthletesAccommodation/ProjectAthletesAccommodation/Forms/FormHotels.cs index a8a3b4a..18c6728 100644 --- a/ProjectAthletesAccommodation/ProjectAthletesAccommodation/Forms/FormHotels.cs +++ b/ProjectAthletesAccommodation/ProjectAthletesAccommodation/Forms/FormHotels.cs @@ -50,7 +50,7 @@ namespace ProjectAthletesAccommodation.Forms return; } - if (MessageBox.Show("Удалить запись?", "Удаление", + if (MessageBox.Show("Удалить запись?", "Удаление", MessageBoxButtons.YesNo) != DialogResult.Yes) { return; @@ -89,7 +89,11 @@ namespace ProjectAthletesAccommodation.Forms } } - private void LoadList() => dataGridView.DataSource = _hotelRepository.ReadHotels(); + private void LoadList() + { + dataGridView.DataSource = _hotelRepository.ReadHotels(); + dataGridView.Columns["Id"].Visible = false; + } private bool TryGetIdentifierFromSelectedRow(out int id) { diff --git a/ProjectAthletesAccommodation/ProjectAthletesAccommodation/Forms/FormRooms.cs b/ProjectAthletesAccommodation/ProjectAthletesAccommodation/Forms/FormRooms.cs index 28fbf00..99dfbf5 100644 --- a/ProjectAthletesAccommodation/ProjectAthletesAccommodation/Forms/FormRooms.cs +++ b/ProjectAthletesAccommodation/ProjectAthletesAccommodation/Forms/FormRooms.cs @@ -89,7 +89,11 @@ namespace ProjectAthletesAccommodation.Forms } } - private void LoadList() => dataGridView.DataSource = _roomRepository.ReadRooms(); + private void LoadList() + { + dataGridView.DataSource = _roomRepository.ReadRooms(); + dataGridView.Columns["Id"].Visible = false; + } private bool TryGetIdentifierFromSelectedRow(out int id) { diff --git a/ProjectAthletesAccommodation/ProjectAthletesAccommodation/Forms/FormServiceProvision.cs b/ProjectAthletesAccommodation/ProjectAthletesAccommodation/Forms/FormServiceProvision.cs index 4cd3405..506bbf6 100644 --- a/ProjectAthletesAccommodation/ProjectAthletesAccommodation/Forms/FormServiceProvision.cs +++ b/ProjectAthletesAccommodation/ProjectAthletesAccommodation/Forms/FormServiceProvision.cs @@ -19,7 +19,7 @@ namespace ProjectAthletesAccommodation.Forms comboBoxHotel.ValueMember = "Id"; ColumnAthlete.DataSource = athleteRepository.ReadAthletes(); - ColumnAthlete.DisplayMember = "Name"; + ColumnAthlete.DisplayMember = "FullName"; ColumnAthlete.ValueMember = "Id"; } diff --git a/ProjectAthletesAccommodation/ProjectAthletesAccommodation/Forms/FormServicesProvision.cs b/ProjectAthletesAccommodation/ProjectAthletesAccommodation/Forms/FormServicesProvision.cs index deab4af..4809ee5 100644 --- a/ProjectAthletesAccommodation/ProjectAthletesAccommodation/Forms/FormServicesProvision.cs +++ b/ProjectAthletesAccommodation/ProjectAthletesAccommodation/Forms/FormServicesProvision.cs @@ -70,8 +70,12 @@ namespace ProjectAthletesAccommodation.Forms } } - private void LoadList() => dataGridView.DataSource = - _serviceProvisionRepository.ReadServiceProvision(); + private void LoadList() + { + dataGridView.DataSource = _serviceProvisionRepository.ReadServiceProvision(); + dataGridView.Columns["Id"].Visible = false; + dataGridView.Columns["Date"].DefaultCellStyle.Format = "dd MMMM yyyy hh:mm"; + } private bool TryGetIdentifierFromSelectedRow(out int id) { diff --git a/ProjectAthletesAccommodation/ProjectAthletesAccommodation/Reports/ChartReport.cs b/ProjectAthletesAccommodation/ProjectAthletesAccommodation/Reports/ChartReport.cs index 0e55061..e21ca5a 100644 --- a/ProjectAthletesAccommodation/ProjectAthletesAccommodation/Reports/ChartReport.cs +++ b/ProjectAthletesAccommodation/ProjectAthletesAccommodation/Reports/ChartReport.cs @@ -11,9 +11,9 @@ public class ChartReport public ChartReport(IAthleteAccommodationRepository athleteAccommodationRepository, ILogger logger) { - _athleteAccommodationRepository = athleteAccommodationRepository ?? + _athleteAccommodationRepository = athleteAccommodationRepository ?? throw new ArgumentNullException(nameof(athleteAccommodationRepository)); - _logger = logger ?? + _logger = logger ?? throw new ArgumentNullException(nameof(logger)); } @@ -23,7 +23,7 @@ public class ChartReport { new PdfBuilder(filePath) .AddHeader("Размещение спортсменов") - .AddPieChart("Заселенные спортсмены (Соотношение стоимостей их проживания)", GetData(dateTime)) + .AddPieChart($"Заселенные спортсмены на {dateTime:dd MMMM yyyy} (Соотношение стоимостей их проживания)", GetData(dateTime)) .Build(); return true; } @@ -37,14 +37,13 @@ public class ChartReport private List<(string Caption, double Value)> GetData(DateTime dateTime) { return _athleteAccommodationRepository - .ReadAthleteAccommodation() - .Where(x => x.DateStart.Date == dateTime.Date) - .GroupBy(x => x.AthleteId, (key, group) => new + .ReadAthleteAccommodation(dateFrom: dateTime.Date, dateTo: dateTime.Date.AddDays(1)) + .GroupBy(x => x.AthleteName, (key, group) => new { - Id = key, + AthleteName = key, Count = group.Sum(x => x.Price) }) - .Select(x => (x.Id.ToString(), (double)x.Count)) + .Select(x => (x.AthleteName.ToString(), (double)x.Count)) .ToList(); } } \ No newline at end of file diff --git a/ProjectAthletesAccommodation/ProjectAthletesAccommodation/Reports/DocReport.cs b/ProjectAthletesAccommodation/ProjectAthletesAccommodation/Reports/DocReport.cs index cab8ef0..0ff98a7 100644 --- a/ProjectAthletesAccommodation/ProjectAthletesAccommodation/Reports/DocReport.cs +++ b/ProjectAthletesAccommodation/ProjectAthletesAccommodation/Reports/DocReport.cs @@ -13,16 +13,16 @@ public class DocReport private readonly ILogger _logger; - public DocReport(IAthleteRepository athleteRepository, IRoomRepository roomRepository, + public DocReport(IAthleteRepository athleteRepository, IRoomRepository roomRepository, IHotelRepository hotelRepository, ILogger logger) { - _athleteRepository = athleteRepository ?? + _athleteRepository = athleteRepository ?? throw new ArgumentNullException(nameof(athleteRepository)); - _roomRepository = roomRepository ?? + _roomRepository = roomRepository ?? throw new ArgumentNullException(nameof(roomRepository)); - _hotelRepository = hotelRepository ?? + _hotelRepository = hotelRepository ?? throw new ArgumentNullException(nameof(hotelRepository)); - _logger = logger ?? + _logger = logger ?? throw new ArgumentNullException(nameof(logger)); } @@ -32,17 +32,17 @@ public class DocReport { var builder = new WordBuilder(filePath).AddHeader("Документ со справочниками"); - if(includeAthletes) + if (includeAthletes) { builder.AddParagraph("Спортсмены").AddTable([2400, 2400, 2000, 2000], GetAthletes()); } - if(includeRooms) + if (includeRooms) { builder.AddParagraph("Номера").AddTable([2400, 2400, 2400], GetRooms()); } - if(includeHotels) + if (includeHotels) { builder.AddParagraph("Гостиницы").AddTable([2400], GetHotels()); } @@ -63,7 +63,7 @@ public class DocReport ["Имя", "Фамилия", "Вид спорта", "Классификация"], .. _athleteRepository .ReadAthletes() - .Select(x => new string[] + .Select(x => new string[] {x.Name, x.Surname, x.KindOfSport.ToString(), x.AthleteClassification.ToString()}), ]; } @@ -82,11 +82,11 @@ public class DocReport private List GetRooms() { return [ - ["Гостиница (Id)", "Номер", "Тип номера"], + ["Гостиница", "Номер", "Тип номера"], .. _roomRepository .ReadRooms() .Select(x => new string[] - {x.HotelId.ToString(), x.Name, x.TypeOfRoom.ToString()}), + {x.HotelName.ToString(), x.Name, x.TypeOfRoom.ToString()}), ]; } } \ No newline at end of file diff --git a/ProjectAthletesAccommodation/ProjectAthletesAccommodation/Reports/PdfBuilder.cs b/ProjectAthletesAccommodation/ProjectAthletesAccommodation/Reports/PdfBuilder.cs index 4bad137..80f575e 100644 --- a/ProjectAthletesAccommodation/ProjectAthletesAccommodation/Reports/PdfBuilder.cs +++ b/ProjectAthletesAccommodation/ProjectAthletesAccommodation/Reports/PdfBuilder.cs @@ -1,7 +1,6 @@ using MigraDoc.DocumentObjectModel; using MigraDoc.DocumentObjectModel.Shapes.Charts; using MigraDoc.Rendering; -using System.Text; namespace ProjectAthletesAccommodation.Reports; diff --git a/ProjectAthletesAccommodation/ProjectAthletesAccommodation/Reports/TableReport.cs b/ProjectAthletesAccommodation/ProjectAthletesAccommodation/Reports/TableReport.cs index b9ee693..65f440e 100644 --- a/ProjectAthletesAccommodation/ProjectAthletesAccommodation/Reports/TableReport.cs +++ b/ProjectAthletesAccommodation/ProjectAthletesAccommodation/Reports/TableReport.cs @@ -16,11 +16,11 @@ public class TableReport public TableReport(IAthleteAccommodationRepository athleteAccommodationRepository, IServiceProvisionRepository serviceProvisionRepository, ILogger logger) { - _athleteAccommodationRepository = athleteAccommodationRepository ?? + _athleteAccommodationRepository = athleteAccommodationRepository ?? throw new ArgumentNullException(nameof(athleteAccommodationRepository)); - _serviceProvisionRepository = serviceProvisionRepository ?? + _serviceProvisionRepository = serviceProvisionRepository ?? throw new ArgumentNullException(nameof(serviceProvisionRepository)); - _logger = logger ?? + _logger = logger ?? throw new ArgumentNullException(nameof(logger)); } @@ -30,7 +30,7 @@ public class TableReport { new ExcelBuilder(filePath) .AddHeader("Сводка по спортсмену", 0, 3) - .AddParagraph("За период", 0) + .AddParagraph($"За период с {startDate:dd.MM.yyyy} по {endDate:dd.MM.yyyy}", 0) .AddTable([15, 15, 15], GetData(athleteId, startDate, endDate)) .Build(); return true; @@ -45,23 +45,21 @@ public class TableReport private List GetData(int athleteId, DateTime startDate, DateTime endDate) { var data = _serviceProvisionRepository - .ReadServiceProvision() - .Where(x => x.Date >= startDate && x.Date <= endDate && x.ServiceProvisionConnection.Any(y => y.AthleteId == athleteId)) + .ReadServiceProvision(dateFrom: startDate, dateTo: endDate, athleteId: athleteId) .Select(x => new { Date = x.Date, PriceService = x.ServiceProvisionConnection.FirstOrDefault(y => y.AthleteId == athleteId)?.Price, PriceRoom = (decimal?)null }) .Union( _athleteAccommodationRepository - .ReadAthleteAccommodation() - .Where(x => x.DateStart >= startDate && x.DateStart <= endDate && x.AthleteId == athleteId) - .Select(x => new {Date = x.DateStart, PriceService = (decimal?)null, PriceRoom = (decimal?)x.Price })) + .ReadAthleteAccommodation(dateFrom: startDate, dateTo: endDate, athleteId: athleteId) + .Select(x => new { Date = x.DateStart, PriceService = (decimal?)null, PriceRoom = (decimal?)x.Price })) .OrderBy(x => x.Date); return new List() { item } .Union( data - .Select(x => new string[] {x.Date.ToString(), x.PriceService?.ToString() ?? string.Empty, x.PriceRoom?.ToString() ?? string.Empty })) + .Select(x => new string[] { x.Date.ToString("dd.MM.yyyy"), x.PriceService?.ToString("N2") ?? string.Empty, x.PriceRoom?.ToString("N2") ?? string.Empty })) .Union( - [["Всего", data.Sum(x => x.PriceService ?? 0).ToString(), data.Sum(x => x.PriceRoom ?? 0).ToString()]]) + [["Всего", data.Sum(x => x.PriceService ?? 0).ToString("N2"), data.Sum(x => x.PriceRoom ?? 0).ToString("N2")]]) .ToList(); } } \ No newline at end of file diff --git a/ProjectAthletesAccommodation/ProjectAthletesAccommodation/Repositories/Implementations/AthleteAccommodationRepository.cs b/ProjectAthletesAccommodation/ProjectAthletesAccommodation/Repositories/Implementations/AthleteAccommodationRepository.cs index 6e33d04..13fdbe5 100644 --- a/ProjectAthletesAccommodation/ProjectAthletesAccommodation/Repositories/Implementations/AthleteAccommodationRepository.cs +++ b/ProjectAthletesAccommodation/ProjectAthletesAccommodation/Repositories/Implementations/AthleteAccommodationRepository.cs @@ -3,6 +3,7 @@ using Microsoft.Extensions.Logging; using Newtonsoft.Json; using Npgsql; using ProjectAthletesAccommodation.Entities; + namespace ProjectAthletesAccommodation.Repositories.Implementations; public class AthleteAccommodationRepository : IAthleteAccommodationRepository @@ -11,7 +12,7 @@ public class AthleteAccommodationRepository : IAthleteAccommodationRepository private readonly ILogger _logger; - public AthleteAccommodationRepository(IConnectionString connectionString, + public AthleteAccommodationRepository(IConnectionString connectionString, ILogger logger) { _connectionString = connectionString; @@ -54,15 +55,42 @@ public class AthleteAccommodationRepository : IAthleteAccommodationRepository } } - public IEnumerable ReadAthleteAccommodation(DateTime? dateFrom = null, DateTime? dateTo = null, + public IEnumerable ReadAthleteAccommodation(DateTime? dateFrom = null, DateTime? dateTo = null, int? roomId = null, int? athleteId = null) { _logger.LogInformation("Получение всех объектов"); try { + var builder = new QueryBuilder(); + + if (dateFrom.HasValue) + { + builder.AddCondition("aa.DateStart >= @dateFrom"); + } + if (dateTo.HasValue) + { + builder.AddCondition("aa.DateStart <= @dateTo"); + } + if (roomId.HasValue) + { + builder.AddCondition("aa.RoomId = @roomId"); + } + if (athleteId.HasValue) + { + builder.AddCondition("aa.AthleteId = @athleteId"); + } + using var connection = new NpgsqlConnection(_connectionString.ConnectionString); - var querySelect = "SELECT * FROM AthleteAccommodation"; - var athleteAccommodation = connection.Query(querySelect); + var querySelect = + $@"SELECT aa.*, + r.Name AS RoomName, + CONCAT(a.Name, ' ', a.Surname) AS AthleteName + FROM AthleteAccommodation aa + LEFT JOIN Room r ON r.Id = aa.RoomId + LEFT JOIN Athlete a ON a.Id = aa.AthleteId + {builder.Build()};"; + var athleteAccommodation = connection.Query(querySelect, + new { dateFrom, dateTo, roomId, athleteId }); _logger.LogDebug("Полученные объекты: {json}", JsonConvert.SerializeObject(athleteAccommodation)); return athleteAccommodation; } diff --git a/ProjectAthletesAccommodation/ProjectAthletesAccommodation/Repositories/Implementations/HotelRepository.cs b/ProjectAthletesAccommodation/ProjectAthletesAccommodation/Repositories/Implementations/HotelRepository.cs index fd82032..593d8f4 100644 --- a/ProjectAthletesAccommodation/ProjectAthletesAccommodation/Repositories/Implementations/HotelRepository.cs +++ b/ProjectAthletesAccommodation/ProjectAthletesAccommodation/Repositories/Implementations/HotelRepository.cs @@ -3,6 +3,7 @@ using Microsoft.Extensions.Logging; using Newtonsoft.Json; using Npgsql; using ProjectAthletesAccommodation.Entities; + namespace ProjectAthletesAccommodation.Repositories.Implementations; public class HotelRepository : IHotelRepository diff --git a/ProjectAthletesAccommodation/ProjectAthletesAccommodation/Repositories/Implementations/QueryBuilder.cs b/ProjectAthletesAccommodation/ProjectAthletesAccommodation/Repositories/Implementations/QueryBuilder.cs new file mode 100644 index 0000000..51f0d0e --- /dev/null +++ b/ProjectAthletesAccommodation/ProjectAthletesAccommodation/Repositories/Implementations/QueryBuilder.cs @@ -0,0 +1,34 @@ +using System.Text; + +namespace ProjectAthletesAccommodation.Repositories.Implementations; + +public 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}"; + } +} \ No newline at end of file diff --git a/ProjectAthletesAccommodation/ProjectAthletesAccommodation/Repositories/Implementations/RoomRepository.cs b/ProjectAthletesAccommodation/ProjectAthletesAccommodation/Repositories/Implementations/RoomRepository.cs index 3a3affe..57d9253 100644 --- a/ProjectAthletesAccommodation/ProjectAthletesAccommodation/Repositories/Implementations/RoomRepository.cs +++ b/ProjectAthletesAccommodation/ProjectAthletesAccommodation/Repositories/Implementations/RoomRepository.cs @@ -3,6 +3,7 @@ using Microsoft.Extensions.Logging; using Newtonsoft.Json; using Npgsql; using Dapper; + namespace ProjectAthletesAccommodation.Repositories.Implementations; public class RoomRepository : IRoomRepository @@ -35,7 +36,7 @@ public class RoomRepository : IRoomRepository throw; } } - + public void UpdateRoom(Room room) { _logger.LogInformation("Редактирование объекта"); @@ -99,7 +100,11 @@ public class RoomRepository : IRoomRepository try { using var connection = new NpgsqlConnection(_connectionString.ConnectionString); - var querySelect = "SELECT * FROM Room"; + var querySelect = + @"SELECT r.*, + h.Name AS HotelName, r.Name AS Name + FROM Room r + LEFT JOIN Hotel h ON h.Id = r.HotelId;"; var rooms = connection.Query(querySelect); _logger.LogDebug("Полученные объекты: {json}", JsonConvert.SerializeObject(rooms)); return rooms; diff --git a/ProjectAthletesAccommodation/ProjectAthletesAccommodation/Repositories/Implementations/ServiceProvisionRepository.cs b/ProjectAthletesAccommodation/ProjectAthletesAccommodation/Repositories/Implementations/ServiceProvisionRepository.cs index 18f10c0..ed3b8ed 100644 --- a/ProjectAthletesAccommodation/ProjectAthletesAccommodation/Repositories/Implementations/ServiceProvisionRepository.cs +++ b/ProjectAthletesAccommodation/ProjectAthletesAccommodation/Repositories/Implementations/ServiceProvisionRepository.cs @@ -3,6 +3,7 @@ using Microsoft.Extensions.Logging; using Newtonsoft.Json; using Npgsql; using ProjectAthletesAccommodation.Entities; + namespace ProjectAthletesAccommodation.Repositories.Implementations; public class ServiceProvisionRepository : IServiceProvisionRepository @@ -11,7 +12,7 @@ public class ServiceProvisionRepository : IServiceProvisionRepository private readonly ILogger _logger; - public ServiceProvisionRepository(IConnectionString connectionString, + public ServiceProvisionRepository(IConnectionString connectionString, ILogger logger) { _connectionString = connectionString; @@ -65,21 +66,66 @@ public class ServiceProvisionRepository : IServiceProvisionRepository } } - public IEnumerable ReadServiceProvision(DateTime? dateFrom = null, DateTime? dateTo = null, + public IEnumerable ReadServiceProvision(DateTime? dateFrom = null, DateTime? dateTo = null, int? hotelId = null, int? athleteId = null) { _logger.LogInformation("Получение всех объектов"); try { + var builder = new QueryBuilder(); + + if (dateFrom.HasValue) + { + builder.AddCondition("sp.Date >= @dateFrom"); + } + if (dateTo.HasValue) + { + builder.AddCondition("sp.Date <= @dateTo"); + } + if (hotelId.HasValue) + { + builder.AddCondition("sp.HotelId = @hotelId"); + } + if (athleteId.HasValue) + { + builder.AddCondition("spc.AthleteId = @athleteId"); + } + using var connection = new NpgsqlConnection(_connectionString.ConnectionString); var querySelect = - @"SELECT sp.*, spc.AthleteId, spc.Price FROM ServiceProvision sp - INNER JOIN ServiceProvisionConnection spc ON spc.ServiceProvisionId = sp.Id"; - var serviceProvision = connection.Query(querySelect); + $@"SELECT sp.*, + h.Name AS HotelName, + spc.AthleteId, + spc.Price, + CONCAT(a.Name, ' ', a.Surname) AS AthleteName + FROM ServiceProvision sp + LEFT JOIN Hotel h ON h.Id = sp.HotelId + INNER JOIN ServiceProvisionConnection spc ON spc.ServiceProvisionId = sp.Id + LEFT JOIN Athlete a ON a.Id = spc.AthleteId + {builder.Build()};"; + + var provisionDict = new Dictionary>(); + + var serviceProvision = + connection.Query(querySelect, + (provision, serviceProvision) => + { + if (!provisionDict.TryGetValue(provision.Id, out var spc)) + { + spc = []; + provisionDict.Add(provision.Id, spc); + } + spc.Add(serviceProvision); + return provision; + }, splitOn: "AthleteId", param: new { dateFrom, dateTo, athleteId, hotelId }); _logger.LogDebug("Полученные объекты: {json}", JsonConvert.SerializeObject(serviceProvision)); - return serviceProvision.GroupBy(x => x.Id, y => y, - (key, value) => ServiceProvision.CreateOpeartion(value.First(), - value.Select(z => ServiceProvisionConnection.CreateElement(0, z.AthleteId, z.Price)))).ToList(); + + return provisionDict.Select(x => + { + var sp = serviceProvision.First(y => y.Id == x.Key); + sp.SetServiceProvisionConnection(x.Value); + return sp; + }).ToArray(); } catch (Exception ex) {