admin starts
This commit is contained in:
parent
4c4bc11335
commit
68b8f523f2
|
|
@ -0,0 +1,654 @@
|
||||||
|
@model OrderSearchModel
|
||||||
|
|
||||||
|
@inject IStoreService storeService
|
||||||
|
@using Nop.Services.Stores
|
||||||
|
|
||||||
|
@{
|
||||||
|
//page title
|
||||||
|
ViewBag.PageTitle = T("Admin.Orders").Text;
|
||||||
|
//active menu item (system name)
|
||||||
|
NopHtml.SetActiveMenuItemSystemName("Orders");
|
||||||
|
}
|
||||||
|
|
||||||
|
@{
|
||||||
|
const string hideSearchBlockAttributeName = "OrdersPage.HideSearchBlock";
|
||||||
|
var hideSearchBlock = await genericAttributeService.GetAttributeAsync<bool>(await workContext.GetCurrentCustomerAsync(), hideSearchBlockAttributeName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@if (Model.LicenseCheckModel.BlockPages != true)
|
||||||
|
{
|
||||||
|
<form asp-controller="Order" asp-action="List" method="post">
|
||||||
|
<div class="content-header clearfix">
|
||||||
|
<h1 class="float-left">
|
||||||
|
@T("Admin.Orders")
|
||||||
|
</h1>
|
||||||
|
<div class="float-right">
|
||||||
|
<div class="btn-group">
|
||||||
|
<button type="button" class="btn btn-success">
|
||||||
|
<i class="fas fa-download"></i>
|
||||||
|
@T("Admin.Common.Export")
|
||||||
|
</button>
|
||||||
|
<button type="button" class="btn btn-success dropdown-toggle dropdown-icon" data-toggle="dropdown" aria-expanded="false">
|
||||||
|
<span class="sr-only"> </span>
|
||||||
|
</button>
|
||||||
|
<ul class="dropdown-menu" role="menu">
|
||||||
|
<li class="dropdown-item">
|
||||||
|
<button asp-action="ExportXml" type="submit" name="exportxml-all">
|
||||||
|
<i class="far fa-file-code"></i>
|
||||||
|
@T("Admin.Common.ExportToXml.All")
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
<li class="dropdown-item">
|
||||||
|
<button type="button" id="exportxml-selected">
|
||||||
|
<i class="far fa-file-code"></i>
|
||||||
|
@T("Admin.Common.ExportToXml.Selected")
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
<li class="dropdown-divider"></li>
|
||||||
|
<li class="dropdown-item">
|
||||||
|
<button asp-action="ExportExcel" type="submit" name="exportexcel-all">
|
||||||
|
<i class="far fa-file-excel"></i>
|
||||||
|
@T("Admin.Common.ExportToExcel.All")
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
<li class="dropdown-item">
|
||||||
|
<button type="button" id="exportexcel-selected">
|
||||||
|
<i class="far fa-file-excel"></i>
|
||||||
|
@T("Admin.Common.ExportToExcel.Selected")
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<button type="button" name="importexcel" class="btn bg-olive" data-toggle="modal" data-target="#importexcel-window">
|
||||||
|
<i class="fas fa-upload"></i>
|
||||||
|
@T("Admin.Common.Import")
|
||||||
|
</button>
|
||||||
|
<div class="btn-group">
|
||||||
|
<button type="button" class="btn btn-info">
|
||||||
|
<i class="far fa-file-pdf"></i>
|
||||||
|
@T("Admin.Orders.PdfInvoices")
|
||||||
|
</button>
|
||||||
|
<button type="button" class="btn btn-info dropdown-toggle dropdown-icon" data-toggle="dropdown" aria-expanded="false">
|
||||||
|
<span class="sr-only"> </span>
|
||||||
|
</button>
|
||||||
|
<ul class="dropdown-menu" role="menu">
|
||||||
|
<li class="dropdown-item">
|
||||||
|
<button asp-action="PdfInvoice" type="submit" name="pdf-invoice-all">
|
||||||
|
@T("Admin.Orders.PdfInvoices.All")
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
<li class="dropdown-item">
|
||||||
|
<button type="button" id="pdf-invoice-selected">
|
||||||
|
@T("Admin.Orders.PdfInvoices.Selected")
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
@await Component.InvokeAsync(typeof(AdminWidgetViewComponent), new { widgetZone = AdminWidgetZones.OrderListButtons, additionalData = Model })
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<section class="content">
|
||||||
|
<div class="container-fluid">
|
||||||
|
<div class="form-horizontal">
|
||||||
|
<div class="cards-group">
|
||||||
|
<div class="card card-default card-search">
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="row search-row @(!hideSearchBlock ? "opened" : "")" data-hideAttribute="@hideSearchBlockAttributeName">
|
||||||
|
<div class="search-text">@T("Admin.Common.Search")</div>
|
||||||
|
<div class="icon-search"><i class="fas fa-magnifying-glass" aria-hidden="true"></i></div>
|
||||||
|
<div class="icon-collapse"><i class="far fa-angle-@(!hideSearchBlock ? "up" : "down")" aria-hidden="true"></i></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="search-body @(hideSearchBlock ? "closed" : "")">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-5">
|
||||||
|
<div class="form-group row">
|
||||||
|
<div class="col-md-4">
|
||||||
|
<nop-label asp-for="StartDate" />
|
||||||
|
</div>
|
||||||
|
<div class="col-md-8">
|
||||||
|
<nop-editor asp-for="StartDate" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row">
|
||||||
|
<div class="col-md-4">
|
||||||
|
<nop-label asp-for="EndDate" />
|
||||||
|
</div>
|
||||||
|
<div class="col-md-8">
|
||||||
|
<nop-editor asp-for="EndDate" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row" @(Model.AvailableWarehouses.SelectionIsNotPossible() ? Html.Raw("style=\"display:none\"") : null)>
|
||||||
|
<div class="col-md-4">
|
||||||
|
<nop-label asp-for="WarehouseId" />
|
||||||
|
</div>
|
||||||
|
<div class="col-md-8">
|
||||||
|
<nop-select asp-for="WarehouseId" asp-items="Model.AvailableWarehouses" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row">
|
||||||
|
<div class="col-md-4">
|
||||||
|
<nop-label asp-for="ProductId" />
|
||||||
|
</div>
|
||||||
|
<div class="col-md-8">
|
||||||
|
<input type="text" id="search-product-name" autocomplete="off" class="form-control" />
|
||||||
|
<span id="search-product-friendly-name"></span>
|
||||||
|
<button type="button" id="search-product-clear" class="btn bg-gray" style="display: none; margin-top: 5px;">@T("Admin.Common.Clear")</button>
|
||||||
|
<input asp-for="ProductId" autocomplete="off" style="display: none;" />
|
||||||
|
<script>
|
||||||
|
$(function() {
|
||||||
|
$('#search-product-name').autocomplete({
|
||||||
|
delay: 500,
|
||||||
|
minLength: 3,
|
||||||
|
source: '@Url.Action("SearchAutoComplete", "SearchComplete")',
|
||||||
|
select: function(event, ui) {
|
||||||
|
$('#@Html.IdFor(model => model.ProductId)').val(ui.item.productid);
|
||||||
|
$('#search-product-friendly-name').text(ui.item.label);
|
||||||
|
|
||||||
|
$('#search-product-clear').show();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//remove button
|
||||||
|
$('#search-product-clear').click(function() {
|
||||||
|
$('#@Html.IdFor(model => model.ProductId)').val('0');
|
||||||
|
$('#search-product-friendly-name').text('');
|
||||||
|
$('#search-product-clear').hide();
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row" @(Model.IsLoggedInAsVendor ? Html.Raw("style='display: none;'") : null)>
|
||||||
|
<div class="col-md-4">
|
||||||
|
<nop-label asp-for="OrderStatusIds" />
|
||||||
|
</div>
|
||||||
|
<div class="col-md-8">
|
||||||
|
<nop-select asp-for="OrderStatusIds" asp-items="Model.AvailableOrderStatuses" asp-multiple="true" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row">
|
||||||
|
<div class="col-md-4">
|
||||||
|
<nop-label asp-for="PaymentStatusIds" />
|
||||||
|
</div>
|
||||||
|
<div class="col-md-8">
|
||||||
|
<nop-select asp-for="PaymentStatusIds" asp-items="Model.AvailablePaymentStatuses" asp-multiple="true" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row" @(Model.IsLoggedInAsVendor ? Html.Raw("style='display: none;'") : null)>
|
||||||
|
<div class="col-md-4">
|
||||||
|
<nop-label asp-for="ShippingStatusIds" />
|
||||||
|
</div>
|
||||||
|
<div class="col-md-8">
|
||||||
|
<nop-select asp-for="ShippingStatusIds" asp-items="Model.AvailableShippingStatuses" asp-multiple="true" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-7">
|
||||||
|
<div class="form-group row" @(Model.HideStoresList ? Html.Raw("style=\"display:none\"") : null)>
|
||||||
|
<div class="col-md-4">
|
||||||
|
<nop-label asp-for="StoreId" />
|
||||||
|
</div>
|
||||||
|
<div class="col-md-8">
|
||||||
|
<nop-select asp-for="StoreId" asp-items="Model.AvailableStores" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row" @(Model.AvailableVendors.SelectionIsNotPossible() || Model.IsLoggedInAsVendor ? Html.Raw("style='display: none;'") : null)>
|
||||||
|
<div class="col-md-4">
|
||||||
|
<nop-label asp-for="VendorId" />
|
||||||
|
</div>
|
||||||
|
<div class="col-md-8">
|
||||||
|
<nop-select asp-for="VendorId" asp-items="Model.AvailableVendors" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@if (Model.BillingPhoneEnabled)
|
||||||
|
{
|
||||||
|
<div class="form-group row">
|
||||||
|
<div class="col-md-4">
|
||||||
|
<nop-label asp-for="BillingPhone" />
|
||||||
|
</div>
|
||||||
|
<div class="col-md-8">
|
||||||
|
<nop-editor asp-for="BillingPhone" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
<div class="form-group row">
|
||||||
|
<div class="col-md-4">
|
||||||
|
<nop-label asp-for="BillingEmail" />
|
||||||
|
</div>
|
||||||
|
<div class="col-md-8">
|
||||||
|
<nop-editor asp-for="BillingEmail" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row">
|
||||||
|
<div class="col-md-4">
|
||||||
|
<nop-label asp-for="BillingLastName" />
|
||||||
|
</div>
|
||||||
|
<div class="col-md-8">
|
||||||
|
<nop-editor asp-for="BillingLastName" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row" @(Model.AvailableCountries.SelectionIsNotPossible() ? Html.Raw("style=\"display:none\"") : null)>
|
||||||
|
<div class="col-md-4">
|
||||||
|
<nop-label asp-for="BillingCountryId" />
|
||||||
|
</div>
|
||||||
|
<div class="col-md-8">
|
||||||
|
<nop-select asp-for="BillingCountryId" asp-items="Model.AvailableCountries" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row" @(Model.AvailablePaymentMethods.SelectionIsNotPossible() || Model.IsLoggedInAsVendor ? Html.Raw("style='display: none;'") : null)>
|
||||||
|
<div class="col-md-4">
|
||||||
|
<nop-label asp-for="PaymentMethodSystemName" />
|
||||||
|
</div>
|
||||||
|
<div class="col-md-8">
|
||||||
|
<nop-select asp-for="PaymentMethodSystemName" asp-items="Model.AvailablePaymentMethods" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row">
|
||||||
|
<div class="col-md-4">
|
||||||
|
<nop-label asp-for="OrderNotes" />
|
||||||
|
</div>
|
||||||
|
<div class="col-md-8">
|
||||||
|
<nop-editor asp-for="OrderNotes" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row">
|
||||||
|
<div class="col-md-4">
|
||||||
|
<nop-label asp-for="GoDirectlyToCustomOrderNumber" />
|
||||||
|
</div>
|
||||||
|
<div class="col-md-8">
|
||||||
|
<div class="input-group input-group-short">
|
||||||
|
<nop-editor asp-for="GoDirectlyToCustomOrderNumber" />
|
||||||
|
<span class="input-group-append">
|
||||||
|
<button type="submit" id="go-to-order-by-number" name="go-to-order-by-number" class="btn btn-info btn-flat">
|
||||||
|
@T("Admin.Common.Go")
|
||||||
|
</button>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="text-center col-12">
|
||||||
|
<button type="button" id="search-orders" class="btn btn-primary btn-search">
|
||||||
|
<i class="fas fa-magnifying-glass"></i>
|
||||||
|
@T("Admin.Common.Search")
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card card-default">
|
||||||
|
<div class="card-body">
|
||||||
|
<nop-doc-reference asp-string-resource="@T("Admin.Documentation.Reference.Orders", Docs.Orders + Utm.OnAdmin)" />
|
||||||
|
|
||||||
|
@{
|
||||||
|
var gridModel = new DataTablesModel
|
||||||
|
{
|
||||||
|
Name = "orders-grid",
|
||||||
|
UrlRead = new DataUrl("OrderList", "Order", null),
|
||||||
|
SearchButtonId = "search-orders",
|
||||||
|
Length = Model.PageSize,
|
||||||
|
LengthMenu = Model.AvailablePageSizes,
|
||||||
|
FooterCallback = !Model.IsLoggedInAsVendor ? "ordersfootercallback" : null,
|
||||||
|
FooterColumns = !Model.IsLoggedInAsVendor ? 10 : 0,
|
||||||
|
Filters = new List<FilterParameter>
|
||||||
|
{
|
||||||
|
new FilterParameter(nameof(Model.StartDate), typeof(DateTime?)),
|
||||||
|
new FilterParameter(nameof(Model.EndDate), typeof(DateTime?)),
|
||||||
|
new FilterParameter(nameof(Model.OrderStatusIds)),
|
||||||
|
new FilterParameter(nameof(Model.PaymentStatusIds)),
|
||||||
|
new FilterParameter(nameof(Model.ShippingStatusIds)),
|
||||||
|
new FilterParameter(nameof(Model.StoreId)),
|
||||||
|
new FilterParameter(nameof(Model.VendorId)),
|
||||||
|
new FilterParameter(nameof(Model.WarehouseId)),
|
||||||
|
new FilterParameter(nameof(Model.BillingEmail)),
|
||||||
|
new FilterParameter(nameof(Model.BillingPhone)),
|
||||||
|
new FilterParameter(nameof(Model.BillingLastName)),
|
||||||
|
new FilterParameter(nameof(Model.BillingCountryId)),
|
||||||
|
new FilterParameter(nameof(Model.PaymentMethodSystemName)),
|
||||||
|
new FilterParameter(nameof(Model.ProductId)),
|
||||||
|
new FilterParameter(nameof(Model.OrderNotes))
|
||||||
|
}
|
||||||
|
};
|
||||||
|
gridModel.ColumnCollection = new List<ColumnProperty>
|
||||||
|
{
|
||||||
|
new ColumnProperty(nameof(OrderModel.Id))
|
||||||
|
{
|
||||||
|
IsMasterCheckBox = true,
|
||||||
|
Render = new RenderCheckBox("checkbox_orders"),
|
||||||
|
ClassName = NopColumnClassDefaults.CenterAll,
|
||||||
|
Width = "50"
|
||||||
|
},
|
||||||
|
new ColumnProperty(nameof(OrderModel.CustomOrderNumber))
|
||||||
|
{
|
||||||
|
Title = T("Admin.Orders.Fields.CustomOrderNumber").Text,
|
||||||
|
Width = "80"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
gridModel.ColumnCollection.Add(new ColumnProperty(nameof(OrderModelExtended.NeedsMeasurement))
|
||||||
|
{
|
||||||
|
Title = "Needs Measurement",
|
||||||
|
Width = "100",
|
||||||
|
Render = new RenderCustom("renderColumnNeedsMeasurement"),
|
||||||
|
ClassName = NopColumnClassDefaults.CenterAll
|
||||||
|
});
|
||||||
|
|
||||||
|
//a vendor does not have access to this functionality
|
||||||
|
if (!Model.IsLoggedInAsVendor)
|
||||||
|
{
|
||||||
|
gridModel.ColumnCollection.Add(new ColumnProperty(nameof(OrderModel.OrderStatus))
|
||||||
|
{
|
||||||
|
Title = T("Admin.Orders.Fields.OrderStatus").Text,
|
||||||
|
Width = "100",
|
||||||
|
Render = new RenderCustom("renderColumnOrderStatus")
|
||||||
|
});
|
||||||
|
}
|
||||||
|
gridModel.ColumnCollection.Add(new ColumnProperty(nameof(OrderModel.PaymentStatus))
|
||||||
|
{
|
||||||
|
Title = T("Admin.Orders.Fields.PaymentStatus").Text,
|
||||||
|
Width = "150"
|
||||||
|
});
|
||||||
|
//a vendor does not have access to this functionality
|
||||||
|
if (!Model.IsLoggedInAsVendor)
|
||||||
|
{
|
||||||
|
gridModel.ColumnCollection.Add(new ColumnProperty(nameof(OrderModel.ShippingStatus))
|
||||||
|
{
|
||||||
|
Title = T("Admin.Orders.Fields.ShippingStatus").Text,
|
||||||
|
Width = "150"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
gridModel.ColumnCollection.Add(new ColumnProperty(nameof(OrderModel.CustomerEmail))
|
||||||
|
{
|
||||||
|
Title = T("Admin.Orders.Fields.Customer").Text,
|
||||||
|
Render = new RenderCustom("renderColumnCustomer")
|
||||||
|
});
|
||||||
|
gridModel.ColumnCollection.Add(new ColumnProperty(nameof(OrderModel.StoreName))
|
||||||
|
{
|
||||||
|
Title = T("Admin.Orders.Fields.Store").Text,
|
||||||
|
Width = "100",
|
||||||
|
Visible = (await storeService.GetAllStoresAsync()).Count > 1
|
||||||
|
});
|
||||||
|
gridModel.ColumnCollection.Add(new ColumnProperty(nameof(OrderModel.CreatedOn))
|
||||||
|
{
|
||||||
|
Title = T("Admin.Orders.Fields.CreatedOn").Text,
|
||||||
|
Width = "120",
|
||||||
|
Render = new RenderDate()
|
||||||
|
});
|
||||||
|
//a vendor does not have access to this functionality
|
||||||
|
if (!Model.IsLoggedInAsVendor)
|
||||||
|
{
|
||||||
|
gridModel.ColumnCollection.Add(new ColumnProperty(nameof(OrderModel.OrderTotal))
|
||||||
|
{
|
||||||
|
Title = T("Admin.Orders.Fields.OrderTotal").Text,
|
||||||
|
Width = "100",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
gridModel.ColumnCollection.Add(new ColumnProperty(nameof(OrderModel.Id))
|
||||||
|
{
|
||||||
|
Title = T("Admin.Common.View").Text,
|
||||||
|
Width = "50",
|
||||||
|
ClassName = NopColumnClassDefaults.Button,
|
||||||
|
Render = new RenderButtonView(new DataUrl("~/Admin/Order/Edit"))
|
||||||
|
});
|
||||||
|
var orderSummaryColumnNumber = 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
@await Html.PartialAsync("Table", gridModel)
|
||||||
|
|
||||||
|
<script>
|
||||||
|
function renderColumnOrderStatus(data, type, row, meta) {
|
||||||
|
var color;
|
||||||
|
switch (row.OrderStatusId) {
|
||||||
|
case 10:
|
||||||
|
color = 'yellow';
|
||||||
|
break;
|
||||||
|
case 20:
|
||||||
|
color = 'blue';
|
||||||
|
break;
|
||||||
|
case 30:
|
||||||
|
color = 'green';
|
||||||
|
break;
|
||||||
|
case 40:
|
||||||
|
color = 'red';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return '<span class="grid-report-item ' + color + '">' + data + '</span >';
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderColumnCustomer(data, type, row, meta) {
|
||||||
|
var link = '@Url.Content("~/Admin/Customer/Edit/")' + row.CustomerId;
|
||||||
|
var textRenderer = $.fn.dataTable.render.text().display;
|
||||||
|
return `${textRenderer(row.CustomerFullName)} <br /><a href="${link}">${data}</a > `;
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderColumnNeedsMeasurement(data, type, row, meta) {
|
||||||
|
if(data === true) {
|
||||||
|
return '<span class="badge badge-warning">Yes</span>';
|
||||||
|
}
|
||||||
|
return '<span class="badge badge-secondary">No</span>';
|
||||||
|
}
|
||||||
|
|
||||||
|
$(function() {
|
||||||
|
$("#@Html.IdFor(model => model.GoDirectlyToCustomOrderNumber)").keydown(
|
||||||
|
function(event) {
|
||||||
|
if (event.keyCode === 13) {
|
||||||
|
$("#go-to-order-by-number").trigger("click");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
function ordersfootercallback(tfoot, data, start, end, display) {
|
||||||
|
//update order totals summary
|
||||||
|
var postData = {
|
||||||
|
StartDate: $('#@Html.IdFor(model => model.StartDate)').val(),
|
||||||
|
EndDate: $('#@Html.IdFor(model => model.EndDate)').val(),
|
||||||
|
OrderStatusIds: $('#@Html.IdFor(model => model.OrderStatusIds)').val(),
|
||||||
|
PaymentStatusIds: $('#@Html.IdFor(model => model.PaymentStatusIds)').val(),
|
||||||
|
ShippingStatusIds: $('#@Html.IdFor(model => model.ShippingStatusIds)').val(),
|
||||||
|
StoreId: $('#@Html.IdFor(model => model.StoreId)').val(),
|
||||||
|
VendorId: $('#@Html.IdFor(model => model.VendorId)').val(),
|
||||||
|
WarehouseId: $('#@Html.IdFor(model => model.WarehouseId)').val(),
|
||||||
|
BillingEmail: $('#@Html.IdFor(model => model.BillingEmail)').val(),
|
||||||
|
BillingPhone: $('#@Html.IdFor(model => model.BillingPhone)').val(),
|
||||||
|
BillingLastName: $('#@Html.IdFor(model => model.BillingLastName)').val(),
|
||||||
|
BillingCountryId: $('#@Html.IdFor(model => model.BillingCountryId)').val(),
|
||||||
|
PaymentMethodSystemName: $('#@Html.IdFor(model => model.PaymentMethodSystemName)').val(),
|
||||||
|
ProductId: $('#@Html.IdFor(model => model.ProductId)').val(),
|
||||||
|
OrderNotes: $('#@Html.IdFor(model => model.OrderNotes)').val()
|
||||||
|
};
|
||||||
|
addAntiForgeryToken(postData);
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
cache: false,
|
||||||
|
type: "POST",
|
||||||
|
url: "@(Url.Action("ReportAggregates", "Order"))",
|
||||||
|
data: postData,
|
||||||
|
success: function (data, textStatus, jqXHR) {
|
||||||
|
if (data) {
|
||||||
|
for (var key in data) {
|
||||||
|
var reportSummary = '<div><strong>@T("Admin.Orders.Report.Summary").Text</strong></div>' +
|
||||||
|
'<div>@T("Admin.Orders.Report.Profit").Text <span>' + data['AggregatorProfit'] +'</span></div>' +
|
||||||
|
'<div>@T("Admin.Orders.Report.Shipping").Text <span>' + data['AggregatorShipping'] + '</span></div>' +
|
||||||
|
'<div>@T("Admin.Orders.Report.Tax").Text <span>' + data['AggregatorTax'] + '</span></div>' +
|
||||||
|
'<div>@T("Admin.Orders.Report.Total").Text <span>' + data['AggregatorTotal'] + '</span></div>'
|
||||||
|
var orderTotalsColumn = $('#orders-grid').DataTable().column(@(orderSummaryColumnNumber));
|
||||||
|
$(orderTotalsColumn.footer()).html(reportSummary);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</form>
|
||||||
|
}
|
||||||
|
|
||||||
|
<script>
|
||||||
|
$(function() {
|
||||||
|
var displayModal = @((Model.LicenseCheckModel.DisplayWarning == true || Model.LicenseCheckModel?.BlockPages == true).ToString().ToLower());
|
||||||
|
if (displayModal){
|
||||||
|
$('#license-window').modal({
|
||||||
|
backdrop: 'static',
|
||||||
|
keyboard: false
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#license-window').on('shown.bs.modal', function (event) {
|
||||||
|
var modalCloseEl = $(this).find('button.close');
|
||||||
|
var closeTextEl = $('span', modalCloseEl);
|
||||||
|
|
||||||
|
var startFrom = 5;
|
||||||
|
closeTextEl.text(startFrom);
|
||||||
|
|
||||||
|
const timer = setInterval(function() {
|
||||||
|
if (startFrom-- > 0)
|
||||||
|
closeTextEl.text(startFrom);
|
||||||
|
}, 1000);
|
||||||
|
|
||||||
|
setTimeout(function() {
|
||||||
|
closeTextEl.html('×');
|
||||||
|
modalCloseEl.on('click', function() {
|
||||||
|
$('#license-window').modal('hide')
|
||||||
|
});
|
||||||
|
clearInterval(timer);
|
||||||
|
}, startFrom*1000);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<div id="license-window" class="modal fade" tabindex="-1" role="dialog">
|
||||||
|
<div class="modal-dialog" role="document">
|
||||||
|
<div class="modal-content">
|
||||||
|
@Html.Raw(Model.LicenseCheckModel?.WarningText)
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@*export selected (XML). We don't use GET approach because it's limited to 2K-4K chars and won't work for large number of entities*@
|
||||||
|
<form asp-controller="Order" asp-action="ExportXmlSelected" method="post" id="export-xml-selected-form">
|
||||||
|
<input type="hidden" id="selectedIds" name="selectedIds" value="" />
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
$(function() {
|
||||||
|
$('#exportxml-selected').click(function (e) {
|
||||||
|
e.preventDefault();
|
||||||
|
var ids = selectedIds.join(",");
|
||||||
|
if (!ids) {
|
||||||
|
$('#exportXmlSelected-info').text("@T("Admin.Orders.NoOrders")");
|
||||||
|
$("#exportXmlSelected").trigger("click");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$('#export-xml-selected-form #selectedIds').val(ids);
|
||||||
|
$('#export-xml-selected-form').submit();
|
||||||
|
updateTable('#orders-grid');
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<nop-alert asp-alert-id="exportXmlSelected" />
|
||||||
|
|
||||||
|
@*export selected (Excel). We don't use GET approach because it's limited to 2K-4K chars and won't work for large number of entities*@
|
||||||
|
<form asp-controller="Order" asp-action="ExportExcelSelected" method="post" id="export-excel-selected-form">
|
||||||
|
<input type="hidden" id="selectedIds" name="selectedIds" value="" />
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
$(function() {
|
||||||
|
$('#exportexcel-selected').click(function (e) {
|
||||||
|
e.preventDefault();
|
||||||
|
var ids = selectedIds.join(",");
|
||||||
|
if (!ids) {
|
||||||
|
$('#exportExcelSelected-info').text("@T("Admin.Orders.NoOrders")");
|
||||||
|
$("#exportExcelSelected").trigger("click");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$('#export-excel-selected-form #selectedIds').val(ids);
|
||||||
|
$('#export-excel-selected-form').submit();
|
||||||
|
updateTable('#orders-grid');
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<nop-alert asp-alert-id="exportExcelSelected" />
|
||||||
|
|
||||||
|
@*Print packaging slips selected (XML). We don't use GET approach because it's limited to 2K-4K chars and won't work for large number of entities*@
|
||||||
|
<form asp-controller="Order" asp-action="PdfInvoiceSelected" method="post" id="pdf-invoice-selected-form">
|
||||||
|
<input type="hidden" id="selectedIds" name="selectedIds" value="" />
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
$(function() {
|
||||||
|
$('#pdf-invoice-selected').click(function (e) {
|
||||||
|
e.preventDefault();
|
||||||
|
var ids = selectedIds.join(",");
|
||||||
|
if (!ids) {
|
||||||
|
$('#pdfInvoiceSelected-info').text("@T("Admin.Orders.NoOrders")");
|
||||||
|
$("#pdfInvoiceSelected").trigger("click");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$('#pdf-invoice-selected-form #selectedIds').val(ids);
|
||||||
|
$('#pdf-invoice-selected-form').submit();
|
||||||
|
updateTable('#orders-grid');
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<nop-alert asp-alert-id="pdfInvoiceSelected" />
|
||||||
|
|
||||||
|
@*import orders form*@
|
||||||
|
<div id="importexcel-window" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="importexcel-window-title">
|
||||||
|
<div class="modal-dialog">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h4 class="modal-title" id="importexcel-window-title">@T("Admin.Common.ImportFromExcel")</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="ImportFromXlsx" method="post" enctype="multipart/form-data">
|
||||||
|
<div class="form-horizontal">
|
||||||
|
<div class="modal-body">
|
||||||
|
<ul class="common-list">
|
||||||
|
<li>
|
||||||
|
<em>@T("Admin.Orders.List.ImportFromExcelTip")</em>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<em>@T("Admin.Common.ImportFromExcel.ManyRecordsWarning")</em>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<div class="form-group row">
|
||||||
|
<div class="col-md-2">
|
||||||
|
<div class="label-wrapper">
|
||||||
|
<label class="col-form-label">
|
||||||
|
@T("Admin.Common.ExcelFile")
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-10">
|
||||||
|
<input type="file" id="importexcelfile" name="importexcelfile" class="form-control" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="submit" class="btn btn-primary">
|
||||||
|
@T("Admin.Common.ImportFromExcel")
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
@{
|
||||||
|
Layout = "_AdminLayout";
|
||||||
|
}
|
||||||
|
<h1>TEST VIEW FROM PLUGIN</h1>
|
||||||
|
|
@ -0,0 +1,213 @@
|
||||||
|
using Microsoft.AspNetCore.Mvc.Infrastructure;
|
||||||
|
using Microsoft.AspNetCore.Mvc.Routing;
|
||||||
|
using Nop.Core.Domain.Catalog;
|
||||||
|
using Nop.Core.Domain.Common;
|
||||||
|
using Nop.Core.Domain.Directory;
|
||||||
|
using Nop.Core.Domain.Orders;
|
||||||
|
using Nop.Core.Domain.Shipping;
|
||||||
|
using Nop.Core.Domain.Tax;
|
||||||
|
using Nop.Core;
|
||||||
|
using Nop.Plugin.Misc.FruitBankPlugin.Services;
|
||||||
|
using Nop.Services.Affiliates;
|
||||||
|
using Nop.Services.Catalog;
|
||||||
|
using Nop.Services.Common;
|
||||||
|
using Nop.Services.Configuration;
|
||||||
|
using Nop.Services.Customers;
|
||||||
|
using Nop.Services.Directory;
|
||||||
|
using Nop.Services.Discounts;
|
||||||
|
using Nop.Services.Helpers;
|
||||||
|
using Nop.Services.Localization;
|
||||||
|
using Nop.Services.Media;
|
||||||
|
using Nop.Services.Orders;
|
||||||
|
using Nop.Services.Payments;
|
||||||
|
using Nop.Services.Security;
|
||||||
|
using Nop.Services.Seo;
|
||||||
|
using Nop.Services.Shipping;
|
||||||
|
using Nop.Services.Stores;
|
||||||
|
using Nop.Services.Tax;
|
||||||
|
using Nop.Services.Vendors;
|
||||||
|
using Nop.Web.Areas.Admin.Factories;
|
||||||
|
using Nop.Web.Areas.Admin.Models.Orders;
|
||||||
|
using Nop.Plugin.Misc.FruitBankPlugin.Models;
|
||||||
|
using System.Reflection;
|
||||||
|
using Nop.Plugin.Misc.FruitBankPlugin.Helpers;
|
||||||
|
|
||||||
|
namespace Nop.Plugin.Misc.FruitBankPlugin.Factories
|
||||||
|
{
|
||||||
|
public class CustomOrderModelFactory : OrderModelFactory
|
||||||
|
{
|
||||||
|
private readonly IOrderMeasurementService _orderMeasurementService;
|
||||||
|
|
||||||
|
public CustomOrderModelFactory(
|
||||||
|
IOrderMeasurementService orderMeasurementService,
|
||||||
|
AddressSettings addressSettings,
|
||||||
|
CatalogSettings catalogSettings,
|
||||||
|
CurrencySettings currencySettings,
|
||||||
|
IActionContextAccessor actionContextAccessor,
|
||||||
|
IAddressModelFactory addressModelFactory,
|
||||||
|
IAddressService addressService,
|
||||||
|
IAffiliateService affiliateService,
|
||||||
|
IBaseAdminModelFactory baseAdminModelFactory,
|
||||||
|
ICountryService countryService,
|
||||||
|
ICurrencyService currencyService,
|
||||||
|
ICustomerService customerService,
|
||||||
|
IDateTimeHelper dateTimeHelper,
|
||||||
|
IDiscountService discountService,
|
||||||
|
IDownloadService downloadService,
|
||||||
|
IEncryptionService encryptionService,
|
||||||
|
IGiftCardService giftCardService,
|
||||||
|
ILocalizationService localizationService,
|
||||||
|
IMeasureService measureService,
|
||||||
|
IOrderProcessingService orderProcessingService,
|
||||||
|
IOrderReportService orderReportService,
|
||||||
|
IOrderService orderService,
|
||||||
|
IPaymentPluginManager paymentPluginManager,
|
||||||
|
IPaymentService paymentService,
|
||||||
|
IPictureService pictureService,
|
||||||
|
IPriceCalculationService priceCalculationService,
|
||||||
|
IPriceFormatter priceFormatter,
|
||||||
|
IProductAttributeService productAttributeService,
|
||||||
|
IProductService productService,
|
||||||
|
IReturnRequestService returnRequestService,
|
||||||
|
IRewardPointService rewardPointService,
|
||||||
|
ISettingService settingService,
|
||||||
|
IShipmentService shipmentService,
|
||||||
|
IShippingService shippingService,
|
||||||
|
IStateProvinceService stateProvinceService,
|
||||||
|
IStoreService storeService,
|
||||||
|
ITaxService taxService,
|
||||||
|
IUrlHelperFactory urlHelperFactory,
|
||||||
|
IVendorService vendorService,
|
||||||
|
IWorkContext workContext,
|
||||||
|
MeasureSettings measureSettings,
|
||||||
|
NopHttpClient nopHttpClient,
|
||||||
|
OrderSettings orderSettings,
|
||||||
|
ShippingSettings shippingSettings,
|
||||||
|
IUrlRecordService urlRecordService,
|
||||||
|
TaxSettings taxSettings
|
||||||
|
) : base(addressSettings,
|
||||||
|
catalogSettings,
|
||||||
|
currencySettings,
|
||||||
|
actionContextAccessor,
|
||||||
|
addressModelFactory,
|
||||||
|
addressService,
|
||||||
|
affiliateService,
|
||||||
|
baseAdminModelFactory,
|
||||||
|
countryService,
|
||||||
|
currencyService,
|
||||||
|
customerService,
|
||||||
|
dateTimeHelper,
|
||||||
|
discountService,
|
||||||
|
downloadService,
|
||||||
|
encryptionService,
|
||||||
|
giftCardService,
|
||||||
|
localizationService,
|
||||||
|
measureService,
|
||||||
|
orderProcessingService,
|
||||||
|
orderReportService,
|
||||||
|
orderService,
|
||||||
|
paymentPluginManager,
|
||||||
|
paymentService,
|
||||||
|
pictureService,
|
||||||
|
priceCalculationService,
|
||||||
|
priceFormatter,
|
||||||
|
productAttributeService,
|
||||||
|
productService,
|
||||||
|
returnRequestService,
|
||||||
|
rewardPointService,
|
||||||
|
settingService,
|
||||||
|
shipmentService,
|
||||||
|
shippingService,
|
||||||
|
stateProvinceService,
|
||||||
|
storeService,
|
||||||
|
taxService,
|
||||||
|
urlHelperFactory,
|
||||||
|
vendorService,
|
||||||
|
workContext,
|
||||||
|
measureSettings,
|
||||||
|
nopHttpClient,
|
||||||
|
orderSettings,
|
||||||
|
shippingSettings,
|
||||||
|
urlRecordService,
|
||||||
|
taxSettings
|
||||||
|
)
|
||||||
|
{
|
||||||
|
_orderMeasurementService = orderMeasurementService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override async Task<OrderSearchModel> PrepareOrderSearchModelAsync(OrderSearchModel searchModel)
|
||||||
|
{
|
||||||
|
// let base prepare default model first
|
||||||
|
var baseModel = await base.PrepareOrderSearchModelAsync(searchModel);
|
||||||
|
|
||||||
|
// create derived/extended instance
|
||||||
|
var extended = new OrderSearchModelExtended();
|
||||||
|
|
||||||
|
// copy all public instance properties from baseModel to extended
|
||||||
|
CopyModelHelper.CopyPublicProperties(baseModel, extended);
|
||||||
|
|
||||||
|
// try to obtain NeedsMeasurement from the incoming searchModel (if it's extended)
|
||||||
|
bool? needsMeasurement = null;
|
||||||
|
var prop = searchModel?.GetType().GetProperty("NeedsMeasurement", BindingFlags.Public | BindingFlags.Instance);
|
||||||
|
if (prop != null && prop.PropertyType == typeof(bool?))
|
||||||
|
{
|
||||||
|
needsMeasurement = (bool?)prop.GetValue(searchModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
extended.NeedsMeasurement = needsMeasurement;
|
||||||
|
|
||||||
|
// return the extended object (it's assignable to OrderSearchModel)
|
||||||
|
return extended;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override async Task<OrderListModel> PrepareOrderListModelAsync(OrderSearchModel searchModel)
|
||||||
|
{
|
||||||
|
// get the default model first
|
||||||
|
var baseModel = await base.PrepareOrderListModelAsync(searchModel);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// project the rows into your extended row type
|
||||||
|
var extendedRows = baseModel.Data.Select(async order => new OrderModelExtended
|
||||||
|
{
|
||||||
|
Id = order.Id,
|
||||||
|
CustomOrderNumber = order.CustomOrderNumber,
|
||||||
|
OrderStatus = order.OrderStatus,
|
||||||
|
PaymentStatus = order.PaymentStatus,
|
||||||
|
ShippingStatus = order.ShippingStatus,
|
||||||
|
OrderTotal = order.OrderTotal,
|
||||||
|
CreatedOn = order.CreatedOn,
|
||||||
|
|
||||||
|
// custom field
|
||||||
|
NeedsMeasurement = await ShouldMarkAsNeedsMeasurementAsync(order)
|
||||||
|
}).ToList();
|
||||||
|
|
||||||
|
// build a new OrderListModel but replace Data with the extended items
|
||||||
|
var model = new OrderListModel
|
||||||
|
{
|
||||||
|
Data = extendedRows.Cast<OrderModel>().ToList(), // still satisfies the grid
|
||||||
|
//Total = baseModel.Total
|
||||||
|
};
|
||||||
|
|
||||||
|
return model;
|
||||||
|
}
|
||||||
|
|
||||||
|
// example async custom logic
|
||||||
|
private async Task<bool> ShouldMarkAsNeedsMeasurementAsync(OrderModel order)
|
||||||
|
{
|
||||||
|
// TODO: your logic (e.g. check if order has products that need measuring)
|
||||||
|
if (order == null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
var fullOrder = await _orderService.GetOrderByIdAsync(order.Id);
|
||||||
|
if (fullOrder != null)
|
||||||
|
{
|
||||||
|
return await _orderMeasurementService.IsPendingMeasurementAsync(fullOrder);
|
||||||
|
}
|
||||||
|
return await Task.FromResult(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -39,6 +39,7 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Filters
|
||||||
|
|
||||||
if (order != null && await _orderMeasurementService.IsPendingMeasurementAsync(order))
|
if (order != null && await _orderMeasurementService.IsPendingMeasurementAsync(order))
|
||||||
{
|
{
|
||||||
|
order.OrderStatus = OrderStatus.Processing;
|
||||||
context.Result = new RedirectToRouteResult(new
|
context.Result = new RedirectToRouteResult(new
|
||||||
{
|
{
|
||||||
controller = "Checkout",
|
controller = "Checkout",
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Nop.Plugin.Misc.FruitBankPlugin.Helpers
|
||||||
|
{
|
||||||
|
public static class CopyModelHelper
|
||||||
|
{
|
||||||
|
public static void CopyPublicProperties<TSource, TDestination>(TSource src, TDestination dest)
|
||||||
|
{
|
||||||
|
if (src == null || dest == null) return;
|
||||||
|
|
||||||
|
var srcProps = typeof(TSource)
|
||||||
|
.GetProperties(BindingFlags.Public | BindingFlags.Instance)
|
||||||
|
.Where(p => p.CanRead);
|
||||||
|
|
||||||
|
foreach (var sp in srcProps)
|
||||||
|
{
|
||||||
|
var dp = typeof(TDestination).GetProperty(sp.Name, BindingFlags.Public | BindingFlags.Instance);
|
||||||
|
if (dp == null || !dp.CanWrite) continue;
|
||||||
|
dp.SetValue(dest, sp.GetValue(src));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -13,9 +13,14 @@ using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Nop.Core.Infrastructure;
|
using Nop.Core.Infrastructure;
|
||||||
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.Filters;
|
using Nop.Plugin.Misc.FruitBankPlugin.Filters;
|
||||||
|
using Nop.Plugin.Misc.FruitBankPlugin.Models;
|
||||||
using Nop.Plugin.Misc.FruitBankPlugin.Services;
|
using Nop.Plugin.Misc.FruitBankPlugin.Services;
|
||||||
using Nop.Services.Catalog;
|
using Nop.Services.Catalog;
|
||||||
|
using Nop.Web.Areas.Admin.Factories;
|
||||||
|
using Nop.Web.Areas.Admin.Models.Catalog;
|
||||||
|
using Nop.Web.Areas.Admin.Models.Orders;
|
||||||
using FruitBankDataController = Nop.Plugin.Misc.FruitBankPlugin.Controllers.FruitBankDataController;
|
using FruitBankDataController = Nop.Plugin.Misc.FruitBankPlugin.Controllers.FruitBankDataController;
|
||||||
|
|
||||||
namespace Nop.Plugin.Misc.FruitBankPlugin.Infrastructure;
|
namespace Nop.Plugin.Misc.FruitBankPlugin.Infrastructure;
|
||||||
|
|
@ -55,6 +60,10 @@ public class PluginNopStartup : INopStartup
|
||||||
services.AddScoped<PriceCalculationService, CustomPriceCalculationService>();
|
services.AddScoped<PriceCalculationService, CustomPriceCalculationService>();
|
||||||
services.AddScoped<IOrderMeasurementService, OrderMeasurementService>();
|
services.AddScoped<IOrderMeasurementService, OrderMeasurementService>();
|
||||||
services.AddScoped<PendingMeasurementCheckoutFilter>();
|
services.AddScoped<PendingMeasurementCheckoutFilter>();
|
||||||
|
services.AddScoped<OrderListModel, OrderListModelExtended>();
|
||||||
|
services.AddScoped<OrderModel, OrderModelExtended>();
|
||||||
|
services.AddScoped<OrderSearchModel, OrderSearchModelExtended>();
|
||||||
|
services.AddScoped<OrderModelFactory, CustomOrderModelFactory>();
|
||||||
services.AddControllersWithViews(options =>
|
services.AddControllersWithViews(options =>
|
||||||
{
|
{
|
||||||
options.Filters.AddService<PendingMeasurementCheckoutFilter>();
|
options.Filters.AddService<PendingMeasurementCheckoutFilter>();
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
using Nop.Web.Areas.Admin.Models.Orders;
|
||||||
|
|
||||||
|
namespace Nop.Plugin.Misc.FruitBankPlugin.Models
|
||||||
|
{
|
||||||
|
public partial record OrderListModelExtended : OrderListModel
|
||||||
|
{
|
||||||
|
public bool? NeedsMeasurement { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
using Nop.Web.Areas.Admin.Models.Orders;
|
||||||
|
|
||||||
|
namespace Nop.Plugin.Misc.FruitBankPlugin.Models
|
||||||
|
{
|
||||||
|
public partial record OrderModelExtended : OrderModel
|
||||||
|
{
|
||||||
|
public bool NeedsMeasurement { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
using Nop.Web.Areas.Admin.Models.Orders;
|
||||||
|
|
||||||
|
namespace Nop.Plugin.Misc.FruitBankPlugin.Models
|
||||||
|
{
|
||||||
|
public partial record OrderSearchModelExtended : OrderSearchModel
|
||||||
|
{
|
||||||
|
public bool? NeedsMeasurement { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -55,8 +55,6 @@
|
||||||
<Folder Include="Areas\Admin\Validators\" />
|
<Folder Include="Areas\Admin\Validators\" />
|
||||||
<Folder Include="Domains\Entities\" />
|
<Folder Include="Domains\Entities\" />
|
||||||
<Folder Include="Extensions\" />
|
<Folder Include="Extensions\" />
|
||||||
<Folder Include="Factories\" />
|
|
||||||
<Folder Include="Models\" />
|
|
||||||
<Folder Include="Validators\" />
|
<Folder Include="Validators\" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
|
@ -135,9 +133,18 @@
|
||||||
<None Update="Areas\Admin\Views\Configure\Configure.cshtml">
|
<None Update="Areas\Admin\Views\Configure\Configure.cshtml">
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
|
<None Update="Areas\Admin\Views\Order\Test.cshtml">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Update="Areas\Admin\Views\Order\List.cshtml">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
<None Update="Views\Checkout\PendingMeasurementWarning.cshtml">
|
<None Update="Views\Checkout\PendingMeasurementWarning.cshtml">
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
|
<None Update="Views\Admin\Order\List.cshtml">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
<None Update="Views\ProductAIListWidget.cshtml">
|
<None Update="Views\ProductAIListWidget.cshtml">
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,657 @@
|
||||||
|
@model OrderSearchModel
|
||||||
|
|
||||||
|
@inject IStoreService storeService
|
||||||
|
@using Nop.Services.Stores
|
||||||
|
|
||||||
|
@{
|
||||||
|
//page title
|
||||||
|
ViewBag.PageTitle = T("Admin.Orders").Text;
|
||||||
|
//active menu item (system name)
|
||||||
|
NopHtml.SetActiveMenuItemSystemName("Orders");
|
||||||
|
}
|
||||||
|
|
||||||
|
@{
|
||||||
|
const string hideSearchBlockAttributeName = "OrdersPage.HideSearchBlock";
|
||||||
|
var hideSearchBlock = await genericAttributeService.GetAttributeAsync<bool>(await workContext.GetCurrentCustomerAsync(), hideSearchBlockAttributeName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@if (Model.LicenseCheckModel.BlockPages != true)
|
||||||
|
{
|
||||||
|
<form asp-controller="Order" asp-action="List" method="post">
|
||||||
|
<div class="content-header clearfix">
|
||||||
|
<h1 class="float-left">
|
||||||
|
@T("Admin.Orders")
|
||||||
|
</h1>
|
||||||
|
<div class="float-right">
|
||||||
|
<div class="btn-group">
|
||||||
|
<button type="button" class="btn btn-success">
|
||||||
|
<i class="fas fa-download"></i>
|
||||||
|
@T("Admin.Common.Export")
|
||||||
|
</button>
|
||||||
|
<button type="button" class="btn btn-success dropdown-toggle dropdown-icon" data-toggle="dropdown" aria-expanded="false">
|
||||||
|
<span class="sr-only"> </span>
|
||||||
|
</button>
|
||||||
|
<ul class="dropdown-menu" role="menu">
|
||||||
|
<li class="dropdown-item">
|
||||||
|
<button asp-action="ExportXml" type="submit" name="exportxml-all">
|
||||||
|
<i class="far fa-file-code"></i>
|
||||||
|
@T("Admin.Common.ExportToXml.All")
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
<li class="dropdown-item">
|
||||||
|
<button type="button" id="exportxml-selected">
|
||||||
|
<i class="far fa-file-code"></i>
|
||||||
|
@T("Admin.Common.ExportToXml.Selected")
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
<li class="dropdown-divider"></li>
|
||||||
|
<li class="dropdown-item">
|
||||||
|
<button asp-action="ExportExcel" type="submit" name="exportexcel-all">
|
||||||
|
<i class="far fa-file-excel"></i>
|
||||||
|
@T("Admin.Common.ExportToExcel.All")
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
<li class="dropdown-item">
|
||||||
|
<button type="button" id="exportexcel-selected">
|
||||||
|
<i class="far fa-file-excel"></i>
|
||||||
|
@T("Admin.Common.ExportToExcel.Selected")
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<button type="button" name="importexcel" class="btn bg-olive" data-toggle="modal" data-target="#importexcel-window">
|
||||||
|
<i class="fas fa-upload"></i>
|
||||||
|
@T("Admin.Common.Import")
|
||||||
|
</button>
|
||||||
|
<div class="btn-group">
|
||||||
|
<button type="button" class="btn btn-info">
|
||||||
|
<i class="far fa-file-pdf"></i>
|
||||||
|
@T("Admin.Orders.PdfInvoices")
|
||||||
|
</button>
|
||||||
|
<button type="button" class="btn btn-info dropdown-toggle dropdown-icon" data-toggle="dropdown" aria-expanded="false">
|
||||||
|
<span class="sr-only"> </span>
|
||||||
|
</button>
|
||||||
|
<ul class="dropdown-menu" role="menu">
|
||||||
|
<li class="dropdown-item">
|
||||||
|
<button asp-action="PdfInvoice" type="submit" name="pdf-invoice-all">
|
||||||
|
@T("Admin.Orders.PdfInvoices.All")
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
<li class="dropdown-item">
|
||||||
|
<button type="button" id="pdf-invoice-selected">
|
||||||
|
@T("Admin.Orders.PdfInvoices.Selected")
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
@await Component.InvokeAsync(typeof(AdminWidgetViewComponent), new { widgetZone = AdminWidgetZones.OrderListButtons, additionalData = Model })
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<section class="content">
|
||||||
|
<div class="container-fluid">
|
||||||
|
<div class="form-horizontal">
|
||||||
|
<div class="cards-group">
|
||||||
|
<div class="card card-default card-search">
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="row search-row @(!hideSearchBlock ? "opened" : "")" data-hideAttribute="@hideSearchBlockAttributeName">
|
||||||
|
<div class="search-text">@T("Admin.Common.Search")</div>
|
||||||
|
<div class="icon-search"><i class="fas fa-magnifying-glass" aria-hidden="true"></i></div>
|
||||||
|
<div class="icon-collapse"><i class="far fa-angle-@(!hideSearchBlock ? "up" : "down")" aria-hidden="true"></i></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="search-body @(hideSearchBlock ? "closed" : "")">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-5">
|
||||||
|
<div class="form-group row">
|
||||||
|
<div class="col-md-4">
|
||||||
|
<nop-label asp-for="StartDate" />
|
||||||
|
</div>
|
||||||
|
<div class="col-md-8">
|
||||||
|
<nop-editor asp-for="StartDate" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row">
|
||||||
|
<div class="col-md-4">
|
||||||
|
<nop-label asp-for="EndDate" />
|
||||||
|
</div>
|
||||||
|
<div class="col-md-8">
|
||||||
|
<nop-editor asp-for="EndDate" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row" @(Model.AvailableWarehouses.SelectionIsNotPossible() ? Html.Raw("style=\"display:none\"") : null)>
|
||||||
|
<div class="col-md-4">
|
||||||
|
<nop-label asp-for="WarehouseId" />
|
||||||
|
</div>
|
||||||
|
<div class="col-md-8">
|
||||||
|
<nop-select asp-for="WarehouseId" asp-items="Model.AvailableWarehouses" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row">
|
||||||
|
<div class="col-md-4">
|
||||||
|
<nop-label asp-for="ProductId" />
|
||||||
|
</div>
|
||||||
|
<div class="col-md-8">
|
||||||
|
<input type="text" id="search-product-name" autocomplete="off" class="form-control" />
|
||||||
|
<span id="search-product-friendly-name"></span>
|
||||||
|
<button type="button" id="search-product-clear" class="btn bg-gray" style="display: none; margin-top: 5px;">@T("Admin.Common.Clear")</button>
|
||||||
|
<input asp-for="ProductId" autocomplete="off" style="display: none;" />
|
||||||
|
<script>
|
||||||
|
$(function() {
|
||||||
|
$('#search-product-name').autocomplete({
|
||||||
|
delay: 500,
|
||||||
|
minLength: 3,
|
||||||
|
source: '@Url.Action("SearchAutoComplete", "SearchComplete")',
|
||||||
|
select: function(event, ui) {
|
||||||
|
$('#@Html.IdFor(model => model.ProductId)').val(ui.item.productid);
|
||||||
|
$('#search-product-friendly-name').text(ui.item.label);
|
||||||
|
|
||||||
|
$('#search-product-clear').show();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//remove button
|
||||||
|
$('#search-product-clear').click(function() {
|
||||||
|
$('#@Html.IdFor(model => model.ProductId)').val('0');
|
||||||
|
$('#search-product-friendly-name').text('');
|
||||||
|
$('#search-product-clear').hide();
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row" @(Model.IsLoggedInAsVendor ? Html.Raw("style='display: none;'") : null)>
|
||||||
|
<div class="col-md-4">
|
||||||
|
<nop-label asp-for="OrderStatusIds" />
|
||||||
|
</div>
|
||||||
|
<div class="col-md-8">
|
||||||
|
<nop-select asp-for="OrderStatusIds" asp-items="Model.AvailableOrderStatuses" asp-multiple="true" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row">
|
||||||
|
<div class="col-md-4">
|
||||||
|
<nop-label asp-for="PaymentStatusIds" />
|
||||||
|
</div>
|
||||||
|
<div class="col-md-8">
|
||||||
|
<nop-select asp-for="PaymentStatusIds" asp-items="Model.AvailablePaymentStatuses" asp-multiple="true" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row" @(Model.IsLoggedInAsVendor ? Html.Raw("style='display: none;'") : null)>
|
||||||
|
<div class="col-md-4">
|
||||||
|
<nop-label asp-for="ShippingStatusIds" />
|
||||||
|
</div>
|
||||||
|
<div class="col-md-8">
|
||||||
|
<nop-select asp-for="ShippingStatusIds" asp-items="Model.AvailableShippingStatuses" asp-multiple="true" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-7">
|
||||||
|
<div class="form-group row" @(Model.HideStoresList ? Html.Raw("style=\"display:none\"") : null)>
|
||||||
|
<div class="col-md-4">
|
||||||
|
<nop-label asp-for="StoreId" />
|
||||||
|
</div>
|
||||||
|
<div class="col-md-8">
|
||||||
|
<nop-select asp-for="StoreId" asp-items="Model.AvailableStores" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row" @(Model.AvailableVendors.SelectionIsNotPossible() || Model.IsLoggedInAsVendor ? Html.Raw("style='display: none;'") : null)>
|
||||||
|
<div class="col-md-4">
|
||||||
|
<nop-label asp-for="VendorId" />
|
||||||
|
</div>
|
||||||
|
<div class="col-md-8">
|
||||||
|
<nop-select asp-for="VendorId" asp-items="Model.AvailableVendors" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@if (Model.BillingPhoneEnabled)
|
||||||
|
{
|
||||||
|
<div class="form-group row">
|
||||||
|
<div class="col-md-4">
|
||||||
|
<nop-label asp-for="BillingPhone" />
|
||||||
|
</div>
|
||||||
|
<div class="col-md-8">
|
||||||
|
<nop-editor asp-for="BillingPhone" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
<div class="form-group row">
|
||||||
|
<div class="col-md-4">
|
||||||
|
<nop-label asp-for="BillingEmail" />
|
||||||
|
</div>
|
||||||
|
<div class="col-md-8">
|
||||||
|
<nop-editor asp-for="BillingEmail" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row">
|
||||||
|
<div class="col-md-4">
|
||||||
|
<nop-label asp-for="BillingLastName" />
|
||||||
|
</div>
|
||||||
|
<div class="col-md-8">
|
||||||
|
<nop-editor asp-for="BillingLastName" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row" @(Model.AvailableCountries.SelectionIsNotPossible() ? Html.Raw("style=\"display:none\"") : null)>
|
||||||
|
<div class="col-md-4">
|
||||||
|
<nop-label asp-for="BillingCountryId" />
|
||||||
|
</div>
|
||||||
|
<div class="col-md-8">
|
||||||
|
<nop-select asp-for="BillingCountryId" asp-items="Model.AvailableCountries" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row" @(Model.AvailablePaymentMethods.SelectionIsNotPossible() || Model.IsLoggedInAsVendor ? Html.Raw("style='display: none;'") : null)>
|
||||||
|
<div class="col-md-4">
|
||||||
|
<nop-label asp-for="PaymentMethodSystemName" />
|
||||||
|
</div>
|
||||||
|
<div class="col-md-8">
|
||||||
|
<nop-select asp-for="PaymentMethodSystemName" asp-items="Model.AvailablePaymentMethods" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row">
|
||||||
|
<div class="col-md-4">
|
||||||
|
<nop-label asp-for="OrderNotes" />
|
||||||
|
</div>
|
||||||
|
<div class="col-md-8">
|
||||||
|
<nop-editor asp-for="OrderNotes" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row">
|
||||||
|
<div class="col-md-4">
|
||||||
|
<nop-label asp-for="GoDirectlyToCustomOrderNumber" />
|
||||||
|
</div>
|
||||||
|
<div class="col-md-8">
|
||||||
|
<div class="input-group input-group-short">
|
||||||
|
<nop-editor asp-for="GoDirectlyToCustomOrderNumber" />
|
||||||
|
<span class="input-group-append">
|
||||||
|
<button type="submit" id="go-to-order-by-number" name="go-to-order-by-number" class="btn btn-info btn-flat">
|
||||||
|
@T("Admin.Common.Go")
|
||||||
|
</button>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="text-center col-12">
|
||||||
|
<button type="button" id="search-orders" class="btn btn-primary btn-search">
|
||||||
|
<i class="fas fa-magnifying-glass"></i>
|
||||||
|
@T("Admin.Common.Search")
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card card-default">
|
||||||
|
<h1>
|
||||||
|
khfdsjklfkl fklsh fjsklhfjskl fhsjklhf sjklhfdsklhf djkfldsh fjklsdjkl
|
||||||
|
</h1>
|
||||||
|
<div class="card-body">
|
||||||
|
<nop-doc-reference asp-string-resource="@T("Admin.Documentation.Reference.Orders", Docs.Orders + Utm.OnAdmin)" />
|
||||||
|
|
||||||
|
@{
|
||||||
|
var gridModel = new DataTablesModel
|
||||||
|
{
|
||||||
|
Name = "orders-grid",
|
||||||
|
UrlRead = new DataUrl("OrderList", "Order", null),
|
||||||
|
SearchButtonId = "search-orders",
|
||||||
|
Length = Model.PageSize,
|
||||||
|
LengthMenu = Model.AvailablePageSizes,
|
||||||
|
FooterCallback = !Model.IsLoggedInAsVendor ? "ordersfootercallback" : null,
|
||||||
|
FooterColumns = !Model.IsLoggedInAsVendor ? 10 : 0,
|
||||||
|
Filters = new List<FilterParameter>
|
||||||
|
{
|
||||||
|
new FilterParameter(nameof(Model.StartDate), typeof(DateTime?)),
|
||||||
|
new FilterParameter(nameof(Model.EndDate), typeof(DateTime?)),
|
||||||
|
new FilterParameter(nameof(Model.OrderStatusIds)),
|
||||||
|
new FilterParameter(nameof(Model.PaymentStatusIds)),
|
||||||
|
new FilterParameter(nameof(Model.ShippingStatusIds)),
|
||||||
|
new FilterParameter(nameof(Model.StoreId)),
|
||||||
|
new FilterParameter(nameof(Model.VendorId)),
|
||||||
|
new FilterParameter(nameof(Model.WarehouseId)),
|
||||||
|
new FilterParameter(nameof(Model.BillingEmail)),
|
||||||
|
new FilterParameter(nameof(Model.BillingPhone)),
|
||||||
|
new FilterParameter(nameof(Model.BillingLastName)),
|
||||||
|
new FilterParameter(nameof(Model.BillingCountryId)),
|
||||||
|
new FilterParameter(nameof(Model.PaymentMethodSystemName)),
|
||||||
|
new FilterParameter(nameof(Model.ProductId)),
|
||||||
|
new FilterParameter(nameof(Model.OrderNotes))
|
||||||
|
}
|
||||||
|
};
|
||||||
|
gridModel.ColumnCollection = new List<ColumnProperty>
|
||||||
|
{
|
||||||
|
new ColumnProperty(nameof(OrderModel.Id))
|
||||||
|
{
|
||||||
|
IsMasterCheckBox = true,
|
||||||
|
Render = new RenderCheckBox("checkbox_orders"),
|
||||||
|
ClassName = NopColumnClassDefaults.CenterAll,
|
||||||
|
Width = "50"
|
||||||
|
},
|
||||||
|
new ColumnProperty(nameof(OrderModel.CustomOrderNumber))
|
||||||
|
{
|
||||||
|
Title = T("Admin.Orders.Fields.CustomOrderNumber").Text,
|
||||||
|
Width = "80"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
gridModel.ColumnCollection.Add(new ColumnProperty(nameof(OrderModelExtended.NeedsMeasurement))
|
||||||
|
{
|
||||||
|
Title = "Needs Measurement",
|
||||||
|
Width = "100",
|
||||||
|
Render = new RenderCustom("renderColumnNeedsMeasurement"),
|
||||||
|
ClassName = NopColumnClassDefaults.CenterAll
|
||||||
|
});
|
||||||
|
|
||||||
|
//a vendor does not have access to this functionality
|
||||||
|
if (!Model.IsLoggedInAsVendor)
|
||||||
|
{
|
||||||
|
gridModel.ColumnCollection.Add(new ColumnProperty(nameof(OrderModel.OrderStatus))
|
||||||
|
{
|
||||||
|
Title = T("Admin.Orders.Fields.OrderStatus").Text,
|
||||||
|
Width = "100",
|
||||||
|
Render = new RenderCustom("renderColumnOrderStatus")
|
||||||
|
});
|
||||||
|
}
|
||||||
|
gridModel.ColumnCollection.Add(new ColumnProperty(nameof(OrderModel.PaymentStatus))
|
||||||
|
{
|
||||||
|
Title = T("Admin.Orders.Fields.PaymentStatus").Text,
|
||||||
|
Width = "150"
|
||||||
|
});
|
||||||
|
//a vendor does not have access to this functionality
|
||||||
|
if (!Model.IsLoggedInAsVendor)
|
||||||
|
{
|
||||||
|
gridModel.ColumnCollection.Add(new ColumnProperty(nameof(OrderModel.ShippingStatus))
|
||||||
|
{
|
||||||
|
Title = T("Admin.Orders.Fields.ShippingStatus").Text,
|
||||||
|
Width = "150"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
gridModel.ColumnCollection.Add(new ColumnProperty(nameof(OrderModel.CustomerEmail))
|
||||||
|
{
|
||||||
|
Title = T("Admin.Orders.Fields.Customer").Text,
|
||||||
|
Render = new RenderCustom("renderColumnCustomer")
|
||||||
|
});
|
||||||
|
gridModel.ColumnCollection.Add(new ColumnProperty(nameof(OrderModel.StoreName))
|
||||||
|
{
|
||||||
|
Title = T("Admin.Orders.Fields.Store").Text,
|
||||||
|
Width = "100",
|
||||||
|
Visible = (await storeService.GetAllStoresAsync()).Count > 1
|
||||||
|
});
|
||||||
|
gridModel.ColumnCollection.Add(new ColumnProperty(nameof(OrderModel.CreatedOn))
|
||||||
|
{
|
||||||
|
Title = T("Admin.Orders.Fields.CreatedOn").Text,
|
||||||
|
Width = "120",
|
||||||
|
Render = new RenderDate()
|
||||||
|
});
|
||||||
|
//a vendor does not have access to this functionality
|
||||||
|
if (!Model.IsLoggedInAsVendor)
|
||||||
|
{
|
||||||
|
gridModel.ColumnCollection.Add(new ColumnProperty(nameof(OrderModel.OrderTotal))
|
||||||
|
{
|
||||||
|
Title = T("Admin.Orders.Fields.OrderTotal").Text,
|
||||||
|
Width = "100",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
gridModel.ColumnCollection.Add(new ColumnProperty(nameof(OrderModel.Id))
|
||||||
|
{
|
||||||
|
Title = T("Admin.Common.View").Text,
|
||||||
|
Width = "50",
|
||||||
|
ClassName = NopColumnClassDefaults.Button,
|
||||||
|
Render = new RenderButtonView(new DataUrl("~/Admin/Order/Edit"))
|
||||||
|
});
|
||||||
|
var orderSummaryColumnNumber = 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
@await Html.PartialAsync("Table", gridModel)
|
||||||
|
|
||||||
|
<script>
|
||||||
|
function renderColumnOrderStatus(data, type, row, meta) {
|
||||||
|
var color;
|
||||||
|
switch (row.OrderStatusId) {
|
||||||
|
case 10:
|
||||||
|
color = 'yellow';
|
||||||
|
break;
|
||||||
|
case 20:
|
||||||
|
color = 'blue';
|
||||||
|
break;
|
||||||
|
case 30:
|
||||||
|
color = 'green';
|
||||||
|
break;
|
||||||
|
case 40:
|
||||||
|
color = 'red';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return '<span class="grid-report-item ' + color + '">' + data + '</span >';
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderColumnCustomer(data, type, row, meta) {
|
||||||
|
var link = '@Url.Content("~/Admin/Customer/Edit/")' + row.CustomerId;
|
||||||
|
var textRenderer = $.fn.dataTable.render.text().display;
|
||||||
|
return `${textRenderer(row.CustomerFullName)} <br /><a href="${link}">${data}</a > `;
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderColumnNeedsMeasurement(data, type, row, meta) {
|
||||||
|
if(data === true) {
|
||||||
|
return '<span class="badge badge-warning">Yes</span>';
|
||||||
|
}
|
||||||
|
return '<span class="badge badge-secondary">No</span>';
|
||||||
|
}
|
||||||
|
|
||||||
|
$(function() {
|
||||||
|
$("#@Html.IdFor(model => model.GoDirectlyToCustomOrderNumber)").keydown(
|
||||||
|
function(event) {
|
||||||
|
if (event.keyCode === 13) {
|
||||||
|
$("#go-to-order-by-number").trigger("click");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
function ordersfootercallback(tfoot, data, start, end, display) {
|
||||||
|
//update order totals summary
|
||||||
|
var postData = {
|
||||||
|
StartDate: $('#@Html.IdFor(model => model.StartDate)').val(),
|
||||||
|
EndDate: $('#@Html.IdFor(model => model.EndDate)').val(),
|
||||||
|
OrderStatusIds: $('#@Html.IdFor(model => model.OrderStatusIds)').val(),
|
||||||
|
PaymentStatusIds: $('#@Html.IdFor(model => model.PaymentStatusIds)').val(),
|
||||||
|
ShippingStatusIds: $('#@Html.IdFor(model => model.ShippingStatusIds)').val(),
|
||||||
|
StoreId: $('#@Html.IdFor(model => model.StoreId)').val(),
|
||||||
|
VendorId: $('#@Html.IdFor(model => model.VendorId)').val(),
|
||||||
|
WarehouseId: $('#@Html.IdFor(model => model.WarehouseId)').val(),
|
||||||
|
BillingEmail: $('#@Html.IdFor(model => model.BillingEmail)').val(),
|
||||||
|
BillingPhone: $('#@Html.IdFor(model => model.BillingPhone)').val(),
|
||||||
|
BillingLastName: $('#@Html.IdFor(model => model.BillingLastName)').val(),
|
||||||
|
BillingCountryId: $('#@Html.IdFor(model => model.BillingCountryId)').val(),
|
||||||
|
PaymentMethodSystemName: $('#@Html.IdFor(model => model.PaymentMethodSystemName)').val(),
|
||||||
|
ProductId: $('#@Html.IdFor(model => model.ProductId)').val(),
|
||||||
|
OrderNotes: $('#@Html.IdFor(model => model.OrderNotes)').val()
|
||||||
|
};
|
||||||
|
addAntiForgeryToken(postData);
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
cache: false,
|
||||||
|
type: "POST",
|
||||||
|
url: "@(Url.Action("ReportAggregates", "Order"))",
|
||||||
|
data: postData,
|
||||||
|
success: function (data, textStatus, jqXHR) {
|
||||||
|
if (data) {
|
||||||
|
for (var key in data) {
|
||||||
|
var reportSummary = '<div><strong>@T("Admin.Orders.Report.Summary").Text</strong></div>' +
|
||||||
|
'<div>@T("Admin.Orders.Report.Profit").Text <span>' + data['AggregatorProfit'] +'</span></div>' +
|
||||||
|
'<div>@T("Admin.Orders.Report.Shipping").Text <span>' + data['AggregatorShipping'] + '</span></div>' +
|
||||||
|
'<div>@T("Admin.Orders.Report.Tax").Text <span>' + data['AggregatorTax'] + '</span></div>' +
|
||||||
|
'<div>@T("Admin.Orders.Report.Total").Text <span>' + data['AggregatorTotal'] + '</span></div>'
|
||||||
|
var orderTotalsColumn = $('#orders-grid').DataTable().column(@(orderSummaryColumnNumber));
|
||||||
|
$(orderTotalsColumn.footer()).html(reportSummary);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</form>
|
||||||
|
}
|
||||||
|
|
||||||
|
<script>
|
||||||
|
$(function() {
|
||||||
|
var displayModal = @((Model.LicenseCheckModel.DisplayWarning == true || Model.LicenseCheckModel?.BlockPages == true).ToString().ToLower());
|
||||||
|
if (displayModal){
|
||||||
|
$('#license-window').modal({
|
||||||
|
backdrop: 'static',
|
||||||
|
keyboard: false
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#license-window').on('shown.bs.modal', function (event) {
|
||||||
|
var modalCloseEl = $(this).find('button.close');
|
||||||
|
var closeTextEl = $('span', modalCloseEl);
|
||||||
|
|
||||||
|
var startFrom = 5;
|
||||||
|
closeTextEl.text(startFrom);
|
||||||
|
|
||||||
|
const timer = setInterval(function() {
|
||||||
|
if (startFrom-- > 0)
|
||||||
|
closeTextEl.text(startFrom);
|
||||||
|
}, 1000);
|
||||||
|
|
||||||
|
setTimeout(function() {
|
||||||
|
closeTextEl.html('×');
|
||||||
|
modalCloseEl.on('click', function() {
|
||||||
|
$('#license-window').modal('hide')
|
||||||
|
});
|
||||||
|
clearInterval(timer);
|
||||||
|
}, startFrom*1000);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<div id="license-window" class="modal fade" tabindex="-1" role="dialog">
|
||||||
|
<div class="modal-dialog" role="document">
|
||||||
|
<div class="modal-content">
|
||||||
|
@Html.Raw(Model.LicenseCheckModel?.WarningText)
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@*export selected (XML). We don't use GET approach because it's limited to 2K-4K chars and won't work for large number of entities*@
|
||||||
|
<form asp-controller="Order" asp-action="ExportXmlSelected" method="post" id="export-xml-selected-form">
|
||||||
|
<input type="hidden" id="selectedIds" name="selectedIds" value="" />
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
$(function() {
|
||||||
|
$('#exportxml-selected').click(function (e) {
|
||||||
|
e.preventDefault();
|
||||||
|
var ids = selectedIds.join(",");
|
||||||
|
if (!ids) {
|
||||||
|
$('#exportXmlSelected-info').text("@T("Admin.Orders.NoOrders")");
|
||||||
|
$("#exportXmlSelected").trigger("click");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$('#export-xml-selected-form #selectedIds').val(ids);
|
||||||
|
$('#export-xml-selected-form').submit();
|
||||||
|
updateTable('#orders-grid');
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<nop-alert asp-alert-id="exportXmlSelected" />
|
||||||
|
|
||||||
|
@*export selected (Excel). We don't use GET approach because it's limited to 2K-4K chars and won't work for large number of entities*@
|
||||||
|
<form asp-controller="Order" asp-action="ExportExcelSelected" method="post" id="export-excel-selected-form">
|
||||||
|
<input type="hidden" id="selectedIds" name="selectedIds" value="" />
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
$(function() {
|
||||||
|
$('#exportexcel-selected').click(function (e) {
|
||||||
|
e.preventDefault();
|
||||||
|
var ids = selectedIds.join(",");
|
||||||
|
if (!ids) {
|
||||||
|
$('#exportExcelSelected-info').text("@T("Admin.Orders.NoOrders")");
|
||||||
|
$("#exportExcelSelected").trigger("click");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$('#export-excel-selected-form #selectedIds').val(ids);
|
||||||
|
$('#export-excel-selected-form').submit();
|
||||||
|
updateTable('#orders-grid');
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<nop-alert asp-alert-id="exportExcelSelected" />
|
||||||
|
|
||||||
|
@*Print packaging slips selected (XML). We don't use GET approach because it's limited to 2K-4K chars and won't work for large number of entities*@
|
||||||
|
<form asp-controller="Order" asp-action="PdfInvoiceSelected" method="post" id="pdf-invoice-selected-form">
|
||||||
|
<input type="hidden" id="selectedIds" name="selectedIds" value="" />
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
$(function() {
|
||||||
|
$('#pdf-invoice-selected').click(function (e) {
|
||||||
|
e.preventDefault();
|
||||||
|
var ids = selectedIds.join(",");
|
||||||
|
if (!ids) {
|
||||||
|
$('#pdfInvoiceSelected-info').text("@T("Admin.Orders.NoOrders")");
|
||||||
|
$("#pdfInvoiceSelected").trigger("click");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$('#pdf-invoice-selected-form #selectedIds').val(ids);
|
||||||
|
$('#pdf-invoice-selected-form').submit();
|
||||||
|
updateTable('#orders-grid');
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<nop-alert asp-alert-id="pdfInvoiceSelected" />
|
||||||
|
|
||||||
|
@*import orders form*@
|
||||||
|
<div id="importexcel-window" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="importexcel-window-title">
|
||||||
|
<div class="modal-dialog">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h4 class="modal-title" id="importexcel-window-title">@T("Admin.Common.ImportFromExcel")</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="ImportFromXlsx" method="post" enctype="multipart/form-data">
|
||||||
|
<div class="form-horizontal">
|
||||||
|
<div class="modal-body">
|
||||||
|
<ul class="common-list">
|
||||||
|
<li>
|
||||||
|
<em>@T("Admin.Orders.List.ImportFromExcelTip")</em>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<em>@T("Admin.Common.ImportFromExcel.ManyRecordsWarning")</em>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<div class="form-group row">
|
||||||
|
<div class="col-md-2">
|
||||||
|
<div class="label-wrapper">
|
||||||
|
<label class="col-form-label">
|
||||||
|
@T("Admin.Common.ExcelFile")
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-10">
|
||||||
|
<input type="file" id="importexcelfile" name="importexcelfile" class="form-control" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="submit" class="btn btn-primary">
|
||||||
|
@T("Admin.Common.ImportFromExcel")
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
Loading…
Reference in New Issue