Introduction
In the last post, we looked at the basics of the N/record
module in SuiteScript. We looked at loading, saving, and deleting records. We looked at getting and setting values. In this post we will look at getting and setting sublists and subrecords.
What is a Sublist?
A sublist is a lists of records, usually found in a subtab on a record. For example, Sales Orders and Item fulfillments have a sublist called item
. Here we list the items that are on the sales order or item fulfillment.
Some common sublists include:
item
(Sales Order, Item Fulfillment, Work Order, etc.)line
(Journal Entry)component
(Bom Revision)expense
(Bills, Invoices)
Because the methods for working will sublists depend on whether the record was loaded in standard or dynamic mode, we will look at each mode separately. The methods for standard mode also work in dynamic mode so we will start with standard mode. See this post for more information on standard and dynamic modes.
Standard Mode (and Dynamic Mode)
Getting a Sublist
Imagine our item
sublist for a Sales Order looks like this:
Item | Rate | Quantity | Amount |
---|---|---|---|
Item 1 | 10 | 1 | 10 |
Item 2 | 20 | 2 | 40 |
To get the rate
field on the item sublist (item
), we would use the record.getSublistValue
method.
1
2
3
4
5
6
7
8
9
10
const rec = record.load({
type: record.Type.SALES_ORDER,
id: 123
});
const item1Rate = rec.getSublistValue({
sublistId: 'item',
fieldId: 'rate',
line: 0
});
The getSublistValue
method takes in an object with the following properties:
- sublistId - The id of the sublist
- fieldId - The id of the field on the sublist
- line - The line number of the sublist
Suppose we want to get the whole sublist and put it in an array of objects:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
[
{
item: 'Item 1',
rate: 10,
quantity: 1,
amount: 10
},
{
item: 'Item 2',
rate: 20,
quantity: 2,
amount: 40
}
]
We would have to loop through the sublist and get each value. But how do we know the length of the sublist? This is where the getLineCount
method comes in.
1
2
3
4
5
const rec = record.load(...);
const lineCount = rec.getLineCount({
sublistId: 'item'
}) // 2 ;
Now we can loop through the sublist and get each value.
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
const rec = record.load(...);
const lineCount = rec.getLineCount({sublistId: 'item'}) // 2 ;
const items = [];
for(let i = 0; i < lineCount; i++) {
items.push({
item: rec.getSublistValue({
sublistId: 'item',
fieldId: 'item',
line: i
}),
rate: rec.getSublistValue({
sublistId: 'item',
fieldId: 'rate',
line: i
}),
quantity: rec.getSublistValue({
sublistId: 'item',
fieldId: 'quantity',
line: i
}),
amount: rec.getSublistValue({
sublistId: 'item',
fieldId: 'amount',
line: i
})
});
}
Setting a Sublist
To set a sublist value, we use the setSublistValue
method.
This method takes the same parameters as the getSublistValue
method, with the addition of a value
parameter.
1
2
3
4
5
6
7
8
const rec = record.load(...);
rec.setSublistValue({
sublistId: 'item',
fieldId: 'item',
line: 0,
value: 1111
});
Where 1111
is the internal id of the item record.
Now if we are setting a new line, we would select the line number as 1 greater than the current index.
1
2
3
4
5
6
7
8
9
const rec = record.load(...);
const lineCount = rec.getLineCount({sublistId: 'item'}) // 2 ;
rec.setSublistValue({
sublistId: 'item',
fieldId: 'item',
line: lineCount,
value: 1111
});
Remember the the line number is 0 based, so the lineCount
which is 2, is the 3rd line. We can then set the next line, using lineCount + 1
as the line number.
If we try to set a line that is more than 1 greater than the current index, we will get an error.
1
2
3
4
5
6
7
8
const rec = record.load(...);
rec.setSublistValue({
sublistId: 'item',
fieldId: 'item',
line: 10,
value: 1111
}); // Error: You have attempted an invalid sublist operation. You are either trying to access a field on a non-existent line or you are trying to add or remove lines from a static sublist.
Let’s suppose we want to add a line to the sublist in a certain position. So using our example above, we want to add a line between the first and second line.
We can use the insertLine
method to do this.
1
2
3
4
5
6
7
8
9
10
11
12
13
const rec = record.load(...);
rec.insertLine({
sublistId: 'item',
line: 1
});
rec.setSublistValue({
sublistId: 'item',
fieldId: 'item',
line: 1,
value: 1111
});
Removing a Sublist Line
To remove a sublist line, we use the removeLine
method.
1
2
3
4
5
6
const rec = record.load(...);
rec.removeLine({
sublistId: 'item',
line: 1
});
If we try to remove a line that does not exist, we will get an error.
1
2
3
4
5
6
const rec = record.load(...);
rec.removeLine({
sublistId: 'item',
line: 10
}); // Error: You have attempted an invalid sublist operation. You are either trying to access a field on a non-existent line or you are trying to add or remove lines from a static sublist.
Dynamic Mode
In dynamic mode we have the ability to work with sublists in a manner similar to working with sublists in the UI.
This means that we will “Select” a line and then work with it and then “Commit” the line.
Selecting a Line
To select a line, we use the selectLine
method.
1
2
3
4
5
const rec = record.load(...);
rec.selectLine({
sublistId: 'item',
line: 0
});
Now that line 0 (the first line) is selected, we can work with it using the getCurrentSublistValue
and setCurrentSublistValue
methods.
1
2
3
4
5
6
7
8
9
10
11
rec.setCurrentSublistValue({
sublistId: 'item',
fieldId: 'item',
value: 1111
});
rec.setCurrentSublistValue({
sublistId: 'item',
fieldId: 'quantity',
value: 10
});
Note that we did not have to specify the line number, since we already selected the line.
After we have set the values, we can commit the line using the commitLine
method.
1
2
3
rec.commitLine({
sublistId: 'item'
});
Now we will take a brief detour to discuss getting and setting subrecords which is a common task when working with sublists.
What is a Subrecord?
A subrecord is a record that is attached to another record. This does not include fields that you select a full record such as location
or subsidiary
. Subrecords are used specifically for records that store information about the main record.
Examples of subrecords include:
- Inventory Detail
- Landed Cost
- Addresses
Getting a Subrecord
Subrecords are retrieved using the getSubrecord
method of a loaded record.
1
2
3
4
5
6
7
8
const rec = record.load({
type: record.Type.SALES_ORDER,
id: 123
});
const subrec = rec.getSubrecord({
fieldId: 'shippingaddress'
});
This will get the shipping address subrecord for the sales order.
We now are able to query the subrecord for information.
1
2
3
4
5
const rec = record.load(...)
const subrec = rec.getSubrecord({ fieldId: 'shippingaddress' });
const shipcity = subrec.getValue({ fieldId: 'city' });
const shipstate = subrec.getValue({ fieldId: 'state' });
We can also set values on the subrecord.
1
2
3
4
const rec = record.load(...)
const subrec = rec.getSubrecord({ fieldId: 'shippingaddress' });
subrec.setValue({ fieldId: 'city', value: 'New York' });
subrec.setValue({ fieldId: 'state', value: 'NY' });
Subrecords do not have to saved; they are saved when the parent record is saved.
Some subrecords, such as the inventory detail subrecord, have their own sublists.
1
2
3
4
5
6
7
8
const rec = record.load(...) // Assembly Build
const subrec = rec.getSubrecord({ fieldId: 'inventorydetail' });
subrec.setSublistValue({
sublistId: 'inventoryassignment',
fieldId: 'quantity',
line: 0,
value: 10
});
Subrecords on Sublists
Many sublists have subrecords attached to them.
The method getSublistSubrecord
is used to get the subrecord for a sublist line.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
const rec = record.load(...) // Assembly Build
const subrec = rec.getSublistSubrecord({
sublistId: 'item',
fieldId: 'inventorydetail',
line: 0
});
subrec.setSublistValue({
sublistId: 'inventoryassignment',
fieldId: 'quantity',
line: 0,
value: 10
});
For dynamic mode, we can use the selectLine
method to select a sublist line and then use the getCurrentSublistSubrecord
method to get the subrecord for the selected line.
1
2
3
4
5
6
7
8
9
10
11
12
const rec = record.load(..., isDynamic: true) // Assembly Build
rec.selectLine({
sublistId: 'item',
line: 0
});
const subrec = rec.getCurrentSublistSubrecord({
sublistId: 'item',
fieldId: 'inventorydetail'
});
Note that subrecords are always loaded in the mode of the parent record. If the parent record is loaded in dynamic mode, then the subrecord will be loaded in dynamic mode and you’ll be able to use methods such as setCurrentSublistValue
.
Conclusion
In this post we looked at sublists and subrecords.
This should wrap up our discussion of the N/record
api. As usual, you should visit the help documentation for a complete overview of the record module.