Scenario:
Create a journal for applying in the credit section of the payment.
Ultimate need is to capture the credit info from the custom record, need to create a journal or custom transaction of journal type then apply the same in the payment record.
We have seen a limitation of once payment is saved the credit subsist is not visible so need to see what are the script possibility and limitations.
Solution:
An alternate possibility is that if this can be done at the time of invoicing. Ie; when we create an invoice we can add a factoring fee along with it if it is needed. We can do it by creating a button. By clicking this button let’s add the factoring fee and submit the form. Then we can create a journal. So this journal can be applied along with the invoice. As per our requirement, this method can be technically feasible.
-Upon click add pop up suitlet with a check box by default unchecked and if the submit button. the navigate them to custoemr payment create page with that invocie seelcted as tru in the apply lines. like what happens if we click standard payment button in invoice , thtaz how i need to see the payment record in created mode if the checkbox is unchecked.
-IF the check box is clicked then show the factoring fee custom record entries to add as multiple lines in a suitlet and they enter it in multiple line and upon its submit create a journal in background and then open the payment page , auto selct that invoie and in the credit tab auto select that journal under the credit option.
For this we need 3 scripts.
One User event script for the click events, one client script for validations and a suitelet script for suitelets
JJ UE AddFactoringFeeButton TAG-89.js
/**
* @NApiVersion 2.1
* @NScriptType UserEventScript
*/
define(['N/error', 'N/record', 'N/search','N/runtime','N/ui/serverWidget'],
/**
* @param{error} error
* @param{record} record
* @param{search} search
* @param{runtime} runtime
* @param{serverWidget} serverWidget
*/
(error, record, search,runtime,serverWidget) => {
/**
* Defines the function definition that is executed before record is loaded.
* @param {Object} scriptContext
* @param {Record} scriptContext.newRecord - New record
* @param {string} scriptContext.type - Trigger type; use values from the context.UserEventType enum
* @param {Form} scriptContext.form - Current form
* @param {ServletRequest} scriptContext.request - HTTP request information sent from the browser for a client action only.
* @since 2015.2
*/
const beforeLoad = (scriptContext) => {
try {
log.debug("Record: ",scriptContext.newRecord)
log.debug("TYpe: ",scriptContext.type)
log.debug("ID: ",scriptContext.newRecord.id)
var rec = record.load({
type: record.Type.INVOICE,
id: scriptContext.newRecord.id
})
var status = rec.getValue({
fieldId: 'status'
})
log.debug("STATUS: ",status)
if(scriptContext.type == 'view' && status != 'Paid In Full'){
log.debug("in BeforeLoad")
var objForm = scriptContext.form
objForm.addButton({
id: 'custpage_factoringfee_btn',
label: 'Factoring Fee',
functionName: 'setFactoringFee'
})
objForm.clientScriptFileId = 2744
}
}
catch (e) {
log.debug("Error @ ",e.name+": "+e.message)
}
}
return {beforeLoad}
});
JJ CS FactoringFeeDetails TAG-89.js
/**
* @NApiVersion 2.1
* @NScriptType ClientScript
* @NModuleScope SameAccount
*/
define(['N/error', 'N/record', 'N/runtime', 'N/search','N/currentRecord','N/url'],
/**
* @param{error} error
* @param{record} record
* @param{runtime} runtime
* @param{search} search
* @param{currentRecord} currentRecord
* @param{url} url
*/
function(error, record, runtime, search, currentRecord, url) {
var curRec = currentRecord.get()
console.log("CUrRec: ",curRec)
console.log("id: ",curRec.id)
/**
* Function to be executed after page is initialized.
*
* @param {Object} scriptContext
* @param {Record} scriptContext.currentRecord - Current form record
* @param {string} scriptContext.mode - The mode in which the record is being accessed (create, copy, or edit)
*
* @since 2015.2
*/
function pageInit(scriptContext) {
return true;
}
/**
* Function to be executed after clicking the Factoring Fee button.
* this function redirects to the suitelet page
*/
function setFactoringFee(){
var sub = curRec.getValue({
fieldId: 'subsidiary'
})
var r = record.load({
type: record.Type.INVOICE,
id: curRec.id
})
console.log("Loaded Rec: ",r);
var vendName = r.getValue({
fieldId: 'entity'
})
var objParams = {
invoiceId: curRec.id,
subsidary: sub,
vendName: vendName
};
console.log("Sub: ",sub)
console.log("Vendor: ",vendName)
var output = url.resolveScript({
scriptId: 'customscript_jj_sl_factoringfee_suitelet',
deploymentId: 'customdeploy_jj_sl_factoringfee_suitelet',
params: objParams
});
// window.open("https://tstdrv2502342.app.netsuite.com/app/site/hosting/scriptlet.nl?script=231&deploy=1")
window.open(output)
console.log("INside fact")
}
/**
* Validation function to be executed when record is saved.
*
* @param {Object} scriptContext
* @param {Record} scriptContext.currentRecord - Current form record
* @returns {boolean} Return true if record is valid
*
* @since 2015.2
*/
function saveRecord(scriptContext) {
console.log("IN SAVE: ")
return true;
}
return {
pageInit: pageInit,
setFactoringFee: setFactoringFee,
saveRecord: saveRecord
};
});
JJ SL suiteletforFactoringFee TAG-89.js
/**
* @NApiVersion 2.1
* @NScriptType Suitelet
*/
define(['N/error', 'N/record', 'N/runtime', 'N/search', 'N/ui/serverWidget', 'N/https'],
/**
* @param{error} error
* @param{record} record
* @param{runtime} runtime
* @param{search} search
* @param{serverWidget} serverWidget
* @param{https} https
*/
(error, record, runtime, search, serverWidget, https) => {
/**
* Function for search operation for fetching accounts
* @param {subsidary} subsidary - subsidaryId
* @returns {resArr[{}]} - search result array of Objects
*/
function accountSearch(subsidary){
var accountSearchObj = search.create({
type: "account",
filters:
[
["subsidiary","anyof",subsidary],
"AND",
["type","anyof","Income","Expense","OthIncome","OthExpense"],
"AND",
["isinactive","is","F"],
"AND",
["issummary","is","F"]
],
columns:
[
search.createColumn({name: "internalid", label: "Internal ID"}),
search.createColumn({
name: "name",
sort: search.Sort.ASC,
label: "Name"
}),
search.createColumn({name: "displayname", label: "Display Name"}),
search.createColumn({name: "type", label: "Account Type"}),
search.createColumn({name: "description", label: "Description"}),
search.createColumn({name: "balance", label: "Balance"}),
search.createColumn({name: "custrecord_fam_account_showinfixedasset", label: "Show in Fixed Assets Management"})
]
});
var searchResultCount = accountSearchObj.runPaged().count;
log.debug("Result count",searchResultCount);
var resArr = []
accountSearchObj.run().each(function(result){
// .run().each has a limit of 4,000 results
var accId = result.getValue({
name: 'internalid'
});
var accountName = result.getValue({
name: 'name'
});
resArr.push({
accountId: accId,
accountName: accountName
})
return true;
});
return resArr
}
/**
* Defines the Suitelet script trigger point.
* @param {Object} scriptContext
* @param {ServerRequest} scriptContext.request - Incoming request
* @param {ServerResponse} scriptContext.response - Suitelet response
* @since 2015.2
*/
const onRequest = (scriptContext) => {
try{
var invoiceId = scriptContext.request.parameters.invoiceId
var subsidary = scriptContext.request.parameters.subsidary
var vendorName = scriptContext.request.parameters.vendName
log.debug("Iid: ",invoiceId)
log.debug("sub: ",subsidary)
log.debug("Vendor: ",vendorName)
var form = serverWidget.createForm({
title: 'Factoring Fee'
});
form.clientScriptFileId = 2744
if(scriptContext.request.method === 'GET') {
var res = accountSearch(subsidary)
log.debug("SEARCH RES: ",res)
var sublistFactoringFee = form.addSublist({
id: 'custpage_factoringfee',
type: serverWidget.SublistType.INLINEEDITOR,
label: 'Details'
});
var select = sublistFactoringFee.addField({
id: 'custpage_account',
type: serverWidget.FieldType.SELECT,
label: 'Account'
});
for(var i=0;i<res.length;i++){
select.addSelectOption({
value: res[i].accountId,
text: res[i].accountName
})
}
select.isMandatory = true
var amount = sublistFactoringFee.addField({
id: 'custpage_amount',
type: serverWidget.FieldType.CURRENCY,
label: 'Amount'
});
amount.isMandatory = true
var vendor = form.addField({
id:'custpage_vendor_name',
type: serverWidget.FieldType.TEXT,
label: 'Name'
});
vendor.defaultValue = vendorName
vendor.updateDisplayType({
displayType: serverWidget.SublistDisplayType.HIDDEN
})
var invoice = form.addField({
id: 'custpage_invoice_num',
type: serverWidget.FieldType.TEXT,
label: 'Invoice'
});
invoice.updateDisplayType({
displayType: serverWidget.SublistDisplayType.HIDDEN
});
invoice.defaultValue = invoiceId
var invSubsidary = form.addField({
id: 'custpage_invoice_subsidary',
type: serverWidget.FieldType.TEXT,
label: 'Subsidiary'
});
invSubsidary.updateDisplayType({
displayType: serverWidget.SublistDisplayType.HIDDEN
});
invSubsidary.defaultValue = subsidary
form.addSubmitButton({
label: 'Submit'
})
scriptContext.response.writePage(form);
}
if(scriptContext.request.method === 'POST') {
var inv = scriptContext.request.parameters.custpage_invoice_num
var invSub = scriptContext.request.parameters.custpage_invoice_subsidary
var vendorName = scriptContext.request.parameters.custpage_vendor_name
var count = scriptContext.request.getLineCount({
group: 'custpage_factoringfee'
})
log.debug("CNT: ",count)
var resultArr = []
var total = Number(0);
if(count>0){
for(var i=0;i<count;i++){
var account = scriptContext.request.getSublistValue({
group: 'custpage_factoringfee',
name: 'custpage_account',
line: i
});
var amount = scriptContext.request.getSublistValue({
group: 'custpage_factoringfee',
name: 'custpage_amount',
line: i
});
total+=Number(amount)
resultArr.push({
account: account,
amount: amount,
inv: inv,
invSub: invSub,
vendorName: vendorName
})
}
log.debug("Total: ",total)
log.debug("RESSS: ",resultArr)
if(resultArr.length>0){
for(var j=0;j<resultArr.length;j++){
var invoiceRecord = record.create({
type: 'customrecord_jj_cust_journal',
isDynamic: true
})
invoiceRecord.setValue({
fieldId: 'custrecord130',
value: resultArr[j].account
});
invoiceRecord.setValue({
fieldId: 'custrecord131',
value: resultArr[j].amount
});
invoiceRecord.setValue({
fieldId: 'custrecord132',
value: resultArr[j].inv
});
var saved = invoiceRecord.save();
log.debug("SAVED: ",saved)
}
journalCreation(resultArr,total)
}
}
scriptContext.response.write('<html><head></head><body><script>window.close()</script></body></html>')
}
}
catch (e) {
log.debug("Error: ",e)
}
}
/**
* Function for creating journal entry records
* @param {resultArr} resultArr - account search result Array
* @param {total} total - total factoring fee Amount which is to be added as credit section in Journal
*/
function journalCreation(resultArr,total){
log.debug("Inisde journal creation Function: ",resultArr)
var journalRec = record.create({
type: record.Type.JOURNAL_ENTRY,
isDynamic: true
})
journalRec.setValue({
fieldId: 'subsidiary',
value: resultArr[0].invSub
})
journalRec.setValue({
fieldId: 'custbody_jj_payment_link',
value: resultArr[0].inv
})
for(var i=0;i<resultArr.length;i++){
journalRec.selectNewLine({
sublistId: 'line'
})
journalRec.setCurrentSublistValue({
sublistId: 'line',
fieldId: 'account',
value: resultArr[i].account
})
journalRec.setCurrentSublistValue({
sublistId: 'line',
fieldId: 'debit',
value: resultArr[i].amount
})
journalRec.setCurrentSublistValue({
sublistId: 'line',
fieldId: 'entity',
value: resultArr[i].vendorName
})
journalRec.commitLine({
sublistId: 'line'
});
}
journalRec.selectNewLine({
sublistId: 'line'
})
journalRec.setCurrentSublistValue({
sublistId: 'line',
fieldId: 'account',
value: 129
})
journalRec.setCurrentSublistValue({
sublistId: 'line',
fieldId: 'credit',
value: total
})
journalRec.setCurrentSublistValue({
sublistId: 'line',
fieldId: 'entity',
value: resultArr[0].vendorName
})
journalRec.commitLine({
sublistId: 'line'
});
var journalSave = journalRec.save();
log.debug("SAVED REC DETAILS: ",journalSave)
}
return {onRequest}
});