From 290d9bbaa89b44abafc9c3b73c7780c1244c1f15 Mon Sep 17 00:00:00 2001 From: "Amir.H Khademi" Date: Sun, 3 Mar 2024 11:42:11 +0330 Subject: [PATCH] feat : add print order , change question dialog --- .../Controller/OrderBagController.cs | 17 +- NetinaShop.Api/Controller/OrderController.cs | 1 + NetinaShop.Api/Controller/UserController.cs | 15 + NetinaShop.Api/NetinaShop.Api.csproj | 1 - NetinaShop.Api/Program.cs | 8 +- .../wwwroot/fonts/iranyekanwebmediumfanum.ttf | Bin 0 -> 60404 bytes .../CheckOrderBagCommandHandler.cs | 59 +++ .../SubmitOrderBagCommandHandler.cs | 60 +++ .../GetOrderInvoiceCommandHandler.cs | 363 +++++++++++++----- NetinaShop.Core/NetinaShop.Core.csproj | 5 +- .../Commands/OrderBagCommands.cs | 2 + .../CommandQueries/Queries/OrderQueries.cs | 1 + .../RequestDtos/CheckOrderBagRequestItem.cs | 7 + .../ResponseDtos/CheckOrderBagResponseItem.cs | 14 + NetinaShop.Domain/Dtos/SmallDtos/OrderSDto.cs | 2 +- .../Entities/Orders/Order.Aggregate.cs | 43 ++- .../Orders/GetUserOrdersQueryHandler.cs | 37 ++ 17 files changed, 511 insertions(+), 124 deletions(-) create mode 100644 NetinaShop.Api/wwwroot/fonts/iranyekanwebmediumfanum.ttf create mode 100644 NetinaShop.Core/EntityServices/OrderBagHandlers/CheckOrderBagCommandHandler.cs create mode 100644 NetinaShop.Core/EntityServices/OrderBagHandlers/SubmitOrderBagCommandHandler.cs create mode 100644 NetinaShop.Domain/Dtos/RequestDtos/CheckOrderBagRequestItem.cs create mode 100644 NetinaShop.Domain/Dtos/ResponseDtos/CheckOrderBagResponseItem.cs create mode 100644 NetinaShop.Repository/Handlers/Orders/GetUserOrdersQueryHandler.cs diff --git a/NetinaShop.Api/Controller/OrderBagController.cs b/NetinaShop.Api/Controller/OrderBagController.cs index 82dd010..4795ecb 100644 --- a/NetinaShop.Api/Controller/OrderBagController.cs +++ b/NetinaShop.Api/Controller/OrderBagController.cs @@ -11,7 +11,12 @@ public class OrderBagController : ICarterModule .RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser()); group.MapGet("", GetUserCurrentOrderBagAsync) - .WithDisplayName("GetUserCurrentOrderBagAsync") + .WithDisplayName("GetUserCurrentOrderBag") + .HasApiVersion(1.0); + + group.MapPost("check", CheckOrderBagAsync) + .WithDisplayName("CheckOrderBag") + .AllowAnonymous() .HasApiVersion(1.0); group.MapPost("add", AddProductToBagAsync) @@ -22,6 +27,10 @@ public class OrderBagController : ICarterModule .WithDisplayName("RemoveFromOrderBag") .HasApiVersion(1.0); + group.MapPost("submit", SubmitOrderBagAsync) + .WithDisplayName("SubmitOrderBag") + .HasApiVersion(1.0); + group.MapPost("discount/{orderId}", AddDiscountToOrderBagAsync) .WithDisplayName("AddDiscountToOrderBag") @@ -37,6 +46,12 @@ public class OrderBagController : ICarterModule .HasApiVersion(1.0); } + private async Task SubmitOrderBagAsync([FromBody] List requestDtos, IMediator mediator, CancellationToken cancellationToken) + => TypedResults.Ok(await mediator.Send(new SubmitOrderBagCommand(requestDtos), cancellationToken)); + + private async Task CheckOrderBagAsync([FromBody] List request, IMediator mediator, CancellationToken cancellationToken) + => TypedResults.Ok(await mediator.Send(new CheckOrderBagCommand(OrderBag: request), cancellationToken)); + public async Task GetUserCurrentOrderBagAsync(IMediator mediator, CancellationToken cancellationToken) => TypedResults.Ok(await mediator.Send(new GetUserOrderBagQuery(), cancellationToken)); diff --git a/NetinaShop.Api/Controller/OrderController.cs b/NetinaShop.Api/Controller/OrderController.cs index d5514d8..24444b2 100644 --- a/NetinaShop.Api/Controller/OrderController.cs +++ b/NetinaShop.Api/Controller/OrderController.cs @@ -26,6 +26,7 @@ public class OrderController : ICarterModule .HasApiVersion(1.0); group.MapGet("{id}/invoice", GetOrderInvoiceAsync) .WithDisplayName("GetOrderInvoice") + .AllowAnonymous() .HasApiVersion(1.0); } diff --git a/NetinaShop.Api/Controller/UserController.cs b/NetinaShop.Api/Controller/UserController.cs index 83653a6..b08a2df 100644 --- a/NetinaShop.Api/Controller/UserController.cs +++ b/NetinaShop.Api/Controller/UserController.cs @@ -1,4 +1,5 @@  +using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Mvc.RazorPages; using NetinaShop.Core.EntityServices.Abstracts; using NetinaShop.Repository.Abstracts; @@ -26,6 +27,14 @@ public class UserController : ICarterModule .WithDisplayName("GetUser") .HasApiVersion(1.0); + group.MapGet("/order", GetUserOrdersAsync) + .WithDisplayName("GetUserOrders") + .HasApiVersion(1.0); + + group.MapGet("{id}/order", GetUserOrdersByIdAsync) + .WithDisplayName("GetUserOrders") + .HasApiVersion(1.0); + group.MapGet("/changelog", GetChangeLogAsync) .WithDisplayName("GetChangeLog") .HasApiVersion(1.0); @@ -40,6 +49,12 @@ public class UserController : ICarterModule .HasApiVersion(1.0); } + private async Task GetUserOrdersAsync([FromServices] IMediator mediator, CancellationToken cancellationToken) + => TypedResults.Ok(await mediator.Send(new GetUserOrdersQuery(default), cancellationToken)); + + private async Task GetUserOrdersByIdAsync(Guid id,[FromServices]IMediator mediator, CancellationToken cancellationToken) + => TypedResults.Ok(await mediator.Send(new GetUserOrdersQuery(id), cancellationToken)); + private async Task GetChangeLogAsync(IUserService userService, CancellationToken cancellationToken) => TypedResults.Ok(await userService.GetAdminChangeLogAsync(cancellationToken)); diff --git a/NetinaShop.Api/NetinaShop.Api.csproj b/NetinaShop.Api/NetinaShop.Api.csproj index e796a7a..b05d873 100644 --- a/NetinaShop.Api/NetinaShop.Api.csproj +++ b/NetinaShop.Api/NetinaShop.Api.csproj @@ -134,7 +134,6 @@ - diff --git a/NetinaShop.Api/Program.cs b/NetinaShop.Api/Program.cs index eb0128a..9f4fc16 100644 --- a/NetinaShop.Api/Program.cs +++ b/NetinaShop.Api/Program.cs @@ -1,8 +1,4 @@ -using Autofac.Core; -using DinkToPdf.Contracts; -using DinkToPdf; using NetinaShop.Repository.Behaviors; -using QuestPDF.Infrastructure; var builder = WebApplication.CreateBuilder(args); builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory()); @@ -44,8 +40,8 @@ builder.Services.AddCustomIdentity(); builder.Services.AddCustomDbContext(configuration); builder.Services.AddMarten(configuration,builder.Environment); builder.Services.AddCarter(); -builder.Services.AddSingleton(typeof(IConverter), new SynchronizedConverter(new PdfTools())); -QuestPDF.Settings.License = LicenseType.Community; + +Syncfusion.Licensing.SyncfusionLicenseProvider.RegisterLicense("Ngo9BigBOggjHTQxAR8/V1NAaF1cXmhKYVtpR2Nbe05yflRGalxSVBYiSV9jS3pTdUViWHtfcHRWQGlcUQ=="); builder.Host.ConfigureContainer(builder => diff --git a/NetinaShop.Api/wwwroot/fonts/iranyekanwebmediumfanum.ttf b/NetinaShop.Api/wwwroot/fonts/iranyekanwebmediumfanum.ttf new file mode 100644 index 0000000000000000000000000000000000000000..551a67f33baef7560540d734b621884b4624f7da GIT binary patch literal 60404 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 +{ + private readonly IRepositoryWrapper _repositoryWrapper; + private readonly IMediator _mediator; + + public CheckOrderBagCommandHandler(IRepositoryWrapper repositoryWrapper,IMediator mediator) + { + _repositoryWrapper = repositoryWrapper; + _mediator = mediator; + } + public async Task> Handle(CheckOrderBagCommand request, CancellationToken cancellationToken) + { + List response = new List(); + + foreach (var item in request.OrderBag) + { + var product = await _repositoryWrapper.SetRepository() + .TableNoTracking + .Where(p => p.Id == item.ProductId) + .Select(ProductMapper.ProjectToSDto) + .FirstOrDefaultAsync(cancellationToken); + + if (product == null) + { + response.Add(new CheckOrderBagResponseItem + { + Count = item.Count, + IsEnable = false, + IsRemoved = true, + ProductId = item.ProductId, + Stock = 0 + }); + } + else + { + await _mediator.Send(new CalculateProductDiscountCommand(product), cancellationToken); + var res = new CheckOrderBagResponseItem + { + ProductId = item.ProductId, + CostWithDiscount = product.CostWithDiscount, + Cost = product.Cost, + DiscountPercent = product.DiscountPercent, + ProductName = product.PersianName, + Stock = product.Stock, + Count = item.Count, + IsEnable = product.IsEnable, + IsRemoved = false + }; + response.Add(res); + } + } + + return response; + } +} \ No newline at end of file diff --git a/NetinaShop.Core/EntityServices/OrderBagHandlers/SubmitOrderBagCommandHandler.cs b/NetinaShop.Core/EntityServices/OrderBagHandlers/SubmitOrderBagCommandHandler.cs new file mode 100644 index 0000000..56a8e87 --- /dev/null +++ b/NetinaShop.Core/EntityServices/OrderBagHandlers/SubmitOrderBagCommandHandler.cs @@ -0,0 +1,60 @@ +namespace NetinaShop.Core.EntityServices.OrderBagHandlers; + +public class SubmitOrderBagCommandHandler : IRequestHandler +{ + private readonly IMediator _mediator; + private readonly IRepositoryWrapper _repositoryWrapper; + private readonly ICurrentUserService _currentUserService; + + public SubmitOrderBagCommandHandler(IMediator mediator, IRepositoryWrapper repositoryWrapper, ICurrentUserService currentUserService) + { + _mediator = mediator; + _repositoryWrapper = repositoryWrapper; + _currentUserService = currentUserService; + } + + public async Task Handle(SubmitOrderBagCommand request, CancellationToken cancellationToken) + { + if (_currentUserService.UserId == null) + throw new AppException("User id notfound", ApiResultStatusCode.BadRequest); + if (!Guid.TryParse(_currentUserService.UserId, out Guid userId)) + throw new AppException("User id wrong", ApiResultStatusCode.BadRequest); + + var orderBag = await _mediator.Send(new GetUserOrderBagQuery(), cancellationToken); + + foreach (var requestDto in request.RequestDtos) + { + + var product = await _repositoryWrapper.SetRepository() + .TableNoTracking + .FirstOrDefaultAsync(p => p.Id == requestDto.ProductId, cancellationToken); + + if (product == null) + throw new AppException("Product not found ", ApiResultStatusCode.NotFound); + if (!product.IsEnable) + throw new AppException("Product is not enable", ApiResultStatusCode.BadRequest); + + var productSDto = product.AdaptToSDto(); + await _mediator.Send(new CalculateProductDiscountCommand(productSDto), cancellationToken); + + orderBag.ChangeOrderBag(productSDto.Id, productSDto.Cost, productSDto.CostWithDiscount, + productSDto.HasDiscount, productSDto.PackingCost, productSDto.CategoryId, requestDto.Count); + } + foreach (var orderProduct in orderBag.OrderProducts.ToList()) + { + if(request.RequestDtos.FirstOrDefault(op=>op.ProductId==orderProduct.ProductId)==null) + { + orderBag.OrderProducts.Remove(orderProduct); + _repositoryWrapper.SetRepository().Delete(orderProduct); + await _repositoryWrapper.SaveChangesAsync(cancellationToken); + } + } + + _repositoryWrapper.SetRepository().Update(orderBag); + await _repositoryWrapper.SaveChangesAsync(cancellationToken); + + var order = await _mediator.Send(new CalculateOrderCommand(orderBag.Id), cancellationToken); + + return order.AdaptToSDto(); + } +} \ No newline at end of file diff --git a/NetinaShop.Core/EntityServices/OrderHandlers/GetOrderInvoiceCommandHandler.cs b/NetinaShop.Core/EntityServices/OrderHandlers/GetOrderInvoiceCommandHandler.cs index cec54e5..00eb6f5 100644 --- a/NetinaShop.Core/EntityServices/OrderHandlers/GetOrderInvoiceCommandHandler.cs +++ b/NetinaShop.Core/EntityServices/OrderHandlers/GetOrderInvoiceCommandHandler.cs @@ -1,9 +1,8 @@ -using DinkToPdf; -using DinkToPdf.Contracts; -using QuestPDF.Fluent; -using QuestPDF.Helpers; -using QuestPDF.Infrastructure; -using Unit = QuestPDF.Infrastructure.Unit; +using Syncfusion.Drawing; +using Syncfusion.Pdf.Graphics; +using Syncfusion.Pdf; +using Syncfusion.Pdf.Grid; +using NetinaShop.Domain.Dtos.LargDtos; namespace NetinaShop.Core.EntityServices.OrderHandlers; @@ -11,118 +10,288 @@ public class GetOrderInvoiceCommandHandler : IRequestHandler Handle(GetOrderInvoiceCommand request, CancellationToken cancellationToken) { var orderLDto = await _mediator.Send(new GetOrderLDtoQuery(request.OrderId), cancellationToken); + PdfDocument document = new PdfDocument(); + PdfPage currentPage = document.Pages.Add(); + SizeF clientSize = currentPage.Size; - //var textStyleWithFallback = TextStyle - // .Default - // .FontSize(18) - // .Fallback(y => y - // .FontFamily(Fonts.Arial) - // .SemiBold() - // .Underline(false) - // .BackgroundColor(Colors.Red.Lighten4)); + var result = HeaderAndAddress(orderLDto, currentPage, clientSize); - //var pdf = Document.Create(container => - //{ - // container.Page(page => - // { - // page.Size(PageSizes.A4); - // page.Margin(2,Unit.Centimetre); - // page.PageColor(Colors.White); - // page.DefaultTextStyle(x=>x.FontSize(14)); + //Product Table + result = ProductTable(orderLDto, result, currentPage, clientSize); - // page.Header() - // .Text(text => - // { - // text.DefaultTextStyle(textStyleWithFallback); - // text.Line("This is normal text."); - // text.EmptyLine(); + //Cost Table + result = CostTable(orderLDto, result, currentPage, clientSize); - // text.Line("Following line should use font fallback:"); - // text.Line("中文文本"); - // text.EmptyLine(); + //Dtail Table + result = DetailTable(orderLDto, result, currentPage, clientSize); - // text.Line("The following line contains a mix of known and unknown characters."); - // text.Line("Mixed line: This 中文 is 文文 a mixed 本 本 line 本 中文文本!"); - // text.EmptyLine(); + MemoryStream stream = new MemoryStream(); + document.Save(stream); + document.Close(true); + stream.Position = 0; + return stream.ToArray(); + } - // text.Span("Emojis work out of the box because of font fallback: 😊😅🥳👍❤😍👌"); - // }); + private PdfLayoutResult HeaderAndAddress(OrderLDto order, PdfPage currentPage, SizeF clientSize) + { + PdfStringFormat format = new PdfStringFormat(); + format.TextDirection = PdfTextDirection.RightToLeft; + format.Alignment = PdfTextAlignment.Right; - // page.Content() - // .ContentFromRightToLeft() - // .Column(x => - // { - // x.Spacing(20); - // x.Item().Text("فاکتور فروش "); - // }); - // }); - //}).GeneratePdf(); - var sb = new StringBuilder(); - sb.Append(@" - - - - -

فاکتور فروش

- - - - - - - "); - foreach (var emp in orderLDto.OrderProducts) + var headerText = new PdfTextElement($"فاکتور فروش {order.FactorCode}", _largeFont); + headerText.StringFormat = format; + var result = headerText.Draw(currentPage, new PointF(clientSize.Width - 100, 5)); + + var orderAtText = new PdfTextElement($"سفارش در : {order.OrderAt.ToPersianDateTime().ToLongDateString()} | {order.OrderAt:T}", _mediumFont); + orderAtText.StringFormat = format; + result = orderAtText.Draw(currentPage, new PointF(clientSize.Width - 100, result.Bounds.Y + 30)); + + var nameText = new PdfTextElement($"{order.UserFullName}", _mediumFont); + nameText.StringFormat = format; + result = nameText.Draw(currentPage, new PointF(clientSize.Width - 100, result.Bounds.Bottom)); + + var phoneText = new PdfTextElement($"{order.UserPhoneNumber}", _mediumFont); + phoneText.StringFormat = new PdfStringFormat(PdfTextAlignment.Left); + result = phoneText.Draw(currentPage, new PointF(0, result.Bounds.Y)); + + PdfPen pen = new PdfPen(PdfBrushes.Black, 1f); + PointF point1 = new PointF(0, result.Bounds.Bottom + 25); + PointF point2 = new PointF(clientSize.Width, result.Bounds.Bottom + 25); + currentPage.Graphics.DrawLine(pen, point1, point2); + + var addressText = new PdfTextElement($"آدرس : {order.OrderDelivery.Address}", _mediumFont); + addressText.StringFormat = format; + result = addressText.Draw(currentPage, new PointF(clientSize.Width - 100, result.Bounds.Y + 55)); + + var postalCode = new PdfTextElement($"استان : {order.OrderDelivery.Province} | شهر : {order.OrderDelivery.City} | کد پستی : {order.OrderDelivery.PostalCode} | پلاک : {order.OrderDelivery.Plaque}", _smallFont); + postalCode.StringFormat = format; + result = postalCode.Draw(currentPage, new PointF(clientSize.Width - 100, result.Bounds.Bottom + 5)); + + var shippingMethod = new PdfTextElement($"روش ارسال : {order.OrderDelivery.ShippingMethod} ", _mediumFont); + shippingMethod.StringFormat = format; + result = shippingMethod.Draw(currentPage, new PointF(clientSize.Width - 100, result.Bounds.Bottom + 5)); + + PointF pointB1 = new PointF(0, result.Bounds.Bottom + 15); + PointF pointB2 = new PointF(clientSize.Width, result.Bounds.Bottom + 15); + currentPage.Graphics.DrawLine(pen, pointB1, pointB2); + return result; + } + + private PdfLayoutResult DetailTable(OrderLDto order, PdfLayoutResult result, PdfPage currentPage, SizeF clientSize) + { + PdfGrid detailGrid = new PdfGrid(); + detailGrid.Style.Font = _gridFont; + detailGrid.Columns.Add(1); + detailGrid.Columns[0].Width = 150; + + + PdfGridCellStyle detailCellStyle = new PdfGridCellStyle(); + detailCellStyle.Font = _gridBoldFont; + detailCellStyle.Borders.All = PdfPens.Transparent; + detailCellStyle.TextBrush = PdfBrushes.White; + detailCellStyle.BackgroundBrush = new PdfSolidBrush(new PdfColor(Color.Black)); + + foreach (var payment in order.Payments.Where(p=>p.Status==PaymentStatus.Paid)) { - sb.AppendFormat(@" - - - - - ", emp.ProductName, emp.Count, emp.ProductFee, emp.ProductCost); + PdfGridRow paymentType = detailGrid.Rows.Add(); + paymentType.Cells[0].Value = $"{payment.Amount:N0} ریال به صورت {payment.Type.ToDisplay()} پرداخت شده"; + paymentType.Cells[0].StringFormat = _stringFormat; + paymentType.Cells[0].Style = _cellStyle; } - sb.Append(@" -
NameLastNameAgeGender
{0}{1}{2}{3}
- - "); + PdfGridRow isPaid = detailGrid.Rows.Add(); + isPaid.Cells[0].Value = order.IsPayed ? "پرداخت شده" : "پرداخت نشده"; + isPaid.Cells[0].StringFormat = _stringFormat; + isPaid.Cells[0].Style = detailCellStyle; - var globalSettings = new GlobalSettings - { - ColorMode = ColorMode.Color, - Orientation = Orientation.Portrait, - PaperSize = PaperKind.A4, - Margins = new MarginSettings { Top = 10 }, - DocumentTitle = "PDF Report", - Out = @"D:\PDFCreator\Employee_Report.pdf" - }; - var objectSettings = new ObjectSettings - { - PagesCount = true, - HtmlContent = sb.ToString(), - WebSettings = { DefaultEncoding = "utf-8", UserStyleSheet = Path.Combine(Directory.GetCurrentDirectory(), "assets", "styles.css") }, - HeaderSettings = { FontName = "Arial", FontSize = 9, Right = "Page [page] of [toPage]", Line = true }, - FooterSettings = { FontName = "Arial", FontSize = 9, Line = true, Center = "Report Footer" } - }; - var pdf = new HtmlToPdfDocument() - { - GlobalSettings = globalSettings, - Objects = { objectSettings } - }; - var file = _converter.Convert(pdf); + detailGrid.ApplyBuiltinStyle(PdfGridBuiltinStyle.GridTable1Light); + detailGrid.Style = _gridStyle; + + result = detailGrid.Draw(currentPage, 0, result.Bounds.Top, 150, _gridLayoutFormat); + return result; + } + + private PdfLayoutResult CostTable(OrderLDto order, PdfLayoutResult result, PdfPage currentPage, SizeF clientSize) + { + PdfGrid pricesGrid = new PdfGrid(); + pricesGrid.Style.Font = _gridFont; + pricesGrid.Columns.Add(2); + pricesGrid.Columns[0].Width = 150; + pricesGrid.Columns[1].Width = 200; + + PdfGridRow totalProductPriceRow = pricesGrid.Rows.Add(); + totalProductPriceRow.Cells[1].Value = $"قیمت تمام شده محصولات"; + totalProductPriceRow.Cells[1].StringFormat = _stringFormat; + totalProductPriceRow.Cells[1].Style = _cellStyle; + + totalProductPriceRow.Cells[0].Value = $"{order.TotalProductsPrice:N0} ریال"; + totalProductPriceRow.Cells[0].StringFormat = _stringFormat; + totalProductPriceRow.Cells[0].Style = _cellStyle; + + PdfGridRow totalDeliveryPrice = pricesGrid.Rows.Add(); + totalDeliveryPrice.Cells[1].Value = $"قیمت ارسال"; + totalDeliveryPrice.Cells[1].StringFormat = _stringFormat; + totalDeliveryPrice.Cells[1].Style = _cellStyle; + + totalDeliveryPrice.Cells[0].Value = $"{order.DeliveryPrice:N0} ریال"; + totalDeliveryPrice.Cells[0].StringFormat = _stringFormat; + totalDeliveryPrice.Cells[0].Style = _cellStyle; + + PdfGridRow discountPrice = pricesGrid.Rows.Add(); + discountPrice.Cells[1].Value = $"تخفیف"; + discountPrice.Cells[1].StringFormat = _stringFormat; + discountPrice.Cells[1].Style = _cellStyle; + + discountPrice.Cells[0].Value = $"{order.DiscountPrice:N0} ریال"; + discountPrice.Cells[0].StringFormat = _stringFormat; + discountPrice.Cells[0].Style = _cellStyle; + + PdfGridRow taxesPrice = pricesGrid.Rows.Add(); + taxesPrice.Cells[1].Value = $"مالیاتــــ"; + taxesPrice.Cells[1].StringFormat = _stringFormat; + taxesPrice.Cells[1].Style = _cellStyle; + + taxesPrice.Cells[0].Value = $"{order.TaxesPrice:N0} ریال"; + taxesPrice.Cells[0].StringFormat = _stringFormat; + taxesPrice.Cells[0].Style = _cellStyle; - return file; + + PdfGridRow totalPrice = pricesGrid.Rows.Add(); + totalPrice.Cells[1].Value = $"مبلغ پرداختی"; + totalPrice.Cells[1].StringFormat = _stringFormat; + totalPrice.Cells[1].Style = _cellStyle; + + totalPrice.Cells[0].Value = $"{order.TotalPrice:N0} ریال"; + totalPrice.Cells[0].StringFormat = _stringFormat; + totalPrice.Cells[0].Style = _cellStyle; + + pricesGrid.ApplyBuiltinStyle(PdfGridBuiltinStyle.GridTable1Light); + pricesGrid.Style = _gridStyle; + result = pricesGrid.Draw(currentPage, clientSize.Width - 430, result.Bounds.Bottom + 15, 350, _gridLayoutFormat); + return result; + } + + private PdfLayoutResult ProductTable(OrderLDto order , PdfLayoutResult result , PdfPage currentPage ,SizeF clientSize ) + { + + PdfGrid grid = new PdfGrid(); + grid.Style.Font = _gridFont; + grid.Columns.Add(4); + grid.Columns[0].Width = 100; + grid.Columns[1].Width = 100; + grid.Columns[2].Width = 50; + + grid.Headers.Add(1); + _stringFormat.TextDirection = PdfTextDirection.RightToLeft; + _stringFormat.WordWrap = PdfWordWrapType.Word; + + PdfGridRow header = grid.Headers[0]; + header.Cells[3].Value = "محصولات"; + header.Cells[3].Style.Font = _gridBoldFont; + header.Cells[3].StringFormat = _stringFormat; + + header.Cells[2].Value = "تعداد"; + header.Cells[2].Style.Font = _gridBoldFont; + header.Cells[2].StringFormat = _stringFormat; + + header.Cells[1].Value = "قیمت فی"; + header.Cells[1].Style.Font = _gridBoldFont; + header.Cells[1].StringFormat = _stringFormat; + + header.Cells[0].Value = "قیمت کل"; + header.Cells[0].Style.Font = _gridBoldFont; + header.Cells[0].StringFormat = _stringFormat; + + PdfGridCellStyle headerCellStyle = new PdfGridCellStyle(); + headerCellStyle.Font = _gridFont; + + headerCellStyle.Borders.All = PdfPens.Transparent; + headerCellStyle.TextBrush = PdfBrushes.White; + headerCellStyle.BackgroundBrush = new PdfSolidBrush(new PdfColor(Color.Black)); + + for (int i = 0; i < header.Cells.Count; i++) + { + PdfGridCell cell = header.Cells[i]; + cell.Style = headerCellStyle; + } + + + foreach (var orderProduct in order.OrderProducts) + { + PdfGridRow row = grid.Rows.Add(); + row.Cells[3].Value = orderProduct.ProductName; + row.Cells[3].StringFormat = _stringFormat; + row.Cells[3].Style = _cellStyle; + + row.Cells[2].Value = orderProduct.Count.ToString(); + row.Cells[2].StringFormat = _stringFormat; + row.Cells[2].Style = _cellStyle; + + row.Cells[1].Value = $"{orderProduct.ProductFeeWithDiscount:N0} ریال"; + row.Cells[1].StringFormat = _stringFormat; + row.Cells[1].Style = _cellStyle; + + row.Cells[0].Value = $"{orderProduct.ProductCost:N0} ریال"; + row.Cells[0].StringFormat = _stringFormat; + row.Cells[0].Style = _cellStyle; + } + + grid.Style = _gridStyle; + grid.ApplyBuiltinStyle(PdfGridBuiltinStyle.GridTable1Light); + result = grid.Draw(currentPage, 0, result.Bounds.Bottom + 25, clientSize.Width, _gridLayoutFormat); + return result; } } \ No newline at end of file diff --git a/NetinaShop.Core/NetinaShop.Core.csproj b/NetinaShop.Core/NetinaShop.Core.csproj index 2e7cbc1..8695861 100644 --- a/NetinaShop.Core/NetinaShop.Core.csproj +++ b/NetinaShop.Core/NetinaShop.Core.csproj @@ -11,13 +11,10 @@ - - - - + diff --git a/NetinaShop.Domain/CommandQueries/Commands/OrderBagCommands.cs b/NetinaShop.Domain/CommandQueries/Commands/OrderBagCommands.cs index 2c61a92..98e4022 100644 --- a/NetinaShop.Domain/CommandQueries/Commands/OrderBagCommands.cs +++ b/NetinaShop.Domain/CommandQueries/Commands/OrderBagCommands.cs @@ -4,11 +4,13 @@ namespace NetinaShop.Domain.CommandQueries.Commands; public sealed record CreateOrderCommand(string DiscountCode, List OrderProducts, OrderDeliverySDto OrderDelivery) : IRequest; +public sealed record CheckOrderBagCommand(List OrderBag) : IRequest>; public sealed record AddToOrderBagCommand(List RequestDtos) : IRequest; public sealed record RemoveFromOrderBagCommand(List RequestDtos) : IRequest; public sealed record SubmitDiscountCommand(Guid OrderId,string DiscountCode) : IRequest; public sealed record SubmitOrderDeliveryCommand(Guid AddressId, Guid OrderId, Guid ShippingId) : IRequest; +public sealed record SubmitOrderBagCommand(List RequestDtos) : IRequest; public sealed record SubmitOrderPaymentCommand(Guid OrderId, OrderPaymentMethod PaymentMethod , bool HasPaid = false) : IRequest; diff --git a/NetinaShop.Domain/CommandQueries/Queries/OrderQueries.cs b/NetinaShop.Domain/CommandQueries/Queries/OrderQueries.cs index ab14aa9..8666859 100644 --- a/NetinaShop.Domain/CommandQueries/Queries/OrderQueries.cs +++ b/NetinaShop.Domain/CommandQueries/Queries/OrderQueries.cs @@ -2,5 +2,6 @@ public sealed record GetOrderLDtoQuery(Guid Id) : IRequest; +public sealed record GetUserOrdersQuery(Guid UserId = default) : IRequest>; public sealed record GetOrderQuery(Guid Id) : IRequest; public sealed record GetOrdersQuery(OrderQueryDateFilter? DateFilter, OrderStatus? OrderStatus,long? SelectedDate, int Page = 0) : IRequest>; \ No newline at end of file diff --git a/NetinaShop.Domain/Dtos/RequestDtos/CheckOrderBagRequestItem.cs b/NetinaShop.Domain/Dtos/RequestDtos/CheckOrderBagRequestItem.cs new file mode 100644 index 0000000..ecbea23 --- /dev/null +++ b/NetinaShop.Domain/Dtos/RequestDtos/CheckOrderBagRequestItem.cs @@ -0,0 +1,7 @@ +namespace NetinaShop.Domain.Dtos.RequestDtos; + +public class CheckOrderBagRequestItem +{ + public Guid ProductId { get; set; } + public int Count { get; set; } +} \ No newline at end of file diff --git a/NetinaShop.Domain/Dtos/ResponseDtos/CheckOrderBagResponseItem.cs b/NetinaShop.Domain/Dtos/ResponseDtos/CheckOrderBagResponseItem.cs new file mode 100644 index 0000000..803303e --- /dev/null +++ b/NetinaShop.Domain/Dtos/ResponseDtos/CheckOrderBagResponseItem.cs @@ -0,0 +1,14 @@ +namespace NetinaShop.Domain.Dtos.ResponseDtos; + +public class CheckOrderBagResponseItem +{ + public Guid ProductId { get; set; } + public string ProductName { get; set; } = string.Empty; + public int Count { get; set; } + public double Cost { get; set; } + public double CostWithDiscount { get; set; } + public double DiscountPercent { get; set; } + public bool IsEnable { get; set; } + public bool IsRemoved { get; set; } + public int Stock { get; set; } +} \ No newline at end of file diff --git a/NetinaShop.Domain/Dtos/SmallDtos/OrderSDto.cs b/NetinaShop.Domain/Dtos/SmallDtos/OrderSDto.cs index 967a046..8f53f8a 100644 --- a/NetinaShop.Domain/Dtos/SmallDtos/OrderSDto.cs +++ b/NetinaShop.Domain/Dtos/SmallDtos/OrderSDto.cs @@ -20,5 +20,5 @@ public class OrderSDto : BaseDto public string DiscountCode { get; set; } = string.Empty; public string UserFullName { get; set; } = string.Empty; public string UserPhoneNumber { get; set; } = string.Empty; - public Guid UserId { get; internal set; } + public Guid UserId { get; set; } } diff --git a/NetinaShop.Domain/Entities/Orders/Order.Aggregate.cs b/NetinaShop.Domain/Entities/Orders/Order.Aggregate.cs index 7bba6d3..4ced9ae 100644 --- a/NetinaShop.Domain/Entities/Orders/Order.Aggregate.cs +++ b/NetinaShop.Domain/Entities/Orders/Order.Aggregate.cs @@ -12,7 +12,7 @@ public partial class Order } - public void AddToOrderBag(Guid productId,double cost,double costWithDiscount,bool hasDiscount,double packingCost ,Guid categoryId , int count) + public void AddToOrderBag(Guid productId, double cost, double costWithDiscount, bool hasDiscount, double packingCost, Guid categoryId, int count) { var orderProduct = OrderProducts.FirstOrDefault(op => op.ProductId == productId); if (orderProduct == null) @@ -44,6 +44,21 @@ public partial class Order } } + public void ChangeOrderBag(Guid productId, double cost, double costWithDiscount, bool hasDiscount, double packingCost, Guid categoryId, int count) + { + var orderProduct = OrderProducts.FirstOrDefault(op => op.ProductId == productId); + if (orderProduct != null) + { + if (orderProduct.Count > count) + RemoveFromOrderBag(productId, count); + else + AddToOrderBag(productId, cost, costWithDiscount, hasDiscount, packingCost, categoryId, count); + } + else + AddToOrderBag(productId, cost, costWithDiscount, hasDiscount, packingCost, categoryId, count); + + } + public void SetDiscount(string discountCode) => DiscountCode = discountCode; public void AddOrderProduct(OrderProduct orderProduct) @@ -111,17 +126,17 @@ public partial class Order OrderDelivery = orderDelivery; } - public void AddOrderDelivery(Guid addressId, double deliveryCost, Guid shippingId, Guid orderId,Guid orderDeliveryId) + public void AddOrderDelivery(Guid addressId, double deliveryCost, Guid shippingId, Guid orderId, Guid orderDeliveryId) { var orderDelivery = OrderDelivery.Create(addressId, deliveryCost, shippingId, orderId); orderDelivery.Id = orderDeliveryId; OrderDelivery = orderDelivery; } - public void SetTotalPrice(double totalProductPrice, - double packingPrice, - double servicePrice, + public void SetTotalPrice(double totalProductPrice, + double packingPrice, + double servicePrice, double deliveryPrice, - double productDiscountPrice, + double productDiscountPrice, double discountCodePrice, double taxesPrice) { @@ -132,7 +147,7 @@ public partial class Order TaxesPrice = taxesPrice; DiscountCodePrice = discountCodePrice; ProductDiscountPrice = productDiscountPrice; - DiscountPrice = productDiscountPrice+discountCodePrice; + DiscountPrice = productDiscountPrice + discountCodePrice; TotalPrice = (totalProductPrice + packingPrice + servicePrice + deliveryPrice + taxesPrice) - DiscountPrice; } @@ -140,14 +155,14 @@ public partial class Order public partial class OrderProduct { - public static OrderProduct Create(int count, - double productFee, + public static OrderProduct Create(int count, + double productFee, double productFeeWithDiscount, bool hasDiscount, - double packingFee, - OrderStatus orderProductStatus, - Guid productId, - Guid productCategoryId, + double packingFee, + OrderStatus orderProductStatus, + Guid productId, + Guid productCategoryId, Guid orderId) { var productCost = count * productFeeWithDiscount; @@ -164,7 +179,7 @@ public partial class OrderProduct public partial class OrderDelivery { - public static OrderDelivery Create(Guid addressId,double deliveryCost, Guid shippingId, Guid orderId) + public static OrderDelivery Create(Guid addressId, double deliveryCost, Guid shippingId, Guid orderId) { return new OrderDelivery(addressId, deliveryCost, shippingId, orderId); } diff --git a/NetinaShop.Repository/Handlers/Orders/GetUserOrdersQueryHandler.cs b/NetinaShop.Repository/Handlers/Orders/GetUserOrdersQueryHandler.cs new file mode 100644 index 0000000..b44fee7 --- /dev/null +++ b/NetinaShop.Repository/Handlers/Orders/GetUserOrdersQueryHandler.cs @@ -0,0 +1,37 @@ +using Microsoft.EntityFrameworkCore; +using NetinaShop.Domain.Entities.Orders; + +namespace NetinaShop.Repository.Handlers.Orders; + +public class GetUserOrdersQueryHandler : IRequestHandler> +{ + private readonly ICurrentUserService _currentUserService; + private readonly IRepositoryWrapper _repositoryWrapper; + + public GetUserOrdersQueryHandler(ICurrentUserService currentUserService,IRepositoryWrapper repositoryWrapper) + { + _currentUserService = currentUserService; + _repositoryWrapper = repositoryWrapper; + } + public async Task> Handle(GetUserOrdersQuery request, CancellationToken cancellationToken) + { + Guid userId = Guid.Empty; + if (request.UserId == default) + { + if (_currentUserService.UserId == null) + throw new AppException("Token is wrong", ApiResultStatusCode.UnAuthorized); + if (!Guid.TryParse(_currentUserService.UserId, out userId)) + throw new AppException("Token is wrong", ApiResultStatusCode.UnAuthorized); + } + else + userId = request.UserId; + + var orders = await _repositoryWrapper.SetRepository() + .TableNoTracking + .Where(o => o.UserId == userId) + .Select(OrderMapper.ProjectToSDto) + .ToListAsync(cancellationToken); + + return orders; + } +} \ No newline at end of file