527 lines
21 KiB
C#
527 lines
21 KiB
C#
using AyCode.Services.SignalRs;
|
|
using FruitBank.Common.Dtos;
|
|
using FruitBank.Common.Entities;
|
|
using FruitBank.Common.Interfaces;
|
|
using FruitBank.Common.Server.Interfaces;
|
|
using FruitBank.Common.SignalRs;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using Newtonsoft.Json;
|
|
using Nop.Core.Domain.Customers;
|
|
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.Factories;
|
|
using Nop.Plugin.Misc.FruitBankPlugin.Models.Orders;
|
|
using Nop.Services.Catalog;
|
|
using Nop.Services.Common;
|
|
using Nop.Services.Customers;
|
|
using Nop.Services.Messages;
|
|
using Nop.Services.Orders;
|
|
using Nop.Services.Payments;
|
|
using Nop.Services.Security;
|
|
using Nop.Web.Areas.Admin.Controllers;
|
|
using Nop.Web.Areas.Admin.Factories;
|
|
using Nop.Web.Areas.Admin.Models.Orders;
|
|
using Nop.Web.Framework;
|
|
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
|
|
{
|
|
[Area(AreaNames.ADMIN)]
|
|
[AuthorizeAdmin]
|
|
public class CustomOrderController : BaseAdminController, ICustomOrderSignalREndpointServer
|
|
{
|
|
private readonly IOrderService _orderService;
|
|
private readonly CustomOrderModelFactory _orderModelFactory;
|
|
private readonly ICustomOrderSignalREndpointServer _customOrderSignalREndpoint;
|
|
private readonly IPermissionService _permissionService;
|
|
private readonly IGenericAttributeService _genericAttributeService;
|
|
private readonly INotificationService _notificationService;
|
|
private readonly ICustomerService _customerService;
|
|
private readonly IProductService _productService;
|
|
// ... other dependencies
|
|
|
|
public CustomOrderController(IOrderService orderService, IOrderModelFactory orderModelFactory, ICustomOrderSignalREndpointServer customOrderSignalREndpoint, IPermissionService permissionService, IGenericAttributeService genericAttributeService, INotificationService notificationService, ICustomerService customerService, IProductService productService)
|
|
{
|
|
_orderService = orderService;
|
|
_orderModelFactory = orderModelFactory as CustomOrderModelFactory;
|
|
_customOrderSignalREndpoint = customOrderSignalREndpoint;
|
|
_permissionService = permissionService;
|
|
_genericAttributeService = genericAttributeService;
|
|
_notificationService = notificationService;
|
|
_customerService = customerService;
|
|
_productService = productService;
|
|
// ... initialize other deps
|
|
}
|
|
|
|
#region CustomOrderSignalREndpoint
|
|
[NonAction] public Task<List<OrderDto>> GetAllOrderDtos() => _customOrderSignalREndpoint.GetAllOrderDtos();
|
|
[NonAction]public Task<OrderDto> GetOrderDtoById(int orderId) => _customOrderSignalREndpoint.GetOrderDtoById(orderId);
|
|
[NonAction]public Task<List<OrderDto>> GetPendingOrderDtos() => _customOrderSignalREndpoint.GetPendingOrderDtos();
|
|
[NonAction]public Task<OrderDto> SetOrderStatusToComplete(int orderId) => _customOrderSignalREndpoint.SetOrderStatusToComplete(orderId);
|
|
[NonAction] public Task<List<OrderDto>> GetAllOrderDtoByIds(int[] orderIds) => _customOrderSignalREndpoint.GetAllOrderDtoByIds(orderIds);
|
|
[NonAction] public Task<OrderItemPallet> AddOrUpdateMeasuredOrderItemPallet(OrderItemPallet orderItemPallet) => _customOrderSignalREndpoint.AddOrUpdateMeasuredOrderItemPallet(orderItemPallet);
|
|
#endregion CustomOrderSignalREndpoint
|
|
|
|
[CheckPermission(StandardPermission.Orders.ORDERS_VIEW)]
|
|
public virtual async Task<IActionResult> List(List<int> orderStatuses = null, List<int> paymentStatuses = null, List<int> shippingStatuses = null)
|
|
{
|
|
//prepare model
|
|
var model = await _orderModelFactory.PrepareOrderSearchModelAsync(new OrderSearchModel
|
|
{
|
|
OrderStatusIds = orderStatuses,
|
|
PaymentStatusIds = paymentStatuses,
|
|
ShippingStatusIds = shippingStatuses,
|
|
});
|
|
|
|
return View("~/Plugins/Misc.FruitBankPlugin/Areas/Admin/Views/Order/List.cshtml", model);
|
|
}
|
|
|
|
[HttpPost]
|
|
[CheckPermission(StandardPermission.Orders.ORDERS_VIEW)]
|
|
public async Task<IActionResult> OrderList(OrderSearchModel searchModel)
|
|
{
|
|
//prepare model
|
|
var orderListModel = await GetOrderListModelByFilter(searchModel);
|
|
//var orderListModel = new OrderListModel();
|
|
|
|
var valami = Json(orderListModel);
|
|
Console.WriteLine(valami);
|
|
return valami;
|
|
}
|
|
|
|
public async Task<OrderListModelExtended> GetOrderListModelByFilter(OrderSearchModel searchModel)
|
|
{
|
|
//return _customOrderService.
|
|
var orderListModel = await _orderModelFactory.PrepareOrderListModelExtendedAsync(searchModel);
|
|
|
|
Console.WriteLine($"Total: {orderListModel.RecordsTotal}, Data Count: {orderListModel.Data.Count()}");
|
|
foreach (var item in orderListModel.Data.Take(3))
|
|
{
|
|
Console.WriteLine($"Order: {item.Id}, {item.CustomOrderNumber}");
|
|
}
|
|
|
|
return orderListModel;
|
|
}
|
|
|
|
public virtual IActionResult Test()
|
|
{
|
|
// Your custom logic here
|
|
// This will use your custom List.cshtml view
|
|
return View("~/Plugins/Misc.FruitBankPlugin/Areas/Admin/Views/Order/Test.cshtml");
|
|
}
|
|
|
|
//[HttpPost]
|
|
//[CheckPermission(Nop.Services.Security.StandardPermission.Orders.ORDERS_VIEW)]
|
|
//public virtual async Task<IActionResult> OrderList(OrderSearchModel searchModel)
|
|
//{
|
|
// //prepare model
|
|
// var model = await _orderModelFactory.PrepareOrderListModelAsync(searchModel);
|
|
|
|
// return Json(model);
|
|
//}
|
|
|
|
[HttpPost]
|
|
[ValidateAntiForgeryToken]
|
|
public async Task<IActionResult> SaveOrderAttributes(OrderAttributesModel model)
|
|
{
|
|
if (!ModelState.IsValid)
|
|
{
|
|
// reload order page with errors
|
|
return RedirectToAction("Edit", "Order", new { id = model.OrderId });
|
|
}
|
|
|
|
var order = await _orderService.GetOrderByIdAsync(model.OrderId);
|
|
if (order == null)
|
|
return RedirectToAction("List", "Order");
|
|
|
|
// store attributes in GenericAttribute table
|
|
await _genericAttributeService.SaveAttributeAsync(order, nameof(IMeasurable.IsMeasurable), model.IsMeasurable);
|
|
await _genericAttributeService.SaveAttributeAsync(order, nameof(IOrderDto.DateOfReceipt), model.DateOfReceipt);
|
|
|
|
_notificationService.SuccessNotification("Custom attributes saved successfully.");
|
|
|
|
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}"
|
|
// });
|
|
// }
|
|
//}
|
|
|
|
}
|
|
}
|
|
|
|
|