Compare commits
2 Commits
30c8cd3e00
...
b9cb52927f
| Author | SHA1 | Date |
|---|---|---|
|
|
b9cb52927f | |
|
|
55c39537ed |
|
|
@ -163,6 +163,8 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Areas.Admin.Controllers
|
||||||
OrderStatusIds = orderStatuses,
|
OrderStatusIds = orderStatuses,
|
||||||
PaymentStatusIds = paymentStatuses,
|
PaymentStatusIds = paymentStatuses,
|
||||||
ShippingStatusIds = shippingStatuses,
|
ShippingStatusIds = shippingStatuses,
|
||||||
|
AvailablePageSizes = "20,50,100,500",
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return View("~/Plugins/Misc.FruitBankPlugin/Areas/Admin/Views/Order/List.cshtml", model);
|
return View("~/Plugins/Misc.FruitBankPlugin/Areas/Admin/Views/Order/List.cshtml", model);
|
||||||
|
|
@ -214,12 +216,79 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Areas.Admin.Controllers
|
||||||
return View("~/Plugins/Misc.FruitBankPlugin/Areas/Admin/Views/Order/Edit.cshtml", model);
|
return View("~/Plugins/Misc.FruitBankPlugin/Areas/Admin/Views/Order/Edit.cshtml", model);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//public async Task<OrderListModelExtended> GetOrderListModelByFilter(OrderSearchModelExtended searchModel)
|
||||||
|
//{
|
||||||
|
// //return _customOrderService.
|
||||||
|
// var orderListModel = await _orderModelFactory.PrepareOrderListModelExtendedAsync(searchModel);
|
||||||
|
|
||||||
|
// _logger.Detail($"Total: {orderListModel.RecordsTotal}, Data Count: {orderListModel.Data.Count()}");
|
||||||
|
// foreach (var item in orderListModel.Data.Take(3))
|
||||||
|
// {
|
||||||
|
// _logger.Detail($"Order: {item.Id}, {item.CustomOrderNumber}");
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return orderListModel;
|
||||||
|
//}
|
||||||
|
|
||||||
public async Task<OrderListModelExtended> GetOrderListModelByFilter(OrderSearchModelExtended searchModel)
|
public async Task<OrderListModelExtended> GetOrderListModelByFilter(OrderSearchModelExtended searchModel)
|
||||||
{
|
{
|
||||||
//return _customOrderService.
|
|
||||||
|
var sortColumnIndex = Request.Form["order[0][column]"].FirstOrDefault();
|
||||||
|
var sortDirection = Request.Form["order[0][dir]"].FirstOrDefault();
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(sortColumnIndex))
|
||||||
|
{
|
||||||
|
// Get the column name from the column index
|
||||||
|
var columnName = Request.Form[$"columns[{sortColumnIndex}][data]"].FirstOrDefault();
|
||||||
|
|
||||||
|
searchModel.SortColumn = columnName;
|
||||||
|
searchModel.SortColumnDirection = sortDirection; // "asc" or "desc"
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the paginated data
|
||||||
var orderListModel = await _orderModelFactory.PrepareOrderListModelExtendedAsync(searchModel);
|
var orderListModel = await _orderModelFactory.PrepareOrderListModelExtendedAsync(searchModel);
|
||||||
|
|
||||||
_logger.Detail($"Total: {orderListModel.RecordsTotal}, Data Count: {orderListModel.Data.Count()}");
|
_logger.Detail($"Total: {orderListModel.RecordsTotal}, Data Count: {orderListModel.Data.Count()}");
|
||||||
|
|
||||||
|
// Apply sorting if specified
|
||||||
|
if (!string.IsNullOrEmpty(searchModel.SortColumn) && orderListModel.Data.Any())
|
||||||
|
{
|
||||||
|
var sortedData = orderListModel.Data.AsQueryable();
|
||||||
|
|
||||||
|
sortedData = searchModel.SortColumn.ToLowerInvariant() switch
|
||||||
|
{
|
||||||
|
"id" => searchModel.SortColumnDirection == "asc"
|
||||||
|
? sortedData.OrderBy(o => o.Id)
|
||||||
|
: sortedData.OrderByDescending(o => o.Id),
|
||||||
|
"customercompany" => searchModel.SortColumnDirection == "asc"
|
||||||
|
? sortedData.OrderBy(o => o.CustomerCompany)
|
||||||
|
: sortedData.OrderByDescending(o => o.CustomerCompany),
|
||||||
|
"customordernumber" => searchModel.SortColumnDirection == "asc"
|
||||||
|
? sortedData.OrderBy(o => o.CustomOrderNumber)
|
||||||
|
: sortedData.OrderByDescending(o => o.CustomOrderNumber),
|
||||||
|
"ordertotal" => searchModel.SortColumnDirection == "asc"
|
||||||
|
? sortedData.OrderBy(o => o.OrderTotal)
|
||||||
|
: sortedData.OrderByDescending(o => o.OrderTotal),
|
||||||
|
"createdon" => searchModel.SortColumnDirection == "asc"
|
||||||
|
? sortedData.OrderBy(o => o.CreatedOn)
|
||||||
|
: sortedData.OrderByDescending(o => o.CreatedOn),
|
||||||
|
"orderstatusid" => searchModel.SortColumnDirection == "asc"
|
||||||
|
? sortedData.OrderBy(o => o.OrderStatusId)
|
||||||
|
: sortedData.OrderByDescending(o => o.OrderStatusId),
|
||||||
|
"paymentstatusid" => searchModel.SortColumnDirection == "asc"
|
||||||
|
? sortedData.OrderBy(o => o.PaymentStatusId)
|
||||||
|
: sortedData.OrderByDescending(o => o.PaymentStatusId),
|
||||||
|
"shippingstatusid" => searchModel.SortColumnDirection == "asc"
|
||||||
|
? sortedData.OrderBy(o => o.ShippingStatusId)
|
||||||
|
: sortedData.OrderByDescending(o => o.ShippingStatusId),
|
||||||
|
_ => sortedData
|
||||||
|
};
|
||||||
|
|
||||||
|
orderListModel.Data = sortedData.ToList();
|
||||||
|
|
||||||
|
_logger.Detail($"Sorted by {searchModel.SortColumn} {searchModel.SortColumnDirection}");
|
||||||
|
}
|
||||||
|
|
||||||
foreach (var item in orderListModel.Data.Take(3))
|
foreach (var item in orderListModel.Data.Take(3))
|
||||||
{
|
{
|
||||||
_logger.Detail($"Order: {item.Id}, {item.CustomOrderNumber}");
|
_logger.Detail($"Order: {item.Id}, {item.CustomOrderNumber}");
|
||||||
|
|
@ -228,6 +297,7 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Areas.Admin.Controllers
|
||||||
return orderListModel;
|
return orderListModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public virtual IActionResult Test()
|
public virtual IActionResult Test()
|
||||||
{
|
{
|
||||||
// Your custom logic here
|
// Your custom logic here
|
||||||
|
|
|
||||||
|
|
@ -219,15 +219,32 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Areas.Admin.Controllers
|
||||||
return Json(model);
|
return Json(model);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
|
public async Task<IActionResult> ProcessShippingDocument(int shippingDocumentId)
|
||||||
|
{
|
||||||
|
return Ok("Ok");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
[RequestSizeLimit(10485760)] // 10MB
|
[RequestSizeLimit(10485760)] // 10MB
|
||||||
[RequestFormLimits(MultipartBodyLengthLimit = 10485760)]
|
[RequestFormLimits(MultipartBodyLengthLimit = 10485760)]
|
||||||
public async Task<IActionResult> UploadFile(List<IFormFile> files, int shippingDocumentId, int? partnerId)
|
public async Task<IActionResult> UploadFile(List<IFormFile> files, int shippingDocumentId, int? partnerId)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
//an empty shippingdocument created by the user
|
||||||
var shippingDocument = await _dbContext.ShippingDocuments.GetByIdAsync(shippingDocumentId);
|
var shippingDocument = await _dbContext.ShippingDocuments.GetByIdAsync(shippingDocumentId);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
ShippingDocumentAnalysisResult shippingDocumentAnalysisResult = new ShippingDocumentAnalysisResult();
|
||||||
|
shippingDocumentAnalysisResult.Partner = new Partner();
|
||||||
|
shippingDocumentAnalysisResult.ShippingDocument = shippingDocument;
|
||||||
|
shippingDocumentAnalysisResult.ShippingItems = new List<ShippingItem>();
|
||||||
|
shippingDocumentAnalysisResult.ShippingDocument.ShippingDocumentToFiles = new List<ShippingDocumentToFiles>();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//checks
|
//checks
|
||||||
// - files exist
|
// - files exist
|
||||||
if (!await _permissionService.AuthorizeAsync(StandardPermission.Security.ACCESS_ADMIN_PANEL))
|
if (!await _permissionService.AuthorizeAsync(StandardPermission.Security.ACCESS_ADMIN_PANEL))
|
||||||
|
|
@ -243,7 +260,7 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Areas.Admin.Controllers
|
||||||
_logger.Debug($"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);
|
shippingDocumentAnalysisResult.Partner = await _dbContext.Partners.GetByIdAsync(partnerId.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
var filesList = new List<Files>();
|
var filesList = new List<Files>();
|
||||||
|
|
@ -252,34 +269,34 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Areas.Admin.Controllers
|
||||||
//iteratation 1: iterate documents to determine their type by AI
|
//iteratation 1: iterate documents to determine their type by AI
|
||||||
|
|
||||||
|
|
||||||
foreach (var file in files)
|
for (int i = 0; i < files.Count; i++)
|
||||||
{
|
{
|
||||||
|
|
||||||
var fileName = file.FileName;
|
var fileName = files[i].FileName;
|
||||||
var fileSize = file.Length;
|
var fileSize = files[i].Length;
|
||||||
var dbFile = new Files();
|
var dbFile = new Files();
|
||||||
string pdfText = "";
|
string pdfText = "";
|
||||||
|
|
||||||
_logger.Detail($"Received file: {fileName} for Document ID: {shippingDocumentId}, content type: {file.ContentType}");
|
_logger.Detail($"Received file: {fileName} for Document ID: {shippingDocumentId}, content type: {files[i].ContentType}");
|
||||||
|
|
||||||
if (!file.ContentType.Equals("application/pdf", StringComparison.OrdinalIgnoreCase) && !file.ContentType.Equals("image/jpeg", StringComparison.OrdinalIgnoreCase))
|
if (!files[i].ContentType.Equals("application/pdf", StringComparison.OrdinalIgnoreCase) && !files[i].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" });
|
||||||
|
|
||||||
// Validate file size (max 20MB)
|
// Validate file size (max 20MB)
|
||||||
if (file.Length > 20 * 1024 * 1024)
|
if (files[i].Length > 20 * 1024 * 1024)
|
||||||
return Json(new { success = false, errorMessage = "File size must be less than 10MB" });
|
return Json(new { success = false, errorMessage = "File size must be less than 10MB" });
|
||||||
|
|
||||||
// - get text extracted from pdf
|
// - get text extracted from pdf
|
||||||
// Validate file type (PDF only)
|
// Validate file type (PDF only)
|
||||||
//if (file.Length > 0 && file.ContentType == "application/pdf")
|
//if (file.Length > 0 && file.ContentType == "application/pdf")
|
||||||
if (file.Length > 0)
|
if (files[i].Length > 0)
|
||||||
{
|
{
|
||||||
if (file.ContentType.Equals("application/pdf", StringComparison.OrdinalIgnoreCase))
|
if (files[i].ContentType.Equals("application/pdf", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// Open the PDF from the IFormFile's stream directly in memory
|
// Open the PDF from the IFormFile's stream directly in memory
|
||||||
using (var stream = file.OpenReadStream())
|
using (var stream = files[i].OpenReadStream())
|
||||||
using (var pdf = UglyToad.PdfPig.PdfDocument.Open(stream))
|
using (var pdf = UglyToad.PdfPig.PdfDocument.Open(stream))
|
||||||
{
|
{
|
||||||
// Now you can analyze the PDF content
|
// Now you can analyze the PDF content
|
||||||
|
|
@ -296,7 +313,7 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Areas.Admin.Controllers
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// ✅ Use the service we implemented earlier
|
// ✅ Use the service we implemented earlier
|
||||||
pdfText = await _openAIApiService.AnalyzePdfAsync(stream, file.FileName, "Please extract all readable text from this PDF.");
|
pdfText = await _openAIApiService.AnalyzePdfAsync(stream, files[i].FileName, "Please extract all readable text from this PDF.");
|
||||||
}
|
}
|
||||||
catch (Exception aiEx)
|
catch (Exception aiEx)
|
||||||
{
|
{
|
||||||
|
|
@ -306,14 +323,14 @@ 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
|
||||||
_logger.Detail($"Extracted text from {file.FileName}: {pdfText}");
|
_logger.Detail($"Extracted text from {files[i].FileName}: {pdfText}");
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
// Handle potential exceptions during PDF processing
|
// Handle potential exceptions during PDF processing
|
||||||
Console.Error.WriteLine($"Error processing PDF file {file.FileName}: {ex.Message}");
|
Console.Error.WriteLine($"Error processing PDF file {files[i].FileName}: {ex.Message}");
|
||||||
return StatusCode(500, $"Error processing PDF file: {ex.Message}");
|
return StatusCode(500, $"Error processing PDF file: {ex.Message}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -322,13 +339,13 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Areas.Admin.Controllers
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// Open the Image from the IFormFile's stream directly in memory
|
// Open the Image from the IFormFile's stream directly in memory
|
||||||
using (var stream = file.OpenReadStream())
|
using (var stream = files[i].OpenReadStream())
|
||||||
{
|
{
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// ✅ Use the service we implemented earlier
|
// ✅ Use the service we implemented earlier
|
||||||
pdfText = await _openAIApiService.AnalyzePdfAsync(stream, file.FileName, "Please extract all readable text from this image.");
|
pdfText = await _openAIApiService.AnalyzePdfAsync(stream, files[i].FileName, "Please extract all readable text from this image.");
|
||||||
}
|
}
|
||||||
catch (Exception aiEx)
|
catch (Exception aiEx)
|
||||||
{
|
{
|
||||||
|
|
@ -337,7 +354,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
|
||||||
_logger.Detail($"Extracted text from {file.FileName}: {pdfText}");
|
_logger.Detail($"Extracted text from {files[i].FileName}: {pdfText}");
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -345,7 +362,7 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Areas.Admin.Controllers
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
// Handle potential exceptions during PDF processing
|
// Handle potential exceptions during PDF processing
|
||||||
Console.Error.WriteLine($"Error processing PDF file {file.FileName}: {ex.Message}");
|
Console.Error.WriteLine($"Error processing PDF file {files[i].FileName}: {ex.Message}");
|
||||||
return StatusCode(500, $"Error processing PDF file: {ex.Message}");
|
return StatusCode(500, $"Error processing PDF file: {ex.Message}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -362,31 +379,7 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Areas.Admin.Controllers
|
||||||
var metaAnalyzis = await _aiCalculationService.GetOpenAIPDFAnalysisFromText(pdfText.ToString(), analysisPrompt);
|
var metaAnalyzis = await _aiCalculationService.GetOpenAIPDFAnalysisFromText(pdfText.ToString(), analysisPrompt);
|
||||||
|
|
||||||
var extractedMetaData = ParseMetaDataAIResponse(metaAnalyzis);
|
var extractedMetaData = ParseMetaDataAIResponse(metaAnalyzis);
|
||||||
|
bool transactionSuccess = await SaveFileInfoToDB(shippingDocumentId, shippingDocumentAnalysisResult, filesList, dbFile, pdfText, extractedMetaData);
|
||||||
if (extractedMetaData.DocumentNumber != null)
|
|
||||||
{
|
|
||||||
dbFile.RawText = pdfText;
|
|
||||||
dbFile.FileExtension = "pdf";
|
|
||||||
dbFile.FileName = extractedMetaData.DocumentNumber;
|
|
||||||
}
|
|
||||||
|
|
||||||
var transactionSuccess = await _dbContext.TransactionSafeAsync(async _ =>
|
|
||||||
{
|
|
||||||
await _dbContext.Files.InsertAsync(dbFile);
|
|
||||||
filesList.Add(dbFile);
|
|
||||||
|
|
||||||
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)");
|
if (!transactionSuccess) _logger.Error($"(transactionSuccess == false)");
|
||||||
|
|
||||||
|
|
@ -399,12 +392,12 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Areas.Admin.Controllers
|
||||||
//find partner in DB... there is a serious chance that the partner Name and Taxid determines the partner
|
//find partner in DB... there is a serious chance that the partner Name and Taxid determines the partner
|
||||||
|
|
||||||
var partners = await _dbContext.Partners.GetAll().ToListAsync();
|
var partners = await _dbContext.Partners.GetAll().ToListAsync();
|
||||||
foreach (var partner in partners)
|
foreach (var dbpartner in partners)
|
||||||
{
|
{
|
||||||
if (pdfText.Contains(partner.Name) || (partner.TaxId != null && pdfText.Contains(partner.TaxId)))
|
if (pdfText.Contains(dbpartner.Name) || (dbpartner.TaxId != null && pdfText.Contains(dbpartner.TaxId)))
|
||||||
{
|
{
|
||||||
partnerId = partner.Id;
|
partnerId = dbpartner.Id;
|
||||||
_logger.Detail($"Found existing partner in DB: {partner.Name} (ID: {partner.Id})");
|
_logger.Detail($"Found existing partner in DB: {dbpartner.Name} (ID: {dbpartner.Id})");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -413,48 +406,13 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Areas.Admin.Controllers
|
||||||
{
|
{
|
||||||
_logger.Detail("No existing partner found in DB, proceeding to extract partner info via AI.");
|
_logger.Detail("No existing partner found in DB, proceeding to extract partner info via AI.");
|
||||||
|
|
||||||
string partnerAnalysisPrompt = "You are an agent of Fruitbank, helping to analyze pdf content. Determine which partner of Fruitbank sent this document, extract their data and return them as JSON: name, taxId, certificationNumber, postalCode, country, state, county, city, street. " +
|
// string partnerAnalysisPrompt = "You are an agent of Fruitbank, helping to analyze pdf content. Determine which partner of Fruitbank sent this document, extract their data and return them as JSON: name, taxId, certificationNumber, postalCode, country, state, county, city, street. " +
|
||||||
"If you can't find information of any of these, return null value for that field.";
|
//"If you can't find information of any of these, return null value for that field.";
|
||||||
|
|
||||||
//here I can start preparing the file entity
|
// //here I can start preparing the file entity
|
||||||
var partnerAnalyzis = await _aiCalculationService.GetOpenAIPDFAnalysisFromText(pdfText.ToString(), partnerAnalysisPrompt);
|
// var partnerAnalyzis = await _aiCalculationService.GetOpenAIPDFAnalysisFromText(pdfText.ToString(), partnerAnalysisPrompt);
|
||||||
var extractedPartnerData = ParsePartnerDataAIResponse(partnerAnalyzis);
|
|
||||||
|
|
||||||
if (extractedPartnerData.Name != null)
|
var partnerPrompt = @"Extract the partner/company information from the following text and return ONLY a valid JSON object with these exact fields:
|
||||||
{
|
|
||||||
_logger.Detail("AI Analysis Partner Result:");
|
|
||||||
_logger.Detail(extractedPartnerData.Name);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (extractedPartnerData.TaxId != null)
|
|
||||||
{
|
|
||||||
_logger.Detail(extractedPartnerData.TaxId);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (extractedPartnerData.Country != null)
|
|
||||||
{
|
|
||||||
|
|
||||||
_logger.Detail(extractedPartnerData.Country);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (extractedPartnerData.State != null)
|
|
||||||
{
|
|
||||||
_logger.Detail(extractedPartnerData.State);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//shortcut
|
|
||||||
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
var partnerPrompt = @"Extract the partner/company information from the following text and return ONLY a valid JSON object with these exact fields:
|
|
||||||
{
|
{
|
||||||
""Name"": ""company name"",
|
""Name"": ""company name"",
|
||||||
""TaxId"": ""tax identification number"",
|
""TaxId"": ""tax identification number"",
|
||||||
|
|
@ -472,13 +430,54 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Areas.Admin.Controllers
|
||||||
Text to analyze:
|
Text to analyze:
|
||||||
" + pdfText;
|
" + pdfText;
|
||||||
|
|
||||||
var partnerResponse = await _aiCalculationService.GetOpenAIPDFAnalysisFromText(
|
var partnerResponse = await _aiCalculationService.GetOpenAIPDFAnalysisFromText(
|
||||||
pdfText,
|
pdfText,
|
||||||
partnerPrompt
|
partnerPrompt
|
||||||
);
|
);
|
||||||
|
|
||||||
|
shippingDocumentAnalysisResult.Partner = JsonSerializer.Deserialize<Partner>(CleanJsonResponse(partnerResponse),
|
||||||
|
new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
|
||||||
|
|
||||||
|
|
||||||
|
if (shippingDocumentAnalysisResult.Partner.Name != null)
|
||||||
|
{
|
||||||
|
_logger.Detail("AI Analysis Partner Result:");
|
||||||
|
_logger.Detail(shippingDocumentAnalysisResult.Partner.Name);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shippingDocumentAnalysisResult.Partner.TaxId != null)
|
||||||
|
{
|
||||||
|
_logger.Detail(shippingDocumentAnalysisResult.Partner.TaxId);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shippingDocumentAnalysisResult.Partner.Country != null)
|
||||||
|
{
|
||||||
|
|
||||||
|
_logger.Detail(shippingDocumentAnalysisResult.Partner.Country);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shippingDocumentAnalysisResult.Partner.State != null)
|
||||||
|
{
|
||||||
|
_logger.Detail(shippingDocumentAnalysisResult.Partner.State);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shippingDocumentAnalysisResult.Partner != null)
|
||||||
|
{
|
||||||
|
shippingDocumentAnalysisResult.Partner = shippingDocumentAnalysisResult.Partner;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//shortcut
|
||||||
|
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
|
||||||
var partner = JsonSerializer.Deserialize<Partner>(CleanJsonResponse(partnerResponse),
|
|
||||||
new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
|
|
||||||
|
|
||||||
// Step 2: Extract Shipping Document Information
|
// Step 2: Extract Shipping Document Information
|
||||||
var shippingDocPrompt = @"Extract the shipping document information from the following text and return ONLY a valid JSON object with these exact fields:
|
var shippingDocPrompt = @"Extract the shipping document information from the following text and return ONLY a valid JSON object with these exact fields:
|
||||||
|
|
@ -504,20 +503,20 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Areas.Admin.Controllers
|
||||||
|
|
||||||
// Step 3: Extract Shipping Items
|
// Step 3: Extract Shipping Items
|
||||||
var itemsPrompt = @"Extract all shipping items (fruits, vegetables, or products) from the following text and return ONLY a valid JSON array with objects having these exact fields:
|
var itemsPrompt = @"Extract all shipping items (fruits, vegetables, or products) from the following text and return ONLY a valid JSON array with objects having these exact fields:
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
""Name"": ""product name"",
|
""Name"": ""product name"",
|
||||||
""PalletsOnDocument"": number_of_pallets,
|
""PalletsOnDocument"": number_of_pallets,
|
||||||
""QuantityOnDocument"": quantity_count,
|
""QuantityOnDocument"": quantity_count,
|
||||||
""NetWeightOnDocument"": net_weight_in_kg,
|
""NetWeightOnDocument"": net_weight_in_kg,
|
||||||
""GrossWeightOnDocument"": gross_weight_in_kg
|
""GrossWeightOnDocument"": gross_weight_in_kg
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
If a numeric field is not found, use 0. Return ONLY the JSON array, no additional text or explanation.
|
If a numeric field is not found, use 0. Return ONLY the JSON array, no additional text or explanation.
|
||||||
|
|
||||||
Text to analyze:
|
Text to analyze:
|
||||||
" + pdfText;
|
" + pdfText;
|
||||||
|
|
||||||
var itemsResponse = await _aiCalculationService.GetOpenAIPDFAnalysisFromText(
|
var itemsResponse = await _aiCalculationService.GetOpenAIPDFAnalysisFromText(
|
||||||
pdfText,
|
pdfText,
|
||||||
|
|
@ -530,7 +529,7 @@ Text to analyze:
|
||||||
// Prepare result
|
// Prepare result
|
||||||
var result = new ShippingDocumentAnalysisResult
|
var result = new ShippingDocumentAnalysisResult
|
||||||
{
|
{
|
||||||
Partner = partner,
|
Partner = shippingDocumentAnalysisResult.Partner,
|
||||||
ShippingDocument = new ShippingDocument
|
ShippingDocument = new ShippingDocument
|
||||||
{
|
{
|
||||||
DocumentIdNumber = shippingDocData.DocumentIdNumber,
|
DocumentIdNumber = shippingDocData.DocumentIdNumber,
|
||||||
|
|
@ -541,56 +540,40 @@ Text to analyze:
|
||||||
ShippingItems = items
|
ShippingItems = items
|
||||||
};
|
};
|
||||||
|
|
||||||
return Ok(result);
|
//return Ok(result);
|
||||||
}
|
}
|
||||||
catch (JsonException ex)
|
catch (JsonException ex)
|
||||||
{
|
{
|
||||||
return BadRequest($"Failed to parse AI response: {ex.Message}");
|
return BadRequest($"Failed to parse AI response: {ex.Message}");
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
return StatusCode(500, $"An error occurred: {ex.Message}");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// - save the documents to file system - wwwroot/uploads/orders/order-{orderId}/fileId-documentId.pdf
|
// - save the documents to file system - wwwroot/uploads/orders/order-{orderId}/fileId-documentId.pdf
|
||||||
// where documentId is the number or id IN the document
|
// where documentId is the number or id IN the document
|
||||||
//try
|
try
|
||||||
//{
|
{
|
||||||
// // Create upload directory if it doesn't exist
|
// Create upload directory if it doesn't exist
|
||||||
// var uploadsPath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "uploads", "orders", "order" + shippingDocumentId.ToString(), "documents");
|
var uploadsPath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "uploads", "orders", "order" + shippingDocumentId.ToString(), "documents");
|
||||||
// Directory.CreateDirectory(uploadsPath);
|
Directory.CreateDirectory(uploadsPath);
|
||||||
|
|
||||||
// // Generate unique filename
|
// Generate unique filename
|
||||||
// fileName = $"{Guid.NewGuid()}_{file.FileName}";
|
fileName = $"{Guid.NewGuid()}_{files[i].FileName}";
|
||||||
// var filePath = Path.Combine(uploadsPath, fileName);
|
var filePath = Path.Combine(uploadsPath, fileName);
|
||||||
|
|
||||||
// // Save file
|
// Save file
|
||||||
// using (var stream = new FileStream(filePath, FileMode.Create))
|
using (var stream = new FileStream(filePath, FileMode.Create))
|
||||||
// {
|
{
|
||||||
// await file.CopyToAsync(stream);
|
await files[i].CopyToAsync(stream);
|
||||||
// }
|
}
|
||||||
//}
|
|
||||||
//catch (Exception ex)
|
return Ok(shippingDocumentAnalysisResult);
|
||||||
//{
|
}
|
||||||
// _logger.Error($"Error saving file: {ex.Message}", ex);
|
catch (Exception ex)
|
||||||
// //return Json(new { success = false, errorMessage = ex.Message });
|
{
|
||||||
// return BadRequest("No files were uploaded.");
|
_logger.Error($"Error saving file: {ex.Message}", ex);
|
||||||
//}
|
//return Json(new { success = false, errorMessage = ex.Message });
|
||||||
|
return BadRequest("No files were uploaded.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// - create a list of documents to read information and to save the document's information to DB
|
// - create a list of documents to read information and to save the document's information to DB
|
||||||
|
|
@ -680,6 +663,35 @@ Text to analyze:
|
||||||
return Ok($"Files for Shipping Document ID {shippingDocumentId} were uploaded successfully!");
|
return Ok($"Files for Shipping Document ID {shippingDocumentId} were uploaded successfully!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async Task<bool> SaveFileInfoToDB(int shippingDocumentId, ShippingDocumentAnalysisResult shippingDocumentAnalysisResult, List<Files> filesList, Files dbFile, string pdfText, ExtractedDocumentMetaData extractedMetaData)
|
||||||
|
{
|
||||||
|
if (extractedMetaData.DocumentNumber != null)
|
||||||
|
{
|
||||||
|
dbFile.RawText = pdfText;
|
||||||
|
dbFile.FileExtension = "pdf";
|
||||||
|
dbFile.FileName = extractedMetaData.DocumentNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
var transactionSuccess = await _dbContext.TransactionSafeAsync(async _ =>
|
||||||
|
{
|
||||||
|
await _dbContext.Files.InsertAsync(dbFile);
|
||||||
|
filesList.Add(dbFile);
|
||||||
|
|
||||||
|
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());
|
||||||
|
shippingDocumentAnalysisResult.ShippingDocument.ShippingDocumentToFiles.Add(shippingDocumentToFiles);
|
||||||
|
await _dbContext.ShippingDocumentToFiles.InsertAsync(shippingDocumentToFiles);
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
return transactionSuccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//[HttpPost]
|
//[HttpPost]
|
||||||
//public async Task<IActionResult> UploadFile(List<IFormFile> files, int shippingDocumentId)
|
//public async Task<IActionResult> UploadFile(List<IFormFile> files, int shippingDocumentId)
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,8 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Areas.Admin.Models.Order
|
||||||
[NopResourceDisplayName("Admin.Orders.List.BillingCompany")]
|
[NopResourceDisplayName("Admin.Orders.List.BillingCompany")]
|
||||||
public string BillingCompany { get; set; }
|
public string BillingCompany { get; set; }
|
||||||
|
|
||||||
//public IList<SelectListItem> AvailableCompanies { get; set; }
|
public string SortColumn { get; set; }
|
||||||
|
public string SortColumnDirection { get; set; }
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,8 +11,7 @@
|
||||||
|
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-6">
|
<div class="col-6">
|
||||||
|
|
||||||
<form method="post" enctype="multipart/form-data" asp-controller="ManagementPage" asp-action="UploadFile">
|
<form method="post" enctype="multipart/form-data" asp-controller="ManagementPage" asp-action="UploadFile">
|
||||||
@(Html.DevExtreme().FileUploader()
|
@(Html.DevExtreme().FileUploader()
|
||||||
.ID("shippingDocumentUploader-" + contextId)
|
.ID("shippingDocumentUploader-" + contextId)
|
||||||
|
|
@ -31,6 +30,12 @@
|
||||||
.UseSubmitBehavior(true)
|
.UseSubmitBehavior(true)
|
||||||
)
|
)
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
|
||||||
|
<button type="button" class="btn btn-primary mt-2" onclick="processShippingDocument_@(contextId)()">
|
||||||
|
<i class="fas fa-cog"></i> Process Shipping Document
|
||||||
|
</button>
|
||||||
|
|
||||||
<div class="content" id="selected-files">
|
<div class="content" id="selected-files">
|
||||||
<div>
|
<div>
|
||||||
<h4>Selected Files</h4>
|
<h4>Selected Files</h4>
|
||||||
|
|
@ -56,6 +61,27 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<script>
|
<script>
|
||||||
|
// Process Shipping Document function
|
||||||
|
function processShippingDocument_@(contextId)() {
|
||||||
|
var shippingDocumentId = @contextId;
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
url: '@Url.Action("ProcessShippingDocument", "ManagementPage")',
|
||||||
|
type: 'POST',
|
||||||
|
data: { shippingDocumentId: shippingDocumentId },
|
||||||
|
success: function(response) {
|
||||||
|
DevExpress.ui.notify("Shipping document processed successfully!", "success", 2000);
|
||||||
|
// Refresh the file manager
|
||||||
|
var fileManager = $("#@fileManagerId").dxFileManager("instance");
|
||||||
|
if (fileManager) {
|
||||||
|
fileManager.refresh();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
error: function(xhr, status, error) {
|
||||||
|
DevExpress.ui.notify("Error processing shipping document: " + error, "error", 3000);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function fileUploader_valueChanged(e) {
|
function fileUploader_valueChanged(e) {
|
||||||
var files = e.value;
|
var files = e.value;
|
||||||
|
|
|
||||||
|
|
@ -348,8 +348,10 @@
|
||||||
Name = "orders-grid",
|
Name = "orders-grid",
|
||||||
UrlRead = new DataUrl("OrderList", "CustomOrder", null),
|
UrlRead = new DataUrl("OrderList", "CustomOrder", null),
|
||||||
SearchButtonId = "search-orders",
|
SearchButtonId = "search-orders",
|
||||||
// Ordering = true,
|
Ordering = true,
|
||||||
// ServerSide = false,
|
ServerSide = true,
|
||||||
|
Paging = true,
|
||||||
|
PagingType = "simple_numbers", // or Full
|
||||||
Length = Model.PageSize,
|
Length = Model.PageSize,
|
||||||
LengthMenu = Model.AvailablePageSizes,
|
LengthMenu = Model.AvailablePageSizes,
|
||||||
FooterCallback = !Model.IsLoggedInAsVendor ? "ordersfootercallback" : null,
|
FooterCallback = !Model.IsLoggedInAsVendor ? "ordersfootercallback" : null,
|
||||||
|
|
|
||||||
|
|
@ -279,7 +279,7 @@
|
||||||
},
|
},
|
||||||
new ColumnProperty(nameof(ProductModelExtended.IncomingQuantity))
|
new ColumnProperty(nameof(ProductModelExtended.IncomingQuantity))
|
||||||
{
|
{
|
||||||
Title = "Bejövő"//T("Admin.Catalog.Products.Fields.Tare").Text
|
Title = "Kamionon"//T("Admin.Catalog.Products.Fields.Tare").Text
|
||||||
},
|
},
|
||||||
new ColumnProperty(nameof(ProductModelExtended.NetWeight))
|
new ColumnProperty(nameof(ProductModelExtended.NetWeight))
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -268,9 +268,12 @@ public class MgOrderModelFactory<TOrderListModelExt, TOrderModelExt> : OrderMode
|
||||||
}
|
}
|
||||||
|
|
||||||
prefiltered.Data = null;
|
prefiltered.Data = null;
|
||||||
|
var totalRecords = prefiltered.RecordsTotal;
|
||||||
|
var filteredRecords = prefiltered.RecordsFiltered;
|
||||||
|
|
||||||
|
|
||||||
//var orderListModelExtended = orderListModel.ToJson().JsonTo<TOrderListModelExt>();
|
//var orderListModelExtended = orderListModel.ToJson().JsonTo<TOrderListModelExt>();
|
||||||
if(searchModel.BillingCompany != null)
|
if (searchModel.BillingCompany != null)
|
||||||
{
|
{
|
||||||
//extendedRows = extendedRows.Where(x => x.CustomerCompany != null && x.CustomerCompany.IndexOf(searchModel.BillingCompany, StringComparison.InvariantCultureIgnoreCase) >= 0).ToList();
|
//extendedRows = extendedRows.Where(x => x.CustomerCompany != null && x.CustomerCompany.IndexOf(searchModel.BillingCompany, StringComparison.InvariantCultureIgnoreCase) >= 0).ToList();
|
||||||
extendedRows = extendedRows.Where(x => x.CustomerId == Convert.ToInt32(searchModel.BillingCompany)).ToList();
|
extendedRows = extendedRows.Where(x => x.CustomerId == Convert.ToInt32(searchModel.BillingCompany)).ToList();
|
||||||
|
|
@ -279,7 +282,9 @@ public class MgOrderModelFactory<TOrderListModelExt, TOrderModelExt> : OrderMode
|
||||||
|
|
||||||
var orderListModelExtended = prefiltered.CloneTo<TOrderListModelExt>();
|
var orderListModelExtended = prefiltered.CloneTo<TOrderListModelExt>();
|
||||||
orderListModelExtended.Data = extendedRows;
|
orderListModelExtended.Data = extendedRows;
|
||||||
orderListModelExtended.RecordsFiltered = extendedRows.Count;
|
|
||||||
|
orderListModelExtended.RecordsTotal = totalRecords;
|
||||||
|
orderListModelExtended.RecordsFiltered = filteredRecords;
|
||||||
return orderListModelExtended;
|
return orderListModelExtended;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -146,6 +146,11 @@ public class RouteProvider : IRouteProvider
|
||||||
name: "Plugin.FruitBank.Admin.Order.Edit",
|
name: "Plugin.FruitBank.Admin.Order.Edit",
|
||||||
pattern: "Admin/Order/Edit/{id}",
|
pattern: "Admin/Order/Edit/{id}",
|
||||||
defaults: new { controller = "CustomOrder", action = "Edit", area = AreaNames.ADMIN });
|
defaults: new { controller = "CustomOrder", action = "Edit", area = AreaNames.ADMIN });
|
||||||
|
|
||||||
|
endpointRouteBuilder.MapControllerRoute(
|
||||||
|
name: "Plugin.FruitBank.Admin.ManagementPage.ProcessShippingDocument",
|
||||||
|
pattern: "Admin/ManagamentPage/ProcessShippingDocument/{id}",
|
||||||
|
defaults: new { controller = "ManagementPage", action = "ProcessShippingdocument", area = AreaNames.ADMIN });
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Services
|
||||||
|
|
||||||
public async Task<string> GetOpenAIPDFAnalysisFromText(string pdfText, string userQuestion)
|
public async Task<string> GetOpenAIPDFAnalysisFromText(string pdfText, string userQuestion)
|
||||||
{
|
{
|
||||||
var systemMessage = $"You are a pdf analyzis assistant, the user is asking you questions about a PDF document, that you have access to. The content of the PDF document is the following: {pdfText}";
|
var systemMessage = $"You are a pdf analyzis assistant of FRUITBANK, the user is asking you questions about a PDF document, that you have access to. The content of the PDF document is the following: {pdfText}";
|
||||||
var response = await _openAIApiService.GetSimpleResponseAsync(systemMessage, userQuestion);
|
var response = await _openAIApiService.GetSimpleResponseAsync(systemMessage, userQuestion);
|
||||||
|
|
||||||
if (response == null) return string.Empty;
|
if (response == null) return string.Empty;
|
||||||
|
|
|
||||||
|
|
@ -2,41 +2,80 @@
|
||||||
@model OrderAttributesModel
|
@model OrderAttributesModel
|
||||||
|
|
||||||
<!-- InnVoice Management Section -->
|
<!-- InnVoice Management Section -->
|
||||||
<div class="card card-default mb-3">
|
<!-- Order Subsection -->
|
||||||
<div class="card-header">
|
<div class="form-group row">
|
||||||
<i class="fas fa-file-invoice"></i>
|
|
||||||
InnVoice Management
|
<div class="col-12 col-md-6">
|
||||||
|
<div class="card card-default mb-3">
|
||||||
|
<div class="card-header">
|
||||||
|
<i class="fas fa-file-invoice"></i>
|
||||||
|
Megrendelés beállítások
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="form-group row">
|
||||||
|
<div class="col-md-3 text-right">
|
||||||
|
<strong>Mérés információ</strong>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-9">
|
||||||
|
@(Model.IsMeasurable ? "Mérendő" : "Nem mérendő")
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row">
|
||||||
|
<div class="col-md-3">
|
||||||
|
<nop-label asp-for="DateOfReceipt" />
|
||||||
|
</div>
|
||||||
|
<div class="col-md-9">
|
||||||
|
<nop-editor asp-for="DateOfReceipt" asp-template="" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row">
|
||||||
|
<div class="col-md-12 text-right">
|
||||||
|
<button type="button" id="saveAttributesBtn" class="btn btn-primary">
|
||||||
|
<i class="fa fa-save"></i> Save Attributes
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body">
|
|
||||||
<!-- Order Subsection -->
|
<div class="col-12 col-md-6">
|
||||||
<div class="form-group row">
|
<div class="card card-default mb-3">
|
||||||
<h3>Innvoice</h3>
|
<div class="card-header">
|
||||||
<div class="col-12 col-md-3">
|
<i class="fas fa-file-invoice"></i>
|
||||||
<h5><i class="fas fa-shopping-cart"></i> Megrendelés beküldése Innvoice-ba</h5>
|
InnVoice Management
|
||||||
<div id="orderStatus" class="alert alert-info" style="display: none;">
|
</div>
|
||||||
<i class="fas fa-info-circle"></i> <span id="orderStatusMessage"></span>
|
<div class="card-body">
|
||||||
|
<div class="col-6">
|
||||||
|
<h5><i class="fas fa-shopping-cart"></i> Megrendelés beküldése Innvoice-ba</h5>
|
||||||
|
<div id="orderStatus" class="alert alert-info" style="display: none;">
|
||||||
|
<i class="fas fa-info-circle"></i> <span id="orderStatusMessage"></span>
|
||||||
|
</div>
|
||||||
|
<div id="orderDetails" style="display: none;">
|
||||||
|
<p><strong>Order Table ID:</strong> <span id="orderTableId"></span></p>
|
||||||
|
<p><strong>Order Tech ID:</strong> <span id="orderTechId"></span></p>
|
||||||
|
<p>
|
||||||
|
<a id="orderPdfLink" href="#" target="_blank" class="btn btn-sm btn-info">
|
||||||
|
<i class="fas fa-file-pdf"></i> PDF megtekintése
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="orderDetails" style="display: none;">
|
|
||||||
<p><strong>Order Table ID:</strong> <span id="orderTableId"></span></p>
|
<div class="col-6 text-right float-end">
|
||||||
<p><strong>Order Tech ID:</strong> <span id="orderTechId"></span></p>
|
<button type="button" id="createOrderBtn" class="btn btn-success">
|
||||||
<p>
|
<i class="fas fa-shopping-cart"></i> Létrehozás
|
||||||
<a id="orderPdfLink" href="#" target="_blank" class="btn btn-sm btn-info">
|
</button>
|
||||||
<i class="fas fa-file-pdf"></i> PDF megtekintése
|
<button type="button" id="checkOrderBtn" class="btn btn-secondary" style="display: none;">
|
||||||
</a>
|
<i class="fas fa-sync"></i> Invoice adat ellenőrzése
|
||||||
</p>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="col-12 col-md-3 text-right float-end">
|
|
||||||
<button type="button" id="createOrderBtn" class="btn btn-success">
|
|
||||||
<i class="fas fa-shopping-cart"></i> Létrehozás
|
|
||||||
</button>
|
|
||||||
<button type="button" id="checkOrderBtn" class="btn btn-secondary" style="display: none;">
|
|
||||||
<i class="fas fa-sync"></i> Invoice adat ellenőrzése
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
@* <div class="col-12 col-md-3">
|
@* <div class="col-12 col-md-3">
|
||||||
<h5><i class="fas fa-file-invoice-dollar"></i> Invoice</h5>
|
<h5><i class="fas fa-file-invoice-dollar"></i> Invoice</h5>
|
||||||
<div id="invoiceStatus" class="alert alert-info" style="display: none;">
|
<div id="invoiceStatus" class="alert alert-info" style="display: none;">
|
||||||
<i class="fas fa-info-circle"></i> <span id="invoiceStatusMessage"></span>
|
<i class="fas fa-info-circle"></i> <span id="invoiceStatusMessage"></span>
|
||||||
|
|
@ -52,7 +91,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div> *@
|
</div> *@
|
||||||
|
|
||||||
@* <div class="col-12 col-md-3 text-right">
|
@* <div class="col-12 col-md-3 text-right">
|
||||||
<button type="button" id="createInvoiceBtn" class="btn btn-success">
|
<button type="button" id="createInvoiceBtn" class="btn btn-success">
|
||||||
<i class="fas fa-file-invoice-dollar"></i> Create Invoice
|
<i class="fas fa-file-invoice-dollar"></i> Create Invoice
|
||||||
</button>
|
</button>
|
||||||
|
|
@ -60,41 +99,10 @@
|
||||||
<i class="fas fa-sync"></i> Refresh Invoice
|
<i class="fas fa-sync"></i> Refresh Invoice
|
||||||
</button>
|
</button>
|
||||||
</div> *@
|
</div> *@
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Attributes Section (NO FORM TAG - just a div) -->
|
|
||||||
<div id="orderAttributesSection">
|
|
||||||
<div class="form-group row">
|
|
||||||
<div class="col-12">
|
|
||||||
<div class="form-group row">
|
|
||||||
<div class="col-md-3 text-right">
|
|
||||||
<strong>Mérés információ</strong>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-9">
|
|
||||||
@(Model.IsMeasurable ? "Mérendő" : "Nem mérendő")
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group row">
|
|
||||||
<div class="col-md-3">
|
|
||||||
<nop-label asp-for="DateOfReceipt" />
|
|
||||||
</div>
|
|
||||||
<div class="col-md-9">
|
|
||||||
<nop-editor asp-for="DateOfReceipt" asp-template="" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group row">
|
|
||||||
<div class="col-md-12 text-right">
|
|
||||||
<button type="button" id="saveAttributesBtn" class="btn btn-primary">
|
|
||||||
<i class="fa fa-save"></i> Save Attributes
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
$(document).ready(function () {
|
$(document).ready(function () {
|
||||||
var createOrderUrl = '/Admin/InnVoiceOrder/CreateOrder';
|
var createOrderUrl = '/Admin/InnVoiceOrder/CreateOrder';
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue