For this project, the client wanted custom notes added on inventory items and have all of these notes pooled into one field on Sales Orders and Quotes/Estimates. To accomplish this, a custom item field (custitem_notes) is created for the inventory items in Customization > List, Records, & Fields > Item Fields > New. This custom field will hold notes added to inventory items. A custom transaction body field (custbody_notes) is also added to the Sales Order and Quote/Estimate forms. Every time a line item is added or changed in these forms, all inventory item notes are reflected in the custom transaction body field (custbody_notes).
Client Script
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
/** *@NApiVersion 2.1 *@NScriptType ClientScript */ define(['N/record', 'N/search'], function (record, search) { function sublistChanged(context) { let curRec = context.currentRecord; let sublistId = context.sublistId; console.log(`Script Triggered: ${sublistId} changed.`); if (sublistId != "item") return; let itemIds = []; let lineCount = curRec.getLineCount({ sublistId: "item" }); for (let line = 0; line < lineCount; line++) { let itemId = curRec.getSublistValue({ sublistId: "item", fieldId: "item", line: line }); itemIds.push(itemId); } if (itemIds.length > 0) { let items = []; let itemSearchObj = search.create({ type: "item", filters: [ ["internalid", "anyof", itemIds] ], columns: [ search.createColumn({ name: "custitem_notes", label: "Notes" }), search.createColumn({ name: "internalid", label: "Internal ID" }), search.createColumn({ name: "itemid", label: "Name" }), search.createColumn({ name: "displayname", label: "Display Name" }) ] }); let searchResultCount = itemSearchObj.runPaged().count; log.debug("itemSearchObj result count", searchResultCount); itemSearchObj.run().each(function (result) { let itemObj = { note: result.getValue("custitem_notes"), name: result.getValue("displayname") } items.push(itemObj); return true; }); let noteBuilder = ""; console.log(items); if (items.length > 0) items.forEach((item) => { let noteVal = item.note; let itemName = item.name; if (noteVal == "") { let noteEmpty = "This item has no notes."; if (noteBuilder != "") noteBuilder += "nn" noteBuilder += "Item: " + itemName + "n" + noteEmpty; } if (noteVal != "") { if (noteBuilder != "") noteBuilder += "nn" noteBuilder += "Item: " + itemName + "n" + noteVal; } }); curRec.setValue({ fieldId: 'custbody_notes', value: noteBuilder }); } else { curRec.setValue({ fieldId: 'custbody_notes', value: "" }); } } return { sublistChanged: sublistChanged } }); |
Expected Behaviors
- A custom body field will be displayed under the Items subtab that will collect and display all the notes from the Inventory Items listed.
- For SO/Quotes with existing items, the Note field is empty on first page load. The Note field is populated if an item is edited/changed.
- The same behavior is expected when a new line item is added.
- Deleting items from the sublist also removes the corresponding notes from the Note field.
- Items without any notes are still included, with the placeholder message, “This item has no notes.”