Get Description, Rate, Account, Tax, and Compute Total On Change of Item

🤠 Get relevant data and compute total whenever there is a change in subrecord.

1. Overview

On change of a subrecord item, this Interaction is designed to update the relevant fields and computer parent totals.

2. Example

This example demonstrates that when there is a change in the "Item" within the "xero-order-items" subrecord, the function retrieves the description, rate, account, and tax-rate. It then computes the total based on the tax rate and updates the parent totals accordingly.

async function handler(C) {
    const index = C.getEventPayload().index;
    const value = C.getSubValueBasedOnIndex("xero-order-items", index);

    const itemId = value.item[0];
    const quantity = value.quantity;
    function getParentUpdates({ net, tax, total }) {
        const lineValues = C.state.subValues["xero-order-items"];
        const newNet =
            lineValues
                .map((v, i) => (i === index ? 0 : +v.net))
                .reduce((agg, v) => v + agg, 0) + net;
        const newTaxTotal =
            lineValues
                .map((v, i) => (i === index ? 0 : +v.tax))
                .reduce((agg, v) => v + agg, 0) + tax;
        const newTotal =
            lineValues
                .map((v, i) => (i === index ? 0 : +v.total))
                .reduce((agg, v) => v + agg, 0) + total;
        return C.mergeAll(
            C.setValue("net-total", newNet),
            C.setValue("tax-total", newTaxTotal),
            C.setValue("total", newTotal)
        );
    }
    if (itemId !== undefined && itemId !== null) {
        const entry = await C.api.getEntry({
            id: [itemId],
            responseType: "iov",
            recordId: 463908,
        });
        // console.log("items entry: ", entry);
        let effectiveTax = 0;
        let taxRateSelectValue = [];
        try {
            taxRateSelectValue = JSON.parse(entry["tax-rate"]);
            const taxRateEntryId = taxRateSelectValue[0];
            if (taxRateEntryId) {
                const taxRateEntry = await C.api.getEntry({
                    id: [taxRateEntryId],
                    responseType: "iov",
                    recordId: 34148,
                });
                // console.log("tax rate entry id:", taxRateEntry);
                effectiveTax = +taxRateEntry["effective-tax-rate"];
            }
        } catch {}
        
        const net = (quantity || 0) * +(entry.rate || 0);
        const tax = (effectiveTax / 100) * net;
        const total = net + tax;
        const updatedLineValues = C.updateSubValueBasedOnIndex(
            "xero-order-items",
            index,
            {
                description: entry.description,
                rate: +entry.rate,
                account: JSON.parse(entry["xero-account"]),
                "tax-rate": taxRateSelectValue,
                net,
                tax,
                total,
            }
        );

        // merged return value
        const returnValue = C.mergeAll(
            updatedLineValues,
            getParentUpdates({ net, tax, total })
        );

        // console.log("return value:", returnValue);
        return returnValue;
    }
    const updatedValues = C.updateSubValueBasedOnIndex(
        "xero-order-items",
        index,
        {
            description: "",
            rate: null,
            account: [],
            "tax-rate": [],
            quantity: 1,
            net: null,
        }
    );

    const returnValue = C.mergeAll(
        updatedValues,
        getParentUpdates({ net: 0, tax: 0, total: 0 })
    );
    return returnValue;
}

📌 Need Help?

If you require assistance or encounter any issues, please don't hesitate to contact us for further support.