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.Entities;
using FruitBank.Common.Interfaces;
using FruitBank.Common.Server.Interfaces;
using FruitBank.Common.SignalRs;
using Mango.Nop.Core.Loggers;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using Nop.Core.Domain.Customers;
@ -36,6 +38,8 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Areas.Admin.Controllers
[AuthorizeAdmin]
public class CustomOrderController : BaseAdminController, ICustomOrderSignalREndpointServer
{
private readonly FruitBankDbContext _dbContext;
private readonly IOrderService _orderService;
private readonly CustomOrderModelFactory _orderModelFactory;
private readonly ICustomOrderSignalREndpointServer _customOrderSignalREndpoint;
@ -46,8 +50,13 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Areas.Admin.Controllers
private readonly IProductService _productService;
// ... 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;
_orderModelFactory = orderModelFactory as CustomOrderModelFactory;
_customOrderSignalREndpoint = customOrderSignalREndpoint;
@ -100,10 +109,10 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Areas.Admin.Controllers
//return _customOrderService.
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))
{
Console.WriteLine($"Order: {item.Id}, {item.CustomOrderNumber}");
_logger.Debug($"Order: {item.Id}, {item.CustomOrderNumber}");
}
return orderListModel;
@ -158,13 +167,10 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Areas.Admin.Controllers
// Validate customer
var customer = await _customerService.GetCustomerByIdAsync(customerId);
if (customer == null)
return RedirectToAction("List");
if (customer == null) return RedirectToAction("List");
// Parse products
var orderProducts = string.IsNullOrEmpty(orderProductsJson)
? new List<OrderProductItem>()
: JsonConvert.DeserializeObject<List<OrderProductItem>>(orderProductsJson);
var orderProducts = string.IsNullOrEmpty(orderProductsJson) ? [] : JsonConvert.DeserializeObject<List<OrderProductItem>>(orderProductsJson);
// Create order
var order = new Order
@ -175,43 +181,55 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Areas.Admin.Controllers
CustomerLanguageId = customer.LanguageId ?? 1,
CustomerTaxDisplayType = TaxDisplayType.IncludingTax,
CustomerIp = string.Empty,
OrderStatusId = (int)OrderStatus.Pending,
PaymentStatusId = (int)PaymentStatus.Pending,
ShippingStatusId = (int)ShippingStatus.ShippingNotRequired,
OrderStatus = OrderStatus.Pending,
PaymentStatus = PaymentStatus.Pending,
ShippingStatus = ShippingStatus.ShippingNotRequired,
CreatedOnUtc = DateTime.UtcNow,
BillingAddressId = customer.BillingAddressId ?? 0,
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
foreach (var item in orderProducts)
var transactionSuccess = await _dbContext.TransactionSafeAsync(async _ =>
{
var product = await _productService.GetProductByIdAsync(item.Id);
if (product != null)
await _orderService.InsertOrderAsync(order);
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,
ProductId = item.Id,
Quantity = item.Quantity,
UnitPriceInclTax = item.Price,
UnitPriceExclTax = item.Price,
PriceInclTax = item.Price * item.Quantity,
PriceExclTax = item.Price * item.Quantity,
OriginalProductCost = product.ProductCost,
AttributeDescription = string.Empty,
AttributesXml = string.Empty,
DiscountAmountInclTax = 0,
DiscountAmountExclTax = 0
};
var orderItem = new OrderItem
{
OrderId = order.Id,
ProductId = item.Id,
Quantity = item.Quantity,
UnitPriceInclTax = item.Price,
UnitPriceExclTax = item.Price,
PriceInclTax = item.Price * item.Quantity,
PriceExclTax = item.Price * item.Quantity,
OriginalProductCost = product.ProductCost,
AttributeDescription = string.Empty,
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
@ -221,6 +239,11 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Areas.Admin.Controllers
public string Sku { get; set; }
public int Quantity { 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)

View File

@ -1,6 +1,8 @@
using DevExpress.Pdf.Native;
using AyCode.Core.Loggers;
using DevExpress.Pdf.Native;
using FruitBank.Common;
using FruitBank.Common.Entities;
using Mango.Nop.Core.Loggers;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
@ -26,8 +28,12 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Areas.Admin.Controllers
protected readonly AICalculationService _aiCalculationService;
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;
_dbContext = fruitBankDbContext;
_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
if (partnerId.HasValue)
{
Console.WriteLine($"Associated with Partner ID: {partnerId.Value}");
_logger.Debug($"Associated with Partner ID: {partnerId.Value}");
//let's get the partner
var partner = await _dbContext.Partners.GetByIdAsync(partnerId.Value);
@ -240,7 +246,7 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Areas.Admin.Controllers
var dbFile = new Files();
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))
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
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
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
Console.WriteLine(pdfText);
_logger.Detail(pdfText);
}
@ -350,18 +356,26 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Areas.Admin.Controllers
dbFile.FileName = extractedMetaData.DocumentNumber;
}
await _dbContext.Files.InsertAsync(dbFile);
filesList.Add(dbFile);
ShippingDocumentToFiles shippingDocumentToFiles = new ShippingDocumentToFiles
var transactionSuccess = await _dbContext.TransactionSafeAsync(async _ =>
{
ShippingDocumentId = shippingDocumentId,
FilesId = dbFile.Id,
DocumentType = extractedMetaData.DocumentType != null ? (DocumentType)Enum.Parse(typeof(DocumentType), extractedMetaData.DocumentType) : DocumentType.Unknown
};
await _dbContext.Files.InsertAsync(dbFile);
filesList.Add(dbFile);
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
// (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 }
@ -376,24 +390,24 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Areas.Admin.Controllers
if (extractedPartnerData.Name != null)
{
Console.WriteLine("AI Analysis Partner Result:");
Console.WriteLine(extractedPartnerData.Name);
_logger.Detail("AI Analysis Partner Result:");
_logger.Detail(extractedPartnerData.Name);
}
if (extractedPartnerData.TaxId != null)
{
Console.WriteLine(extractedPartnerData.TaxId);
_logger.Detail(extractedPartnerData.TaxId);
}
if (extractedPartnerData.Country != null)
{
Console.WriteLine(extractedPartnerData.Country);
_logger.Detail(extractedPartnerData.Country);
}
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)
{
Console.WriteLine($"Error saving file: {ex}");
_logger.Error($"Error saving file: {ex.Message}", ex);
//return Json(new { success = false, errorMessage = ex.Message });
return BadRequest("No files were uploaded.");
}
@ -447,13 +461,13 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Areas.Admin.Controllers
var extractedData = ParseShippingDocumentAIResponse(aiAnalysis);
//TODO: Save document record to database
Console.WriteLine("AI Analysis Result:");
Console.WriteLine(extractedData.RecipientName);
Console.WriteLine(extractedData.SenderName);
Console.WriteLine(extractedData.InvoiceNumber);
Console.WriteLine(extractedData.TotalAmount);
Console.WriteLine(extractedData.ItemCount);
Console.WriteLine(extractedData.Notes);
_logger.Detail("AI Analysis Result:");
_logger.Detail(extractedData.RecipientName);
_logger.Detail(extractedData.SenderName);
_logger.Detail(extractedData.InvoiceNumber);
_logger.Detail(extractedData.TotalAmount.ToString());
_logger.Detail(extractedData.ItemCount.ToString());
_logger.Detail(extractedData.Notes);
var documentId = 1; // Replace with: savedDocument.Id
@ -492,7 +506,7 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Areas.Admin.Controllers
}
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 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.
// // 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.