Hey Team, I want to get all the Subcustomers based...
# suitescript
n
Hey Team, I want to get all the Subcustomers based on top level parent or get all parent and subcustomers to all hierarachy in single array, meaning if there are 5 parent customers then get 5 arrays. or get one by one array in Reduce function. tried many ways but not working Kindly help or guide! right now using map/reduce and passing top level parent from getInput to map and doing operation in reduce
d
I've solved it once by loading ALL the customers and then build the tree programmatically
n
Share your code @Nilesh Patil
n
right now I don't have any code, I build multiple code but not working anything. I used to get all top parents in getInput and flow down to map & reduce and get subcustomers in reduce but not working . Now trying it in summary but if any idea or any code snippet where I can pass parent and I get all subcustomers under or something like this is there then kindly help here
@Dmitry Masanov, how did you do that?
d
Copy code
export function fetchCustomersSubtreeThroughSQL(topLevelParentId: number, maxDepth: number = 10, log?: (message: string) => void): { [id: number]: {id: number, parent: number | null, children: number[]} } {
    /*
    Runs a SQL query to fetch the subtree of customers with a given top level parent id.
    The result is a dictionary where each node has an id, parent id and children ids.
    It doesn't care if the customer is inactive or not.
     */
    function buildTree(queryResult: query.QueryResultMap[]): { [id: number]: {id: number, parent: number | null, children: number[]} } {
        /**
         * This function builds a tree from the result of a SQL query that returns a list of ids.
         */
        const nodes: { [id: number]: {id: number, parent: number | null, children: number[]} } = {};
        for (const row of queryResult) {
            const ids = Object.values(row) as number[];
            for (let i = 0; i < ids.length; i++) {
                const id = ids[i];
                if (id !== null) {
                    // Get parent id if it exists, otherwise null
                    const parentId = i > 0 ? ids[i - 1] : null;
                    // Get the next id if it exists, otherwise null
                    const childId = i < ids.length - 1 ? ids[i + 1] : null;

                    // If the node doesn't exist, create it
                    if (!nodes[id]) {
                        nodes[id] = {id: id, parent: parentId, children: []}
                    }

                    // If the childId exists and it's not already in the childrenIds array, add it
                    if (childId !== null && !nodes[id].children.includes(childId)) {
                        nodes[id].children.push(childId);
                    }
                }
            }
        }
        return nodes;
    }

    if (maxDepth <= 1) {
        return {[topLevelParentId]: {id: topLevelParentId, parent: null, children: []}};
    }
    let selectPart = `SELECT `
    for (let i = 1; i <= maxDepth; i++) {
        selectPart += `c${i}.id as c${i}_id, `;
    }
    selectPart = selectPart.slice(0, -2) + ' FROM customer c1 ';
    let joins = '';
    for (let i = 2; i <= maxDepth + 1; i++) {
        joins += `LEFT JOIN customer c${i} ON c${i - 1}.id = c${i}.parent `;
    }
    const sql = selectPart + joins + `WHERE c1.id = ${topLevelParentId}`;
    log?.(sql)
    const result = SQLUnlimited(sql);
    return buildTree(result);
}
n
thank you but how did you run it? in what kind of script? and how did you pass the top level parent to this code? My end goal is to get all the subcustomers into an array so that I can update a field value on all those which is there on parent
d
It's just a JS function that I can call from any script. Actually it's just the idea, because it's using some other functions
n
yeah, did you use this js function in netsuite script?
d
Yes, like in the UserEvent script I call
Copy code
import {fetchCustomersSubtreeThroughSQL, getTopLevelParentId} from "../netsuite-libs/Helpers";
n
will it give all subcustomers? in an array or something? and you are passing the top level parent internal ID as a param? while calling?
d
It will return all subcustomers if depth is not more than 10, just a plain array
n
Thanks a lot, I'm trying to use it directly in Map/reduce and for one test it worked fine.will be testing it for multiple parents now. Thanks a lot @Dmitry Masanov
🙌 1
r
If you know at max there are 5-6 lvls you can just build a query.