ShippingDocumentToFiles fix; CustomOrder create improvements;

This commit is contained in:
Loretta 2025-10-19 15:08:38 +02:00
parent cc4f5a3f8c
commit 89aa10e07b
2 changed files with 102 additions and 65 deletions

View File

@ -1,9 +1,11 @@
using AyCode.Services.SignalRs; using AyCode.Core.Loggers;
using AyCode.Services.SignalRs;
using FruitBank.Common.Dtos; using FruitBank.Common.Dtos;
using FruitBank.Common.Entities; using FruitBank.Common.Entities;
using FruitBank.Common.Interfaces; using FruitBank.Common.Interfaces;
using FruitBank.Common.Server.Interfaces; using FruitBank.Common.Server.Interfaces;
using FruitBank.Common.SignalRs; using FruitBank.Common.SignalRs;
using Mango.Nop.Core.Loggers;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json; using Newtonsoft.Json;
using Nop.Core.Domain.Customers; using Nop.Core.Domain.Customers;
@ -36,6 +38,8 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Areas.Admin.Controllers
[AuthorizeAdmin] [AuthorizeAdmin]
public class CustomOrderController : BaseAdminController, ICustomOrderSignalREndpointServer public class CustomOrderController : BaseAdminController, ICustomOrderSignalREndpointServer
{ {
private readonly FruitBankDbContext _dbContext;
private readonly IOrderService _orderService; private readonly IOrderService _orderService;
private readonly CustomOrderModelFactory _orderModelFactory; private readonly CustomOrderModelFactory _orderModelFactory;
private readonly ICustomOrderSignalREndpointServer _customOrderSignalREndpoint; private readonly ICustomOrderSignalREndpointServer _customOrderSignalREndpoint;
@ -46,8 +50,13 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Areas.Admin.Controllers
private readonly IProductService _productService; private readonly IProductService _productService;
// ... other dependencies // ... other dependencies
public CustomOrderController(IOrderService orderService, IOrderModelFactory orderModelFactory, ICustomOrderSignalREndpointServer customOrderSignalREndpoint, IPermissionService permissionService, IGenericAttributeService genericAttributeService, INotificationService notificationService, ICustomerService customerService, IProductService productService) private readonly ILogger _logger;
public CustomOrderController(FruitBankDbContext fruitBankDbContext, IOrderService orderService, IOrderModelFactory orderModelFactory, ICustomOrderSignalREndpointServer customOrderSignalREndpoint, IPermissionService permissionService, IGenericAttributeService genericAttributeService, INotificationService notificationService, ICustomerService customerService, IProductService productService, IEnumerable<IAcLogWriterBase> logWriters)
{ {
_logger = new Logger<CustomOrderController>(logWriters.ToArray());
_dbContext = fruitBankDbContext;
_orderService = orderService; _orderService = orderService;
_orderModelFactory = orderModelFactory as CustomOrderModelFactory; _orderModelFactory = orderModelFactory as CustomOrderModelFactory;
_customOrderSignalREndpoint = customOrderSignalREndpoint; _customOrderSignalREndpoint = customOrderSignalREndpoint;
@ -100,10 +109,10 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Areas.Admin.Controllers
//return _customOrderService. //return _customOrderService.
var orderListModel = await _orderModelFactory.PrepareOrderListModelExtendedAsync(searchModel); var orderListModel = await _orderModelFactory.PrepareOrderListModelExtendedAsync(searchModel);
Console.WriteLine($"Total: {orderListModel.RecordsTotal}, Data Count: {orderListModel.Data.Count()}"); _logger.Debug($"Total: {orderListModel.RecordsTotal}, Data Count: {orderListModel.Data.Count()}");
foreach (var item in orderListModel.Data.Take(3)) foreach (var item in orderListModel.Data.Take(3))
{ {
Console.WriteLine($"Order: {item.Id}, {item.CustomOrderNumber}"); _logger.Debug($"Order: {item.Id}, {item.CustomOrderNumber}");
} }
return orderListModel; return orderListModel;
@ -158,13 +167,10 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Areas.Admin.Controllers
// Validate customer // Validate customer
var customer = await _customerService.GetCustomerByIdAsync(customerId); var customer = await _customerService.GetCustomerByIdAsync(customerId);
if (customer == null) if (customer == null) return RedirectToAction("List");
return RedirectToAction("List");
// Parse products // Parse products
var orderProducts = string.IsNullOrEmpty(orderProductsJson) var orderProducts = string.IsNullOrEmpty(orderProductsJson) ? [] : JsonConvert.DeserializeObject<List<OrderProductItem>>(orderProductsJson);
? new List<OrderProductItem>()
: JsonConvert.DeserializeObject<List<OrderProductItem>>(orderProductsJson);
// Create order // Create order
var order = new Order var order = new Order
@ -175,43 +181,55 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Areas.Admin.Controllers
CustomerLanguageId = customer.LanguageId ?? 1, CustomerLanguageId = customer.LanguageId ?? 1,
CustomerTaxDisplayType = TaxDisplayType.IncludingTax, CustomerTaxDisplayType = TaxDisplayType.IncludingTax,
CustomerIp = string.Empty, CustomerIp = string.Empty,
OrderStatusId = (int)OrderStatus.Pending, OrderStatus = OrderStatus.Pending,
PaymentStatusId = (int)PaymentStatus.Pending, PaymentStatus = PaymentStatus.Pending,
ShippingStatusId = (int)ShippingStatus.ShippingNotRequired, ShippingStatus = ShippingStatus.ShippingNotRequired,
CreatedOnUtc = DateTime.UtcNow, CreatedOnUtc = DateTime.UtcNow,
BillingAddressId = customer.BillingAddressId ?? 0, BillingAddressId = customer.BillingAddressId ?? 0,
ShippingAddressId = customer.ShippingAddressId ShippingAddressId = customer.ShippingAddressId
}; };
await _orderService.InsertOrderAsync(order); var productDtosById = await _dbContext.ProductDtos.GetAllByIds(orderProducts.Select(op => op.Id)).ToDictionaryAsync(p => p.Id, prodDto => prodDto);
// Add order items var transactionSuccess = await _dbContext.TransactionSafeAsync(async _ =>
foreach (var item in orderProducts)
{ {
var product = await _productService.GetProductByIdAsync(item.Id); await _orderService.InsertOrderAsync(order);
if (product != null)
foreach (var item in orderProducts)
{ {
var orderItem = new OrderItem //var product = await _productService.GetProductByIdAsync(item.Id);
//if (product != null)
if (productDtosById.TryGetValue(item.Id, out var product))
{ {
OrderId = order.Id, var orderItem = new OrderItem
ProductId = item.Id, {
Quantity = item.Quantity, OrderId = order.Id,
UnitPriceInclTax = item.Price, ProductId = item.Id,
UnitPriceExclTax = item.Price, Quantity = item.Quantity,
PriceInclTax = item.Price * item.Quantity, UnitPriceInclTax = item.Price,
PriceExclTax = item.Price * item.Quantity, UnitPriceExclTax = item.Price,
OriginalProductCost = product.ProductCost, PriceInclTax = item.Price * item.Quantity,
AttributeDescription = string.Empty, PriceExclTax = item.Price * item.Quantity,
AttributesXml = string.Empty, OriginalProductCost = product.ProductCost,
DiscountAmountInclTax = 0, AttributeDescription = string.Empty,
DiscountAmountExclTax = 0 AttributesXml = string.Empty,
}; DiscountAmountInclTax = 0,
DiscountAmountExclTax = 0
};
await _orderService.InsertOrderItemAsync(orderItem); await _orderService.InsertOrderItemAsync(orderItem);
}
else _logger.Error($"(productDtosById.TryGetValue(item.Id, out var product) == false); {item}");
} }
}
return RedirectToAction("Edit", new { id = order.Id }); return true;
});
if (transactionSuccess) return RedirectToAction("Edit", new { id = order.Id });
_logger.Error($"(transactionSuccess == false)");
return RedirectToAction("Error", new { id = order.Id });
} }
public class OrderProductItem public class OrderProductItem
@ -221,6 +239,11 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Areas.Admin.Controllers
public string Sku { get; set; } public string Sku { get; set; }
public int Quantity { get; set; } public int Quantity { get; set; }
public decimal Price { get; set; } public decimal Price { get; set; }
public override string ToString()
{
return $"{nameof(OrderProductItem)} [Id: {Id}; Name: {Name}; Sku: {Sku}; Quantity: {Quantity}; Price: {Price}]";
}
} }
//private static OrderItem CreateOrderItem(ProductToAuctionMapping productToAuction, Order order, decimal orderTotal) //private static OrderItem CreateOrderItem(ProductToAuctionMapping productToAuction, Order order, decimal orderTotal)

