Add business Finance hub with invoices and templates.
Ship invoice issue/list/templates under Finance, fix tenant theme reset and owner role badge, and show customers-joined charts by Persian months. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
co-authored by
Cursor
parent
722933dda9
commit
917b840ee5
@@ -0,0 +1,45 @@
|
||||
import type { DailyActivityPoint } from '../services/dailyActivityService'
|
||||
import { buildLast12MonthKeys, formatMonthLabel } from './productActivity'
|
||||
|
||||
export interface MonthActivityPoint {
|
||||
monthKey: string
|
||||
label: string
|
||||
primary: number
|
||||
secondary: number
|
||||
}
|
||||
|
||||
function toMonthKey(dateKey: string): string {
|
||||
return dateKey.slice(0, 7)
|
||||
}
|
||||
|
||||
/** Roll daily dual series into the last 12 calendar months. */
|
||||
export function aggregateDailyActivityByMonth(
|
||||
primaryItems: DailyActivityPoint[],
|
||||
secondaryItems: DailyActivityPoint[],
|
||||
locale: string,
|
||||
): MonthActivityPoint[] {
|
||||
const monthKeys = buildLast12MonthKeys()
|
||||
const primaryByMonth = new Map(monthKeys.map((key) => [key, 0]))
|
||||
const secondaryByMonth = new Map(monthKeys.map((key) => [key, 0]))
|
||||
|
||||
for (const item of primaryItems) {
|
||||
const key = toMonthKey(item.date)
|
||||
if (primaryByMonth.has(key)) {
|
||||
primaryByMonth.set(key, (primaryByMonth.get(key) ?? 0) + item.count)
|
||||
}
|
||||
}
|
||||
|
||||
for (const item of secondaryItems) {
|
||||
const key = toMonthKey(item.date)
|
||||
if (secondaryByMonth.has(key)) {
|
||||
secondaryByMonth.set(key, (secondaryByMonth.get(key) ?? 0) + item.count)
|
||||
}
|
||||
}
|
||||
|
||||
return monthKeys.map((monthKey) => ({
|
||||
monthKey,
|
||||
label: formatMonthLabel(monthKey, locale),
|
||||
primary: primaryByMonth.get(monthKey) ?? 0,
|
||||
secondary: secondaryByMonth.get(monthKey) ?? 0,
|
||||
}))
|
||||
}
|
||||
Reference in New Issue
Block a user