using Microsoft.Extensions.Logging; using LDBproject.Entities; using Newtonsoft.Json; using Npgsql; using Dapper; namespace LDBproject.Repositories.Implementations; public class OrderR : IOrderRep { private readonly IConnectionString _connectionString; private readonly ILogger<OrderR> _logger; public OrderR(IConnectionString connectionString, ILogger<OrderR> logger) { _connectionString = connectionString; _logger = logger; } public void CreateOrder(Order order) { _logger.LogInformation("< Adding new ORDER > [!]"); _logger.LogDebug("Object - {json}", JsonConvert.SerializeObject(order)); try { using var connection = new NpgsqlConnection(_connectionString.ConnectionString); connection.Open(); using var transaction = connection.BeginTransaction(); // 1. Insert the Order without RETURNING var queryInsert = @"INSERT INTO Orders (CardID, LibrarianID, BorrowDate) VALUES (@CardID, @LibrarianID, @BorrowDate)"; connection.Execute(queryInsert, new { order.CardID, order.LibrarianID, order.BorrowDate }, transaction); // 2. Get the last inserted OrderID var queryGetLastInsertedId = "SELECT MAX(OrderID) FROM Orders"; int orderID = connection.QuerySingle<int>(queryGetLastInsertedId, transaction: transaction); // 3. Insert the Registrations associated with the order var querySubInsert = @"INSERT INTO Registrations (OrderID, BookID, Note) VALUES (@OrderID, @BookID, @Note)"; foreach (var elem in order.Registrations) { connection.Execute(querySubInsert, new { OrderID = orderID, elem.BookID, elem.Note }, transaction); } transaction.Commit(); } catch (Exception ex) { _logger.LogError(ex, "< Error while adding ORDER >"); throw; } } public void UpdateOrderInfo(Order order) { _logger.LogInformation("< Updating order info >"); _logger.LogDebug("Object - {json}", JsonConvert.SerializeObject(order)); try { using var connection = new NpgsqlConnection(_connectionString.ConnectionString); using var transaction = connection.BeginTransaction(); // 1. Update order var queryUpdate = @" UPDATE Orders SET CardID = @CardID, LibrarianID = @LibrarianID, BorrowDate = @BorrowDate WHERE OrderID = @OrderID"; connection.Execute(queryUpdate, new { order.CardID, order.LibrarianID, order.BorrowDate, order.OrderID }, transaction); //2. Update registrations: var queryDeleteRegistrations = "DELETE FROM Registrations WHERE OrderID = @OrderID"; connection.Execute(queryDeleteRegistrations, new { OrderID = order.OrderID }, transaction); var querySubInsert = @"INSERT INTO Registrations (OrderID, BookID, Note) VALUES (@OrderID, @BookID, @Note)"; foreach (var elem in order.Registrations) { connection.Execute(querySubInsert, new { OrderID = order.OrderID, elem.BookID, elem.Note }, transaction); } transaction.Commit(); } catch (Exception ex) { _logger.LogError(ex, "< Error while updating order info >"); throw; } } public void DeleteOrderinfo(int orderID) { _logger.LogInformation("< Deleting exact order >"); _logger.LogDebug("Obj: {id}", orderID); try { using var connection = new NpgsqlConnection(_connectionString.ConnectionString); connection.Open(); using var transaction = connection.BeginTransaction(); // 1. Delete registrations for the order var queryDeleteRegistrations = @"DELETE FROM Registrations WHERE OrderID=@OrderID"; connection.Execute(queryDeleteRegistrations, new { OrderID = orderID }, transaction); // 2. Delete the order itself var queryDel = @"DELETE FROM Orders WHERE OrderID=@OrderID"; connection.Execute(queryDel, new { orderID }, transaction); transaction.Commit(); } catch (Exception ex) { _logger.LogError(ex, "< Error while deleting ORDER >"); throw; } } public IEnumerable<Order> GetOrdersInfo(DateTime? brDate = null, DateTime? tilldate = null, int? cardID = null, int? librnID = null) { _logger.LogInformation("< Getting ORDERS >"); try { var builder = new QueryBuilder(); if (brDate.HasValue) { builder.AddCondition("orders.BorrowDate >= @brDate"); } if (brDate.HasValue) { builder.AddCondition("orders.BorrowDate <= @tilldate"); } if (cardID.HasValue) { builder.AddCondition("orders.CardID = @cardID"); } if (librnID.HasValue) { builder.AddCondition("orders.LibrarianID = @librnID"); } using var connection = new NpgsqlConnection(_connectionString.ConnectionString); connection.Open(); var querySelectAll = @$"SELECT orders.*, lc.FIO as EmployeeName, CONCAT(books.Title, ' ', books.Author) as BookInfo, CONCAT(cc.CardID, ' ', cc.FIO) as ReaderName, regs.BookID, regs.Note FROM Orders orders INNER JOIN LibrarianCards lc ON lc.CardID = orders.LibrarianID INNER JOIN CustomerCards cc ON cc.CardID = orders.CardID INNER JOIN Registrations regs ON regs.OrderID = orders.OrderID LEFT JOIN Books books ON books.BookID = regs.BookID {builder.Build()}"; var regsDict = new Dictionary<int, List<Registration>>(); var orders = connection.Query<Order, Registration, Order>(querySelectAll, (order, orders) => { if (!regsDict.TryGetValue(order.OrderID, out var reg)) { reg = []; regsDict.Add(order.OrderID, reg); } reg.Add(orders); return order; }, splitOn: "BookID"); // params: ... - variables parameters from GetOrdersInfo(...) [ ! ] // unnessessary - [ + ] _logger.LogDebug("Aimed objects: {json}", JsonConvert.SerializeObject(orders)); return regsDict.Select(x => { var odr = orders.First(y => y.OrderID == x.Key); odr.SetRegs(x.Value); return odr; }).ToList(); } catch (Exception ex) { _logger.LogError(ex, "< Error while reading ORDERS >"); throw; } } }