@mx-cartographer/experiences 9.4.39 → 9.4.41

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 (24) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/dist/core/stores/GlobalStore.es.js +12 -8
  3. package/dist/core/stores/GlobalStore.es.js.map +1 -1
  4. package/dist/core/stores/RecurringTransactionsStore.d.ts +1 -0
  5. package/dist/core/stores/RecurringTransactionsStore.es.js +40 -36
  6. package/dist/core/stores/RecurringTransactionsStore.es.js.map +1 -1
  7. package/dist/core/types/Transaction.d.ts +1 -0
  8. package/dist/core/types/Transaction.es.js.map +1 -1
  9. package/dist/core/utils/TransactionUtils.d.ts +4 -2
  10. package/dist/core/utils/TransactionUtils.es.js +52 -50
  11. package/dist/core/utils/TransactionUtils.es.js.map +1 -1
  12. package/dist/transactions/components/shared/TransactionDetails.es.js +84 -82
  13. package/dist/transactions/components/shared/TransactionDetails.es.js.map +1 -1
  14. package/dist/transactions/components/shared/transactiondetails/Description.d.ts +1 -0
  15. package/dist/transactions/components/shared/transactiondetails/Description.es.js +39 -39
  16. package/dist/transactions/components/shared/transactiondetails/Description.es.js.map +1 -1
  17. package/dist/transactions/components/shared/transactiondetails/TransactionAmountHeader.es.js +18 -17
  18. package/dist/transactions/components/shared/transactiondetails/TransactionAmountHeader.es.js.map +1 -1
  19. package/dist/transactions/components/shared/transactionlist/TransactionRow.es.js +26 -25
  20. package/dist/transactions/components/shared/transactionlist/TransactionRow.es.js.map +1 -1
  21. package/dist/transactions/components/shared/transactiontable/cells/PayeeCell.d.ts +2 -1
  22. package/dist/transactions/components/shared/transactiontable/cells/PayeeCell.es.js +27 -23
  23. package/dist/transactions/components/shared/transactiontable/cells/PayeeCell.es.js.map +1 -1
  24. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -1,3 +1,11 @@
1
+ ## [9.4.41] - 09-24-2026
2
+
3
+ - **FIXED** - Account-to-account transfers now show the institution name instead of the raw feed description in the transaction detail header title and the transactions table/list Payee column (MEW-3972)
4
+
5
+ ## [9.4.40] - 09-24-2026
6
+
7
+ - **FIXED** - double error reporting from Recurring Transactions. Its errors now surface only through `onCaptureException`, and `GlobalStore.captureException` falls back to `console.error` when the host provides no handler (MEW-4169)
8
+
1
9
  ## [9.4.39] - 09-23-2026
2
10
 
3
11
  - **FIXED** - Trends category rows no longer show a nonzero total with "0 transactions" and no chevron. (MEW-4021)
@@ -8,7 +8,7 @@ import { CategoryStore as w } from "./CategoryStore.es.js";
8
8
  import { ConnectStore as d } from "./ConnectStore.es.js";
9
9
  import { DebtsStore as u } from "./DebtsStore.es.js";
10
10
  import { FinstrongStore as b } from "./FinstrongStore.es.js";
11
- import { DefaultAppConfig as h } from "../constants/DefaultConfig.es.js";
11
+ import { DefaultAppConfig as S } from "../constants/DefaultConfig.es.js";
12
12
  import { GlobalUiStore as y } from "./GlobalUiStore.es.js";
13
13
  import { GlobalCopyStore as C } from "./GlobalCopyStore.es.js";
14
14
  import { GoalStore as U } from "./GoalStore.es.js";
@@ -24,8 +24,8 @@ import { TransactionStore as M } from "./TransactionStore.es.js";
24
24
  import { TrendsStore as V } from "./TrendsStore.es.js";
25
25
  import { UserStore as W } from "./UserStore.es.js";
26
26
  import { autorun as v, makeAutoObservable as z } from "mobx";
