Files
dashback/src/defaultApplets/order-revenue-by-month.applet.js
2026-10-12 14:18:54 +02:00

52 lines
2.2 KiB
JavaScript

// @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;
};