From 4c71a7a3b151913d25f189a2940c8de86ec2050f Mon Sep 17 00:00:00 2001 From: Hoid Date: Mon, 9 Feb 2026 01:36:02 +0000 Subject: [PATCH] FreeScout: add --customer filter for report and excel --- bin/freescout | 40 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 36 insertions(+), 4 deletions(-) diff --git a/bin/freescout b/bin/freescout index ebbac08..56efa43 100755 --- a/bin/freescout +++ b/bin/freescout @@ -75,14 +75,23 @@ async function cmdUsers() { await conn.end(); } +// Resolve customer name to custom field option ID +function resolveCustomerOptionId(cfMap, customerName) { + const cf = cfMap.customer; + if (!cf) return null; + const match = Object.entries(cf.options).find(([k, v]) => v.toLowerCase() === customerName.toLowerCase()); + return match ? match[0] : null; +} + async function cmdReport(args) { const mailboxId = getFlag(args, '--mailbox'); const from = getFlag(args, '--from'); const to = getFlag(args, '--to'); const userId = getFlag(args, '--user'); + const customerFilter = getFlag(args, '--customer'); if (!from || !to) { - console.error('Usage: freescout report --from YYYY-MM-DD --to YYYY-MM-DD [--mailbox ID] [--user ID]'); + console.error('Usage: freescout report --from YYYY-MM-DD --to YYYY-MM-DD [--mailbox ID] [--user ID] [--customer NAME]'); process.exit(1); } @@ -110,6 +119,17 @@ async function cmdReport(args) { if (mailboxId) { query += ' AND c.mailbox_id = ?'; params.push(mailboxId); } if (userId) { query += ' AND t.user_id = ?'; params.push(userId); } + if (customerFilter && cfMap.customer) { + const optId = resolveCustomerOptionId(cfMap, customerFilter); + if (!optId) { + const available = Object.values(cfMap.customer.options).join(', '); + console.error(`Customer "${customerFilter}" not found. Available: ${available}`); + await conn.end(); + process.exit(1); + } + query += ' AND c.id IN (SELECT conversation_id FROM conversation_custom_field WHERE custom_field_id = ? AND value = ?)'; + params.push(cfMap.customer.id, optId); + } query += ' ORDER BY t.created_at'; @@ -143,10 +163,11 @@ async function cmdExcel(args) { const from = getFlag(args, '--from'); const to = getFlag(args, '--to'); const userId = getFlag(args, '--user'); + const customerFilter = getFlag(args, '--customer'); const output = getFlag(args, '--output') || `invoice-${from}-${to}.xlsx`; if (!from || !to) { - console.error('Usage: freescout excel --from YYYY-MM-DD --to YYYY-MM-DD [--mailbox ID] [--user ID] [--output file.xlsx]'); + console.error('Usage: freescout excel --from YYYY-MM-DD --to YYYY-MM-DD [--mailbox ID] [--user ID] [--customer NAME] [--output file.xlsx]'); process.exit(1); } @@ -171,6 +192,17 @@ async function cmdExcel(args) { if (mailboxId) { query += ' AND c.mailbox_id = ?'; params.push(mailboxId); } if (userId) { query += ' AND t.user_id = ?'; params.push(userId); } + if (customerFilter && cfMap.customer) { + const optId = resolveCustomerOptionId(cfMap, customerFilter); + if (!optId) { + const available = Object.values(cfMap.customer.options).join(', '); + console.error(`Customer "${customerFilter}" not found. Available: ${available}`); + await conn.end(); + process.exit(1); + } + query += ' AND c.id IN (SELECT conversation_id FROM conversation_custom_field WHERE custom_field_id = ? AND value = ?)'; + params.push(cfMap.customer.id, optId); + } query += ' ORDER BY t.created_at'; @@ -259,9 +291,9 @@ Commands: mailboxes List mailboxes users List users report --from DATE --to DATE Show time report (tab-separated) - [--mailbox ID] [--user ID] + [--mailbox ID] [--user ID] [--customer NAME] excel --from DATE --to DATE Generate invoice Excel - [--mailbox ID] [--user ID] [--output file.xlsx]`); + [--mailbox ID] [--user ID] [--customer NAME] [--output file.xlsx]`); process.exit(0); }