@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.
Files changed (234) hide show
  1. package/dist-client/route.d.ts +1 -1
  2. package/dist-client/route.js +0 -12
  3. package/dist-client/route.js.map +1 -1
  4. package/dist-client/tsconfig.tsbuildinfo +1 -1
  5. package/dist-server/index.d.ts +0 -1
  6. package/dist-server/index.js +0 -1
  7. package/dist-server/index.js.map +1 -1
  8. package/dist-server/service/account/account-history.d.ts +13 -6
  9. package/dist-server/service/account/account-history.js +44 -17
  10. package/dist-server/service/account/account-history.js.map +1 -1
  11. package/dist-server/service/account/account-mutation.js +2 -2
  12. package/dist-server/service/account/account-mutation.js.map +1 -1
  13. package/dist-server/service/account/account-type.d.ts +16 -0
  14. package/dist-server/service/account/account-type.js +71 -13
  15. package/dist-server/service/account/account-type.js.map +1 -1
  16. package/dist-server/service/account/account.d.ts +9 -3
  17. package/dist-server/service/account/account.js +34 -8
  18. package/dist-server/service/account/account.js.map +1 -1
  19. package/dist-server/service/accounting-category/accounting-category-mutation.js +2 -2
  20. package/dist-server/service/accounting-category/accounting-category-mutation.js.map +1 -1
  21. package/dist-server/service/accounting-document/accounting-document-mutation.js +12 -3
  22. package/dist-server/service/accounting-document/accounting-document-mutation.js.map +1 -1
  23. package/dist-server/service/accounting-document/accounting-document-query.js +2 -0
  24. package/dist-server/service/accounting-document/accounting-document-query.js.map +1 -1
  25. package/dist-server/service/bank-account/bank-account-history.d.ts +11 -14
  26. package/dist-server/service/bank-account/bank-account-history.js +46 -59
  27. package/dist-server/service/bank-account/bank-account-history.js.map +1 -1
  28. package/dist-server/service/bank-account/bank-account-mutation.d.ts +1 -2
  29. package/dist-server/service/bank-account/bank-account-mutation.js +25 -69
  30. package/dist-server/service/bank-account/bank-account-mutation.js.map +1 -1
  31. package/dist-server/service/bank-account/bank-account-query.js +2 -0
  32. package/dist-server/service/bank-account/bank-account-query.js.map +1 -1
  33. package/dist-server/service/bank-account/bank-account-service.d.ts +5 -0
  34. package/dist-server/service/bank-account/bank-account-service.js +21 -0
  35. package/dist-server/service/bank-account/bank-account-service.js.map +1 -0
  36. package/dist-server/service/bank-account/bank-account-type.d.ts +13 -19
  37. package/dist-server/service/bank-account/bank-account-type.js +45 -69
  38. package/dist-server/service/bank-account/bank-account-type.js.map +1 -1
  39. package/dist-server/service/bank-account/bank-account.d.ts +14 -17
  40. package/dist-server/service/bank-account/bank-account.js +45 -57
  41. package/dist-server/service/bank-account/bank-account.js.map +1 -1
  42. package/dist-server/service/bank-statement/bank-statement-query.d.ts +14 -0
  43. package/dist-server/service/bank-statement/bank-statement-query.js +92 -0
  44. package/dist-server/service/bank-statement/bank-statement-query.js.map +1 -0
  45. package/dist-server/service/bank-statement/bank-statement.d.ts +26 -0
  46. package/dist-server/service/bank-statement/bank-statement.js +109 -0
  47. package/dist-server/service/bank-statement/bank-statement.js.map +1 -0
  48. package/dist-server/service/bank-statement/index.d.ts +5 -0
  49. package/dist-server/service/bank-statement/index.js +9 -0
  50. package/dist-server/service/bank-statement/index.js.map +1 -0
  51. package/dist-server/service/cash-flow-type.d.ts +5 -0
  52. package/dist-server/service/cash-flow-type.js +15 -0
  53. package/dist-server/service/cash-flow-type.js.map +1 -0
  54. package/dist-server/service/financial-institution/financial-institution-mutation.js +10 -1
  55. package/dist-server/service/financial-institution/financial-institution-mutation.js.map +1 -1
  56. package/dist-server/service/financial-institution/financial-institution-query.js +14 -6
  57. package/dist-server/service/financial-institution/financial-institution-query.js.map +1 -1
  58. package/dist-server/service/financial-institution/index.d.ts +1 -1
  59. package/dist-server/service/financial-statement/financial-statement-history.d.ts +11 -9
  60. package/dist-server/service/financial-statement/financial-statement-history.js +47 -36
  61. package/dist-server/service/financial-statement/financial-statement-history.js.map +1 -1
  62. package/dist-server/service/financial-statement/financial-statement-line.d.ts +24 -0
  63. package/dist-server/service/financial-statement/financial-statement-line.js +108 -0
  64. package/dist-server/service/financial-statement/financial-statement-line.js.map +1 -0
  65. package/dist-server/service/financial-statement/financial-statement-mutation.d.ts +1 -8
  66. package/dist-server/service/financial-statement/financial-statement-mutation.js +10 -135
  67. package/dist-server/service/financial-statement/financial-statement-mutation.js.map +1 -1
  68. package/dist-server/service/financial-statement/financial-statement-query.d.ts +8 -7
  69. package/dist-server/service/financial-statement/financial-statement-query.js +40 -30
  70. package/dist-server/service/financial-statement/financial-statement-query.js.map +1 -1
  71. package/dist-server/service/financial-statement/financial-statement-service.d.ts +33 -0
  72. package/dist-server/service/financial-statement/financial-statement-service.js +44 -0
  73. package/dist-server/service/financial-statement/financial-statement-service.js.map +1 -0
  74. package/dist-server/service/financial-statement/financial-statement.d.ts +19 -11
  75. package/dist-server/service/financial-statement/financial-statement.js +73 -65
  76. package/dist-server/service/financial-statement/financial-statement.js.map +1 -1
  77. package/dist-server/service/financial-statement/index.d.ts +3 -2
  78. package/dist-server/service/financial-statement/index.js +2 -2
  79. package/dist-server/service/financial-statement/index.js.map +1 -1
  80. package/dist-server/service/index.d.ts +15 -3
  81. package/dist-server/service/index.js +30 -13
  82. package/dist-server/service/index.js.map +1 -1
  83. package/dist-server/service/payment/index.d.ts +1 -0
  84. package/dist-server/service/payment/index.js +1 -0
  85. package/dist-server/service/payment/index.js.map +1 -1
  86. package/dist-server/service/payment/payment-history.d.ts +9 -16
  87. package/dist-server/service/payment/payment-history.js +36 -70
  88. package/dist-server/service/payment/payment-history.js.map +1 -1
  89. package/dist-server/service/payment/payment-mutation.d.ts +0 -1
  90. package/dist-server/service/payment/payment-mutation.js +14 -79
  91. package/dist-server/service/payment/payment-mutation.js.map +1 -1
  92. package/dist-server/service/payment/payment-query.d.ts +3 -0
  93. package/dist-server/service/payment/payment-query.js +30 -1
  94. package/dist-server/service/payment/payment-query.js.map +1 -1
  95. package/dist-server/service/payment/payment-service.d.ts +16 -0
  96. package/dist-server/service/payment/payment-service.js +140 -0
  97. package/dist-server/service/payment/payment-service.js.map +1 -0
  98. package/dist-server/service/payment/payment-targets.d.ts +31 -0
  99. package/dist-server/service/payment/payment-targets.js +19 -0
  100. package/dist-server/service/payment/payment-targets.js.map +1 -0
  101. package/dist-server/service/payment/payment-type.d.ts +13 -17
  102. package/dist-server/service/payment/payment-type.js +35 -51
  103. package/dist-server/service/payment/payment-type.js.map +1 -1
  104. package/dist-server/service/payment/payment.d.ts +23 -22
  105. package/dist-server/service/payment/payment.js +66 -94
  106. package/dist-server/service/payment/payment.js.map +1 -1
  107. package/dist-server/service/payment/transfer-target.d.ts +1 -0
  108. package/dist-server/service/payment/transfer-target.js +43 -0
  109. package/dist-server/service/payment/transfer-target.js.map +1 -0
  110. package/dist-server/service/recurring-cash-item/index.d.ts +6 -0
  111. package/dist-server/service/recurring-cash-item/index.js +10 -0
  112. package/dist-server/service/recurring-cash-item/index.js.map +1 -0
  113. package/dist-server/service/recurring-cash-item/recurring-cash-item-mutation.d.ts +7 -0
  114. package/dist-server/service/recurring-cash-item/recurring-cash-item-mutation.js +63 -0
  115. package/dist-server/service/recurring-cash-item/recurring-cash-item-mutation.js.map +1 -0
  116. package/dist-server/service/recurring-cash-item/recurring-cash-item-query.d.ts +15 -0
  117. package/dist-server/service/recurring-cash-item/recurring-cash-item-query.js +101 -0
  118. package/dist-server/service/recurring-cash-item/recurring-cash-item-query.js.map +1 -0
  119. package/dist-server/service/recurring-cash-item/recurring-cash-item-service.d.ts +23 -0
  120. package/dist-server/service/recurring-cash-item/recurring-cash-item-service.js +91 -0
  121. package/dist-server/service/recurring-cash-item/recurring-cash-item-service.js.map +1 -0
  122. package/dist-server/service/recurring-cash-item/recurring-cash-item-type.d.ts +23 -0
  123. package/dist-server/service/recurring-cash-item/recurring-cash-item-type.js +85 -0
  124. package/dist-server/service/recurring-cash-item/recurring-cash-item-type.js.map +1 -0
  125. package/dist-server/service/recurring-cash-item/recurring-cash-item.d.ts +35 -0
  126. package/dist-server/service/recurring-cash-item/recurring-cash-item.js +142 -0
  127. package/dist-server/service/recurring-cash-item/recurring-cash-item.js.map +1 -0
  128. package/dist-server/service/recurring-cash-item/recurring-schedule.d.ts +36 -0
  129. package/dist-server/service/recurring-cash-item/recurring-schedule.js +41 -0
  130. package/dist-server/service/recurring-cash-item/recurring-schedule.js.map +1 -0
  131. package/dist-server/service/transaction/transaction-history.d.ts +42 -15
  132. package/dist-server/service/transaction/transaction-history.js +160 -54
  133. package/dist-server/service/transaction/transaction-history.js.map +1 -1
  134. package/dist-server/service/transaction/transaction-mutation.d.ts +0 -1
  135. package/dist-server/service/transaction/transaction-mutation.js +13 -78
  136. package/dist-server/service/transaction/transaction-mutation.js.map +1 -1
  137. package/dist-server/service/transaction/transaction-period.d.ts +16 -0
  138. package/dist-server/service/transaction/transaction-period.js +49 -0
  139. package/dist-server/service/transaction/transaction-period.js.map +1 -0
  140. package/dist-server/service/transaction/transaction-query.d.ts +12 -0
  141. package/dist-server/service/transaction/transaction-query.js +84 -2
  142. package/dist-server/service/transaction/transaction-query.js.map +1 -1
  143. package/dist-server/service/transaction/transaction-service.d.ts +30 -0
  144. package/dist-server/service/transaction/transaction-service.js +130 -0
  145. package/dist-server/service/transaction/transaction-service.js.map +1 -0
  146. package/dist-server/service/transaction/transaction-type.d.ts +39 -7
  147. package/dist-server/service/transaction/transaction-type.js +145 -23
  148. package/dist-server/service/transaction/transaction-type.js.map +1 -1
  149. package/dist-server/service/transaction/transaction.d.ts +58 -31
  150. package/dist-server/service/transaction/transaction.js +216 -102
  151. package/dist-server/service/transaction/transaction.js.map +1 -1
  152. package/dist-server/tsconfig.tsbuildinfo +1 -1
  153. package/package.json +5 -3
  154. package/things-factory.config.js +0 -4
  155. package/translations/en.json +34 -2
  156. package/translations/ja.json +0 -1
  157. package/translations/ko.json +34 -2
  158. package/translations/ms.json +0 -1
  159. package/translations/zh.json +0 -1
  160. package/dist-client/pages/account/account-importer.d.ts +0 -22
  161. package/dist-client/pages/account/account-importer.js +0 -99
  162. package/dist-client/pages/account/account-importer.js.map +0 -1
  163. package/dist-client/pages/account/account-list-page.d.ts +0 -57
  164. package/dist-client/pages/account/account-list-page.js +0 -306
  165. package/dist-client/pages/account/account-list-page.js.map +0 -1
  166. package/dist-client/pages/bank-account/bank-account-importer.d.ts +0 -23
  167. package/dist-client/pages/bank-account/bank-account-importer.js +0 -92
  168. package/dist-client/pages/bank-account/bank-account-importer.js.map +0 -1
  169. package/dist-client/pages/bank-account/bank-account-list-page.d.ts +0 -60
  170. package/dist-client/pages/bank-account/bank-account-list-page.js +0 -317
  171. package/dist-client/pages/bank-account/bank-account-list-page.js.map +0 -1
  172. package/dist-client/pages/financial-statement/financial-statement-importer.d.ts +0 -22
  173. package/dist-client/pages/financial-statement/financial-statement-importer.js +0 -99
  174. package/dist-client/pages/financial-statement/financial-statement-importer.js.map +0 -1
  175. package/dist-client/pages/financial-statement/financial-statement-list-page.d.ts +0 -57
  176. package/dist-client/pages/financial-statement/financial-statement-list-page.js +0 -280
  177. package/dist-client/pages/financial-statement/financial-statement-list-page.js.map +0 -1
  178. package/dist-client/pages/income-statement/income-statement-importer.d.ts +0 -22
  179. package/dist-client/pages/income-statement/income-statement-importer.js +0 -99
  180. package/dist-client/pages/income-statement/income-statement-importer.js.map +0 -1
  181. package/dist-client/pages/income-statement/income-statement-list-page.d.ts +0 -57
  182. package/dist-client/pages/income-statement/income-statement-list-page.js +0 -280
  183. package/dist-client/pages/income-statement/income-statement-list-page.js.map +0 -1
  184. package/dist-client/pages/payment/payment-importer.d.ts +0 -23
  185. package/dist-client/pages/payment/payment-importer.js +0 -92
  186. package/dist-client/pages/payment/payment-importer.js.map +0 -1
  187. package/dist-client/pages/payment/payment-list-page.d.ts +0 -60
  188. package/dist-client/pages/payment/payment-list-page.js +0 -317
  189. package/dist-client/pages/payment/payment-list-page.js.map +0 -1
  190. package/dist-client/pages/transaction/transaction-importer.d.ts +0 -22
  191. package/dist-client/pages/transaction/transaction-importer.js +0 -99
  192. package/dist-client/pages/transaction/transaction-importer.js.map +0 -1
  193. package/dist-client/pages/transaction/transaction-list-page.d.ts +0 -57
  194. package/dist-client/pages/transaction/transaction-list-page.js +0 -280
  195. package/dist-client/pages/transaction/transaction-list-page.js.map +0 -1
  196. package/dist-server/controllers/index.d.ts +0 -1
  197. package/dist-server/controllers/index.js +0 -5
  198. package/dist-server/controllers/index.js.map +0 -1
  199. package/dist-server/controllers/summary-statements.d.ts +0 -4
  200. package/dist-server/controllers/summary-statements.js +0 -149
  201. package/dist-server/controllers/summary-statements.js.map +0 -1
  202. package/dist-server/migrations/1725201567284-seed-country-codes.d.ts +0 -5
  203. package/dist-server/migrations/1725201567284-seed-country-codes.js +0 -255
  204. package/dist-server/migrations/1725201567284-seed-country-codes.js.map +0 -1
  205. package/dist-server/service/financial-statement/financial-statement-line-item.d.ts +0 -19
  206. package/dist-server/service/financial-statement/financial-statement-line-item.js +0 -95
  207. package/dist-server/service/financial-statement/financial-statement-line-item.js.map +0 -1
  208. package/dist-server/service/financial-statement/financial-statement-type.d.ts +0 -20
  209. package/dist-server/service/financial-statement/financial-statement-type.js +0 -77
  210. package/dist-server/service/financial-statement/financial-statement-type.js.map +0 -1
  211. package/dist-server/service/income-statement/event-subscriber.d.ts +0 -7
  212. package/dist-server/service/income-statement/event-subscriber.js +0 -21
  213. package/dist-server/service/income-statement/event-subscriber.js.map +0 -1
  214. package/dist-server/service/income-statement/income-statement-history.d.ts +0 -28
  215. package/dist-server/service/income-statement/income-statement-history.js +0 -146
  216. package/dist-server/service/income-statement/income-statement-history.js.map +0 -1
  217. package/dist-server/service/income-statement/income-statement-line-item.d.ts +0 -19
  218. package/dist-server/service/income-statement/income-statement-line-item.js +0 -97
  219. package/dist-server/service/income-statement/income-statement-line-item.js.map +0 -1
  220. package/dist-server/service/income-statement/income-statement-mutation.d.ts +0 -10
  221. package/dist-server/service/income-statement/income-statement-mutation.js +0 -159
  222. package/dist-server/service/income-statement/income-statement-mutation.js.map +0 -1
  223. package/dist-server/service/income-statement/income-statement-query.d.ts +0 -11
  224. package/dist-server/service/income-statement/income-statement-query.js +0 -81
  225. package/dist-server/service/income-statement/income-statement-query.js.map +0 -1
  226. package/dist-server/service/income-statement/income-statement-type.d.ts +0 -20
  227. package/dist-server/service/income-statement/income-statement-type.js +0 -77
  228. package/dist-server/service/income-statement/income-statement-type.js.map +0 -1
  229. package/dist-server/service/income-statement/income-statement.d.ts +0 -28
  230. package/dist-server/service/income-statement/income-statement.js +0 -137
  231. package/dist-server/service/income-statement/income-statement.js.map +0 -1
  232. package/dist-server/service/income-statement/index.d.ts +0 -8
  233. package/dist-server/service/income-statement/index.js +0 -13
  234. 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: ['name', 'description']
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":"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","sourcesContent":["import { Resolver, Query, FieldResolver, Root, Args, Arg, Ctx, Directive } from 'type-graphql'\nimport { Domain, getQueryBuilderFromListParams, getRepository, ListParam } from '@things-factory/shell'\nimport { User } from '@things-factory/auth-base'\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(@Args() params: ListParam, @Ctx() context: ResolverContext): Promise<TransactionList> {\n const { domain } = context.state\n\n const queryBuilder = getQueryBuilderFromListParams({\n domain,\n params,\n repository: await getRepository(Transaction),\n searchables: ['name', 'description']\n })\n\n const [items, total] = await queryBuilder.getManyAndCount()\n\n return { items, total }\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"]}
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 { Transaction, TransactionType } from './transaction';
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
- name: string;
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
- type?: TransactionType;
6
- active?: boolean;
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
- name?: string;
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
- type?: TransactionType;
13
- active?: boolean;
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, "name", void 0);
15
+ ], NewTransaction.prototype, "category", void 0);
14
16
  tslib_1.__decorate([
15
- (0, type_graphql_1.Field)({ nullable: true }),
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)(type => transaction_1.TransactionType, { nullable: true }),
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, "type", void 0);
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", Boolean)
25
- ], NewTransaction.prototype, "active", void 0);
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, "name", void 0);
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)(type => transaction_1.TransactionType, { nullable: true }),
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, "type", void 0);
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", Boolean)
51
- ], TransactionPatch.prototype, "active", void 0);
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