@mx-cartographer/experiences 9.4.42 → 9.4.43

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/dist/categories/components/CategoryList.es.js +34 -27
  3. package/dist/categories/components/CategoryList.es.js.map +1 -1
  4. package/dist/common/components/listitems/CollapseExpandListItem.es.js +26 -25
  5. package/dist/common/components/listitems/CollapseExpandListItem.es.js.map +1 -1
  6. package/dist/core/stores/TransactionStore.es.js +1 -1
  7. package/dist/core/stores/TransactionStore.es.js.map +1 -1
  8. package/dist/core/types/localization/CommonCopy.d.ts +2 -0
  9. package/dist/core/types/localization/TrendsCopy.d.ts +0 -1
  10. package/dist/core/utils/CategoryUtil.d.ts +11 -0
  11. package/dist/core/utils/CategoryUtil.es.js +36 -32
  12. package/dist/core/utils/CategoryUtil.es.js.map +1 -1
  13. package/dist/core/utils/NetWorthUtils.d.ts +2 -2
  14. package/dist/core/utils/NetWorthUtils.es.js +64 -64
  15. package/dist/core/utils/NetWorthUtils.es.js.map +1 -1
  16. package/dist/core/utils/TransactionUtils.d.ts +2 -2
  17. package/dist/core/utils/TransactionUtils.es.js +93 -92
  18. package/dist/core/utils/TransactionUtils.es.js.map +1 -1
  19. package/dist/debts/components/debtstable/AccountCell.es.js +13 -13
  20. package/dist/debts/components/debtstable/AccountCell.es.js.map +1 -1
  21. package/dist/finstrong/components/SpendLessThanYouMake/SpendLessThanYouMakeComponent.es.js +40 -36
  22. package/dist/finstrong/components/SpendLessThanYouMake/SpendLessThanYouMakeComponent.es.js.map +1 -1
  23. package/dist/networth/components/AssetsLiabilitiesDetail.es.js +47 -47
  24. package/dist/networth/components/AssetsLiabilitiesDetail.es.js.map +1 -1
  25. package/dist/spending/components/MiniSpendingChart.es.js +52 -47
  26. package/dist/spending/components/MiniSpendingChart.es.js.map +1 -1
  27. package/dist/spending/components/Spending.es.js +82 -74
  28. package/dist/spending/components/Spending.es.js.map +1 -1
  29. package/dist/spending/utils/SpendingData.d.ts +7 -5
  30. package/dist/spending/utils/SpendingData.es.js +34 -31
  31. package/dist/spending/utils/SpendingData.es.js.map +1 -1
  32. package/package.json +1 -1
@@ -1,96 +1,96 @@
1
- import { AccountIcon as _, AccountIconVariants as p, AccountTypeName as y } from "../types/Account.es.js";
1
+ import { AccountIcon as _, AccountIconVariants as p } from "../types/Account.es.js";
2
2
  import { isAccountLiability as d } from "./AccountUtils.es.js";
3
- import { format as b } from "date-fns/format";
4
- import { startOfMonth as v } from "date-fns/startOfMonth";
5
- import { subMonths as A } from "date-fns/subMonths";
6
- import { fromUnixTime as M } from "date-fns/fromUnixTime";
7
- var h = 13, W = (e, r) => e.filter((n) => {
8
- const { is_closed: a, is_deleted: s, is_hidden: t, is_manual: o } = n;
9
- return a || s || t ? !1 : o || !n.guid ? !0 : r.some((g) => e.some((c) => g.guid === c.member_guid));
10
- }), G = (e, r) => [...e, ...r], R = (e) => {
3
+ import { format as y } from "date-fns/format";
4
+ import { startOfMonth as b } from "date-fns/startOfMonth";
5
+ import { subMonths as v } from "date-fns/subMonths";
6
+ import { fromUnixTime as A } from "date-fns/fromUnixTime";
7
+ var h = 13, O = (e, r) => e.filter((s) => {
8
+ const { is_closed: n, is_deleted: i, is_hidden: t, is_manual: o } = s;
9
+ return n || i || t ? !1 : o || !s.guid ? !0 : r.some((g) => e.some((m) => g.guid === m.member_guid));
10
+ }), W = (e, r) => [...e, ...r], G = (e) => {
11
11
  if (e && e.length > 0) return e[e.length - 1];
12
- }, U = (e, r) => e.year_month - r.year_month, N = () => Array.from({ length: h }, (e, r) => Math.floor(v(A(/* @__PURE__ */ new Date(), r)).getTime() / 1e3)).sort(), j = (e, r, n) => !e.length || !r.length ? [] : N().reduceRight((a, s) => {
13
- const t = r.filter(({ year_month: i }) => i === parseInt(b(M(s), "yyyyMM"))), o = e.map((i) => {
14
- const l = t.find((u) => u.account_guid === i.guid), m = {
12
+ }, R = (e, r) => e.year_month - r.year_month, M = () => Array.from({ length: h }, (e, r) => Math.floor(b(v(/* @__PURE__ */ new Date(), r)).getTime() / 1e3)).sort(), U = (e, r, s) => !e.length || !r.length ? [] : M().reduceRight((n, i) => {
13
+ const t = r.filter(({ year_month: a }) => a === parseInt(y(A(i), "yyyyMM"))), o = e.map((a) => {
14
+ const l = t.find((u) => u.account_guid === a.guid), c = {
15
15
  change: 0,
16
- guid: i.guid,
17
- name: i.name,
18
- type: i.account_type,
16
+ guid: a.guid,
17
+ name: a.name,
18
+ type: a.account_type,
19
19
  balance: 0
20
20
  };
21
- if (!l && a.length === 0 && !i.balance) return m;
22
- if (!l && a.length === 0) return {
23
- ...m,
24
- value: d(i) ? -(i.balance ?? 0) : i.balance ?? 0
21
+ if (!l && n.length === 0 && !a.balance) return c;
22
+ if (!l && n.length === 0) return {
23
+ ...c,
24
+ value: d(a) ? -(a.balance ?? 0) : a.balance ?? 0
25
25
  };
26
26
  if (!l) {
27
- const u = a[0].accounts.find((f) => f.guid === i.guid);
28
- return u || m;
27
+ const u = n[0].accounts.find((f) => f.guid === a.guid);
28
+ return u || c;
29
29
  }
30
30
  return {
31
31
  change: l.transaction_total,
32
- guid: i.guid,
33
- name: i.name,
34
- type: i.account_type,
32
+ guid: a.guid,
33
+ name: a.name,
34
+ type: a.account_type,
35
35
  value: l.balance
36
36
  };
37
- }), { y: g, change: c } = o.reduce((i, l) => ({
38
- y: i.y + (l.value || 0),
39
- change: i.change + (l.change || 0)
37
+ }), { y: g, change: m } = o.reduce((a, l) => ({
38
+ y: a.y + (l.value || 0),
39
+ change: a.change + (l.change || 0)
40
40
  }), {
41
41
  y: 0,
42
42
  change: 0
43
43
  });
44
44
  return [{
45
45
  accounts: o,
46
- x: s,
46
+ x: i,
47
47
  y: g,
48
- change: c
49
- }, ...a];
50
- }, []).slice(h - n), k = (e) => {
51
- const r = [], n = [];
52
- let a = 0, s = 0;
48
+ change: m
49
+ }, ...n];
50
+ }, []).slice(h - s), j = (e) => {
51
+ const r = [], s = [];
52
+ let n = 0, i = 0;
53
53
  return e?.accounts.forEach((t) => {
54
54
  t.change > 0 && (r.push({
55
55
  accountName: t.name,
56
56
  gain: t.change
57
- }), a += t.change), t.change < 0 && (n.push({
57
+ }), n += t.change), t.change < 0 && (s.push({
58
58
  accountName: t.name,
59
59
  loss: t.change
60
- }), s += t.change);
60
+ }), i += t.change);
61
61
  }), {
62
62
  netWorth: e,
63
63
  gains: r,
64
- losses: n,
65
- totalGains: a,
66
- totalLosses: s
64
+ losses: s,
65
+ totalGains: n,
66
+ totalLosses: i
67
67
  };
68
- }, w = (e) => {
69
- const r = [], n = [];
70
- let a = 0, s = 0;
68
+ }, k = (e) => {
69
+ const r = [], s = [];
70
+ let n = 0, i = 0;
71
71
  return e.forEach((t) => {
72
72
  if (d(t)) {
73
73
  const o = t.balance ?? 0;
74
- n.push({
74
+ s.push({
75
75
  accountName: t.name,
76
76
  accountType: t.account_type,
77
77
  balance: o
78
- }), s += o;
78
+ }), i += o;
79
79
  } else {
80
80
  const o = t.balance ?? 0;
81
81
  r.push({
82
82
  accountName: t.name,
83
83
  accountType: t.account_type,
84
84
  balance: o
85
- }), a += o;
85
+ }), n += o;
86
86
  }
87
87
  }), {
88
88
  assets: r,
89
- liabilities: n,
90
- totalAssets: a,
91
- totalLiabilities: s
89
+ liabilities: s,
90
+ totalAssets: n,
91
+ totalLiabilities: i
92
92
  };