27
- var St = class {
28
- appConfig = h;
27
+ var ht = class {
28
+ appConfig = S;
29
29
  endpoint = "/";
30
30
  sessionToken = "";
31
31
  onCaptureException;
@@ -55,7 +55,7 @@ var St = class {
55
55
  userStore;
56
56
  globalUiStore;
57
57
  insightsV2Store;
58
- constructor(t = h, o = "/", r, e, i) {
58
+ constructor(t = S, o = "/", r, e, i) {
59
59
  this.appConfig = t, this.endpoint = o, this.sessionToken = t.options.session_token ?? "", this.onCaptureException = i, this.onError = r, this.onStoreUpdate = e, this.accountStore = new p(this), this.appDataStore = new c(this), this.analyticsStore = new m(this), this.beatStore = new f(this), this.budgetsStore = new l(this), this.cashflowStore = new g(this), this.categoryStore = new w(this), this.connectStore = new d(this), this.copyStore = new C(this), this.debtsStore = new u(this), this.finstrongStore = new b(this), this.goalStore = new U(this), this.helpStore = new D(this), this.holdingStore = new A(this), this.merchantStore = new E(this), this.netWorthStore = new x(this), this.notificationStore = new k(this), this.recurringTransactionsStore = new G(this), this.settingsStore = new I(this), this.transactionStore = new M(this), this.trendsStore = new V(this), this.userStore = new W(this), this.globalUiStore = new y(this), this.insightsV2Store = new T(this), z(this), v(() => {
60
60
  const { transactions: s } = this.transactionStore;
61
61
  this.emitUpdate({ transactions: s });
@@ -65,7 +65,11 @@ var St = class {
65
65
  return this.globalUiStore.isInitialized;
66
66
  }
67
67
  captureException = (t, o) => {
68
- this.onCaptureException?.(t, o);
68
+ if (this.onCaptureException) {
69
+ this.onCaptureException(t, o);
70
+ return;
71
+ }
72
+ console.error("Unreported error:", t, o);
69
73
  };
70
74
  emitUpdate = (t) => {
71
75
  this.onStoreUpdate?.(t);
@@ -78,12 +82,12 @@ var St = class {
78
82
  this.userStore.loadUserFeatures()
79
83
  ]);
80
84
  };
81
- loadData = async ({ accounts: t, appData: o, associatedBeats: r, categories: e, institutions: i, transactionRules: s, transactions: a, userFeatures: n, merchantBudgets: S } = {}) => {
82
- (!o || !n) && await this.loadConfigData(), o && this.appDataStore.setAppData(o), n && this.userStore.setUserFeatures(n), t && (await this.accountStore.loadMembers(), i && this.accountStore.setInstitutions(i), this.accountStore.setAccounts(t)), r && this.transactionStore.setAssociatedBeats(r), e && this.categoryStore.setCategories(e), a && this.transactionStore.setTransactions(a), s && this.transactionStore.setTransactionRules(s), S && this.budgetsStore.setMerchantBudgets(S);
85
+ loadData = async ({ accounts: t, appData: o, associatedBeats: r, categories: e, institutions: i, transactionRules: s, transactions: a, userFeatures: n, merchantBudgets: h } = {}) => {
86
+ (!o || !n) && await this.loadConfigData(), o && this.appDataStore.setAppData(o), n && this.userStore.setUserFeatures(n), t && (await this.accountStore.loadMembers(), i && this.accountStore.setInstitutions(i), this.accountStore.setAccounts(t)), r && this.transactionStore.setAssociatedBeats(r), e && this.categoryStore.setCategories(e), a && this.transactionStore.setTransactions(a), s && this.transactionStore.setTransactionRules(s), h && this.budgetsStore.setMerchantBudgets(h);
83
87
  };
84
88
  };
85
89
  export {
86
- St as GlobalStore
90
+ ht as GlobalStore
87
91
  };
88
92
 
89
93
  //# sourceMappingURL=GlobalStore.es.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"GlobalStore.es.js","names":[],"sources":["../../../src/core/stores/GlobalStore.ts"],"sourcesContent":["import { autorun, makeAutoObservable } from 'mobx'\n\nimport { DefaultAppConfig } from '../constants/DefaultConfig'\n\nimport {\n AccountStore,\n AnalyticsStore,\n AppDataStore,\n BeatStore,\n BudgetsStore,\n CashflowStore,\n CategoryStore,\n ConnectStore,\n DebtsStore,\n FinstrongStore,\n GlobalCopyStore,\n GlobalUiStore,\n GoalStore,\n HelpStore,\n HoldingStore,\n InsightsV2Store,\n MerchantStore,\n NetWorthStore,\n NotificationStore,\n RecurringTransactionsStore,\n SettingsStore,\n TransactionStore,\n TrendsStore,\n UserStore,\n} from '../stores'\n\nimport type {\n Account,\n Category,\n Institution,\n Member,\n AppConfig,\n AppData,\n Beat,\n GlobalCaptureException,\n GlobalErrorHandler,\n MerchantBudget,\n Tag,\n Tagging,\n Transaction,\n TransactionRule,\n UserFeature,\n} from '../types'\n\ninterface LoadDataProps {\n accounts?: Account[]\n appData?: AppData\n associatedBeats?: Beat[]\n categories?: Category[]\n institutions?: Institution[]\n members?: Member[]\n merchantBudgets?: MerchantBudget[]\n taggings?: Tagging[]\n tags?: Tag[]\n transactionRules?: TransactionRule[]\n transactions?: Transaction[]\n userFeatures?: UserFeature[]\n}\n\ntype OnStoreUpdate = (update: ObservedUpdate) => void\ntype ObservedUpdate = {\n transactions: Transaction[]\n}\nexport class GlobalStore {\n // Global properties\n appConfig: AppConfig = DefaultAppConfig\n endpoint: string = '/'\n sessionToken: string = ''\n onCaptureException?: GlobalCaptureException\n onError?: GlobalErrorHandler\n onStoreUpdate?: OnStoreUpdate\n\n // Data Stores\n accountStore: AccountStore\n appDataStore: AppDataStore\n analyticsStore: AnalyticsStore\n beatStore: BeatStore\n budgetsStore: BudgetsStore\n cashflowStore: CashflowStore\n categoryStore: CategoryStore\n connectStore: ConnectStore\n copyStore: GlobalCopyStore\n debtsStore: DebtsStore\n finstrongStore: FinstrongStore\n goalStore: GoalStore\n helpStore: HelpStore\n holdingStore: HoldingStore\n merchantStore: MerchantStore\n netWorthStore: NetWorthStore\n notificationStore: NotificationStore\n recurringTransactionsStore: RecurringTransactionsStore\n settingsStore: SettingsStore\n transactionStore: TransactionStore\n trendsStore: TrendsStore\n userStore: UserStore\n\n // UI Stores\n globalUiStore: GlobalUiStore\n insightsV2Store: InsightsV2Store\n\n constructor(\n appConfig: AppConfig = DefaultAppConfig,\n endpoint: string = '/',\n onError?: GlobalErrorHandler,\n onStoreUpdate?: OnStoreUpdate,\n onCaptureException?: GlobalCaptureException,\n ) {\n this.appConfig = appConfig\n this.endpoint = endpoint\n this.sessionToken = appConfig.options.session_token ?? ''\n this.onCaptureException = onCaptureException\n this.onError = onError\n this.onStoreUpdate = onStoreUpdate\n\n this.accountStore = new AccountStore(this)\n this.appDataStore = new AppDataStore(this)\n this.analyticsStore = new AnalyticsStore(this)\n this.beatStore = new BeatStore(this)\n this.budgetsStore = new BudgetsStore(this)\n this.cashflowStore = new CashflowStore(this)\n this.categoryStore = new CategoryStore(this)\n this.connectStore = new ConnectStore(this)\n this.copyStore = new GlobalCopyStore(this)\n this.debtsStore = new DebtsStore(this)\n this.finstrongStore = new FinstrongStore(this)\n this.goalStore = new GoalStore(this)\n this.helpStore = new HelpStore(this)\n this.holdingStore = new HoldingStore(this)\n this.merchantStore = new MerchantStore(this)\n this.netWorthStore = new NetWorthStore(this)\n this.notificationStore = new NotificationStore(this)\n this.recurringTransactionsStore = new RecurringTransactionsStore(this)\n this.settingsStore = new SettingsStore(this)\n this.transactionStore = new TransactionStore(this)\n this.trendsStore = new TrendsStore(this)\n this.userStore = new UserStore(this)\n\n this.globalUiStore = new GlobalUiStore(this)\n this.insightsV2Store = new InsightsV2Store(this)\n\n makeAutoObservable(this)\n\n // detects a change based on an observed value\n autorun(() => {\n // destructure or assign new variables to observe changes to them\n // in this case we are observing changes to `transactions`\n const { transactions } = this.transactionStore\n this.emitUpdate({\n transactions,\n })\n })\n }\n\n get isInitialized() {\n return this.globalUiStore.isInitialized\n }\n\n captureException = (error: unknown, context?: Record<string, string>) => {\n this.onCaptureException?.(error, context)\n }\n\n // emits change triggered in the autorun\n emitUpdate = (change: ObservedUpdate) => {\n this.onStoreUpdate?.(change)\n }\n\n loadConfigData = async () => {\n await Promise.all([\n // Load copy, config and user data\n this.copyStore.loadCopy(),\n this.appDataStore.loadAppData(),\n this.accountStore.refreshMembers(),\n this.userStore.loadUserFeatures(),\n ])\n }\n\n loadData = async ({\n accounts,\n appData,\n associatedBeats,\n categories,\n institutions,\n transactionRules,\n transactions,\n userFeatures,\n merchantBudgets,\n }: LoadDataProps = {}) => {\n if (!appData || !userFeatures) {\n await this.loadConfigData()\n }\n\n // Keep for backwards compatibility for Insights\n if (appData) {\n this.appDataStore.setAppData(appData)\n }\n\n if (userFeatures) {\n this.userStore.setUserFeatures(userFeatures)\n }\n\n if (accounts) {\n await this.accountStore.loadMembers()\n if (institutions) {\n this.accountStore.setInstitutions(institutions)\n }\n this.accountStore.setAccounts(accounts)\n }\n\n if (associatedBeats) {\n this.transactionStore.setAssociatedBeats(associatedBeats)\n }\n\n if (categories) {\n this.categoryStore.setCategories(categories)\n }\n\n if (transactions) {\n this.transactionStore.setTransactions(transactions)\n }\n\n if (transactionRules) {\n this.transactionStore.setTransactionRules(transactionRules)\n }\n\n if (merchantBudgets) {\n this.budgetsStore.setMerchantBudgets(merchantBudgets)\n }\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"GlobalStore.es.js","names":[],"sources":["../../../src/core/stores/GlobalStore.ts"],"sourcesContent":["import { autorun, makeAutoObservable } from 'mobx'\n\nimport { DefaultAppConfig } from '../constants/DefaultConfig'\n\nimport {\n AccountStore,\n AnalyticsStore,\n AppDataStore,\n BeatStore,\n BudgetsStore,\n CashflowStore,\n CategoryStore,\n ConnectStore,\n DebtsStore,\n FinstrongStore,\n GlobalCopyStore,\n GlobalUiStore,\n GoalStore,\n HelpStore,\n HoldingStore,\n InsightsV2Store,\n MerchantStore,\n NetWorthStore,\n NotificationStore,\n RecurringTransactionsStore,\n SettingsStore,\n TransactionStore,\n TrendsStore,\n UserStore,\n} from '../stores'\n\nimport type {\n Account,\n Category,\n Institution,\n Member,\n AppConfig,\n AppData,\n Beat,\n GlobalCaptureException,\n GlobalErrorHandler,\n MerchantBudget,\n Tag,\n Tagging,\n Transaction,\n TransactionRule,\n UserFeature,\n} from '../types'\n\ninterface LoadDataProps {\n accounts?: Account[]\n appData?: AppData\n associatedBeats?: Beat[]\n categories?: Category[]\n institutions?: Institution[]\n members?: Member[]\n merchantBudgets?: MerchantBudget[]\n taggings?: Tagging[]\n tags?: Tag[]\n transactionRules?: TransactionRule[]\n transactions?: Transaction[]\n userFeatures?: UserFeature[]\n}\n\ntype OnStoreUpdate = (update: ObservedUpdate) => void\ntype ObservedUpdate = {\n transactions: Transaction[]\n}\nexport class GlobalStore {\n // Global properties\n appConfig: AppConfig = DefaultAppConfig\n endpoint: string = '/'\n sessionToken: string = ''\n onCaptureException?: GlobalCaptureException\n onError?: GlobalErrorHandler\n onStoreUpdate?: OnStoreUpdate\n\n // Data Stores\n accountStore: AccountStore\n appDataStore: AppDataStore\n analyticsStore: AnalyticsStore\n beatStore: BeatStore\n budgetsStore: BudgetsStore\n cashflowStore: CashflowStore\n categoryStore: CategoryStore\n connectStore: ConnectStore\n copyStore: GlobalCopyStore\n debtsStore: DebtsStore\n finstrongStore: FinstrongStore\n goalStore: GoalStore\n helpStore: HelpStore\n holdingStore: HoldingStore\n merchantStore: MerchantStore\n netWorthStore: NetWorthStore\n notificationStore: NotificationStore\n recurringTransactionsStore: RecurringTransactionsStore\n settingsStore: SettingsStore\n transactionStore: TransactionStore\n trendsStore: TrendsStore\n userStore: UserStore\n\n // UI Stores\n globalUiStore: GlobalUiStore\n insightsV2Store: InsightsV2Store\n\n constructor(\n appConfig: AppConfig = DefaultAppConfig,\n endpoint: string = '/',\n onError?: GlobalErrorHandler,\n onStoreUpdate?: OnStoreUpdate,\n onCaptureException?: GlobalCaptureException,\n ) {\n this.appConfig = appConfig\n this.endpoint = endpoint\n this.sessionToken = appConfig.options.session_token ?? ''\n this.onCaptureException = onCaptureException\n this.onError = onError\n this.onStoreUpdate = onStoreUpdate\n\n this.accountStore = new AccountStore(this)\n this.appDataStore = new AppDataStore(this)\n this.analyticsStore = new AnalyticsStore(this)\n this.beatStore = new BeatStore(this)\n this.budgetsStore = new BudgetsStore(this)\n this.cashflowStore = new CashflowStore(this)\n this.categoryStore = new CategoryStore(this)\n this.connectStore = new ConnectStore(this)\n this.copyStore = new GlobalCopyStore(this)\n this.debtsStore = new DebtsStore(this)\n this.finstrongStore = new FinstrongStore(this)\n this.goalStore = new GoalStore(this)\n this.helpStore = new HelpStore(this)\n this.holdingStore = new HoldingStore(this)\n this.merchantStore = new MerchantStore(this)\n this.netWorthStore = new NetWorthStore(this)\n this.notificationStore = new NotificationStore(this)\n this.recurringTransactionsStore = new RecurringTransactionsStore(this)\n this.settingsStore = new SettingsStore(this)\n this.transactionStore = new TransactionStore(this)\n this.trendsStore = new TrendsStore(this)\n this.userStore = new UserStore(this)\n\n this.globalUiStore = new GlobalUiStore(this)\n this.insightsV2Store = new InsightsV2Store(this)\n\n makeAutoObservable(this)\n\n // detects a change based on an observed value\n autorun(() => {\n // destructure or assign new variables to observe changes to them\n // in this case we are observing changes to `transactions`\n const { transactions } = this.transactionStore\n this.emitUpdate({\n transactions,\n })\n })\n }\n\n get isInitialized() {\n return this.globalUiStore.isInitialized\n }\n\n captureException = (error: unknown, context?: Record<string, string>) => {\n if (this.onCaptureException) {\n this.onCaptureException(error, context)\n return\n }\n console.error('Unreported error:', error, context)\n }\n\n // emits change triggered in the autorun\n emitUpdate = (change: ObservedUpdate) => {\n this.onStoreUpdate?.(change)\n }\n\n loadConfigData = async () => {\n await Promise.all([\n // Load copy, config and user data\n this.copyStore.loadCopy(),\n this.appDataStore.loadAppData(),\n this.accountStore.refreshMembers(),\n this.userStore.loadUserFeatures(),\n ])\n }\n\n loadData = async ({\n accounts,\n appData,\n associatedBeats,\n categories,\n institutions,\n transactionRules,\n transactions,\n userFeatures,\n merchantBudgets,\n }: LoadDataProps = {}) => {\n if (!appData || !userFeatures) {\n await this.loadConfigData()\n }\n\n // Keep for backwards compatibility for Insights\n if (appData) {\n this.appDataStore.setAppData(appData)\n }\n\n if (userFeatures) {\n this.userStore.setUserFeatures(userFeatures)\n }\n\n if (accounts) {\n await this.accountStore.loadMembers()\n if (institutions) {\n this.accountStore.setInstitutions(institutions)\n }\n this.accountStore.setAccounts(accounts)\n }\n\n if (associatedBeats) {\n this.transactionStore.setAssociatedBeats(associatedBeats)\n }\n\n if (categories) {\n this.categoryStore.setCategories(categories)\n }\n\n if (transactions) {\n this.transactionStore.setTransactions(transactions)\n }\n\n if (transactionRules) {\n this.transactionStore.setTransactionRules(transactionRules)\n }\n\n if (merchantBudgets) {\n this.budgetsStore.setMerchantBudgets(merchantBudgets)\n }\n }\n}\n"],"mappings":"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"}
@@ -159,6 +159,7 @@ export declare class RecurringTransactionsStore {
159
159
  * @param transaction - The transaction to unlink.
160
160
  */
161
161
  markRecurrenceAsUnpaid: (transaction: Transaction) => Promise<void>;
162
+ private captureError;
162
163
  setAlert: (message: string, severity?: RecurringAlertProps["severity"]) => {
163
164
  message: string;
164
165
  severity: import('@mui/types').OverridableStringUnion<import('@mui/material').AlertColor, import('@mui/material').AlertPropsColorOverrides> | undefined;
@@ -1,24 +1,24 @@
1
- import { RepeatingTransactionsApi as p } from "../api/RepeatingTransactionsApi.es.js";
2
- import { RecurrenceStatus as n, RecurrenceType as o } from "../types/RepeatingTransaction.es.js";
3
- import { augmentRepeatingTransactions as c, buildAllRecurrences as m } from "../utils/RecurringTransactionsUtil.es.js";
1
+ import { RepeatingTransactionsApi as l } from "../api/RepeatingTransactionsApi.es.js";
2
+ import { RecurrenceStatus as n, RecurrenceType as c } from "../types/RepeatingTransaction.es.js";
3
+ import { augmentRepeatingTransactions as o, buildAllRecurrences as m } from "../utils/RecurringTransactionsUtil.es.js";
4
4
  import { endOfMonth as R } from "date-fns/endOfMonth";
5
5
  import { isBefore as T } from "date-fns/isBefore";
6
6
  import { startOfMonth as f } from "date-fns/startOfMonth";
7
- import { startOfToday as a } from "date-fns/startOfToday";
7
+ import { startOfToday as s } from "date-fns/startOfToday";
8
8
  import { isSameDay as g } from "date-fns/isSameDay";
9
9
  import { isWithinInterval as h } from "date-fns/isWithinInterval";
10
- import { subDays as S } from "date-fns/subDays";
11
- import { makeAutoObservable as y, runInAction as u } from "mobx";
12
- import { isAfter as l } from "date-fns/isAfter";
13
- var d = (e, t) => h(t.expectedDate, e), s = (e, t) => e + t.amount, U = class {
10
+ import { subDays as y } from "date-fns/subDays";
11
+ import { makeAutoObservable as S, runInAction as u } from "mobx";
12
+ import { isAfter as p } from "date-fns/isAfter";
13
+ var d = (e, t) => h(t.expectedDate, e), a = (e, t) => e + t.amount, U = class {
14
14
  globalStore;
15
- api = new p("/", "");
15
+ api = new l("/", "");
16
16
  repeatingTransactions = [];
17
17
  isDataLoaded = !1;
18
18
  selectedDay;
19
19
  dateRange = {
20
- start: f(a()),
21
- end: R(a())
20
+ start: f(s()),
21
+ end: R(s())
22
22
  };
23
23
  selectedRepeatingTransactionGuid = null;
24
24
  selectedRecurrence = null;
@@ -27,7 +27,7 @@ var d = (e, t) => h(t.expectedDate, e), s = (e, t) => e + t.amount, U = class {
27
27
  severity: void 0
28
28
  };
29
29
  constructor(e) {
30
- this.globalStore = e, this.api = new p(e.endpoint, e.sessionToken, e.onError), y(this, {
30
+ this.globalStore = e, this.api = new l(e.endpoint, e.sessionToken, e.onError), S(this, {
31
31
  recurrencesForRange: !1,
32
32
  upcomingExpensesForRange: !1,
33
33
  upcomingIncomeForRange: !1,
@@ -39,16 +39,16 @@ var d = (e, t) => h(t.expectedDate, e), s = (e, t) => e + t.amount, U = class {
39
39
  return this.globalStore.copyStore.copy.recurring;
40
40
  }
41
41
  get detailedRepeatingTransactions() {
42
- return c(this.globalStore.accountStore.visibleAccounts, this.repeatingTransactions, this.globalStore.transactionStore.transactions);
42
+ return o(this.globalStore.accountStore.visibleAccounts, this.repeatingTransactions, this.globalStore.transactionStore.transactions);
43
43
  }
44
44
  recurrencesForRange = (e) => {
45
45
  const t = this.globalStore.accountStore.visibleAccounts;
46
46
  return m(this.detailedRepeatingTransactions, e).filter((r) => t.some((i) => i.guid === r.accountGuid && !i.is_excluded_from_accounts)).filter((r) => h(r.expectedDate, e));
47
47
  };
48
- upcomingExpensesForRange = (e) => this.recurrencesForRange(e).filter((t) => t.type === o.Expense && t.status === n.Upcoming);
49
- incomeForRange = (e) => this.recurrencesForRange(e).filter((t) => t.type === o.Income);
48
+ upcomingExpensesForRange = (e) => this.recurrencesForRange(e).filter((t) => t.type === c.Expense && t.status === n.Upcoming);
49
+ incomeForRange = (e) => this.recurrencesForRange(e).filter((t) => t.type === c.Income);
50
50
  upcomingIncomeForRange = (e) => this.incomeForRange(e).filter((t) => t.status === n.Upcoming);
51
- nextIncomeForRange = (e) => this.upcomingIncomeForRange(e).find((t) => l(t.expectedDate, a()));
51
+ nextIncomeForRange = (e) => this.upcomingIncomeForRange(e).find((t) => p(t.expectedDate, s()));
52
52
  get recurrences() {
53
53
  return this.recurrencesForRange(this.dateRange);
54
54
  }
@@ -56,22 +56,22 @@ var d = (e, t) => h(t.expectedDate, e), s = (e, t) => e + t.amount, U = class {
56
56
  return this.recurrences.filter((e) => e.status === n.Paid || e.status === n.Missed);
57
57
  }
58
58
  get upcomingRecurrences() {
59
- return this.recurrences.filter((e) => l(e.expectedDate, S(a(), 3)) && T(e.expectedDate, this.dateRange.end) && e.status === n.Upcoming);
59
+ return this.recurrences.filter((e) => p(e.expectedDate, y(s(), 3)) && T(e.expectedDate, this.dateRange.end) && e.status === n.Upcoming);
60
60
  }
61
61
  get expenses() {
62
- return this.recurrences.filter((e) => e.type === o.Expense);
62
+ return this.recurrences.filter((e) => e.type === c.Expense);
63
63
  }
64
64
  get upcomingExpenses() {
65
65
  return this.expenses.filter((e) => e.status === n.Upcoming);
66
66
  }
67
67
  get income() {
68
- return this.recurrences.filter((e) => e.type === o.Income);
68
+ return this.recurrences.filter((e) => e.type === c.Income);
69
69
  }
70
70
  get upcomingIncome() {
71
71
  return this.income.filter((e) => e.status === n.Upcoming);
72
72
  }
73
73
  get nextIncomeRecurrence() {
74
- return this.upcomingIncome.find((e) => l(e.expectedDate, a()));
74
+ return this.upcomingIncome.find((e) => p(e.expectedDate, s()));
75
75
  }
76
76
  get currentMonthExpenses() {
77
77
  return this.expenses.filter((e) => d(this.dateRange, e));
@@ -80,25 +80,25 @@ var d = (e, t) => h(t.expectedDate, e), s = (e, t) => e + t.amount, U = class {
80
80
  return this.income.filter((e) => d(this.dateRange, e));
81
81
  }
82
82
  get expenseTotal() {
83
- return this.currentMonthExpenses.reduce(s, 0);
83
+ return this.currentMonthExpenses.reduce(a, 0);
84
84
  }
85
85
  get paidExpenseTotal() {
86
- return this.currentMonthExpenses.filter((e) => e.status === n.Paid).reduce(s, 0);
86
+ return this.currentMonthExpenses.filter((e) => e.status === n.Paid).reduce(a, 0);
87
87
  }
88
88
  get missedExpenseTotal() {
89
- return this.currentMonthExpenses.filter((e) => e.status === n.Missed).reduce(s, 0);
89
+ return this.currentMonthExpenses.filter((e) => e.status === n.Missed).reduce(a, 0);
90
90
  }
91
91
  get upcomingExpenseTotal() {
92
- return this.currentMonthExpenses.filter((e) => e.status === n.Upcoming).reduce(s, 0);
92
+ return this.currentMonthExpenses.filter((e) => e.status === n.Upcoming).reduce(a, 0);
93
93
  }
94
94
  get incomeTotal() {
95
- return this.currentMonthIncome.reduce(s, 0);
95
+ return this.currentMonthIncome.reduce(a, 0);
96
96
  }
97
97
  get paidIncomeTotal() {
98
- return this.currentMonthIncome.filter((e) => e.status === n.Paid).reduce(s, 0);
98
+ return this.currentMonthIncome.filter((e) => e.status === n.Paid).reduce(a, 0);
99
99
  }
100
100
  get upcomingIncomeTotal() {
101
- return this.currentMonthIncome.filter((e) => e.status === n.Upcoming).reduce(s, 0);
101
+ return this.currentMonthIncome.filter((e) => e.status === n.Upcoming).reduce(a, 0);
102
102
  }
103
103
  get selectedDayRecurrences() {
104
104
  return this.selectedDay && this.recurrences.filter((e) => this.selectedDay && g(e.occurredOnDate || e.expectedDate, this.selectedDay));
@@ -127,7 +127,7 @@ var d = (e, t) => h(t.expectedDate, e), s = (e, t) => e + t.amount, U = class {
127
127
  const e = await this.api.getRepeatingTransactions();
128
128
  this.setRepeatingTransactions(e);
129
129
  } catch (e) {
130
- console.error("Error occurred while getting repeating transactions:", e), this.globalStore.captureException(e, { store: "RecurringTransactionsStore" });
130
+ this.captureError("getRepeatingTransactions", e);
131
131
  }
132
132
  };
133
133
  addRepeatingTransaction = async (e, t) => {
@@ -137,19 +137,19 @@ var d = (e, t) => h(t.expectedDate, e), s = (e, t) => e + t.amount, U = class {
137
137
  ...t,
138
138
  repeating_transaction_guid: r.guid
139
139
  }), u(() => {
140
- this.repeatingTransactions = [...this.repeatingTransactions, ...c(this.globalStore.accountStore.visibleAccounts, [r], this.globalStore.transactionStore.transactions)];
140
+ this.repeatingTransactions = [...this.repeatingTransactions, ...o(this.globalStore.accountStore.visibleAccounts, [r], this.globalStore.transactionStore.transactions)];
141
141
  }), this.setAlert(this.copy.add_repeating_transaction_success, "success"), !0;
142
142
  } catch (r) {
143
- return console.error("Error occurred while adding repeating transaction:", r), this.globalStore.captureException(r, { store: "RecurringTransactionsStore" }), this.setAlert(this.copy.add_repeating_transaction_error, "error"), !1;
143
+ return this.captureError("addRepeatingTransaction", r), this.setAlert(this.copy.add_repeating_transaction_error, "error"), !1;
144
144
  }
145
145
  };
146
146
  deleteRepeatingTransaction = async (e) => {
147
147
  try {
148
148
  return await this.api.deleteRepeatingTransaction(e), u(() => {
149
- this.repeatingTransactions = [...this.repeatingTransactions.filter((t) => t.guid !== e)];
149
+ this.repeatingTransactions = this.repeatingTransactions.filter((t) => t.guid !== e);
150
150
  }), this.setAlert(this.copy.remove_repeating_transaction_success, "success"), !0;
151
151
  } catch (t) {
152
- return console.error("Error occurred while deleting repeating transaction:", t), this.globalStore.captureException(t, { store: "RecurringTransactionsStore" }), this.setAlert(this.copy.remove_repeating_transaction_error, "error"), !1;
152
+ return this.captureError("deleteRepeatingTransaction", t), this.setAlert(this.copy.remove_repeating_transaction_error, "error"), !1;
153
153
  }
154
154
  };
155
155
  updateRepeatingTransaction = async (e) => {
@@ -158,12 +158,12 @@ var d = (e, t) => h(t.expectedDate, e), s = (e, t) => e + t.amount, U = class {
158
158
  return r < 0 ? !1 : (u(() => {
159
159
  this.repeatingTransactions = [
160
160
  ...this.repeatingTransactions.slice(0, r),
161
- ...c(this.globalStore.accountStore.visibleAccounts, [t], this.globalStore.transactionStore.transactions),
161
+ ...o(this.globalStore.accountStore.visibleAccounts, [t], this.globalStore.transactionStore.transactions),
162
162
  ...this.repeatingTransactions.slice(r + 1)
163
163
  ];
164
164
  }), this.setAlert(this.copy.update_repeating_transaction_success, "success"), !0);
165
165
  } catch (t) {
166
- return console.error("Error occurred while updating repeating transaction:", t), this.globalStore.captureException(t, { store: "RecurringTransactionsStore" }), this.setAlert(this.copy.update_repeating_transaction_error, "error"), !1;
166
+ return this.captureError("updateRepeatingTransaction", t), this.setAlert(this.copy.update_repeating_transaction_error, "error"), !1;
167
167
  }
168
168
  };
169
169
  markRecurrenceAsPaid = async (e, t) => {
@@ -173,7 +173,7 @@ var d = (e, t) => h(t.expectedDate, e), s = (e, t) => e + t.amount, U = class {
173
173
  repeating_transaction_guid: e
174
174
  }), await this.loadRepeatingTransactions(), this.setSelectedRecurrence(null), this.setAlert(this.copy.link_transaction_success, "success");
175
175
  } catch (r) {
176
- console.error("Error occurred while marking recurrence as paid:", r), this.globalStore.captureException(r, { store: "RecurringTransactionsStore" }), this.setAlert(this.copy.link_transaction_error, "error");
176
+ this.captureError("markRecurrenceAsPaid", r), this.setAlert(this.copy.link_transaction_error, "error");
177
177
  }
178
178
  };
179
179
  markRecurrenceAsUnpaid = async (e) => {
@@ -183,9 +183,13 @@ var d = (e, t) => h(t.expectedDate, e), s = (e, t) => e + t.amount, U = class {
183
183
  repeating_transaction_guid: null
184
184
  }), await this.loadRepeatingTransactions(), this.setSelectedRecurrence(null), this.setAlert(this.copy.unlink_transaction_success, "success");
185
185
  } catch (t) {
186
- console.error("Error occurred while marking recurrence as unpaid:", t), this.globalStore.captureException(t, { store: "RecurringTransactionsStore" }), this.setAlert(this.copy.unlink_transaction_error, "error");
186
+ this.captureError("markRecurrenceAsUnpaid", t), this.setAlert(this.copy.unlink_transaction_error, "error");
187
187
  }
188
188
  };
189
+ captureError = (e, t) => this.globalStore.captureException(t, {
190
+ store: "RecurringTransactionsStore",
191
+ action: e
192
+ });
189
193
  setAlert = (e, t = void 0) => this.alert = {
190
194
  message: e,
191
195
  severity: t
@@ -1 +1 @@
1
- {"version":3,"file":"RecurringTransactionsStore.es.js","names":[],"sources":["../../../src/core/stores/RecurringTransactionsStore.ts"],"sourcesContent":["import { type AlertProps } from '@mui/material'\nimport { makeAutoObservable, runInAction } from 'mobx'\nimport { endOfMonth } from 'date-fns/endOfMonth'\nimport { isAfter } from 'date-fns/isAfter'\nimport { isBefore } from 'date-fns/isBefore'\nimport { isSameDay } from 'date-fns/isSameDay'\nimport { isWithinInterval } from 'date-fns/isWithinInterval'\nimport { startOfMonth } from 'date-fns/startOfMonth'\nimport { startOfToday } from 'date-fns/startOfToday'\nimport { subDays } from 'date-fns/subDays'\n\nimport { RepeatingTransactionsApi } from '../api'\nimport {\n type Recurrence,\n type RecurringCopy,\n type RepeatingTransaction,\n type Transaction,\n RecurrenceStatus,\n RecurrenceType,\n type DateRange,\n} from '../types'\nimport {\n augmentRepeatingTransactions,\n buildAllRecurrences,\n} from '../utils/RecurringTransactionsUtil'\n\nimport { GlobalStore } from './GlobalStore'\n\nconst currentMonthFilter = (date: DateRange, recurrence: Recurrence) =>\n isWithinInterval(recurrence.expectedDate, date)\n\nconst recurrenceTotalReducer = (total: number, recurrence: Recurrence) => total + recurrence.amount\n\ninterface RecurringAlertProps {\n message: string\n severity: AlertProps['severity']\n}\n\nexport class RecurringTransactionsStore {\n globalStore: GlobalStore\n api = new RepeatingTransactionsApi('/', '')\n\n repeatingTransactions: RepeatingTransaction[] = []\n isDataLoaded: boolean = false\n\n selectedDay: Date | undefined\n dateRange: DateRange = { start: startOfMonth(startOfToday()), end: endOfMonth(startOfToday()) }\n selectedRepeatingTransactionGuid: string | null = null\n selectedRecurrence: Recurrence | null = null\n\n alert: RecurringAlertProps = { message: '', severity: undefined }\n\n constructor(globalStore: GlobalStore) {\n this.globalStore = globalStore\n this.api = new RepeatingTransactionsApi(\n globalStore.endpoint,\n globalStore.sessionToken,\n globalStore.onError,\n )\n\n // The *ForRange helpers are parameterized computeds: they must stay plain\n // methods (not actions) so observable reads inside them remain tracked when\n // invoked from an observer/derivation. makeAutoObservable would otherwise\n // annotate them as actions, which do not track reads.\n makeAutoObservable(this, {\n recurrencesForRange: false,\n upcomingExpensesForRange: false,\n upcomingIncomeForRange: false,\n incomeForRange: false,\n nextIncomeForRange: false,\n })\n }\n\n get copy(): RecurringCopy {\n return this.globalStore.copyStore.copy.recurring\n }\n\n get detailedRepeatingTransactions(): RepeatingTransaction[] {\n return augmentRepeatingTransactions(\n this.globalStore.accountStore.visibleAccounts,\n this.repeatingTransactions,\n this.globalStore.transactionStore.transactions,\n )\n }\n\n /**\n * Returns all recurrences built from repeating transactions and filtered by\n * accounts, scoped to the supplied date range. This is the range-parameterized\n * core used by both the shared getters (which pass this.dateRange) and by\n * consumers such as Cash Flow that need their own independent window without\n * mutating the shared dateRange.\n */\n recurrencesForRange = (dateRange: DateRange): Recurrence[] => {\n const accounts = this.globalStore.accountStore.visibleAccounts\n\n return buildAllRecurrences(this.detailedRepeatingTransactions, dateRange)\n .filter((r) => accounts.some((a) => a.guid === r.accountGuid && !a.is_excluded_from_accounts))\n .filter((r) => isWithinInterval(r.expectedDate, dateRange))\n }\n\n /**\n * Returns the upcoming expense recurrences scoped to the supplied date range.\n */\n upcomingExpensesForRange = (dateRange: DateRange): Recurrence[] => {\n return this.recurrencesForRange(dateRange).filter(\n (recurrence: Recurrence) =>\n recurrence.type === RecurrenceType.Expense &&\n recurrence.status === RecurrenceStatus.Upcoming,\n )\n }\n\n /**\n * Returns the income recurrences scoped to the supplied date range.\n */\n incomeForRange = (dateRange: DateRange): Recurrence[] => {\n return this.recurrencesForRange(dateRange).filter(\n (recurrence: Recurrence) => recurrence.type === RecurrenceType.Income,\n )\n }\n\n /**\n * Returns the upcoming income recurrences scoped to the supplied date range.\n */\n upcomingIncomeForRange = (dateRange: DateRange): Recurrence[] => {\n return this.incomeForRange(dateRange).filter(\n (recurrence: Recurrence) => recurrence.status === RecurrenceStatus.Upcoming,\n )\n }\n\n /**\n * Returns the next upcoming income recurrence scoped to the supplied range.\n */\n nextIncomeForRange = (dateRange: DateRange): Recurrence | undefined => {\n return this.upcomingIncomeForRange(dateRange).find((r) =>\n isAfter(r.expectedDate, startOfToday()),\n )\n }\n\n /**\n * Returns all recurrences built from repeating transactions and filtered by accounts.\n */\n get recurrences(): Recurrence[] {\n return this.recurrencesForRange(this.dateRange)\n }\n\n /**\n * Returns all recurrences that have occurred in the past, including those that are paid or missed\n */\n get pastRecurrences(): Recurrence[] {\n return this.recurrences.filter(\n (recurrence: Recurrence) =>\n recurrence.status === RecurrenceStatus.Paid ||\n recurrence.status === RecurrenceStatus.Missed,\n )\n }\n\n /**\n * Returns all recurrences that are expected to occur through the end of the month\n * or should have occurred in the last 3 days.\n */\n get upcomingRecurrences(): Recurrence[] {\n return this.recurrences.filter(\n (r) =>\n isAfter(r.expectedDate, subDays(startOfToday(), 3)) &&\n isBefore(r.expectedDate, this.dateRange.end) &&\n r.status === RecurrenceStatus.Upcoming,\n )\n }\n\n /**\n * Returns all expense recurrences.\n */\n get expenses(): Recurrence[] {\n return this.recurrences.filter(\n (recurrence: Recurrence) => recurrence.type === RecurrenceType.Expense,\n )\n }\n\n /**\n * Returns the upcoming expense recurrences.\n */\n get upcomingExpenses(): Recurrence[] {\n return this.expenses.filter(\n (recurrence: Recurrence) => recurrence.status === RecurrenceStatus.Upcoming,\n )\n }\n\n /**\n * Returns all income recurrences.\n */\n get income(): Recurrence[] {\n return this.recurrences.filter(\n (recurrence: Recurrence) => recurrence.type === RecurrenceType.Income,\n )\n }\n\n /**\n * Returns the upcoming income recurrences.\n */\n get upcomingIncome(): Recurrence[] {\n return this.income.filter(\n (recurrence: Recurrence) => recurrence.status === RecurrenceStatus.Upcoming,\n )\n }\n\n get nextIncomeRecurrence() {\n return this.upcomingIncome.find((r) => isAfter(r.expectedDate, startOfToday()))\n }\n\n /**\n * Returns the expense recurrences for the current month.\n */\n get currentMonthExpenses(): Recurrence[] {\n return this.expenses.filter((recurrence: Recurrence) =>\n currentMonthFilter(this.dateRange, recurrence),\n )\n }\n\n /**\n * Returns the income recurrences for the current month.\n */\n get currentMonthIncome(): Recurrence[] {\n return this.income.filter((recurrence: Recurrence) =>\n currentMonthFilter(this.dateRange, recurrence),\n )\n }\n\n /**\n * Calculates the total amount of all expenses for the current month.\n */\n get expenseTotal(): number {\n return this.currentMonthExpenses.reduce(recurrenceTotalReducer, 0)\n }\n\n /**\n * Calculates the total amount of all paid expenses for the current month.\n */\n get paidExpenseTotal(): number {\n return this.currentMonthExpenses\n .filter((recurrence: Recurrence) => recurrence.status === RecurrenceStatus.Paid)\n .reduce(recurrenceTotalReducer, 0)\n }\n\n /**\n * Calculates the total amount of all missed expenses for the current month.\n */\n get missedExpenseTotal(): number {\n return this.currentMonthExpenses\n .filter((recurrence: Recurrence) => recurrence.status === RecurrenceStatus.Missed)\n .reduce(recurrenceTotalReducer, 0)\n }\n\n /**\n * Calculates the total amount of all upcoming expenses for the current month.\n */\n get upcomingExpenseTotal(): number {\n return this.currentMonthExpenses\n .filter((recurrence: Recurrence) => recurrence.status === RecurrenceStatus.Upcoming)\n .reduce(recurrenceTotalReducer, 0)\n }\n\n /**\n * Calculates the total amount of all income for the current month.\n */\n get incomeTotal(): number {\n return this.currentMonthIncome.reduce(recurrenceTotalReducer, 0)\n }\n\n /**\n * Calculates the total amount of all paid income for the current month.\n */\n get paidIncomeTotal(): number {\n return this.currentMonthIncome\n .filter((recurrence: Recurrence) => recurrence.status === RecurrenceStatus.Paid)\n .reduce(recurrenceTotalReducer, 0)\n }\n\n /**\n * Calculates the total amount of all upcoming income for the current month.\n */\n get upcomingIncomeTotal(): number {\n return this.currentMonthIncome\n .filter((recurrence: Recurrence) => recurrence.status === RecurrenceStatus.Upcoming)\n .reduce(recurrenceTotalReducer, 0)\n }\n\n /**\n * Get the recurrences for the currently selected day.\n */\n get selectedDayRecurrences(): Recurrence[] | undefined {\n return (\n this.selectedDay &&\n this.recurrences.filter(\n (recurrence: Recurrence) =>\n this.selectedDay &&\n isSameDay(recurrence.occurredOnDate || recurrence.expectedDate, this.selectedDay),\n )\n )\n }\n\n get selectedRepeatingTransaction(): RepeatingTransaction | undefined {\n return this.selectedRepeatingTransactionGuid\n ? this.detailedRepeatingTransactions.find(\n (rt) => rt.guid === this.selectedRepeatingTransactionGuid,\n )\n : undefined\n }\n\n setSelectedRepeatingTransactionGuid = (guid: string | null) =>\n (this.selectedRepeatingTransactionGuid = guid)\n\n setSelectedRecurrence = (recurrence: Recurrence | null) => (this.selectedRecurrence = recurrence)\n\n setRepeatingTransactions = (repeating: RepeatingTransaction[]) => {\n this.repeatingTransactions = repeating\n this.isDataLoaded = true\n }\n\n /**\n * Set the date range for filtering recurrences.\n * @param dateRange - The date range to set.\n */\n setDateRange = (dateRange: DateRange) => (this.dateRange = dateRange)\n\n /**\n * Set the currently selected day.\n * @param day - The day to select.\n */\n setSelectedDay = (day: Date) => {\n this.selectedDay = this.selectedDay && isSameDay(day, this.selectedDay) ? undefined : day\n }\n\n loadRepeatingTransactionData = async () => {\n await Promise.all([\n this.globalStore.accountStore.loadAccountData(),\n this.globalStore.categoryStore.loadCategories(),\n this.globalStore.transactionStore.loadTransactionData(),\n ])\n await this.loadRepeatingTransactions()\n }\n\n /**\n * Load repeating transactions and augment them with additional data.\n */\n loadRepeatingTransactions = async () => {\n try {\n const repeatingTransactions = await this.api.getRepeatingTransactions()\n this.setRepeatingTransactions(repeatingTransactions)\n } catch (error) {\n console.error('Error occurred while getting repeating transactions:', error)\n this.globalStore.captureException(error, { store: 'RecurringTransactionsStore' })\n }\n }\n\n /**\n * Add a new repeating transaction and link it to the associated transaction.\n * @param repeatingTransaction - The repeating transaction to add.\n * @param transaction - The transaction associated with the repeating transaction.\n */\n addRepeatingTransaction = async (\n repeatingTransaction: RepeatingTransaction,\n transaction: Transaction,\n ): Promise<boolean> => {\n try {\n const newRepeating = await this.api.addRepeatingTransaction(repeatingTransaction)\n\n await this.globalStore.transactionStore.updateTransaction({\n ...transaction,\n repeating_transaction_guid: newRepeating.guid,\n })\n\n runInAction(() => {\n this.repeatingTransactions = [\n ...this.repeatingTransactions,\n ...augmentRepeatingTransactions(\n this.globalStore.accountStore.visibleAccounts,\n [newRepeating],\n this.globalStore.transactionStore.transactions,\n ),\n ]\n })\n\n this.setAlert(this.copy.add_repeating_transaction_success, 'success')\n\n return true\n } catch (error) {\n console.error('Error occurred while adding repeating transaction:', error)\n this.globalStore.captureException(error, { store: 'RecurringTransactionsStore' })\n this.setAlert(this.copy.add_repeating_transaction_error, 'error')\n\n return false\n }\n }\n\n /**\n * Delete a repeating transaction by its GUID.\n * @param guid - The GUID of the repeating transaction to delete.\n */\n deleteRepeatingTransaction = async (guid: string): Promise<boolean> => {\n try {\n await this.api.deleteRepeatingTransaction(guid)\n\n runInAction(() => {\n this.repeatingTransactions = [\n ...this.repeatingTransactions.filter((rt) => rt.guid !== guid),\n ]\n })\n\n this.setAlert(this.copy.remove_repeating_transaction_success, 'success')\n\n return true\n } catch (error) {\n console.error('Error occurred while deleting repeating transaction:', error)\n this.globalStore.captureException(error, { store: 'RecurringTransactionsStore' })\n this.setAlert(this.copy.remove_repeating_transaction_error, 'error')\n\n return false\n }\n }\n\n /**\n * Update an existing repeating transaction.\n * @param transaction - The repeating transaction to update.\n */\n updateRepeatingTransaction = async (transaction: RepeatingTransaction): Promise<boolean> => {\n try {\n const updatedTransaction = await this.api.updateRepeatingTransaction(transaction)\n\n const index = this.repeatingTransactions.findIndex(\n (rt) => rt.guid === updatedTransaction.guid,\n )\n if (index < 0) return false\n\n runInAction(() => {\n this.repeatingTransactions = [\n ...this.repeatingTransactions.slice(0, index),\n ...augmentRepeatingTransactions(\n this.globalStore.accountStore.visibleAccounts,\n [updatedTransaction],\n this.globalStore.transactionStore.transactions,\n ),\n ...this.repeatingTransactions.slice(index + 1),\n ]\n })\n\n this.setAlert(this.copy.update_repeating_transaction_success, 'success')\n\n return true\n } catch (error) {\n console.error('Error occurred while updating repeating transaction:', error)\n this.globalStore.captureException(error, { store: 'RecurringTransactionsStore' })\n this.setAlert(this.copy.update_repeating_transaction_error, 'error')\n\n return false\n }\n }\n\n /**\n * Mark a recurrence as paid by linking a transaction to the repeating transaction.\n * @param repeatingTransactionGuid - The GUID of the repeating transaction.\n * @param transaction - The transaction to link.\n */\n markRecurrenceAsPaid = async (repeatingTransactionGuid: string, transaction: Transaction) => {\n try {\n await this.globalStore.transactionStore.updateTransaction({\n ...transaction,\n repeating_transaction_guid: repeatingTransactionGuid,\n })\n\n await this.loadRepeatingTransactions()\n this.setSelectedRecurrence(null)\n this.setAlert(this.copy.link_transaction_success, 'success')\n } catch (error) {\n console.error('Error occurred while marking recurrence as paid:', error)\n this.globalStore.captureException(error, { store: 'RecurringTransactionsStore' })\n this.setAlert(this.copy.link_transaction_error, 'error')\n }\n }\n\n /**\n * Mark a recurrence as unpaid by unlinking the associated transaction from the repeating transaction.\n * @param transaction - The transaction to unlink.\n */\n markRecurrenceAsUnpaid = async (transaction: Transaction) => {\n try {\n await this.globalStore.transactionStore.updateTransaction({\n ...transaction,\n repeating_transaction_guid: null,\n })\n\n await this.loadRepeatingTransactions()\n this.setSelectedRecurrence(null)\n this.setAlert(this.copy.unlink_transaction_success, 'success')\n } catch (error) {\n console.error('Error occurred while marking recurrence as unpaid:', error)\n this.globalStore.captureException(error, { store: 'RecurringTransactionsStore' })\n this.setAlert(this.copy.unlink_transaction_error, 'error')\n }\n }\n\n setAlert = (message: string, severity: RecurringAlertProps['severity'] = undefined) =>\n (this.alert = { message, severity })\n}\n"],"mappings":";;;;;;;;;;;;AA4BA,IAAM,IAAA,CAAsB,GAAiB,MAC3C,EAAiB,EAAW,cAAc,CAAI,GAE1C,IAAA,CAA0B,GAAe,MAA2B,IAAQ,EAAW,QAOhF,IAAb,MAAwC;AAAA,EACtC;AAAA,EACA,MAAM,IAAI,EAAyB,KAAK,EAAE;AAAA,EAE1C,wBAAgD,CAAC;AAAA,EACjD,eAAwB;AAAA,EAExB;AAAA,EACA,YAAuB;AAAA,IAAE,OAAO,EAAa,EAAa,CAAC;AAAA,IAAG,KAAK,EAAW,EAAa,CAAC;AAAA,EAAE;AAAA,EAC9F,mCAAkD;AAAA,EAClD,qBAAwC;AAAA,EAExC,QAA6B;AAAA,IAAE,SAAS;AAAA,IAAI,UAAU;AAAA,EAAU;AAAA,EAEhE,YAAY,GAA0B;AACpC,SAAK,cAAc,GACnB,KAAK,MAAM,IAAI,EACb,EAAY,UACZ,EAAY,cACZ,EAAY,OACd,GAMA,EAAmB,MAAM;AAAA,MACvB,qBAAqB;AAAA,MACrB,0BAA0B;AAAA,MAC1B,wBAAwB;AAAA,MACxB,gBAAgB;AAAA,MAChB,oBAAoB;AAAA,IACtB,CAAC;AAAA,EACH;AAAA,EAEA,IAAI,OAAsB;AACxB,WAAO,KAAK,YAAY,UAAU,KAAK;AAAA,EACzC;AAAA,EAEA,IAAI,gCAAwD;AAC1D,WAAO,EACL,KAAK,YAAY,aAAa,iBAC9B,KAAK,uBACL,KAAK,YAAY,iBAAiB,YACpC;AAAA,EACF;AAAA,EASA,sBAAA,CAAuB,MAAuC;AAC5D,UAAM,IAAW,KAAK,YAAY,aAAa;AAE/C,WAAO,EAAoB,KAAK,+BAA+B,CAAS,EACrE,OAAA,CAAQ,MAAM,EAAS,KAAA,CAAM,MAAM,EAAE,SAAS,EAAE,eAAe,CAAC,EAAE,yBAAyB,CAAC,EAC5F,OAAA,CAAQ,MAAM,EAAiB,EAAE,cAAc,CAAS,CAAC;AAAA,EAC9D;AAAA,EAKA,2BAAA,CAA4B,MACnB,KAAK,oBAAoB,CAAS,EAAE,OAAA,CACxC,MACC,EAAW,SAAS,EAAe,WACnC,EAAW,WAAW,EAAiB,QAC3C;AAAA,EAMF,iBAAA,CAAkB,MACT,KAAK,oBAAoB,CAAS,EAAE,OAAA,CACxC,MAA2B,EAAW,SAAS,EAAe,MACjE;AAAA,EAMF,yBAAA,CAA0B,MACjB,KAAK,eAAe,CAAS,EAAE,OAAA,CACnC,MAA2B,EAAW,WAAW,EAAiB,QACrE;AAAA,EAMF,qBAAA,CAAsB,MACb,KAAK,uBAAuB,CAAS,EAAE,KAAA,CAAM,MAClD,EAAQ,EAAE,cAAc,EAAa,CAAC,CACxC;AAAA,EAMF,IAAI,cAA4B;AAC9B,WAAO,KAAK,oBAAoB,KAAK,SAAS;AAAA,EAChD;AAAA,EAKA,IAAI,kBAAgC;AAClC,WAAO,KAAK,YAAY,OAAA,CACrB,MACC,EAAW,WAAW,EAAiB,QACvC,EAAW,WAAW,EAAiB,MAC3C;AAAA,EACF;AAAA,EAMA,IAAI,sBAAoC;AACtC,WAAO,KAAK,YAAY,OAAA,CACrB,MACC,EAAQ,EAAE,cAAc,EAAQ,EAAa,GAAG,CAAC,CAAC,KAClD,EAAS,EAAE,cAAc,KAAK,UAAU,GAAG,KAC3C,EAAE,WAAW,EAAiB,QAClC;AAAA,EACF;AAAA,EAKA,IAAI,WAAyB;AAC3B,WAAO,KAAK,YAAY,OAAA,CACrB,MAA2B,EAAW,SAAS,EAAe,OACjE;AAAA,EACF;AAAA,EAKA,IAAI,mBAAiC;AACnC,WAAO,KAAK,SAAS,OAAA,CAClB,MAA2B,EAAW,WAAW,EAAiB,QACrE;AAAA,EACF;AAAA,EAKA,IAAI,SAAuB;AACzB,WAAO,KAAK,YAAY,OAAA,CACrB,MAA2B,EAAW,SAAS,EAAe,MACjE;AAAA,EACF;AAAA,EAKA,IAAI,iBAA+B;AACjC,WAAO,KAAK,OAAO,OAAA,CAChB,MAA2B,EAAW,WAAW,EAAiB,QACrE;AAAA,EACF;AAAA,EAEA,IAAI,uBAAuB;AACzB,WAAO,KAAK,eAAe,KAAA,CAAM,MAAM,EAAQ,EAAE,cAAc,EAAa,CAAC,CAAC;AAAA,EAChF;AAAA,EAKA,IAAI,uBAAqC;AACvC,WAAO,KAAK,SAAS,OAAA,CAAQ,MAC3B,EAAmB,KAAK,WAAW,CAAU,CAC/C;AAAA,EACF;AAAA,EAKA,IAAI,qBAAmC;AACrC,WAAO,KAAK,OAAO,OAAA,CAAQ,MACzB,EAAmB,KAAK,WAAW,CAAU,CAC/C;AAAA,EACF;AAAA,EAKA,IAAI,eAAuB;AACzB,WAAO,KAAK,qBAAqB,OAAO,GAAwB,CAAC;AAAA,EACnE;AAAA,EAKA,IAAI,mBAA2B;AAC7B,WAAO,KAAK,qBACT,OAAA,CAAQ,MAA2B,EAAW,WAAW,EAAiB,IAAI,EAC9E,OAAO,GAAwB,CAAC;AAAA,EACrC;AAAA,EAKA,IAAI,qBAA6B;AAC/B,WAAO,KAAK,qBACT,OAAA,CAAQ,MAA2B,EAAW,WAAW,EAAiB,MAAM,EAChF,OAAO,GAAwB,CAAC;AAAA,EACrC;AAAA,EAKA,IAAI,uBAA+B;AACjC,WAAO,KAAK,qBACT,OAAA,CAAQ,MAA2B,EAAW,WAAW,EAAiB,QAAQ,EAClF,OAAO,GAAwB,CAAC;AAAA,EACrC;AAAA,EAKA,IAAI,cAAsB;AACxB,WAAO,KAAK,mBAAmB,OAAO,GAAwB,CAAC;AAAA,EACjE;AAAA,EAKA,IAAI,kBAA0B;AAC5B,WAAO,KAAK,mBACT,OAAA,CAAQ,MAA2B,EAAW,WAAW,EAAiB,IAAI,EAC9E,OAAO,GAAwB,CAAC;AAAA,EACrC;AAAA,EAKA,IAAI,sBAA8B;AAChC,WAAO,KAAK,mBACT,OAAA,CAAQ,MAA2B,EAAW,WAAW,EAAiB,QAAQ,EAClF,OAAO,GAAwB,CAAC;AAAA,EACrC;AAAA,EAKA,IAAI,yBAAmD;AACrD,WACE,KAAK,eACL,KAAK,YAAY,OAAA,CACd,MACC,KAAK,eACL,EAAU,EAAW,kBAAkB,EAAW,cAAc,KAAK,WAAW,CACpF;AAAA,EAEJ;AAAA,EAEA,IAAI,+BAAiE;AACnE,WAAO,KAAK,mCACR,KAAK,8BAA8B,KAAA,CAChC,MAAO,EAAG,SAAS,KAAK,gCAC3B,IACA;AAAA,EACN;AAAA,EAEA,sCAAA,CAAuC,MACpC,KAAK,mCAAmC;AAAA,EAE3C,wBAAA,CAAyB,MAAmC,KAAK,qBAAqB;AAAA,EAEtF,2BAAA,CAA4B,MAAsC;AAChE,SAAK,wBAAwB,GAC7B,KAAK,eAAe;AAAA,EACtB;AAAA,EAMA,eAAA,CAAgB,MAA0B,KAAK,YAAY;AAAA,EAM3D,iBAAA,CAAkB,MAAc;AAC9B,SAAK,cAAc,KAAK,eAAe,EAAU,GAAK,KAAK,WAAW,IAAI,SAAY;AAAA,EACxF;AAAA,EAEA,+BAA+B,YAAY;AACzC,UAAM,QAAQ,IAAI;AAAA,MAChB,KAAK,YAAY,aAAa,gBAAgB;AAAA,MAC9C,KAAK,YAAY,cAAc,eAAe;AAAA,MAC9C,KAAK,YAAY,iBAAiB,oBAAoB;AAAA,IACxD,CAAC,GACD,MAAM,KAAK,0BAA0B;AAAA,EACvC;AAAA,EAKA,4BAA4B,YAAY;AACtC,QAAI;AACF,YAAM,IAAwB,MAAM,KAAK,IAAI,yBAAyB;AACtE,WAAK,yBAAyB,CAAqB;AAAA,IACrD,SAAS,GAAO;AACd,cAAQ,MAAM,wDAAwD,CAAK,GAC3E,KAAK,YAAY,iBAAiB,GAAO,EAAE,OAAO,6BAA6B,CAAC;AAAA,IAClF;AAAA,EACF;AAAA,EAOA,0BAA0B,OACxB,GACA,MACqB;AACrB,QAAI;AACF,YAAM,IAAe,MAAM,KAAK,IAAI,wBAAwB,CAAoB;AAEhF,mBAAM,KAAK,YAAY,iBAAiB,kBAAkB;AAAA,QACxD,GAAG;AAAA,QACH,4BAA4B,EAAa;AAAA,MAC3C,CAAC,GAED,EAAA,MAAkB;AAChB,aAAK,wBAAwB,CAC3B,GAAG,KAAK,uBACR,GAAG,EACD,KAAK,YAAY,aAAa,iBAC9B,CAAC,CAAY,GACb,KAAK,YAAY,iBAAiB,YACpC,CACF;AAAA,MACF,CAAC,GAED,KAAK,SAAS,KAAK,KAAK,mCAAmC,SAAS,GAE7D;AAAA,IACT,SAAS,GAAO;AACd,qBAAQ,MAAM,sDAAsD,CAAK,GACzE,KAAK,YAAY,iBAAiB,GAAO,EAAE,OAAO,6BAA6B,CAAC,GAChF,KAAK,SAAS,KAAK,KAAK,iCAAiC,OAAO,GAEzD;AAAA,IACT;AAAA,EACF;AAAA,EAMA,6BAA6B,OAAO,MAAmC;AACrE,QAAI;AACF,mBAAM,KAAK,IAAI,2BAA2B,CAAI,GAE9C,EAAA,MAAkB;AAChB,aAAK,wBAAwB,CAC3B,GAAG,KAAK,sBAAsB,OAAA,CAAQ,MAAO,EAAG,SAAS,CAAI,CAC/D;AAAA,MACF,CAAC,GAED,KAAK,SAAS,KAAK,KAAK,sCAAsC,SAAS,GAEhE;AAAA,IACT,SAAS,GAAO;AACd,qBAAQ,MAAM,wDAAwD,CAAK,GAC3E,KAAK,YAAY,iBAAiB,GAAO,EAAE,OAAO,6BAA6B,CAAC,GAChF,KAAK,SAAS,KAAK,KAAK,oCAAoC,OAAO,GAE5D;AAAA,IACT;AAAA,EACF;AAAA,EAMA,6BAA6B,OAAO,MAAwD;AAC1F,QAAI;AACF,YAAM,IAAqB,MAAM,KAAK,IAAI,2BAA2B,CAAW,GAE1E,IAAQ,KAAK,sBAAsB,UAAA,CACtC,MAAO,EAAG,SAAS,EAAmB,IACzC;AACA,aAAI,IAAQ,IAAU,MAEtB,EAAA,MAAkB;AAChB,aAAK,wBAAwB;AAAA,UAC3B,GAAG,KAAK,sBAAsB,MAAM,GAAG,CAAK;AAAA,UAC5C,GAAG,EACD,KAAK,YAAY,aAAa,iBAC9B,CAAC,CAAkB,GACnB,KAAK,YAAY,iBAAiB,YACpC;AAAA,UACA,GAAG,KAAK,sBAAsB,MAAM,IAAQ,CAAC;AAAA,QAC/C;AAAA,MACF,CAAC,GAED,KAAK,SAAS,KAAK,KAAK,sCAAsC,SAAS,GAEhE;AAAA,IACT,SAAS,GAAO;AACd,qBAAQ,MAAM,wDAAwD,CAAK,GAC3E,KAAK,YAAY,iBAAiB,GAAO,EAAE,OAAO,6BAA6B,CAAC,GAChF,KAAK,SAAS,KAAK,KAAK,oCAAoC,OAAO,GAE5D;AAAA,IACT;AAAA,EACF;AAAA,EAOA,uBAAuB,OAAO,GAAkC,MAA6B;AAC3F,QAAI;AACF,YAAM,KAAK,YAAY,iBAAiB,kBAAkB;AAAA,QACxD,GAAG;AAAA,QACH,4BAA4B;AAAA,MAC9B,CAAC,GAED,MAAM,KAAK,0BAA0B,GACrC,KAAK,sBAAsB,IAAI,GAC/B,KAAK,SAAS,KAAK,KAAK,0BAA0B,SAAS;AAAA,IAC7D,SAAS,GAAO;AACd,cAAQ,MAAM,oDAAoD,CAAK,GACvE,KAAK,YAAY,iBAAiB,GAAO,EAAE,OAAO,6BAA6B,CAAC,GAChF,KAAK,SAAS,KAAK,KAAK,wBAAwB,OAAO;AAAA,IACzD;AAAA,EACF;AAAA,EAMA,yBAAyB,OAAO,MAA6B;AAC3D,QAAI;AACF,YAAM,KAAK,YAAY,iBAAiB,kBAAkB;AAAA,QACxD,GAAG;AAAA,QACH,4BAA4B;AAAA,MAC9B,CAAC,GAED,MAAM,KAAK,0BAA0B,GACrC,KAAK,sBAAsB,IAAI,GAC/B,KAAK,SAAS,KAAK,KAAK,4BAA4B,SAAS;AAAA,IAC/D,SAAS,GAAO;AACd,cAAQ,MAAM,sDAAsD,CAAK,GACzE,KAAK,YAAY,iBAAiB,GAAO,EAAE,OAAO,6BAA6B,CAAC,GAChF,KAAK,SAAS,KAAK,KAAK,0BAA0B,OAAO;AAAA,IAC3D;AAAA,EACF;AAAA,EAEA,WAAA,CAAY,GAAiB,IAA4C,WACtE,KAAK,QAAQ;AAAA,IAAE,SAAA;AAAA,IAAS,UAAA;AAAA,EAAS;AACtC"}
1
+ {"version":3,"file":"RecurringTransactionsStore.es.js","names":[],"sources":["../../../src/core/stores/RecurringTransactionsStore.ts"],"sourcesContent":["import { type AlertProps } from '@mui/material'\nimport { makeAutoObservable, runInAction } from 'mobx'\nimport { endOfMonth } from 'date-fns/endOfMonth'\nimport { isAfter } from 'date-fns/isAfter'\nimport { isBefore } from 'date-fns/isBefore'\nimport { isSameDay } from 'date-fns/isSameDay'\nimport { isWithinInterval } from 'date-fns/isWithinInterval'\nimport { startOfMonth } from 'date-fns/startOfMonth'\nimport { startOfToday } from 'date-fns/startOfToday'\nimport { subDays } from 'date-fns/subDays'\n\nimport { RepeatingTransactionsApi } from '../api'\nimport {\n type Recurrence,\n type RecurringCopy,\n type RepeatingTransaction,\n type Transaction,\n RecurrenceStatus,\n RecurrenceType,\n type DateRange,\n} from '../types'\nimport {\n augmentRepeatingTransactions,\n buildAllRecurrences,\n} from '../utils/RecurringTransactionsUtil'\n\nimport { GlobalStore } from './GlobalStore'\n\nconst currentMonthFilter = (date: DateRange, recurrence: Recurrence) =>\n isWithinInterval(recurrence.expectedDate, date)\n\nconst recurrenceTotalReducer = (total: number, recurrence: Recurrence) => total + recurrence.amount\n\ninterface RecurringAlertProps {\n message: string\n severity: AlertProps['severity']\n}\n\nexport class RecurringTransactionsStore {\n globalStore: GlobalStore\n api = new RepeatingTransactionsApi('/', '')\n\n repeatingTransactions: RepeatingTransaction[] = []\n isDataLoaded: boolean = false\n\n selectedDay: Date | undefined\n dateRange: DateRange = { start: startOfMonth(startOfToday()), end: endOfMonth(startOfToday()) }\n selectedRepeatingTransactionGuid: string | null = null\n selectedRecurrence: Recurrence | null = null\n\n alert: RecurringAlertProps = { message: '', severity: undefined }\n\n constructor(globalStore: GlobalStore) {\n this.globalStore = globalStore\n this.api = new RepeatingTransactionsApi(\n globalStore.endpoint,\n globalStore.sessionToken,\n globalStore.onError,\n )\n\n // The *ForRange helpers are parameterized computeds: they must stay plain\n // methods (not actions) so observable reads inside them remain tracked when\n // invoked from an observer/derivation. makeAutoObservable would otherwise\n // annotate them as actions, which do not track reads.\n makeAutoObservable(this, {\n recurrencesForRange: false,\n upcomingExpensesForRange: false,\n upcomingIncomeForRange: false,\n incomeForRange: false,\n nextIncomeForRange: false,\n })\n }\n\n get copy(): RecurringCopy {\n return this.globalStore.copyStore.copy.recurring\n }\n\n get detailedRepeatingTransactions(): RepeatingTransaction[] {\n return augmentRepeatingTransactions(\n this.globalStore.accountStore.visibleAccounts,\n this.repeatingTransactions,\n this.globalStore.transactionStore.transactions,\n )\n }\n\n /**\n * Returns all recurrences built from repeating transactions and filtered by\n * accounts, scoped to the supplied date range. This is the range-parameterized\n * core used by both the shared getters (which pass this.dateRange) and by\n * consumers such as Cash Flow that need their own independent window without\n * mutating the shared dateRange.\n */\n recurrencesForRange = (dateRange: DateRange): Recurrence[] => {\n const accounts = this.globalStore.accountStore.visibleAccounts\n\n return buildAllRecurrences(this.detailedRepeatingTransactions, dateRange)\n .filter((r) => accounts.some((a) => a.guid === r.accountGuid && !a.is_excluded_from_accounts))\n .filter((r) => isWithinInterval(r.expectedDate, dateRange))\n }\n\n /**\n * Returns the upcoming expense recurrences scoped to the supplied date range.\n */\n upcomingExpensesForRange = (dateRange: DateRange): Recurrence[] => {\n return this.recurrencesForRange(dateRange).filter(\n (recurrence: Recurrence) =>\n recurrence.type === RecurrenceType.Expense &&\n recurrence.status === RecurrenceStatus.Upcoming,\n )\n }\n\n /**\n * Returns the income recurrences scoped to the supplied date range.\n */\n incomeForRange = (dateRange: DateRange): Recurrence[] => {\n return this.recurrencesForRange(dateRange).filter(\n (recurrence: Recurrence) => recurrence.type === RecurrenceType.Income,\n )\n }\n\n /**\n * Returns the upcoming income recurrences scoped to the supplied date range.\n */\n upcomingIncomeForRange = (dateRange: DateRange): Recurrence[] => {\n return this.incomeForRange(dateRange).filter(\n (recurrence: Recurrence) => recurrence.status === RecurrenceStatus.Upcoming,\n )\n }\n\n /**\n * Returns the next upcoming income recurrence scoped to the supplied range.\n */\n nextIncomeForRange = (dateRange: DateRange): Recurrence | undefined => {\n return this.upcomingIncomeForRange(dateRange).find((r) =>\n isAfter(r.expectedDate, startOfToday()),\n )\n }\n\n /**\n * Returns all recurrences built from repeating transactions and filtered by accounts.\n */\n get recurrences(): Recurrence[] {\n return this.recurrencesForRange(this.dateRange)\n }\n\n /**\n * Returns all recurrences that have occurred in the past, including those that are paid or missed\n */\n get pastRecurrences(): Recurrence[] {\n return this.recurrences.filter(\n (recurrence: Recurrence) =>\n recurrence.status === RecurrenceStatus.Paid ||\n recurrence.status === RecurrenceStatus.Missed,\n )\n }\n\n /**\n * Returns all recurrences that are expected to occur through the end of the month\n * or should have occurred in the last 3 days.\n */\n get upcomingRecurrences(): Recurrence[] {\n return this.recurrences.filter(\n (r) =>\n isAfter(r.expectedDate, subDays(startOfToday(), 3)) &&\n isBefore(r.expectedDate, this.dateRange.end) &&\n r.status === RecurrenceStatus.Upcoming,\n )\n }\n\n /**\n * Returns all expense recurrences.\n */\n get expenses(): Recurrence[] {\n return this.recurrences.filter(\n (recurrence: Recurrence) => recurrence.type === RecurrenceType.Expense,\n )\n }\n\n /**\n * Returns the upcoming expense recurrences.\n */\n get upcomingExpenses(): Recurrence[] {\n return this.expenses.filter(\n (recurrence: Recurrence) => recurrence.status === RecurrenceStatus.Upcoming,\n )\n }\n\n /**\n * Returns all income recurrences.\n */\n get income(): Recurrence[] {\n return this.recurrences.filter(\n (recurrence: Recurrence) => recurrence.type === RecurrenceType.Income,\n )\n }\n\n /**\n * Returns the upcoming income recurrences.\n */\n get upcomingIncome(): Recurrence[] {\n return this.income.filter(\n (recurrence: Recurrence) => recurrence.status === RecurrenceStatus.Upcoming,\n )\n }\n\n get nextIncomeRecurrence() {\n return this.upcomingIncome.find((r) => isAfter(r.expectedDate, startOfToday()))\n }\n\n /**\n * Returns the expense recurrences for the current month.\n */\n get currentMonthExpenses(): Recurrence[] {\n return this.expenses.filter((recurrence: Recurrence) =>\n currentMonthFilter(this.dateRange, recurrence),\n )\n }\n\n /**\n * Returns the income recurrences for the current month.\n */\n get currentMonthIncome(): Recurrence[] {\n return this.income.filter((recurrence: Recurrence) =>\n currentMonthFilter(this.dateRange, recurrence),\n )\n }\n\n /**\n * Calculates the total amount of all expenses for the current month.\n */\n get expenseTotal(): number {\n return this.currentMonthExpenses.reduce(recurrenceTotalReducer, 0)\n }\n\n /**\n * Calculates the total amount of all paid expenses for the current month.\n */\n get paidExpenseTotal(): number {\n return this.currentMonthExpenses\n .filter((recurrence: Recurrence) => recurrence.status === RecurrenceStatus.Paid)\n .reduce(recurrenceTotalReducer, 0)\n }\n\n /**\n * Calculates the total amount of all missed expenses for the current month.\n */\n get missedExpenseTotal(): number {\n return this.currentMonthExpenses\n .filter((recurrence: Recurrence) => recurrence.status === RecurrenceStatus.Missed)\n .reduce(recurrenceTotalReducer, 0)\n }\n\n /**\n * Calculates the total amount of all upcoming expenses for the current month.\n */\n get upcomingExpenseTotal(): number {\n return this.currentMonthExpenses\n .filter((recurrence: Recurrence) => recurrence.status === RecurrenceStatus.Upcoming)\n .reduce(recurrenceTotalReducer, 0)\n }\n\n /**\n * Calculates the total amount of all income for the current month.\n */\n get incomeTotal(): number {\n return this.currentMonthIncome.reduce(recurrenceTotalReducer, 0)\n }\n\n /**\n * Calculates the total amount of all paid income for the current month.\n */\n get paidIncomeTotal(): number {\n return this.currentMonthIncome\n .filter((recurrence: Recurrence) => recurrence.status === RecurrenceStatus.Paid)\n .reduce(recurrenceTotalReducer, 0)\n }\n\n /**\n * Calculates the total amount of all upcoming income for the current month.\n */\n get upcomingIncomeTotal(): number {\n return this.currentMonthIncome\n .filter((recurrence: Recurrence) => recurrence.status === RecurrenceStatus.Upcoming)\n .reduce(recurrenceTotalReducer, 0)\n }\n\n /**\n * Get the recurrences for the currently selected day.\n */\n get selectedDayRecurrences(): Recurrence[] | undefined {\n return (\n this.selectedDay &&\n this.recurrences.filter(\n (recurrence: Recurrence) =>\n this.selectedDay &&\n isSameDay(recurrence.occurredOnDate || recurrence.expectedDate, this.selectedDay),\n )\n )\n }\n\n get selectedRepeatingTransaction(): RepeatingTransaction | undefined {\n return this.selectedRepeatingTransactionGuid\n ? this.detailedRepeatingTransactions.find(\n (rt) => rt.guid === this.selectedRepeatingTransactionGuid,\n )\n : undefined\n }\n\n setSelectedRepeatingTransactionGuid = (guid: string | null) =>\n (this.selectedRepeatingTransactionGuid = guid)\n\n setSelectedRecurrence = (recurrence: Recurrence | null) => (this.selectedRecurrence = recurrence)\n\n setRepeatingTransactions = (repeating: RepeatingTransaction[]) => {\n this.repeatingTransactions = repeating\n this.isDataLoaded = true\n }\n\n /**\n * Set the date range for filtering recurrences.\n * @param dateRange - The date range to set.\n */\n setDateRange = (dateRange: DateRange) => (this.dateRange = dateRange)\n\n /**\n * Set the currently selected day.\n * @param day - The day to select.\n */\n setSelectedDay = (day: Date) => {\n this.selectedDay = this.selectedDay && isSameDay(day, this.selectedDay) ? undefined : day\n }\n\n loadRepeatingTransactionData = async () => {\n await Promise.all([\n this.globalStore.accountStore.loadAccountData(),\n this.globalStore.categoryStore.loadCategories(),\n this.globalStore.transactionStore.loadTransactionData(),\n ])\n await this.loadRepeatingTransactions()\n }\n\n /**\n * Load repeating transactions and augment them with additional data.\n */\n loadRepeatingTransactions = async () => {\n try {\n const repeatingTransactions = await this.api.getRepeatingTransactions()\n this.setRepeatingTransactions(repeatingTransactions)\n } catch (error) {\n this.captureError('getRepeatingTransactions', error)\n }\n }\n\n /**\n * Add a new repeating transaction and link it to the associated transaction.\n * @param repeatingTransaction - The repeating transaction to add.\n * @param transaction - The transaction associated with the repeating transaction.\n */\n addRepeatingTransaction = async (\n repeatingTransaction: RepeatingTransaction,\n transaction: Transaction,\n ): Promise<boolean> => {\n try {\n const newRepeating = await this.api.addRepeatingTransaction(repeatingTransaction)\n\n await this.globalStore.transactionStore.updateTransaction({\n ...transaction,\n repeating_transaction_guid: newRepeating.guid,\n })\n\n runInAction(() => {\n this.repeatingTransactions = [\n ...this.repeatingTransactions,\n ...augmentRepeatingTransactions(\n this.globalStore.accountStore.visibleAccounts,\n [newRepeating],\n this.globalStore.transactionStore.transactions,\n ),\n ]\n })\n\n this.setAlert(this.copy.add_repeating_transaction_success, 'success')\n\n return true\n } catch (error) {\n this.captureError('addRepeatingTransaction', error)\n this.setAlert(this.copy.add_repeating_transaction_error, 'error')\n\n return false\n }\n }\n\n /**\n * Delete a repeating transaction by its GUID.\n * @param guid - The GUID of the repeating transaction to delete.\n */\n deleteRepeatingTransaction = async (guid: string): Promise<boolean> => {\n try {\n await this.api.deleteRepeatingTransaction(guid)\n\n runInAction(() => {\n this.repeatingTransactions = this.repeatingTransactions.filter((rt) => rt.guid !== guid)\n })\n\n this.setAlert(this.copy.remove_repeating_transaction_success, 'success')\n\n return true\n } catch (error) {\n this.captureError('deleteRepeatingTransaction', error)\n this.setAlert(this.copy.remove_repeating_transaction_error, 'error')\n\n return false\n }\n }\n\n /**\n * Update an existing repeating transaction.\n * @param transaction - The repeating transaction to update.\n */\n updateRepeatingTransaction = async (transaction: RepeatingTransaction): Promise<boolean> => {\n try {\n const updatedTransaction = await this.api.updateRepeatingTransaction(transaction)\n\n const index = this.repeatingTransactions.findIndex(\n (rt) => rt.guid === updatedTransaction.guid,\n )\n if (index < 0) return false\n\n runInAction(() => {\n this.repeatingTransactions = [\n ...this.repeatingTransactions.slice(0, index),\n ...augmentRepeatingTransactions(\n this.globalStore.accountStore.visibleAccounts,\n [updatedTransaction],\n this.globalStore.transactionStore.transactions,\n ),\n ...this.repeatingTransactions.slice(index + 1),\n ]\n })\n\n this.setAlert(this.copy.update_repeating_transaction_success, 'success')\n\n return true\n } catch (error) {\n this.captureError('updateRepeatingTransaction', error)\n this.setAlert(this.copy.update_repeating_transaction_error, 'error')\n\n return false\n }\n }\n\n /**\n * Mark a recurrence as paid by linking a transaction to the repeating transaction.\n * @param repeatingTransactionGuid - The GUID of the repeating transaction.\n * @param transaction - The transaction to link.\n */\n markRecurrenceAsPaid = async (repeatingTransactionGuid: string, transaction: Transaction) => {\n try {\n await this.globalStore.transactionStore.updateTransaction({\n ...transaction,\n repeating_transaction_guid: repeatingTransactionGuid,\n })\n\n await this.loadRepeatingTransactions()\n this.setSelectedRecurrence(null)\n this.setAlert(this.copy.link_transaction_success, 'success')\n } catch (error) {\n this.captureError('markRecurrenceAsPaid', error)\n this.setAlert(this.copy.link_transaction_error, 'error')\n }\n }\n\n /**\n * Mark a recurrence as unpaid by unlinking the associated transaction from the repeating transaction.\n * @param transaction - The transaction to unlink.\n */\n markRecurrenceAsUnpaid = async (transaction: Transaction) => {\n try {\n await this.globalStore.transactionStore.updateTransaction({\n ...transaction,\n repeating_transaction_guid: null,\n })\n\n await this.loadRepeatingTransactions()\n this.setSelectedRecurrence(null)\n this.setAlert(this.copy.unlink_transaction_success, 'success')\n } catch (error) {\n this.captureError('markRecurrenceAsUnpaid', error)\n this.setAlert(this.copy.unlink_transaction_error, 'error')\n }\n }\n\n private captureError = (action: string, error: unknown) =>\n this.globalStore.captureException(error, { store: 'RecurringTransactionsStore', action })\n\n setAlert = (message: string, severity: RecurringAlertProps['severity'] = undefined) =>\n (this.alert = { message, severity })\n}\n"],"mappings":"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"}
@@ -52,6 +52,7 @@ export interface Transaction {
52
52
  accountIsClosed?: boolean;
53
53
  accountIsHidden?: boolean;
54
54
  category?: string;
55
+ institutionName?: string;
55
56
  isIncome?: boolean;
56
57
  isPending?: boolean;
57
58
  number?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"Transaction.es.js","names":[],"sources":["../../../src/core/types/Transaction.ts"],"sourcesContent":["export interface Transaction {\n guid: string\n account_guid: string\n amount: number\n attachment_guid?: string | null\n category_guid?: string\n check_number?: string | null\n currency_code: string | null\n date: number\n description: string\n duplicate: boolean\n external_guid?: string | null\n feed_attachment_guid?: string | null\n feed_description: string\n feed_localized_description?: string | null\n feed_posted_date?: number | null\n feed_status: TransactionStatus | null\n feed_transaction_date: number | null\n flags?: number | null\n has_been_split: boolean\n has_been_viewed: boolean\n is_cleared: boolean\n is_flagged: boolean\n is_hidden: boolean\n is_international?: boolean | null\n is_manual: boolean\n is_personal: boolean\n is_reimbursable: boolean\n is_subscription: boolean\n is_void: boolean\n localized_description?: string | null\n localized_memo?: string | null\n main_class_guid?: string | null\n memo?: string | null\n metadata?: string | null\n merchant_guid?: string | null\n parent_guid?: string | null\n posted_date?: number | null\n reference?: string | null\n revision: number\n repeating_transaction_guid?: string | null\n scheduled_payment_guid?: string | null\n top_level_category_guid?: string\n transaction_type: TransactionType\n user_date?: number | null\n user_guid: string\n user_transaction_rule_guid?: string | null\n is_duplicate: boolean\n tags: string[]\n feed_transacted_at: number | null\n\n // Detailed Transaction fields\n account?: string\n accountIsClosed?: boolean\n accountIsHidden?: boolean\n category?: string\n isIncome?: boolean\n isPending?: boolean\n number?: string\n payee?: string\n}\n\nexport enum TransactionType {\n CREDIT = 1,\n DEBIT = 2,\n}\n\nexport enum TransactionStatus {\n POSTED = 1,\n PENDING = 2,\n}\n\nexport interface Tag {\n guid: string\n is_default_tag: boolean\n name: string\n user_guid: string\n}\n\nexport interface Tagging {\n guid: string\n user_guid: string\n tag_guid: string\n transaction_guid: string\n}\n\nexport interface TransactionRule {\n guid: string\n user_guid: string\n category_guid: string | null\n match_description: string\n description: string | null\n}\n"],"mappings":"AA8DA,IAAY,IAAL,0BAAA,GAAA;AACL,SAAA,EAAA,EAAA,SAAA,CAAA,IAAA,UACA,EAAA,EAAA,QAAA,CAAA,IAAA;AACF,GAAA,CAAA,CAAA,GAEY,IAAL,0BAAA,GAAA;AACL,SAAA,EAAA,EAAA,SAAA,CAAA,IAAA,UACA,EAAA,EAAA,UAAA,CAAA,IAAA;AACF,GAAA,CAAA,CAAA"}
1
+ {"version":3,"file":"Transaction.es.js","names":[],"sources":["../../../src/core/types/Transaction.ts"],"sourcesContent":["export interface Transaction {\n guid: string\n account_guid: string\n amount: number\n attachment_guid?: string | null\n category_guid?: string\n check_number?: string | null\n currency_code: string | null\n date: number\n description: string\n duplicate: boolean\n external_guid?: string | null\n feed_attachment_guid?: string | null\n feed_description: string\n feed_localized_description?: string | null\n feed_posted_date?: number | null\n feed_status: TransactionStatus | null\n feed_transaction_date: number | null\n flags?: number | null\n has_been_split: boolean\n has_been_viewed: boolean\n is_cleared: boolean\n is_flagged: boolean\n is_hidden: boolean\n is_international?: boolean | null\n is_manual: boolean\n is_personal: boolean\n is_reimbursable: boolean\n is_subscription: boolean\n is_void: boolean\n localized_description?: string | null\n localized_memo?: string | null\n main_class_guid?: string | null\n memo?: string | null\n metadata?: string | null\n merchant_guid?: string | null\n parent_guid?: string | null\n posted_date?: number | null\n reference?: string | null\n revision: number\n repeating_transaction_guid?: string | null\n scheduled_payment_guid?: string | null\n top_level_category_guid?: string\n transaction_type: TransactionType\n user_date?: number | null\n user_guid: string\n user_transaction_rule_guid?: string | null\n is_duplicate: boolean\n tags: string[]\n feed_transacted_at: number | null\n\n // Detailed Transaction fields\n account?: string\n accountIsClosed?: boolean\n accountIsHidden?: boolean\n category?: string\n institutionName?: string\n isIncome?: boolean\n isPending?: boolean\n number?: string\n payee?: string\n}\n\nexport enum TransactionType {\n CREDIT = 1,\n DEBIT = 2,\n}\n\nexport enum TransactionStatus {\n POSTED = 1,\n PENDING = 2,\n}\n\nexport interface Tag {\n guid: string\n is_default_tag: boolean\n name: string\n user_guid: string\n}\n\nexport interface Tagging {\n guid: string\n user_guid: string\n tag_guid: string\n transaction_guid: string\n}\n\nexport interface TransactionRule {\n guid: string\n user_guid: string\n category_guid: string | null\n match_description: string\n description: string | null\n}\n"],"mappings":"AA+DA,IAAY,IAAL,0BAAA,GAAA;AACL,SAAA,EAAA,EAAA,SAAA,CAAA,IAAA,UACA,EAAA,EAAA,QAAA,CAAA,IAAA;AACF,GAAA,CAAA,CAAA,GAEY,IAAL,0BAAA,GAAA;AACL,SAAA,EAAA,EAAA,SAAA,CAAA,IAAA,UACA,EAAA,EAAA,UAAA,CAAA,IAAA;AACF,GAAA,CAAA,CAAA"}
@@ -1,10 +1,12 @@
1
- import { TransactionStatus, TransactionType, Account, Category, Tag, Tagging, Transaction } from '../types';
1
+ import { TransactionStatus, TransactionType, Category, DetailedAccount, Tag, Tagging, Transaction } from '../types';
2
2
  import { TransactionFilter } from '../stores/TransactionStore';
3
- export declare const buildDetailedTransactions: (transactions: Transaction[], accounts: Account[], categories: Category[], taggings?: Tagging[]) => {
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
5
  account: string;
5
6
  accountIsClosed: boolean;
6
7
  accountIsHidden: boolean;
7
8
  category: string;
9
+ institutionName: string | undefined;
8
10
  isIncome: boolean;
9
11
  isPending: boolean;
10
12
  number: string;