Create Order
This commit is contained in:
parent
959cbf5d62
commit
d87823bb41
|
|
@ -5,10 +5,14 @@ using FruitBank.Common.Server.Interfaces;
|
||||||
using FruitBank.Common.SignalRs;
|
using FruitBank.Common.SignalRs;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
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;
|
using Nop.Plugin.Misc.FruitBankPlugin.Models;
|
||||||
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.Security;
|
using Nop.Services.Security;
|
||||||
|
|
@ -30,9 +34,10 @@ 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;
|
||||||
// ... other dependencies
|
// ... other dependencies
|
||||||
|
|
||||||
public CustomOrderController(IOrderService orderService, IOrderModelFactory orderModelFactory, ICustomOrderSignalREndpointServer customOrderSignalREndpoint, IPermissionService permissionService, IGenericAttributeService genericAttributeService, INotificationService notificationService)
|
public CustomOrderController(IOrderService orderService, IOrderModelFactory orderModelFactory, ICustomOrderSignalREndpointServer customOrderSignalREndpoint, IPermissionService permissionService, IGenericAttributeService genericAttributeService, INotificationService notificationService, ICustomerService customerService)
|
||||||
{
|
{
|
||||||
_orderService = orderService;
|
_orderService = orderService;
|
||||||
_orderModelFactory = orderModelFactory as CustomOrderModelFactory;
|
_orderModelFactory = orderModelFactory as CustomOrderModelFactory;
|
||||||
|
|
@ -40,6 +45,7 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Areas.Admin.Controllers
|
||||||
_permissionService = permissionService;
|
_permissionService = permissionService;
|
||||||
_genericAttributeService = genericAttributeService;
|
_genericAttributeService = genericAttributeService;
|
||||||
_notificationService = notificationService;
|
_notificationService = notificationService;
|
||||||
|
_customerService = customerService;
|
||||||
// ... initialize other deps
|
// ... initialize other deps
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -131,6 +137,93 @@ 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]
|
||||||
|
public virtual async Task<IActionResult> Create(int customerId)
|
||||||
|
{
|
||||||
|
if (!await _permissionService.AuthorizeAsync(StandardPermission.Orders.ORDERS_CREATE_EDIT_DELETE))
|
||||||
|
return AccessDeniedView();
|
||||||
|
|
||||||
|
// Validate customer exists
|
||||||
|
var customer = await _customerService.GetCustomerByIdAsync(customerId);
|
||||||
|
if (customer == null)
|
||||||
|
return RedirectToAction("List");
|
||||||
|
|
||||||
|
// Create new empty order
|
||||||
|
var order = new Order
|
||||||
|
{
|
||||||
|
OrderGuid = Guid.NewGuid(),
|
||||||
|
CustomerId = customerId,
|
||||||
|
CustomerLanguageId = customer.LanguageId ?? 1,
|
||||||
|
CustomerTaxDisplayType = (TaxDisplayType)customer.TaxDisplayType,
|
||||||
|
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);
|
||||||
|
|
||||||
|
// Redirect to edit page
|
||||||
|
return RedirectToAction("Edit", new { id = order.Id });
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[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);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -186,6 +186,20 @@ 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
|
||||||
|
|
@ -286,14 +300,14 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Areas.Admin.Controllers
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// Open the PDF 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 = 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 PDF.");
|
pdfText = await _openAIApiService.AnalyzePdfAsync(stream, file.FileName, "Please extract all readable text from this image.");
|
||||||
}
|
}
|
||||||
catch (Exception aiEx)
|
catch (Exception aiEx)
|
||||||
{
|
{
|
||||||
|
|
@ -319,7 +333,6 @@ 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)}" +
|
||||||
|
|
@ -342,10 +355,10 @@ 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
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
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
|
||||||
// (check if all 3 refers to the same partner)
|
// (check if all 3 refers to the same partner)
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,10 @@
|
||||||
@T("Admin.Orders")
|
@T("Admin.Orders")
|
||||||
</h1>
|
</h1>
|
||||||
<div class="float-right">
|
<div class="float-right">
|
||||||
|
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#create-order-window">
|
||||||
|
<i class="fas fa-plus"></i>
|
||||||
|
@T("Admin.Common.AddNew")
|
||||||
|
</button>
|
||||||
<div class="btn-group">
|
<div class="btn-group">
|
||||||
<button type="button" class="btn btn-success">
|
<button type="button" class="btn btn-success">
|
||||||
<i class="fas fa-download"></i>
|
<i class="fas fa-download"></i>
|
||||||
|
|
@ -94,6 +98,7 @@
|
||||||
@await Component.InvokeAsync(typeof(AdminWidgetViewComponent), new { widgetZone = AdminWidgetZones.OrderListButtons, additionalData = Model })
|
@await Component.InvokeAsync(typeof(AdminWidgetViewComponent), new { widgetZone = AdminWidgetZones.OrderListButtons, additionalData = Model })
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<section class="content">
|
<section class="content">
|
||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
<div class="form-horizontal">
|
<div class="form-horizontal">
|
||||||
|
|
@ -677,3 +682,68 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@*create new order form*@
|
||||||
|
<div id="create-order-window" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="create-order-window-title">
|
||||||
|
<div class="modal-dialog">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h4 class="modal-title" id="create-order-window-title">@T("Admin.Orders.AddNew")</h4>
|
||||||
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
||||||
|
</div>
|
||||||
|
<form asp-controller="Order" asp-action="Create" method="post" id="create-order-form">
|
||||||
|
<div class="form-horizontal">
|
||||||
|
<div class="modal-body">
|
||||||
|
<div class="form-group row">
|
||||||
|
<div class="col-md-3">
|
||||||
|
<div class="label-wrapper">
|
||||||
|
<label class="col-form-label">
|
||||||
|
@T("Admin.Orders.Fields.Customer")
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-9">
|
||||||
|
<input type="text" id="create-order-customer-search" autocomplete="off" class="form-control" placeholder="Type customer name or email..." />
|
||||||
|
<span id="create-order-customer-name" class="mt-2 d-inline-block"></span>
|
||||||
|
<input type="hidden" id="create-order-customer-id" name="customerId" value="" />
|
||||||
|
<span class="field-validation-error" id="create-order-customer-error" style="display:none;">Please select a customer</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-secondary" data-dismiss="modal">
|
||||||
|
@T("Admin.Common.Cancel")
|
||||||
|
</button>
|
||||||
|
<button type="submit" class="btn btn-primary" id="create-order-submit">
|
||||||
|
@T("Admin.Common.Create")
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
/* Fix z-index for autocomplete dropdown in modal */
|
||||||
|
.ui-autocomplete {
|
||||||
|
z-index: 1060 !important; /* Bootstrap modal z-index is 1050 */
|
||||||
|
max-height: 200px;
|
||||||
|
overflow-y: auto;
|
||||||
|
overflow-x: hidden;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
$('#create-order-customer-search').autocomplete({
|
||||||
|
delay: 500,
|
||||||
|
minLength: 2,
|
||||||
|
source: '@Url.Action("CustomerSearchAutoComplete", "CustomOrder")',
|
||||||
|
select: function(event, ui) {
|
||||||
|
$('#create-order-customer-id').val(ui.item.value);
|
||||||
|
$('#create-order-customer-name').html('<strong>' + ui.item.label + '</strong>');
|
||||||
|
$('#create-order-customer-search').val('');
|
||||||
|
$('#create-order-customer-error').hide();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
@ -24,14 +24,22 @@
|
||||||
})
|
})
|
||||||
.Columns(c => {
|
.Columns(c => {
|
||||||
c.Add().DataField("Id").AllowEditing(false);
|
c.Add().DataField("Id").AllowEditing(false);
|
||||||
c.Add().DataField("Partner.Name").AllowEditing(false);
|
c.Add().DataField("PartnerId")
|
||||||
|
.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");
|
c.Add().DataField("IsAllMeasured").AllowEditing(false);
|
||||||
c.Add()
|
c.Add()
|
||||||
.Caption("Completed")
|
.Caption("Completed")
|
||||||
.DataType(GridColumnDataType.Boolean)
|
.DataType(GridColumnDataType.Boolean)
|
||||||
|
|
@ -54,8 +62,10 @@
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.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"))
|
||||||
|
|
@ -108,6 +118,40 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@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));
|
||||||
|
|
@ -180,10 +224,6 @@
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
||||||
|
|
@ -196,4 +236,20 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
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,6 +131,11 @@ 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,8 +1,9 @@
|
||||||
using System.Linq;
|
using FruitBank.Common.Interfaces;
|
||||||
using FruitBank.Common.Interfaces;
|
using Microsoft.AspNetCore.Http;
|
||||||
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;
|
||||||
using Nop.Services.Catalog;
|
using Nop.Services.Catalog;
|
||||||
using Nop.Services.Common;
|
using Nop.Services.Common;
|
||||||
|
|
@ -13,10 +14,11 @@ 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<AdminMenuCreatedEvent>
|
public class EventConsumer : BaseAdminMenuCreatedEventConsumer, IConsumer<OrderPlacedEvent>, IConsumer<EntityUpdatedEvent<Order>>, IConsumer<AdminMenuCreatedEvent>
|
||||||
{
|
{
|
||||||
private readonly IGenericAttributeService _genericAttributeService;
|
private readonly IGenericAttributeService _genericAttributeService;
|
||||||
private readonly IProductService _productService;
|
private readonly IProductService _productService;
|
||||||
|
|
@ -27,6 +29,8 @@ 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,
|
||||||
|
|
@ -38,7 +42,9 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Services
|
||||||
IWorkContext workContext,
|
IWorkContext workContext,
|
||||||
IStoreContext storeContext,
|
IStoreContext storeContext,
|
||||||
IAdminMenu adminMenu,
|
IAdminMenu adminMenu,
|
||||||
ILocalizationService localizationService) : base(pluginManager)
|
ILocalizationService localizationService,
|
||||||
|
IHttpContextAccessor httpContextAccessor,
|
||||||
|
FruitBankAttributeService fruitBankAttributeService) : base(pluginManager)
|
||||||
{
|
{
|
||||||
_genericAttributeService = genericAttributeService;
|
_genericAttributeService = genericAttributeService;
|
||||||
_productService = productService;
|
_productService = productService;
|
||||||
|
|
@ -49,6 +55,8 @@ 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";
|
||||||
|
|
@ -120,6 +128,39 @@ 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;
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,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"),
|
||||||
pickupDateTimeUtc: $("#@Html.IdFor(m => m.DateOfReceipt)").val(),
|
dateOfReceipt: $("#@Html.IdFor(m => m.DateOfReceipt)").val(),
|
||||||
__RequestVerificationToken: $('input[name="__RequestVerificationToken"]').val()
|
__RequestVerificationToken: $('input[name="__RequestVerificationToken"]').val()
|
||||||
},
|
},
|
||||||
success: function () {
|
success: function () {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue