Hi all, new-ish to SuiteScript but long-time admin...
# suitescript
a
Hi all, new-ish to SuiteScript but long-time admin here. I'm trying to write a map/reduce script that removes special characters from vendor name and vendor address fields. I have a function that removes special characters, but I don't think anything is happening when I try to set the "cleaned" value to the respective field. Any help much appreciated
/** * @NApiVersion 2.1 * @NScriptType MapReduceScript */ define(['N/record', 'N/search', 'N/log'], /** * @param{record} record * @param{search} search */ (record, search, log) => { const getInputData = (context) => { var vendorSearch = search.create({ type: record.Type.VENDOR, filters: ["datecreated","within","previousoneweek"], columns: ['internalid'] }); return vendorSearch; } function map(context) { log.debug('map context:', context) var vendorId = context.key; var vendorRecord = record.load({ type: record.Type.VENDOR, id: vendorId, isDynamic: true, }); // Get the name field var vendorName = vendorRecord.getValue({ fieldId: 'companyname' }); log.debug('company name', vendorName); var cleanedVendorName = cleanSpecialCharacters(vendorName); log.debug('cleaned company name', cleanedVendorName); vendorRecord.setValue({ fieldId: 'companyname', value: cleanedVendorName }); var lineCount = vendorRecord.getLineCount({sublistId: "addressbook"}); for(var i = 0; i < lineCount; i++){ var vendorAddress = vendorRecord.getSublistSubrecord({ sublistId: 'addressbook', fieldId: 'addressbookaddress', line: i }); var addr1 = vendorAddress.getValue({ fieldId: 'addr1' }); var city = vendorAddress.getValue({ fieldId: 'city' }); var addressee = vendorAddress.getValue({ fieldId: 'addressee' }); log.debug('addr1', addr1); var cleanedAddr1 = cleanSpecialCharacters(addr1); log.debug('cleanedAddr1', cleanedAddr1); var cleanedCity = cleanSpecialCharacters(city); var cleanedAddressee = cleanSpecialCharacters(addressee); vendorAddress.setValue({ fieldId: 'addr1', value: cleanedAddr1 }); vendorAddress.setValue({ fieldId: 'city', value: cleanedCity }); vendorAddress.setValue({ fieldId: 'addressee', value: cleanedAddressee }); } vendorRecord.save(); } /** * Utility function to remove special characters (including accent marks) from a string. * * @param {string} inputString - Input string with special characters * @returns {string} - String with special characters removed */ function cleanSpecialCharacters(inputString) { // Replace special characters and accent marks with their base characters return inputString.normalize('NFD').replace(/[\u0300-\u036f]/g, ''); } /** * Summarize the script execution. * * @param {Object} summary - Summary object * @returns {string} - Summary message */ function summarize(summary) { log.debug('Script Summary', 'Records processed: ' + summary.inputSummary.totalRecords); } return { getInputData: getInputData, map: map, summarize: summarize }; } );
n
Are you logs in your map stage outputting anything? Might be helpful to wrap the whole map stage in a try/catch and log errors in the catch. map/reduce scripts are weird about throwing errors in the map and reduce stage unless you explicitly tell it to log them
a
okay, will try that.. the only logs that output anything are "map context", "company name", and "cleaned company name" which all look good. no logs are output from anything in the for loop however
n
Ah yeah then it’s erroring in your address stuff probably. Then the record.save is never happening.
I think there’s also a way in summary context to get the errors from the map stage.
a
yeah, thanks for the tip on try/catch.. .. i'm now seeing that its saying it's an error on the "vendorRecord.getSubllistSubrecord is not a function
c
Is that a direct paste? The method is misspelled
n
I think they just mistyped. In the code it’s correct. First thing I checked lol
👍 1
a
ah I found it.. getSublistSubrecord is only available in standard mode, not dynamic
not sure why i would need dynamic anyway so i'll turn it off
n
Ohhhhh dynamic is getCurrentSublistSubrecord paired with a selectLine
n
I would always include error reporting in your summary. So many times people here say "my M/R doesn't work, I see no errors" and if they just did this it'd be much clearer what issue they have 🙂 Get Input Data will only ever have one error if it fails
Copy code
let gidError = summaryContext.inputSummary.error||'';
log.error('Input Error', gidError );
Map on the other hand could have several
Copy code
summary.mapSummary.errors.iterator().each(function (code, message) {
    log.error({title: 'Map Error : ' + code, details: message});
});
as can reduce:
Copy code
summary.reduceSummary.errors.iterator().each(function (key, error) {
    log.error('Reduce Error for key: ' + key, error);
    return true;
});