This commit is contained in:
asakky 2024-12-25 19:10:14 +04:00
parent 77878a457c
commit eaf822519c
20 changed files with 228 additions and 63 deletions

View File

@ -1,6 +1,7 @@
using ProjectLibrary.Entities.Enums;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
@ -11,10 +12,13 @@ public class Book
{
public int Id { get; private set; }
[DisplayName("Название")]
public string Title { get; private set; } = string.Empty;
[DisplayName("Жанр")]
public BookTopic Topic { get; private set; }
[DisplayName("Вернули?")]
public Boolean IsIssued { get; private set; }
public static Book CreateEntity(int id, string title, BookTopic topic, Boolean isIssued)

View File

@ -14,6 +14,8 @@ public class BookIssue
public int BookId { get;private set; }
public string BookName { get; private set; } = string.Empty;
public static BookIssue CreateElement(int id, string description, int bookId)
{
return new BookIssue

View File

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
@ -9,11 +10,23 @@ namespace ProjectLibrary.Entities;
public class BookRestoration
{
public int Id { get; private set; }
[Browsable(false)]
public int LibrarianId { get; private set; }
[Browsable(false)]
public int BookId { get; private set; }
[DisplayName("Книга")]
public string BookName { get; private set; } = string.Empty;
[DisplayName("Сотрудник")]
public string LibrarianName { get; private set; } = string.Empty;
[DisplayName("Дата реставрации")]
public DateTime RestorationDate { get; private set; }
[DisplayName("Описание")]
public string Description { get; private set; } = string.Empty;
public static BookRestoration CreateOperation(int id, int librarianId, int bookId, DateTime restorationDate, string description)

View File

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
@ -10,18 +11,35 @@ public class Issue
{
public int Id { get; private set; }
[DisplayName("Дата выпуска")]
public DateTime IssueDate { get; private set; }
[DisplayName("Срок")]
public DateTime DueDate { get; private set; }
[DisplayName("Дата возврата")]
public DateTime ReturnDate { get; private set; }
[Browsable(false)]
public int LibrarianId { get; private set;}
[DisplayName("Имя сотрудника")]
public string LibrarianName { get; private set; } = string.Empty;
[Browsable(false)]
public int ReaderId { get; private set; }
[DisplayName("Имя клиента")]
public string ReaderName { get; private set; } = string.Empty;
[Browsable(false)]
public IEnumerable<BookIssue> BookIssue { get; private set; } = [];
[DisplayName("Выданные книги")]
public string Books => BookIssue != null ?
string.Join(", ", BookIssue.Select(x => $"{x.BookName}")) :
string.Empty;
public static Issue CreateOperation(int id, DateTime issueDate, DateTime dueDate, DateTime returnDate, int librarianId, int readerId, IEnumerable<BookIssue> bookIssue)
{
return new Issue
@ -36,17 +54,11 @@ public class Issue
};
}
public static Issue CreateOperation(TempBookIssue tempBookIssue, IEnumerable<BookIssue> bookIssue)
public void SetBookIssue(IEnumerable<BookIssue> bookIssue)
{
return new Issue
if (bookIssue != null && bookIssue.Any())
{
Id = tempBookIssue.Id,
IssueDate = tempBookIssue.IssueDate,
DueDate = tempBookIssue.DueDate,
ReturnDate = tempBookIssue.ReturnDate,
LibrarianId = tempBookIssue.LibrarianId,
ReaderId = tempBookIssue.ReaderId,
BookIssue = bookIssue
};
BookIssue = bookIssue;
}
}
}

View File

@ -2,6 +2,7 @@
using ProjectLibrary.Entities.Enums;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
@ -12,8 +13,10 @@ public class Librarian
{
public int Id { get; private set; }
[DisplayName("Имя")]
public string Name { get; private set; } = string.Empty;
[DisplayName("Тип")]
public AllowedTopic AllowedTopic { get; private set; }
public static Librarian CreateEntity(int id, string name, AllowedTopic allowedTopic)

View File

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
@ -10,10 +11,13 @@ public class Reader
{
public int Id { get; private set; }
[DisplayName("Имя")]
public string Name { get; private set; } = string.Empty;
[DisplayName("Читательский билет")]
public int LibraryCard { get; private set; }
[DisplayName("До какого выдан")]
public DateTime CardValidity { get; private set; }
public static Reader CreateEntity(int id, string name, int libraryCard)

View File

@ -1,26 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ProjectLibrary.Entities;
public class TempBookIssue
{
public int Id { get; private set; }
public DateTime IssueDate { get; private set; }
public DateTime DueDate { get; private set; }
public DateTime ReturnDate { get; private set; }
public int LibrarianId { get; private set; }
public int ReaderId { get; private set; }
public string Description { get; private set; } = string.Empty;
public int BookId { get; private set; }
}

View File

@ -75,7 +75,11 @@ namespace ProjectLibrary.Forms
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void LoadList() => dataGridView.DataSource = _bookRestorationRepository.ReadBookRestorations();
private void LoadList()
{
dataGridView.DataSource = _bookRestorationRepository.ReadBookRestorations();
dataGridView.Columns["Id"].Visible = false;
}
private bool TryGetIdentifierFromSelectedRow(out int id)
{
id = 0;

View File

@ -97,7 +97,11 @@ namespace ProjectLibrary.Forms
}
}
private void LoadList() => dataGridView.DataSource = _bookRepository.ReadBooks();
private void LoadList()
{
dataGridView.DataSource = _bookRepository.ReadBooks();
dataGridView.Columns["Id"].Visible = false;
}
private bool TryGetIdentifierFromSelectedRow(out int id)
{
id = 0;

View File

@ -76,8 +76,11 @@ namespace ProjectLibrary.Forms
}
}
private void LoadList() => dataGridView.DataSource = _issueRepository.ReadIssue();
private void LoadList()
{
dataGridView.DataSource = _issueRepository.ReadIssue();
dataGridView.Columns["Id"].Visible = false;
}
private bool TryGetIdentifierFromSelectedRow(out int id)
{
id = 0;

View File

@ -94,8 +94,11 @@ namespace ProjectLibrary.Forms
}
}
private void LoadList() => dataGridView.DataSource = _librarianRepository.ReadLibrarians();
private void LoadList()
{
dataGridView.DataSource = _librarianRepository.ReadLibrarians();
dataGridView.Columns["Id"].Visible = false;
}
private bool TryGetIdentifierFromSelectedRow(out int id)
{
id = 0;

View File

@ -94,7 +94,11 @@ namespace ProjectLibrary.Forms
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void LoadList() => dataGridView.DataSource = _readerRepository.ReadReaders();
private void LoadList()
{
dataGridView.DataSource = _readerRepository.ReadReaders();
dataGridView.Columns["Id"].Visible = false;
}
private bool TryGetIdentifierFromSelectedRow(out int id)
{
id = 0;

View File

@ -35,8 +35,7 @@ internal class ChartReport
private List<(string Caption, double Value)> GetData(DateTime dateTime)
{
var issueCount = _issueRepository
.ReadIssue()
.Where(x => x.IssueDate.Date == dateTime.Date)
.ReadIssue(dateFrom: dateTime.Date, dateTo: dateTime.Date.AddDays(1))
.SelectMany(x => x.BookIssue)
.Count();

View File

@ -53,9 +53,7 @@ internal class TableReport
var librarianId = librarian.Id;
var issueData = _issueRepository.ReadIssue()
.Where(issue => issue.IssueDate >= startDate && issue.IssueDate <= endDate)
.Where(issue => issue.LibrarianId == librarianId)
var issueData = _issueRepository.ReadIssue(librarianId, startDate, endDate)
.SelectMany(issue => issue.BookIssue, (issue, bookIssue) => new
{
Librarian = librarian.Name,
@ -65,9 +63,7 @@ internal class TableReport
});
var restorationData = _bookRestorationRepository.ReadBookRestorations()
.Where(restoration => restoration.RestorationDate >= startDate && restoration.RestorationDate <= endDate)
.Where(restoration => restoration.LibrarianId == librarianId)
var restorationData = _bookRestorationRepository.ReadBookRestorations(librarianId, startDate, endDate)
.GroupBy(restoration => new
{
restoration.RestorationDate,

View File

@ -9,7 +9,7 @@ namespace ProjectLibrary.Repositories;
public interface IBookRestorationRepository
{
IEnumerable<BookRestoration> ReadBookRestorations(int? id = null, int? librarianId = null, int? bookId=null, string? description = null, DateTime? dateFrom = null, DateTime? dateTo = null);
IEnumerable<BookRestoration> ReadBookRestorations(int? librarianId = null, DateTime? dateFrom = null, DateTime? dateTo = null);
void CreateBookRestoration(BookRestoration bookRestoration);

View File

@ -9,7 +9,7 @@ namespace ProjectLibrary.Repositories;
public interface IIssueRepository
{
IEnumerable<Issue> ReadIssue(int? id=null, int? librarianId = null, int? readerId = null, DateTime? dateFrom = null, DateTime? dateTo = null);
IEnumerable<Issue> ReadIssue(int? librarianId = null, DateTime? dateFrom = null, DateTime? dateTo = null);
void CreateIssue(Issue issue);

View File

@ -66,16 +66,32 @@ public class BookRestorationRepository : IBookRestorationRepository
}
}
public IEnumerable<BookRestoration> ReadBookRestorations(int? id, int? librarianId, int? bookId, string? description, DateTime? dateFrom = null, DateTime? dateTo = null)
public IEnumerable<BookRestoration> ReadBookRestorations(int? librarianId, DateTime? dateFrom = null, DateTime? dateTo = null)
{
_logger.LogInformation("Получение всех объектов");
try
{
var builder = new QueryBuilder();
if (dateFrom.HasValue)
{
builder.AddCondition("bor.RestorationDate >= @dateFrom");
}
if (dateTo.HasValue)
{
builder.AddCondition("bor.RestorationDate <= @dateTo");
}
if (librarianId.HasValue)
{
builder.AddCondition("bor.librarianId = @librarianId");
}
using var connection = new
NpgsqlConnection(_connectionString.ConnectionString);
var querySelect = "SELECT * FROM BookRestoration";
var querySelect = @$"SELECT bor.*, boo.Title as BookName, lib.Name as LibrarianName FROM BookRestoration bor
LEFT JOIN Book boo on boo.Id = bor.BookId
LEFT JOIN Librarian lib on lib.Id = bor.LibrarianId
{builder.Build()}";
var bookRestoration =
connection.Query<BookRestoration>(querySelect);
connection.Query<BookRestoration>(querySelect, new {dateFrom, dateTo, librarianId});
_logger.LogDebug("Полученные объекты: {json}",
JsonConvert.SerializeObject(bookRestoration));
return bookRestoration;

View File

@ -89,22 +89,61 @@ public class IssueRepository : IIssueRepository
}
}
public IEnumerable<Issue> ReadIssue(int? id, int? librarianId, int? readerId, DateTime? dateFrom = null, DateTime? dateTo = null)
public IEnumerable<Issue> ReadIssue(int? librarianId, DateTime? dateFrom = null, DateTime? dateTo = null)
{
_logger.LogInformation("Получение всех объектов");
try
{
var builder = new QueryBuilder();
if (dateFrom.HasValue)
{
builder.AddCondition("iss.IssueDate >= @dateFrom");
}
if (dateTo.HasValue)
{
builder.AddCondition("iss.IssueDate <= @dateTo");
}
if (librarianId.HasValue)
{
builder.AddCondition("iss.librarianId = @librarianId");
}
using var connection = new
NpgsqlConnection(_connectionString.ConnectionString);
var querySelect = @"SELECT
iss.*, biss.Description, biss.BookId
iss.*,
lib.Name as LibrarianName,
rea.Name as ReaderName,
biss.Description,
biss.BookId,
bo.Title as BookName
FROM Issue iss
INNER JOIN Book_Issue biss on biss.IssueId = iss.Id";
var issue =
connection.Query<TempBookIssue>(querySelect);
LEFT JOIN Librarian lib on lib.Id = iss.LibrarianId
LEFT JOIN Reader rea on rea.Id = iss.ReaderId
INNER JOIN Book_Issue biss on biss.IssueId = iss.Id
LEFT JOIN Book bo on bo.Id = biss.BookId";
var issuesDict = new Dictionary<int, List<BookIssue>>();
var bookIssues = connection.Query<Issue, BookIssue, Issue>(querySelect,
(issue, bookIssue) =>
{
if (!issuesDict.TryGetValue(issue.Id, out var ccf))
{
ccf = [];
issuesDict.Add(issue.Id, ccf);
}
ccf.Add(bookIssue);
return issue;
}, splitOn: "BookId", param: new { dateFrom, dateTo, librarianId });
_logger.LogDebug("Полученные объекты: {json}",
JsonConvert.SerializeObject(issue));
return issue.GroupBy(x => x.Id, y => y, (key, value) => Issue.CreateOperation(value.First(), value.Select(z => BookIssue.CreateElement(0, z.Description, z.BookId)))).ToList();
JsonConvert.SerializeObject(bookIssues));
return issuesDict.Select(x =>
{
var cf = bookIssues.First(y => y.Id == x.Key);
cf.SetBookIssue(x.Value);
return cf;
}).ToArray();
}
catch (Exception ex)
{

View File

@ -0,0 +1,34 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ProjectLibrary.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

@ -0,0 +1,51 @@
2024-12-25 19:09:51.773 +04:00 [INF] Получение всех объектов
2024-12-25 19:09:52.186 +04:00 [ERR] Ошибка при чтении объектов
Npgsql.PostgresException (0x80004005): 28P01: <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> "postgres" <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (<28><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)
at Npgsql.Internal.NpgsqlConnector.ReadMessageLong(Boolean async, DataRowLoadingMode dataRowLoadingMode, Boolean readingNotifications, Boolean isReadingPrependedMessage)
at System.Runtime.CompilerServices.PoolingAsyncValueTaskMethodBuilder`1.StateMachineBox`1.System.Threading.Tasks.Sources.IValueTaskSource<TResult>.GetResult(Int16 token)
at Npgsql.Internal.NpgsqlConnector.AuthenticateSASL(List`1 mechanisms, String username, Boolean async, CancellationToken cancellationToken)
at Npgsql.Internal.NpgsqlConnector.Authenticate(String username, NpgsqlTimeout timeout, Boolean async, CancellationToken cancellationToken)
at Npgsql.Internal.NpgsqlConnector.<Open>g__OpenCore|214_1(NpgsqlConnector conn, SslMode sslMode, NpgsqlTimeout timeout, Boolean async, CancellationToken cancellationToken)
at Npgsql.Internal.NpgsqlConnector.Open(NpgsqlTimeout timeout, Boolean async, CancellationToken cancellationToken)
at Npgsql.PoolingDataSource.OpenNewConnector(NpgsqlConnection conn, NpgsqlTimeout timeout, Boolean async, CancellationToken cancellationToken)
at Npgsql.PoolingDataSource.<Get>g__RentAsync|33_0(NpgsqlConnection conn, NpgsqlTimeout timeout, Boolean async, CancellationToken cancellationToken)
at Npgsql.NpgsqlConnection.<Open>g__OpenAsync|42_0(Boolean async, CancellationToken cancellationToken)
at Npgsql.NpgsqlConnection.Open()
at Dapper.SqlMapper.MultiMapImpl[TFirst,TSecond,TThird,TFourth,TFifth,TSixth,TSeventh,TReturn](IDbConnection cnn, CommandDefinition command, Delegate map, String splitOn, DbDataReader reader, Identity identity, Boolean finalize)+MoveNext() in /_/Dapper/SqlMapper.cs:line 1566
at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
at Dapper.SqlMapper.MultiMap[TFirst,TSecond,TThird,TFourth,TFifth,TSixth,TSeventh,TReturn](IDbConnection cnn, String sql, Delegate map, Object param, IDbTransaction transaction, Boolean buffered, String splitOn, Nullable`1 commandTimeout, Nullable`1 commandType) in /_/Dapper/SqlMapper.cs:line 1548
at Dapper.SqlMapper.Query[TFirst,TSecond,TReturn](IDbConnection cnn, String sql, Func`3 map, Object param, IDbTransaction transaction, Boolean buffered, String splitOn, Nullable`1 commandTimeout, Nullable`1 commandType) in /_/Dapper/SqlMapper.cs:line 1397
at ProjectLibrary.Repositories.Implementations.IssueRepository.ReadIssue(Nullable`1 librarianId, Nullable`1 dateFrom, Nullable`1 dateTo) in F:\OTP2\ProjectLibrary\ProjectLibrary\Repositories\Implementations\IssueRepository.cs:line 126
Exception data:
Severity: <20><><EFBFBD><EFBFBD><EFBFBD>
SqlState: 28P01
MessageText: <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> "postgres" <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (<28><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)
File: auth.c
Line: 324
Routine: auth_failed
2024-12-25 19:09:55.412 +04:00 [INF] Получение всех объектов
2024-12-25 19:09:55.437 +04:00 [ERR] Ошибка при чтении объектов
Npgsql.PostgresException (0x80004005): 28P01: <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> "postgres" <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (<28><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)
at Npgsql.Internal.NpgsqlConnector.ReadMessageLong(Boolean async, DataRowLoadingMode dataRowLoadingMode, Boolean readingNotifications, Boolean isReadingPrependedMessage)
at System.Runtime.CompilerServices.PoolingAsyncValueTaskMethodBuilder`1.StateMachineBox`1.System.Threading.Tasks.Sources.IValueTaskSource<TResult>.GetResult(Int16 token)
at Npgsql.Internal.NpgsqlConnector.AuthenticateSASL(List`1 mechanisms, String username, Boolean async, CancellationToken cancellationToken)
at Npgsql.Internal.NpgsqlConnector.Authenticate(String username, NpgsqlTimeout timeout, Boolean async, CancellationToken cancellationToken)
at Npgsql.Internal.NpgsqlConnector.<Open>g__OpenCore|214_1(NpgsqlConnector conn, SslMode sslMode, NpgsqlTimeout timeout, Boolean async, CancellationToken cancellationToken)
at Npgsql.Internal.NpgsqlConnector.Open(NpgsqlTimeout timeout, Boolean async, CancellationToken cancellationToken)
at Npgsql.PoolingDataSource.OpenNewConnector(NpgsqlConnection conn, NpgsqlTimeout timeout, Boolean async, CancellationToken cancellationToken)
at Npgsql.PoolingDataSource.<Get>g__RentAsync|33_0(NpgsqlConnection conn, NpgsqlTimeout timeout, Boolean async, CancellationToken cancellationToken)
at Npgsql.NpgsqlConnection.<Open>g__OpenAsync|42_0(Boolean async, CancellationToken cancellationToken)
at Npgsql.NpgsqlConnection.Open()
at Dapper.SqlMapper.QueryImpl[T](IDbConnection cnn, CommandDefinition command, Type effectiveType)+MoveNext() in /_/Dapper/SqlMapper.cs:line 1183
at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
at Dapper.SqlMapper.Query[T](IDbConnection cnn, String sql, Object param, IDbTransaction transaction, Boolean buffered, Nullable`1 commandTimeout, Nullable`1 commandType) in /_/Dapper/SqlMapper.cs:line 815
at ProjectLibrary.Repositories.Implementations.LibrarianRepository.ReadLibrarians() in F:\OTP2\ProjectLibrary\ProjectLibrary\Repositories\Implementations\LibrarianRepository.cs:line 101
Exception data:
Severity: <20><><EFBFBD><EFBFBD><EFBFBD>
SqlState: 28P01
MessageText: <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> "postgres" <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (<28><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)
File: auth.c
Line: 324
Routine: auth_failed