Skip to content

Instantly share code, notes, and snippets.

@michoelchaikin
Last active December 7, 2018 20:56
Show Gist options
  • Save michoelchaikin/cb0632060be368943bf6a7e8e1f34534 to your computer and use it in GitHub Desktop.
Save michoelchaikin/cb0632060be368943bf6a7e8e1f34534 to your computer and use it in GitHub Desktop.
Lookup History Netsuite Customization
/**
* Client side code for Lookup History customization
*
* Script Type: Client Script
* Deployed to: <not deployed>
*
*/
'use strict';
function mos_lookup_history_closeorder(id, lineuniquekey) {
Ext.Msg.confirm('Confirm close order?', 'Are you sure you would like to close this order line?', function(btn) {
if (btn === 'yes') {
// Avoid the standard NetSuite warning message when navigating away (http://blog.prolecto.com/2016/10/29/video-learn-how-to-avoid-do-you-want-to-leave-this-site-message/)
if (window.onbeforeunload) {
window.onbeforeunload = function() {
null;
};
}
var url = nlapiResolveURL('SUITELET', 'customscript_mos_lookup_history_sl', 'customdeploy_mos_lookup_history_sl')
+ '&custom_item=' + nlapiGetFieldValue('item')
+ '&custom_recordtype=' + nlapiGetFieldValue('recordtype')
+ '&custom_closeorder=' + id
+ '&custom_lineuniquekey=' + lineuniquekey
+ '&ifrmcntnr=T'; // remove the form title, added by nlExtOpenWindow() so added here for uniformity
window.top.document.getElementById('mos_lookup_history_frame').src = url;
}
});
}
function mos_lookup_history_selectline(line) {
var recordtype = nlapiGetFieldValue('recordtype');
var linenum = nlapiGetFieldValue('linenum');
var rate = nlapiGetLineItemValue('history', 'rate', line);
var vendor = nlapiGetLineItemValue('history', 'vendor', line);
if (line > nlapiGetLineItemCount('history')) {
return;
}
switch (recordtype) {
case 'salesorder':
case 'estimate':
case 'invoice':
case 'cashsale':
case 'purchaseorder':
window.parent.nlapiSetCurrentLineItemValue('item', 'price', '-1');
window.parent.nlapiSetCurrentLineItemValue('item', 'rate', rate);
break;
case 'orderdispatch':
window.parent.nlapiSetLineItemValue('item', 'rate', linenum, rate);
break;
case 'purchasewizard':
window.parent.nlapiSetCurrentLineItemValue('suppliers', 'custpage_supplier', vendor);
window.parent.nlapiSetCurrentLineItemValue('suppliers', 'custpage_itemrate', rate);
window.parent.nlapiSelectLineItem('suppliers', parseInt(window.parent.nlapiGetCurrentLineItemIndex('suppliers')) + 1);
break;
}
window.parent.Ext.WindowMgr.getActive().close();
}
function mos_lookup_history_pageinit() {
// Ensure the iframe grabs the focus after it is loaded so the keyboard shortcuts work
window.focus();
Mousetrap.bind('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'.split(''), function(e) {
var line = (e.charCode > 96) ? e.charCode - 96 : e.charCode - 64;
mos_lookup_history_selectline(line);
});
Mousetrap.bind('esc', function(e) {
window.top.Ext.WindowMgr.getActive().close();
});
}
// It looks like NS doesn't load libraries if a Client Script is not loaded from a Deployment, so for now it is manually included here
/* mousetrap v1.5.3 craig.is/killing/mice */
(function(C,r,g){function t(a,b,h){a.addEventListener?a.addEventListener(b,h,!1):a.attachEvent("on"+b,h)}function x(a){if("keypress"==a.type){var b=String.fromCharCode(a.which);a.shiftKey||(b=b.toLowerCase());return b}return l[a.which]?l[a.which]:p[a.which]?p[a.which]:String.fromCharCode(a.which).toLowerCase()}function D(a){var b=[];a.shiftKey&&b.push("shift");a.altKey&&b.push("alt");a.ctrlKey&&b.push("ctrl");a.metaKey&&b.push("meta");return b}function u(a){return"shift"==a||"ctrl"==a||"alt"==a||
"meta"==a}function y(a,b){var h,c,e,g=[];h=a;"+"===h?h=["+"]:(h=h.replace(/\+{2}/g,"+plus"),h=h.split("+"));for(e=0;e<h.length;++e)c=h[e],z[c]&&(c=z[c]),b&&"keypress"!=b&&A[c]&&(c=A[c],g.push("shift")),u(c)&&g.push(c);h=c;e=b;if(!e){if(!k){k={};for(var m in l)95<m&&112>m||l.hasOwnProperty(m)&&(k[l[m]]=m)}e=k[h]?"keydown":"keypress"}"keypress"==e&&g.length&&(e="keydown");return{key:c,modifiers:g,action:e}}function B(a,b){return null===a||a===r?!1:a===b?!0:B(a.parentNode,b)}function c(a){function b(a){a=
a||{};var b=!1,n;for(n in q)a[n]?b=!0:q[n]=0;b||(v=!1)}function h(a,b,n,f,c,h){var g,e,l=[],m=n.type;if(!d._callbacks[a])return[];"keyup"==m&&u(a)&&(b=[a]);for(g=0;g<d._callbacks[a].length;++g)if(e=d._callbacks[a][g],(f||!e.seq||q[e.seq]==e.level)&&m==e.action){var k;(k="keypress"==m&&!n.metaKey&&!n.ctrlKey)||(k=e.modifiers,k=b.sort().join(",")===k.sort().join(","));k&&(k=f&&e.seq==f&&e.level==h,(!f&&e.combo==c||k)&&d._callbacks[a].splice(g,1),l.push(e))}return l}function g(a,b,n,f){d.stopCallback(b,
b.target||b.srcElement,n,f)||!1!==a(b,n)||(b.preventDefault?b.preventDefault():b.returnValue=!1,b.stopPropagation?b.stopPropagation():b.cancelBubble=!0)}function e(a){"number"!==typeof a.which&&(a.which=a.keyCode);var b=x(a);b&&("keyup"==a.type&&w===b?w=!1:d.handleKey(b,D(a),a))}function l(a,c,n,f){function e(c){return function(){v=c;++q[a];clearTimeout(k);k=setTimeout(b,1E3)}}function h(c){g(n,c,a);"keyup"!==f&&(w=x(c));setTimeout(b,10)}for(var d=q[a]=0;d<c.length;++d){var p=d+1===c.length?h:e(f||
y(c[d+1]).action);m(c[d],p,f,a,d)}}function m(a,b,c,f,e){d._directMap[a+":"+c]=b;a=a.replace(/\s+/g," ");var g=a.split(" ");1<g.length?l(a,g,b,c):(c=y(a,c),d._callbacks[c.key]=d._callbacks[c.key]||[],h(c.key,c.modifiers,{type:c.action},f,a,e),d._callbacks[c.key][f?"unshift":"push"]({callback:b,modifiers:c.modifiers,action:c.action,seq:f,level:e,combo:a}))}var d=this;a=a||r;if(!(d instanceof c))return new c(a);d.target=a;d._callbacks={};d._directMap={};var q={},k,w=!1,p=!1,v=!1;d._handleKey=function(a,
c,e){var f=h(a,c,e),d;c={};var k=0,l=!1;for(d=0;d<f.length;++d)f[d].seq&&(k=Math.max(k,f[d].level));for(d=0;d<f.length;++d)f[d].seq?f[d].level==k&&(l=!0,c[f[d].seq]=1,g(f[d].callback,e,f[d].combo,f[d].seq)):l||g(f[d].callback,e,f[d].combo);f="keypress"==e.type&&p;e.type!=v||u(a)||f||b(c);p=l&&"keydown"==e.type};d._bindMultiple=function(a,b,c){for(var d=0;d<a.length;++d)m(a[d],b,c)};t(a,"keypress",e);t(a,"keydown",e);t(a,"keyup",e)}var l={8:"backspace",9:"tab",13:"enter",16:"shift",17:"ctrl",18:"alt",
20:"capslock",27:"esc",32:"space",33:"pageup",34:"pagedown",35:"end",36:"home",37:"left",38:"up",39:"right",40:"down",45:"ins",46:"del",91:"meta",93:"meta",224:"meta"},p={106:"*",107:"+",109:"-",110:".",111:"/",186:";",187:"=",188:",",189:"-",190:".",191:"/",192:"`",219:"[",220:"\\",221:"]",222:"'"},A={"~":"`","!":"1","@":"2","#":"3",$:"4","%":"5","^":"6","&":"7","*":"8","(":"9",")":"0",_:"-","+":"=",":":";",'"':"'","<":",",">":".","?":"/","|":"\\"},z={option:"alt",command:"meta","return":"enter",
escape:"esc",plus:"+",mod:/Mac|iPod|iPhone|iPad/.test(navigator.platform)?"meta":"ctrl"},k;for(g=1;20>g;++g)l[111+g]="f"+g;for(g=0;9>=g;++g)l[g+96]=g;c.prototype.bind=function(a,b,c){a=a instanceof Array?a:[a];this._bindMultiple.call(this,a,b,c);return this};c.prototype.unbind=function(a,b){return this.bind.call(this,a,function(){},b)};c.prototype.trigger=function(a,b){if(this._directMap[a+":"+b])this._directMap[a+":"+b]({},a);return this};c.prototype.reset=function(){this._callbacks={};this._directMap=
{};return this};c.prototype.stopCallback=function(a,b){return-1<(" "+b.className+" ").indexOf(" mousetrap ")||B(b,this.target)?!1:"INPUT"==b.tagName||"SELECT"==b.tagName||"TEXTAREA"==b.tagName||b.isContentEditable};c.prototype.handleKey=function(){return this._handleKey.apply(this,arguments)};c.init=function(){var a=c(r),b;for(b in a)"_"!==b.charAt(0)&&(c[b]=function(b){return function(){return a[b].apply(a,arguments)}}(b))};c.init();C.Mousetrap=c;"undefined"!==typeof module&&module.exports&&(module.exports=
c);"function"===typeof define&&define.amd&&define(function(){return c})})(window,document);
/* eof (mousetrap.js) */
/**
* Quickly look up past order history during purchase and sale order entry.
*
* Script Type: Suitelet
*
*/
'use strict';
function addUnreceivedLink(text, isUnreceived, id, lineuniquekey) {
return isUnreceived
? "<a href='#' style='color: red; font-weight: bold; text-decoration: none' onclick='mos_lookup_history_closeorder(" + id + ", " + lineuniquekey + ");'>" + text + "</a>"
: text;
}
function addRecordLink(text, recordtype, id) {
return "<a target='_blank' style='text-decoration: none' href='" + nlapiResolveURL('RECORD', recordtype, id) + "'>" + text + "</a>";
}
function get_purchase_history(item, recordtype, message) {
var form = nlapiCreateForm('Purchase History', true);
form.setScript('customscript_mos_lookup_history_cs');
form.addField('item', 'text', 'Item').setDisplayType('hidden').setDefaultValue(item);
form.addField('recordtype', 'text', 'Record Type').setDisplayType('hidden').setDefaultValue(recordtype);
if (message) {
form.addField('message', 'inlinehtml').setDefaultValue(message);
}
var sublist = form.addSubList('history', 'list', 'Purchase History');
sublist.addField('kbshortcut', 'text');
sublist.addField('number', 'text', 'PO/Invoice #');
sublist.addField('companyname', 'text', 'Creditor');
sublist.addField('trandate', 'text', 'Date', 'left');
sublist.addField('quantityordered', 'float', 'Qty Ordered');
sublist.addField('quantityreceived', 'float', 'Qty Received');
sublist.addField('rate', 'currency', 'Rate');
sublist.addField('select', 'text', '');
sublist.addField('vendor', 'integer', '').setDisplayType('hidden');
var sublistValues = [];
nlapiCreateSearch(
'transaction',
[
[['type', 'anyOf', 'VendBill'], 'OR', [['type', 'anyOf', 'PurchOrd'], 'AND', ['quantitybilled', 'equalto', '0'], 'AND', ['closed', 'is', 'F']]],
'AND', ['quantity', 'greaterthan', 0],
'AND', ['item', 'anyOf', item]
],
[
new nlobjSearchColumn('formulatext').setFormula("CASE WHEN {type} = 'Bill' AND {createdfrom} IS NOT NULL THEN {createdfrom.number} ELSE {number} END"),
new nlobjSearchColumn('companyname', 'vendor'),
new nlobjSearchColumn('entityid', 'vendor'),
new nlobjSearchColumn('internalid', 'vendor'),
new nlobjSearchColumn('trandate').setSort(true),
new nlobjSearchColumn('quantity').setFunction('absoluteValue'),
new nlobjSearchColumn('formulanumeric').setFunction('absoluteValue').setFormula("DECODE({type}, 'Bill', {quantity}, {quantityshiprecv})"),
new nlobjSearchColumn('rate'),
new nlobjSearchColumn('lineuniquekey'),
])
.runSearch()
.forEachResult(function(result) {
var line = sublistValues.length + 1;
var id = result.getId();
var lineuniquekey = result.getValue('lineuniquekey');
var isUnreceived = (result.getRecordType() === 'purchaseorder' && parseFloat(result.getValue('quantity')) > parseFloat(result.getValue('formulanumeric')) );
sublistValues.push({
kbshortcut: (line <= 26) ? String.fromCharCode(sublistValues.length + 65) : '',
number: addRecordLink(result.getValue('formulatext'), result.getRecordType(), id),
companyname: addUnreceivedLink(result.getValue('companyname', 'vendor') + " (" + result.getValue('entityid', 'vendor') + ")", isUnreceived, id, lineuniquekey),
trandate: addUnreceivedLink(result.getValue('trandate'), isUnreceived, id, lineuniquekey),
quantityordered: result.getValue('quantity'),
quantityreceived: result.getValue('formulanumeric'),
rate: result.getValue('rate'),
select: "<a href='#' onclick='mos_lookup_history_selectline(" + line + ");'>Select</a>",
vendor: result.getValue('internalid', 'vendor'),
});
return (sublistValues.length < 50);
});
sublist.setLineItemValues(sublistValues);
return form;
}
function get_sales_history(entity, item, recordtype, linenum) {
var form = nlapiCreateForm('Sales History', true);
form.setScript('customscript_mos_lookup_history_cs');
form.addField('recordtype', 'text', 'Record Type').setDisplayType('hidden').setDefaultValue(recordtype);
form.addField('linenum', 'text', 'Line Num').setDisplayType('hidden').setDefaultValue(linenum);
var sublist = form.addSubList('history', 'list', 'Sales History');
sublist.addField('kbshortcut', 'text', '');
sublist.addField('number', 'text', 'Invoice #');
sublist.addField('otherrefnum', 'text', 'Customer Order #', 'left');
sublist.addField('trandate', 'date', 'Date', 'left');
sublist.addField('quantity', 'float', 'Quantity');
sublist.addField('rate', 'currency', 'Rate');
sublist.addField('select', 'text', 'Select');
var sublistValues = [];
nlapiCreateSearch(
'transaction',
[
['type', 'anyOf', ['CustInvc', 'CashSale', 'Estimate']],
'AND', ['accounttype', 'anyOf', 'Income'],
'AND', ['entity', 'anyOf', entity],
'AND', ['item', 'anyOf', item],
'AND', ['quantity', 'greaterthan', 0]
],
[
new nlobjSearchColumn('tranid'),
new nlobjSearchColumn('otherrefnum'),
new nlobjSearchColumn('trandate').setSort(true),
new nlobjSearchColumn('quantity'),
new nlobjSearchColumn('rate')
])
.runSearch()
.forEachResult(function(result) {
var line = sublistValues.length + 1;
sublistValues.push({
kbshortcut: (line <= 26) ? String.fromCharCode(sublistValues.length + 65) : '',
number: addRecordLink(result.getValue('tranid'), result.getRecordType(), result.getId()),
otherrefnum: result.getValue('otherrefnum'),
trandate: result.getValue('trandate'),
quantity: result.getValue('quantity'),
rate: result.getValue('rate'),
select: "<a href='#' onclick='mos_lookup_history_selectline(" + line + ");'>Select</a>"
});
return (sublistValues.length < 10);
});
sublist.setLineItemValues(sublistValues);
return form;
}
function checkParameters(recordtype, entity, item, linenum) {
if (!item) {
return false;
}
if (['salesorder', 'estimate', 'invoice', 'cashsale'].indexOf(recordtype) !== -1 && !entity) {
return false;
}
if (recordtype === 'orderdispatch' && !linenum) {
return false;
}
return true;
}
function closeOrderLine(id, lineuniquekey) {
try {
var record = nlapiLoadRecord('purchaseorder', id);
var line = record.findLineItemValue('item', 'lineuniquekey', lineuniquekey);
if (!line || line === -1) {
return 'Line not found on purchase order';
}
var quantityreceived = record.getLineItemValue('item', 'quantityreceived', line) || 0;
// Close or update qty on source PO
if (parseFloat(quantityreceived) > 0) {
record.setLineItemValue('item', 'quantity', line, quantityreceived);
} else {
record.setLineItemValue('item', 'isclosed', line, 'T');
}
nlapiSubmitRecord(record);
return 'Purchase order closed';
} catch (err) {
return 'An error occured when trying to close the purchase order: ' + err.message;
}
}
function suitelet(request, response) {
// Special "recordtypes" from other customizations - "orderdispatch", and "purchasewizard"
var recordtype = request.getParameter('custom_recordtype');
var entity = request.getParameter('custom_entity');
var item = request.getParameter('custom_item');
var linenum = request.getParameter('custom_linenum');
var closeorder = request.getParameter('custom_closeorder');
var lineuniquekey = request.getParameter('custom_lineuniquekey');
var message = null;
if (!checkParameters(recordtype, entity, item, linenum)) {
response.setContentType('PLAINTEXT');
response.write('Required parameters missing');
return;
}
if (closeorder && lineuniquekey) {
message = closeOrderLine(closeorder, lineuniquekey);
}
var form = (recordtype === 'purchaseorder' || recordtype === 'purchasewizard')
? get_purchase_history(item, recordtype, message)
: get_sales_history(entity, item, recordtype, linenum);
response.writePage(form);
}
/**
* Quickly look up past order history during purchase and sale order entry, client side script
*
* Script Type: Client Script
* Deployed to: Sales Order, Estimate, Invoice, Cash Sale, Purchase Order
*
*/
function mos_lookup_history_field_changed(type, name, linenum) {
if(type !== 'item' || name !== 'custcol_mos_lookup_history') {
return;
}
if(nlapiGetCurrentLineItemValue('item', 'itemtype') !== 'Description') {
var recordtype = nlapiGetRecordType();
var entity = nlapiGetFieldValue('entity');
var item = nlapiGetCurrentLineItemValue('item', 'item');
if(recordtype != 'purchaseorder' && ! entity) {
alert('You must select a customer before looking up history!');
} else if (! item) {
alert('You must select an item before looking up history!');
} else {
var url = nlapiResolveURL('SUITELET', 'customscript_mos_lookup_history_sl', 'customdeploy_mos_lookup_history_sl')
+ '&custom_item=' + item
+ '&custom_entity=' + entity
+ '&custom_recordtype=' + recordtype;
if(! Ext.WindowMgr.get('mos_lookup_history')) {
nlExtOpenWindow(url, 'mos_lookup_history', 750, 400, '', false, 'Product History');
}
}
}
nlapiSetCurrentLineItemValue('item', 'custcol_mos_lookup_history', 'F', false);
return false;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment