@things-factory/accounting 10.1.134 → 10.1.135
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/dist-client/route.d.ts +1 -1
- package/dist-client/route.js +0 -12
- package/dist-client/route.js.map +1 -1
- package/dist-client/tsconfig.tsbuildinfo +1 -1
- package/dist-server/index.d.ts +0 -1
- package/dist-server/index.js +0 -1
- package/dist-server/index.js.map +1 -1
- package/dist-server/service/account/account-history.d.ts +13 -6
- package/dist-server/service/account/account-history.js +44 -17
- package/dist-server/service/account/account-history.js.map +1 -1
- package/dist-server/service/account/account-mutation.js +2 -2
- package/dist-server/service/account/account-mutation.js.map +1 -1
- package/dist-server/service/account/account-type.d.ts +16 -0
- package/dist-server/service/account/account-type.js +71 -13
- package/dist-server/service/account/account-type.js.map +1 -1
- package/dist-server/service/account/account.d.ts +9 -3
- package/dist-server/service/account/account.js +34 -8
- package/dist-server/service/account/account.js.map +1 -1
- package/dist-server/service/accounting-category/accounting-category-mutation.js +2 -2
- package/dist-server/service/accounting-category/accounting-category-mutation.js.map +1 -1
- package/dist-server/service/accounting-document/accounting-document-mutation.js +12 -3
- package/dist-server/service/accounting-document/accounting-document-mutation.js.map +1 -1
- package/dist-server/service/accounting-document/accounting-document-query.js +2 -0
- package/dist-server/service/accounting-document/accounting-document-query.js.map +1 -1
- package/dist-server/service/bank-account/bank-account-history.d.ts +11 -14
- package/dist-server/service/bank-account/bank-account-history.js +46 -59
- package/dist-server/service/bank-account/bank-account-history.js.map +1 -1
- package/dist-server/service/bank-account/bank-account-mutation.d.ts +1 -2
- package/dist-server/service/bank-account/bank-account-mutation.js +25 -69
- package/dist-server/service/bank-account/bank-account-mutation.js.map +1 -1
- package/dist-server/service/bank-account/bank-account-query.js +2 -0
- package/dist-server/service/bank-account/bank-account-query.js.map +1 -1
- package/dist-server/service/bank-account/bank-account-service.d.ts +5 -0
- package/dist-server/service/bank-account/bank-account-service.js +21 -0
- package/dist-server/service/bank-account/bank-account-service.js.map +1 -0
- package/dist-server/service/bank-account/bank-account-type.d.ts +13 -19
- package/dist-server/service/bank-account/bank-account-type.js +45 -69
- package/dist-server/service/bank-account/bank-account-type.js.map +1 -1
- package/dist-server/service/bank-account/bank-account.d.ts +14 -17
- package/dist-server/service/bank-account/bank-account.js +45 -57
- package/dist-server/service/bank-account/bank-account.js.map +1 -1
- package/dist-server/service/bank-statement/bank-statement-query.d.ts +14 -0
- package/dist-server/service/bank-statement/bank-statement-query.js +92 -0
- package/dist-server/service/bank-statement/bank-statement-query.js.map +1 -0
- package/dist-server/service/bank-statement/bank-statement.d.ts +26 -0
- package/dist-server/service/bank-statement/bank-statement.js +109 -0
- package/dist-server/service/bank-statement/bank-statement.js.map +1 -0
- package/dist-server/service/bank-statement/index.d.ts +5 -0
- package/dist-server/service/bank-statement/index.js +9 -0
- package/dist-server/service/bank-statement/index.js.map +1 -0
- package/dist-server/service/cash-flow-type.d.ts +5 -0
- package/dist-server/service/cash-flow-type.js +15 -0
- package/dist-server/service/cash-flow-type.js.map +1 -0
- package/dist-server/service/financial-institution/financial-institution-mutation.js +10 -1
- package/dist-server/service/financial-institution/financial-institution-mutation.js.map +1 -1
- package/dist-server/service/financial-institution/financial-institution-query.js +14 -6
- package/dist-server/service/financial-institution/financial-institution-query.js.map +1 -1
- package/dist-server/service/financial-institution/index.d.ts +1 -1
- package/dist-server/service/financial-statement/financial-statement-history.d.ts +11 -9
- package/dist-server/service/financial-statement/financial-statement-history.js +47 -36
- package/dist-server/service/financial-statement/financial-statement-history.js.map +1 -1
- package/dist-server/service/financial-statement/financial-statement-line.d.ts +24 -0
- package/dist-server/service/financial-statement/financial-statement-line.js +108 -0
- package/dist-server/service/financial-statement/financial-statement-line.js.map +1 -0
- package/dist-server/service/financial-statement/financial-statement-mutation.d.ts +1 -8
- package/dist-server/service/financial-statement/financial-statement-mutation.js +10 -135
- package/dist-server/service/financial-statement/financial-statement-mutation.js.map +1 -1
- package/dist-server/service/financial-statement/financial-statement-query.d.ts +8 -7
- package/dist-server/service/financial-statement/financial-statement-query.js +40 -30
- package/dist-server/service/financial-statement/financial-statement-query.js.map +1 -1
- package/dist-server/service/financial-statement/financial-statement-service.d.ts +33 -0
- package/dist-server/service/financial-statement/financial-statement-service.js +44 -0
- package/dist-server/service/financial-statement/financial-statement-service.js.map +1 -0
- package/dist-server/service/financial-statement/financial-statement.d.ts +19 -11
- package/dist-server/service/financial-statement/financial-statement.js +73 -65
- package/dist-server/service/financial-statement/financial-statement.js.map +1 -1
- package/dist-server/service/financial-statement/index.d.ts +3 -2
- package/dist-server/service/financial-statement/index.js +2 -2
- package/dist-server/service/financial-statement/index.js.map +1 -1
- package/dist-server/service/index.d.ts +15 -3
- package/dist-server/service/index.js +30 -13
- package/dist-server/service/index.js.map +1 -1
- package/dist-server/service/payment/index.d.ts +1 -0
- package/dist-server/service/payment/index.js +1 -0
- package/dist-server/service/payment/index.js.map +1 -1
- package/dist-server/service/payment/payment-history.d.ts +9 -16
- package/dist-server/service/payment/payment-history.js +36 -70
- package/dist-server/service/payment/payment-history.js.map +1 -1
- package/dist-server/service/payment/payment-mutation.d.ts +0 -1
- package/dist-server/service/payment/payment-mutation.js +14 -79
- package/dist-server/service/payment/payment-mutation.js.map +1 -1
- package/dist-server/service/payment/payment-query.d.ts +3 -0
- package/dist-server/service/payment/payment-query.js +30 -1
- package/dist-server/service/payment/payment-query.js.map +1 -1
- package/dist-server/service/payment/payment-service.d.ts +16 -0
- package/dist-server/service/payment/payment-service.js +140 -0
- package/dist-server/service/payment/payment-service.js.map +1 -0
- package/dist-server/service/payment/payment-targets.d.ts +31 -0
- package/dist-server/service/payment/payment-targets.js +19 -0
- package/dist-server/service/payment/payment-targets.js.map +1 -0
- package/dist-server/service/payment/payment-type.d.ts +13 -17
- package/dist-server/service/payment/payment-type.js +35 -51
- package/dist-server/service/payment/payment-type.js.map +1 -1
- package/dist-server/service/payment/payment.d.ts +23 -22
- package/dist-server/service/payment/payment.js +66 -94
- package/dist-server/service/payment/payment.js.map +1 -1
- package/dist-server/service/payment/transfer-target.d.ts +1 -0
- package/dist-server/service/payment/transfer-target.js +43 -0
- package/dist-server/service/payment/transfer-target.js.map +1 -0
- package/dist-server/service/recurring-cash-item/index.d.ts +6 -0
- package/dist-server/service/recurring-cash-item/index.js +10 -0
- package/dist-server/service/recurring-cash-item/index.js.map +1 -0
- package/dist-server/service/recurring-cash-item/recurring-cash-item-mutation.d.ts +7 -0
- package/dist-server/service/recurring-cash-item/recurring-cash-item-mutation.js +63 -0
- package/dist-server/service/recurring-cash-item/recurring-cash-item-mutation.js.map +1 -0
- package/dist-server/service/recurring-cash-item/recurring-cash-item-query.d.ts +15 -0
- package/dist-server/service/recurring-cash-item/recurring-cash-item-query.js +101 -0
- package/dist-server/service/recurring-cash-item/recurring-cash-item-query.js.map +1 -0
- package/dist-server/service/recurring-cash-item/recurring-cash-item-service.d.ts +23 -0
- package/dist-server/service/recurring-cash-item/recurring-cash-item-service.js +91 -0
- package/dist-server/service/recurring-cash-item/recurring-cash-item-service.js.map +1 -0
- package/dist-server/service/recurring-cash-item/recurring-cash-item-type.d.ts +23 -0
- package/dist-server/service/recurring-cash-item/recurring-cash-item-type.js +85 -0
- package/dist-server/service/recurring-cash-item/recurring-cash-item-type.js.map +1 -0
- package/dist-server/service/recurring-cash-item/recurring-cash-item.d.ts +35 -0
- package/dist-server/service/recurring-cash-item/recurring-cash-item.js +142 -0
- package/dist-server/service/recurring-cash-item/recurring-cash-item.js.map +1 -0
- package/dist-server/service/recurring-cash-item/recurring-schedule.d.ts +36 -0
- package/dist-server/service/recurring-cash-item/recurring-schedule.js +41 -0
- package/dist-server/service/recurring-cash-item/recurring-schedule.js.map +1 -0
- package/dist-server/service/transaction/transaction-history.d.ts +42 -15
- package/dist-server/service/transaction/transaction-history.js +160 -54
- package/dist-server/service/transaction/transaction-history.js.map +1 -1
- package/dist-server/service/transaction/transaction-mutation.d.ts +0 -1
- package/dist-server/service/transaction/transaction-mutation.js +13 -78
- package/dist-server/service/transaction/transaction-mutation.js.map +1 -1
- package/dist-server/service/transaction/transaction-period.d.ts +16 -0
- package/dist-server/service/transaction/transaction-period.js +49 -0
- package/dist-server/service/transaction/transaction-period.js.map +1 -0
- package/dist-server/service/transaction/transaction-query.d.ts +12 -0
- package/dist-server/service/transaction/transaction-query.js +84 -2
- package/dist-server/service/transaction/transaction-query.js.map +1 -1
- package/dist-server/service/transaction/transaction-service.d.ts +30 -0
- package/dist-server/service/transaction/transaction-service.js +130 -0
- package/dist-server/service/transaction/transaction-service.js.map +1 -0
- package/dist-server/service/transaction/transaction-type.d.ts +39 -7
- package/dist-server/service/transaction/transaction-type.js +145 -23
- package/dist-server/service/transaction/transaction-type.js.map +1 -1
- package/dist-server/service/transaction/transaction.d.ts +58 -31
- package/dist-server/service/transaction/transaction.js +216 -102
- package/dist-server/service/transaction/transaction.js.map +1 -1
- package/dist-server/tsconfig.tsbuildinfo +1 -1
- package/package.json +5 -3
- package/things-factory.config.js +0 -4
- package/translations/en.json +34 -2
- package/translations/ja.json +0 -1
- package/translations/ko.json +34 -2
- package/translations/ms.json +0 -1
- package/translations/zh.json +0 -1
- package/dist-client/pages/account/account-importer.d.ts +0 -22
- package/dist-client/pages/account/account-importer.js +0 -99
- package/dist-client/pages/account/account-importer.js.map +0 -1
- package/dist-client/pages/account/account-list-page.d.ts +0 -57
- package/dist-client/pages/account/account-list-page.js +0 -306
- package/dist-client/pages/account/account-list-page.js.map +0 -1
- package/dist-client/pages/bank-account/bank-account-importer.d.ts +0 -23
- package/dist-client/pages/bank-account/bank-account-importer.js +0 -92
- package/dist-client/pages/bank-account/bank-account-importer.js.map +0 -1
- package/dist-client/pages/bank-account/bank-account-list-page.d.ts +0 -60
- package/dist-client/pages/bank-account/bank-account-list-page.js +0 -317
- package/dist-client/pages/bank-account/bank-account-list-page.js.map +0 -1
- package/dist-client/pages/financial-statement/financial-statement-importer.d.ts +0 -22
- package/dist-client/pages/financial-statement/financial-statement-importer.js +0 -99
- package/dist-client/pages/financial-statement/financial-statement-importer.js.map +0 -1
- package/dist-client/pages/financial-statement/financial-statement-list-page.d.ts +0 -57
- package/dist-client/pages/financial-statement/financial-statement-list-page.js +0 -280
- package/dist-client/pages/financial-statement/financial-statement-list-page.js.map +0 -1
- package/dist-client/pages/income-statement/income-statement-importer.d.ts +0 -22
- package/dist-client/pages/income-statement/income-statement-importer.js +0 -99
- package/dist-client/pages/income-statement/income-statement-importer.js.map +0 -1
- package/dist-client/pages/income-statement/income-statement-list-page.d.ts +0 -57
- package/dist-client/pages/income-statement/income-statement-list-page.js +0 -280
- package/dist-client/pages/income-statement/income-statement-list-page.js.map +0 -1
- package/dist-client/pages/payment/payment-importer.d.ts +0 -23
- package/dist-client/pages/payment/payment-importer.js +0 -92
- package/dist-client/pages/payment/payment-importer.js.map +0 -1
- package/dist-client/pages/payment/payment-list-page.d.ts +0 -60
- package/dist-client/pages/payment/payment-list-page.js +0 -317
- package/dist-client/pages/payment/payment-list-page.js.map +0 -1
- package/dist-client/pages/transaction/transaction-importer.d.ts +0 -22
- package/dist-client/pages/transaction/transaction-importer.js +0 -99
- package/dist-client/pages/transaction/transaction-importer.js.map +0 -1
- package/dist-client/pages/transaction/transaction-list-page.d.ts +0 -57
- package/dist-client/pages/transaction/transaction-list-page.js +0 -280
- package/dist-client/pages/transaction/transaction-list-page.js.map +0 -1
- package/dist-server/controllers/index.d.ts +0 -1
- package/dist-server/controllers/index.js +0 -5
- package/dist-server/controllers/index.js.map +0 -1
- package/dist-server/controllers/summary-statements.d.ts +0 -4
- package/dist-server/controllers/summary-statements.js +0 -149
- package/dist-server/controllers/summary-statements.js.map +0 -1
- package/dist-server/migrations/1725201567284-seed-country-codes.d.ts +0 -5
- package/dist-server/migrations/1725201567284-seed-country-codes.js +0 -255
- package/dist-server/migrations/1725201567284-seed-country-codes.js.map +0 -1
- package/dist-server/service/financial-statement/financial-statement-line-item.d.ts +0 -19
- package/dist-server/service/financial-statement/financial-statement-line-item.js +0 -95
- package/dist-server/service/financial-statement/financial-statement-line-item.js.map +0 -1
- package/dist-server/service/financial-statement/financial-statement-type.d.ts +0 -20
- package/dist-server/service/financial-statement/financial-statement-type.js +0 -77
- package/dist-server/service/financial-statement/financial-statement-type.js.map +0 -1
- package/dist-server/service/income-statement/event-subscriber.d.ts +0 -7
- package/dist-server/service/income-statement/event-subscriber.js +0 -21
- package/dist-server/service/income-statement/event-subscriber.js.map +0 -1
- package/dist-server/service/income-statement/income-statement-history.d.ts +0 -28
- package/dist-server/service/income-statement/income-statement-history.js +0 -146
- package/dist-server/service/income-statement/income-statement-history.js.map +0 -1
- package/dist-server/service/income-statement/income-statement-line-item.d.ts +0 -19
- package/dist-server/service/income-statement/income-statement-line-item.js +0 -97
- package/dist-server/service/income-statement/income-statement-line-item.js.map +0 -1
- package/dist-server/service/income-statement/income-statement-mutation.d.ts +0 -10
- package/dist-server/service/income-statement/income-statement-mutation.js +0 -159
- package/dist-server/service/income-statement/income-statement-mutation.js.map +0 -1
- package/dist-server/service/income-statement/income-statement-query.d.ts +0 -11
- package/dist-server/service/income-statement/income-statement-query.js +0 -81
- package/dist-server/service/income-statement/income-statement-query.js.map +0 -1
- package/dist-server/service/income-statement/income-statement-type.d.ts +0 -20
- package/dist-server/service/income-statement/income-statement-type.js +0 -77
- package/dist-server/service/income-statement/income-statement-type.js.map +0 -1
- package/dist-server/service/income-statement/income-statement.d.ts +0 -28
- package/dist-server/service/income-statement/income-statement.js +0 -137
- package/dist-server/service/income-statement/income-statement.js.map +0 -1
- package/dist-server/service/income-statement/index.d.ts +0 -8
- package/dist-server/service/income-statement/index.js +0 -13
- package/dist-server/service/income-statement/index.js.map +0 -1
|
@@ -1,10 +1,22 @@
|
|
|
1
1
|
import { Domain, ListParam } from '@things-factory/shell';
|
|
2
2
|
import { User } from '@things-factory/auth-base';
|
|
3
|
+
import { Counterparty } from '@things-factory/biz-base';
|
|
4
|
+
import { Account } from '../account/account';
|
|
5
|
+
import { BankAccount } from '../bank-account/bank-account';
|
|
6
|
+
import { BankStatement } from '../bank-statement/bank-statement';
|
|
7
|
+
import { Payment } from '../payment/payment';
|
|
8
|
+
import { RecurringCashItem } from '../recurring-cash-item/recurring-cash-item';
|
|
3
9
|
import { Transaction } from './transaction';
|
|
4
10
|
import { TransactionList } from './transaction-type';
|
|
5
11
|
export declare class TransactionQuery {
|
|
6
12
|
transaction(id: string, context: ResolverContext): Promise<Transaction>;
|
|
7
13
|
transactions(params: ListParam, context: ResolverContext): Promise<TransactionList>;
|
|
14
|
+
bankAccount(transaction: Transaction): Promise<BankAccount | null>;
|
|
15
|
+
account(transaction: Transaction): Promise<Account | null>;
|
|
16
|
+
counterparty(transaction: Transaction): Promise<Counterparty | null>;
|
|
17
|
+
bankStatement(transaction: Transaction): Promise<BankStatement | null>;
|
|
18
|
+
recurringItem(transaction: Transaction): Promise<RecurringCashItem | null>;
|
|
19
|
+
payments(transaction: Transaction): Promise<Payment[]>;
|
|
8
20
|
domain(transaction: Transaction): Promise<Domain>;
|
|
9
21
|
updater(transaction: Transaction): Promise<User>;
|
|
10
22
|
creator(transaction: Transaction): Promise<User>;
|
|
@@ -5,6 +5,12 @@ const tslib_1 = require("tslib");
|
|
|
5
5
|
const type_graphql_1 = require("type-graphql");
|
|
6
6
|
const shell_1 = require("@things-factory/shell");
|
|
7
7
|
const auth_base_1 = require("@things-factory/auth-base");
|
|
8
|
+
const biz_base_1 = require("@things-factory/biz-base");
|
|
9
|
+
const account_1 = require("../account/account");
|
|
10
|
+
const bank_account_1 = require("../bank-account/bank-account");
|
|
11
|
+
const bank_statement_1 = require("../bank-statement/bank-statement");
|
|
12
|
+
const payment_1 = require("../payment/payment");
|
|
13
|
+
const recurring_cash_item_1 = require("../recurring-cash-item/recurring-cash-item");
|
|
8
14
|
const transaction_1 = require("./transaction");
|
|
9
15
|
const transaction_type_1 = require("./transaction-type");
|
|
10
16
|
let TransactionQuery = class TransactionQuery {
|
|
@@ -20,11 +26,45 @@ let TransactionQuery = class TransactionQuery {
|
|
|
20
26
|
domain,
|
|
21
27
|
params,
|
|
22
28
|
repository: await (0, shell_1.getRepository)(transaction_1.Transaction),
|
|
23
|
-
searchables: [
|
|
29
|
+
searchables: [
|
|
30
|
+
'description',
|
|
31
|
+
'counterpartyName',
|
|
32
|
+
'ledgerCategory',
|
|
33
|
+
'bankDescription',
|
|
34
|
+
'bankCounterpartyName',
|
|
35
|
+
'bankMemo',
|
|
36
|
+
'notes'
|
|
37
|
+
]
|
|
24
38
|
});
|
|
25
39
|
const [items, total] = await queryBuilder.getManyAndCount();
|
|
26
40
|
return { items, total };
|
|
27
41
|
}
|
|
42
|
+
async bankAccount(transaction) {
|
|
43
|
+
return transaction.bankAccountId
|
|
44
|
+
? await (0, shell_1.getRepository)(bank_account_1.BankAccount).findOneBy({ id: transaction.bankAccountId })
|
|
45
|
+
: null;
|
|
46
|
+
}
|
|
47
|
+
async account(transaction) {
|
|
48
|
+
return transaction.accountId ? await (0, shell_1.getRepository)(account_1.Account).findOneBy({ id: transaction.accountId }) : null;
|
|
49
|
+
}
|
|
50
|
+
async counterparty(transaction) {
|
|
51
|
+
return transaction.counterpartyId
|
|
52
|
+
? await (0, shell_1.getRepository)(biz_base_1.Counterparty).findOneBy({ id: transaction.counterpartyId })
|
|
53
|
+
: null;
|
|
54
|
+
}
|
|
55
|
+
async bankStatement(transaction) {
|
|
56
|
+
return transaction.bankStatementId
|
|
57
|
+
? await (0, shell_1.getRepository)(bank_statement_1.BankStatement).findOneBy({ id: transaction.bankStatementId })
|
|
58
|
+
: null;
|
|
59
|
+
}
|
|
60
|
+
async recurringItem(transaction) {
|
|
61
|
+
return transaction.recurringItemId
|
|
62
|
+
? await (0, shell_1.getRepository)(recurring_cash_item_1.RecurringCashItem).findOneBy({ id: transaction.recurringItemId })
|
|
63
|
+
: null;
|
|
64
|
+
}
|
|
65
|
+
async payments(transaction) {
|
|
66
|
+
return await (0, shell_1.getRepository)(payment_1.Payment).find({ where: { transaction: { id: transaction.id } } });
|
|
67
|
+
}
|
|
28
68
|
async domain(transaction) {
|
|
29
69
|
return await (0, shell_1.getRepository)(shell_1.Domain).findOneBy({ id: transaction.domainId });
|
|
30
70
|
}
|
|
@@ -48,12 +88,54 @@ tslib_1.__decorate([
|
|
|
48
88
|
tslib_1.__decorate([
|
|
49
89
|
(0, type_graphql_1.Directive)('@privilege(category: "accounting", privilege: "query", domainOwnerGranted: true)'),
|
|
50
90
|
(0, type_graphql_1.Query)(returns => transaction_type_1.TransactionList, { description: 'To fetch multiple Transactions' }),
|
|
51
|
-
tslib_1.__param(0, (0, type_graphql_1.Args)()),
|
|
91
|
+
tslib_1.__param(0, (0, type_graphql_1.Args)(type => shell_1.ListParam)),
|
|
52
92
|
tslib_1.__param(1, (0, type_graphql_1.Ctx)()),
|
|
53
93
|
tslib_1.__metadata("design:type", Function),
|
|
54
94
|
tslib_1.__metadata("design:paramtypes", [shell_1.ListParam, Object]),
|
|
55
95
|
tslib_1.__metadata("design:returntype", Promise)
|
|
56
96
|
], TransactionQuery.prototype, "transactions", null);
|
|
97
|
+
tslib_1.__decorate([
|
|
98
|
+
(0, type_graphql_1.FieldResolver)(type => bank_account_1.BankAccount, { nullable: true }),
|
|
99
|
+
tslib_1.__param(0, (0, type_graphql_1.Root)()),
|
|
100
|
+
tslib_1.__metadata("design:type", Function),
|
|
101
|
+
tslib_1.__metadata("design:paramtypes", [transaction_1.Transaction]),
|
|
102
|
+
tslib_1.__metadata("design:returntype", Promise)
|
|
103
|
+
], TransactionQuery.prototype, "bankAccount", null);
|
|
104
|
+
tslib_1.__decorate([
|
|
105
|
+
(0, type_graphql_1.FieldResolver)(type => account_1.Account, { nullable: true }),
|
|
106
|
+
tslib_1.__param(0, (0, type_graphql_1.Root)()),
|
|
107
|
+
tslib_1.__metadata("design:type", Function),
|
|
108
|
+
tslib_1.__metadata("design:paramtypes", [transaction_1.Transaction]),
|
|
109
|
+
tslib_1.__metadata("design:returntype", Promise)
|
|
110
|
+
], TransactionQuery.prototype, "account", null);
|
|
111
|
+
tslib_1.__decorate([
|
|
112
|
+
(0, type_graphql_1.FieldResolver)(type => biz_base_1.Counterparty, { nullable: true }),
|
|
113
|
+
tslib_1.__param(0, (0, type_graphql_1.Root)()),
|
|
114
|
+
tslib_1.__metadata("design:type", Function),
|
|
115
|
+
tslib_1.__metadata("design:paramtypes", [transaction_1.Transaction]),
|
|
116
|
+
tslib_1.__metadata("design:returntype", Promise)
|
|
117
|
+
], TransactionQuery.prototype, "counterparty", null);
|
|
118
|
+
tslib_1.__decorate([
|
|
119
|
+
(0, type_graphql_1.FieldResolver)(type => bank_statement_1.BankStatement, { nullable: true }),
|
|
120
|
+
tslib_1.__param(0, (0, type_graphql_1.Root)()),
|
|
121
|
+
tslib_1.__metadata("design:type", Function),
|
|
122
|
+
tslib_1.__metadata("design:paramtypes", [transaction_1.Transaction]),
|
|
123
|
+
tslib_1.__metadata("design:returntype", Promise)
|
|
124
|
+
], TransactionQuery.prototype, "bankStatement", null);
|
|
125
|
+
tslib_1.__decorate([
|
|
126
|
+
(0, type_graphql_1.FieldResolver)(type => recurring_cash_item_1.RecurringCashItem, { nullable: true }),
|
|
127
|
+
tslib_1.__param(0, (0, type_graphql_1.Root)()),
|
|
128
|
+
tslib_1.__metadata("design:type", Function),
|
|
129
|
+
tslib_1.__metadata("design:paramtypes", [transaction_1.Transaction]),
|
|
130
|
+
tslib_1.__metadata("design:returntype", Promise)
|
|
131
|
+
], TransactionQuery.prototype, "recurringItem", null);
|
|
132
|
+
tslib_1.__decorate([
|
|
133
|
+
(0, type_graphql_1.FieldResolver)(type => [payment_1.Payment]),
|
|
134
|
+
tslib_1.__param(0, (0, type_graphql_1.Root)()),
|
|
135
|
+
tslib_1.__metadata("design:type", Function),
|
|
136
|
+
tslib_1.__metadata("design:paramtypes", [transaction_1.Transaction]),
|
|
137
|
+
tslib_1.__metadata("design:returntype", Promise)
|
|
138
|
+
], TransactionQuery.prototype, "payments", null);
|
|
57
139
|
tslib_1.__decorate([
|
|
58
140
|
(0, type_graphql_1.FieldResolver)(type => shell_1.Domain),
|
|
59
141
|
tslib_1.__param(0, (0, type_graphql_1.Root)()),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transaction-query.js","sourceRoot":"","sources":["../../../server/service/transaction/transaction-query.ts"],"names":[],"mappings":";;;;AAAA,+CAA8F;
|
|
1
|
+
{"version":3,"file":"transaction-query.js","sourceRoot":"","sources":["../../../server/service/transaction/transaction-query.ts"],"names":[],"mappings":"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","sourcesContent":["import { Resolver, Query, FieldResolver, Root, Args, Arg, Ctx, Directive } from 'type-graphql'\n\nimport { Domain, getQueryBuilderFromListParams, getRepository, ListParam } from '@things-factory/shell'\nimport { User } from '@things-factory/auth-base'\nimport { Counterparty } from '@things-factory/biz-base'\n\nimport { Account } from '../account/account'\nimport { BankAccount } from '../bank-account/bank-account'\nimport { BankStatement } from '../bank-statement/bank-statement'\nimport { Payment } from '../payment/payment'\nimport { RecurringCashItem } from '../recurring-cash-item/recurring-cash-item'\nimport { Transaction } from './transaction'\nimport { TransactionList } from './transaction-type'\n\n@Resolver(Transaction)\nexport class TransactionQuery {\n @Directive('@privilege(category: \"accounting\", privilege: \"query\", domainOwnerGranted: true)')\n @Query(returns => Transaction!, { nullable: true, description: 'To fetch a Transaction' })\n async transaction(@Arg('id') id: string, @Ctx() context: ResolverContext): Promise<Transaction> {\n const { domain } = context.state\n\n return await getRepository(Transaction).findOne({\n where: { domain: { id: domain.id }, id }\n })\n }\n\n @Directive('@privilege(category: \"accounting\", privilege: \"query\", domainOwnerGranted: true)')\n @Query(returns => TransactionList, { description: 'To fetch multiple Transactions' })\n async transactions(\n @Args(type => ListParam) params: ListParam,\n @Ctx() context: ResolverContext\n ): Promise<TransactionList> {\n const { domain } = context.state\n\n const queryBuilder = getQueryBuilderFromListParams({\n domain,\n params,\n repository: await getRepository(Transaction),\n searchables: [\n 'description',\n 'counterpartyName',\n 'ledgerCategory',\n 'bankDescription',\n 'bankCounterpartyName',\n 'bankMemo',\n 'notes'\n ]\n })\n\n const [items, total] = await queryBuilder.getManyAndCount()\n\n return { items, total }\n }\n\n @FieldResolver(type => BankAccount, { nullable: true })\n async bankAccount(@Root() transaction: Transaction): Promise<BankAccount | null> {\n return transaction.bankAccountId\n ? await getRepository(BankAccount).findOneBy({ id: transaction.bankAccountId })\n : null\n }\n\n @FieldResolver(type => Account, { nullable: true })\n async account(@Root() transaction: Transaction): Promise<Account | null> {\n return transaction.accountId ? await getRepository(Account).findOneBy({ id: transaction.accountId }) : null\n }\n\n @FieldResolver(type => Counterparty, { nullable: true })\n async counterparty(@Root() transaction: Transaction): Promise<Counterparty | null> {\n return transaction.counterpartyId\n ? await getRepository(Counterparty).findOneBy({ id: transaction.counterpartyId })\n : null\n }\n\n @FieldResolver(type => BankStatement, { nullable: true })\n async bankStatement(@Root() transaction: Transaction): Promise<BankStatement | null> {\n return transaction.bankStatementId\n ? await getRepository(BankStatement).findOneBy({ id: transaction.bankStatementId })\n : null\n }\n\n @FieldResolver(type => RecurringCashItem, { nullable: true })\n async recurringItem(@Root() transaction: Transaction): Promise<RecurringCashItem | null> {\n return transaction.recurringItemId\n ? await getRepository(RecurringCashItem).findOneBy({ id: transaction.recurringItemId })\n : null\n }\n\n @FieldResolver(type => [Payment])\n async payments(@Root() transaction: Transaction): Promise<Payment[]> {\n return await getRepository(Payment).find({ where: { transaction: { id: transaction.id } } })\n }\n\n @FieldResolver(type => Domain)\n async domain(@Root() transaction: Transaction): Promise<Domain> {\n return await getRepository(Domain).findOneBy({ id: transaction.domainId })\n }\n\n @FieldResolver(type => User)\n async updater(@Root() transaction: Transaction): Promise<User> {\n return await getRepository(User).findOneBy({ id: transaction.updaterId })\n }\n\n @FieldResolver(type => User)\n async creator(@Root() transaction: Transaction): Promise<User> {\n return await getRepository(User).findOneBy({ id: transaction.creatorId })\n }\n}\n"]}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { EntityManager } from 'typeorm';
|
|
2
|
+
import { Transaction } from './transaction';
|
|
3
|
+
/** A transaction as a module writes it: what a person may write, and the facts a bank statement gives. */
|
|
4
|
+
export type TransactionInput = Partial<Omit<Transaction, 'bankAccount' | 'account' | 'counterparty' | 'recurringItem' | 'bankStatement'>> & {
|
|
5
|
+
id?: string;
|
|
6
|
+
cuFlag?: string;
|
|
7
|
+
bankAccount?: {
|
|
8
|
+
id: string;
|
|
9
|
+
} | null;
|
|
10
|
+
account?: {
|
|
11
|
+
id: string;
|
|
12
|
+
} | null;
|
|
13
|
+
counterparty?: {
|
|
14
|
+
id: string;
|
|
15
|
+
} | null;
|
|
16
|
+
recurringItem?: {
|
|
17
|
+
id: string;
|
|
18
|
+
} | null;
|
|
19
|
+
bankStatement?: {
|
|
20
|
+
id: string;
|
|
21
|
+
} | null;
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Apply rows to a domain's transactions: `+` (or no id) adds, `M` changes, `-` deletes (softly - a financial row
|
|
25
|
+
* that was deleted stays readable). A transaction that pays something, or is paid, is unlinked before it is
|
|
26
|
+
* deleted; when its money changes, its payments are checked again - the general rule and each target kind's own.
|
|
27
|
+
*/
|
|
28
|
+
export declare function saveTransactions(tx: EntityManager, domain: {
|
|
29
|
+
id: string;
|
|
30
|
+
}, user: any, inputs: TransactionInput[]): Promise<Transaction[]>;
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.saveTransactions = saveTransactions;
|
|
4
|
+
const typeorm_1 = require("typeorm");
|
|
5
|
+
const shell_1 = require("@things-factory/shell");
|
|
6
|
+
const bank_account_1 = require("../bank-account/bank-account");
|
|
7
|
+
const cash_flow_type_1 = require("../cash-flow-type");
|
|
8
|
+
const payment_1 = require("../payment/payment");
|
|
9
|
+
const payment_service_1 = require("../payment/payment-service");
|
|
10
|
+
const payment_targets_1 = require("../payment/payment-targets");
|
|
11
|
+
const transaction_1 = require("./transaction");
|
|
12
|
+
const transaction_period_1 = require("./transaction-period");
|
|
13
|
+
/** What changes the money of a transaction - its payments are checked again when one of these changes. */
|
|
14
|
+
const MONEY = ['amount', 'type', 'currency'];
|
|
15
|
+
/**
|
|
16
|
+
* The row a patch writes over the current one: a confirmed transaction has a day and takes its year and month from it;
|
|
17
|
+
* a forecast has a year and a month, and the day its timing names.
|
|
18
|
+
*/
|
|
19
|
+
function rowOf(input, current) {
|
|
20
|
+
const { id, cuFlag, ...fields } = input;
|
|
21
|
+
const row = { ...fields };
|
|
22
|
+
const merged = { ...current, ...row };
|
|
23
|
+
const category = merged.category ?? transaction_1.TransactionCategory.CONFIRMED;
|
|
24
|
+
row.category = category;
|
|
25
|
+
if (!current && !row.type)
|
|
26
|
+
throw new shell_1.Refusal('transaction-type-required', {}, 'type: money in or money out');
|
|
27
|
+
if (row.type !== undefined && !Object.values(cash_flow_type_1.CashFlowType).includes(row.type))
|
|
28
|
+
throw new shell_1.Refusal('transaction-type-required', {}, 'type: money in or money out');
|
|
29
|
+
if (!current && (row.amount === undefined || row.amount === null))
|
|
30
|
+
row.amount = 0;
|
|
31
|
+
if (category === transaction_1.TransactionCategory.CONFIRMED) {
|
|
32
|
+
const period = (0, transaction_period_1.yearMonthOf)(merged.transactionDate);
|
|
33
|
+
if (!period)
|
|
34
|
+
throw new shell_1.Refusal('transaction-date-required', { value: merged.transactionDate ?? '' }, 'transactionDate: YYYY-MM-DD');
|
|
35
|
+
Object.assign(row, period, { status: null });
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
const [year, month] = [Number(merged.year), Number(merged.month)];
|
|
39
|
+
if (!year)
|
|
40
|
+
throw new shell_1.Refusal('forecast-year-required', {}, 'year: the year it is planned in');
|
|
41
|
+
if (!(month >= 1 && month <= 12))
|
|
42
|
+
throw new shell_1.Refusal('month-out-of-range', { month: merged.month ?? '' }, 'month: must be 1 to 12');
|
|
43
|
+
if (!String(merged.description ?? '').trim())
|
|
44
|
+
throw new shell_1.Refusal('forecast-description-required', {}, 'description: what is planned');
|
|
45
|
+
Object.assign(row, { year, month, transactionDate: (0, transaction_period_1.forecastDay)(year, month, merged.timing) });
|
|
46
|
+
if (!merged.status)
|
|
47
|
+
row.status = transaction_1.ForecastStatus.PLANNED;
|
|
48
|
+
}
|
|
49
|
+
if (merged.probability !== undefined &&
|
|
50
|
+
merged.probability !== null &&
|
|
51
|
+
!(merged.probability >= 0 && merged.probability <= 100)) {
|
|
52
|
+
throw new shell_1.Refusal('probability-out-of-range', {}, 'probability: must be 0 to 100');
|
|
53
|
+
}
|
|
54
|
+
return row;
|
|
55
|
+
}
|
|
56
|
+
/** The payments on these transactions, and the transfers into them, by target kind. */
|
|
57
|
+
async function paymentsOn(tx, domain, ids) {
|
|
58
|
+
if (!ids.length)
|
|
59
|
+
return [];
|
|
60
|
+
const repo = tx.getRepository(payment_1.Payment);
|
|
61
|
+
return [
|
|
62
|
+
...(await repo.find({
|
|
63
|
+
where: { domain: { id: domain.id }, transaction: { id: (0, typeorm_1.In)(ids) } },
|
|
64
|
+
relations: ['transaction']
|
|
65
|
+
})),
|
|
66
|
+
...(await repo.find({
|
|
67
|
+
where: { domain: { id: domain.id }, targetType: 'Transaction', targetId: (0, typeorm_1.In)(ids) },
|
|
68
|
+
relations: ['transaction']
|
|
69
|
+
}))
|
|
70
|
+
];
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Apply rows to a domain's transactions: `+` (or no id) adds, `M` changes, `-` deletes (softly - a financial row
|
|
74
|
+
* that was deleted stays readable). A transaction that pays something, or is paid, is unlinked before it is
|
|
75
|
+
* deleted; when its money changes, its payments are checked again - the general rule and each target kind's own.
|
|
76
|
+
*/
|
|
77
|
+
async function saveTransactions(tx, domain, user, inputs) {
|
|
78
|
+
const repo = tx.getRepository(transaction_1.Transaction);
|
|
79
|
+
const deletes = [...new Set(inputs.filter(one => one.cuFlag === '-' && one.id).map(one => one.id))];
|
|
80
|
+
if (deletes.length) {
|
|
81
|
+
const found = await repo.find({ where: { domain: { id: domain.id }, id: (0, typeorm_1.In)(deletes) } });
|
|
82
|
+
if (found.length !== deletes.length)
|
|
83
|
+
throw new shell_1.Refusal('transaction-not-found', {}, 'a transaction was not found - reload and try again');
|
|
84
|
+
if ((await paymentsOn(tx, domain, deletes)).length)
|
|
85
|
+
throw new shell_1.Refusal('transaction-has-payments', {}, 'unlink what the transaction paid before deleting it');
|
|
86
|
+
await repo.softRemove(found);
|
|
87
|
+
}
|
|
88
|
+
const saved = [];
|
|
89
|
+
const moneyChanged = [];
|
|
90
|
+
for (const input of inputs.filter(one => one.cuFlag !== '-')) {
|
|
91
|
+
const isNew = !input.id || input.cuFlag === '+';
|
|
92
|
+
const current = isNew ? undefined : await repo.findOne({ where: { domain: { id: domain.id }, id: input.id } });
|
|
93
|
+
if (!isNew && !current)
|
|
94
|
+
throw new shell_1.Refusal('transaction-not-found', {}, 'a transaction was not found - reload and try again');
|
|
95
|
+
const row = rowOf(input, current);
|
|
96
|
+
if (row.bankAccount?.id && !('currency' in input)) {
|
|
97
|
+
const account = await tx
|
|
98
|
+
.getRepository(bank_account_1.BankAccount)
|
|
99
|
+
.findOne({ where: { domain: { id: domain.id }, id: row.bankAccount.id } });
|
|
100
|
+
if (!account)
|
|
101
|
+
throw new shell_1.Refusal('bank-account-not-found', {}, 'the bank account was not found - reload and try again');
|
|
102
|
+
if (account.currency)
|
|
103
|
+
row.currency = account.currency;
|
|
104
|
+
}
|
|
105
|
+
if (row.bankFingerprint) {
|
|
106
|
+
const twin = await repo.findOne({ where: { domain: { id: domain.id }, bankFingerprint: row.bankFingerprint } });
|
|
107
|
+
if (twin && twin.id !== current?.id)
|
|
108
|
+
throw new shell_1.Refusal('bank-line-twice', { day: twin.transactionDate ?? '' }, 'this bank line is already in the books');
|
|
109
|
+
}
|
|
110
|
+
const written = await repo.save({ ...(current ?? { domain, creator: user }), ...row, updater: user });
|
|
111
|
+
if (current && MONEY.some(field => field in row && row[field] !== current[field]))
|
|
112
|
+
moneyChanged.push(current.id);
|
|
113
|
+
saved.push(written);
|
|
114
|
+
}
|
|
115
|
+
if (moneyChanged.length) {
|
|
116
|
+
const payments = await paymentsOn(tx, domain, moneyChanged);
|
|
117
|
+
await (0, payment_service_1.checkPaymentsWithin)(tx, domain, payments.map(one => one.transaction.id));
|
|
118
|
+
const kinds = new Map();
|
|
119
|
+
for (const payment of payments)
|
|
120
|
+
kinds.set(payment.targetType, [...(kinds.get(payment.targetType) ?? []), payment]);
|
|
121
|
+
for (const [targetType, ofKind] of kinds) {
|
|
122
|
+
await (0, payment_targets_1.paymentTargetOf)(targetType)?.validate?.(tx, domain, {
|
|
123
|
+
targetIds: [...new Set(ofKind.map(one => one.targetId))],
|
|
124
|
+
transactionIds: [...new Set(ofKind.map(one => one.transaction.id))]
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
return saved;
|
|
129
|
+
}
|
|
130
|
+
//# sourceMappingURL=transaction-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transaction-service.js","sourceRoot":"","sources":["../../../server/service/transaction/transaction-service.ts"],"names":[],"mappings":"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","sourcesContent":["import { EntityManager, In } from 'typeorm'\n\nimport { Refusal } from '@things-factory/shell'\n\nimport { BankAccount } from '../bank-account/bank-account'\nimport { CashFlowType } from '../cash-flow-type'\nimport { Payment } from '../payment/payment'\nimport { checkPaymentsWithin } from '../payment/payment-service'\nimport { paymentTargetOf } from '../payment/payment-targets'\nimport { ForecastStatus, Transaction, TransactionCategory } from './transaction'\nimport { forecastDay, yearMonthOf } from './transaction-period'\n\n/** A transaction as a module writes it: what a person may write, and the facts a bank statement gives. */\nexport type TransactionInput = Partial<\n Omit<Transaction, 'bankAccount' | 'account' | 'counterparty' | 'recurringItem' | 'bankStatement'>\n> & {\n id?: string\n cuFlag?: string\n bankAccount?: { id: string } | null\n account?: { id: string } | null\n counterparty?: { id: string } | null\n recurringItem?: { id: string } | null\n bankStatement?: { id: string } | null\n}\n\n/** What changes the money of a transaction - its payments are checked again when one of these changes. */\nconst MONEY = ['amount', 'type', 'currency'] as const\n\n/**\n * The row a patch writes over the current one: a confirmed transaction has a day and takes its year and month from it;\n * a forecast has a year and a month, and the day its timing names.\n */\nfunction rowOf(input: TransactionInput, current: Transaction | undefined): Record<string, any> {\n const { id, cuFlag, ...fields } = input\n const row: Record<string, any> = { ...fields }\n const merged = { ...current, ...row }\n const category = merged.category ?? TransactionCategory.CONFIRMED\n row.category = category\n\n if (!current && !row.type) throw new Refusal('transaction-type-required', {}, 'type: money in or money out')\n if (row.type !== undefined && !Object.values(CashFlowType).includes(row.type))\n throw new Refusal('transaction-type-required', {}, 'type: money in or money out')\n if (!current && (row.amount === undefined || row.amount === null)) row.amount = 0\n\n if (category === TransactionCategory.CONFIRMED) {\n const period = yearMonthOf(merged.transactionDate)\n if (!period)\n throw new Refusal(\n 'transaction-date-required',\n { value: merged.transactionDate ?? '' },\n 'transactionDate: YYYY-MM-DD'\n )\n Object.assign(row, period, { status: null })\n } else {\n const [year, month] = [Number(merged.year), Number(merged.month)]\n if (!year) throw new Refusal('forecast-year-required', {}, 'year: the year it is planned in')\n if (!(month >= 1 && month <= 12))\n throw new Refusal('month-out-of-range', { month: merged.month ?? '' }, 'month: must be 1 to 12')\n if (!String(merged.description ?? '').trim())\n throw new Refusal('forecast-description-required', {}, 'description: what is planned')\n Object.assign(row, { year, month, transactionDate: forecastDay(year, month, merged.timing) })\n if (!merged.status) row.status = ForecastStatus.PLANNED\n }\n\n if (\n merged.probability !== undefined &&\n merged.probability !== null &&\n !(merged.probability >= 0 && merged.probability <= 100)\n ) {\n throw new Refusal('probability-out-of-range', {}, 'probability: must be 0 to 100')\n }\n\n return row\n}\n\n/** The payments on these transactions, and the transfers into them, by target kind. */\nasync function paymentsOn(tx: EntityManager, domain: { id: string }, ids: string[]): Promise<Payment[]> {\n if (!ids.length) return []\n const repo = tx.getRepository(Payment)\n return [\n ...(await repo.find({\n where: { domain: { id: domain.id }, transaction: { id: In(ids) } },\n relations: ['transaction']\n })),\n ...(await repo.find({\n where: { domain: { id: domain.id }, targetType: 'Transaction', targetId: In(ids) },\n relations: ['transaction']\n }))\n ]\n}\n\n/**\n * Apply rows to a domain's transactions: `+` (or no id) adds, `M` changes, `-` deletes (softly - a financial row\n * that was deleted stays readable). A transaction that pays something, or is paid, is unlinked before it is\n * deleted; when its money changes, its payments are checked again - the general rule and each target kind's own.\n */\nexport async function saveTransactions(\n tx: EntityManager,\n domain: { id: string },\n user: any,\n inputs: TransactionInput[]\n): Promise<Transaction[]> {\n const repo = tx.getRepository(Transaction)\n\n const deletes = [...new Set(inputs.filter(one => one.cuFlag === '-' && one.id).map(one => one.id!))]\n if (deletes.length) {\n const found = await repo.find({ where: { domain: { id: domain.id }, id: In(deletes) } })\n if (found.length !== deletes.length)\n throw new Refusal('transaction-not-found', {}, 'a transaction was not found - reload and try again')\n if ((await paymentsOn(tx, domain, deletes)).length)\n throw new Refusal('transaction-has-payments', {}, 'unlink what the transaction paid before deleting it')\n await repo.softRemove(found)\n }\n\n const saved: Transaction[] = []\n const moneyChanged: string[] = []\n for (const input of inputs.filter(one => one.cuFlag !== '-')) {\n const isNew = !input.id || input.cuFlag === '+'\n const current = isNew ? undefined : await repo.findOne({ where: { domain: { id: domain.id }, id: input.id } })\n if (!isNew && !current)\n throw new Refusal('transaction-not-found', {}, 'a transaction was not found - reload and try again')\n\n const row = rowOf(input, current)\n if (row.bankAccount?.id && !('currency' in input)) {\n const account = await tx\n .getRepository(BankAccount)\n .findOne({ where: { domain: { id: domain.id }, id: row.bankAccount.id } })\n if (!account)\n throw new Refusal('bank-account-not-found', {}, 'the bank account was not found - reload and try again')\n if (account.currency) row.currency = account.currency\n }\n\n if (row.bankFingerprint) {\n const twin = await repo.findOne({ where: { domain: { id: domain.id }, bankFingerprint: row.bankFingerprint } })\n if (twin && twin.id !== current?.id)\n throw new Refusal(\n 'bank-line-twice',\n { day: twin.transactionDate ?? '' },\n 'this bank line is already in the books'\n )\n }\n\n const written = await repo.save({ ...(current ?? { domain, creator: user }), ...row, updater: user } as Transaction)\n if (current && MONEY.some(field => field in row && row[field] !== (current as any)[field]))\n moneyChanged.push(current.id)\n saved.push(written)\n }\n\n if (moneyChanged.length) {\n const payments = await paymentsOn(tx, domain, moneyChanged)\n await checkPaymentsWithin(\n tx,\n domain,\n payments.map(one => one.transaction.id)\n )\n const kinds = new Map<string, Payment[]>()\n for (const payment of payments) kinds.set(payment.targetType, [...(kinds.get(payment.targetType) ?? []), payment])\n for (const [targetType, ofKind] of kinds) {\n await paymentTargetOf(targetType)?.validate?.(tx, domain, {\n targetIds: [...new Set(ofKind.map(one => one.targetId))],\n transactionIds: [...new Set(ofKind.map(one => one.transaction.id))]\n })\n }\n }\n\n return saved\n}\n"]}
|
|
@@ -1,16 +1,48 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ObjectRef } from '@things-factory/shell';
|
|
2
|
+
import { CashFlowType } from '../cash-flow-type';
|
|
3
|
+
import { ForecastStatus, Transaction, TransactionCategory } from './transaction';
|
|
2
4
|
export declare class NewTransaction {
|
|
3
|
-
|
|
5
|
+
category?: TransactionCategory;
|
|
6
|
+
type: CashFlowType;
|
|
7
|
+
bankAccount?: ObjectRef;
|
|
8
|
+
transactionDate?: string;
|
|
9
|
+
year?: number;
|
|
10
|
+
month?: number;
|
|
11
|
+
amount?: number;
|
|
12
|
+
currency?: string;
|
|
13
|
+
balance?: number;
|
|
14
|
+
account?: ObjectRef;
|
|
4
15
|
description?: string;
|
|
5
|
-
|
|
6
|
-
|
|
16
|
+
ledgerCategory?: string;
|
|
17
|
+
counterpartyName?: string;
|
|
18
|
+
counterparty?: ObjectRef;
|
|
19
|
+
timing?: string;
|
|
20
|
+
status?: ForecastStatus;
|
|
21
|
+
probability?: number;
|
|
22
|
+
notes?: string;
|
|
23
|
+
recurringItem?: ObjectRef;
|
|
7
24
|
}
|
|
8
25
|
export declare class TransactionPatch {
|
|
9
26
|
id?: string;
|
|
10
|
-
|
|
27
|
+
category?: TransactionCategory;
|
|
28
|
+
type?: CashFlowType;
|
|
29
|
+
bankAccount?: ObjectRef;
|
|
30
|
+
transactionDate?: string;
|
|
31
|
+
year?: number;
|
|
32
|
+
month?: number;
|
|
33
|
+
amount?: number;
|
|
34
|
+
currency?: string;
|
|
35
|
+
balance?: number;
|
|
36
|
+
account?: ObjectRef;
|
|
11
37
|
description?: string;
|
|
12
|
-
|
|
13
|
-
|
|
38
|
+
ledgerCategory?: string;
|
|
39
|
+
counterpartyName?: string;
|
|
40
|
+
counterparty?: ObjectRef;
|
|
41
|
+
timing?: string;
|
|
42
|
+
status?: ForecastStatus;
|
|
43
|
+
probability?: number;
|
|
44
|
+
notes?: string;
|
|
45
|
+
recurringItem?: ObjectRef;
|
|
14
46
|
cuFlag?: string;
|
|
15
47
|
}
|
|
16
48
|
export declare class TransactionList {
|
|
@@ -3,71 +3,193 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.TransactionList = exports.TransactionPatch = exports.NewTransaction = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const type_graphql_1 = require("type-graphql");
|
|
6
|
+
const shell_1 = require("@things-factory/shell");
|
|
7
|
+
const cash_flow_type_1 = require("../cash-flow-type");
|
|
6
8
|
const transaction_1 = require("./transaction");
|
|
7
9
|
let NewTransaction = class NewTransaction {
|
|
8
10
|
};
|
|
9
11
|
exports.NewTransaction = NewTransaction;
|
|
10
12
|
tslib_1.__decorate([
|
|
11
|
-
(0, type_graphql_1.Field)(),
|
|
13
|
+
(0, type_graphql_1.Field)(type => transaction_1.TransactionCategory, { nullable: true, description: 'Confirmed when not given' }),
|
|
12
14
|
tslib_1.__metadata("design:type", String)
|
|
13
|
-
], NewTransaction.prototype, "
|
|
15
|
+
], NewTransaction.prototype, "category", void 0);
|
|
14
16
|
tslib_1.__decorate([
|
|
15
|
-
(0, type_graphql_1.Field)({
|
|
17
|
+
(0, type_graphql_1.Field)(type => cash_flow_type_1.CashFlowType, { description: 'Money in or money out' }),
|
|
18
|
+
tslib_1.__metadata("design:type", String)
|
|
19
|
+
], NewTransaction.prototype, "type", void 0);
|
|
20
|
+
tslib_1.__decorate([
|
|
21
|
+
(0, type_graphql_1.Field)(type => shell_1.ObjectRef, { nullable: true, description: 'The account the money moved in or out of' }),
|
|
22
|
+
tslib_1.__metadata("design:type", shell_1.ObjectRef)
|
|
23
|
+
], NewTransaction.prototype, "bankAccount", void 0);
|
|
24
|
+
tslib_1.__decorate([
|
|
25
|
+
(0, type_graphql_1.Field)({ nullable: true, description: 'YYYY-MM-DD - required for a confirmed transaction' }),
|
|
26
|
+
tslib_1.__metadata("design:type", String)
|
|
27
|
+
], NewTransaction.prototype, "transactionDate", void 0);
|
|
28
|
+
tslib_1.__decorate([
|
|
29
|
+
(0, type_graphql_1.Field)(type => type_graphql_1.Int, { nullable: true, description: 'The year a forecast is planned in' }),
|
|
30
|
+
tslib_1.__metadata("design:type", Number)
|
|
31
|
+
], NewTransaction.prototype, "year", void 0);
|
|
32
|
+
tslib_1.__decorate([
|
|
33
|
+
(0, type_graphql_1.Field)(type => type_graphql_1.Int, { nullable: true, description: 'The month a forecast is planned in' }),
|
|
34
|
+
tslib_1.__metadata("design:type", Number)
|
|
35
|
+
], NewTransaction.prototype, "month", void 0);
|
|
36
|
+
tslib_1.__decorate([
|
|
37
|
+
(0, type_graphql_1.Field)(type => type_graphql_1.Float, { nullable: true, description: 'Amount - zero when not given' }),
|
|
38
|
+
tslib_1.__metadata("design:type", Number)
|
|
39
|
+
], NewTransaction.prototype, "amount", void 0);
|
|
40
|
+
tslib_1.__decorate([
|
|
41
|
+
(0, type_graphql_1.Field)({ nullable: true, description: "ISO 4217 code - the bank account's when not given" }),
|
|
42
|
+
tslib_1.__metadata("design:type", String)
|
|
43
|
+
], NewTransaction.prototype, "currency", void 0);
|
|
44
|
+
tslib_1.__decorate([
|
|
45
|
+
(0, type_graphql_1.Field)(type => type_graphql_1.Float, { nullable: true, description: 'Account balance after it' }),
|
|
46
|
+
tslib_1.__metadata("design:type", Number)
|
|
47
|
+
], NewTransaction.prototype, "balance", void 0);
|
|
48
|
+
tslib_1.__decorate([
|
|
49
|
+
(0, type_graphql_1.Field)(type => shell_1.ObjectRef, { nullable: true, description: 'The account subject it is booked to' }),
|
|
50
|
+
tslib_1.__metadata("design:type", shell_1.ObjectRef)
|
|
51
|
+
], NewTransaction.prototype, "account", void 0);
|
|
52
|
+
tslib_1.__decorate([
|
|
53
|
+
(0, type_graphql_1.Field)({ nullable: true, description: 'What a person wrote about it' }),
|
|
16
54
|
tslib_1.__metadata("design:type", String)
|
|
17
55
|
], NewTransaction.prototype, "description", void 0);
|
|
18
56
|
tslib_1.__decorate([
|
|
19
|
-
(0, type_graphql_1.Field)(
|
|
57
|
+
(0, type_graphql_1.Field)({ nullable: true, description: 'The classifying word of the ledger it was kept in' }),
|
|
58
|
+
tslib_1.__metadata("design:type", String)
|
|
59
|
+
], NewTransaction.prototype, "ledgerCategory", void 0);
|
|
60
|
+
tslib_1.__decorate([
|
|
61
|
+
(0, type_graphql_1.Field)({ nullable: true, description: 'The counterparty name as a person wrote it' }),
|
|
62
|
+
tslib_1.__metadata("design:type", String)
|
|
63
|
+
], NewTransaction.prototype, "counterpartyName", void 0);
|
|
64
|
+
tslib_1.__decorate([
|
|
65
|
+
(0, type_graphql_1.Field)(type => shell_1.ObjectRef, { nullable: true, description: 'The registered counterparty' }),
|
|
66
|
+
tslib_1.__metadata("design:type", shell_1.ObjectRef)
|
|
67
|
+
], NewTransaction.prototype, "counterparty", void 0);
|
|
68
|
+
tslib_1.__decorate([
|
|
69
|
+
(0, type_graphql_1.Field)({ nullable: true, description: 'When in the month a forecast falls' }),
|
|
70
|
+
tslib_1.__metadata("design:type", String)
|
|
71
|
+
], NewTransaction.prototype, "timing", void 0);
|
|
72
|
+
tslib_1.__decorate([
|
|
73
|
+
(0, type_graphql_1.Field)(type => transaction_1.ForecastStatus, { nullable: true, description: 'State of a forecast' }),
|
|
74
|
+
tslib_1.__metadata("design:type", String)
|
|
75
|
+
], NewTransaction.prototype, "status", void 0);
|
|
76
|
+
tslib_1.__decorate([
|
|
77
|
+
(0, type_graphql_1.Field)(type => type_graphql_1.Int, { nullable: true, description: 'The probability of a forecast being realized (0 to 100)' }),
|
|
20
78
|
tslib_1.__metadata("design:type", Number)
|
|
21
|
-
], NewTransaction.prototype, "
|
|
79
|
+
], NewTransaction.prototype, "probability", void 0);
|
|
80
|
+
tslib_1.__decorate([
|
|
81
|
+
(0, type_graphql_1.Field)({ nullable: true, description: 'Notes' }),
|
|
82
|
+
tslib_1.__metadata("design:type", String)
|
|
83
|
+
], NewTransaction.prototype, "notes", void 0);
|
|
22
84
|
tslib_1.__decorate([
|
|
23
|
-
(0, type_graphql_1.Field)({ nullable: true }),
|
|
24
|
-
tslib_1.__metadata("design:type",
|
|
25
|
-
], NewTransaction.prototype, "
|
|
85
|
+
(0, type_graphql_1.Field)(type => shell_1.ObjectRef, { nullable: true, description: 'The recurring item a forecast was made from' }),
|
|
86
|
+
tslib_1.__metadata("design:type", shell_1.ObjectRef)
|
|
87
|
+
], NewTransaction.prototype, "recurringItem", void 0);
|
|
26
88
|
exports.NewTransaction = NewTransaction = tslib_1.__decorate([
|
|
27
|
-
(0, type_graphql_1.InputType)()
|
|
89
|
+
(0, type_graphql_1.InputType)({ description: 'A transaction someone writes - a bank line by hand, or a forecast' })
|
|
28
90
|
], NewTransaction);
|
|
29
91
|
let TransactionPatch = class TransactionPatch {
|
|
30
92
|
};
|
|
31
93
|
exports.TransactionPatch = TransactionPatch;
|
|
32
94
|
tslib_1.__decorate([
|
|
33
|
-
(0, type_graphql_1.Field)(type => type_graphql_1.ID, { nullable: true }),
|
|
95
|
+
(0, type_graphql_1.Field)(type => type_graphql_1.ID, { nullable: true, description: 'The transaction to change or delete' }),
|
|
34
96
|
tslib_1.__metadata("design:type", String)
|
|
35
97
|
], TransactionPatch.prototype, "id", void 0);
|
|
36
98
|
tslib_1.__decorate([
|
|
37
|
-
(0, type_graphql_1.Field)({ nullable: true }),
|
|
99
|
+
(0, type_graphql_1.Field)(type => transaction_1.TransactionCategory, { nullable: true, description: 'Confirmed or forecast' }),
|
|
38
100
|
tslib_1.__metadata("design:type", String)
|
|
39
|
-
], TransactionPatch.prototype, "
|
|
101
|
+
], TransactionPatch.prototype, "category", void 0);
|
|
40
102
|
tslib_1.__decorate([
|
|
41
|
-
(0, type_graphql_1.Field)({ nullable: true }),
|
|
103
|
+
(0, type_graphql_1.Field)(type => cash_flow_type_1.CashFlowType, { nullable: true, description: 'Money in or money out' }),
|
|
104
|
+
tslib_1.__metadata("design:type", String)
|
|
105
|
+
], TransactionPatch.prototype, "type", void 0);
|
|
106
|
+
tslib_1.__decorate([
|
|
107
|
+
(0, type_graphql_1.Field)(type => shell_1.ObjectRef, { nullable: true, description: 'The account the money moved in or out of' }),
|
|
108
|
+
tslib_1.__metadata("design:type", shell_1.ObjectRef)
|
|
109
|
+
], TransactionPatch.prototype, "bankAccount", void 0);
|
|
110
|
+
tslib_1.__decorate([
|
|
111
|
+
(0, type_graphql_1.Field)({ nullable: true, description: 'YYYY-MM-DD' }),
|
|
112
|
+
tslib_1.__metadata("design:type", String)
|
|
113
|
+
], TransactionPatch.prototype, "transactionDate", void 0);
|
|
114
|
+
tslib_1.__decorate([
|
|
115
|
+
(0, type_graphql_1.Field)(type => type_graphql_1.Int, { nullable: true, description: 'The year a forecast is planned in' }),
|
|
116
|
+
tslib_1.__metadata("design:type", Number)
|
|
117
|
+
], TransactionPatch.prototype, "year", void 0);
|
|
118
|
+
tslib_1.__decorate([
|
|
119
|
+
(0, type_graphql_1.Field)(type => type_graphql_1.Int, { nullable: true, description: 'The month a forecast is planned in' }),
|
|
120
|
+
tslib_1.__metadata("design:type", Number)
|
|
121
|
+
], TransactionPatch.prototype, "month", void 0);
|
|
122
|
+
tslib_1.__decorate([
|
|
123
|
+
(0, type_graphql_1.Field)(type => type_graphql_1.Float, { nullable: true, description: 'Amount' }),
|
|
124
|
+
tslib_1.__metadata("design:type", Number)
|
|
125
|
+
], TransactionPatch.prototype, "amount", void 0);
|
|
126
|
+
tslib_1.__decorate([
|
|
127
|
+
(0, type_graphql_1.Field)({ nullable: true, description: 'ISO 4217 code' }),
|
|
128
|
+
tslib_1.__metadata("design:type", String)
|
|
129
|
+
], TransactionPatch.prototype, "currency", void 0);
|
|
130
|
+
tslib_1.__decorate([
|
|
131
|
+
(0, type_graphql_1.Field)(type => type_graphql_1.Float, { nullable: true, description: 'Account balance after it' }),
|
|
132
|
+
tslib_1.__metadata("design:type", Number)
|
|
133
|
+
], TransactionPatch.prototype, "balance", void 0);
|
|
134
|
+
tslib_1.__decorate([
|
|
135
|
+
(0, type_graphql_1.Field)(type => shell_1.ObjectRef, { nullable: true, description: 'The account subject it is booked to' }),
|
|
136
|
+
tslib_1.__metadata("design:type", shell_1.ObjectRef)
|
|
137
|
+
], TransactionPatch.prototype, "account", void 0);
|
|
138
|
+
tslib_1.__decorate([
|
|
139
|
+
(0, type_graphql_1.Field)({ nullable: true, description: 'What a person wrote about it' }),
|
|
42
140
|
tslib_1.__metadata("design:type", String)
|
|
43
141
|
], TransactionPatch.prototype, "description", void 0);
|
|
44
142
|
tslib_1.__decorate([
|
|
45
|
-
(0, type_graphql_1.Field)(
|
|
143
|
+
(0, type_graphql_1.Field)({ nullable: true, description: 'The classifying word of the ledger it was kept in' }),
|
|
144
|
+
tslib_1.__metadata("design:type", String)
|
|
145
|
+
], TransactionPatch.prototype, "ledgerCategory", void 0);
|
|
146
|
+
tslib_1.__decorate([
|
|
147
|
+
(0, type_graphql_1.Field)({ nullable: true, description: 'The counterparty name as a person wrote it' }),
|
|
148
|
+
tslib_1.__metadata("design:type", String)
|
|
149
|
+
], TransactionPatch.prototype, "counterpartyName", void 0);
|
|
150
|
+
tslib_1.__decorate([
|
|
151
|
+
(0, type_graphql_1.Field)(type => shell_1.ObjectRef, { nullable: true, description: 'The registered counterparty' }),
|
|
152
|
+
tslib_1.__metadata("design:type", shell_1.ObjectRef)
|
|
153
|
+
], TransactionPatch.prototype, "counterparty", void 0);
|
|
154
|
+
tslib_1.__decorate([
|
|
155
|
+
(0, type_graphql_1.Field)({ nullable: true, description: 'When in the month a forecast falls' }),
|
|
156
|
+
tslib_1.__metadata("design:type", String)
|
|
157
|
+
], TransactionPatch.prototype, "timing", void 0);
|
|
158
|
+
tslib_1.__decorate([
|
|
159
|
+
(0, type_graphql_1.Field)(type => transaction_1.ForecastStatus, { nullable: true, description: 'State of a forecast' }),
|
|
160
|
+
tslib_1.__metadata("design:type", String)
|
|
161
|
+
], TransactionPatch.prototype, "status", void 0);
|
|
162
|
+
tslib_1.__decorate([
|
|
163
|
+
(0, type_graphql_1.Field)(type => type_graphql_1.Int, { nullable: true, description: 'The probability of a forecast being realized (0 to 100)' }),
|
|
46
164
|
tslib_1.__metadata("design:type", Number)
|
|
47
|
-
], TransactionPatch.prototype, "
|
|
165
|
+
], TransactionPatch.prototype, "probability", void 0);
|
|
166
|
+
tslib_1.__decorate([
|
|
167
|
+
(0, type_graphql_1.Field)({ nullable: true, description: 'Notes' }),
|
|
168
|
+
tslib_1.__metadata("design:type", String)
|
|
169
|
+
], TransactionPatch.prototype, "notes", void 0);
|
|
48
170
|
tslib_1.__decorate([
|
|
49
|
-
(0, type_graphql_1.Field)({ nullable: true }),
|
|
50
|
-
tslib_1.__metadata("design:type",
|
|
51
|
-
], TransactionPatch.prototype, "
|
|
171
|
+
(0, type_graphql_1.Field)(type => shell_1.ObjectRef, { nullable: true, description: 'The recurring item a forecast was made from' }),
|
|
172
|
+
tslib_1.__metadata("design:type", shell_1.ObjectRef)
|
|
173
|
+
], TransactionPatch.prototype, "recurringItem", void 0);
|
|
52
174
|
tslib_1.__decorate([
|
|
53
|
-
(0, type_graphql_1.Field)({ nullable: true }),
|
|
175
|
+
(0, type_graphql_1.Field)({ nullable: true, description: '+ adds, M changes, - deletes' }),
|
|
54
176
|
tslib_1.__metadata("design:type", String)
|
|
55
177
|
], TransactionPatch.prototype, "cuFlag", void 0);
|
|
56
178
|
exports.TransactionPatch = TransactionPatch = tslib_1.__decorate([
|
|
57
|
-
(0, type_graphql_1.InputType)()
|
|
179
|
+
(0, type_graphql_1.InputType)({ description: 'A change to a transaction, or a grid row: cuFlag + adds, M changes, - deletes' })
|
|
58
180
|
], TransactionPatch);
|
|
59
181
|
let TransactionList = class TransactionList {
|
|
60
182
|
};
|
|
61
183
|
exports.TransactionList = TransactionList;
|
|
62
184
|
tslib_1.__decorate([
|
|
63
|
-
(0, type_graphql_1.Field)(type => [transaction_1.Transaction]),
|
|
185
|
+
(0, type_graphql_1.Field)(type => [transaction_1.Transaction], { description: 'The transactions on this page' }),
|
|
64
186
|
tslib_1.__metadata("design:type", Array)
|
|
65
187
|
], TransactionList.prototype, "items", void 0);
|
|
66
188
|
tslib_1.__decorate([
|
|
67
|
-
(0, type_graphql_1.Field)(type => type_graphql_1.Int),
|
|
189
|
+
(0, type_graphql_1.Field)(type => type_graphql_1.Int, { description: 'How many there are in all' }),
|
|
68
190
|
tslib_1.__metadata("design:type", Number)
|
|
69
191
|
], TransactionList.prototype, "total", void 0);
|
|
70
192
|
exports.TransactionList = TransactionList = tslib_1.__decorate([
|
|
71
|
-
(0, type_graphql_1.ObjectType)()
|
|
193
|
+
(0, type_graphql_1.ObjectType)({ description: 'A page of transactions' })
|
|
72
194
|
], TransactionList);
|
|
73
195
|
//# sourceMappingURL=transaction-type.js.map
|