using AutoMapper; using CandyHouseBase.DataModels; using CandyHouseBase.Exceptions; using CandyHouseBase.Interfaces.StoragesContracts; using CandyHouseDataBase.Models; using Microsoft.EntityFrameworkCore; using Npgsql; using System.Collections.Generic; namespace CandyHouseDataBase.Implementations; internal class OrderStorageContract : IOrderStorageContact { private readonly CandyHouseDbContext _dbContext; private readonly Mapper _mapper; public OrderStorageContract(CandyHouseDbContext dbContext) { _dbContext = dbContext ?? throw new ArgumentNullException(nameof(dbContext)); var config = new MapperConfiguration(cfg => { cfg.CreateMap() .ForMember(dest => dest.Id, opt => opt.MapFrom(src => src.Id)) .ForMember(dest => dest.CustomerName, opt => opt.MapFrom(src => src.CustomerName)) .ForMember(dest => dest.OrderDate, opt => opt.MapFrom(src => src.OrderDate)) .ForMember(dest => dest.TotalAmount, opt => opt.MapFrom(src => src.TotalAmount)) .ForMember(dest => dest.DiscountAmount, opt => opt.MapFrom(src => src.DiscountAmount)) .ForMember(dest => dest.ProductId, opt => opt.MapFrom(src => src.ProductId)) .ForMember(dest => dest.PekarId, opt => opt.MapFrom(src => src.PekarId)) .ForMember(dest => dest.StatusType, opt => opt.MapFrom(src => src.StatusType)); cfg.CreateMap() .ForMember(dest => dest.Id, opt => opt.MapFrom(src => src.Id)) .ForMember(dest => dest.CustomerName, opt => opt.MapFrom(src => src.CustomerName)) .ForMember(dest => dest.OrderDate, opt => opt.MapFrom(src => src.OrderDate)) .ForMember(dest => dest.TotalAmount, opt => opt.MapFrom(src => src.TotalAmount)) .ForMember(dest => dest.DiscountAmount, opt => opt.MapFrom(src => src.DiscountAmount)) .ForMember(dest => dest.ProductId, opt => opt.MapFrom(src => src.ProductId)) .ForMember(dest => dest.PekarId, opt => opt.MapFrom(src => src.PekarId)) .ForMember(dest => dest.StatusType, opt => opt.MapFrom(src => src.StatusType)); }); _mapper = new Mapper(config); } public List GetOrders() { try { return _dbContext.Orders .Select(x => _mapper.Map(x)) .ToList(); } catch (Exception ex) { _dbContext.ChangeTracker.Clear(); throw new StorageException(ex); } } public void AddElement(OrderDataModel order) { try { order.Validate(); var entity = _mapper.Map(order); _dbContext.Orders.Add(entity); _dbContext.SaveChanges(); } catch (ValidationException ex) { _dbContext.ChangeTracker.Clear(); throw; } catch (DbUpdateException ex) when (ex.InnerException is PostgresException { ConstraintName: "IX_Orders_PekarId_OrderDate" }) { _dbContext.ChangeTracker.Clear(); throw new ElementExistsException("OrderDate", order.OrderDate.ToString()); } catch (Exception ex) { _dbContext.ChangeTracker.Clear(); throw new StorageException(ex); } } public void UpdateElement(OrderDataModel order) { try { order.Validate(); var entity = GetOrderById(order.Id) ?? throw new ElementNotFoundException(order.Id); _dbContext.Orders.Update(_mapper.Map(order, entity)); _dbContext.SaveChanges(); } catch (ValidationException ex) { _dbContext.ChangeTracker.Clear(); throw; } catch (ElementNotFoundException) { _dbContext.ChangeTracker.Clear(); throw; } catch (DbUpdateException ex) when (ex.InnerException is PostgresException { ConstraintName: "IX_Orders_PekarId_OrderDate" }) { _dbContext.ChangeTracker.Clear(); throw new ElementExistsException("OrderDate", order.OrderDate.ToString()); } catch (Exception ex) { _dbContext.ChangeTracker.Clear(); throw new StorageException(ex); } } public void DeleteElement(OrderDataModel order) { try { var entity = GetOrderById(order.Id) ?? throw new ElementNotFoundException(order.Id); _dbContext.Orders.Remove(entity); _dbContext.SaveChanges(); } catch (ElementNotFoundException) { _dbContext.ChangeTracker.Clear(); throw; } catch (Exception ex) { _dbContext.ChangeTracker.Clear(); throw new StorageException(ex); } } public OrderDataModel GetElementById(string orderId) { try { var entity = GetOrderById(orderId) ?? throw new ElementNotFoundException(orderId); return _mapper.Map(entity); } catch (Exception ex) { _dbContext.ChangeTracker.Clear(); throw new StorageException(ex); } } private Order? GetOrderById(string id) => _dbContext.Orders.FirstOrDefault(x => x.Id == id); }