<style type='text/css'>
/* * {
font-family: 'Open Sans', Arial, sans-serif;
}*/
#Main_Title {
font-size: 20px;
font-weight: 300;
/* border-bottom: 1px solid #cac9c9;*/
height: 45px;
color: #333;
max-width: 190px;
}
.input-container {
display: flex;
flex-wrap: wrap;
margin: 5px 0 25px;
box-sizing: border-box;
}
.dx-field {
flex-direction: column;
display: flex;
width: 50;
}
.dx-field.one .dx-field-value {
display: flex;
width !important;
}
.dx-field-label {
float: left;
width: 100;
font-weight: 700;
}
div#salesOrderNumberLookup {
width;
}
.btn {
border-width: 2px;
font-weight: 400;
letter-spacing: 1.7px;
-webkit-transition: all 0.2s ease-in-out, color 0.2s ease-in-out, box-shadow 0.1s ease-in-out;
transition: all 0.2s ease-in-out, color 0.2s ease-in-out, box-shadow 0.1s ease-in-out;
outline-color: #f60 !important;
padding: 7px 12px 6px;
}
.dx-button-mode-text.dx-button-default {
background-color: #cac7c7;
color: #000000;
}
.dx-button-mode-text.dx-button-default.dx-state-hover {
background-color: #000;
color: #fff;
}
.btn-primary,
.dx-toolbar-button .dx-button-mode-contained {
color: #fff;
background-color: #f60;
border-color: #f60;
}
.btn-import.dx-button-mode-contained {
color: #ee3a43;
background-color: #e9ece7;
border-radius: 0;
margin-left: -10px !important;
}
button.btn.btn-primary {
font-size: 1.0em;
min-width: 115px;
}
.dx-button-mode-contained.dx-button-default {
background: #f60;
color: #fff;
}
.dx-button-mode-contained.dx-button-default.dx-state-hover,
.default_btn_class.dx-button-mode-contained.dx-button-default.dx-state-focused {
background: #000;
color: #fff;
}
.dx-item.dx-list-item.dx-state-focused {
background-color: #fff !important;
color: #000 !important;
}
.dx-list-static-delete-button .dx-button-content,
.dx-list-switchable-delete-button .dx-button-content {
padding: 4px;
}
i.dx-icon.fa.fa-trash {
font-size: 16px;
color: #808080 !important;
}
.dx-widget.dx-numberbox-spin-button.dx-numberbox-spin-up.dx-state-hover,
.dx-widget.dx-numberbox-spin-button.dx-numberbox-spin-down.dx-state-hover {
background: #fff !important;
}
.dx-widget.dx-numberbox-spin-button.dx-numberbox-spin-up.dx-state-hover .dx-numberbox-spin-up-icon,
.dx-widget.dx-numberbox-spin-button.dx-numberbox-spin-down.dx-state-hover .dx-numberbox-spin-down-icon {
color: red;
background: #fff !important;
}
.dx-item.dx-list-item.dx-state-active {
background-color: rgba(00, 0, 0, 0.04) !important;
}
.dx-button-mode-contained {
color: #fff;
background-color: #f60;
border-color: #f60;
border-width: 0;
}
.dx-button-mode-contained.dx-state-hover {
color: #fff;
background-color: #000;
border-width: 0;
}
i.dx-icon.fa.fa-long-arrow-right {
float: right;
margin-left: 20px;
color: #fff;
}
/* used to mark questions for client*/
.ClientQs {
color: blue;
font-size: 12px;
font-weight: bold;
}
/* RMA FORM STYLES */
.rmaHeaderRow {
display: flex;
justify-content: space-between;
}
.rmaHeaderRow div {
font-weight: 700;
/*color: #808080;*/
}
.rmaHeaderRow .inputWrapper {
display: flex;
justify-content: space-between;
flex-basis: 50;
}
.productHeader {
flex-basis;
}
.qtyHeader {
flex-basis: 47;
}
.reasonHeader {
flex-basis;
}
.rmaRow {
display: flex;
flex-direction: row;
/* flex-wrap: nowrap;
padding: 15px;
gap: 20px;*/
}
.rmaRow .image {
padding: 0 10px;
}
.rmaRow .image img {
width: 80px;
}
.dataRows {
display: flex;
flex-direction: column;
justify-content: space-evenly;
flex-grow: 1;
flex-wrap: wrap;
/* width: 100;*/
}
.dataRowOne,
.dataRowTwo {
display: flex;
flex-wrap: wrap;
margin-bottom: 20px;
margin-right: 20px;
}
.dataRowOne {
justify-content: space-between;
/*padding-right: 5px;*/
margin-right: 20px;
margin-bottom: 0px;
}
.details {
/* flex-grow: 2; */
/* max-width: 350px; */
flex-basis;
}
.details .name {
font-weight: 500;
padding-left: 10px;
}
.details .stockcode {
font-size: 12px;
padding-left: 10px;
}
.selectWrapper {
display: flex;
flex-basis: 55;
justify-content: space-around;
padding: 0px;
}
.selectWrapper > div {
flex-basis;
}
.dataRowOne .qty {
max-width: 85px;
margin: 0 8px 0 0;
}
.dataRowOne .qty input {
text-align: center;
}
.dataRowOne .reason {
flex-basis: 25;
}
.dataRowTwo {
justify-content: space-between;
max-width: 510px;
}
.dataRowTwo .condition,
.dataRowTwo .rmaType {
width;
}
.dx-numberbox-spin-down,
.dx-numberbox-spin-up {
position: relative;
width: 100 !important;
height !important;
cursor: pointer !important;
display: block !important;
}
.dx-field-value-static,
.dx-field-value:not(.dx-switch):not(.dx-checkbox):not(.dx-button) {
width: fit-content;
}
div#skuNumber {
width: 50;
}
div#rmaHeaderNote {
width;
}
#ReturnFileUploaderContainer {
width: 50;
}
.dx-fileuploader-button.dx-button-mode-contained {
color: #333;
background-color: #ffffff;
border-color: #fff;
border-width: 1px;
}
.dx-fileuploader-button.dx-button-mode-contained.dx-state-hover {
color: #333;
background-color: #ffffff;
border-color: #ddd;
border-width: 1px;
}
@media (min-width: 320px) {
.rmaRow {
flex-wrap: wrap;
}
.dataRows {
display: block;
flex-wrap: wrap;
}
.dataRowOne,
.dataRowTwo {
flex-direction: column;
margin-bottom: 0px;
}
.details {
flex-basis;
margin-bottom: 20px;
}
.selectWrapper {
flex-basis: 100;
justify-content: space-between;
display: block;
padding: 10px;
}
.selectWrapper > div {
flex-basis;
margin-bottom: 20px;
}
.dataRowTwo > div {
flex-basis: 38;
margin-bottom: 20px;
}
.dx-numberbox-spin-touch-friendly .dx-numberbox-spin-container {
width: 34px !important;
}
.dx-list-item-after-bag,
.dx-list-item-before-bag {
vertical-align: top;
padding-top: 10px;
}
.dx-list-static-delete-button,
.dx-list-switchable-delete-button {
padding: 5px;
top: -140px;
right: 10px;
}
.dx-icon-remove::before {
color: #fff;
}
}
@media (min-width: 768px) {
.dataRowOne,
.dataRowTwo {
flex-direction: row;
margin-bottom: 0px;
}
.productHeader {
flex-basis;
}
.rmaHeaderRow .inputWrapper {
flex-basis: 57;
}
.selectWrapper > div {
flex-basis;
margin-bottom: 20px;
}
.dataRowTwo > div {
flex-basis: 38;
}
.dx-list-item-after-bag,
.dx-list-item-before-bag {
vertical-align: middle;
padding-top: 0px;
}
.dx-list-static-delete-button,
.dx-list-switchable-delete-button {
padding: 5px;
top: -100px;
right: 0px;
position: relative;
border-width: 0px;
/* background-color: #fff !important;*/
}
.dx-icon-remove::before {
color: #fff;
}
}
@media (min-width: 926px) {
.dataRows {
flex-wrap: nowrap;
}
.dataRowOne,
.dataRowTwo {
flex-direction: row;
margin-bottom: 10px;
justify-content: space-between;
}
.productHeader {
flex-basis;
}
.rmaHeaderRow .inputWrapper {
flex-basis: 57;
}
.details {
flex-basis;
margin-bottom: 0;
}
.selectWrapper {
display: flex;
flex-basis: 55;
justify-content: space-between;
}
.selectWrapper > div {
flex-basis;
margin-bottom: 0px;
}
.dataRowTwo > div {
flex-basis: 46;
}
.dx-list-static-delete-button,
.dx-list-switchable-delete-button {
padding: 5px;
top: -10px;
right: 0px;
position: relative;
border-width: 0px;
/* background-color: #fff !important;*/
}
.dx-button-mode-contained .dx-icon {
/*color: #000;*/
}
}
@media (min-width: 1200px) {
.productHeader {
flex-basis;
}
.rmaRow {
flex-wrap: nowrap;
}
}
/* NOTE */
.fileUploadArea {
border: 1px solid rgb(211, 208, 208);
}
.dx-fileuploader-upload-button {
display: none;
color: #000;
}
.note {
display: flex;
font-size: 10pt;
color: #484848;
margin-left: 9px;
font-weight: 700
}
.note > span {
font-weight: 500
}
.note > div {
font-weight: 500;
max-width: 161px;
white-space: normal;
padding: 0 5px;
}
.noteData {
display: inline;
}
.dx-fileuploader-upload-button {
}
</style>
<div class='returnBodyWrapper'>
<div id='Main_Title'>
<h1>Returns</h1>
</div>
<div id='returnHistoryBtn'></div>
<!-- import SO Number -->
<div class='input-container'>
<div class='dx-field one'>
<div class='dx-field-label'>
Online Order Lookup
</div>
<div class='dx-field-value'>
<div id='salesOrderNumberLookup'>
</div>
</div>
</div>
<div class='dx-field one'>
<div class='dx-field-label'>
Add Item To Return
</div>
<div class='dx-field-value'>
<div id='skuNumber'>
</div>
</div>
</div><br />
<div class='dx-field one'>
<div class='dx-field-label'>
Notes:
</div>
<div class='dx-field-value'>
<div id='rmaHeaderNote'>
</div>
</div>
</div>
<div class='dx-field one'>
<div class='dx-field-label'>
Upload File (Optional)
</div>
<div class='dx-field-value'>
<div id='ReturnFileUploaderContainer' class='fileUploadArea'>
</div>
</div>
<div>
<div class='note_widgetOptions note'>
Allowed file extensions:
<div class='fileTypeDisplay_widgetOptions noteData'></div>
</div>
<div class='note_widgetOptions note'>
Maximum file size:
<div class='maxFileSizeDisplay_widgetOptions noteData'> </div>
</div>
</div>
</div>
</div>
<!-- add SKU may not be in system StockCode-->
<div class='input-container'>
</div>
<!-- display Sale Order section Header -->
<div class='rmaHeaderRow hidden-xs hidden-sm'>
<div class='productHeader'>Product Details</div>
<div class='inputWrapper'>
<div class='qtyHeader'>Qty to Return</div>
<div class='reasonHeader'>Reason for Return</div>
<div class='reasonHeader'>Note</div>
</div>
</div>
<div>
<hr>
</div>
<!-- Display order items in DX list control -->
<div id='returnListWidgetDiv'></div>
<!-- submit button -->
<div class='dx-field-value col-sm-12 col-md-4 import'>
<div class='btn btn-primary btn-lgd' id='icon-submit'>
</div>
</div>
</div>
<div id="popReturn"></div>
<script>
// '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
// ' Base Widget: ItemReturnForm.html
// '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
// ' Custom Widget Filename: ItemReturnForm.html
// '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
// ' (c) 2021 by Dovetail Internet Technologies, LLC
// ' www.dovetailinternet.com
// ' info@dovetailinternet.com
// '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
// ' All rights reserved. Not to be used without permission.
// '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
// ' Development Date: July 2021
// ' Revision: 1.0
// ' Modified: 11/01/2022 - PR
// '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
// ' Create an RMA for Gentec so that Items can be returned. TP # 13515
// ''
// Global Variables
var ReturnData_widgetID = [];
var ReturnListWidget_widgetID;
//var RmaNumber = '';
let AllProblemCodes = [];
var DefaultProblemCode = '';
var PendingReturn = {};
var UOMTypes = [0, 'P', 'PRE', 'PREFERRED', 1, 'S', 'STK', 'STOCKING', 2, 'A', 'ALT', 'ALTERNATE', 3, 'O', 'OTH', 'OTHER'];
/**================================================================================================
** GetReturnLineID
*? Get the ID for the return line from an ID string?
*@param eid The element id string
*@return The return line identifier as an integer
*================================================================================================**/
function GetReturnLineID(eid) {
return parseInt(eid.substring(eid.indexOf('_') + 1));
}
///-------------------------------------------------------------------------------------------------
/// <summary>
/// Loads data into the return list.
/// </summary>
///
/// <param name="data">
/// The data.
/// </param>
///
/// <returns>
/// The return list.
/// </returns>
//NOTE
///-------------------------------------------------------------------------------------------------
function LoadReturnList_widgetID(data) {
ReturnData_widgetID = data;
for (var i = 0; i < data.length; i++) {
var d = data[i];
// handle Custom Data nulls
if (_.isUndefined(d.CustomData) == false && d.CustomData != '') {
if (_.isUndefined(d.Options)) {
d.Options = {};
}
if (_.isObject(d.CustomData)) {
d.Options.CustomData = d.CustomData;
} else if (_.isString(d.CustomData)) {
d.Options.CustomData = JSON.parse(d.CustomData);
}
}
// handle purchase date nulls
// NOTE move to a function if we need to do more of this in the future
if (!_.isUndefined(d.PurchaseDate)) {
if (d.PurchaseDate === null) {
d.PurchaseDate = '';
}
} else {
d.PurchaseDate = '';
}
}
ReturnData_widgetID = data;
// $('#icon-submit').dxButton('option', 'disabled', _.isEmpty(ReturnData_widgetID))
enableSubmitBtn(_.isEmpty(ReturnData_widgetID));
ReturnListWidget_widgetID.option("dataSource", ReturnData_widgetID);
}
/**================================================================================================
** UpdateReturnLine_widgetID
*? Updates the detail line on a return?
*@param objIndex int
*@param name type
*@return type
// NOTE {ID, StockCode, Qty, UOM, PurchaseDate, SerialNumber, ReturnType, ProblemCode, ProblemNotes, Options{}}
*================================================================================================**/
function UpdateReturnLine_widgetID(objIndex) {
var l = ReturnData_widgetID[objIndex];
//console.log(l);
var uom = (_.isUndefined(l.UOM))
? 0
: (_.contains(UOMTypes, l.UOM))
? l.UOM
: (!isNaN(l.UOM))
? '@' + l.UOM
: 0;
MakeAJAXCall("Return.UpdateReturnLine", {
ID: l.ID,
StockCode: l.StockCode,
Qty: l.Quantity,
UOM: uom,
PurchaseDate: l.PurchaseDate,
SerialNumber: l.SerialNumber,
ReturnType: (l.ReturnType.length > 0 ? l.ReturnType : 'G'),
ProblemCode: l.ProblemCode,
ProblemNotes: l.ProblemNotes,
Options: l.Options
}, function (DATA) {
if (ValidAJAXResponse(DATA)) {
var d = JSON.parse(DATA);
if (d.Result.Success) {
LoadReturnList_widgetID(d.Data.Details);
} else {
ToastAlert(d.Result.Message, false);
}
}
});
}
///-------------------------------------------------------------------------------------------------
/// <summary>
/// Searches for the index of the first object in an array that has a specific attribute value.
/// </summary>
///
/// <param name="array">
/// The array.
/// </param>
/// <param name="attr">
/// The attribute.
/// </param>
/// <param name="value">
/// The value.
/// </param>
///
/// <returns>
/// The zero-based index of the found array by attribute value, or -1 if no match was found.
/// </returns>
///-------------------------------------------------------------------------------------------------
function IndexOfByAttrValue(array, attr, value) {
for (var i = 0; i < array.length; i++) {
if (array[i][attr] === value) {
return i;
}
}
return -1;
}
/**================================================================================================
** setWidgetOptionDefaults
*? set - check default values for widget options in one place?
*@return type
//TODO Need better default ==> deconstruction would work
//NOTE if widgetOption == '' that is valid
*================================================================================================**/
function setWidgetOptionDefaults(widgetOptions = {}) {
if (!_.isString(widgetOptions.allowedExtensionsForUpload) || widgetOptions.allowedExtensionsForUpload == '') {
widgetOptions.allowedExtensionsForUpload = '.jpg, .jpeg, .png, .pdf';
}
(!_.isString(widgetOptions.selectButtonText)) ? widgetOptions.selectButtonText = 'Click or Drop File here' : widgetOptions.selectButtonText = widgetOptions.selectButtonText;
(!_.isString(widgetOptions.fileUploadPrefix)) ? widgetOptions.fileUploadPrefix = '' : widgetOptions.fileUploadPrefix = widgetOptions.fileUploadPrefix;
(!_.isString(widgetOptions.fileUploadSuffix)) ? widgetOptions.fileUploadSuffix = '' : widgetOptions.fileUploadSuffix = widgetOptions.fileUploadSuffix;
(!_.isString(widgetOptions.popupText)) ? widgetOptions.popupText = 'Thank You, We have received your return.' : widgetOptions.popupText = widgetOptions.popupText;
(!_.isString(widgetOptions.popupHeader)) ? widgetOptions.popupHeader = 'The return has been entered' : widgetOptions.popupHeader = widgetOptions.popupHeader;
(!_.isString(widgetOptions.popupButtonText)) ? widgetOptions.popupButtonText = 'Continue to Returns Section' : widgetOptions.popupButtonText = widgetOptions.popupButtonText;
(!_.isString(widgetOptions.submitButtonText)) ? widgetOptions.submitButtonText = 'Submit Return' : widgetOptions.submitButtonText = widgetOptions.submitButtonText;
(!_.isString(widgetOptions.salesOrderPlaceholder)) ? widgetOptions.salesOrderPlaceholder = 'Enter Order Number' : widgetOptions.salesOrderPlaceholder = widgetOptions.salesOrderPlaceholder;
widgetOptions.allowMultipleFiles === true ? widgetOptions.allowMultipleFiles = widgetOptions.allowMultipleFiles : widgetOptions.allowMultipleFiles = false;
widgetOptions.strObscureFilename === true ? widgetOptions.strObscureFilename = widgetOptions.strObscureFilename : widgetOptions.strObscureFilename = false;
widgetOptions.AddReturnNumberToFileName === true ? widgetOptions.AddReturnNumberToFileName = widgetOptions.AddReturnNumberToFileName : widgetOptions.AddReturnNumberToFileName = false;
(_.isNaN(widgetOptions.maxFileSize)) ? widgetOptions.maxFileSize = 4500000 : widgetOptions.maxFileSize = widgetOptions.maxFileSize;
widgetOptions.displayRules === false ? widgetOptions.displayRules = widgetOptions.displayRules : widgetOptions.displayRules = true;
}
/**================================================================================================
** enableSubmitBtn
*? disable the submit button if the form can not validate or if there is no items?
*@param isTrue bool
*================================================================================================**/
function enableSubmitBtn(isTrue) {
$('#icon-submit').dxButton('option', 'disabled', isTrue)
}
/**================================================================================================
** Onload
*================================================================================================**/
$(function () {
//page level vars
let isNewNote = false;
var salesOrderNumber = '';
let saveNoteTracker = 0;
//NOTE Template get underscore
DevExpress.setTemplateEngine('underscore');
_.templateSettings.variable = 'item';
setWidgetOptionDefaults(widgetOptions);
$('#returnHistoryBtn').dxButton({
text: 'Return History',
type: "default",
stylingMode: "contained",
elementAttr: {
class: "default_btn_class DT-Button"
},
onClick: function (e) { document.location = SITE_PATHS.application + '/ReturnHistory.aspx'; }
});
/**================================================================================================
** Sales order input
*================================================================================================**/
var txtImportOrder = $('#salesOrderNumberLookup').dxTextBox({
placeholder: widgetOptions.salesOrderPlaceholder,
onValueChanged: function (e) {
salesOrderNumber = e.value;
},
onEnterKey: function (e) {
var textBox = e.component;
textBox.blur();
getOrderDetails(salesOrderNumber);
textBox.focus();
},
buttons: [{
name: 'import',
location: 'after',
options: {
text: 'Import',
type: 'default',
stylingMode: 'text',
elementAttr: { id: 'btnImportOrder', class: 'DT-Button' },
onClick: function () {
getOrderDetails(salesOrderNumber);
txtImportOrder.focus();
}
}
}]
});
/**================================================================================================
* Stock code input
*================================================================================================**/
$('#skuNumber').dxAutocomplete({
dataSource: new DevExpress.data.CustomStore({
loadMode: "raw",
load: function () {
return $.getJSON("/ecommerce/exports/stockcodes.json");
}
}),
placeholder: 'Enter Product Number',
valueExpr: 'stockcode',
searchExpr: ['stockcode', 'name'],
itemTemplate: function (data, index) {
return data.stockcode + ' - ' + data.name;
},
showClearButton: true,
onEnterKey: function (e) {
e.component.blur();
StockCodeLookup(e.component.option('value'));
},
onValueChanged: function (data) { },
buttons: [{
name: 'add',
location: 'after',
options: {
text: 'Add',
type: 'default',
stylingMode: 'text',
elementAttr: { id: 'btnAddSku', class: 'DT-Button' },
onClick: function (e) {
StockCodeLookup($('#skuNumber').dxAutocomplete('option', 'value'));
}
}
}],
});
/**================================================================================================
** Note field (syspro Special instructions)
*================================================================================================**/
$('#rmaHeaderNote').dxTextArea({
value: '',
placeholder: 'Max length is 30 characters',
height: 34,
maxLength: 30,
onValueChanged(e) {
if (e.Value != e.previousValue) {
isNewNote = true;
}
},
onFocusOut(e) {
if (e.event.target.value.length >= 0 && isNewNote) {
PendingReturn.SpecialInstrs = e.event.target.value;
SaveReturnOptions(PendingReturn);
}
}
});
// .dxValidator({
// name: 'note',
// validationRules: [{
// type: 'required'
// }]
// });
/**================================================================================================
** SaveReturnOptions
*? save note input to SpecialInstrs field?
*@param PendingReturn returnObj
//NOTE {Branch, Fax, UserField1, SpecialInstructions, OrderType, AlternateKey, ServiceTicket}
*================================================================================================**/
function SaveReturnOptions({ Branch: B = '', Fax: F = '', UserField1: UF = '', SpecialInstrs: SI = '', OrderType: OT = '', AlternateKey: AK = '', ServiceTicket: ST = '' }) {
try {
MakeAJAXCall("Return.SaveReturnOptions", {
Branch: B,
Fax: F,
UserField1: UF,
SpecialInstructions: SI,
OrderType: OT,
AlternateKey: AK,
ServiceTicket: ST
}, function (DATA) {
if (ValidAJAXResponse(DATA)) {
var data = JSON.parse(DATA);
if (data.Result.Success) {
}
if (!data.Result.Success) {
if (saveNoteTracker < 3) {
saveNoteTracker++;
SaveReturnOptions(PendingReturn);
}
if (saveNoteTracker >= 3) {
ToastAlert(data.Result.Message, 'The note was not saved.', 3000);
}
}
}
})
} catch (error) {
console.log("Error: " + error);
}
}
/**================================================================================================
* functions for the file loader
*================================================================================================**/
var allowedExtensionsForUploadArray = []
allowedExtensionsForUploadArray = widgetOptions.allowedExtensionsForUpload.split(',');
var allowedExtensions = buildFileTypesArray(allowedExtensionsForUploadArray);
// update widget displays with widget info
$('.maxFileSizeDisplay_widgetOptions').html((widgetOptions.maxFileSize / 1000000) + ' MB');
$('.fileTypeDisplay_widgetOptions').html(buildDisplayString(allowedExtensions));
(widgetOptions.displayRules) ? $('note_widgetOptions').show() : $('.note_widgetOptions').hide();
/**================================================================================================
** buildDisplayString
*? display accepted file types?
*@param someArray array
*@return display of file types
*================================================================================================**/
function buildDisplayString(someArray) {
var html = '';
someArray.forEach(function (item, i, someArray) {
// if (i % 5 == 0) {
// if (i !== 0) { html += '</br>'; }
// }
html += item + ' ';
});
return html;
}
function buildFileTypesArray(anArray) {
var returnArray = [];
// if (anArray.length <= 0) {
// returnArray = ['.jpg', '.jpeg', '.gif', '.png', '.pdf']; // default file types
// }
if (anArray.length > 0) {
returnArray = anArray.map(item => item.replace(/\s/g, ''));
returnArray = returnArray.map(function (item) {
if (item.startsWith('.')) {
return item;
}
if (!item.startsWith('.')) {
var newItem = '.' + item;
return newItem;
}
})
}
return returnArray;
}
/**================================================================================================
* * Build file upoader
* widgetOptions.strObscureFilename
* widgetOptions.filePrefix
* widgetOptions.fileSuffix
* widgetOptions.maxFileSize
* widgetOptions.displayRules
* widgetOptions.selectButtonText: 'Click or Drop File here',
*
*================================================================================================**/
var returnFormFileUplpader = $('#ReturnFileUploaderContainer').dxFileUploader({
uploadMode: 'useButtons',
maxFileSize: widgetOptions.maxFileSize,
selectButtonText: widgetOptions.selectButtonText,
invalidFileExtensionMessage: 'File type is not allowed',
invalidMaxFileSizeMessage: 'File is too large',
allowedFileExtensions: allowedExtensions,
showFileList: true,
uploadButtonText: '',
labelText: '',
multiple: widgetOptions.allowMultipleFiles
}).dxFileUploader('instance');
/**================================================================================================
* Submit Return button
*================================================================================================**/
$('#icon-submit').dxButton({
text: widgetOptions.submitButtonText,
elementAttr: {
class: "default_btn_class DT-Button"
},
onClick: function (e) {
var result = e.validationGroup.validate();
DevExpress.validationEngine.validateGroup();
if (result.isValid) {
enableSubmitBtn(result.isValid);
//NOTE confirm the note has been saved
MakeAJAXCall("Return.PostReturn", {
Options: {}
}, function (DATA) {
if (ValidAJAXResponse(DATA)) {
let data = JSON.parse(DATA);
if (data.Result.Success) {
let fileNamePrefix = '';
if (widgetOptions.AddReturnNumberToFileName) {
fileNamePrefix = `${widgetOptions.fileUploadPrefix}${data.Data.RMANumber}_`;
}
if (!widgetOptions.AddReturnNumberToFileName) {
fileNamePrefix = `${widgetOptions.fileUploadPrefix}`;
}
//NOTE save file if uploaded
$('#ReturnFileUploaderContainer').dxFileUploader("instance").option('uploadUrl', FileUploadUtil(widgetOptions.strObscureFilename, fileNamePrefix, widgetOptions.fileUploadSuffix));
$('#ReturnFileUploaderContainer').dxFileUploader("instance").upload();
$('#ReturnFileUploaderContainer').dxFileUploader("instance").reset();
$("#rmaHeaderNote").dxTextArea("instance").reset();
createPopup(data.Data.RMANumber);
LoadReturnList_widgetID([]);
ScrollTop();
}
else {
// we had an error submitting the form
ToastAlert(data.Result.Message, data.Result.Success, 5000);
}
}
});
}
if (!result.isValid) {
//enableSubmitBtn(result.isValid);
// $('#icon-submit').dxButton('option', 'disabled', )
var msg = 'A required field is missing a value.'
if (result.brokenRules.length > 1) {
msg = result.brokenRules.length + ' required fields are missing values.'
}
ToastAlert(msg, result.isValid, 3000);
}
}
});
/**================================================================================================
** Build and fill return line detail list
*================================================================================================**/
ReturnListWidget_widgetID = $('#returnListWidgetDiv').dxList({
height: 'auto',
itemTemplate: $('#itemTemplate'),
noDataText: '',
allowItemDeleting: true,
noDataText: 'Start your return request by entering an Order or Product number above.',
onInitialized: function (e) {
// load the currently pending return detail lines into the widget
MakeAJAXCall("Return.GetPendingReturn", {}, function (DATA) {
if (ValidAJAXResponse(DATA)) {
var data = JSON.parse(DATA);
AllProblemCodes = data.LookupData.ProblemCodes;
DefaultProblemCode = data.LookupData.DefaultProblemCode;
PendingReturn = data.Data;
LoadReturnList_widgetID(data.Data.Details);
}
})
},
onItemDeleted: function (e) {
// delete the line from the pending return
MakeAJAXCall('Return.DeleteReturnLine', { ID: e.itemData.ID }, function (DATA) {
if (ValidAJAXResponse(DATA)) {
var data = JSON.parse(DATA);
LoadReturnList_widgetID(data.Data.Details);
}
});
}
}).dxList('instance');
// }
///-------------------------------------------------------------------------------------------------
/// <summary>
/// Gets order details.
/// </summary>
///
/// <param name="salesOrderNumber">
/// The sales order number.
/// </param>
///
/// <returns>
/// .
/// </returns>
///-------------------------------------------------------------------------------------------------
function getOrderDetails(salesOrderNumber) {
MakeAJAXCall('Order.GetOrder', { OrderNumber: salesOrderNumber }, function (DATA) {
if (ValidAJAXResponse(DATA)) {
var d = JSON.parse(DATA);
if (_.isEmpty(d.Data)) {
ToastAlert(d.Result.Message, false);
}
AddOrderToReturn(d.Data.Details);
}
});
}
///-------------------------------------------------------------------------------------------------
/// <summary>
/// Adds an order to the return
/// </summary>
///
/// <param name="dataSource">
/// The data source.stoc
/// </param>
/// <returns>
/// .
/// </returns>
///-------------------------------------------------------------------------------------------------
function AddOrderToReturn(dataSource) {
var items = [];
dataSource.forEach(function (detail) {
items.push({
StockCode: detail.StockCode,
Qty: detail.Quantity,
UOM: String.Format('@{0}', detail.UOM),
PurchaseDate: '',
SerialNumber: '',
Options: {}
})
});
MakeAJAXCall("Return.AddItemsToReturn", { Items: items }, function (DATA) {
if (ValidAJAXResponse(DATA)) {
var data = JSON.parse(DATA);
LoadReturnList_widgetID(data.Data.Details);
}
});
$('#salesOrderNumberLookup').dxTextBox('option', 'value', '');
}
///-------------------------------------------------------------------------------------------------
/// <summary>
/// Perform the stock code lookup, and add the item to the return list
/// </summary>
///
/// <param name="stockCode">
/// The stock code.
/// </param>
///
/// <returns>
/// confirms that the item number is not null
/// </returns>
///-------------------------------------------------------------------------------------------------
function StockCodeLookup(stockCode) {
if (stockCode === null || stockCode === undefined || (stockCode.trim()).length <= 0) {
$('#skuNumber').dxAutocomplete('option', 'isValid', false);
setTimeout(function () {
$('#skuNumber').dxAutocomplete('option', 'isValid', true);
}, 7000);
ToastAlert('A product number is required.', false, 5000, 5000);
return;
}
stockCode = stockCode.replace(/[\f\n\r\t\v]+/g, '');
$('#skuNumber').dxAutocomplete('option', 'isValid', true)
//NOTE the input exists good or bad look up the stockCode and get response
MakeAJAXCall('Inventory.GetItemByStockCode', {
StockCode: stockCode
}, function (DATA) {
let returnedItem = { StockCode: '', NonStockedItem: false }
if (DATA) {
var data = JSON.parse(DATA);
if (data.Results.Success) {
returnedItem.StockCode = data.StockCode,
returnedItem.NonStockedItem = false;
}
if (!data.Results.Success) {
returnedItem.StockCode = stockCode,
returnedItem.NonStockedItem = true;
}
addItemToReturnList(returnedItem)
}
})
}
///-------------------------------------------------------------------------------------------------
/// <summary>
/// Adds an item to return list.
/// </summary>
///
/// <param name="returnedItem">
/// { StockCode: string, NonStockedItem: bool }
/// </param>
///-------------------------------------------------------------------------------------------------
function addItemToReturnList(returnedItem) {
MakeAJAXCall("Return.AddItemToReturnByStockCode",
{
StockCode: returnedItem.StockCode,
Qty: 1,
UOM: 0,
PurchaseDate: '',
SerialNumber: '',
Options: {
NonStockItem: returnedItem.NonStockedItem,
}
}, function (DATA) {
if (ValidAJAXResponse(DATA)) {
var d = JSON.parse(DATA);
if (d.Result.Success) {
$('#skuNumber').dxAutocomplete('option', 'value', '');
LoadReturnList_widgetID(d.Data.Details);
} else {
ToastAlert(d.Result.Message, false);
}
}
$('#skuNumber').dxAutocomplete('instance').focus();
});
}
/**================================================================================================
** createPopup
*? create and display RMA popup?
*@param rmaNumber string
*@return dxPopup
*================================================================================================**/
function createPopup(rmaNumber) {
var popReturn = $('#popReturn').dxPopup({
contentTemplate: function (contentElement) {
contentElement.append(
$('<h2 />').text(`${widgetOptions.popupHeader}`),
$('<h4 />').text(`RMA Number: ${rmaNumber}`),
$('<p />').text(`${widgetOptions.popupText}`)
)
},
animation: {
show: {
delay: 125,
type: 'pop',
duration: 400
}
},
height: 'auto',
width: '600px',
visible: false,
showTitle: false,
closeOnOutsideClick: true,
resizeEnabled: true,
dragEnabled: true,
elementAttr: {
class: 'thankYouPopup'
},
toolbarItems: [{
widget: 'dxButton',
toolbar: 'bottom',
location: 'after',
options: {
text: widgetOptions.popupButtonText,
type: 'success',
stylingMode: 'contained',
onClick: function (e) {
popReturn.hide();
},
elementAttr: {
class: 'btn-primary DT-Button'
},
}
}]
}).dxPopup('instance');
popReturn.show();
}
});
///-------------------------------------------------------------------------------------------------
/// <summary>
/// Check options and custom data objects exist in a ReturnData member.
/// </summary>
///
/// <param name="index">
/// Zero-based index of the.
/// </param>
///
/// <returns>
/// .
/// </returns>
//NOTE this function is not used in the base version but could be used if custome data in utilized
///-------------------------------------------------------------------------------------------------
function CheckOptions(index) {
if (_.isUndefined(ReturnData_widgetID[index].Options)) {
ReturnData_widgetID[index].Options = {};
}
if (_.isUndefined(ReturnData_widgetID[index].Options.CustomData)) {
ReturnData
ReturnData_widgetID[index].Options.CustomData = {};
}
}
/**================================================================================================
** BuildRowWidgets
*? Builds and fills the line detail widgets?
*@param item array - return line detail
*@return type
*================================================================================================**/
function BuildRowWidgets(item) {
/**------------------------------------------------------------------------------------------------
* QTY input
*------------------------------------------------------------------------------------------------**/
$('#qty_' + item.ID).dxNumberBox({
mode: 'number',
min: 1,
value: item.Quantity,
showSpinButtons: true,
onValueChanged: function (e) {
var r = IndexOfByAttrValue(ReturnData_widgetID, 'ID', item.ID);
ReturnData_widgetID[r].Quantity = e.value;
UpdateReturnLine_widgetID(r);
}
}).dxValidator({
name: 'Quantity',
validationRules: [{
type: 'required'
}]
});
/**------------------------------------------------------------------------------------------------
* New Return reason with Problem codes
*------------------------------------------------------------------------------------------------**/
$('#reason_' + item.ID).dxSelectBox({
dataSource: AllProblemCodes,
displayExpr: 'DisplayText',
valueExpr: 'Code',
placeholder: 'Select One',
onInitialized: function (e) {
if (item.ProblemCode === '' && DefaultProblemCode !== '') {
e.component.option('value', DefaultProblemCode);
item.ProblemCode = DefaultProblemCode;
}
if (item.ProblemCode !== '') {
e.component.option('value', item.ProblemCode);
}
},
onValueChanged: function (e) {
var r = IndexOfByAttrValue(ReturnData_widgetID, 'ID', item.ID);
ReturnData_widgetID[r].ProblemCode = e.value;
UpdateReturnLine_widgetID(r);
}
}).dxValidator({
name: 'Reason',
validationRules: [{
type: 'required'
}]
});
/**================================================================================================
* Line item notes
*================================================================================================**/
$('#note_' + item.ID).dxTextArea({
placeholder: "Add a note",
height: 45,
onInitialized: function (e) {
if (!_.isUndefined(item.ProblemNotes)) {
e.component.option('value', item.ProblemNotes);
}
},
maxLength: 250,
onValueChanged(e) {
var r = IndexOfByAttrValue(ReturnData_widgetID, 'ID', item.ID);
//CheckOptions(r);
ReturnData_widgetID[r].ProblemNotes = e.component.option('value')
UpdateReturnLine_widgetID(r);
}
}).dxValidator({
name: 'Line Note',
validationRules: [{
type: 'required'
}]
});;
/**================================================================================================
* RMA type hidden
*================================================================================================**/
$('#rmaType_' + item.ID).dxTextBox({
value: 'General Return',
readOnly: true,
visible: false,
onValueChanged: function (e) {
}
});
}
</script>
<!------------------------------------------ Line detail template template ------------------------------------------>
<!--NOTE use underscore template to build display -->
<script type='text/html' id='itemTemplate'>
<div class='row rmaRow'>
<div class='image'>
<img src='<%= item.Photo1 %>' />
</div>
<div class='dataRows'>
<div class='dataRowOne'>
<div class='details'>
<div class='name'> <%= item.Description %></div>
<div class='stockcode'><%= item.StockCode %></div>
</div>
<div class="selectWrapper">
<div class='rowQty' id='qty_<%= item.ID %>'></div>
<div class='rowSelect' id='reason_<%= item.ID %>'></div>
<div class='rowTextArea' id='note_<%= item.ID %>'></div>
<div id='rmaType_<%= item.ID %>'></div>
</div>
</div>
<!-- <div class='dataRowTwo'>
<div id='condition_<%= item.ID %>'></div>
<div id='rmaType_<%= item.ID %>'></div>
</div> -->
</div>
</div>
<% $(function () { BuildRowWidgets(item); }); %>
</script>