import { string, date } from 'alga-js' import refreshTokenHelper from '../../utils/refreshTokenHelper' import errorHandlingHelper from '../../utils/errorHandlingHelper' import fetchHelper from '../../utils/fetchHelper' function buildDateRanges(period: string) { const ranges: { period: string; startDate: string; endDate: string }[] = [] if (period === 'today') { const newDate = date.now('date') ranges.push({ period: newDate, startDate: newDate + ' 00:00:00', endDate: newDate + ' 23:59:59' }) } else if (period === 'yesterday') { const newDate = date.sub(date.now('date'), 1, 'date') ranges.push({ period: newDate, startDate: newDate + ' 00:00:00', endDate: newDate + ' 23:59:59' }) } else if (period === 'last_month') { for (let i = 0; i < 30; i++) { const newDate = i === 0 ? date.now('date') : date.sub(date.now('date'), i, 'date') ranges.push({ period: `${newDate.split('-')?.[1] ?? '00'}/${newDate.split('-')?.[2] ?? '01'}`, startDate: newDate + ' 00:00:00', endDate: newDate + ' 23:59:59' }) } } else if (period === 'last_quarter') { for (let i = 0; i < 13; i++) { const subWeek = i * 7 const d = new Date() d.setDate(d.getDate() - subWeek) const newDate = d.toISOString().split('T')[0] const endD = new Date(d) endD.setDate(endD.getDate() + 6) const endDateStr = endD.toISOString().split('T')[0] ranges.push({ period: `W${13 - i}`, startDate: newDate + ' 00:00:00', endDate: endDateStr + ' 23:59:59' }) } } else if (period === 'last_year') { for (let i = 0; i < 12; i++) { const subMonth = (Number(new Date().getMonth()) + 1) - i let newMonth = subMonth let newYear = new Date().getFullYear() if (subMonth <= 0) { newMonth = Number(subMonth) + 12 newYear = Number(new Date().getFullYear()) - 1 } const newDate = `${newYear}-${date.doubleFormat(newMonth)}` const daysInMonth = date.daysInMonth(newYear, newMonth) ranges.push({ period: newDate, startDate: newDate + '-01 00:00:00', endDate: newDate + `-${daysInMonth} 23:59:59` }) } } else { // default: last_week (7 days) for (let i = 0; i < 7; i++) { const newDate = i === 0 ? date.now('date') : date.sub(date.now('date'), i, 'date') ranges.push({ period: newDate, startDate: newDate + ' 00:00:00', endDate: newDate + ' 23:59:59' }) } } return ranges } const handleFunc = async (event: any, authToken: any = null) => { const token = authToken ?? await getTokenHelper(event) const query = getQuery(event) const organizationId = getCookie(event, 'logship_organization_id') const role = getCookie(event, 'logship_role') const period = (query?.period as string) || 'last_week' const orgIdParam = query?.org_id as string const newUserRole = JSON.parse(role ?? '{}') let orgFilter = '' if (!newUserRole?.IsClientAdministrator) { orgFilter = ` AND ad_org_id eq ${orgIdParam || organizationId}` } else if (orgIdParam) { orgFilter = ` AND ad_org_id eq ${orgIdParam}` } const dateRanges = buildDateRanges(period) const records: any[] = [] for (const rgDate of dateRanges) { const soFilter = string.urlEncode(`IsSOTrx eq true AND created ge '${rgDate.startDate}' AND created le '${rgDate.endDate}'${orgFilter}`) const dateFilter = string.urlEncode(`created ge '${rgDate.startDate}' AND created le '${rgDate.endDate}'${orgFilter}`) const invoiceFilter = string.urlEncode(`IsSOTrx eq true AND created ge '${rgDate.startDate}' AND created le '${rgDate.endDate}'${orgFilter}`) const [ordersRes, shipmentsRes, invoicesRes]: any[] = await Promise.all([ fetchHelper(event, `models/c_order?$filter=${soFilter}&$select=created,GrandTotal`, 'GET', token, null).catch(() => null), fetchHelper(event, `models/m_inout?$filter=${dateFilter}&$select=created`, 'GET', token, null).catch(() => null), fetchHelper(event, `models/c_invoice?$filter=${invoiceFilter}&$select=created,GrandTotal`, 'GET', token, null).catch(() => null), ]) const orderRecords = ordersRes?.records || [] const revenue = orderRecords.reduce((sum: number, r: any) => sum + (Number(r.GrandTotal) || 0), 0) records.push({ period: rgDate.period, orders: ordersRes?.['row-count'] ?? 0, revenue: Math.round(revenue * 100) / 100, shipments: shipmentsRes?.['row-count'] ?? 0, invoices: invoicesRes?.['row-count'] ?? 0, }) } // Also fetch orders grouped by org for the horizontal bar chart const now = new Date() const startForOrg = dateRanges.length > 0 ? dateRanges[dateRanges.length - 1].startDate : date.now('date') + ' 00:00:00' const endForOrg = dateRanges.length > 0 ? dateRanges[0].endDate : date.now('date') + ' 23:59:59' let ordersByOrg: Record = {} try { const orgSoFilter = string.urlEncode(`IsSOTrx eq true AND created ge '${startForOrg}' AND created le '${endForOrg}'${orgFilter}`) const orgRes: any = await fetchHelper(event, `models/c_order?$filter=${orgSoFilter}&$select=AD_Org_ID`, 'GET', token, null) if (orgRes?.records) { for (const record of orgRes.records) { const name = record.AD_Org_ID?.identifier || 'Unknown' ordersByOrg[name] = (ordersByOrg[name] || 0) + 1 } } } catch { // ignore } // Fetch order status distribution let ordersByStatus: Record = {} try { const statusFilter = string.urlEncode(`IsSOTrx eq true AND created ge '${startForOrg}' AND created le '${endForOrg}'${orgFilter}`) const statusRes: any = await fetchHelper(event, `models/c_order?$filter=${statusFilter}&$select=DocStatus`, 'GET', token, null) if (statusRes?.records) { const statusLabels: Record = { 'DR': 'Draft', 'CO': 'Completed', 'CL': 'Closed', 'IP': 'In Progress', 'VO': 'Voided', 'AP': 'Approved', 'NA': 'Not Approved', 'WP': 'Waiting Payment', } for (const record of statusRes.records) { const code = record.DocStatus || 'Unknown' const label = statusLabels[code] || code ordersByStatus[label] = (ordersByStatus[label] || 0) + 1 } } } catch { // ignore } return { records: records.reverse(), ordersByOrg, ordersByStatus, } } export default defineEventHandler(async (event) => { let data: any = {} try { data = await handleFunc(event) } catch (err: any) { try { const authToken: any = await refreshTokenHelper(event) data = await handleFunc(event, authToken) } catch (error: any) { data = errorHandlingHelper(err?.data ?? err, error?.data ?? error) } } return data })