Compare commits
No commits in common. "0bee8979b7659bfd665722112cc209df1d4797fb" and "0035725399a5f0208a73a37d9d064ba93ed5cbfc" have entirely different histories.
0bee8979b7
...
0035725399
|
|
@ -5,30 +5,19 @@ using FruitBank.Common.Interfaces;
|
||||||
using FruitBank.Common.Server.Interfaces;
|
using FruitBank.Common.Server.Interfaces;
|
||||||
using FruitBank.Common.SignalRs;
|
using FruitBank.Common.SignalRs;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Newtonsoft.Json;
|
|
||||||
using Nop.Core.Domain.Customers;
|
|
||||||
using Nop.Core.Domain.Orders;
|
using Nop.Core.Domain.Orders;
|
||||||
using Nop.Core.Domain.Payments;
|
|
||||||
using Nop.Core.Domain.Shipping;
|
|
||||||
using Nop.Core.Domain.Tax;
|
|
||||||
using Nop.Plugin.Misc.FruitBankPlugin.Domains.DataLayer;
|
using Nop.Plugin.Misc.FruitBankPlugin.Domains.DataLayer;
|
||||||
using Nop.Plugin.Misc.FruitBankPlugin.Factories;
|
using Nop.Plugin.Misc.FruitBankPlugin.Factories;
|
||||||
using Nop.Plugin.Misc.FruitBankPlugin.Models.Orders;
|
using Nop.Plugin.Misc.FruitBankPlugin.Models.Orders;
|
||||||
using Nop.Services.Catalog;
|
|
||||||
using Nop.Services.Common;
|
using Nop.Services.Common;
|
||||||
using Nop.Services.Customers;
|
|
||||||
using Nop.Services.Messages;
|
using Nop.Services.Messages;
|
||||||
using Nop.Services.Orders;
|
using Nop.Services.Orders;
|
||||||
using Nop.Services.Payments;
|
|
||||||
using Nop.Services.Security;
|
using Nop.Services.Security;
|
||||||
using Nop.Web.Areas.Admin.Controllers;
|
using Nop.Web.Areas.Admin.Controllers;
|
||||||
using Nop.Web.Areas.Admin.Factories;
|
using Nop.Web.Areas.Admin.Factories;
|
||||||
using Nop.Web.Areas.Admin.Models.Orders;
|
using Nop.Web.Areas.Admin.Models.Orders;
|
||||||
using Nop.Web.Framework;
|
using Nop.Web.Framework;
|
||||||
using Nop.Web.Framework.Mvc.Filters;
|
using Nop.Web.Framework.Mvc.Filters;
|
||||||
using System.Text.Json.Serialization;
|
|
||||||
using System.Xml;
|
|
||||||
using System.Xml.Serialization;
|
|
||||||
|
|
||||||
namespace Nop.Plugin.Misc.FruitBankPlugin.Areas.Admin.Controllers
|
namespace Nop.Plugin.Misc.FruitBankPlugin.Areas.Admin.Controllers
|
||||||
{
|
{
|
||||||
|
|
@ -42,11 +31,9 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Areas.Admin.Controllers
|
||||||
private readonly IPermissionService _permissionService;
|
private readonly IPermissionService _permissionService;
|
||||||
private readonly IGenericAttributeService _genericAttributeService;
|
private readonly IGenericAttributeService _genericAttributeService;
|
||||||
private readonly INotificationService _notificationService;
|
private readonly INotificationService _notificationService;
|
||||||
private readonly ICustomerService _customerService;
|
|
||||||
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)
|
public CustomOrderController(IOrderService orderService, IOrderModelFactory orderModelFactory, ICustomOrderSignalREndpointServer customOrderSignalREndpoint, IPermissionService permissionService, IGenericAttributeService genericAttributeService, INotificationService notificationService)
|
||||||
{
|
{
|
||||||
_orderService = orderService;
|
_orderService = orderService;
|
||||||
_orderModelFactory = orderModelFactory as CustomOrderModelFactory;
|
_orderModelFactory = orderModelFactory as CustomOrderModelFactory;
|
||||||
|
|
@ -54,8 +41,6 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Areas.Admin.Controllers
|
||||||
_permissionService = permissionService;
|
_permissionService = permissionService;
|
||||||
_genericAttributeService = genericAttributeService;
|
_genericAttributeService = genericAttributeService;
|
||||||
_notificationService = notificationService;
|
_notificationService = notificationService;
|
||||||
_customerService = customerService;
|
|
||||||
_productService = productService;
|
|
||||||
// ... initialize other deps
|
// ... initialize other deps
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -149,377 +134,6 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Areas.Admin.Controllers
|
||||||
return RedirectToAction("Edit", "Order", new { id = model.OrderId });
|
return RedirectToAction("Edit", "Order", new { id = model.OrderId });
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpPost]
|
|
||||||
//[CheckPermission(StandardPermission.Orders.ORDERS_CREATE)]
|
|
||||||
public virtual async Task<IActionResult> Create(int customerId, string orderProductsJson)
|
|
||||||
{
|
|
||||||
if (!await _permissionService.AuthorizeAsync(StandardPermission.Orders.ORDERS_CREATE_EDIT_DELETE))
|
|
||||||
return AccessDeniedView();
|
|
||||||
|
|
||||||
// Validate customer
|
|
||||||
var customer = await _customerService.GetCustomerByIdAsync(customerId);
|
|
||||||
if (customer == null)
|
|
||||||
return RedirectToAction("List");
|
|
||||||
|
|
||||||
// Parse products
|
|
||||||
var orderProducts = string.IsNullOrEmpty(orderProductsJson)
|
|
||||||
? new List<OrderProductItem>()
|
|
||||||
: JsonConvert.DeserializeObject<List<OrderProductItem>>(orderProductsJson);
|
|
||||||
|
|
||||||
// Create order
|
|
||||||
var order = new Order
|
|
||||||
{
|
|
||||||
OrderGuid = Guid.NewGuid(),
|
|
||||||
CustomOrderNumber = "",
|
|
||||||
CustomerId = customerId,
|
|
||||||
CustomerLanguageId = customer.LanguageId ?? 1,
|
|
||||||
CustomerTaxDisplayType = TaxDisplayType.IncludingTax,
|
|
||||||
CustomerIp = string.Empty,
|
|
||||||
OrderStatusId = (int)OrderStatus.Pending,
|
|
||||||
PaymentStatusId = (int)PaymentStatus.Pending,
|
|
||||||
ShippingStatusId = (int)ShippingStatus.ShippingNotRequired,
|
|
||||||
CreatedOnUtc = DateTime.UtcNow,
|
|
||||||
BillingAddressId = customer.BillingAddressId ?? 0,
|
|
||||||
ShippingAddressId = customer.ShippingAddressId
|
|
||||||
};
|
|
||||||
|
|
||||||
await _orderService.InsertOrderAsync(order);
|
|
||||||
|
|
||||||
// Add order items
|
|
||||||
foreach (var item in orderProducts)
|
|
||||||
{
|
|
||||||
var product = await _productService.GetProductByIdAsync(item.Id);
|
|
||||||
if (product != null)
|
|
||||||
{
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return RedirectToAction("Edit", new { id = order.Id });
|
|
||||||
}
|
|
||||||
|
|
||||||
public class OrderProductItem
|
|
||||||
{
|
|
||||||
public int Id { get; set; }
|
|
||||||
public string Name { get; set; }
|
|
||||||
public string Sku { get; set; }
|
|
||||||
public int Quantity { get; set; }
|
|
||||||
public decimal Price { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
//private static OrderItem CreateOrderItem(ProductToAuctionMapping productToAuction, Order order, decimal orderTotal)
|
|
||||||
//{
|
|
||||||
// return new OrderItem
|
|
||||||
// {
|
|
||||||
// ProductId = productToAuction.ProductId,
|
|
||||||
// OrderId = order.Id,
|
|
||||||
// OrderItemGuid = Guid.NewGuid(),
|
|
||||||
// PriceExclTax = orderTotal,
|
|
||||||
// PriceInclTax = orderTotal,
|
|
||||||
// UnitPriceExclTax = orderTotal,
|
|
||||||
// UnitPriceInclTax = orderTotal,
|
|
||||||
// Quantity = productToAuction.ProductAmount,
|
|
||||||
// };
|
|
||||||
//}
|
|
||||||
|
|
||||||
//private static Order CreateOrder(ProductToAuctionMapping productToAuction, decimal orderTotal, Customer customer, Address billingAddress, int storeId, Dictionary<string, object> customValues)
|
|
||||||
//{
|
|
||||||
// return new Order
|
|
||||||
// {
|
|
||||||
// BillingAddressId = billingAddress.Id,
|
|
||||||
// CreatedOnUtc = DateTime.UtcNow,
|
|
||||||
// CurrencyRate = 1,
|
|
||||||
// CustomOrderNumber = productToAuction.AuctionId + "/" + productToAuction.SortIndex,
|
|
||||||
// CustomValuesXml = SerializeCustomValuesToXml(customValues),
|
|
||||||
// CustomerCurrencyCode = "HUF",
|
|
||||||
// CustomerId = productToAuction.WinnerCustomerId,
|
|
||||||
// CustomerLanguageId = 2,
|
|
||||||
// CustomerTaxDisplayType = TaxDisplayType.IncludingTax,
|
|
||||||
// OrderGuid = Guid.NewGuid(),
|
|
||||||
// OrderStatus = OrderStatus.Pending,
|
|
||||||
// OrderTotal = orderTotal,
|
|
||||||
// PaymentStatus = PaymentStatus.Pending,
|
|
||||||
// PaymentMethodSystemName = "Payments.CheckMoneyOrder",
|
|
||||||
// ShippingStatus = ShippingStatus.ShippingNotRequired,
|
|
||||||
// StoreId = storeId,
|
|
||||||
// VatNumber = customer.VatNumber,
|
|
||||||
// CustomerIp = customer.LastIpAddress,
|
|
||||||
// OrderSubtotalExclTax = orderTotal,
|
|
||||||
// OrderSubtotalInclTax = orderTotal
|
|
||||||
// };
|
|
||||||
//}
|
|
||||||
|
|
||||||
private static OrderNote CreateOrderNote(Order order, string note)
|
|
||||||
{
|
|
||||||
return new OrderNote
|
|
||||||
{
|
|
||||||
CreatedOnUtc = order.CreatedOnUtc,
|
|
||||||
DisplayToCustomer = true,
|
|
||||||
OrderId = order.Id,
|
|
||||||
Note = note
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string SerializeCustomValuesToXml(Dictionary<string, object> sourceDictionary)
|
|
||||||
{
|
|
||||||
ArgumentNullException.ThrowIfNull(sourceDictionary);
|
|
||||||
|
|
||||||
if (!sourceDictionary.Any())
|
|
||||||
return null;
|
|
||||||
|
|
||||||
var ds = new DictionarySerializer(sourceDictionary);
|
|
||||||
var xs = new XmlSerializer(typeof(DictionarySerializer));
|
|
||||||
|
|
||||||
using var textWriter = new StringWriter();
|
|
||||||
using (var xmlWriter = XmlWriter.Create(textWriter))
|
|
||||||
{
|
|
||||||
xs.Serialize(xmlWriter, ds);
|
|
||||||
}
|
|
||||||
|
|
||||||
var result = textWriter.ToString();
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
[HttpGet] // Change from [HttpPost] to [HttpGet]
|
|
||||||
[CheckPermission(StandardPermission.Customers.CUSTOMERS_VIEW)]
|
|
||||||
public virtual async Task<IActionResult> CustomerSearchAutoComplete(string term)
|
|
||||||
{
|
|
||||||
if (string.IsNullOrWhiteSpace(term) || term.Length < 2)
|
|
||||||
return Json(new List<object>());
|
|
||||||
|
|
||||||
const int maxResults = 15;
|
|
||||||
|
|
||||||
// Search by email (contains)
|
|
||||||
var customersByEmail = await _customerService.GetAllCustomersAsync(
|
|
||||||
email: term,
|
|
||||||
pageIndex: 0,
|
|
||||||
pageSize: maxResults);
|
|
||||||
|
|
||||||
// Search by first name (contains)
|
|
||||||
var customersByFirstName = await _customerService.GetAllCustomersAsync(
|
|
||||||
firstName: term,
|
|
||||||
pageIndex: 0,
|
|
||||||
pageSize: maxResults);
|
|
||||||
|
|
||||||
// Search by last name (contains)
|
|
||||||
var customersByLastName = await _customerService.GetAllCustomersAsync(
|
|
||||||
lastName: term,
|
|
||||||
pageIndex: 0,
|
|
||||||
pageSize: maxResults);
|
|
||||||
|
|
||||||
// Combine and deduplicate results
|
|
||||||
var allCustomers = customersByEmail
|
|
||||||
.Union(customersByFirstName)
|
|
||||||
.Union(customersByLastName)
|
|
||||||
.DistinctBy(c => c.Id)
|
|
||||||
.Take(maxResults)
|
|
||||||
.ToList();
|
|
||||||
|
|
||||||
var result = new List<object>();
|
|
||||||
foreach (var customer in allCustomers)
|
|
||||||
{
|
|
||||||
var fullName = await _customerService.GetCustomerFullNameAsync(customer);
|
|
||||||
var displayText = !string.IsNullOrEmpty(customer.Email)
|
|
||||||
? $"{customer.Email} ({fullName})"
|
|
||||||
: fullName;
|
|
||||||
|
|
||||||
result.Add(new
|
|
||||||
{
|
|
||||||
label = displayText,
|
|
||||||
value = customer.Id
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return Json(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
[HttpGet]
|
|
||||||
[CheckPermission(StandardPermission.Catalog.PRODUCTS_VIEW)]
|
|
||||||
public virtual async Task<IActionResult> ProductSearchAutoComplete(string term)
|
|
||||||
{
|
|
||||||
if (string.IsNullOrWhiteSpace(term) || term.Length < 2)
|
|
||||||
return Json(new List<object>());
|
|
||||||
|
|
||||||
const int maxResults = 15;
|
|
||||||
|
|
||||||
// Search products by name or SKU
|
|
||||||
var products = await _productService.SearchProductsAsync(
|
|
||||||
keywords: term,
|
|
||||||
pageIndex: 0,
|
|
||||||
pageSize: maxResults);
|
|
||||||
|
|
||||||
var result = new List<object>();
|
|
||||||
foreach (var product in products)
|
|
||||||
{
|
|
||||||
result.Add(new
|
|
||||||
{
|
|
||||||
label = product.Name,
|
|
||||||
value = product.Id,
|
|
||||||
sku = product.Sku,
|
|
||||||
price = product.Price
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return Json(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//[HttpPost]
|
|
||||||
//public async Task<IActionResult> CreateInvoice(int orderId)
|
|
||||||
//{
|
|
||||||
// try
|
|
||||||
// {
|
|
||||||
// var order = await _orderService.GetOrderByIdAsync(orderId);
|
|
||||||
// if (order == null)
|
|
||||||
// return Json(new { success = false, message = "Order not found" });
|
|
||||||
|
|
||||||
// var billingAddress = await _customerService.GetCustomerBillingAddressAsync(order.Customer);
|
|
||||||
// if (billingAddress == null)
|
|
||||||
// return Json(new { success = false, message = "Billing address not found" });
|
|
||||||
|
|
||||||
// var country = await _countryService.GetCountryByAddressAsync(billingAddress);
|
|
||||||
// var countryCode = country?.TwoLetterIsoCode ?? "HU";
|
|
||||||
|
|
||||||
// // Create invoice request
|
|
||||||
// var invoiceRequest = new InvoiceCreateRequest
|
|
||||||
// {
|
|
||||||
// VevoNev = $"{billingAddress.FirstName} {billingAddress.LastName}",
|
|
||||||
// VevoIrsz = billingAddress.ZipPostalCode ?? "",
|
|
||||||
// VevoTelep = billingAddress.City ?? "",
|
|
||||||
// VevoOrszag = countryCode,
|
|
||||||
// VevoUtcaHsz = $"{billingAddress.Address1} {billingAddress.Address2}".Trim(),
|
|
||||||
// SzamlatombID = 1, // Configure this based on your setup
|
|
||||||
// SzamlaKelte = DateTime.Now,
|
|
||||||
// TeljesitesKelte = DateTime.Now,
|
|
||||||
// Hatarido = DateTime.Now.AddDays(15), // 15 days payment term
|
|
||||||
// Devizanem = order.CustomerCurrencyCode,
|
|
||||||
// FizetesiMod = order.PaymentMethodSystemName,
|
|
||||||
// Felretett = false,
|
|
||||||
// Proforma = false,
|
|
||||||
// Email = billingAddress.Email,
|
|
||||||
// Telefon = billingAddress.PhoneNumber
|
|
||||||
// };
|
|
||||||
|
|
||||||
// // Add order items
|
|
||||||
// var orderItems = await _orderService.GetOrderItemsAsync(order.Id);
|
|
||||||
// foreach (var item in orderItems)
|
|
||||||
// {
|
|
||||||
// var product = await _productService.GetProductByIdAsync(item.ProductId);
|
|
||||||
|
|
||||||
// invoiceRequest.AddItem(new InvoiceItem
|
|
||||||
// {
|
|
||||||
// TetelNev = product?.Name ?? "Product",
|
|
||||||
// AfaSzoveg = "27%", // Configure VAT rate as needed
|
|
||||||
// Brutto = true,
|
|
||||||
// EgysegAr = item.UnitPriceInclTax,
|
|
||||||
// Mennyiseg = item.Quantity,
|
|
||||||
// MennyisegEgyseg = "db",
|
|
||||||
// CikkSzam = product?.Sku
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // Create invoice via API
|
|
||||||
// var response = await _innVoiceApiService.CreateInvoiceAsync(invoiceRequest);
|
|
||||||
|
|
||||||
// if (response.IsSuccess)
|
|
||||||
// {
|
|
||||||
// // TODO: Save invoice details to your database for future reference
|
|
||||||
// // You might want to create a custom table to store:
|
|
||||||
// // - OrderId
|
|
||||||
// // - InnVoice TableId
|
|
||||||
// // - Invoice Number
|
|
||||||
// // - PDF URL
|
|
||||||
// // - Created Date
|
|
||||||
|
|
||||||
// return Json(new
|
|
||||||
// {
|
|
||||||
// success = true,
|
|
||||||
// message = "Invoice created successfully",
|
|
||||||
// data = new
|
|
||||||
// {
|
|
||||||
// tableId = response.TableId,
|
|
||||||
// invoiceNumber = response.Sorszam,
|
|
||||||
// sorszam = response.Sorszam,
|
|
||||||
// printUrl = response.PrintUrl
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
// else
|
|
||||||
// {
|
|
||||||
// return Json(new
|
|
||||||
// {
|
|
||||||
// success = false,
|
|
||||||
// message = $"InnVoice API Error: {response.Message}"
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// catch (Exception ex)
|
|
||||||
// {
|
|
||||||
// return Json(new
|
|
||||||
// {
|
|
||||||
// success = false,
|
|
||||||
// message = $"Error: {ex.Message}"
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
|
|
||||||
//[HttpGet]
|
|
||||||
//public async Task<IActionResult> GetInvoiceStatus(int orderId)
|
|
||||||
//{
|
|
||||||
// try
|
|
||||||
// {
|
|
||||||
// // TODO: Retrieve invoice details from your database
|
|
||||||
// // This is a placeholder - you need to implement actual storage/retrieval
|
|
||||||
|
|
||||||
// // Example: var invoiceData = await _yourInvoiceService.GetByOrderIdAsync(orderId);
|
|
||||||
// // if (invoiceData != null)
|
|
||||||
// // {
|
|
||||||
// // return Json(new
|
|
||||||
// // {
|
|
||||||
// // success = true,
|
|
||||||
// // data = new
|
|
||||||
// // {
|
|
||||||
// // tableId = invoiceData.TableId,
|
|
||||||
// // invoiceNumber = invoiceData.InvoiceNumber,
|
|
||||||
// // sorszam = invoiceData.InvoiceNumber,
|
|
||||||
// // printUrl = invoiceData.PrintUrl
|
|
||||||
// // }
|
|
||||||
// // });
|
|
||||||
// // }
|
|
||||||
|
|
||||||
// return Json(new
|
|
||||||
// {
|
|
||||||
// success = false,
|
|
||||||
// message = "No invoice found for this order"
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
// catch (Exception ex)
|
|
||||||
// {
|
|
||||||
// return Json(new
|
|
||||||
// {
|
|
||||||
// success = false,
|
|
||||||
// message = $"Error: {ex.Message}"
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -186,20 +186,6 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Areas.Admin.Controllers
|
||||||
return Json(model);
|
return Json(model);
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet]
|
|
||||||
public async Task<IActionResult> GetAllPartners()
|
|
||||||
{
|
|
||||||
if (!await _permissionService.AuthorizeAsync(StandardPermission.Security.ACCESS_ADMIN_PANEL))
|
|
||||||
return AccessDeniedView();
|
|
||||||
|
|
||||||
// Mock data for now
|
|
||||||
var model = await _dbContext.Partners.GetAll().ToListAsync();
|
|
||||||
var valami = model;
|
|
||||||
//model. = await _dbContext.GetShippingDocumentsByShippingIdAsync(shippingId);
|
|
||||||
return Json(model);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
[RequestSizeLimit(10485760)] // 10MB
|
[RequestSizeLimit(10485760)] // 10MB
|
||||||
|
|
@ -254,7 +240,7 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Areas.Admin.Controllers
|
||||||
//if (file.Length > 0 && file.ContentType == "application/pdf")
|
//if (file.Length > 0 && file.ContentType == "application/pdf")
|
||||||
if (file.Length > 0)
|
if (file.Length > 0)
|
||||||
{
|
{
|
||||||
if (file.ContentType.Equals("application/pdf", StringComparison.OrdinalIgnoreCase)){
|
if (!file.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
|
||||||
|
|
@ -296,18 +282,18 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Areas.Admin.Controllers
|
||||||
return StatusCode(500, $"Error processing PDF file: {ex.Message}");
|
return StatusCode(500, $"Error processing PDF file: {ex.Message}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else //read from image
|
else
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// Open the Image 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 = file.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, file.FileName, "Please extract all readable text from this PDF.");
|
||||||
}
|
}
|
||||||
catch (Exception aiEx)
|
catch (Exception aiEx)
|
||||||
{
|
{
|
||||||
|
|
@ -333,6 +319,7 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Areas.Admin.Controllers
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
string analysisPrompt = "Extract the document identification number from this document, determine the type of the " +
|
string analysisPrompt = "Extract the document identification number from this document, determine the type of the " +
|
||||||
"document IN ENGLISH from the available list, and return them as JSON: documentNumber, documentType. " +
|
"document IN ENGLISH from the available list, and return them as JSON: documentNumber, documentType. " +
|
||||||
$"Available filetypes: {nameof(DocumentType.Invoice)}, {nameof(DocumentType.ShippingDocument)} , {nameof(DocumentType.OrderConfirmation)}, {nameof(DocumentType.Unknown)}" +
|
$"Available filetypes: {nameof(DocumentType.Invoice)}, {nameof(DocumentType.ShippingDocument)} , {nameof(DocumentType.OrderConfirmation)}, {nameof(DocumentType.Unknown)}" +
|
||||||
|
|
@ -355,11 +342,9 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Areas.Admin.Controllers
|
||||||
ShippingDocumentToFiles shippingDocumentToFiles = new ShippingDocumentToFiles
|
ShippingDocumentToFiles shippingDocumentToFiles = new ShippingDocumentToFiles
|
||||||
{
|
{
|
||||||
ShippingDocumentId = shippingDocumentId,
|
ShippingDocumentId = shippingDocumentId,
|
||||||
FilesId = dbFile.Id,
|
FilesId = dbFile.Id
|
||||||
DocumentType = extractedMetaData.DocumentType != null ? (DocumentType)Enum.Parse(typeof(DocumentType), extractedMetaData.DocumentType) : DocumentType.Unknown
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Console.WriteLine(shippingDocumentToFiles.DocumentType);
|
|
||||||
|
|
||||||
await _dbContext.ShippingDocumentToFiles.InsertAsync(shippingDocumentToFiles);
|
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
|
||||||
|
|
@ -440,7 +425,7 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Areas.Admin.Controllers
|
||||||
// Analyze PDF with AI to extract structured data
|
// Analyze PDF with AI to extract structured data
|
||||||
var aiAnalysis = await _aiCalculationService.GetOpenAIPDFAnalysisFromText(
|
var aiAnalysis = await _aiCalculationService.GetOpenAIPDFAnalysisFromText(
|
||||||
pdfText.ToString(),
|
pdfText.ToString(),
|
||||||
"You work for FruitBank. Extract the following information from this shipping document and return as JSON: documentDate, recipientName, senderName, invoiceNumber, totalAmount, itemCount, notes. If a field is not found, return null for that field."
|
"Extract the following information from this shipping document and return as JSON: documentDate, recipientName, senderName, invoiceNumber, totalAmount, itemCount, notes. If a field is not found, return null for that field."
|
||||||
);
|
);
|
||||||
|
|
||||||
// Parse AI response (assuming it returns JSON)
|
// Parse AI response (assuming it returns JSON)
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -24,22 +24,14 @@
|
||||||
})
|
})
|
||||||
.Columns(c => {
|
.Columns(c => {
|
||||||
c.Add().DataField("Id").AllowEditing(false);
|
c.Add().DataField("Id").AllowEditing(false);
|
||||||
c.Add().DataField("PartnerId")
|
c.Add().DataField("Partner.Name").AllowEditing(false);
|
||||||
.AllowEditing(true)
|
|
||||||
.Lookup(lookup => lookup
|
|
||||||
.DataSource(d => d.Mvc().Controller("ManagementPage").LoadAction("GetAllPartners").Key("Id"))
|
|
||||||
.ValueExpr("Id")
|
|
||||||
.DisplayExpr("Name")
|
|
||||||
)
|
|
||||||
.EditCellTemplate(new TemplateName("DropDownBoxTemplate"))
|
|
||||||
.Width(150);
|
|
||||||
c.Add()
|
c.Add()
|
||||||
.Caption("Items in order")
|
.Caption("Items in order")
|
||||||
.DataType(GridColumnDataType.Number)
|
.DataType(GridColumnDataType.Number)
|
||||||
.CalculateCellValue("calculateItemsCount").AllowEditing(false);
|
.CalculateCellValue("calculateItemsCount").AllowEditing(false);
|
||||||
@* c.Add().DataField("PartnerId"); *@
|
c.Add().DataField("PartnerId");
|
||||||
c.Add().DataField("DocumentIdNumber");
|
c.Add().DataField("DocumentIdNumber");
|
||||||
c.Add().DataField("IsAllMeasured").AllowEditing(false);
|
c.Add().DataField("IsAllMeasured");
|
||||||
c.Add()
|
c.Add()
|
||||||
.Caption("Completed")
|
.Caption("Completed")
|
||||||
.DataType(GridColumnDataType.Boolean)
|
.DataType(GridColumnDataType.Boolean)
|
||||||
|
|
@ -62,10 +54,8 @@
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.MasterDetail(md => md.Enabled(true).Template(new TemplateName("masterDetailTemplate"))
|
.MasterDetail(md => md.Enabled(true).Template(new TemplateName("masterDetailTemplate")))
|
||||||
)
|
)
|
||||||
)
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@using (Html.DevExtreme().NamedTemplate("masterDetailTemplate"))
|
@using (Html.DevExtreme().NamedTemplate("masterDetailTemplate"))
|
||||||
|
|
@ -118,40 +108,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@using(Html.DevExtreme().NamedTemplate("DropDownBoxTemplate")) {
|
|
||||||
@(Html.DevExtreme().DropDownBox()
|
|
||||||
.DataSource(d => d.Mvc().Controller("ManagementPage").LoadAction("GetAllPartners").Key("Id"))
|
|
||||||
.Value(new JS("value"))
|
|
||||||
.ValueExpr("Id")
|
|
||||||
.InputAttr("aria-label", "Partner")
|
|
||||||
.DisplayExpr("Name")
|
|
||||||
.DropDownOptions(options => options.Width(500))
|
|
||||||
.Option("setValue", new JS("setValue"))
|
|
||||||
.ContentTemplate(new TemplateName("ContentTemplate"))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
@using(Html.DevExtreme().NamedTemplate("ContentTemplate")) {
|
|
||||||
@(Html.DevExtreme().DataGrid()
|
|
||||||
.DataSource(d => d.Mvc().Controller("ManagementPage").LoadAction("GetAllPartners").Key("Id"))
|
|
||||||
.RemoteOperations(true)
|
|
||||||
.Height(250)
|
|
||||||
.Columns(c => {
|
|
||||||
c.Add().DataField("Name");
|
|
||||||
c.Add().DataField("Country");
|
|
||||||
c.Add().DataField("TaxId");
|
|
||||||
})
|
|
||||||
.Scrolling(s => s.Mode(GridScrollingMode.Virtual))
|
|
||||||
.HoverStateEnabled(true)
|
|
||||||
.Selection(s => s.Mode(SelectionMode.Single))
|
|
||||||
.SelectedRowKeys(new JS("component.option('value') !== undefined && component.option('value') !== null ? [component.option('value')] : []"))
|
|
||||||
.FocusedRowEnabled(true)
|
|
||||||
.FocusedRowKey(new JS("component.option('value')"))
|
|
||||||
.OnContextMenuPreparing("function(e) { e.items = [] }")
|
|
||||||
.OnSelectionChanged("function(e) { onPartnerSelectionChanged(e, component) }")
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
// Store the parent grid model as JSON
|
// Store the parent grid model as JSON
|
||||||
var parentGridModel = @Html.Raw(Json.Serialize(Model));
|
var parentGridModel = @Html.Raw(Json.Serialize(Model));
|
||||||
|
|
@ -224,6 +180,10 @@
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function onSelectionChanged(data) {
|
||||||
|
let dataGrid = $("#orderDataGridContainer").dxDataGrid("instance");
|
||||||
|
dataGrid.option("toolbar.items[1].options.disabled", !data.selectedRowsData.length);
|
||||||
|
}
|
||||||
|
|
||||||
function onRowExpanded(e) {
|
function onRowExpanded(e) {
|
||||||
// Trigger loading of first tab when row expands
|
// Trigger loading of first tab when row expands
|
||||||
|
|
@ -236,20 +196,4 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function onInitNewRow(e) {
|
|
||||||
// Replace this with actual default values and db insert
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
function onPartnerSelectionChanged(e, dropDownBoxComponent) {
|
|
||||||
var selectedRowKey = e.selectedRowKeys[0];
|
|
||||||
|
|
||||||
if (e.selectedRowKeys.length > 0) {
|
|
||||||
dropDownBoxComponent.option('value', selectedRowKey);
|
|
||||||
dropDownBoxComponent.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
@ -131,11 +131,6 @@ public class RouteProvider : IRouteProvider
|
||||||
name: "Plugin.FruitBank.Admin.Orders.SaveOrderAttributes",
|
name: "Plugin.FruitBank.Admin.Orders.SaveOrderAttributes",
|
||||||
pattern: "Admin/CustomOrder/SaveOrderAttributes",
|
pattern: "Admin/CustomOrder/SaveOrderAttributes",
|
||||||
defaults: new { controller = "CustomOrder", action = "SaveOrderAttributes", area = AreaNames.ADMIN });
|
defaults: new { controller = "CustomOrder", action = "SaveOrderAttributes", area = AreaNames.ADMIN });
|
||||||
|
|
||||||
endpointRouteBuilder.MapControllerRoute(
|
|
||||||
name: "Plugin.FruitBank.Admin.Orders.CustomerSearchAutoComplete",
|
|
||||||
pattern: "Admin/CustomOrder/CustomerSearchAutoComplete",
|
|
||||||
defaults: new { controller = "CustomOrder", action = "CustomerSearchAutoComplete", area = AreaNames.ADMIN });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,8 @@
|
||||||
using FruitBank.Common.Interfaces;
|
using System.Linq;
|
||||||
using Microsoft.AspNetCore.Http;
|
using FruitBank.Common.Interfaces;
|
||||||
using Nop.Core;
|
using Nop.Core;
|
||||||
using Nop.Core.Domain.Catalog;
|
using Nop.Core.Domain.Catalog;
|
||||||
using Nop.Core.Domain.Orders;
|
using Nop.Core.Domain.Orders;
|
||||||
using Nop.Core.Events;
|
|
||||||
using Nop.Plugin.Misc.FruitBankPlugin.Models;
|
|
||||||
using Nop.Plugin.Misc.FruitBankPlugin.Models.Orders;
|
using Nop.Plugin.Misc.FruitBankPlugin.Models.Orders;
|
||||||
using Nop.Services.Catalog;
|
using Nop.Services.Catalog;
|
||||||
using Nop.Services.Common;
|
using Nop.Services.Common;
|
||||||
|
|
@ -15,11 +13,10 @@ using Nop.Services.Plugins;
|
||||||
using Nop.Web.Framework.Events;
|
using Nop.Web.Framework.Events;
|
||||||
using Nop.Web.Framework.Menu;
|
using Nop.Web.Framework.Menu;
|
||||||
using Nop.Web.Models.Sitemap;
|
using Nop.Web.Models.Sitemap;
|
||||||
using System.Linq;
|
|
||||||
|
|
||||||
namespace Nop.Plugin.Misc.FruitBankPlugin.Services
|
namespace Nop.Plugin.Misc.FruitBankPlugin.Services
|
||||||
{
|
{
|
||||||
public class EventConsumer : BaseAdminMenuCreatedEventConsumer, IConsumer<OrderPlacedEvent>, IConsumer<EntityUpdatedEvent<Order>>, IConsumer<AdminMenuCreatedEvent>
|
public class EventConsumer : BaseAdminMenuCreatedEventConsumer, IConsumer<OrderPlacedEvent>, IConsumer<AdminMenuCreatedEvent>
|
||||||
{
|
{
|
||||||
private readonly IGenericAttributeService _genericAttributeService;
|
private readonly IGenericAttributeService _genericAttributeService;
|
||||||
private readonly IProductService _productService;
|
private readonly IProductService _productService;
|
||||||
|
|
@ -30,8 +27,6 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Services
|
||||||
private readonly IStoreContext _storeContext;
|
private readonly IStoreContext _storeContext;
|
||||||
private readonly IAdminMenu _adminMenu;
|
private readonly IAdminMenu _adminMenu;
|
||||||
private readonly ILocalizationService _localizationService;
|
private readonly ILocalizationService _localizationService;
|
||||||
private readonly IHttpContextAccessor _httpContextAccessor;
|
|
||||||
private readonly FruitBankAttributeService _fruitBankAttributeService;
|
|
||||||
|
|
||||||
public EventConsumer(
|
public EventConsumer(
|
||||||
IGenericAttributeService genericAttributeService,
|
IGenericAttributeService genericAttributeService,
|
||||||
|
|
@ -43,9 +38,7 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Services
|
||||||
IWorkContext workContext,
|
IWorkContext workContext,
|
||||||
IStoreContext storeContext,
|
IStoreContext storeContext,
|
||||||
IAdminMenu adminMenu,
|
IAdminMenu adminMenu,
|
||||||
ILocalizationService localizationService,
|
ILocalizationService localizationService) : base(pluginManager)
|
||||||
IHttpContextAccessor httpContextAccessor,
|
|
||||||
FruitBankAttributeService fruitBankAttributeService) : base(pluginManager)
|
|
||||||
{
|
{
|
||||||
_genericAttributeService = genericAttributeService;
|
_genericAttributeService = genericAttributeService;
|
||||||
_productService = productService;
|
_productService = productService;
|
||||||
|
|
@ -56,8 +49,6 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Services
|
||||||
_storeContext = storeContext;
|
_storeContext = storeContext;
|
||||||
_adminMenu = adminMenu;
|
_adminMenu = adminMenu;
|
||||||
_localizationService = localizationService;
|
_localizationService = localizationService;
|
||||||
_httpContextAccessor = httpContextAccessor;
|
|
||||||
_fruitBankAttributeService = fruitBankAttributeService;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override string PluginSystemName => "Misc.FruitBankPlugin";
|
protected override string PluginSystemName => "Misc.FruitBankPlugin";
|
||||||
|
|
@ -129,39 +120,6 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Services
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task HandleEventAsync(EntityUpdatedEvent<Order> eventMessage)
|
|
||||||
{
|
|
||||||
await SaveOrderCustomAttributesAsync(eventMessage.Entity);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private async Task SaveOrderCustomAttributesAsync(Order order)
|
|
||||||
{
|
|
||||||
if (order == null) return;
|
|
||||||
|
|
||||||
var form = _httpContextAccessor.HttpContext?.Request?.Form;
|
|
||||||
if (form == null || form.Count == 0) return;
|
|
||||||
|
|
||||||
if (form.ContainsKey(nameof(IMeasurable.IsMeasurable)))
|
|
||||||
{
|
|
||||||
var isMeasurable = form[nameof(IMeasurable.IsMeasurable)].ToString().Contains("true");
|
|
||||||
//var isMeasurable = CommonHelper.To<bool>(form[nameof(IMeasurable.IsMeasurable)].ToString());
|
|
||||||
|
|
||||||
|
|
||||||
await _fruitBankAttributeService.InsertOrUpdateGenericAttributeAsync<Order, bool>(order.Id, nameof(IMeasurable.IsMeasurable), isMeasurable);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (form.ContainsKey(nameof(IOrderDto.DateOfReceipt)))
|
|
||||||
{
|
|
||||||
var dateOfReceipt = form[nameof(IOrderDto.DateOfReceipt)];
|
|
||||||
|
|
||||||
await _fruitBankAttributeService.InsertOrUpdateGenericAttributeAsync<Order, DateTime>(order.Id, nameof(IOrderDto.DateOfReceipt), DateTime.Parse(dateOfReceipt));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public async Task HandleEventAsync(AdminMenuCreatedEvent eventMessage)
|
public async Task HandleEventAsync(AdminMenuCreatedEvent eventMessage)
|
||||||
{
|
{
|
||||||
var rootNode = eventMessage.RootMenuItem;
|
var rootNode = eventMessage.RootMenuItem;
|
||||||
|
|
|
||||||
|
|
@ -1,43 +1,6 @@
|
||||||
@using Nop.Plugin.Misc.FruitBankPlugin.Models.Orders
|
@using Nop.Plugin.Misc.FruitBankPlugin.Models.Orders
|
||||||
@model OrderAttributesModel
|
@model OrderAttributesModel
|
||||||
|
|
||||||
<!-- InnVoice Invoice Section -->
|
|
||||||
<div class="card card-default mb-3">
|
|
||||||
<div class="card-header">
|
|
||||||
<i class="fas fa-file-invoice"></i>
|
|
||||||
InnVoice Invoice Management
|
|
||||||
</div>
|
|
||||||
<div class="card-body">
|
|
||||||
<div class="form-group row">
|
|
||||||
<div class="col-md-12">
|
|
||||||
<div id="invoiceStatus" class="alert alert-info" style="display: none;">
|
|
||||||
<i class="fas fa-info-circle"></i> <span id="invoiceStatusMessage"></span>
|
|
||||||
</div>
|
|
||||||
<div id="invoiceDetails" style="display: none;">
|
|
||||||
<p><strong>Invoice Number:</strong> <span id="invoiceNumber"></span></p>
|
|
||||||
<p><strong>Table ID:</strong> <span id="invoiceTableId"></span></p>
|
|
||||||
<p>
|
|
||||||
<a id="invoicePdfLink" href="#" target="_blank" class="btn btn-sm btn-info">
|
|
||||||
<i class="fas fa-file-pdf"></i> View PDF
|
|
||||||
</a>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group row">
|
|
||||||
<div class="col-md-12 text-right">
|
|
||||||
<button type="button" id="createInvoiceBtn" class="btn btn-success">
|
|
||||||
<i class="fas fa-file-invoice-dollar"></i> Create & Upload Invoice
|
|
||||||
</button>
|
|
||||||
<button type="button" id="checkInvoiceBtn" class="btn btn-secondary" style="display: none;">
|
|
||||||
<i class="fas fa-sync"></i> Check Invoice Status
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Custom Order Attributes Section -->
|
|
||||||
<div class="card card-default">
|
<div class="card card-default">
|
||||||
<div class="card-header">
|
<div class="card-header">
|
||||||
<i class="fas fa-tags"></i>
|
<i class="fas fa-tags"></i>
|
||||||
|
|
@ -53,6 +16,7 @@
|
||||||
<span asp-validation-for="IsMeasurable"></span>
|
<span asp-validation-for="IsMeasurable"></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group row">
|
<div class="form-group row">
|
||||||
<div class="col-md-3">
|
<div class="col-md-3">
|
||||||
<nop-label asp-for="DateOfReceipt" />
|
<nop-label asp-for="DateOfReceipt" />
|
||||||
|
|
@ -62,6 +26,7 @@
|
||||||
<span asp-validation-for="DateOfReceipt"></span>
|
<span asp-validation-for="DateOfReceipt"></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group row">
|
<div class="form-group row">
|
||||||
<div class="col-md-12 text-right">
|
<div class="col-md-12 text-right">
|
||||||
<button type="button" id="saveAttributesBtn" class="btn btn-primary">
|
<button type="button" id="saveAttributesBtn" class="btn btn-primary">
|
||||||
|
|
@ -74,7 +39,6 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
$(document).ready(function () {
|
$(document).ready(function () {
|
||||||
// Save Order Attributes
|
|
||||||
$("#saveAttributesBtn").click(function () {
|
$("#saveAttributesBtn").click(function () {
|
||||||
$.ajax({
|
$.ajax({
|
||||||
type: "POST",
|
type: "POST",
|
||||||
|
|
@ -82,7 +46,7 @@
|
||||||
data: {
|
data: {
|
||||||
orderId: "@Model.OrderId",
|
orderId: "@Model.OrderId",
|
||||||
isMeasurable: $("#@Html.IdFor(m => m.IsMeasurable)").is(":checked"),
|
isMeasurable: $("#@Html.IdFor(m => m.IsMeasurable)").is(":checked"),
|
||||||
dateOfReceipt: $("#@Html.IdFor(m => m.DateOfReceipt)").val(),
|
pickupDateTimeUtc: $("#@Html.IdFor(m => m.DateOfReceipt)").val(),
|
||||||
__RequestVerificationToken: $('input[name="__RequestVerificationToken"]').val()
|
__RequestVerificationToken: $('input[name="__RequestVerificationToken"]').val()
|
||||||
},
|
},
|
||||||
success: function () {
|
success: function () {
|
||||||
|
|
@ -93,106 +57,6 @@
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// Create Invoice
|
|
||||||
$("#createInvoiceBtn").click(function () {
|
|
||||||
var btn = $(this);
|
|
||||||
btn.prop("disabled", true).html('<i class="fas fa-spinner fa-spin"></i> Creating Invoice...');
|
|
||||||
|
|
||||||
showInvoiceStatus("Creating invoice, please wait...", "info");
|
|
||||||
|
|
||||||
$.ajax({
|
|
||||||
type: "POST",
|
|
||||||
url: "@Url.Action("CreateInvoice", "InnVoice")",
|
|
||||||
data: {
|
|
||||||
orderId: "@Model.OrderId",
|
|
||||||
__RequestVerificationToken: $('input[name="__RequestVerificationToken"]').val()
|
|
||||||
},
|
|
||||||
success: function (response) {
|
|
||||||
btn.prop("disabled", false).html('<i class="fas fa-file-invoice-dollar"></i> Create & Upload Invoice');
|
|
||||||
|
|
||||||
if (response.success) {
|
|
||||||
showInvoiceStatus("Invoice created successfully!", "success");
|
|
||||||
displayInvoiceDetails(response.data);
|
|
||||||
$("#checkInvoiceBtn").show();
|
|
||||||
} else {
|
|
||||||
showInvoiceStatus("Error: " + response.message, "danger");
|
|
||||||
}
|
|
||||||
},
|
|
||||||
error: function (xhr) {
|
|
||||||
btn.prop("disabled", false).html('<i class="fas fa-file-invoice-dollar"></i> Create & Upload Invoice');
|
|
||||||
|
|
||||||
var errorMessage = "Error creating invoice";
|
|
||||||
if (xhr.responseJSON && xhr.responseJSON.message) {
|
|
||||||
errorMessage = xhr.responseJSON.message;
|
|
||||||
}
|
|
||||||
showInvoiceStatus(errorMessage, "danger");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// Check Invoice Status
|
|
||||||
$("#checkInvoiceBtn").click(function () {
|
|
||||||
var btn = $(this);
|
|
||||||
btn.prop("disabled", true).html('<i class="fas fa-spinner fa-spin"></i> Checking...');
|
|
||||||
|
|
||||||
$.ajax({
|
|
||||||
type: "GET",
|
|
||||||
url: "@Url.Action("GetInvoiceStatus", "InnVoice")",
|
|
||||||
data: {
|
|
||||||
orderId: "@Model.OrderId"
|
|
||||||
},
|
|
||||||
success: function (response) {
|
|
||||||
btn.prop("disabled", false).html('<i class="fas fa-sync"></i> Check Invoice Status');
|
|
||||||
|
|
||||||
if (response.success && response.data) {
|
|
||||||
displayInvoiceDetails(response.data);
|
|
||||||
showInvoiceStatus("Invoice details loaded", "success");
|
|
||||||
} else {
|
|
||||||
showInvoiceStatus("No invoice found for this order", "warning");
|
|
||||||
}
|
|
||||||
},
|
|
||||||
error: function () {
|
|
||||||
btn.prop("disabled", false).html('<i class="fas fa-sync"></i> Check Invoice Status');
|
|
||||||
showInvoiceStatus("Error checking invoice status", "danger");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
function showInvoiceStatus(message, type) {
|
|
||||||
var statusDiv = $("#invoiceStatus");
|
|
||||||
statusDiv.removeClass("alert-info alert-success alert-warning alert-danger")
|
|
||||||
.addClass("alert-" + type);
|
|
||||||
$("#invoiceStatusMessage").text(message);
|
|
||||||
statusDiv.show();
|
|
||||||
}
|
|
||||||
|
|
||||||
function displayInvoiceDetails(data) {
|
|
||||||
$("#invoiceNumber").text(data.invoiceNumber || data.sorszam || "N/A");
|
|
||||||
$("#invoiceTableId").text(data.tableId || "N/A");
|
|
||||||
|
|
||||||
if (data.printUrl) {
|
|
||||||
$("#invoicePdfLink").attr("href", data.printUrl).show();
|
|
||||||
} else {
|
|
||||||
$("#invoicePdfLink").hide();
|
|
||||||
}
|
|
||||||
|
|
||||||
$("#invoiceDetails").show();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if invoice exists on page load
|
|
||||||
$.ajax({
|
|
||||||
type: "GET",
|
|
||||||
url: "@Url.Action("GetInvoiceStatus", "InnVoice")",
|
|
||||||
data: {
|
|
||||||
orderId: "@Model.OrderId"
|
|
||||||
},
|
|
||||||
success: function (response) {
|
|
||||||
if (response.success && response.data) {
|
|
||||||
displayInvoiceDetails(response.data);
|
|
||||||
$("#checkInvoiceBtn").show();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue