@things-factory/saas 10.1.238 → 10.1.239
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/service/saas-bill.d.ts +1 -0
- package/dist-server/service/saas-bill.js +5 -0
- package/dist-server/service/saas-bill.js.map +1 -1
- package/dist-server/service/saas-mutation.d.ts +5 -1
- package/dist-server/service/saas-mutation.js +15 -0
- package/dist-server/service/saas-mutation.js.map +1 -1
- package/dist-server/service/saas-service.js +2 -0
- package/dist-server/service/saas-service.js.map +1 -1
- package/dist-server/service/saas-sync.d.ts +35 -0
- package/dist-server/service/saas-sync.js +66 -6
- package/dist-server/service/saas-sync.js.map +1 -1
- package/dist-server/service/saas-type.d.ts +24 -0
- package/dist-server/service/saas-type.js +87 -1
- package/dist-server/service/saas-type.js.map +1 -1
- package/dist-server/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -2
- package/translations/en.json +4 -3
- package/translations/es.json +4 -3
- package/translations/ja.json +4 -3
- package/translations/ko.json +4 -3
- package/translations/ms.json +4 -3
- package/translations/zh.json +4 -3
|
@@ -54,6 +54,11 @@ tslib_1.__decorate([
|
|
|
54
54
|
(0, type_graphql_1.Field)({ description: 'The currency it is in - the account’s when it was written' }),
|
|
55
55
|
tslib_1.__metadata("design:type", String)
|
|
56
56
|
], SaasBill.prototype, "currency", void 0);
|
|
57
|
+
tslib_1.__decorate([
|
|
58
|
+
(0, typeorm_1.Column)({ default: false }),
|
|
59
|
+
(0, type_graphql_1.Field)({ description: "Written by a sync from the vendor's cost report - a later sync rewrites it; a bill a person wrote is never rewritten" }),
|
|
60
|
+
tslib_1.__metadata("design:type", Boolean)
|
|
61
|
+
], SaasBill.prototype, "synced", void 0);
|
|
57
62
|
tslib_1.__decorate([
|
|
58
63
|
(0, typeorm_1.OneToMany)(type => SaasBillLine, line => line.bill),
|
|
59
64
|
(0, type_graphql_1.Field)(type => [SaasBillLine], { nullable: true, description: 'One line a subscription, and lines on none - tax, credits' }),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"saas-bill.js","sourceRoot":"","sources":["../../server/service/saas-bill.ts"],"names":[],"mappings":";;;;AAAA,yDAAgD;AAChD,iDAA2D;AAC3D,+CAA2D;AAC3D,qCAA+J;AAE/J,iDAA4C;AAC5C,2DAAsD;AAEtD;;;;GAIG;AAII,IAAM,QAAQ,GAAd,MAAM,QAAQ;
|
|
1
|
+
{"version":3,"file":"saas-bill.js","sourceRoot":"","sources":["../../server/service/saas-bill.ts"],"names":[],"mappings":"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","sourcesContent":["import { User } from '@things-factory/auth-base'\nimport { Domain, moneyColumn } from '@things-factory/shell'\nimport { Field, Float, ID, ObjectType } from 'type-graphql'\nimport { Column, CreateDateColumn, DeleteDateColumn, Entity, Index, ManyToOne, OneToMany, PrimaryGeneratedColumn, RelationId, UpdateDateColumn } from 'typeorm'\n\nimport { SaasAccount } from './saas-account'\nimport { SaasSubscription } from './saas-subscription'\n\n/**\n * What an account was actually billed for a month (ADR-0177 decisions 5, 9) - one a month, in the account's currency,\n * one line a subscription and lines on none for tax and credits. Its total is the sum of its lines; the cost trend is\n * computed from these.\n */\n@Entity()\n@Index('ix_saas_bill_0', (bill: SaasBill) => [bill.domain, bill.account, bill.month])\n@ObjectType({ description: 'Entity for SaasBill — what an account was billed for a month' })\nexport class SaasBill {\n @PrimaryGeneratedColumn('uuid')\n @Field(type => ID, { description: 'Unique identifier of the bill' })\n readonly id: string\n\n @ManyToOne(type => Domain)\n @Field(type => Domain, { nullable: true, description: 'The domain the bill belongs to' })\n domain?: Domain\n\n @RelationId((bill: SaasBill) => bill.domain)\n domainId?: string\n\n @ManyToOne(type => SaasAccount, { onDelete: 'CASCADE' })\n @Field(type => SaasAccount, { nullable: true, description: 'The account billed' })\n account?: SaasAccount\n\n @RelationId((bill: SaasBill) => bill.account)\n accountId?: string\n\n @Column()\n @Field({ description: 'The month it bills - YYYY-MM' })\n month: string\n\n @Column({ nullable: true })\n @Field({ nullable: true, description: 'The day the vendor billed it - YYYY-MM-DD' })\n billedOn?: string\n\n @Column({ default: 'KRW' })\n @Field({ description: 'The currency it is in - the account’s when it was written' })\n currency: string\n\n @Column({ default: false })\n @Field({ description: \"Written by a sync from the vendor's cost report - a later sync rewrites it; a bill a person wrote is never rewritten\" })\n synced: boolean\n\n @OneToMany(type => SaasBillLine, line => line.bill)\n @Field(type => [SaasBillLine], { nullable: true, description: 'One line a subscription, and lines on none - tax, credits' })\n lines?: SaasBillLine[]\n\n @Field(type => Float, { nullable: true, description: 'The sum of its lines - filled by the query' })\n total?: number\n\n @Column({ type: 'text', nullable: true })\n @Field({ nullable: true, description: 'Notes' })\n description?: string\n\n @CreateDateColumn()\n @Field({ nullable: true, description: 'When the bill was written' })\n createdAt?: Date\n\n @UpdateDateColumn()\n @Field({ nullable: true, description: 'When the bill last changed' })\n updatedAt?: Date\n\n @DeleteDateColumn()\n @Field({ nullable: true, description: 'When the bill was deleted' })\n deletedAt?: Date\n\n @ManyToOne(type => User, { nullable: true })\n @Field(type => User, { nullable: true, description: 'Who wrote it' })\n creator?: User\n\n @RelationId((bill: SaasBill) => bill.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((bill: SaasBill) => bill.updater)\n updaterId?: string\n}\n\n/** One line of a bill - what one subscription cost that month, or tax and credits on none. */\n@Entity()\n@Index('ix_saas_bill_line_0', (line: SaasBillLine) => [line.domain, line.bill])\n@ObjectType({ description: 'Entity for SaasBillLine — what one subscription cost in a bill, or tax and credits' })\nexport class SaasBillLine {\n @PrimaryGeneratedColumn('uuid')\n @Field(type => ID, { description: 'Unique identifier of the line' })\n readonly id: string\n\n @ManyToOne(type => Domain)\n @Field(type => Domain, { nullable: true, description: 'The domain the line belongs to' })\n domain?: Domain\n\n @RelationId((line: SaasBillLine) => line.domain)\n domainId?: string\n\n @ManyToOne(type => SaasBill, bill => bill.lines, { onDelete: 'CASCADE' })\n @Field(type => SaasBill, { nullable: true, description: 'The bill it is a line of' })\n bill?: SaasBill\n\n @RelationId((line: SaasBillLine) => line.bill)\n billId?: string\n\n @ManyToOne(type => SaasSubscription, { nullable: true, onDelete: 'SET NULL' })\n @Field(type => SaasSubscription, { nullable: true, description: 'The subscription it is for; none for tax and credits' })\n subscription?: SaasSubscription\n\n @RelationId((line: SaasBillLine) => line.subscription)\n subscriptionId?: string\n\n @Column({ nullable: true })\n @Field({ nullable: true, description: 'What the bill calls it - tax, a credit, a support fee' })\n label?: string\n\n @Column(moneyColumn())\n @Field(type => Float, { description: 'What it cost; a credit is below zero' })\n amount: number\n}\n"]}
|
|
@@ -2,9 +2,13 @@ import { SaasAccount } from './saas-account';
|
|
|
2
2
|
import { SaasBill } from './saas-bill';
|
|
3
3
|
import { SaasSeat } from './saas-seat';
|
|
4
4
|
import { SaasSubscription } from './saas-subscription';
|
|
5
|
-
import { SaasAccountPatch, SaasBillInput, SaasLicensesInput, SaasSeatPatch, SaasSubscriptionPatch } from './saas-type';
|
|
5
|
+
import { SaasAccountPatch, SaasBillInput, SaasCostsInput, SaasLicensesInput, SaasSeatPatch, SaasSubscriptionPatch } from './saas-type';
|
|
6
6
|
export declare class SaasMutation {
|
|
7
7
|
syncSaasLicenses(licenses: SaasLicensesInput, context: ResolverContext): Promise<import("./saas-sync").LicenseSyncResult>;
|
|
8
|
+
syncSaasCosts(costs: SaasCostsInput[], context: ResolverContext): Promise<{
|
|
9
|
+
results: import("./saas-sync").CostSyncResult[];
|
|
10
|
+
unmatched: string[];
|
|
11
|
+
}>;
|
|
8
12
|
updateMultipleSaasAccount(patches: SaasAccountPatch[], context: ResolverContext): Promise<SaasAccount[]>;
|
|
9
13
|
createSaasAccountsFromCandidates(keys: string[], context: ResolverContext): Promise<SaasAccount[]>;
|
|
10
14
|
hideSaasCandidates(keys: string[], hide: boolean, context: ResolverContext): Promise<boolean>;
|
|
@@ -29,6 +29,11 @@ let SaasMutation = class SaasMutation {
|
|
|
29
29
|
const { tx, domain, user } = context.state;
|
|
30
30
|
return (0, saas_sync_1.syncSaasLicenses)(tx, domain, user, licenses, new Date().toISOString().slice(0, 10));
|
|
31
31
|
}
|
|
32
|
+
/* A scenario's step (ADR-0177 개정 3): the bills of the closed months as the vendor's cost report says. */
|
|
33
|
+
syncSaasCosts(costs, context) {
|
|
34
|
+
const { tx, domain, user } = context.state;
|
|
35
|
+
return (0, saas_sync_1.syncSaasCostsOf)(tx, domain, user, costs, new Date().toISOString().slice(0, 10));
|
|
36
|
+
}
|
|
32
37
|
updateMultipleSaasAccount(patches, context) {
|
|
33
38
|
const { tx, domain, user } = context.state;
|
|
34
39
|
return (0, saas_service_1.saveSaasAccounts)(tx, domain, user, patches);
|
|
@@ -71,6 +76,16 @@ tslib_1.__decorate([
|
|
|
71
76
|
tslib_1.__metadata("design:paramtypes", [saas_type_1.SaasLicensesInput, Object]),
|
|
72
77
|
tslib_1.__metadata("design:returntype", void 0)
|
|
73
78
|
], SaasMutation.prototype, "syncSaasLicenses", null);
|
|
79
|
+
tslib_1.__decorate([
|
|
80
|
+
(0, type_graphql_1.Directive)('@transaction'),
|
|
81
|
+
(0, type_graphql_1.Directive)('@privilege(category: "saas-sync", privilege: "mutation", domainOwnerGranted: true)'),
|
|
82
|
+
(0, type_graphql_1.Mutation)(type => saas_type_1.SaasCostSyncs, { description: "To write accounts' bills of the closed months from their vendors' cost reports - an entry an account; never over a bill a person wrote; vendor accounts no account names are passed over" }),
|
|
83
|
+
tslib_1.__param(0, (0, type_graphql_1.Arg)('costs', type => [saas_type_1.SaasCostsInput])),
|
|
84
|
+
tslib_1.__param(1, (0, type_graphql_1.Ctx)()),
|
|
85
|
+
tslib_1.__metadata("design:type", Function),
|
|
86
|
+
tslib_1.__metadata("design:paramtypes", [Array, Object]),
|
|
87
|
+
tslib_1.__metadata("design:returntype", void 0)
|
|
88
|
+
], SaasMutation.prototype, "syncSaasCosts", null);
|
|
74
89
|
tslib_1.__decorate([
|
|
75
90
|
(0, type_graphql_1.Directive)('@transaction'),
|
|
76
91
|
(0, type_graphql_1.Directive)('@privilege(category: "saas", privilege: "mutation", domainOwnerGranted: true)'),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"saas-mutation.js","sourceRoot":"","sources":["../../server/service/saas-mutation.ts"],"names":[],"mappings":"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","sourcesContent":["import { checkPermission } from '@things-factory/auth-base'\nimport { Refusal, SpeakRefusals } from '@things-factory/shell'\nimport { Arg, Ctx, Directive, Mutation, Resolver, UseMiddleware } from 'type-graphql'\n\nimport { scopeOf } from './saas-access'\nimport { SaasAccount } from './saas-account'\nimport { SaasBill } from './saas-bill'\nimport { createSaasAccountsFromCandidates, deleteSaasBill, hideSaasCandidates, saveSaasAccounts, saveSaasBill, saveSaasSeats, saveSaasSubscriptions } from './saas-service'\nimport { SaasSeat } from './saas-seat'\nimport { SaasSubscription } from './saas-subscription'\nimport { syncSaasLicenses } from './saas-sync'\nimport { SaasAccountPatch, SaasBillInput, SaasLicenseSync, SaasLicensesInput, SaasSeatPatch, SaasSubscriptionPatch } from './saas-type'\n\n/** The bank's fact (ADR-0139) is read only by whoever reads bank lines. */\nasync function mustReadBank(state: any) {\n const { domain, user, unsafeIP, prohibitedPrivileges } = state\n if (!(await checkPermission({ category: 'bank', privilege: 'query', owner: false } as any, user, domain, unsafeIP, prohibitedPrivileges)))\n throw new Refusal('saas-candidates-need-bank', {}, 'Making accounts from the books needs reading the bank lines')\n}\n\n/*\n * The accounts are the keepers'. What is under an account - its subscriptions, their seats, its bills - is also its\n * admins', whatever their seat (ADR-0177 Q4): those doors ask `saas-self`, and the service keeps an admin to their own.\n */\n@UseMiddleware(SpeakRefusals)\n@Resolver(SaasAccount)\nexport class SaasMutation {\n /* A scenario's step (ADR-0177 개정 2): seats and quantities only, so its own category - the system admin runs it. */\n @Directive('@transaction')\n @Directive('@privilege(category: \"saas-sync\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Mutation(type => SaasLicenseSync, { description: \"To keep an account's seats and quantities as its vendor tenant says - what it bought and who holds each\" })\n syncSaasLicenses(@Arg('licenses', type => SaasLicensesInput) licenses: SaasLicensesInput, @Ctx() context: ResolverContext) {\n const { tx, domain, user } = context.state\n return syncSaasLicenses(tx, domain, user, licenses, new Date().toISOString().slice(0, 10))\n }\n\n @Directive('@transaction')\n @Directive('@privilege(category: \"saas\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Directive('@auditTarget(kind: \"SaasAccount\", arg: \"patches\")')\n @Mutation(type => [SaasAccount], { description: 'To save the accounts grid - new, changed and deleted rows together' })\n updateMultipleSaasAccount(@Arg('patches', type => [SaasAccountPatch]) patches: SaasAccountPatch[], @Ctx() context: ResolverContext) {\n const { tx, domain, user } = context.state\n return saveSaasAccounts(tx, domain, user, patches)\n }\n\n /* The candidates are read from the bank and card lines - a keeper who also reads them (checked in the service). */\n @Directive('@transaction')\n @Directive('@privilege(category: \"saas\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Mutation(type => [SaasAccount], { description: 'To make an account, with one usage subscription at the monthly average, of each candidate (by its key)' })\n async createSaasAccountsFromCandidates(@Arg('keys', type => [String]) keys: string[], @Ctx() context: ResolverContext) {\n const { tx, domain, user } = context.state\n await mustReadBank(context.state)\n return createSaasAccountsFromCandidates(tx, domain, user, keys, new Date().toISOString().slice(0, 10))\n }\n\n @Directive('@transaction')\n @Directive('@privilege(category: \"saas\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Mutation(type => Boolean, { description: 'To hide candidates (by their keys), or with hide false to show them again' })\n async hideSaasCandidates(@Arg('keys', type => [String]) keys: string[], @Arg('hide') hide: boolean, @Ctx() context: ResolverContext) {\n const { tx, domain, user } = context.state\n return hideSaasCandidates(tx, domain, user, keys, hide)\n }\n\n @Directive('@transaction')\n @Directive('@privilege(category: \"saas-self\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Directive('@auditTarget(kind: \"SaasAccount\", arg: \"accountId\")')\n @Mutation(type => [SaasSubscription], { description: \"To save an account's subscriptions grid\" })\n async updateMultipleSaasSubscription(@Arg('accountId') accountId: string, @Arg('patches', type => [SaasSubscriptionPatch]) patches: SaasSubscriptionPatch[], @Ctx() context: ResolverContext) {\n const { tx, domain, user } = context.state\n return saveSaasSubscriptions(tx, domain, user, await scopeOf(context.state, 'mutation', tx), accountId, patches)\n }\n\n @Directive('@transaction')\n @Directive('@privilege(category: \"saas-self\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Directive('@auditTarget(kind: \"SaasSubscription\", arg: \"subscriptionId\")')\n @Mutation(type => [SaasSeat], { description: \"To save a subscription's seats grid\" })\n async updateMultipleSaasSeat(@Arg('subscriptionId') subscriptionId: string, @Arg('patches', type => [SaasSeatPatch]) patches: SaasSeatPatch[], @Ctx() context: ResolverContext) {\n const { tx, domain, user } = context.state\n return saveSaasSeats(tx, domain, user, await scopeOf(context.state, 'mutation', tx), subscriptionId, patches)\n }\n\n @Directive('@transaction')\n @Directive('@privilege(category: \"saas-self\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Directive('@auditTarget(kind: \"SaasAccount\", arg: \"accountId\")')\n @Mutation(type => SaasBill, { description: \"To write an account's bill for a month, its lines whole\" })\n async saveSaasBill(@Arg('accountId') accountId: string, @Arg('bill', type => SaasBillInput) bill: SaasBillInput, @Ctx() context: ResolverContext) {\n const { tx, domain, user } = context.state\n return saveSaasBill(tx, domain, user, await scopeOf(context.state, 'mutation', tx), accountId, bill)\n }\n\n @Directive('@transaction')\n @Directive('@privilege(category: \"saas-self\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Directive('@auditTarget(kind: \"SaasBill\", arg: \"id\")')\n @Mutation(type => Boolean, { description: 'To delete a bill' })\n async deleteSaasBill(@Arg('id') id: string, @Ctx() context: ResolverContext) {\n const { tx, domain } = context.state\n return deleteSaasBill(tx, domain, await scopeOf(context.state, 'mutation', tx), id)\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"saas-mutation.js","sourceRoot":"","sources":["../../server/service/saas-mutation.ts"],"names":[],"mappings":"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","sourcesContent":["import { checkPermission } from '@things-factory/auth-base'\nimport { Refusal, SpeakRefusals } from '@things-factory/shell'\nimport { Arg, Ctx, Directive, Mutation, Resolver, UseMiddleware } from 'type-graphql'\n\nimport { scopeOf } from './saas-access'\nimport { SaasAccount } from './saas-account'\nimport { SaasBill } from './saas-bill'\nimport { createSaasAccountsFromCandidates, deleteSaasBill, hideSaasCandidates, saveSaasAccounts, saveSaasBill, saveSaasSeats, saveSaasSubscriptions } from './saas-service'\nimport { SaasSeat } from './saas-seat'\nimport { SaasSubscription } from './saas-subscription'\nimport { syncSaasCostsOf, syncSaasLicenses } from './saas-sync'\nimport { SaasAccountPatch, SaasBillInput, SaasCostSyncs, SaasCostsInput, SaasLicenseSync, SaasLicensesInput, SaasSeatPatch, SaasSubscriptionPatch } from './saas-type'\n\n/** The bank's fact (ADR-0139) is read only by whoever reads bank lines. */\nasync function mustReadBank(state: any) {\n const { domain, user, unsafeIP, prohibitedPrivileges } = state\n if (!(await checkPermission({ category: 'bank', privilege: 'query', owner: false } as any, user, domain, unsafeIP, prohibitedPrivileges)))\n throw new Refusal('saas-candidates-need-bank', {}, 'Making accounts from the books needs reading the bank lines')\n}\n\n/*\n * The accounts are the keepers'. What is under an account - its subscriptions, their seats, its bills - is also its\n * admins', whatever their seat (ADR-0177 Q4): those doors ask `saas-self`, and the service keeps an admin to their own.\n */\n@UseMiddleware(SpeakRefusals)\n@Resolver(SaasAccount)\nexport class SaasMutation {\n /* A scenario's step (ADR-0177 개정 2): seats and quantities only, so its own category - the system admin runs it. */\n @Directive('@transaction')\n @Directive('@privilege(category: \"saas-sync\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Mutation(type => SaasLicenseSync, { description: \"To keep an account's seats and quantities as its vendor tenant says - what it bought and who holds each\" })\n syncSaasLicenses(@Arg('licenses', type => SaasLicensesInput) licenses: SaasLicensesInput, @Ctx() context: ResolverContext) {\n const { tx, domain, user } = context.state\n return syncSaasLicenses(tx, domain, user, licenses, new Date().toISOString().slice(0, 10))\n }\n\n /* A scenario's step (ADR-0177 개정 3): the bills of the closed months as the vendor's cost report says. */\n @Directive('@transaction')\n @Directive('@privilege(category: \"saas-sync\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Mutation(type => SaasCostSyncs, { description: \"To write accounts' bills of the closed months from their vendors' cost reports - an entry an account; never over a bill a person wrote; vendor accounts no account names are passed over\" })\n syncSaasCosts(@Arg('costs', type => [SaasCostsInput]) costs: SaasCostsInput[], @Ctx() context: ResolverContext) {\n const { tx, domain, user } = context.state\n return syncSaasCostsOf(tx, domain, user, costs, new Date().toISOString().slice(0, 10))\n }\n\n @Directive('@transaction')\n @Directive('@privilege(category: \"saas\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Directive('@auditTarget(kind: \"SaasAccount\", arg: \"patches\")')\n @Mutation(type => [SaasAccount], { description: 'To save the accounts grid - new, changed and deleted rows together' })\n updateMultipleSaasAccount(@Arg('patches', type => [SaasAccountPatch]) patches: SaasAccountPatch[], @Ctx() context: ResolverContext) {\n const { tx, domain, user } = context.state\n return saveSaasAccounts(tx, domain, user, patches)\n }\n\n /* The candidates are read from the bank and card lines - a keeper who also reads them (checked in the service). */\n @Directive('@transaction')\n @Directive('@privilege(category: \"saas\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Mutation(type => [SaasAccount], { description: 'To make an account, with one usage subscription at the monthly average, of each candidate (by its key)' })\n async createSaasAccountsFromCandidates(@Arg('keys', type => [String]) keys: string[], @Ctx() context: ResolverContext) {\n const { tx, domain, user } = context.state\n await mustReadBank(context.state)\n return createSaasAccountsFromCandidates(tx, domain, user, keys, new Date().toISOString().slice(0, 10))\n }\n\n @Directive('@transaction')\n @Directive('@privilege(category: \"saas\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Mutation(type => Boolean, { description: 'To hide candidates (by their keys), or with hide false to show them again' })\n async hideSaasCandidates(@Arg('keys', type => [String]) keys: string[], @Arg('hide') hide: boolean, @Ctx() context: ResolverContext) {\n const { tx, domain, user } = context.state\n return hideSaasCandidates(tx, domain, user, keys, hide)\n }\n\n @Directive('@transaction')\n @Directive('@privilege(category: \"saas-self\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Directive('@auditTarget(kind: \"SaasAccount\", arg: \"accountId\")')\n @Mutation(type => [SaasSubscription], { description: \"To save an account's subscriptions grid\" })\n async updateMultipleSaasSubscription(@Arg('accountId') accountId: string, @Arg('patches', type => [SaasSubscriptionPatch]) patches: SaasSubscriptionPatch[], @Ctx() context: ResolverContext) {\n const { tx, domain, user } = context.state\n return saveSaasSubscriptions(tx, domain, user, await scopeOf(context.state, 'mutation', tx), accountId, patches)\n }\n\n @Directive('@transaction')\n @Directive('@privilege(category: \"saas-self\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Directive('@auditTarget(kind: \"SaasSubscription\", arg: \"subscriptionId\")')\n @Mutation(type => [SaasSeat], { description: \"To save a subscription's seats grid\" })\n async updateMultipleSaasSeat(@Arg('subscriptionId') subscriptionId: string, @Arg('patches', type => [SaasSeatPatch]) patches: SaasSeatPatch[], @Ctx() context: ResolverContext) {\n const { tx, domain, user } = context.state\n return saveSaasSeats(tx, domain, user, await scopeOf(context.state, 'mutation', tx), subscriptionId, patches)\n }\n\n @Directive('@transaction')\n @Directive('@privilege(category: \"saas-self\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Directive('@auditTarget(kind: \"SaasAccount\", arg: \"accountId\")')\n @Mutation(type => SaasBill, { description: \"To write an account's bill for a month, its lines whole\" })\n async saveSaasBill(@Arg('accountId') accountId: string, @Arg('bill', type => SaasBillInput) bill: SaasBillInput, @Ctx() context: ResolverContext) {\n const { tx, domain, user } = context.state\n return saveSaasBill(tx, domain, user, await scopeOf(context.state, 'mutation', tx), accountId, bill)\n }\n\n @Directive('@transaction')\n @Directive('@privilege(category: \"saas-self\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Directive('@auditTarget(kind: \"SaasBill\", arg: \"id\")')\n @Mutation(type => Boolean, { description: 'To delete a bill' })\n async deleteSaasBill(@Arg('id') id: string, @Ctx() context: ResolverContext) {\n const { tx, domain } = context.state\n return deleteSaasBill(tx, domain, await scopeOf(context.state, 'mutation', tx), id)\n }\n}\n"]}
|
|
@@ -271,6 +271,8 @@ async function saveSaasBill(tx, domain, user, scope, accountId, input) {
|
|
|
271
271
|
month,
|
|
272
272
|
billedOn: (0, patches_js_1.dayOf)(input.billedOn, 'saas-day-invalid'),
|
|
273
273
|
description: (0, patches_js_1.textOf)(input.description),
|
|
274
|
+
/* Whoever writes it owns it: a person's save keeps a later sync off it (a sync marks its own, 개정 3). */
|
|
275
|
+
synced: false,
|
|
274
276
|
updater: user
|
|
275
277
|
});
|
|
276
278
|
await tx.getRepository(saas_bill_1.SaasBillLine).delete({ bill: { id: bill.id } });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"saas-service.js","sourceRoot":"","sources":["../../server/service/saas-service.ts"],"names":[],"mappings":"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","sourcesContent":["import { BankAccount, CashFlowType, linkLinesByName, RecurringCashItem, Transaction, TransactionCategory } from '@things-factory/accounting'\nimport { Asset } from '@things-factory/asset'\n/* The register grids' save, the asset module's - this module saves its grids the same way (one implementation). */\nimport { amountOf, applyPatches, dayOf, Patch, textOf, touched } from '@things-factory/asset/dist-server/service/patches.js'\nimport { Counterparty, CounterpartyKind, looksLikePersonName, nameKey, partyNamed, saveCounterparties } from '@things-factory/biz-base'\nimport { fieldChanges, readFactChanges, recordFactChanges } from '@things-factory/fact-change'\nimport { Department, Employee } from '@things-factory/organization'\nimport { Domain, Refusal } from '@things-factory/shell'\nimport { EntityManager, In } from 'typeorm'\n\nimport { accountIn, SaasScope } from './saas-access'\nimport { SaasAccount } from './saas-account'\nimport { SaasBill, SaasBillLine } from './saas-bill'\nimport { SaasHiddenVendor } from './saas-hidden-vendor'\nimport {\n alertsOf,\n BillFacts,\n billTotal,\n candidatesOf,\n expectedOfMonth,\n MONTH,\n monthsFrom,\n SaasAccountStatus,\n SaasBilling,\n CandidateFacts,\n SaasSubscriptionStatus,\n seatHeld,\n shiftMonth,\n trendOf\n} from './saas-rules'\nimport { SaasSeat } from './saas-seat'\nimport { SaasSubscription } from './saas-subscription'\nimport { SaasTrend } from './saas-trend-type'\n\nconst currencyOf = (value: any, fallback: string | null) => {\n const text = String(value ?? '').trim().toUpperCase()\n if (!text) return fallback\n if (!/^[A-Z]{3}$/.test(text)) throw new Refusal('saas-currency-invalid', { value: text }, `'${text}' is not a currency code (KRW, USD)`)\n return text\n}\n\nconst intOf = (value: any, code: string, min: number, max: number): number | null => {\n if (value === null || value === undefined || value === '') return null\n const number = Number(value)\n if (!Number.isInteger(number) || number < min || number > max) throw new Refusal(code, { min, max }, `Give a whole number from ${min} to ${max}`)\n return number\n}\n\nasync function oneOf<T>(tx: EntityManager, target: any, domain: Domain, id: string | null | undefined, code: string): Promise<T | null> {\n if (!id) return null\n const found = await tx.getRepository(target).findOne({ where: { domain: { id: domain.id }, id } as any })\n if (!found) throw new Refusal(code, {}, 'What it points at was not found')\n return found as T\n}\n\nconst field = (patch: Patch, name: string, old?: any) => (patch[name] !== undefined ? patch[name] : old?.[name])\n\n/*\n * What moved on an account or a subscription, field by field (ADR-0177 decision 11) - the fact-change module keeps it.\n * A row's relations are told by their id; a new row has no history yet.\n */\nexport const SAAS_ACCOUNT_FACT = 'saas-account'\nexport const SAAS_SUBSCRIPTION_FACT = 'saas-subscription'\nconst ACCOUNT_TRACKED = ['name', 'counterpartyId', 'identifier', 'parentId', 'paymentAccountId', 'currency', 'billingDay', 'increaseAlertRate', 'status', 'closedOn'] as const\nconst SUBSCRIPTION_TRACKED = ['name', 'billing', 'vendorKey', 'trial', 'quantity', 'unitPrice', 'amount', 'budget', 'everyMonths', 'startOn', 'renewalOn', 'autoRenew', 'noticeDays', 'departmentId', 'assetId', 'status', 'endedOn'] as const\nconst idsOf = (row: Record<string, any>) =>\n Object.fromEntries(Object.entries(row).map(([key, value]) => (value && typeof value === 'object' && 'id' in value ? [`${key}Id`, value.id] : value === null && ['counterparty', 'parent', 'paymentAccount', 'department', 'asset'].includes(key) ? [`${key}Id`, null] : [key, value])))\n\nasync function recordChanges(tx: EntityManager, domain: Domain, user: any, factKind: string, old: any, row: Record<string, any>, fields: readonly string[]) {\n if (!old) return\n const after = { ...old, ...idsOf(row) }\n await recordFactChanges(tx, domain, { factKind, factName: old.id, changes: fieldChanges(old, after, fields as any) }, { user, source: 'saas' })\n}\n\n/* ----------------------------------------------------------------------------------------------------------------- */\n/* Accounts (decision 2) - kept by `saas` keepers only */\n\nexport async function saveSaasAccounts(tx: EntityManager, domain: Domain, user: any, patches: Patch[]) {\n const saved = await applyPatches(\n tx,\n SaasAccount,\n domain,\n user,\n patches,\n async (patch, old) => {\n const row: Record<string, any> = {}\n const name = touched(patch, 'name', old) ? textOf(patch.name) : old!.name\n if (!name) throw new Refusal('saas-account-name-required', {}, 'Name the service')\n row.name = name\n for (const one of ['identifier', 'purpose', 'billingEmail', 'secretLocation', 'description']) if (touched(patch, one, old)) row[one] = textOf(patch[one])\n if (touched(patch, 'currency', old)) row.currency = currencyOf(patch.currency, 'KRW')\n if (touched(patch, 'billingDay', old)) row.billingDay = intOf(patch.billingDay, 'saas-billing-day-invalid', 1, 31)\n if (touched(patch, 'increaseAlertRate', old)) {\n const rate = amountOf(patch.increaseAlertRate, 'saas-alert-rate-invalid')\n if (rate !== null && rate > 10) throw new Refusal('saas-alert-rate-invalid', {}, 'Give the rate as a part - 0.2 for 20%')\n row.increaseAlertRate = rate\n }\n if (touched(patch, 'counterpartyId', old)) row.counterparty = await oneOf(tx, Counterparty, domain, patch.counterpartyId, 'saas-counterparty-not-found')\n if (touched(patch, 'paymentAccountId', old)) row.paymentAccount = await oneOf(tx, BankAccount, domain, patch.paymentAccountId, 'saas-payment-account-not-found')\n if (touched(patch, 'parentId', old)) {\n const parent = await oneOf<SaasAccount>(tx, SaasAccount, domain, patch.parentId, 'saas-parent-not-found')\n if (parent && (parent.id === old?.id || (await tx.getRepository(SaasAccount).findOne({ where: { id: parent.id }, relations: ['parent'] }))?.parent))\n throw new Refusal('saas-parent-invalid', {}, 'An account is under a top account only, and not under itself')\n if (parent && old && (await tx.getRepository(SaasSubscription).count({ where: { account: { id: old.id } } as any })))\n throw new Refusal('saas-parent-has-subscriptions', {}, 'An account with subscriptions is billed itself - it cannot go under another')\n row.parent = parent\n }\n if (touched(patch, 'adminIds', old)) {\n const ids: string[] = [...new Set<string>((patch.adminIds ?? []).filter(Boolean))]\n const admins = ids.length ? await tx.getRepository(Employee).find({ where: { id: In(ids), domain: { id: domain.id } } as any }) : []\n if (admins.length !== ids.length) throw new Refusal('saas-admin-not-found', {}, 'An admin is no employee of this domain')\n row.admins = admins\n }\n if (touched(patch, 'status', old)) row.status = patch.status ?? SaasAccountStatus.ACTIVE\n if (touched(patch, 'closedOn', old)) row.closedOn = dayOf(patch.closedOn, 'saas-day-invalid')\n if ((row.status ?? old?.status) === SaasAccountStatus.CLOSED && !(row.closedOn !== undefined ? row.closedOn : old?.closedOn))\n throw new Refusal('saas-closed-on-required', {}, 'Give the day it was closed')\n await recordChanges(tx, domain, user, SAAS_ACCOUNT_FACT, old, row, ACCOUNT_TRACKED)\n return row\n },\n 'saas-account-not-found'\n )\n /* The vendor's lines written with its name and not linked yet are the account's months (개정 1). */\n const vendors = patches.filter(one => one.cuFlag !== '-' && one.counterpartyId).map(one => one.counterpartyId as string)\n if (vendors.length) await linkLinesByName(tx, domain, user, vendors)\n return saved\n}\n\n/* ----------------------------------------------------------------------------------------------------------------- */\n/* Subscriptions (decision 3) - by keepers, and by the account's admins */\n\nexport async function saveSaasSubscriptions(tx: EntityManager, domain: Domain, user: any, scope: SaasScope, accountId: string, patches: Patch[]) {\n const account = await accountIn(tx, domain, scope, accountId)\n if (account.parentId && patches.some(one => one.cuFlag !== '-'))\n throw new Refusal('saas-subscription-on-sub-account', {}, 'An account under another is billed by its parent - subscribe there')\n return applyPatches(\n tx,\n SaasSubscription,\n domain,\n user,\n patches,\n async (patch, old) => {\n const row: Record<string, any> = old ? {} : { account }\n const name = touched(patch, 'name', old) ? textOf(patch.name) : old!.name\n if (!name) throw new Refusal('saas-subscription-name-required', {}, 'Name the product or plan')\n row.name = name\n const billing = (field(patch, 'billing', old) ?? SaasBilling.FIXED) as SaasBilling\n if (!Object.values(SaasBilling).includes(billing)) throw new Refusal('saas-billing-invalid', {}, 'Say how it is paid for')\n row.billing = billing\n for (const one of ['quantity', 'unitPrice', 'amount', 'budget']) if (touched(patch, one, old)) row[one] = amountOf(patch[one], 'saas-amount-invalid')\n /* `vendorKey` and `trial` are a sync's (개정 2) - the GraphQL patch does not carry them. */\n if (touched(patch, 'vendorKey', old)) row.vendorKey = textOf(patch.vendorKey)\n if (touched(patch, 'trial', old)) row.trial = patch.trial === true\n const value = (name: string) => (row[name] !== undefined ? row[name] : old?.[name])\n /* A plan read from the vendor's tenant may wait for its price (개정 2) - it is expected at nothing until then. */\n const priced = value('unitPrice') !== null && value('unitPrice') !== undefined\n if (billing === SaasBilling.SEAT && !(Number(value('quantity')) > 0 && (priced || value('vendorKey'))))\n throw new Refusal('saas-seat-price-required', {}, 'A seat plan takes its seats and the price of one')\n if ((billing === SaasBilling.FIXED || billing === SaasBilling.COMMITMENT) && (value('amount') === null || value('amount') === undefined))\n throw new Refusal('saas-amount-required', {}, 'Give what one billing costs')\n if (touched(patch, 'everyMonths', old)) row.everyMonths = intOf(patch.everyMonths, 'saas-every-months-invalid', 1, 120) ?? 1\n row.startOn = touched(patch, 'startOn', old) ? dayOf(patch.startOn, 'saas-start-on-invalid', true) : old!.startOn\n if (touched(patch, 'renewalOn', old)) row.renewalOn = dayOf(patch.renewalOn, 'saas-day-invalid')\n if (touched(patch, 'endedOn', old)) row.endedOn = dayOf(patch.endedOn, 'saas-day-invalid')\n if (touched(patch, 'autoRenew', old)) row.autoRenew = patch.autoRenew !== false\n if (touched(patch, 'noticeDays', old)) row.noticeDays = intOf(patch.noticeDays, 'saas-notice-days-invalid', 0, 365)\n if (touched(patch, 'description', old)) row.description = textOf(patch.description)\n if (touched(patch, 'departmentId', old)) row.department = await oneOf(tx, Department, domain, patch.departmentId, 'saas-department-not-found')\n if (touched(patch, 'assetId', old)) row.asset = await oneOf(tx, Asset, domain, patch.assetId, 'saas-asset-not-found')\n if (billing === SaasBilling.OWNED && !(row.asset !== undefined ? row.asset : old?.assetId))\n throw new Refusal('saas-owned-asset-required', {}, 'A license owned points at its asset in the register - its cost is there')\n if (billing === SaasBilling.COMMITMENT && !value('renewalOn')) throw new Refusal('saas-term-end-required', {}, 'A commitment takes the day its term ends')\n if (touched(patch, 'status', old)) row.status = patch.status ?? SaasSubscriptionStatus.ACTIVE\n const status = row.status ?? old?.status ?? SaasSubscriptionStatus.ACTIVE\n if (status === SaasSubscriptionStatus.CANCELLED && !value('endedOn')) throw new Refusal('saas-ended-on-required', {}, 'Give the day it ended')\n if (status === SaasSubscriptionStatus.CANCELLING && !value('renewalOn')) throw new Refusal('saas-renewal-on-required', {}, 'Not renewing needs the day it would renew')\n if (value('endedOn') && value('endedOn') < row.startOn) throw new Refusal('saas-ended-before-start', {}, 'It ended before it started')\n await recordChanges(tx, domain, user, SAAS_SUBSCRIPTION_FACT, old, row, SUBSCRIPTION_TRACKED)\n return row\n },\n 'saas-subscription-not-found',\n { account: { id: account.id } }\n )\n}\n\n/** The subscriptions of an account, with the seats held today. */\nexport async function saasSubscriptionsOf(tx: EntityManager, domain: Domain, scope: SaasScope, accountId: string, today: string) {\n const account = await accountIn(tx, domain, scope, accountId)\n const subs = await tx.getRepository(SaasSubscription).find({ where: { domain: { id: domain.id }, account: { id: account.id } } as any, relations: ['department', 'asset'], order: { name: 'ASC' } as any })\n const seats = subs.length ? await tx.getRepository(SaasSeat).find({ where: { domain: { id: domain.id }, subscription: { id: In(subs.map(one => one.id)) } } as any }) : []\n for (const sub of subs) sub.seatsHeld = seats.filter(seat => seat.subscriptionId === sub.id && seatHeld(seat, today)).length\n return subs\n}\n\n/* ----------------------------------------------------------------------------------------------------------------- */\n/* Seats (decision 6) */\n\nasync function subscriptionIn(tx: EntityManager, domain: Domain, scope: SaasScope, subscriptionId: string) {\n const sub = subscriptionId ? await tx.getRepository(SaasSubscription).findOne({ where: { domain: { id: domain.id }, id: subscriptionId } as any }) : null\n if (!sub || (scope !== 'all' && !scope.has(sub.accountId!))) throw new Refusal('saas-subscription-not-found', {}, 'The subscription was not found - reload and try again')\n return sub\n}\n\nexport async function saveSaasSeats(tx: EntityManager, domain: Domain, user: any, scope: SaasScope, subscriptionId: string, patches: Patch[]) {\n const subscription = await subscriptionIn(tx, domain, scope, subscriptionId)\n return applyPatches(\n tx,\n SaasSeat,\n domain,\n user,\n patches,\n async (patch, old) => {\n const row: Record<string, any> = old ? {} : { subscription }\n if (touched(patch, 'employeeId', old)) row.employee = await oneOf(tx, Employee, domain, patch.employeeId, 'saas-seat-employee-not-found')\n /* `login` is a sync's (개정 2) - the GraphQL patch does not carry it. */\n for (const one of ['holder', 'login', 'description']) if (touched(patch, one, old)) row[one] = textOf(patch[one])\n if (!(row.employee !== undefined ? row.employee : old?.employeeId) && !(row.holder !== undefined ? row.holder : old?.holder))\n throw new Refusal('saas-seat-holder-required', {}, 'Say who holds the seat - an employee, or a name')\n if (touched(patch, 'fromOn', old)) row.fromOn = dayOf(patch.fromOn, 'saas-day-invalid')\n if (touched(patch, 'untilOn', old)) row.untilOn = dayOf(patch.untilOn, 'saas-day-invalid')\n const from = row.fromOn !== undefined ? row.fromOn : old?.fromOn\n const until = row.untilOn !== undefined ? row.untilOn : old?.untilOn\n if (from && until && until < from) throw new Refusal('saas-seat-until-before-from', {}, 'It was taken back before it was given')\n return row\n },\n 'saas-seat-not-found',\n { subscription: { id: subscription.id } }\n )\n}\n\nexport async function saasSeatsOf(tx: EntityManager, domain: Domain, scope: SaasScope, subscriptionId: string) {\n const sub = await subscriptionIn(tx, domain, scope, subscriptionId)\n return tx.getRepository(SaasSeat).find({ where: { domain: { id: domain.id }, subscription: { id: sub.id } } as any, relations: ['employee'], order: { fromOn: 'DESC' } as any })\n}\n\n/* ----------------------------------------------------------------------------------------------------------------- */\n/* Bills (decisions 5, 9) - one an account a month, its lines replaced whole */\n\nexport interface SaasBillFields {\n id?: string | null\n month: string\n billedOn?: string | null\n description?: string | null\n lines: { subscriptionId?: string | null; label?: string | null; amount: number }[]\n}\n\nexport async function saveSaasBill(tx: EntityManager, domain: Domain, user: any, scope: SaasScope, accountId: string, input: SaasBillFields) {\n const account = await accountIn(tx, domain, scope, accountId)\n if (account.parentId) throw new Refusal('saas-bill-on-sub-account', {}, 'An account under another is billed by its parent')\n const month = String(input.month ?? '').trim()\n if (!MONTH.test(month)) throw new Refusal('saas-month-invalid', { value: month }, 'Write the month as YYYY-MM')\n const bills = tx.getRepository(SaasBill)\n const old = input.id ? await bills.findOne({ where: { domain: { id: domain.id }, id: input.id, account: { id: account.id } } as any }) : null\n if (input.id && !old) throw new Refusal('saas-bill-not-found', {}, 'The bill was not found - reload and try again')\n const twin = await bills.findOne({ where: { domain: { id: domain.id }, account: { id: account.id }, month } as any })\n if (twin && twin.id !== old?.id) throw new Refusal('saas-bill-month-taken', { month }, `The account already has a bill for ${month} - change that one`)\n const lines = (input.lines ?? []).filter(line => line && (line.subscriptionId || textOf(line.label) || Number(line.amount)))\n if (!lines.length) throw new Refusal('saas-bill-lines-required', {}, 'A bill takes at least one line')\n const subIds = [...new Set(lines.map(line => line.subscriptionId).filter(Boolean))] as string[]\n if (subIds.length) {\n const found = await tx.getRepository(SaasSubscription).count({ where: { domain: { id: domain.id }, account: { id: account.id }, id: In(subIds) } as any })\n if (found !== subIds.length) throw new Refusal('saas-bill-subscription-not-found', {}, 'A line names a subscription not of this account')\n }\n for (const line of lines) if (!Number.isFinite(Number(line.amount))) throw new Refusal('saas-amount-invalid', {}, 'Give the amount as a number')\n const bill = await bills.save({\n ...(old ?? { domain, account, creator: user, currency: account.currency }),\n month,\n billedOn: dayOf(input.billedOn, 'saas-day-invalid'),\n description: textOf(input.description),\n updater: user\n } as any)\n await tx.getRepository(SaasBillLine).delete({ bill: { id: bill.id } } as any)\n await tx.getRepository(SaasBillLine).save(\n lines.map(line => ({ domain, bill: { id: bill.id }, subscription: line.subscriptionId ? { id: line.subscriptionId } : null, label: textOf(line.label), amount: Number(line.amount) })) as any\n )\n return billsOf(tx, domain, [account.id]).then(all => all.find(one => one.id === bill.id)!)\n}\n\nexport async function deleteSaasBill(tx: EntityManager, domain: Domain, scope: SaasScope, id: string): Promise<boolean> {\n const bill = await tx.getRepository(SaasBill).findOne({ where: { domain: { id: domain.id }, id } as any })\n if (!bill || (scope !== 'all' && !scope.has(bill.accountId!))) throw new Refusal('saas-bill-not-found', {}, 'The bill was not found - reload and try again')\n await tx.getRepository(SaasBill).softDelete({ id })\n return true\n}\n\n/** The bills of some accounts (all when none named) from a month on, with their lines and totals, latest first. */\nexport async function billsOf(tx: EntityManager, domain: Domain, accountIds?: string[], from?: string, to?: string): Promise<SaasBill[]> {\n const query = tx\n .getRepository(SaasBill)\n .createQueryBuilder('bill')\n .leftJoinAndSelect('bill.lines', 'line')\n .leftJoinAndSelect('line.subscription', 'subscription')\n .where('bill.domain = :domain', { domain: domain.id })\n if (accountIds) {\n if (!accountIds.length) return []\n query.andWhere('bill.account IN (:...accounts)', { accounts: accountIds })\n }\n if (from) query.andWhere('bill.month >= :from', { from })\n if (to) query.andWhere('bill.month <= :to', { to })\n const bills = await query.orderBy('bill.month', 'DESC').getMany()\n for (const bill of bills) bill.total = billTotal(bill.lines ?? [])\n return bills\n}\n\nexport async function saasBillsOf(tx: EntityManager, domain: Domain, scope: SaasScope, accountId: string) {\n const account = await accountIn(tx, domain, scope, accountId)\n return billsOf(tx, domain, [account.id])\n}\n\nconst factsOf = (bill: SaasBill): BillFacts => ({\n accountId: bill.accountId!,\n month: bill.month,\n currency: bill.currency,\n lines: (bill.lines ?? []).map(line => ({ subscriptionId: line.subscriptionId ?? null, amount: Number(line.amount) }))\n})\n\n/* ----------------------------------------------------------------------------------------------------------------- */\n/* What is still to come (decision 4) - read by an application's expected cash */\n\nexport interface SaasExpectedRow {\n accountId: string\n accountName: string\n counterpartyId?: string | null\n paymentAccountId?: string | null\n month: string\n day: string | null\n amount: number\n currency: string\n /** A bill is written for the month: the amount is the bill's, not an estimate. */\n billed: boolean\n}\n\n/**\n * What each account is expected to be billed, month by month from `from` to `to`: the bill when one is written for the\n * month, else what its subscriptions say (usage at the average of its latest bills).\n */\nexport async function saasExpected(tx: EntityManager, domain: Domain, from: string, to: string): Promise<SaasExpectedRow[]> {\n const accounts = await tx.getRepository(SaasAccount).find({ where: { domain: { id: domain.id }, status: SaasAccountStatus.ACTIVE } as any })\n const top = accounts.filter(one => !one.parentId)\n if (!top.length) return []\n const subs = await tx.getRepository(SaasSubscription).find({ where: { domain: { id: domain.id }, account: { id: In(top.map(one => one.id)) } } as any })\n const bills = await billsOf(tx, domain, top.map(one => one.id), shiftMonth(from, -12), to)\n const billed = new Map<string, { month: string; amount: number }[]>()\n for (const bill of bills)\n if (bill.month < from)\n for (const line of bill.lines ?? []) if (line.subscriptionId) billed.set(line.subscriptionId, [...(billed.get(line.subscriptionId) ?? []), { month: bill.month, amount: Number(line.amount) }])\n const rows: SaasExpectedRow[] = []\n for (const account of top) {\n const own = subs.filter(one => one.accountId === account.id)\n for (const month of monthsFrom(from, to)) {\n const [year, m] = month.split('-').map(Number)\n const bill = bills.find(one => one.accountId === account.id && one.month === month)\n const expected = expectedOfMonth(account, own, billed, year, m)\n if (!bill && !expected) continue\n rows.push({\n accountId: account.id,\n accountName: account.name,\n counterpartyId: account.counterpartyId ?? null,\n paymentAccountId: account.paymentAccountId ?? null,\n month,\n day: bill?.billedOn ?? expected?.day ?? null,\n amount: bill ? bill.total! : expected!.amount,\n currency: account.currency,\n billed: !!bill\n })\n }\n }\n return rows\n}\n\n/* ----------------------------------------------------------------------------------------------------------------- */\n/* The cost trend (decision 9) */\n\n/** Whose department each employee is in. */\nasync function departmentsOfEmployees(tx: EntityManager, domain: Domain, ids: string[]): Promise<Map<string, { id: string; name: string }>> {\n if (!ids.length) return new Map()\n const employees = await tx.getRepository(Employee).find({ where: { domain: { id: domain.id }, id: In(ids) } as any, relations: ['department'] })\n return new Map(employees.filter(one => one.department).map(one => [one.id, { id: one.department!.id, name: one.department!.name }]))\n}\n\n/**\n * The bills of the months from `from` to `to` as series - all, an account, a subscription - and a department series: a\n * line of a seat plan split by the seats held at the month's end by department, any other line its subscription's\n * department. Plus what the latest month's bills are worth telling.\n */\nexport async function saasCostTrend(tx: EntityManager, domain: Domain, from: string, to: string) {\n if (!MONTH.test(from) || !MONTH.test(to) || from > to) throw new Refusal('saas-month-invalid', {}, 'Give the months as YYYY-MM, the first before the last')\n if (monthsFrom(from, to).length > 60) throw new Refusal('saas-trend-too-long', { max: 60 }, 'Up to 60 months at once')\n const bills = await billsOf(tx, domain, undefined, shiftMonth(from, -1), to)\n const facts = bills.map(factsOf)\n const trend = trendOf(facts, from, to)\n\n const accounts = await tx.getRepository(SaasAccount).find({ where: { domain: { id: domain.id } } as any, withDeleted: true })\n const subs = await tx.getRepository(SaasSubscription).find({ where: { domain: { id: domain.id } } as any, relations: ['department'], withDeleted: true })\n const seats = subs.length ? await tx.getRepository(SaasSeat).find({ where: { domain: { id: domain.id }, subscription: { id: In(subs.map(one => one.id)) } } as any }) : []\n const departmentOf = await departmentsOfEmployees(tx, domain, [...new Set(seats.map(one => one.employeeId).filter(Boolean))] as string[])\n\n const months = trend.months\n const departments = new Map<string, { key: string; departmentId: string | null; name: string | null; currency: string; amounts: number[] }>()\n const addTo = (id: string | null, name: string | null, currency: string, at: number, amount: number) => {\n const key = `${id ?? ''}|${currency}`\n let one = departments.get(key)\n if (!one) departments.set(key, (one = { key, departmentId: id, name, currency, amounts: months.map(() => 0) }))\n one.amounts[at] += amount\n }\n for (const bill of facts) {\n const at = months.indexOf(bill.month)\n if (at < 0) continue\n const monthEnd = `${bill.month}-31`\n for (const line of bill.lines) {\n const sub = subs.find(one => one.id === line.subscriptionId)\n const held = sub?.billing === SaasBilling.SEAT ? seats.filter(seat => seat.subscriptionId === sub.id && seatHeld(seat, monthEnd) && (!seat.fromOn || seat.fromOn <= monthEnd)) : []\n if (held.length) {\n for (const seat of held) {\n const department = seat.employeeId ? departmentOf.get(seat.employeeId) : undefined\n addTo(department?.id ?? sub?.department?.id ?? null, department?.name ?? sub?.department?.name ?? null, bill.currency, at, line.amount / held.length)\n }\n } else addTo(sub?.department?.id ?? null, sub?.department?.name ?? null, bill.currency, at, line.amount)\n }\n }\n\n const latest = facts.filter(one => one.month <= to).map(one => one.month).sort().pop()\n const alerts = latest\n ? facts\n .filter(one => one.month === latest)\n .flatMap(bill => {\n const account = accounts.find(one => one.id === bill.accountId)\n if (!account) return []\n const previous = facts.find(one => one.accountId === bill.accountId && one.month === shiftMonth(bill.month, -1))\n return alertsOf(account, subs.filter(one => one.accountId === account.id), bill, previous).map(alert => ({ ...alert, accountId: account.id, month: bill.month }))\n })\n : []\n\n const name = (id?: string | null) => accounts.find(one => one.id === id)?.name ?? null\n const subName = (id?: string | null) => subs.find(one => one.id === id)?.name ?? null\n return {\n months,\n all: trend.all,\n accounts: trend.accounts.map(one => ({ ...one, name: name(one.accountId) })),\n subscriptions: trend.subscriptions.map(one => ({ ...one, name: subName(one.subscriptionId), accountName: name(one.accountId) })),\n departments: [...departments.values()].map(one => ({ ...one, total: one.amounts.reduce((sum, amount) => sum + amount, 0) })).sort((a, b) => b.total - a.total),\n alerts: alerts.map(alert => ({ ...alert, accountName: name(alert.accountId), subscriptionName: subName(alert.subscriptionId) }))\n }\n}\n\n/* ----------------------------------------------------------------------------------------------------------------- */\n/* A row's months for the list and the 360 (decision 10) and what moved on it (decision 11) */\n\n/**\n * What went out to an account's vendor (ADR-0177 decision 10, the user 2026-10-30: 「이테크 입금 이력이 있을텐데」;\n * 개정 1) - the bank withdrawals and the card charges (accounting, CONFIRMED and CARD) to the account's counterparty,\n * newest first. A line takes its counterparty when it lands (accounting `saveTransactions`), so a vendor's lines are\n * its linked ones. Only lines in the account's currency count toward its months.\n */\nexport async function vendorLinesOf(tx: EntityManager, domain: Domain, counterpartyIds: string[], from?: string, to?: string): Promise<Transaction[]> {\n if (!counterpartyIds.length) return []\n const query = tx\n .getRepository(Transaction)\n .createQueryBuilder('line')\n .leftJoinAndSelect('line.bankAccount', 'bankAccount')\n .where('line.domain = :domain', { domain: domain.id })\n .andWhere('line.category IN (:...categories)', { categories: [TransactionCategory.CONFIRMED, TransactionCategory.CARD] })\n .andWhere('line.type = :type', { type: CashFlowType.EXPENSE })\n .andWhere('line.counterparty IN (:...parties)', { parties: counterpartyIds })\n if (from) query.andWhere('line.transactionDate >= :from', { from })\n if (to) query.andWhere('line.transactionDate <= :to', { to })\n return query.orderBy('line.transactionDate', 'DESC').addOrderBy('line.amount', 'DESC').getMany()\n}\n\n/** The bank and card lines that paid an account's vendor, every one - for its 360. */\nexport async function saasPaymentsOf(tx: EntityManager, domain: Domain, scope: SaasScope, accountId: string) {\n const account = await accountIn(tx, domain, scope, accountId)\n return account.counterpartyId ? vendorLinesOf(tx, domain, [account.counterpartyId]) : []\n}\n\n/**\n * Each account's last twelve months before this one and the next three expected (`saasExpected`). A month is its bill\n * when one is written; else, for a reader of the bank lines (`withBank`), what went out to its vendor that month from\n * the bank or a card (decision 10, 개정 1); else empty. One read for all the accounts of a list.\n */\nexport async function saasTrendsOf(tx: EntityManager, domain: Domain, accounts: SaasAccount[], today: string, withBank = false): Promise<Map<string, SaasTrend>> {\n const trends = new Map<string, SaasTrend>()\n if (!accounts.length) return trends\n const now = today.slice(0, 7)\n const months = monthsFrom(shiftMonth(now, -12), shiftMonth(now, -1))\n const nextMonths = monthsFrom(now, shiftMonth(now, 2))\n const bills = await billsOf(tx, domain, accounts.map(one => one.id), months[0], months[months.length - 1])\n const expected = await saasExpected(tx, domain, nextMonths[0], nextMonths[nextMonths.length - 1])\n const parties = [...new Set(accounts.map(one => one.counterpartyId).filter(Boolean))] as string[]\n const paid = withBank ? await vendorLinesOf(tx, domain, parties, `${months[0]}-01`, `${months[months.length - 1]}-31`) : []\n for (const account of accounts) {\n const own = bills.filter(one => one.accountId === account.id)\n const lines = paid.filter(line => line.counterpartyId === account.counterpartyId && (line.currency || 'KRW') === account.currency)\n const banked = (month: string) => {\n const of = lines.filter(line => line.transactionDate?.slice(0, 7) === month)\n return of.length ? of.reduce((sum, line) => sum + Number(line.amount), 0) : null\n }\n const values = months.map(month => own.find(one => one.month === month)?.total ?? banked(month))\n trends.set(account.id, {\n months,\n values,\n sources: months.map((month, i) =>\n own.some(one => one.month === month)\n ? 'bill'\n : values[i] === null\n ? null\n : lines.some(line => line.transactionDate?.slice(0, 7) === month && line.category === TransactionCategory.CONFIRMED)\n ? 'bank'\n : 'card'\n ),\n nextMonths,\n expected: nextMonths.map(month => expected.find(one => one.accountId === account.id && one.month === month)?.amount ?? null),\n currency: account.currency\n })\n }\n return trends\n}\n\n/** What moved on an account and on each of its subscriptions, newest first. */\nexport async function saasChangesOf(tx: EntityManager, domain: Domain, scope: SaasScope, accountId: string) {\n const account = await accountIn(tx, domain, scope, accountId)\n const subs = await tx.getRepository(SaasSubscription).find({ where: { domain: { id: domain.id }, account: { id: account.id } } as any, withDeleted: true })\n const rows = [\n ...(await readFactChanges(tx, domain, SAAS_ACCOUNT_FACT, account.id)).map(one => Object.assign(one, { subject: account.name })),\n ...(await Promise.all(subs.map(async sub => (await readFactChanges(tx, domain, SAAS_SUBSCRIPTION_FACT, sub.id)).map(one => Object.assign(one, { subject: sub.name }))))).flat()\n ]\n return rows.sort((a, b) => new Date(b.at).getTime() - new Date(a.at).getTime())\n}\n\n/* ----------------------------------------------------------------------------------------------------------------- */\n/* What the books already say is subscribed to (개정 1) */\n\n/** A candidate with its vendor's name, for the list. */\nexport type SaasCandidateRow = CandidateFacts & { counterpartyName: string; hidden: boolean }\n\n\n/**\n * Whom the bank and card lines of the last twelve months show paid month after month that is no account yet and no\n * recurring item - what a keeper may make an account of with one press. A line on a subject outside profit and loss\n * (a card bill, a tax, a transfer, a loan) pays no vendor, and a person (salary, expenses) is no vendor. With `hidden`,\n * the ones a keeper hid instead.\n */\nexport async function saasCandidatesOf(tx: EntityManager, domain: Domain, today: string, hidden = false): Promise<SaasCandidateRow[]> {\n const now = today.slice(0, 7)\n const from = `${shiftMonth(now, -12)}-01`\n const lines = await tx\n .getRepository(Transaction)\n .createQueryBuilder('line')\n .leftJoinAndSelect('line.account', 'subject')\n .where('line.domain = :domain', { domain: domain.id })\n .andWhere('line.category IN (:...categories)', { categories: [TransactionCategory.CONFIRMED, TransactionCategory.CARD] })\n .andWhere('line.type = :type', { type: CashFlowType.EXPENSE })\n .andWhere('line.transactionDate >= :from', { from })\n .getMany()\n const accounts = await tx.getRepository(SaasAccount).find({ where: { domain: { id: domain.id } } as any })\n const recurring = await tx.getRepository(RecurringCashItem).find({ where: { domain: { id: domain.id } } as any })\n const hiddenKeys = new Set((await tx.getRepository(SaasHiddenVendor).find({ where: { domain: { id: domain.id } } as any })).map(one => one.counterpartyId ?? `name:${one.nameKey}`))\n const skip = new Set([...accounts.map(one => one.counterpartyId), ...recurring.map(one => one.counterpartyId), ...(hidden ? [] : hiddenKeys)].filter(Boolean) as string[])\n const parties = await tx.getRepository(Counterparty).find({ where: { domain: { id: domain.id } } as any, select: ['id', 'name', 'aliases', 'kind'] })\n const named = partyNamed(parties)\n const people = new Set(parties.filter(one => one.kind === CounterpartyKind.PERSON).map(one => one.id))\n /* Whom a line paid: its counterparty, else the one its written name is (the rule a line is linked by), else the name. */\n const vendorOf = (line: Transaction) => {\n const id = line.counterpartyId ?? named(line.counterpartyName)?.id\n if (id) return people.has(id) ? null : { key: id, counterpartyId: id }\n const key = nameKey(line.counterpartyName)\n return key && !looksLikePersonName(line.counterpartyName!) ? { key: `name:${key}`, counterpartyId: null } : null\n }\n const found = candidatesOf(\n lines\n .filter(line => line.account?.profitAndLoss !== false)\n .flatMap(line => {\n const vendor = vendorOf(line)\n return vendor ? [{ ...vendor, name: line.counterpartyName, transactionDate: line.transactionDate!, amount: Number(line.amount), currency: line.currency, bankAccountId: line.bankAccountId }] : []\n }),\n skip\n ).filter(one => hiddenKeys.has(one.key) === hidden)\n return found.map(one => ({ ...one, counterpartyName: parties.find(party => party.id === one.counterpartyId)?.name ?? one.name ?? '', hidden }))\n}\n\n/**\n * Make an account of each candidate - named after the vendor, paid from where it was paid most, on the day it was paid\n * most - with one usage subscription budgeted at the monthly average, so the months to come are expected at it until\n * bills say otherwise. A vendor the lines only name is registered as a counterparty first; the lines written with its\n * name are linked to it (accounting `linkLinesByName`). One that is no candidate any more is refused.\n */\nexport async function createSaasAccountsFromCandidates(tx: EntityManager, domain: Domain, user: any, keys: string[], today: string): Promise<SaasAccount[]> {\n const candidates = await saasCandidatesOf(tx, domain, today)\n const made: SaasAccount[] = []\n for (const key of [...new Set(keys)]) {\n const one = candidates.find(candidate => candidate.key === key)\n if (!one) throw new Refusal('saas-candidate-not-found', {}, 'It is no candidate any more - reload and try again')\n const counterpartyId = one.counterpartyId ?? (await saveCounterparties(tx, domain, user, [{ cuFlag: '+', name: one.counterpartyName, kind: CounterpartyKind.COMPANY }]))[0].id\n /* Its lines written with its name and not linked yet are its months. */\n await linkLinesByName(tx, domain, user, [counterpartyId])\n const [account] = await saveSaasAccounts(tx, domain, user, [\n { cuFlag: '+', name: one.counterpartyName, counterpartyId, paymentAccountId: one.paymentAccountId, currency: one.currency, billingDay: one.billingDay, status: SaasAccountStatus.ACTIVE }\n ])\n await saveSaasSubscriptions(tx, domain, user, 'all', account.id, [\n { cuFlag: '+', name: one.counterpartyName, billing: SaasBilling.USAGE, budget: one.average, startOn: one.firstDate, status: SaasSubscriptionStatus.ACTIVE }\n ])\n made.push(account)\n }\n return made\n}\n\n/** Hide candidates - by their keys - or show them again. */\nexport async function hideSaasCandidates(tx: EntityManager, domain: Domain, user: any, keys: string[], hide: boolean): Promise<boolean> {\n const repo = tx.getRepository(SaasHiddenVendor)\n const wanted = [...new Set(keys)].filter(Boolean)\n const names = wanted.filter(key => key.startsWith('name:')).map(key => key.slice(5))\n const ids = wanted.filter(key => !key.startsWith('name:'))\n const parties = ids.length ? await tx.getRepository(Counterparty).find({ where: { domain: { id: domain.id }, id: In(ids) } as any }) : []\n if (parties.length !== ids.length) throw new Refusal('saas-counterparty-not-found', {}, 'The vendor was not found - reload and try again')\n const rows = await repo.find({ where: { domain: { id: domain.id } } as any })\n const held = (row: SaasHiddenVendor) => (row.counterpartyId ? ids.includes(row.counterpartyId) : names.includes(row.nameKey!))\n if (!hide) {\n const gone = rows.filter(held)\n if (gone.length) await repo.remove(gone)\n return true\n }\n for (const party of parties) if (!rows.some(row => row.counterpartyId === party.id)) await repo.save({ domain, counterparty: party, creator: user })\n for (const key of names) if (!rows.some(row => !row.counterpartyId && row.nameKey === key)) await repo.save({ domain, nameKey: key, creator: user })\n return true\n}\n"]}
|
|
1
|
+
{"version":3,"file":"saas-service.js","sourceRoot":"","sources":["../../server/service/saas-service.ts"],"names":[],"mappings":"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","sourcesContent":["import { BankAccount, CashFlowType, linkLinesByName, RecurringCashItem, Transaction, TransactionCategory } from '@things-factory/accounting'\nimport { Asset } from '@things-factory/asset'\n/* The register grids' save, the asset module's - this module saves its grids the same way (one implementation). */\nimport { amountOf, applyPatches, dayOf, Patch, textOf, touched } from '@things-factory/asset/dist-server/service/patches.js'\nimport { Counterparty, CounterpartyKind, looksLikePersonName, nameKey, partyNamed, saveCounterparties } from '@things-factory/biz-base'\nimport { fieldChanges, readFactChanges, recordFactChanges } from '@things-factory/fact-change'\nimport { Department, Employee } from '@things-factory/organization'\nimport { Domain, Refusal } from '@things-factory/shell'\nimport { EntityManager, In } from 'typeorm'\n\nimport { accountIn, SaasScope } from './saas-access'\nimport { SaasAccount } from './saas-account'\nimport { SaasBill, SaasBillLine } from './saas-bill'\nimport { SaasHiddenVendor } from './saas-hidden-vendor'\nimport {\n alertsOf,\n BillFacts,\n billTotal,\n candidatesOf,\n expectedOfMonth,\n MONTH,\n monthsFrom,\n SaasAccountStatus,\n SaasBilling,\n CandidateFacts,\n SaasSubscriptionStatus,\n seatHeld,\n shiftMonth,\n trendOf\n} from './saas-rules'\nimport { SaasSeat } from './saas-seat'\nimport { SaasSubscription } from './saas-subscription'\nimport { SaasTrend } from './saas-trend-type'\n\nconst currencyOf = (value: any, fallback: string | null) => {\n const text = String(value ?? '').trim().toUpperCase()\n if (!text) return fallback\n if (!/^[A-Z]{3}$/.test(text)) throw new Refusal('saas-currency-invalid', { value: text }, `'${text}' is not a currency code (KRW, USD)`)\n return text\n}\n\nconst intOf = (value: any, code: string, min: number, max: number): number | null => {\n if (value === null || value === undefined || value === '') return null\n const number = Number(value)\n if (!Number.isInteger(number) || number < min || number > max) throw new Refusal(code, { min, max }, `Give a whole number from ${min} to ${max}`)\n return number\n}\n\nasync function oneOf<T>(tx: EntityManager, target: any, domain: Domain, id: string | null | undefined, code: string): Promise<T | null> {\n if (!id) return null\n const found = await tx.getRepository(target).findOne({ where: { domain: { id: domain.id }, id } as any })\n if (!found) throw new Refusal(code, {}, 'What it points at was not found')\n return found as T\n}\n\nconst field = (patch: Patch, name: string, old?: any) => (patch[name] !== undefined ? patch[name] : old?.[name])\n\n/*\n * What moved on an account or a subscription, field by field (ADR-0177 decision 11) - the fact-change module keeps it.\n * A row's relations are told by their id; a new row has no history yet.\n */\nexport const SAAS_ACCOUNT_FACT = 'saas-account'\nexport const SAAS_SUBSCRIPTION_FACT = 'saas-subscription'\nconst ACCOUNT_TRACKED = ['name', 'counterpartyId', 'identifier', 'parentId', 'paymentAccountId', 'currency', 'billingDay', 'increaseAlertRate', 'status', 'closedOn'] as const\nconst SUBSCRIPTION_TRACKED = ['name', 'billing', 'vendorKey', 'trial', 'quantity', 'unitPrice', 'amount', 'budget', 'everyMonths', 'startOn', 'renewalOn', 'autoRenew', 'noticeDays', 'departmentId', 'assetId', 'status', 'endedOn'] as const\nconst idsOf = (row: Record<string, any>) =>\n Object.fromEntries(Object.entries(row).map(([key, value]) => (value && typeof value === 'object' && 'id' in value ? [`${key}Id`, value.id] : value === null && ['counterparty', 'parent', 'paymentAccount', 'department', 'asset'].includes(key) ? [`${key}Id`, null] : [key, value])))\n\nasync function recordChanges(tx: EntityManager, domain: Domain, user: any, factKind: string, old: any, row: Record<string, any>, fields: readonly string[]) {\n if (!old) return\n const after = { ...old, ...idsOf(row) }\n await recordFactChanges(tx, domain, { factKind, factName: old.id, changes: fieldChanges(old, after, fields as any) }, { user, source: 'saas' })\n}\n\n/* ----------------------------------------------------------------------------------------------------------------- */\n/* Accounts (decision 2) - kept by `saas` keepers only */\n\nexport async function saveSaasAccounts(tx: EntityManager, domain: Domain, user: any, patches: Patch[]) {\n const saved = await applyPatches(\n tx,\n SaasAccount,\n domain,\n user,\n patches,\n async (patch, old) => {\n const row: Record<string, any> = {}\n const name = touched(patch, 'name', old) ? textOf(patch.name) : old!.name\n if (!name) throw new Refusal('saas-account-name-required', {}, 'Name the service')\n row.name = name\n for (const one of ['identifier', 'purpose', 'billingEmail', 'secretLocation', 'description']) if (touched(patch, one, old)) row[one] = textOf(patch[one])\n if (touched(patch, 'currency', old)) row.currency = currencyOf(patch.currency, 'KRW')\n if (touched(patch, 'billingDay', old)) row.billingDay = intOf(patch.billingDay, 'saas-billing-day-invalid', 1, 31)\n if (touched(patch, 'increaseAlertRate', old)) {\n const rate = amountOf(patch.increaseAlertRate, 'saas-alert-rate-invalid')\n if (rate !== null && rate > 10) throw new Refusal('saas-alert-rate-invalid', {}, 'Give the rate as a part - 0.2 for 20%')\n row.increaseAlertRate = rate\n }\n if (touched(patch, 'counterpartyId', old)) row.counterparty = await oneOf(tx, Counterparty, domain, patch.counterpartyId, 'saas-counterparty-not-found')\n if (touched(patch, 'paymentAccountId', old)) row.paymentAccount = await oneOf(tx, BankAccount, domain, patch.paymentAccountId, 'saas-payment-account-not-found')\n if (touched(patch, 'parentId', old)) {\n const parent = await oneOf<SaasAccount>(tx, SaasAccount, domain, patch.parentId, 'saas-parent-not-found')\n if (parent && (parent.id === old?.id || (await tx.getRepository(SaasAccount).findOne({ where: { id: parent.id }, relations: ['parent'] }))?.parent))\n throw new Refusal('saas-parent-invalid', {}, 'An account is under a top account only, and not under itself')\n if (parent && old && (await tx.getRepository(SaasSubscription).count({ where: { account: { id: old.id } } as any })))\n throw new Refusal('saas-parent-has-subscriptions', {}, 'An account with subscriptions is billed itself - it cannot go under another')\n row.parent = parent\n }\n if (touched(patch, 'adminIds', old)) {\n const ids: string[] = [...new Set<string>((patch.adminIds ?? []).filter(Boolean))]\n const admins = ids.length ? await tx.getRepository(Employee).find({ where: { id: In(ids), domain: { id: domain.id } } as any }) : []\n if (admins.length !== ids.length) throw new Refusal('saas-admin-not-found', {}, 'An admin is no employee of this domain')\n row.admins = admins\n }\n if (touched(patch, 'status', old)) row.status = patch.status ?? SaasAccountStatus.ACTIVE\n if (touched(patch, 'closedOn', old)) row.closedOn = dayOf(patch.closedOn, 'saas-day-invalid')\n if ((row.status ?? old?.status) === SaasAccountStatus.CLOSED && !(row.closedOn !== undefined ? row.closedOn : old?.closedOn))\n throw new Refusal('saas-closed-on-required', {}, 'Give the day it was closed')\n await recordChanges(tx, domain, user, SAAS_ACCOUNT_FACT, old, row, ACCOUNT_TRACKED)\n return row\n },\n 'saas-account-not-found'\n )\n /* The vendor's lines written with its name and not linked yet are the account's months (개정 1). */\n const vendors = patches.filter(one => one.cuFlag !== '-' && one.counterpartyId).map(one => one.counterpartyId as string)\n if (vendors.length) await linkLinesByName(tx, domain, user, vendors)\n return saved\n}\n\n/* ----------------------------------------------------------------------------------------------------------------- */\n/* Subscriptions (decision 3) - by keepers, and by the account's admins */\n\nexport async function saveSaasSubscriptions(tx: EntityManager, domain: Domain, user: any, scope: SaasScope, accountId: string, patches: Patch[]) {\n const account = await accountIn(tx, domain, scope, accountId)\n if (account.parentId && patches.some(one => one.cuFlag !== '-'))\n throw new Refusal('saas-subscription-on-sub-account', {}, 'An account under another is billed by its parent - subscribe there')\n return applyPatches(\n tx,\n SaasSubscription,\n domain,\n user,\n patches,\n async (patch, old) => {\n const row: Record<string, any> = old ? {} : { account }\n const name = touched(patch, 'name', old) ? textOf(patch.name) : old!.name\n if (!name) throw new Refusal('saas-subscription-name-required', {}, 'Name the product or plan')\n row.name = name\n const billing = (field(patch, 'billing', old) ?? SaasBilling.FIXED) as SaasBilling\n if (!Object.values(SaasBilling).includes(billing)) throw new Refusal('saas-billing-invalid', {}, 'Say how it is paid for')\n row.billing = billing\n for (const one of ['quantity', 'unitPrice', 'amount', 'budget']) if (touched(patch, one, old)) row[one] = amountOf(patch[one], 'saas-amount-invalid')\n /* `vendorKey` and `trial` are a sync's (개정 2) - the GraphQL patch does not carry them. */\n if (touched(patch, 'vendorKey', old)) row.vendorKey = textOf(patch.vendorKey)\n if (touched(patch, 'trial', old)) row.trial = patch.trial === true\n const value = (name: string) => (row[name] !== undefined ? row[name] : old?.[name])\n /* A plan read from the vendor's tenant may wait for its price (개정 2) - it is expected at nothing until then. */\n const priced = value('unitPrice') !== null && value('unitPrice') !== undefined\n if (billing === SaasBilling.SEAT && !(Number(value('quantity')) > 0 && (priced || value('vendorKey'))))\n throw new Refusal('saas-seat-price-required', {}, 'A seat plan takes its seats and the price of one')\n if ((billing === SaasBilling.FIXED || billing === SaasBilling.COMMITMENT) && (value('amount') === null || value('amount') === undefined))\n throw new Refusal('saas-amount-required', {}, 'Give what one billing costs')\n if (touched(patch, 'everyMonths', old)) row.everyMonths = intOf(patch.everyMonths, 'saas-every-months-invalid', 1, 120) ?? 1\n row.startOn = touched(patch, 'startOn', old) ? dayOf(patch.startOn, 'saas-start-on-invalid', true) : old!.startOn\n if (touched(patch, 'renewalOn', old)) row.renewalOn = dayOf(patch.renewalOn, 'saas-day-invalid')\n if (touched(patch, 'endedOn', old)) row.endedOn = dayOf(patch.endedOn, 'saas-day-invalid')\n if (touched(patch, 'autoRenew', old)) row.autoRenew = patch.autoRenew !== false\n if (touched(patch, 'noticeDays', old)) row.noticeDays = intOf(patch.noticeDays, 'saas-notice-days-invalid', 0, 365)\n if (touched(patch, 'description', old)) row.description = textOf(patch.description)\n if (touched(patch, 'departmentId', old)) row.department = await oneOf(tx, Department, domain, patch.departmentId, 'saas-department-not-found')\n if (touched(patch, 'assetId', old)) row.asset = await oneOf(tx, Asset, domain, patch.assetId, 'saas-asset-not-found')\n if (billing === SaasBilling.OWNED && !(row.asset !== undefined ? row.asset : old?.assetId))\n throw new Refusal('saas-owned-asset-required', {}, 'A license owned points at its asset in the register - its cost is there')\n if (billing === SaasBilling.COMMITMENT && !value('renewalOn')) throw new Refusal('saas-term-end-required', {}, 'A commitment takes the day its term ends')\n if (touched(patch, 'status', old)) row.status = patch.status ?? SaasSubscriptionStatus.ACTIVE\n const status = row.status ?? old?.status ?? SaasSubscriptionStatus.ACTIVE\n if (status === SaasSubscriptionStatus.CANCELLED && !value('endedOn')) throw new Refusal('saas-ended-on-required', {}, 'Give the day it ended')\n if (status === SaasSubscriptionStatus.CANCELLING && !value('renewalOn')) throw new Refusal('saas-renewal-on-required', {}, 'Not renewing needs the day it would renew')\n if (value('endedOn') && value('endedOn') < row.startOn) throw new Refusal('saas-ended-before-start', {}, 'It ended before it started')\n await recordChanges(tx, domain, user, SAAS_SUBSCRIPTION_FACT, old, row, SUBSCRIPTION_TRACKED)\n return row\n },\n 'saas-subscription-not-found',\n { account: { id: account.id } }\n )\n}\n\n/** The subscriptions of an account, with the seats held today. */\nexport async function saasSubscriptionsOf(tx: EntityManager, domain: Domain, scope: SaasScope, accountId: string, today: string) {\n const account = await accountIn(tx, domain, scope, accountId)\n const subs = await tx.getRepository(SaasSubscription).find({ where: { domain: { id: domain.id }, account: { id: account.id } } as any, relations: ['department', 'asset'], order: { name: 'ASC' } as any })\n const seats = subs.length ? await tx.getRepository(SaasSeat).find({ where: { domain: { id: domain.id }, subscription: { id: In(subs.map(one => one.id)) } } as any }) : []\n for (const sub of subs) sub.seatsHeld = seats.filter(seat => seat.subscriptionId === sub.id && seatHeld(seat, today)).length\n return subs\n}\n\n/* ----------------------------------------------------------------------------------------------------------------- */\n/* Seats (decision 6) */\n\nasync function subscriptionIn(tx: EntityManager, domain: Domain, scope: SaasScope, subscriptionId: string) {\n const sub = subscriptionId ? await tx.getRepository(SaasSubscription).findOne({ where: { domain: { id: domain.id }, id: subscriptionId } as any }) : null\n if (!sub || (scope !== 'all' && !scope.has(sub.accountId!))) throw new Refusal('saas-subscription-not-found', {}, 'The subscription was not found - reload and try again')\n return sub\n}\n\nexport async function saveSaasSeats(tx: EntityManager, domain: Domain, user: any, scope: SaasScope, subscriptionId: string, patches: Patch[]) {\n const subscription = await subscriptionIn(tx, domain, scope, subscriptionId)\n return applyPatches(\n tx,\n SaasSeat,\n domain,\n user,\n patches,\n async (patch, old) => {\n const row: Record<string, any> = old ? {} : { subscription }\n if (touched(patch, 'employeeId', old)) row.employee = await oneOf(tx, Employee, domain, patch.employeeId, 'saas-seat-employee-not-found')\n /* `login` is a sync's (개정 2) - the GraphQL patch does not carry it. */\n for (const one of ['holder', 'login', 'description']) if (touched(patch, one, old)) row[one] = textOf(patch[one])\n if (!(row.employee !== undefined ? row.employee : old?.employeeId) && !(row.holder !== undefined ? row.holder : old?.holder))\n throw new Refusal('saas-seat-holder-required', {}, 'Say who holds the seat - an employee, or a name')\n if (touched(patch, 'fromOn', old)) row.fromOn = dayOf(patch.fromOn, 'saas-day-invalid')\n if (touched(patch, 'untilOn', old)) row.untilOn = dayOf(patch.untilOn, 'saas-day-invalid')\n const from = row.fromOn !== undefined ? row.fromOn : old?.fromOn\n const until = row.untilOn !== undefined ? row.untilOn : old?.untilOn\n if (from && until && until < from) throw new Refusal('saas-seat-until-before-from', {}, 'It was taken back before it was given')\n return row\n },\n 'saas-seat-not-found',\n { subscription: { id: subscription.id } }\n )\n}\n\nexport async function saasSeatsOf(tx: EntityManager, domain: Domain, scope: SaasScope, subscriptionId: string) {\n const sub = await subscriptionIn(tx, domain, scope, subscriptionId)\n return tx.getRepository(SaasSeat).find({ where: { domain: { id: domain.id }, subscription: { id: sub.id } } as any, relations: ['employee'], order: { fromOn: 'DESC' } as any })\n}\n\n/* ----------------------------------------------------------------------------------------------------------------- */\n/* Bills (decisions 5, 9) - one an account a month, its lines replaced whole */\n\nexport interface SaasBillFields {\n id?: string | null\n month: string\n billedOn?: string | null\n description?: string | null\n lines: { subscriptionId?: string | null; label?: string | null; amount: number }[]\n}\n\nexport async function saveSaasBill(tx: EntityManager, domain: Domain, user: any, scope: SaasScope, accountId: string, input: SaasBillFields) {\n const account = await accountIn(tx, domain, scope, accountId)\n if (account.parentId) throw new Refusal('saas-bill-on-sub-account', {}, 'An account under another is billed by its parent')\n const month = String(input.month ?? '').trim()\n if (!MONTH.test(month)) throw new Refusal('saas-month-invalid', { value: month }, 'Write the month as YYYY-MM')\n const bills = tx.getRepository(SaasBill)\n const old = input.id ? await bills.findOne({ where: { domain: { id: domain.id }, id: input.id, account: { id: account.id } } as any }) : null\n if (input.id && !old) throw new Refusal('saas-bill-not-found', {}, 'The bill was not found - reload and try again')\n const twin = await bills.findOne({ where: { domain: { id: domain.id }, account: { id: account.id }, month } as any })\n if (twin && twin.id !== old?.id) throw new Refusal('saas-bill-month-taken', { month }, `The account already has a bill for ${month} - change that one`)\n const lines = (input.lines ?? []).filter(line => line && (line.subscriptionId || textOf(line.label) || Number(line.amount)))\n if (!lines.length) throw new Refusal('saas-bill-lines-required', {}, 'A bill takes at least one line')\n const subIds = [...new Set(lines.map(line => line.subscriptionId).filter(Boolean))] as string[]\n if (subIds.length) {\n const found = await tx.getRepository(SaasSubscription).count({ where: { domain: { id: domain.id }, account: { id: account.id }, id: In(subIds) } as any })\n if (found !== subIds.length) throw new Refusal('saas-bill-subscription-not-found', {}, 'A line names a subscription not of this account')\n }\n for (const line of lines) if (!Number.isFinite(Number(line.amount))) throw new Refusal('saas-amount-invalid', {}, 'Give the amount as a number')\n const bill = await bills.save({\n ...(old ?? { domain, account, creator: user, currency: account.currency }),\n month,\n billedOn: dayOf(input.billedOn, 'saas-day-invalid'),\n description: textOf(input.description),\n /* Whoever writes it owns it: a person's save keeps a later sync off it (a sync marks its own, 개정 3). */\n synced: false,\n updater: user\n } as any)\n await tx.getRepository(SaasBillLine).delete({ bill: { id: bill.id } } as any)\n await tx.getRepository(SaasBillLine).save(\n lines.map(line => ({ domain, bill: { id: bill.id }, subscription: line.subscriptionId ? { id: line.subscriptionId } : null, label: textOf(line.label), amount: Number(line.amount) })) as any\n )\n return billsOf(tx, domain, [account.id]).then(all => all.find(one => one.id === bill.id)!)\n}\n\nexport async function deleteSaasBill(tx: EntityManager, domain: Domain, scope: SaasScope, id: string): Promise<boolean> {\n const bill = await tx.getRepository(SaasBill).findOne({ where: { domain: { id: domain.id }, id } as any })\n if (!bill || (scope !== 'all' && !scope.has(bill.accountId!))) throw new Refusal('saas-bill-not-found', {}, 'The bill was not found - reload and try again')\n await tx.getRepository(SaasBill).softDelete({ id })\n return true\n}\n\n/** The bills of some accounts (all when none named) from a month on, with their lines and totals, latest first. */\nexport async function billsOf(tx: EntityManager, domain: Domain, accountIds?: string[], from?: string, to?: string): Promise<SaasBill[]> {\n const query = tx\n .getRepository(SaasBill)\n .createQueryBuilder('bill')\n .leftJoinAndSelect('bill.lines', 'line')\n .leftJoinAndSelect('line.subscription', 'subscription')\n .where('bill.domain = :domain', { domain: domain.id })\n if (accountIds) {\n if (!accountIds.length) return []\n query.andWhere('bill.account IN (:...accounts)', { accounts: accountIds })\n }\n if (from) query.andWhere('bill.month >= :from', { from })\n if (to) query.andWhere('bill.month <= :to', { to })\n const bills = await query.orderBy('bill.month', 'DESC').getMany()\n for (const bill of bills) bill.total = billTotal(bill.lines ?? [])\n return bills\n}\n\nexport async function saasBillsOf(tx: EntityManager, domain: Domain, scope: SaasScope, accountId: string) {\n const account = await accountIn(tx, domain, scope, accountId)\n return billsOf(tx, domain, [account.id])\n}\n\nconst factsOf = (bill: SaasBill): BillFacts => ({\n accountId: bill.accountId!,\n month: bill.month,\n currency: bill.currency,\n lines: (bill.lines ?? []).map(line => ({ subscriptionId: line.subscriptionId ?? null, amount: Number(line.amount) }))\n})\n\n/* ----------------------------------------------------------------------------------------------------------------- */\n/* What is still to come (decision 4) - read by an application's expected cash */\n\nexport interface SaasExpectedRow {\n accountId: string\n accountName: string\n counterpartyId?: string | null\n paymentAccountId?: string | null\n month: string\n day: string | null\n amount: number\n currency: string\n /** A bill is written for the month: the amount is the bill's, not an estimate. */\n billed: boolean\n}\n\n/**\n * What each account is expected to be billed, month by month from `from` to `to`: the bill when one is written for the\n * month, else what its subscriptions say (usage at the average of its latest bills).\n */\nexport async function saasExpected(tx: EntityManager, domain: Domain, from: string, to: string): Promise<SaasExpectedRow[]> {\n const accounts = await tx.getRepository(SaasAccount).find({ where: { domain: { id: domain.id }, status: SaasAccountStatus.ACTIVE } as any })\n const top = accounts.filter(one => !one.parentId)\n if (!top.length) return []\n const subs = await tx.getRepository(SaasSubscription).find({ where: { domain: { id: domain.id }, account: { id: In(top.map(one => one.id)) } } as any })\n const bills = await billsOf(tx, domain, top.map(one => one.id), shiftMonth(from, -12), to)\n const billed = new Map<string, { month: string; amount: number }[]>()\n for (const bill of bills)\n if (bill.month < from)\n for (const line of bill.lines ?? []) if (line.subscriptionId) billed.set(line.subscriptionId, [...(billed.get(line.subscriptionId) ?? []), { month: bill.month, amount: Number(line.amount) }])\n const rows: SaasExpectedRow[] = []\n for (const account of top) {\n const own = subs.filter(one => one.accountId === account.id)\n for (const month of monthsFrom(from, to)) {\n const [year, m] = month.split('-').map(Number)\n const bill = bills.find(one => one.accountId === account.id && one.month === month)\n const expected = expectedOfMonth(account, own, billed, year, m)\n if (!bill && !expected) continue\n rows.push({\n accountId: account.id,\n accountName: account.name,\n counterpartyId: account.counterpartyId ?? null,\n paymentAccountId: account.paymentAccountId ?? null,\n month,\n day: bill?.billedOn ?? expected?.day ?? null,\n amount: bill ? bill.total! : expected!.amount,\n currency: account.currency,\n billed: !!bill\n })\n }\n }\n return rows\n}\n\n/* ----------------------------------------------------------------------------------------------------------------- */\n/* The cost trend (decision 9) */\n\n/** Whose department each employee is in. */\nasync function departmentsOfEmployees(tx: EntityManager, domain: Domain, ids: string[]): Promise<Map<string, { id: string; name: string }>> {\n if (!ids.length) return new Map()\n const employees = await tx.getRepository(Employee).find({ where: { domain: { id: domain.id }, id: In(ids) } as any, relations: ['department'] })\n return new Map(employees.filter(one => one.department).map(one => [one.id, { id: one.department!.id, name: one.department!.name }]))\n}\n\n/**\n * The bills of the months from `from` to `to` as series - all, an account, a subscription - and a department series: a\n * line of a seat plan split by the seats held at the month's end by department, any other line its subscription's\n * department. Plus what the latest month's bills are worth telling.\n */\nexport async function saasCostTrend(tx: EntityManager, domain: Domain, from: string, to: string) {\n if (!MONTH.test(from) || !MONTH.test(to) || from > to) throw new Refusal('saas-month-invalid', {}, 'Give the months as YYYY-MM, the first before the last')\n if (monthsFrom(from, to).length > 60) throw new Refusal('saas-trend-too-long', { max: 60 }, 'Up to 60 months at once')\n const bills = await billsOf(tx, domain, undefined, shiftMonth(from, -1), to)\n const facts = bills.map(factsOf)\n const trend = trendOf(facts, from, to)\n\n const accounts = await tx.getRepository(SaasAccount).find({ where: { domain: { id: domain.id } } as any, withDeleted: true })\n const subs = await tx.getRepository(SaasSubscription).find({ where: { domain: { id: domain.id } } as any, relations: ['department'], withDeleted: true })\n const seats = subs.length ? await tx.getRepository(SaasSeat).find({ where: { domain: { id: domain.id }, subscription: { id: In(subs.map(one => one.id)) } } as any }) : []\n const departmentOf = await departmentsOfEmployees(tx, domain, [...new Set(seats.map(one => one.employeeId).filter(Boolean))] as string[])\n\n const months = trend.months\n const departments = new Map<string, { key: string; departmentId: string | null; name: string | null; currency: string; amounts: number[] }>()\n const addTo = (id: string | null, name: string | null, currency: string, at: number, amount: number) => {\n const key = `${id ?? ''}|${currency}`\n let one = departments.get(key)\n if (!one) departments.set(key, (one = { key, departmentId: id, name, currency, amounts: months.map(() => 0) }))\n one.amounts[at] += amount\n }\n for (const bill of facts) {\n const at = months.indexOf(bill.month)\n if (at < 0) continue\n const monthEnd = `${bill.month}-31`\n for (const line of bill.lines) {\n const sub = subs.find(one => one.id === line.subscriptionId)\n const held = sub?.billing === SaasBilling.SEAT ? seats.filter(seat => seat.subscriptionId === sub.id && seatHeld(seat, monthEnd) && (!seat.fromOn || seat.fromOn <= monthEnd)) : []\n if (held.length) {\n for (const seat of held) {\n const department = seat.employeeId ? departmentOf.get(seat.employeeId) : undefined\n addTo(department?.id ?? sub?.department?.id ?? null, department?.name ?? sub?.department?.name ?? null, bill.currency, at, line.amount / held.length)\n }\n } else addTo(sub?.department?.id ?? null, sub?.department?.name ?? null, bill.currency, at, line.amount)\n }\n }\n\n const latest = facts.filter(one => one.month <= to).map(one => one.month).sort().pop()\n const alerts = latest\n ? facts\n .filter(one => one.month === latest)\n .flatMap(bill => {\n const account = accounts.find(one => one.id === bill.accountId)\n if (!account) return []\n const previous = facts.find(one => one.accountId === bill.accountId && one.month === shiftMonth(bill.month, -1))\n return alertsOf(account, subs.filter(one => one.accountId === account.id), bill, previous).map(alert => ({ ...alert, accountId: account.id, month: bill.month }))\n })\n : []\n\n const name = (id?: string | null) => accounts.find(one => one.id === id)?.name ?? null\n const subName = (id?: string | null) => subs.find(one => one.id === id)?.name ?? null\n return {\n months,\n all: trend.all,\n accounts: trend.accounts.map(one => ({ ...one, name: name(one.accountId) })),\n subscriptions: trend.subscriptions.map(one => ({ ...one, name: subName(one.subscriptionId), accountName: name(one.accountId) })),\n departments: [...departments.values()].map(one => ({ ...one, total: one.amounts.reduce((sum, amount) => sum + amount, 0) })).sort((a, b) => b.total - a.total),\n alerts: alerts.map(alert => ({ ...alert, accountName: name(alert.accountId), subscriptionName: subName(alert.subscriptionId) }))\n }\n}\n\n/* ----------------------------------------------------------------------------------------------------------------- */\n/* A row's months for the list and the 360 (decision 10) and what moved on it (decision 11) */\n\n/**\n * What went out to an account's vendor (ADR-0177 decision 10, the user 2026-10-30: 「이테크 입금 이력이 있을텐데」;\n * 개정 1) - the bank withdrawals and the card charges (accounting, CONFIRMED and CARD) to the account's counterparty,\n * newest first. A line takes its counterparty when it lands (accounting `saveTransactions`), so a vendor's lines are\n * its linked ones. Only lines in the account's currency count toward its months.\n */\nexport async function vendorLinesOf(tx: EntityManager, domain: Domain, counterpartyIds: string[], from?: string, to?: string): Promise<Transaction[]> {\n if (!counterpartyIds.length) return []\n const query = tx\n .getRepository(Transaction)\n .createQueryBuilder('line')\n .leftJoinAndSelect('line.bankAccount', 'bankAccount')\n .where('line.domain = :domain', { domain: domain.id })\n .andWhere('line.category IN (:...categories)', { categories: [TransactionCategory.CONFIRMED, TransactionCategory.CARD] })\n .andWhere('line.type = :type', { type: CashFlowType.EXPENSE })\n .andWhere('line.counterparty IN (:...parties)', { parties: counterpartyIds })\n if (from) query.andWhere('line.transactionDate >= :from', { from })\n if (to) query.andWhere('line.transactionDate <= :to', { to })\n return query.orderBy('line.transactionDate', 'DESC').addOrderBy('line.amount', 'DESC').getMany()\n}\n\n/** The bank and card lines that paid an account's vendor, every one - for its 360. */\nexport async function saasPaymentsOf(tx: EntityManager, domain: Domain, scope: SaasScope, accountId: string) {\n const account = await accountIn(tx, domain, scope, accountId)\n return account.counterpartyId ? vendorLinesOf(tx, domain, [account.counterpartyId]) : []\n}\n\n/**\n * Each account's last twelve months before this one and the next three expected (`saasExpected`). A month is its bill\n * when one is written; else, for a reader of the bank lines (`withBank`), what went out to its vendor that month from\n * the bank or a card (decision 10, 개정 1); else empty. One read for all the accounts of a list.\n */\nexport async function saasTrendsOf(tx: EntityManager, domain: Domain, accounts: SaasAccount[], today: string, withBank = false): Promise<Map<string, SaasTrend>> {\n const trends = new Map<string, SaasTrend>()\n if (!accounts.length) return trends\n const now = today.slice(0, 7)\n const months = monthsFrom(shiftMonth(now, -12), shiftMonth(now, -1))\n const nextMonths = monthsFrom(now, shiftMonth(now, 2))\n const bills = await billsOf(tx, domain, accounts.map(one => one.id), months[0], months[months.length - 1])\n const expected = await saasExpected(tx, domain, nextMonths[0], nextMonths[nextMonths.length - 1])\n const parties = [...new Set(accounts.map(one => one.counterpartyId).filter(Boolean))] as string[]\n const paid = withBank ? await vendorLinesOf(tx, domain, parties, `${months[0]}-01`, `${months[months.length - 1]}-31`) : []\n for (const account of accounts) {\n const own = bills.filter(one => one.accountId === account.id)\n const lines = paid.filter(line => line.counterpartyId === account.counterpartyId && (line.currency || 'KRW') === account.currency)\n const banked = (month: string) => {\n const of = lines.filter(line => line.transactionDate?.slice(0, 7) === month)\n return of.length ? of.reduce((sum, line) => sum + Number(line.amount), 0) : null\n }\n const values = months.map(month => own.find(one => one.month === month)?.total ?? banked(month))\n trends.set(account.id, {\n months,\n values,\n sources: months.map((month, i) =>\n own.some(one => one.month === month)\n ? 'bill'\n : values[i] === null\n ? null\n : lines.some(line => line.transactionDate?.slice(0, 7) === month && line.category === TransactionCategory.CONFIRMED)\n ? 'bank'\n : 'card'\n ),\n nextMonths,\n expected: nextMonths.map(month => expected.find(one => one.accountId === account.id && one.month === month)?.amount ?? null),\n currency: account.currency\n })\n }\n return trends\n}\n\n/** What moved on an account and on each of its subscriptions, newest first. */\nexport async function saasChangesOf(tx: EntityManager, domain: Domain, scope: SaasScope, accountId: string) {\n const account = await accountIn(tx, domain, scope, accountId)\n const subs = await tx.getRepository(SaasSubscription).find({ where: { domain: { id: domain.id }, account: { id: account.id } } as any, withDeleted: true })\n const rows = [\n ...(await readFactChanges(tx, domain, SAAS_ACCOUNT_FACT, account.id)).map(one => Object.assign(one, { subject: account.name })),\n ...(await Promise.all(subs.map(async sub => (await readFactChanges(tx, domain, SAAS_SUBSCRIPTION_FACT, sub.id)).map(one => Object.assign(one, { subject: sub.name }))))).flat()\n ]\n return rows.sort((a, b) => new Date(b.at).getTime() - new Date(a.at).getTime())\n}\n\n/* ----------------------------------------------------------------------------------------------------------------- */\n/* What the books already say is subscribed to (개정 1) */\n\n/** A candidate with its vendor's name, for the list. */\nexport type SaasCandidateRow = CandidateFacts & { counterpartyName: string; hidden: boolean }\n\n\n/**\n * Whom the bank and card lines of the last twelve months show paid month after month that is no account yet and no\n * recurring item - what a keeper may make an account of with one press. A line on a subject outside profit and loss\n * (a card bill, a tax, a transfer, a loan) pays no vendor, and a person (salary, expenses) is no vendor. With `hidden`,\n * the ones a keeper hid instead.\n */\nexport async function saasCandidatesOf(tx: EntityManager, domain: Domain, today: string, hidden = false): Promise<SaasCandidateRow[]> {\n const now = today.slice(0, 7)\n const from = `${shiftMonth(now, -12)}-01`\n const lines = await tx\n .getRepository(Transaction)\n .createQueryBuilder('line')\n .leftJoinAndSelect('line.account', 'subject')\n .where('line.domain = :domain', { domain: domain.id })\n .andWhere('line.category IN (:...categories)', { categories: [TransactionCategory.CONFIRMED, TransactionCategory.CARD] })\n .andWhere('line.type = :type', { type: CashFlowType.EXPENSE })\n .andWhere('line.transactionDate >= :from', { from })\n .getMany()\n const accounts = await tx.getRepository(SaasAccount).find({ where: { domain: { id: domain.id } } as any })\n const recurring = await tx.getRepository(RecurringCashItem).find({ where: { domain: { id: domain.id } } as any })\n const hiddenKeys = new Set((await tx.getRepository(SaasHiddenVendor).find({ where: { domain: { id: domain.id } } as any })).map(one => one.counterpartyId ?? `name:${one.nameKey}`))\n const skip = new Set([...accounts.map(one => one.counterpartyId), ...recurring.map(one => one.counterpartyId), ...(hidden ? [] : hiddenKeys)].filter(Boolean) as string[])\n const parties = await tx.getRepository(Counterparty).find({ where: { domain: { id: domain.id } } as any, select: ['id', 'name', 'aliases', 'kind'] })\n const named = partyNamed(parties)\n const people = new Set(parties.filter(one => one.kind === CounterpartyKind.PERSON).map(one => one.id))\n /* Whom a line paid: its counterparty, else the one its written name is (the rule a line is linked by), else the name. */\n const vendorOf = (line: Transaction) => {\n const id = line.counterpartyId ?? named(line.counterpartyName)?.id\n if (id) return people.has(id) ? null : { key: id, counterpartyId: id }\n const key = nameKey(line.counterpartyName)\n return key && !looksLikePersonName(line.counterpartyName!) ? { key: `name:${key}`, counterpartyId: null } : null\n }\n const found = candidatesOf(\n lines\n .filter(line => line.account?.profitAndLoss !== false)\n .flatMap(line => {\n const vendor = vendorOf(line)\n return vendor ? [{ ...vendor, name: line.counterpartyName, transactionDate: line.transactionDate!, amount: Number(line.amount), currency: line.currency, bankAccountId: line.bankAccountId }] : []\n }),\n skip\n ).filter(one => hiddenKeys.has(one.key) === hidden)\n return found.map(one => ({ ...one, counterpartyName: parties.find(party => party.id === one.counterpartyId)?.name ?? one.name ?? '', hidden }))\n}\n\n/**\n * Make an account of each candidate - named after the vendor, paid from where it was paid most, on the day it was paid\n * most - with one usage subscription budgeted at the monthly average, so the months to come are expected at it until\n * bills say otherwise. A vendor the lines only name is registered as a counterparty first; the lines written with its\n * name are linked to it (accounting `linkLinesByName`). One that is no candidate any more is refused.\n */\nexport async function createSaasAccountsFromCandidates(tx: EntityManager, domain: Domain, user: any, keys: string[], today: string): Promise<SaasAccount[]> {\n const candidates = await saasCandidatesOf(tx, domain, today)\n const made: SaasAccount[] = []\n for (const key of [...new Set(keys)]) {\n const one = candidates.find(candidate => candidate.key === key)\n if (!one) throw new Refusal('saas-candidate-not-found', {}, 'It is no candidate any more - reload and try again')\n const counterpartyId = one.counterpartyId ?? (await saveCounterparties(tx, domain, user, [{ cuFlag: '+', name: one.counterpartyName, kind: CounterpartyKind.COMPANY }]))[0].id\n /* Its lines written with its name and not linked yet are its months. */\n await linkLinesByName(tx, domain, user, [counterpartyId])\n const [account] = await saveSaasAccounts(tx, domain, user, [\n { cuFlag: '+', name: one.counterpartyName, counterpartyId, paymentAccountId: one.paymentAccountId, currency: one.currency, billingDay: one.billingDay, status: SaasAccountStatus.ACTIVE }\n ])\n await saveSaasSubscriptions(tx, domain, user, 'all', account.id, [\n { cuFlag: '+', name: one.counterpartyName, billing: SaasBilling.USAGE, budget: one.average, startOn: one.firstDate, status: SaasSubscriptionStatus.ACTIVE }\n ])\n made.push(account)\n }\n return made\n}\n\n/** Hide candidates - by their keys - or show them again. */\nexport async function hideSaasCandidates(tx: EntityManager, domain: Domain, user: any, keys: string[], hide: boolean): Promise<boolean> {\n const repo = tx.getRepository(SaasHiddenVendor)\n const wanted = [...new Set(keys)].filter(Boolean)\n const names = wanted.filter(key => key.startsWith('name:')).map(key => key.slice(5))\n const ids = wanted.filter(key => !key.startsWith('name:'))\n const parties = ids.length ? await tx.getRepository(Counterparty).find({ where: { domain: { id: domain.id }, id: In(ids) } as any }) : []\n if (parties.length !== ids.length) throw new Refusal('saas-counterparty-not-found', {}, 'The vendor was not found - reload and try again')\n const rows = await repo.find({ where: { domain: { id: domain.id } } as any })\n const held = (row: SaasHiddenVendor) => (row.counterpartyId ? ids.includes(row.counterpartyId) : names.includes(row.nameKey!))\n if (!hide) {\n const gone = rows.filter(held)\n if (gone.length) await repo.remove(gone)\n return true\n }\n for (const party of parties) if (!rows.some(row => row.counterpartyId === party.id)) await repo.save({ domain, counterparty: party, creator: user })\n for (const key of names) if (!rows.some(row => !row.counterpartyId && row.nameKey === key)) await repo.save({ domain, nameKey: key, creator: user })\n return true\n}\n"]}
|