@mx-cartographer/experiences 9.3.7-alpha.al0 → 9.3.7
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.
- package/CHANGELOG.md +2 -2
- package/dist/core/stores/AccountStore.es.js +29 -28
- package/dist/core/stores/AccountStore.es.js.map +1 -1
- package/dist/core/stores/BudgetsStore.es.js +29 -32
- package/dist/core/stores/BudgetsStore.es.js.map +1 -1
- package/dist/core/stores/GoalStore.es.js +109 -113
- package/dist/core/stores/GoalStore.es.js.map +1 -1
- package/dist/core/stores/TransactionStore.es.js +29 -28
- package/dist/core/stores/TransactionStore.es.js.map +1 -1
- package/dist/core/utils/upsertByGuid.d.ts +3 -0
- package/dist/core/utils/upsertByGuid.es.js +12 -0
- package/dist/core/utils/upsertByGuid.es.js.map +1 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
## [9.3.7] - 08-
|
|
1
|
+
## [9.3.7] - 08-20-2026
|
|
2
2
|
|
|
3
|
-
- **FIXED** -
|
|
3
|
+
- **FIXED** - Prevent duplicate items caused by race conditions between REST responses and WebSocket events
|
|
4
4
|
|
|
5
5
|
## [9.3.6] - 08-12-2026
|
|
6
6
|
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { AccountApi as h } from "../api/AccountApi.es.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
2
|
+
import { upsertByGuid as p } from "../utils/upsertByGuid.es.js";
|
|
3
|
+
import { AccountSubType as a, AccountType as c } from "../types/Account.es.js";
|
|
4
|
+
import { augmentAccounts as g } from "../utils/AccountUtils.es.js";
|
|
5
|
+
import { isFeatureEnabled as m } from "../utils/UserUtils.es.js";
|
|
5
6
|
import { makeAutoObservable as A, runInAction as d } from "mobx";
|
|
6
|
-
var
|
|
7
|
+
var C = class {
|
|
7
8
|
globalStore;
|
|
8
9
|
api = new h("/", "");
|
|
9
10
|
accounts = [];
|
|
@@ -17,7 +18,7 @@ var S = class {
|
|
|
17
18
|
membersLoading = !1;
|
|
18
19
|
uiStore;
|
|
19
20
|
constructor(t) {
|
|
20
|
-
this.globalStore = t, this.uiStore = new
|
|
21
|
+
this.globalStore = t, this.uiStore = new _(), this.api = new h(t.endpoint, t.sessionToken, t.onError), A(this);
|
|
21
22
|
}
|
|
22
23
|
loadAccountData = async () => {
|
|
23
24
|
await Promise.all([
|
|
@@ -30,14 +31,14 @@ var S = class {
|
|
|
30
31
|
return this.accountsLoaded && this.membersLoaded && this.institutionsLoaded;
|
|
31
32
|
}
|
|
32
33
|
get detailedAccounts() {
|
|
33
|
-
const t = this.globalStore.userStore.userFeatures, e =
|
|
34
|
-
return
|
|
34
|
+
const t = this.globalStore.userStore.userFeatures, e = m(t, "MD_EXCLUDE_EXTERNAL_ACCOUNTS"), s = this.globalStore.appConfig.config.display_only_external_accounts_in_accounts && this.globalStore.appConfig.options.subtype === "accounts";
|
|
35
|
+
return g(this.accounts, this.institutions, this.members, e, s);
|
|
35
36
|
}
|
|
36
37
|
get accountsByTypeMap() {
|
|
37
38
|
return this.detailedAccounts.reduce((t, e) => {
|
|
38
39
|
const s = e.account_type;
|
|
39
|
-
let
|
|
40
|
-
return
|
|
40
|
+
let o = t.get(s);
|
|
41
|
+
return o || (o = []), o.push(e), t.set(s, o), t;
|
|
41
42
|
}, /* @__PURE__ */ new Map());
|
|
42
43
|
}
|
|
43
44
|
get cashAccounts() {
|
|
@@ -71,7 +72,7 @@ var S = class {
|
|
|
71
72
|
return this.detailedAccounts.filter((t) => t.account_type === c.SAVINGS);
|
|
72
73
|
}
|
|
73
74
|
get retirementAccounts() {
|
|
74
|
-
return this.detailedAccounts.filter((t) => t.account_type === c.INVESTMENT || t.account_type === c.SAVINGS || t.account_type === c.CHECKING || t.account_type === c.CASH || t.account_type === c.PROPERTY || t.account_type === c.INSURANCE && (t.account_subtype ===
|
|
75
|
+
return this.detailedAccounts.filter((t) => t.account_type === c.INVESTMENT || t.account_type === c.SAVINGS || t.account_type === c.CHECKING || t.account_type === c.CASH || t.account_type === c.PROPERTY || t.account_type === c.INSURANCE && (t.account_subtype === a.WHOLE_LIFE || t.account_subtype === a.UNIVERSAL_LIFE || t.account_subtype === a.VARIABLE_UNIVERSAL_LIFE));
|
|
75
76
|
}
|
|
76
77
|
get visibleAccounts() {
|
|
77
78
|
return this.detailedAccounts.filter((t) => !t.is_hidden && !t.is_closed);
|
|
@@ -119,7 +120,7 @@ var S = class {
|
|
|
119
120
|
try {
|
|
120
121
|
const e = await this.api.createAccount(t);
|
|
121
122
|
d(() => {
|
|
122
|
-
this.accounts =
|
|
123
|
+
this.accounts = p(this.accounts, e);
|
|
123
124
|
});
|
|
124
125
|
} catch (e) {
|
|
125
126
|
console.error("Error occurred while adding an account:", e), this.globalStore.captureException(e, { store: "AccountStore" });
|
|
@@ -162,9 +163,9 @@ var S = class {
|
|
|
162
163
|
try {
|
|
163
164
|
const e = await this.api.mergeAccounts(t), s = e[Object.keys(e)[0]];
|
|
164
165
|
d(() => {
|
|
165
|
-
const
|
|
166
|
-
this.accounts.splice(
|
|
167
|
-
const i = this.accounts.findIndex((
|
|
166
|
+
const o = this.accounts.findIndex((n) => n.guid === t[1]);
|
|
167
|
+
this.accounts.splice(o, 1);
|
|
168
|
+
const i = this.accounts.findIndex((n) => n.guid === t[0]);
|
|
168
169
|
this.accounts.splice(i, 1, s);
|
|
169
170
|
});
|
|
170
171
|
} catch (e) {
|
|
@@ -196,14 +197,14 @@ var S = class {
|
|
|
196
197
|
};
|
|
197
198
|
updateAccount = async (t) => {
|
|
198
199
|
try {
|
|
199
|
-
const e = await this.api.updateAccount(t), s = this.accounts.findIndex((
|
|
200
|
+
const e = await this.api.updateAccount(t), s = this.accounts.findIndex((o) => o.guid === e.guid);
|
|
200
201
|
this.accounts.splice(s, 1, e);
|
|
201
202
|
} catch (e) {
|
|
202
203
|
console.error("Error occurred while updating account:", e), this.globalStore.captureException(e, { store: "AccountStore" });
|
|
203
204
|
}
|
|
204
205
|
};
|
|
205
206
|
updateAccountBalance = (t, e) => {
|
|
206
|
-
const s = this.accounts.find((
|
|
207
|
+
const s = this.accounts.find((o) => o.guid === t);
|
|
207
208
|
s && d(() => {
|
|
208
209
|
s.balance = (s.balance || 0) + e;
|
|
209
210
|
});
|
|
@@ -211,27 +212,27 @@ var S = class {
|
|
|
211
212
|
updateAccountFilter = async (t) => {
|
|
212
213
|
try {
|
|
213
214
|
const e = [];
|
|
214
|
-
for (const [i,
|
|
215
|
-
const r = this.accounts.find((
|
|
216
|
-
if (r && r.is_excluded_from_accounts ===
|
|
217
|
-
const
|
|
215
|
+
for (const [i, n] of t.entries()) {
|
|
216
|
+
const r = this.accounts.find((u) => u.guid === i);
|
|
217
|
+
if (r && r.is_excluded_from_accounts === n) {
|
|
218
|
+
const u = {
|
|
218
219
|
...r,
|
|
219
|
-
is_excluded_from_accounts: !
|
|
220
|
+
is_excluded_from_accounts: !n
|
|
220
221
|
};
|
|
221
|
-
e.push(this.api.updateAccount(
|
|
222
|
+
e.push(this.api.updateAccount(u).catch((l) => (console.error("Error occurred while updating account filter:", l), this.globalStore.captureException(l, { store: "AccountStore" }), null)));
|
|
222
223
|
}
|
|
223
224
|
}
|
|
224
|
-
const s = (await Promise.all(e)).filter((i) => i !== null),
|
|
225
|
+
const s = (await Promise.all(e)).filter((i) => i !== null), o = [...this.accounts];
|
|
225
226
|
for (const i of s) {
|
|
226
|
-
const
|
|
227
|
-
|
|
227
|
+
const n = o.findIndex((r) => r.guid === i.guid);
|
|
228
|
+
n !== -1 && o.splice(n, 1, i);
|
|
228
229
|
}
|
|
229
|
-
this.setAccounts(
|
|
230
|
+
this.setAccounts(o);
|
|
230
231
|
} catch (e) {
|
|
231
232
|
console.error("Error occurred while updating account filter:", e), this.globalStore.captureException(e, { store: "AccountStore" });
|
|
232
233
|
}
|
|
233
234
|
};
|
|
234
|
-
},
|
|
235
|
+
}, _ = class {
|
|
235
236
|
selectedAccount = {};
|
|
236
237
|
selectedMember = {};
|
|
237
238
|
constructor() {
|
|
@@ -241,7 +242,7 @@ var S = class {
|
|
|
241
242
|
setSelectedMember = (t) => this.selectedMember = t;
|
|
242
243
|
};
|
|
243
244
|
export {
|
|
244
|
-
|
|
245
|
+
C as AccountStore
|
|
245
246
|
};
|
|
246
247
|
|
|
247
248
|
//# sourceMappingURL=AccountStore.es.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AccountStore.es.js","names":[],"sources":["../../../src/core/stores/AccountStore.ts"],"sourcesContent":["import { makeAutoObservable, runInAction } from 'mobx'\n\nimport { AccountApi } from '../api'\nimport {\n type Account,\n type DetailedAccount,\n type Institution,\n type Member,\n AccountType,\n AccountSubType,\n} from '../types'\nimport { augmentAccounts } from '../utils/AccountUtils'\nimport { isFeatureEnabled } from '../utils/UserUtils'\n\nimport { GlobalStore } from './GlobalStore'\n\nexport class AccountStore {\n globalStore: GlobalStore\n api: AccountApi = new AccountApi('/', '')\n\n accounts: Account[] = []\n accountsLoaded: boolean = false\n accountsLoading: boolean = false\n institutions: Institution[] = []\n institutionsLoaded: boolean = false\n institutionsLoading: boolean = false\n members: Member[] = []\n membersLoaded: boolean = false\n membersLoading: boolean = false\n uiStore: UiStore\n\n constructor(globalStore: GlobalStore) {\n this.globalStore = globalStore\n this.uiStore = new UiStore()\n this.api = new AccountApi(globalStore.endpoint, globalStore.sessionToken, globalStore.onError)\n\n makeAutoObservable(this)\n }\n\n loadAccountData = async () => {\n await Promise.all([this.loadAccounts(), this.loadMembers(), this.loadInstitutions()])\n }\n\n get isAccountDataLoaded(): boolean {\n return this.accountsLoaded && this.membersLoaded && this.institutionsLoaded\n }\n\n get detailedAccounts(): DetailedAccount[] {\n const userFeatures = this.globalStore.userStore.userFeatures\n const excludeExternal = isFeatureEnabled(userFeatures, 'MD_EXCLUDE_EXTERNAL_ACCOUNTS')\n\n // Hide held account when this flag is toggled and this is the individual accounts widget\n const excludeHeld =\n this.globalStore.appConfig.config.display_only_external_accounts_in_accounts &&\n this.globalStore.appConfig.options.subtype === 'accounts' // Indicates this is an individual widget\n\n return augmentAccounts(\n this.accounts,\n this.institutions,\n this.members,\n excludeExternal,\n excludeHeld,\n )\n }\n\n get accountsByTypeMap(): Map<AccountType, DetailedAccount[]> {\n return this.detailedAccounts.reduce((typeMap: Map<AccountType, DetailedAccount[]>, account) => {\n const accountType = account.account_type\n\n let accounts = typeMap.get(accountType)\n if (!accounts) {\n accounts = []\n }\n accounts.push(account)\n typeMap.set(accountType, accounts)\n\n return typeMap\n }, new Map<AccountType, DetailedAccount[]>())\n }\n\n get cashAccounts(): DetailedAccount[] {\n return this.detailedAccounts.filter(\n (account: Account) =>\n account.account_type === AccountType.CASH ||\n account.account_type === AccountType.CHECKING ||\n account.account_type === AccountType.PREPAID ||\n account.account_type === AccountType.SAVINGS ||\n account.account_type === AccountType.CHECKING_LINE_OF_CREDIT,\n )\n }\n\n get cashBalance(): number {\n return this.cashAccounts.reduce((total, account) => total + (account?.balance || 0), 0)\n }\n\n get checkingAccounts(): DetailedAccount[] {\n return this.detailedAccounts.filter((a: Account) => a.account_type === AccountType.CHECKING)\n }\n\n get debtAccounts(): DetailedAccount[] {\n return this.detailedAccounts.filter(\n (account: Account) =>\n account.account_type === AccountType.CREDIT_CARD ||\n account.account_type === AccountType.LOAN ||\n account.account_type === AccountType.MORTGAGE ||\n account.account_type === AccountType.LINE_OF_CREDIT ||\n account.account_type === AccountType.CHECKING_LINE_OF_CREDIT,\n )\n }\n\n get finstrongAccounts(): DetailedAccount[] {\n const eligibleTypes = new Set([\n AccountType.CHECKING,\n AccountType.SAVINGS,\n AccountType.CREDIT_CARD,\n AccountType.INVESTMENT,\n ])\n\n return this.detailedAccounts.filter((account) => eligibleTypes.has(account.account_type))\n }\n\n get investmentAccounts(): DetailedAccount[] {\n return this.detailedAccounts.filter(\n (account: Account) => account.account_type === AccountType.INVESTMENT,\n )\n }\n\n get manualAccounts(): DetailedAccount[] {\n return this.detailedAccounts.filter((account) => account.is_manual)\n }\n\n get savingsAccounts(): DetailedAccount[] {\n return this.detailedAccounts.filter((a: Account) => a.account_type === AccountType.SAVINGS)\n }\n\n get retirementAccounts(): Account[] {\n return this.detailedAccounts.filter(\n (account: Account) =>\n account.account_type === AccountType.INVESTMENT ||\n account.account_type === AccountType.SAVINGS ||\n account.account_type === AccountType.CHECKING ||\n account.account_type === AccountType.CASH ||\n account.account_type === AccountType.PROPERTY ||\n (account.account_type === AccountType.INSURANCE &&\n (account.account_subtype === AccountSubType.WHOLE_LIFE ||\n account.account_subtype === AccountSubType.UNIVERSAL_LIFE ||\n account.account_subtype === AccountSubType.VARIABLE_UNIVERSAL_LIFE)),\n )\n }\n\n get visibleAccounts(): DetailedAccount[] {\n return this.detailedAccounts.filter((a: Account) => !a.is_hidden && !a.is_closed)\n }\n\n get visibleCashAccounts(): DetailedAccount[] {\n return this.cashAccounts.filter((account: Account) => !account.is_hidden)\n }\n\n get visibleCashBalance(): number {\n return this.visibleCashAccounts.reduce((total, account) => total + (account?.balance || 0), 0)\n }\n\n get visibleCheckingAccounts(): DetailedAccount[] {\n return this.checkingAccounts.filter((account: Account) => !account.is_hidden)\n }\n\n get visibleDebtAccounts(): DetailedAccount[] {\n return this.debtAccounts.filter((account: Account) => !account.is_hidden)\n }\n\n get visibleFinstrongAccounts(): DetailedAccount[] {\n return this.finstrongAccounts.filter(\n (account: Account) => !(account.is_closed || account.is_deleted || account.is_hidden),\n )\n }\n\n get visibleRetirementAccounts(): Account[] {\n return this.retirementAccounts.filter((account: Account) => !account.is_hidden)\n }\n\n get visibleInvestmentAccounts(): DetailedAccount[] {\n return this.investmentAccounts.filter((account: Account) => !account.is_hidden)\n }\n\n get visibleSavingsAccounts(): DetailedAccount[] {\n return this.savingsAccounts.filter((account: Account) => !account.is_hidden)\n }\n\n get savingsAndCheckingAccountsBalance(): number {\n const savingsAndCheckingAccountsList = this.savingsAndCheckingAccounts\n\n return savingsAndCheckingAccountsList.reduce(\n (total, account) => total + (account?.balance || 0),\n 0,\n )\n }\n\n get savingsAndCheckingAccounts(): Account[] {\n const savingsAndCheckingAccounts = this.accounts.filter(\n (account: Account) =>\n account.account_type === AccountType.SAVINGS ||\n account.account_type === AccountType.CHECKING,\n )\n\n return savingsAndCheckingAccounts\n }\n\n setAccounts = (accounts: Account[]) => {\n this.accounts = accounts\n this.accountsLoading = false\n this.accountsLoaded = true\n }\n\n setMembers = (members: Member[]) => {\n this.members = members\n this.membersLoading = false\n this.membersLoaded = true\n }\n\n setInstitutions = (institutions: Institution[]) => {\n this.institutions = institutions\n this.institutionsLoading = false\n this.institutionsLoaded = true\n }\n\n addAccount = async (account: Account) => {\n try {\n const newAccount = await this.api.createAccount(account)\n\n runInAction(() => {\n this.accounts = [...this.accounts, newAccount]\n })\n } catch (error) {\n console.error('Error occurred while adding an account:', error)\n this.globalStore.captureException(error, { store: 'AccountStore' })\n }\n }\n\n loadAccounts = async () => {\n if (this.accountsLoading) return\n\n this.accountsLoading = true\n try {\n const accounts = await this.api.getAccounts()\n this.setAccounts(accounts)\n } catch (error) {\n console.error('Error occurred while loading accounts:', error)\n this.globalStore.captureException(error, { store: 'AccountStore' })\n this.setAccounts([])\n }\n }\n\n loadInstitutions = async () => {\n if (this.institutionsLoading) return\n\n this.institutionsLoading = true\n try {\n const institutions = await this.api.getInstitutions()\n this.setInstitutions(institutions)\n } catch (error) {\n console.error('Error occurred while loading institutions:', error)\n this.globalStore.captureException(error, { store: 'AccountStore' })\n this.setInstitutions([])\n }\n }\n\n loadMembers = async () => {\n if (this.membersLoading) return\n\n this.membersLoading = true\n try {\n const members = await this.api.getMembers()\n this.setMembers(members)\n } catch (error) {\n console.error('Error occurred while loading members:', error)\n this.globalStore.captureException(error, { store: 'AccountStore' })\n this.setMembers([])\n }\n }\n\n mergeAccounts = async (accountGuids: string[]) => {\n try {\n const response = await this.api.mergeAccounts(accountGuids)\n // the response from the api is a funky database key here, so this is essentially just getting the first item in the returned object\n // to prevent making multiple api calls here\n const mergedAccount = response[Object.keys(response)[0]]\n\n runInAction(() => {\n const account2Index = this.accounts.findIndex((account) => account.guid === accountGuids[1])\n this.accounts.splice(account2Index, 1)\n\n const account1Index = this.accounts.findIndex((account) => account.guid === accountGuids[0])\n this.accounts.splice(account1Index, 1, mergedAccount)\n })\n } catch (error) {\n console.error('Error occurred while merging accounts:', error)\n this.globalStore.captureException(error, { store: 'AccountStore' })\n }\n }\n\n /**\n * DEPRECATED: Use loadAccountData instead\n */\n refreshAccounts = async () => {\n await Promise.all([this.loadAccounts(), this.loadInstitutions(), this.loadMembers()])\n }\n\n refreshMembers = async () => {\n try {\n await this.api.refreshAllMembers()\n } catch (error) {\n console.error('Error occurred while refreshing members:', error)\n this.globalStore.captureException(error, { store: 'AccountStore' })\n }\n }\n\n removeAccount = async (accountGuid: string) => {\n try {\n await this.api.deleteAccount(accountGuid)\n\n const deletedIndex = this.accounts.findIndex((account) => account.guid === accountGuid)\n this.accounts.splice(deletedIndex, 1)\n } catch (error) {\n console.error('Error occurred while removing an account:', error)\n this.globalStore.captureException(error, { store: 'AccountStore' })\n }\n }\n\n updateAccount = async (account: Account) => {\n try {\n const updatedAccount = await this.api.updateAccount(account)\n\n const updatedAccountIndex = this.accounts.findIndex(\n (account) => account.guid === updatedAccount.guid,\n )\n\n this.accounts.splice(updatedAccountIndex, 1, updatedAccount)\n } catch (error) {\n console.error('Error occurred while updating account:', error)\n this.globalStore.captureException(error, { store: 'AccountStore' })\n }\n }\n\n updateAccountBalance = (accountGuid: string, balanceChange: number) => {\n const account = this.accounts.find((a) => a.guid === accountGuid)\n\n if (account) {\n runInAction(() => {\n account.balance = (account.balance || 0) + balanceChange\n })\n }\n }\n\n updateAccountFilter = async (accountMap: Map<string, boolean>) => {\n try {\n const accountUpdates: Promise<Account | null>[] = []\n for (const [guid, isSelected] of accountMap.entries()) {\n const account = this.accounts.find((acc) => acc.guid === guid)\n\n if (account && account.is_excluded_from_accounts === isSelected) {\n const updatedPayload = { ...account, is_excluded_from_accounts: !isSelected }\n accountUpdates.push(\n this.api.updateAccount(updatedPayload).catch((error) => {\n console.error('Error occurred while updating account filter:', error)\n this.globalStore.captureException(error, { store: 'AccountStore' })\n return null\n }),\n )\n }\n }\n\n const results = await Promise.all(accountUpdates)\n const updatedAccounts: Account[] = results.filter((acc): acc is Account => acc !== null)\n\n const accounts = [...this.accounts]\n for (const updatedAccount of updatedAccounts) {\n const index = accounts.findIndex((acc) => acc.guid === updatedAccount.guid)\n if (index !== -1) {\n accounts.splice(index, 1, updatedAccount)\n }\n }\n this.setAccounts(accounts)\n } catch (error) {\n console.error('Error occurred while updating account filter:', error)\n this.globalStore.captureException(error, { store: 'AccountStore' })\n }\n }\n}\n\n// TODO: Move into AccountStore\nclass UiStore {\n selectedAccount: Account = {} as Account\n selectedMember: Member = {} as Member\n\n constructor() {\n makeAutoObservable(this)\n }\n\n setSelectedAccount = (account: Account) => (this.selectedAccount = account)\n setSelectedMember = (member: Member) => (this.selectedMember = member)\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"AccountStore.es.js","names":[],"sources":["../../../src/core/stores/AccountStore.ts"],"sourcesContent":["import { makeAutoObservable, runInAction } from 'mobx'\n\nimport { AccountApi } from '../api'\nimport { upsertByGuid } from '../utils/upsertByGuid'\nimport {\n type Account,\n type DetailedAccount,\n type Institution,\n type Member,\n AccountType,\n AccountSubType,\n} from '../types'\nimport { augmentAccounts } from '../utils/AccountUtils'\nimport { isFeatureEnabled } from '../utils/UserUtils'\n\nimport { GlobalStore } from './GlobalStore'\n\nexport class AccountStore {\n globalStore: GlobalStore\n api: AccountApi = new AccountApi('/', '')\n\n accounts: Account[] = []\n accountsLoaded: boolean = false\n accountsLoading: boolean = false\n institutions: Institution[] = []\n institutionsLoaded: boolean = false\n institutionsLoading: boolean = false\n members: Member[] = []\n membersLoaded: boolean = false\n membersLoading: boolean = false\n uiStore: UiStore\n\n constructor(globalStore: GlobalStore) {\n this.globalStore = globalStore\n this.uiStore = new UiStore()\n this.api = new AccountApi(globalStore.endpoint, globalStore.sessionToken, globalStore.onError)\n\n makeAutoObservable(this)\n }\n\n loadAccountData = async () => {\n await Promise.all([this.loadAccounts(), this.loadMembers(), this.loadInstitutions()])\n }\n\n get isAccountDataLoaded(): boolean {\n return this.accountsLoaded && this.membersLoaded && this.institutionsLoaded\n }\n\n get detailedAccounts(): DetailedAccount[] {\n const userFeatures = this.globalStore.userStore.userFeatures\n const excludeExternal = isFeatureEnabled(userFeatures, 'MD_EXCLUDE_EXTERNAL_ACCOUNTS')\n\n // Hide held account when this flag is toggled and this is the individual accounts widget\n const excludeHeld =\n this.globalStore.appConfig.config.display_only_external_accounts_in_accounts &&\n this.globalStore.appConfig.options.subtype === 'accounts' // Indicates this is an individual widget\n\n return augmentAccounts(\n this.accounts,\n this.institutions,\n this.members,\n excludeExternal,\n excludeHeld,\n )\n }\n\n get accountsByTypeMap(): Map<AccountType, DetailedAccount[]> {\n return this.detailedAccounts.reduce((typeMap: Map<AccountType, DetailedAccount[]>, account) => {\n const accountType = account.account_type\n\n let accounts = typeMap.get(accountType)\n if (!accounts) {\n accounts = []\n }\n accounts.push(account)\n typeMap.set(accountType, accounts)\n\n return typeMap\n }, new Map<AccountType, DetailedAccount[]>())\n }\n\n get cashAccounts(): DetailedAccount[] {\n return this.detailedAccounts.filter(\n (account: Account) =>\n account.account_type === AccountType.CASH ||\n account.account_type === AccountType.CHECKING ||\n account.account_type === AccountType.PREPAID ||\n account.account_type === AccountType.SAVINGS ||\n account.account_type === AccountType.CHECKING_LINE_OF_CREDIT,\n )\n }\n\n get cashBalance(): number {\n return this.cashAccounts.reduce((total, account) => total + (account?.balance || 0), 0)\n }\n\n get checkingAccounts(): DetailedAccount[] {\n return this.detailedAccounts.filter((a: Account) => a.account_type === AccountType.CHECKING)\n }\n\n get debtAccounts(): DetailedAccount[] {\n return this.detailedAccounts.filter(\n (account: Account) =>\n account.account_type === AccountType.CREDIT_CARD ||\n account.account_type === AccountType.LOAN ||\n account.account_type === AccountType.MORTGAGE ||\n account.account_type === AccountType.LINE_OF_CREDIT ||\n account.account_type === AccountType.CHECKING_LINE_OF_CREDIT,\n )\n }\n\n get finstrongAccounts(): DetailedAccount[] {\n const eligibleTypes = new Set([\n AccountType.CHECKING,\n AccountType.SAVINGS,\n AccountType.CREDIT_CARD,\n AccountType.INVESTMENT,\n ])\n\n return this.detailedAccounts.filter((account) => eligibleTypes.has(account.account_type))\n }\n\n get investmentAccounts(): DetailedAccount[] {\n return this.detailedAccounts.filter(\n (account: Account) => account.account_type === AccountType.INVESTMENT,\n )\n }\n\n get manualAccounts(): DetailedAccount[] {\n return this.detailedAccounts.filter((account) => account.is_manual)\n }\n\n get savingsAccounts(): DetailedAccount[] {\n return this.detailedAccounts.filter((a: Account) => a.account_type === AccountType.SAVINGS)\n }\n\n get retirementAccounts(): Account[] {\n return this.detailedAccounts.filter(\n (account: Account) =>\n account.account_type === AccountType.INVESTMENT ||\n account.account_type === AccountType.SAVINGS ||\n account.account_type === AccountType.CHECKING ||\n account.account_type === AccountType.CASH ||\n account.account_type === AccountType.PROPERTY ||\n (account.account_type === AccountType.INSURANCE &&\n (account.account_subtype === AccountSubType.WHOLE_LIFE ||\n account.account_subtype === AccountSubType.UNIVERSAL_LIFE ||\n account.account_subtype === AccountSubType.VARIABLE_UNIVERSAL_LIFE)),\n )\n }\n\n get visibleAccounts(): DetailedAccount[] {\n return this.detailedAccounts.filter((a: Account) => !a.is_hidden && !a.is_closed)\n }\n\n get visibleCashAccounts(): DetailedAccount[] {\n return this.cashAccounts.filter((account: Account) => !account.is_hidden)\n }\n\n get visibleCashBalance(): number {\n return this.visibleCashAccounts.reduce((total, account) => total + (account?.balance || 0), 0)\n }\n\n get visibleCheckingAccounts(): DetailedAccount[] {\n return this.checkingAccounts.filter((account: Account) => !account.is_hidden)\n }\n\n get visibleDebtAccounts(): DetailedAccount[] {\n return this.debtAccounts.filter((account: Account) => !account.is_hidden)\n }\n\n get visibleFinstrongAccounts(): DetailedAccount[] {\n return this.finstrongAccounts.filter(\n (account: Account) => !(account.is_closed || account.is_deleted || account.is_hidden),\n )\n }\n\n get visibleRetirementAccounts(): Account[] {\n return this.retirementAccounts.filter((account: Account) => !account.is_hidden)\n }\n\n get visibleInvestmentAccounts(): DetailedAccount[] {\n return this.investmentAccounts.filter((account: Account) => !account.is_hidden)\n }\n\n get visibleSavingsAccounts(): DetailedAccount[] {\n return this.savingsAccounts.filter((account: Account) => !account.is_hidden)\n }\n\n get savingsAndCheckingAccountsBalance(): number {\n const savingsAndCheckingAccountsList = this.savingsAndCheckingAccounts\n\n return savingsAndCheckingAccountsList.reduce(\n (total, account) => total + (account?.balance || 0),\n 0,\n )\n }\n\n get savingsAndCheckingAccounts(): Account[] {\n const savingsAndCheckingAccounts = this.accounts.filter(\n (account: Account) =>\n account.account_type === AccountType.SAVINGS ||\n account.account_type === AccountType.CHECKING,\n )\n\n return savingsAndCheckingAccounts\n }\n\n setAccounts = (accounts: Account[]) => {\n this.accounts = accounts\n this.accountsLoading = false\n this.accountsLoaded = true\n }\n\n setMembers = (members: Member[]) => {\n this.members = members\n this.membersLoading = false\n this.membersLoaded = true\n }\n\n setInstitutions = (institutions: Institution[]) => {\n this.institutions = institutions\n this.institutionsLoading = false\n this.institutionsLoaded = true\n }\n\n addAccount = async (account: Account) => {\n try {\n const newAccount = await this.api.createAccount(account)\n\n runInAction(() => {\n this.accounts = upsertByGuid(this.accounts, newAccount)\n })\n } catch (error) {\n console.error('Error occurred while adding an account:', error)\n this.globalStore.captureException(error, { store: 'AccountStore' })\n }\n }\n\n loadAccounts = async () => {\n if (this.accountsLoading) return\n\n this.accountsLoading = true\n try {\n const accounts = await this.api.getAccounts()\n this.setAccounts(accounts)\n } catch (error) {\n console.error('Error occurred while loading accounts:', error)\n this.globalStore.captureException(error, { store: 'AccountStore' })\n this.setAccounts([])\n }\n }\n\n loadInstitutions = async () => {\n if (this.institutionsLoading) return\n\n this.institutionsLoading = true\n try {\n const institutions = await this.api.getInstitutions()\n this.setInstitutions(institutions)\n } catch (error) {\n console.error('Error occurred while loading institutions:', error)\n this.globalStore.captureException(error, { store: 'AccountStore' })\n this.setInstitutions([])\n }\n }\n\n loadMembers = async () => {\n if (this.membersLoading) return\n\n this.membersLoading = true\n try {\n const members = await this.api.getMembers()\n this.setMembers(members)\n } catch (error) {\n console.error('Error occurred while loading members:', error)\n this.globalStore.captureException(error, { store: 'AccountStore' })\n this.setMembers([])\n }\n }\n\n mergeAccounts = async (accountGuids: string[]) => {\n try {\n const response = await this.api.mergeAccounts(accountGuids)\n // the response from the api is a funky database key here, so this is essentially just getting the first item in the returned object\n // to prevent making multiple api calls here\n const mergedAccount = response[Object.keys(response)[0]]\n\n runInAction(() => {\n const account2Index = this.accounts.findIndex((account) => account.guid === accountGuids[1])\n this.accounts.splice(account2Index, 1)\n\n const account1Index = this.accounts.findIndex((account) => account.guid === accountGuids[0])\n this.accounts.splice(account1Index, 1, mergedAccount)\n })\n } catch (error) {\n console.error('Error occurred while merging accounts:', error)\n this.globalStore.captureException(error, { store: 'AccountStore' })\n }\n }\n\n /**\n * DEPRECATED: Use loadAccountData instead\n */\n refreshAccounts = async () => {\n await Promise.all([this.loadAccounts(), this.loadInstitutions(), this.loadMembers()])\n }\n\n refreshMembers = async () => {\n try {\n await this.api.refreshAllMembers()\n } catch (error) {\n console.error('Error occurred while refreshing members:', error)\n this.globalStore.captureException(error, { store: 'AccountStore' })\n }\n }\n\n removeAccount = async (accountGuid: string) => {\n try {\n await this.api.deleteAccount(accountGuid)\n\n const deletedIndex = this.accounts.findIndex((account) => account.guid === accountGuid)\n this.accounts.splice(deletedIndex, 1)\n } catch (error) {\n console.error('Error occurred while removing an account:', error)\n this.globalStore.captureException(error, { store: 'AccountStore' })\n }\n }\n\n updateAccount = async (account: Account) => {\n try {\n const updatedAccount = await this.api.updateAccount(account)\n\n const updatedAccountIndex = this.accounts.findIndex(\n (account) => account.guid === updatedAccount.guid,\n )\n\n this.accounts.splice(updatedAccountIndex, 1, updatedAccount)\n } catch (error) {\n console.error('Error occurred while updating account:', error)\n this.globalStore.captureException(error, { store: 'AccountStore' })\n }\n }\n\n updateAccountBalance = (accountGuid: string, balanceChange: number) => {\n const account = this.accounts.find((a) => a.guid === accountGuid)\n\n if (account) {\n runInAction(() => {\n account.balance = (account.balance || 0) + balanceChange\n })\n }\n }\n\n updateAccountFilter = async (accountMap: Map<string, boolean>) => {\n try {\n const accountUpdates: Promise<Account | null>[] = []\n for (const [guid, isSelected] of accountMap.entries()) {\n const account = this.accounts.find((acc) => acc.guid === guid)\n\n if (account && account.is_excluded_from_accounts === isSelected) {\n const updatedPayload = { ...account, is_excluded_from_accounts: !isSelected }\n accountUpdates.push(\n this.api.updateAccount(updatedPayload).catch((error) => {\n console.error('Error occurred while updating account filter:', error)\n this.globalStore.captureException(error, { store: 'AccountStore' })\n return null\n }),\n )\n }\n }\n\n const results = await Promise.all(accountUpdates)\n const updatedAccounts: Account[] = results.filter((acc): acc is Account => acc !== null)\n\n const accounts = [...this.accounts]\n for (const updatedAccount of updatedAccounts) {\n const index = accounts.findIndex((acc) => acc.guid === updatedAccount.guid)\n if (index !== -1) {\n accounts.splice(index, 1, updatedAccount)\n }\n }\n this.setAccounts(accounts)\n } catch (error) {\n console.error('Error occurred while updating account filter:', error)\n this.globalStore.captureException(error, { store: 'AccountStore' })\n }\n }\n}\n\n// TODO: Move into AccountStore\nclass UiStore {\n selectedAccount: Account = {} as Account\n selectedMember: Member = {} as Member\n\n constructor() {\n makeAutoObservable(this)\n }\n\n setSelectedAccount = (account: Account) => (this.selectedAccount = account)\n setSelectedMember = (member: Member) => (this.selectedMember = member)\n}\n"],"mappings":"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"}
|
|
@@ -1,17 +1,18 @@
|
|
|
1
|
-
import { CategoryGuids as
|
|
1
|
+
import { CategoryGuids as i } from "../constants/Category.es.js";
|
|
2
2
|
import { BudgetsApi as o } from "../api/BudgetsApi.es.js";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
3
|
+
import { upsertByGuid as u } from "../utils/upsertByGuid.es.js";
|
|
4
|
+
import { augmentBudgets as g, findBudget as h, findSubBudget as l } from "../utils/BudgetUtil.es.js";
|
|
5
|
+
import { endOfMonth as B } from "date-fns/endOfMonth";
|
|
6
|
+
import { startOfMonth as p } from "date-fns/startOfMonth";
|
|
6
7
|
import { startOfToday as n } from "date-fns/startOfToday";
|
|
7
|
-
import { makeAutoObservable as
|
|
8
|
-
var
|
|
8
|
+
import { makeAutoObservable as b, reaction as S, runInAction as d } from "mobx";
|
|
9
|
+
var _ = class {
|
|
9
10
|
api = new o("/", "");
|
|
10
11
|
globalStore;
|
|
11
12
|
alert = "";
|
|
12
13
|
dateRange = {
|
|
13
|
-
start:
|
|
14
|
-
end:
|
|
14
|
+
start: p(n()),
|
|
15
|
+
end: B(n())
|
|
15
16
|
};
|
|
16
17
|
budgets = [];
|
|
17
18
|
selectedBudget;
|
|
@@ -20,23 +21,23 @@ var M = class {
|
|
|
20
21
|
theme = {};
|
|
21
22
|
merchantBudgets = [];
|
|
22
23
|
constructor(t) {
|
|
23
|
-
this.globalStore = t, this.api = new o(t.endpoint, t.sessionToken, t.onError),
|
|
24
|
+
this.globalStore = t, this.api = new o(t.endpoint, t.sessionToken, t.onError), b(this);
|
|
24
25
|
}
|
|
25
26
|
loadBudgetData = async () => {
|
|
26
|
-
this.globalStore.recurringTransactionsStore.isDataLoaded || await this.globalStore.recurringTransactionsStore.loadRepeatingTransactionData(), await this.loadBudgets(),
|
|
27
|
+
this.globalStore.recurringTransactionsStore.isDataLoaded || await this.globalStore.recurringTransactionsStore.loadRepeatingTransactionData(), await this.loadBudgets(), S(() => this.detailedBudgets, (t) => {
|
|
27
28
|
if (t) {
|
|
28
29
|
const e = this.selectedBudget;
|
|
29
|
-
e && (this.selectedBudget =
|
|
30
|
+
e && (this.selectedBudget = h(t, e.guid));
|
|
30
31
|
const r = this.selectedSubBudget;
|
|
31
|
-
r && r.parent_guid && (this.selectedSubBudget =
|
|
32
|
+
r && r.parent_guid && (this.selectedSubBudget = l(t, r.guid, r.parent_guid));
|
|
32
33
|
}
|
|
33
34
|
});
|
|
34
35
|
};
|
|
35
36
|
get detailedBudgets() {
|
|
36
|
-
return g(this.budgets.filter((t) => t.category_guid !==
|
|
37
|
+
return g(this.budgets.filter((t) => t.category_guid !== i.INCOME && t.category_guid !== i.TRANSFER && t.category_guid !== i.INVESTMENTS), this.globalStore.categoryStore.detailedCategories, this.globalStore.copyStore.copy.budgets, this.theme).sort((t, e) => t.percentage > e.percentage ? -1 : t.percentage < e.percentage ? 1 : 0);
|
|
37
38
|
}
|
|
38
39
|
get incomeBudget() {
|
|
39
|
-
return g(this.budgets.filter((t) => !t.parent_guid), this.globalStore.categoryStore.detailedCategories, this.globalStore.copyStore.copy.budgets, this.theme).reduce((t, e) => e.category_guid !==
|
|
40
|
+
return g(this.budgets.filter((t) => !t.parent_guid), this.globalStore.categoryStore.detailedCategories, this.globalStore.copyStore.copy.budgets, this.theme).reduce((t, e) => e.category_guid !== i.INCOME ? t : !t || e.percentage > t.percentage ? e : t, void 0)?.amount;
|
|
40
41
|
}
|
|
41
42
|
get unbudgetedCategories() {
|
|
42
43
|
return this.globalStore.categoryStore.spendCategories.filter((t) => !this.detailedBudgets.find((e) => e.category_guid === t.guid));
|
|
@@ -47,9 +48,8 @@ var M = class {
|
|
|
47
48
|
addBudget = async (t, e, r = null) => {
|
|
48
49
|
try {
|
|
49
50
|
const s = await this.api.addBudget(t, e, r);
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
d >= 0 ? this.budgets[d] = s : this.budgets.push(s);
|
|
51
|
+
d(() => {
|
|
52
|
+
this.budgets = u(this.budgets, s);
|
|
53
53
|
});
|
|
54
54
|
} catch (s) {
|
|
55
55
|
console.error("Error adding budget:", s), this.globalStore.captureException(s, { store: "BudgetsStore" });
|
|
@@ -57,7 +57,7 @@ var M = class {
|
|
|
57
57
|
};
|
|
58
58
|
deleteBudget = async (t) => {
|
|
59
59
|
try {
|
|
60
|
-
await this.api.deleteBudget(t),
|
|
60
|
+
await this.api.deleteBudget(t), d(() => {
|
|
61
61
|
const e = this.budgets.findIndex((r) => r.guid === t);
|
|
62
62
|
e >= 0 && this.budgets.splice(e, 1);
|
|
63
63
|
});
|
|
@@ -75,8 +75,7 @@ var M = class {
|
|
|
75
75
|
};
|
|
76
76
|
setAlert = (t) => this.alert = t;
|
|
77
77
|
setBudgets = (t) => {
|
|
78
|
-
|
|
79
|
-
this.budgets = t.filter((r) => !r.guid || !e.has(r.guid) ? (r.guid && e.add(r.guid), !0) : !1), this.isDataLoaded = !0;
|
|
78
|
+
this.budgets = t, this.isDataLoaded = !0;
|
|
80
79
|
};
|
|
81
80
|
setDateRange = (t) => this.dateRange = t;
|
|
82
81
|
setSelectedBudget = (t) => this.selectedBudget = t;
|
|
@@ -85,7 +84,7 @@ var M = class {
|
|
|
85
84
|
recalculateBudgets = async (t) => {
|
|
86
85
|
try {
|
|
87
86
|
for (const r of t) {
|
|
88
|
-
const s = this.budgets.find((
|
|
87
|
+
const s = this.budgets.find((a) => a.category_guid === r.guid);
|
|
89
88
|
s ? await this.api.updateBudget({
|
|
90
89
|
...s,
|
|
91
90
|
amount: r.totalAverageAmount
|
|
@@ -107,7 +106,7 @@ var M = class {
|
|
|
107
106
|
updateBudget = async (t) => {
|
|
108
107
|
try {
|
|
109
108
|
const e = await this.api.updateBudget(t);
|
|
110
|
-
|
|
109
|
+
d(() => {
|
|
111
110
|
const r = this.budgets.findIndex((s) => s.guid === t.guid);
|
|
112
111
|
r >= 0 && (this.budgets[r] = e);
|
|
113
112
|
});
|
|
@@ -117,15 +116,13 @@ var M = class {
|
|
|
117
116
|
};
|
|
118
117
|
getMerchantBudgetByMerchantGuid = (t) => this.merchantBudgets.find((e) => e?.merchant_guid === t);
|
|
119
118
|
setMerchantBudgets = (t) => {
|
|
120
|
-
|
|
121
|
-
this.merchantBudgets = t.filter((r) => !r.guid || !e.has(r.guid) ? (r.guid && e.add(r.guid), !0) : !1);
|
|
119
|
+
this.merchantBudgets = t;
|
|
122
120
|
};
|
|
123
121
|
addMerchantBudget = async (t, e) => {
|
|
124
122
|
try {
|
|
125
123
|
const r = await this.api.addMerchantBudget(t, e);
|
|
126
|
-
return
|
|
127
|
-
|
|
128
|
-
s >= 0 ? this.merchantBudgets[s] = r : this.merchantBudgets.push(r);
|
|
124
|
+
return d(() => {
|
|
125
|
+
this.merchantBudgets = u(this.merchantBudgets, r);
|
|
129
126
|
}), { isSuccess: !0 };
|
|
130
127
|
} catch (r) {
|
|
131
128
|
return console.error("Error adding merchant budget:", r), this.globalStore.captureException(r, { store: "BudgetsStore" }), { isSuccess: !1 };
|
|
@@ -134,9 +131,9 @@ var M = class {
|
|
|
134
131
|
updateMerchantBudget = async (t) => {
|
|
135
132
|
try {
|
|
136
133
|
const { guid: e, amount: r } = t, s = await this.api.updateMerchantBudget(e, r);
|
|
137
|
-
return
|
|
138
|
-
const
|
|
139
|
-
|
|
134
|
+
return d(() => {
|
|
135
|
+
const a = this.merchantBudgets.findIndex((c) => c.guid === t.guid);
|
|
136
|
+
a >= 0 && (this.merchantBudgets[a] = s);
|
|
140
137
|
}), { isSuccess: !0 };
|
|
141
138
|
} catch (e) {
|
|
142
139
|
return console.error("Error updating merchant budget:", e), this.globalStore.captureException(e, { store: "BudgetsStore" }), { isSuccess: !1 };
|
|
@@ -144,7 +141,7 @@ var M = class {
|
|
|
144
141
|
};
|
|
145
142
|
deleteMerchantBudget = async (t) => {
|
|
146
143
|
try {
|
|
147
|
-
return await this.api.deleteMerchantBudget(t),
|
|
144
|
+
return await this.api.deleteMerchantBudget(t), d(() => {
|
|
148
145
|
this.merchantBudgets = this.merchantBudgets.filter((e) => e.guid !== t);
|
|
149
146
|
}), { isSuccess: !0 };
|
|
150
147
|
} catch (e) {
|
|
@@ -153,7 +150,7 @@ var M = class {
|
|
|
153
150
|
};
|
|
154
151
|
};
|
|
155
152
|
export {
|
|
156
|
-
|
|
153
|
+
_ as BudgetsStore
|
|
157
154
|
};
|
|
158
155
|
|
|
159
156
|
//# sourceMappingURL=BudgetsStore.es.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BudgetsStore.es.js","names":[],"sources":["../../../src/core/stores/BudgetsStore.ts"],"sourcesContent":["import { makeAutoObservable, reaction, runInAction } from 'mobx'\n\nimport { endOfMonth } from 'date-fns/endOfMonth'\nimport { startOfMonth } from 'date-fns/startOfMonth'\nimport { startOfToday } from 'date-fns/startOfToday'\n\nimport { Theme } from '@mui/system'\n\nimport { BudgetsApi } from '../api'\nimport { CategoryGuids } from '../constants'\nimport { augmentBudgets, findBudget, findSubBudget } from '../utils/BudgetUtil'\n\nimport { GlobalStore } from './GlobalStore'\n\nimport type {\n Budget,\n Category,\n DateRange,\n DetailedBudget,\n DetailedCategory,\n MerchantBudget,\n} from '../types'\n\nexport class BudgetsStore {\n api: BudgetsApi = new BudgetsApi('/', '')\n\n globalStore: GlobalStore\n\n alert: string = ''\n dateRange: DateRange = { start: startOfMonth(startOfToday()), end: endOfMonth(startOfToday()) }\n budgets: Budget[] = []\n selectedBudget: DetailedBudget | undefined\n selectedSubBudget: DetailedBudget | undefined\n isDataLoaded = false\n theme = {} as Theme\n merchantBudgets: MerchantBudget[] = []\n\n constructor(globalStore: GlobalStore) {\n this.globalStore = globalStore\n this.api = new BudgetsApi(globalStore.endpoint, globalStore.sessionToken, globalStore.onError)\n\n makeAutoObservable(this)\n }\n\n loadBudgetData = async () => {\n if (!this.globalStore.recurringTransactionsStore.isDataLoaded) {\n await this.globalStore.recurringTransactionsStore.loadRepeatingTransactionData()\n }\n await this.loadBudgets()\n\n /** Reaction to update the selected budget/sub-budget if detailedBudgets is updated **/\n reaction(\n () => this.detailedBudgets,\n (detailedBudgets) => {\n if (detailedBudgets) {\n const budget = this.selectedBudget\n if (budget) {\n this.selectedBudget = findBudget(detailedBudgets, budget.guid)\n }\n\n const subBudget = this.selectedSubBudget\n if (subBudget && subBudget.parent_guid) {\n this.selectedSubBudget = findSubBudget(\n detailedBudgets,\n subBudget.guid,\n subBudget.parent_guid,\n )\n }\n }\n },\n )\n }\n\n get detailedBudgets(): DetailedBudget[] {\n return augmentBudgets(\n this.budgets.filter(\n (budget: Budget) =>\n budget.category_guid !== CategoryGuids.INCOME &&\n budget.category_guid !== CategoryGuids.TRANSFER &&\n budget.category_guid !== CategoryGuids.INVESTMENTS,\n ),\n this.globalStore.categoryStore.detailedCategories,\n this.globalStore.copyStore.copy.budgets,\n this.theme,\n ).sort((a, b) => {\n if (a.percentage > b.percentage) return -1\n if (a.percentage < b.percentage) return 1\n return 0\n })\n }\n\n // TODO: Replace this with income from recurring transactions. Income budgets are deprecated.\n get incomeBudget(): number | undefined {\n const filteredBudgets = augmentBudgets(\n this.budgets.filter((budget: Budget) => !budget.parent_guid),\n this.globalStore.categoryStore.detailedCategories,\n this.globalStore.copyStore.copy.budgets,\n this.theme,\n )\n\n const incomeBudget = filteredBudgets.reduce(\n (acc, curr) => {\n if (curr.category_guid !== CategoryGuids.INCOME) return acc\n if (!acc || curr.percentage > acc.percentage) return curr\n return acc\n },\n undefined as DetailedBudget | undefined,\n )\n\n return incomeBudget?.amount\n }\n\n get unbudgetedCategories(): DetailedCategory[] {\n return this.globalStore.categoryStore.spendCategories.filter(\n (category) => !this.detailedBudgets.find((budget) => budget.category_guid === category.guid),\n )\n }\n\n get totalBudgeted(): number {\n return this.detailedBudgets.reduce((total, budget) => total + budget.amount, 0)\n }\n\n addBudget = async (category: Category, amount: number, parentGuid: string | null = null) => {\n try {\n const budget = await this.api.addBudget(category, amount, parentGuid)\n runInAction(() => {\n const index = this.budgets.findIndex((b) => b.guid === budget.guid)\n if (index >= 0) {\n this.budgets[index] = budget\n } else {\n this.budgets.push(budget)\n }\n })\n } catch (error) {\n console.error('Error adding budget:', error)\n this.globalStore.captureException(error, { store: 'BudgetsStore' })\n }\n }\n\n deleteBudget = async (guid: string) => {\n try {\n await this.api.deleteBudget(guid)\n\n runInAction(() => {\n const index = this.budgets.findIndex((budget) => budget.guid === guid)\n if (index >= 0) {\n this.budgets.splice(index, 1)\n }\n })\n } catch (error) {\n console.error('Error deleting budget:', error)\n this.globalStore.captureException(error, { store: 'BudgetsStore' })\n }\n }\n\n loadBudgets = async () => {\n try {\n const budgets = await this.api.getBudgets()\n this.setBudgets(budgets)\n } catch (error) {\n console.error('Error occurred while loading budgets:', error)\n this.globalStore.captureException(error, { store: 'BudgetsStore' })\n throw error\n }\n }\n\n setAlert = (alert: string) => (this.alert = alert)\n\n setBudgets = (budgets: Budget[]) => {\n const seen = new Set<string>()\n this.budgets = budgets.filter((budget) => {\n if (!budget.guid || !seen.has(budget.guid)) {\n if (budget.guid) seen.add(budget.guid)\n return true\n }\n return false\n })\n this.isDataLoaded = true\n }\n\n setDateRange = (dateRange: DateRange) => (this.dateRange = dateRange)\n\n setSelectedBudget = (budget: DetailedBudget | undefined) => (this.selectedBudget = budget)\n\n setSelectedSubBudget = (budget: DetailedBudget | undefined) => (this.selectedSubBudget = budget)\n\n setTheme = (theme: Theme) => (this.theme = theme)\n\n /**\n * Recalculate budget by using the average amount from top-level categories\n * @param categories Detailed categories\n */\n recalculateBudgets = async (categories: DetailedCategory[]) => {\n try {\n for (const category of categories) {\n const budget = this.budgets.find((budget) => budget.category_guid === category.guid)\n if (budget) {\n await this.api.updateBudget({\n ...budget,\n amount: category.totalAverageAmount,\n })\n } else {\n await this.api.addBudget(category, category.totalAverageAmount)\n }\n }\n const budgetsToDelete = this.budgets.filter(\n (budget) => !categories.find((c) => c.guid === budget.category_guid),\n )\n\n for (const budgetToDelete of budgetsToDelete) {\n await this.api.deleteBudget(budgetToDelete.guid)\n }\n\n await this.loadBudgets()\n\n return { data: this.budgets, isSuccess: true }\n } catch (error) {\n console.error('Error recalculating budgets:', error)\n this.globalStore.captureException(error, { store: 'BudgetsStore' })\n return { data: [], isSuccess: false }\n }\n }\n\n updateBudget = async (budget: Budget) => {\n try {\n const updatedBudget = await this.api.updateBudget(budget)\n\n runInAction(() => {\n const index = this.budgets.findIndex((b) => b.guid === budget.guid)\n if (index >= 0) {\n this.budgets[index] = updatedBudget\n }\n })\n } catch (error) {\n console.error('Error updating budget:', error)\n this.globalStore.captureException(error, { store: 'BudgetsStore' })\n }\n }\n\n getMerchantBudgetByMerchantGuid = (merchantGuid: string): MerchantBudget | undefined => {\n return this.merchantBudgets.find(\n (eachMerchantBudget) => eachMerchantBudget?.merchant_guid === merchantGuid,\n )\n }\n\n setMerchantBudgets = (merchantBudgets: MerchantBudget[]) => {\n const seen = new Set<string>()\n this.merchantBudgets = merchantBudgets.filter((mb) => {\n if (!mb.guid || !seen.has(mb.guid)) {\n if (mb.guid) seen.add(mb.guid)\n return true\n }\n return false\n })\n }\n\n addMerchantBudget = async (merchantGuid: string, amount: number) => {\n try {\n const newMerchantBudget = await this.api.addMerchantBudget(merchantGuid, amount)\n\n runInAction(() => {\n const index = this.merchantBudgets.findIndex((b) => b.guid === newMerchantBudget.guid)\n if (index >= 0) {\n this.merchantBudgets[index] = newMerchantBudget\n } else {\n this.merchantBudgets.push(newMerchantBudget)\n }\n })\n return { isSuccess: true }\n } catch (error) {\n console.error('Error adding merchant budget:', error)\n this.globalStore.captureException(error, { store: 'BudgetsStore' })\n return { isSuccess: false }\n }\n }\n\n updateMerchantBudget = async (merchantBudget: MerchantBudget) => {\n try {\n const { guid: merchantBudgetGuid, amount } = merchantBudget\n const updatedMerchantBudget = await this.api.updateMerchantBudget(merchantBudgetGuid, amount)\n\n runInAction(() => {\n const index = this.merchantBudgets.findIndex((b) => b.guid === merchantBudget.guid)\n if (index >= 0) {\n this.merchantBudgets[index] = updatedMerchantBudget\n }\n })\n return { isSuccess: true }\n } catch (error) {\n console.error('Error updating merchant budget:', error)\n this.globalStore.captureException(error, { store: 'BudgetsStore' })\n return { isSuccess: false }\n }\n }\n\n deleteMerchantBudget = async (merchantBudgetGuid: string) => {\n try {\n await this.api.deleteMerchantBudget(merchantBudgetGuid)\n\n runInAction(() => {\n this.merchantBudgets = this.merchantBudgets.filter((b) => b.guid !== merchantBudgetGuid)\n })\n return { isSuccess: true }\n } catch (error) {\n console.error('Error deleting merchant budget:', error)\n this.globalStore.captureException(error, { store: 'BudgetsStore' })\n return { isSuccess: false }\n }\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"BudgetsStore.es.js","names":[],"sources":["../../../src/core/stores/BudgetsStore.ts"],"sourcesContent":["import { makeAutoObservable, reaction, runInAction } from 'mobx'\n\nimport { endOfMonth } from 'date-fns/endOfMonth'\nimport { startOfMonth } from 'date-fns/startOfMonth'\nimport { startOfToday } from 'date-fns/startOfToday'\n\nimport { Theme } from '@mui/system'\n\nimport { BudgetsApi } from '../api'\nimport { upsertByGuid } from '../utils/upsertByGuid'\nimport { CategoryGuids } from '../constants'\nimport { augmentBudgets, findBudget, findSubBudget } from '../utils/BudgetUtil'\n\nimport { GlobalStore } from './GlobalStore'\n\nimport type {\n Budget,\n Category,\n DateRange,\n DetailedBudget,\n DetailedCategory,\n MerchantBudget,\n} from '../types'\n\nexport class BudgetsStore {\n api: BudgetsApi = new BudgetsApi('/', '')\n\n globalStore: GlobalStore\n\n alert: string = ''\n dateRange: DateRange = { start: startOfMonth(startOfToday()), end: endOfMonth(startOfToday()) }\n budgets: Budget[] = []\n selectedBudget: DetailedBudget | undefined\n selectedSubBudget: DetailedBudget | undefined\n isDataLoaded = false\n theme = {} as Theme\n merchantBudgets: MerchantBudget[] = []\n\n constructor(globalStore: GlobalStore) {\n this.globalStore = globalStore\n this.api = new BudgetsApi(globalStore.endpoint, globalStore.sessionToken, globalStore.onError)\n\n makeAutoObservable(this)\n }\n\n loadBudgetData = async () => {\n if (!this.globalStore.recurringTransactionsStore.isDataLoaded) {\n await this.globalStore.recurringTransactionsStore.loadRepeatingTransactionData()\n }\n await this.loadBudgets()\n\n /** Reaction to update the selected budget/sub-budget if detailedBudgets is updated **/\n reaction(\n () => this.detailedBudgets,\n (detailedBudgets) => {\n if (detailedBudgets) {\n const budget = this.selectedBudget\n if (budget) {\n this.selectedBudget = findBudget(detailedBudgets, budget.guid)\n }\n\n const subBudget = this.selectedSubBudget\n if (subBudget && subBudget.parent_guid) {\n this.selectedSubBudget = findSubBudget(\n detailedBudgets,\n subBudget.guid,\n subBudget.parent_guid,\n )\n }\n }\n },\n )\n }\n\n get detailedBudgets(): DetailedBudget[] {\n return augmentBudgets(\n this.budgets.filter(\n (budget: Budget) =>\n budget.category_guid !== CategoryGuids.INCOME &&\n budget.category_guid !== CategoryGuids.TRANSFER &&\n budget.category_guid !== CategoryGuids.INVESTMENTS,\n ),\n this.globalStore.categoryStore.detailedCategories,\n this.globalStore.copyStore.copy.budgets,\n this.theme,\n ).sort((a, b) => {\n if (a.percentage > b.percentage) return -1\n if (a.percentage < b.percentage) return 1\n return 0\n })\n }\n\n // TODO: Replace this with income from recurring transactions. Income budgets are deprecated.\n get incomeBudget(): number | undefined {\n const filteredBudgets = augmentBudgets(\n this.budgets.filter((budget: Budget) => !budget.parent_guid),\n this.globalStore.categoryStore.detailedCategories,\n this.globalStore.copyStore.copy.budgets,\n this.theme,\n )\n\n const incomeBudget = filteredBudgets.reduce(\n (acc, curr) => {\n if (curr.category_guid !== CategoryGuids.INCOME) return acc\n if (!acc || curr.percentage > acc.percentage) return curr\n return acc\n },\n undefined as DetailedBudget | undefined,\n )\n\n return incomeBudget?.amount\n }\n\n get unbudgetedCategories(): DetailedCategory[] {\n return this.globalStore.categoryStore.spendCategories.filter(\n (category) => !this.detailedBudgets.find((budget) => budget.category_guid === category.guid),\n )\n }\n\n get totalBudgeted(): number {\n return this.detailedBudgets.reduce((total, budget) => total + budget.amount, 0)\n }\n\n addBudget = async (category: Category, amount: number, parentGuid: string | null = null) => {\n try {\n const budget = await this.api.addBudget(category, amount, parentGuid)\n runInAction(() => {\n this.budgets = upsertByGuid(this.budgets, budget)\n })\n } catch (error) {\n console.error('Error adding budget:', error)\n this.globalStore.captureException(error, { store: 'BudgetsStore' })\n }\n }\n\n deleteBudget = async (guid: string) => {\n try {\n await this.api.deleteBudget(guid)\n\n runInAction(() => {\n const index = this.budgets.findIndex((budget) => budget.guid === guid)\n if (index >= 0) {\n this.budgets.splice(index, 1)\n }\n })\n } catch (error) {\n console.error('Error deleting budget:', error)\n this.globalStore.captureException(error, { store: 'BudgetsStore' })\n }\n }\n\n loadBudgets = async () => {\n try {\n const budgets = await this.api.getBudgets()\n this.setBudgets(budgets)\n } catch (error) {\n console.error('Error occurred while loading budgets:', error)\n this.globalStore.captureException(error, { store: 'BudgetsStore' })\n throw error\n }\n }\n\n setAlert = (alert: string) => (this.alert = alert)\n\n setBudgets = (budgets: Budget[]) => {\n this.budgets = budgets\n this.isDataLoaded = true\n }\n\n setDateRange = (dateRange: DateRange) => (this.dateRange = dateRange)\n\n setSelectedBudget = (budget: DetailedBudget | undefined) => (this.selectedBudget = budget)\n\n setSelectedSubBudget = (budget: DetailedBudget | undefined) => (this.selectedSubBudget = budget)\n\n setTheme = (theme: Theme) => (this.theme = theme)\n\n /**\n * Recalculate budget by using the average amount from top-level categories\n * @param categories Detailed categories\n */\n recalculateBudgets = async (categories: DetailedCategory[]) => {\n try {\n for (const category of categories) {\n const budget = this.budgets.find((budget) => budget.category_guid === category.guid)\n if (budget) {\n await this.api.updateBudget({\n ...budget,\n amount: category.totalAverageAmount,\n })\n } else {\n await this.api.addBudget(category, category.totalAverageAmount)\n }\n }\n const budgetsToDelete = this.budgets.filter(\n (budget) => !categories.find((c) => c.guid === budget.category_guid),\n )\n\n for (const budgetToDelete of budgetsToDelete) {\n await this.api.deleteBudget(budgetToDelete.guid)\n }\n\n await this.loadBudgets()\n\n return { data: this.budgets, isSuccess: true }\n } catch (error) {\n console.error('Error recalculating budgets:', error)\n this.globalStore.captureException(error, { store: 'BudgetsStore' })\n return { data: [], isSuccess: false }\n }\n }\n\n updateBudget = async (budget: Budget) => {\n try {\n const updatedBudget = await this.api.updateBudget(budget)\n\n runInAction(() => {\n const index = this.budgets.findIndex((b) => b.guid === budget.guid)\n if (index >= 0) {\n this.budgets[index] = updatedBudget\n }\n })\n } catch (error) {\n console.error('Error updating budget:', error)\n this.globalStore.captureException(error, { store: 'BudgetsStore' })\n }\n }\n\n getMerchantBudgetByMerchantGuid = (merchantGuid: string): MerchantBudget | undefined => {\n return this.merchantBudgets.find(\n (eachMerchantBudget) => eachMerchantBudget?.merchant_guid === merchantGuid,\n )\n }\n\n setMerchantBudgets = (merchantBudgets: MerchantBudget[]) => {\n this.merchantBudgets = merchantBudgets\n }\n\n addMerchantBudget = async (merchantGuid: string, amount: number) => {\n try {\n const newMerchantBudget = await this.api.addMerchantBudget(merchantGuid, amount)\n\n runInAction(() => {\n this.merchantBudgets = upsertByGuid(this.merchantBudgets, newMerchantBudget)\n })\n return { isSuccess: true }\n } catch (error) {\n console.error('Error adding merchant budget:', error)\n this.globalStore.captureException(error, { store: 'BudgetsStore' })\n return { isSuccess: false }\n }\n }\n\n updateMerchantBudget = async (merchantBudget: MerchantBudget) => {\n try {\n const { guid: merchantBudgetGuid, amount } = merchantBudget\n const updatedMerchantBudget = await this.api.updateMerchantBudget(merchantBudgetGuid, amount)\n\n runInAction(() => {\n const index = this.merchantBudgets.findIndex((b) => b.guid === merchantBudget.guid)\n if (index >= 0) {\n this.merchantBudgets[index] = updatedMerchantBudget\n }\n })\n return { isSuccess: true }\n } catch (error) {\n console.error('Error updating merchant budget:', error)\n this.globalStore.captureException(error, { store: 'BudgetsStore' })\n return { isSuccess: false }\n }\n }\n\n deleteMerchantBudget = async (merchantBudgetGuid: string) => {\n try {\n await this.api.deleteMerchantBudget(merchantBudgetGuid)\n\n runInAction(() => {\n this.merchantBudgets = this.merchantBudgets.filter((b) => b.guid !== merchantBudgetGuid)\n })\n return { isSuccess: true }\n } catch (error) {\n console.error('Error deleting merchant budget:', error)\n this.globalStore.captureException(error, { store: 'BudgetsStore' })\n return { isSuccess: false }\n }\n }\n}\n"],"mappings":";;;;;;;;AAwBA,IAAa,IAAb,MAA0B;AAAA,EACxB,MAAkB,IAAI,EAAW,KAAK,EAAE;AAAA,EAExC;AAAA,EAEA,QAAgB;AAAA,EAChB,YAAuB;AAAA,IAAE,OAAO,EAAa,EAAa,CAAC;AAAA,IAAG,KAAK,EAAW,EAAa,CAAC;AAAA,EAAE;AAAA,EAC9F,UAAoB,CAAC;AAAA,EACrB;AAAA,EACA;AAAA,EACA,eAAe;AAAA,EACf,QAAQ,CAAC;AAAA,EACT,kBAAoC,CAAC;AAAA,EAErC,YAAY,GAA0B;AACpC,SAAK,cAAc,GACnB,KAAK,MAAM,IAAI,EAAW,EAAY,UAAU,EAAY,cAAc,EAAY,OAAO,GAE7F,EAAmB,IAAI;AAAA,EACzB;AAAA,EAEA,iBAAiB,YAAY;AAC3B,IAAK,KAAK,YAAY,2BAA2B,gBAC/C,MAAM,KAAK,YAAY,2BAA2B,6BAA6B,GAEjF,MAAM,KAAK,YAAY,GAGvB,EAAA,MACQ,KAAK,iBAAA,CACV,MAAoB;AACnB,UAAI,GAAiB;AACnB,cAAM,IAAS,KAAK;AACpB,QAAI,MACF,KAAK,iBAAiB,EAAW,GAAiB,EAAO,IAAI;AAG/D,cAAM,IAAY,KAAK;AACvB,QAAI,KAAa,EAAU,gBACzB,KAAK,oBAAoB,EACvB,GACA,EAAU,MACV,EAAU,WACZ;AAAA,MAEJ;AAAA,IACF,CACF;AAAA,EACF;AAAA,EAEA,IAAI,kBAAoC;AACtC,WAAO,EACL,KAAK,QAAQ,OAAA,CACV,MACC,EAAO,kBAAkB,EAAc,UACvC,EAAO,kBAAkB,EAAc,YACvC,EAAO,kBAAkB,EAAc,WAC3C,GACA,KAAK,YAAY,cAAc,oBAC/B,KAAK,YAAY,UAAU,KAAK,SAChC,KAAK,KACP,EAAE,KAAA,CAAM,GAAG,MACL,EAAE,aAAa,EAAE,aAAmB,KACpC,EAAE,aAAa,EAAE,aAAmB,IACjC,CACR;AAAA,EACH;AAAA,EAGA,IAAI,eAAmC;AAiBrC,WAhBwB,EACtB,KAAK,QAAQ,OAAA,CAAQ,MAAmB,CAAC,EAAO,WAAW,GAC3D,KAAK,YAAY,cAAc,oBAC/B,KAAK,YAAY,UAAU,KAAK,SAChC,KAAK,KAGc,EAAgB,OAAA,CAClC,GAAK,MACA,EAAK,kBAAkB,EAAc,SAAe,IACpD,CAAC,KAAO,EAAK,aAAa,EAAI,aAAmB,IAC9C,GAET,MAGK,GAAc;AAAA,EACvB;AAAA,EAEA,IAAI,uBAA2C;AAC7C,WAAO,KAAK,YAAY,cAAc,gBAAgB,OAAA,CACnD,MAAa,CAAC,KAAK,gBAAgB,KAAA,CAAM,MAAW,EAAO,kBAAkB,EAAS,IAAI,CAC7F;AAAA,EACF;AAAA,EAEA,IAAI,gBAAwB;AAC1B,WAAO,KAAK,gBAAgB,OAAA,CAAQ,GAAO,MAAW,IAAQ,EAAO,QAAQ,CAAC;AAAA,EAChF;AAAA,EAEA,YAAY,OAAO,GAAoB,GAAgB,IAA4B,SAAS;AAC1F,QAAI;AACF,YAAM,IAAS,MAAM,KAAK,IAAI,UAAU,GAAU,GAAQ,CAAU;AACpE,MAAA,EAAA,MAAkB;AAChB,aAAK,UAAU,EAAa,KAAK,SAAS,CAAM;AAAA,MAClD,CAAC;AAAA,IACH,SAAS,GAAO;AACd,cAAQ,MAAM,wBAAwB,CAAK,GAC3C,KAAK,YAAY,iBAAiB,GAAO,EAAE,OAAO,eAAe,CAAC;AAAA,IACpE;AAAA,EACF;AAAA,EAEA,eAAe,OAAO,MAAiB;AACrC,QAAI;AACF,YAAM,KAAK,IAAI,aAAa,CAAI,GAEhC,EAAA,MAAkB;AAChB,cAAM,IAAQ,KAAK,QAAQ,UAAA,CAAW,MAAW,EAAO,SAAS,CAAI;AACrE,QAAI,KAAS,KACX,KAAK,QAAQ,OAAO,GAAO,CAAC;AAAA,MAEhC,CAAC;AAAA,IACH,SAAS,GAAO;AACd,cAAQ,MAAM,0BAA0B,CAAK,GAC7C,KAAK,YAAY,iBAAiB,GAAO,EAAE,OAAO,eAAe,CAAC;AAAA,IACpE;AAAA,EACF;AAAA,EAEA,cAAc,YAAY;AACxB,QAAI;AACF,YAAM,IAAU,MAAM,KAAK,IAAI,WAAW;AAC1C,WAAK,WAAW,CAAO;AAAA,IACzB,SAAS,GAAO;AACd,oBAAQ,MAAM,yCAAyC,CAAK,GAC5D,KAAK,YAAY,iBAAiB,GAAO,EAAE,OAAO,eAAe,CAAC,GAC5D;AAAA,IACR;AAAA,EACF;AAAA,EAEA,WAAA,CAAY,MAAmB,KAAK,QAAQ;AAAA,EAE5C,aAAA,CAAc,MAAsB;AAClC,SAAK,UAAU,GACf,KAAK,eAAe;AAAA,EACtB;AAAA,EAEA,eAAA,CAAgB,MAA0B,KAAK,YAAY;AAAA,EAE3D,oBAAA,CAAqB,MAAwC,KAAK,iBAAiB;AAAA,EAEnF,uBAAA,CAAwB,MAAwC,KAAK,oBAAoB;AAAA,EAEzF,WAAA,CAAY,MAAkB,KAAK,QAAQ;AAAA,EAM3C,qBAAqB,OAAO,MAAmC;AAC7D,QAAI;AACF,iBAAW,KAAY,GAAY;AACjC,cAAM,IAAS,KAAK,QAAQ,KAAA,CAAM,MAAW,EAAO,kBAAkB,EAAS,IAAI;AACnF,QAAI,IACF,MAAM,KAAK,IAAI,aAAa;AAAA,UAC1B,GAAG;AAAA,UACH,QAAQ,EAAS;AAAA,QACnB,CAAC,IAED,MAAM,KAAK,IAAI,UAAU,GAAU,EAAS,kBAAkB;AAAA,MAElE;AACA,YAAM,IAAkB,KAAK,QAAQ,OAAA,CAClC,MAAW,CAAC,EAAW,KAAA,CAAM,MAAM,EAAE,SAAS,EAAO,aAAa,CACrE;AAEA,iBAAW,KAAkB,EAC3B,OAAM,KAAK,IAAI,aAAa,EAAe,IAAI;AAGjD,mBAAM,KAAK,YAAY,GAEhB;AAAA,QAAE,MAAM,KAAK;AAAA,QAAS,WAAW;AAAA,MAAK;AAAA,IAC/C,SAAS,GAAO;AACd,qBAAQ,MAAM,gCAAgC,CAAK,GACnD,KAAK,YAAY,iBAAiB,GAAO,EAAE,OAAO,eAAe,CAAC,GAC3D;AAAA,QAAE,MAAM,CAAC;AAAA,QAAG,WAAW;AAAA,MAAM;AAAA,IACtC;AAAA,EACF;AAAA,EAEA,eAAe,OAAO,MAAmB;AACvC,QAAI;AACF,YAAM,IAAgB,MAAM,KAAK,IAAI,aAAa,CAAM;AAExD,MAAA,EAAA,MAAkB;AAChB,cAAM,IAAQ,KAAK,QAAQ,UAAA,CAAW,MAAM,EAAE,SAAS,EAAO,IAAI;AAClE,QAAI,KAAS,MACX,KAAK,QAAQ,CAAA,IAAS;AAAA,MAE1B,CAAC;AAAA,IACH,SAAS,GAAO;AACd,cAAQ,MAAM,0BAA0B,CAAK,GAC7C,KAAK,YAAY,iBAAiB,GAAO,EAAE,OAAO,eAAe,CAAC;AAAA,IACpE;AAAA,EACF;AAAA,EAEA,kCAAA,CAAmC,MAC1B,KAAK,gBAAgB,KAAA,CACzB,MAAuB,GAAoB,kBAAkB,CAChE;AAAA,EAGF,qBAAA,CAAsB,MAAsC;AAC1D,SAAK,kBAAkB;AAAA,EACzB;AAAA,EAEA,oBAAoB,OAAO,GAAsB,MAAmB;AAClE,QAAI;AACF,YAAM,IAAoB,MAAM,KAAK,IAAI,kBAAkB,GAAc,CAAM;AAE/E,aAAA,EAAA,MAAkB;AAChB,aAAK,kBAAkB,EAAa,KAAK,iBAAiB,CAAiB;AAAA,MAC7E,CAAC,GACM,EAAE,WAAW,GAAK;AAAA,IAC3B,SAAS,GAAO;AACd,qBAAQ,MAAM,iCAAiC,CAAK,GACpD,KAAK,YAAY,iBAAiB,GAAO,EAAE,OAAO,eAAe,CAAC,GAC3D,EAAE,WAAW,GAAM;AAAA,IAC5B;AAAA,EACF;AAAA,EAEA,uBAAuB,OAAO,MAAmC;AAC/D,QAAI;AACF,YAAM,EAAE,MAAM,GAAoB,QAAA,EAAA,IAAW,GACvC,IAAwB,MAAM,KAAK,IAAI,qBAAqB,GAAoB,CAAM;AAE5F,aAAA,EAAA,MAAkB;AAChB,cAAM,IAAQ,KAAK,gBAAgB,UAAA,CAAW,MAAM,EAAE,SAAS,EAAe,IAAI;AAClF,QAAI,KAAS,MACX,KAAK,gBAAgB,CAAA,IAAS;AAAA,MAElC,CAAC,GACM,EAAE,WAAW,GAAK;AAAA,IAC3B,SAAS,GAAO;AACd,qBAAQ,MAAM,mCAAmC,CAAK,GACtD,KAAK,YAAY,iBAAiB,GAAO,EAAE,OAAO,eAAe,CAAC,GAC3D,EAAE,WAAW,GAAM;AAAA,IAC5B;AAAA,EACF;AAAA,EAEA,uBAAuB,OAAO,MAA+B;AAC3D,QAAI;AACF,mBAAM,KAAK,IAAI,qBAAqB,CAAkB,GAEtD,EAAA,MAAkB;AAChB,aAAK,kBAAkB,KAAK,gBAAgB,OAAA,CAAQ,MAAM,EAAE,SAAS,CAAkB;AAAA,MACzF,CAAC,GACM,EAAE,WAAW,GAAK;AAAA,IAC3B,SAAS,GAAO;AACd,qBAAQ,MAAM,mCAAmC,CAAK,GACtD,KAAK,YAAY,iBAAiB,GAAO,EAAE,OAAO,eAAe,CAAC,GAC3D,EAAE,WAAW,GAAM;AAAA,IAC5B;AAAA,EACF;AACF"}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import { GoalApi as
|
|
1
|
+
import { GoalApi as n } from "../api/GoalApi.es.js";
|
|
2
|
+
import { upsertByGuid as l } from "../utils/upsertByGuid.es.js";
|
|
2
3
|
import { TrackType as a } from "../types/Goal.es.js";
|
|
3
|
-
import { getProjectedRetirementDate as
|
|
4
|
-
import { makeAutoObservable as
|
|
4
|
+
import { getProjectedRetirementDate as c } from "../utils/GoalsUtil.es.js";
|
|
5
|
+
import { makeAutoObservable as d, runInAction as s } from "mobx";
|
|
5
6
|
var g = class {
|
|
6
7
|
globalStore;
|
|
7
|
-
api = new
|
|
8
|
+
api = new n("/", "");
|
|
8
9
|
goals = [];
|
|
9
10
|
goalsLoaded = !1;
|
|
10
11
|
retirementGoals = [];
|
|
@@ -16,54 +17,54 @@ var g = class {
|
|
|
16
17
|
newRetirementGoalAccounts = [];
|
|
17
18
|
alert = "";
|
|
18
19
|
selectedGoal = void 0;
|
|
19
|
-
constructor(
|
|
20
|
-
this.globalStore =
|
|
20
|
+
constructor(e) {
|
|
21
|
+
this.globalStore = e, this.api = new n(e.endpoint, e.sessionToken, e.onError), d(this);
|
|
21
22
|
}
|
|
22
23
|
get allGoals() {
|
|
23
24
|
if (!this.isAllGoalDataLoaded) return [];
|
|
24
|
-
const
|
|
25
|
+
const e = this.globalStore.copyStore.copy.goals, t = this.globalStore.userStore.user.birthday;
|
|
25
26
|
return [...this.goals, ...this.retirementGoals.map((o) => ({
|
|
26
27
|
...o,
|
|
27
28
|
amount: o.target_amount,
|
|
28
|
-
name:
|
|
29
|
+
name: e.retirement,
|
|
29
30
|
track_type: a.RETIREMENT_TRACK,
|
|
30
|
-
projected_to_complete_at: o.retirement_age &&
|
|
31
|
+
projected_to_complete_at: o.retirement_age && t ? c(o.retirement_age, t) : void 0
|
|
31
32
|
}))];
|
|
32
33
|
}
|
|
33
34
|
get orderedGoals() {
|
|
34
|
-
return this.allGoals.slice().sort((
|
|
35
|
+
return this.allGoals.slice().sort((e, t) => e.position - t.position);
|
|
35
36
|
}
|
|
36
37
|
get debtGoals() {
|
|
37
|
-
return this.orderedGoals.filter((
|
|
38
|
+
return this.orderedGoals.filter((e) => e.track_type === a.DEBT_TRACK);
|
|
38
39
|
}
|
|
39
40
|
get retirmentGoals() {
|
|
40
|
-
return this.orderedGoals.filter((
|
|
41
|
+
return this.orderedGoals.filter((e) => e.track_type === a.RETIREMENT_TRACK);
|
|
41
42
|
}
|
|
42
43
|
get savingGoals() {
|
|
43
|
-
return this.orderedGoals.filter((
|
|
44
|
+
return this.orderedGoals.filter((e) => e.track_type === a.SAVINGS_TRACK);
|
|
44
45
|
}
|
|
45
46
|
get ongoingGoalsForMicroWidget() {
|
|
46
|
-
const
|
|
47
|
+
const e = this.allGoals.filter((o) => !o.is_complete && o.track_type !== a.EMERGENCY_FUND_TRACK && o.track_type !== null), t = [
|
|
47
48
|
a.SAVINGS_TRACK,
|
|
48
49
|
a.DEBT_TRACK,
|
|
49
50
|
a.RETIREMENT_TRACK
|
|
50
51
|
];
|
|
51
|
-
return
|
|
52
|
+
return e.sort((o, r) => (o.track_type ? t.indexOf(o.track_type) : -1) - (r.track_type ? t.indexOf(r.track_type) : -1)).slice(0, 3);
|
|
52
53
|
}
|
|
53
54
|
get isAllGoalDataLoaded() {
|
|
54
55
|
return this.goalsLoaded && this.retirementGoalsLoaded && this.retirementGoalAccountsLoaded && this.monthlyCashFlowProfileLoaded;
|
|
55
56
|
}
|
|
56
|
-
setGoals = (
|
|
57
|
-
this.goals =
|
|
57
|
+
setGoals = (e) => {
|
|
58
|
+
this.goals = e, this.goalsLoaded = !0;
|
|
58
59
|
};
|
|
59
|
-
setRetirementGoals = (
|
|
60
|
-
this.retirementGoals =
|
|
60
|
+
setRetirementGoals = (e) => {
|
|
61
|
+
this.retirementGoals = e, this.retirementGoalsLoaded = !0;
|
|
61
62
|
};
|
|
62
|
-
setRetirementGoalAccounts = (
|
|
63
|
-
this.retirementGoalAccounts =
|
|
63
|
+
setRetirementGoalAccounts = (e) => {
|
|
64
|
+
this.retirementGoalAccounts = e, this.retirementGoalAccountsLoaded = !0;
|
|
64
65
|
};
|
|
65
|
-
setMonthlyCashFlowProfile = (
|
|
66
|
-
this.monthlyCashFlowProfile =
|
|
66
|
+
setMonthlyCashFlowProfile = (e) => {
|
|
67
|
+
this.monthlyCashFlowProfile = e, this.monthlyCashFlowProfileLoaded = !0;
|
|
67
68
|
};
|
|
68
69
|
loadGoalData = async () => {
|
|
69
70
|
await Promise.all([
|
|
@@ -75,154 +76,149 @@ var g = class {
|
|
|
75
76
|
};
|
|
76
77
|
loadGoals = async () => {
|
|
77
78
|
try {
|
|
78
|
-
const
|
|
79
|
-
this.setGoals(
|
|
80
|
-
} catch (
|
|
81
|
-
console.error("Error occurred while getting goals:",
|
|
79
|
+
const e = await this.api.getGoals();
|
|
80
|
+
this.setGoals(e);
|
|
81
|
+
} catch (e) {
|
|
82
|
+
console.error("Error occurred while getting goals:", e), this.globalStore.captureException(e, { store: "GoalStore" });
|
|
82
83
|
}
|
|
83
84
|
};
|
|
84
85
|
loadRetirementGoals = async () => {
|
|
85
86
|
try {
|
|
86
|
-
const
|
|
87
|
-
this.setRetirementGoals(
|
|
88
|
-
} catch (
|
|
89
|
-
console.error("Error occurred while loading retirement goals:",
|
|
87
|
+
const e = await this.api.getRetirementGoals();
|
|
88
|
+
this.setRetirementGoals(e);
|
|
89
|
+
} catch (e) {
|
|
90
|
+
console.error("Error occurred while loading retirement goals:", e), this.globalStore.captureException(e, { store: "GoalStore" });
|
|
90
91
|
}
|
|
91
92
|
};
|
|
92
93
|
loadRetirementGoalAccounts = async () => {
|
|
93
94
|
try {
|
|
94
|
-
const
|
|
95
|
-
this.setRetirementGoalAccounts(
|
|
96
|
-
} catch (
|
|
97
|
-
console.error("Error occurred while loading retirement goal accounts:",
|
|
95
|
+
const e = await this.api.getRetirementGoalAccounts();
|
|
96
|
+
this.setRetirementGoalAccounts(e);
|
|
97
|
+
} catch (e) {
|
|
98
|
+
console.error("Error occurred while loading retirement goal accounts:", e), this.globalStore.captureException(e, { store: "GoalStore" });
|
|
98
99
|
}
|
|
99
100
|
};
|
|
100
101
|
loadMonthlyCashFlowProfile = async () => {
|
|
101
102
|
try {
|
|
102
|
-
const
|
|
103
|
-
this.setMonthlyCashFlowProfile(
|
|
104
|
-
} catch (
|
|
105
|
-
console.error("Error occurred while loading monthly cash flow profile:",
|
|
103
|
+
const e = await this.api.getMonthlyCashFlowProfile();
|
|
104
|
+
this.setMonthlyCashFlowProfile(e);
|
|
105
|
+
} catch (e) {
|
|
106
|
+
console.error("Error occurred while loading monthly cash flow profile:", e), this.globalStore.captureException(e, { store: "GoalStore" });
|
|
106
107
|
}
|
|
107
108
|
};
|
|
108
|
-
addGoal = async (
|
|
109
|
+
addGoal = async (e) => {
|
|
109
110
|
try {
|
|
110
|
-
const
|
|
111
|
-
this.setGoals(
|
|
112
|
-
} catch (
|
|
113
|
-
console.error("Error occurred while adding goal:",
|
|
111
|
+
const t = await this.api.addGoal(e);
|
|
112
|
+
this.setGoals(l(this.goals, t));
|
|
113
|
+
} catch (t) {
|
|
114
|
+
console.error("Error occurred while adding goal:", t), this.globalStore.captureException(t, { store: "GoalStore" });
|
|
114
115
|
}
|
|
115
116
|
};
|
|
116
|
-
addRetirementGoal = async (
|
|
117
|
-
const e = this.globalStore.copyStore.copy.goals;
|
|
117
|
+
addRetirementGoal = async (e) => {
|
|
118
118
|
try {
|
|
119
|
-
const
|
|
120
|
-
for (const
|
|
121
|
-
const
|
|
122
|
-
...
|
|
123
|
-
retirement_goal_guid:
|
|
119
|
+
const t = await this.api.addRetirementGoal(e), o = [];
|
|
120
|
+
for (const r of this.newRetirementGoalAccounts) {
|
|
121
|
+
const i = await this.api.addRetirementGoalAccount({
|
|
122
|
+
...r,
|
|
123
|
+
retirement_goal_guid: t.guid
|
|
124
124
|
});
|
|
125
|
-
|
|
125
|
+
o.push(i);
|
|
126
126
|
}
|
|
127
|
-
this.setNewRetirementGoalAccounts([]),
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
projected_to_complete_at: o.retirement_age && i ? n(o.retirement_age, i) : void 0
|
|
133
|
-
}], this.setRetirementGoalAccounts([...this.retirementGoalAccounts, ...r]);
|
|
134
|
-
} catch (o) {
|
|
135
|
-
console.error("Error occurred while adding retirement goal:", o), this.globalStore.captureException(o, { store: "GoalStore" });
|
|
127
|
+
this.setNewRetirementGoalAccounts([]), s(() => {
|
|
128
|
+
this.setRetirementGoals(l(this.retirementGoals, t)), this.setRetirementGoalAccounts(o.reduce((r, i) => l(r, i), this.retirementGoalAccounts));
|
|
129
|
+
});
|
|
130
|
+
} catch (t) {
|
|
131
|
+
console.error("Error occurred while adding retirement goal:", t), this.globalStore.captureException(t, { store: "GoalStore" });
|
|
136
132
|
}
|
|
137
133
|
};
|
|
138
|
-
addRetirementGoalAccount = async (
|
|
134
|
+
addRetirementGoalAccount = async (e) => {
|
|
139
135
|
try {
|
|
140
|
-
const
|
|
136
|
+
const t = await this.api.addRetirementGoalAccount(e);
|
|
141
137
|
s(() => {
|
|
142
|
-
this.retirementGoalAccounts =
|
|
138
|
+
this.retirementGoalAccounts = l(this.retirementGoalAccounts, t);
|
|
143
139
|
});
|
|
144
|
-
} catch (
|
|
145
|
-
console.error("Error occurred while adding retirement goal account:",
|
|
140
|
+
} catch (t) {
|
|
141
|
+
console.error("Error occurred while adding retirement goal account:", t), this.globalStore.captureException(t, { store: "GoalStore" });
|
|
146
142
|
}
|
|
147
143
|
};
|
|
148
|
-
deleteGoal = async (
|
|
144
|
+
deleteGoal = async (e) => {
|
|
149
145
|
try {
|
|
150
|
-
await this.api.removeGoal(
|
|
151
|
-
const
|
|
152
|
-
|
|
153
|
-
} catch (
|
|
154
|
-
console.error("Error occurred while deleting goal:",
|
|
146
|
+
await this.api.removeGoal(e);
|
|
147
|
+
const t = this.goals.findIndex((o) => o.guid === e);
|
|
148
|
+
t >= 0 && this.goals.splice(t, 1);
|
|
149
|
+
} catch (t) {
|
|
150
|
+
console.error("Error occurred while deleting goal:", t), this.globalStore.captureException(t, { store: "GoalStore" });
|
|
155
151
|
}
|
|
156
152
|
};
|
|
157
|
-
deleteRetirementGoal = async (
|
|
153
|
+
deleteRetirementGoal = async (e) => {
|
|
158
154
|
try {
|
|
159
|
-
const
|
|
160
|
-
for (const r of
|
|
161
|
-
await this.api.removeRetirementGoal(
|
|
162
|
-
const o = this.retirementGoals.findIndex((r) => r.guid ===
|
|
155
|
+
const t = this.retirementGoalAccounts.filter((r) => r.retirement_goal_guid === e.guid);
|
|
156
|
+
for (const r of t) await this.deleteRetirementGoalAccount(r.guid);
|
|
157
|
+
await this.api.removeRetirementGoal(e.guid);
|
|
158
|
+
const o = this.retirementGoals.findIndex((r) => r.guid === e.guid);
|
|
163
159
|
o >= 0 && this.retirementGoals.splice(o, 1);
|
|
164
|
-
} catch (
|
|
165
|
-
console.error("Error deleting retirement goal:",
|
|
160
|
+
} catch (t) {
|
|
161
|
+
console.error("Error deleting retirement goal:", t), this.globalStore.captureException(t, { store: "GoalStore" });
|
|
166
162
|
}
|
|
167
163
|
};
|
|
168
|
-
deleteRetirementGoalAccount = async (
|
|
164
|
+
deleteRetirementGoalAccount = async (e) => {
|
|
169
165
|
try {
|
|
170
|
-
await this.api.removeRetirementGoalAccount(
|
|
171
|
-
const
|
|
172
|
-
|
|
173
|
-
} catch (
|
|
174
|
-
console.error("Error deleting retirement goal account:",
|
|
166
|
+
await this.api.removeRetirementGoalAccount(e);
|
|
167
|
+
const t = this.retirementGoalAccounts.findIndex((o) => o.guid === e);
|
|
168
|
+
t >= 0 && this.retirementGoalAccounts.splice(t, 1);
|
|
169
|
+
} catch (t) {
|
|
170
|
+
console.error("Error deleting retirement goal account:", t), this.globalStore.captureException(t, { store: "GoalStore" });
|
|
175
171
|
}
|
|
176
172
|
};
|
|
177
|
-
reorderGoals = async (
|
|
173
|
+
reorderGoals = async (e) => {
|
|
178
174
|
try {
|
|
179
|
-
const
|
|
175
|
+
const t = await this.api.reorderGoals(e);
|
|
180
176
|
s(() => {
|
|
181
|
-
for (const o of
|
|
177
|
+
for (const o of t) {
|
|
182
178
|
const r = this.goals.findIndex((i) => i.guid === o.guid);
|
|
183
179
|
r >= 0 && (this.goals[r].position = o.position);
|
|
184
180
|
}
|
|
185
181
|
});
|
|
186
|
-
} catch (
|
|
187
|
-
console.error("Error reordering goals:",
|
|
182
|
+
} catch (t) {
|
|
183
|
+
console.error("Error reordering goals:", t), this.globalStore.captureException(t, { store: "GoalStore" });
|
|
188
184
|
}
|
|
189
185
|
};
|
|
190
|
-
setAlert = (
|
|
191
|
-
setNewRetirementGoalAccounts = (
|
|
192
|
-
this.newRetirementGoalAccounts =
|
|
186
|
+
setAlert = (e) => this.alert = e;
|
|
187
|
+
setNewRetirementGoalAccounts = (e) => {
|
|
188
|
+
this.newRetirementGoalAccounts = e;
|
|
193
189
|
};
|
|
194
|
-
setSelectedGoal = (
|
|
195
|
-
updateGoal = async (
|
|
190
|
+
setSelectedGoal = (e) => this.selectedGoal = e;
|
|
191
|
+
updateGoal = async (e) => {
|
|
196
192
|
try {
|
|
197
|
-
const
|
|
193
|
+
const t = await this.api.updateGoal(e);
|
|
198
194
|
s(() => {
|
|
199
|
-
const o = this.goals.findIndex((r) => r.guid ===
|
|
200
|
-
o >= 0 && (this.goals[o] =
|
|
195
|
+
const o = this.goals.findIndex((r) => r.guid === e.guid);
|
|
196
|
+
o >= 0 && (this.goals[o] = t), this.selectedGoal?.guid === e.guid && this.setSelectedGoal(t);
|
|
201
197
|
});
|
|
202
|
-
} catch (
|
|
203
|
-
console.error("Error occurred while updating goal:",
|
|
198
|
+
} catch (t) {
|
|
199
|
+
console.error("Error occurred while updating goal:", t), this.globalStore.captureException(t, { store: "GoalStore" });
|
|
204
200
|
}
|
|
205
201
|
};
|
|
206
|
-
updateRetirementGoal = async (
|
|
202
|
+
updateRetirementGoal = async (e) => {
|
|
207
203
|
try {
|
|
208
|
-
const
|
|
209
|
-
...
|
|
210
|
-
target_amount:
|
|
204
|
+
const t = await this.api.updateRetirementGoal({
|
|
205
|
+
...e,
|
|
206
|
+
target_amount: e.amount
|
|
211
207
|
});
|
|
212
208
|
s(() => {
|
|
213
|
-
const o = this.retirementGoals.findIndex((r) => r.guid ===
|
|
214
|
-
o >= 0 && (this.retirementGoals[o] =
|
|
209
|
+
const o = this.retirementGoals.findIndex((r) => r.guid === e.guid);
|
|
210
|
+
o >= 0 && (this.retirementGoals[o] = t), this.selectedGoal?.guid === e.guid && this.setSelectedGoal(this.allGoals.find((r) => r.guid === e.guid));
|
|
215
211
|
});
|
|
216
|
-
} catch (
|
|
217
|
-
console.error("Error occurred while updating retirement goal:",
|
|
212
|
+
} catch (t) {
|
|
213
|
+
console.error("Error occurred while updating retirement goal:", t), this.globalStore.captureException(t, { store: "GoalStore" });
|
|
218
214
|
}
|
|
219
215
|
};
|
|
220
|
-
updateMonthlyCashFlowProfile = async (
|
|
216
|
+
updateMonthlyCashFlowProfile = async (e) => {
|
|
221
217
|
try {
|
|
222
|
-
const
|
|
223
|
-
this.setMonthlyCashFlowProfile(
|
|
224
|
-
} catch (
|
|
225
|
-
console.error("Error occurred while updating monthly cash flow profile:",
|
|
218
|
+
const t = await this.api.updateMonthlyCashFlowProfile(e);
|
|
219
|
+
this.setMonthlyCashFlowProfile(t);
|
|
220
|
+
} catch (t) {
|
|
221
|
+
console.error("Error occurred while updating monthly cash flow profile:", t), this.globalStore.captureException(t, { store: "GoalStore" });
|
|
226
222
|
}
|
|
227
223
|
};
|
|
228
224
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GoalStore.es.js","names":[],"sources":["../../../src/core/stores/GoalStore.ts"],"sourcesContent":["import { makeAutoObservable, runInAction } from 'mobx'\n\nimport { GoalApi } from '../api'\n\nimport {\n type Goal,\n type MonthlyCashFlowProfile,\n type RetirementGoalAccount,\n TrackType,\n} from '../types'\nimport { getProjectedRetirementDate } from '../utils/GoalsUtil'\n\nimport { GlobalStore } from './GlobalStore'\n\nexport class GoalStore {\n globalStore: GlobalStore\n api = new GoalApi('/', '')\n\n goals: Goal[] = []\n goalsLoaded: boolean = false\n retirementGoals: Goal[] = []\n retirementGoalsLoaded: boolean = false\n retirementGoalAccounts: RetirementGoalAccount[] = []\n retirementGoalAccountsLoaded: boolean = false\n monthlyCashFlowProfile: MonthlyCashFlowProfile | undefined = undefined\n monthlyCashFlowProfileLoaded: boolean = false\n\n newRetirementGoalAccounts: RetirementGoalAccount[] = []\n\n alert: string = ''\n selectedGoal: Goal | undefined = undefined\n\n constructor(globalStore: GlobalStore) {\n this.globalStore = globalStore\n this.api = new GoalApi(globalStore.endpoint, globalStore.sessionToken, globalStore.onError)\n\n makeAutoObservable(this)\n }\n\n get allGoals(): Goal[] {\n if (!this.isAllGoalDataLoaded) return []\n\n const goalsCopy = this.globalStore.copyStore.copy.goals\n const userBirthday = this.globalStore.userStore.user.birthday\n return [\n ...this.goals,\n ...this.retirementGoals.map((goal: Goal) => ({\n ...goal,\n amount: goal.target_amount,\n name: goalsCopy.retirement,\n track_type: TrackType.RETIREMENT_TRACK,\n projected_to_complete_at:\n goal.retirement_age && userBirthday\n ? getProjectedRetirementDate(goal.retirement_age, userBirthday)\n : undefined,\n })),\n ] as Goal[]\n }\n\n get orderedGoals(): Goal[] {\n return this.allGoals.slice().sort((a, b) => a.position - b.position)\n }\n\n get debtGoals() {\n return this.orderedGoals.filter((goal) => goal.track_type === TrackType.DEBT_TRACK)\n }\n\n get retirmentGoals() {\n return this.orderedGoals.filter((goal) => goal.track_type === TrackType.RETIREMENT_TRACK)\n }\n\n get savingGoals() {\n return this.orderedGoals.filter((goal) => goal.track_type === TrackType.SAVINGS_TRACK)\n }\n\n get ongoingGoalsForMicroWidget() {\n const ongoingGoals = this.allGoals.filter(\n (goal) =>\n !goal.is_complete &&\n goal.track_type !== TrackType.EMERGENCY_FUND_TRACK &&\n goal.track_type !== null,\n )\n const priorityOrder = [\n TrackType.SAVINGS_TRACK,\n TrackType.DEBT_TRACK,\n TrackType.RETIREMENT_TRACK,\n ]\n return ongoingGoals\n .sort((a, b) => {\n const aIndex = a.track_type ? priorityOrder.indexOf(a.track_type) : -1\n const bIndex = b.track_type ? priorityOrder.indexOf(b.track_type) : -1\n return aIndex - bIndex\n })\n .slice(0, 3)\n }\n\n get isAllGoalDataLoaded() {\n return (\n this.goalsLoaded &&\n this.retirementGoalsLoaded &&\n this.retirementGoalAccountsLoaded &&\n this.monthlyCashFlowProfileLoaded\n )\n }\n\n setGoals = (goals: Goal[]) => {\n this.goals = goals\n this.goalsLoaded = true\n }\n\n setRetirementGoals = (goals: Goal[]) => {\n this.retirementGoals = goals\n this.retirementGoalsLoaded = true\n }\n\n setRetirementGoalAccounts = (accounts: RetirementGoalAccount[]) => {\n this.retirementGoalAccounts = accounts\n this.retirementGoalAccountsLoaded = true\n }\n\n setMonthlyCashFlowProfile = (profile: MonthlyCashFlowProfile) => {\n this.monthlyCashFlowProfile = profile\n this.monthlyCashFlowProfileLoaded = true\n }\n\n loadGoalData = async () => {\n await Promise.all([\n this.loadGoals(),\n this.loadRetirementGoals(),\n this.loadRetirementGoalAccounts(),\n this.loadMonthlyCashFlowProfile(),\n ])\n }\n\n loadGoals = async () => {\n try {\n const goals = await this.api.getGoals()\n this.setGoals(goals)\n } catch (error) {\n console.error('Error occurred while getting goals:', error)\n this.globalStore.captureException(error, { store: 'GoalStore' })\n }\n }\n\n loadRetirementGoals = async () => {\n try {\n const retirementGoals = await this.api.getRetirementGoals()\n this.setRetirementGoals(retirementGoals)\n } catch (error) {\n console.error('Error occurred while loading retirement goals:', error)\n this.globalStore.captureException(error, { store: 'GoalStore' })\n }\n }\n\n loadRetirementGoalAccounts = async () => {\n try {\n const retirementGoalAccounts = await this.api.getRetirementGoalAccounts()\n this.setRetirementGoalAccounts(retirementGoalAccounts)\n } catch (error) {\n console.error('Error occurred while loading retirement goal accounts:', error)\n this.globalStore.captureException(error, { store: 'GoalStore' })\n }\n }\n\n loadMonthlyCashFlowProfile = async () => {\n try {\n const monthlyCashFlowProfile = await this.api.getMonthlyCashFlowProfile()\n this.setMonthlyCashFlowProfile(monthlyCashFlowProfile)\n } catch (error) {\n console.error('Error occurred while loading monthly cash flow profile:', error)\n this.globalStore.captureException(error, { store: 'GoalStore' })\n }\n }\n\n addGoal = async (goal: Goal) => {\n try {\n const newGoal = await this.api.addGoal(goal)\n this.setGoals([...this.goals, newGoal])\n } catch (error) {\n console.error('Error occurred while adding goal:', error)\n this.globalStore.captureException(error, { store: 'GoalStore' })\n }\n }\n\n addRetirementGoal = async (goal: Goal) => {\n const goalsCopy = this.globalStore.copyStore.copy.goals\n try {\n const newGoal: Goal = await this.api.addRetirementGoal(goal)\n const newAccounts = [] as RetirementGoalAccount[]\n const userBirthday = this.globalStore.userStore.user.birthday\n for (const account of this.newRetirementGoalAccounts) {\n const newAccount = await this.api.addRetirementGoalAccount({\n ...account,\n retirement_goal_guid: newGoal.guid,\n })\n newAccounts.push(newAccount)\n }\n this.setNewRetirementGoalAccounts([])\n\n this.retirementGoals = [\n ...this.retirementGoals,\n {\n ...newGoal,\n amount: newGoal.target_amount,\n name: goalsCopy.retirement,\n track_type: TrackType.RETIREMENT_TRACK,\n projected_to_complete_at:\n newGoal.retirement_age && userBirthday\n ? getProjectedRetirementDate(newGoal.retirement_age, userBirthday)\n : undefined,\n } as Goal,\n ]\n this.setRetirementGoalAccounts([...this.retirementGoalAccounts, ...newAccounts])\n } catch (error) {\n console.error('Error occurred while adding retirement goal:', error)\n this.globalStore.captureException(error, { store: 'GoalStore' })\n }\n }\n\n addRetirementGoalAccount = async (account: RetirementGoalAccount) => {\n try {\n const newAccount = await this.api.addRetirementGoalAccount(account)\n\n runInAction(() => {\n this.retirementGoalAccounts = [...this.retirementGoalAccounts, newAccount]\n })\n } catch (error) {\n console.error('Error occurred while adding retirement goal account:', error)\n this.globalStore.captureException(error, { store: 'GoalStore' })\n }\n }\n\n deleteGoal = async (guid: string) => {\n try {\n await this.api.removeGoal(guid)\n\n const index = this.goals.findIndex((g) => g.guid === guid)\n if (index >= 0) {\n this.goals.splice(index, 1)\n }\n } catch (error) {\n console.error('Error occurred while deleting goal:', error)\n this.globalStore.captureException(error, { store: 'GoalStore' })\n }\n }\n\n deleteRetirementGoal = async (goal: Goal) => {\n try {\n const accounts = this.retirementGoalAccounts.filter(\n (g) => g.retirement_goal_guid === goal.guid,\n )\n for (const account of accounts) {\n await this.deleteRetirementGoalAccount(account.guid)\n }\n await this.api.removeRetirementGoal(goal.guid)\n\n const index = this.retirementGoals.findIndex((g) => g.guid === goal.guid)\n if (index >= 0) {\n this.retirementGoals.splice(index, 1)\n }\n } catch (error) {\n console.error('Error deleting retirement goal:', error)\n this.globalStore.captureException(error, { store: 'GoalStore' })\n }\n }\n\n deleteRetirementGoalAccount = async (guid: string) => {\n try {\n await this.api.removeRetirementGoalAccount(guid)\n\n const index = this.retirementGoalAccounts.findIndex((rga) => rga.guid === guid)\n if (index >= 0) {\n this.retirementGoalAccounts.splice(index, 1)\n }\n } catch (error) {\n console.error('Error deleting retirement goal account:', error)\n this.globalStore.captureException(error, { store: 'GoalStore' })\n }\n }\n\n reorderGoals = async (goals: Goal[]) => {\n try {\n const reordered = (await this.api.reorderGoals(goals)) as Goal[]\n\n runInAction(() => {\n for (const goal of reordered) {\n const index = this.goals.findIndex((g) => g.guid === goal.guid)\n if (index >= 0) {\n this.goals[index].position = goal.position\n }\n }\n })\n } catch (error) {\n console.error('Error reordering goals:', error)\n this.globalStore.captureException(error, { store: 'GoalStore' })\n }\n }\n\n setAlert = (alert: string) => (this.alert = alert)\n\n setNewRetirementGoalAccounts = (accounts: RetirementGoalAccount[]) => {\n this.newRetirementGoalAccounts = accounts\n }\n\n setSelectedGoal = (goal: Goal | undefined) => (this.selectedGoal = goal)\n\n updateGoal = async (goal: Goal) => {\n try {\n const updatedGoal = await this.api.updateGoal(goal)\n\n runInAction(() => {\n const index = this.goals.findIndex((g) => g.guid === goal.guid)\n if (index >= 0) {\n this.goals[index] = updatedGoal\n }\n if (this.selectedGoal?.guid === goal.guid) {\n this.setSelectedGoal(updatedGoal)\n }\n })\n } catch (error) {\n console.error('Error occurred while updating goal:', error)\n this.globalStore.captureException(error, { store: 'GoalStore' })\n }\n }\n\n updateRetirementGoal = async (goal: Goal) => {\n try {\n const updatedRetirementGoal = await this.api.updateRetirementGoal({\n ...goal,\n target_amount: goal.amount,\n })\n\n runInAction(() => {\n const index = this.retirementGoals.findIndex((g) => g.guid === goal.guid)\n if (index >= 0) {\n this.retirementGoals[index] = updatedRetirementGoal\n }\n\n if (this.selectedGoal?.guid === goal.guid) {\n this.setSelectedGoal(this.allGoals.find((g) => g.guid === goal.guid))\n }\n })\n } catch (error) {\n console.error('Error occurred while updating retirement goal:', error)\n this.globalStore.captureException(error, { store: 'GoalStore' })\n }\n }\n\n updateMonthlyCashFlowProfile = async (profile: MonthlyCashFlowProfile) => {\n try {\n const updatedProfile = await this.api.updateMonthlyCashFlowProfile(profile)\n this.setMonthlyCashFlowProfile(updatedProfile)\n } catch (error) {\n console.error('Error occurred while updating monthly cash flow profile:', error)\n this.globalStore.captureException(error, { store: 'GoalStore' })\n }\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"GoalStore.es.js","names":[],"sources":["../../../src/core/stores/GoalStore.ts"],"sourcesContent":["import { makeAutoObservable, runInAction } from 'mobx'\n\nimport { GoalApi } from '../api'\nimport { upsertByGuid } from '../utils/upsertByGuid'\n\nimport {\n type Goal,\n type MonthlyCashFlowProfile,\n type RetirementGoalAccount,\n TrackType,\n} from '../types'\nimport { getProjectedRetirementDate } from '../utils/GoalsUtil'\n\nimport { GlobalStore } from './GlobalStore'\n\nexport class GoalStore {\n globalStore: GlobalStore\n api = new GoalApi('/', '')\n\n goals: Goal[] = []\n goalsLoaded: boolean = false\n retirementGoals: Goal[] = []\n retirementGoalsLoaded: boolean = false\n retirementGoalAccounts: RetirementGoalAccount[] = []\n retirementGoalAccountsLoaded: boolean = false\n monthlyCashFlowProfile: MonthlyCashFlowProfile | undefined = undefined\n monthlyCashFlowProfileLoaded: boolean = false\n\n newRetirementGoalAccounts: RetirementGoalAccount[] = []\n\n alert: string = ''\n selectedGoal: Goal | undefined = undefined\n\n constructor(globalStore: GlobalStore) {\n this.globalStore = globalStore\n this.api = new GoalApi(globalStore.endpoint, globalStore.sessionToken, globalStore.onError)\n\n makeAutoObservable(this)\n }\n\n get allGoals(): Goal[] {\n if (!this.isAllGoalDataLoaded) return []\n\n const goalsCopy = this.globalStore.copyStore.copy.goals\n const userBirthday = this.globalStore.userStore.user.birthday\n return [\n ...this.goals,\n ...this.retirementGoals.map((goal: Goal) => ({\n ...goal,\n amount: goal.target_amount,\n name: goalsCopy.retirement,\n track_type: TrackType.RETIREMENT_TRACK,\n projected_to_complete_at:\n goal.retirement_age && userBirthday\n ? getProjectedRetirementDate(goal.retirement_age, userBirthday)\n : undefined,\n })),\n ] as Goal[]\n }\n\n get orderedGoals(): Goal[] {\n return this.allGoals.slice().sort((a, b) => a.position - b.position)\n }\n\n get debtGoals() {\n return this.orderedGoals.filter((goal) => goal.track_type === TrackType.DEBT_TRACK)\n }\n\n get retirmentGoals() {\n return this.orderedGoals.filter((goal) => goal.track_type === TrackType.RETIREMENT_TRACK)\n }\n\n get savingGoals() {\n return this.orderedGoals.filter((goal) => goal.track_type === TrackType.SAVINGS_TRACK)\n }\n\n get ongoingGoalsForMicroWidget() {\n const ongoingGoals = this.allGoals.filter(\n (goal) =>\n !goal.is_complete &&\n goal.track_type !== TrackType.EMERGENCY_FUND_TRACK &&\n goal.track_type !== null,\n )\n const priorityOrder = [\n TrackType.SAVINGS_TRACK,\n TrackType.DEBT_TRACK,\n TrackType.RETIREMENT_TRACK,\n ]\n return ongoingGoals\n .sort((a, b) => {\n const aIndex = a.track_type ? priorityOrder.indexOf(a.track_type) : -1\n const bIndex = b.track_type ? priorityOrder.indexOf(b.track_type) : -1\n return aIndex - bIndex\n })\n .slice(0, 3)\n }\n\n get isAllGoalDataLoaded() {\n return (\n this.goalsLoaded &&\n this.retirementGoalsLoaded &&\n this.retirementGoalAccountsLoaded &&\n this.monthlyCashFlowProfileLoaded\n )\n }\n\n setGoals = (goals: Goal[]) => {\n this.goals = goals\n this.goalsLoaded = true\n }\n\n setRetirementGoals = (goals: Goal[]) => {\n this.retirementGoals = goals\n this.retirementGoalsLoaded = true\n }\n\n setRetirementGoalAccounts = (accounts: RetirementGoalAccount[]) => {\n this.retirementGoalAccounts = accounts\n this.retirementGoalAccountsLoaded = true\n }\n\n setMonthlyCashFlowProfile = (profile: MonthlyCashFlowProfile) => {\n this.monthlyCashFlowProfile = profile\n this.monthlyCashFlowProfileLoaded = true\n }\n\n loadGoalData = async () => {\n await Promise.all([\n this.loadGoals(),\n this.loadRetirementGoals(),\n this.loadRetirementGoalAccounts(),\n this.loadMonthlyCashFlowProfile(),\n ])\n }\n\n loadGoals = async () => {\n try {\n const goals = await this.api.getGoals()\n this.setGoals(goals)\n } catch (error) {\n console.error('Error occurred while getting goals:', error)\n this.globalStore.captureException(error, { store: 'GoalStore' })\n }\n }\n\n loadRetirementGoals = async () => {\n try {\n const retirementGoals = await this.api.getRetirementGoals()\n this.setRetirementGoals(retirementGoals)\n } catch (error) {\n console.error('Error occurred while loading retirement goals:', error)\n this.globalStore.captureException(error, { store: 'GoalStore' })\n }\n }\n\n loadRetirementGoalAccounts = async () => {\n try {\n const retirementGoalAccounts = await this.api.getRetirementGoalAccounts()\n this.setRetirementGoalAccounts(retirementGoalAccounts)\n } catch (error) {\n console.error('Error occurred while loading retirement goal accounts:', error)\n this.globalStore.captureException(error, { store: 'GoalStore' })\n }\n }\n\n loadMonthlyCashFlowProfile = async () => {\n try {\n const monthlyCashFlowProfile = await this.api.getMonthlyCashFlowProfile()\n this.setMonthlyCashFlowProfile(monthlyCashFlowProfile)\n } catch (error) {\n console.error('Error occurred while loading monthly cash flow profile:', error)\n this.globalStore.captureException(error, { store: 'GoalStore' })\n }\n }\n\n addGoal = async (goal: Goal) => {\n try {\n const newGoal = await this.api.addGoal(goal)\n this.setGoals(upsertByGuid(this.goals, newGoal))\n } catch (error) {\n console.error('Error occurred while adding goal:', error)\n this.globalStore.captureException(error, { store: 'GoalStore' })\n }\n }\n\n addRetirementGoal = async (goal: Goal) => {\n try {\n const newGoal: Goal = await this.api.addRetirementGoal(goal)\n const newAccounts = [] as RetirementGoalAccount[]\n for (const account of this.newRetirementGoalAccounts) {\n const newAccount = await this.api.addRetirementGoalAccount({\n ...account,\n retirement_goal_guid: newGoal.guid,\n })\n newAccounts.push(newAccount)\n }\n this.setNewRetirementGoalAccounts([])\n\n runInAction(() => {\n this.setRetirementGoals(upsertByGuid(this.retirementGoals, newGoal))\n this.setRetirementGoalAccounts(\n newAccounts.reduce((acc, a) => upsertByGuid(acc, a), this.retirementGoalAccounts),\n )\n })\n } catch (error) {\n console.error('Error occurred while adding retirement goal:', error)\n this.globalStore.captureException(error, { store: 'GoalStore' })\n }\n }\n\n addRetirementGoalAccount = async (account: RetirementGoalAccount) => {\n try {\n const newAccount = await this.api.addRetirementGoalAccount(account)\n\n runInAction(() => {\n this.retirementGoalAccounts = upsertByGuid(this.retirementGoalAccounts, newAccount)\n })\n } catch (error) {\n console.error('Error occurred while adding retirement goal account:', error)\n this.globalStore.captureException(error, { store: 'GoalStore' })\n }\n }\n\n deleteGoal = async (guid: string) => {\n try {\n await this.api.removeGoal(guid)\n\n const index = this.goals.findIndex((g) => g.guid === guid)\n if (index >= 0) {\n this.goals.splice(index, 1)\n }\n } catch (error) {\n console.error('Error occurred while deleting goal:', error)\n this.globalStore.captureException(error, { store: 'GoalStore' })\n }\n }\n\n deleteRetirementGoal = async (goal: Goal) => {\n try {\n const accounts = this.retirementGoalAccounts.filter(\n (g) => g.retirement_goal_guid === goal.guid,\n )\n for (const account of accounts) {\n await this.deleteRetirementGoalAccount(account.guid)\n }\n await this.api.removeRetirementGoal(goal.guid)\n\n const index = this.retirementGoals.findIndex((g) => g.guid === goal.guid)\n if (index >= 0) {\n this.retirementGoals.splice(index, 1)\n }\n } catch (error) {\n console.error('Error deleting retirement goal:', error)\n this.globalStore.captureException(error, { store: 'GoalStore' })\n }\n }\n\n deleteRetirementGoalAccount = async (guid: string) => {\n try {\n await this.api.removeRetirementGoalAccount(guid)\n\n const index = this.retirementGoalAccounts.findIndex((rga) => rga.guid === guid)\n if (index >= 0) {\n this.retirementGoalAccounts.splice(index, 1)\n }\n } catch (error) {\n console.error('Error deleting retirement goal account:', error)\n this.globalStore.captureException(error, { store: 'GoalStore' })\n }\n }\n\n reorderGoals = async (goals: Goal[]) => {\n try {\n const reordered = (await this.api.reorderGoals(goals)) as Goal[]\n\n runInAction(() => {\n for (const goal of reordered) {\n const index = this.goals.findIndex((g) => g.guid === goal.guid)\n if (index >= 0) {\n this.goals[index].position = goal.position\n }\n }\n })\n } catch (error) {\n console.error('Error reordering goals:', error)\n this.globalStore.captureException(error, { store: 'GoalStore' })\n }\n }\n\n setAlert = (alert: string) => (this.alert = alert)\n\n setNewRetirementGoalAccounts = (accounts: RetirementGoalAccount[]) => {\n this.newRetirementGoalAccounts = accounts\n }\n\n setSelectedGoal = (goal: Goal | undefined) => (this.selectedGoal = goal)\n\n updateGoal = async (goal: Goal) => {\n try {\n const updatedGoal = await this.api.updateGoal(goal)\n\n runInAction(() => {\n const index = this.goals.findIndex((g) => g.guid === goal.guid)\n if (index >= 0) {\n this.goals[index] = updatedGoal\n }\n if (this.selectedGoal?.guid === goal.guid) {\n this.setSelectedGoal(updatedGoal)\n }\n })\n } catch (error) {\n console.error('Error occurred while updating goal:', error)\n this.globalStore.captureException(error, { store: 'GoalStore' })\n }\n }\n\n updateRetirementGoal = async (goal: Goal) => {\n try {\n const updatedRetirementGoal = await this.api.updateRetirementGoal({\n ...goal,\n target_amount: goal.amount,\n })\n\n runInAction(() => {\n const index = this.retirementGoals.findIndex((g) => g.guid === goal.guid)\n if (index >= 0) {\n this.retirementGoals[index] = updatedRetirementGoal\n }\n\n if (this.selectedGoal?.guid === goal.guid) {\n this.setSelectedGoal(this.allGoals.find((g) => g.guid === goal.guid))\n }\n })\n } catch (error) {\n console.error('Error occurred while updating retirement goal:', error)\n this.globalStore.captureException(error, { store: 'GoalStore' })\n }\n }\n\n updateMonthlyCashFlowProfile = async (profile: MonthlyCashFlowProfile) => {\n try {\n const updatedProfile = await this.api.updateMonthlyCashFlowProfile(profile)\n this.setMonthlyCashFlowProfile(updatedProfile)\n } catch (error) {\n console.error('Error occurred while updating monthly cash flow profile:', error)\n this.globalStore.captureException(error, { store: 'GoalStore' })\n }\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
import { BeatApi as d } from "../api/BeatApi.es.js";
|
|
2
2
|
import { TransactionApi as g } from "../api/TransactionApi.es.js";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
3
|
+
import { upsertByGuid as p } from "../utils/upsertByGuid.es.js";
|
|
4
|
+
import { TransactionType as T } from "../types/Transaction.es.js";
|
|
5
|
+
import { TABLE_CONST as f } from "../constants/Table.es.js";
|
|
6
|
+
import { COLUMN_NAMES as S, DEFAULT_TRANSACTION as w } from "../constants/Transaction.es.js";
|
|
7
|
+
import { buildDetailedTransactions as m, flattenTransactionsWithSplits as y, sortAndFilterTransactions as L } from "../utils/TransactionUtils.es.js";
|
|
8
|
+
import { endOfMonth as E } from "date-fns/endOfMonth";
|
|
9
|
+
import { isBefore as b } from "date-fns/isBefore";
|
|
9
10
|
import { startOfMonth as h } from "date-fns/startOfMonth";
|
|
10
|
-
import { startOfToday as
|
|
11
|
+
import { startOfToday as x } from "date-fns/startOfToday";
|
|
11
12
|
import { endOfToday as l } from "date-fns/endOfToday";
|
|
12
|
-
import { subDays as
|
|
13
|
+
import { subDays as D } from "date-fns/subDays";
|
|
13
14
|
import { makeAutoObservable as u, runInAction as o } from "mobx";
|
|
14
15
|
import { getUnixTime as c } from "date-fns/getUnixTime";
|
|
15
|
-
import { formatISO as
|
|
16
|
-
var
|
|
16
|
+
import { formatISO as A } from "date-fns/formatISO";
|
|
17
|
+
var j = class {
|
|
17
18
|
globalStore;
|
|
18
19
|
uiStore;
|
|
19
20
|
api = new g("/", "");
|
|
@@ -34,14 +35,14 @@ var z = class {
|
|
|
34
35
|
transactionRulesLoaded = !1;
|
|
35
36
|
transactionRulesLoading = !1;
|
|
36
37
|
transactionSplitting = !1;
|
|
37
|
-
cachedStartDate = x(
|
|
38
|
+
cachedStartDate = D(x(), 90);
|
|
38
39
|
filter = {};
|
|
39
40
|
isLoading = !0;
|
|
40
41
|
alert = "";
|
|
41
|
-
sortColumn =
|
|
42
|
-
sortDirection =
|
|
42
|
+
sortColumn = S.DATE;
|
|
43
|
+
sortDirection = f.DESC;
|
|
43
44
|
constructor(t) {
|
|
44
|
-
this.globalStore = t, this.uiStore = new
|
|
45
|
+
this.globalStore = t, this.uiStore = new R(), this.api = new g(t.endpoint, t.sessionToken, t.onError), this.beatApi = new d(t.endpoint, t.sessionToken, t.onError), u(this);
|
|
45
46
|
}
|
|
46
47
|
loadTransactionData = async () => {
|
|
47
48
|
this.globalStore.accountStore.isAccountDataLoaded || await this.globalStore.accountStore.loadAccountData(), this.globalStore.categoryStore.categoriesLoaded || await this.globalStore.categoryStore.loadCategories(), await Promise.all([
|
|
@@ -56,13 +57,13 @@ var z = class {
|
|
|
56
57
|
return this.associatedBeatsLoaded && this.tagsLoaded && this.taggingsLoaded && this.transactionRulesLoaded && this.transactionsLoaded;
|
|
57
58
|
}
|
|
58
59
|
get detailedTransactions() {
|
|
59
|
-
return this.isTransactionDataLoaded ?
|
|
60
|
+
return this.isTransactionDataLoaded ? m(this.transactions, this.globalStore.accountStore.visibleAccounts, this.globalStore.categoryStore.categories, this.taggings) : [];
|
|
60
61
|
}
|
|
61
62
|
get sortedTransactions() {
|
|
62
|
-
return
|
|
63
|
+
return L(this.filter, this.uiStore.expandedSplits, this.sortColumn, this.sortDirection, this.tags, this.detailedTransactions);
|
|
63
64
|
}
|
|
64
65
|
get sortedTransactionsWithSplits() {
|
|
65
|
-
return
|
|
66
|
+
return y(this.sortedTransactions, this.detailedTransactions);
|
|
66
67
|
}
|
|
67
68
|
setAssociatedBeats = (t) => {
|
|
68
69
|
this.associatedBeats = t, this.associatedBeatsLoading = !1, this.associatedBeatsLoaded = !0;
|
|
@@ -118,11 +119,11 @@ var z = class {
|
|
|
118
119
|
addTransaction = async (t) => {
|
|
119
120
|
try {
|
|
120
121
|
const a = await this.api.addTransaction(t);
|
|
121
|
-
|
|
122
|
-
this.setTransactions(
|
|
123
|
-
const s = a.transaction_type ===
|
|
122
|
+
a && o(() => {
|
|
123
|
+
this.setTransactions(p(this.transactions, a, !0));
|
|
124
|
+
const s = a.transaction_type === T.CREDIT ? a.amount : -a.amount;
|
|
124
125
|
this.globalStore.accountStore.updateAccountBalance(a.account_guid, s);
|
|
125
|
-
}
|
|
126
|
+
});
|
|
126
127
|
} catch (a) {
|
|
127
128
|
console.error("Error occurred while adding transaction:", a), this.globalStore.captureException(a, { store: "TransactionStore" });
|
|
128
129
|
}
|
|
@@ -130,7 +131,7 @@ var z = class {
|
|
|
130
131
|
loadAssociatedBeats = async (t) => {
|
|
131
132
|
if (this.associatedBeatsLoading) return;
|
|
132
133
|
this.associatedBeatsLoading = !0;
|
|
133
|
-
const a = t ?
|
|
134
|
+
const a = t ? A(t, { representation: "date" }) : void 0;
|
|
134
135
|
try {
|
|
135
136
|
const s = await this.beatApi.getBeatsWithAssociatedTransaction(a);
|
|
136
137
|
this.setAssociatedBeats(s);
|
|
@@ -237,7 +238,7 @@ var z = class {
|
|
|
237
238
|
}
|
|
238
239
|
};
|
|
239
240
|
setFilter = (t) => {
|
|
240
|
-
this.filter = t, t.dateRange &&
|
|
241
|
+
this.filter = t, t.dateRange && b(t.dateRange.start, this.cachedStartDate) && this.loadTransactions(t.dateRange.start);
|
|
241
242
|
};
|
|
242
243
|
setIsLoading = (t) => this.isLoading = t;
|
|
243
244
|
splitTransaction = async (t, a) => {
|
|
@@ -325,16 +326,16 @@ var z = class {
|
|
|
325
326
|
console.error("Error occurred while loading embedded instance transactions:", a), this.globalStore.captureException(a, { store: "TransactionStore" });
|
|
326
327
|
}
|
|
327
328
|
};
|
|
328
|
-
},
|
|
329
|
+
}, R = class {
|
|
329
330
|
beginDate = h(/* @__PURE__ */ new Date());
|
|
330
|
-
endDate =
|
|
331
|
+
endDate = E(/* @__PURE__ */ new Date());
|
|
331
332
|
expandedSplits = [];
|
|
332
333
|
height = 550;
|
|
333
334
|
width = 1e3;
|
|
334
335
|
shouldDisableDrawerScroll = !1;
|
|
335
336
|
searchValue = "";
|
|
336
337
|
selectedAccountGuids = [];
|
|
337
|
-
manualTransaction =
|
|
338
|
+
manualTransaction = w;
|
|
338
339
|
isAmountValid = !1;
|
|
339
340
|
showInsights = !1;
|
|
340
341
|
constructor() {
|
|
@@ -365,8 +366,8 @@ var z = class {
|
|
|
365
366
|
};
|
|
366
367
|
};
|
|
367
368
|
export {
|
|
368
|
-
|
|
369
|
-
|
|
369
|
+
j as TransactionStore,
|
|
370
|
+
R as UiStore
|
|
370
371
|
};
|
|
371
372
|
|
|
372
373
|
//# sourceMappingURL=TransactionStore.es.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TransactionStore.es.js","names":[],"sources":["../../../src/core/stores/TransactionStore.ts"],"sourcesContent":["import { makeAutoObservable, runInAction } from 'mobx'\nimport { endOfMonth } from 'date-fns/endOfMonth'\nimport { endOfToday } from 'date-fns/endOfToday'\nimport { formatISO } from 'date-fns/formatISO'\nimport { getUnixTime } from 'date-fns/getUnixTime'\nimport { isBefore } from 'date-fns/isBefore'\nimport { startOfMonth } from 'date-fns/startOfMonth'\nimport { startOfToday } from 'date-fns/startOfToday'\nimport { subDays } from 'date-fns/subDays'\n\nimport { BeatApi, TransactionApi } from '../api'\nimport { TABLE_CONST } from '../constants/Table'\nimport { COLUMN_NAMES, DEFAULT_TRANSACTION } from '../constants/Transaction'\nimport { TransactionType } from '../types'\nimport type { Beat, Tag, Tagging, Transaction, TransactionRule } from '../types'\nimport {\n buildDetailedTransactions,\n flattenTransactionsWithSplits,\n sortAndFilterTransactions,\n} from '../utils/TransactionUtils'\n\nimport { GlobalStore } from './GlobalStore'\n\nexport type TransactionFilter = {\n accounts?: string[]\n dateRange?: { start: Date; end: Date }\n custom?: (value: Transaction) => boolean\n searchTerm?: string\n showSplits?: boolean\n}\n\nexport class TransactionStore {\n globalStore: GlobalStore\n uiStore: UiStore\n api = new TransactionApi('/', '')\n beatApi = new BeatApi('/', '')\n\n associatedBeats: Beat[] = []\n associatedBeatsLoaded: boolean = false\n associatedBeatsLoading: boolean = false\n transactions: Transaction[] = []\n transactionsLoaded: boolean = false\n transactionsLoading: boolean = false\n taggings: Tagging[] = []\n taggingsLoaded: boolean = false\n taggingsLoading: boolean = false\n tags: Tag[] = []\n tagsLoaded: boolean = false\n tagsLoading: boolean = false\n transactionRules: TransactionRule[] = []\n transactionRulesLoaded: boolean = false\n transactionRulesLoading: boolean = false\n transactionSplitting: boolean = false\n\n cachedStartDate: Date = subDays(startOfToday(), 90)\n filter: TransactionFilter = {}\n isLoading = true\n\n alert = ''\n\n sortColumn = COLUMN_NAMES.DATE\n sortDirection = TABLE_CONST.DESC\n\n constructor(globalStore: GlobalStore) {\n this.globalStore = globalStore\n this.uiStore = new UiStore()\n this.api = new TransactionApi(\n globalStore.endpoint,\n globalStore.sessionToken,\n globalStore.onError,\n )\n this.beatApi = new BeatApi(globalStore.endpoint, globalStore.sessionToken, globalStore.onError)\n\n makeAutoObservable(this)\n }\n\n loadTransactionData = async () => {\n if (!this.globalStore.accountStore.isAccountDataLoaded) {\n await this.globalStore.accountStore.loadAccountData()\n }\n if (!this.globalStore.categoryStore.categoriesLoaded) {\n await this.globalStore.categoryStore.loadCategories()\n }\n await Promise.all([\n this.loadAssociatedBeats(startOfMonth(new Date())),\n this.loadTags(),\n this.loadTaggings(),\n this.loadTransactionRules(),\n // By default loads 90 days of transactions\n this.loadTransactions(this.cachedStartDate),\n ])\n }\n\n get isTransactionDataLoaded(): boolean {\n return (\n this.associatedBeatsLoaded &&\n this.tagsLoaded &&\n this.taggingsLoaded &&\n this.transactionRulesLoaded &&\n this.transactionsLoaded\n )\n }\n\n get detailedTransactions(): Transaction[] {\n return this.isTransactionDataLoaded\n ? buildDetailedTransactions(\n this.transactions,\n this.globalStore.accountStore.visibleAccounts,\n this.globalStore.categoryStore.categories,\n this.taggings,\n )\n : []\n }\n\n get sortedTransactions(): Transaction[] {\n return sortAndFilterTransactions(\n this.filter,\n this.uiStore.expandedSplits,\n this.sortColumn,\n this.sortDirection,\n this.tags,\n this.detailedTransactions,\n )\n }\n\n get sortedTransactionsWithSplits(): Transaction[] {\n return flattenTransactionsWithSplits(this.sortedTransactions, this.detailedTransactions)\n }\n\n setAssociatedBeats = (beats: Beat[]) => {\n this.associatedBeats = beats\n this.associatedBeatsLoading = false\n this.associatedBeatsLoaded = true\n }\n\n setTaggings = (taggings: Tagging[]) => {\n this.taggings = taggings\n this.taggingsLoading = false\n this.taggingsLoaded = true\n }\n\n setTags = (tags: Tag[]) => {\n this.tags = tags\n this.tagsLoading = false\n this.tagsLoaded = true\n }\n\n setTransactionRules = (transactionRules: TransactionRule[]) => {\n this.transactionRules = transactionRules\n this.transactionRulesLoading = false\n this.transactionRulesLoaded = true\n }\n\n setTransactions = (transactions: Transaction[]) => {\n this.transactions = transactions\n this.transactionsLoading = false\n this.transactionsLoaded = true\n }\n\n setAlert = (alert: string) => {\n this.alert = alert\n }\n\n addTag = async (name: string) => {\n try {\n await this.api.addTag({ name } as Tag)\n await this.loadTags()\n } catch (error) {\n console.error('Error occurred while adding tag:', error)\n this.globalStore.captureException(error, { store: 'TransactionStore' })\n }\n }\n\n addTagging = async (tagGuid: string, transactionGuid: string) => {\n try {\n await this.api.addTagging({\n tag_guid: tagGuid,\n transaction_guid: transactionGuid,\n } as Tagging)\n } catch (error) {\n console.error('Error occurred while adding tagging:', error)\n this.globalStore.captureException(error, { store: 'TransactionStore' })\n }\n }\n\n addOrUpdateTransactionRule = async (categoryGuid: string, transaction: Transaction) => {\n try {\n const existingRule = this.transactionRules.find(\n (rule: TransactionRule) => rule.guid === transaction.user_transaction_rule_guid,\n ) as TransactionRule | undefined\n\n if (existingRule) {\n await this.api.updateTransactionRule({\n ...existingRule,\n category_guid: categoryGuid,\n description: transaction.description,\n } as TransactionRule)\n } else {\n await this.api.addTransactionRule({\n category_guid: categoryGuid,\n description: transaction.description,\n match_description: transaction.description,\n } as TransactionRule)\n }\n await this.loadTransactionRules()\n } catch (error) {\n console.error('Error occurred while adding/updating transaction rule:', error)\n this.globalStore.captureException(error, { store: 'TransactionStore' })\n }\n }\n\n addTransaction = async (transaction: Transaction) => {\n try {\n const newTransaction = await this.api.addTransaction(transaction)\n\n if (newTransaction) {\n this.setTransactions([newTransaction, ...this.transactions])\n\n // Update the related account balance\n const balanceChange =\n newTransaction.transaction_type === TransactionType.CREDIT\n ? newTransaction.amount\n : -newTransaction.amount\n\n this.globalStore.accountStore.updateAccountBalance(\n newTransaction.account_guid,\n balanceChange,\n )\n }\n } catch (error) {\n console.error('Error occurred while adding transaction:', error)\n this.globalStore.captureException(error, { store: 'TransactionStore' })\n }\n }\n\n loadAssociatedBeats = async (fromDate?: Date) => {\n if (this.associatedBeatsLoading) return\n\n this.associatedBeatsLoading = true\n const fromDateISO = fromDate ? formatISO(fromDate, { representation: 'date' }) : undefined\n try {\n const beats = await this.beatApi.getBeatsWithAssociatedTransaction(fromDateISO)\n this.setAssociatedBeats(beats)\n } catch (error) {\n console.error('Error occurred while loading associated beats:', error)\n this.globalStore.captureException(error, { store: 'TransactionStore' })\n this.setAssociatedBeats([])\n } finally {\n // Clear the in-flight flag even on failure so a later load (e.g. a widget\n // remount) can retry instead of being no-oped by the guard above, which would\n // leave isTransactionDataLoaded false and the list empty until a hard refresh.\n runInAction(() => {\n this.associatedBeatsLoading = false\n })\n }\n }\n\n loadTags = async () => {\n if (this.tagsLoading) return\n\n this.tagsLoading = true\n try {\n const tags = await this.api.getTags()\n this.setTags(tags)\n } catch (error) {\n console.error('Error occurred while loading tags:', error)\n this.globalStore.captureException(error, { store: 'TransactionStore' })\n } finally {\n runInAction(() => {\n this.tagsLoading = false\n })\n }\n }\n\n loadTaggings = async () => {\n if (this.taggingsLoading) return\n\n this.taggingsLoading = true\n try {\n const taggings = await this.api.getTaggings()\n this.setTaggings(taggings)\n } catch (error) {\n console.error('Error occurred while loading taggings:', error)\n this.globalStore.captureException(error, { store: 'TransactionStore' })\n this.setTaggings([])\n } finally {\n runInAction(() => {\n this.taggingsLoading = false\n })\n }\n }\n\n loadTransactionRules = async () => {\n if (this.transactionRulesLoading) return\n\n this.transactionRulesLoading = true\n try {\n const transactionRules = await this.api.getTransactionRules()\n this.setTransactionRules(transactionRules)\n } catch (error) {\n // Catch so a rejection can't abort the Promise.all in loadTransactionData.\n console.error('Error occurred while loading transaction rules:', error)\n this.globalStore.captureException(error, { store: 'TransactionStore' })\n this.setTransactionRules([])\n } finally {\n runInAction(() => {\n this.transactionRulesLoading = false\n })\n }\n }\n\n loadTransactions = async (startDate: Date = this.cachedStartDate) => {\n if (this.transactionsLoading) return\n\n this.setIsLoading(true)\n this.transactionsLoading = true\n\n try {\n const transactions = await this.api.getTransactionsByDateRange(\n getUnixTime(startDate),\n getUnixTime(endOfToday()),\n )\n this.setTransactions(transactions)\n // Advance the cache only after the range is actually loaded, so the invariant\n // \"we hold transactions back to cachedStartDate\" always holds.\n runInAction(() => {\n this.cachedStartDate = startDate\n })\n } catch (error) {\n console.error('Error occurred while loading transactions:', error)\n this.globalStore.captureException(error, { store: 'TransactionStore' })\n } finally {\n // See loadAssociatedBeats: clear the flag on failure so retries aren't no-oped.\n runInAction(() => {\n this.transactionsLoading = false\n })\n this.setIsLoading(false)\n }\n }\n\n modifyTransactionByAccountGuid = (guid: string, updates: Partial<Transaction>) => {\n this.transactions = this.transactions.map((txn) =>\n txn.account_guid === guid ? { ...txn, ...updates } : txn,\n )\n }\n\n removeTag = async (tagGuid: string) => {\n try {\n await this.api.removeTag(tagGuid)\n await this.loadTags()\n } catch (error) {\n console.error('Error occurred while removing tag:', error)\n this.globalStore.captureException(error, { store: 'TransactionStore' })\n }\n }\n\n removeTagging = async (taggingGuid: string) => {\n try {\n await this.api.removeTagging(taggingGuid)\n } catch (error) {\n console.error('Error occurred while removing tagging:', error)\n this.globalStore.captureException(error, { store: 'TransactionStore' })\n }\n }\n\n removeTransaction = async (transactionGuid: string) => {\n try {\n await this.api.removeTransaction(transactionGuid)\n\n const index = this.transactions.findIndex((t: Transaction) => t.guid === transactionGuid)\n\n if (index >= 0) {\n const updatedTransactions = [...this.transactions]\n updatedTransactions.splice(index, 1)\n this.setTransactions(updatedTransactions)\n }\n } catch (error) {\n console.error('Error occurred while removing transaction:', error)\n this.globalStore.captureException(error, { store: 'TransactionStore' })\n }\n }\n\n setFilter = (filter: TransactionFilter) => {\n this.filter = filter\n\n // Only reload if the new start date is prior to the cached start date; end date\n // is always today. loadTransactions advances cachedStartDate on success, so we\n // must not advance it here (a skipped/failed load would leave the list empty).\n if (filter.dateRange && isBefore(filter.dateRange.start, this.cachedStartDate)) {\n this.loadTransactions(filter.dateRange.start)\n }\n }\n\n setIsLoading = (isLoading: boolean) => (this.isLoading = isLoading)\n\n splitTransaction = async (transaction: Transaction, splits: Transaction[]) => {\n if (this.transactionSplitting) return\n this.transactionSplitting = true\n\n try {\n const updatedTransaction = await this.api.updateTransaction(transaction)\n const children = [] as Transaction[]\n\n for (let i = 0; i < splits.length; i++) {\n const child = await this.api.addTransaction(splits[i])\n children.push(child)\n }\n\n const index = this.transactions.findIndex((t: Transaction) => t.guid === transaction.guid)\n\n if (index >= 0) {\n // Remove old parent and any existing children\n const filtered = this.transactions.filter(\n (t) => t.guid !== transaction.guid && t.parent_guid !== transaction.guid,\n )\n\n // Insert updated parent + new children at original position\n this.setTransactions([\n ...filtered.slice(0, index),\n updatedTransaction,\n ...children,\n ...filtered.slice(index),\n ])\n }\n } catch (error) {\n console.error('Error occurred while splitting transaction:', error)\n this.globalStore.captureException(error, { store: 'TransactionStore' })\n throw error\n } finally {\n this.transactionSplitting = false\n }\n }\n\n unSplitTransaction = async (guid: string) => {\n try {\n const children = this.transactions.filter((t) => t.parent_guid === guid)\n\n await this.api.removeTransactionSplit(guid)\n\n // Remove children\n const transactions = [...this.transactions]\n children.forEach((child) => {\n const index = transactions.findIndex((t) => t.guid === child.guid)\n\n if (index >= 0) {\n transactions.splice(index, 1)\n }\n })\n\n // Update parent\n const index = transactions.findIndex((t) => t.guid === guid)\n\n runInAction(() => {\n const transaction = transactions[index]\n if (transaction) {\n transaction.has_been_split = false\n }\n\n if (index >= 0) {\n this.setTransactions([\n ...transactions.slice(0, index),\n transaction,\n ...transactions.slice(index + 1),\n ])\n }\n })\n } catch (error) {\n console.error('Error occurred while unsplitting transaction:', error)\n this.globalStore.captureException(error, { store: 'TransactionStore' })\n }\n }\n\n updateTaggings = async (tagGuids: string[], transactionGuid: string) => {\n try {\n const currentTaggings = this.taggings.filter((t) => t.transaction_guid === transactionGuid)\n\n const currentTagGuids = new Set(currentTaggings.map((t) => t.tag_guid))\n const incomingTagGuids = new Set(tagGuids)\n\n // Add new taggings that don't already exist\n for (const tagGuid of tagGuids) {\n if (!currentTagGuids.has(tagGuid)) {\n await this.addTagging(tagGuid, transactionGuid)\n }\n }\n\n // Remove taggings that are no longer needed\n for (const tagging of currentTaggings) {\n if (!incomingTagGuids.has(tagging.tag_guid)) {\n await this.removeTagging(tagging.guid)\n }\n }\n\n await this.loadTaggings()\n } catch (error) {\n console.error('Error occurred while updating taggings:', error)\n this.globalStore.captureException(error, { store: 'TransactionStore' })\n }\n }\n\n updateTag = async (tag: Tag) => {\n try {\n await this.api.updateTag(tag)\n await this.loadTags()\n } catch (error) {\n console.error('Error occurred while updating tag:', error)\n this.globalStore.captureException(error, { store: 'TransactionStore' })\n }\n }\n\n updateTransaction = async (transaction: Transaction) => {\n try {\n const updatedTransaction = await this.api.updateTransaction(transaction)\n\n const index = this.transactions.findIndex((t: Transaction) => t.guid === transaction.guid)\n\n if (index >= 0) {\n this.setTransactions([\n ...this.transactions.slice(0, index),\n updatedTransaction,\n ...this.transactions.slice(index + 1),\n ])\n }\n } catch (error) {\n console.error('Error occurred while updating transaction:', error)\n this.globalStore.captureException(error, { store: 'TransactionStore' })\n }\n }\n\n // This is used for loading the transactions list on demand, on clicking the different transactions of the insightful beats.\n loadEmbeddedInstanceTransactions = async (fromDate: Date) => {\n try {\n const transactions = await this.api.getTransactionsByDateRange(\n getUnixTime(fromDate),\n getUnixTime(endOfToday()),\n )\n this.cachedStartDate = fromDate\n this.transactions = transactions\n } catch (error) {\n console.error('Error occurred while loading embedded instance transactions:', error)\n this.globalStore.captureException(error, { store: 'TransactionStore' })\n }\n }\n}\n\nexport class UiStore {\n beginDate = startOfMonth(new Date())\n endDate = endOfMonth(new Date())\n\n expandedSplits = [] as string[]\n height = 550\n width = 1000\n shouldDisableDrawerScroll = false\n\n searchValue = ''\n selectedAccountGuids = [] as string[]\n\n manualTransaction: Transaction = DEFAULT_TRANSACTION\n isAmountValid = false\n\n showInsights = false\n\n constructor() {\n makeAutoObservable(this)\n }\n\n setDateRange = (beginDate: Date, endDate: Date) => {\n this.beginDate = beginDate\n this.endDate = endDate\n }\n\n setIsAmountValid = (valid: boolean) => (this.isAmountValid = valid)\n\n setSearchValue = (searchValue: string) => (this.searchValue = searchValue)\n\n setSelectedAccountGuids = (accountGuids: string[]) => (this.selectedAccountGuids = accountGuids)\n\n setShouldDisableDrawerScroll = (shouldDisable: boolean) =>\n (this.shouldDisableDrawerScroll = shouldDisable)\n\n setShowInsights = (showInsights: boolean) => {\n this.showInsights = showInsights\n }\n\n setSize = (height: number, width: number) => {\n this.height = height\n this.width = width\n }\n\n toggleSplit = (guid: string) => {\n const expandedSplits = [...this.expandedSplits]\n const index = this.expandedSplits.findIndex((splitGuid) => splitGuid === guid)\n\n if (index >= 0) {\n expandedSplits.splice(index, 1)\n } else {\n expandedSplits.push(guid)\n }\n\n this.expandedSplits = expandedSplits\n }\n\n clearExpandedSplits = () => {\n if (this.expandedSplits.length === 0) return\n this.expandedSplits = []\n }\n\n updateManualTransaction = (manualTransaction: Transaction) => {\n this.manualTransaction = manualTransaction\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"TransactionStore.es.js","names":[],"sources":["../../../src/core/stores/TransactionStore.ts"],"sourcesContent":["import { makeAutoObservable, runInAction } from 'mobx'\nimport { endOfMonth } from 'date-fns/endOfMonth'\nimport { endOfToday } from 'date-fns/endOfToday'\nimport { formatISO } from 'date-fns/formatISO'\nimport { getUnixTime } from 'date-fns/getUnixTime'\nimport { isBefore } from 'date-fns/isBefore'\nimport { startOfMonth } from 'date-fns/startOfMonth'\nimport { startOfToday } from 'date-fns/startOfToday'\nimport { subDays } from 'date-fns/subDays'\n\nimport { BeatApi, TransactionApi } from '../api'\nimport { TABLE_CONST } from '../constants/Table'\nimport { COLUMN_NAMES, DEFAULT_TRANSACTION } from '../constants/Transaction'\nimport { TransactionType } from '../types'\nimport type { Beat, Tag, Tagging, Transaction, TransactionRule } from '../types'\nimport {\n buildDetailedTransactions,\n flattenTransactionsWithSplits,\n sortAndFilterTransactions,\n} from '../utils/TransactionUtils'\n\nimport { GlobalStore } from './GlobalStore'\nimport { upsertByGuid } from '../utils/upsertByGuid'\n\nexport type TransactionFilter = {\n accounts?: string[]\n dateRange?: { start: Date; end: Date }\n custom?: (value: Transaction) => boolean\n searchTerm?: string\n showSplits?: boolean\n}\n\nexport class TransactionStore {\n globalStore: GlobalStore\n uiStore: UiStore\n api = new TransactionApi('/', '')\n beatApi = new BeatApi('/', '')\n\n associatedBeats: Beat[] = []\n associatedBeatsLoaded: boolean = false\n associatedBeatsLoading: boolean = false\n transactions: Transaction[] = []\n transactionsLoaded: boolean = false\n transactionsLoading: boolean = false\n taggings: Tagging[] = []\n taggingsLoaded: boolean = false\n taggingsLoading: boolean = false\n tags: Tag[] = []\n tagsLoaded: boolean = false\n tagsLoading: boolean = false\n transactionRules: TransactionRule[] = []\n transactionRulesLoaded: boolean = false\n transactionRulesLoading: boolean = false\n transactionSplitting: boolean = false\n\n cachedStartDate: Date = subDays(startOfToday(), 90)\n filter: TransactionFilter = {}\n isLoading = true\n\n alert = ''\n\n sortColumn = COLUMN_NAMES.DATE\n sortDirection = TABLE_CONST.DESC\n\n constructor(globalStore: GlobalStore) {\n this.globalStore = globalStore\n this.uiStore = new UiStore()\n this.api = new TransactionApi(\n globalStore.endpoint,\n globalStore.sessionToken,\n globalStore.onError,\n )\n this.beatApi = new BeatApi(globalStore.endpoint, globalStore.sessionToken, globalStore.onError)\n\n makeAutoObservable(this)\n }\n\n loadTransactionData = async () => {\n if (!this.globalStore.accountStore.isAccountDataLoaded) {\n await this.globalStore.accountStore.loadAccountData()\n }\n if (!this.globalStore.categoryStore.categoriesLoaded) {\n await this.globalStore.categoryStore.loadCategories()\n }\n await Promise.all([\n this.loadAssociatedBeats(startOfMonth(new Date())),\n this.loadTags(),\n this.loadTaggings(),\n this.loadTransactionRules(),\n // By default loads 90 days of transactions\n this.loadTransactions(this.cachedStartDate),\n ])\n }\n\n get isTransactionDataLoaded(): boolean {\n return (\n this.associatedBeatsLoaded &&\n this.tagsLoaded &&\n this.taggingsLoaded &&\n this.transactionRulesLoaded &&\n this.transactionsLoaded\n )\n }\n\n get detailedTransactions(): Transaction[] {\n return this.isTransactionDataLoaded\n ? buildDetailedTransactions(\n this.transactions,\n this.globalStore.accountStore.visibleAccounts,\n this.globalStore.categoryStore.categories,\n this.taggings,\n )\n : []\n }\n\n get sortedTransactions(): Transaction[] {\n return sortAndFilterTransactions(\n this.filter,\n this.uiStore.expandedSplits,\n this.sortColumn,\n this.sortDirection,\n this.tags,\n this.detailedTransactions,\n )\n }\n\n get sortedTransactionsWithSplits(): Transaction[] {\n return flattenTransactionsWithSplits(this.sortedTransactions, this.detailedTransactions)\n }\n\n setAssociatedBeats = (beats: Beat[]) => {\n this.associatedBeats = beats\n this.associatedBeatsLoading = false\n this.associatedBeatsLoaded = true\n }\n\n setTaggings = (taggings: Tagging[]) => {\n this.taggings = taggings\n this.taggingsLoading = false\n this.taggingsLoaded = true\n }\n\n setTags = (tags: Tag[]) => {\n this.tags = tags\n this.tagsLoading = false\n this.tagsLoaded = true\n }\n\n setTransactionRules = (transactionRules: TransactionRule[]) => {\n this.transactionRules = transactionRules\n this.transactionRulesLoading = false\n this.transactionRulesLoaded = true\n }\n\n setTransactions = (transactions: Transaction[]) => {\n this.transactions = transactions\n this.transactionsLoading = false\n this.transactionsLoaded = true\n }\n\n setAlert = (alert: string) => {\n this.alert = alert\n }\n\n addTag = async (name: string) => {\n try {\n await this.api.addTag({ name } as Tag)\n await this.loadTags()\n } catch (error) {\n console.error('Error occurred while adding tag:', error)\n this.globalStore.captureException(error, { store: 'TransactionStore' })\n }\n }\n\n addTagging = async (tagGuid: string, transactionGuid: string) => {\n try {\n await this.api.addTagging({\n tag_guid: tagGuid,\n transaction_guid: transactionGuid,\n } as Tagging)\n } catch (error) {\n console.error('Error occurred while adding tagging:', error)\n this.globalStore.captureException(error, { store: 'TransactionStore' })\n }\n }\n\n addOrUpdateTransactionRule = async (categoryGuid: string, transaction: Transaction) => {\n try {\n const existingRule = this.transactionRules.find(\n (rule: TransactionRule) => rule.guid === transaction.user_transaction_rule_guid,\n ) as TransactionRule | undefined\n\n if (existingRule) {\n await this.api.updateTransactionRule({\n ...existingRule,\n category_guid: categoryGuid,\n description: transaction.description,\n } as TransactionRule)\n } else {\n await this.api.addTransactionRule({\n category_guid: categoryGuid,\n description: transaction.description,\n match_description: transaction.description,\n } as TransactionRule)\n }\n await this.loadTransactionRules()\n } catch (error) {\n console.error('Error occurred while adding/updating transaction rule:', error)\n this.globalStore.captureException(error, { store: 'TransactionStore' })\n }\n }\n\n addTransaction = async (transaction: Transaction) => {\n try {\n const newTransaction = await this.api.addTransaction(transaction)\n\n if (newTransaction) {\n runInAction(() => {\n this.setTransactions(upsertByGuid(this.transactions, newTransaction, true))\n\n // Brokaw may insert the transaction via WebSocket, but it never\n // updates the account balance — that only happens here.\n // See: money-dashboard/src/util/BrokawClient.ts::handleTransactionEvents (search \"setTransactions\")\n // If that handler ever calls updateAccountBalance, remove this call or guard on !existing.\n const balanceChange =\n newTransaction.transaction_type === TransactionType.CREDIT\n ? newTransaction.amount\n : -newTransaction.amount\n\n this.globalStore.accountStore.updateAccountBalance(\n newTransaction.account_guid,\n balanceChange,\n )\n })\n }\n } catch (error) {\n console.error('Error occurred while adding transaction:', error)\n this.globalStore.captureException(error, { store: 'TransactionStore' })\n }\n }\n\n loadAssociatedBeats = async (fromDate?: Date) => {\n if (this.associatedBeatsLoading) return\n\n this.associatedBeatsLoading = true\n const fromDateISO = fromDate ? formatISO(fromDate, { representation: 'date' }) : undefined\n try {\n const beats = await this.beatApi.getBeatsWithAssociatedTransaction(fromDateISO)\n this.setAssociatedBeats(beats)\n } catch (error) {\n console.error('Error occurred while loading associated beats:', error)\n this.globalStore.captureException(error, { store: 'TransactionStore' })\n this.setAssociatedBeats([])\n } finally {\n // Clear the in-flight flag even on failure so a later load (e.g. a widget\n // remount) can retry instead of being no-oped by the guard above, which would\n // leave isTransactionDataLoaded false and the list empty until a hard refresh.\n runInAction(() => {\n this.associatedBeatsLoading = false\n })\n }\n }\n\n loadTags = async () => {\n if (this.tagsLoading) return\n\n this.tagsLoading = true\n try {\n const tags = await this.api.getTags()\n this.setTags(tags)\n } catch (error) {\n console.error('Error occurred while loading tags:', error)\n this.globalStore.captureException(error, { store: 'TransactionStore' })\n } finally {\n runInAction(() => {\n this.tagsLoading = false\n })\n }\n }\n\n loadTaggings = async () => {\n if (this.taggingsLoading) return\n\n this.taggingsLoading = true\n try {\n const taggings = await this.api.getTaggings()\n this.setTaggings(taggings)\n } catch (error) {\n console.error('Error occurred while loading taggings:', error)\n this.globalStore.captureException(error, { store: 'TransactionStore' })\n this.setTaggings([])\n } finally {\n runInAction(() => {\n this.taggingsLoading = false\n })\n }\n }\n\n loadTransactionRules = async () => {\n if (this.transactionRulesLoading) return\n\n this.transactionRulesLoading = true\n try {\n const transactionRules = await this.api.getTransactionRules()\n this.setTransactionRules(transactionRules)\n } catch (error) {\n // Catch so a rejection can't abort the Promise.all in loadTransactionData.\n console.error('Error occurred while loading transaction rules:', error)\n this.globalStore.captureException(error, { store: 'TransactionStore' })\n this.setTransactionRules([])\n } finally {\n runInAction(() => {\n this.transactionRulesLoading = false\n })\n }\n }\n\n loadTransactions = async (startDate: Date = this.cachedStartDate) => {\n if (this.transactionsLoading) return\n\n this.setIsLoading(true)\n this.transactionsLoading = true\n\n try {\n const transactions = await this.api.getTransactionsByDateRange(\n getUnixTime(startDate),\n getUnixTime(endOfToday()),\n )\n this.setTransactions(transactions)\n // Advance the cache only after the range is actually loaded, so the invariant\n // \"we hold transactions back to cachedStartDate\" always holds.\n runInAction(() => {\n this.cachedStartDate = startDate\n })\n } catch (error) {\n console.error('Error occurred while loading transactions:', error)\n this.globalStore.captureException(error, { store: 'TransactionStore' })\n } finally {\n // See loadAssociatedBeats: clear the flag on failure so retries aren't no-oped.\n runInAction(() => {\n this.transactionsLoading = false\n })\n this.setIsLoading(false)\n }\n }\n\n modifyTransactionByAccountGuid = (guid: string, updates: Partial<Transaction>) => {\n this.transactions = this.transactions.map((txn) =>\n txn.account_guid === guid ? { ...txn, ...updates } : txn,\n )\n }\n\n removeTag = async (tagGuid: string) => {\n try {\n await this.api.removeTag(tagGuid)\n await this.loadTags()\n } catch (error) {\n console.error('Error occurred while removing tag:', error)\n this.globalStore.captureException(error, { store: 'TransactionStore' })\n }\n }\n\n removeTagging = async (taggingGuid: string) => {\n try {\n await this.api.removeTagging(taggingGuid)\n } catch (error) {\n console.error('Error occurred while removing tagging:', error)\n this.globalStore.captureException(error, { store: 'TransactionStore' })\n }\n }\n\n removeTransaction = async (transactionGuid: string) => {\n try {\n await this.api.removeTransaction(transactionGuid)\n\n const index = this.transactions.findIndex((t: Transaction) => t.guid === transactionGuid)\n\n if (index >= 0) {\n const updatedTransactions = [...this.transactions]\n updatedTransactions.splice(index, 1)\n this.setTransactions(updatedTransactions)\n }\n } catch (error) {\n console.error('Error occurred while removing transaction:', error)\n this.globalStore.captureException(error, { store: 'TransactionStore' })\n }\n }\n\n setFilter = (filter: TransactionFilter) => {\n this.filter = filter\n\n // Only reload if the new start date is prior to the cached start date; end date\n // is always today. loadTransactions advances cachedStartDate on success, so we\n // must not advance it here (a skipped/failed load would leave the list empty).\n if (filter.dateRange && isBefore(filter.dateRange.start, this.cachedStartDate)) {\n this.loadTransactions(filter.dateRange.start)\n }\n }\n\n setIsLoading = (isLoading: boolean) => (this.isLoading = isLoading)\n\n splitTransaction = async (transaction: Transaction, splits: Transaction[]) => {\n if (this.transactionSplitting) return\n this.transactionSplitting = true\n\n try {\n const updatedTransaction = await this.api.updateTransaction(transaction)\n const children = [] as Transaction[]\n\n for (let i = 0; i < splits.length; i++) {\n const child = await this.api.addTransaction(splits[i])\n children.push(child)\n }\n\n const index = this.transactions.findIndex((t: Transaction) => t.guid === transaction.guid)\n\n if (index >= 0) {\n // Remove old parent and any existing children\n const filtered = this.transactions.filter(\n (t) => t.guid !== transaction.guid && t.parent_guid !== transaction.guid,\n )\n\n // Insert updated parent + new children at original position\n this.setTransactions([\n ...filtered.slice(0, index),\n updatedTransaction,\n ...children,\n ...filtered.slice(index),\n ])\n }\n } catch (error) {\n console.error('Error occurred while splitting transaction:', error)\n this.globalStore.captureException(error, { store: 'TransactionStore' })\n throw error\n } finally {\n this.transactionSplitting = false\n }\n }\n\n unSplitTransaction = async (guid: string) => {\n try {\n const children = this.transactions.filter((t) => t.parent_guid === guid)\n\n await this.api.removeTransactionSplit(guid)\n\n // Remove children\n const transactions = [...this.transactions]\n children.forEach((child) => {\n const index = transactions.findIndex((t) => t.guid === child.guid)\n\n if (index >= 0) {\n transactions.splice(index, 1)\n }\n })\n\n // Update parent\n const index = transactions.findIndex((t) => t.guid === guid)\n\n runInAction(() => {\n const transaction = transactions[index]\n if (transaction) {\n transaction.has_been_split = false\n }\n\n if (index >= 0) {\n this.setTransactions([\n ...transactions.slice(0, index),\n transaction,\n ...transactions.slice(index + 1),\n ])\n }\n })\n } catch (error) {\n console.error('Error occurred while unsplitting transaction:', error)\n this.globalStore.captureException(error, { store: 'TransactionStore' })\n }\n }\n\n updateTaggings = async (tagGuids: string[], transactionGuid: string) => {\n try {\n const currentTaggings = this.taggings.filter((t) => t.transaction_guid === transactionGuid)\n\n const currentTagGuids = new Set(currentTaggings.map((t) => t.tag_guid))\n const incomingTagGuids = new Set(tagGuids)\n\n // Add new taggings that don't already exist\n for (const tagGuid of tagGuids) {\n if (!currentTagGuids.has(tagGuid)) {\n await this.addTagging(tagGuid, transactionGuid)\n }\n }\n\n // Remove taggings that are no longer needed\n for (const tagging of currentTaggings) {\n if (!incomingTagGuids.has(tagging.tag_guid)) {\n await this.removeTagging(tagging.guid)\n }\n }\n\n await this.loadTaggings()\n } catch (error) {\n console.error('Error occurred while updating taggings:', error)\n this.globalStore.captureException(error, { store: 'TransactionStore' })\n }\n }\n\n updateTag = async (tag: Tag) => {\n try {\n await this.api.updateTag(tag)\n await this.loadTags()\n } catch (error) {\n console.error('Error occurred while updating tag:', error)\n this.globalStore.captureException(error, { store: 'TransactionStore' })\n }\n }\n\n updateTransaction = async (transaction: Transaction) => {\n try {\n const updatedTransaction = await this.api.updateTransaction(transaction)\n\n const index = this.transactions.findIndex((t: Transaction) => t.guid === transaction.guid)\n\n if (index >= 0) {\n this.setTransactions([\n ...this.transactions.slice(0, index),\n updatedTransaction,\n ...this.transactions.slice(index + 1),\n ])\n }\n } catch (error) {\n console.error('Error occurred while updating transaction:', error)\n this.globalStore.captureException(error, { store: 'TransactionStore' })\n }\n }\n\n // This is used for loading the transactions list on demand, on clicking the different transactions of the insightful beats.\n loadEmbeddedInstanceTransactions = async (fromDate: Date) => {\n try {\n const transactions = await this.api.getTransactionsByDateRange(\n getUnixTime(fromDate),\n getUnixTime(endOfToday()),\n )\n this.cachedStartDate = fromDate\n this.transactions = transactions\n } catch (error) {\n console.error('Error occurred while loading embedded instance transactions:', error)\n this.globalStore.captureException(error, { store: 'TransactionStore' })\n }\n }\n}\n\nexport class UiStore {\n beginDate = startOfMonth(new Date())\n endDate = endOfMonth(new Date())\n\n expandedSplits = [] as string[]\n height = 550\n width = 1000\n shouldDisableDrawerScroll = false\n\n searchValue = ''\n selectedAccountGuids = [] as string[]\n\n manualTransaction: Transaction = DEFAULT_TRANSACTION\n isAmountValid = false\n\n showInsights = false\n\n constructor() {\n makeAutoObservable(this)\n }\n\n setDateRange = (beginDate: Date, endDate: Date) => {\n this.beginDate = beginDate\n this.endDate = endDate\n }\n\n setIsAmountValid = (valid: boolean) => (this.isAmountValid = valid)\n\n setSearchValue = (searchValue: string) => (this.searchValue = searchValue)\n\n setSelectedAccountGuids = (accountGuids: string[]) => (this.selectedAccountGuids = accountGuids)\n\n setShouldDisableDrawerScroll = (shouldDisable: boolean) =>\n (this.shouldDisableDrawerScroll = shouldDisable)\n\n setShowInsights = (showInsights: boolean) => {\n this.showInsights = showInsights\n }\n\n setSize = (height: number, width: number) => {\n this.height = height\n this.width = width\n }\n\n toggleSplit = (guid: string) => {\n const expandedSplits = [...this.expandedSplits]\n const index = this.expandedSplits.findIndex((splitGuid) => splitGuid === guid)\n\n if (index >= 0) {\n expandedSplits.splice(index, 1)\n } else {\n expandedSplits.push(guid)\n }\n\n this.expandedSplits = expandedSplits\n }\n\n clearExpandedSplits = () => {\n if (this.expandedSplits.length === 0) return\n this.expandedSplits = []\n }\n\n updateManualTransaction = (manualTransaction: Transaction) => {\n this.manualTransaction = manualTransaction\n }\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
var o = (u, r, n = !1) => {
|
|
2
|
+
if (!r.guid) return n ? [r, ...u] : [...u, r];
|
|
3
|
+
const d = u.findIndex((g) => g.guid === r.guid);
|
|
4
|
+
if (d < 0) return n ? [r, ...u] : [...u, r];
|
|
5
|
+
const f = [...u];
|
|
6
|
+
return f[d] = r, f;
|
|
7
|
+
};
|
|
8
|
+
export {
|
|
9
|
+
o as upsertByGuid
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
//# sourceMappingURL=upsertByGuid.es.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"upsertByGuid.es.js","names":[],"sources":["../../../src/core/utils/upsertByGuid.ts"],"sourcesContent":["export const upsertByGuid = <T extends { guid: string }>(\n list: readonly T[],\n item: T,\n prepend = false,\n): T[] => {\n if (!item.guid) {\n return prepend ? [item, ...list] : [...list, item]\n }\n\n const i = list.findIndex((x) => x.guid === item.guid)\n\n if (i < 0) return prepend ? [item, ...list] : [...list, item]\n\n const next = [...list]\n next[i] = item\n return next\n}\n"],"mappings":"AAAA,IAAa,IAAA,CACX,GACA,GACA,IAAU,OACF;AACR,MAAI,CAAC,EAAK,KACR,QAAO,IAAU,CAAC,GAAM,GAAG,CAAI,IAAI,CAAC,GAAG,GAAM,CAAI;AAGnD,QAAM,IAAI,EAAK,UAAA,CAAW,MAAM,EAAE,SAAS,EAAK,IAAI;AAEpD,MAAI,IAAI,EAAG,QAAO,IAAU,CAAC,GAAM,GAAG,CAAI,IAAI,CAAC,GAAG,GAAM,CAAI;AAE5D,QAAM,IAAO,CAAC,GAAG,CAAI;AACrB,SAAA,EAAK,CAAA,IAAK,GACH;AACT"}
|