Add migration for DiscountProductImages table
Build and Deploy to Kubernetes / build-and-deploy (push) Successful in 1m53s

- Created a new table `DiscountProductImages` in the CMS schema.
- Added columns for image details including `Title`, `AltText`, `ImagePath`, `ThumbnailPath`, `SortOrder`, `IsActive`, `Created`, `CreatedBy`, `LastModified`, `LastModifiedBy`, and `IsDeleted`.
- Established a foreign key relationship with the `DiscountProducts` table.
- Created indexes on `DiscountProductId` and a composite index on `DiscountProductId` and `SortOrder`.
This commit is contained in:
masoodafar-web
2026-01-01 02:26:33 +03:30
parent 500e169141
commit f0117eb1d5
29 changed files with 5068 additions and 4 deletions
@@ -0,0 +1,12 @@
using MediatR;
namespace CMSMicroservice.Application.DiscountShopCQ.Commands.AddDiscountProductImage;
public class AddDiscountProductImageCommand : IRequest<long>
{
public long DiscountProductId { get; set; }
public string ImagePath { get; set; } = string.Empty;
public string ThumbnailPath { get; set; } = string.Empty;
public string? Title { get; set; }
public string? AltText { get; set; }
}
@@ -0,0 +1,47 @@
using CMSMicroservice.Application.Common.Interfaces;
using CMSMicroservice.Domain.Entities.DiscountShop;
using MediatR;
using Microsoft.EntityFrameworkCore;
namespace CMSMicroservice.Application.DiscountShopCQ.Commands.AddDiscountProductImage;
public class AddDiscountProductImageCommandHandler : IRequestHandler<AddDiscountProductImageCommand, long>
{
private readonly IApplicationDbContext _context;
public AddDiscountProductImageCommandHandler(IApplicationDbContext context)
{
_context = context;
}
public async Task<long> Handle(AddDiscountProductImageCommand request, CancellationToken cancellationToken)
{
// Verify product exists
var productExists = await _context.DiscountProducts
.AnyAsync(p => p.Id == request.DiscountProductId, cancellationToken);
if (!productExists)
throw new InvalidOperationException($"DiscountProduct with Id {request.DiscountProductId} not found.");
// Get the max sort order for this product
var maxSortOrder = await _context.DiscountProductImages
.Where(i => i.DiscountProductId == request.DiscountProductId)
.MaxAsync(i => (int?)i.SortOrder, cancellationToken) ?? 0;
var image = new DiscountProductImage
{
DiscountProductId = request.DiscountProductId,
ImagePath = request.ImagePath,
ThumbnailPath = request.ThumbnailPath,
Title = request.Title,
AltText = request.AltText,
SortOrder = maxSortOrder + 1,
IsActive = true
};
_context.DiscountProductImages.Add(image);
await _context.SaveChangesAsync(cancellationToken);
return image.Id;
}
}
@@ -0,0 +1,8 @@
using MediatR;
namespace CMSMicroservice.Application.DiscountShopCQ.Commands.DeleteDiscountProductImage;
public class DeleteDiscountProductImageCommand : IRequest<bool>
{
public long Id { get; set; }
}
@@ -0,0 +1,41 @@
using CMSMicroservice.Application.Common.Interfaces;
using MediatR;
using Microsoft.EntityFrameworkCore;
namespace CMSMicroservice.Application.DiscountShopCQ.Commands.DeleteDiscountProductImage;
public class DeleteDiscountProductImageCommandHandler : IRequestHandler<DeleteDiscountProductImageCommand, bool>
{
private readonly IApplicationDbContext _context;
public DeleteDiscountProductImageCommandHandler(IApplicationDbContext context)
{
_context = context;
}
public async Task<bool> Handle(DeleteDiscountProductImageCommand request, CancellationToken cancellationToken)
{
var image = await _context.DiscountProductImages
.FirstOrDefaultAsync(i => i.Id == request.Id, cancellationToken);
if (image == null)
return false;
_context.DiscountProductImages.Remove(image);
await _context.SaveChangesAsync(cancellationToken);
// Reorder remaining images for this product
var remainingImages = await _context.DiscountProductImages
.Where(i => i.DiscountProductId == image.DiscountProductId)
.OrderBy(i => i.SortOrder)
.ToListAsync(cancellationToken);
for (int i = 0; i < remainingImages.Count; i++)
{
remainingImages[i].SortOrder = i + 1;
}
await _context.SaveChangesAsync(cancellationToken);
return true;
}
}
@@ -1,4 +1,5 @@
using CMSMicroservice.Application.Common.Interfaces;
using CMSMicroservice.Application.Common.Services;
using CMSMicroservice.Domain.Entities.DiscountShop;
using CMSMicroservice.Domain.Entities.Payment;
using CMSMicroservice.Domain.Enums;
@@ -109,9 +110,10 @@ public class PlaceOrderCommandHandler : IRequestHandler<PlaceOrderCommand, Place
var gatewayAmountRequired = totalAmount - actualDiscountBalanceUsed;
// Calculate VAT (9%)
var vatAmount = (gatewayAmountRequired * 9) / 100;
var finalGatewayAmount = gatewayAmountRequired + vatAmount;
// Calculate VAT using centralized calculator
var vatBreakdown = VatCalculator.CalculateBreakdown(gatewayAmountRequired);
var vatAmount = vatBreakdown.VatAmount;
var finalGatewayAmount = vatBreakdown.GrossAmount;
// Create transaction for gateway payment
var transaction = new Transaction
@@ -0,0 +1,9 @@
using MediatR;
namespace CMSMicroservice.Application.DiscountShopCQ.Commands.ReorderDiscountProductImages;
public class ReorderDiscountProductImagesCommand : IRequest<bool>
{
public long DiscountProductId { get; set; }
public List<long> ImageIds { get; set; } = new();
}
@@ -0,0 +1,43 @@
using CMSMicroservice.Application.Common.Interfaces;
using MediatR;
using Microsoft.EntityFrameworkCore;
namespace CMSMicroservice.Application.DiscountShopCQ.Commands.ReorderDiscountProductImages;
public class ReorderDiscountProductImagesCommandHandler : IRequestHandler<ReorderDiscountProductImagesCommand, bool>
{
private readonly IApplicationDbContext _context;
public ReorderDiscountProductImagesCommandHandler(IApplicationDbContext context)
{
_context = context;
}
public async Task<bool> Handle(ReorderDiscountProductImagesCommand request, CancellationToken cancellationToken)
{
var images = await _context.DiscountProductImages
.Where(i => i.DiscountProductId == request.DiscountProductId)
.ToListAsync(cancellationToken);
if (!images.Any())
return false;
// Validate all image IDs belong to this product
var imageIdSet = images.Select(i => i.Id).ToHashSet();
if (!request.ImageIds.All(id => imageIdSet.Contains(id)))
return false;
// Update sort order based on the new order
for (int i = 0; i < request.ImageIds.Count; i++)
{
var image = images.FirstOrDefault(img => img.Id == request.ImageIds[i]);
if (image != null)
{
image.SortOrder = i + 1;
}
}
await _context.SaveChangesAsync(cancellationToken);
return true;
}
}
@@ -0,0 +1,13 @@
using MediatR;
namespace CMSMicroservice.Application.DiscountShopCQ.Commands.UpdateDiscountProductImage;
public class UpdateDiscountProductImageCommand : IRequest<bool>
{
public long Id { get; set; }
public string ImagePath { get; set; } = string.Empty;
public string ThumbnailPath { get; set; } = string.Empty;
public string? Title { get; set; }
public string? AltText { get; set; }
public bool IsActive { get; set; }
}
@@ -0,0 +1,33 @@
using CMSMicroservice.Application.Common.Interfaces;
using MediatR;
using Microsoft.EntityFrameworkCore;
namespace CMSMicroservice.Application.DiscountShopCQ.Commands.UpdateDiscountProductImage;
public class UpdateDiscountProductImageCommandHandler : IRequestHandler<UpdateDiscountProductImageCommand, bool>
{
private readonly IApplicationDbContext _context;
public UpdateDiscountProductImageCommandHandler(IApplicationDbContext context)
{
_context = context;
}
public async Task<bool> Handle(UpdateDiscountProductImageCommand request, CancellationToken cancellationToken)
{
var image = await _context.DiscountProductImages
.FirstOrDefaultAsync(i => i.Id == request.Id, cancellationToken);
if (image == null)
return false;
image.ImagePath = request.ImagePath;
image.ThumbnailPath = request.ThumbnailPath;
image.Title = request.Title;
image.AltText = request.AltText;
image.IsActive = request.IsActive;
await _context.SaveChangesAsync(cancellationToken);
return true;
}
}