Контракты

This commit is contained in:
rakhaliullov 2025-03-11 00:13:19 +04:00
parent 48bdafeae4
commit 24b6a866dc
9 changed files with 802 additions and 12 deletions

View File

@ -1,12 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SoftBedContracts.Enums
{
internal class MaterialType
{
}
}

View File

@ -0,0 +1,6 @@
namespace SoftBedContracts.Exceptions;
public class ElementDeletedException : Exception
{
public ElementDeletedException(string id) : base($"Cannot modify a deleted item (id: {id})") { }
}

View File

@ -0,0 +1,98 @@
using AutoMapper;
using SoftBedContracts.DataModels;
using SoftBedContracts.Exceptions;
using SoftBedDatabase;
using SoftBedDatabase.Models;
namespace SoftBedContracts.StoragesContracts;
internal class CollectStorageContract : ICollectStorageContract
{
private readonly SoftBedDbContext _dbContext;
private readonly Mapper _mapper;
public CollectStorageContract(SoftBedDbContext dbContext)
{
_dbContext = dbContext;
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<Collect, CollectDataModel>();
cfg.CreateMap<CollectDataModel, Collect>();
});
_mapper = new Mapper(config);
}
public List<CollectDataModel> GetList(DateTime? startDate = null, DateTime? endDate = null, string? workerId = null, string? furnitureId = null)
{
try
{
var query = _dbContext.Collects.AsQueryable();
if (startDate is not null && endDate is not null)
{
query = query.Where(x => x.SaleDate >= startDate && x.SaleDate < endDate);
}
if (workerId is not null)
{
query = query.Where(x => x.WorkerId == workerId);
}
if (furnitureId is not null)
{
query = query.Where(x => x.FurnitureId == furnitureId);
}
return [.. query.Select(x => _mapper.Map<CollectDataModel>(x))];
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex);
}
}
public CollectDataModel? GetElementById(string id)
{
try
{
return _mapper.Map<CollectDataModel>(GetCollectById(id));
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex);
}
}
public void AddElement(CollectDataModel collectDataModel)
{
try
{
_dbContext.Collects.Add(_mapper.Map<Collect>(collectDataModel));
_dbContext.SaveChanges();
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex);
}
}
public void DelElement(string id)
{
try
{
var element = GetCollectById(id) ?? throw new ElementNotFoundException(id);
_dbContext.SaveChanges();
}
catch (Exception ex) when (ex is ElementDeletedException || ex is ElementNotFoundException)
{
_dbContext.ChangeTracker.Clear();
throw;
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex);
}
}
private Collect? GetCollectById(string id) => _dbContext.Collects.FirstOrDefault(x => x.Id == id);
}

View File