View File

@ -1,6 +1,8 @@
using DevExpress.Pdf.Native; using AyCode.Core.Loggers;
using DevExpress.Pdf.Native;
using FruitBank.Common; using FruitBank.Common;
using FruitBank.Common.Entities; using FruitBank.Common.Entities;
using Mango.Nop.Core.Loggers;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
@ -26,8 +28,12 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Areas.Admin.Controllers
protected readonly AICalculationService _aiCalculationService; protected readonly AICalculationService _aiCalculationService;
protected readonly OpenAIApiService _openAIApiService; protected readonly OpenAIApiService _openAIApiService;
public ManagementPageController(IPermissionService permissionService, FruitBankDbContext fruitBankDbContext, AICalculationService aiCalculationService, OpenAIApiService openAIApiService) private readonly ILogger _logger;
public ManagementPageController(IPermissionService permissionService, FruitBankDbContext fruitBankDbContext, AICalculationService aiCalculationService, OpenAIApiService openAIApiService, IEnumerable<IAcLogWriterBase> logWriters)
{ {
_logger = new Logger<CustomOrderController>(logWriters.ToArray());
_permissionService = permissionService; _permissionService = permissionService;
_dbContext = fruitBankDbContext; _dbContext = fruitBankDbContext;
_aiCalculationService = aiCalculationService; _aiCalculationService = aiCalculationService;
@ -220,7 +226,7 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Areas.Admin.Controllers
// - do we have partnerId - if so, we already have at least one doecument uploaded earlier // - do we have partnerId - if so, we already have at least one doecument uploaded earlier
if (partnerId.HasValue) if (partnerId.HasValue)
{ {
Console.WriteLine($"Associated with Partner ID: {partnerId.Value}"); _logger.Debug($"Associated with Partner ID: {partnerId.Value}");
//let's get the partner //let's get the partner
var partner = await _dbContext.Partners.GetByIdAsync(partnerId.Value); var partner = await _dbContext.Partners.GetByIdAsync(partnerId.Value);
@ -240,7 +246,7 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Areas.Admin.Controllers
var dbFile = new Files(); var dbFile = new Files();
string pdfText = ""; string pdfText = "";
Console.WriteLine($"Received file: {fileName} for Document ID: {shippingDocumentId}, content type: {file.ContentType}"); _logger.Detail($"Received file: {fileName} for Document ID: {shippingDocumentId}, content type: {file.ContentType}");
if (!file.ContentType.Equals("application/pdf", StringComparison.OrdinalIgnoreCase) && !file.ContentType.Equals("image/jpeg", StringComparison.OrdinalIgnoreCase)) if (!file.ContentType.Equals("application/pdf", StringComparison.OrdinalIgnoreCase) && !file.ContentType.Equals("image/jpeg", StringComparison.OrdinalIgnoreCase))
return Json(new { success = false, errorMessage = "Only PDF or jpg files are allowed" }); return Json(new { success = false, errorMessage = "Only PDF or jpg files are allowed" });
@ -285,7 +291,7 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Areas.Admin.Controllers
} }
// For demonstration, let's just log the extracted text // For demonstration, let's just log the extracted text
Console.WriteLine($"Extracted text from {file.FileName}: {pdfText}"); _logger.Detail($"Extracted text from {file.FileName}: {pdfText}");
} }
} }
@ -316,7 +322,7 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Areas.Admin.Controllers
} }
// For demonstration, let's just log the extracted text // For demonstration, let's just log the extracted text
Console.WriteLine($"Extracted text from {file.FileName}: {pdfText}"); _logger.Detail($"Extracted text from {file.FileName}: {pdfText}");
} }
} }
@ -329,7 +335,7 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Areas.Admin.Controllers
} }
} }
//we should have some kind of text now //we should have some kind of text now
Console.WriteLine(pdfText); _logger.Detail(pdfText);
} }
@ -350,18 +356,26 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Areas.Admin.Controllers
dbFile.FileName = extractedMetaData.DocumentNumber; dbFile.FileName = extractedMetaData.DocumentNumber;
} }
await _dbContext.Files.InsertAsync(dbFile); var transactionSuccess = await _dbContext.TransactionSafeAsync(async _ =>
filesList.Add(dbFile);
ShippingDocumentToFiles shippingDocumentToFiles = new ShippingDocumentToFiles
{ {
ShippingDocumentId = shippingDocumentId, await _dbContext.Files.InsertAsync(dbFile);
FilesId = dbFile.Id, filesList.Add(dbFile);
DocumentType = extractedMetaData.DocumentType != null ? (DocumentType)Enum.Parse(typeof(DocumentType), extractedMetaData.DocumentType) : DocumentType.Unknown
};
Console.WriteLine(shippingDocumentToFiles.DocumentType); var shippingDocumentToFiles = new ShippingDocumentToFiles
{
ShippingDocumentId = shippingDocumentId,
FilesId = dbFile.Id,
DocumentType = extractedMetaData.DocumentType != null ? (DocumentType)Enum.Parse(typeof(DocumentType), extractedMetaData.DocumentType) : DocumentType.Unknown
};
_logger.Detail(shippingDocumentToFiles.DocumentType.ToString());
await _dbContext.ShippingDocumentToFiles.InsertAsync(shippingDocumentToFiles);
return true;
});
if (!transactionSuccess) _logger.Error($"(transactionSuccess == false)");
await _dbContext.ShippingDocumentToFiles.InsertAsync(shippingDocumentToFiles);
// - IF WE DON'T HAVE PARTNERID ALREADY: read partner information // - IF WE DON'T HAVE PARTNERID ALREADY: read partner information
// (check if all 3 refers to the same partner) // (check if all 3 refers to the same partner)
// save partner information to partners table { Id, Name, TaxId, CertificationNumber, PostalCode, Country, State, County, City, Street } // save partner information to partners table { Id, Name, TaxId, CertificationNumber, PostalCode, Country, State, County, City, Street }
@ -376,24 +390,24 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Areas.Admin.Controllers
if (extractedPartnerData.Name != null) if (extractedPartnerData.Name != null)
{ {
Console.WriteLine("AI Analysis Partner Result:"); _logger.Detail("AI Analysis Partner Result:");
Console.WriteLine(extractedPartnerData.Name); _logger.Detail(extractedPartnerData.Name);
} }
if (extractedPartnerData.TaxId != null) if (extractedPartnerData.TaxId != null)
{ {
Console.WriteLine(extractedPartnerData.TaxId); _logger.Detail(extractedPartnerData.TaxId);
} }
if (extractedPartnerData.Country != null) if (extractedPartnerData.Country != null)
{ {
Console.WriteLine(extractedPartnerData.Country); _logger.Detail(extractedPartnerData.Country);
} }
if (extractedPartnerData.State != null) if (extractedPartnerData.State != null)
{ {
Console.WriteLine(extractedPartnerData.State); _logger.Detail(extractedPartnerData.State);
} }
} }
@ -418,7 +432,7 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Areas.Admin.Controllers
} }
catch (Exception ex) catch (Exception ex)
{ {
Console.WriteLine($"Error saving file: {ex}"); _logger.Error($"Error saving file: {ex.Message}", ex);
//return Json(new { success = false, errorMessage = ex.Message }); //return Json(new { success = false, errorMessage = ex.Message });
return BadRequest("No files were uploaded."); return BadRequest("No files were uploaded.");
} }
@ -447,13 +461,13 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Areas.Admin.Controllers
var extractedData = ParseShippingDocumentAIResponse(aiAnalysis); var extractedData = ParseShippingDocumentAIResponse(aiAnalysis);
//TODO: Save document record to database //TODO: Save document record to database
Console.WriteLine("AI Analysis Result:"); _logger.Detail("AI Analysis Result:");
Console.WriteLine(extractedData.RecipientName); _logger.Detail(extractedData.RecipientName);
Console.WriteLine(extractedData.SenderName); _logger.Detail(extractedData.SenderName);
Console.WriteLine(extractedData.InvoiceNumber); _logger.Detail(extractedData.InvoiceNumber);
Console.WriteLine(extractedData.TotalAmount); _logger.Detail(extractedData.TotalAmount.ToString());
Console.WriteLine(extractedData.ItemCount); _logger.Detail(extractedData.ItemCount.ToString());
Console.WriteLine(extractedData.Notes); _logger.Detail(extractedData.Notes);
var documentId = 1; // Replace with: savedDocument.Id var documentId = 1; // Replace with: savedDocument.Id
@ -492,7 +506,7 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Areas.Admin.Controllers
} }
catch (Exception ex) catch (Exception ex)
{ {
Console.WriteLine($"Error uploading file: {ex}"); _logger.Error($"Error uploading file: {ex.Message}", ex);
//return Json(new { success = false, errorMessage = ex.Message }); //return Json(new { success = false, errorMessage = ex.Message });
return BadRequest("No files were uploaded."); return BadRequest("No files were uploaded.");
} }
@ -531,7 +545,7 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Areas.Admin.Controllers
// // Log or process the file and its associated ID. // // Log or process the file and its associated ID.
// // For demonstration, let's just return a success message. // // For demonstration, let's just return a success message.
// Console.WriteLine($"Received file: {fileName} for Document ID: {shippingDocumentId}"); // _logger.Detail($"Received file: {fileName} for Document ID: {shippingDocumentId}");
// } // }
// // Return a success response. The DevExtreme FileUploader expects a 200 OK status. // // Return a success response. The DevExtreme FileUploader expects a 200 OK status.