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

This commit is contained in:
TikhonElli 2024-12-16 21:20:09 +04:00
parent 21a4ca5b54
commit c60a1d2120
24 changed files with 246 additions and 88 deletions

View File

@ -1,4 +1,5 @@
using ProjectAthletesAccommodation.Entities.Enums; using ProjectAthletesAccommodation.Entities.Enums;
using System.ComponentModel;
namespace ProjectAthletesAccommodation.Entities; namespace ProjectAthletesAccommodation.Entities;
@ -6,12 +7,18 @@ public class Athlete
{ {
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 Surname { get; private set; } = string.Empty; public string Surname { get; private set; } = string.Empty;
public string FullName => $"{Name} {Surname}";
[DisplayName("Вид спорта")]
public KindOfSport KindOfSport { get; private set; } public KindOfSport KindOfSport { get; private set; }
[DisplayName("Классификация")]
public AthleteClassification AthleteClassification { get; private set; } public AthleteClassification AthleteClassification { get; private set; }
public static Athlete CreateEntity(int id, string name, string surname, public static Athlete CreateEntity(int id, string name, string surname,

View File

@ -1,17 +1,30 @@
namespace ProjectAthletesAccommodation.Entities; using System.ComponentModel;
namespace ProjectAthletesAccommodation.Entities;
public class AthleteAccommodation public class AthleteAccommodation
{ {
public int Id { get; private set; } public int Id { get; private set; }
[Browsable(false)]
public int RoomId { get; private set; } public int RoomId { get; private set; }
[Browsable(false)]
public int AthleteId { get; private set; } 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; } public decimal Price { get; private set; }
[DisplayName("Дата заезда")]
public DateTime DateStart { get; private set; } public DateTime DateStart { get; private set; }
[DisplayName("Дата выезда")]
public DateTime DateEnd { get; private set; } public DateTime DateEnd { get; private set; }
public static AthleteAccommodation CreateOpeartion(int id, int roomId, int athleteId, decimal price) public static AthleteAccommodation CreateOpeartion(int id, int roomId, int athleteId, decimal price)

View File

@ -1,9 +1,12 @@
namespace ProjectAthletesAccommodation.Entities; using System.ComponentModel;
namespace ProjectAthletesAccommodation.Entities;
public class Hotel public class Hotel
{ {
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;
public static Hotel CreateEntity(int id, string name) public static Hotel CreateEntity(int id, string name)

View File

@ -1,4 +1,5 @@
using ProjectAthletesAccommodation.Entities.Enums; using ProjectAthletesAccommodation.Entities.Enums;
using System.ComponentModel;
namespace ProjectAthletesAccommodation.Entities; namespace ProjectAthletesAccommodation.Entities;
@ -6,10 +7,16 @@ public class Room
{ {
public int Id { get; private set; } public int Id { get; private set; }
[Browsable(false)]
public int HotelId { get; private set; } public int HotelId { get; private set; }
[DisplayName("Гостиница")]
public string HotelName { get; private set; } = string.Empty;
[DisplayName("Номер")]
public string Name { get; private set; } = string.Empty; public string Name { get; private set; } = string.Empty;
[DisplayName("Тип номера")]
public TypeOfRoom TypeOfRoom { get; private set; } public TypeOfRoom TypeOfRoom { get; private set; }
public static Room CreateEntity(int id, int hotelId, string name, public static Room CreateEntity(int id, int hotelId, string name,

View File

@ -1,15 +1,29 @@
namespace ProjectAthletesAccommodation.Entities; using System.ComponentModel;
namespace ProjectAthletesAccommodation.Entities;
public class ServiceProvision public class ServiceProvision
{ {
public int Id { get; private set; } public int Id { get; private set; }
[Browsable(false)]
public int HotelId { get; private set; } public int HotelId { get; private set; }
[DisplayName("Гостиница")]
public string HotelName { get; private set; } = string.Empty;
[DisplayName("Услуга")]
public string Name { get; private set; } = string.Empty; public string Name { get; private set; } = string.Empty;
[DisplayName("Дата и время предоставления")]
public DateTime Date { get; private set; } 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> ServiceProvisionConnection { get; private set; } = []; public IEnumerable<ServiceProvisionConnection> ServiceProvisionConnection { get; private set; } = [];
public static ServiceProvision CreateOpeartion(int id, int hotelId, string name, public static ServiceProvision CreateOpeartion(int id, int hotelId, string name,
@ -25,16 +39,12 @@ public class ServiceProvision
}; };
} }
public static ServiceProvision CreateOpeartion(TempServiceProvisionConnection tempServiceProvisionConnection, public void SetServiceProvisionConnection(IEnumerable<ServiceProvisionConnection>
IEnumerable<ServiceProvisionConnection> serviceProvisionConnection) serviceProvisionConnection)
{ {
return new ServiceProvision if (serviceProvisionConnection != null && serviceProvisionConnection.Any())
{ {
Id = tempServiceProvisionConnection.Id, ServiceProvisionConnection = serviceProvisionConnection;
HotelId = tempServiceProvisionConnection.HotelId, }
Name = tempServiceProvisionConnection.Name,
Date = tempServiceProvisionConnection.Date,
ServiceProvisionConnection = serviceProvisionConnection
};
} }
} }

View File

@ -6,6 +6,8 @@ public class ServiceProvisionConnection
public int AthleteId { get; private set; } public int AthleteId { get; private set; }
public string AthleteName { get; private set; } = string.Empty;
public decimal Price { get; private set; } public decimal Price { get; private set; }
public static ServiceProvisionConnection CreateElement(int id, int athleteId, decimal price) public static ServiceProvisionConnection CreateElement(int id, int athleteId, decimal price)

View File

@ -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; }
}

View File

@ -19,7 +19,7 @@ namespace ProjectAthletesAccommodation.Forms
comboBoxRoom.ValueMember = "Id"; comboBoxRoom.ValueMember = "Id";
comboBoxAthlete.DataSource = athleteRepository.ReadAthletes(); comboBoxAthlete.DataSource = athleteRepository.ReadAthletes();
comboBoxAthlete.DisplayMember = "Name"; comboBoxAthlete.DisplayMember = "FullName";
comboBoxAthlete.ValueMember = "Id"; comboBoxAthlete.ValueMember = "Id";
} }

View File

@ -15,7 +15,7 @@ public partial class FormAthleteReport : Form
throw new ArgumentNullException(nameof(container)); throw new ArgumentNullException(nameof(container));
comboBoxAthlete.DataSource = athleteRepository.ReadAthletes(); comboBoxAthlete.DataSource = athleteRepository.ReadAthletes();
comboBoxAthlete.DisplayMember = "Name"; comboBoxAthlete.DisplayMember = "FullName";
comboBoxAthlete.ValueMember = "Id"; comboBoxAthlete.ValueMember = "Id";
} }

View File

@ -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) private bool TryGetIdentifierFromSelectedRow(out int id)
{ {

View File

@ -70,8 +70,13 @@ namespace ProjectAthletesAccommodation.Forms
} }
} }
private void LoadList() => dataGridView.DataSource = private void LoadList()
_athleteAccommodationRepository.ReadAthleteAccommodation(); {
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) private bool TryGetIdentifierFromSelectedRow(out int id)
{ {

View File

@ -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) private bool TryGetIdentifierFromSelectedRow(out int id)
{ {

View File

@ -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) private bool TryGetIdentifierFromSelectedRow(out int id)
{ {

View File

@ -19,7 +19,7 @@ namespace ProjectAthletesAccommodation.Forms
comboBoxHotel.ValueMember = "Id"; comboBoxHotel.ValueMember = "Id";
ColumnAthlete.DataSource = athleteRepository.ReadAthletes(); ColumnAthlete.DataSource = athleteRepository.ReadAthletes();
ColumnAthlete.DisplayMember = "Name"; ColumnAthlete.DisplayMember = "FullName";
ColumnAthlete.ValueMember = "Id"; ColumnAthlete.ValueMember = "Id";
} }

View File

@ -70,8 +70,12 @@ namespace ProjectAthletesAccommodation.Forms
} }
} }
private void LoadList() => dataGridView.DataSource = private void LoadList()
_serviceProvisionRepository.ReadServiceProvision(); {
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) private bool TryGetIdentifierFromSelectedRow(out int id)
{ {

View File

@ -23,7 +23,7 @@ public class ChartReport
{ {
new PdfBuilder(filePath) new PdfBuilder(filePath)
.AddHeader("Размещение спортсменов") .AddHeader("Размещение спортсменов")
.AddPieChart("Заселенные спортсмены (Соотношение стоимостей их проживания)", GetData(dateTime)) .AddPieChart($"Заселенные спортсмены на {dateTime:dd MMMM yyyy} (Соотношение стоимостей их проживания)", GetData(dateTime))
.Build(); .Build();
return true; return true;
} }
@ -37,14 +37,13 @@ public class ChartReport
private List<(string Caption, double Value)> GetData(DateTime dateTime) private List<(string Caption, double Value)> GetData(DateTime dateTime)
{ {
return _athleteAccommodationRepository return _athleteAccommodationRepository
.ReadAthleteAccommodation() .ReadAthleteAccommodation(dateFrom: dateTime.Date, dateTo: dateTime.Date.AddDays(1))
.Where(x => x.DateStart.Date == dateTime.Date) .GroupBy(x => x.AthleteName, (key, group) => new
.GroupBy(x => x.AthleteId, (key, group) => new
{ {
Id = key, AthleteName = key,
Count = group.Sum(x => x.Price) Count = group.Sum(x => x.Price)
}) })
.Select(x => (x.Id.ToString(), (double)x.Count)) .Select(x => (x.AthleteName.ToString(), (double)x.Count))
.ToList(); .ToList();
} }
} }