@ -0,0 +1,176 @@
using AutoMapper;
using Microsoft.EntityFrameworkCore;
using Npgsql;
using SoftBedContracts.DataModels;
using SoftBedContracts.Exceptions;
using SoftBedContracts.StoragesContracts;
using SoftBedDatabase.Models;
namespace SoftBedDatabase.Implementations;
internal class FurnitureStorageContract : IFurnitureStorageContract
{
private readonly SoftBedDbContext _dbContext;
private readonly Mapper _mapper;
public FurnitureStorageContract(SoftBedDbContext dbContext)
{
_dbContext = dbContext;
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<Furniture, FurnitureDataModel>();
cfg.CreateMap<FurnitureDataModel, Furniture>()
.ForMember(x => x.IsDeleted, x => x.MapFrom(src => false))
.ForMember(x => x.FurnitureWorkPieces, x => x.MapFrom(src => src.WorkPieces));
cfg.CreateMap<FurnitureHistory, FurnitureHistoryDataModel>();
});
_mapper = new Mapper(config);
}
public List<FurnitureDataModel> GetList(bool onlyActive = true, string workPieceId = null)
{
try
{
var query = _dbContext.Furnitures.Include(x => x.FurnitureWorkPieces).AsQueryable();
if (onlyActive)
{
query = query.Where(x => !x.IsDeleted);
}
if (workPieceId is not null)
{
query = query.Where(x => x.FurnitureWorkPieces!.Any(y => y.WorkPieceId == workPieceId));
}
return [.. query.Select(x => _mapper.Map<FurnitureDataModel>(x))];
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex);
}
}
public List<FurnitureHistoryDataModel> GetHistoryByFurnitureId(string furnitureId)
{
try
{
return [.. _dbContext.FurnitureHistories.Where(x => x.FurnitureId == furnitureId).OrderByDescending(x => x.ChangeDate).Select(x => _mapper.Map<FurnitureHistoryDataModel>(x))];
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex);
}
}
public FurnitureDataModel? GetElementById(string id)
{
try
{
return _mapper.Map<FurnitureDataModel>(GetFurnitureById(id));
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex);
}
}
public FurnitureDataModel? GetElementByName(string name)
{
try
{
return _mapper.Map<FurnitureDataModel>(_dbContext.Furnitures.FirstOrDefault(x => x.FurnitureName == name && !x.IsDeleted));
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex);
}
}
public void AddElement(FurnitureDataModel furnitureDataModel)
{
try
{
_dbContext.Furnitures.Add(_mapper.Map<Furniture>(furnitureDataModel));
_dbContext.SaveChanges();
}
catch (InvalidOperationException ex) when (ex.TargetSite?.Name == "ThrowIdentityConflict")
{
_dbContext.ChangeTracker.Clear();
throw new ElementExistsException("Id", furnitureDataModel.Id);
}
catch (DbUpdateException ex) when (ex.InnerException is PostgresException { ConstraintName: "IX_Furnitures_FurnitureName_IsDeleted" })
{
_dbContext.ChangeTracker.Clear();
throw new ElementExistsException("FurnitureName", furnitureDataModel.FurnitureName);
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex);
}
}
public void UpdElement(FurnitureDataModel furnitureDataModel)
{
try
{
var transaction = _dbContext.Database.BeginTransaction();
try
{
var element = GetFurnitureById(furnitureDataModel.Id) ?? throw new ElementNotFoundException(furnitureDataModel.Id);
if (element.Price != furnitureDataModel.Price)
{
_dbContext.FurnitureHistories.Add(new FurnitureHistory() { FurnitureId = element.Id, OldPrice = element.Price });
_dbContext.SaveChanges();
}
_dbContext.Furnitures.Update(_mapper.Map(furnitureDataModel, element));
_dbContext.SaveChanges();
transaction.Commit();
}
catch
{
transaction.Rollback();
throw;
}
}
catch (DbUpdateException ex) when (ex.InnerException is PostgresException { ConstraintName: "IX_Furnitures_FurnitureName_IsDeleted" })
{
_dbContext.ChangeTracker.Clear();
throw new ElementExistsException("FurnitureName", furnitureDataModel.FurnitureName);
}
catch (Exception ex) when (ex is ElementDeletedException || ex is ElementNotFoundException)
{
_dbContext.ChangeTracker.Clear();
throw;
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex);
}
}
public void DelElement(string id)
{
try
{
var element = GetFurnitureById(id) ?? throw new ElementNotFoundException(id);
element.IsDeleted = true;
_dbContext.SaveChanges();
}
catch (ElementNotFoundException ex)
{
_dbContext.ChangeTracker.Clear();
throw;
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex);
}
}
private Furniture? GetFurnitureById(string id) => _dbContext.Furnitures.FirstOrDefault(x => x.Id == id && !x.IsDeleted);
}

View File

