// @applet-input-schema {"type":"object","properties":{"month":{"type":"string","title":"Month (YYYY-MM)","default":"","description":"Only include orders placed in this month. Leave empty for all months."},"limit":{"type":"integer","title":"Max rows","default":50,"minimum":1,"maximum":500}}} // @applet-output-schema month:string;orders:integer;positions:integer;net:number // @applet-description "Order revenue by month — orders grouped per calendar month." // // Order revenue by month — orders grouped per calendar month. // // Demonstrates: paging, then aggregating into a Map keyed by `YYYY-MM` and rendering a small // report. `GET /order` list rows already carry their line items, so no detail call is needed. // Endpoints: GET /order (paged). module.exports = async function (applet_input) { const only = String(applet_input.month || '').trim(); const maxRows = Math.max(1, Number(applet_input.limit) || 50); // 1. Page through orders. const orders = []; let offset = 0; for (;;) { const res = await fetch(`/order?offset=${offset}&limit=100`); if (!res.ok) throw new Error(`GET /order failed: ${res.status}`); const data = await res.json(); const page = data.orders || []; orders.push(...page); offset += page.length; if (page.length === 0 || offset >= (data.total ?? orders.length)) break; } // 2. Aggregate per calendar month. const buckets = new Map(); for (const order of orders) { const month = String(order.date || '').slice(0, 7); if (!month) continue; if (only && month !== only) continue; const bucket = buckets.get(month) || { month, orders: 0, positions: 0, net: 0 }; bucket.orders += 1; for (const line of order.lines || []) { bucket.positions += 1; bucket.net += (line.amount || 0) * (line.net || 0); } buckets.set(month, bucket); } const rows = [...buckets.values()] .map((b) => ({ ...b, net: Math.round(b.net * 100) / 100 })) .sort((a, b) => a.month.localeCompare(b.month)) .slice(-maxRows); const totalNet = rows.reduce((sum, r) => sum + r.net, 0); console.log(`${rows.length} month(s), ${rows.reduce((n, r) => n + r.orders, 0)} order(s), net ${totalNet.toFixed(2)}.`); return rows; };