diff --git a/RealEstateTransactions/RealEstateTransactions/Entities/Apartment.cs b/RealEstateTransactions/RealEstateTransactions/Entities/Apartment.cs index e5d8419..5bfbfd1 100644 --- a/RealEstateTransactions/RealEstateTransactions/Entities/Apartment.cs +++ b/RealEstateTransactions/RealEstateTransactions/Entities/Apartment.cs @@ -1,4 +1,5 @@ using RealEstateTransactions.Entities.Enums; +using System.ComponentModel; namespace RealEstateTransactions.Entities { @@ -6,18 +7,26 @@ namespace RealEstateTransactions.Entities { public int Id { get; private set; } + [DisplayName("Агенство")] public AgencyType Agency_ID { get; private set; } + [DisplayName("Комнаты")] public FormFactorType Form_factor_ID { get; private set; } + [DisplayName("Площадь")] public float Area { get; private set; } + [DisplayName("Цена за кв.м.")] public float Price_per_SM { get; private set; } + [DisplayName("Начальная стоимость")] public float Base_price { get; private set; } + [DisplayName("Стоимость от агенства")] public float Desired_price { get; private set; } + public string GetStr { get => $"{Agency_ID.ToString()} {Area.ToString()}"; } + public static Apartment CreateApartment(int id, AgencyType agencyId, FormFactorType formFactorId, float area, float pricePerSM, float basePrice, float desiredPrice) { diff --git a/RealEstateTransactions/RealEstateTransactions/Entities/Buyer.cs b/RealEstateTransactions/RealEstateTransactions/Entities/Buyer.cs index 5b264be..626a3f6 100644 --- a/RealEstateTransactions/RealEstateTransactions/Entities/Buyer.cs +++ b/RealEstateTransactions/RealEstateTransactions/Entities/Buyer.cs @@ -1,13 +1,18 @@ -namespace RealEstateTransactions.Entities +using System.ComponentModel; + +namespace RealEstateTransactions.Entities { public class Buyer { public int Id { get; private set; } + [DisplayName("ФИО")] public string Full_name { get; private set; } = string.Empty; + [DisplayName("Серия паспорта")] public int Passport_series { get; private set; } + [DisplayName("Номер паспорта")] public int Passport_number { get; private set; } public static Buyer CreateBuyer(int id, string fullName, int passportSeries, int passportNumber) diff --git a/RealEstateTransactions/RealEstateTransactions/Entities/Deal.cs b/RealEstateTransactions/RealEstateTransactions/Entities/Deal.cs index 1d1897c..28c4ce8 100644 --- a/RealEstateTransactions/RealEstateTransactions/Entities/Deal.cs +++ b/RealEstateTransactions/RealEstateTransactions/Entities/Deal.cs @@ -1,17 +1,31 @@ -namespace RealEstateTransactions.Entities +using System.ComponentModel; + +namespace RealEstateTransactions.Entities { public class Deal { public int Id { get; private set; } + [DisplayName("ID квартиры")] public int Apartment_ID { get; private set; } + [Browsable(false)] public int Buyer_ID { get; private set; } + [DisplayName("ФИО покупателя")] + public string BuyerName { get; private set; } = string.Empty; + + [DisplayName("Цена сделки")] public float Deal_price { get; private set; } + [DisplayName("Дата сделки")] public DateTime Deal_date { get; private set; } + [DisplayName("Услуги")] + public string Services => DealServices != null ? + string.Join(", ", DealServices.Select(x => $"{x.DealName} {x.Execution_time}")) : string.Empty; + + [Browsable(false)] public IEnumerable DealServices { get; private set; } = []; public static Deal CreateDeal(int id, int apartmentId, int buyerId, float dealPrice, @@ -27,5 +41,10 @@ DealServices = dealServices }; } + + public void SetServicesDeal(IEnumerable servicesDeal) + { + if (servicesDeal != null && servicesDeal.Any()) DealServices = servicesDeal; + } } } \ No newline at end of file diff --git a/RealEstateTransactions/RealEstateTransactions/Entities/PreSalesServices.cs b/RealEstateTransactions/RealEstateTransactions/Entities/PreSalesServices.cs index 183a597..5987cdc 100644 --- a/RealEstateTransactions/RealEstateTransactions/Entities/PreSalesServices.cs +++ b/RealEstateTransactions/RealEstateTransactions/Entities/PreSalesServices.cs @@ -1,13 +1,18 @@ -namespace RealEstateTransactions.Entities +using System.ComponentModel; + +namespace RealEstateTransactions.Entities { public class PreSalesServices { public int Id { get; private set; } + [DisplayName("ID квартиры")] public int Apartment_ID { get; private set; } + [DisplayName("Название")] public string Name { get; private set; } = string.Empty; + [DisplayName("Стоимость")] public float Cost { get; private set; } public static PreSalesServices CreatePreSalesServices(int id, int apartmentId, string name, float cost) diff --git a/RealEstateTransactions/RealEstateTransactions/Entities/Services.cs b/RealEstateTransactions/RealEstateTransactions/Entities/Services.cs index 134631b..8ba4f21 100644 --- a/RealEstateTransactions/RealEstateTransactions/Entities/Services.cs +++ b/RealEstateTransactions/RealEstateTransactions/Entities/Services.cs @@ -1,11 +1,15 @@ -namespace RealEstateTransactions.Entities +using System.ComponentModel; + +namespace RealEstateTransactions.Entities { public class Services { public int Id { get; private set; } + [DisplayName("Название")] public string Name { get; private set; } = string.Empty; + [DisplayName("Стоимость")] public float Price { get; private set; } public static Services CreateService(int id, string name, float price) diff --git a/RealEstateTransactions/RealEstateTransactions/Entities/ServicesDeal.cs b/RealEstateTransactions/RealEstateTransactions/Entities/ServicesDeal.cs index e37c7fe..9062946 100644 --- a/RealEstateTransactions/RealEstateTransactions/Entities/ServicesDeal.cs +++ b/RealEstateTransactions/RealEstateTransactions/Entities/ServicesDeal.cs @@ -1,4 +1,6 @@ -namespace RealEstateTransactions.Entities +using System.ComponentModel; + +namespace RealEstateTransactions.Entities { public class ServicesDeal { @@ -6,6 +8,9 @@ public int Deal_ID { get; private set; } + public string DealName { get; private set; } = string.Empty; + + [DisplayName("Время выполнения")] public double Execution_time { get; private set; } public static ServicesDeal CreateServicesDeal(int servicesId, int dealId, double executionTime) diff --git a/RealEstateTransactions/RealEstateTransactions/Forms/FormApartments.cs b/RealEstateTransactions/RealEstateTransactions/Forms/FormApartments.cs index 6910d40..d3eebdf 100644 --- a/RealEstateTransactions/RealEstateTransactions/Forms/FormApartments.cs +++ b/RealEstateTransactions/RealEstateTransactions/Forms/FormApartments.cs @@ -76,7 +76,12 @@ namespace RealEstateTransactions.Forms } } - private void LoadList() => dataGridView.DataSource = _repository.ReadApartments(); + private void LoadList() + { + dataGridView.DataSource = _repository.ReadApartments(); + dataGridView.Columns["Id"].Visible = false; + dataGridView.Columns["GetStr"].Visible = false; + } private bool TryGetIdentifierFormSelectedRow(out int id) { diff --git a/RealEstateTransactions/RealEstateTransactions/Forms/FormBuyers.cs b/RealEstateTransactions/RealEstateTransactions/Forms/FormBuyers.cs index 393dc1b..342f83a 100644 --- a/RealEstateTransactions/RealEstateTransactions/Forms/FormBuyers.cs +++ b/RealEstateTransactions/RealEstateTransactions/Forms/FormBuyers.cs @@ -76,7 +76,11 @@ namespace RealEstateTransactions.Forms } } - private void LoadList() => dataGridView.DataSource = _repository.ReadBuyers(); + private void LoadList() + { + dataGridView.DataSource = _repository.ReadBuyers(); + dataGridView.Columns["Id"].Visible = false; + } private bool TryGetIdentifierFormSelectedRow(out int id) { diff --git a/RealEstateTransactions/RealEstateTransactions/Forms/FormDeal.cs b/RealEstateTransactions/RealEstateTransactions/Forms/FormDeal.cs index cfc3760..f5e60c0 100644 --- a/RealEstateTransactions/RealEstateTransactions/Forms/FormDeal.cs +++ b/RealEstateTransactions/RealEstateTransactions/Forms/FormDeal.cs @@ -18,7 +18,7 @@ namespace RealEstateTransactions.Forms comboBoxApartmentId.ValueMember = "Id"; comboBoxFullName.DataSource = buyerRepository.ReadBuyers(); - comboBoxFullName.DisplayMember = "FullName"; + comboBoxFullName.DisplayMember = "Full_name"; comboBoxFullName.ValueMember = "Id"; ColumnService.DataSource = servicesRepository.ReadServices(); diff --git a/RealEstateTransactions/RealEstateTransactions/Forms/FormDeals.cs b/RealEstateTransactions/RealEstateTransactions/Forms/FormDeals.cs index 9cc0622..8c2f312 100644 --- a/RealEstateTransactions/RealEstateTransactions/Forms/FormDeals.cs +++ b/RealEstateTransactions/RealEstateTransactions/Forms/FormDeals.cs @@ -60,7 +60,12 @@ namespace RealEstateTransactions.Entities } } - private void LoadList() => dataGridView.DataSource = _repository.ReadDeals(); + private void LoadList() + { + dataGridView.DataSource = _repository.ReadDeals(); + dataGridView.Columns["Id"].Visible = false; + dataGridView.Columns["Deal_date"].DefaultCellStyle.Format = "dd MMMM yyyy hh:mm"; + } private bool TryGetIdentifierFormSelectedRow(out int id) { diff --git a/RealEstateTransactions/RealEstateTransactions/Forms/FormPreSalesServices.cs b/RealEstateTransactions/RealEstateTransactions/Forms/FormPreSalesServices.cs index a6e8cf4..d568697 100644 --- a/RealEstateTransactions/RealEstateTransactions/Forms/FormPreSalesServices.cs +++ b/RealEstateTransactions/RealEstateTransactions/Forms/FormPreSalesServices.cs @@ -59,7 +59,11 @@ namespace RealEstateTransactions.Forms } } - private void LoadList() => dataGridView.DataSource = _repository.ReadPreSalesServices(); + private void LoadList() + { + dataGridView.DataSource = _repository.ReadPreSalesServices(); + dataGridView.Columns["Id"].Visible = false; + } private bool TryGetIdentifierFormSelectedRow(out int id) { diff --git a/RealEstateTransactions/RealEstateTransactions/Forms/FormPriceReport.cs b/RealEstateTransactions/RealEstateTransactions/Forms/FormPriceReport.cs index d34a365..225bd0e 100644 --- a/RealEstateTransactions/RealEstateTransactions/Forms/FormPriceReport.cs +++ b/RealEstateTransactions/RealEstateTransactions/Forms/FormPriceReport.cs @@ -13,7 +13,7 @@ namespace RealEstateTransactions.Forms InitializeComponent(); _container = container ?? throw new ArgumentNullException(nameof(container)); comboBoxApartmentId.DataSource = repository.ReadApartments(); - comboBoxApartmentId.DisplayMember = "Id"; + comboBoxApartmentId.DisplayMember = "GetStr"; comboBoxApartmentId.ValueMember = "Id"; } diff --git a/RealEstateTransactions/RealEstateTransactions/Forms/FormServices.cs b/RealEstateTransactions/RealEstateTransactions/Forms/FormServices.cs index b80d5d0..e82ebf8 100644 --- a/RealEstateTransactions/RealEstateTransactions/Forms/FormServices.cs +++ b/RealEstateTransactions/RealEstateTransactions/Forms/FormServices.cs @@ -77,7 +77,11 @@ namespace RealEstateTransactions.Entities } } - private void LoadList() => dataGridView.DataSource = _repository.ReadServices(); + private void LoadList() + { + dataGridView.DataSource = _repository.ReadServices(); + dataGridView.Columns["Id"].Visible = false; + } private bool TryGetIdentifierFormSelectedRow(out int id) { diff --git a/RealEstateTransactions/RealEstateTransactions/Reports/ChartReport.cs b/RealEstateTransactions/RealEstateTransactions/Reports/ChartReport.cs index fa41d02..4481ae0 100644 --- a/RealEstateTransactions/RealEstateTransactions/Reports/ChartReport.cs +++ b/RealEstateTransactions/RealEstateTransactions/Reports/ChartReport.cs @@ -22,7 +22,7 @@ namespace RealEstateTransactions.Reports { new PdfBuilder(filePath) .AddHeader("Доход с продажи квартир") - .AddPieChart("Проданные квартиры", GetData(dateTime)) + .AddPieChart($"Проданные квартиры {dateTime:dd.MM.yyyy}", GetData(dateTime)) .Build(); return true; } @@ -36,9 +36,8 @@ namespace RealEstateTransactions.Reports private List<(string Caption, double Value)> GetData(DateTime dateTime) { return _dealRepository - .ReadDeals() - .Where(x => x.Deal_date.Date == dateTime.Date) - .Select(x => (x.Apartment_ID.ToString(), (double)x.Deal_price)) + .ReadDeals(dateFrom: dateTime.Date, dateTo: dateTime.Date.AddDays(1)) + .Select(x => (x.BuyerName, (double)x.Deal_price)) .ToList(); } } diff --git a/RealEstateTransactions/RealEstateTransactions/Reports/TableReport.cs b/RealEstateTransactions/RealEstateTransactions/Reports/TableReport.cs index aeaadbd..6da62aa 100644 --- a/RealEstateTransactions/RealEstateTransactions/Reports/TableReport.cs +++ b/RealEstateTransactions/RealEstateTransactions/Reports/TableReport.cs @@ -30,7 +30,7 @@ namespace RealEstateTransactions.Reports { new ExcelBuilder(filePath) .AddHeader("Сводка по доходу от продажи квартиры", 0, 4) - .AddParagraph("за период", 0) + .AddParagraph($"за период с {startDate:dd.MM.yyyy} по {endDate:dd.MM.yyyy}", 0) .AddTable([10, 10, 10, 15], GetData(apartmentId, startDate, endDate)) .Build(); @@ -47,9 +47,7 @@ namespace RealEstateTransactions.Reports endDate) { var data = _dealRepository - .ReadDeals() - .Where(x => x.Deal_date >= startDate && x.Deal_date <= endDate && - x.Apartment_ID == apartmentId) + .ReadDeals(startDate, endDate, apartmentId) .Select(x => new { DealId = (int?)x.Id, Date = (DateTime?)x.Deal_date, DealPrice = (float?)x.Deal_price, ServicesPrice = (float?)null }) @@ -67,7 +65,7 @@ namespace RealEstateTransactions.Reports .Union( data .Select(x => new string[] { - x.DealId?.ToString() ?? string.Empty, x.Date?.ToString() ?? string.Empty, + x.DealId?.ToString("N0") ?? string.Empty, x.Date?.ToString("dd.MM.yyyy") ?? string.Empty, x.DealPrice?.ToString() ?? string.Empty, x.ServicesPrice?.ToString() ?? string.Empty})) .Union( [["Всего", "", data.Sum(x => x.DealPrice ?? 0).ToString(), diff --git a/RealEstateTransactions/RealEstateTransactions/Repositories/IDealRepository.cs b/RealEstateTransactions/RealEstateTransactions/Repositories/IDealRepository.cs index fca26ee..1f69280 100644 --- a/RealEstateTransactions/RealEstateTransactions/Repositories/IDealRepository.cs +++ b/RealEstateTransactions/RealEstateTransactions/Repositories/IDealRepository.cs @@ -4,8 +4,8 @@ namespace RealEstateTransactions.Repositories { public interface IDealRepository { - IEnumerable ReadDeals(DateTime? dateForm = null, DateTime? dateTo = null, - int? servicesID = null, int? dealID = null); + IEnumerable ReadDeals(DateTime? dateFrom = null, DateTime? dateTo = null, + int? apartmentId = null); void CreateDeal(Deal deal); diff --git a/RealEstateTransactions/RealEstateTransactions/Repositories/Implementations/DealRepository.cs b/RealEstateTransactions/RealEstateTransactions/Repositories/Implementations/DealRepository.cs index bfc0da8..46314de 100644 --- a/RealEstateTransactions/RealEstateTransactions/Repositories/Implementations/DealRepository.cs +++ b/RealEstateTransactions/RealEstateTransactions/Repositories/Implementations/DealRepository.cs @@ -28,14 +28,14 @@ namespace RealEstateTransactions.Repositories.Implementations connection.Open(); using var transaction = connection.BeginTransaction(); var insertQuery = @" -INSERT INTO Deal (Apartment_ID, Buyer_ID, Deal_price, Deal_date) -VALUES (@Apartment_ID, @Buyer_ID, @Deal_price, @Deal_date); -SELECT MAX(Id) FROM Deal"; + INSERT INTO Deal (Apartment_ID, Buyer_ID, Deal_price, Deal_date) + VALUES (@Apartment_ID, @Buyer_ID, @Deal_price, @Deal_date); + SELECT MAX(Id) FROM Deal"; var dealId = connection.QueryFirst(insertQuery, deal, transaction); var subInsertQuery = @" -INSERT INTO Services_Deal (Services_ID, Deal_ID, Execution_time) -VALUES (@Services_ID, @Deal_ID, @Execution_time)"; + INSERT INTO Services_Deal (Services_ID, Deal_ID, Execution_time) + VALUES (@Services_ID, @Deal_ID, @Execution_time)"; foreach (var elem in deal.DealServices) { connection.Execute(subInsertQuery, new { elem.Services_ID, @@ -58,9 +58,8 @@ VALUES (@Services_ID, @Deal_ID, @Execution_time)"; try { using var connection = new NpgsqlConnection(_connectionString.ConnectionString); - var deleteQuery = @" -DELETE FROM Deal -WHERE Id = @id"; + var deleteQuery = @"DELETE FROM Deal + WHERE Id = @id"; connection.Execute(deleteQuery, new { id }); } catch (Exception ex) @@ -70,17 +69,55 @@ WHERE Id = @id"; } } - public IEnumerable ReadDeals(DateTime? dateForm = null, DateTime? dateTo = null, - int? servicesID = null, int? dealID = null) + public IEnumerable ReadDeals(DateTime? dateFrom = null, DateTime? dateTo = null, + int? apartmentId = null) { _logger.LogInformation("Получение всех объектов"); try { + var builder = new QueryBuilder(); + if (dateFrom.HasValue) + builder.AddCondition("de.Deal_date >= @dateFrom"); + if (dateTo.HasValue) + builder.AddCondition("de.Deal_date <= @dateTo"); + if (apartmentId.HasValue) + builder.AddCondition("de.Apartment_Id = @apartmentId"); + using var connection = new NpgsqlConnection(_connectionString.ConnectionString); - var selectQuery = @"SELECT * FROM Deal"; - var deals = connection.Query(selectQuery); + var selectQuery = $@"SELECT + de.*, + bu.Full_name BuyerName, + sd.Deal_Id, + ss.Name DealName, + sd.Services_Id, + sd.Execution_time + FROM Deal de + LEFT JOIN Buyer bu on bu.Id = de.Buyer_Id + INNER JOIN Services_Deal sd on sd.Deal_Id = de.Id + LEFT JOIN Services ss on ss.Id = sd.Services_Id + {builder.Build()}"; + var servicesDict = new Dictionary>(); + + var deals = connection.Query(selectQuery, + (deal, servicesDeal) => + { + if (!servicesDict.TryGetValue(deal.Id, out var sd)) + { + sd = []; + servicesDict.Add(deal.Id, sd); + } + + sd.Add(servicesDeal); + return deal; + }, splitOn: "Deal_Id", param: new {dateFrom, dateTo, apartmentId}); _logger.LogDebug("Полученные объекты: {json}", JsonConvert.SerializeObject(deals)); - return deals; + + return servicesDict.Select(x => + { + var dl = deals.First(y => y.Id == x.Key); + dl.SetServicesDeal(x.Value); + return dl; + }).ToArray(); } catch (Exception ex) { diff --git a/RealEstateTransactions/RealEstateTransactions/Repositories/Implementations/QueryBuilder.cs b/RealEstateTransactions/RealEstateTransactions/Repositories/Implementations/QueryBuilder.cs new file mode 100644 index 0000000..fd3936b --- /dev/null +++ b/RealEstateTransactions/RealEstateTransactions/Repositories/Implementations/QueryBuilder.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace RealEstateTransactions.Repositories.Implementations +{ + public class QueryBuilder + { + private readonly StringBuilder _builder; + + public QueryBuilder() + { + _builder = new StringBuilder(); + } + + 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