@ -0,0 +1,190 @@
using AutoMapper;
using Microsoft.EntityFrameworkCore;
using Npgsql;
using SoftBedContracts.DataModels;
using SoftBedContracts.Exceptions;
using SoftBedContracts.StoragesContracts;
using SoftBedDatabase.Models;
namespace SoftBedDatabase.Implementations;
internal class PostStorageContract : IPostStorageContract
{
private readonly SoftBedDbContext _dbContext;
private readonly Mapper _mapper;
public PostStorageContract(SoftBedDbContext dbContext)
{
_dbContext = dbContext;
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<Post, PostDataModel>()
.ForMember(x => x.Id, x => x.MapFrom(src => src.PostId));
cfg.CreateMap<PostDataModel, Post>()
.ForMember(x => x.Id, x => x.Ignore())
.ForMember(x => x.PostId, x => x.MapFrom(src => src.Id))
.ForMember(x => x.IsActual, x => x.MapFrom(src => true))
.ForMember(x => x.ChangeDate, x => x.MapFrom(src => DateTime.UtcNow));
});
_mapper = new Mapper(config);
}
public List<PostDataModel> GetList(bool onlyActual = true)
{
try
{
var query = _dbContext.Posts.AsQueryable();
if (onlyActual)
{
query = query.Where(x => x.IsActual);
}
return [.. query.Select(x => _mapper.Map<PostDataModel>(x))];
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex);
}
}
public List<PostDataModel> GetPostWithHistory(string postId)
{
try
{
return [.. _dbContext.Posts.Where(x => x.PostId == postId).Select(x => _mapper.Map<PostDataModel>(x))];
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex);
}
}
public PostDataModel? GetElementById(string id)
{
try
{
return _mapper.Map<PostDataModel>(_dbContext.Posts.FirstOrDefault(x => x.PostId == id && x.IsActual));
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex);
}
}
public PostDataModel? GetElementByName(string name)
{
try
{
return _mapper.Map<PostDataModel>(_dbContext.Posts.FirstOrDefault(x => x.PostName == name && x.IsActual));
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex);
}
}
public void AddElement(PostDataModel postDataModel)
{
try
{
_dbContext.Posts.Add(_mapper.Map<Post>(postDataModel));
_dbContext.SaveChanges();
}
catch (DbUpdateException ex) when (ex.InnerException is PostgresException { ConstraintName: "IX_Posts_PostName_IsActual" })
{
_dbContext.ChangeTracker.Clear();
throw new ElementExistsException("PostName", postDataModel.PostName);
}
catch (DbUpdateException ex) when (ex.InnerException is PostgresException { ConstraintName: "IX_Posts_PostId_IsActual" })
{
_dbContext.ChangeTracker.Clear();
throw new ElementExistsException("PostId", postDataModel.Id);
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex);
}
}
public void UpdElement(PostDataModel postDataModel)
{
try
{
var transaction = _dbContext.Database.BeginTransaction();
try
{
var element = GetPostById(postDataModel.Id) ?? throw new ElementNotFoundException(postDataModel.Id);
if (!element.IsActual)
{
throw new ElementDeletedException(postDataModel.Id);
}
element.IsActual = false;
_dbContext.SaveChanges();
var newElement = _mapper.Map<Post>(postDataModel);
_dbContext.Posts.Add(newElement);
_dbContext.SaveChanges();
transaction.Commit();
}
catch
{
transaction.Rollback();
throw;
}
}
catch (DbUpdateException ex) when (ex.InnerException is PostgresException { ConstraintName: "IX_Posts_PostName_IsActual" })
{
_dbContext.ChangeTracker.Clear();
throw new ElementExistsException("PostName", postDataModel.PostName);
}
catch (Exception ex) when (ex is ElementDeletedException || ex is ElementNotFoundException)
{
_dbContext.ChangeTracker.Clear();
throw;
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex);
}
}
public void DelElement(string id)
{
try
{
var element = GetPostById(id) ?? throw new ElementNotFoundException(id);
if (!element.IsActual)
{
throw new ElementDeletedException(id);
}
element.IsActual = false;
_dbContext.SaveChanges();
}
catch
{
_dbContext.ChangeTracker.Clear();
throw;
}
}
public void ResElement(string id)
{
try
{
var element = GetPostById(id) ?? throw new ElementNotFoundException(id);
element.IsActual = true;
_dbContext.SaveChanges();
}
catch
{
_dbContext.ChangeTracker.Clear();
throw;
}
}
private Post? GetPostById(string id) => _dbContext.Posts.Where(x => x.PostId == id).OrderByDescending(x => x.ChangeDate).FirstOrDefault();
}

View File

