Mango.Nop.Plugins/Nop.Plugin.Misc.AIPlugin/Areas/Admin/Controllers/InnVoiceOrderController.cs

469 lines
19 KiB
C#

using Microsoft.AspNetCore.Mvc;
using Nop.Core;
using Nop.Core.Domain.Orders;
using Nop.Plugin.Misc.FruitBankPlugin.Domains.DataLayer;
using Nop.Plugin.Misc.FruitBankPlugin.Services;
using Nop.Services.Catalog;
using Nop.Services.Common;
using Nop.Services.Customers;
using Nop.Services.Directory;
using Nop.Services.Orders;
using Nop.Web.Framework;
using Nop.Web.Framework.Controllers;
using Nop.Web.Framework.Mvc.Filters;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Nop.Plugin.Misc.FruitBankPlugin.Areas.Admin.Controllers
{
[Area(AreaNames.ADMIN)]
[AuthorizeAdmin]
public class InnVoiceOrderController : BasePluginController
{
private readonly IOrderService _orderService;
private readonly IWorkContext _workContext;
private readonly IStoreContext _storeContext;
private readonly ICustomerService _customerService;
private readonly ICountryService _countryService;
private readonly IProductService _productService;
private readonly InnVoiceOrderService _innVoiceOrderService;
private readonly FruitBankAttributeService _fruitBankAttributeService;
private readonly IGenericAttributeService _genericAttributeService;
private readonly FruitBankDbContext _dbContext;
public InnVoiceOrderController(
IOrderService orderService,
IWorkContext workContext,
IStoreContext storeContext,
ICustomerService customerService,
ICountryService countryService,
IProductService productService,
InnVoiceOrderService innVoiceOrderService,
FruitBankAttributeService fruitBankAttributeService,
IGenericAttributeService genericAttributeService,
FruitBankDbContext dbContext)
{
_orderService = orderService;
_workContext = workContext;
_storeContext = storeContext;
_customerService = customerService;
_countryService = countryService;
_productService = productService;
_innVoiceOrderService = innVoiceOrderService;
_fruitBankAttributeService = fruitBankAttributeService;
_genericAttributeService = genericAttributeService;
_dbContext = dbContext;
}
/// <summary>
/// Create an order in InnVoice from a NopCommerce order
/// </summary>
[HttpPost]
[IgnoreAntiforgeryToken]
public async Task<IActionResult> CreateOrder(int orderId)
{
try
{
// Validate and get order
var order = await _orderService.GetOrderByIdAsync(orderId);
var orderDto = await _dbContext.OrderDtos.GetByIdAsync(orderId, true);
if (order == null)
{
return Json(new { success = false, message = "Order not found" });
}
if (orderDto == null)
{
return Json(new { success = false, message = "OrderDTO not found" });
}
if (orderDto.DateOfReceipt == null)
{
return Json(new { success = false, message = "Ki kell tölteni az átvétel idejét." });
}
// Validate and get customer
var customer = await _customerService.GetCustomerByIdAsync(orderDto.CustomerId);
if (customer == null)
{
return Json(new { success = false, message = "Customer not found" });
}
// Get and validate billing address
var billingAddress = await _customerService.GetCustomerBillingAddressAsync(customer);
if (billingAddress == null)
{
return Json(new { success = false, message = "Billing address not found" });
}
var billingCountry = await _countryService.GetCountryByAddressAsync(billingAddress);
var billingCountryCode = billingCountry?.TwoLetterIsoCode ?? "HU";
// Get shipping address (fallback to billing if not found)
var shippingAddress = await _customerService.GetCustomerShippingAddressAsync(customer) ?? billingAddress;
var shippingCountry = await _countryService.GetCountryByAddressAsync(shippingAddress);
var shippingCountryCode = shippingCountry?.TwoLetterIsoCode ?? billingCountryCode;
// Create order request
var orderRequest = new OrderCreateRequest
{
VevoNev = customer.Company ?? string.Empty,
VevoIrsz = billingAddress.ZipPostalCode ?? string.Empty,
VevoTelep = billingAddress.City ?? string.Empty,
VevoUtcaHsz = $"{billingAddress.Address1} {billingAddress.Address2}".Trim(),
VevoOrszag = billingCountryCode,
VevoAdoszam = customer.VatNumber,
MegrendelestombID = 1,
MegrendelesKelte = ((DateTime)orderDto.DateOfReceipt).ToLocalTime(),
Hatarido = DateTime.Now.AddDays(7),
Devizanem = "Ft", // TODO: get real default - A.
//FizetesiMod = order.PaymentMethodSystemName ?? "átutalás",
FizetesiMod = "átutalás",
//Email = customer.Email ?? string.Empty,
Email = billingAddress.Email ?? customer.Email ?? string.Empty,
Telefon = billingAddress.PhoneNumber ?? string.Empty,
MegrendelesSzamStr = orderDto.Id.ToString()
};
// Add shipping address details
orderRequest.SzallNev = $"{shippingAddress.FirstName} {shippingAddress.LastName}".Trim();
orderRequest.SzallIrsz = shippingAddress.ZipPostalCode ?? string.Empty;
orderRequest.SzallTelep = shippingAddress.City ?? string.Empty;
orderRequest.SzallUtcaHsz = $"{shippingAddress.Address1} {shippingAddress.Address2}".Trim();
orderRequest.SzallOrszag = shippingCountryCode;
// Get and validate order items
var orderItems = await _dbContext.OrderItemDtos.GetAllByOrderId(order.Id, true).ToListAsync();
if (orderItems == null || orderItems.Count == 0)
{
return Json(new { success = false, message = "Order has no items" });
}
// Add order items
foreach (var item in orderItems)
{
var product = _dbContext.ProductDtos.GetById(item.ProductId);
var productName = product?.Name ?? "Product";
if (item.IsMeasurable)
{
// For measurable products, quantity is weight stored in NetWeight
orderRequest.AddItem(new InnVoiceOrderItem
{
TetelNev = productName,
AfaSzoveg = "27%", // TODO: Configure VAT rate dynamically
Brutto = true,
EgysegAr = item.UnitPriceInclTax,
Mennyiseg = item.NetWeight > 0 ? Convert.ToDecimal(item.NetWeight) : 0,
MennyisegEgyseg = "kg",
CikkSzam = string.Empty
});
}
else
{
orderRequest.AddItem(new InnVoiceOrderItem
{
TetelNev = productName,
AfaSzoveg = "27%", // TODO: Configure VAT rate dynamically
Brutto = true,
EgysegAr = item.UnitPriceInclTax,
Mennyiseg = item.Quantity,
MennyisegEgyseg = "kt",
CikkSzam = string.Empty
});
}
}
// Create order via API
var response = await _innVoiceOrderService.CreateOrderAsync(orderRequest);
if (response == null)
{
return Json(new { success = false, message = "No response from InnVoice API" });
}
if (response.IsSuccess)
{
var currentStore = await _storeContext.GetCurrentStoreAsync();
var storeId = currentStore?.Id ?? 0;
// Save InnVoice order details as attributes
//await _fruitBankAttributeService.InsertOrUpdateGenericAttributeAsync<Order, string>(
// order.Id,
// "InnVoiceOrderTechId",
// response.TechId,
// storeId
//);
await _genericAttributeService.SaveAttributeAsync(
order,
"InnVoiceOrderTechId",
response.TechId,
storeId
);
await _genericAttributeService.SaveAttributeAsync(
order,
"InnVoiceOrderTableId",
response.TableId?.ToString() ?? string.Empty,
storeId
);
await _genericAttributeService.SaveAttributeAsync(
order,
"InnVoiceOrderPrintLink",
response.PrintUrl?.ToString() ?? string.Empty,
storeId
);
return Json(new
{
success = true,
message = "Order created successfully in InnVoice",
data = new
{
tableId = response.TableId,
techId = response.TechId,
printUrl = response.PrintUrl
}
});
}
return Json(new
{
success = false,
message = $"InnVoice API Error: {response.Message ?? "Unknown error"}"
});
}
catch (Exception ex)
{
// Log the exception here
// _logger.LogError(ex, "Error creating order {OrderId} in InnVoice", orderId);
return Json(new
{
success = false,
message = $"Error: {ex.Message}"
});
}
}
/// <summary>
/// Get InnVoice order status for a NopCommerce order
/// </summary>
/// <summary>
/// Get InnVoice order status for a NopCommerce order
/// </summary>
[HttpGet]
public async Task<IActionResult> GetOrderStatus(int orderId)
{
try
{
var order = await _orderService.GetOrderByIdAsync(orderId);
if (order == null)
return Json(new { success = false, message = "Order not found" });
var storeId = (await _storeContext.GetCurrentStoreAsync()).Id;
// Get saved InnVoice order TechId
var techId = await _genericAttributeService.GetAttributeAsync<string>(
order,
"InnVoiceOrderTechId",
storeId
);
var printLink = await _genericAttributeService.GetAttributeAsync<string>(
order,
"InnVoiceOrderPrintLink",
storeId
);
if (string.IsNullOrEmpty(techId))
{
return Json(new
{
success = false,
message = "No InnVoice order found for this order"
});
}
// Fetch the order details from InnVoice API using TechId
var innVoiceOrders = await _innVoiceOrderService.GetOrderByTechIdAsync(techId);
if (innVoiceOrders == null || innVoiceOrders.Count == 0)
{
return Json(new
{
success = false,
message = "Order not found in InnVoice"
});
}
var innVoiceOrder = innVoiceOrders.FirstOrDefault();
return Json(new
{
success = true,
data = new
{
tableId = innVoiceOrder.TableId,
techId = innVoiceOrder.TechId,
printUrl = printLink,
customerName = innVoiceOrder.CustomerName,
totalGross = innVoiceOrder.TotalGross,
currency = innVoiceOrder.Currency,
orderDate = innVoiceOrder.OrderDate
}
});
}
catch (Exception ex)
{
return Json(new
{
success = false,
message = $"Error: {ex.Message}"
});
}
}
/// <summary>
/// Create multiple orders in InnVoice from multiple NopCommerce orders
/// </summary>
[HttpPost]
[IgnoreAntiforgeryToken]
public async Task<IActionResult> CreateMultipleOrders([FromBody] int[] orderIds)
{
try
{
if (orderIds == null || orderIds.Length == 0)
return Json(new { success = false, message = "No order IDs provided" });
var orderRequests = new List<OrderCreateRequest>();
foreach (var orderId in orderIds)
{
var order = await _orderService.GetOrderByIdAsync(orderId);
if (order == null)
continue;
var customer = await _customerService.GetCustomerByIdAsync(order.CustomerId);
var billingAddress = await _customerService.GetCustomerBillingAddressAsync(customer);
if (billingAddress == null)
continue;
var billingCountry = await _countryService.GetCountryByAddressAsync(billingAddress);
var billingCountryCode = billingCountry?.TwoLetterIsoCode ?? "HU";
var orderRequest = new OrderCreateRequest
{
VevoNev = $"{billingAddress.FirstName} {billingAddress.LastName}",
VevoIrsz = billingAddress.ZipPostalCode ?? "",
VevoTelep = billingAddress.City ?? "",
VevoUtcaHsz = $"{billingAddress.Address1} {billingAddress.Address2}".Trim(),
VevoOrszag = billingCountryCode,
MegrendelestombID = 1,
MegrendelesKelte = order.CreatedOnUtc.ToLocalTime(),
Hatarido = DateTime.Now.AddDays(7),
Devizanem = "Ft",
FizetesiMod = order.PaymentMethodSystemName,
Email = billingAddress.Email,
Telefon = billingAddress.PhoneNumber,
MegrendelesSzamStr = order.Id.ToString()
};
// Add order items
var orderItems = await _orderService.GetOrderItemsAsync(order.Id);
foreach (var item in orderItems)
{
var product = await _productService.GetProductByIdAsync(item.ProductId);
orderRequest.AddItem(new InnVoiceOrderItem
{
TetelNev = product?.Name ?? "Product",
AfaSzoveg = "27%",
Brutto = true,
EgysegAr = item.UnitPriceInclTax,
Mennyiseg = item.Quantity,
MennyisegEgyseg = "db",
CikkSzam = product?.Sku
});
}
orderRequests.Add(orderRequest);
}
if (orderRequests.Count == 0)
return Json(new { success = false, message = "No valid orders to create" });
// Create orders via API
var responses = await _innVoiceOrderService.CreateOrdersAsync(orderRequests);
if (responses != null)
{
var successCount = responses.Count(r => r.IsSuccess);
var failureCount = responses.Count - successCount;
// Save TechIds for successful orders
var storeId = (await _storeContext.GetCurrentStoreAsync()).Id;
for (int i = 0; i < responses.Count && i < orderIds.Length; i++)
{
if (responses[i].IsSuccess)
{
var order = await _orderService.GetOrderByIdAsync(orderIds[i]);
if (order != null)
{
await _genericAttributeService.SaveAttributeAsync(
order,
"InnVoiceOrderTechId",
responses[i].TechId,
storeId
);
await _genericAttributeService.SaveAttributeAsync(
order,
"InnVoiceOrderTableId",
responses[i].TableId?.ToString(),
storeId
);
}
}
}
return Json(new
{
success = successCount > 0,
message = $"Created {successCount} orders successfully. {failureCount} failed.",
data = new
{
successCount,
failureCount,
responses = responses.Select(r => new
{
success = r.IsSuccess,
tableId = r.TableId,
techId = r.TechId,
message = r.Message,
printUrl = r.PrintUrl
})
}
});
}
else
{
throw new Exception($"InvoiceOrderAPi invalid response");
}
}
catch (Exception ex)
{
return Json(new
{
success = false,
message = $"Error: {ex.Message}"
});
}
}
}
}