Jira Code: PROT-176
This article includes the CSS, HTML, JS used for creating the single SO pickup screen. The screen is added to WMS lite. The HTML is used to list out all the items of SO where it groups the kit items as well as inventory items
<!DOCTYPE html>
<html>
<head>
<title>Single Sales Order Picking</title>
<!-- Jquery -->
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<!-- Ends -->
<!-- Bootstrap Starts -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script>
<!-- Bootstrap Ends -->
<!-- Google Fonts -->
<link href="https://fonts.googleapis.com/css?family=Open+Sans" rel="stylesheet">
<!-- Ends -->
<!-- Sweet-Alert2 CSS,JS -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/limonte-sweetalert2/7.33.1/sweetalert2.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/limonte-sweetalert2/7.33.1/sweetalert2.min.js"></script>
<!-- Ends -->
<!-- FOOTABLE -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jquery-footable/3.1.6/footable.core.standalone.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-footable/3.0.8/footable.min.js"></script>
<!-- -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-footable/3.0.8/footable.paging.min.js"></script>
<!-- Ends -->
<!-- Custom CSS,JS -->
<link rel="stylesheet" type="text/css" href="https://system.netsuite.com/core/media/media.nl?id=690627&c=1312745_SB1&h=969a5ed588d45a7d5125&_xt=.css">
<script src="https://system.netsuite.com/core/media/media.nl?id=690628&c=1312745_SB1&h=e460c9a847511f05ada6&_xt=.js"></script>
<!-- Ends -->
</head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<body>
<!-- <div class="alert alert-success">
<h1 class="title">Single SO Pickup</h1>
</div> -->
<div class="container" id="SOITEMS">
<div class="jumbotron mt-5">
<div class="row">
<div class="form-group col-sm-8 col-6" style="display: flex;">
<br>
<input type="text" class="form-control" id="SOID" placeholder="Enter SO#" name="SOID">
</div>
<div class="col-sm-4 col-6">
<button id="searchbtn" class="btn btn-success btn-block float-right">Submit SO#</button>
</div>
</div>
</div>
<div id="itemTable">
<div id="ItemTable">
</div>
</div>
<div class="row mt-3" id="Itembutton">
<div class="col-sm-6 col-md-4 col-6">
<button type="button" class="btn btn-success btn-lg btn-block" id="proceed">Proceed</button>
</div>
<div class="col-sm-6 col-md-4 col-6">
<button type="button" class="btn btn-danger btn-lg btn-block" id="cancel">Cancel</button>
</div>
</div>
</div>
</div>
<div class="container" id="LOT">
<div class="alert alert-primary mb-5 mt-5" role="alert">
<p id="itemName"></p>
<p id="picked"></p>
</div>
<div id="LotTable" class="mb-5 mt-5">
</div>
<div id="LotPage">
</div>
<div class="row mt-3">
<div class="col-sm-6 col-md-4 col-6">
<button type="button" class="btn btn-success btn-lg btn-block" id="Lotproceed">Proceed</button>
</div>
<div class="col-sm-6 col-md-4 col-6">
<button type="button" class="btn btn-danger btn-lg btn-block" id="Lotcancel">Cancel</button>
</div>
</div>
</div>
</div>
</body>
</html>
body {
font-family: 'Open Sans', sans-serif;
}
.pageTitle {
background-color: #5182d182;
height: 75px;
width: 100%;
}
.title {
/* margin-top: 0px;
color: #fff;
font-weight: bold;
vertical-align: middle;
line-height: 75px;*/
text-align: center;
}
.Search {
margin-top: 25px;
margin-bottom: 50px;
height: 125px;
width: 50%;
background-color: #adadad82;
position: relative;
left: 25%;
}
.SOinput {
width: 75% !important;
position: relative;
left: 12%;
}
.SOinputCenter {
line-height: 60px;
}
.Tocenter {
text-align: center;
vertical-align: middle;
}
.searchbtn {
padding: 6px 75px !important;
}
.buttongroup {
width: 50%;
float: right;
}
.focus {
background-color: #ff00ff;
color: #fff;
cursor: pointer;
font-weight: bold;
}
.pageNumber {
border: 1px solid #a7a9ab;
padding: 5px;
}
.pageNumber:hover {
cursor: pointer;
}
.page-item-selected {
border: 1px solid #a7a9ab;
padding: 5px;
background: #6495ed;
color: white;
font-weight: 600;
}
.fooicon-plus:before {
content: "\2b" !important;
}
.fooicon-minus:before {
content: "\2212" !important;
}
tfoot {
text-align: center;
}
var SOSerachURL = "/app/site/hosting/scriptlet.nl?script=569&deploy=1";
var LotSearchURL = "/app/site/hosting/scriptlet.nl?script=570&deploy=1";
var IFCreateURL = "/app/site/hosting/scriptlet.nl?script=571&deploy=1";
var ITEMS = {};
var LOTS = {};
$(function() {
$('#LOT').hide();
$('#Itembutton').hide();
$('#ItemPage').hide();
$('#searchbtn').click(function() {
Swal.showLoading();
ITEMS = {};
$('#itemTable').hide();
$('#ItemPage').hide();
$('#Itembutton').hide();
var SOID = $('#SOID').val().trim();
if (SOID != '') {
$.post(SOSerachURL, { so: SOID },
function(data, status) {
if (data == "FAILED")
Swal.fire({
type: 'info',
title: 'No Result Found',
text: 'Enter a valid SO#'
})
else {
ITEMS = JSON.parse(data);
var status = ITEMS[Object.keys(ITEMS)[0]].status;
if (status == "Billed") {
Swal.fire({
type: 'info',
title: 'SO Billed'
})
} else if (status == "Closed") {
Swal.fire({
type: 'info',
title: 'SO Closed'
})
} else if (status == "Partially Fulfilled") {
Swal.fire({
type: 'info',
title: 'SO Partially Fulfilled'
})
createTable(ITEMS);
} else
createTable(ITEMS);
//console.log(ITEMS)
}
});
} else {
Swal.fire({
type: 'error',
title: 'Oops...',
text: 'Enter SO#'
})
}
});
$('#Lotcancel').click(function() {
var summary = [];
var LotUsed = {};
ITEM_ID = $('#itemID').text();
ITEMS[ITEM_ID].summary = summary;
ITEMS[ITEM_ID]['Lots'] = LotUsed;
createTable(ITEMS);
$('#LOT').hide();
$('#SOITEMS').show();
});
$('#Lotproceed').click(function() {
var summary = [];
var LotUsed = {};
for (var key in LOTS) {
if (Number(LOTS[key].available) != 0) {
var qty = Number($('#' + key).val());
if (qty != 0) {
summary.push(LOTS[key].lot + ': ' + LOTS[key].bin.text + ': ' + '<b>' + qty + '</b>');
LotUsed[key] = { LotId: key, BinID: LOTS[key].bin.value, Quantity: qty };
}
}
}
ITEM_ID = $('#itemID').text();
ITEMS[ITEM_ID].summary = summary;
ITEMS[ITEM_ID]['Lots'] = LotUsed;
//console.log('ITEMS', ITEMS);
createTable(ITEMS);
$('#LOT').hide();
$('#SOITEMS').show();
});
$('#proceed').click(function() {
Swal.showLoading();
fetch(IFCreateURL, {
method: 'POST', // or 'PUT'
body: JSON.stringify(ITEMS), // data can be `string` or {object}!
headers: { 'Content-Type': 'application/json' }
}).then(function(res) {
console.log('res', res);
return res.json();
})
.then(function(response) {
console.log('Success:', JSON.stringify(response));
var data = response;
// console.log('data', data);
if (data.text == 'SUCCESS') {
Swal.close();
Swal.fire({
type: 'success',
title: 'Item Fulfillment Created: ' + data.value,
allowOutsideClick: false
}).then(function() {
window.location.reload();
})
} else if (data.text == 'FAIL') {
Swal.close();
Swal.fire({
type: 'error',
title: 'Pick items & Proceed'
});
} else {
Swal.close();
Swal.fire({
type: 'error',
title: 'Error in Creating Item fulfillment'
});
}
})
.catch(function(error) {
console.log('Error:', error)
Swal.close();
Swal.fire({
type: 'error',
title: 'Error in Creating Item fulfillment'
});
})
});
$('#cancel').click(function() {
window.location.reload();
})
});
function createTable(items) {
var create = false;
for (var key in items) {
if (Number(items[key].qty) > 0) {
create = true;
break;
}
}
if (create) {
$('#ItemPage').html('');
var table_body = '<table id="ItemTable" class="table table-bordered table-striped table-condensed table-hover table-sm" data-show-toggle="true" data-expand-first="false" data-paging="true" data-paging-size="3">';
table_body += "<thead>";
table_body += "<tr>";
table_body += " <th>Item</th>";
table_body += "<th>Qty to Pick</th>";
table_body += " <th data-breakpoints=\"xs sm\">Summary</th>";
table_body += " <th>Action</th>";
table_body += "</tr>";
table_body += "</thead>";
table_body += "</tbody>";
for (var key in items) {
if (items[key].type == 'InvtPart' && Number(items[key].qty) != 0) {
table_body += '<tr>';
table_body += '<td>';
table_body += items[key].name;
table_body += '</td>';
table_body += '<td>';
table_body += items[key].qty;
table_body += '</td>';
table_body += '<td>';
table_body += createList(items[key].summary);
table_body += '</td>';
table_body += '<td>';
if (createList(items[key].summary) == '---')
table_body += '<div><button class="btn btn-primary btn-sm" onclick="pickItem(' + items[key].id + ',' + items[key].qty + ',' + '\'' + items[key].name + '\'' + ')">Pick</button></div>';
else
table_body += '<div><button class="btn btn-danger btn-sm" onclick="pickItem(' + items[key].id + ',' + items[key].qty + ',' + '\'' + items[key].name + '\'' + ')">Picked</button></div>';
table_body += '</td>';
table_body += '</tr>';
}
}
table_body += '</tbody>';
table_body += '</table>';
$('#itemTable').html(table_body);
$('#ItemTable').footable({
"columns": [{
"type": "text"
},
{
"type": "text"
},
{
"type": "html"
}, {
"type": "html"
}
]
});
Swal.close();
$('#itemTable').show();
$('#Itembutton').show();
} else {
Swal.close();
Swal.fire({
type: 'info',
title: 'All items picked'
});
}
}
function pickItem(ITEM_ID, ITEM_QTY, ITEM_NAME) {
Swal.showLoading();
$.post(LotSearchURL, { itemId: ITEM_ID },
function(data, status) {
if (data == "")
Swal.fire({
type: 'error',
title: 'Oops...',
text: 'Something went wrong!!'
})
else if (data == 'FAILED')
Swal.fire({
type: 'info',
title: 'Item Not Available'
})
else {
LOTS = JSON.parse(data);
createLotTable(LOTS, ITEM_ID, ITEM_QTY, ITEM_NAME);
}
});
}
function createLotTable(lots, ITEM_ID, ITEM_QTY, ITEM_NAME) {
var create = false;
for (var key in lots) {
if (Number(lots[key].available) > 0) {
create = true;
break;
}
}
if (create) {
$('#ItemPage').hide();
var itemQty = 'Item Name: ' + ITEM_NAME + '(ID: <span id=\"itemID\">' + ITEM_ID + '</span>)' + ', Quantity to Pick: ' + ITEM_QTY;
var itemPickedMsg = "Quantity Picked: 0";
$('#itemName').html(itemQty);
$('#picked').text(itemPickedMsg);
var table_body = '<table id="lotTable" class="table table-bordered table-striped table-condensed table-hover table-sm">';
table_body += "<thead>";
table_body += "<tr>";
table_body += " <th>Bin</th>";
table_body += "<th>Lot</th>";
table_body += " <th>Available Qty</th>";
table_body += " <th>Pick Qty</th>";
table_body += "</tr>";
table_body += "</thead>";
table_body += "</tbody>";
for (var key in lots) {
if (Number(lots[key].available) != 0) {
var Onchange = "quantityPick(" + key + ",'" + escape(JSON.stringify(lots)) + "'," + ITEM_ID + "," + ITEM_QTY + ")";
table_body += '<tr>';
table_body += '<td>';
table_body += lots[key].bin.text;
table_body += '</td>';
table_body += '<td>';
table_body += lots[key].lot;
table_body += '</td>';
table_body += '<td>';
table_body += lots[key].available;
table_body += '</td>';
table_body += '<td>';
table_body += '<input type="number" id="' + key + '" min="0" max="' + ITEM_QTY + '" value="0" onchange="' + Onchange + '"></input>';
table_body += '</td>';
table_body += '</tr>';
}
}
table_body += '</tbody>';
table_body += '</table>';
Swal.close();
$('#SOITEMS').hide();
$('#LOT').show();
$('#LotTable').html(table_body);
} else {
Swal.close();
Swal.fire({
type: 'info',
title: 'Item Not Available'
})
}
}
function quantityPick(ID, lots, ITEM_ID, ITEM_QTY) {
var PickeQty = 0;
lots = JSON.parse(unescape(lots));
var SelectedQty = $('#' + ID).val();
if (Number(SelectedQty) > Number(lots[ID].available)) {
Swal.fire({
type: 'info',
title: 'Oops...',
text: 'Selected quantity not available at inventory'
});
$('#' + ID).val(0);
}
if (Number(SelectedQty) > Number(ITEM_QTY)) {
$('#' + ID).val(ITEM_QTY);
}
for (var key in lots) {
if (Number(lots[key].available) != 0) {
var qty = Number($('#' + key).val());
PickeQty += qty;
}
}
if (Number(PickeQty) > Number(ITEM_QTY)) {
Swal.fire({
type: 'error',
title: 'Oops...',
text: 'Picked Quantity is greater than Quantity to Pick'
})
$('#' + ID).val(0);
return false;
}
var itemPickedMsg = "Quantity Picked: " + PickeQty;
ITEMS[ITEM_ID]['PICKED'] = PickeQty;
ITEMS[ITEM_ID]['SetQty'] = PickeQty;
$('#picked').text(itemPickedMsg);
}
function createList(Summary) {
if (Summary == '---')
return Summary;
else if (Summary.length == 0)
return '---';
else {
var list = '<ul>';
for (var i = 0; i < Summary.length; i++) {
list += '<li>' + Summary[i] + '</li>';
}
list += '</ul>';
return list;
}
}