From c21c01c4322eb3db4bcf90d4e24873b4e7bf873f Mon Sep 17 00:00:00 2001 From: lumijiez <59575049+lumijiez@users.noreply.github.com> Date: Wed, 25 Jun 2025 22:34:39 +0300 Subject: [PATCH] Add Order/Address/OrderAddress repos, and handlers --- .../Addresses/CreateAddressHandler.cs | 52 +++++++++++++ .../Addresses/GetAddressByIdHandler.cs | 31 ++++++++ .../Addresses/GetAddressesByUserIdHandler.cs | 36 +++++++++ .../Commands/Orders/CreateOrderHandler.cs | 77 +++++++++++++++++++ .../Commands/Orders/GetOrderByIdHandler.cs | 31 ++++++++ .../Orders/GetOrdersByMerchantIdHandler.cs | 31 ++++++++ .../Orders/GetOrdersByUserIdHandler.cs | 31 ++++++++ src/Imprink.Application/Dtos/AddressDto.cs | 26 +++++++ .../Dtos/OrderAddressDto.cs | 24 ++++++ src/Imprink.Application/Dtos/OrderDto.cs | 30 ++++++++ .../Dtos/OrderStatusDto.cs | 8 ++ .../Dtos/ShippingStatusDto.cs | 8 ++ src/Imprink.Application/IUnitOfWork.cs | 1 + .../Imprink.Application.csproj | 4 - .../Repositories/IOrderAddressRepository.cs | 16 ++++ .../Database/ApplicationDbContext.cs | 2 +- .../Repositories/OrderAddressRepository.cs | 77 +++++++++++++++++++ src/Imprink.Infrastructure/UnitOfWork.cs | 4 +- .../StartupApplicationExtensions.cs | 1 + 19 files changed, 484 insertions(+), 6 deletions(-) create mode 100644 src/Imprink.Application/Commands/Addresses/CreateAddressHandler.cs create mode 100644 src/Imprink.Application/Commands/Addresses/GetAddressByIdHandler.cs create mode 100644 src/Imprink.Application/Commands/Addresses/GetAddressesByUserIdHandler.cs create mode 100644 src/Imprink.Application/Commands/Orders/CreateOrderHandler.cs create mode 100644 src/Imprink.Application/Commands/Orders/GetOrderByIdHandler.cs create mode 100644 src/Imprink.Application/Commands/Orders/GetOrdersByMerchantIdHandler.cs create mode 100644 src/Imprink.Application/Commands/Orders/GetOrdersByUserIdHandler.cs create mode 100644 src/Imprink.Application/Dtos/AddressDto.cs create mode 100644 src/Imprink.Application/Dtos/OrderAddressDto.cs create mode 100644 src/Imprink.Application/Dtos/OrderDto.cs create mode 100644 src/Imprink.Application/Dtos/OrderStatusDto.cs create mode 100644 src/Imprink.Application/Dtos/ShippingStatusDto.cs create mode 100644 src/Imprink.Domain/Repositories/IOrderAddressRepository.cs create mode 100644 src/Imprink.Infrastructure/Repositories/OrderAddressRepository.cs diff --git a/src/Imprink.Application/Commands/Addresses/CreateAddressHandler.cs b/src/Imprink.Application/Commands/Addresses/CreateAddressHandler.cs new file mode 100644 index 0000000..5d8da24 --- /dev/null +++ b/src/Imprink.Application/Commands/Addresses/CreateAddressHandler.cs @@ -0,0 +1,52 @@ +using AutoMapper; +using Imprink.Application.Dtos; +using Imprink.Domain.Entities; +using MediatR; + +namespace Imprink.Application.Commands.Addresses; + +public class CreateAddressCommand : IRequest +{ + public string UserId { get; set; } = null!; + public string AddressType { get; set; } = null!; + public string? FirstName { get; set; } + public string? LastName { get; set; } + public string? Company { get; set; } + public string AddressLine1 { get; set; } = null!; + public string? AddressLine2 { get; set; } + public string? ApartmentNumber { get; set; } + public string? BuildingNumber { get; set; } + public string? Floor { get; set; } + public string City { get; set; } = null!; + public string State { get; set; } = null!; + public string PostalCode { get; set; } = null!; + public string Country { get; set; } = null!; + public string? PhoneNumber { get; set; } + public string? Instructions { get; set; } + public bool IsDefault { get; set; } + public bool IsActive { get; set; } = true; +} + +public class CreateAddressHandler(IUnitOfWork uw, IMapper mapper) : IRequestHandler +{ + public async Task Handle(CreateAddressCommand request, CancellationToken cancellationToken) + { + return await uw.TransactAsync(async () => + { + var address = mapper.Map
(request); + + if (address.IsDefault) + { + var currentDefault = await uw.AddressRepository.GetDefaultByUserIdAsync(address.UserId, cancellationToken); + if (currentDefault != null) + { + currentDefault.IsDefault = false; + await uw.AddressRepository.UpdateAsync(currentDefault, cancellationToken); + } + } + + var createdAddress = await uw.AddressRepository.AddAsync(address, cancellationToken); + return mapper.Map(createdAddress); + }, cancellationToken); + } +} \ No newline at end of file diff --git a/src/Imprink.Application/Commands/Addresses/GetAddressByIdHandler.cs b/src/Imprink.Application/Commands/Addresses/GetAddressByIdHandler.cs new file mode 100644 index 0000000..3d14552 --- /dev/null +++ b/src/Imprink.Application/Commands/Addresses/GetAddressByIdHandler.cs @@ -0,0 +1,31 @@ +using AutoMapper; +using Imprink.Application.Dtos; +using Imprink.Domain.Entities; +using MediatR; + +namespace Imprink.Application.Commands.Addresses; + +public class GetAddressByIdQuery : IRequest +{ + public Guid Id { get; set; } + public string? UserId { get; set; } +} + +public class GetAddressByIdHandler(IUnitOfWork uw, IMapper mapper) : IRequestHandler +{ + public async Task Handle(GetAddressByIdQuery request, CancellationToken cancellationToken) + { + Address? address; + + if (!string.IsNullOrEmpty(request.UserId)) + { + address = await uw.AddressRepository.GetByIdAndUserIdAsync(request.Id, request.UserId, cancellationToken); + } + else + { + address = await uw.AddressRepository.GetByIdAsync(request.Id, cancellationToken); + } + + return address != null ? mapper.Map(address) : null; + } +} \ No newline at end of file diff --git a/src/Imprink.Application/Commands/Addresses/GetAddressesByUserIdHandler.cs b/src/Imprink.Application/Commands/Addresses/GetAddressesByUserIdHandler.cs new file mode 100644 index 0000000..9d151cc --- /dev/null +++ b/src/Imprink.Application/Commands/Addresses/GetAddressesByUserIdHandler.cs @@ -0,0 +1,36 @@ +using AutoMapper; +using Imprink.Application.Dtos; +using Imprink.Domain.Entities; +using MediatR; + +namespace Imprink.Application.Commands.Addresses; + +public class GetAddressesByUserIdQuery : IRequest> +{ + public string UserId { get; set; } = null!; + public bool ActiveOnly { get; set; } = false; + public string? AddressType { get; set; } +} + +public class GetAddressesByUserIdHandler(IUnitOfWork uw, IMapper mapper) : IRequestHandler> +{ + public async Task> Handle(GetAddressesByUserIdQuery request, CancellationToken cancellationToken) + { + IEnumerable
addresses; + + if (!string.IsNullOrEmpty(request.AddressType)) + { + addresses = await uw.AddressRepository.GetByUserIdAndTypeAsync(request.UserId, request.AddressType, cancellationToken); + } + else if (request.ActiveOnly) + { + addresses = await uw.AddressRepository.GetActiveByUserIdAsync(request.UserId, cancellationToken); + } + else + { + addresses = await uw.AddressRepository.GetByUserIdAsync(request.UserId, cancellationToken); + } + + return mapper.Map>(addresses); + } +} diff --git a/src/Imprink.Application/Commands/Orders/CreateOrderHandler.cs b/src/Imprink.Application/Commands/Orders/CreateOrderHandler.cs new file mode 100644 index 0000000..ac9a59c --- /dev/null +++ b/src/Imprink.Application/Commands/Orders/CreateOrderHandler.cs @@ -0,0 +1,77 @@ +using AutoMapper; +using Imprink.Application.Dtos; +using Imprink.Domain.Entities; +using MediatR; + +namespace Imprink.Application.Commands.Orders; + +public class CreateOrderCommand : IRequest +{ + public string UserId { get; set; } = null!; + public decimal Amount { get; set; } + public int Quantity { get; set; } + public Guid ProductId { get; set; } + public Guid? ProductVariantId { get; set; } + public string? Notes { get; set; } + public string? MerchantId { get; set; } + public string? ComposingImageUrl { get; set; } + public string[] OriginalImageUrls { get; set; } = []; + public string CustomizationImageUrl { get; set; } = null!; + public string CustomizationDescription { get; set; } = null!; + + public Guid AddressId { get; set; } +} + +public class CreateOrderHandler(IUnitOfWork uw, IMapper mapper) : IRequestHandler +{ + public async Task Handle(CreateOrderCommand request, CancellationToken cancellationToken) + { + return await uw.TransactAsync(async () => + { + var sourceAddress = await uw.AddressRepository.GetByIdAndUserIdAsync(request.AddressId, request.UserId, cancellationToken); + if (sourceAddress == null) + { + throw new ArgumentException($"Address with ID {request.AddressId} not found for user {request.UserId}"); + } + + var order = mapper.Map(request); + order.OrderDate = DateTime.UtcNow; + order.OrderStatusId = 1; + order.ShippingStatusId = 1; + + var createdOrder = await uw.OrderRepository.AddAsync(order, cancellationToken); + + var orderAddress = new OrderAddress + { + OrderId = createdOrder.Id, + AddressType = sourceAddress.AddressType, + FirstName = sourceAddress.FirstName, + LastName = sourceAddress.LastName, + Company = sourceAddress.Company, + AddressLine1 = sourceAddress.AddressLine1, + AddressLine2 = sourceAddress.AddressLine2, + ApartmentNumber = sourceAddress.ApartmentNumber, + BuildingNumber = sourceAddress.BuildingNumber, + Floor = sourceAddress.Floor, + City = sourceAddress.City, + State = sourceAddress.State, + PostalCode = sourceAddress.PostalCode, + Country = sourceAddress.Country, + PhoneNumber = sourceAddress.PhoneNumber, + Instructions = sourceAddress.Instructions, + Order = createdOrder + }; + + await uw.OrderAddressRepository.AddAsync(orderAddress, cancellationToken); + + createdOrder.Product = (await uw.ProductRepository.GetByIdAsync(createdOrder.ProductId, cancellationToken))!; + + if (createdOrder.ProductVariantId.HasValue) + { + createdOrder.ProductVariant = await uw.ProductVariantRepository.GetByIdAsync(createdOrder.ProductVariantId.Value, cancellationToken); + } + + return mapper.Map(createdOrder); + }, cancellationToken); + } +} diff --git a/src/Imprink.Application/Commands/Orders/GetOrderByIdHandler.cs b/src/Imprink.Application/Commands/Orders/GetOrderByIdHandler.cs new file mode 100644 index 0000000..be46ab9 --- /dev/null +++ b/src/Imprink.Application/Commands/Orders/GetOrderByIdHandler.cs @@ -0,0 +1,31 @@ +using AutoMapper; +using Imprink.Application.Dtos; +using Imprink.Domain.Entities; +using MediatR; + +namespace Imprink.Application.Commands.Orders; + +public class GetOrderByIdQuery : IRequest +{ + public Guid Id { get; set; } + public bool IncludeDetails { get; set; } = false; +} + +public class GetOrderByIdHandler(IUnitOfWork uw, IMapper mapper) : IRequestHandler +{ + public async Task Handle(GetOrderByIdQuery request, CancellationToken cancellationToken) + { + Order? order; + + if (request.IncludeDetails) + { + order = await uw.OrderRepository.GetByIdWithDetailsAsync(request.Id, cancellationToken); + } + else + { + order = await uw.OrderRepository.GetByIdAsync(request.Id, cancellationToken); + } + + return order != null ? mapper.Map(order) : null; + } +} \ No newline at end of file diff --git a/src/Imprink.Application/Commands/Orders/GetOrdersByMerchantIdHandler.cs b/src/Imprink.Application/Commands/Orders/GetOrdersByMerchantIdHandler.cs new file mode 100644 index 0000000..b34ea92 --- /dev/null +++ b/src/Imprink.Application/Commands/Orders/GetOrdersByMerchantIdHandler.cs @@ -0,0 +1,31 @@ +using AutoMapper; +using Imprink.Application.Dtos; +using Imprink.Domain.Entities; +using MediatR; + +namespace Imprink.Application.Commands.Orders; + +public class GetOrdersByMerchantIdQuery : IRequest> +{ + public string MerchantId { get; set; } = null!; + public bool IncludeDetails { get; set; } = false; +} + +public class GetOrdersByMerchantIdHandler(IUnitOfWork uw, IMapper mapper) : IRequestHandler> +{ + public async Task> Handle(GetOrdersByMerchantIdQuery request, CancellationToken cancellationToken) + { + IEnumerable orders; + + if (request.IncludeDetails) + { + orders = await uw.OrderRepository.GetByMerchantIdWithDetailsAsync(request.MerchantId, cancellationToken); + } + else + { + orders = await uw.OrderRepository.GetByMerchantIdAsync(request.MerchantId, cancellationToken); + } + + return mapper.Map>(orders); + } +} \ No newline at end of file diff --git a/src/Imprink.Application/Commands/Orders/GetOrdersByUserIdHandler.cs b/src/Imprink.Application/Commands/Orders/GetOrdersByUserIdHandler.cs new file mode 100644 index 0000000..6f778a3 --- /dev/null +++ b/src/Imprink.Application/Commands/Orders/GetOrdersByUserIdHandler.cs @@ -0,0 +1,31 @@ +using AutoMapper; +using Imprink.Application.Dtos; +using Imprink.Domain.Entities; +using MediatR; + +namespace Imprink.Application.Commands.Orders; + +public class GetOrdersByUserIdQuery : IRequest> +{ + public string UserId { get; set; } = null!; + public bool IncludeDetails { get; set; } = false; +} + +public class GetOrdersByUserIdHandler(IUnitOfWork uw, IMapper mapper) : IRequestHandler> +{ + public async Task> Handle(GetOrdersByUserIdQuery request, CancellationToken cancellationToken) + { + IEnumerable orders; + + if (request.IncludeDetails) + { + orders = await uw.OrderRepository.GetByUserIdWithDetailsAsync(request.UserId, cancellationToken); + } + else + { + orders = await uw.OrderRepository.GetByUserIdAsync(request.UserId, cancellationToken); + } + + return mapper.Map>(orders); + } +} \ No newline at end of file diff --git a/src/Imprink.Application/Dtos/AddressDto.cs b/src/Imprink.Application/Dtos/AddressDto.cs new file mode 100644 index 0000000..6887b18 --- /dev/null +++ b/src/Imprink.Application/Dtos/AddressDto.cs @@ -0,0 +1,26 @@ +namespace Imprink.Application.Dtos; + +public class AddressDto +{ + public Guid Id { get; set; } + public string UserId { get; set; } = null!; + public string AddressType { get; set; } = null!; + public string? FirstName { get; set; } + public string? LastName { get; set; } + public string? Company { get; set; } + public string AddressLine1 { get; set; } = null!; + public string? AddressLine2 { get; set; } + public string? ApartmentNumber { get; set; } + public string? BuildingNumber { get; set; } + public string? Floor { get; set; } + public string City { get; set; } = null!; + public string State { get; set; } = null!; + public string PostalCode { get; set; } = null!; + public string Country { get; set; } = null!; + public string? PhoneNumber { get; set; } + public string? Instructions { get; set; } + public bool IsDefault { get; set; } + public bool IsActive { get; set; } + public DateTime CreatedAt { get; set; } + public DateTime UpdatedAt { get; set; } +} \ No newline at end of file diff --git a/src/Imprink.Application/Dtos/OrderAddressDto.cs b/src/Imprink.Application/Dtos/OrderAddressDto.cs new file mode 100644 index 0000000..0fdfaad --- /dev/null +++ b/src/Imprink.Application/Dtos/OrderAddressDto.cs @@ -0,0 +1,24 @@ +namespace Imprink.Application.Dtos; + +public class OrderAddressDto +{ + public Guid Id { get; set; } + public Guid OrderId { get; set; } + public string AddressType { get; set; } = null!; + public string? FirstName { get; set; } + public string? LastName { get; set; } + public string? Company { get; set; } + public string AddressLine1 { get; set; } = null!; + public string? AddressLine2 { get; set; } + public string? ApartmentNumber { get; set; } + public string? BuildingNumber { get; set; } + public string? Floor { get; set; } + public string City { get; set; } = null!; + public string State { get; set; } = null!; + public string PostalCode { get; set; } = null!; + public string Country { get; set; } = null!; + public string? PhoneNumber { get; set; } + public string? Instructions { get; set; } + public DateTime CreatedAt { get; set; } + public DateTime UpdatedAt { get; set; } +} \ No newline at end of file diff --git a/src/Imprink.Application/Dtos/OrderDto.cs b/src/Imprink.Application/Dtos/OrderDto.cs new file mode 100644 index 0000000..9c1cb3f --- /dev/null +++ b/src/Imprink.Application/Dtos/OrderDto.cs @@ -0,0 +1,30 @@ +namespace Imprink.Application.Dtos; + +public class OrderDto +{ + public Guid Id { get; set; } + public string UserId { get; set; } = null!; + public DateTime OrderDate { get; set; } + public decimal Amount { get; set; } + public int Quantity { get; set; } + public Guid ProductId { get; set; } + public Guid? ProductVariantId { get; set; } + public int OrderStatusId { get; set; } + public int ShippingStatusId { get; set; } + public string OrderNumber { get; set; } = null!; + public string? Notes { get; set; } + public string? MerchantId { get; set; } + public string? ComposingImageUrl { get; set; } + public string[] OriginalImageUrls { get; set; } = []; + public string CustomizationImageUrl { get; set; } = null!; + public string CustomizationDescription { get; set; } = null!; + public DateTime CreatedAt { get; set; } + public DateTime UpdatedAt { get; set; } + + public OrderStatusDto? OrderStatus { get; set; } + public UserDto? User { get; set; } + public ShippingStatusDto? ShippingStatus { get; set; } + public OrderAddressDto? OrderAddress { get; set; } + public ProductDto? Product { get; set; } + public ProductVariantDto? ProductVariant { get; set; } +} \ No newline at end of file diff --git a/src/Imprink.Application/Dtos/OrderStatusDto.cs b/src/Imprink.Application/Dtos/OrderStatusDto.cs new file mode 100644 index 0000000..fb1622f --- /dev/null +++ b/src/Imprink.Application/Dtos/OrderStatusDto.cs @@ -0,0 +1,8 @@ +namespace Imprink.Application.Dtos; + +public class OrderStatusDto +{ + public int Id { get; set; } + public string Name { get; set; } = null!; + public string? Description { get; set; } +} \ No newline at end of file diff --git a/src/Imprink.Application/Dtos/ShippingStatusDto.cs b/src/Imprink.Application/Dtos/ShippingStatusDto.cs new file mode 100644 index 0000000..8ea670d --- /dev/null +++ b/src/Imprink.Application/Dtos/ShippingStatusDto.cs @@ -0,0 +1,8 @@ +namespace Imprink.Application.Dtos; + +public class ShippingStatusDto +{ + public int Id { get; set; } + public string Name { get; set; } = null!; + public string? Description { get; set; } +} \ No newline at end of file diff --git a/src/Imprink.Application/IUnitOfWork.cs b/src/Imprink.Application/IUnitOfWork.cs index 4655022..507fe10 100644 --- a/src/Imprink.Application/IUnitOfWork.cs +++ b/src/Imprink.Application/IUnitOfWork.cs @@ -12,6 +12,7 @@ public interface IUnitOfWork public IRoleRepository RoleRepository { get; } public IOrderRepository OrderRepository { get; } public IAddressRepository AddressRepository { get; } + public IOrderAddressRepository OrderAddressRepository { get; } Task SaveAsync(CancellationToken cancellationToken = default); Task BeginTransactionAsync(CancellationToken cancellationToken = default); diff --git a/src/Imprink.Application/Imprink.Application.csproj b/src/Imprink.Application/Imprink.Application.csproj index bde7f6a..17480c4 100644 --- a/src/Imprink.Application/Imprink.Application.csproj +++ b/src/Imprink.Application/Imprink.Application.csproj @@ -19,8 +19,4 @@ - - - - diff --git a/src/Imprink.Domain/Repositories/IOrderAddressRepository.cs b/src/Imprink.Domain/Repositories/IOrderAddressRepository.cs new file mode 100644 index 0000000..fb5f53d --- /dev/null +++ b/src/Imprink.Domain/Repositories/IOrderAddressRepository.cs @@ -0,0 +1,16 @@ +using Imprink.Domain.Entities; + +namespace Imprink.Domain.Repositories; + +public interface IOrderAddressRepository +{ + Task GetByIdAsync(Guid id, CancellationToken cancellationToken = default); + Task GetByOrderIdAsync(Guid orderId, CancellationToken cancellationToken = default); + Task> GetByOrderIdsAsync(IEnumerable orderIds, CancellationToken cancellationToken = default); + Task AddAsync(OrderAddress orderAddress, CancellationToken cancellationToken = default); + Task UpdateAsync(OrderAddress orderAddress, CancellationToken cancellationToken = default); + Task DeleteAsync(Guid id, CancellationToken cancellationToken = default); + Task DeleteByOrderIdAsync(Guid orderId, CancellationToken cancellationToken = default); + Task ExistsAsync(Guid id, CancellationToken cancellationToken = default); + Task ExistsByOrderIdAsync(Guid orderId, CancellationToken cancellationToken = default); +} \ No newline at end of file diff --git a/src/Imprink.Infrastructure/Database/ApplicationDbContext.cs b/src/Imprink.Infrastructure/Database/ApplicationDbContext.cs index 423bef6..b0f9746 100644 --- a/src/Imprink.Infrastructure/Database/ApplicationDbContext.cs +++ b/src/Imprink.Infrastructure/Database/ApplicationDbContext.cs @@ -11,7 +11,6 @@ public class ApplicationDbContext(DbContextOptions options public DbSet Products { get; set; } public DbSet ProductVariants { get; set; } public DbSet Orders { get; set; } - public DbSet OrderAddresses { get; set; } public DbSet
Addresses { get; set; } public DbSet OrderStatuses { get; set; } public DbSet ShippingStatuses { get; set; } @@ -19,6 +18,7 @@ public class ApplicationDbContext(DbContextOptions options public DbSet UserRole { get; set; } public DbSet Roles { get; set; } public DbSet Categories { get; set; } + public DbSet OrderAddresses { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) { diff --git a/src/Imprink.Infrastructure/Repositories/OrderAddressRepository.cs b/src/Imprink.Infrastructure/Repositories/OrderAddressRepository.cs new file mode 100644 index 0000000..33e44aa --- /dev/null +++ b/src/Imprink.Infrastructure/Repositories/OrderAddressRepository.cs @@ -0,0 +1,77 @@ +using Imprink.Domain.Entities; +using Imprink.Domain.Repositories; +using Imprink.Infrastructure.Database; +using Microsoft.EntityFrameworkCore; + +namespace Imprink.Infrastructure.Repositories; + +public class OrderAddressRepository(ApplicationDbContext context) : IOrderAddressRepository +{ + + public async Task GetByIdAsync(Guid id, CancellationToken cancellationToken = default) + { + return await context.OrderAddresses + .Include(oa => oa.Order) + .FirstOrDefaultAsync(oa => oa.Id == id, cancellationToken); + } + + public async Task GetByOrderIdAsync(Guid orderId, CancellationToken cancellationToken = default) + { + return await context.OrderAddresses + .Include(oa => oa.Order) + .FirstOrDefaultAsync(oa => oa.OrderId == orderId, cancellationToken); + } + + public async Task> GetByOrderIdsAsync(IEnumerable orderIds, CancellationToken cancellationToken = default) + { + return await context.OrderAddresses + .Include(oa => oa.Order) + .Where(oa => orderIds.Contains(oa.OrderId)) + .ToListAsync(cancellationToken); + } + + public async Task AddAsync(OrderAddress orderAddress, CancellationToken cancellationToken = default) + { + var entry = await context.OrderAddresses.AddAsync(orderAddress, cancellationToken); + await context.SaveChangesAsync(cancellationToken); + return entry.Entity; + } + + public async Task UpdateAsync(OrderAddress orderAddress, CancellationToken cancellationToken = default) + { + context.OrderAddresses.Update(orderAddress); + await context.SaveChangesAsync(cancellationToken); + return orderAddress; + } + + public async Task DeleteAsync(Guid id, CancellationToken cancellationToken = default) + { + var orderAddress = await context.OrderAddresses.FindAsync([id], cancellationToken); + if (orderAddress == null) + return false; + + context.OrderAddresses.Remove(orderAddress); + await context.SaveChangesAsync(cancellationToken); + return true; + } + + public async Task DeleteByOrderIdAsync(Guid orderId, CancellationToken cancellationToken = default) + { + var orderAddress = await context.OrderAddresses.FirstOrDefaultAsync(oa => oa.OrderId == orderId, cancellationToken); + if (orderAddress == null) + return false; + + context.OrderAddresses.Remove(orderAddress); + return true; + } + + public async Task ExistsAsync(Guid id, CancellationToken cancellationToken = default) + { + return await context.OrderAddresses.AnyAsync(oa => oa.Id == id, cancellationToken); + } + + public async Task ExistsByOrderIdAsync(Guid orderId, CancellationToken cancellationToken = default) + { + return await context.OrderAddresses.AnyAsync(oa => oa.OrderId == orderId, cancellationToken); + } +} \ No newline at end of file diff --git a/src/Imprink.Infrastructure/UnitOfWork.cs b/src/Imprink.Infrastructure/UnitOfWork.cs index 29ae434..80e3472 100644 --- a/src/Imprink.Infrastructure/UnitOfWork.cs +++ b/src/Imprink.Infrastructure/UnitOfWork.cs @@ -13,7 +13,8 @@ public class UnitOfWork( IUserRoleRepository userRoleRepository, IRoleRepository roleRepository, IOrderRepository orderRepository, - IAddressRepository addressRepository) : IUnitOfWork + IAddressRepository addressRepository, + IOrderAddressRepository orderAddressRepository) : IUnitOfWork { public IProductRepository ProductRepository => productRepository; public IProductVariantRepository ProductVariantRepository => productVariantRepository; @@ -23,6 +24,7 @@ public class UnitOfWork( public IRoleRepository RoleRepository => roleRepository; public IOrderRepository OrderRepository => orderRepository; public IAddressRepository AddressRepository => addressRepository; + public IOrderAddressRepository OrderAddressRepository => orderAddressRepository; public async Task SaveAsync(CancellationToken cancellationToken = default) { diff --git a/src/Imprink.WebApi/Extensions/StartupApplicationExtensions.cs b/src/Imprink.WebApi/Extensions/StartupApplicationExtensions.cs index 48e12fb..e10b03b 100644 --- a/src/Imprink.WebApi/Extensions/StartupApplicationExtensions.cs +++ b/src/Imprink.WebApi/Extensions/StartupApplicationExtensions.cs @@ -20,6 +20,7 @@ public static class StartupApplicationExtensions services.AddScoped(); services.AddScoped(); services.AddScoped(); + services.AddScoped(); services.AddScoped(); services.AddScoped(); services.AddScoped();