From 3ae7c03f1cbfbfc75192a19a1c5b9e448633fa31 Mon Sep 17 00:00:00 2001 From: xom9k Date: Sat, 26 Apr 2025 11:21:39 +0400 Subject: [PATCH] =?UTF-8?q?feat:=20=D1=81=D1=82=D0=BE=D1=80=D0=B0=D0=B4?= =?UTF-8?q?=D0=B6=20=D0=BA=D0=BE=D0=BD=D1=82=D1=80=D0=B0=D0=BA=D1=82=D1=8B?= =?UTF-8?q?=20=D0=BA=D0=BB=D0=B5=D1=80=D0=BA=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../BankBusinessLogic.csproj | 4 + .../DepositBusinessLogicContract.cs | 2 +- .../IDepositStorageContract.cs | 2 +- .../Implementations/ClientStorageContract.cs | 177 ++++++++++++++++++ .../Implementations/DepositStorageContract.cs | 18 +- .../ReplenishmentStorageContract.cs | 102 ++++++++++ 6 files changed, 289 insertions(+), 16 deletions(-) create mode 100644 TheBank/BankDatabase/Implementations/ClientStorageContract.cs create mode 100644 TheBank/BankDatabase/Implementations/ReplenishmentStorageContract.cs diff --git a/TheBank/BankBusinessLogic/BankBusinessLogic.csproj b/TheBank/BankBusinessLogic/BankBusinessLogic.csproj index 1f4500e..83b7798 100644 --- a/TheBank/BankBusinessLogic/BankBusinessLogic.csproj +++ b/TheBank/BankBusinessLogic/BankBusinessLogic.csproj @@ -6,6 +6,10 @@ enable + + + + diff --git a/TheBank/BankBusinessLogic/Implementations/DepositBusinessLogicContract.cs b/TheBank/BankBusinessLogic/Implementations/DepositBusinessLogicContract.cs index 415572c..af3ee85 100644 --- a/TheBank/BankBusinessLogic/Implementations/DepositBusinessLogicContract.cs +++ b/TheBank/BankBusinessLogic/Implementations/DepositBusinessLogicContract.cs @@ -57,7 +57,7 @@ internal class DepositBusinessLogicContract( return _depositStorageContract.GetElementById(data) ?? throw new ElementNotFoundException($"element not found: {data}"); } - return _depositStorageContract.GetElementByName(data) + return _depositStorageContract.GetElementByInterestRate(data) ?? throw new ElementNotFoundException($"element not found: {data}"); } diff --git a/TheBank/BankContracts/StorageContracts/IDepositStorageContract.cs b/TheBank/BankContracts/StorageContracts/IDepositStorageContract.cs index 827f93d..3719a65 100644 --- a/TheBank/BankContracts/StorageContracts/IDepositStorageContract.cs +++ b/TheBank/BankContracts/StorageContracts/IDepositStorageContract.cs @@ -8,7 +8,7 @@ public interface IDepositStorageContract DepositDataModel? GetElementById(string id); - DepositDataModel? GetElementByName(string name); + DepositDataModel? GetElementByInterestRate(float interestRate); void AddElement(DepositDataModel depositDataModel); diff --git a/TheBank/BankDatabase/Implementations/ClientStorageContract.cs b/TheBank/BankDatabase/Implementations/ClientStorageContract.cs new file mode 100644 index 0000000..ab27779 --- /dev/null +++ b/TheBank/BankDatabase/Implementations/ClientStorageContract.cs @@ -0,0 +1,177 @@ +using AutoMapper; +using BankContracts.DataModels; +using BankContracts.Exceptions; +using BankContracts.StorageContracts; +using BankDatabase.Models; +using Microsoft.EntityFrameworkCore; +using Npgsql; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Xml.Linq; + +namespace BankDatabase.Implementations; + +internal class ClientStorageContract : IClientStorageContract +{ + + private readonly BankDbContext _dbContext; + private readonly Mapper _mapper; + + public ClientStorageContract(BankDbContext dbContext) + { + _dbContext = dbContext; + var config = new MapperConfiguration(cfg => + { + cfg.CreateMap(); + cfg.CreateMap(); + cfg.CreateMap(); + cfg.CreateMap(); + }); + _mapper = new Mapper(config); + } + + public List GetList(string? clerkId = null) + { + try + { + var query = _dbContext.Deposits.Include(x => x.Clerk).AsQueryable(); + if (clerkId is not null) + { + query = query.Where(x => x.ClerkId == clerkId); + } + return [.. query.Select(x => _mapper.Map(x))]; + } + catch (Exception ex) + { + _dbContext.ChangeTracker.Clear(); + throw new StorageException(ex.Message); + } + } + + public ClientDataModel? GetElementById(string id) + { + try + { + return _mapper.Map(_dbContext.Clients.FirstOrDefault(x => x.Id == id)); + } + catch (Exception ex) + { + _dbContext.ChangeTracker.Clear(); + throw new StorageException(ex.Message); + } + } + + public ClientDataModel? GetElementByName(string name) + { + try + { + return _mapper.Map(_dbContext.Clients.Include(x => x.Clerk).FirstOrDefault(x => x.Name == name)); + } + catch (Exception ex) + { + _dbContext.ChangeTracker.Clear(); + throw new StorageException(ex.Message); + } + } + + public ClientDataModel? GetElementBySurname(string surname) + { + try + { + return _mapper.Map(_dbContext.Clients.Include(x => x.Clerk).FirstOrDefault(x => x.Surname == surname)); + } + catch (Exception ex) + { + _dbContext.ChangeTracker.Clear(); + throw new StorageException(ex.Message); + } + } + + public void AddElement(ClientDataModel clientDataModel) + { + try + { + _dbContext.Clients.Add(_mapper.Map(clientDataModel)); + _dbContext.SaveChanges(); + } + catch (InvalidOperationException ex) when (ex.TargetSite?.Name == "ThrowIdentityConflict") + { + _dbContext.ChangeTracker.Clear(); + throw new ElementExistsException($"Id {clientDataModel.Id}"); + } + catch (DbUpdateException ex) when (ex.InnerException is PostgresException { ConstraintName: "IX_Clients_Name" }) + { + _dbContext.ChangeTracker.Clear(); + throw new ElementExistsException($"Name {clientDataModel.Name}"); + } + catch (DbUpdateException ex) when (ex.InnerException is PostgresException { ConstraintName: "IX_Clients_Surname" }) + { + _dbContext.ChangeTracker.Clear(); + throw new ElementExistsException($"Surname {clientDataModel.Surname}"); + } + catch (Exception ex) + { + _dbContext.ChangeTracker.Clear(); + throw new StorageException(ex.Message); + } + } + + public void UpdElement(ClientDataModel clientDataModel) + { + try + { + var transaction = _dbContext.Database.BeginTransaction(); + try + { + var element = GetClientById(clientDataModel.Id) ?? throw new ElementNotFoundException(clientDataModel.Id); + //проверь пожалуйста(не уверен) + if (clientDataModel.Deposits != null && clientDataModel.CreditPrograms != null) + { + if (element.DepositClients != null || element.DepositClients?.Count >= 0) + { + _dbContext.DepositClients.RemoveRange(element.DepositClients); + } + + if (element.CreditProgramClients != null || element.CreditProgramClients?.Count >= 0) + { + _dbContext.DepositClients.RemoveRange(element.DepositClients); + } + + element.DepositClients = _mapper.Map>(clientDataModel.Deposits); + element.DepositClients = _mapper.Map>(clientDataModel.CreditPrograms); + } + _dbContext.SaveChanges(); + transaction.Commit(); + } + catch + { + transaction.Rollback(); + throw; + } + } + catch (ElementNotFoundException) + { + _dbContext.ChangeTracker.Clear(); + throw; + } + catch (DbUpdateException ex) when (ex.InnerException is PostgresException { ConstraintName: "IX_Clients_Name" }) + { + _dbContext.ChangeTracker.Clear(); + throw new ElementExistsException($"Name {clientDataModel.Name}"); + } + catch (DbUpdateException ex) when (ex.InnerException is PostgresException { ConstraintName: "IX_Clients_Surname" }) + { + _dbContext.ChangeTracker.Clear(); + throw new ElementExistsException($"Surname {clientDataModel.Surname}"); + } + catch (Exception ex) + { + _dbContext.ChangeTracker.Clear(); + throw new StorageException(ex.Message); + } + } + private Client? GetClientById(string id) => _dbContext.Clients.FirstOrDefault(x => x.Id == id); +} diff --git a/TheBank/BankDatabase/Implementations/DepositStorageContract.cs b/TheBank/BankDatabase/Implementations/DepositStorageContract.cs index 8e7c7e2..48ab38a 100644 --- a/TheBank/BankDatabase/Implementations/DepositStorageContract.cs +++ b/TheBank/BankDatabase/Implementations/DepositStorageContract.cs @@ -5,11 +5,6 @@ using BankContracts.StorageContracts; using BankDatabase.Models; using Microsoft.EntityFrameworkCore; using Npgsql; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace BankDatabase.Implementations; @@ -114,7 +109,7 @@ internal class DepositStorageContract : IDepositStorageContract _dbContext.DepositCurrencies.RemoveRange(element.DepositCurrencies); } - element.Components = _mapper.Map>(shipDataModel.Components); + element.DepositCurrencies = _mapper.Map>(depositDataModel.Currencies); } _dbContext.SaveChanges(); transaction.Commit(); @@ -130,20 +125,15 @@ internal class DepositStorageContract : IDepositStorageContract _dbContext.ChangeTracker.Clear(); throw; } - catch (DbUpdateException ex) when (ex.InnerException is PostgresException { ConstraintName: "IX_Ships_Name" }) + catch (DbUpdateException ex) when (ex.InnerException is PostgresException { ConstraintName: "IX_Deposits_InterestRate" }) { _dbContext.ChangeTracker.Clear(); - throw new ElementExistsException("Name", shipDataModel.Name); - } - catch (Exception ex) when (ex is ElementDeletedException || ex is ElementNotFoundException) - { - _dbContext.ChangeTracker.Clear(); - throw; + throw new ElementExistsException($"InterestRate {depositDataModel.InterestRate}"); } catch (Exception ex) { _dbContext.ChangeTracker.Clear(); - throw new StorageException(ex); + throw new StorageException(ex.Message); } } diff --git a/TheBank/BankDatabase/Implementations/ReplenishmentStorageContract.cs b/TheBank/BankDatabase/Implementations/ReplenishmentStorageContract.cs new file mode 100644 index 0000000..0a1991a --- /dev/null +++ b/TheBank/BankDatabase/Implementations/ReplenishmentStorageContract.cs @@ -0,0 +1,102 @@ +using AutoMapper; +using BankContracts.DataModels; +using BankContracts.Exceptions; +using BankContracts.StorageContracts; +using BankDatabase.Models; +using Microsoft.EntityFrameworkCore; +using Npgsql; + +namespace BankDatabase.Implementations; + +internal class ReplenishmentStorageContract : IReplenishmentStorageContract +{ + private readonly BankDbContext _dbContext; + private readonly Mapper _mapper; + + public ReplenishmentStorageContract(BankDbContext dbContext) + { + _dbContext = dbContext; + var config = new MapperConfiguration(cfg => + { + cfg.CreateMap(); + cfg.CreateMap(); + }); + _mapper = new Mapper(config); + } + + public List GetList(DateTime? fromDate = null, DateTime? toDate = null, string? clerkId = null, string? depositId = null) + { + try + { + var query = _dbContext.Replenishments.Where(x => x.Date >= fromDate && x.Date <= toDate); + if (clerkId is not null) + { + query = query.Where(x => x.ClerkId == clerkId); + } + if (depositId is not null) + { + query = query.Where(x => x.DepositId == depositId); + } + return [.. query.Select(x => _mapper.Map(x))]; + } + catch (Exception ex) + { + _dbContext.ChangeTracker.Clear(); + throw new StorageException(ex.Message); + } + } + + public ReplenishmentDataModel? GetElementById(string id) + { + try + { + return _mapper.Map(_dbContext.Replenishments.FirstOrDefault(x => x.Id == id)); + } + catch (Exception ex) + { + _dbContext.ChangeTracker.Clear(); + throw new StorageException(ex.Message); + } + } + + + public void AddElement(ReplenishmentDataModel replenishmentDataModel) + { + try + { + _dbContext.Replenishments.Add(_mapper.Map(replenishmentDataModel)); + _dbContext.SaveChanges(); + } + catch (InvalidOperationException ex) when (ex.TargetSite?.Name == "ThrowIdentityConflict") + { + _dbContext.ChangeTracker.Clear(); + throw new ElementExistsException($"Id {replenishmentDataModel.Id}"); + } + catch (Exception ex) + { + _dbContext.ChangeTracker.Clear(); + throw new StorageException(ex.Message); + } + } + + public void UpdElement(ReplenishmentDataModel replenishmentDataModel) + { + try + { + var element = GetReplenishmentById(replenishmentDataModel.Id) ?? throw new ElementNotFoundException(replenishmentDataModel.Id); + _dbContext.Replenishments.Update(_mapper.Map(replenishmentDataModel, element)); + _dbContext.SaveChanges(); + } + catch (ElementNotFoundException) + { + _dbContext.ChangeTracker.Clear(); + throw; + } + catch (Exception ex) + { + _dbContext.ChangeTracker.Clear(); + throw new StorageException(ex.Message); + } + } + private Replenishment? GetReplenishmentById(string id) => _dbContext.Replenishments.FirstOrDefault(x => x.Id == id); +}