<div id="popupContainerView"></div>
<style>
.dx-popup-title {
background: #333;
color: #fff;
}
.dx-button-mode-text .dx-icon {
color: #fff;
}
.logoWrapper {
border-bottom: 1px solid #888;
margin-bottom: 20px;
display: flex;
justify-content: space-between;
align-items: flex-end;
}
.divTableCell.title {
font-weight: 700;
font-size: 24px;
padding: 15px;
}
.Invoice-box,
.Return-box,
.Order-box,
.Dispatch-box {
max-width: 80;
margin: auto;
padding: 30px;
border: 1px solid #eee;
box-shadow: 0 0 10px rgba(0, 0, 0, .15);
font-size: 14px;
line-height: 1.2em;
font-family: 'Open Sans', Arial, sans-serif;
color: #555;
}
.orderdisplayTitle.dispatchNotePopupLink {
text-align: left;
padding: 5px 15px;
}
td.orderdisplayTitle.dispatchNotePopupLink,
.orderdisplayTitle {
font-weight: 700;
padding: 5px 0 30px;
width;
}
.dx-popup-title.dx-toolbar .dx-toolbar-label {
max-width:none !important;
}
.orderDisplayTable,
.orderdisplayTable {
margin: 0 auto;
width: 100;
}
.detailRow {
display: grid;
grid-template-columns: 1fr 2fr;
}
.dispatchNote .detailRow {
display: grid;
grid-template-columns: 1fr 1fr;
}
.orderdisplaydetailLabel {
background: #ddd;
padding: 5px;
}
.orderdisplaydetailField {
font-weight: 400;
padding: 5px;
}
td.orderdisplaydetailField, .orderdisplaydetailField {
padding: 5px 10px;
text-align: left;
white-space: normal;
word-break: break-all;
}
.orderDisplayLabel, .orderdisplayLabel {
font-weight: 700;
text-align: left;
padding: 5px;
}
.evenRow td, .orderDisplaySubTable .evenRow td, .divTableRow.itemDetails:nth-child(odd),
.returnData .divTableRow:nth-child(odd) {
background: #f7f7f6;
}
td.orderDisplayField,
td.orderdisplayField {
padding: 5px;
}
.orderDisplaySubTable {
margin-top: 25px;
width;
}
table.DispatchNotesTable {
margin: 20px auto;
width: 99;
}
.DispatchNotesTable tbody tr th,
.orderDisplaySubTable td.orderDisplayDetailLabel,
td.orderDisplayDetailLabel {
background: #ddd;
padding: 5px;
font-weight: bold;
}
.DispatchNotesTable tbody tr td {
padding: 5px;
}
td.orderDisplayDetailField {
padding: 7px 5px;
}
/* FROM BILLING WIDGET */
.divTable {
display: table;
width;
}
.divTableRow.headerRow,
.divTableRow.itemDetails {
display: flex;
justify-content: space-between;
}
.returnData .divTableRow.headerRow,
.returnData .divTableRow {
display: grid;
grid-template-columns: repeat(7, 1fr) 2fr;
justify-content: space-between;
}
.returnData .divTableCell {
text-align: center;
}
.divTableRow.headerRow,
.divTableRow.headerRow {
background-color: #ddd !important;
color: #000;
}
.divTableHeading {
background-color: #EEE;
display: table-header-group;
}
.divTableCell.logo {
background-image: url(/ecommerce/site/themes/images/logo.png);
background-repeat: no-repeat;
width: 250px;
height: 100px;
background-size: 100;
margin: 0 0px;
min-height: 10px;
max-height: 180px;
}
.divTableRow.invoiceDetails {
display: grid;
justify-content: space-between;
grid-template-columns, auto) minmax(49, auto);
}
.divTableRow.customerDetails {
float: right;
}
.divTableRow.invoiceTotals {
width;
}
.divTableRow.itemDetails {
margin-bottom: 10px;
}
.divTableCell {
display: table-cell;
padding: 5px 10px;
}
.divTableHead {
display: table-cell;
font-weight: bold;
font-weight: bold;
}
.invoiceDetails .divTableRight {
text-align: left;
float: left;
}
.divTableRow.invoiceTotals {
width: 100;
display: grid;
grid-template-columns: minmax(144px, auto) minmax(160px, auto);
justify-content: end;
justify-items: end;
float: right;
margin: 10px 0 -5px;
font-weight: 700;
}
.divTableBody {
display: table-row-group;
}
.pseudocell {
display: inline-block;
width: 100px;
text-align: left;
}
.divTableCell.StockCode,
.divTableCell.divTableHead.divTableItem {
min-width;
text-align:left;
}
.divTableCell.StockDes,
.divTableCell.divTableHead.divTableDesc {
min-width: 35;
}
.divTableCell.Qty,
.divTableCell.divTableHead.divTableQTY {
min-width;
text-align: center;
}
.divTableCell.Price,
.divTableCell.divTableHead.divTableEA {
min-width: 15;
text-align: right;
}
.divTableCell.Gross,
.divTableCell.divTableHead.divTablePrice {
min-width;
text-align: right;
}
.divTableCell.orderTotal {
font-weight: 700;
width: 100;
}
.orderdisplayTable table {
border: 0px solid #999;
}
.dx-popup-title.dx-toolbar .dx-toolbar-label {
max-width: none !important;
}
/* New CSS added fpr response Popup */
.msgLine1 {
font-size;
font-weight: 700;
padding-bottom: 10px;
}
.msgLine2 {
font-size: 120;
padding-bottom: 10px;
}
.grid-container-response-popup {
display: grid;
grid-template-columns 16% 73%;
grid-gap: 10px;
padding-bottom: 5px;
padding-top: 5px;
}
.grid-container-response-popup > div {
}
.responseCartLineDetail_qty {
font-weight: 700;
text-align: right;
}
.responseCartLineDetail_stockCode {
}
.responseCartLineDetail_desc {
}
.orderdisplayLabel.shipToLabel {
text-align:right;
padding: 5px 7px;
}
@media (max-width: 767px) {
.divTableRow.invoiceDetails {
grid-template-columns: 1fr;
}
.detailRow {
grid-template-columns: 1fr 1fr;
}
.orderdisplayLabel.shipToLabel {
text-align:left;
padding: 5px;
}
}
</style>
<script type="text/javascript">
// '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
// ' Base Widget: DocumentViewer_Popup.html
// '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
// ' Custom Widget Filename:
// '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
// ' (c) 2021 by Dovetail Internet Technologies, LLC
// ' www.dovetailinternet.com
// ' info@dovetailinternet.com
// '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
// ' All rights reserved. Not to be used without permission.
// '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
// ' Development Date: Sept 2021
// ' Revision: 1.0
// ' Modified: 10/06/2021
// ' Revision: 2.0
// ' Modified: 04/14/2022 - PR Document links added
// ' Modified: 03/07/2023 - PR TP18416 Reorder button added
// '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
// ' Purpose: Display Orders, Invoices and Returns in a popup window
// ' that provides print functionality.
// ' Built to display and print any document type added to the
// ' documentDisplayList object.
// '
// '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
/**================================================================================================
** setDocumentViewerWidgetOptionDefaults
*? set default or check values for widget options in one place?
*@return JSON
//TODO Need better default ==> deconstruction might work
//NOTE if widgetOption === '' that is valid for some options
*================================================================================================**/
function setDocumentViewerWidgetOptionDefaults(widgetOptions = {}) {
//REVIEW Dev force popup //widgetOptions.addedToCartNotificationType = 'PopUp';
widgetOptions.showReOrderButton = widgetOptions.showReOrderButton ?? true;
widgetOptions.reOrderButtonText = widgetOptions.reOrderButtonText ?? 'Reorder';
widgetOptions.addedToCartButtonText = widgetOptions.addedToCartButtonText ?? 'Items Added';
widgetOptions.addedToCartNotificationType = widgetOptions.addedToCartNotificationType?.toLowerCase() ?? 'toast';
widgetOptions.goToCartURL = widgetOptions.goToCartURL ?? '/shoppingcart.aspx';
widgetOptions.toastDisplayTime = widgetOptions.toastDisplayTime ?? 5000;
}
/**================================================================================================
** showDocumentViewerPopUp
*? Starts to process of building the popUp. This function may be called from other widgets or internally?
*@param docType str
*@param docInfoReference str
*@return
*================================================================================================**/
function showDocumentViewerPopUp(docType, docInfoReference) {
setDocumentViewerWidgetOptionDefaults(widgetOptions);
var documentDisplayList =
[{ DocumentType: 'Order', ServiceCall: 'Order.GetOrderDetailView', ParamName: 'OrderNumber', ServiceParam: {} },
{ DocumentType: 'Invoice', ServiceCall: 'Billing.GetInvoiceDetailView', ParamName: 'InvoiceNumber', ServiceParam: {} },
{ DocumentType: 'Return', ServiceCall: 'Return.GetReturnDetailView', ParamName: 'RMANumber', ServiceParam: {} },
{ DocumentType: 'Dispatch', ServiceCall: 'Fulfillment.GetDispatchNoteDetailView', ParamName: 'DispatchNoteNumber', ServiceParam: {} }
];
// get the ServiceCall
documentDisplayList.forEach(function (item, index) {
if (documentDisplayList[index].DocumentType == docType) {
documentDisplayList[index].ServiceParam[documentDisplayList[index].ParamName] = docInfoReference;
MakeAJAXCall(documentDisplayList[index].ServiceCall, documentDisplayList[index].ServiceParam,
function (DATA) {
if (DATA != null) {
var data = JSON.parse(DATA);
if (data.Result.Success) {
buildPopup(data.Html, docType, docInfoReference);
}
}
}
);
}
})
}
/**=======+++++++++++++++++++++++++++++++++++++++++++++++++++=======================================
** removeSpecialCharsForPopupId()
*? Returns the docInfoReference that has had the special chars replaced with '_'. Needed for use as div id?
*@param docRef string
*@return string
*=====================================++++++++++++++++++++++++++++++++++++++++++++++++++++========**/
function removeSpecialCharsForPopupId(docRef) {
return docRef.replace(/[^a-zA-Z0-9_-]/g, '_');
}
/**================================================================================================
** buildPopup
*? Builds popup?
*@param returnedHtml html
*@param docType str
*@param docInfoReference str
*@return type
*================================================================================================**/
function buildPopup(returnedHtml, docType, docInfoReference) {
//REVIEW Can order numbers and Invoice numbers contain special characters
var docId = docType + removeSpecialCharsForPopupId(docInfoReference);
let docClass = docType + '-box';
// need to set the destination for each popup
let dynamicPopupContainer = $('#popupContainerView')
.append($('<div />').attr('id', docId));
var dynmicPopup = $('#' + docId).dxPopup({
visible: true,
showTitle: true,
showCloseButton: true,
closeOnOutsideClick: true,
elementAttr: {
class: "order"
},
resizeEnabled: true,
contentTemplate: function (contentElement) {
contentElement.append(
$('<div />').attr('id', 'scrollbarContainer')
.append($('<div />').attr('id', docId + '_scroll').attr('class', docClass)
.append(returnedHtml)
).dxScrollView({
direction: 'both',
scrollByThumb: true,
scrollByContent: true,
showScrollbar: 'always',
useNative: true
})
)
},
onShowing: function () {
PretifyNumbers();
buildDrillDownPopUplinks();
},
toolbarItems: [{
location: "before"
},
{
widget: "dxButton",
location: "after",
options:
{
elementAttr: { id: `reOrderBtn_${docId}`, class: 'DT-Button' },
text: widgetOptions.reOrderButtonText,
visible: showReOrderBtn(docType),
onClick: function (e) {
const DocData = { docInfoReference: docInfoReference, docType: docType, docId: docId, addToCartBtnId: `#reOrderBtn_${docId}` };
addItemsToCart(DocData, widgetOptions.addedToCartNotificationType);
}
}
},
{
widget: "dxButton",
location: "after",
options: {
elementAttr: { id: `printBtn_${docId}`, class: 'DT-Button' },
text: "Print",
onClick: function () {
var divToPrint = document.getElementById(docId + '_scroll');
var newWin = null;
newWin = window.open('', '_blank');
if (newWin == null) {
var alertResult = DevExpress.ui.dialog.alert('You must enable popup in this browser to use the print function', 'Message');
alertResult.done(function () {
// nothing to do here
});
}
if (newWin != null) {
setTimeout(function () {
newWin.document.open();
setTimeout(function () {
newWin.document.write('<html><head><link href="/Ecommerce/site/themes/css/printInvoice.css" rel="stylesheet" /></head><body onload="window.print()">' + divToPrint.innerHTML + '</body></html>');
setTimeout(function () {
newWin.document.close();
setTimeout(function () {
newWin.close();
}, 200);
}, 200);
}, 200);
}, 200);
}
}
}
}]
}).dxPopup('instance');
let popInst = $('#' + docId).dxPopup("instance");
popInst.option('title', docType + ' ' + docInfoReference);
if (docType == 'Dispatch') {
popInst.option('title', `${docType} Note ${docInfoReference}`);
}
}
/**================================================================================================
** showReOrderBtn
*? Display reorder button ?
*@param docType str (Order, invoice)
*@return bool
*================================================================================================**/
function showReOrderBtn(docType) {
//NOTE check permission Widget option?
if (widgetOptions.showReOrderButton === false) {
return false;
}
//NOTE check doc type
if (docType === 'Order' || docType === 'Invoice') {
return true;
}
//NOTE check doc type
if (docType !== 'Order' && docType !== 'Invoice') {
return false;
}
}
/**================================================================================================
** new addItemsToCart
*? Adds the items from an invoice or order to a cart?
*@param DATA str Stringified JSON
*@param DocData obj document data
*@return type
*================================================================================================**/
function addItemsToCart(DocData, notificationType) {
//NOTE if type == order && responsee === silent || toast
if (DocData.docType === 'Order') {
if (notificationType !== 'popup') {
MakeAJAXCall("Cart.AddOrderItemsToCart", {
OrderNumber: DocData.docInfoReference
}, ValidateAddToCartOther, DocData)
}
// if (notificationType.toLocaleLowerCase() === 'popup') {
// MakeAJAXCall("Cart.AddOrderItemsToCart", {
// OrderNumber: DocData.docInfoReference
// }, validateAddToCartWithPopup, DocData)
// }
}
if (DocData.docType === 'Invoice') {
if (notificationType !== 'popup') {
MakeAJAXCall("Cart.AddInvoiceItemsToCart", {
InvoiceNumber: DocData.docInfoReference
}, ValidateAddToCartOther, DocData)
}
// if (notificationType === 'popup') {
// MakeAJAXCall("Cart.AddInvoiceItemsToCart", {
// InvoiceNumber: DocData.docInfoReference
// }, validateAddToCartWithPopup, DocData)
// }
}
}
/**================================================================================================
** ValidateAddToCartOther
*? Process response from ajax call and update cart badge toast is optional ?
*@param DATA str Stringified JSON
*@param DocData obj document data
*================================================================================================**/
function ValidateAddToCartOther(DATA, DocData) {
if (ValidAJAXResponse(DATA)) {
let data = JSON.parse(DATA);
if (data.Result.Success) {
let reOrdBtnTxt = $(`${DocData.addToCartBtnId} div span`);
if (widgetOptions.addedToCartNotificationType.toLocaleLowerCase() === 'toast') {
$(reOrdBtnTxt).text(widgetOptions.addedToCartButtonText);
//Update the cartBadge
/$('#spnCartBadge2').html(data.Data.ItemCount)
$(DocData.addToCartBtnId).addClass("added");
setTimeout(function () {
$(reOrdBtnTxt).text(widgetOptions.reOrderButtonText);
$(DocData.addToCartBtnId).removeClass("added");
}, widgetOptions.toastDisplayTime);
ToastAlert(
data.Result.Message,
data.Result.Success,
widgetOptions.toastDisplayTime,
widgetOptions.toastDisplayTime
)
}
NotifyCart();
}
if (!data.Result.Success) {
ToastAlert(
data.Result.Message,
data.Result.Success,
widgetOptions.toastDisplayTime,
widgetOptions.toastDisplayTime
)
}
}
}
/**================================================================================================
** buildDrillDownPopUplinks
*? Creates a link for orders, invoices, returns ...?
*@return html
*================================================================================================**/
function buildDrillDownPopUplinks() {
//NOTE handle the different types of docs that can be passed --> add function by class added in Customer_XX_Display.xslt files.
// MakeAJAXCall("Billing.GetCustomerInvoices", {}, console.log) --> .invoicePopupLink
//Return.GetReturnDetailView --> .rmaPopupLink
//Order.GetOrderDetailView --> .orderPopupLink
//Fulfilment.GetDispatchNoteDetailView --> .DispatchNotePopupLink
$('.invoicePopupLink').each(function () {
var iRefNumber = $(this).text();
var iLookUpType = "Invoice";
$(this).html('<a href="#" onclick="showDocumentViewerPopUp(\'' + iLookUpType + '\',\'' + iRefNumber + '\')">' + iRefNumber + '</a>');
})
$('.rmaPopupLink').each(function () {
var rRefNumber = $(this).text();
var rLookUpType = "Return";
$(this).html('<a href="#" onclick="showDocumentViewerPopUp(\'' + rLookUpType + '\',\'' + rRefNumber + '\')">' + rRefNumber + '</a>');
})
$('.orderPopupLink').each(function () {
var oRefNumber = $(this).text();
var oLookUpType = "Order";
$(this).html('<a href="#" onclick="showDocumentViewerPopUp(\'' + oLookUpType + '\',\'' + oRefNumber + '\')">' + oRefNumber + '</a>');
})
$('.dispatchPopupLink').each(function () {
var dRefNumber = $(this).text();
var dRookUpType = "Dispatch";
$(this).html('<a href="#" onclick="showDocumentViewerPopUp(\'' + dRookUpType + '\',\'' + dRefNumber + '\')">' + dRefNumber + '</a>');
})
}
/**================================================================================================
** validateAddToCartWithPopup
*? Process response from ajax call create popup and update cart badge ?
*@param DATA str Stringified JSON
*@param DocData obj document data
*@return type
*================================================================================================**/
/**================================================================================================
* ! WARNING
//TODO displaying cart data in the popup has been shelved at the moment
// This function and the 2 places it is called from have been commented out
*================================================================================================**/
// function validateAddToCartWithPopup(DATA, DocData) {
// if (ValidAJAXResponse(DATA)) {
// let data = JSON.parse(DATA);
// if (data.Result.Success) {
// //Update the cartBadge
// $('#spnCartBadge2').html(data.Data.ItemCount)
// let msgLineOne = (data.Result.Message.trim()).split('. ');
// let msgStr = `<div class ='msgLine1'>${msgLineOne[0]}.</div>`;
// let title = '';
// // if (data.Data.ItemCount === 1) {
// // msgStr = msgStr + `<div class ='msgLine2'>Your cart contains ${data.Data.ItemCount} item.</div>`;
// // }
// // if (data.Data.ItemCount !== 1) {
// // msgStr = msgStr + `<div class ='msgLine2'>Your cart contains ${data.Data.ItemCount} items.</div>`;
// // }
// if (data.Data.ItemCount === 1) {
// title = `Your cart contains ${data.Data.ItemCount} item`;
// }
// if (data.Data.ItemCount !== 1) {
// title = `Your cart contains ${data.Data.ItemCount} items`;
// }
// data.Data.Detail.forEach((orderItem, i) => {
// msgStr = msgStr + `<div class='grid-container-response-popup'>
// <div class='responseCartLineDetail_qty'>${orderItem.Quantity}</div>
// <div class='responseCartLineDetail_stockCode'>${orderItem.StockCode}</div>
// <div class='responseCartLineDetail_desc'>${orderItem.Description}</div> </div>`;
// });
// ResponsePopUp(msgStr, DocData, title);
// }
// if (!data.Result.Success) {
// if (data.Result.Message != null && data.Result.Message.trim() != "") {
// //REVIEW
// ToastAlert(
// data.Result.Message,
// data.Result.Success,
// widgetOptions.toastDisplayTime,
// widgetOptions.toastDisplayTime
// );
// }
// }
// }
// NotifyCart();
// }
/**================================================================================================
** ResponsePopUp
*? Displays cart data in popup after items added?
*@param msg str html at populate the popup
*@param obj data about the document
*@return dxpopup
*================================================================================================**/
// function ResponsePopUp(msg, DocData, title) {
// let rDocId = `${DocData.docType}${DocData.docInfoReference}Response`;
// // var let = docType + '-box';
// let dynamicPopupContainer = $('#' + DocData.docId)
// .append($('<div />').attr('id', rDocId).attr('class', 'notUsedYet2'));
// let resopnsePopup = $('#' + rDocId).dxPopup({
// wrapperAttr: {
// id: "theResopnsePopup",
// class: "notUsedYet"
// },
// visible: true,
// minheight: '30vh',
// height: 'auto',
// width: '500px',
// showTitle: false,
// position: "center",
// showCloseButton: false,
// closeOnOutsideClick: true,
// showCloseButton: true,
// showTitle: true,
// title: title,
// //contentTemplate: msg,
// contentTemplate: function (contentElement) {
// contentElement.append(msg);
// },
// toolbarItems: [
// {
// toolbar: "top",
// location: "right",
// widget: "dxButton",
// options: {
// elementAttr: {
// class: "DT-Button"
// },
// text: "Go to Cart",
// onClick: function (e) {
// document.location = SITE_PATHS.application + widgetOptions.goToCartURL;
// }
// }
// }
// ]
// }).dxPopup('instance');
// //Turn off scroll
// $(("#theResopnsePopup > div > div.dx-popup-content")).css('overflow', 'hidden');
// }
</script>