Cretee a UserEvent Script
Eg: jj_ue_Custom_Tax_Calculation_RSPDC-1361.js
/**
* @NApiVersion 2.1
* @NScriptType UserEventScript
*/
define([‘N/record’],
/**
* @param{record} record
*/
(record) => {
/**
* 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) => {
let newRecord = scriptContext.newRecord;
let recordType=newRecord.type;
// log.debug(“recordType”,recordType);
if(recordType===“customrecord_jj_proforma_invoices”){
if (scriptContext.type == scriptContext.UserEventType.EDIT) {
let form = scriptContext.form;
form.addButton({
id: ‘custpage_jj_create_project’,
label: ‘Preview Tax’,
functionName: ‘previewTaxDetails’
});
log.debug(“Button Added”)
form.clientScriptModulePath = ‘./jj_cs_populate_tax_details_RSPDC-1361.js’;
log.debug(“Client Script Caalled”);
}
}
}
/**
* Defines the function definition that is executed before record is submitted.
* @param {Object} scriptContext
* @param {Record} scriptContext.newRecord – New record
* @param {Record} scriptContext.oldRecord – Old record
* @param {string} scriptContext.type – Trigger type; use values from the context.UserEventType enum
* @since 2015.2
*/
function beforeSubmit(context) {
var newRecord = context.newRecord;
let recordType=newRecord.type;
if (context.type !== context.UserEventType.CREATE && context.type !== context.UserEventType.EDIT) {
return;
}
// Get the customer ID from the transaction record
if(recordType===‘invoice’){
var placeofSupply = newRecord.getValue({ fieldId: ‘custbody_in_gst_pos’ });
log.debug(“placeofSupply”,placeofSupply);
var customerId = newRecord.getValue({ fieldId: ‘entity’ });
if (customerId) {
// Load customer record to check SIZ (SEZ) checkbox
var customerRecord = record.load({
type: record.Type.CUSTOMER,
id: customerId
});
// Check if the SIZ checkbox is enabled
var isSEZ = customerRecord.getValue({ fieldId: ‘custentity_jj_siz’ });
var custSubsidiary = customerRecord.getValue({ fieldId: ‘subsidiary’ });
log.debug(“custSubsidiary”,custSubsidiary);
log.debug(“isSEZ”,isSEZ);
if (isSEZ) {
// If SEZ is checked, set all tax-related fields to zero
var lineCount = newRecord.getLineCount({ sublistId: ‘item’ });
log.debug(“lineCount”,lineCount);
// Iterate through each tax detail line
for (var i = 0; i < lineCount; i++) {
// Set tax rate to 0% for each line
log.debug(“For loop Started”)
newRecord.setSublistValue({
sublistId: ‘item’,
fieldId: ‘custcol_in_hsn_code’, // Assuming ‘taxrate’ is the correct field ID
line: i,
value: ” // Setting the tax rate to 0%
});
}
}
}
}
}
/**
* Defines the function definition that is executed after record is submitted.
* @param {Object} scriptContext
* @param {Record} scriptContext.newRecord – New record
* @param {Record} scriptContext.oldRecord – Old record
* @param {string} scriptContext.type – Trigger type; use values from the context.UserEventType enum
* @since 2015.2
*/
const afterSubmit = (scriptContext) => {
}
return {beforeLoad, beforeSubmit, afterSubmit}
});
Create A Client Script
Eg: jj_cs_populate_tax_details_RSPDC-1361.js
/**
* @NApiVersion 2.1
* @NScriptType ClientScript
* @NModuleScope SameAccount
*/
define([‘N/search’, ‘N/record’, ‘N/ui/message’, ‘N/log’], function (search, record, message, log) {
/**
* Save record function for regular save logic
* @param {Object} context – Script context
* @returns {boolean} – Return true to continue saving
*/
function saveRecord(context) {
return true;
}
/**
* Preview the tax details by removing existing lines and adding new tax details
*/
function previewTaxDetails() {
let currentRecord = getCurrentRecord();
if (currentRecord) {
let recordType = currentRecord.type;
if (recordType === “customrecord_jj_proforma_invoices”) {
let sublist = ‘recmachcustrecord_jj_proforma_invoices_items’;
let taxSublist = ‘recmachcustrecord_jj_tax_details_new’;
try {
removeExistingTaxLines(currentRecord, taxSublist);
addTaxDetails(currentRecord, sublist, taxSublist);
message.create({
title: “Tax Preview”,
message: “Tax details have been previewed successfully!”,
type: message.Type.CONFIRMATION
}).show();
} catch (error) {
log.error(‘Error in previewTaxDetails’, error);
}
}
}
}
/**
* Get the current record object
* @returns {Object} – Current record object
*/
function getCurrentRecord() {
try {
let currentRecord = require(‘N/currentRecord’).get();
return currentRecord;
} catch (error) {
log.error(‘Error in getCurrentRecord’, error);
}
return null;
}
/**
* Remove all existing tax lines from the tax sublist
* @param {Object} currentRecord – The current record object
* @param {string} taxSublist – The tax sublist ID
*/
function removeExistingTaxLines(currentRecord, taxSublist) {
try {
let taxLineCount = currentRecord.getLineCount({ sublistId: taxSublist });
if (taxLineCount > 0) {
for (let j = taxLineCount – 1; j >= 0; j—) {
currentRecord.removeLine({
sublistId: taxSublist,
line: j,
ignoreRecalc: true
});
}
}
} catch (error) {
log.error(‘Error in removeExistingTaxLines’, error);
}
}
/**
* Add new tax details to the tax sublist based on the items in the invoice sublist
* @param {Object} currentRecord – The current record object
* @param {string} sublist – The invoice sublist ID
* @param {string} taxSublist – The tax sublist ID
*/
function addTaxDetails(currentRecord, sublist, taxSublist) {
try {
let lineCount = currentRecord.getLineCount({ sublistId: sublist });
let nexusProforma = currentRecord.getValue({ fieldId: “custrecord_jj_nexus” });
log.debug(“nexusProforma”, nexusProforma);
for (let i = 0; i < lineCount; i++) {
let itemData = getItemData(currentRecord, sublist, i);
let customerRecord = getCustomerRecord(itemData.customerID);
let subsidiaryRecord = getSubsidiaryRecord(customerRecord.getValue({ fieldId: ‘subsidiary’ }));
let transactionId = getTransactionId(
subsidiaryRecord.getText({ fieldId: ‘dropdownstate’ }).toLowerCase(),
itemData.placeOfSupply.split(‘-‘)[1].trim().toLowerCase()
);
let regType = getSubsidiaryRegType(subsidiaryRecord, nexusProforma);
let gstTaxRules = getGSTTaxRules(regType, itemData, customerRecord, transactionId);
gstTaxRules.run().each(function (result) {
addTaxLine(currentRecord, taxSublist, itemData, result);
return true;
});
}
} catch (error) {
log.error(‘Error in addTaxDetails’, error);
}
}
/**
* Retrieve item data from the invoice sublist
* @param {Object} currentRecord – The current record object
* @param {string} sublist – The sublist ID
* @param {number} index – Line index
* @returns {Object} – Item data object
*/
function getItemData(currentRecord, sublist, index) {
try {
let itemId = currentRecord.getSublistValue({ sublistId: sublist, fieldId: ‘custrecord_jj_line_item_items’, line: index });
let itemnameText = currentRecord.getSublistText({ sublistId: sublist, fieldId: ‘custrecord_jj_line_item_items’, line: index });
let hsnSacCodeID = currentRecord.getSublistValue({ sublistId: sublist, fieldId: ‘custrecord_jj_tax_hsn_sac_code’, line: index });
let lineAmount = currentRecord.getSublistValue({ sublistId: sublist, fieldId: ‘custrecord_jj_line_item_amount’, line: index });
let placeOfSupply = currentRecord.getText({ fieldId: ‘custrecord_jj_place_of_supply’ });
let customerID = currentRecord.getValue({ fieldId: ‘custrecord_jj_entity’ });
return { itemId, itemnameText, hsnSacCodeID, lineAmount, placeOfSupply, customerID };
} catch (error) {
log.error(‘Error in getItemData’, error);
}
return null;
}
/**
* Load the customer record by customer ID
* @param {number} customerID – The customer ID
* @returns {Object} – Customer record object
*/
function getCustomerRecord(customerID) {
try {
return record.load({
type: record.Type.CUSTOMER,
id: customerID
});
} catch (error) {
log.error(‘Error in getCustomerRecord’, error);
}
return null;
}
/**
* Load the subsidiary record by subsidiary ID
* @param {number} subsidiaryId – The subsidiary ID
* @returns {Object} – Subsidiary record object
*/
function getSubsidiaryRecord(subsidiaryId) {
try {
return record.load({
type: ‘subsidiary’,
id: subsidiaryId
});
} catch (error) {
log.error(‘Error in getSubsidiaryRecord’, error);
}
return null;
}
/**
* Get transaction ID based on state comparison
* @param {string} subsidiaryState – Subsidiary state
* @param {string} placeOfSupplyState – Place of supply state
* @returns {number} – Transaction ID
*/
function getTransactionId(subsidiaryState, placeOfSupplyState) {
try {
return (subsidiaryState === placeOfSupplyState) ? 1 : 2;
} catch (error) {
log.error(‘Error in getTransactionId’, error);
}
return null;
}
/**
* Retrieve the GST registration type for the subsidiary
* @param {Object} subsidiaryRecord – Subsidiary record object
* @param {string} nexusProforma – Nexus ID for the proforma invoice
* @returns {string|null} – Registration type
*/
function getSubsidiaryRegType(subsidiaryRecord, nexusProforma) {
try {
let subListId = ‘taxregistration’;
let lineCount = subsidiaryRecord.getLineCount({ sublistId: subListId });
for (let k = 0; k < lineCount; k++) {
let nexusLine = subsidiaryRecord.getSublistValue({ sublistId: subListId, fieldId: ‘nexus’, line: k });
if (nexusProforma == nexusLine) {
return subsidiaryRecord.getSublistValue({ sublistId: subListId, fieldId: ‘custpage_in_reg_type’, line: k });
}
}
} catch (error) {
log.error(‘Error in getSubsidiaryRegType’, error);
}
return null;
}
/**
* Retrieve GST tax rules based on item data and customer details
* @param {string} regType – Registration type
* @param {Object} itemData – Item data object
* @param {Object} customerRecord – Customer record object
* @param {number} transactionId – Transaction ID
* @returns {Object} – Search object for GST tax rules
*/
function getGSTTaxRules(regType, itemData, customerRecord, transactionId) {
try {
return search.create({
type: “customrecord_in_gst_tax_rate_rule”,
filters: [
[“custrecord_in_gst_rate_rule_com_reg_type”, “anyof”, regType],
“AND”,
[“custrecord_in_gst_rate_rule_available_on”, “anyof”, “2”],
“AND”,
[“custrecord_in_gst_rate_rule_vend_regtype”, “anyof”, customerRecord.getValue({ fieldId: ‘custentity_in_gst_vendor_regist_type’ })],
“AND”,
[“custrecord_in_gst_rate_rule_hsn_code”, “anyof”, itemData.hsnSacCodeID],
“AND”,
[“custrecord_in_gst_rate_rule_supply_class”, “anyof”, transactionId],
“AND”,
[“custrecord_in_gst_rate_rule_taxable”, “is”, “T”]
],
columns: [
search.createColumn({ name: “custrecord_in_gst_rate_rule_rate”, label: “GST Rate” }),
search.createColumn({ name: “custrecord_in_gst_rate_rule_tax_type”, join: “CUSTRECORD_IN_GST_RATE_RULE_FK”, label: “Tax Type” }),
search.createColumn({ name: “custrecord_in_gst_rate_rule_tax_code”, join: “CUSTRECORD_IN_GST_RATE_RULE_FK”, label: “Tax Code” }),
search.createColumn({ name: “custrecord_in_gst_rate_rule_tax_rate”, join: “CUSTRECORD_IN_GST_RATE_RULE_FK”, label: “Tax Rate” })
]
});
} catch (error) {
log.error(‘Error in getGSTTaxRules’, error);
}
return null;
}
/**
* Add a new tax line to the tax sublist
* @param {Object} currentRecord – The current record object
* @param {string} taxSublist – The tax sublist ID
* @param {Object} itemData – Item data object
* @param {Object} result – Tax rule search result
*/
function addTaxLine(currentRecord, taxSublist, itemData, result) {
try {
let taxRate = parseFloat(result.getValue({ name: “custrecord_in_gst_rate_rule_tax_rate”, join: “CUSTRECORD_IN_GST_RATE_RULE_FK” }).replace(‘%’, ”)).toFixed(0);
let taxAmount = (itemData.lineAmount * taxRate) / 100;
currentRecord.selectNewLine({ sublistId: taxSublist });
currentRecord.setCurrentSublistValue({
sublistId: taxSublist,
fieldId: ‘custrecord_line_type’,
value: ‘Item’,
ignoreFieldChange: true
});
currentRecord.setCurrentSublistValue({
sublistId: taxSublist,
fieldId: ‘custrecord_jj_name_tax’,
value: itemData.itemnameText,
ignoreFieldChange: true
});
currentRecord.setCurrentSublistValue({
sublistId: taxSublist,
fieldId: ‘custrecord_jj_net_amount’,
value: itemData.lineAmount,
ignoreFieldChange: true
});
currentRecord.setCurrentSublistValue({
sublistId: taxSublist,
fieldId: ‘custrecord_jj_tax_type’,
value: result.getValue({ name: “custrecord_in_gst_rate_rule_tax_type”, join: “CUSTRECORD_IN_GST_RATE_RULE_FK” }),
ignoreFieldChange: true
});
currentRecord.setCurrentSublistValue({
sublistId: taxSublist,
fieldId: ‘custrecord_jj_tax_code’,
value: result.getValue({ name: “custrecord_in_gst_rate_rule_tax_code”, join: “CUSTRECORD_IN_GST_RATE_RULE_FK” }),
ignoreFieldChange: true
});
currentRecord.setCurrentSublistValue({
sublistId: taxSublist,
fieldId: ‘custrecord_jj_tax_basis’,
value: itemData.lineAmount,
ignoreFieldChange: true
});
currentRecord.setCurrentSublistValue({
sublistId: taxSublist,
fieldId: ‘custrecord_jj_tax_rate’,
value: taxRate,
ignoreFieldChange: true
});
currentRecord.setCurrentSublistValue({
sublistId: taxSublist,
fieldId: ‘custrecord_jj_tax_amount’,
value: taxAmount,
ignoreFieldChange: true
});
currentRecord.commitLine({ sublistId: taxSublist });
} catch (error) {
log.error(‘Error in addTaxLine’, error);
}
}
return {
saveRecord: saveRecord,
previewTaxDetails: previewTaxDetails
};
});
Modify the Code According to your Requiremnt if needed
Deploy the user event Script in the respective Record.