@actual-app/api 25.1.0 → 25.2.1
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/@types/loot-core/client/constants.d.ts +0 -11
- package/@types/loot-core/client/state-types/index.d.ts +0 -14
- package/@types/loot-core/client/state-types/modals.d.ts +7 -2
- package/@types/loot-core/mocks/index.d.ts +9 -20
- package/@types/loot-core/platform/client/fetch/index.d.ts +10 -1
- package/@types/loot-core/platform/client/undo/index.d.ts +8 -4
- package/@types/loot-core/platform/server/connection/index.d.ts +1 -1
- package/@types/loot-core/server/accounts/sync.d.ts +1 -1
- package/@types/loot-core/server/accounts/transaction-rules.d.ts +0 -3
- package/@types/loot-core/server/accounts/transactions.d.ts +0 -3
- package/@types/loot-core/server/accounts/transfer.d.ts +0 -11
- package/@types/loot-core/server/admin/app.d.ts +9 -4
- package/@types/loot-core/server/admin/types/handlers.d.ts +4 -2
- package/@types/loot-core/server/app.d.ts +14 -4
- package/@types/loot-core/server/aql/compiler.d.ts +4 -6
- package/@types/loot-core/server/aql/schema/index.d.ts +3 -0
- package/@types/loot-core/server/budget/actions.d.ts +6 -0
- package/@types/loot-core/server/budget/app.d.ts +10 -5
- package/@types/loot-core/server/budget/types/handlers.d.ts +4 -0
- package/@types/loot-core/server/dashboard/app.d.ts +9 -4
- package/@types/loot-core/server/filters/app.d.ts +9 -4
- package/@types/loot-core/server/importers/ynab4-types.d.ts +0 -2
- package/@types/loot-core/server/importers/ynab5-types.d.ts +0 -2
- package/@types/loot-core/server/main-app.d.ts +10 -5
- package/@types/loot-core/server/main.d.ts +2 -2
- package/@types/loot-core/server/notes/app.d.ts +9 -4
- package/@types/loot-core/server/preferences/app.d.ts +9 -4
- package/@types/loot-core/server/reports/app.d.ts +11 -4
- package/@types/loot-core/server/rules/app.d.ts +9 -4
- package/@types/loot-core/server/rules/types/handlers.d.ts +4 -4
- package/@types/loot-core/server/schedules/app.d.ts +10 -7
- package/@types/loot-core/server/schedules/types/handlers.d.ts +5 -5
- package/@types/loot-core/server/tools/app.d.ts +9 -4
- package/@types/loot-core/server/tools/types/handlers.d.ts +2 -1
- package/@types/loot-core/shared/schedules.d.ts +5 -31
- package/@types/loot-core/shared/transactions.d.ts +101 -17
- package/@types/loot-core/shared/util.d.ts +23 -9
- package/@types/loot-core/types/api-handlers.d.ts +3 -0
- package/@types/loot-core/types/models/dashboard.d.ts +1 -1
- package/@types/loot-core/types/models/payee.d.ts +1 -0
- package/@types/loot-core/types/models/reports.d.ts +4 -0
- package/@types/loot-core/types/models/rule.d.ts +6 -4
- package/@types/loot-core/types/models/schedule.d.ts +5 -18
- package/@types/loot-core/types/models/simplefin.d.ts +2 -0
- package/@types/loot-core/types/models/transaction.d.ts +6 -0
- package/@types/loot-core/types/prefs.d.ts +3 -2
- package/@types/loot-core/types/server-events.d.ts +80 -17
- package/@types/loot-core/types/server-handlers.d.ts +19 -7
- package/@types/loot-core/types/util.d.ts +5 -0
- package/@types/methods.d.ts +4 -4
- package/dist/app/bundle.api.js +334 -187
- package/dist/methods.js +4 -1
- package/dist/migrations/1736640000000__custom_report_sorting.sql +7 -0
- package/dist/migrations/1737158400000_add_learn_categories_to_payees.sql +5 -0
- package/dist/migrations/1738491452000__sorting_rename.sql +13 -0
- package/dist/package.json +1 -1
- package/package.json +1 -1
- package/@types/loot-core/client/actions/types.d.ts +0 -6
- package/@types/loot-core/client/state-types/account.d.ts +0 -27
- package/@types/loot-core/client/state-types/app.d.ts +0 -42
- package/@types/loot-core/client/state-types/queries.d.ts +0 -76
package/dist/app/bundle.api.js
CHANGED
|
@@ -31418,9 +31418,13 @@
|
|
|
31418
31418
|
});
|
|
31419
31419
|
}
|
|
31420
31420
|
function importTransactions(accountId, transactions) {
|
|
31421
|
+
var opts = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : {
|
|
31422
|
+
defaultCleared: true
|
|
31423
|
+
};
|
|
31421
31424
|
return send('api/transactions-import', {
|
|
31422
31425
|
accountId: accountId,
|
|
31423
|
-
transactions: transactions
|
|
31426
|
+
transactions: transactions,
|
|
31427
|
+
opts: opts
|
|
31424
31428
|
});
|
|
31425
31429
|
}
|
|
31426
31430
|
function getTransactions(accountId, startDate, endDate) {
|
|
@@ -33870,7 +33874,7 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
|
|
|
33870
33874
|
});
|
|
33871
33875
|
/* harmony import */ var _db__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../db */ "./packages/loot-core/src/server/db/index.ts");
|
|
33872
33876
|
// @ts-strict-ignore
|
|
33873
|
-
|
|
33877
|
+
async function createPayee(description) {
|
|
33874
33878
|
// Check to make sure no payee already exists with exactly the same
|
|
33875
33879
|
// name
|
|
33876
33880
|
const row = await _db__WEBPACK_IMPORTED_MODULE_0__.first(`SELECT id FROM payees WHERE UNICODE_LOWER(name) = ? AND tombstone = 0`, [
|
|
@@ -34014,10 +34018,16 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
|
|
|
34014
34018
|
/* harmony export */ rankRules: () => ( /* binding */rankRules)
|
|
34015
34019
|
/* harmony export */
|
|
34016
34020
|
});
|
|
34017
|
-
/* harmony import */ var
|
|
34018
|
-
/* harmony import */ var
|
|
34019
|
-
/* harmony import */ var
|
|
34020
|
-
/* harmony import */ var
|
|
34021
|
+
/* harmony import */ var date_fns__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! date-fns */ "./node_modules/date-fns/esm/isValid/index.js");
|
|
34022
|
+
/* harmony import */ var date_fns__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! date-fns */ "./node_modules/date-fns/esm/parseISO/index.js");
|
|
34023
|
+
/* harmony import */ var date_fns__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! date-fns */ "./node_modules/date-fns/esm/subDays/index.js");
|
|
34024
|
+
/* harmony import */ var date_fns__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! date-fns */ "./node_modules/date-fns/esm/addDays/index.js");
|
|
34025
|
+
/* harmony import */ var date_fns__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! date-fns */ "./node_modules/date-fns/esm/addMonths/index.js");
|
|
34026
|
+
/* harmony import */ var date_fns__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! date-fns */ "./node_modules/date-fns/esm/subMonths/index.js");
|
|
34027
|
+
/* harmony import */ var date_fns__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! date-fns */ "./node_modules/date-fns/esm/addWeeks/index.js");
|
|
34028
|
+
/* harmony import */ var date_fns__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! date-fns */ "./node_modules/date-fns/esm/subWeeks/index.js");
|
|
34029
|
+
/* harmony import */ var date_fns__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! date-fns */ "./node_modules/date-fns/esm/addYears/index.js");
|
|
34030
|
+
/* harmony import */ var date_fns__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! date-fns */ "./node_modules/date-fns/esm/subYears/index.js");
|
|
34021
34031
|
/* harmony import */ var handlebars__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! handlebars */ "./node_modules/handlebars/lib/index.js");
|
|
34022
34032
|
/* harmony import */ var handlebars__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/ __webpack_require__.n(handlebars__WEBPACK_IMPORTED_MODULE_0__);
|
|
34023
34033
|
/* harmony import */ var _shared_months__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../shared/months */ "./packages/loot-core/src/shared/months.ts");
|
|
@@ -34037,8 +34047,8 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
|
|
|
34037
34047
|
return b.map(Number).reduce(fn, Number(a));
|
|
34038
34048
|
};
|
|
34039
34049
|
}
|
|
34040
|
-
|
|
34041
|
-
|
|
34050
|
+
function regexHelper(mapRegex, mapNonRegex, apply) {
|
|
34051
|
+
return (value, regex, replace) => {
|
|
34042
34052
|
if (value == null) {
|
|
34043
34053
|
return null;
|
|
34044
34054
|
}
|
|
@@ -34049,13 +34059,18 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
|
|
|
34049
34059
|
const match = regexTest.exec(regex);
|
|
34050
34060
|
// Regex is in format /regex/flags
|
|
34051
34061
|
if (match) {
|
|
34052
|
-
regexp =
|
|
34062
|
+
regexp = mapRegex(match[1], match[2]);
|
|
34053
34063
|
}
|
|
34054
34064
|
else {
|
|
34055
|
-
regexp =
|
|
34065
|
+
regexp = mapNonRegex(regex);
|
|
34056
34066
|
}
|
|
34057
|
-
return String(value)
|
|
34058
|
-
}
|
|
34067
|
+
return apply(String(value), regexp, replace);
|
|
34068
|
+
};
|
|
34069
|
+
}
|
|
34070
|
+
const helpers = {
|
|
34071
|
+
regex: regexHelper((regex, flags) => new RegExp(regex, flags), (value) => new RegExp(value), (value, regex, replace) => value.replace(regex, replace)),
|
|
34072
|
+
replace: regexHelper((regex, flags) => new RegExp(regex, flags), (value) => value, (value, regex, replace) => value.replace(regex, replace)),
|
|
34073
|
+
replaceAll: regexHelper((regex, flags) => new RegExp(regex, flags), (value) => value, (value, regex, replace) => value.replaceAll(regex, replace)),
|
|
34059
34074
|
add: mathHelper((a, b) => a + b),
|
|
34060
34075
|
sub: mathHelper((a, b) => a - b),
|
|
34061
34076
|
div: mathHelper((a, b) => a / b),
|
|
@@ -34072,9 +34087,56 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
|
|
|
34072
34087
|
month: (date) => date && (0, _shared_months__WEBPACK_IMPORTED_MODULE_1__.format)(date, 'M'),
|
|
34073
34088
|
year: (date) => date && (0, _shared_months__WEBPACK_IMPORTED_MODULE_1__.format)(date, 'yyyy'),
|
|
34074
34089
|
format: (date, f) => date && f && (0, _shared_months__WEBPACK_IMPORTED_MODULE_1__.format)(date, f),
|
|
34090
|
+
addDays: (date, days) => {
|
|
34091
|
+
if (!days || !days)
|
|
34092
|
+
return date;
|
|
34093
|
+
return (0, _shared_months__WEBPACK_IMPORTED_MODULE_1__.format)((0, _shared_months__WEBPACK_IMPORTED_MODULE_1__.addDays)(date, days), 'yyyy-MM-dd');
|
|
34094
|
+
},
|
|
34095
|
+
subDays: (date, days) => {
|
|
34096
|
+
if (!days || !days)
|
|
34097
|
+
return date;
|
|
34098
|
+
return (0, _shared_months__WEBPACK_IMPORTED_MODULE_1__.format)((0, _shared_months__WEBPACK_IMPORTED_MODULE_1__.subDays)(date, days), 'yyyy-MM-dd');
|
|
34099
|
+
},
|
|
34100
|
+
addMonths: (date, months) => {
|
|
34101
|
+
if (!months || !months)
|
|
34102
|
+
return date;
|
|
34103
|
+
return (0, _shared_months__WEBPACK_IMPORTED_MODULE_1__.format)((0, date_fns__WEBPACK_IMPORTED_MODULE_8__["default"])((0, _shared_months__WEBPACK_IMPORTED_MODULE_1__.parseDate)(date), months), 'yyyy-MM-dd');
|
|
34104
|
+
},
|
|
34105
|
+
subMonths: (date, months) => {
|
|
34106
|
+
if (!months || !months)
|
|
34107
|
+
return date;
|
|
34108
|
+
return (0, _shared_months__WEBPACK_IMPORTED_MODULE_1__.format)((0, date_fns__WEBPACK_IMPORTED_MODULE_9__["default"])((0, _shared_months__WEBPACK_IMPORTED_MODULE_1__.parseDate)(date), months), 'yyyy-MM-dd');
|
|
34109
|
+
},
|
|
34110
|
+
addWeeks: (date, weeks) => {
|
|
34111
|
+
if (!weeks || !weeks)
|
|
34112
|
+
return date;
|
|
34113
|
+
return (0, _shared_months__WEBPACK_IMPORTED_MODULE_1__.format)((0, date_fns__WEBPACK_IMPORTED_MODULE_10__["default"])((0, _shared_months__WEBPACK_IMPORTED_MODULE_1__.parseDate)(date), weeks), 'yyyy-MM-dd');
|
|
34114
|
+
},
|
|
34115
|
+
subWeeks: (date, weeks) => {
|
|
34116
|
+
if (!weeks || !weeks)
|
|
34117
|
+
return date;
|
|
34118
|
+
return (0, _shared_months__WEBPACK_IMPORTED_MODULE_1__.format)((0, date_fns__WEBPACK_IMPORTED_MODULE_11__["default"])((0, _shared_months__WEBPACK_IMPORTED_MODULE_1__.parseDate)(date), weeks), 'yyyy-MM-dd');
|
|
34119
|
+
},
|
|
34120
|
+
addYears: (date, years) => {
|
|
34121
|
+
if (!years || !years)
|
|
34122
|
+
return date;
|
|
34123
|
+
return (0, _shared_months__WEBPACK_IMPORTED_MODULE_1__.format)((0, date_fns__WEBPACK_IMPORTED_MODULE_12__["default"])((0, _shared_months__WEBPACK_IMPORTED_MODULE_1__.parseDate)(date), years), 'yyyy-MM-dd');
|
|
34124
|
+
},
|
|
34125
|
+
subYears: (date, years) => {
|
|
34126
|
+
if (!years || !years)
|
|
34127
|
+
return date;
|
|
34128
|
+
return (0, _shared_months__WEBPACK_IMPORTED_MODULE_1__.format)((0, date_fns__WEBPACK_IMPORTED_MODULE_13__["default"])((0, _shared_months__WEBPACK_IMPORTED_MODULE_1__.parseDate)(date), years), 'yyyy-MM-dd');
|
|
34129
|
+
},
|
|
34130
|
+
setDay: (date, day) => {
|
|
34131
|
+
if (!date)
|
|
34132
|
+
return date;
|
|
34133
|
+
const actualDay = Number((0, _shared_months__WEBPACK_IMPORTED_MODULE_1__.format)(date, 'd'));
|
|
34134
|
+
return (0, _shared_months__WEBPACK_IMPORTED_MODULE_1__.format)((0, _shared_months__WEBPACK_IMPORTED_MODULE_1__.addDays)(date, day - actualDay), 'yyyy-MM-dd');
|
|
34135
|
+
},
|
|
34075
34136
|
debug: (value) => {
|
|
34076
34137
|
console.log(value);
|
|
34077
|
-
}
|
|
34138
|
+
},
|
|
34139
|
+
concat: (...args) => args.slice(0, -1).join('')
|
|
34078
34140
|
};
|
|
34079
34141
|
for (const [name, fn] of Object.entries(helpers)) {
|
|
34080
34142
|
handlebars__WEBPACK_IMPORTED_MODULE_0__.registerHelper(name, fn);
|
|
@@ -34110,7 +34172,7 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
|
|
|
34110
34172
|
}
|
|
34111
34173
|
else if (str.length === 10) {
|
|
34112
34174
|
// YYYY-MM-DD
|
|
34113
|
-
if (!
|
|
34175
|
+
if (!date_fns__WEBPACK_IMPORTED_MODULE_14__["default"](date_fns__WEBPACK_IMPORTED_MODULE_15__["default"](str))) {
|
|
34114
34176
|
return null;
|
|
34115
34177
|
}
|
|
34116
34178
|
return {
|
|
@@ -34120,7 +34182,7 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
|
|
|
34120
34182
|
}
|
|
34121
34183
|
else if (str.length === 7) {
|
|
34122
34184
|
// YYYY-MM
|
|
34123
|
-
if (!
|
|
34185
|
+
if (!date_fns__WEBPACK_IMPORTED_MODULE_14__["default"](date_fns__WEBPACK_IMPORTED_MODULE_15__["default"](str + '-01'))) {
|
|
34124
34186
|
return null;
|
|
34125
34187
|
}
|
|
34126
34188
|
return {
|
|
@@ -34130,7 +34192,7 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
|
|
|
34130
34192
|
}
|
|
34131
34193
|
else if (str.length === 4) {
|
|
34132
34194
|
// YYYY
|
|
34133
|
-
if (!
|
|
34195
|
+
if (!date_fns__WEBPACK_IMPORTED_MODULE_14__["default"](date_fns__WEBPACK_IMPORTED_MODULE_15__["default"](str + '-01-01'))) {
|
|
34134
34196
|
return null;
|
|
34135
34197
|
}
|
|
34136
34198
|
return {
|
|
@@ -34284,13 +34346,16 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
|
|
|
34284
34346
|
}
|
|
34285
34347
|
eval(object) {
|
|
34286
34348
|
let fieldValue = object[this.field];
|
|
34349
|
+
const type = this.type;
|
|
34350
|
+
if (type === 'string') {
|
|
34351
|
+
fieldValue ??= '';
|
|
34352
|
+
}
|
|
34287
34353
|
if (fieldValue === undefined) {
|
|
34288
34354
|
return false;
|
|
34289
34355
|
}
|
|
34290
34356
|
if (typeof fieldValue === 'string') {
|
|
34291
34357
|
fieldValue = fieldValue.toLowerCase();
|
|
34292
34358
|
}
|
|
34293
|
-
const type = this.type;
|
|
34294
34359
|
if (type === 'number' && this.options) {
|
|
34295
34360
|
if (this.options.outflow) {
|
|
34296
34361
|
if (fieldValue > 0) {
|
|
@@ -34316,7 +34381,7 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
|
|
|
34316
34381
|
const { schedule } = this.value;
|
|
34317
34382
|
if (this.op === 'isapprox') {
|
|
34318
34383
|
const fieldDate = (0, _shared_months__WEBPACK_IMPORTED_MODULE_1__.parseDate)(fieldValue);
|
|
34319
|
-
return schedule.occursBetween(
|
|
34384
|
+
return schedule.occursBetween(date_fns__WEBPACK_IMPORTED_MODULE_16__["default"](fieldDate, 2), date_fns__WEBPACK_IMPORTED_MODULE_17__["default"](fieldDate, 2));
|
|
34320
34385
|
}
|
|
34321
34386
|
else {
|
|
34322
34387
|
return schedule.occursOn({
|
|
@@ -34612,7 +34677,7 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
|
|
|
34612
34677
|
lastNonFixedTransactionIndex = Math.max(lastNonFixedTransactionIndex, splitTransactionIndex);
|
|
34613
34678
|
});
|
|
34614
34679
|
// The last remainder split will be adjusted for any leftovers from rounding.
|
|
34615
|
-
newTransactions[lastNonFixedTransactionIndex].amount
|
|
34680
|
+
newTransactions[lastNonFixedTransactionIndex].amount += getSplitRemainder(newTransactions);
|
|
34616
34681
|
}
|
|
34617
34682
|
// The split index 0 (transaction index 1) is reserved for "Apply to all" actions.
|
|
34618
34683
|
// Remove that entry from the transaction list.
|
|
@@ -35252,7 +35317,7 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
|
|
|
35252
35317
|
}
|
|
35253
35318
|
});
|
|
35254
35319
|
}
|
|
35255
|
-
async function reconcileTransactions(acctId, transactions, isBankSyncAccount = false, strictIdChecking = true, isPreview = false) {
|
|
35320
|
+
async function reconcileTransactions(acctId, transactions, isBankSyncAccount = false, strictIdChecking = true, isPreview = false, defaultCleared = true) {
|
|
35256
35321
|
console.log('Performing transaction reconciliation');
|
|
35257
35322
|
const updated = [];
|
|
35258
35323
|
const added = [];
|
|
@@ -35283,7 +35348,7 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
|
|
|
35283
35348
|
category: existing.category || trans.category || null,
|
|
35284
35349
|
imported_payee: trans.imported_payee || null,
|
|
35285
35350
|
notes: existing.notes || trans.notes || null,
|
|
35286
|
-
cleared: trans.cleared
|
|
35351
|
+
cleared: trans.cleared ?? existing.cleared
|
|
35287
35352
|
};
|
|
35288
35353
|
if ((0, _shared_util__WEBPACK_IMPORTED_MODULE_4__.hasFieldsChanged)(existing, updates, Object.keys(updates))) {
|
|
35289
35354
|
updated.push({
|
|
@@ -35326,7 +35391,7 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
|
|
|
35326
35391
|
...newTrans,
|
|
35327
35392
|
id: (0, uuid__WEBPACK_IMPORTED_MODULE_16__["default"])(),
|
|
35328
35393
|
category: trans.category || null,
|
|
35329
|
-
cleared: trans.cleared
|
|
35394
|
+
cleared: trans.cleared ?? defaultCleared
|
|
35330
35395
|
};
|
|
35331
35396
|
if (subtransactions && subtransactions.length > 0) {
|
|
35332
35397
|
added.push(...makeSplitTransaction(finalTransaction, subtransactions));
|
|
@@ -36633,7 +36698,8 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
|
|
|
36633
36698
|
// (this might change when we think about scheduled transactions)
|
|
36634
36699
|
const register = await _db__WEBPACK_IMPORTED_MODULE_5__.all(`SELECT t.* FROM v_transactions t
|
|
36635
36700
|
LEFT JOIN accounts a ON a.id = t.account
|
|
36636
|
-
|
|
36701
|
+
LEFT JOIN payees p ON p.id = t.payee
|
|
36702
|
+
WHERE date >= ? AND date <= ? AND is_parent = 0 AND a.closed = 0 AND p.learn_categories = 1
|
|
36637
36703
|
ORDER BY date DESC`, [
|
|
36638
36704
|
(0, _models__WEBPACK_IMPORTED_MODULE_8__.toDateRepr)(oldestDate),
|
|
36639
36705
|
(0, _models__WEBPACK_IMPORTED_MODULE_8__.toDateRepr)((0, _shared_months__WEBPACK_IMPORTED_MODULE_0__.addDays)((0, _shared_months__WEBPACK_IMPORTED_MODULE_0__.currentDay)(), 180))
|
|
@@ -36961,32 +37027,6 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
|
|
|
36961
37027
|
const { id: fromPayee } = await _db__WEBPACK_IMPORTED_MODULE_0__.first('SELECT id FROM payees WHERE transfer_acct = ?', [
|
|
36962
37028
|
transaction.account
|
|
36963
37029
|
]);
|
|
36964
|
-
// We need to enforce certain constraints with child transaction transfers
|
|
36965
|
-
if (transaction.parent_id) {
|
|
36966
|
-
const row = await _db__WEBPACK_IMPORTED_MODULE_0__.first(`
|
|
36967
|
-
SELECT p.id, p.transfer_acct FROM v_transactions t
|
|
36968
|
-
LEFT JOIN payees p ON p.id = t.payee
|
|
36969
|
-
WHERE t.id = ?
|
|
36970
|
-
`, [
|
|
36971
|
-
transaction.parent_id
|
|
36972
|
-
]);
|
|
36973
|
-
if (row.transfer_acct) {
|
|
36974
|
-
if (row.id !== transaction.payee) {
|
|
36975
|
-
// This child transaction is trying to use a transfer payee,
|
|
36976
|
-
// but the parent is already using a different transfer payee.
|
|
36977
|
-
// This is not allowed, so not only do we do nothing, we clear
|
|
36978
|
-
// the payee of the child transaction to make it clear
|
|
36979
|
-
await _db__WEBPACK_IMPORTED_MODULE_0__.updateTransaction({
|
|
36980
|
-
id: transaction.id,
|
|
36981
|
-
payee: null
|
|
36982
|
-
});
|
|
36983
|
-
return {
|
|
36984
|
-
id: transaction.id,
|
|
36985
|
-
payee: null
|
|
36986
|
-
};
|
|
36987
|
-
}
|
|
36988
|
-
}
|
|
36989
|
-
}
|
|
36990
37030
|
const id = await _db__WEBPACK_IMPORTED_MODULE_0__.insertTransaction({
|
|
36991
37031
|
account: transferredAccount,
|
|
36992
37032
|
amount: -transaction.amount,
|
|
@@ -38189,10 +38229,6 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
|
|
|
38189
38229
|
/* harmony import */ var mitt__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! mitt */ "./node_modules/mitt/dist/mitt.mjs");
|
|
38190
38230
|
/* harmony import */ var _platform_exceptions__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../platform/exceptions */ "./packages/loot-core/src/platform/exceptions/index.electron.ts");
|
|
38191
38231
|
// @ts-strict-ignore
|
|
38192
|
-
// This is a simple helper abstraction for defining methods exposed to
|
|
38193
|
-
// the client. It doesn't do much, but checks for naming conflicts and
|
|
38194
|
-
// makes it cleaner to combine methods. We call a group of related
|
|
38195
|
-
// methods an "app".
|
|
38196
38232
|
class App {
|
|
38197
38233
|
constructor() {
|
|
38198
38234
|
this.handlers = {};
|
|
@@ -39050,7 +39086,7 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
|
|
|
39050
39086
|
return compileAnd(state, cond);
|
|
39051
39087
|
}
|
|
39052
39088
|
else if (field === '$or') {
|
|
39053
|
-
if (!cond) {
|
|
39089
|
+
if (!cond || Array.isArray(cond) && cond.length === 0) {
|
|
39054
39090
|
return null;
|
|
39055
39091
|
}
|
|
39056
39092
|
return compileOr(state, cond);
|
|
@@ -40060,6 +40096,9 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
|
|
|
40060
40096
|
group_by: f('string', {
|
|
40061
40097
|
default: 'Category'
|
|
40062
40098
|
}),
|
|
40099
|
+
sort_by: f('string', {
|
|
40100
|
+
default: 'desc'
|
|
40101
|
+
}),
|
|
40063
40102
|
balance_type: f('string', {
|
|
40064
40103
|
default: 'Expense'
|
|
40065
40104
|
}),
|
|
@@ -40102,7 +40141,9 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
|
|
|
40102
40141
|
zero_budgets: {
|
|
40103
40142
|
id: f('id'),
|
|
40104
40143
|
month: f('integer'),
|
|
40105
|
-
category: f('string'
|
|
40144
|
+
category: f('string', {
|
|
40145
|
+
ref: 'categories'
|
|
40146
|
+
}),
|
|
40106
40147
|
amount: f('integer'),
|
|
40107
40148
|
carryover: f('integer'),
|
|
40108
40149
|
goal: f('integer'),
|
|
@@ -40644,7 +40685,9 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
|
|
|
40644
40685
|
/* harmony export */ holdForNextMonth: () => ( /* binding */holdForNextMonth),
|
|
40645
40686
|
/* harmony export */ isReflectBudget: () => ( /* binding */isReflectBudget),
|
|
40646
40687
|
/* harmony export */ resetHold: () => ( /* binding */resetHold),
|
|
40688
|
+
/* harmony export */ set12MonthAvg: () => ( /* binding */set12MonthAvg),
|
|
40647
40689
|
/* harmony export */ set3MonthAvg: () => ( /* binding */set3MonthAvg),
|
|
40690
|
+
/* harmony export */ set6MonthAvg: () => ( /* binding */set6MonthAvg),
|
|
40648
40691
|
/* harmony export */ setBudget: () => ( /* binding */setBudget),
|
|
40649
40692
|
/* harmony export */ setBuffer: () => ( /* binding */setBuffer),
|
|
40650
40693
|
/* harmony export */ setCategoryCarryover: () => ( /* binding */setCategoryCarryover),
|
|
@@ -40861,6 +40904,36 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
|
|
|
40861
40904
|
}
|
|
40862
40905
|
});
|
|
40863
40906
|
}
|
|
40907
|
+
async function set12MonthAvg({ month }) {
|
|
40908
|
+
const categories = await _db__WEBPACK_IMPORTED_MODULE_2__.all('SELECT * FROM v_categories WHERE tombstone = 0');
|
|
40909
|
+
await (0, _sync__WEBPACK_IMPORTED_MODULE_4__.batchMessages)(async () => {
|
|
40910
|
+
for (const cat of categories) {
|
|
40911
|
+
if (cat.is_income === 1 && !isReflectBudget()) {
|
|
40912
|
+
continue;
|
|
40913
|
+
}
|
|
40914
|
+
setNMonthAvg({
|
|
40915
|
+
month,
|
|
40916
|
+
N: 12,
|
|
40917
|
+
category: cat.id
|
|
40918
|
+
});
|
|
40919
|
+
}
|
|
40920
|
+
});
|
|
40921
|
+
}
|
|
40922
|
+
async function set6MonthAvg({ month }) {
|
|
40923
|
+
const categories = await _db__WEBPACK_IMPORTED_MODULE_2__.all('SELECT * FROM v_categories WHERE tombstone = 0');
|
|
40924
|
+
await (0, _sync__WEBPACK_IMPORTED_MODULE_4__.batchMessages)(async () => {
|
|
40925
|
+
for (const cat of categories) {
|
|
40926
|
+
if (cat.is_income === 1 && !isReflectBudget()) {
|
|
40927
|
+
continue;
|
|
40928
|
+
}
|
|
40929
|
+
setNMonthAvg({
|
|
40930
|
+
month,
|
|
40931
|
+
N: 6,
|
|
40932
|
+
category: cat.id
|
|
40933
|
+
});
|
|
40934
|
+
}
|
|
40935
|
+
});
|
|
40936
|
+
}
|
|
40864
40937
|
async function setNMonthAvg({ month, N, category }) {
|
|
40865
40938
|
const categoryFromDb = await _db__WEBPACK_IMPORTED_MODULE_2__.first('SELECT is_income FROM v_categories WHERE id = ?', [
|
|
40866
40939
|
category
|
|
@@ -41043,6 +41116,8 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
|
|
|
41043
41116
|
app.method('budget/copy-single-month', (0, _mutators__WEBPACK_IMPORTED_MODULE_1__.mutator)((0, _undo__WEBPACK_IMPORTED_MODULE_2__.undoable)(_actions__WEBPACK_IMPORTED_MODULE_3__.copySinglePreviousMonth)));
|
|
41044
41117
|
app.method('budget/set-zero', (0, _mutators__WEBPACK_IMPORTED_MODULE_1__.mutator)((0, _undo__WEBPACK_IMPORTED_MODULE_2__.undoable)(_actions__WEBPACK_IMPORTED_MODULE_3__.setZero)));
|
|
41045
41118
|
app.method('budget/set-3month-avg', (0, _mutators__WEBPACK_IMPORTED_MODULE_1__.mutator)((0, _undo__WEBPACK_IMPORTED_MODULE_2__.undoable)(_actions__WEBPACK_IMPORTED_MODULE_3__.set3MonthAvg)));
|
|
41119
|
+
app.method('budget/set-6month-avg', (0, _mutators__WEBPACK_IMPORTED_MODULE_1__.mutator)((0, _undo__WEBPACK_IMPORTED_MODULE_2__.undoable)(_actions__WEBPACK_IMPORTED_MODULE_3__.set6MonthAvg)));
|
|
41120
|
+
app.method('budget/set-12month-avg', (0, _mutators__WEBPACK_IMPORTED_MODULE_1__.mutator)((0, _undo__WEBPACK_IMPORTED_MODULE_2__.undoable)(_actions__WEBPACK_IMPORTED_MODULE_3__.set12MonthAvg)));
|
|
41046
41121
|
app.method('budget/set-n-month-avg', (0, _mutators__WEBPACK_IMPORTED_MODULE_1__.mutator)((0, _undo__WEBPACK_IMPORTED_MODULE_2__.undoable)(_actions__WEBPACK_IMPORTED_MODULE_3__.setNMonthAvg)));
|
|
41047
41122
|
app.method('budget/check-templates', (0, _mutators__WEBPACK_IMPORTED_MODULE_1__.mutator)((0, _undo__WEBPACK_IMPORTED_MODULE_2__.undoable)(_goaltemplates__WEBPACK_IMPORTED_MODULE_5__.runCheckTemplates)));
|
|
41048
41123
|
app.method('budget/apply-goal-template', (0, _mutators__WEBPACK_IMPORTED_MODULE_1__.mutator)((0, _undo__WEBPACK_IMPORTED_MODULE_2__.undoable)(_goaltemplates__WEBPACK_IMPORTED_MODULE_5__.applyTemplate)));
|
|
@@ -41542,57 +41617,61 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
|
|
|
41542
41617
|
let scheduleFlag = false;
|
|
41543
41618
|
// switch on template type and calculate the amount for the line
|
|
41544
41619
|
for (let i = 0; i < t.length; i++) {
|
|
41620
|
+
let newBudget = 0;
|
|
41545
41621
|
switch (t[i].type) {
|
|
41546
41622
|
case 'simple':
|
|
41547
41623
|
{
|
|
41548
|
-
|
|
41624
|
+
newBudget = this.runSimple(t[i], this.limitAmount);
|
|
41549
41625
|
break;
|
|
41550
41626
|
}
|
|
41551
41627
|
case 'copy':
|
|
41552
41628
|
{
|
|
41553
|
-
|
|
41629
|
+
newBudget = await this.runCopy(t[i]);
|
|
41554
41630
|
break;
|
|
41555
41631
|
}
|
|
41556
41632
|
case 'week':
|
|
41557
41633
|
{
|
|
41558
|
-
|
|
41634
|
+
newBudget = this.runWeek(t[i]);
|
|
41559
41635
|
break;
|
|
41560
41636
|
}
|
|
41561
41637
|
case 'spend':
|
|
41562
41638
|
{
|
|
41563
|
-
|
|
41639
|
+
newBudget = await this.runSpend(t[i]);
|
|
41564
41640
|
break;
|
|
41565
41641
|
}
|
|
41566
41642
|
case 'percentage':
|
|
41567
41643
|
{
|
|
41568
|
-
|
|
41644
|
+
newBudget = await this.runPercentage(t[i], availStart);
|
|
41569
41645
|
break;
|
|
41570
41646
|
}
|
|
41571
41647
|
case 'by':
|
|
41572
41648
|
{
|
|
41573
41649
|
//TODO add the logic to run all of these at once or whatever is needed
|
|
41574
41650
|
const ret = this.runBy(t[i], first, remainder);
|
|
41575
|
-
|
|
41651
|
+
newBudget = ret.ret;
|
|
41576
41652
|
remainder = ret.remainder;
|
|
41577
41653
|
first = false;
|
|
41578
41654
|
break;
|
|
41579
41655
|
}
|
|
41580
41656
|
case 'schedule':
|
|
41581
41657
|
{
|
|
41582
|
-
const budgeted =
|
|
41658
|
+
const budgeted = this.fromLastMonth + toBudget;
|
|
41583
41659
|
const ret = await (0, _goalsSchedule__WEBPACK_IMPORTED_MODULE_4__.goalsSchedule)(scheduleFlag, t, this.month, budgeted, remainder, this.fromLastMonth, toBudget, [], this.category);
|
|
41584
|
-
|
|
41660
|
+
// Schedules assume that its to budget value is the whole thing so this
|
|
41661
|
+
// needs to remove the previous funds so they aren't double counted
|
|
41662
|
+
newBudget = ret.to_budget - toBudget;
|
|
41585
41663
|
remainder = ret.remainder;
|
|
41586
41664
|
scheduleFlag = ret.scheduleFlag;
|
|
41587
41665
|
break;
|
|
41588
41666
|
}
|
|
41589
41667
|
case 'average':
|
|
41590
41668
|
{
|
|
41591
|
-
|
|
41669
|
+
newBudget = await this.runAverage(t[i]);
|
|
41592
41670
|
break;
|
|
41593
41671
|
}
|
|
41594
41672
|
}
|
|
41595
|
-
available = available -
|
|
41673
|
+
available = available - newBudget;
|
|
41674
|
+
toBudget += newBudget;
|
|
41596
41675
|
}
|
|
41597
41676
|
//check limit
|
|
41598
41677
|
if (this.limitCheck) {
|
|
@@ -42464,7 +42543,7 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
|
|
|
42464
42543
|
// Unless the current category is relevant to the schedule, target the post-rule amount.
|
|
42465
42544
|
const sign = category.is_income ? 1 : -1;
|
|
42466
42545
|
const target = sign * (categorySubtransactions?.length ? categorySubtransactions.reduce((acc, t) => acc + t.amount, 0) : postRuleAmount ?? scheduleAmount);
|
|
42467
|
-
const next_date_string = (0,
|
|
42546
|
+
const next_date_string = (0, _shared_schedules__WEBPACK_IMPORTED_MODULE_1__.getNextDate)(dateConditions, _shared_months__WEBPACK_IMPORTED_MODULE_0__._parse(current_month));
|
|
42468
42547
|
const target_interval = dateConditions.value.interval ? dateConditions.value.interval : 1;
|
|
42469
42548
|
const target_frequency = dateConditions.value.frequency;
|
|
42470
42549
|
const isRepeating = Object(dateConditions.value) === dateConditions.value && 'frequency' in dateConditions.value;
|
|
@@ -42490,14 +42569,14 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
|
|
|
42490
42569
|
if (isRepeating) {
|
|
42491
42570
|
let monthlyTarget = 0;
|
|
42492
42571
|
const nextMonth = _shared_months__WEBPACK_IMPORTED_MODULE_0__.addMonths(current_month, t[t.length - 1].num_months + 1);
|
|
42493
|
-
let nextBaseDate = (0,
|
|
42494
|
-
let nextDate = dateConditions.value.skipWeekend ? _shared_months__WEBPACK_IMPORTED_MODULE_0__.dayFromDate((0,
|
|
42572
|
+
let nextBaseDate = (0, _shared_schedules__WEBPACK_IMPORTED_MODULE_1__.getNextDate)(dateConditions, _shared_months__WEBPACK_IMPORTED_MODULE_0__._parse(current_month), true);
|
|
42573
|
+
let nextDate = dateConditions.value.skipWeekend ? _shared_months__WEBPACK_IMPORTED_MODULE_0__.dayFromDate((0, _shared_schedules__WEBPACK_IMPORTED_MODULE_1__.getDateWithSkippedWeekend)(_shared_months__WEBPACK_IMPORTED_MODULE_0__._parse(nextBaseDate), dateConditions.value.weekendSolveMode)) : nextBaseDate;
|
|
42495
42574
|
while (nextDate < nextMonth) {
|
|
42496
42575
|
monthlyTarget += -target;
|
|
42497
42576
|
const currentDate = nextBaseDate;
|
|
42498
42577
|
const oneDayLater = _shared_months__WEBPACK_IMPORTED_MODULE_0__.addDays(nextBaseDate, 1);
|
|
42499
|
-
nextBaseDate = (0,
|
|
42500
|
-
nextDate = dateConditions.value.skipWeekend ? _shared_months__WEBPACK_IMPORTED_MODULE_0__.dayFromDate((0,
|
|
42578
|
+
nextBaseDate = (0, _shared_schedules__WEBPACK_IMPORTED_MODULE_1__.getNextDate)(dateConditions, _shared_months__WEBPACK_IMPORTED_MODULE_0__._parse(oneDayLater), true);
|
|
42579
|
+
nextDate = dateConditions.value.skipWeekend ? _shared_months__WEBPACK_IMPORTED_MODULE_0__.dayFromDate((0, _shared_schedules__WEBPACK_IMPORTED_MODULE_1__.getDateWithSkippedWeekend)(_shared_months__WEBPACK_IMPORTED_MODULE_0__._parse(nextBaseDate), dateConditions.value.weekendSolveMode)) : nextBaseDate;
|
|
42501
42580
|
const diffDays = _shared_months__WEBPACK_IMPORTED_MODULE_0__.differenceInCalendarDays(nextBaseDate, currentDate);
|
|
42502
42581
|
if (!diffDays) {
|
|
42503
42582
|
break;
|
|
@@ -43026,13 +43105,13 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
|
|
|
43026
43105
|
const schedules = await (0, _statements__WEBPACK_IMPORTED_MODULE_2__.getActiveSchedules)();
|
|
43027
43106
|
const scheduleNames = schedules.map(({ name }) => name);
|
|
43028
43107
|
const errors = [];
|
|
43029
|
-
categoryWithTemplates.forEach(({
|
|
43108
|
+
categoryWithTemplates.forEach(({ name, templates }) => {
|
|
43030
43109
|
templates.forEach((template) => {
|
|
43031
43110
|
if (template.type === 'error') {
|
|
43032
43111
|
errors.push(`${name}: ${template.line}`);
|
|
43033
43112
|
}
|
|
43034
43113
|
else if (template.type === 'schedule' && !scheduleNames.includes(template.name)) {
|
|
43035
|
-
errors.push(`${
|
|
43114
|
+
errors.push(`${name}: Schedule “${template.name}” does not exist`);
|
|
43036
43115
|
}
|
|
43037
43116
|
});
|
|
43038
43117
|
});
|
|
@@ -43057,7 +43136,7 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
|
|
|
43057
43136
|
}
|
|
43058
43137
|
const parsedTemplates = [];
|
|
43059
43138
|
note.split('\n').forEach((line) => {
|
|
43060
|
-
const trimmedLine = line.trim();
|
|
43139
|
+
const trimmedLine = line.substring(line.indexOf('#')).trim();
|
|
43061
43140
|
if (!trimmedLine.startsWith(TEMPLATE_PREFIX) && !trimmedLine.startsWith(GOAL_PREFIX)) {
|
|
43062
43141
|
return;
|
|
43063
43142
|
}
|
|
@@ -45862,8 +45941,8 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
|
|
|
45862
45941
|
/* harmony import */ var _app__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./app */ "./packages/loot-core/src/server/app.ts");
|
|
45863
45942
|
// Main app
|
|
45864
45943
|
const app = (0, _app__WEBPACK_IMPORTED_MODULE_1__.createApp)();
|
|
45865
|
-
app.events.on('sync', (
|
|
45866
|
-
_platform_server_connection__WEBPACK_IMPORTED_MODULE_0__.send('sync-event',
|
|
45944
|
+
app.events.on('sync', (event) => {
|
|
45945
|
+
_platform_server_connection__WEBPACK_IMPORTED_MODULE_0__.send('sync-event', event);
|
|
45867
45946
|
});
|
|
45868
45947
|
/***/
|
|
45869
45948
|
}),
|
|
@@ -46916,13 +46995,13 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
|
|
|
46916
46995
|
console.groupEnd();
|
|
46917
46996
|
return retVal;
|
|
46918
46997
|
};
|
|
46919
|
-
handlers['transactions-import'] = (0, _mutators__WEBPACK_IMPORTED_MODULE_36__.mutator)(function ({ accountId, transactions, isPreview }) {
|
|
46998
|
+
handlers['transactions-import'] = (0, _mutators__WEBPACK_IMPORTED_MODULE_36__.mutator)(function ({ accountId, transactions, isPreview, opts }) {
|
|
46920
46999
|
return (0, _undo__WEBPACK_IMPORTED_MODULE_51__.withUndo)(async () => {
|
|
46921
47000
|
if (typeof accountId !== 'string') {
|
|
46922
47001
|
throw (0, _errors__WEBPACK_IMPORTED_MODULE_32__.APIError)('transactions-import: accountId must be an id');
|
|
46923
47002
|
}
|
|
46924
47003
|
try {
|
|
46925
|
-
return await _accounts_sync__WEBPACK_IMPORTED_MODULE_18__.reconcileTransactions(accountId, transactions, false, true, isPreview);
|
|
47004
|
+
return await _accounts_sync__WEBPACK_IMPORTED_MODULE_18__.reconcileTransactions(accountId, transactions, false, true, isPreview, opts?.defaultCleared);
|
|
46926
47005
|
}
|
|
46927
47006
|
catch (err) {
|
|
46928
47007
|
if (err instanceof _errors__WEBPACK_IMPORTED_MODULE_32__.TransactionError) {
|
|
@@ -47004,6 +47083,9 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
|
|
|
47004
47083
|
if ('floatingSidebar' in prefs) {
|
|
47005
47084
|
await _platform_server_asyncStorage__WEBPACK_IMPORTED_MODULE_5__.setItem('floating-sidebar', '' + prefs.floatingSidebar);
|
|
47006
47085
|
}
|
|
47086
|
+
if ('language' in prefs) {
|
|
47087
|
+
await _platform_server_asyncStorage__WEBPACK_IMPORTED_MODULE_5__.setItem('language', prefs.language);
|
|
47088
|
+
}
|
|
47007
47089
|
if ('theme' in prefs) {
|
|
47008
47090
|
await _platform_server_asyncStorage__WEBPACK_IMPORTED_MODULE_5__.setItem('theme', prefs.theme);
|
|
47009
47091
|
}
|
|
@@ -47016,11 +47098,12 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
|
|
|
47016
47098
|
return 'ok';
|
|
47017
47099
|
};
|
|
47018
47100
|
handlers['load-global-prefs'] = async function () {
|
|
47019
|
-
const [[, floatingSidebar], [, maxMonths], [, documentDir], [, encryptKey], [, theme], [, preferredDarkTheme], [, serverSelfSignedCert]] = await _platform_server_asyncStorage__WEBPACK_IMPORTED_MODULE_5__.multiGet([
|
|
47101
|
+
const [[, floatingSidebar], [, maxMonths], [, documentDir], [, encryptKey], [, language], [, theme], [, preferredDarkTheme], [, serverSelfSignedCert]] = await _platform_server_asyncStorage__WEBPACK_IMPORTED_MODULE_5__.multiGet([
|
|
47020
47102
|
'floating-sidebar',
|
|
47021
47103
|
'max-months',
|
|
47022
47104
|
'document-dir',
|
|
47023
47105
|
'encrypt-key',
|
|
47106
|
+
'language',
|
|
47024
47107
|
'theme',
|
|
47025
47108
|
'preferred-dark-theme',
|
|
47026
47109
|
'server-self-signed-cert'
|
|
@@ -47030,6 +47113,7 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
|
|
|
47030
47113
|
maxMonths: (0, _shared_util__WEBPACK_IMPORTED_MODULE_13__.stringToInteger)(maxMonths || ''),
|
|
47031
47114
|
documentDir: documentDir || getDefaultDocumentDir(),
|
|
47032
47115
|
keyId: encryptKey && JSON.parse(encryptKey).id,
|
|
47116
|
+
language,
|
|
47033
47117
|
theme: theme === 'light' || theme === 'dark' || theme === 'auto' || theme === 'development' || theme === 'midnight' ? theme : 'auto',
|
|
47034
47118
|
preferredDarkTheme: preferredDarkTheme === 'dark' || preferredDarkTheme === 'midnight' ? preferredDarkTheme : 'dark',
|
|
47035
47119
|
serverSelfSignedCert: serverSelfSignedCert || undefined
|
|
@@ -47646,7 +47730,7 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
|
|
|
47646
47730
|
}
|
|
47647
47731
|
}
|
|
47648
47732
|
catch { } // Ignore cleanup errors
|
|
47649
|
-
throw new Error(`Failed to duplicate budget: ${error.message}`);
|
|
47733
|
+
throw new Error(`Failed to duplicate budget file: ${error.message}`);
|
|
47650
47734
|
}
|
|
47651
47735
|
// load in and validate
|
|
47652
47736
|
const { error } = await loadBudget(newId);
|
|
@@ -48063,7 +48147,6 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
|
|
|
48063
48147
|
await ensureExists(documentDir);
|
|
48064
48148
|
_platform_server_fs__WEBPACK_IMPORTED_MODULE_7__._setDocumentDir(documentDir);
|
|
48065
48149
|
}
|
|
48066
|
-
// eslint-disable-next-line import/no-unused-modules
|
|
48067
48150
|
async function initApp(isDev, socketName) {
|
|
48068
48151
|
await _platform_server_sqlite__WEBPACK_IMPORTED_MODULE_9__.init();
|
|
48069
48152
|
await Promise.all([
|
|
@@ -48100,7 +48183,6 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
|
|
|
48100
48183
|
global.$setSyncingMode = _sync__WEBPACK_IMPORTED_MODULE_48__.setSyncingMode;
|
|
48101
48184
|
}
|
|
48102
48185
|
}
|
|
48103
|
-
// eslint-disable-next-line import/no-unused-modules
|
|
48104
48186
|
async function init(config) {
|
|
48105
48187
|
// Get from build
|
|
48106
48188
|
let dataDir, serverURL;
|
|
@@ -48139,7 +48221,6 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
|
|
|
48139
48221
|
return lib;
|
|
48140
48222
|
}
|
|
48141
48223
|
// Export a few things required for the platform
|
|
48142
|
-
// eslint-disable-next-line import/no-unused-modules
|
|
48143
48224
|
const lib = {
|
|
48144
48225
|
getDataDir: _platform_server_fs__WEBPACK_IMPORTED_MODULE_7__.getDataDir,
|
|
48145
48226
|
sendMessage: (msg, args) => _platform_server_connection__WEBPACK_IMPORTED_MODULE_6__.send(msg, args),
|
|
@@ -48936,6 +49017,7 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
|
|
|
48936
49017
|
dateRange: row.date_range,
|
|
48937
49018
|
mode: row.mode,
|
|
48938
49019
|
groupBy: row.group_by,
|
|
49020
|
+
sortBy: row.sort_by,
|
|
48939
49021
|
interval: row.interval,
|
|
48940
49022
|
balanceType: row.balance_type,
|
|
48941
49023
|
showEmpty: row.show_empty === 1,
|
|
@@ -48958,6 +49040,7 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
|
|
|
48958
49040
|
date_range: report.dateRange,
|
|
48959
49041
|
mode: report.mode,
|
|
48960
49042
|
group_by: report.groupBy,
|
|
49043
|
+
sort_by: report.sortBy,
|
|
48961
49044
|
interval: report.interval,
|
|
48962
49045
|
balance_type: report.balanceType,
|
|
48963
49046
|
show_empty: report.showEmpty ? 1 : 0,
|
|
@@ -49156,22 +49239,17 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
|
|
|
49156
49239
|
/* harmony export */ app: () => ( /* binding */app),
|
|
49157
49240
|
/* harmony export */ createSchedule: () => ( /* binding */createSchedule),
|
|
49158
49241
|
/* harmony export */ deleteSchedule: () => ( /* binding */deleteSchedule),
|
|
49159
|
-
/* harmony export */ getDateWithSkippedWeekend: () => ( /* binding */getDateWithSkippedWeekend),
|
|
49160
|
-
/* harmony export */ getNextDate: () => ( /* binding */getNextDate),
|
|
49161
49242
|
/* harmony export */ getRuleForSchedule: () => ( /* binding */getRuleForSchedule),
|
|
49162
49243
|
/* harmony export */ setNextDate: () => ( /* binding */setNextDate),
|
|
49163
49244
|
/* harmony export */ updateConditions: () => ( /* binding */updateConditions),
|
|
49164
49245
|
/* harmony export */ updateSchedule: () => ( /* binding */updateSchedule)
|
|
49165
49246
|
/* harmony export */
|
|
49166
49247
|
});
|
|
49167
|
-
/* harmony import */ var
|
|
49168
|
-
/* harmony import */ var date_fns__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(/*! date-fns */ "./node_modules/date-fns/esm/
|
|
49169
|
-
/* harmony import */ var date_fns__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(/*! date-fns */ "./node_modules/date-fns/esm/isWeekend/index.js");
|
|
49170
|
-
/* harmony import */ var date_fns__WEBPACK_IMPORTED_MODULE_23__ = __webpack_require__(/*! date-fns */ "./node_modules/date-fns/esm/nextMonday/index.js");
|
|
49171
|
-
/* harmony import */ var date_fns__WEBPACK_IMPORTED_MODULE_24__ = __webpack_require__(/*! date-fns */ "./node_modules/date-fns/esm/previousFriday/index.js");
|
|
49248
|
+
/* harmony import */ var date_fns__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! date-fns */ "./node_modules/date-fns/esm/addDays/index.js");
|
|
49249
|
+
/* harmony import */ var date_fns__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(/*! date-fns */ "./node_modules/date-fns/esm/startOfDay/index.js");
|
|
49172
49250
|
/* harmony import */ var deep_equal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! deep-equal */ "./node_modules/deep-equal/index.js");
|
|
49173
49251
|
/* harmony import */ var deep_equal__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/ __webpack_require__.n(deep_equal__WEBPACK_IMPORTED_MODULE_0__);
|
|
49174
|
-
/* harmony import */ var
|
|
49252
|
+
/* harmony import */ var uuid__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! uuid */ "./node_modules/uuid/dist/esm-node/v4.js");
|
|
49175
49253
|
/* harmony import */ var _platform_exceptions__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../platform/exceptions */ "./packages/loot-core/src/platform/exceptions/index.electron.ts");
|
|
49176
49254
|
/* harmony import */ var _platform_server_connection__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../platform/server/connection */ "./packages/loot-core/src/platform/server/connection/index.api.ts");
|
|
49177
49255
|
/* harmony import */ var _shared_months__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../shared/months */ "./packages/loot-core/src/shared/months.ts");
|
|
@@ -49213,36 +49291,6 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
|
|
|
49213
49291
|
const added = replacements.filter((x) => x[0] == null && x[1] != null).map((x) => x[1]);
|
|
49214
49292
|
return updated.concat(added);
|
|
49215
49293
|
}
|
|
49216
|
-
function getNextDate(dateCond, start = new Date((0, _shared_months__WEBPACK_IMPORTED_MODULE_3__.currentDay)()), noSkipWeekend = false) {
|
|
49217
|
-
start = date_fns__WEBPACK_IMPORTED_MODULE_19__["default"](start);
|
|
49218
|
-
const cond = new _accounts_rules__WEBPACK_IMPORTED_MODULE_6__.Condition(dateCond.op, 'date', dateCond.value, null);
|
|
49219
|
-
const value = cond.getValue();
|
|
49220
|
-
if (value.type === 'date') {
|
|
49221
|
-
return value.date;
|
|
49222
|
-
}
|
|
49223
|
-
else if (value.type === 'recur') {
|
|
49224
|
-
let dates = value.schedule.occurrences({
|
|
49225
|
-
start,
|
|
49226
|
-
take: 1
|
|
49227
|
-
}).toArray();
|
|
49228
|
-
if (dates.length === 0) {
|
|
49229
|
-
// Could be a schedule with limited occurrences, so we try to
|
|
49230
|
-
// find the last occurrence
|
|
49231
|
-
dates = value.schedule.occurrences({
|
|
49232
|
-
reverse: true,
|
|
49233
|
-
take: 1
|
|
49234
|
-
}).toArray();
|
|
49235
|
-
}
|
|
49236
|
-
if (dates.length > 0) {
|
|
49237
|
-
let date = dates[0].date;
|
|
49238
|
-
if (value.schedule.data.skipWeekend && !noSkipWeekend) {
|
|
49239
|
-
date = getDateWithSkippedWeekend(date, value.schedule.data.weekendSolve);
|
|
49240
|
-
}
|
|
49241
|
-
return (0, _shared_months__WEBPACK_IMPORTED_MODULE_3__.dayFromDate)(date);
|
|
49242
|
-
}
|
|
49243
|
-
}
|
|
49244
|
-
return null;
|
|
49245
|
-
}
|
|
49246
49294
|
async function getRuleForSchedule(id) {
|
|
49247
49295
|
if (id == null) {
|
|
49248
49296
|
throw new Error('Schedule not attached to a rule');
|
|
@@ -49303,7 +49351,7 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
|
|
|
49303
49351
|
}).calculate('next_date'));
|
|
49304
49352
|
// Only do this if a date condition exists
|
|
49305
49353
|
if (dateCond) {
|
|
49306
|
-
const newNextDate = getNextDate(dateCond, start ? start(nextDate) : new Date());
|
|
49354
|
+
const newNextDate = (0, _shared_schedules__WEBPACK_IMPORTED_MODULE_5__.getNextDate)(dateCond, start ? start(nextDate) : new Date());
|
|
49307
49355
|
if (newNextDate !== nextDate) {
|
|
49308
49356
|
// Our `update` functon requires the id of the item and we don't
|
|
49309
49357
|
// have it, so we need to query it
|
|
@@ -49336,7 +49384,7 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
|
|
|
49336
49384
|
return true;
|
|
49337
49385
|
}
|
|
49338
49386
|
async function createSchedule({ schedule = null, conditions = [] } = {}) {
|
|
49339
|
-
const scheduleId = schedule?.id || (0,
|
|
49387
|
+
const scheduleId = schedule?.id || (0, uuid__WEBPACK_IMPORTED_MODULE_19__["default"])();
|
|
49340
49388
|
const { date: dateCond } = (0, _shared_schedules__WEBPACK_IMPORTED_MODULE_5__.extractScheduleConds)(conditions);
|
|
49341
49389
|
if (dateCond == null) {
|
|
49342
49390
|
throw new Error('A date condition is required to create a schedule');
|
|
@@ -49344,7 +49392,7 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
|
|
|
49344
49392
|
if (dateCond.value == null) {
|
|
49345
49393
|
throw new Error('Date is required');
|
|
49346
49394
|
}
|
|
49347
|
-
const nextDate = getNextDate(dateCond);
|
|
49395
|
+
const nextDate = (0, _shared_schedules__WEBPACK_IMPORTED_MODULE_5__.getNextDate)(dateCond);
|
|
49348
49396
|
const nextDateRepr = nextDate ? (0, _models__WEBPACK_IMPORTED_MODULE_12__.toDateRepr)(nextDate) : null;
|
|
49349
49397
|
if (schedule) {
|
|
49350
49398
|
if (schedule.name) {
|
|
@@ -49437,6 +49485,7 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
|
|
|
49437
49485
|
}
|
|
49438
49486
|
await _db__WEBPACK_IMPORTED_MODULE_11__.updateWithSchema('schedules', schedule);
|
|
49439
49487
|
});
|
|
49488
|
+
return schedule.id;
|
|
49440
49489
|
}
|
|
49441
49490
|
async function deleteSchedule({ id }) {
|
|
49442
49491
|
const { data: ruleId } = await (0, _aql__WEBPACK_IMPORTED_MODULE_10__.runQuery)((0, _shared_query__WEBPACK_IMPORTED_MODULE_4__.q)('schedules').filter({
|
|
@@ -49451,7 +49500,7 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
|
|
|
49451
49500
|
return setNextDate({
|
|
49452
49501
|
id,
|
|
49453
49502
|
start: (nextDate) => {
|
|
49454
|
-
return
|
|
49503
|
+
return date_fns__WEBPACK_IMPORTED_MODULE_20__["default"]((0, _shared_months__WEBPACK_IMPORTED_MODULE_3__.parseDate)(nextDate), 1);
|
|
49455
49504
|
}
|
|
49456
49505
|
});
|
|
49457
49506
|
}
|
|
@@ -49465,9 +49514,9 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
|
|
|
49465
49514
|
rrules: rules
|
|
49466
49515
|
});
|
|
49467
49516
|
return schedule.occurrences({
|
|
49468
|
-
start:
|
|
49517
|
+
start: date_fns__WEBPACK_IMPORTED_MODULE_21__["default"](new Date()),
|
|
49469
49518
|
take: count
|
|
49470
|
-
}).toArray().map((date) => config.skipWeekend ? getDateWithSkippedWeekend(date.date, config.weekendSolveMode) : date.date).map((date) => (0, _shared_months__WEBPACK_IMPORTED_MODULE_3__.dayFromDate)(date));
|
|
49519
|
+
}).toArray().map((date) => config.skipWeekend ? (0, _shared_schedules__WEBPACK_IMPORTED_MODULE_5__.getDateWithSkippedWeekend)(date.date, config.weekendSolveMode) : date.date).map((date) => (0, _shared_months__WEBPACK_IMPORTED_MODULE_3__.dayFromDate)(date));
|
|
49471
49520
|
}
|
|
49472
49521
|
catch (err) {
|
|
49473
49522
|
(0, _platform_exceptions__WEBPACK_IMPORTED_MODULE_1__.captureBreadcrumb)(config);
|
|
@@ -49551,9 +49600,8 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
|
|
|
49551
49600
|
const { data: upcomingLength } = await (0, _aql__WEBPACK_IMPORTED_MODULE_10__.runQuery)((0, _shared_query__WEBPACK_IMPORTED_MODULE_4__.q)('preferences').filter({
|
|
49552
49601
|
id: 'upcomingScheduledTransactionLength'
|
|
49553
49602
|
}).select('value'));
|
|
49554
|
-
const upcomingLengthValue = upcomingLength[0]?.value ?? '7'; // Default to 7 days if not set
|
|
49555
49603
|
for (const schedule of schedules) {
|
|
49556
|
-
const status = (0, _shared_schedules__WEBPACK_IMPORTED_MODULE_5__.getStatus)(schedule.next_date, schedule.completed, hasTrans.has(schedule.id),
|
|
49604
|
+
const status = (0, _shared_schedules__WEBPACK_IMPORTED_MODULE_5__.getStatus)(schedule.next_date, schedule.completed, hasTrans.has(schedule.id), upcomingLength[0]?.value ?? '7');
|
|
49557
49605
|
if (status === 'paid') {
|
|
49558
49606
|
if (schedule._date) {
|
|
49559
49607
|
// Move forward recurring schedules
|
|
@@ -49595,9 +49643,7 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
|
|
|
49595
49643
|
}
|
|
49596
49644
|
}
|
|
49597
49645
|
if (failedToPost.length > 0) {
|
|
49598
|
-
_platform_server_connection__WEBPACK_IMPORTED_MODULE_2__.send('schedules-offline'
|
|
49599
|
-
payees: failedToPost
|
|
49600
|
-
});
|
|
49646
|
+
_platform_server_connection__WEBPACK_IMPORTED_MODULE_2__.send('schedules-offline');
|
|
49601
49647
|
}
|
|
49602
49648
|
else if (didPost) {
|
|
49603
49649
|
// This forces a full refresh of transactions because it
|
|
@@ -49609,7 +49655,7 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
|
|
|
49609
49655
|
tables: [
|
|
49610
49656
|
'transactions'
|
|
49611
49657
|
],
|
|
49612
|
-
syncDisabled:
|
|
49658
|
+
syncDisabled: false
|
|
49613
49659
|
});
|
|
49614
49660
|
}
|
|
49615
49661
|
}
|
|
@@ -49636,20 +49682,6 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
|
|
|
49636
49682
|
}
|
|
49637
49683
|
}
|
|
49638
49684
|
});
|
|
49639
|
-
function getDateWithSkippedWeekend(date, solveMode) {
|
|
49640
|
-
if (date_fns__WEBPACK_IMPORTED_MODULE_22__["default"](date)) {
|
|
49641
|
-
if (solveMode === 'after') {
|
|
49642
|
-
return date_fns__WEBPACK_IMPORTED_MODULE_23__["default"](date);
|
|
49643
|
-
}
|
|
49644
|
-
else if (solveMode === 'before') {
|
|
49645
|
-
return date_fns__WEBPACK_IMPORTED_MODULE_24__["default"](date);
|
|
49646
|
-
}
|
|
49647
|
-
else {
|
|
49648
|
-
throw new Error('Unknown weekend solve mode, this should not happen!');
|
|
49649
|
-
}
|
|
49650
|
-
}
|
|
49651
|
-
return date;
|
|
49652
|
-
}
|
|
49653
49685
|
/***/
|
|
49654
49686
|
}),
|
|
49655
49687
|
/***/ "./packages/loot-core/src/server/schedules/find-schedules.ts":
|
|
@@ -52021,10 +52053,30 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
|
|
|
52021
52053
|
const subValue = t.subtransactions.reduce((acc, st) => acc + st.amount, 0);
|
|
52022
52054
|
return subValue !== t.amount;
|
|
52023
52055
|
});
|
|
52056
|
+
// 5. Fix transfers that should not have categories
|
|
52057
|
+
const brokenTransfers = await _db__WEBPACK_IMPORTED_MODULE_4__.all(`
|
|
52058
|
+
SELECT t1.id
|
|
52059
|
+
FROM v_transactions_internal t1
|
|
52060
|
+
JOIN accounts a1 ON t1.account = a1.id
|
|
52061
|
+
JOIN v_transactions_internal t2 ON t1.transfer_id = t2.id
|
|
52062
|
+
JOIN accounts a2 ON t2.account = a2.id
|
|
52063
|
+
WHERE a1.offbudget = a2.offbudget
|
|
52064
|
+
AND t1.category IS NOT NULL
|
|
52065
|
+
`);
|
|
52066
|
+
await (0, _mutators__WEBPACK_IMPORTED_MODULE_5__.runMutator)(async () => {
|
|
52067
|
+
const updated = brokenTransfers.map((row) => ({
|
|
52068
|
+
id: row.id,
|
|
52069
|
+
category: null
|
|
52070
|
+
}));
|
|
52071
|
+
await (0, _accounts_transactions__WEBPACK_IMPORTED_MODULE_1__.batchUpdateTransactions)({
|
|
52072
|
+
updated
|
|
52073
|
+
});
|
|
52074
|
+
});
|
|
52024
52075
|
return {
|
|
52025
52076
|
numBlankPayees: blankPayeeRows.length,
|
|
52026
52077
|
numCleared: clearedRows.length,
|
|
52027
52078
|
numDeleted: deletedRows.length,
|
|
52079
|
+
numTransfersFixed: brokenTransfers.length,
|
|
52028
52080
|
mismatchedSplits
|
|
52029
52081
|
};
|
|
52030
52082
|
});
|
|
@@ -52571,7 +52623,7 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
|
|
|
52571
52623
|
/* harmony export */ isPreviewEnvironment: () => ( /* binding */isPreviewEnvironment)
|
|
52572
52624
|
/* harmony export */
|
|
52573
52625
|
});
|
|
52574
|
-
|
|
52626
|
+
function isPreviewEnvironment() {
|
|
52575
52627
|
return String(process.env.REACT_APP_NETLIFY) === 'true';
|
|
52576
52628
|
}
|
|
52577
52629
|
function isDevelopmentEnvironment() {
|
|
@@ -52675,7 +52727,7 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
|
|
|
52675
52727
|
return (0, i18next__WEBPACK_IMPORTED_MODULE_0__.t)('This budget cannot be loaded with this version of the app.');
|
|
52676
52728
|
}
|
|
52677
52729
|
else if (error === 'budget-not-found') {
|
|
52678
|
-
return (0, i18next__WEBPACK_IMPORTED_MODULE_0__.t)('Budget “{id}” not found. Check the
|
|
52730
|
+
return (0, i18next__WEBPACK_IMPORTED_MODULE_0__.t)('Budget “{{id}}” not found. Check the ID of your budget in the Advanced section of the settings page.', {
|
|
52679
52731
|
id
|
|
52680
52732
|
});
|
|
52681
52733
|
}
|
|
@@ -52704,7 +52756,7 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
|
|
|
52704
52756
|
case 'unauthorized':
|
|
52705
52757
|
return (0, i18next__WEBPACK_IMPORTED_MODULE_0__.t)('You are not logged in.');
|
|
52706
52758
|
case 'token-expired':
|
|
52707
|
-
return (0, i18next__WEBPACK_IMPORTED_MODULE_0__.t)('Login expired, please
|
|
52759
|
+
return (0, i18next__WEBPACK_IMPORTED_MODULE_0__.t)('Login expired, please log in again.');
|
|
52708
52760
|
case 'user-cant-be-empty':
|
|
52709
52761
|
return (0, i18next__WEBPACK_IMPORTED_MODULE_0__.t)('Please select a user.');
|
|
52710
52762
|
case 'invalid-file-id':
|
|
@@ -53816,18 +53868,28 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
|
|
|
53816
53868
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
53817
53869
|
/* harmony export */ describeSchedule: () => ( /* binding */describeSchedule),
|
|
53818
53870
|
/* harmony export */ extractScheduleConds: () => ( /* binding */extractScheduleConds),
|
|
53871
|
+
/* harmony export */ getDateWithSkippedWeekend: () => ( /* binding */getDateWithSkippedWeekend),
|
|
53819
53872
|
/* harmony export */ getHasTransactionsQuery: () => ( /* binding */getHasTransactionsQuery),
|
|
53873
|
+
/* harmony export */ getNextDate: () => ( /* binding */getNextDate),
|
|
53820
53874
|
/* harmony export */ getRecurringDescription: () => ( /* binding */getRecurringDescription),
|
|
53821
53875
|
/* harmony export */ getScheduledAmount: () => ( /* binding */getScheduledAmount),
|
|
53822
53876
|
/* harmony export */ getStatus: () => ( /* binding */getStatus),
|
|
53823
|
-
/* harmony export */
|
|
53877
|
+
/* harmony export */ getUpcomingDays: () => ( /* binding */getUpcomingDays),
|
|
53878
|
+
/* harmony export */ recurConfigToRSchedule: () => ( /* binding */recurConfigToRSchedule),
|
|
53879
|
+
/* harmony export */ scheduleIsRecurring: () => ( /* binding */scheduleIsRecurring)
|
|
53824
53880
|
/* harmony export */
|
|
53825
53881
|
});
|
|
53826
|
-
/* harmony import */ var
|
|
53827
|
-
/* harmony import */ var
|
|
53882
|
+
/* harmony import */ var date_fns__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! date-fns */ "./node_modules/date-fns/esm/startOfDay/index.js");
|
|
53883
|
+
/* harmony import */ var date_fns__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! date-fns */ "./node_modules/date-fns/esm/isWeekend/index.js");
|
|
53884
|
+
/* harmony import */ var date_fns__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! date-fns */ "./node_modules/date-fns/esm/nextMonday/index.js");
|
|
53885
|
+
/* harmony import */ var date_fns__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! date-fns */ "./node_modules/date-fns/esm/previousFriday/index.js");
|
|
53886
|
+
/* harmony import */ var _server_accounts_rules__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../server/accounts/rules */ "./packages/loot-core/src/server/accounts/rules.ts");
|
|
53887
|
+
/* harmony import */ var _months__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./months */ "./packages/loot-core/src/shared/months.ts");
|
|
53888
|
+
/* harmony import */ var _query__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./query */ "./packages/loot-core/src/shared/query.ts");
|
|
53828
53889
|
// @ts-strict-ignore
|
|
53829
53890
|
function getStatus(nextDate, completed, hasTrans, upcomingLength) {
|
|
53830
|
-
const
|
|
53891
|
+
const upcomingDays = getUpcomingDays(upcomingLength);
|
|
53892
|
+
const today = _months__WEBPACK_IMPORTED_MODULE_1__.currentDay();
|
|
53831
53893
|
if (completed) {
|
|
53832
53894
|
return 'completed';
|
|
53833
53895
|
}
|
|
@@ -53837,7 +53899,7 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
|
|
|
53837
53899
|
else if (nextDate === today) {
|
|
53838
53900
|
return 'due';
|
|
53839
53901
|
}
|
|
53840
|
-
else if (nextDate > today && nextDate <=
|
|
53902
|
+
else if (nextDate > today && nextDate <= _months__WEBPACK_IMPORTED_MODULE_1__.addDays(today, upcomingDays)) {
|
|
53841
53903
|
return 'upcoming';
|
|
53842
53904
|
}
|
|
53843
53905
|
else if (nextDate < today) {
|
|
@@ -53854,12 +53916,12 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
|
|
|
53854
53916
|
$and: {
|
|
53855
53917
|
schedule: schedule.id,
|
|
53856
53918
|
date: {
|
|
53857
|
-
$gte: dateCond && dateCond.op === 'is' ? schedule.next_date :
|
|
53919
|
+
$gte: dateCond && dateCond.op === 'is' ? schedule.next_date : _months__WEBPACK_IMPORTED_MODULE_1__.subDays(schedule.next_date, 2)
|
|
53858
53920
|
}
|
|
53859
53921
|
}
|
|
53860
53922
|
};
|
|
53861
53923
|
});
|
|
53862
|
-
return (0,
|
|
53924
|
+
return (0, _query__WEBPACK_IMPORTED_MODULE_2__.q)('transactions').options({
|
|
53863
53925
|
splits: 'all'
|
|
53864
53926
|
}).filter({
|
|
53865
53927
|
$or: filters
|
|
@@ -53873,7 +53935,7 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
|
|
|
53873
53935
|
function makeNumberSuffix(num) {
|
|
53874
53936
|
// Slight abuse of date-fns to turn a number like "1" into the full
|
|
53875
53937
|
// form "1st" but formatting a date with that number
|
|
53876
|
-
return
|
|
53938
|
+
return _months__WEBPACK_IMPORTED_MODULE_1__.format(new Date(2020, 0, num, 12), 'do');
|
|
53877
53939
|
}
|
|
53878
53940
|
function prettyDayName(day) {
|
|
53879
53941
|
const days = {
|
|
@@ -53900,7 +53962,7 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
|
|
|
53900
53962
|
}
|
|
53901
53963
|
break;
|
|
53902
53964
|
case 'on_date':
|
|
53903
|
-
endModeSuffix = `, until ${
|
|
53965
|
+
endModeSuffix = `, until ${_months__WEBPACK_IMPORTED_MODULE_1__.format(config.endDate, dateFormat)}`;
|
|
53904
53966
|
break;
|
|
53905
53967
|
default:
|
|
53906
53968
|
}
|
|
@@ -53917,7 +53979,7 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
|
|
|
53917
53979
|
{
|
|
53918
53980
|
let desc = 'Every ';
|
|
53919
53981
|
desc += interval !== 1 ? `${interval} weeks` : 'week';
|
|
53920
|
-
desc += ' on ' +
|
|
53982
|
+
desc += ' on ' + _months__WEBPACK_IMPORTED_MODULE_1__.format(config.start, 'EEEE');
|
|
53921
53983
|
return desc + suffix;
|
|
53922
53984
|
}
|
|
53923
53985
|
case 'monthly':
|
|
@@ -53979,7 +54041,7 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
|
|
|
53979
54041
|
}
|
|
53980
54042
|
}
|
|
53981
54043
|
else {
|
|
53982
|
-
desc += ' on the ' +
|
|
54044
|
+
desc += ' on the ' + _months__WEBPACK_IMPORTED_MODULE_1__.format(config.start, 'do');
|
|
53983
54045
|
}
|
|
53984
54046
|
return desc + suffix;
|
|
53985
54047
|
}
|
|
@@ -53987,7 +54049,7 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
|
|
|
53987
54049
|
{
|
|
53988
54050
|
let desc = 'Every ';
|
|
53989
54051
|
desc += interval !== 1 ? `${interval} years` : 'year';
|
|
53990
|
-
desc += ' on ' +
|
|
54052
|
+
desc += ' on ' + _months__WEBPACK_IMPORTED_MODULE_1__.format(config.start, 'LLL do');
|
|
53991
54053
|
return desc + suffix;
|
|
53992
54054
|
}
|
|
53993
54055
|
default:
|
|
@@ -53996,7 +54058,7 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
|
|
|
53996
54058
|
}
|
|
53997
54059
|
function recurConfigToRSchedule(config) {
|
|
53998
54060
|
const base = {
|
|
53999
|
-
start:
|
|
54061
|
+
start: _months__WEBPACK_IMPORTED_MODULE_1__.parseDate(config.start),
|
|
54000
54062
|
// @ts-ignore: issues with https://gitlab.com/john.carroll.p/rschedule/-/issues/86
|
|
54001
54063
|
frequency: config.frequency.toUpperCase(),
|
|
54002
54064
|
byHourOfDay: [
|
|
@@ -54012,7 +54074,7 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
|
|
|
54012
54074
|
base.count = config.endOccurrences;
|
|
54013
54075
|
break;
|
|
54014
54076
|
case 'on_date':
|
|
54015
|
-
base.end =
|
|
54077
|
+
base.end = _months__WEBPACK_IMPORTED_MODULE_1__.parseDate(config.endDate);
|
|
54016
54078
|
break;
|
|
54017
54079
|
default:
|
|
54018
54080
|
}
|
|
@@ -54068,6 +54130,50 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
|
|
|
54068
54130
|
date: conditions.find((cond) => (cond.op === 'is' || cond.op === 'isapprox') && cond.field === 'date') || null
|
|
54069
54131
|
};
|
|
54070
54132
|
}
|
|
54133
|
+
function getNextDate(dateCond, start = new Date(_months__WEBPACK_IMPORTED_MODULE_1__.currentDay()), noSkipWeekend = false) {
|
|
54134
|
+
start = date_fns__WEBPACK_IMPORTED_MODULE_3__["default"](start);
|
|
54135
|
+
const cond = new _server_accounts_rules__WEBPACK_IMPORTED_MODULE_0__.Condition(dateCond.op, 'date', dateCond.value, null);
|
|
54136
|
+
const value = cond.getValue();
|
|
54137
|
+
if (value.type === 'date') {
|
|
54138
|
+
return value.date;
|
|
54139
|
+
}
|
|
54140
|
+
else if (value.type === 'recur') {
|
|
54141
|
+
let dates = value.schedule.occurrences({
|
|
54142
|
+
start,
|
|
54143
|
+
take: 1
|
|
54144
|
+
}).toArray();
|
|
54145
|
+
if (dates.length === 0) {
|
|
54146
|
+
// Could be a schedule with limited occurrences, so we try to
|
|
54147
|
+
// find the last occurrence
|
|
54148
|
+
dates = value.schedule.occurrences({
|
|
54149
|
+
reverse: true,
|
|
54150
|
+
take: 1
|
|
54151
|
+
}).toArray();
|
|
54152
|
+
}
|
|
54153
|
+
if (dates.length > 0) {
|
|
54154
|
+
let date = dates[0].date;
|
|
54155
|
+
if (value.schedule.data.skipWeekend && !noSkipWeekend) {
|
|
54156
|
+
date = getDateWithSkippedWeekend(date, value.schedule.data.weekendSolve);
|
|
54157
|
+
}
|
|
54158
|
+
return _months__WEBPACK_IMPORTED_MODULE_1__.dayFromDate(date);
|
|
54159
|
+
}
|
|
54160
|
+
}
|
|
54161
|
+
return null;
|
|
54162
|
+
}
|
|
54163
|
+
function getDateWithSkippedWeekend(date, solveMode) {
|
|
54164
|
+
if (date_fns__WEBPACK_IMPORTED_MODULE_4__["default"](date)) {
|
|
54165
|
+
if (solveMode === 'after') {
|
|
54166
|
+
return date_fns__WEBPACK_IMPORTED_MODULE_5__["default"](date);
|
|
54167
|
+
}
|
|
54168
|
+
else if (solveMode === 'before') {
|
|
54169
|
+
return date_fns__WEBPACK_IMPORTED_MODULE_6__["default"](date);
|
|
54170
|
+
}
|
|
54171
|
+
else {
|
|
54172
|
+
throw new Error('Unknown weekend solve mode, this should not happen!');
|
|
54173
|
+
}
|
|
54174
|
+
}
|
|
54175
|
+
return date;
|
|
54176
|
+
}
|
|
54071
54177
|
function getScheduledAmount(amount, inverse = false) {
|
|
54072
54178
|
// this check is temporary, and required at the moment as a schedule rule
|
|
54073
54179
|
// allows the amount condition to be deleted which causes a crash
|
|
@@ -54087,6 +54193,47 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
|
|
|
54087
54193
|
return `Next: ${schedule.next_date}`;
|
|
54088
54194
|
}
|
|
54089
54195
|
}
|
|
54196
|
+
function getUpcomingDays(upcomingLength = '7') {
|
|
54197
|
+
const today = _months__WEBPACK_IMPORTED_MODULE_1__.currentDay();
|
|
54198
|
+
const month = _months__WEBPACK_IMPORTED_MODULE_1__.getMonth(today);
|
|
54199
|
+
switch (upcomingLength) {
|
|
54200
|
+
case 'currentMonth':
|
|
54201
|
+
{
|
|
54202
|
+
const day = _months__WEBPACK_IMPORTED_MODULE_1__.getDay(today);
|
|
54203
|
+
const end = _months__WEBPACK_IMPORTED_MODULE_1__.getDay(_months__WEBPACK_IMPORTED_MODULE_1__.getMonthEnd(today));
|
|
54204
|
+
return end - day + 1;
|
|
54205
|
+
}
|
|
54206
|
+
case 'oneMonth':
|
|
54207
|
+
{
|
|
54208
|
+
return _months__WEBPACK_IMPORTED_MODULE_1__.differenceInCalendarDays(_months__WEBPACK_IMPORTED_MODULE_1__.nextMonth(month), month) + 1;
|
|
54209
|
+
}
|
|
54210
|
+
default:
|
|
54211
|
+
if (upcomingLength.includes('-')) {
|
|
54212
|
+
const [num, unit] = upcomingLength.split('-');
|
|
54213
|
+
const value = Math.max(1, parseInt(num, 10));
|
|
54214
|
+
switch (unit) {
|
|
54215
|
+
case 'day':
|
|
54216
|
+
return value;
|
|
54217
|
+
case 'week':
|
|
54218
|
+
return value * 7;
|
|
54219
|
+
case 'month':
|
|
54220
|
+
const future = _months__WEBPACK_IMPORTED_MODULE_1__.addMonths(today, value);
|
|
54221
|
+
return _months__WEBPACK_IMPORTED_MODULE_1__.differenceInCalendarDays(future, month) + 1;
|
|
54222
|
+
case 'year':
|
|
54223
|
+
const futureYear = _months__WEBPACK_IMPORTED_MODULE_1__.addYears(today, value);
|
|
54224
|
+
return _months__WEBPACK_IMPORTED_MODULE_1__.differenceInCalendarDays(futureYear, month) + 1;
|
|
54225
|
+
default:
|
|
54226
|
+
return 7;
|
|
54227
|
+
}
|
|
54228
|
+
}
|
|
54229
|
+
return parseInt(upcomingLength, 10);
|
|
54230
|
+
}
|
|
54231
|
+
}
|
|
54232
|
+
function scheduleIsRecurring(dateCond) {
|
|
54233
|
+
const cond = new _server_accounts_rules__WEBPACK_IMPORTED_MODULE_0__.Condition(dateCond.op, 'date', dateCond.value, null);
|
|
54234
|
+
const value = cond.getValue();
|
|
54235
|
+
return value.type === 'recur';
|
|
54236
|
+
}
|
|
54090
54237
|
/***/
|
|
54091
54238
|
}),
|
|
54092
54239
|
/***/ "./packages/loot-core/src/shared/transactions.ts":
|
|
@@ -54167,8 +54314,9 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
|
|
|
54167
54314
|
// Calculate the new total of split transactions and make sure
|
|
54168
54315
|
// that it equals the parent amount
|
|
54169
54316
|
const total = (trans.subtransactions || []).reduce((acc, t) => acc + num(t.amount), 0);
|
|
54317
|
+
const { error, ...rest } = trans;
|
|
54170
54318
|
return {
|
|
54171
|
-
...
|
|
54319
|
+
...rest,
|
|
54172
54320
|
error: total === num(trans.amount) ? null : SplitTransactionError(total, trans)
|
|
54173
54321
|
};
|
|
54174
54322
|
}
|
|
@@ -54348,11 +54496,10 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
|
|
|
54348
54496
|
return null;
|
|
54349
54497
|
}
|
|
54350
54498
|
else if (trans.subtransactions?.length === 1) {
|
|
54499
|
+
const { error, subtransactions, ...rest } = trans;
|
|
54351
54500
|
return {
|
|
54352
|
-
...
|
|
54353
|
-
|
|
54354
|
-
is_parent: false,
|
|
54355
|
-
error: null
|
|
54501
|
+
...rest,
|
|
54502
|
+
is_parent: false
|
|
54356
54503
|
};
|
|
54357
54504
|
}
|
|
54358
54505
|
else {
|
|
@@ -54376,8 +54523,9 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
|
|
|
54376
54523
|
const subtransactions = createSubtransactions?.(trans) || [
|
|
54377
54524
|
makeChild(trans)
|
|
54378
54525
|
];
|
|
54526
|
+
const { error, ...rest } = trans;
|
|
54379
54527
|
return {
|
|
54380
|
-
...
|
|
54528
|
+
...rest,
|
|
54381
54529
|
is_parent: true,
|
|
54382
54530
|
error: num(trans.amount) === 0 ? null : SplitTransactionError(0, trans),
|
|
54383
54531
|
subtransactions: subtransactions.map((t) => ({
|
|
@@ -54746,7 +54894,6 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
|
|
|
54746
54894
|
separatorRegex
|
|
54747
54895
|
};
|
|
54748
54896
|
}
|
|
54749
|
-
// Number utilities
|
|
54750
54897
|
// We dont use `Number.MAX_SAFE_NUMBER` and such here because those
|
|
54751
54898
|
// numbers are so large that it's not safe to convert them to floats
|
|
54752
54899
|
// (i.e. N / 100). For example, `9007199254740987 / 100 ===
|
|
@@ -54765,33 +54912,33 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
|
|
|
54765
54912
|
}
|
|
54766
54913
|
return value;
|
|
54767
54914
|
}
|
|
54768
|
-
function toRelaxedNumber(
|
|
54769
|
-
return integerToAmount(currencyToInteger(
|
|
54915
|
+
function toRelaxedNumber(currencyAmount) {
|
|
54916
|
+
return integerToAmount(currencyToInteger(currencyAmount) || 0);
|
|
54770
54917
|
}
|
|
54771
|
-
function integerToCurrency(
|
|
54772
|
-
return formatter.format(safeNumber(
|
|
54918
|
+
function integerToCurrency(integerAmount, formatter = getNumberFormat().formatter) {
|
|
54919
|
+
return formatter.format(safeNumber(integerAmount) / 100);
|
|
54773
54920
|
}
|
|
54774
|
-
function amountToCurrency(
|
|
54775
|
-
return getNumberFormat().formatter.format(
|
|
54921
|
+
function amountToCurrency(amount) {
|
|
54922
|
+
return getNumberFormat().formatter.format(amount);
|
|
54776
54923
|
}
|
|
54777
|
-
function amountToCurrencyNoDecimal(
|
|
54924
|
+
function amountToCurrencyNoDecimal(amount) {
|
|
54778
54925
|
return getNumberFormat({
|
|
54779
54926
|
...numberFormatConfig,
|
|
54780
54927
|
hideFraction: true
|
|
54781
|
-
}).formatter.format(
|
|
54928
|
+
}).formatter.format(amount);
|
|
54782
54929
|
}
|
|
54783
|
-
function currencyToAmount(
|
|
54930
|
+
function currencyToAmount(currencyAmount) {
|
|
54784
54931
|
let amount;
|
|
54785
54932
|
if (getNumberFormat().separatorRegex) {
|
|
54786
|
-
amount = parseFloat(
|
|
54933
|
+
amount = parseFloat(currencyAmount.replace(getNumberFormat().regex, '').replace(getNumberFormat().separatorRegex, '.'));
|
|
54787
54934
|
}
|
|
54788
54935
|
else {
|
|
54789
|
-
amount = parseFloat(
|
|
54936
|
+
amount = parseFloat(currencyAmount.replace(getNumberFormat().regex, '').replace(getNumberFormat().separator, '.'));
|
|
54790
54937
|
}
|
|
54791
54938
|
return isNaN(amount) ? null : amount;
|
|
54792
54939
|
}
|
|
54793
|
-
function currencyToInteger(
|
|
54794
|
-
const amount = currencyToAmount(
|
|
54940
|
+
function currencyToInteger(currencyAmount) {
|
|
54941
|
+
const amount = currencyToAmount(currencyAmount);
|
|
54795
54942
|
return amount == null ? null : amountToInteger(amount);
|
|
54796
54943
|
}
|
|
54797
54944
|
function stringToInteger(str) {
|
|
@@ -54801,11 +54948,11 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
|
|
|
54801
54948
|
}
|
|
54802
54949
|
return null;
|
|
54803
54950
|
}
|
|
54804
|
-
function amountToInteger(
|
|
54805
|
-
return Math.round(
|
|
54951
|
+
function amountToInteger(amount) {
|
|
54952
|
+
return Math.round(amount * 100);
|
|
54806
54953
|
}
|
|
54807
|
-
function integerToAmount(
|
|
54808
|
-
return parseFloat((safeNumber(
|
|
54954
|
+
function integerToAmount(integerAmount) {
|
|
54955
|
+
return parseFloat((safeNumber(integerAmount) / 100).toFixed(2));
|
|
54809
54956
|
}
|
|
54810
54957
|
// This is used when the input format could be anything (from
|
|
54811
54958
|
// financial files and we don't want to parse based on the user's
|