@ -0,0 +1,57 @@
using AutoMapper;
using SoftBedContracts.DataModels;
using SoftBedContracts.Exceptions;
using SoftBedContracts.StoragesContracts;
using SoftBedDatabase.Models;
namespace SoftBedDatabase.Implementations;
internal class SalaryStorageContract : ISalaryStorageContract
{
private readonly SoftBedDbContext _dbContext;
private readonly Mapper _mapper;
public SalaryStorageContract(SoftBedDbContext dbContext)
{
_dbContext = dbContext;
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<Salary, SalaryDataModel>();
cfg.CreateMap<SalaryDataModel, Salary>()
.ForMember(dest => dest.WorkerSalary, opt => opt.MapFrom(src => src.Salary));
});
_mapper = new Mapper(config);
}
public List<SalaryDataModel> GetList(DateTime startDate, DateTime endDate, string? workerId = null)
{
try
{
var query = _dbContext.Salaries.Where(x => x.SalaryDate >= startDate && x.SalaryDate <= endDate);
if (workerId is not null)
{
query = query.Where(x => x.WorkerId == workerId);
}
return [.. query.Select(x => _mapper.Map<SalaryDataModel>(x))];
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex);
}
}
public void AddElement(SalaryDataModel salaryDataModel)
{
try
{
_dbContext.Salaries.Add(_mapper.Map<Salary>(salaryDataModel));
_dbContext.SaveChanges();
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex);
}
}
}

View File

@ -0,0 +1,137 @@
using AutoMapper;
using Microsoft.EntityFrameworkCore;
using Npgsql;
using SoftBedContracts.DataModels;
using SoftBedContracts.Exceptions;
using SoftBedContracts.StoragesContracts;
using SoftBedDatabase.Models;
using System;
namespace SoftBedDatabase.Implementations;
internal class WorkPieceStorageContract : IWorkPieceStorageContract
{
private readonly SoftBedDbContext _dbContext;
private readonly Mapper _mapper;
public WorkPieceStorageContract(SoftBedDbContext dbContext)
{
_dbContext = dbContext;
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<WorkPiece, WorkPieceDataModel>();
cfg.CreateMap<WorkPieceDataModel, WorkPiece>();
});
_mapper = new Mapper(config);
}
public List<WorkPieceDataModel> GetList()
{
try
{
return [.. _dbContext.WorkPieces.Select(x => _mapper.Map<WorkPieceDataModel>(x))];
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex);
}
}
public WorkPieceDataModel? GetElementById(string id)
{
try
{
return _mapper.Map<WorkPieceDataModel>(GetWorkPieceById(id));
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex);
}
}
public WorkPieceDataModel? GetElementBySize(string size)
{
try
{
return _mapper.Map<WorkPieceDataModel>(_dbContext.WorkPieces.FirstOrDefault(x => x.Size == size));
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex);
}
}
public void AddElement(WorkPieceDataModel workPieceDataModel)
{
try
{
_dbContext.WorkPieces.Add(_mapper.Map<WorkPiece>(workPieceDataModel));
_dbContext.SaveChanges();
}
catch (InvalidOperationException ex) when (ex.TargetSite?.Name == "ThrowIdentityConflict")
{
_dbContext.ChangeTracker.Clear();
throw new ElementExistsException("Id", workPieceDataModel.Id);
}
catch (DbUpdateException ex) when (ex.InnerException is PostgresException { ConstraintName: "IX_WorkPieces_Size" })
{
_dbContext.ChangeTracker.Clear();
throw new ElementExistsException("Size", workPieceDataModel.Size);
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex);
}
}
public void UpdElement(WorkPieceDataModel workPieceDataModel)
{
try
{
var element = GetWorkPieceById(workPieceDataModel.Id) ?? throw new ElementNotFoundException(workPieceDataModel.Id);
_dbContext.WorkPieces.Update(_mapper.Map(workPieceDataModel, element));
_dbContext.SaveChanges();
}
catch (ElementNotFoundException)
{
_dbContext.ChangeTracker.Clear();
throw;
}
catch (DbUpdateException ex) when (ex.InnerException is PostgresException { ConstraintName: "IX_WorkPieces_Size" })
{
_dbContext.ChangeTracker.Clear();
throw new ElementExistsException("Size", workPieceDataModel.Size);
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex);
}
}
public void DelElement(string id)
{
try
{
var element = GetWorkPieceById(id) ?? throw new ElementNotFoundException(id);
_dbContext.WorkPieces.Remove(element);
_dbContext.SaveChanges();
}
catch (ElementNotFoundException)
{
_dbContext.ChangeTracker.Clear();
throw;
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex);
}
}
private WorkPiece? GetWorkPieceById(string id) => _dbContext.WorkPieces.FirstOrDefault(x => x.Id == id);
}

