Skip to content

Instantly share code, notes, and snippets.

@michoelchaikin
Created March 8, 2018 22:11
Show Gist options
  • Save michoelchaikin/700db64bb0349380b26d274db1e6750e to your computer and use it in GitHub Desktop.
Save michoelchaikin/700db64bb0349380b26d274db1e6750e to your computer and use it in GitHub Desktop.
Product Search Suitelet
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<link rel="stylesheet" type="text/css"
href="https://cdn.datatables.net/r/zf-5.5.2/jq-2.1.4,dt-1.10.9/datatables.min.css"/>
<script type="text/javascript"
src="https://cdn.datatables.net/r/zf-5.5.2/jq-2.1.4,dt-1.10.9/datatables.min.js"></script>
<script>
"use strict";
//=include ./lib/localforage.min.js
window.onbeforeunload = () =>
'Consider leaving the Product Search page open to avoid having to wait for it to load!';
$(document).ready(() => {
$.fn.dataTable.ext.errMode = 'none';
const netSuiteProductLink = (id, label) => `<a href="/app/common/item/item.nl?id=${id}" target="_blank">${label}</a>`;
const websiteProductLink = (id, label) => `<a href="https://melbourneofficesupplies.com.au/products/view/${id}" target="_blank">${label}</a>`;
const table = $('#table_search')
.on('error.dt', function(e, settings, techNote, message) {
console.log('An error has been reported by DataTables: ', message);
})
.DataTable({
ajax: function(data, callback) {
localforage.getItem('product_data').then(value => ({ data: JSON.parse(value) || [] })).then(callback);
},
columns: [
{ title: 'Code', data: 'itemid', width: '10%', render: (data, type, row) => netSuiteProductLink(row['internalid'], data) },
{ title: 'Description', data: 'salesdescription', width: '40%' },
{ title: 'Supplier Code', data: 'vendorcode', width: '10%' },
{ title: 'Barcode', data: 'upccode', width: '5%' },
{ title: 'Search Keywords', data: 'custitem_store_search_keywords', width: '5%', searchable: true },
{ title: 'UOM', data: 'custitem_uom', width: '5%', searchable: false },
{ title: 'QOH', data: 'quantityonhand', width: '5%', searchable: false },
{ title: 'Last Cost', data: 'lastpurchaseprice', width: '5%', searchable: false },
{ title: 'Sell Price', data: 'baseprice', width: '5%', searchable: false },
{ title: 'Bin Location', data: 'custitem_bin_location_mos', width: '5%', searchable: true },
{ title: 'Avg Sales', data: 'custitem_mos_monthly_average', type: 'num', visible: false, searchable: false},
{ title: 'Status', width: '5%', render: (data, type, row) =>
(row['isinactive'] === 'T' ? '&nbsp;<span class="label alert">Inactive</span>': '') +
(row['isonline'] === 'T' ? `&nbsp;<span class="label success">${websiteProductLink(row['externalid'], 'Online')}</span>`: '') +
(row['custitem_discontinued'] === 'T' ? '&nbsp;<span class="label warning">Discontinued</span>': '') +
(row['custitem_subsites_only'] === 'T' ? '&nbsp;<span class="label secondary">Subsites Only</span>': '') },
],
order: [
[10, 'desc']
],
language: {
emptyTable: 'Loading.. please wait..'
},
});
let url = window.location.href;
url = url.replace('custom_request_type=html', 'custom_request_type=items');
const updateData = (() => {
$.get(url, data => {
localforage.setItem('product_data', data).then(() => table.ajax.reload(null, false));
});
})();
window.setInterval(updateData, 900000);
});
</script>
</head>
<body>
<div class="container">
<table id="table_search" class="display compact" cellspacing="0" width="100%">
</table>
</div>
</body>
</html>
/**
* Suitelet to make searching for stock codes really easy
*
* Script Type: Suitelet
*
*/
function getItems() {
const columns = [
'internalid',
'externalid',
'itemid',
'salesdescription',
'baseprice',
'lastpurchaseprice',
'custitem_uom',
'upccode',
'quantityonhand',
'vendorcode',
'isinactive',
'custitem_mos_monthly_average',
'custitem_bin_location_mos',
'isonline',
'custitem_store_search_keywords',
'custitem_discontinued',
'custitem_subsites_only',
];
const searchColumns = columns.map(column => new nlobjSearchColumn(column));
const search = nlapiCreateSearch('item', null, searchColumns);
const results = search.runSearch();
const items = [];
let slice = [];
let i = 0;
do {
slice = results.getResults(i, i + 1000);
slice.forEach(result => {
// convert nlobjSearchResult into simple js object
const item = {};
columns.forEach(column => (item[column] = result.getValue(column)));
items.push(item);
i++;
});
} while (slice.length >= 1000);
return items;
}
function suitelet(request, response) {
let result;
switch (request.getParameter('custom_request_type')) {
case 'items':
result = JSON.stringify(getItems());
response.write(result);
break;
case 'html':
result = nlapiLoadFile('SuiteScripts/Product Search/assets/mos_product_search.html').getValue();
response.write(result);
break;
default:
result = nlapiCreateForm('Product Search');
result.addField('content', 'inlinehtml', '').setDefaultValue(
`<iframe
style="display: block; height: 80vh; width: 100%; border: none;"
src="${nlapiResolveURL(
'SUITELET',
'customscript_mos_stock_code_search',
'customdeploy_mos_stock_code_search'
)}&custom_request_type=html"></iframe>`
);
response.writePage(result);
}
}
@AkberAlwani
Copy link

What exactly it does? can you put some pictures how it looks like
Can you also convert your code in 2.0 version
I like your help if you can like I wanted to create a suitelet with cascade assembly item list

@AkberAlwani
Copy link

I get Syntax error when trying to apply the script in my system.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment