@things-factory/biz-base 10.1.154 → 10.1.156
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-server/index.d.ts +1 -0
- package/dist-server/index.js +1 -0
- package/dist-server/index.js.map +1 -1
- package/dist-server/service/counterparty/counterparty-bank-account-mutation.d.ts +9 -0
- package/dist-server/service/counterparty/counterparty-bank-account-mutation.js +70 -0
- package/dist-server/service/counterparty/counterparty-bank-account-mutation.js.map +1 -0
- package/dist-server/service/counterparty/counterparty-bank-account-query.d.ts +16 -0
- package/dist-server/service/counterparty/counterparty-bank-account-query.js +104 -0
- package/dist-server/service/counterparty/counterparty-bank-account-query.js.map +1 -0
- package/dist-server/service/counterparty/counterparty-bank-account-service.d.ts +27 -0
- package/dist-server/service/counterparty/counterparty-bank-account-service.js +87 -0
- package/dist-server/service/counterparty/counterparty-bank-account-service.js.map +1 -0
- package/dist-server/service/counterparty/counterparty-bank-account.d.ts +29 -0
- package/dist-server/service/counterparty/counterparty-bank-account.js +103 -0
- package/dist-server/service/counterparty/counterparty-bank-account.js.map +1 -0
- package/dist-server/service/counterparty/counterparty-document-readers.d.ts +7 -0
- package/dist-server/service/counterparty/counterparty-document-readers.js +18 -0
- package/dist-server/service/counterparty/counterparty-document-readers.js.map +1 -0
- package/dist-server/service/counterparty/counterparty-names.d.ts +22 -0
- package/dist-server/service/counterparty/counterparty-names.js +30 -14
- package/dist-server/service/counterparty/counterparty-names.js.map +1 -1
- package/dist-server/service/counterparty/counterparty-service.js +5 -0
- package/dist-server/service/counterparty/counterparty-service.js.map +1 -1
- package/dist-server/service/counterparty/counterparty-type.d.ts +9 -0
- package/dist-server/service/counterparty/counterparty-type.js +35 -1
- package/dist-server/service/counterparty/counterparty-type.js.map +1 -1
- package/dist-server/service/counterparty/index.d.ts +5 -2
- package/dist-server/service/counterparty/index.js +5 -2
- package/dist-server/service/counterparty/index.js.map +1 -1
- package/dist-server/service/index.d.ts +4 -2
- package/dist-server/service/index.js +2 -0
- package/dist-server/service/index.js.map +1 -1
- package/dist-server/tsconfig.tsbuildinfo +1 -1
- package/package.json +4 -3
- package/tests/counterparty-bank-account.test.mjs +117 -0
- package/translations/en.json +4 -1
- package/translations/es.json +4 -1
- package/translations/ja.json +4 -1
- package/translations/ko.json +4 -1
- package/translations/ms.json +4 -1
- package/translations/zh.json +4 -1
package/dist-server/index.d.ts
CHANGED
package/dist-server/index.js
CHANGED
|
@@ -4,4 +4,5 @@ const tslib_1 = require("tslib");
|
|
|
4
4
|
tslib_1.__exportStar(require("./service"), exports);
|
|
5
5
|
tslib_1.__exportStar(require("./migrations"), exports);
|
|
6
6
|
tslib_1.__exportStar(require("./utils"), exports);
|
|
7
|
+
require("./service/counterparty/counterparty-document-readers");
|
|
7
8
|
//# sourceMappingURL=index.js.map
|
package/dist-server/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../server/index.ts"],"names":[],"mappings":";;;AAAA,oDAAyB;AACzB,uDAA4B;AAC5B,kDAAuB","sourcesContent":["export * from './service'\nexport * from './migrations'\nexport * from './utils'\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../server/index.ts"],"names":[],"mappings":";;;AAAA,oDAAyB;AACzB,uDAA4B;AAC5B,kDAAuB;AAEvB,gEAA6D","sourcesContent":["export * from './service'\nexport * from './migrations'\nexport * from './utils'\n\nimport './service/counterparty/counterparty-document-readers'\n"]}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { FileUpload } from 'graphql-upload/GraphQLUpload.js';
|
|
2
|
+
import { Attachment } from '@things-factory/attachment-base';
|
|
3
|
+
import { CounterpartyBankAccount } from './counterparty-bank-account';
|
|
4
|
+
import { CounterpartyBankAccountPatch } from './counterparty-type';
|
|
5
|
+
export declare class CounterpartyBankAccountMutation {
|
|
6
|
+
updateMultipleCounterpartyBankAccount(patches: CounterpartyBankAccountPatch[], context: ResolverContext): Promise<CounterpartyBankAccount[]>;
|
|
7
|
+
attachCounterpartyPassbook(accountId: string, file: FileUpload | null, context: ResolverContext): Promise<Attachment | null>;
|
|
8
|
+
attachCounterpartyBusinessRegistration(counterpartyId: string, file: FileUpload | null, context: ResolverContext): Promise<Attachment | null>;
|
|
9
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CounterpartyBankAccountMutation = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const GraphQLUpload_js_1 = tslib_1.__importDefault(require("graphql-upload/GraphQLUpload.js"));
|
|
6
|
+
const type_graphql_1 = require("type-graphql");
|
|
7
|
+
const attachment_base_1 = require("@things-factory/attachment-base");
|
|
8
|
+
const shell_1 = require("@things-factory/shell");
|
|
9
|
+
const counterparty_1 = require("./counterparty");
|
|
10
|
+
const counterparty_bank_account_1 = require("./counterparty-bank-account");
|
|
11
|
+
const counterparty_bank_account_service_1 = require("./counterparty-bank-account-service");
|
|
12
|
+
const counterparty_type_1 = require("./counterparty-type");
|
|
13
|
+
let CounterpartyBankAccountMutation = class CounterpartyBankAccountMutation {
|
|
14
|
+
async updateMultipleCounterpartyBankAccount(patches, context) {
|
|
15
|
+
const { tx, domain, user } = context.state;
|
|
16
|
+
return await (0, counterparty_bank_account_service_1.saveCounterpartyBankAccounts)(tx, domain, user, patches);
|
|
17
|
+
}
|
|
18
|
+
async attachCounterpartyPassbook(accountId, file, context) {
|
|
19
|
+
const { tx, domain } = context.state;
|
|
20
|
+
const account = await tx.getRepository(counterparty_bank_account_1.CounterpartyBankAccount).findOne({ where: { domain: { id: domain.id }, id: accountId } });
|
|
21
|
+
if (!account)
|
|
22
|
+
throw new shell_1.Refusal('counterparty-account-not-found', {}, 'an account was not found - reload and try again');
|
|
23
|
+
return await (0, attachment_base_1.replaceAttachment)({ file, refType: counterparty_bank_account_service_1.PASSBOOK_REF_TYPE, refBy: account.id, category: 'passbook' }, context);
|
|
24
|
+
}
|
|
25
|
+
async attachCounterpartyBusinessRegistration(counterpartyId, file, context) {
|
|
26
|
+
const { tx, domain } = context.state;
|
|
27
|
+
const counterparty = await tx.getRepository(counterparty_1.Counterparty).findOne({ where: { domain: { id: domain.id }, id: counterpartyId } });
|
|
28
|
+
if (!counterparty)
|
|
29
|
+
throw new shell_1.Refusal('counterparty-not-found', {}, 'a counterparty was not found - reload and try again');
|
|
30
|
+
return await (0, attachment_base_1.replaceAttachment)({ file, refType: counterparty_bank_account_service_1.BUSINESS_REGISTRATION_REF_TYPE, refBy: counterparty.id, category: 'business-registration' }, context);
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
exports.CounterpartyBankAccountMutation = CounterpartyBankAccountMutation;
|
|
34
|
+
tslib_1.__decorate([
|
|
35
|
+
(0, type_graphql_1.Directive)('@transaction'),
|
|
36
|
+
(0, type_graphql_1.Directive)('@privilege(category: "counterparty", privilege: "mutation", domainOwnerGranted: true)'),
|
|
37
|
+
(0, type_graphql_1.Mutation)(returns => [counterparty_bank_account_1.CounterpartyBankAccount], { description: 'To save counterparty accounts - new, changed and deleted rows together' }),
|
|
38
|
+
tslib_1.__param(0, (0, type_graphql_1.Arg)('patches', type => [counterparty_type_1.CounterpartyBankAccountPatch])),
|
|
39
|
+
tslib_1.__param(1, (0, type_graphql_1.Ctx)()),
|
|
40
|
+
tslib_1.__metadata("design:type", Function),
|
|
41
|
+
tslib_1.__metadata("design:paramtypes", [Array, Object]),
|
|
42
|
+
tslib_1.__metadata("design:returntype", Promise)
|
|
43
|
+
], CounterpartyBankAccountMutation.prototype, "updateMultipleCounterpartyBankAccount", null);
|
|
44
|
+
tslib_1.__decorate([
|
|
45
|
+
(0, type_graphql_1.Directive)('@transaction'),
|
|
46
|
+
(0, type_graphql_1.Directive)('@privilege(category: "counterparty", privilege: "mutation", domainOwnerGranted: true)'),
|
|
47
|
+
(0, type_graphql_1.Mutation)(returns => attachment_base_1.Attachment, { nullable: true, description: 'To put the passbook copy on a counterparty account, replacing the one it had; no file takes it away' }),
|
|
48
|
+
tslib_1.__param(0, (0, type_graphql_1.Arg)('accountId')),
|
|
49
|
+
tslib_1.__param(1, (0, type_graphql_1.Arg)('file', type => GraphQLUpload_js_1.default, { nullable: true })),
|
|
50
|
+
tslib_1.__param(2, (0, type_graphql_1.Ctx)()),
|
|
51
|
+
tslib_1.__metadata("design:type", Function),
|
|
52
|
+
tslib_1.__metadata("design:paramtypes", [String, Object, Object]),
|
|
53
|
+
tslib_1.__metadata("design:returntype", Promise)
|
|
54
|
+
], CounterpartyBankAccountMutation.prototype, "attachCounterpartyPassbook", null);
|
|
55
|
+
tslib_1.__decorate([
|
|
56
|
+
(0, type_graphql_1.Directive)('@transaction'),
|
|
57
|
+
(0, type_graphql_1.Directive)('@privilege(category: "counterparty", privilege: "mutation", domainOwnerGranted: true)'),
|
|
58
|
+
(0, type_graphql_1.Mutation)(returns => attachment_base_1.Attachment, { nullable: true, description: 'To put the business registration certificate on a counterparty, replacing the one it had; no file takes it away' }),
|
|
59
|
+
tslib_1.__param(0, (0, type_graphql_1.Arg)('counterpartyId')),
|
|
60
|
+
tslib_1.__param(1, (0, type_graphql_1.Arg)('file', type => GraphQLUpload_js_1.default, { nullable: true })),
|
|
61
|
+
tslib_1.__param(2, (0, type_graphql_1.Ctx)()),
|
|
62
|
+
tslib_1.__metadata("design:type", Function),
|
|
63
|
+
tslib_1.__metadata("design:paramtypes", [String, Object, Object]),
|
|
64
|
+
tslib_1.__metadata("design:returntype", Promise)
|
|
65
|
+
], CounterpartyBankAccountMutation.prototype, "attachCounterpartyBusinessRegistration", null);
|
|
66
|
+
exports.CounterpartyBankAccountMutation = CounterpartyBankAccountMutation = tslib_1.__decorate([
|
|
67
|
+
(0, type_graphql_1.Resolver)(counterparty_bank_account_1.CounterpartyBankAccount),
|
|
68
|
+
(0, type_graphql_1.UseMiddleware)(shell_1.SpeakRefusals)
|
|
69
|
+
], CounterpartyBankAccountMutation);
|
|
70
|
+
//# sourceMappingURL=counterparty-bank-account-mutation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"counterparty-bank-account-mutation.js","sourceRoot":"","sources":["../../../server/service/counterparty/counterparty-bank-account-mutation.ts"],"names":[],"mappings":"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","sourcesContent":["import type { FileUpload } from 'graphql-upload/GraphQLUpload.js'\nimport GraphQLUpload from 'graphql-upload/GraphQLUpload.js'\nimport { Arg, Ctx, Directive, Mutation, Resolver, UseMiddleware } from 'type-graphql'\n\nimport { Attachment, replaceAttachment } from '@things-factory/attachment-base'\nimport { getRepository, Refusal, SpeakRefusals } from '@things-factory/shell'\n\nimport { Counterparty } from './counterparty'\nimport { CounterpartyBankAccount } from './counterparty-bank-account'\nimport { BUSINESS_REGISTRATION_REF_TYPE, PASSBOOK_REF_TYPE, saveCounterpartyBankAccounts } from './counterparty-bank-account-service'\nimport { CounterpartyBankAccountPatch } from './counterparty-type'\n\n@Resolver(CounterpartyBankAccount)\n@UseMiddleware(SpeakRefusals)\nexport class CounterpartyBankAccountMutation {\n @Directive('@transaction')\n @Directive('@privilege(category: \"counterparty\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Mutation(returns => [CounterpartyBankAccount], { description: 'To save counterparty accounts - new, changed and deleted rows together' })\n async updateMultipleCounterpartyBankAccount(\n @Arg('patches', type => [CounterpartyBankAccountPatch]) patches: CounterpartyBankAccountPatch[],\n @Ctx() context: ResolverContext\n ): Promise<CounterpartyBankAccount[]> {\n const { tx, domain, user } = context.state\n return await saveCounterpartyBankAccounts(tx, domain, user, patches)\n }\n\n @Directive('@transaction')\n @Directive('@privilege(category: \"counterparty\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Mutation(returns => Attachment, { nullable: true, description: 'To put the passbook copy on a counterparty account, replacing the one it had; no file takes it away' })\n async attachCounterpartyPassbook(\n @Arg('accountId') accountId: string,\n @Arg('file', type => GraphQLUpload, { nullable: true }) file: FileUpload | null,\n @Ctx() context: ResolverContext\n ): Promise<Attachment | null> {\n const { tx, domain } = context.state\n const account = await tx.getRepository(CounterpartyBankAccount).findOne({ where: { domain: { id: domain.id }, id: accountId } })\n if (!account) throw new Refusal('counterparty-account-not-found', {}, 'an account was not found - reload and try again')\n return await replaceAttachment({ file, refType: PASSBOOK_REF_TYPE, refBy: account.id, category: 'passbook' }, context)\n }\n\n @Directive('@transaction')\n @Directive('@privilege(category: \"counterparty\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Mutation(returns => Attachment, { nullable: true, description: 'To put the business registration certificate on a counterparty, replacing the one it had; no file takes it away' })\n async attachCounterpartyBusinessRegistration(\n @Arg('counterpartyId') counterpartyId: string,\n @Arg('file', type => GraphQLUpload, { nullable: true }) file: FileUpload | null,\n @Ctx() context: ResolverContext\n ): Promise<Attachment | null> {\n const { tx, domain } = context.state\n const counterparty = await tx.getRepository(Counterparty).findOne({ where: { domain: { id: domain.id }, id: counterpartyId } })\n if (!counterparty) throw new Refusal('counterparty-not-found', {}, 'a counterparty was not found - reload and try again')\n return await replaceAttachment({ file, refType: BUSINESS_REGISTRATION_REF_TYPE, refBy: counterparty.id, category: 'business-registration' }, context)\n }\n}\n"]}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Attachment } from '@things-factory/attachment-base';
|
|
2
|
+
import { User } from '@things-factory/auth-base';
|
|
3
|
+
import { Counterparty } from './counterparty';
|
|
4
|
+
import { CounterpartyBankAccount } from './counterparty-bank-account';
|
|
5
|
+
export declare class CounterpartyBankAccountQuery {
|
|
6
|
+
counterpartyBankAccounts(counterpartyId: string, context: ResolverContext): Promise<CounterpartyBankAccount[]>;
|
|
7
|
+
counterparty(account: CounterpartyBankAccount): Promise<Counterparty | null>;
|
|
8
|
+
passbookCopy(account: CounterpartyBankAccount): Promise<Attachment | null>;
|
|
9
|
+
creator(account: CounterpartyBankAccount): Promise<User | null>;
|
|
10
|
+
updater(account: CounterpartyBankAccount): Promise<User | null>;
|
|
11
|
+
}
|
|
12
|
+
/** What a counterparty has on file: its business registration and the accounts it is paid into. */
|
|
13
|
+
export declare class CounterpartyFilesQuery {
|
|
14
|
+
businessRegistration(counterparty: Counterparty): Promise<Attachment | null>;
|
|
15
|
+
bankAccountCount(counterparty: Counterparty): Promise<number>;
|
|
16
|
+
}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CounterpartyFilesQuery = exports.CounterpartyBankAccountQuery = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const type_graphql_1 = require("type-graphql");
|
|
6
|
+
const attachment_base_1 = require("@things-factory/attachment-base");
|
|
7
|
+
const auth_base_1 = require("@things-factory/auth-base");
|
|
8
|
+
const shell_1 = require("@things-factory/shell");
|
|
9
|
+
const counterparty_1 = require("./counterparty");
|
|
10
|
+
const counterparty_bank_account_1 = require("./counterparty-bank-account");
|
|
11
|
+
const counterparty_bank_account_service_1 = require("./counterparty-bank-account-service");
|
|
12
|
+
/** The one file a record keeps under a refType, or null. */
|
|
13
|
+
async function documentOf(domainId, refType, refBy) {
|
|
14
|
+
return await (0, shell_1.getRepository)(attachment_base_1.Attachment).findOne({ where: { domain: { id: domainId }, refType, refBy }, order: { createdAt: 'DESC' } });
|
|
15
|
+
}
|
|
16
|
+
let CounterpartyBankAccountQuery = class CounterpartyBankAccountQuery {
|
|
17
|
+
async counterpartyBankAccounts(counterpartyId, context) {
|
|
18
|
+
return await (0, shell_1.getRepository)(counterparty_bank_account_1.CounterpartyBankAccount).find({
|
|
19
|
+
where: { domain: { id: context.state.domain.id }, counterparty: { id: counterpartyId } },
|
|
20
|
+
order: { createdAt: 'ASC' }
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
async counterparty(account) {
|
|
24
|
+
return account.counterparty ?? (account.counterpartyId ? await (0, shell_1.getRepository)(counterparty_1.Counterparty).findOneBy({ id: account.counterpartyId }) : null);
|
|
25
|
+
}
|
|
26
|
+
async passbookCopy(account) {
|
|
27
|
+
return await documentOf(account.domainId, counterparty_bank_account_service_1.PASSBOOK_REF_TYPE, account.id);
|
|
28
|
+
}
|
|
29
|
+
async creator(account) {
|
|
30
|
+
return account.creator ?? (account.creatorId ? await (0, shell_1.getRepository)(auth_base_1.User).findOneBy({ id: account.creatorId }) : null);
|
|
31
|
+
}
|
|
32
|
+
async updater(account) {
|
|
33
|
+
return account.updater ?? (account.updaterId ? await (0, shell_1.getRepository)(auth_base_1.User).findOneBy({ id: account.updaterId }) : null);
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
exports.CounterpartyBankAccountQuery = CounterpartyBankAccountQuery;
|
|
37
|
+
tslib_1.__decorate([
|
|
38
|
+
(0, type_graphql_1.Directive)('@privilege(category: "counterparty", privilege: "query", domainOwnerGranted: true)'),
|
|
39
|
+
(0, type_graphql_1.Query)(returns => [counterparty_bank_account_1.CounterpartyBankAccount], { description: 'The accounts a counterparty of the domain is paid into' }),
|
|
40
|
+
tslib_1.__param(0, (0, type_graphql_1.Arg)('counterpartyId')),
|
|
41
|
+
tslib_1.__param(1, (0, type_graphql_1.Ctx)()),
|
|
42
|
+
tslib_1.__metadata("design:type", Function),
|
|
43
|
+
tslib_1.__metadata("design:paramtypes", [String, Object]),
|
|
44
|
+
tslib_1.__metadata("design:returntype", Promise)
|
|
45
|
+
], CounterpartyBankAccountQuery.prototype, "counterpartyBankAccounts", null);
|
|
46
|
+
tslib_1.__decorate([
|
|
47
|
+
(0, type_graphql_1.FieldResolver)(type => counterparty_1.Counterparty, { nullable: true }),
|
|
48
|
+
tslib_1.__param(0, (0, type_graphql_1.Root)()),
|
|
49
|
+
tslib_1.__metadata("design:type", Function),
|
|
50
|
+
tslib_1.__metadata("design:paramtypes", [counterparty_bank_account_1.CounterpartyBankAccount]),
|
|
51
|
+
tslib_1.__metadata("design:returntype", Promise)
|
|
52
|
+
], CounterpartyBankAccountQuery.prototype, "counterparty", null);
|
|
53
|
+
tslib_1.__decorate([
|
|
54
|
+
(0, type_graphql_1.FieldResolver)(type => attachment_base_1.Attachment, { nullable: true, description: 'The passbook copy (통장사본) - it shows the account number' }),
|
|
55
|
+
tslib_1.__param(0, (0, type_graphql_1.Root)()),
|
|
56
|
+
tslib_1.__metadata("design:type", Function),
|
|
57
|
+
tslib_1.__metadata("design:paramtypes", [counterparty_bank_account_1.CounterpartyBankAccount]),
|
|
58
|
+
tslib_1.__metadata("design:returntype", Promise)
|
|
59
|
+
], CounterpartyBankAccountQuery.prototype, "passbookCopy", null);
|
|
60
|
+
tslib_1.__decorate([
|
|
61
|
+
(0, type_graphql_1.FieldResolver)(type => auth_base_1.User, { nullable: true }),
|
|
62
|
+
tslib_1.__param(0, (0, type_graphql_1.Root)()),
|
|
63
|
+
tslib_1.__metadata("design:type", Function),
|
|
64
|
+
tslib_1.__metadata("design:paramtypes", [counterparty_bank_account_1.CounterpartyBankAccount]),
|
|
65
|
+
tslib_1.__metadata("design:returntype", Promise)
|
|
66
|
+
], CounterpartyBankAccountQuery.prototype, "creator", null);
|
|
67
|
+
tslib_1.__decorate([
|
|
68
|
+
(0, type_graphql_1.FieldResolver)(type => auth_base_1.User, { nullable: true }),
|
|
69
|
+
tslib_1.__param(0, (0, type_graphql_1.Root)()),
|
|
70
|
+
tslib_1.__metadata("design:type", Function),
|
|
71
|
+
tslib_1.__metadata("design:paramtypes", [counterparty_bank_account_1.CounterpartyBankAccount]),
|
|
72
|
+
tslib_1.__metadata("design:returntype", Promise)
|
|
73
|
+
], CounterpartyBankAccountQuery.prototype, "updater", null);
|
|
74
|
+
exports.CounterpartyBankAccountQuery = CounterpartyBankAccountQuery = tslib_1.__decorate([
|
|
75
|
+
(0, type_graphql_1.Resolver)(counterparty_bank_account_1.CounterpartyBankAccount)
|
|
76
|
+
], CounterpartyBankAccountQuery);
|
|
77
|
+
/** What a counterparty has on file: its business registration and the accounts it is paid into. */
|
|
78
|
+
let CounterpartyFilesQuery = class CounterpartyFilesQuery {
|
|
79
|
+
async businessRegistration(counterparty) {
|
|
80
|
+
return await documentOf(counterparty.domainId, counterparty_bank_account_service_1.BUSINESS_REGISTRATION_REF_TYPE, counterparty.id);
|
|
81
|
+
}
|
|
82
|
+
async bankAccountCount(counterparty) {
|
|
83
|
+
return await (0, shell_1.getRepository)(counterparty_bank_account_1.CounterpartyBankAccount).count({ where: { counterparty: { id: counterparty.id } } });
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
exports.CounterpartyFilesQuery = CounterpartyFilesQuery;
|
|
87
|
+
tslib_1.__decorate([
|
|
88
|
+
(0, type_graphql_1.FieldResolver)(type => attachment_base_1.Attachment, { nullable: true, description: 'Its business registration certificate (사업자등록증)' }),
|
|
89
|
+
tslib_1.__param(0, (0, type_graphql_1.Root)()),
|
|
90
|
+
tslib_1.__metadata("design:type", Function),
|
|
91
|
+
tslib_1.__metadata("design:paramtypes", [counterparty_1.Counterparty]),
|
|
92
|
+
tslib_1.__metadata("design:returntype", Promise)
|
|
93
|
+
], CounterpartyFilesQuery.prototype, "businessRegistration", null);
|
|
94
|
+
tslib_1.__decorate([
|
|
95
|
+
(0, type_graphql_1.FieldResolver)(type => type_graphql_1.Int, { description: 'How many accounts it is paid into are registered' }),
|
|
96
|
+
tslib_1.__param(0, (0, type_graphql_1.Root)()),
|
|
97
|
+
tslib_1.__metadata("design:type", Function),
|
|
98
|
+
tslib_1.__metadata("design:paramtypes", [counterparty_1.Counterparty]),
|
|
99
|
+
tslib_1.__metadata("design:returntype", Promise)
|
|
100
|
+
], CounterpartyFilesQuery.prototype, "bankAccountCount", null);
|
|
101
|
+
exports.CounterpartyFilesQuery = CounterpartyFilesQuery = tslib_1.__decorate([
|
|
102
|
+
(0, type_graphql_1.Resolver)(counterparty_1.Counterparty)
|
|
103
|
+
], CounterpartyFilesQuery);
|
|
104
|
+
//# sourceMappingURL=counterparty-bank-account-query.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"counterparty-bank-account-query.js","sourceRoot":"","sources":["../../../server/service/counterparty/counterparty-bank-account-query.ts"],"names":[],"mappings":"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","sourcesContent":["import { Arg, Ctx, Directive, FieldResolver, Int, Query, Resolver, Root } from 'type-graphql'\n\nimport { Attachment } from '@things-factory/attachment-base'\nimport { User } from '@things-factory/auth-base'\nimport { getRepository } from '@things-factory/shell'\n\nimport { Counterparty } from './counterparty'\nimport { CounterpartyBankAccount } from './counterparty-bank-account'\nimport { BUSINESS_REGISTRATION_REF_TYPE, PASSBOOK_REF_TYPE } from './counterparty-bank-account-service'\n\n/** The one file a record keeps under a refType, or null. */\nasync function documentOf(domainId: string | undefined, refType: string, refBy: string): Promise<Attachment | null> {\n return await getRepository(Attachment).findOne({ where: { domain: { id: domainId }, refType, refBy }, order: { createdAt: 'DESC' } as any })\n}\n\n@Resolver(CounterpartyBankAccount)\nexport class CounterpartyBankAccountQuery {\n @Directive('@privilege(category: \"counterparty\", privilege: \"query\", domainOwnerGranted: true)')\n @Query(returns => [CounterpartyBankAccount], { description: 'The accounts a counterparty of the domain is paid into' })\n async counterpartyBankAccounts(@Arg('counterpartyId') counterpartyId: string, @Ctx() context: ResolverContext): Promise<CounterpartyBankAccount[]> {\n return await getRepository(CounterpartyBankAccount).find({\n where: { domain: { id: context.state.domain.id }, counterparty: { id: counterpartyId } },\n order: { createdAt: 'ASC' }\n })\n }\n\n @FieldResolver(type => Counterparty, { nullable: true })\n async counterparty(@Root() account: CounterpartyBankAccount): Promise<Counterparty | null> {\n return account.counterparty ?? (account.counterpartyId ? await getRepository(Counterparty).findOneBy({ id: account.counterpartyId }) : null)\n }\n\n @FieldResolver(type => Attachment, { nullable: true, description: 'The passbook copy (통장사본) - it shows the account number' })\n async passbookCopy(@Root() account: CounterpartyBankAccount): Promise<Attachment | null> {\n return await documentOf(account.domainId, PASSBOOK_REF_TYPE, account.id)\n }\n\n @FieldResolver(type => User, { nullable: true })\n async creator(@Root() account: CounterpartyBankAccount): Promise<User | null> {\n return account.creator ?? (account.creatorId ? await getRepository(User).findOneBy({ id: account.creatorId }) : null)\n }\n\n @FieldResolver(type => User, { nullable: true })\n async updater(@Root() account: CounterpartyBankAccount): Promise<User | null> {\n return account.updater ?? (account.updaterId ? await getRepository(User).findOneBy({ id: account.updaterId }) : null)\n }\n}\n\n/** What a counterparty has on file: its business registration and the accounts it is paid into. */\n@Resolver(Counterparty)\nexport class CounterpartyFilesQuery {\n @FieldResolver(type => Attachment, { nullable: true, description: 'Its business registration certificate (사업자등록증)' })\n async businessRegistration(@Root() counterparty: Counterparty): Promise<Attachment | null> {\n return await documentOf(counterparty.domainId, BUSINESS_REGISTRATION_REF_TYPE, counterparty.id)\n }\n\n @FieldResolver(type => Int, { description: 'How many accounts it is paid into are registered' })\n async bankAccountCount(@Root() counterparty: Counterparty): Promise<number> {\n return await getRepository(CounterpartyBankAccount).count({ where: { counterparty: { id: counterparty.id } } })\n }\n}\n"]}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { EntityManager } from 'typeorm';
|
|
2
|
+
import { CounterpartyBankAccount } from './counterparty-bank-account';
|
|
3
|
+
import { CounterpartyBankAccountPatch } from './counterparty-type';
|
|
4
|
+
/**
|
|
5
|
+
* Saving the accounts counterparties are paid into (ADR-0134), and what a module does once they are saved.
|
|
6
|
+
*
|
|
7
|
+
* A module whose rows carry an account number the bank wrote (accounting's bank lines) links them to the counterparty
|
|
8
|
+
* the number is registered to — that is its rule, not this one's — by listening here (§`onCounterpartyBankAccountsSaved`).
|
|
9
|
+
*/
|
|
10
|
+
/** The refType of a counterparty's business registration certificate. */
|
|
11
|
+
export declare const BUSINESS_REGISTRATION_REF_TYPE = "Counterparty Business Registration";
|
|
12
|
+
/** The refType of the passbook copy of a counterparty account - it shows the account number. */
|
|
13
|
+
export declare const PASSBOOK_REF_TYPE = "Counterparty Passbook";
|
|
14
|
+
type Saved = (tx: EntityManager, domain: {
|
|
15
|
+
id: string;
|
|
16
|
+
}, saved: CounterpartyBankAccount[], user: any) => Promise<void>;
|
|
17
|
+
/** Run after every save of counterparty accounts, in the same transaction. */
|
|
18
|
+
export declare function onCounterpartyBankAccountsSaved(listener: Saved): void;
|
|
19
|
+
/**
|
|
20
|
+
* Apply grid rows to a domain's counterparty accounts: `+` (or no id) registers, `M` changes, `-` deletes (softly — its
|
|
21
|
+
* passbook copy stays with it). An account number held by two live accounts is refused, naming the counterparty that
|
|
22
|
+
* holds it.
|
|
23
|
+
*/
|
|
24
|
+
export declare function saveCounterpartyBankAccounts(tx: EntityManager, domain: {
|
|
25
|
+
id: string;
|
|
26
|
+
}, user: any, patches: CounterpartyBankAccountPatch[]): Promise<CounterpartyBankAccount[]>;
|
|
27
|
+
export {};
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PASSBOOK_REF_TYPE = exports.BUSINESS_REGISTRATION_REF_TYPE = void 0;
|
|
4
|
+
exports.onCounterpartyBankAccountsSaved = onCounterpartyBankAccountsSaved;
|
|
5
|
+
exports.saveCounterpartyBankAccounts = saveCounterpartyBankAccounts;
|
|
6
|
+
const typeorm_1 = require("typeorm");
|
|
7
|
+
const shell_1 = require("@things-factory/shell");
|
|
8
|
+
const counterparty_1 = require("./counterparty");
|
|
9
|
+
const counterparty_bank_account_1 = require("./counterparty-bank-account");
|
|
10
|
+
const counterparty_names_1 = require("./counterparty-names");
|
|
11
|
+
/**
|
|
12
|
+
* Saving the accounts counterparties are paid into (ADR-0134), and what a module does once they are saved.
|
|
13
|
+
*
|
|
14
|
+
* A module whose rows carry an account number the bank wrote (accounting's bank lines) links them to the counterparty
|
|
15
|
+
* the number is registered to — that is its rule, not this one's — by listening here (§`onCounterpartyBankAccountsSaved`).
|
|
16
|
+
*/
|
|
17
|
+
/** The refType of a counterparty's business registration certificate. */
|
|
18
|
+
exports.BUSINESS_REGISTRATION_REF_TYPE = 'Counterparty Business Registration';
|
|
19
|
+
/** The refType of the passbook copy of a counterparty account - it shows the account number. */
|
|
20
|
+
exports.PASSBOOK_REF_TYPE = 'Counterparty Passbook';
|
|
21
|
+
const listeners = [];
|
|
22
|
+
/** Run after every save of counterparty accounts, in the same transaction. */
|
|
23
|
+
function onCounterpartyBankAccountsSaved(listener) {
|
|
24
|
+
listeners.push(listener);
|
|
25
|
+
}
|
|
26
|
+
const TEXT = ['bankName', 'holderName', 'notes'];
|
|
27
|
+
function rowOf(patch, isNew) {
|
|
28
|
+
const row = {};
|
|
29
|
+
for (const field of TEXT)
|
|
30
|
+
if (patch[field] !== undefined)
|
|
31
|
+
row[field] = String(patch[field] ?? '').trim() || null;
|
|
32
|
+
if (patch.accountNumber !== undefined || isNew) {
|
|
33
|
+
const key = (0, counterparty_names_1.accountKey)(patch.accountNumber);
|
|
34
|
+
if (!key)
|
|
35
|
+
throw new shell_1.Refusal('counterparty-account-number-required', {}, 'an account needs its number');
|
|
36
|
+
row.accountNumber = key;
|
|
37
|
+
}
|
|
38
|
+
if (patch.counterpartyId !== undefined || isNew) {
|
|
39
|
+
if (!patch.counterpartyId)
|
|
40
|
+
throw new shell_1.Refusal('counterparty-not-found', {}, 'an account needs its counterparty');
|
|
41
|
+
row.counterpartyId = patch.counterpartyId;
|
|
42
|
+
}
|
|
43
|
+
return row;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Apply grid rows to a domain's counterparty accounts: `+` (or no id) registers, `M` changes, `-` deletes (softly — its
|
|
47
|
+
* passbook copy stays with it). An account number held by two live accounts is refused, naming the counterparty that
|
|
48
|
+
* holds it.
|
|
49
|
+
*/
|
|
50
|
+
async function saveCounterpartyBankAccounts(tx, domain, user, patches) {
|
|
51
|
+
const repo = tx.getRepository(counterparty_bank_account_1.CounterpartyBankAccount);
|
|
52
|
+
const deletes = patches.filter(one => one.cuFlag === '-' && one.id).map(one => one.id);
|
|
53
|
+
const updates = patches.filter(one => one.id && one.cuFlag !== '-' && one.cuFlag !== '+').map(one => ({ id: one.id, ...rowOf(one, false) }));
|
|
54
|
+
const creates = patches.filter(one => !one.id || one.cuFlag === '+').filter(one => one.cuFlag !== '-').map(one => rowOf(one, true));
|
|
55
|
+
const parties = new Map((await tx.getRepository(counterparty_1.Counterparty).find({ where: { domain: { id: domain.id } }, select: ['id', 'name'] })).map(one => [one.id, one]));
|
|
56
|
+
for (const row of [...updates, ...creates])
|
|
57
|
+
if (row.counterpartyId && !parties.has(row.counterpartyId))
|
|
58
|
+
throw new shell_1.Refusal('counterparty-not-found', {}, 'a counterparty was not found - reload and try again');
|
|
59
|
+
const existing = await repo.find({ where: { domain: { id: domain.id } } });
|
|
60
|
+
const owned = new Map(existing.map(one => [one.id, one]));
|
|
61
|
+
for (const id of [...deletes, ...updates.map(one => one.id)])
|
|
62
|
+
if (!owned.has(id))
|
|
63
|
+
throw new shell_1.Refusal('counterparty-account-not-found', {}, 'an account was not found - reload and try again');
|
|
64
|
+
const holder = (counterpartyId) => parties.get(counterpartyId ?? '')?.name ?? '';
|
|
65
|
+
const clash = (0, counterparty_names_1.keyClash)(existing.map(one => ({ id: one.id, label: holder(one.counterpartyId), key: one.accountNumber })), [...updates, ...creates].map(one => ({
|
|
66
|
+
id: one.id,
|
|
67
|
+
label: one.counterpartyId ? holder(one.counterpartyId) : undefined,
|
|
68
|
+
key: one.accountNumber
|
|
69
|
+
})), deletes);
|
|
70
|
+
if (clash)
|
|
71
|
+
throw new shell_1.Refusal('counterparty-account-clash', clash, `account ${clash.number} is already registered to '${clash.existing}'`);
|
|
72
|
+
if (deletes.length)
|
|
73
|
+
await repo.softDelete({ id: (0, typeorm_1.In)(deletes) });
|
|
74
|
+
const ids = [];
|
|
75
|
+
for (const { counterpartyId, ...row } of updates) {
|
|
76
|
+
const current = owned.get(row.id);
|
|
77
|
+
ids.push((await repo.save({ ...current, ...row, ...(counterpartyId ? { counterparty: { id: counterpartyId } } : {}), updater: user })).id);
|
|
78
|
+
}
|
|
79
|
+
for (const { counterpartyId, ...row } of creates)
|
|
80
|
+
ids.push((await repo.save({ ...row, counterparty: { id: counterpartyId }, domain, creator: user, updater: user })).id);
|
|
81
|
+
/* Read back, so a listener has the counterparty of each as well as its number. */
|
|
82
|
+
const saved = ids.length ? await repo.find({ where: { id: (0, typeorm_1.In)(ids) } }) : [];
|
|
83
|
+
for (const listener of listeners)
|
|
84
|
+
await listener(tx, domain, saved, user);
|
|
85
|
+
return saved;
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=counterparty-bank-account-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"counterparty-bank-account-service.js","sourceRoot":"","sources":["../../../server/service/counterparty/counterparty-bank-account-service.ts"],"names":[],"mappings":"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","sourcesContent":["import { EntityManager, In } from 'typeorm'\n\nimport { Refusal } from '@things-factory/shell'\n\nimport { Counterparty } from './counterparty'\nimport { CounterpartyBankAccount } from './counterparty-bank-account'\nimport { accountKey, keyClash } from './counterparty-names'\nimport { CounterpartyBankAccountPatch } from './counterparty-type'\n\n/**\n * Saving the accounts counterparties are paid into (ADR-0134), and what a module does once they are saved.\n *\n * A module whose rows carry an account number the bank wrote (accounting's bank lines) links them to the counterparty\n * the number is registered to — that is its rule, not this one's — by listening here (§`onCounterpartyBankAccountsSaved`).\n */\n\n/** The refType of a counterparty's business registration certificate. */\nexport const BUSINESS_REGISTRATION_REF_TYPE = 'Counterparty Business Registration'\n/** The refType of the passbook copy of a counterparty account - it shows the account number. */\nexport const PASSBOOK_REF_TYPE = 'Counterparty Passbook'\n\ntype Saved = (tx: EntityManager, domain: { id: string }, saved: CounterpartyBankAccount[], user: any) => Promise<void>\nconst listeners: Saved[] = []\n\n/** Run after every save of counterparty accounts, in the same transaction. */\nexport function onCounterpartyBankAccountsSaved(listener: Saved): void {\n listeners.push(listener)\n}\n\nconst TEXT = ['bankName', 'holderName', 'notes'] as const\n\nfunction rowOf(patch: CounterpartyBankAccountPatch, isNew: boolean): Partial<CounterpartyBankAccount> & { counterpartyId?: string } {\n const row: Record<string, any> = {}\n for (const field of TEXT) if (patch[field] !== undefined) row[field] = String(patch[field] ?? '').trim() || null\n if (patch.accountNumber !== undefined || isNew) {\n const key = accountKey(patch.accountNumber)\n if (!key) throw new Refusal('counterparty-account-number-required', {}, 'an account needs its number')\n row.accountNumber = key\n }\n if (patch.counterpartyId !== undefined || isNew) {\n if (!patch.counterpartyId) throw new Refusal('counterparty-not-found', {}, 'an account needs its counterparty')\n row.counterpartyId = patch.counterpartyId\n }\n return row\n}\n\n/**\n * Apply grid rows to a domain's counterparty accounts: `+` (or no id) registers, `M` changes, `-` deletes (softly — its\n * passbook copy stays with it). An account number held by two live accounts is refused, naming the counterparty that\n * holds it.\n */\nexport async function saveCounterpartyBankAccounts(\n tx: EntityManager,\n domain: { id: string },\n user: any,\n patches: CounterpartyBankAccountPatch[]\n): Promise<CounterpartyBankAccount[]> {\n const repo = tx.getRepository(CounterpartyBankAccount)\n const deletes = patches.filter(one => one.cuFlag === '-' && one.id).map(one => one.id!)\n const updates = patches.filter(one => one.id && one.cuFlag !== '-' && one.cuFlag !== '+').map(one => ({ id: one.id!, ...rowOf(one, false) }))\n const creates = patches.filter(one => !one.id || one.cuFlag === '+').filter(one => one.cuFlag !== '-').map(one => rowOf(one, true))\n\n const parties = new Map(\n (await tx.getRepository(Counterparty).find({ where: { domain: { id: domain.id } }, select: ['id', 'name'] })).map(one => [one.id, one])\n )\n for (const row of [...updates, ...creates])\n if (row.counterpartyId && !parties.has(row.counterpartyId))\n throw new Refusal('counterparty-not-found', {}, 'a counterparty was not found - reload and try again')\n\n const existing = await repo.find({ where: { domain: { id: domain.id } } })\n const owned = new Map(existing.map(one => [one.id, one]))\n for (const id of [...deletes, ...updates.map(one => one.id)])\n if (!owned.has(id)) throw new Refusal('counterparty-account-not-found', {}, 'an account was not found - reload and try again')\n\n const holder = (counterpartyId?: string) => parties.get(counterpartyId ?? '')?.name ?? ''\n const clash = keyClash(\n existing.map(one => ({ id: one.id, label: holder(one.counterpartyId), key: one.accountNumber })),\n [...updates, ...creates].map(one => ({\n id: (one as any).id,\n label: one.counterpartyId ? holder(one.counterpartyId) : undefined,\n key: one.accountNumber\n })),\n deletes\n )\n if (clash)\n throw new Refusal('counterparty-account-clash', clash, `account ${clash.number} is already registered to '${clash.existing}'`)\n\n if (deletes.length) await repo.softDelete({ id: In(deletes) })\n\n const ids: string[] = []\n for (const { counterpartyId, ...row } of updates) {\n const current = owned.get(row.id)!\n ids.push((await repo.save({ ...current, ...row, ...(counterpartyId ? { counterparty: { id: counterpartyId } } : {}), updater: user } as CounterpartyBankAccount)).id)\n }\n for (const { counterpartyId, ...row } of creates)\n ids.push((await repo.save({ ...row, counterparty: { id: counterpartyId }, domain, creator: user, updater: user } as CounterpartyBankAccount)).id)\n\n /* Read back, so a listener has the counterparty of each as well as its number. */\n const saved = ids.length ? await repo.find({ where: { id: In(ids) } }) : []\n for (const listener of listeners) await listener(tx, domain, saved, user)\n return saved\n}\n"]}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { User } from '@things-factory/auth-base';
|
|
2
|
+
import { Domain } from '@things-factory/shell';
|
|
3
|
+
import { Counterparty } from './counterparty';
|
|
4
|
+
/**
|
|
5
|
+
* An account a counterparty is paid into — where money to it goes, and how a bank line paying it is told apart (ADR-0134).
|
|
6
|
+
*
|
|
7
|
+
* Not the business's own account (accounting `BankAccount`, a book of its money): this one has no balance and no lines.
|
|
8
|
+
* Only an account a person confirmed is kept; what the bank lines suggest is read from them, never stored.
|
|
9
|
+
*
|
|
10
|
+
* The number is kept as its digits (`accountKey`) and is one counterparty's in the domain — an account has one holder.
|
|
11
|
+
*/
|
|
12
|
+
export declare class CounterpartyBankAccount {
|
|
13
|
+
readonly id: string;
|
|
14
|
+
domain?: Domain;
|
|
15
|
+
domainId?: string;
|
|
16
|
+
counterparty?: Counterparty;
|
|
17
|
+
counterpartyId?: string;
|
|
18
|
+
bankName?: string;
|
|
19
|
+
accountNumber: string;
|
|
20
|
+
holderName?: string;
|
|
21
|
+
notes?: string;
|
|
22
|
+
createdAt?: Date;
|
|
23
|
+
updatedAt?: Date;
|
|
24
|
+
deletedAt?: Date;
|
|
25
|
+
creator?: User;
|
|
26
|
+
creatorId?: string;
|
|
27
|
+
updater?: User;
|
|
28
|
+
updaterId?: string;
|
|
29
|
+
}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CounterpartyBankAccount = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const type_graphql_1 = require("type-graphql");
|
|
6
|
+
const typeorm_1 = require("typeorm");
|
|
7
|
+
const auth_base_1 = require("@things-factory/auth-base");
|
|
8
|
+
const shell_1 = require("@things-factory/shell");
|
|
9
|
+
const counterparty_1 = require("./counterparty");
|
|
10
|
+
/**
|
|
11
|
+
* An account a counterparty is paid into — where money to it goes, and how a bank line paying it is told apart (ADR-0134).
|
|
12
|
+
*
|
|
13
|
+
* Not the business's own account (accounting `BankAccount`, a book of its money): this one has no balance and no lines.
|
|
14
|
+
* Only an account a person confirmed is kept; what the bank lines suggest is read from them, never stored.
|
|
15
|
+
*
|
|
16
|
+
* The number is kept as its digits (`accountKey`) and is one counterparty's in the domain — an account has one holder.
|
|
17
|
+
*/
|
|
18
|
+
let CounterpartyBankAccount = class CounterpartyBankAccount {
|
|
19
|
+
};
|
|
20
|
+
exports.CounterpartyBankAccount = CounterpartyBankAccount;
|
|
21
|
+
tslib_1.__decorate([
|
|
22
|
+
(0, typeorm_1.PrimaryGeneratedColumn)('uuid'),
|
|
23
|
+
(0, type_graphql_1.Field)(type => type_graphql_1.ID, { description: 'Unique identifier' }),
|
|
24
|
+
tslib_1.__metadata("design:type", String)
|
|
25
|
+
], CounterpartyBankAccount.prototype, "id", void 0);
|
|
26
|
+
tslib_1.__decorate([
|
|
27
|
+
(0, typeorm_1.ManyToOne)(type => shell_1.Domain),
|
|
28
|
+
(0, type_graphql_1.Field)(type => shell_1.Domain, { nullable: true, description: 'The domain whose record this is' }),
|
|
29
|
+
tslib_1.__metadata("design:type", shell_1.Domain)
|
|
30
|
+
], CounterpartyBankAccount.prototype, "domain", void 0);
|
|
31
|
+
tslib_1.__decorate([
|
|
32
|
+
(0, typeorm_1.RelationId)((account) => account.domain),
|
|
33
|
+
tslib_1.__metadata("design:type", String)
|
|
34
|
+
], CounterpartyBankAccount.prototype, "domainId", void 0);
|
|
35
|
+
tslib_1.__decorate([
|
|
36
|
+
(0, typeorm_1.ManyToOne)(type => counterparty_1.Counterparty, { nullable: false }),
|
|
37
|
+
(0, type_graphql_1.Field)(type => counterparty_1.Counterparty, { nullable: true, description: 'The counterparty the account is of' }),
|
|
38
|
+
tslib_1.__metadata("design:type", counterparty_1.Counterparty)
|
|
39
|
+
], CounterpartyBankAccount.prototype, "counterparty", void 0);
|
|
40
|
+
tslib_1.__decorate([
|
|
41
|
+
(0, typeorm_1.RelationId)((account) => account.counterparty),
|
|
42
|
+
tslib_1.__metadata("design:type", String)
|
|
43
|
+
], CounterpartyBankAccount.prototype, "counterpartyId", void 0);
|
|
44
|
+
tslib_1.__decorate([
|
|
45
|
+
(0, typeorm_1.Column)({ nullable: true }),
|
|
46
|
+
(0, type_graphql_1.Field)({ nullable: true, description: 'The bank' }),
|
|
47
|
+
tslib_1.__metadata("design:type", String)
|
|
48
|
+
], CounterpartyBankAccount.prototype, "bankName", void 0);
|
|
49
|
+
tslib_1.__decorate([
|
|
50
|
+
(0, typeorm_1.Column)(),
|
|
51
|
+
(0, type_graphql_1.Field)({ description: 'The account number, its digits - one counterparty\'s in the domain' }),
|
|
52
|
+
tslib_1.__metadata("design:type", String)
|
|
53
|
+
], CounterpartyBankAccount.prototype, "accountNumber", void 0);
|
|
54
|
+
tslib_1.__decorate([
|
|
55
|
+
(0, typeorm_1.Column)({ nullable: true }),
|
|
56
|
+
(0, type_graphql_1.Field)({ nullable: true, description: 'The account holder (예금주) as the bank has it' }),
|
|
57
|
+
tslib_1.__metadata("design:type", String)
|
|
58
|
+
], CounterpartyBankAccount.prototype, "holderName", void 0);
|
|
59
|
+
tslib_1.__decorate([
|
|
60
|
+
(0, typeorm_1.Column)({ type: 'text', nullable: true }),
|
|
61
|
+
(0, type_graphql_1.Field)({ nullable: true, description: 'Notes' }),
|
|
62
|
+
tslib_1.__metadata("design:type", String)
|
|
63
|
+
], CounterpartyBankAccount.prototype, "notes", void 0);
|
|
64
|
+
tslib_1.__decorate([
|
|
65
|
+
(0, typeorm_1.CreateDateColumn)(),
|
|
66
|
+
(0, type_graphql_1.Field)({ nullable: true, description: 'When it was registered' }),
|
|
67
|
+
tslib_1.__metadata("design:type", Date)
|
|
68
|
+
], CounterpartyBankAccount.prototype, "createdAt", void 0);
|
|
69
|
+
tslib_1.__decorate([
|
|
70
|
+
(0, typeorm_1.UpdateDateColumn)(),
|
|
71
|
+
(0, type_graphql_1.Field)({ nullable: true, description: 'When it last changed' }),
|
|
72
|
+
tslib_1.__metadata("design:type", Date)
|
|
73
|
+
], CounterpartyBankAccount.prototype, "updatedAt", void 0);
|
|
74
|
+
tslib_1.__decorate([
|
|
75
|
+
(0, typeorm_1.DeleteDateColumn)(),
|
|
76
|
+
(0, type_graphql_1.Field)({ nullable: true, description: 'When it was deleted' }),
|
|
77
|
+
tslib_1.__metadata("design:type", Date)
|
|
78
|
+
], CounterpartyBankAccount.prototype, "deletedAt", void 0);
|
|
79
|
+
tslib_1.__decorate([
|
|
80
|
+
(0, typeorm_1.ManyToOne)(type => auth_base_1.User, { nullable: true }),
|
|
81
|
+
(0, type_graphql_1.Field)(type => auth_base_1.User, { nullable: true, description: 'Who registered it' }),
|
|
82
|
+
tslib_1.__metadata("design:type", auth_base_1.User)
|
|
83
|
+
], CounterpartyBankAccount.prototype, "creator", void 0);
|
|
84
|
+
tslib_1.__decorate([
|
|
85
|
+
(0, typeorm_1.RelationId)((account) => account.creator),
|
|
86
|
+
tslib_1.__metadata("design:type", String)
|
|
87
|
+
], CounterpartyBankAccount.prototype, "creatorId", void 0);
|
|
88
|
+
tslib_1.__decorate([
|
|
89
|
+
(0, typeorm_1.ManyToOne)(type => auth_base_1.User, { nullable: true }),
|
|
90
|
+
(0, type_graphql_1.Field)(type => auth_base_1.User, { nullable: true, description: 'Who last changed it' }),
|
|
91
|
+
tslib_1.__metadata("design:type", auth_base_1.User)
|
|
92
|
+
], CounterpartyBankAccount.prototype, "updater", void 0);
|
|
93
|
+
tslib_1.__decorate([
|
|
94
|
+
(0, typeorm_1.RelationId)((account) => account.updater),
|
|
95
|
+
tslib_1.__metadata("design:type", String)
|
|
96
|
+
], CounterpartyBankAccount.prototype, "updaterId", void 0);
|
|
97
|
+
exports.CounterpartyBankAccount = CounterpartyBankAccount = tslib_1.__decorate([
|
|
98
|
+
(0, typeorm_1.Entity)(),
|
|
99
|
+
(0, typeorm_1.Index)('ix_counterparty_bank_account_0', (account) => [account.domain, account.accountNumber], { unique: true, where: '"deleted_at" IS NULL' }),
|
|
100
|
+
(0, typeorm_1.Index)('ix_counterparty_bank_account_1', (account) => [account.domain, account.counterparty], { where: '"deleted_at" IS NULL' }),
|
|
101
|
+
(0, type_graphql_1.ObjectType)({ description: 'An account a counterparty is paid into' })
|
|
102
|
+
], CounterpartyBankAccount);
|
|
103
|
+
//# sourceMappingURL=counterparty-bank-account.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"counterparty-bank-account.js","sourceRoot":"","sources":["../../../server/service/counterparty/counterparty-bank-account.ts"],"names":[],"mappings":"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","sourcesContent":["import { Field, ID, ObjectType } from 'type-graphql'\nimport { Column, CreateDateColumn, DeleteDateColumn, Entity, Index, ManyToOne, PrimaryGeneratedColumn, RelationId, UpdateDateColumn } from 'typeorm'\n\nimport { User } from '@things-factory/auth-base'\nimport { Domain } from '@things-factory/shell'\n\nimport { Counterparty } from './counterparty'\n\n/**\n * An account a counterparty is paid into — where money to it goes, and how a bank line paying it is told apart (ADR-0134).\n *\n * Not the business's own account (accounting `BankAccount`, a book of its money): this one has no balance and no lines.\n * Only an account a person confirmed is kept; what the bank lines suggest is read from them, never stored.\n *\n * The number is kept as its digits (`accountKey`) and is one counterparty's in the domain — an account has one holder.\n */\n@Entity()\n@Index('ix_counterparty_bank_account_0', (account: CounterpartyBankAccount) => [account.domain, account.accountNumber], { unique: true, where: '\"deleted_at\" IS NULL' })\n@Index('ix_counterparty_bank_account_1', (account: CounterpartyBankAccount) => [account.domain, account.counterparty], { where: '\"deleted_at\" IS NULL' })\n@ObjectType({ description: 'An account a counterparty is paid into' })\nexport class CounterpartyBankAccount {\n @PrimaryGeneratedColumn('uuid')\n @Field(type => ID, { description: 'Unique identifier' })\n readonly id: string\n\n @ManyToOne(type => Domain)\n @Field(type => Domain, { nullable: true, description: 'The domain whose record this is' })\n domain?: Domain\n\n @RelationId((account: CounterpartyBankAccount) => account.domain)\n domainId?: string\n\n @ManyToOne(type => Counterparty, { nullable: false })\n @Field(type => Counterparty, { nullable: true, description: 'The counterparty the account is of' })\n counterparty?: Counterparty\n\n @RelationId((account: CounterpartyBankAccount) => account.counterparty)\n counterpartyId?: string\n\n @Column({ nullable: true })\n @Field({ nullable: true, description: 'The bank' })\n bankName?: string\n\n @Column()\n @Field({ description: 'The account number, its digits - one counterparty\\'s in the domain' })\n accountNumber: string\n\n @Column({ nullable: true })\n @Field({ nullable: true, description: 'The account holder (예금주) as the bank has it' })\n holderName?: string\n\n @Column({ type: 'text', nullable: true })\n @Field({ nullable: true, description: 'Notes' })\n notes?: string\n\n @CreateDateColumn()\n @Field({ nullable: true, description: 'When it was registered' })\n createdAt?: Date\n\n @UpdateDateColumn()\n @Field({ nullable: true, description: 'When it last changed' })\n updatedAt?: Date\n\n @DeleteDateColumn()\n @Field({ nullable: true, description: 'When it was deleted' })\n deletedAt?: Date\n\n @ManyToOne(type => User, { nullable: true })\n @Field(type => User, { nullable: true, description: 'Who registered it' })\n creator?: User\n\n @RelationId((account: CounterpartyBankAccount) => account.creator)\n creatorId?: string\n\n @ManyToOne(type => User, { nullable: true })\n @Field(type => User, { nullable: true, description: 'Who last changed it' })\n updater?: User\n\n @RelationId((account: CounterpartyBankAccount) => account.updater)\n updaterId?: string\n}\n"]}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { checkPermission } from '@things-factory/auth-base';
|
|
2
|
+
/**
|
|
3
|
+
* Who may read a counterparty's business registration and its passbook copies by their attachment path (ADR-0106
|
|
4
|
+
* decision 2, ADR-0134): whoever may query counterparties. A passbook copy shows an account number, so it is no more open
|
|
5
|
+
* by its path than the account is. attachment-base has already checked the attachment is of the request's domain.
|
|
6
|
+
*/
|
|
7
|
+
export declare function counterpartyDocumentReader(_attachment: unknown, context: any, check?: typeof checkPermission): Promise<boolean>;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.counterpartyDocumentReader = counterpartyDocumentReader;
|
|
4
|
+
const attachment_base_1 = require("@things-factory/attachment-base");
|
|
5
|
+
const auth_base_1 = require("@things-factory/auth-base");
|
|
6
|
+
const counterparty_bank_account_service_1 = require("./counterparty-bank-account-service");
|
|
7
|
+
/**
|
|
8
|
+
* Who may read a counterparty's business registration and its passbook copies by their attachment path (ADR-0106
|
|
9
|
+
* decision 2, ADR-0134): whoever may query counterparties. A passbook copy shows an account number, so it is no more open
|
|
10
|
+
* by its path than the account is. attachment-base has already checked the attachment is of the request's domain.
|
|
11
|
+
*/
|
|
12
|
+
async function counterpartyDocumentReader(_attachment, context, check = auth_base_1.checkPermission) {
|
|
13
|
+
const { domain, user, unsafeIP, prohibitedPrivileges } = context?.state ?? {};
|
|
14
|
+
return !!(await check({ category: 'counterparty', privilege: 'query', owner: true }, user, domain, unsafeIP, prohibitedPrivileges));
|
|
15
|
+
}
|
|
16
|
+
for (const refType of [counterparty_bank_account_service_1.BUSINESS_REGISTRATION_REF_TYPE, counterparty_bank_account_service_1.PASSBOOK_REF_TYPE])
|
|
17
|
+
(0, attachment_base_1.registerAttachmentReader)(refType, (attachment, context) => counterpartyDocumentReader(attachment, context));
|
|
18
|
+
//# sourceMappingURL=counterparty-document-readers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"counterparty-document-readers.js","sourceRoot":"","sources":["../../../server/service/counterparty/counterparty-document-readers.ts"],"names":[],"mappings":";;AAUA,gEAGC;AAbD,qEAA0E;AAC1E,yDAA2D;AAE3D,2FAAuG;AAEvG;;;;GAIG;AACI,KAAK,UAAU,0BAA0B,CAAC,WAAoB,EAAE,OAAY,EAAE,QAAgC,2BAAe;IAClI,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,oBAAoB,EAAE,GAAG,OAAO,EAAE,KAAK,IAAI,EAAE,CAAA;IAC7E,OAAO,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,QAAQ,EAAE,cAAc,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,oBAAoB,CAAC,CAAC,CAAA;AACrI,CAAC;AAED,KAAK,MAAM,OAAO,IAAI,CAAC,kEAA8B,EAAE,qDAAiB,CAAC;IACvE,IAAA,0CAAwB,EAAC,OAAO,EAAE,CAAC,UAAU,EAAE,OAAO,EAAE,EAAE,CAAC,0BAA0B,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC,CAAA","sourcesContent":["import { registerAttachmentReader } from '@things-factory/attachment-base'\nimport { checkPermission } from '@things-factory/auth-base'\n\nimport { BUSINESS_REGISTRATION_REF_TYPE, PASSBOOK_REF_TYPE } from './counterparty-bank-account-service'\n\n/**\n * Who may read a counterparty's business registration and its passbook copies by their attachment path (ADR-0106\n * decision 2, ADR-0134): whoever may query counterparties. A passbook copy shows an account number, so it is no more open\n * by its path than the account is. attachment-base has already checked the attachment is of the request's domain.\n */\nexport async function counterpartyDocumentReader(_attachment: unknown, context: any, check: typeof checkPermission = checkPermission): Promise<boolean> {\n const { domain, user, unsafeIP, prohibitedPrivileges } = context?.state ?? {}\n return !!(await check({ category: 'counterparty', privilege: 'query', owner: true }, user, domain, unsafeIP, prohibitedPrivileges))\n}\n\nfor (const refType of [BUSINESS_REGISTRATION_REF_TYPE, PASSBOOK_REF_TYPE])\n registerAttachmentReader(refType, (attachment, context) => counterpartyDocumentReader(attachment, context))\n"]}
|
|
@@ -56,6 +56,28 @@ export declare function numberClash(existing: readonly (KnownCounterparty & {
|
|
|
56
56
|
existing: string;
|
|
57
57
|
name: string;
|
|
58
58
|
} | undefined;
|
|
59
|
+
/**
|
|
60
|
+
* Two rows holding one key that must be one row's — a business number, an account number — after a batch would apply.
|
|
61
|
+
* Only a clash the batch makes counts: a key it writes. A clash already in the rows does not stop another save.
|
|
62
|
+
*/
|
|
63
|
+
export declare function keyClash(existing: readonly {
|
|
64
|
+
id: string;
|
|
65
|
+
label: string;
|
|
66
|
+
key?: string | null;
|
|
67
|
+
}[], changes: readonly {
|
|
68
|
+
id?: string;
|
|
69
|
+
label?: string | null;
|
|
70
|
+
key?: string | null;
|
|
71
|
+
}[], deleted?: readonly string[]): {
|
|
72
|
+
number: string;
|
|
73
|
+
existing: string;
|
|
74
|
+
name: string;
|
|
75
|
+
} | undefined;
|
|
76
|
+
/**
|
|
77
|
+
* An account number as it is compared and kept — its digits. Banks print the same account with the hyphens in
|
|
78
|
+
* different places, so `110-123-456789` and `110123456789` are one account. Empty when there are no digits.
|
|
79
|
+
*/
|
|
80
|
+
export declare function accountKey(value: unknown): string;
|
|
59
81
|
/** Names to register: one spelling per party, skipping blanks and parties already known. */
|
|
60
82
|
export declare function namesToRegister(names: readonly (string | null | undefined)[], known: readonly KnownCounterparty[]): string[];
|
|
61
83
|
export interface PartyForMatch {
|