View File

@ -82,11 +82,11 @@ public class DocReport
private List<string[]> GetRooms() private List<string[]> GetRooms()
{ {
return [ return [
["Гостиница (Id)", "Номер", "Тип номера"], ["Гостиница", "Номер", "Тип номера"],
.. _roomRepository .. _roomRepository
.ReadRooms() .ReadRooms()
.Select(x => new string[] .Select(x => new string[]
{x.HotelId.ToString(), x.Name, x.TypeOfRoom.ToString()}), {x.HotelName.ToString(), x.Name, x.TypeOfRoom.ToString()}),
]; ];
} }
} }

View File

@ -1,7 +1,6 @@
using MigraDoc.DocumentObjectModel; using MigraDoc.DocumentObjectModel;
using MigraDoc.DocumentObjectModel.Shapes.Charts; using MigraDoc.DocumentObjectModel.Shapes.Charts;
using MigraDoc.Rendering; using MigraDoc.Rendering;
using System.Text;
namespace ProjectAthletesAccommodation.Reports; namespace ProjectAthletesAccommodation.Reports;

View File

@ -30,7 +30,7 @@ public class TableReport
{ {
new ExcelBuilder(filePath) new ExcelBuilder(filePath)
.AddHeader("Сводка по спортсмену", 0, 3) .AddHeader("Сводка по спортсмену", 0, 3)
.AddParagraph("За период", 0) .AddParagraph($"За период с {startDate:dd.MM.yyyy} по {endDate:dd.MM.yyyy}", 0)
.AddTable([15, 15, 15], GetData(athleteId, startDate, endDate)) .AddTable([15, 15, 15], GetData(athleteId, startDate, endDate))
.Build(); .Build();
return true; return true;
@ -45,13 +45,11 @@ public class TableReport
private List<string[]> GetData(int athleteId, DateTime startDate, DateTime endDate) private List<string[]> GetData(int athleteId, DateTime startDate, DateTime endDate)
{ {
var data = _serviceProvisionRepository var data = _serviceProvisionRepository
.ReadServiceProvision() .ReadServiceProvision(dateFrom: startDate, dateTo: endDate, athleteId: athleteId)
.Where(x => x.Date >= startDate && x.Date <= endDate && x.ServiceProvisionConnection.Any(y => y.AthleteId == athleteId))
.Select(x => new { Date = x.Date, PriceService = x.ServiceProvisionConnection.FirstOrDefault(y => y.AthleteId == athleteId)?.Price, PriceRoom = (decimal?)null }) .Select(x => new { Date = x.Date, PriceService = x.ServiceProvisionConnection.FirstOrDefault(y => y.AthleteId == athleteId)?.Price, PriceRoom = (decimal?)null })
.Union( .Union(
_athleteAccommodationRepository _athleteAccommodationRepository
.ReadAthleteAccommodation() .ReadAthleteAccommodation(dateFrom: startDate, dateTo: endDate, athleteId: athleteId)
.Where(x => x.DateStart >= startDate && x.DateStart <= endDate && x.AthleteId == athleteId)
.Select(x => new { Date = x.DateStart, PriceService = (decimal?)null, PriceRoom = (decimal?)x.Price })) .Select(x => new { Date = x.DateStart, PriceService = (decimal?)null, PriceRoom = (decimal?)x.Price }))
.OrderBy(x => x.Date); .OrderBy(x => x.Date);
@ -59,9 +57,9 @@ public class TableReport
new List<string[]>() { item } new List<string[]>() { item }
.Union( .Union(
data 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( .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(); .ToList();
} }
} }

View File

@ -3,6 +3,7 @@ using Microsoft.Extensions.Logging;
using Newtonsoft.Json; using Newtonsoft.Json;
using Npgsql; using Npgsql;
using ProjectAthletesAccommodation.Entities; using ProjectAthletesAccommodation.Entities;
namespace ProjectAthletesAccommodation.Repositories.Implementations; namespace ProjectAthletesAccommodation.Repositories.Implementations;
public class AthleteAccommodationRepository : IAthleteAccommodationRepository public class AthleteAccommodationRepository : IAthleteAccommodationRepository
@ -60,9 +61,36 @@ public class AthleteAccommodationRepository : IAthleteAccommodationRepository
_logger.LogInformation("Получение всех объектов"); _logger.LogInformation("Получение всех объектов");
try 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); using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var querySelect = "SELECT * FROM AthleteAccommodation"; var querySelect =
var athleteAccommodation = connection.Query<AthleteAccommodation>(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<AthleteAccommodation>(querySelect,
new { dateFrom, dateTo, roomId, athleteId });
_logger.LogDebug("Полученные объекты: {json}", JsonConvert.SerializeObject(athleteAccommodation)); _logger.LogDebug("Полученные объекты: {json}", JsonConvert.SerializeObject(athleteAccommodation));
return athleteAccommodation; return athleteAccommodation;
} }

View File

@ -3,6 +3,7 @@ using Microsoft.Extensions.Logging;
using Newtonsoft.Json; using Newtonsoft.Json;
using Npgsql; using Npgsql;
using ProjectAthletesAccommodation.Entities; using ProjectAthletesAccommodation.Entities;
namespace ProjectAthletesAccommodation.Repositories.Implementations; namespace ProjectAthletesAccommodation.Repositories.Implementations;
public class HotelRepository : IHotelRepository public class HotelRepository : IHotelRepository

View File

@ -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}";
}
}

