<style type="text/css">
row-label Price .container {
width: 85 !important;
}
.addStockCodeInput {
margin: 20px 0;
}
.rowClass1 {
padding: 0 5px;
display: inline-block;
}
.field-label {
display: inline-block;
}
.field-value {
display: inline-block;
padding: 10px;
font-weight: bold;
}
tr.dx-row.dx-header-row {
font-weight: 700;
color: #000;
font-size:14px;
}
.listHeader {
padding: 5px;
display: inline-block;
font-weight: 700;
font-size: 14px;
}
.listHeader.Price {
justify-self: end;
text-align: right;
}
/*REVIEW */
.listHeader.show-stock {
justify-self: center;
text-align: right;
}
.row.qoeRows {
margin-bottom: 0;
}
.listData {
padding: 5px;
display: inline-block;
white-space: normal;
}
.cartListHeader {
/*REVIEW visibility: hidden */
visibility: hidden;
background-color: rgb(187, 208, 236);
display: grid;
grid-template-columns: repeat(2, 1fr) 3fr repeat(4, 1fr) 3fr 1fr;
grid-gap: 10px;
align-items: end;
}
.details {
display: grid;
grid-template-columns: repeat(2, 1fr) 3fr repeat(4, 1fr) 3fr 1fr;
grid-gap: 10px;
align-items: center;
}
#cartList .dx-list-item-content {
padding: 10px 10px 0;
}
.dx-item.dx-list-item {
border: 1px solid #e1e1e1;
margin-bottom: 9px;
}
.dx-item.dx-list-item:nth-child(even) {
background: #f6f6f6;
}
.btnClass {
width: 320px;
}
.dx-button-has-text .dx-button-content,
.dx-button.dx-button-default {
padding: 5px;
top: -2px;
position: relative;
}
.listData.btnWrapper.dx-button {
margin: 0 5px;
max-height: 40px;
height;
}
.listData.OHQ {
display: none;
}
.dx-list-item-after-bag.dx-list-static-delete-button-container {
/* position: fixed;*/
}
.dx-list-static-delete-button,
.dx-list-switchable-delete-button {
position: relative;
top: 15px;
right: 25px;
}
.dx-numberbox.dx-texteditor.dx-numberbox-spin,
.dx-texteditor-input {
/*width: auto !important;*/
max-width: 90px;
padding: 0 3px 0;
height: 40px;
}
.dx-autocomplete .dx-texteditor-input {
max-width: 200px;
}
div#goToCartBtn {
width:fit-content
min-width: 90px;
margin: 25px 0;
}
div#goToCartBtn .dx-button-content {
padding: 5px 10px;
}
.qtyWrapper {
display: grid;
grid-template-columns: 2fr 1fr;
min-width: 120px;
align-items: center;
}
.warehouseDetail {
justify-content: flex-start;
padding: 0 15px;
}
.warehouse-text {
/* font-weight: bold; */
color: crimson;
}
/* Image */
.listData.image {
padding: 0;
text-align: center;
}
.image img {
max-height: 70px;
width: auto;
}
.listData.deleteBtn {
background-color: transparent !important;
/*background-image: url(/Ecommerce/Images/close.png);*/
background-size: 40px;
}
.listData.deleteBtn:hover {
background-color: transparent !important;
/*background-image: url(/Ecommerce/Images/close-over.png);*/
background-size: 40px;
}
/* Pricing */
.listHeader.totalPrice,
.listData.totalPrice,
.listData.itemDescription {
font-weight: 700;
}
/* Fee ROWS */
.FeeRowWrapper {
min-height: 30px;
background: #d9d9d9;
}
.FeeRow {
display: grid;
grid-template-columns: repeat(2, 1fr) 3fr repeat(4, 1fr) 3fr 1fr;
background: #d9d9d9;
grid-gap: 10px;
align-items: baseline;
}
.warehouseFeeRow {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(200px, 220px));
background: #d9d9d9;
}
/*REVIEW Original css */
/* .row-warehouse-SelectLink {
grid-column: span 2;
justify-self: end;
} */
.row-warehouse-SelectLink {
grid-column: span 1;
justify-self: start;
padding-left: 10px;
}
/* REVIEW needed padding */
.warehouse-link {
padding: 5px;
display: inline-block;
white-space: normal;
}
.FeeRow > div,
.warehouseFeeRow > div {
/* padding: 5px 0; */
align-items: baseline;
}
.fee-row-img {
justify-self: center;
}
.fee-row-img img {
max-width: 20px !important;
}
.fee-row-TotalPrice2 {
justify-self: end;
font-weight: 700;
align-items: baseline;
}
.listData.btnWrapper.showStockBtn.dx-button.dx-button-default.dx-button-mode-contained.dx-widget.dx-button-has-text.dx-state-focused,
/* #clearFormBtn.dx-state-focused, */
#addToCartBtn.dx-state-focused,
.listData.btnWrapper.deleteBtn.dx-button.dx-button-default.dx-button-mode-contained.dx-widget.dx-state-focused {
border-color: #337ab7;
}
@media (min-width: 328px) {
.cartListHeader {
display: none;
}
.details {
display: grid;
grid-template-columns: 2fr 2fr 4fr 2fr;
grid-gap: 10px;
padding: 5px;
}
.fee-row-img {
justify-self: start;
}
.listData.showStockBtn {
grid-column: auto / span 3;
}
.listData.OHQ {
grid-column: auto / span 3;
}
.listData.deleteBtn {
grid-column: auto / span 1;
justify-self: end;
}
.listData.defaultPrice:before {
display: none;
content: 'Default Price: ';
font-weight: 700;
}
.listData.customerPrice:before {
/* display: none; */
content: 'Customer Price: ';
font-weight: 700;
}
.listData.discountPrice:before {
display: none;
content: 'Discount Price: ';
font-weight: 700;
}
.listData.webPrice:before {
/* display: none; */
content: 'Web Price: ';
font-weight: 700;
}
.listData.totalPrice:before {
/* display: none; */
content: 'Total Price: ';
font-weight: 700;
}
.listData.btnWrapper.deleteBtn.dx-button {
margin-bottom: 15px;
}
.FeeRow {
grid-template-columns: repeat(2, 1fr) 2fr repeat(4, 1fr) 1fr 1fr;
}
.FeeRow .row-label {
grid-column: span 7;
white-space: normal;
}
/* REVIEW noved spacer two to the end of fee row??*/
.spacerTwo {
display: none;
/* background-color: red; */
}
/*REVIEW Original css */
/* .row-warehouse-SelectLink {
grid-column: span 6;
justify-self: end;
} */
.row-warehouse-SelectLink {
grid-column: span 1;
justify-self: start;
}
/* REVIEW needed padding */
.warehouse-link {
padding: 5px;
display: inline-block;
white-space: normal;
}
}
@media (min-width: 1020px) {
.cartListHeader {
display: grid;
}
.details {
display: grid;
grid-template-columns: repeat(2, 1fr) 3fr repeat(4, 1fr) 3fr 1fr;
grid-gap: 10px;
padding: 0px 10px;
}
.fee-row-img {
justify-self: center;
}
.listData.defaultPrice {
grid-column: auto;
justify-self: end;
}
.listData.customerPrice {
grid-column: auto;
justify-self: end;
}
.listData.discountPrice {
grid-column: auto;
justify-self: end;
}
.listData.webPrice {
grid-column: auto;
justify-self: end;
}
.listData.totalPrice {
grid-column: auto;
justify-self: end;
}
.listData.showStockBtn {
grid-column: auto;
justify-self: center;
}
.listData.OHQ {
grid-column: auto;
}
.listData.deleteBtn {
grid-column: auto;
justify-self: end;
}
.listData.defaultPrice:before {
display: none;
}
.listData.customerPrice:before {
display: none;
}
.listData.discountPrice:before {
display: none;
}
.listData.webPrice:before {
display: none;
}
.listData.totalPrice:before {
display: none;
}
.listData.btnWrapper.deleteBtn.dx-button {
margin-bottom: 0px;
}
.FeeRow {
grid-template-columns: repeat(2, 1fr) 3fr repeat(4, 1fr) 3fr 1fr;
}
/*REVIEW Original code
.FeeRow .row-label {
grid-column: span 2;
} */
.FeeRow .row-label {
grid-column: span 1;
}
/*REVIEW Original code
.row-warehouse-SelectLink {
grid-column: span2;
}*/
.row-warehouse-SelectLink {
grid-column: span 1;
}
/* REVIEW needed padding */
.warehouse-link {
padding: 5px;
display: inline-block;
white-space: normal;
}
}
/* START styles inported from WarehouseShipFrom_Display */
.outer > * {
}
.data {
font-weight: bold;
padding-right: 5px;
padding-left: 5px;
}
.listLine {
padding: 5px 0px;
}
.dx-popup-wrapper > .dx-overlay-content {
padding: 15px;
}
.dx-popup-content .outer {
margin-bottom: 20px;
display: grid;
grid-template-columns: 1fr 1fr;
}
.popUpTitle {
font-weight: bold;
padding-right: 10px;
padding-left: 10px;
font-size: 1.3em;
}
div#simpleList {
font-size: 1.2em;
}
#simpleList .dx-list-item-selected {
font-weight: 700;
}
.warehouseList {
display: grid;
/* justify-content: start; */
grid-template-columns: 1fr 3fr 1fr 1fr;
justify-items: start;
}
.warehouseBox {
margin-top: 15px;
display: inline-block;
}
.warehouseBox .data-row.outer {
margin-right: -15px;
}
.row-warehouse-SeviceFee.data {
margin-left: auto;
}
.warehouseCode.listLine {
}
.warehouseDesc.listLine {
}
.warehouseRank.listLine {
}
.warehouseFee.listLine {
margin-left: auto;
text-align: right;
padding: 5px 0px
}
div#whLink:before {
}
/* REVIEW Original css */
/* div#whLink {
display: block;
font-weight: 700;
} */
/* span#whLink {
display: inline-flex;
justify-self: end;
font-weight: 700;
} */
.btnholder {
float: right;
justify-self: end;
}
.btnholder button {
background-color: #657680;
color: #fff;
padding: 8px 20px;
border-radius: 7px;
border-width: 0;
}
.btnholder button:hover {
background-color: #000;
}
.warehouseBox .dx-popup-content {
min-height: 200px;
}
/* END styles inported from WarehouseShipFrom_Display */
/* QSTARINT CSS moved from bottom */
.addStockCodeInput {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
gap: 15px;
}
#skuNumber {
order: 1;
grid-column: auto / span 3;
}
/* #clearFormBtn {
order: 2;
} */
/* #clearFormBtn, */
.showStockBtn.dx-button-mode-contained.dx-button-default {
color: #000000;
font: 12px Tahoma, Geneva, sans-serif;
border: 1px solid #7F7F7F;
background: #E0DFDF url(/ECommerce/DXR.axd?r=1_77-Me8wi) repeat-x top;
padding: 1px;
}
/*
#clearFormBtn:hover, */
.showStockBtn.dx-button-mode-contained.dx-button-default:hover {
color: #000000;
background: #F2F2F2 url('/ECommerce/DXR.axd?r=1_78-Me8wi') repeat-x top;
border: 1px solid #606060;
}
#skuQty {
order: 3;
}
#addToCartBtn {
order: 4;
}
.dx-button-mode-contained.dx-button-default {
background-color: #657680;
border-color: transparent;
color: #fff;
}
.dx-button-mode-contained.dx-button-default.dx-state-hover {
background-color: #000;
}
.dx-button-mode-contained.dx-button-default.dx-state-focused {
background-color: #657680;
border-color: #337ab7;
color: #fff
}
.cartListHeader {
background-color: #d9d9d9;
/* display: none; */
}
/* REVIEW original css */
/* div#whLink {
display: grid;
font-weight: 700;
margin-right: 20px;
} */
/* span#whLink {
display: inline-flex;
justify-self: end;
padding-left: 10%;
/* display: grid;
font-weight: 700;
margin-right: 20px;
font-weight: 700;
} */
.dx-radiobutton-icon-checked .dx-radiobutton-icon-dot {
background: #013CA6;
}
.One,
.Three,
.spacerTwo,
.spacerThree {
display: none;
}
</style>
<div class="quickOrderWrapper">
<!--Headder-->
<div id="Main_Title">
<h3>
Quick Order Entry
</h3>
<div class="infoStatement">
Quickly add items directly to your cart by entering stock codes below.
</div>
</div>
<!--Subtotal-->
<div class="subTotalDisplay">
<div class="field-label">
Subtotal:
</div>
<div class="field-value" id="subTotal">
</div>
</div>
<!--Add stockCode to Cart-->
<div class="addStockCodeInput">
<div class="rowClass1" id="skuQty">
</div>
<div class="rowClass1" id="skuNumber">
</div>
<div class="rowClass1" id="addToCartBtn">
</div>
</div>
</div>
<!-- Header for DX list control -->
<div class="cartListHeader">
<div class="listHeader">
</div>
<div id="stockCodeColumnHeader" class="listHeader"></div>
<div id="DescriptionColumnHeader" class="listHeader"></div>
<div class="qtyWrapper">
<div id="QuantityColumnHeader" class="listHeader"></div>
<!-- spacer for UOM -->
<div class="listHeader"></div>
</div>
<!-- REVIEW -->
<div class="listHeader Price One defaultPrice">
Default Price
</div>
<div class="listHeader Price Two customerPrice">
Customer Price
</div>
<div class="listHeader Price Three discountPrice">
Discount Price
</div>
<div class="listHeader Price Four WebPrice">
Web Price
</div>
<div id="ExtPriceColumnHeader" class="listHeader Price totalPrice"></div>
<div id="OnHandQuantityColumnHeader" class="listHeader show-stock"></div>
</div>
<div id="cartList">
</div>
<div id="goToCartBtn">
</div>
<!-- For popup?? -->
<div class="warehouseBox">
</div>
<div id="popupContainerView">
</div>
</div>
<script>
// '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
// ' Base Widget: Cart_QuickOrder.html
// '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
// ' (c) 2022 by Dovetail Internet Technologies, LLC
// ' www.dovetailinternet.com
// ' info@dovetailinternet.com
// '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
// ' All rights reserved. Not to be used without permission.
// '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
// ' Development Date: Jan 2022
// ' Release Version: 2.21.0
// ' Revision: 1.0
// ' Modified: 12/09/2022
// '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
// Global Variables
var cartDataSource_widgetID = [];
var CartList_widgetID;
const AllAvalibleWarehouseNames = [];
const Profile = { PreferredWarehouse: '', EnableWarehouseSelection: false };
let NoPrefWarehouseInfo = { Warehouse: '', Description: `No Preference`, InventoryQty: 0, SurchargeFee: '', SurchargeFeeAmount: 0 };
/**================================================================================================
** processCartData_widgetID
*? Takes the cart data combindes item detail lines and fee lines then uses data for dx.list dataSource?
*@param cart cartData obj from different ajax call
*@return cartDataSource_widgetID Array used as the data source for disply cart(list)
*================================================================================================**/
function processCartData_widgetID(cart) {
cartDataSource_widgetID = [];
let feeArray = [];
let combinedCartRow = [];
cart.Data.Detail.forEach((row, i) => {
if (row.Parent_ID != -1) {
feeArray.push(row);
}
if (row.Parent_ID == -1) {
combinedCartRow.push(row);
}
});
for (var i = 0; i < combinedCartRow.length; i++) {
for (var j = 0; j < feeArray.length; j++) {
if (feeArray[j].Parent_ID == combinedCartRow[i].ID) {
combinedCartRow[i].fee = feeArray[j];
}
}
if (cart.Data.OriginalDetail) {
if (cart.Data.OriginalDetail.Item_ID == combinedCartRow[i].Item_ID) {
combinedCartRow[i].OriginalDetail = cart.Data.OriginalDetail;
}
}
}
cartDataSource_widgetID = combinedCartRow;
$('#subTotal').html(cart.Data.SubTotal);
CartList_widgetID.option('dataSource', cartDataSource_widgetID);
//NOTE if there are items in the cart and ShowColumnHeader === true
if (!_.isEmpty(cartDataSource_widgetID) && widgetOptions.ShowColumnHeader) {
$('.cartListHeader').show();
}
else {
$('.cartListHeader').hide();
}
SetUpCartDisplay(!_.isEmpty(cartDataSource_widgetID));
NotifyCart();
clearForm();
setFocus(widgetOptions.DefaultFocusedElementID);
//REVIEW focus now set with widgetOption $('#skuNumber').dxAutocomplete('focus');
}
/**================================================================================================
** SetUpCartDisplay
*? use widget options to determin what columns are displayed. ?
*? This function is called if there are items in the cart. ?
*@param hasItems bool
*================================================================================================**/
function SetUpCartDisplay(hasItems) {
if (hasItems) {
$('.cartListHeader').css("visibility", "visible");
if (widgetOptions.DisplayCartHeaderCustomerPrice) {
$('.listData.customerPrice').css("visibility", "visible");
$('.listHeader.Price.Two.customerPrice').css("visibility", "visible");
} else {
$('.listData.customerPrice').css("visibility", "hidden");
$('.listHeader.Price.Two.customerPrice').css("visibility", "hidden");
}
//NOTE col header
$('#stockCodeColumnHeader').html(widgetOptions.StockCodeColumnHeaderText);
$('#DescriptionColumnHeader').html(widgetOptions.DescriptionColumnHeaderText);
$('#QuantityColumnHeader').html(widgetOptions.QuantityColumnHeaderText);
$('#ExtPriceColumnHeader').html(widgetOptions.ExtPriceColumnHeaderText);
$('#OnHandQuantityColumnHeader').html(widgetOptions.OnHandQuantityColumnHeaderText);
//NOTE display DiscountPrice
// if (widgetOptions.DisplayCartHeaderDiscountPrice) {
// $('.listData.discountPrice ').css("visibility", "visible");
// $('.listHeader.Price.Three.discountPrice').css("visibility", "visible");
// } else {
// $('.listData.discountPrice ').css("visibility", "hidden");
// $('.listHeader.Price.Three.discountPrice').css("visibility", "hidden");
// }
//NOTE display DefaultPrice
// if (widgetOptions.DisplayCartHeaderDefaultPrice) {
// $('.listData.defaultPrice').css("visibility", "visible");
// $('.listData.defaultPrice.One.defaultPrice').css("visibility", "visible");
// } else {
// $('.listData.defaultPrice').css("visibility", "hidden");
// $('.listData.defaultPrice.One.defaultPrice').css("visibility", "hidden");
// }
}
}
/**================================================================================================
** setFocus
*? What does it do?
*@param is string
*================================================================================================**/
function setFocus(id) {
if (id === 'skuQty') {
$('#skuQty').dxNumberBox('focus');
}
if (id === 'skuNumber') {
$('#skuNumber').dxAutocomplete('focus');
}
if (id === 'addToCartBtn') {
$('#addToCartBtn').dxButton('focus');
}
if (id === 'goToCartBtn') {
$('#goToCartBtn').dxButton('focus');
}
}
$(function () {
//variables
let skuNumberDataSource = {};
let skuNumberDataSearchMode = '';
/**================================================================================================
* widgetOptions
*================================================================================================**/
widgetOptions.ShowColumnHeader = widgetOptions.ShowColumnHeader ?? true;
widgetOptions.DisplayCartHeaderCustomerPrice = widgetOptions.DisplayCartHeaderCustomerPrice ?? true;
widgetOptions.AutoCompleteSearchMode = widgetOptions.AutoCompleteSearchMode ?? 'StartsWith'; // [Contains,StartsWith,Exact]
widgetOptions.StockCodeFilterMinimumLength = widgetOptions.StockCodeFilterMinimumLength ?? 2;
widgetOptions.EnableFilterModeSelection = widgetOptions.EnableFilterModeSelection ?? true;
widgetOptions.StockCodeFilterDelay = widgetOptions.StockCodeFilterDelay ?? 0;
widgetOptions.EnableOnHandQuantityDisplay = widgetOptions.EnableOnHandQuantityDisplay ?? true;
widgetOptions.StockCodeFilterDropDownLength = widgetOptions.StockCodeFilterDropDownLength ?? 8;
widgetOptions.StockCodeColumnHeaderText = widgetOptions.StockCodeColumnHeaderText ?? 'Stock Code';
widgetOptions.DescriptionColumnHeaderText = widgetOptions.DescriptionColumnHeaderText ?? 'Description';
widgetOptions.QuantityColumnHeaderText = widgetOptions.QuantityColumnHeaderText ?? 'Qty';
widgetOptions.ExtPriceColumnHeaderText = widgetOptions.ExtPriceColumnHeaderText ?? 'Total';
widgetOptions.OnHandQuantityColumnHeaderText = widgetOptions.OnHandQuantityColumnHeaderText ?? 'Stock';
widgetOptions.DefaultFocusedElementID = widgetOptions.DefaultFocusedElementID ?? 'skuNumber'; //'[skuNumber, skuQty]'
widgetOptions.AfterQuantityFocusedElementID = widgetOptions.AfterQuantityFocusedElementID ?? 'skuNumber'; //'[addToCartBtn,skuNumber, skuQty]'
widgetOptions.QuantityInputEnterBehavior = widgetOptions.QuantityInputEnterBehavior ?? 'addToCart'; //[tab,addToCart]
widgetOptions.AddToCartButtonCssClass = widgetOptions.AddToCartButtonCssClass ?? '';
//REVIEW future add other pricing cols to cart grid
// // widgetOptions.DisplayCartHeaderDefaultPrice = widgetOptions.DisplayCartHeaderDefaultPrice ?? true;
// // widgetOptions.DisplayCartHeaderDiscountPrice = widgetOptions.DisplayCartHeaderDiscountPrice ?? true
//NOTE Template get underscore
_.templateSettings.variable = 'item';
/*================================== START OF FORM INPUTS SECTION ==========================================*/
if (widgetOptions.EnableFilterModeSelection) {
if (widgetOptions.AutoCompleteSearchMode !== 'Exact') {
skuNumberDataSearchMode = widgetOptions.AutoCompleteSearchMode;
skuNumberDataSource = new DevExpress.data.CustomStore(
{
loadMode: 'raw',
load: function () {
return $.getJSON('/ecommerce/exports/stockcodes.json');
}
}
)
}
}
$('#skuNumber').dxAutocomplete({
dataSource: skuNumberDataSource,
placeholder: 'Enter Stock Code...',
width: '320px',
valueExpr: 'stockcode',
searchExpr: ['stockcode', 'name'],
itemTemplate: function (data, index) {
return data.stockcode + ' - ' + data.name;
},
showClearButton: true,
onEnterKey: function (e) {
e.component.blur();
$('#skuQty').dxNumberBox('focus');
//confirmItemToAdd();
},
onFocusOut: function () {
/$('#skuQty').dxNumberBox('focus');
},
tabIndex: 1,
searchMode: skuNumberDataSearchMode,
minSearchLength: widgetOptions.StockCodeFilterMinimumLength,
searchTimeout: widgetOptions.StockCodeFilterDelay,
maxItemCount: widgetOptions.StockCodeFilterDropDownLength
});
$('#skuQty').dxNumberBox({
value: 1,
min: 1,
mode: 'number',
placeholder: 'Qty',
showSpinButtons: true,
width: '100px',
onFocusIn: e => { e.element.find('.dx-texteditor-input').select() },
onFocusOut: e => { setFocus(widgetOptions.AfterQuantityFocusedElementID) },
valueChangeEvent: 'input enterKey',
onValueChanged: function (e) {
if (e.value == null || e.value == 0) {
e.component.option('value', 1);
}
},
onEnterKey: function (e) {
if (widgetOptions.QuantityInputEnterBehavior === 'addToCart') {
confirmItemToAdd();
}
if (widgetOptions.QuantityInputEnterBehavior === 'tab') {
setFocus(widgetOptions.AfterQuantityFocusedElementID);
}
//confirmItemToAdd();
// $('#skuNumber').dxAutocomplete('focus');
},
tabIndex: 2,
});
$('#addToCartBtn').dxButton({
stylingMode: 'contained',
text: 'Add To Cart',
elementAttr: {
class: 'DT-Button'
},
type: 'default',
width: 120,
onClick: function () { confirmItemToAdd() },
tabIndex: 3,
});
$('#goToCartBtn').dxButton({
stylingMode: 'contained',
text: 'Checkout',
elementAttr: {
class: 'DT-Button'
},
type: 'default',
width: 90,
onClick() {
//REVIEW redirect to Cart while the checkout redirect requirments are pending
//document.location = SITE_PATHS.application + '/Checkout.aspx';
document.location = SITE_PATHS.application + '/ShoppingCart.aspx';
},
});
/*================================== END OF FORM INPUTS SECTION ==========================================*/
setFocus(widgetOptions.DefaultFocusedElementID);
//TODO
$('#addToCartBtn').addClass(widgetOptions.AddToCartButtonCssClass);
/**========================================================================
** confirmItemToAdd
*? Confirms form input data and submits getWarehouseForNewItem(stockcode, qty) if data is valid?
*@return getWarehouseForNewItem(stockcode, qty)
*========================================================================**/
function confirmItemToAdd() {
//NOTE what if the autocomplete is not a stockcode
let qty = $('#skuQty').dxNumberBox('option', 'value') ?? 1;
let stockcode = $('#skuNumber').dxAutocomplete('option', 'value')?.toUpperCase() ?? ''
if (stockcode === '') {
ToastAlert('You must select a valid stock code.', false);
$('#skuNumber').dxAutocomplete('focus');
return;
}
getWarehouseForNewItem(stockcode, qty);
}
/**================================================================================================
** buildCartDisplay
*? Gets the cart data, sends the data to the processCartData_widgetID function for proccessing ?
*? then displays the dxList using the cartTemplate ?
*@return data obj
*================================================================================================**/
function buildCartDisplay() {
let noDataMsg = ``;
CartList_widgetID = $('#cartList').dxList({
height: 'auto',
itemTemplate: $('#cartTemplate'),
noDataText: noDataMsg,
allowItemDeleting: false,
focusStateEnabled: false,
activeStateEnabled: false,
onInitialized: function (e) {
try {
MakeAJAXCall('Cart.GetCart', {},
function (DATA) {
if (DATA != null) {
var data = JSON.parse(DATA);
if (data.Result.Success) {
Profile.EnableWarehouseSelection = data.LookupData.Profile?.EnableWarehouseSelection ?? false;
Profile.PreferredWarehouse = data.LookupData.Profile?.PreferredWarehouse ?? '';
AllAvalibleWarehouseNames.push(data.LookupData.Warehouses);
if (data.Data?.Detail.length > 0) {
processCartData_widgetID(data);
}
//NOTE if the cart detail === 0 or if data.Data is null or undefined then display
if (data.Data?.Detail.length <= 0) {
noDataMsg = `There are no items in the cart.`;
$('#cartList').dxList('option', 'noDataText', noDataMsg);
$('.cartListHeader').hide();
}
//NOTE if data.Data === null or if Detail.length =< 0
if (data.Data?.Detail?.length === undefined || data.Data?.Detail?.length <= 0) {
noDataMsg = `There are no items in the cart.`;
$('#cartList').dxList('option', 'noDataText', noDataMsg);
$('.cartListHeader').hide();
}
}
if (!data.Result.Success) {
ToastAlert('Can not find the cart data ' + data.Message, false);
}
}
});
} catch (error) {
console.log(error);
}
},
onItemDeleted: function (e) { }
}).dxList('instance');
}
//NOTE lets get the cart data and load the page.
buildCartDisplay();
});//end of load ready
/**================================================================================================
** addItemToCart
*? Adds a new Iten to the cart then it updates the datasource for the the dx.list where cart data is displayed?
*@param stockcode str
*@param qty int
*@param warehouse string
*@return Array
*================================================================================================
/// * INFO
/// Type of the unit of measure valid options are as follows: Stocking : "stocking", "STK",
/// "S" or 1 Alternate : "alternate", "ALT", "A" or 2 Other : "other", "OTH", "O" or 3
/// Preferred : "preferred", "PREF", "P" or 0. Alternatively, the actual UOM label p the up[date if the slection has not changed
/// by an @ symbol (i.e. "@EA") which will then be translated to the appropriate UOM type.
*================================================================================================**/
function addItemToCart(stockcode, qty, warehouse) {
try {
MakeAJAXCall('Cart.AddItemToCartByStockCode', {
StockCode: stockcode,
Qty: qty,
UOM: 0
, Options: { Warehouse: warehouse }
}, function (DATA) {
if (DATA != null) {
var data = JSON.parse(DATA);
if (data.Result.Success) {
processCartData_widgetID(data);
}
if (!data.Result.Success) {
ToastAlert(`The item could not be added to the Order. ${data.Message}`, false);
}
}
})
} catch (error) {
console.log(error);
}
}
///-------------------------------------------------------------------------------------------------
/// <summary>
/// Display the in Stock information for an Item
/// </summary>
///
/// <param name='item'>
/// Cart line item detail with fee data appended if the fee{} exists
/// </param>
///-------------------------------------------------------------------------------------------------
function showStockData(item) {
try {
MakeAJAXCall('Inventory.GetItemInventoryQuantities', {
Item_ID: item.Item_ID
, UOM: item.UnitType
}, function (DATA) {
if (DATA != null) {
var data = JSON.parse(DATA);
if (data.Result.Success) {
if (data.Data.Warehouses && data.Data.Warehouses.length > 0) {
$('#showStockBtn_' + item.ID).hide()
$('#showStockData_' + item.ID).show();
$warehousecontainer = $('#showStockData_' + item.ID);
$warehousecontainer.empty();
var uom = ((data.Data.UOM != '' && data.Data.UOM != null) ? data.Data.UOM : 'EA')
var warehouseRow = $('<div>').addClass('data-row outer');
$('<div>')
.addClass('data totalOHQ')
.text(data.Data.InventoryQty + ' ' + uom + ' Limited Available')
.appendTo(warehouseRow);
data.Data.Warehouses.forEach(function (val, i) {
$('<div>')
.addClass('warehouseDetail')
.html('<span class="warehouse">' + val.Warehouse + '</span>' + ' ' + '<span class="warehouseQTY">' + val.InventoryQty + '</span>')
.appendTo(warehouseRow);
});
warehouseRow.appendTo($warehousecontainer);
}
if (!data.Data.Warehouses) {
ToastAlert('There is no warehouse data for ' + item.Item_ID, false);
}
}
}
}
)
} catch (error) {
console.log(error);
}
}
/**================================================================================================
** buildDisplayWidgetRow
*? Called from the template for each cart item line. Duilds the display and inputs for each item line?
*@param item{} Cart item line detail with appended fee if fee exists processCartData_widgetID(cart)
*================================================================================================**/
function buildDisplayWidgetRow(item) {
$('#qty_' + item.ID).dxNumberBox({
mode: 'number',
min: 1,
value: item.Quantity,
width: '100px',
showSpinButtons: true,
onEnterKey: function (e) {
e.component.blur();
},
onValueChanged: function (e) {
if (e.value == null || e.value == 0) {
e.value = e.previousValue;
}
},
onFocusOut: function (e) {
var newQty = e.component._$submitElement[0].value;
if (newQty != item.Quantity && newQty != null) {
updateCartLineWarehouse(item.ID, item.StockCode, newQty, item.UnitType, item.Warehouse);
}
}
});
//NOTE if widgetOptions.EnableOnHandQuantityDisplay then create button else create empty div
if (widgetOptions.EnableOnHandQuantityDisplay) {
$('#showStockBtn_' + item.ID).dxButton({
stylingMode: 'contained',
text: 'Check Stock',
elementAttr: {
class: 'DT-Button'
},
type: 'default',
width: 110,
onClick() {
showStockData(item);
}
});
}
if (!widgetOptions.EnableOnHandQuantityDisplay) {
$('#showStockBtn_' + item.ID).html('<div class=""></div>')
}
$('#deleteItem_' + item.ID).dxButton({
stylingMode: 'contained',
text: '',
icon: 'trash',
type: 'default',
width: 40,
elementAttr: {
class: 'deleteButton DT-Button',
},
onClick() {
try {
MakeAJAXCall('Cart.DeleteCartLine', {
'ID': item.ID
}, function (DATA) {
if (DATA != null) {
var data = JSON.parse(DATA);
if (data.Result.Success) {
processCartData_widgetID(data);
}
if (!data.Result.Success) {
ToastAlert('The item ' + item.StockCode + ' has not been deleted from your cart.' + data.Result.Message, false);
}
}
}
)
} catch (error) {
console.log(error)
}
},
});
}
/**================================================================================================
** getWarehouseDescription
*? returns Warehouse Description by lookup ?
*@param warehouse str
*@return Warhouse.Description string
*================================================================================================**/
function getWarehouseDescription(warehouseName) {
const { Warehouse, Description } = NoPrefWarehouseInfo;
if (warehouseName == Warehouse) {
return Description;
}
let x = AllAvalibleWarehouseNames[0].find(e => e.Warehouse == warehouseName);
return x.Description
}
/**================================================================================================
** getWarehouseDescription
*? returns Warehouse Description by lookup ?
*@param warehouse str
*@return Warhouse.Description string
*================================================================================================**/
function getWarehouseDescription(warehouseName) {
const { Warehouse, Description } = NoPrefWarehouseInfo;
if (warehouseName == Warehouse) {
return Description;
}
let x = AllAvalibleWarehouseNames[0].find(e => e.Warehouse == warehouseName);
return x.Description
}
/**================================================================================================
** buildServiceFeeRow
*? Builds the service fee line. Function called from the template as the display list is rendered.?
*@param item{} Cart item line detail with appended fee if fee exists processCartData_widgetID(cart)
*================================================================================================**/
function buildServiceFeeRow(item) {
let cartItemFeeLine = { ItemDetail: {} };
cartItemFeeLine.ItemDetail = Object.assign({}, item)
let wareHouseName = getWarehouseDescription(item.Warehouse);
let TotalPrice = '';
let Description = '';
let warehouseNameText = `Will Ship from warehouse: ${wareHouseName} ${item.Warehouse}`;
if (!_.isUndefined(cartItemFeeLine.ItemDetail.fee) && !_.isEmpty(cartItemFeeLine.ItemDetail.fee)) {
TotalPrice = cartItemFeeLine.ItemDetail.fee.TotalPrice ?? '';
Description = cartItemFeeLine.ItemDetail.fee.Description ?? '';
}
if (Profile.EnableWarehouseSelection) {
$('<div>')
.addClass('fee-row-spacer spacerOne')
.appendTo('#serviceFeeRow_' + item.ID);
$('<div>')
.addClass('fee-row-img')
.prepend('<img id="theImg" src="/ecommerce/images/arrow-right-angle.png" />')
.appendTo('#serviceFeeRow_' + item.ID);
$('<div>')
.attr('id', 'wareHouseName_' + item.ID)
.addClass('row-label')
.text(warehouseNameText)
.appendTo('#serviceFeeRow_' + item.ID);
$('<span>')
.addClass('row-warehouse-SelectLink')
.attr('id', 'whLink' + item.ID)
.html('<a class="warehouse-link">Change</a>')
.on('click', function () {
getInventoryWarehouseData(cartItemFeeLine);
})
.appendTo('#wareHouseName_' + item.ID);
$('<div>')
.addClass('fee-row-spacer spacerThree')
.appendTo('#serviceFeeRow_' + item.ID);
$('<div>')
.addClass('fee-row-spacer spacerFour')
.appendTo('#serviceFeeRow_' + item.ID);
$('<div>')
.addClass('fee-row-TotalPrice2')
.html(Description)
.appendTo('#serviceFeeRow_' + item.ID);
$('<div>')
.addClass('fee-row-TotalPrice2')
.html(TotalPrice)
.appendTo('#serviceFeeRow_' + item.ID);
$('<div>')
.addClass('fee-row-spacer spacerTwo')
.appendTo('#serviceFeeRow_' + item.ID);
}
//Build display row without Warehouse data
if (Profile.EnableWarehouseSelection == false && item.fee) {
$('<div>')
.addClass('fee-row-spacer')
.appendTo('#serviceFeeRow_' + item.ID);
$('<div>')
.addClass('fee-row-img')
.prepend('<img id="theImg" src="/ecommerce/images/arrow-right-angle.png" />')
.appendTo('#serviceFeeRow_' + item.ID);
$('<div>')
.addClass('row-label')
.text('')
.appendTo('#serviceFeeRow_' + item.ID);
$('<div>')
.addClass('fee-row-spacer')
.appendTo('#serviceFeeRow_' + item.ID);
$('<div>')
.addClass('fee-row-spacer')
.appendTo('#serviceFeeRow_' + item.ID);
$('<div>')
.addClass('fee-row-spacer')
.appendTo('#serviceFeeRow_' + item.ID);
$('<div>')
.addClass('fee-row-TotalPrice2')
.html(Description)
.appendTo('#serviceFeeRow_' + item.ID);
$('<div>')
.addClass('fee-row-TotalPrice2')
.html(TotalPrice)
.appendTo('#serviceFeeRow_' + item.ID);
$('<div>')
.addClass('fee-row-spacer')
.text('')
.appendTo('#serviceFeeRow_' + item.ID);
}
}
/**================================================================================================
** getInventoryWarehouseData
*? get the inventory warehouse data for the popup then display the popup?
*@param cartLineData obj
*@return type
*================================================================================================**/
function getInventoryWarehouseData(cartLineData) {
//build an obj with the data we need
let warehousePopupData = Object.assign({}, cartLineData);
try {
MakeAJAXCall(
'Inventory.GetItemInventoryQuantities',
{
Item_ID: cartLineData.ItemDetail.Item_ID,
UOM: cartLineData.ItemDetail.UnitType,
}, function (DATA) {
if (DATA != null) {
var data = JSON.parse(DATA);
if (data.Result.Success) {
if (data?.Data?.Warehouses === undefined) {
ToastAlert(`Warehouse selection is not avalible for this item. Please contact customer service.`, false);
return;
}
//NOTE the item wh is the wh we want. need the arr of wh for the popup. add no pref to arr
if (data?.Data?.Warehouses !== undefined) {
const ItemWarehouseArray = [...data?.Data?.Warehouses];
if (ItemWarehouseArray.length === data.Data.Warehouses.length) {
ItemWarehouseArray.unshift(NoPrefWarehouseInfo);
}
warehousePopupData.ItemTnventory = Object.assign({}, data.Data);
warehousePopupData.ItemWarehouseArray = [...ItemWarehouseArray];
buildWarehousePopup(warehousePopupData);
}
if (!data.Result.Success) {
throw error = Result.Message
}
}
}
})
} catch (error) {
console.log(error)
}
}
/**========================================================================
** getWarehouseForNewItem
*? Find the correct Warehouse for when the item is first added to the cart?
*@param stockcode str
*@param qty int
*@return theWarehouse string
*========================================================================**/
function getWarehouseForNewItem(stockcode, qty) {
let warehouse = '';
try {
MakeAJAXCall('Inventory.GetItemInventoryQuantitiesByStockCode', {
StockCode: stockcode,
UOM: 0
}, function (DATA) {
if (DATA != null) {
var data = JSON.parse(DATA);
if (data.Result.Success) {
//NOTE 1.preferredWarehouse
if (data.Data.PreferredWarehouse != '') {
warehouse = data.Data.PreferredWarehouse;
}//NOTE 2.DefaultWarehouse
else if (data.Data.PreferredWarehouse == '' && data.Data.DefaultWarehouse != '') {
warehouse = data.Data.DefaultWarehouse;
}
addItemToCart(stockcode, qty, warehouse)
}
}
})
} catch (error) {
console.log(error);
}
}
/**================================================================================================
** buildWarehousePopup
*? Build the warehouse selector popup.?
*@param warehousePopupData JSON
* {ItemDetail:{},ItemTnventory:{},ItemWarehouseArray:{}}
*================================================================================================**/
function buildWarehousePopup(warehousePopupData) {
const OriginalItemWarehouse = [];
const SelectedItemWarehouse = [];
var dataArr = warehousePopupData.ItemWarehouseArray
var listWidget = $('<div id="simpleList">').dxList({
height: 'auto',
dataSource: dataArr,
editEnabled: true,
allowItemDeleting: false,
hoverStateEnabled: true,
showSelectionControls: true,
selectionMode: 'single',
onSelectionChanged: function (e) {
if (_.isEmpty(e.removedItems)) {
OriginalItemWarehouse.WareHouseBeforPopup = Object.assign([], e.addedItems)
SelectedItemWarehouse.SelectedWarehouse = Object.assign([], e.addedItems);
}
if (!_.isEmpty(e.removedItems)) {
SelectedItemWarehouse.SelectedWarehouse = Object.assign([], e.addedItems);
}
},
itemTemplate: function (dataArr, index) {
var result = $('<div>').addClass('warehouseList');
$('<div>')
.addClass('warehouseCode listLine')
.text(dataArr.Warehouse)
.appendTo(result);
$('<div>')
.addClass('warehouseDesc listLine')
.text(dataArr.Description)
.appendTo(result);
$('<div>')
.addClass('warehouseRank listLine')
.text(dataArr.Status)
.appendTo(result);
$('<div>')
.addClass('warehouseFee listLine')
.html(dataArr.SurchargeFee)
.appendTo(result);
return result;
},
});
$('#popupContainerView').dxPopup({
showTitle: false,
height: 'auto',
width: '600px',
closeOnOutsideClick: false,
onHiding: function () { },
contentTemplate: function (contentElement) {
var popUpHead = $('<div>').addClass('outer');
$('<div>')
.addClass('popUpTitle')
.text('Select a warehouse')
.appendTo(popUpHead);
$('<div>')
.addClass('btnholder DT-Button')
.attr('id', 'closeBtn')
.html('<button>X</button>')
.on('click', function (e) {
if (SelectedItemWarehouse.SelectedWarehouse[0].Warehouse === OriginalItemWarehouse.WareHouseBeforPopup[0].Warehouse) {
$('#popupContainerView').dxPopup('instance').hide();
return;
}
if (SelectedItemWarehouse.SelectedWarehouse[0].Warehouse !== OriginalItemWarehouse.WareHouseBeforPopup[0].Warehouse) {
let id = warehousePopupData.ItemDetail.ID;
let stockCode = warehousePopupData.ItemDetail.StockCode;
let qty = warehousePopupData.ItemDetail.Quantity;
let uom = warehousePopupData.ItemDetail.UnitType;
let warehouse = SelectedItemWarehouse.SelectedWarehouse[0].Warehouse;
updateCartLineWarehouse(id, stockCode, qty, uom, warehouse);
}
$('#popupContainerView').dxPopup('instance').hide();
})
.appendTo(popUpHead);
contentElement.append(popUpHead);
contentElement.append(listWidget);
},
});
$('#popupContainerView').dxPopup('instance').show();
//NOTE when the popup loads the current item warehouse for that line item should be selected.
let itemWarehousePopupDefaultIndex = warehousePopupData.ItemWarehouseArray.findIndex(x => x.Warehouse == warehousePopupData.ItemDetail.Warehouse);
updatePopupSelectedWarehouse(warehousePopupData.ItemWarehouseArray[itemWarehousePopupDefaultIndex]);
}
/**================================================================================================
** updatePopupSelectedWarehouse
*? Updates the selected warehouse when the popup loads ?
*@param arr array item with a warehouse
*@return array selectedKeys
*================================================================================================**/
function updatePopupSelectedWarehouse(arr) {
let selectedKeys = []
selectedKeys.push(arr);
const list = $('#simpleList').dxList('instance');
list.option('selectedItemKeys', selectedKeys);
}
/**================================================================================================
** updateCartLineWarehouse
*? Updates the cart line Item Warehouse with the user selected warehouse. ?
*? Reloads the dataSourse for the cart dx.list ?
*@param Item_Detail_Inventory combined warehouse & cart data.
*@return updated Cart data
*================================================================================================**/
function updateCartLineWarehouse(id, stockCode, qty, uom, warehouse) {
//NOTE confirmed the warehouse has changed before update
try {
MakeAJAXCall('Cart.UpdateCartLine', {
ID: id,
StockCode: stockCode,
Qty: qty,
UOM: uom,
Options: {
Warehouse: warehouse
}
}, function (DATA) {
if (DATA != null) {
var data = JSON.parse(DATA);
if (data.Result.Success) {
processCartData_widgetID(data);
//ToastAlert('The Quanty of ' + item.StockCode + ' has changed from ' + item.Quantity + ' to ' + newQty);
}
if (!data.Result.Success) {
ToastAlert(`The Warehouse could not be updated. ${data.Result.Message}`, false);
console.log(data.Result.Message);
}
}
})
} catch (error) {
console.log
}
}
/**================================================================================================
** clearForm
*? clears form ?
*================================================================================================**/
function clearForm() {
$('#skuQty').dxNumberBox('option', 'value', 0);
$('#skuNumber').dxAutocomplete('option', 'value', '');
}
</script>
<!--* INFO --->
<script id="cartTemplate" type="text/html">
<div class='row qoeRows'>
<div class='dataRows'>
<div class='dataRowOne'>
<div class='details'>
<div class=' listData image'>
<img src='<%= item.Photo %>' />
</div>
<div class='listData stockCode'><%= item.StockCode %></div>
<div class='listData itemDescription'><a href= <%= item.URL %>><%= item.Description %></a></div>
<div class='qtyWrapper'>
<div class='listData selectWrapper' id='qty_<%= item.ID %>'></div>
<div class='listData'><%= item.UOM %></div>
</div>
<div class='listData defaultPrice One'><%= item.DefaultPrice %></div>
<div class='listData customerPrice Two'><%= item.CustomerPrice %></div>
<div class='listData discountPrice Three'><%= item.DiscountPrice %></div>
<div class='listData webPrice Four'><%= item.WebPrice %></div>
<div class='listData totalPrice'><%= item.TotalPrice %></div>
<div class='listData btnWrapper showStockBtn' id='showStockBtn_<%= item.ID %>'></div>
<div class='listData OHQ' id='showStockData_<%= item.ID %>'></div>
<div class='listData btnWrapper deleteBtn' id='deleteItem_<%= item.ID %>'></div>
</div>
<div class='FeeRowWrapper'>
<div class='FeeRow' id='serviceFeeRow_<%= item.ID %>'></div>
</div>
</div>
</div>
</div>
<% $(function () { buildDisplayWidgetRow(item); }); %>
<% $(function () { buildServiceFeeRow(item); }); %>
</script>
<style>
.dx-button-has-text .dx-button-content {
overflow: visible;
}
</style>