93
- }, x = (e) => ({
93
+ }, w = (e) => ({
94
94
  account_guid: e.account_guid,
95
95
  balance: e.balance,
96
96
  credit_transaction_total: 0,
@@ -101,27 +101,27 @@ var h = 13, W = (e, r) => e.filter((n) => {
101
101
  user_guid: e.user_guid,
102
102
  year: e.year,
103
103
  year_month: e.year_month
104
- }), z = (e) => {
105
- const r = e.reduce((n, a) => {
106
- const s = a.accountType;
107
- return n[s] || (n[s] = []), n[s].push(a), n;
104
+ }), x = (e, r) => {
105
+ const s = e.reduce((n, i) => {
106
+ const t = i.accountType;
107
+ return n[t] || (n[t] = []), n[t].push(i), n;
108
108
  }, {});
109
- return Object.entries(r).map(([n, a]) => ({
109
+ return Object.entries(s).map(([n, i]) => ({
110
110
  icon: p[+n] || _[+n],
111
- name: y[+n],
112
- accounts: a
111
+ name: r[+n],
112
+ accounts: i
113
113
  }));
114
114
  };
115
115
  export {
116
- w as buildAssetsLiabilities,
117
- j as buildChartData,
118
- k as buildGainsLosses,
119
- W as filterAccounts,
120
- G as flattenBalances,
121
- R as getLatestNetWorthData,
122
- z as groupAccounts,
123
- U as sortByYearMonthAscending,
124
- x as toMonthlyAccountBalance
116
+ k as buildAssetsLiabilities,
117
+ U as buildChartData,
118
+ j as buildGainsLosses,
119
+ O as filterAccounts,
120
+ W as flattenBalances,
121
+ G as getLatestNetWorthData,
122
+ x as groupAccounts,
123
+ R as sortByYearMonthAscending,
124
+ w as toMonthlyAccountBalance
125
125
  };
126
126
 
127
127
  //# sourceMappingURL=NetWorthUtils.es.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"NetWorthUtils.es.js","names":[],"sources":["../../../src/core/utils/NetWorthUtils.ts"],"sourcesContent":["import { format } from 'date-fns/format'\nimport { fromUnixTime } from 'date-fns/fromUnixTime'\nimport { startOfMonth } from 'date-fns/startOfMonth'\nimport { subMonths } from 'date-fns/subMonths'\n\nimport type {\n Account,\n AccountGroup,\n FinancialAccount,\n HistoricalAccountBalance,\n Member,\n MonthlyAccountBalance,\n NetWorth,\n} from '../types'\nimport { AccountTypeName, AccountIcon, AccountIconVariants } from '../types'\nimport { isAccountLiability } from '../utils/AccountUtils'\n\nconst MAX_NUMBER_MONTHS = 13\n\nexport const filterAccounts = (accounts: Account[], members: Member[]) => {\n return accounts.filter((account) => {\n const { is_closed, is_deleted, is_hidden, is_manual } = account\n\n if (is_closed || is_deleted || is_hidden) return false\n if (is_manual || !account.guid) return true\n\n return members.some((member) => {\n return accounts.some((account) => {\n return member.guid === account.member_guid\n })\n })\n })\n}\n\nexport const flattenBalances = (\n allBalances: MonthlyAccountBalance[],\n currentBalances: MonthlyAccountBalance[],\n) => {\n return [...allBalances, ...currentBalances]\n}\n\nexport const getLatestNetWorthData = (chartData: NetWorth[]) => {\n if (chartData && chartData.length > 0) {\n return chartData[chartData.length - 1]\n } else return undefined\n}\n\nexport const sortByYearMonthAscending = (a: MonthlyAccountBalance, b: MonthlyAccountBalance) =>\n a.year_month - b.year_month\n\nconst buildDateTicks = () => {\n return Array.from({ length: MAX_NUMBER_MONTHS }, (_, count) => {\n return Math.floor(startOfMonth(subMonths(new Date(), count)).getTime() / 1000)\n }).sort()\n}\n\nexport const buildChartData = (\n accounts: Account[],\n monthlyAccountBalances: MonthlyAccountBalance[],\n numberOfMonths: number,\n) => {\n if (!accounts.length || !monthlyAccountBalances.length) return []\n const dateTicks = buildDateTicks()\n return dateTicks\n .reduceRight((result: any, x) => {\n const balances = monthlyAccountBalances.filter(\n ({ year_month }) => year_month === parseInt(format(fromUnixTime(x), 'yyyyMM')),\n )\n const accountsWithBalances = accounts.map((account) => {\n const balance = balances.find((balance) => balance.account_guid === account.guid)\n\n const zeroBalance = {\n change: 0,\n guid: account.guid,\n name: account.name,\n type: account.account_type,\n balance: 0,\n }\n\n if (!balance && result.length === 0 && !account.balance) return zeroBalance\n\n // The servers return the monthly account balances in Utah time. Frontend starts all the date calculations\n // in UTC. We get into overlaps for a few hours depending on the timezone with no monthly account balances\n // for all accounts.\n if (!balance && result.length === 0) {\n return {\n ...zeroBalance,\n value: isAccountLiability(account) ? -(account.balance ?? 0) : (account.balance ?? 0),\n }\n }\n\n if (!balance) {\n const lastBalance = result[0].accounts.find((acc: Account) => acc.guid === account.guid)\n\n return lastBalance ? lastBalance : zeroBalance\n }\n\n return {\n change: balance.transaction_total,\n guid: account.guid,\n name: account.name,\n type: account.account_type,\n value: balance.balance,\n }\n })\n\n const { y, change } = accountsWithBalances.reduce(\n (acc, current) => {\n return {\n y: acc.y + (current.value || 0),\n change: acc.change + (current.change || 0),\n }\n },\n { y: 0, change: 0 },\n )\n\n return [\n {\n accounts: accountsWithBalances,\n x,\n y,\n change,\n },\n ...result,\n ]\n }, [])\n .slice(MAX_NUMBER_MONTHS - numberOfMonths)\n}\n\nexport const buildGainsLosses = (selectedData?: NetWorth) => {\n const gains: { accountName: string; gain: number }[] = []\n const losses: { accountName: string; loss: number }[] = []\n let totalGains = 0\n let totalLosses = 0\n\n selectedData?.accounts.forEach((account) => {\n if (account.change > 0) {\n gains.push({ accountName: account.name, gain: account.change })\n totalGains += account.change\n }\n if (account.change < 0) {\n losses.push({ accountName: account.name, loss: account.change })\n totalLosses += account.change\n }\n })\n\n return { netWorth: selectedData, gains, losses, totalGains, totalLosses }\n}\n\nexport const buildAssetsLiabilities = (accounts: Account[]) => {\n const assets: FinancialAccount[] = []\n const liabilities: FinancialAccount[] = []\n let totalAssets = 0\n let totalLiabilities = 0\n\n accounts.forEach((account) => {\n if (isAccountLiability(account)) {\n const balance = account.balance ?? 0\n liabilities.push({ accountName: account.name, accountType: account.account_type, balance })\n totalLiabilities += balance\n } else {\n const balance = account.balance ?? 0\n assets.push({ accountName: account.name, accountType: account.account_type, balance })\n totalAssets += balance\n }\n })\n\n return { assets, liabilities, totalAssets, totalLiabilities }\n}\nexport const toMonthlyAccountBalance = (hab: HistoricalAccountBalance): MonthlyAccountBalance => ({\n account_guid: hab.account_guid,\n balance: hab.balance,\n credit_transaction_total: 0,\n debit_transaction_total: 0,\n id: hab.guid,\n month: hab.month,\n transaction_total: hab.transaction_total ?? 0,\n user_guid: hab.user_guid,\n year: hab.year,\n year_month: hab.year_month,\n})\n\n// groups accounts by account type\n// returns array of account groups, each with an icon, name, and the grouped accounts\nexport const groupAccounts = (accounts: FinancialAccount[]): AccountGroup[] => {\n const groupedAccounts = accounts.reduce<{ [key: number]: FinancialAccount[] }>((acc, account) => {\n const accountType = account.accountType\n if (!acc[accountType]) {\n acc[accountType] = []\n }\n acc[accountType].push(account)\n return acc\n }, {})\n\n return Object.entries(groupedAccounts).map(([accountType, accounts]) => ({\n icon: AccountIconVariants[+accountType] || AccountIcon[+accountType],\n name: AccountTypeName[+accountType],\n accounts,\n }))\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"NetWorthUtils.es.js","names":[],"sources":["../../../src/core/utils/NetWorthUtils.ts"],"sourcesContent":["import { format } from 'date-fns/format'\nimport { fromUnixTime } from 'date-fns/fromUnixTime'\nimport { startOfMonth } from 'date-fns/startOfMonth'\nimport { subMonths } from 'date-fns/subMonths'\n\nimport type {\n Account,\n AccountGroup,\n AccountsCopy,\n FinancialAccount,\n HistoricalAccountBalance,\n Member,\n MonthlyAccountBalance,\n NetWorth,\n} from '../types'\nimport { AccountIcon, AccountIconVariants } from '../types'\nimport { isAccountLiability } from '../utils/AccountUtils'\n\nconst MAX_NUMBER_MONTHS = 13\n\nexport const filterAccounts = (accounts: Account[], members: Member[]) => {\n return accounts.filter((account) => {\n const { is_closed, is_deleted, is_hidden, is_manual } = account\n\n if (is_closed || is_deleted || is_hidden) return false\n if (is_manual || !account.guid) return true\n\n return members.some((member) => {\n return accounts.some((account) => {\n return member.guid === account.member_guid\n })\n })\n })\n}\n\nexport const flattenBalances = (\n allBalances: MonthlyAccountBalance[],\n currentBalances: MonthlyAccountBalance[],\n) => {\n return [...allBalances, ...currentBalances]\n}\n\nexport const getLatestNetWorthData = (chartData: NetWorth[]) => {\n if (chartData && chartData.length > 0) {\n return chartData[chartData.length - 1]\n } else return undefined\n}\n\nexport const sortByYearMonthAscending = (a: MonthlyAccountBalance, b: MonthlyAccountBalance) =>\n a.year_month - b.year_month\n\nconst buildDateTicks = () => {\n return Array.from({ length: MAX_NUMBER_MONTHS }, (_, count) => {\n return Math.floor(startOfMonth(subMonths(new Date(), count)).getTime() / 1000)\n }).sort()\n}\n\nexport const buildChartData = (\n accounts: Account[],\n monthlyAccountBalances: MonthlyAccountBalance[],\n numberOfMonths: number,\n) => {\n if (!accounts.length || !monthlyAccountBalances.length) return []\n const dateTicks = buildDateTicks()\n return dateTicks\n .reduceRight((result: any, x) => {\n const balances = monthlyAccountBalances.filter(\n ({ year_month }) => year_month === parseInt(format(fromUnixTime(x), 'yyyyMM')),\n )\n const accountsWithBalances = accounts.map((account) => {\n const balance = balances.find((balance) => balance.account_guid === account.guid)\n\n const zeroBalance = {\n change: 0,\n guid: account.guid,\n name: account.name,\n type: account.account_type,\n balance: 0,\n }\n\n if (!balance && result.length === 0 && !account.balance) return zeroBalance\n\n // The servers return the monthly account balances in Utah time. Frontend starts all the date calculations\n // in UTC. We get into overlaps for a few hours depending on the timezone with no monthly account balances\n // for all accounts.\n if (!balance && result.length === 0) {\n return {\n ...zeroBalance,\n value: isAccountLiability(account) ? -(account.balance ?? 0) : (account.balance ?? 0),\n }\n }\n\n if (!balance) {\n const lastBalance = result[0].accounts.find((acc: Account) => acc.guid === account.guid)\n\n return lastBalance ? lastBalance : zeroBalance\n }\n\n return {\n change: balance.transaction_total,\n guid: account.guid,\n name: account.name,\n type: account.account_type,\n value: balance.balance,\n }\n })\n\n const { y, change } = accountsWithBalances.reduce(\n (acc, current) => {\n return {\n y: acc.y + (current.value || 0),\n change: acc.change + (current.change || 0),\n }\n },\n { y: 0, change: 0 },\n )\n\n return [\n {\n accounts: accountsWithBalances,\n x,\n y,\n change,\n },\n ...result,\n ]\n }, [])\n .slice(MAX_NUMBER_MONTHS - numberOfMonths)\n}\n\nexport const buildGainsLosses = (selectedData?: NetWorth) => {\n const gains: { accountName: string; gain: number }[] = []\n const losses: { accountName: string; loss: number }[] = []\n let totalGains = 0\n let totalLosses = 0\n\n selectedData?.accounts.forEach((account) => {\n if (account.change > 0) {\n gains.push({ accountName: account.name, gain: account.change })\n totalGains += account.change\n }\n if (account.change < 0) {\n losses.push({ accountName: account.name, loss: account.change })\n totalLosses += account.change\n }\n })\n\n return { netWorth: selectedData, gains, losses, totalGains, totalLosses }\n}\n\nexport const buildAssetsLiabilities = (accounts: Account[]) => {\n const assets: FinancialAccount[] = []\n const liabilities: FinancialAccount[] = []\n let totalAssets = 0\n let totalLiabilities = 0\n\n accounts.forEach((account) => {\n if (isAccountLiability(account)) {\n const balance = account.balance ?? 0\n liabilities.push({ accountName: account.name, accountType: account.account_type, balance })\n totalLiabilities += balance\n } else {\n const balance = account.balance ?? 0\n assets.push({ accountName: account.name, accountType: account.account_type, balance })\n totalAssets += balance\n }\n })\n\n return { assets, liabilities, totalAssets, totalLiabilities }\n}\nexport const toMonthlyAccountBalance = (hab: HistoricalAccountBalance): MonthlyAccountBalance => ({\n account_guid: hab.account_guid,\n balance: hab.balance,\n credit_transaction_total: 0,\n debit_transaction_total: 0,\n id: hab.guid,\n month: hab.month,\n transaction_total: hab.transaction_total ?? 0,\n user_guid: hab.user_guid,\n year: hab.year,\n year_month: hab.year_month,\n})\n\n// groups accounts by account type\n// returns array of account groups, each with an icon, localized name, and the grouped accounts\nexport const groupAccounts = (\n accounts: FinancialAccount[],\n accountTypes: AccountsCopy['account_types'],\n): AccountGroup[] => {\n const groupedAccounts = accounts.reduce<{ [key: number]: FinancialAccount[] }>((acc, account) => {\n const accountType = account.accountType\n if (!acc[accountType]) {\n acc[accountType] = []\n }\n acc[accountType].push(account)\n return acc\n }, {})\n\n return Object.entries(groupedAccounts).map(([accountType, accounts]) => ({\n icon: AccountIconVariants[+accountType] || AccountIcon[+accountType],\n name: accountTypes[+accountType],\n accounts,\n }))\n}\n"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
- import { TransactionStatus, TransactionType, Category, DetailedAccount, Tag, Tagging, Transaction } from '../types';
1
+ import { TransactionStatus, TransactionType, Category, CategoryCopy, DetailedAccount, Tag, Tagging, Transaction } from '../types';
2
2
  import { TransactionFilter } from '../stores/TransactionStore';
3
3
  export declare const isTransferTransaction: (transaction: Pick<Transaction, "top_level_category_guid">) => boolean;
4
- export declare const buildDetailedTransactions: (transactions: Transaction[], accounts: DetailedAccount[], categories: Category[], taggings?: Tagging[]) => {
4
+ export declare const buildDetailedTransactions: (transactions: Transaction[], accounts: DetailedAccount[], categories: Category[], taggings: Tagging[] | undefined, categoryCopy: CategoryCopy) => {
5
5
  account: string;
6
6
  accountIsClosed: boolean;
7
7
  accountIsHidden: boolean;
@@ -1,116 +1,117 @@
1
- import { CategoryGuidToName as y, CategoryGuids as T } from "../constants/Category.es.js";
1
+ import { CategoryGuidToName as y, CategoryGuids as h } from "../constants/Category.es.js";
2
2
  import { DATE_FORMATS_INTL as m, formatDate as f } from "../constants/DateFormats.es.js";
3
- import { TransactionStatus as v, TransactionType as C } from "../types/Transaction.es.js";
4
- import { formatCurrency as A } from "./NumberFormatting.es.js";
5
- import { fromUnixUTC as E } from "./DateUtil.es.js";
6
- import { TABLE_CONST as S } from "../constants/Table.es.js";
7
- import { COLUMN_NAMES as l } from "../constants/Transaction.es.js";
8
- import { format as b } from "date-fns/format";
9
- import { startOfMonth as O } from "date-fns/startOfMonth";
10
- import { startOfToday as D } from "date-fns/startOfToday";
3
+ import { TransactionStatus as C, TransactionType as v } from "../types/Transaction.es.js";
4
+ import { getLocalizedCategoryName as A } from "./CategoryUtil.es.js";
5
+ import { formatCurrency as E } from "./NumberFormatting.es.js";
6
+ import { fromUnixUTC as S } from "./DateUtil.es.js";
7
+ import { TABLE_CONST as b } from "../constants/Table.es.js";
8
+ import { COLUMN_NAMES as _ } from "../constants/Transaction.es.js";
9
+ import { format as O } from "date-fns/format";
10
+ import { startOfMonth as D } from "date-fns/startOfMonth";
11
+ import { startOfToday as N } from "date-fns/startOfToday";
11
12
  import { endOfToday as M } from "date-fns/endOfToday";
12
- import { fromUnixTime as N } from "date-fns/fromUnixTime";
13
- import { getUnixTime as _ } from "date-fns/getUnixTime";
14
- var X = (t) => t.top_level_category_guid === T.TRANSFER, ee = (t, r, n, a = []) => {
15
- const s = r.reduce((o, e) => ({
16
- ...o,
17
- [e.guid]: e
18
- }), {}), d = n.reduce((o, e) => ({
19
- ...o,
20
- [e.guid]: e
21
- }), {}), i = a.reduce((o, e) => {
22
- const { transaction_guid: u, tag_guid: c } = e;
23
- if (!o[u]) return {
24
- ...o,
25
- [u]: [c]
13
+ import { fromUnixTime as U } from "date-fns/fromUnixTime";
14
+ import { getUnixTime as T } from "date-fns/getUnixTime";
15
+ var te = (t) => t.top_level_category_guid === h.TRANSFER, re = (t, r, o, d = [], i) => {
16
+ const c = r.reduce((e, s) => ({
17
+ ...e,
18
+ [s.guid]: s
19
+ }), {}), n = o.reduce((e, s) => ({
20
+ ...e,
21
+ [s.guid]: s
22
+ }), {}), a = d.reduce((e, s) => {
23
+ const { transaction_guid: u, tag_guid: g } = s;
24
+ if (!e[u]) return {
25
+ ...e,
26
+ [u]: [g]
26
27
  };
27
- const g = [...o[u], c];
28
+ const l = [...e[u], g];
28
29
  return {
29
- ...o,
30
- [u]: g
30
+ ...e,
31
+ [u]: l
31
32
  };
32
33
  }, {});
33
- return t.map((o) => {
34
- const e = s[o.account_guid], u = o.category_guid ? d[o.category_guid] : null, c = i[o.guid] ?? [];
34
+ return t.map((e) => {
35
+ const s = c[e.account_guid], u = e.category_guid ? n[e.category_guid] : null, g = a[e.guid] ?? [];
35
36
  return {
36
- ...o,
37
- account: e?.user_name || "Unknown",
38
- accountIsClosed: e?.is_closed,
39
- accountIsHidden: e?.is_hidden,
40
- category: u?.name || "Uncategorized",
41
- institutionName: e?.institution?.name || e?.institutionName || void 0,
42
- isIncome: o.top_level_category_guid === T.INCOME,
43
- isPending: o.feed_status === v.PENDING,
44
- number: e?.account_number || "",
45
- payee: o.description,
46
- tags: c
37
+ ...e,
38
+ account: s?.user_name || "Unknown",
39
+ accountIsClosed: s?.is_closed,
40
+ accountIsHidden: s?.is_hidden,
41
+ category: u ? A(u, i) : "Uncategorized",
42
+ institutionName: s?.institution?.name || s?.institutionName || void 0,
43
+ isIncome: e.top_level_category_guid === h.INCOME,
44
+ isPending: e.feed_status === C.PENDING,
45
+ number: s?.account_number || "",
46
+ payee: e.description,
47
+ tags: g
47
48
  };
48
49
  });
49
- }, U = "uncategorized", te = (t, r, n, a, s, d) => {
50
- const i = R(t, s, d), o = I(i, n, a);
50
+ }, L = "uncategorized", oe = (t, r, o, d, i, c) => {
51
+ const n = R(t, i, c), a = I(n, o, d);
51
52
  return r.forEach((e) => {
52
- const u = o.findIndex((g) => g.guid === e), c = d.filter((g) => g.parent_guid === e);
53
- o.splice(u + 1, 0, ...c);
54
- }), o;
55
- }, R = (t, r, n) => {
56
- const { accounts: a = [], dateRange: s = {
57
- start: O(D()),
53
+ const s = a.findIndex((g) => g.guid === e), u = c.filter((g) => g.parent_guid === e);
54
+ a.splice(s + 1, 0, ...u);
55
+ }), a;
56
+ }, R = (t, r, o) => {
57
+ const { accounts: d = [], dateRange: i = {
58
+ start: D(N()),
58
59
  end: M()
59
- }, custom: d = () => !0, searchTerm: i = "", showSplits: o = !1 } = t;
60
- return n.filter((e) => o ? !e.has_been_split : !e.parent_guid).filter((e) => !!a.find((u) => u === e.account_guid)).filter((e) => e.date >= _(s.start) && e.date <= _(s.end)).filter(d).filter((e) => {
61
- if (i === U && e.has_been_split) return !1;
62
- if (/^spl/i.test(i) && (e.has_been_split || e.parent_guid)) return !0;
63
- const u = e.tags.some((g) => p(i, r.find((h) => h.guid === g)?.name)), c = N(e.date);
64
- return p(i, e.payee) || p(i, e.feed_description) || p(i, e.category) || p(i, f(c, m.MONTH)) || p(i, f(c, m.DAY)) || p(i, f(c, m.FULL_MONTH_DAY)) || p(i, f(c, m.MONTH_DAY_YEAR)) || p(i, b(c, "do")) || p(i, e.account) || p(i, A(e.amount, "0,0.00")) || p(i, e.memo) || u;
60
+ }, custom: c = () => !0, searchTerm: n = "", showSplits: a = !1 } = t;
61
+ return o.filter((e) => a ? !e.has_been_split : !e.parent_guid).filter((e) => !!d.find((s) => s === e.account_guid)).filter((e) => e.date >= T(i.start) && e.date <= T(i.end)).filter(c).filter((e) => {
62
+ if (n === L && e.has_been_split) return !1;
63
+ if (/^spl/i.test(n) && (e.has_been_split || e.parent_guid)) return !0;
64
+ const s = e.tags.some((g) => p(n, r.find((l) => l.guid === g)?.name)), u = U(e.date);
65
+ return p(n, e.payee) || p(n, e.feed_description) || p(n, e.category) || p(n, f(u, m.MONTH)) || p(n, f(u, m.DAY)) || p(n, f(u, m.FULL_MONTH_DAY)) || p(n, f(u, m.MONTH_DAY_YEAR)) || p(n, O(u, "do")) || p(n, e.account) || p(n, E(e.amount, "0,0.00")) || p(n, e.memo) || s;
65
66
  });
66
- }, I = (t, r, n) => [...t].sort((a, s) => {
67
- const d = r, i = (a[d] || "") > (s[d] || "");
68
- let o = i ? -1 : 1, e = i ? 1 : -1;
69
- return (r === l.DATE || r === l.AMOUNT) && (o = i ? 1 : -1, e = i ? -1 : 1), n === S.ASC ? o : e;
67
+ }, I = (t, r, o) => [...t].sort((d, i) => {
68
+ const c = r, n = (d[c] || "") > (i[c] || "");
69
+ let a = n ? -1 : 1, e = n ? 1 : -1;
70
+ return (r === _.DATE || r === _.AMOUNT) && (a = n ? 1 : -1, e = n ? -1 : 1), o === b.ASC ? a : e;
70
71
  }), p = (t, r) => {
71
- const n = t.toLowerCase().split(" "), a = r?.toString().toLowerCase() ?? "";
72
- return n.every((s) => a.indexOf(s) > -1);
72
+ const o = t.toLowerCase().split(" "), d = r?.toString().toLowerCase() ?? "";
73
+ return o.every((i) => d.indexOf(i) > -1);
73
74
  };
74
- function L(t) {
75
+ function w(t) {
75
76
  return new Set(t.filter((r) => r.parent_guid !== void 0).map((r) => r.parent_guid));
76
77
  }
77
- function w(t) {
78
- return t.reduce((r, n) => (n.parent_guid && (r[n.parent_guid] || (r[n.parent_guid] = []), r[n.parent_guid].push(n)), r), {});
78
+ function j(t) {
79
+ return t.reduce((r, o) => (o.parent_guid && (r[o.parent_guid] || (r[o.parent_guid] = []), r[o.parent_guid].push(o)), r), {});
79
80
  }
80
- function re(t, r) {
81
- const n = L(r), a = w(r), s = /* @__PURE__ */ new Set(), d = [];
82
- for (const i of t) n.has(i.guid) ? (a[i.guid] ?? []).slice().sort((o, e) => Math.abs(e.amount) - Math.abs(o.amount)).forEach((o) => {
83
- s.has(o.guid) || (d.push(o), s.add(o.guid));
84
- }) : s.has(i.guid) || (d.push(i), s.add(i.guid));
85
- return d;
81
+ function ne(t, r) {
82
+ const o = w(r), d = j(r), i = /* @__PURE__ */ new Set(), c = [];
83
+ for (const n of t) o.has(n.guid) ? (d[n.guid] ?? []).slice().sort((a, e) => Math.abs(e.amount) - Math.abs(a.amount)).forEach((a) => {
84
+ i.has(a.guid) || (c.push(a), i.add(a.guid));
85
+ }) : i.has(n.guid) || (c.push(n), i.add(n.guid));
86
+ return c;
86
87
  }
87
- var ne = (t, r) => {
88
- const n = P(j(t, r)), a = new Blob([n], { type: "text/csv;charset=utf-8;" }), s = document.createElement("a");
89
- s.href = URL.createObjectURL(a), s.setAttribute("download", "transactions.csv"), document.body.appendChild(s), s.click(), document.body.removeChild(s), URL.revokeObjectURL(s.href);
90
- }, j = (t, r) => t.map((n) => ({
91
- Date: f(E(n.date), m.YEAR_MONTH_DAY),
92
- Description: x(n),
93
- "Original Description": n.feed_description,
94
- Amount: `${n.amount}`,
95
- Type: n.transaction_type === C.CREDIT ? "Credit" : "Debit",
96
- "Parent Category": y[n.top_level_category_guid || ""],
97
- Category: n.category,
98
- Account: n.account,
99
- Tags: F(n, r),
100
- Memo: n.memo,
101
- Pending: n.isPending ? "TRUE" : "FALSE"
102
- })), G = (t) => t ? /[,"\n\r]/.test(t) ? `"${t.replace(/"/g, '""')}"` : t : "", P = (t) => t.length === 0 ? "" : Object.keys(t[0]).join(",").concat(`\r
103
- `) + t.map((r) => Object.values(r).map(G).join(",")).join(`\r
104
- `), x = (t) => {
88
+ var ie = (t, r) => {
89
+ const o = x(G(t, r)), d = new Blob([o], { type: "text/csv;charset=utf-8;" }), i = document.createElement("a");
90
+ i.href = URL.createObjectURL(d), i.setAttribute("download", "transactions.csv"), document.body.appendChild(i), i.click(), document.body.removeChild(i), URL.revokeObjectURL(i.href);
91
+ }, G = (t, r) => t.map((o) => ({
92
+ Date: f(S(o.date), m.YEAR_MONTH_DAY),
93
+ Description: F(o),
94
+ "Original Description": o.feed_description,
95
+ Amount: `${o.amount}`,
96
+ Type: o.transaction_type === v.CREDIT ? "Credit" : "Debit",
97
+ "Parent Category": y[o.top_level_category_guid || ""],
98
+ Category: o.category,
99
+ Account: o.account,
100
+ Tags: B(o, r),
101
+ Memo: o.memo,
102
+ Pending: o.isPending ? "TRUE" : "FALSE"
103
+ })), P = (t) => t ? /[,"\n\r]/.test(t) ? `"${t.replace(/"/g, '""')}"` : t : "", x = (t) => t.length === 0 ? "" : Object.keys(t[0]).join(",").concat(`\r
104
+ `) + t.map((r) => Object.values(r).map(P).join(",")).join(`\r
105
+ `), F = (t) => {
105
106
  let r = t.parent_guid ? "Split: " : "";
106
107
  return r += t.is_hidden ? "(Excluded) " : "", r += t.description, r;
107
- }, F = (t, r) => t.tags.map((n) => r.filter((a) => a.guid === n)[0]?.name ?? "").join(" ");
108
+ }, B = (t, r) => t.tags.map((o) => r.filter((d) => d.guid === o)[0]?.name ?? "").join(" ");
108
109
  export {
109
- ee as buildDetailedTransactions,
110
- ne as exportTransactionsToCSV,
111
- re as flattenTransactionsWithSplits,
112
- X as isTransferTransaction,
113
- te as sortAndFilterTransactions
110
+ re as buildDetailedTransactions,
111
+ ie as exportTransactionsToCSV,
112
+ ne as flattenTransactionsWithSplits,
113
+ te as isTransferTransaction,
114
+ oe as sortAndFilterTransactions
114
115
  };
115
116
 
116
117
  //# sourceMappingURL=TransactionUtils.es.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"TransactionUtils.es.js","names":[],"sources":["../../../src/core/utils/TransactionUtils.ts"],"sourcesContent":["import { endOfToday } from 'date-fns/endOfToday'\nimport { format } from 'date-fns/format'\nimport { fromUnixTime } from 'date-fns/fromUnixTime'\nimport { getUnixTime } from 'date-fns/getUnixTime'\nimport { startOfMonth } from 'date-fns/startOfMonth'\nimport { startOfToday } from 'date-fns/startOfToday'\n\nimport { TABLE_CONST } from '../constants/Table'\nimport {\n CategoryGuids,\n CategoryGuidToName,\n DATE_FORMATS_INTL,\n formatDate,\n ORDINAL_DATE_FORMAT,\n} from '../constants'\nimport { COLUMN_NAMES } from '../constants/Transaction'\nimport { TransactionStatus, TransactionType } from '../types'\nimport type { Category, DetailedAccount, Tag, Tagging, Transaction } from '../types'\n\nimport { type TransactionFilter } from '../stores/TransactionStore'\n\nimport { fromUnixUTC } from './DateUtil'\nimport { formatCurrency } from './NumberFormatting'\n\ninterface AccountsMap {\n [key: string]: DetailedAccount\n}\n\n// True for account-to-account transfers (top-level Transfer category). Used to\n// swap the payee/description for the institution name in the transaction detail\n// header, the table Payee column, and the mobile list.\nexport const isTransferTransaction = (\n transaction: Pick<Transaction, 'top_level_category_guid'>,\n): boolean => transaction.top_level_category_guid === CategoryGuids.TRANSFER\n\ninterface CategoriesMap {\n [key: string]: Category\n}\n\ninterface TaggingsMap {\n [key: string]: string[]\n}\n\nexport const buildDetailedTransactions = (\n transactions: Transaction[],\n accounts: DetailedAccount[],\n categories: Category[],\n taggings: Tagging[] = [],\n) => {\n const accountsMap = accounts.reduce((acc: AccountsMap, account: DetailedAccount) => {\n return { ...acc, [account.guid]: account }\n }, {})\n\n const categoriesMap = categories.reduce((acc: CategoriesMap, category: Category) => {\n return { ...acc, [category.guid]: category }\n }, {})\n\n const taggingsMap = taggings.reduce((acc: TaggingsMap, tagging: Tagging) => {\n const { transaction_guid, tag_guid } = tagging\n\n if (!acc[transaction_guid]) {\n return {\n ...acc,\n [transaction_guid]: [tag_guid],\n }\n }\n const tags = [...acc[transaction_guid], tag_guid] as string[]\n\n return {\n ...acc,\n [transaction_guid]: tags,\n }\n }, {})\n\n return transactions.map((transaction: Transaction) => {\n const account = accountsMap[transaction.account_guid]\n const category = transaction.category_guid ? categoriesMap[transaction.category_guid] : null\n const tags = taggingsMap[transaction.guid] ?? []\n\n return {\n ...transaction,\n account: account?.user_name || 'Unknown',\n accountIsClosed: account?.is_closed,\n accountIsHidden: account?.is_hidden,\n category: category?.name || 'Uncategorized',\n institutionName: account?.institution?.name || account?.institutionName || undefined,\n isIncome: transaction.top_level_category_guid === CategoryGuids.INCOME,\n isPending: transaction.feed_status === TransactionStatus.PENDING,\n number: account?.account_number || '',\n payee: transaction.description,\n tags,\n }\n })\n}\n\nconst UNCATEGORIZED_TERM = 'uncategorized'\n\nexport const sortAndFilterTransactions = (\n filter: TransactionFilter,\n expandedSplits: string[],\n sortColumn: string,\n sortDirection: string,\n tags: Tag[],\n transactions: Transaction[],\n) => {\n const filteredTransactions = filterTransactions(filter, tags, transactions)\n\n const sortedTransactions = sortTransactions(filteredTransactions, sortColumn, sortDirection)\n\n expandedSplits.forEach((guid) => {\n const index = sortedTransactions.findIndex((t) => t.guid === guid)\n const children = transactions.filter((t) => t.parent_guid === guid)\n sortedTransactions.splice(index + 1, 0, ...children)\n })\n return sortedTransactions\n}\n\nconst filterTransactions = (\n filter: TransactionFilter,\n tags: Tag[],\n transactions: Transaction[],\n) => {\n const {\n accounts = [],\n dateRange = { start: startOfMonth(startOfToday()), end: endOfToday() },\n custom = () => true,\n searchTerm: searchFilter = '',\n showSplits = false,\n } = filter\n\n return (\n transactions\n // Filters out parent of split transactions when showSplits is true and filters out split\n // transaction children when showSplits is false\n .filter((t) => (showSplits ? !t.has_been_split : !t.parent_guid))\n // Filter for selected accounts\n .filter((t) => Boolean(accounts.find((guid) => guid === t.account_guid)))\n // Filter for Date Range.\n // NOTE: bounds are local-midnight (getUnixTime of a local Date) while dates\n // are rendered/exported on the UTC calendar day (fromUnixUTC). For a\n // midnight-UTC row near a month boundary in a negative-offset browser the\n // two can disagree by a day. Left as-is here to keep this fix low-risk;\n // unifying range + search on UTC is tracked with the core-data ISO\n // migration (MEW-3961 follow-up).\n .filter((t) => t.date >= getUnixTime(dateRange.start) && t.date <= getUnixTime(dateRange.end))\n // Custom filter\n .filter(custom)\n // Search filter\n .filter((transaction) => {\n // Don't return uncategorized split transactions\n if (searchFilter === UNCATEGORIZED_TERM && transaction.has_been_split) {\n return false\n }\n\n // Split check - When searching for \"Splits\" and transaction is a split or is a parent of a split(s)\n const splitPattern = /^spl/i\n if (\n splitPattern.test(searchFilter) &&\n (transaction.has_been_split || Boolean(transaction.parent_guid))\n ) {\n return true\n }\n\n // Check transactions tags\n const isTagIncludedInSearch = transaction.tags.some((guid) =>\n isIncludedInSearch(searchFilter, tags.find((tag) => tag.guid === guid)?.name),\n )\n const date = fromUnixTime(transaction.date)\n return (\n isIncludedInSearch(searchFilter, transaction.payee) ||\n isIncludedInSearch(searchFilter, transaction.feed_description) ||\n isIncludedInSearch(searchFilter, transaction.category) ||\n isIncludedInSearch(searchFilter, formatDate(date, DATE_FORMATS_INTL.MONTH)) ||\n isIncludedInSearch(searchFilter, formatDate(date, DATE_FORMATS_INTL.DAY)) ||\n isIncludedInSearch(searchFilter, formatDate(date, DATE_FORMATS_INTL.FULL_MONTH_DAY)) ||\n isIncludedInSearch(searchFilter, formatDate(date, DATE_FORMATS_INTL.MONTH_DAY_YEAR)) ||\n isIncludedInSearch(searchFilter, format(date, ORDINAL_DATE_FORMAT)) ||\n isIncludedInSearch(searchFilter, transaction.account) ||\n isIncludedInSearch(searchFilter, formatCurrency(transaction.amount, '0,0.00')) ||\n isIncludedInSearch(searchFilter, transaction.memo) ||\n isTagIncludedInSearch\n )\n })\n )\n}\n\nconst sortTransactions = (\n transactions: Transaction[],\n sortColumn: string,\n sortDirection: string,\n) => {\n return [...transactions].sort((a: Transaction, b: Transaction) => {\n const column = sortColumn as keyof Transaction\n const sortCompare = (a[column] || '') > (b[column] || '')\n\n let sortASC = sortCompare ? -1 : 1\n let sortDESC = sortCompare ? 1 : -1\n\n if (sortColumn === COLUMN_NAMES.DATE || sortColumn === COLUMN_NAMES.AMOUNT) {\n sortASC = sortCompare ? 1 : -1\n sortDESC = sortCompare ? -1 : 1\n }\n\n return sortDirection === TABLE_CONST.ASC ? sortASC : sortDESC\n })\n}\n\n/**\n * Determines if a value is included within the terms set in the search bar\n */\nconst isIncludedInSearch = (searchFilter: string, value: string | null | undefined) => {\n const lowerCasedTerms = searchFilter.toLowerCase().split(' ')\n const lowerCasedValue = value?.toString().toLowerCase() ?? ''\n\n return lowerCasedTerms.every((filter) => lowerCasedValue.indexOf(filter) > -1)\n}\n\n// TODO: Change the way formatting data is exported in order to handle localization\ntype FormattedTransaction = {\n Date: string\n Description: string\n 'Original Description': string\n Amount: string\n Type: string\n 'Parent Category': string\n Category: string\n Account: string\n Tags: string\n Memo: string\n Pending: string\n}\n\n/**\n * Collects the GUIDs of all transactions that act as parents\n * to one or more split (child) transactions.\n */\nfunction extractParentTransactionGuids(transactions: Transaction[]): Set<string> {\n return new Set(\n transactions.filter((tx) => tx.parent_guid !== undefined).map((tx) => tx.parent_guid!),\n )\n}\n\n/**\n * Organizes child transactions by their parent transaction GUID.\n * Returns a map from parent GUID to an array of its child transactions.\n */\nfunction mapChildTransactionsByParent(transactions: Transaction[]): Record<string, Transaction[]> {\n return transactions.reduce<Record<string, Transaction[]>>((accumulator, tx) => {\n if (tx.parent_guid) {\n if (!accumulator[tx.parent_guid]) accumulator[tx.parent_guid] = []\n accumulator[tx.parent_guid].push(tx)\n }\n return accumulator\n }, {})\n}\n\n/**\n * Produces a list of transactions based on the given sorted transactions,\n * where parent transactions that have split children are replaced by those\n * children sorted by descending absolute amount. All other transactions\n * are included as-is, with duplicates removed.\n */\nexport function flattenTransactionsWithSplits(\n sortedTransactions: Transaction[],\n allTransactions: Transaction[],\n): Transaction[] {\n // Set of parent transaction GUIDs that have split child transactions\n const parentTransactionGuidsWithSplits = extractParentTransactionGuids(allTransactions)\n\n // Map from parent GUID to array of its child split transactions\n const childTransactionsGroupedByParent = mapChildTransactionsByParent(allTransactions)\n\n // Track GUIDs of transactions already included in the result to avoid duplicates\n const processedTransactionGuids = new Set<string>()\n\n // Resulting list of transactions with parents replaced by their split children\n const flattenedTransactionList: Transaction[] = []\n\n for (const transaction of sortedTransactions) {\n if (parentTransactionGuidsWithSplits.has(transaction.guid)) {\n // This transaction is a parent with splits, so replace it with its children\n const splitChildTransactions = childTransactionsGroupedByParent[transaction.guid] ?? []\n\n splitChildTransactions\n .slice()\n .sort((a, b) => Math.abs(b.amount) - Math.abs(a.amount))\n .forEach((childTransaction) => {\n if (!processedTransactionGuids.has(childTransaction.guid)) {\n flattenedTransactionList.push(childTransaction)\n processedTransactionGuids.add(childTransaction.guid)\n }\n })\n } else if (!processedTransactionGuids.has(transaction.guid)) {\n // Normal transaction (no splits), add as-is if not already added\n flattenedTransactionList.push(transaction)\n processedTransactionGuids.add(transaction.guid)\n }\n }\n\n return flattenedTransactionList\n}\n\nexport const exportTransactionsToCSV = (transactions: Transaction[], tags: Tag[]) => {\n const csvContent = structureCSVData(formatTransactions(transactions, tags))\n\n const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' })\n const link = document.createElement('a')\n link.href = URL.createObjectURL(blob)\n link.setAttribute('download', 'transactions.csv')\n\n document.body.appendChild(link)\n link.click()\n document.body.removeChild(link)\n\n URL.revokeObjectURL(link.href)\n}\n\n/**\n * Formats a list of transactions into a list that will be used when\n * downloaded to a CSV file.\n */\nconst formatTransactions = (transactions: Transaction[], tags: Tag[]) => {\n return transactions.map((transaction) => ({\n // Post dates are calendar days; format on the UTC day so the export can't\n // shift to the prior day in a Western-offset browser.\n Date: formatDate(fromUnixUTC(transaction.date), DATE_FORMATS_INTL.YEAR_MONTH_DAY),\n Description: getDescription(transaction),\n 'Original Description': transaction.feed_description,\n Amount: `${transaction.amount}`,\n Type: transaction.transaction_type === TransactionType.CREDIT ? 'Credit' : 'Debit',\n 'Parent Category': CategoryGuidToName[transaction.top_level_category_guid || ''],\n Category: transaction.category,\n Account: transaction.account,\n Tags: getTags(transaction, tags),\n Memo: transaction.memo,\n Pending: transaction.isPending ? 'TRUE' : 'FALSE',\n })) as FormattedTransaction[]\n}\n\n/**\n * Escapes a value for safe CSV output\n */\nconst escapeCsvField = (field?: string | null): string => {\n if (!field) return ''\n return /[,\"\\n\\r]/.test(field) ? `\"${field.replace(/\"/g, '\"\"')}\"` : field\n}\n\n/**\n * Structures the CSV file data using the formatted transactions\n */\nconst structureCSVData = (formattedTransactions: FormattedTransaction[]) => {\n // Guard the empty export: Object.keys(undefined) would throw for a zero-row\n // list (e.g. an over-filtered range), so emit an empty file instead.\n if (formattedTransactions.length === 0) return ''\n\n const csvHeader = Object.keys(formattedTransactions[0]).join(',').concat('\\r\\n')\n const csvRows = formattedTransactions\n .map((transaction) => Object.values(transaction).map(escapeCsvField).join(','))\n .join('\\r\\n')\n\n return csvHeader + csvRows\n}\n\n/**\n * Get the description for a transaction that will be used within the CSV copy.\n * We want to highlight that split transactions are a split as well as\n * hidden transactions are hidden.\n */\nconst getDescription = (transaction: Transaction) => {\n let description = transaction.parent_guid ? 'Split: ' : ''\n description += transaction.is_hidden ? '(Excluded) ' : ''\n description += transaction.description\n\n return description\n}\n\nconst getTags = (transaction: Transaction, tags: Tag[]) => {\n return transaction.tags\n .map((tagGuid) => {\n const tag = tags.filter((t) => t.guid === tagGuid)[0]\n\n return tag?.name ?? ''\n })\n .join(' ')\n}\n"],"mappings":";;;;;;;;;;;;;AA+BA,IAAa,IAAA,CACX,MACY,EAAY,4BAA4B,EAAc,UAUvD,KAAA,CACX,GACA,GACA,GACA,IAAsB,CAAC,MACpB;AACH,QAAM,IAAc,EAAS,OAAA,CAAQ,GAAkB,OAC9C;AAAA,IAAE,GAAG;AAAA,IAAM,CAAA,EAAQ,IAAA,GAAO;AAAA,EAAQ,IACxC,CAAC,CAAC,GAEC,IAAgB,EAAW,OAAA,CAAQ,GAAoB,OACpD;AAAA,IAAE,GAAG;AAAA,IAAM,CAAA,EAAS,IAAA,GAAO;AAAA,EAAS,IAC1C,CAAC,CAAC,GAEC,IAAc,EAAS,OAAA,CAAQ,GAAkB,MAAqB;AAC1E,UAAM,EAAE,kBAAA,GAAkB,UAAA,EAAA,IAAa;AAEvC,QAAI,CAAC,EAAI,CAAA,EACP,QAAO;AAAA,MACL,GAAG;AAAA,MACF,CAAA,CAAA,GAAmB,CAAC,CAAQ;AAAA,IAC/B;AAEF,UAAM,IAAO,CAAC,GAAG,EAAI,CAAA,GAAmB,CAAQ;AAEhD,WAAO;AAAA,MACL,GAAG;AAAA,MACF,CAAA,CAAA,GAAmB;AAAA,IACtB;AAAA,EACF,GAAG,CAAC,CAAC;AAEL,SAAO,EAAa,IAAA,CAAK,MAA6B;AACpD,UAAM,IAAU,EAAY,EAAY,YAAA,GAClC,IAAW,EAAY,gBAAgB,EAAc,EAAY,aAAA,IAAiB,MAClF,IAAO,EAAY,EAAY,IAAA,KAAS,CAAC;AAE/C,WAAO;AAAA,MACL,GAAG;AAAA,MACH,SAAS,GAAS,aAAa;AAAA,MAC/B,iBAAiB,GAAS;AAAA,MAC1B,iBAAiB,GAAS;AAAA,MAC1B,UAAU,GAAU,QAAQ;AAAA,MAC5B,iBAAiB,GAAS,aAAa,QAAQ,GAAS,mBAAmB;AAAA,MAC3E,UAAU,EAAY,4BAA4B,EAAc;AAAA,MAChE,WAAW,EAAY,gBAAgB,EAAkB;AAAA,MACzD,QAAQ,GAAS,kBAAkB;AAAA,MACnC,OAAO,EAAY;AAAA,MACnB,MAAA;AAAA,IACF;AAAA,EACF,CAAC;AACH,GAEM,IAAqB,iBAEd,KAAA,CACX,GACA,GACA,GACA,GACA,GACA,MACG;AACH,QAAM,IAAuB,EAAmB,GAAQ,GAAM,CAAY,GAEpE,IAAqB,EAAiB,GAAsB,GAAY,CAAa;AAE3F,SAAA,EAAe,QAAA,CAAS,MAAS;AAC/B,UAAM,IAAQ,EAAmB,UAAA,CAAW,MAAM,EAAE,SAAS,CAAI,GAC3D,IAAW,EAAa,OAAA,CAAQ,MAAM,EAAE,gBAAgB,CAAI;AAClE,IAAA,EAAmB,OAAO,IAAQ,GAAG,GAAG,GAAG,CAAQ;AAAA,EACrD,CAAC,GACM;AACT,GAEM,IAAA,CACJ,GACA,GACA,MACG;AACH,QAAM,EACJ,UAAA,IAAW,CAAC,GACZ,WAAA,IAAY;AAAA,IAAE,OAAO,EAAa,EAAa,CAAC;AAAA,IAAG,KAAK,EAAW;AAAA,EAAE,GACrE,QAAA,IAAA,MAAe,IACf,YAAY,IAAe,IAC3B,YAAA,IAAa,GAAA,IACX;AAEJ,SACE,EAGG,OAAA,CAAQ,MAAO,IAAa,CAAC,EAAE,iBAAiB,CAAC,EAAE,WAAY,EAE/D,OAAA,CAAQ,MAAM,EAAQ,EAAS,KAAA,CAAM,MAAS,MAAS,EAAE,YAAY,CAAE,EAQvE,OAAA,CAAQ,MAAM,EAAE,QAAQ,EAAY,EAAU,KAAK,KAAK,EAAE,QAAQ,EAAY,EAAU,GAAG,CAAC,EAE5F,OAAO,CAAM,EAEb,OAAA,CAAQ,MAAgB;AAEvB,QAAI,MAAiB,KAAsB,EAAY,eACrD,QAAO;AAKT,QACE,QAAa,KAAK,CAAY,MAC7B,EAAY,kBAA0B,EAAY,aAEnD,QAAO;AAIT,UAAM,IAAwB,EAAY,KAAK,KAAA,CAAM,MACnD,EAAmB,GAAc,EAAK,KAAA,CAAM,MAAQ,EAAI,SAAS,CAAI,GAAG,IAAI,CAC9E,GACM,IAAO,EAAa,EAAY,IAAI;AAC1C,WACE,EAAmB,GAAc,EAAY,KAAK,KAClD,EAAmB,GAAc,EAAY,gBAAgB,KAC7D,EAAmB,GAAc,EAAY,QAAQ,KACrD,EAAmB,GAAc,EAAW,GAAM,EAAkB,KAAK,CAAC,KAC1E,EAAmB,GAAc,EAAW,GAAM,EAAkB,GAAG,CAAC,KACxE,EAAmB,GAAc,EAAW,GAAM,EAAkB,cAAc,CAAC,KACnF,EAAmB,GAAc,EAAW,GAAM,EAAkB,cAAc,CAAC,KACnF,EAAmB,GAAc,EAAO,GAAA,IAAyB,CAAC,KAClE,EAAmB,GAAc,EAAY,OAAO,KACpD,EAAmB,GAAc,EAAe,EAAY,QAAQ,QAAQ,CAAC,KAC7E,EAAmB,GAAc,EAAY,IAAI,KACjD;AAAA,EAEJ,CAAC;AAEP,GAEM,IAAA,CACJ,GACA,GACA,MAEO,CAAC,GAAG,CAAY,EAAE,KAAA,CAAM,GAAgB,MAAmB;AAChE,QAAM,IAAS,GACT,KAAe,EAAE,CAAA,KAAW,OAAO,EAAE,CAAA,KAAW;AAEtD,MAAI,IAAU,IAAc,KAAK,GAC7B,IAAW,IAAc,IAAI;AAEjC,UAAI,MAAe,EAAa,QAAQ,MAAe,EAAa,YAClE,IAAU,IAAc,IAAI,IAC5B,IAAW,IAAc,KAAK,IAGzB,MAAkB,EAAY,MAAM,IAAU;AACvD,CAAC,GAMG,IAAA,CAAsB,GAAsB,MAAqC;AACrF,QAAM,IAAkB,EAAa,YAAY,EAAE,MAAM,GAAG,GACtD,IAAkB,GAAO,SAAS,EAAE,YAAY,KAAK;AAE3D,SAAO,EAAgB,MAAA,CAAO,MAAW,EAAgB,QAAQ,CAAM,IAAI,EAAE;AAC/E;AAqBA,SAAS,EAA8B,GAA0C;AAC/E,SAAO,IAAI,IACT,EAAa,OAAA,CAAQ,MAAO,EAAG,gBAAgB,MAAS,EAAE,IAAA,CAAK,MAAO,EAAG,WAAY,CACvF;AACF;AAMA,SAAS,EAA6B,GAA4D;AAChG,SAAO,EAAa,OAAA,CAAuC,GAAa,OAClE,EAAG,gBACA,EAAY,EAAG,WAAA,MAAc,EAAY,EAAG,WAAA,IAAe,CAAC,IACjE,EAAY,EAAG,WAAA,EAAa,KAAK,CAAE,IAE9B,IACN,CAAC,CAAC;AACP;AAQA,SAAgB,GACd,GACA,GACe;AAEf,QAAM,IAAmC,EAA8B,CAAe,GAGhF,IAAmC,EAA6B,CAAe,GAG/E,IAA4B,oBAAI,IAAY,GAG5C,IAA0C,CAAC;AAEjD,aAAW,KAAe,EACxB,CAAI,EAAiC,IAAI,EAAY,IAAI,KAExB,EAAiC,EAAY,IAAA,KAAS,CAAC,GAGnF,MAAM,EACN,KAAA,CAAM,GAAG,MAAM,KAAK,IAAI,EAAE,MAAM,IAAI,KAAK,IAAI,EAAE,MAAM,CAAC,EACtD,QAAA,CAAS,MAAqB;AAC7B,IAAK,EAA0B,IAAI,EAAiB,IAAI,MACtD,EAAyB,KAAK,CAAgB,GAC9C,EAA0B,IAAI,EAAiB,IAAI;AAAA,EAEvD,CAAC,IACO,EAA0B,IAAI,EAAY,IAAI,MAExD,EAAyB,KAAK,CAAW,GACzC,EAA0B,IAAI,EAAY,IAAI;AAIlD,SAAO;AACT;AAEA,IAAa,KAAA,CAA2B,GAA6B,MAAgB;AACnF,QAAM,IAAa,EAAiB,EAAmB,GAAc,CAAI,CAAC,GAEpE,IAAO,IAAI,KAAK,CAAC,CAAU,GAAG,EAAE,MAAM,0BAA0B,CAAC,GACjE,IAAO,SAAS,cAAc,GAAG;AACvC,EAAA,EAAK,OAAO,IAAI,gBAAgB,CAAI,GACpC,EAAK,aAAa,YAAY,kBAAkB,GAEhD,SAAS,KAAK,YAAY,CAAI,GAC9B,EAAK,MAAM,GACX,SAAS,KAAK,YAAY,CAAI,GAE9B,IAAI,gBAAgB,EAAK,IAAI;AAC/B,GAMM,IAAA,CAAsB,GAA6B,MAChD,EAAa,IAAA,CAAK,OAAiB;AAAA,EAGxC,MAAM,EAAW,EAAY,EAAY,IAAI,GAAG,EAAkB,cAAc;AAAA,EAChF,aAAa,EAAe,CAAW;AAAA,EACvC,wBAAwB,EAAY;AAAA,EACpC,QAAQ,GAAG,EAAY,MAAA;AAAA,EACvB,MAAM,EAAY,qBAAqB,EAAgB,SAAS,WAAW;AAAA,EAC3E,mBAAmB,EAAmB,EAAY,2BAA2B,EAAA;AAAA,EAC7E,UAAU,EAAY;AAAA,EACtB,SAAS,EAAY;AAAA,EACrB,MAAM,EAAQ,GAAa,CAAI;AAAA,EAC/B,MAAM,EAAY;AAAA,EAClB,SAAS,EAAY,YAAY,SAAS;AAC5C,EAAE,GAME,IAAA,CAAkB,MACjB,IACE,WAAW,KAAK,CAAK,IAAI,IAAI,EAAM,QAAQ,MAAM,IAAI,CAAA,MAAO,IADhD,IAOf,IAAA,CAAoB,MAGpB,EAAsB,WAAW,IAAU,KAE7B,OAAO,KAAK,EAAsB,CAAA,CAAE,EAAE,KAAK,GAAG,EAAE,OAAO;AAAA,CAKlE,IAJS,EACb,IAAA,CAAK,MAAgB,OAAO,OAAO,CAAW,EAAE,IAAI,CAAc,EAAE,KAAK,GAAG,CAAC,EAC7E,KAAK;AAAA,CAEW,GAQf,IAAA,CAAkB,MAA6B;AACnD,MAAI,IAAc,EAAY,cAAc,YAAY;AACxD,SAAA,KAAe,EAAY,YAAY,gBAAgB,IACvD,KAAe,EAAY,aAEpB;AACT,GAEM,IAAA,CAAW,GAA0B,MAClC,EAAY,KAChB,IAAA,CAAK,MACQ,EAAK,OAAA,CAAQ,MAAM,EAAE,SAAS,CAAO,EAAE,CAAA,GAEvC,QAAQ,EACrB,EACA,KAAK,GAAG"}
1
+ {"version":3,"file":"TransactionUtils.es.js","names":[],"sources":["../../../src/core/utils/TransactionUtils.ts"],"sourcesContent":["import { endOfToday } from 'date-fns/endOfToday'\nimport { format } from 'date-fns/format'\nimport { fromUnixTime } from 'date-fns/fromUnixTime'\nimport { getUnixTime } from 'date-fns/getUnixTime'\nimport { startOfMonth } from 'date-fns/startOfMonth'\nimport { startOfToday } from 'date-fns/startOfToday'\n\nimport { TABLE_CONST } from '../constants/Table'\nimport {\n CategoryGuids,\n CategoryGuidToName,\n DATE_FORMATS_INTL,\n formatDate,\n ORDINAL_DATE_FORMAT,\n} from '../constants'\nimport { COLUMN_NAMES } from '../constants/Transaction'\nimport { TransactionStatus, TransactionType } from '../types'\nimport type { Category, CategoryCopy, DetailedAccount, Tag, Tagging, Transaction } from '../types'\n\nimport { type TransactionFilter } from '../stores/TransactionStore'\n\nimport { getLocalizedCategoryName } from './CategoryUtil'\nimport { fromUnixUTC } from './DateUtil'\nimport { formatCurrency } from './NumberFormatting'\n\ninterface AccountsMap {\n [key: string]: DetailedAccount\n}\n\n// True for account-to-account transfers (top-level Transfer category). Used to\n// swap the payee/description for the institution name in the transaction detail\n// header, the table Payee column, and the mobile list.\nexport const isTransferTransaction = (\n transaction: Pick<Transaction, 'top_level_category_guid'>,\n): boolean => transaction.top_level_category_guid === CategoryGuids.TRANSFER\n\ninterface CategoriesMap {\n [key: string]: Category\n}\n\ninterface TaggingsMap {\n [key: string]: string[]\n}\n\nexport const buildDetailedTransactions = (\n transactions: Transaction[],\n accounts: DetailedAccount[],\n categories: Category[],\n taggings: Tagging[] = [],\n categoryCopy: CategoryCopy,\n) => {\n const accountsMap = accounts.reduce((acc: AccountsMap, account: DetailedAccount) => {\n return { ...acc, [account.guid]: account }\n }, {})\n\n const categoriesMap = categories.reduce((acc: CategoriesMap, category: Category) => {\n return { ...acc, [category.guid]: category }\n }, {})\n\n const taggingsMap = taggings.reduce((acc: TaggingsMap, tagging: Tagging) => {\n const { transaction_guid, tag_guid } = tagging\n\n if (!acc[transaction_guid]) {\n return {\n ...acc,\n [transaction_guid]: [tag_guid],\n }\n }\n const tags = [...acc[transaction_guid], tag_guid] as string[]\n\n return {\n ...acc,\n [transaction_guid]: tags,\n }\n }, {})\n\n return transactions.map((transaction: Transaction) => {\n const account = accountsMap[transaction.account_guid]\n const category = transaction.category_guid ? categoriesMap[transaction.category_guid] : null\n const tags = taggingsMap[transaction.guid] ?? []\n\n return {\n ...transaction,\n account: account?.user_name || 'Unknown',\n accountIsClosed: account?.is_closed,\n accountIsHidden: account?.is_hidden,\n category: category ? getLocalizedCategoryName(category, categoryCopy) : 'Uncategorized',\n institutionName: account?.institution?.name || account?.institutionName || undefined,\n isIncome: transaction.top_level_category_guid === CategoryGuids.INCOME,\n isPending: transaction.feed_status === TransactionStatus.PENDING,\n number: account?.account_number || '',\n payee: transaction.description,\n tags,\n }\n })\n}\n\nconst UNCATEGORIZED_TERM = 'uncategorized'\n\nexport const sortAndFilterTransactions = (\n filter: TransactionFilter,\n expandedSplits: string[],\n sortColumn: string,\n sortDirection: string,\n tags: Tag[],\n transactions: Transaction[],\n) => {\n const filteredTransactions = filterTransactions(filter, tags, transactions)\n\n const sortedTransactions = sortTransactions(filteredTransactions, sortColumn, sortDirection)\n\n expandedSplits.forEach((guid) => {\n const index = sortedTransactions.findIndex((t) => t.guid === guid)\n const children = transactions.filter((t) => t.parent_guid === guid)\n sortedTransactions.splice(index + 1, 0, ...children)\n })\n return sortedTransactions\n}\n\nconst filterTransactions = (\n filter: TransactionFilter,\n tags: Tag[],\n transactions: Transaction[],\n) => {\n const {\n accounts = [],\n dateRange = { start: startOfMonth(startOfToday()), end: endOfToday() },\n custom = () => true,\n searchTerm: searchFilter = '',\n showSplits = false,\n } = filter\n\n return (\n transactions\n // Filters out parent of split transactions when showSplits is true and filters out split\n // transaction children when showSplits is false\n .filter((t) => (showSplits ? !t.has_been_split : !t.parent_guid))\n // Filter for selected accounts\n .filter((t) => Boolean(accounts.find((guid) => guid === t.account_guid)))\n // Filter for Date Range.\n // NOTE: bounds are local-midnight (getUnixTime of a local Date) while dates\n // are rendered/exported on the UTC calendar day (fromUnixUTC). For a\n // midnight-UTC row near a month boundary in a negative-offset browser the\n // two can disagree by a day. Left as-is here to keep this fix low-risk;\n // unifying range + search on UTC is tracked with the core-data ISO\n // migration (MEW-3961 follow-up).\n .filter((t) => t.date >= getUnixTime(dateRange.start) && t.date <= getUnixTime(dateRange.end))\n // Custom filter\n .filter(custom)\n // Search filter\n .filter((transaction) => {\n // Don't return uncategorized split transactions\n if (searchFilter === UNCATEGORIZED_TERM && transaction.has_been_split) {\n return false\n }\n\n // Split check - When searching for \"Splits\" and transaction is a split or is a parent of a split(s)\n const splitPattern = /^spl/i\n if (\n splitPattern.test(searchFilter) &&\n (transaction.has_been_split || Boolean(transaction.parent_guid))\n ) {\n return true\n }\n\n // Check transactions tags\n const isTagIncludedInSearch = transaction.tags.some((guid) =>\n isIncludedInSearch(searchFilter, tags.find((tag) => tag.guid === guid)?.name),\n )\n const date = fromUnixTime(transaction.date)\n return (\n isIncludedInSearch(searchFilter, transaction.payee) ||\n isIncludedInSearch(searchFilter, transaction.feed_description) ||\n isIncludedInSearch(searchFilter, transaction.category) ||\n isIncludedInSearch(searchFilter, formatDate(date, DATE_FORMATS_INTL.MONTH)) ||\n isIncludedInSearch(searchFilter, formatDate(date, DATE_FORMATS_INTL.DAY)) ||\n isIncludedInSearch(searchFilter, formatDate(date, DATE_FORMATS_INTL.FULL_MONTH_DAY)) ||\n isIncludedInSearch(searchFilter, formatDate(date, DATE_FORMATS_INTL.MONTH_DAY_YEAR)) ||\n isIncludedInSearch(searchFilter, format(date, ORDINAL_DATE_FORMAT)) ||\n isIncludedInSearch(searchFilter, transaction.account) ||\n isIncludedInSearch(searchFilter, formatCurrency(transaction.amount, '0,0.00')) ||\n isIncludedInSearch(searchFilter, transaction.memo) ||\n isTagIncludedInSearch\n )\n })\n )\n}\n\nconst sortTransactions = (\n transactions: Transaction[],\n sortColumn: string,\n sortDirection: string,\n) => {\n return [...transactions].sort((a: Transaction, b: Transaction) => {\n const column = sortColumn as keyof Transaction\n const sortCompare = (a[column] || '') > (b[column] || '')\n\n let sortASC = sortCompare ? -1 : 1\n let sortDESC = sortCompare ? 1 : -1\n\n if (sortColumn === COLUMN_NAMES.DATE || sortColumn === COLUMN_NAMES.AMOUNT) {\n sortASC = sortCompare ? 1 : -1\n sortDESC = sortCompare ? -1 : 1\n }\n\n return sortDirection === TABLE_CONST.ASC ? sortASC : sortDESC\n })\n}\n\n/**\n * Determines if a value is included within the terms set in the search bar\n */\nconst isIncludedInSearch = (searchFilter: string, value: string | null | undefined) => {\n const lowerCasedTerms = searchFilter.toLowerCase().split(' ')\n const lowerCasedValue = value?.toString().toLowerCase() ?? ''\n\n return lowerCasedTerms.every((filter) => lowerCasedValue.indexOf(filter) > -1)\n}\n\n// TODO: Change the way formatting data is exported in order to handle localization\ntype FormattedTransaction = {\n Date: string\n Description: string\n 'Original Description': string\n Amount: string\n Type: string\n 'Parent Category': string\n Category: string\n Account: string\n Tags: string\n Memo: string\n Pending: string\n}\n\n/**\n * Collects the GUIDs of all transactions that act as parents\n * to one or more split (child) transactions.\n */\nfunction extractParentTransactionGuids(transactions: Transaction[]): Set<string> {\n return new Set(\n transactions.filter((tx) => tx.parent_guid !== undefined).map((tx) => tx.parent_guid!),\n )\n}\n\n/**\n * Organizes child transactions by their parent transaction GUID.\n * Returns a map from parent GUID to an array of its child transactions.\n */\nfunction mapChildTransactionsByParent(transactions: Transaction[]): Record<string, Transaction[]> {\n return transactions.reduce<Record<string, Transaction[]>>((accumulator, tx) => {\n if (tx.parent_guid) {\n if (!accumulator[tx.parent_guid]) accumulator[tx.parent_guid] = []\n accumulator[tx.parent_guid].push(tx)\n }\n return accumulator\n }, {})\n}\n\n/**\n * Produces a list of transactions based on the given sorted transactions,\n * where parent transactions that have split children are replaced by those\n * children sorted by descending absolute amount. All other transactions\n * are included as-is, with duplicates removed.\n */\nexport function flattenTransactionsWithSplits(\n sortedTransactions: Transaction[],\n allTransactions: Transaction[],\n): Transaction[] {\n // Set of parent transaction GUIDs that have split child transactions\n const parentTransactionGuidsWithSplits = extractParentTransactionGuids(allTransactions)\n\n // Map from parent GUID to array of its child split transactions\n const childTransactionsGroupedByParent = mapChildTransactionsByParent(allTransactions)\n\n // Track GUIDs of transactions already included in the result to avoid duplicates\n const processedTransactionGuids = new Set<string>()\n\n // Resulting list of transactions with parents replaced by their split children\n const flattenedTransactionList: Transaction[] = []\n\n for (const transaction of sortedTransactions) {\n if (parentTransactionGuidsWithSplits.has(transaction.guid)) {\n // This transaction is a parent with splits, so replace it with its children\n const splitChildTransactions = childTransactionsGroupedByParent[transaction.guid] ?? []\n\n splitChildTransactions\n .slice()\n .sort((a, b) => Math.abs(b.amount) - Math.abs(a.amount))\n .forEach((childTransaction) => {\n if (!processedTransactionGuids.has(childTransaction.guid)) {\n flattenedTransactionList.push(childTransaction)\n processedTransactionGuids.add(childTransaction.guid)\n }\n })\n } else if (!processedTransactionGuids.has(transaction.guid)) {\n // Normal transaction (no splits), add as-is if not already added\n flattenedTransactionList.push(transaction)\n processedTransactionGuids.add(transaction.guid)\n }\n }\n\n return flattenedTransactionList\n}\n\nexport const exportTransactionsToCSV = (transactions: Transaction[], tags: Tag[]) => {\n const csvContent = structureCSVData(formatTransactions(transactions, tags))\n\n const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' })\n const link = document.createElement('a')\n link.href = URL.createObjectURL(blob)\n link.setAttribute('download', 'transactions.csv')\n\n document.body.appendChild(link)\n link.click()\n document.body.removeChild(link)\n\n URL.revokeObjectURL(link.href)\n}\n\n/**\n * Formats a list of transactions into a list that will be used when\n * downloaded to a CSV file.\n */\nconst formatTransactions = (transactions: Transaction[], tags: Tag[]) => {\n return transactions.map((transaction) => ({\n // Post dates are calendar days; format on the UTC day so the export can't\n // shift to the prior day in a Western-offset browser.\n Date: formatDate(fromUnixUTC(transaction.date), DATE_FORMATS_INTL.YEAR_MONTH_DAY),\n Description: getDescription(transaction),\n 'Original Description': transaction.feed_description,\n Amount: `${transaction.amount}`,\n Type: transaction.transaction_type === TransactionType.CREDIT ? 'Credit' : 'Debit',\n 'Parent Category': CategoryGuidToName[transaction.top_level_category_guid || ''],\n Category: transaction.category,\n Account: transaction.account,\n Tags: getTags(transaction, tags),\n Memo: transaction.memo,\n Pending: transaction.isPending ? 'TRUE' : 'FALSE',\n })) as FormattedTransaction[]\n}\n\n/**\n * Escapes a value for safe CSV output\n */\nconst escapeCsvField = (field?: string | null): string => {\n if (!field) return ''\n return /[,\"\\n\\r]/.test(field) ? `\"${field.replace(/\"/g, '\"\"')}\"` : field\n}\n\n/**\n * Structures the CSV file data using the formatted transactions\n */\nconst structureCSVData = (formattedTransactions: FormattedTransaction[]) => {\n // Guard the empty export: Object.keys(undefined) would throw for a zero-row\n // list (e.g. an over-filtered range), so emit an empty file instead.\n if (formattedTransactions.length === 0) return ''\n\n const csvHeader = Object.keys(formattedTransactions[0]).join(',').concat('\\r\\n')\n const csvRows = formattedTransactions\n .map((transaction) => Object.values(transaction).map(escapeCsvField).join(','))\n .join('\\r\\n')\n\n return csvHeader + csvRows\n}\n\n/**\n * Get the description for a transaction that will be used within the CSV copy.\n * We want to highlight that split transactions are a split as well as\n * hidden transactions are hidden.\n */\nconst getDescription = (transaction: Transaction) => {\n let description = transaction.parent_guid ? 'Split: ' : ''\n description += transaction.is_hidden ? '(Excluded) ' : ''\n description += transaction.description\n\n return description\n}\n\nconst getTags = (transaction: Transaction, tags: Tag[]) => {\n return transaction.tags\n .map((tagGuid) => {\n const tag = tags.filter((t) => t.guid === tagGuid)[0]\n\n return tag?.name ?? ''\n })\n .join(' ')\n}\n"],"mappings":"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"}
@@ -1,21 +1,21 @@
1
- import { AccountTypeName as a } from "../../../core/types/Account.es.js";
2
- import o from "@mui/material/Stack";
3
- import { InstitutionLogo as u, Text as i } from "@mxenabled/mxui";
4
- import { jsx as n, jsxs as c } from "react/jsx-runtime";
5
- var d = (r) => {
6
- const t = r.row.account, e = a[t.account_type];
7
- return /* @__PURE__ */ c(o, {
1
+ import { useGlobalCopyStore as u } from "../../../common/context/hooks.es.js";
2
+ import n from "@mui/material/Stack";
3
+ import { InstitutionLogo as s, Text as c } from "@mxenabled/mxui";
4
+ import { jsx as o, jsxs as i } from "react/jsx-runtime";
5
+ var f = (r) => {
6
+ const { accounts: a } = u(), t = r.row.account, e = a.account_types[t.account_type];
7
+ return /* @__PURE__ */ i(n, {
8
8
  alignItems: "center",
9
9
  flexDirection: "row",
10
- children: [/* @__PURE__ */ n(u, {
10
+ children: [/* @__PURE__ */ o(s, {
11
11
  alt: `${t.institutionName}`,
12
12
  institutionGuid: t.institution_guid || ""
13
- }), /* @__PURE__ */ c(o, {
13
+ }), /* @__PURE__ */ i(n, {
14
14
  ml: 12,
15
- children: [/* @__PURE__ */ n(i, {
15
+ children: [/* @__PURE__ */ o(c, {
16
16
  variant: "body2",
17
17
  children: t.name
18
- }), /* @__PURE__ */ n(i, {
18
+ }), /* @__PURE__ */ o(c, {
19
19
  variant: "caption",
20
20
  children: e
21
21
  })]
@@ -23,8 +23,8 @@ var d = (r) => {
23
23
  });
24
24
  };
25
25
  export {
26
- d as AccountCell,
27
- d as default
26
+ f as AccountCell,
27
+ f as default
28
28
  };
29
29
 
30
30
  //# sourceMappingURL=AccountCell.es.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"AccountCell.es.js","names":[],"sources":["../../../../src/debts/components/debtstable/AccountCell.tsx"],"sourcesContent":["import { GridCellParams } from '@mui/x-data-grid-pro'\nimport { InstitutionLogo, Text } from '@mxenabled/mxui'\nimport Stack from '@mui/material/Stack'\n\nimport { AccountTypeName, type Account } from '../../../core'\n\nexport const AccountCell = (params: GridCellParams) => {\n const account = params.row.account as Account\n const accountType = AccountTypeName[account.account_type]\n\n return (\n <Stack alignItems=\"center\" flexDirection=\"row\">\n <InstitutionLogo\n alt={`${account.institutionName}`}\n institutionGuid={account.institution_guid || ''}\n />\n <Stack ml={12}>\n <Text variant=\"body2\">{account.name}</Text>\n <Text variant=\"caption\">{accountType}</Text>\n </Stack>\n </Stack>\n )\n}\n\nexport default AccountCell\n"],"mappings":";;;;AAMA,IAAa,IAAA,CAAe,MAA2B;AACrD,QAAM,IAAU,EAAO,IAAI,SACrB,IAAc,EAAgB,EAAQ,YAAA;AAE5C,SACE,gBAAA,EAAC,GAAD;AAAA,IAAO,YAAW;AAAA,IAAS,eAAc;AAAA,IAAzC,UAAA,CACE,gBAAA,EAAC,GAAD;AAAA,MACE,KAAK,GAAG,EAAQ,eAAA;AAAA,MAChB,iBAAiB,EAAQ,oBAAoB;AAAA,IAC9C,CAAA,GACD,gBAAA,EAAC,GAAD;AAAA,MAAO,IAAI;AAAA,MAAX,UAAA,CACE,gBAAA,EAAC,GAAD;AAAA,QAAM,SAAQ;AAAA,QAAS,UAAA,EAAQ;AAAA,MAAW,CAAA,GAC1C,gBAAA,EAAC,GAAD;AAAA,QAAM,SAAQ;AAAA,QAAW,UAAA;AAAA,MAAkB,CAAA,CACtC;AAAA,IACF,CAAA,CAAA;AAAA;AAEX"}
1
+ {"version":3,"file":"AccountCell.es.js","names":[],"sources":["../../../../src/debts/components/debtstable/AccountCell.tsx"],"sourcesContent":["import { GridCellParams } from '@mui/x-data-grid-pro'\nimport { InstitutionLogo, Text } from '@mxenabled/mxui'\nimport Stack from '@mui/material/Stack'\n\nimport { type Account } from '../../../core'\nimport { useGlobalCopyStore } from '../../../common'\n\nexport const AccountCell = (params: GridCellParams) => {\n const { accounts: accountsCopy } = useGlobalCopyStore()\n const account = params.row.account as Account\n const accountType = accountsCopy.account_types[account.account_type]\n\n return (\n <Stack alignItems=\"center\" flexDirection=\"row\">\n <InstitutionLogo\n alt={`${account.institutionName}`}\n institutionGuid={account.institution_guid || ''}\n />\n <Stack ml={12}>\n <Text variant=\"body2\">{account.name}</Text>\n <Text variant=\"caption\">{accountType}</Text>\n </Stack>\n </Stack>\n )\n}\n\nexport default AccountCell\n"],"mappings":";;;;AAOA,IAAa,IAAA,CAAe,MAA2B;AACrD,QAAM,EAAE,UAAU,EAAA,IAAiB,EAAmB,GAChD,IAAU,EAAO,IAAI,SACrB,IAAc,EAAa,cAAc,EAAQ,YAAA;AAEvD,SACE,gBAAA,EAAC,GAAD;AAAA,IAAO,YAAW;AAAA,IAAS,eAAc;AAAA,IAAzC,UAAA,CACE,gBAAA,EAAC,GAAD;AAAA,MACE,KAAK,GAAG,EAAQ,eAAA;AAAA,MAChB,iBAAiB,EAAQ,oBAAoB;AAAA,IAC9C,CAAA,GACD,gBAAA,EAAC,GAAD;AAAA,MAAO,IAAI;AAAA,MAAX,UAAA,CACE,gBAAA,EAAC,GAAD;AAAA,QAAM,SAAQ;AAAA,QAAS,UAAA,EAAQ;AAAA,MAAW,CAAA,GAC1C,gBAAA,EAAC,GAAD;AAAA,QAAM,SAAQ;AAAA,QAAW,UAAA;AAAA,MAAkB,CAAA,CACtC;AAAA,IACF,CAAA,CAAA;AAAA;AAEX"}