diff --git a/docs/EXCLUDED-HANDLERS-FIX-PLAN.md b/docs/EXCLUDED-HANDLERS-FIX-PLAN.md index 12a8613..4f5ba1f 100644 --- a/docs/EXCLUDED-HANDLERS-FIX-PLAN.md +++ b/docs/EXCLUDED-HANDLERS-FIX-PLAN.md @@ -1,22 +1,71 @@ # Plan: فعال‌سازی مرحله‌ای Handler های کامنت‌شده **تاریخ:** 8 دسامبر 2025 -**وضعیت:** در انتظار اجرا -**تعداد کل فایل‌های کامنت‌شده:** 37 فایل در 3 دسته +**وضعیت:** ✅ کامل شده +**آخرین به‌روزرسانی:** 1 ژانویه 2026 --- ## خلاصه اجرایی -در `BackOffice.BFF.Application.csproj` سه دسته handler کامنت شده‌اند: +در `BackOffice.BFF.Application.csproj` سه دسته handler کامنت شده بودند که همه فعال شدند: -1. **DiscountOrderCQ/** (18 فایل) - عدم تطابق Proto با CMS -2. **DiscountShoppingCartCQ/** (16 فایل) - عدم تطابق Proto -3. **CommissionCQ/Commands/ProcessWithdrawal/** (3 فایل) - مشکل تبدیل StringValue +1. **DiscountOrderCQ/** (18 فایل) - ✅ فعال شد +2. **DiscountShoppingCartCQ/** (16 فایل) - ✅ فعال شد و با CMS proto هماهنگ شد +3. **CommissionCQ/Commands/ProcessWithdrawal/** (3 فایل) - ✅ قبلاً فعال شده بود + +**همچنین در BackOffice UI (1 ژانویه 2026):** +- فعال‌سازی همه سرویس‌ها در `ConfigureService.cs` +- ثبت gRPC Clients برای DiscountProduct, DiscountCategory, DiscountOrder, Tag, ProductTag, PublicMessage +- ثبت Application Services --- -## مرحله 1: ProcessWithdrawal (30 دقیقه - ساده ✅) +## تغییرات انجام‌شده (1 ژانویه 2026) + +### BackOffice UI - فعال‌سازی فرانت‌اند + +#### ConfigureService.cs +- فعال‌سازی using statements برای همه proto clients +- ثبت gRPC Clients در DI container +- ثبت Application Services (IDiscountProductService, IDiscountCategoryService, etc.) + +#### صفحات فعال شده: +| Route | صفحه | +|-------|------| +| `/discount-products` | مدیریت محصولات تخفیفی | +| `/discount-categories` | مدیریت دسته‌بندی‌ها | +| `/discount-orders` | مدیریت سفارشات | +| `/tags` | مدیریت تگ‌ها | +| `/public-messages` | پیام‌های عمومی | + +--- + +## تغییرات انجام‌شده (13 ژانویه 2025) + +### DiscountShoppingCartCQ - اصلاحات Proto + +#### RemoveFromCart +- `CartItemId` → `ProductId` (مطابق با proto) + +#### UpdateCartItemCount +- `CartItemId` → `ProductId` (مطابق با proto) + +#### GetUserCart Response +- حذف `UserId` از response +- `TotalDiscountedPrice` → `TotalDiscountAmount` +- `TotalSavings` → حذف شد +- اضافه شدن `FinalPrice` + +#### CartItemDto +- حذف `Id` +- `DiscountedPrice` → `DiscountAmount` +- `AddedAt` → `Created` +- اضافه شدن `FinalPrice`, `ProductRemainingCount` + +--- + +## مرحله 1: ProcessWithdrawal ✅ (قبلاً انجام شده) ### ویژگی بیزینسی مدیریت درخواست‌های برداشت کمیسیون توسط ادمین (تایید/رد) diff --git a/src/BackOffice.BFF.Application/BackOffice.BFF.Application.csproj b/src/BackOffice.BFF.Application/BackOffice.BFF.Application.csproj index 46a75ad..e79f19d 100644 --- a/src/BackOffice.BFF.Application/BackOffice.BFF.Application.csproj +++ b/src/BackOffice.BFF.Application/BackOffice.BFF.Application.csproj @@ -5,14 +5,10 @@ enable - + + - - - - - - + diff --git a/src/BackOffice.BFF.Application/DiscountOrderCQ/Queries/GetAllDiscountOrders/GetAllDiscountOrdersQuery.cs b/src/BackOffice.BFF.Application/DiscountOrderCQ/Queries/GetAllDiscountOrders/GetAllDiscountOrdersQuery.cs new file mode 100644 index 0000000..7689338 --- /dev/null +++ b/src/BackOffice.BFF.Application/DiscountOrderCQ/Queries/GetAllDiscountOrders/GetAllDiscountOrdersQuery.cs @@ -0,0 +1,50 @@ +namespace BackOffice.BFF.Application.DiscountOrderCQ.Queries.GetAllDiscountOrders; + +/// +/// کوئری دریافت همه سفارشات فروشگاه تخفیفی برای ادمین +/// +public class GetAllDiscountOrdersQuery : IRequest +{ + public int PageNumber { get; set; } = 1; + public int PageSize { get; set; } = 20; + + public long? UserId { get; set; } + public int? PaymentStatus { get; set; } + public int? DeliveryStatus { get; set; } + public string? UserMobile { get; set; } + public string? TrackingCode { get; set; } + public DateTime? FromDate { get; set; } + public DateTime? ToDate { get; set; } + public long? MinAmount { get; set; } + public long? MaxAmount { get; set; } +} + +public class GetAllDiscountOrdersResponseDto +{ + public MetaData MetaData { get; set; } = new(); + public List Orders { get; set; } = new(); +} + +public class AdminOrderDto +{ + public long Id { get; set; } + public long UserId { get; set; } + public string UserFullName { get; set; } = string.Empty; + public string UserMobile { get; set; } = string.Empty; + public long TotalAmount { get; set; } + public long DiscountBalanceUsed { get; set; } + public long GatewayAmountPaid { get; set; } + public long VatAmount { get; set; } + public int PaymentStatus { get; set; } + public DateTime? PaymentDate { get; set; } + public int DeliveryStatus { get; set; } + public DateTime? DeliveryDate { get; set; } + public string? ShippingAddress { get; set; } + public string? ReceiverName { get; set; } + public string? ReceiverMobile { get; set; } + public string? TrackingCode { get; set; } + public string? AdminNote { get; set; } + public DateTime Created { get; set; } + public DateTime? LastModified { get; set; } + public int ItemsCount { get; set; } +} diff --git a/src/BackOffice.BFF.Application/DiscountOrderCQ/Queries/GetAllDiscountOrders/GetAllDiscountOrdersQueryHandler.cs b/src/BackOffice.BFF.Application/DiscountOrderCQ/Queries/GetAllDiscountOrders/GetAllDiscountOrdersQueryHandler.cs new file mode 100644 index 0000000..b6e2805 --- /dev/null +++ b/src/BackOffice.BFF.Application/DiscountOrderCQ/Queries/GetAllDiscountOrders/GetAllDiscountOrdersQueryHandler.cs @@ -0,0 +1,88 @@ +using CMSMicroservice.Protobuf.Protos.DiscountOrder; +using Google.Protobuf.WellKnownTypes; + +namespace BackOffice.BFF.Application.DiscountOrderCQ.Queries.GetAllDiscountOrders; + +public class GetAllDiscountOrdersQueryHandler : IRequestHandler +{ + private readonly IApplicationContractContext _context; + + public GetAllDiscountOrdersQueryHandler(IApplicationContractContext context) + { + _context = context; + } + + public async Task Handle(GetAllDiscountOrdersQuery request, CancellationToken cancellationToken) + { + var grpcRequest = new GetAllDiscountOrdersRequest + { + PageNumber = request.PageNumber, + PageSize = request.PageSize + }; + + if (request.UserId.HasValue) + grpcRequest.UserId = request.UserId.Value; + + if (request.PaymentStatus.HasValue) + grpcRequest.PaymentStatus = request.PaymentStatus.Value; + + if (request.DeliveryStatus.HasValue) + grpcRequest.DeliveryStatus = request.DeliveryStatus.Value; + + if (!string.IsNullOrWhiteSpace(request.UserMobile)) + grpcRequest.UserMobile = request.UserMobile; + + if (!string.IsNullOrWhiteSpace(request.TrackingCode)) + grpcRequest.TrackingCode = request.TrackingCode; + + if (request.FromDate.HasValue) + grpcRequest.FromDate = Timestamp.FromDateTime(DateTime.SpecifyKind(request.FromDate.Value, DateTimeKind.Utc)); + + if (request.ToDate.HasValue) + grpcRequest.ToDate = Timestamp.FromDateTime(DateTime.SpecifyKind(request.ToDate.Value, DateTimeKind.Utc)); + + if (request.MinAmount.HasValue) + grpcRequest.MinAmount = request.MinAmount.Value; + + if (request.MaxAmount.HasValue) + grpcRequest.MaxAmount = request.MaxAmount.Value; + + var response = await _context.DiscountOrders.GetAllDiscountOrdersAsync(grpcRequest, cancellationToken: cancellationToken); + + return new GetAllDiscountOrdersResponseDto + { + MetaData = new MetaData + { + CurrentPage = response.MetaData.CurrentPage, + TotalPage = response.MetaData.TotalPage, + PageSize = response.MetaData.PageSize, + TotalCount = response.MetaData.TotalCount, + HasPrevious = response.MetaData.HasPrevious, + HasNext = response.MetaData.HasNext + }, + Orders = response.Models.Select(o => new AdminOrderDto + { + Id = o.Id, + UserId = o.UserId, + UserFullName = o.UserFullName, + UserMobile = o.UserMobile, + TotalAmount = o.TotalAmount, + DiscountBalanceUsed = o.DiscountBalanceUsed, + GatewayAmountPaid = o.GatewayAmountPaid, + VatAmount = o.VatAmount, + PaymentStatus = (int)o.PaymentStatus, + PaymentDate = o.PaymentDate?.ToDateTime(), + DeliveryStatus = (int)o.DeliveryStatus, + DeliveryDate = o.DeliveryDate?.ToDateTime(), + ShippingAddress = o.ShippingAddress, + ReceiverName = o.ReceiverName, + ReceiverMobile = o.ReceiverMobile, + TrackingCode = o.TrackingCode, + AdminNote = o.AdminNote, + Created = o.Created.ToDateTime(), + LastModified = o.LastModified?.ToDateTime(), + ItemsCount = o.ItemsCount + }).ToList() + }; + } +} diff --git a/src/BackOffice.BFF.Application/DiscountOrderCQ/Queries/GetDiscountSalesReport/GetDiscountSalesReportQuery.cs b/src/BackOffice.BFF.Application/DiscountOrderCQ/Queries/GetDiscountSalesReport/GetDiscountSalesReportQuery.cs new file mode 100644 index 0000000..01f1cee --- /dev/null +++ b/src/BackOffice.BFF.Application/DiscountOrderCQ/Queries/GetDiscountSalesReport/GetDiscountSalesReportQuery.cs @@ -0,0 +1,53 @@ +namespace BackOffice.BFF.Application.DiscountOrderCQ.Queries.GetDiscountSalesReport; + +public class GetDiscountSalesReportQuery : IRequest +{ + public DateTime FromDate { get; set; } + public DateTime ToDate { get; set; } + public ReportPeriodType PeriodType { get; set; } = ReportPeriodType.Daily; +} + +public enum ReportPeriodType +{ + Summary = 0, + Daily = 1, + Weekly = 2, + Monthly = 3 +} + +public class DiscountSalesReportDto +{ + public DateTime FromDate { get; set; } + public DateTime ToDate { get; set; } + public ReportPeriodType PeriodType { get; set; } + public SalesSummaryDto Summary { get; set; } = new(); + public List Periods { get; set; } = new(); +} + +public class SalesSummaryDto +{ + public int TotalOrders { get; set; } + public int SuccessfulOrders { get; set; } + public int PendingOrders { get; set; } + public int RejectedOrders { get; set; } + public decimal TotalRevenue { get; set; } + public decimal TotalDiscountUsed { get; set; } + public decimal TotalGatewayPayments { get; set; } + public decimal TotalVat { get; set; } + public int TotalItemsSold { get; set; } + public int UniqueCustomers { get; set; } + public decimal AverageOrderValue { get; set; } +} + +public class PeriodSalesDto +{ + public string PeriodLabel { get; set; } = string.Empty; + public DateTime PeriodStart { get; set; } + public DateTime PeriodEnd { get; set; } + public int OrderCount { get; set; } + public decimal Revenue { get; set; } + public decimal DiscountUsed { get; set; } + public decimal GatewayPayments { get; set; } + public decimal VatAmount { get; set; } + public int ItemsSold { get; set; } +} diff --git a/src/BackOffice.BFF.Application/DiscountOrderCQ/Queries/GetDiscountSalesReport/GetDiscountSalesReportQueryHandler.cs b/src/BackOffice.BFF.Application/DiscountOrderCQ/Queries/GetDiscountSalesReport/GetDiscountSalesReportQueryHandler.cs new file mode 100644 index 0000000..c763937 --- /dev/null +++ b/src/BackOffice.BFF.Application/DiscountOrderCQ/Queries/GetDiscountSalesReport/GetDiscountSalesReportQueryHandler.cs @@ -0,0 +1,59 @@ +using CMSMicroservice.Protobuf.Protos.DiscountOrder; +using Google.Protobuf.WellKnownTypes; + +namespace BackOffice.BFF.Application.DiscountOrderCQ.Queries.GetDiscountSalesReport; + +public class GetDiscountSalesReportQueryHandler : IRequestHandler +{ + private readonly IApplicationContractContext _context; + + public GetDiscountSalesReportQueryHandler(IApplicationContractContext context) + { + _context = context; + } + + public async Task Handle(GetDiscountSalesReportQuery request, CancellationToken cancellationToken) + { + var grpcRequest = new GetDiscountSalesReportRequest + { + FromDate = Timestamp.FromDateTime(DateTime.SpecifyKind(request.FromDate, DateTimeKind.Utc)), + ToDate = Timestamp.FromDateTime(DateTime.SpecifyKind(request.ToDate, DateTimeKind.Utc)), + ReportType = (SalesReportType)request.PeriodType + }; + + var response = await _context.DiscountOrders.GetDiscountSalesReportAsync(grpcRequest, cancellationToken: cancellationToken); + + return new DiscountSalesReportDto + { + FromDate = request.FromDate, + ToDate = request.ToDate, + PeriodType = request.PeriodType, + Summary = new SalesSummaryDto + { + TotalOrders = response.Summary.TotalOrders, + SuccessfulOrders = response.Summary.CompletedOrders, + PendingOrders = response.Summary.PendingOrders, + RejectedOrders = response.Summary.CancelledOrders, + TotalRevenue = response.Summary.TotalSalesAmount, + TotalDiscountUsed = response.Summary.TotalDiscountUsed, + TotalGatewayPayments = response.Summary.TotalGatewayPaid, + TotalVat = response.Summary.TotalVatAmount, + TotalItemsSold = response.Summary.TotalProductsSold, + UniqueCustomers = response.Summary.UniqueCustomers, + AverageOrderValue = response.Summary.AverageOrderValue + }, + Periods = response.Periods.Select(p => new PeriodSalesDto + { + PeriodLabel = p.PeriodLabel, + PeriodStart = p.PeriodStart.ToDateTime(), + PeriodEnd = p.PeriodEnd.ToDateTime(), + OrderCount = p.OrdersCount, + Revenue = p.TotalAmount, + DiscountUsed = p.DiscountUsed, + GatewayPayments = p.GatewayPaid, + VatAmount = 0, // Not in proto response + ItemsSold = 0 // Not in proto response + }).ToList() + }; + } +} diff --git a/src/BackOffice.BFF.Application/DiscountProductCQ/Commands/AddDiscountProductImage/AddDiscountProductImageCommand.cs b/src/BackOffice.BFF.Application/DiscountProductCQ/Commands/AddDiscountProductImage/AddDiscountProductImageCommand.cs new file mode 100644 index 0000000..cb1d773 --- /dev/null +++ b/src/BackOffice.BFF.Application/DiscountProductCQ/Commands/AddDiscountProductImage/AddDiscountProductImageCommand.cs @@ -0,0 +1,22 @@ +namespace BackOffice.BFF.Application.DiscountProductCQ.Commands.AddDiscountProductImage; + +public class AddDiscountProductImageCommand : IRequest +{ + public long DiscountProductId { get; set; } + public ImageFileInput? ImageFile { get; set; } + public ImageFileInput? ThumbnailFile { get; set; } + public string? Title { get; set; } + public string? AltText { get; set; } +} + +public class ImageFileInput +{ + public byte[] Data { get; set; } = []; + public string FileName { get; set; } = string.Empty; + public string MimeType { get; set; } = string.Empty; +} + +public class AddDiscountProductImageResponseDto +{ + public long ImageId { get; set; } +} diff --git a/src/BackOffice.BFF.Application/DiscountProductCQ/Commands/AddDiscountProductImage/AddDiscountProductImageCommandHandler.cs b/src/BackOffice.BFF.Application/DiscountProductCQ/Commands/AddDiscountProductImage/AddDiscountProductImageCommandHandler.cs new file mode 100644 index 0000000..468c5bf --- /dev/null +++ b/src/BackOffice.BFF.Application/DiscountProductCQ/Commands/AddDiscountProductImage/AddDiscountProductImageCommandHandler.cs @@ -0,0 +1,67 @@ +using CMSMicroservice.Protobuf.Protos.DiscountProduct; +using Google.Protobuf; + +namespace BackOffice.BFF.Application.DiscountProductCQ.Commands.AddDiscountProductImage; + +public class AddDiscountProductImageCommandHandler : IRequestHandler +{ + private readonly IApplicationContractContext _context; + + public AddDiscountProductImageCommandHandler(IApplicationContractContext context) + { + _context = context; + } + + public async Task Handle(AddDiscountProductImageCommand request, CancellationToken cancellationToken) + { + var addRequest = new AddDiscountProductImageRequest + { + DiscountProductId = request.DiscountProductId + }; + + if (!string.IsNullOrWhiteSpace(request.Title)) + addRequest.Title = request.Title; + + if (!string.IsNullOrWhiteSpace(request.AltText)) + addRequest.AltText = request.AltText; + + // Upload Image + if (request.ImageFile != null && request.ImageFile.Data != null && request.ImageFile.Data.Length > 0) + { + var imageFileInfo = await _context.FileInfos.CreateNewFileInfoAsync(new() + { + Directory = "Images/DiscountShop/Products/Gallery", + IsBase64 = false, + MIME = request.ImageFile.MimeType, + FileName = request.ImageFile.FileName, + File = ByteString.CopyFrom(request.ImageFile.Data) + }, cancellationToken: cancellationToken); + + if (imageFileInfo != null && !string.IsNullOrWhiteSpace(imageFileInfo.File)) + addRequest.ImagePath = imageFileInfo.File; + } + + // Upload Thumbnail + if (request.ThumbnailFile != null && request.ThumbnailFile.Data != null && request.ThumbnailFile.Data.Length > 0) + { + var thumbnailFileInfo = await _context.FileInfos.CreateNewFileInfoAsync(new() + { + Directory = "Images/DiscountShop/Products/Gallery/Thumbnails", + IsBase64 = false, + MIME = request.ThumbnailFile.MimeType, + FileName = request.ThumbnailFile.FileName, + File = ByteString.CopyFrom(request.ThumbnailFile.Data) + }, cancellationToken: cancellationToken); + + if (thumbnailFileInfo != null && !string.IsNullOrWhiteSpace(thumbnailFileInfo.File)) + addRequest.ThumbnailPath = thumbnailFileInfo.File; + } + + var response = await _context.DiscountProducts.AddDiscountProductImageAsync(addRequest, cancellationToken: cancellationToken); + + return new AddDiscountProductImageResponseDto + { + ImageId = response.ImageId + }; + } +} diff --git a/src/BackOffice.BFF.Application/DiscountProductCQ/Commands/DeleteDiscountProductImage/DeleteDiscountProductImageCommand.cs b/src/BackOffice.BFF.Application/DiscountProductCQ/Commands/DeleteDiscountProductImage/DeleteDiscountProductImageCommand.cs new file mode 100644 index 0000000..8e9fbf1 --- /dev/null +++ b/src/BackOffice.BFF.Application/DiscountProductCQ/Commands/DeleteDiscountProductImage/DeleteDiscountProductImageCommand.cs @@ -0,0 +1,6 @@ +namespace BackOffice.BFF.Application.DiscountProductCQ.Commands.DeleteDiscountProductImage; + +public class DeleteDiscountProductImageCommand : IRequest +{ + public long Id { get; set; } +} diff --git a/src/BackOffice.BFF.Application/DiscountProductCQ/Commands/DeleteDiscountProductImage/DeleteDiscountProductImageCommandHandler.cs b/src/BackOffice.BFF.Application/DiscountProductCQ/Commands/DeleteDiscountProductImage/DeleteDiscountProductImageCommandHandler.cs new file mode 100644 index 0000000..5ed2890 --- /dev/null +++ b/src/BackOffice.BFF.Application/DiscountProductCQ/Commands/DeleteDiscountProductImage/DeleteDiscountProductImageCommandHandler.cs @@ -0,0 +1,23 @@ +using CMSMicroservice.Protobuf.Protos.DiscountProduct; + +namespace BackOffice.BFF.Application.DiscountProductCQ.Commands.DeleteDiscountProductImage; + +public class DeleteDiscountProductImageCommandHandler : IRequestHandler +{ + private readonly IApplicationContractContext _context; + + public DeleteDiscountProductImageCommandHandler(IApplicationContractContext context) + { + _context = context; + } + + public async Task Handle(DeleteDiscountProductImageCommand request, CancellationToken cancellationToken) + { + await _context.DiscountProducts.DeleteDiscountProductImageAsync(new DeleteDiscountProductImageRequest + { + Id = request.Id + }, cancellationToken: cancellationToken); + + return Unit.Value; + } +} diff --git a/src/BackOffice.BFF.Application/DiscountProductCQ/Commands/ReorderDiscountProductImages/ReorderDiscountProductImagesCommand.cs b/src/BackOffice.BFF.Application/DiscountProductCQ/Commands/ReorderDiscountProductImages/ReorderDiscountProductImagesCommand.cs new file mode 100644 index 0000000..1637a57 --- /dev/null +++ b/src/BackOffice.BFF.Application/DiscountProductCQ/Commands/ReorderDiscountProductImages/ReorderDiscountProductImagesCommand.cs @@ -0,0 +1,7 @@ +namespace BackOffice.BFF.Application.DiscountProductCQ.Commands.ReorderDiscountProductImages; + +public class ReorderDiscountProductImagesCommand : IRequest +{ + public long DiscountProductId { get; set; } + public List ImageIds { get; set; } = new(); +} diff --git a/src/BackOffice.BFF.Application/DiscountProductCQ/Commands/ReorderDiscountProductImages/ReorderDiscountProductImagesCommandHandler.cs b/src/BackOffice.BFF.Application/DiscountProductCQ/Commands/ReorderDiscountProductImages/ReorderDiscountProductImagesCommandHandler.cs new file mode 100644 index 0000000..5f877d8 --- /dev/null +++ b/src/BackOffice.BFF.Application/DiscountProductCQ/Commands/ReorderDiscountProductImages/ReorderDiscountProductImagesCommandHandler.cs @@ -0,0 +1,26 @@ +using CMSMicroservice.Protobuf.Protos.DiscountProduct; + +namespace BackOffice.BFF.Application.DiscountProductCQ.Commands.ReorderDiscountProductImages; + +public class ReorderDiscountProductImagesCommandHandler : IRequestHandler +{ + private readonly IApplicationContractContext _context; + + public ReorderDiscountProductImagesCommandHandler(IApplicationContractContext context) + { + _context = context; + } + + public async Task Handle(ReorderDiscountProductImagesCommand request, CancellationToken cancellationToken) + { + var reorderRequest = new ReorderDiscountProductImagesRequest + { + DiscountProductId = request.DiscountProductId + }; + reorderRequest.ImageIds.AddRange(request.ImageIds); + + await _context.DiscountProducts.ReorderDiscountProductImagesAsync(reorderRequest, cancellationToken: cancellationToken); + + return Unit.Value; + } +} diff --git a/src/BackOffice.BFF.Application/DiscountProductCQ/Commands/UpdateDiscountProductImage/UpdateDiscountProductImageCommand.cs b/src/BackOffice.BFF.Application/DiscountProductCQ/Commands/UpdateDiscountProductImage/UpdateDiscountProductImageCommand.cs new file mode 100644 index 0000000..872bfcb --- /dev/null +++ b/src/BackOffice.BFF.Application/DiscountProductCQ/Commands/UpdateDiscountProductImage/UpdateDiscountProductImageCommand.cs @@ -0,0 +1,13 @@ +using BackOffice.BFF.Application.DiscountProductCQ.Commands.AddDiscountProductImage; + +namespace BackOffice.BFF.Application.DiscountProductCQ.Commands.UpdateDiscountProductImage; + +public class UpdateDiscountProductImageCommand : IRequest +{ + public long Id { get; set; } + public ImageFileInput? ImageFile { get; set; } + public ImageFileInput? ThumbnailFile { get; set; } + public string? Title { get; set; } + public string? AltText { get; set; } + public bool IsActive { get; set; } +} diff --git a/src/BackOffice.BFF.Application/DiscountProductCQ/Commands/UpdateDiscountProductImage/UpdateDiscountProductImageCommandHandler.cs b/src/BackOffice.BFF.Application/DiscountProductCQ/Commands/UpdateDiscountProductImage/UpdateDiscountProductImageCommandHandler.cs new file mode 100644 index 0000000..382f7a9 --- /dev/null +++ b/src/BackOffice.BFF.Application/DiscountProductCQ/Commands/UpdateDiscountProductImage/UpdateDiscountProductImageCommandHandler.cs @@ -0,0 +1,65 @@ +using CMSMicroservice.Protobuf.Protos.DiscountProduct; +using Google.Protobuf; + +namespace BackOffice.BFF.Application.DiscountProductCQ.Commands.UpdateDiscountProductImage; + +public class UpdateDiscountProductImageCommandHandler : IRequestHandler +{ + private readonly IApplicationContractContext _context; + + public UpdateDiscountProductImageCommandHandler(IApplicationContractContext context) + { + _context = context; + } + + public async Task Handle(UpdateDiscountProductImageCommand request, CancellationToken cancellationToken) + { + var updateRequest = new UpdateDiscountProductImageRequest + { + Id = request.Id, + IsActive = request.IsActive + }; + + if (!string.IsNullOrWhiteSpace(request.Title)) + updateRequest.Title = request.Title; + + if (!string.IsNullOrWhiteSpace(request.AltText)) + updateRequest.AltText = request.AltText; + + // Upload new Image if provided + if (request.ImageFile != null && request.ImageFile.Data != null && request.ImageFile.Data.Length > 0) + { + var imageFileInfo = await _context.FileInfos.CreateNewFileInfoAsync(new() + { + Directory = "Images/DiscountShop/Products/Gallery", + IsBase64 = false, + MIME = request.ImageFile.MimeType, + FileName = request.ImageFile.FileName, + File = ByteString.CopyFrom(request.ImageFile.Data) + }, cancellationToken: cancellationToken); + + if (imageFileInfo != null && !string.IsNullOrWhiteSpace(imageFileInfo.File)) + updateRequest.ImagePath = imageFileInfo.File; + } + + // Upload new Thumbnail if provided + if (request.ThumbnailFile != null && request.ThumbnailFile.Data != null && request.ThumbnailFile.Data.Length > 0) + { + var thumbnailFileInfo = await _context.FileInfos.CreateNewFileInfoAsync(new() + { + Directory = "Images/DiscountShop/Products/Gallery/Thumbnails", + IsBase64 = false, + MIME = request.ThumbnailFile.MimeType, + FileName = request.ThumbnailFile.FileName, + File = ByteString.CopyFrom(request.ThumbnailFile.Data) + }, cancellationToken: cancellationToken); + + if (thumbnailFileInfo != null && !string.IsNullOrWhiteSpace(thumbnailFileInfo.File)) + updateRequest.ThumbnailPath = thumbnailFileInfo.File; + } + + await _context.DiscountProducts.UpdateDiscountProductImageAsync(updateRequest, cancellationToken: cancellationToken); + + return Unit.Value; + } +} diff --git a/src/BackOffice.BFF.Application/DiscountProductCQ/Queries/GetDiscountProductImages/GetDiscountProductImagesQuery.cs b/src/BackOffice.BFF.Application/DiscountProductCQ/Queries/GetDiscountProductImages/GetDiscountProductImagesQuery.cs new file mode 100644 index 0000000..bfa0112 --- /dev/null +++ b/src/BackOffice.BFF.Application/DiscountProductCQ/Queries/GetDiscountProductImages/GetDiscountProductImagesQuery.cs @@ -0,0 +1,24 @@ +namespace BackOffice.BFF.Application.DiscountProductCQ.Queries.GetDiscountProductImages; + +public class GetDiscountProductImagesQuery : IRequest +{ + public long DiscountProductId { get; set; } + public bool OnlyActive { get; set; } = false; // Admin can see all +} + +public class GetDiscountProductImagesResponseDto +{ + public List Images { get; set; } = new(); +} + +public class DiscountProductImageDto +{ + public long Id { get; set; } + public long DiscountProductId { get; set; } + public string ImagePath { get; set; } = string.Empty; + public string? ThumbnailPath { get; set; } + public string? Title { get; set; } + public string? AltText { get; set; } + public int SortOrder { get; set; } + public bool IsActive { get; set; } +} diff --git a/src/BackOffice.BFF.Application/DiscountProductCQ/Queries/GetDiscountProductImages/GetDiscountProductImagesQueryHandler.cs b/src/BackOffice.BFF.Application/DiscountProductCQ/Queries/GetDiscountProductImages/GetDiscountProductImagesQueryHandler.cs new file mode 100644 index 0000000..3da89d8 --- /dev/null +++ b/src/BackOffice.BFF.Application/DiscountProductCQ/Queries/GetDiscountProductImages/GetDiscountProductImagesQueryHandler.cs @@ -0,0 +1,39 @@ +using CMSMicroservice.Protobuf.Protos.DiscountProduct; + +namespace BackOffice.BFF.Application.DiscountProductCQ.Queries.GetDiscountProductImages; + +public class GetDiscountProductImagesQueryHandler : IRequestHandler +{ + private readonly IApplicationContractContext _context; + + public GetDiscountProductImagesQueryHandler(IApplicationContractContext context) + { + _context = context; + } + + public async Task Handle(GetDiscountProductImagesQuery request, CancellationToken cancellationToken) + { + var grpcRequest = new GetDiscountProductImagesRequest + { + DiscountProductId = request.DiscountProductId, + OnlyActive = request.OnlyActive + }; + + var response = await _context.DiscountProducts.GetDiscountProductImagesAsync(grpcRequest, cancellationToken: cancellationToken); + + return new GetDiscountProductImagesResponseDto + { + Images = response.Images.Select(i => new DiscountProductImageDto + { + Id = i.Id, + DiscountProductId = i.DiscountProductId, + ImagePath = i.ImagePath, + ThumbnailPath = i.ThumbnailPath, + Title = i.Title, + AltText = i.AltText, + SortOrder = i.SortOrder, + IsActive = i.IsActive + }).ToList() + }; + } +} diff --git a/src/BackOffice.BFF.Application/DiscountShoppingCartCQ/Commands/RemoveFromCart/RemoveFromCartCommand.cs b/src/BackOffice.BFF.Application/DiscountShoppingCartCQ/Commands/RemoveFromCart/RemoveFromCartCommand.cs index c433270..6335f2a 100644 --- a/src/BackOffice.BFF.Application/DiscountShoppingCartCQ/Commands/RemoveFromCart/RemoveFromCartCommand.cs +++ b/src/BackOffice.BFF.Application/DiscountShoppingCartCQ/Commands/RemoveFromCart/RemoveFromCartCommand.cs @@ -5,6 +5,6 @@ public record RemoveFromCartCommand : IRequest /// شناسه کاربر public long UserId { get; init; } - /// شناسه آیتم سبد خرید - public long CartItemId { get; init; } + /// شناسه محصول + public long ProductId { get; init; } } diff --git a/src/BackOffice.BFF.Application/DiscountShoppingCartCQ/Commands/RemoveFromCart/RemoveFromCartCommandHandler.cs b/src/BackOffice.BFF.Application/DiscountShoppingCartCQ/Commands/RemoveFromCart/RemoveFromCartCommandHandler.cs index 88c3f29..0f14d7a 100644 --- a/src/BackOffice.BFF.Application/DiscountShoppingCartCQ/Commands/RemoveFromCart/RemoveFromCartCommandHandler.cs +++ b/src/BackOffice.BFF.Application/DiscountShoppingCartCQ/Commands/RemoveFromCart/RemoveFromCartCommandHandler.cs @@ -17,7 +17,7 @@ public class RemoveFromCartCommandHandler : IRequestHandler x.UserId) .GreaterThan(0).WithMessage("شناسه کاربر نامعتبر است"); - RuleFor(x => x.CartItemId) - .GreaterThan(0).WithMessage("شناسه آیتم سبد خرید نامعتبر است"); + RuleFor(x => x.ProductId) + .GreaterThan(0).WithMessage("شناسه محصول نامعتبر است"); } } diff --git a/src/BackOffice.BFF.Application/DiscountShoppingCartCQ/Commands/UpdateCartItemCount/UpdateCartItemCountCommand.cs b/src/BackOffice.BFF.Application/DiscountShoppingCartCQ/Commands/UpdateCartItemCount/UpdateCartItemCountCommand.cs index 1827200..16bb878 100644 --- a/src/BackOffice.BFF.Application/DiscountShoppingCartCQ/Commands/UpdateCartItemCount/UpdateCartItemCountCommand.cs +++ b/src/BackOffice.BFF.Application/DiscountShoppingCartCQ/Commands/UpdateCartItemCount/UpdateCartItemCountCommand.cs @@ -5,8 +5,8 @@ public record UpdateCartItemCountCommand : IRequest /// شناسه کاربر public long UserId { get; init; } - /// شناسه آیتم سبد خرید - public long CartItemId { get; init; } + /// شناسه محصول + public long ProductId { get; init; } /// تعداد جدید public int NewCount { get; init; } diff --git a/src/BackOffice.BFF.Application/DiscountShoppingCartCQ/Commands/UpdateCartItemCount/UpdateCartItemCountCommandHandler.cs b/src/BackOffice.BFF.Application/DiscountShoppingCartCQ/Commands/UpdateCartItemCount/UpdateCartItemCountCommandHandler.cs index 5a9e815..b685233 100644 --- a/src/BackOffice.BFF.Application/DiscountShoppingCartCQ/Commands/UpdateCartItemCount/UpdateCartItemCountCommandHandler.cs +++ b/src/BackOffice.BFF.Application/DiscountShoppingCartCQ/Commands/UpdateCartItemCount/UpdateCartItemCountCommandHandler.cs @@ -17,7 +17,7 @@ public class UpdateCartItemCountCommandHandler : IRequestHandler x.UserId) .GreaterThan(0).WithMessage("شناسه کاربر نامعتبر است"); - RuleFor(x => x.CartItemId) - .GreaterThan(0).WithMessage("شناسه آیتم سبد خرید نامعتبر است"); + RuleFor(x => x.ProductId) + .GreaterThan(0).WithMessage("شناسه محصول نامعتبر است"); RuleFor(x => x.NewCount) .GreaterThan(0).WithMessage("تعداد جدید باید بیشتر از صفر باشد"); diff --git a/src/BackOffice.BFF.Application/DiscountShoppingCartCQ/Queries/GetUserCart/GetUserCartQueryHandler.cs b/src/BackOffice.BFF.Application/DiscountShoppingCartCQ/Queries/GetUserCart/GetUserCartQueryHandler.cs index 48541ed..3bc13b0 100644 --- a/src/BackOffice.BFF.Application/DiscountShoppingCartCQ/Queries/GetUserCart/GetUserCartQueryHandler.cs +++ b/src/BackOffice.BFF.Application/DiscountShoppingCartCQ/Queries/GetUserCart/GetUserCartQueryHandler.cs @@ -19,13 +19,11 @@ public class GetUserCartQueryHandler : IRequestHandler new CartItemDto { - Id = item.Id, ProductId = item.ProductId, ProductTitle = item.ProductTitle, ProductImagePath = item.ProductImagePath, @@ -33,8 +31,10 @@ public class GetUserCartQueryHandler : IRequestHandler Items { get; set; } = new(); + /// جمع کل قیمت (بدون تخفیف) public long TotalPrice { get; set; } - public long TotalDiscountedPrice { get; set; } - public long TotalSavings { get; set; } + /// جمع تخفیف‌ها + public long TotalDiscountAmount { get; set; } + /// قیمت نهایی (با تخفیف) + public long FinalPrice { get; set; } } public class CartItemDto { - public long Id { get; set; } public long ProductId { get; set; } - public string ProductTitle { get; set; } - public string ProductImagePath { get; set; } + public string ProductTitle { get; set; } = string.Empty; + public string ProductImagePath { get; set; } = string.Empty; public long UnitPrice { get; set; } public int MaxDiscountPercent { get; set; } public int Count { get; set; } public long TotalPrice { get; set; } - public long DiscountedPrice { get; set; } - public DateTime AddedAt { get; set; } + /// مبلغ تخفیف + public long DiscountAmount { get; set; } + /// قیمت نهایی آیتم + public long FinalPrice { get; set; } + public int ProductRemainingCount { get; set; } + public DateTime Created { get; set; } } diff --git a/src/BackOffice.BFF.Application/ProductTagCQ/Commands/DeleteProductTag/DeleteProductTagCommand.cs b/src/BackOffice.BFF.Application/ProductTagCQ/Commands/DeleteProductTag/DeleteProductTagCommand.cs new file mode 100644 index 0000000..2c39edf --- /dev/null +++ b/src/BackOffice.BFF.Application/ProductTagCQ/Commands/DeleteProductTag/DeleteProductTagCommand.cs @@ -0,0 +1,6 @@ +namespace BackOffice.BFF.Application.ProductTagCQ.Commands.DeleteProductTag; + +public record DeleteProductTagCommand : IRequest +{ + public long Id { get; init; } +} diff --git a/src/BackOffice.BFF.Application/ProductTagCQ/Commands/DeleteProductTag/DeleteProductTagCommandHandler.cs b/src/BackOffice.BFF.Application/ProductTagCQ/Commands/DeleteProductTag/DeleteProductTagCommandHandler.cs new file mode 100644 index 0000000..22ff6a4 --- /dev/null +++ b/src/BackOffice.BFF.Application/ProductTagCQ/Commands/DeleteProductTag/DeleteProductTagCommandHandler.cs @@ -0,0 +1,25 @@ +using CMSMicroservice.Protobuf.Protos.ProductTag; + +namespace BackOffice.BFF.Application.ProductTagCQ.Commands.DeleteProductTag; + +public class DeleteProductTagCommandHandler : IRequestHandler +{ + private readonly IApplicationContractContext _context; + + public DeleteProductTagCommandHandler(IApplicationContractContext context) + { + _context = context; + } + + public async Task Handle(DeleteProductTagCommand request, CancellationToken cancellationToken) + { + await _context.ProductTags.DeleteProductTagAsync( + new DeleteProductTagRequest + { + Id = request.Id + }, + cancellationToken: cancellationToken); + + return Unit.Value; + } +} diff --git a/src/BackOffice.BFF.Application/ProductTagCQ/Commands/UpdateProductTag/UpdateProductTagCommand.cs b/src/BackOffice.BFF.Application/ProductTagCQ/Commands/UpdateProductTag/UpdateProductTagCommand.cs new file mode 100644 index 0000000..e4e425c --- /dev/null +++ b/src/BackOffice.BFF.Application/ProductTagCQ/Commands/UpdateProductTag/UpdateProductTagCommand.cs @@ -0,0 +1,8 @@ +namespace BackOffice.BFF.Application.ProductTagCQ.Commands.UpdateProductTag; + +public record UpdateProductTagCommand : IRequest +{ + public long Id { get; init; } + public long ProductId { get; init; } + public long TagId { get; init; } +} diff --git a/src/BackOffice.BFF.Application/ProductTagCQ/Commands/UpdateProductTag/UpdateProductTagCommandHandler.cs b/src/BackOffice.BFF.Application/ProductTagCQ/Commands/UpdateProductTag/UpdateProductTagCommandHandler.cs new file mode 100644 index 0000000..cbd9edd --- /dev/null +++ b/src/BackOffice.BFF.Application/ProductTagCQ/Commands/UpdateProductTag/UpdateProductTagCommandHandler.cs @@ -0,0 +1,27 @@ +using CMSMicroservice.Protobuf.Protos.ProductTag; + +namespace BackOffice.BFF.Application.ProductTagCQ.Commands.UpdateProductTag; + +public class UpdateProductTagCommandHandler : IRequestHandler +{ + private readonly IApplicationContractContext _context; + + public UpdateProductTagCommandHandler(IApplicationContractContext context) + { + _context = context; + } + + public async Task Handle(UpdateProductTagCommand request, CancellationToken cancellationToken) + { + await _context.ProductTags.UpdateProductTagAsync( + new UpdateProductTagRequest + { + Id = request.Id, + ProductId = request.ProductId, + TagId = request.TagId + }, + cancellationToken: cancellationToken); + + return Unit.Value; + } +} diff --git a/src/BackOffice.BFF.Application/ProductTagCQ/Queries/GetAllProductTags/GetAllProductTagsQuery.cs b/src/BackOffice.BFF.Application/ProductTagCQ/Queries/GetAllProductTags/GetAllProductTagsQuery.cs new file mode 100644 index 0000000..915ec0f --- /dev/null +++ b/src/BackOffice.BFF.Application/ProductTagCQ/Queries/GetAllProductTags/GetAllProductTagsQuery.cs @@ -0,0 +1,23 @@ +namespace BackOffice.BFF.Application.ProductTagCQ.Queries.GetAllProductTags; + +public record GetAllProductTagsQuery : IRequest +{ + public int PageNumber { get; init; } = 1; + public int PageSize { get; init; } = 10; + public string? SortBy { get; init; } + public long? ProductId { get; init; } + public long? TagId { get; init; } +} + +public record GetAllProductTagsResponseDto +{ + public MetaData MetaData { get; init; } = default!; + public List Items { get; init; } = new(); +} + +public record ProductTagItemDto +{ + public long Id { get; init; } + public long ProductId { get; init; } + public long TagId { get; init; } +} diff --git a/src/BackOffice.BFF.Application/ProductTagCQ/Queries/GetAllProductTags/GetAllProductTagsQueryHandler.cs b/src/BackOffice.BFF.Application/ProductTagCQ/Queries/GetAllProductTags/GetAllProductTagsQueryHandler.cs new file mode 100644 index 0000000..a46d702 --- /dev/null +++ b/src/BackOffice.BFF.Application/ProductTagCQ/Queries/GetAllProductTags/GetAllProductTagsQueryHandler.cs @@ -0,0 +1,51 @@ +using CMSMicroservice.Protobuf.Protos.ProductTag; +using CmsPaginationState = CMSMicroservice.Protobuf.Protos.PaginationState; + +namespace BackOffice.BFF.Application.ProductTagCQ.Queries.GetAllProductTags; + +public class GetAllProductTagsQueryHandler : IRequestHandler +{ + private readonly IApplicationContractContext _context; + + public GetAllProductTagsQueryHandler(IApplicationContractContext context) + { + _context = context; + } + + public async Task Handle(GetAllProductTagsQuery request, CancellationToken cancellationToken) + { + var response = await _context.ProductTags.GetAllProductTagByFilterAsync( + new GetAllProductTagByFilterRequest + { + PaginationState = new CmsPaginationState + { + PageNumber = request.PageNumber, + PageSize = request.PageSize + }, + SortBy = request.SortBy ?? "", + Filter = new GetAllProductTagByFilterFilter + { + ProductId = request.ProductId ?? 0, + TagId = request.TagId ?? 0 + } + }, + cancellationToken: cancellationToken); + + return new GetAllProductTagsResponseDto + { + MetaData = new MetaData + { + CurrentPage = response.MetaData.CurrentPage, + PageSize = response.MetaData.PageSize, + TotalCount = response.MetaData.TotalCount, + TotalPage = response.MetaData.TotalPage + }, + Items = response.Models.Select(pt => new ProductTagItemDto + { + Id = pt.Id, + ProductId = pt.ProductId, + TagId = pt.TagId + }).ToList() + }; + } +} diff --git a/src/BackOffice.BFF.Application/ProductTagCQ/Queries/GetProductTag/GetProductTagQuery.cs b/src/BackOffice.BFF.Application/ProductTagCQ/Queries/GetProductTag/GetProductTagQuery.cs new file mode 100644 index 0000000..f1161ff --- /dev/null +++ b/src/BackOffice.BFF.Application/ProductTagCQ/Queries/GetProductTag/GetProductTagQuery.cs @@ -0,0 +1,13 @@ +namespace BackOffice.BFF.Application.ProductTagCQ.Queries.GetProductTag; + +public record GetProductTagQuery : IRequest +{ + public long Id { get; init; } +} + +public record GetProductTagResponseDto +{ + public long Id { get; init; } + public long ProductId { get; init; } + public long TagId { get; init; } +} diff --git a/src/BackOffice.BFF.Application/ProductTagCQ/Queries/GetProductTag/GetProductTagQueryHandler.cs b/src/BackOffice.BFF.Application/ProductTagCQ/Queries/GetProductTag/GetProductTagQueryHandler.cs new file mode 100644 index 0000000..ca4737f --- /dev/null +++ b/src/BackOffice.BFF.Application/ProductTagCQ/Queries/GetProductTag/GetProductTagQueryHandler.cs @@ -0,0 +1,30 @@ +using CMSMicroservice.Protobuf.Protos.ProductTag; + +namespace BackOffice.BFF.Application.ProductTagCQ.Queries.GetProductTag; + +public class GetProductTagQueryHandler : IRequestHandler +{ + private readonly IApplicationContractContext _context; + + public GetProductTagQueryHandler(IApplicationContractContext context) + { + _context = context; + } + + public async Task Handle(GetProductTagQuery request, CancellationToken cancellationToken) + { + var response = await _context.ProductTags.GetProductTagAsync( + new GetProductTagRequest + { + Id = request.Id + }, + cancellationToken: cancellationToken); + + return new GetProductTagResponseDto + { + Id = response.Id, + ProductId = response.ProductId, + TagId = response.TagId + }; + } +} diff --git a/src/BackOffice.BFF.Domain/BackOffice.BFF.Domain.csproj b/src/BackOffice.BFF.Domain/BackOffice.BFF.Domain.csproj index 35db127..a1e62ee 100644 --- a/src/BackOffice.BFF.Domain/BackOffice.BFF.Domain.csproj +++ b/src/BackOffice.BFF.Domain/BackOffice.BFF.Domain.csproj @@ -7,7 +7,7 @@ - + diff --git a/src/BackOffice.BFF.WebApi/BackOffice.BFF.WebApi.csproj b/src/BackOffice.BFF.WebApi/BackOffice.BFF.WebApi.csproj index 795a1dc..6ac4fec 100644 --- a/src/BackOffice.BFF.WebApi/BackOffice.BFF.WebApi.csproj +++ b/src/BackOffice.BFF.WebApi/BackOffice.BFF.WebApi.csproj @@ -42,6 +42,12 @@ + + + + + + diff --git a/src/BackOffice.BFF.WebApi/Services/DiscountCategoryService.cs b/src/BackOffice.BFF.WebApi/Services/DiscountCategoryService.cs new file mode 100644 index 0000000..4a26056 --- /dev/null +++ b/src/BackOffice.BFF.WebApi/Services/DiscountCategoryService.cs @@ -0,0 +1,38 @@ +using BackOffice.BFF.DiscountCategory.Protobuf.Protos.DiscountCategory; +using BackOffice.BFF.WebApi.Common.Services; +using BackOffice.BFF.Application.DiscountCategoryCQ.Commands.CreateDiscountCategory; +using BackOffice.BFF.Application.DiscountCategoryCQ.Commands.UpdateDiscountCategory; +using BackOffice.BFF.Application.DiscountCategoryCQ.Commands.DeleteDiscountCategory; +using BackOffice.BFF.Application.DiscountCategoryCQ.Queries.GetDiscountCategories; + +namespace BackOffice.BFF.WebApi.Services; + +public class DiscountCategoryService : DiscountCategoryContract.DiscountCategoryContractBase +{ + private readonly IDispatchRequestToCQRS _dispatchRequestToCQRS; + + public DiscountCategoryService(IDispatchRequestToCQRS dispatchRequestToCQRS) + { + _dispatchRequestToCQRS = dispatchRequestToCQRS; + } + + public override async Task CreateDiscountCategory(CreateDiscountCategoryRequest request, ServerCallContext context) + { + return await _dispatchRequestToCQRS.Handle(request, context); + } + + public override async Task UpdateDiscountCategory(UpdateDiscountCategoryRequest request, ServerCallContext context) + { + return await _dispatchRequestToCQRS.Handle(request, context); + } + + public override async Task DeleteDiscountCategory(DeleteDiscountCategoryRequest request, ServerCallContext context) + { + return await _dispatchRequestToCQRS.Handle(request, context); + } + + public override async Task GetDiscountCategories(GetDiscountCategoriesRequest request, ServerCallContext context) + { + return await _dispatchRequestToCQRS.Handle(request, context); + } +} diff --git a/src/BackOffice.BFF.WebApi/Services/DiscountOrderService.cs b/src/BackOffice.BFF.WebApi/Services/DiscountOrderService.cs new file mode 100644 index 0000000..a89ff8b --- /dev/null +++ b/src/BackOffice.BFF.WebApi/Services/DiscountOrderService.cs @@ -0,0 +1,59 @@ +using BackOffice.BFF.DiscountOrder.Protobuf.Protos.DiscountOrder; +using BackOffice.BFF.WebApi.Common.Services; +using BackOffice.BFF.Application.DiscountOrderCQ.Commands.PlaceOrder; +using BackOffice.BFF.Application.DiscountOrderCQ.Commands.CompleteOrderPayment; +using BackOffice.BFF.Application.DiscountOrderCQ.Commands.UpdateOrderStatus; +using BackOffice.BFF.Application.DiscountOrderCQ.Queries.GetOrderById; +using BackOffice.BFF.Application.DiscountOrderCQ.Queries.GetUserOrders; +using BackOffice.BFF.Application.DiscountOrderCQ.Queries.GetAllDiscountOrders; +using BackOffice.BFF.Application.DiscountOrderCQ.Queries.GetDiscountSalesReport; + +namespace BackOffice.BFF.WebApi.Services; + +public class DiscountOrderService : DiscountOrderContract.DiscountOrderContractBase +{ + private readonly IDispatchRequestToCQRS _dispatchRequestToCQRS; + + public DiscountOrderService(IDispatchRequestToCQRS dispatchRequestToCQRS) + { + _dispatchRequestToCQRS = dispatchRequestToCQRS; + } + + // Order Management + public override async Task PlaceOrder(PlaceOrderRequest request, ServerCallContext context) + { + return await _dispatchRequestToCQRS.Handle(request, context); + } + + public override async Task CompleteOrderPayment(CompleteOrderPaymentRequest request, ServerCallContext context) + { + return await _dispatchRequestToCQRS.Handle(request, context); + } + + public override async Task UpdateOrderStatus(UpdateOrderStatusRequest request, ServerCallContext context) + { + return await _dispatchRequestToCQRS.Handle(request, context); + } + + // Order Queries + public override async Task GetOrderById(GetOrderByIdRequest request, ServerCallContext context) + { + return await _dispatchRequestToCQRS.Handle(request, context); + } + + public override async Task GetUserOrders(GetUserOrdersRequest request, ServerCallContext context) + { + return await _dispatchRequestToCQRS.Handle(request, context); + } + + // Admin APIs + public override async Task GetAllDiscountOrders(GetAllDiscountOrdersRequest request, ServerCallContext context) + { + return await _dispatchRequestToCQRS.Handle(request, context); + } + + public override async Task GetDiscountSalesReport(GetDiscountSalesReportRequest request, ServerCallContext context) + { + return await _dispatchRequestToCQRS.Handle(request, context); + } +} diff --git a/src/BackOffice.BFF.WebApi/Services/DiscountProductService.cs b/src/BackOffice.BFF.WebApi/Services/DiscountProductService.cs new file mode 100644 index 0000000..b13208e --- /dev/null +++ b/src/BackOffice.BFF.WebApi/Services/DiscountProductService.cs @@ -0,0 +1,76 @@ +using BackOffice.BFF.DiscountProduct.Protobuf.Protos.DiscountProduct; +using BackOffice.BFF.WebApi.Common.Services; +using BackOffice.BFF.Application.DiscountProductCQ.Commands.CreateDiscountProduct; +using BackOffice.BFF.Application.DiscountProductCQ.Commands.UpdateDiscountProduct; +using BackOffice.BFF.Application.DiscountProductCQ.Commands.DeleteDiscountProduct; +using BackOffice.BFF.Application.DiscountProductCQ.Commands.AddDiscountProductImage; +using BackOffice.BFF.Application.DiscountProductCQ.Commands.UpdateDiscountProductImage; +using BackOffice.BFF.Application.DiscountProductCQ.Commands.DeleteDiscountProductImage; +using BackOffice.BFF.Application.DiscountProductCQ.Commands.ReorderDiscountProductImages; +using BackOffice.BFF.Application.DiscountProductCQ.Queries.GetDiscountProductById; +using BackOffice.BFF.Application.DiscountProductCQ.Queries.GetDiscountProducts; +using BackOffice.BFF.Application.DiscountProductCQ.Queries.GetDiscountProductImages; + +namespace BackOffice.BFF.WebApi.Services; + +public class DiscountProductService : DiscountProductContract.DiscountProductContractBase +{ + private readonly IDispatchRequestToCQRS _dispatchRequestToCQRS; + + public DiscountProductService(IDispatchRequestToCQRS dispatchRequestToCQRS) + { + _dispatchRequestToCQRS = dispatchRequestToCQRS; + } + + // Product CRUD + public override async Task CreateDiscountProduct(CreateDiscountProductRequest request, ServerCallContext context) + { + return await _dispatchRequestToCQRS.Handle(request, context); + } + + public override async Task UpdateDiscountProduct(UpdateDiscountProductRequest request, ServerCallContext context) + { + return await _dispatchRequestToCQRS.Handle(request, context); + } + + public override async Task DeleteDiscountProduct(DeleteDiscountProductRequest request, ServerCallContext context) + { + return await _dispatchRequestToCQRS.Handle(request, context); + } + + public override async Task GetDiscountProductById(GetDiscountProductByIdRequest request, ServerCallContext context) + { + return await _dispatchRequestToCQRS.Handle(request, context); + } + + public override async Task GetDiscountProducts(GetDiscountProductsRequest request, ServerCallContext context) + { + return await _dispatchRequestToCQRS.Handle(request, context); + } + + // Product Image Gallery + public override async Task AddDiscountProductImage(AddDiscountProductImageRequest request, ServerCallContext context) + { + return await _dispatchRequestToCQRS.Handle(request, context); + } + + public override async Task UpdateDiscountProductImage(UpdateDiscountProductImageRequest request, ServerCallContext context) + { + return await _dispatchRequestToCQRS.Handle(request, context); + } + + public override async Task DeleteDiscountProductImage(DeleteDiscountProductImageRequest request, ServerCallContext context) + { + return await _dispatchRequestToCQRS.Handle(request, context); + } + + public override async Task ReorderDiscountProductImages(ReorderDiscountProductImagesRequest request, ServerCallContext context) + { + return await _dispatchRequestToCQRS.Handle(request, context); + } + + public override async Task GetDiscountProductImages(GetDiscountProductImagesRequest request, ServerCallContext context) + { + return await _dispatchRequestToCQRS.Handle(request, context); + } +} diff --git a/src/BackOffice.BFF.WebApi/Services/DiscountShoppingCartService.cs b/src/BackOffice.BFF.WebApi/Services/DiscountShoppingCartService.cs new file mode 100644 index 0000000..65e12bd --- /dev/null +++ b/src/BackOffice.BFF.WebApi/Services/DiscountShoppingCartService.cs @@ -0,0 +1,44 @@ +using BackOffice.BFF.DiscountShoppingCart.Protobuf.Protos.DiscountShoppingCart; +using BackOffice.BFF.WebApi.Common.Services; +using BackOffice.BFF.Application.DiscountShoppingCartCQ.Commands.AddToCart; +using BackOffice.BFF.Application.DiscountShoppingCartCQ.Commands.RemoveFromCart; +using BackOffice.BFF.Application.DiscountShoppingCartCQ.Commands.UpdateCartItemCount; +using BackOffice.BFF.Application.DiscountShoppingCartCQ.Commands.ClearCart; +using BackOffice.BFF.Application.DiscountShoppingCartCQ.Queries.GetUserCart; + +namespace BackOffice.BFF.WebApi.Services; + +public class DiscountShoppingCartService : DiscountShoppingCartContract.DiscountShoppingCartContractBase +{ + private readonly IDispatchRequestToCQRS _dispatchRequestToCQRS; + + public DiscountShoppingCartService(IDispatchRequestToCQRS dispatchRequestToCQRS) + { + _dispatchRequestToCQRS = dispatchRequestToCQRS; + } + + public override async Task AddToCart(AddToCartRequest request, ServerCallContext context) + { + return await _dispatchRequestToCQRS.Handle(request, context); + } + + public override async Task RemoveFromCart(RemoveFromCartRequest request, ServerCallContext context) + { + return await _dispatchRequestToCQRS.Handle(request, context); + } + + public override async Task UpdateCartItemCount(UpdateCartItemCountRequest request, ServerCallContext context) + { + return await _dispatchRequestToCQRS.Handle(request, context); + } + + public override async Task GetUserCart(GetUserCartRequest request, ServerCallContext context) + { + return await _dispatchRequestToCQRS.Handle(request, context); + } + + public override async Task ClearCart(ClearCartRequest request, ServerCallContext context) + { + return await _dispatchRequestToCQRS.Handle(request, context); + } +} diff --git a/src/BackOffice.BFF.WebApi/Services/ProductTagService.cs b/src/BackOffice.BFF.WebApi/Services/ProductTagService.cs new file mode 100644 index 0000000..9abde67 --- /dev/null +++ b/src/BackOffice.BFF.WebApi/Services/ProductTagService.cs @@ -0,0 +1,44 @@ +using BackOffice.BFF.ProductTag.Protobuf.Protos.ProductTag; +using BackOffice.BFF.WebApi.Common.Services; +using BackOffice.BFF.Application.ProductTagCQ.Commands.AssignTagToProduct; +using BackOffice.BFF.Application.ProductTagCQ.Commands.UpdateProductTag; +using BackOffice.BFF.Application.ProductTagCQ.Commands.DeleteProductTag; +using BackOffice.BFF.Application.ProductTagCQ.Queries.GetProductTag; +using BackOffice.BFF.Application.ProductTagCQ.Queries.GetAllProductTags; + +namespace BackOffice.BFF.WebApi.Services; + +public class ProductTagService : ProductTagContract.ProductTagContractBase +{ + private readonly IDispatchRequestToCQRS _dispatchRequestToCQRS; + + public ProductTagService(IDispatchRequestToCQRS dispatchRequestToCQRS) + { + _dispatchRequestToCQRS = dispatchRequestToCQRS; + } + + public override async Task CreateNewProductTag(CreateNewProductTagRequest request, ServerCallContext context) + { + return await _dispatchRequestToCQRS.Handle(request, context); + } + + public override async Task UpdateProductTag(UpdateProductTagRequest request, ServerCallContext context) + { + return await _dispatchRequestToCQRS.Handle(request, context); + } + + public override async Task DeleteProductTag(DeleteProductTagRequest request, ServerCallContext context) + { + return await _dispatchRequestToCQRS.Handle(request, context); + } + + public override async Task GetProductTag(GetProductTagRequest request, ServerCallContext context) + { + return await _dispatchRequestToCQRS.Handle(request, context); + } + + public override async Task GetAllProductTagByFilter(GetAllProductTagByFilterRequest request, ServerCallContext context) + { + return await _dispatchRequestToCQRS.Handle(request, context); + } +} diff --git a/src/BackOffice.BFF.WebApi/Services/TagService.cs b/src/BackOffice.BFF.WebApi/Services/TagService.cs new file mode 100644 index 0000000..54b0ffe --- /dev/null +++ b/src/BackOffice.BFF.WebApi/Services/TagService.cs @@ -0,0 +1,50 @@ +using BackOffice.BFF.Tag.Protobuf.Protos.Tag; +using BackOffice.BFF.WebApi.Common.Services; +using BackOffice.BFF.Application.TagCQ.Commands.CreateTag; +using BackOffice.BFF.Application.TagCQ.Commands.UpdateTag; +using BackOffice.BFF.Application.TagCQ.Commands.DeleteTag; +using BackOffice.BFF.Application.TagCQ.Queries.GetTag; +using BackOffice.BFF.Application.TagCQ.Queries.GetAllTags; +using BackOffice.BFF.Application.TagCQ.Queries.GetProductsByTag; + +namespace BackOffice.BFF.WebApi.Services; + +public class TagService : TagContract.TagContractBase +{ + private readonly IDispatchRequestToCQRS _dispatchRequestToCQRS; + + public TagService(IDispatchRequestToCQRS dispatchRequestToCQRS) + { + _dispatchRequestToCQRS = dispatchRequestToCQRS; + } + + public override async Task CreateNewTag(CreateNewTagRequest request, ServerCallContext context) + { + return await _dispatchRequestToCQRS.Handle(request, context); + } + + public override async Task UpdateTag(UpdateTagRequest request, ServerCallContext context) + { + return await _dispatchRequestToCQRS.Handle(request, context); + } + + public override async Task DeleteTag(DeleteTagRequest request, ServerCallContext context) + { + return await _dispatchRequestToCQRS.Handle(request, context); + } + + public override async Task GetTag(GetTagRequest request, ServerCallContext context) + { + return await _dispatchRequestToCQRS.Handle(request, context); + } + + public override async Task GetAllTagByFilter(GetAllTagByFilterRequest request, ServerCallContext context) + { + return await _dispatchRequestToCQRS.Handle(request, context); + } + + public override async Task GetProductsByTag(GetProductsByTagRequest request, ServerCallContext context) + { + return await _dispatchRequestToCQRS.Handle(request, context); + } +} diff --git a/src/Protobufs/BackOffice.BFF.DiscountCategory.Protobuf/BackOffice.BFF.DiscountCategory.Protobuf.csproj b/src/Protobufs/BackOffice.BFF.DiscountCategory.Protobuf/BackOffice.BFF.DiscountCategory.Protobuf.csproj index 7dbc522..3197da1 100644 --- a/src/Protobufs/BackOffice.BFF.DiscountCategory.Protobuf/BackOffice.BFF.DiscountCategory.Protobuf.csproj +++ b/src/Protobufs/BackOffice.BFF.DiscountCategory.Protobuf/BackOffice.BFF.DiscountCategory.Protobuf.csproj @@ -4,7 +4,7 @@ net9.0 enable enable - 0.0.3 + 0.0.4 None False False @@ -23,7 +23,7 @@ - + diff --git a/src/Protobufs/BackOffice.BFF.DiscountOrder.Protobuf/BackOffice.BFF.DiscountOrder.Protobuf.csproj b/src/Protobufs/BackOffice.BFF.DiscountOrder.Protobuf/BackOffice.BFF.DiscountOrder.Protobuf.csproj index 8a3a42b..9ee5ea2 100644 --- a/src/Protobufs/BackOffice.BFF.DiscountOrder.Protobuf/BackOffice.BFF.DiscountOrder.Protobuf.csproj +++ b/src/Protobufs/BackOffice.BFF.DiscountOrder.Protobuf/BackOffice.BFF.DiscountOrder.Protobuf.csproj @@ -4,7 +4,7 @@ net9.0 enable enable - 0.0.3 + 0.0.4 None False False @@ -23,7 +23,7 @@ - + diff --git a/src/Protobufs/BackOffice.BFF.DiscountOrder.Protobuf/Protos/discountorder.proto b/src/Protobufs/BackOffice.BFF.DiscountOrder.Protobuf/Protos/discountorder.proto index 5739e9d..aa8aa8d 100644 --- a/src/Protobufs/BackOffice.BFF.DiscountOrder.Protobuf/Protos/discountorder.proto +++ b/src/Protobufs/BackOffice.BFF.DiscountOrder.Protobuf/Protos/discountorder.proto @@ -40,6 +40,20 @@ service DiscountOrderContract get: "/GetUserOrders" }; }; + + // Admin: Get All Discount Orders with filters + rpc GetAllDiscountOrders(GetAllDiscountOrdersRequest) returns (GetAllDiscountOrdersResponse){ + option (google.api.http) = { + get: "/GetAllDiscountOrders" + }; + }; + + // Admin: Get Sales Report + rpc GetDiscountSalesReport(GetDiscountSalesReportRequest) returns (GetDiscountSalesReportResponse){ + option (google.api.http) = { + get: "/GetDiscountSalesReport" + }; + }; } // Place Order (Initial Step - Create Order) @@ -175,3 +189,118 @@ message OrderSummaryDto int32 items_count = 9; google.protobuf.Timestamp created = 10; } + +// ===== Admin: Get All Discount Orders ===== + +message GetAllDiscountOrdersRequest +{ + google.protobuf.Int64Value user_id = 1; + google.protobuf.Int32Value payment_status = 2; + google.protobuf.Int32Value delivery_status = 3; + google.protobuf.StringValue user_mobile = 4; + google.protobuf.StringValue tracking_code = 5; + google.protobuf.Timestamp from_date = 6; + google.protobuf.Timestamp to_date = 7; + google.protobuf.Int64Value min_amount = 8; + google.protobuf.Int64Value max_amount = 9; + int32 page_number = 10; + int32 page_size = 11; +} + +message GetAllDiscountOrdersResponse +{ + messages.MetaData meta_data = 1; + repeated AdminOrderDto models = 2; +} + +message AdminOrderDto +{ + int64 id = 1; + int64 user_id = 2; + string user_full_name = 3; + string user_mobile = 4; + int64 total_amount = 5; + int64 discount_balance_used = 6; + int64 gateway_amount_paid = 7; + int64 vat_amount = 8; + PaymentStatus payment_status = 9; + google.protobuf.Timestamp payment_date = 10; + DeliveryStatus delivery_status = 11; + google.protobuf.Timestamp delivery_date = 12; + google.protobuf.StringValue shipping_address = 13; + google.protobuf.StringValue receiver_name = 14; + google.protobuf.StringValue receiver_mobile = 15; + google.protobuf.StringValue tracking_code = 16; + google.protobuf.StringValue admin_note = 17; + google.protobuf.Timestamp created = 18; + google.protobuf.Timestamp last_modified = 19; + int32 items_count = 20; +} + +enum PaymentStatus +{ + PAYMENT_PENDING = 0; + PAYMENT_COMPLETED = 1; + PAYMENT_FAILED = 2; + PAYMENT_REFUNDED = 3; +} + +// ===== Sales Report Messages ===== + +enum SalesReportType +{ + REPORT_SUMMARY = 0; + REPORT_DAILY = 1; + REPORT_WEEKLY = 2; + REPORT_MONTHLY = 3; +} + +message GetDiscountSalesReportRequest +{ + google.protobuf.Timestamp from_date = 1; + google.protobuf.Timestamp to_date = 2; + SalesReportType report_type = 3; +} + +message GetDiscountSalesReportResponse +{ + SalesSummary summary = 1; + repeated SalesPeriodDto periods = 2; + repeated TopSellingProductDto top_products = 3; +} + +message SalesSummary +{ + int32 total_orders = 1; + int32 completed_orders = 2; + int32 pending_orders = 3; + int32 cancelled_orders = 4; + int64 total_sales_amount = 5; + int64 total_discount_used = 6; + int64 total_gateway_paid = 7; + int64 total_vat_amount = 8; + int64 average_order_value = 9; + int32 unique_customers = 10; + int32 total_products_sold = 11; +} + +message SalesPeriodDto +{ + string period_label = 1; + google.protobuf.Timestamp period_start = 2; + google.protobuf.Timestamp period_end = 3; + int32 orders_count = 4; + int64 total_amount = 5; + int64 discount_used = 6; + int64 gateway_paid = 7; +} + +message TopSellingProductDto +{ + int64 product_id = 1; + string product_title = 2; + google.protobuf.StringValue image_path = 3; + int32 quantity_sold = 4; + int64 total_revenue = 5; + int32 orders_count = 6; +} diff --git a/src/Protobufs/BackOffice.BFF.DiscountProduct.Protobuf/BackOffice.BFF.DiscountProduct.Protobuf.csproj b/src/Protobufs/BackOffice.BFF.DiscountProduct.Protobuf/BackOffice.BFF.DiscountProduct.Protobuf.csproj index dcd57ad..39c585c 100644 --- a/src/Protobufs/BackOffice.BFF.DiscountProduct.Protobuf/BackOffice.BFF.DiscountProduct.Protobuf.csproj +++ b/src/Protobufs/BackOffice.BFF.DiscountProduct.Protobuf/BackOffice.BFF.DiscountProduct.Protobuf.csproj @@ -4,7 +4,7 @@ net9.0 enable enable - 0.0.3 + 0.0.4 None False False @@ -23,7 +23,7 @@ - + diff --git a/src/Protobufs/BackOffice.BFF.DiscountProduct.Protobuf/Protos/discountproduct.proto b/src/Protobufs/BackOffice.BFF.DiscountProduct.Protobuf/Protos/discountproduct.proto index b513a12..98d3a31 100644 --- a/src/Protobufs/BackOffice.BFF.DiscountProduct.Protobuf/Protos/discountproduct.proto +++ b/src/Protobufs/BackOffice.BFF.DiscountProduct.Protobuf/Protos/discountproduct.proto @@ -40,6 +40,37 @@ service DiscountProductContract get: "/GetDiscountProducts" }; }; + + // Product Image Gallery Operations + rpc AddDiscountProductImage(AddDiscountProductImageRequest) returns (AddDiscountProductImageResponse){ + option (google.api.http) = { + post: "/AddDiscountProductImage" + body: "*" + }; + }; + rpc UpdateDiscountProductImage(UpdateDiscountProductImageRequest) returns (google.protobuf.Empty){ + option (google.api.http) = { + put: "/UpdateDiscountProductImage" + body: "*" + }; + }; + rpc DeleteDiscountProductImage(DeleteDiscountProductImageRequest) returns (google.protobuf.Empty){ + option (google.api.http) = { + delete: "/DeleteDiscountProductImage" + body: "*" + }; + }; + rpc ReorderDiscountProductImages(ReorderDiscountProductImagesRequest) returns (google.protobuf.Empty){ + option (google.api.http) = { + put: "/ReorderDiscountProductImages" + body: "*" + }; + }; + rpc GetDiscountProductImages(GetDiscountProductImagesRequest) returns (GetDiscountProductImagesResponse){ + option (google.api.http) = { + get: "/GetDiscountProductImages" + }; + }; } // Create Product @@ -150,3 +181,68 @@ message DiscountProductDto bool is_active = 10; google.protobuf.Timestamp created = 11; } + +// ===== Product Image Gallery Messages ===== + +// Add Product Image +message AddDiscountProductImageRequest +{ + int64 discount_product_id = 1; + string image_path = 2; + string thumbnail_path = 3; + google.protobuf.StringValue title = 4; + google.protobuf.StringValue alt_text = 5; +} + +message AddDiscountProductImageResponse +{ + int64 image_id = 1; +} + +// Update Product Image +message UpdateDiscountProductImageRequest +{ + int64 id = 1; + string image_path = 2; + string thumbnail_path = 3; + google.protobuf.StringValue title = 4; + google.protobuf.StringValue alt_text = 5; + bool is_active = 6; +} + +// Delete Product Image +message DeleteDiscountProductImageRequest +{ + int64 id = 1; +} + +// Reorder Product Images +message ReorderDiscountProductImagesRequest +{ + int64 discount_product_id = 1; + repeated int64 image_ids = 2; +} + +// Get Product Images +message GetDiscountProductImagesRequest +{ + int64 discount_product_id = 1; + bool only_active = 2; +} + +message GetDiscountProductImagesResponse +{ + repeated DiscountProductImageDto images = 1; +} + +message DiscountProductImageDto +{ + int64 id = 1; + int64 discount_product_id = 2; + string image_path = 3; + string thumbnail_path = 4; + google.protobuf.StringValue title = 5; + google.protobuf.StringValue alt_text = 6; + int32 sort_order = 7; + bool is_active = 8; +} diff --git a/src/Protobufs/BackOffice.BFF.DiscountShoppingCart.Protobuf/BackOffice.BFF.DiscountShoppingCart.Protobuf.csproj b/src/Protobufs/BackOffice.BFF.DiscountShoppingCart.Protobuf/BackOffice.BFF.DiscountShoppingCart.Protobuf.csproj index 456a1bf..e8ab89b 100644 --- a/src/Protobufs/BackOffice.BFF.DiscountShoppingCart.Protobuf/BackOffice.BFF.DiscountShoppingCart.Protobuf.csproj +++ b/src/Protobufs/BackOffice.BFF.DiscountShoppingCart.Protobuf/BackOffice.BFF.DiscountShoppingCart.Protobuf.csproj @@ -4,7 +4,7 @@ net9.0 enable enable - 0.0.3 + 0.0.4 None False False @@ -23,7 +23,7 @@ - + diff --git a/src/Protobufs/BackOffice.BFF.ProductTag.Protobuf/BackOffice.BFF.ProductTag.Protobuf.csproj b/src/Protobufs/BackOffice.BFF.ProductTag.Protobuf/BackOffice.BFF.ProductTag.Protobuf.csproj index b0beca3..87fbe5b 100644 --- a/src/Protobufs/BackOffice.BFF.ProductTag.Protobuf/BackOffice.BFF.ProductTag.Protobuf.csproj +++ b/src/Protobufs/BackOffice.BFF.ProductTag.Protobuf/BackOffice.BFF.ProductTag.Protobuf.csproj @@ -4,7 +4,7 @@ net9.0 enable enable - 0.0.3 + 0.0.4 None False False @@ -23,7 +23,7 @@ - + diff --git a/src/Protobufs/BackOffice.BFF.Tag.Protobuf/BackOffice.BFF.Tag.Protobuf.csproj b/src/Protobufs/BackOffice.BFF.Tag.Protobuf/BackOffice.BFF.Tag.Protobuf.csproj index 5376490..7188d16 100644 --- a/src/Protobufs/BackOffice.BFF.Tag.Protobuf/BackOffice.BFF.Tag.Protobuf.csproj +++ b/src/Protobufs/BackOffice.BFF.Tag.Protobuf/BackOffice.BFF.Tag.Protobuf.csproj @@ -4,7 +4,7 @@ net9.0 enable enable - 0.0.4 + 0.0.5 None False False @@ -23,7 +23,7 @@ - +