AI finalized

This commit is contained in:
Adam 2026-02-10 23:03:29 +01:00
parent 15dbec5aad
commit 611df8f60f
5 changed files with 696 additions and 644 deletions

View File

@ -14,6 +14,7 @@ using Nop.Plugin.Misc.FruitBankPlugin.Helpers;
using Nop.Plugin.Misc.FruitBankPlugin.Services;
using Nop.Plugin.Misc.FruitBankPlugin.Services.FileStorage;
using Nop.Services.Catalog;
using Nop.Services.Common;
using Nop.Services.Security;
using Nop.Web.Framework;
using Nop.Web.Framework.Controllers;
@ -31,31 +32,37 @@ namespace Nop.Plugin.Misc.FruitBank.Controllers
{
private readonly IPermissionService _permissionService;
private readonly OpenAIApiService _aiApiService;
private readonly CerebrasAPIService _cerebrasApiService;
private readonly AICalculationService _aiCalculationService;
private readonly IProductService _productService;
private readonly FruitBankDbContext _dbContext;
private readonly PdfToImageService _pdfToImageService;
private readonly IWorkContext _workContext;
private readonly FileStorageService _fileStorageService;
private readonly FruitBankAttributeService _fruitBankAttributeService;
public FileManagerController(
IPermissionService permissionService,
OpenAIApiService aiApiService,
CerebrasAPIService cerebrasApiService,
AICalculationService aiCalculationService,
IProductService productService,
FruitBankDbContext fruitBankDbContext,
PdfToImageService pdfToImageService,
IWorkContext workContext,
FileStorageService fileStorageService)
FileStorageService fileStorageService,
FruitBankAttributeService fruitBankAttributeService)
{
_permissionService = permissionService;
_aiApiService = aiApiService;
_cerebrasApiService = cerebrasApiService;
_aiCalculationService = aiCalculationService;
_productService = productService;
_dbContext = fruitBankDbContext;
_pdfToImageService = pdfToImageService;
_workContext = workContext;
_fileStorageService = fileStorageService;
_fruitBankAttributeService = fruitBankAttributeService;
}
/// <summary>
@ -483,7 +490,8 @@ namespace Nop.Plugin.Misc.FruitBank.Controllers
deserializedProduct.name + "\n\n" +
"Return the best matching product name from the catalog above (matching ALL details including size/grade), or 'NONE' if no good match exists.";
var aiMatchedProductName = await _aiApiService.GetSimpleResponseAsync(systemPrompt, userPrompt);
//var aiMatchedProductName = await _aiApiService.GetSimpleResponseAsync(systemPrompt, userPrompt);
var aiMatchedProductName = await _cerebrasApiService.GetSimpleResponseAsync(systemPrompt, userPrompt);
//var aiMatchedProductName = await _aiApiService.GetSimpleResponseAsync(aiMatchPrompt, deserializedProduct.name);
Console.WriteLine($"AI matched product name for {deserializedProduct.name}: {aiMatchedProductName}");
@ -577,7 +585,8 @@ namespace Nop.Plugin.Misc.FruitBank.Controllers
deserializedProduct.name + "\n\n" +
"Return the best matching product name from the catalog above that matches ALL details (size, grade, quality), or 'NONE' if no confident match exists.";
var aiMatchedProductName2 = await _aiApiService.GetSimpleResponseAsync(systemPrompt2, userPrompt2);
//var aiMatchedProductName2 = await _aiApiService.GetSimpleResponseAsync(systemPrompt2, userPrompt2);
var aiMatchedProductName2 = await _cerebrasApiService.GetSimpleResponseAsync(systemPrompt2, userPrompt2);
Console.WriteLine($"AI matched product name from hybrid catalog for {deserializedProduct.name}: {aiMatchedProductName2}");
if (!string.IsNullOrEmpty(aiMatchedProductName2) && aiMatchedProductName2 != "NONE")
@ -737,7 +746,8 @@ namespace Nop.Plugin.Misc.FruitBank.Controllers
partnerAnalysis + "\n\n" +
"Return ONLY the numeric ID of the matching partner, or '0' if no match found.";
var aiResponse = await _aiApiService.GetSimpleResponseAsync(systemPrompt, userPrompt);
//var aiResponse = await _aiApiService.GetSimpleResponseAsync(systemPrompt, userPrompt);
var aiResponse = await _cerebrasApiService.GetSimpleResponseAsync(systemPrompt, userPrompt);
Console.WriteLine($"AI Partner Match Response: {aiResponse}");
// Parse the ID
@ -828,7 +838,8 @@ namespace Nop.Plugin.Misc.FruitBank.Controllers
"4. Return ONLY the company name, nothing else\n\n" +
"If uncertain, return the most prominent non-FruitBank company name from the document.";
var partnerAnalysis = await _aiApiService.GetSimpleResponseAsync(systemPrompt, userPrompt);
//var partnerAnalysis = await _aiApiService.GetSimpleResponseAsync(systemPrompt, userPrompt);
var partnerAnalysis = await _cerebrasApiService.GetSimpleResponseAsync(systemPrompt, userPrompt);
// Clean up the response
var cleanedPartnerName = CleanPartnerName(partnerAnalysis);
@ -1087,6 +1098,17 @@ namespace Nop.Plugin.Misc.FruitBank.Controllers
Console.WriteLine("⚠ No original file provided - skipping file save");
}
//everything done, let's update the genericattribute "IncomingQuantity" of the product
foreach (var item in shippingDocument.ShippingItems.Where(x => x.ProductId != null))
{
await _fruitBankAttributeService.InsertOrUpdateGenericAttributeAsync<Product, int>(
item.ProductId.Value,
"IncomingQuantity",
item.QuantityOnDocument
);
}
return Json(new
{
success = true,

View File

@ -24,6 +24,7 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Areas.Admin.Controllers
{
private readonly IPermissionService _permissionService;
private readonly OpenAIApiService _aiApiService;
private readonly CerebrasAPIService _cerebrasApiService;
private readonly ICustomerService _customerService;
private readonly IProductService _productService;
private readonly FruitBankDbContext _dbContext;
@ -31,12 +32,14 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Areas.Admin.Controllers
public VoiceOrderController(
IPermissionService permissionService,
OpenAIApiService aiApiService,
CerebrasAPIService cerebrasApiService,
ICustomerService customerService,
IProductService productService,
FruitBankDbContext dbContext)
{
_permissionService = permissionService;
_aiApiService = aiApiService;
_cerebrasApiService = cerebrasApiService;
_customerService = customerService;
_productService = productService;
_dbContext = dbContext;
@ -320,6 +323,12 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Areas.Admin.Controllers
transcribedText = await _aiApiService.TranscribeAudioAsync(audioStream, fileName, language, customPrompt);
}
if(transcribedText.EndsWith(".") || transcribedText.EndsWith("!") || transcribedText.EndsWith("?"))
{
//remove trailing punctuation
transcribedText = transcribedText.Substring(0, transcribedText.Length - 1);
}
// Clean up temporary file
try
{
@ -412,9 +421,7 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Areas.Admin.Controllers
try
{
// Get all customers with company names (increased limit)
var allCustomersWithCompany = await _customerService.GetAllCustomersAsync(
pageIndex: 0,
pageSize: 1000); // Increased from 500 to catch more companies
var allCustomersWithCompany = await _customerService.GetAllCustomersAsync(); // Increased from 500 to catch more companies
// Filter to only those with company names
var customersWithCompany = allCustomersWithCompany
@ -441,7 +448,7 @@ CRITICAL MATCHING RULES (in priority order):
2. SUBSTRING MATCH: If the search term is contained within a company name (e.g., 'Junket' in 'Junket Silver Kft.')
3. WORD MATCH: If all words from search term appear in company name (any order)
4. PARTIAL MATCH: If significant words overlap (e.g., 'Silver' matches 'Junket Silver')
5. PHONETIC SIMILARITY: How it sounds when spoken
5. PHONETIC SIMILARITY: How it sounds when spoken in Hungarian (e.g. 'Ökotály' should be matched to 'Öcotáj')
6. ABBREVIATIONS: 'SFI' matches 'SFI Rotterdam B.V.'
EXAMPLES:
@ -461,7 +468,8 @@ OUTPUT FORMAT (JSON only):
Companies:
{companyList}";
var aiResponse = await _aiApiService.GetSimpleResponseAsync(systemPrompt, userPrompt);
//var aiResponse = await _aiApiService.GetSimpleResponseAsync(systemPrompt, userPrompt);
var aiResponse = await _cerebrasApiService.GetSimpleResponseAsync(systemPrompt, userPrompt);
Console.WriteLine($"[VoiceOrder] AI company matching response: {aiResponse}");
@ -552,7 +560,8 @@ Output: [{""product"":""szőlő"",""quantity"":50}]";
var userPrompt = $"Parse this: {text}";
var aiResponse = await _aiApiService.GetSimpleResponseAsync(systemPrompt, userPrompt);
//var aiResponse = await _aiApiService.GetSimpleResponseAsync(systemPrompt, userPrompt);
var aiResponse = await _cerebrasApiService.GetSimpleResponseAsync(systemPrompt, userPrompt);
Console.WriteLine($"[VoiceOrder] AI Response: {aiResponse}");

View File

@ -333,6 +333,7 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Services
"TaxId",
customer.VatNumber);
}
_dbContext.Customers.Update(customer, false);
}
}
}

View File

@ -840,7 +840,7 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Services
role = "system",
content = new object[]
{
new { type = "text", text = prompt },
new { type = "text", text = systemPrompt },
}
},
new {