View File

@ -3,6 +3,7 @@ using Microsoft.Extensions.Logging;
using Newtonsoft.Json; using Newtonsoft.Json;
using Npgsql; using Npgsql;
using Dapper; using Dapper;
namespace ProjectAthletesAccommodation.Repositories.Implementations; namespace ProjectAthletesAccommodation.Repositories.Implementations;
public class RoomRepository : IRoomRepository public class RoomRepository : IRoomRepository
@ -99,7 +100,11 @@ public class RoomRepository : IRoomRepository
try try
{ {
using var connection = new NpgsqlConnection(_connectionString.ConnectionString); 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<Room>(querySelect); var rooms = connection.Query<Room>(querySelect);
_logger.LogDebug("Полученные объекты: {json}", JsonConvert.SerializeObject(rooms)); _logger.LogDebug("Полученные объекты: {json}", JsonConvert.SerializeObject(rooms));
return rooms; return rooms;

View File

@ -3,6 +3,7 @@ using Microsoft.Extensions.Logging;
using Newtonsoft.Json; using Newtonsoft.Json;
using Npgsql; using Npgsql;
using ProjectAthletesAccommodation.Entities; using ProjectAthletesAccommodation.Entities;
namespace ProjectAthletesAccommodation.Repositories.Implementations; namespace ProjectAthletesAccommodation.Repositories.Implementations;
public class ServiceProvisionRepository : IServiceProvisionRepository public class ServiceProvisionRepository : IServiceProvisionRepository
@ -71,15 +72,60 @@ public class ServiceProvisionRepository : IServiceProvisionRepository
_logger.LogInformation("Получение всех объектов"); _logger.LogInformation("Получение всех объектов");
try 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); using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var querySelect = var querySelect =
@"SELECT sp.*, spc.AthleteId, spc.Price FROM ServiceProvision sp $@"SELECT sp.*,
INNER JOIN ServiceProvisionConnection spc ON spc.ServiceProvisionId = sp.Id"; h.Name AS HotelName,
var serviceProvision = connection.Query<TempServiceProvisionConnection>(querySelect); 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<int, List<ServiceProvisionConnection>>();
var serviceProvision =
connection.Query<ServiceProvision, ServiceProvisionConnection, ServiceProvision>(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)); _logger.LogDebug("Полученные объекты: {json}", JsonConvert.SerializeObject(serviceProvision));
return serviceProvision.GroupBy(x => x.Id, y => y,
(key, value) => ServiceProvision.CreateOpeartion(value.First(), return provisionDict.Select(x =>
value.Select(z => ServiceProvisionConnection.CreateElement(0, z.AthleteId, z.Price)))).ToList(); {
var sp = serviceProvision.First(y => y.Id == x.Key);
sp.SetServiceProvisionConnection(x.Value);
return sp;
}).ToArray();
} }
catch (Exception ex) catch (Exception ex)
{ {