I am attempting to create a calculation on deal records that will sum the net amounts on all line items of a specific Product Type. Steps I’ve taken:
- Created a private app to view line items, products, deals and edit deals
- Created a property <def_amount> that is a currency property
- Defined def_amount
- Added def_amount as a data output
I’m not a dev so excuse the likely **bleep** code, but the code is below. When I test the action, I keep getting the error that def_amount is not defined in the code. What is going on?
const hubspot = require(‘@hubspot/api-client’);
const MATCH_VALUE = ‘DEFENDIFY’;
const PRODUCT_TYPE_PROP = ‘hs_product_type’;
// Net total preference order
const NET_PRIMARY = ‘amount’; // HubSpot line-item net total
const NET_FALLBACK = ‘hs_total_amount’; // fallback if present
// Fallback compute fields
const PRICE_PROPS = [‘price’, ‘hs_price’];
const QTY_PROP = ‘quantity’;
const DISC_AMT_PROP = ‘hs_discount_amount’;
const DISC_PCT_PROP = ‘hs_discount_percentage’;
const normalize = v => String(v ?? ‘’).trim().toUpperCase();
const toNumber = v => {
if (v == null) return 0;
const n = parseFloat(String(v).replace(/[^0-9.\-]/g, ‘’));
return Number.isFinite(n) ? n : 0;
};
exports.main = async (event) => {
const client = new hubspot.Client({ accessToken: process.env.DEFENDIFY_CALC });
const dealId = event.object.objectId;
try {
const deal = await client.crm.deals.basicApi.getById(dealId, undefined, undefined, [‘line_items’]);
const lineItemIds = (deal?.associations?.line_items?.results || []).map(x => String(x.id)).filter(Boolean);
if (lineItemIds.length === 0) return { outputFields: { def_amount: 0 } };
const propsToFetch = [
PRODUCT_TYPE_PROP, NET_PRIMARY, NET_FALLBACK,
…PRICE_PROPS, QTY_PROP, DISC_AMT_PROP, DISC_PCT_PROP,
];
const batch = await client.crm.lineItems.batchApi.read({
properties: propsToFetch,
inputs: lineItemIds.map(id => ({ id })),
});
let sum = 0;
for (const row of (batch?.results || [])) {
const p = row?.properties || {};
if (normalize(p[PRODUCT_TYPE_PROP]) !== MATCH_VALUE) continue;
let net = toNumber(p[NET_PRIMARY]);
if (!(net > 0)) net = toNumber(p[NET_FALLBACK]);
if (!(net > 0)) {
const qty = toNumber(p[QTY_PROP]) || 1;
const unit = PRICE_PROPS.reduce((acc, k) => (acc > 0 ? acc : toNumber(p[k])), 0) || 0;
const pre = unit * qty;
const discAmt = toNumber(p[DISC_AMT_PROP]);
const discPct = toNumber(p[DISC_PCT_PROP]);
const totalDisc = discAmt > 0 ? discAmt * qty : (discPct > 0 ? pre * (discPct / 100) : 0);
net = Math.max(0, pre - totalDisc);
}
sum += net;
}
return { outputFields: { def_amount: sum } };
} catch {
return { outputFields: { def_amount: 0 } };
}
};