View File

@ -0,0 +1,137 @@
using AutoMapper;
using SoftBedContracts.DataModels;
using SoftBedContracts.Exceptions;
using SoftBedContracts.StoragesContracts;
using SoftBedDatabase.Models;
namespace SoftBedDatabase.Implementations;
internal class WorkerStorageContract : IWorkerStorageContract
{
private readonly SoftBedDbContext _dbContext;
private readonly Mapper _mapper;
public WorkerStorageContract(SoftBedDbContext dbContext)
{
_dbContext = dbContext;
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<Worker, WorkerDataModel>();
cfg.CreateMap<WorkerDataModel, Worker>();
});
_mapper = new Mapper(config);
}
public List<WorkerDataModel> GetList(string? postId = null, DateTime? fromBirthDate = null, DateTime? toBirthDate = null, DateTime? fromEmploymentDate = null, DateTime? toEmploymentDate = null)
{
try
{
var query = _dbContext.Workers.AsQueryable();
if (postId is not null)
{
query = query.Where(x => x.PostId == postId);
}
if (fromBirthDate is not null && toBirthDate is not null)
{
query = query.Where(x => x.BirthDate >= fromBirthDate && x.BirthDate <= toBirthDate);
}
if (fromEmploymentDate is not null && toEmploymentDate is not null)
{
query = query.Where(x => x.EmploymentDate >= fromEmploymentDate && x.EmploymentDate <= toEmploymentDate);
}
return [.. query.Select(x => _mapper.Map<WorkerDataModel>(x))];
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex);
}
}
public WorkerDataModel? GetElementById(string id)
{
try
{
return _mapper.Map<WorkerDataModel>(GetWorkerById(id));
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex);
}
}
public WorkerDataModel? GetElementByFIO(string fio)
{
try
{
return _mapper.Map<WorkerDataModel>(_dbContext.Workers.FirstOrDefault(x => x.FIO == fio));
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex);
}
}
public void AddElement(WorkerDataModel workerDataModel)
{
try
{
_dbContext.Workers.Add(_mapper.Map<Worker>(workerDataModel));
_dbContext.SaveChanges();
}
catch (InvalidOperationException ex) when (ex.TargetSite?.Name == "ThrowIdentityConflict")
{
_dbContext.ChangeTracker.Clear();
throw new ElementExistsException("Id", workerDataModel.Id);
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex);
}
}
public void UpdElement(WorkerDataModel workerDataModel)
{
try
{
var element = GetWorkerById(workerDataModel.Id) ?? throw new ElementNotFoundException(workerDataModel.Id);
_dbContext.Workers.Update(_mapper.Map(workerDataModel, element));
_dbContext.SaveChanges();
}
catch (ElementNotFoundException)
{
_dbContext.ChangeTracker.Clear();
throw;
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex);
}
}
public void DelElement(string id)
{
try
{
var element = GetWorkerById(id) ?? throw new ElementNotFoundException(id);
element.IsDeleted = true;
_dbContext.SaveChanges();
}
catch (ElementNotFoundException)
{
_dbContext.ChangeTracker.Clear();
throw;
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex);
}
}
private Worker? GetWorkerById(string id) => _dbContext.Workers.FirstOrDefault(x => x.Id == id && !x.IsDeleted);
}

View File

@ -7,6 +7,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="AutoMapper" Version="14.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="9.0.2" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="9.0.4" />
</ItemGroup>