@things-factory/saas 0.0.0-stage → 10.1.234

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/README.md +19 -2
  2. package/dist-client/bootstrap.d.ts +1 -0
  3. package/dist-client/bootstrap.js +5 -0
  4. package/dist-client/bootstrap.js.map +1 -0
  5. package/dist-client/components/saas-bill-editor.d.ts +59 -0
  6. package/dist-client/components/saas-bill-editor.js +211 -0
  7. package/dist-client/components/saas-bill-editor.js.map +1 -0
  8. package/dist-client/entity360/saas-account-360.d.ts +12 -0
  9. package/dist-client/entity360/saas-account-360.js +231 -0
  10. package/dist-client/entity360/saas-account-360.js.map +1 -0
  11. package/dist-client/index.d.ts +3 -0
  12. package/dist-client/index.js +4 -0
  13. package/dist-client/index.js.map +1 -0
  14. package/dist-client/pages/saas-account-list.d.ts +57 -0
  15. package/dist-client/pages/saas-account-list.js +175 -0
  16. package/dist-client/pages/saas-account-list.js.map +1 -0
  17. package/dist-client/pages/saas-account-page.d.ts +54 -0
  18. package/dist-client/pages/saas-account-page.js +352 -0
  19. package/dist-client/pages/saas-account-page.js.map +1 -0
  20. package/dist-client/pages/saas-cost-trend.d.ts +23 -0
  21. package/dist-client/pages/saas-cost-trend.js +219 -0
  22. package/dist-client/pages/saas-cost-trend.js.map +1 -0
  23. package/dist-client/route.d.ts +1 -0
  24. package/dist-client/route.js +16 -0
  25. package/dist-client/route.js.map +1 -0
  26. package/dist-client/tsconfig.tsbuildinfo +1 -0
  27. package/dist-client/words.d.ts +47 -0
  28. package/dist-client/words.js +39 -0
  29. package/dist-client/words.js.map +1 -0
  30. package/dist-server/index.d.ts +1 -0
  31. package/dist-server/index.js +9 -0
  32. package/dist-server/index.js.map +1 -0
  33. package/dist-server/role-tasks.d.ts +2 -0
  34. package/dist-server/role-tasks.js +16 -0
  35. package/dist-server/role-tasks.js.map +1 -0
  36. package/dist-server/service/checks.d.ts +32 -0
  37. package/dist-server/service/checks.js +83 -0
  38. package/dist-server/service/checks.js.map +1 -0
  39. package/dist-server/service/index.d.ts +20 -0
  40. package/dist-server/service/index.js +38 -0
  41. package/dist-server/service/index.js.map +1 -0
  42. package/dist-server/service/saas-access.d.ts +20 -0
  43. package/dist-server/service/saas-access.js +36 -0
  44. package/dist-server/service/saas-access.js.map +1 -0
  45. package/dist-server/service/saas-account.d.ts +43 -0
  46. package/dist-server/service/saas-account.js +166 -0
  47. package/dist-server/service/saas-account.js.map +1 -0
  48. package/dist-server/service/saas-bill.d.ts +41 -0
  49. package/dist-server/service/saas-bill.js +160 -0
  50. package/dist-server/service/saas-bill.js.map +1 -0
  51. package/dist-server/service/saas-mutation.d.ts +12 -0
  52. package/dist-server/service/saas-mutation.js +103 -0
  53. package/dist-server/service/saas-mutation.js.map +1 -0
  54. package/dist-server/service/saas-query.d.ts +69 -0
  55. package/dist-server/service/saas-query.js +215 -0
  56. package/dist-server/service/saas-query.js.map +1 -0
  57. package/dist-server/service/saas-rules.d.ts +138 -0
  58. package/dist-server/service/saas-rules.js +217 -0
  59. package/dist-server/service/saas-rules.js.map +1 -0
  60. package/dist-server/service/saas-seat.d.ts +25 -0
  61. package/dist-server/service/saas-seat.js +105 -0
  62. package/dist-server/service/saas-seat.js.map +1 -0
  63. package/dist-server/service/saas-service.d.ts +119 -0
  64. package/dist-server/service/saas-service.js +492 -0
  65. package/dist-server/service/saas-service.js.map +1 -0
  66. package/dist-server/service/saas-subscription.d.ts +44 -0
  67. package/dist-server/service/saas-subscription.js +174 -0
  68. package/dist-server/service/saas-subscription.js.map +1 -0
  69. package/dist-server/service/saas-trend-type.d.ts +9 -0
  70. package/dist-server/service/saas-trend-type.js +37 -0
  71. package/dist-server/service/saas-trend-type.js.map +1 -0
  72. package/dist-server/service/saas-type.d.ts +113 -0
  73. package/dist-server/service/saas-type.js +430 -0
  74. package/dist-server/service/saas-type.js.map +1 -0
  75. package/dist-server/tsconfig.tsbuildinfo +1 -0
  76. package/package.json +49 -4
  77. package/things-factory.config.js +13 -0
  78. package/translations/en.json +185 -0
  79. package/translations/es.json +185 -0
  80. package/translations/ja.json +185 -0
  81. package/translations/ko.json +185 -0
  82. package/translations/ms.json +185 -0
  83. package/translations/zh.json +185 -0
@@ -0,0 +1,160 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SaasBillLine = exports.SaasBill = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const auth_base_1 = require("@things-factory/auth-base");
6
+ const shell_1 = require("@things-factory/shell");
7
+ const type_graphql_1 = require("type-graphql");
8
+ const typeorm_1 = require("typeorm");
9
+ const saas_account_1 = require("./saas-account");
10
+ const saas_subscription_1 = require("./saas-subscription");
11
+ /**
12
+ * What an account was actually billed for a month (ADR-0177 decisions 5, 9) - one a month, in the account's currency,
13
+ * one line a subscription and lines on none for tax and credits. Its total is the sum of its lines; the cost trend is
14
+ * computed from these.
15
+ */
16
+ let SaasBill = class SaasBill {
17
+ };
18
+ exports.SaasBill = SaasBill;
19
+ tslib_1.__decorate([
20
+ (0, typeorm_1.PrimaryGeneratedColumn)('uuid'),
21
+ (0, type_graphql_1.Field)(type => type_graphql_1.ID, { description: 'Unique identifier of the bill' }),
22
+ tslib_1.__metadata("design:type", String)
23
+ ], SaasBill.prototype, "id", void 0);
24
+ tslib_1.__decorate([
25
+ (0, typeorm_1.ManyToOne)(type => shell_1.Domain),
26
+ (0, type_graphql_1.Field)(type => shell_1.Domain, { nullable: true, description: 'The domain the bill belongs to' }),
27
+ tslib_1.__metadata("design:type", shell_1.Domain)
28
+ ], SaasBill.prototype, "domain", void 0);
29
+ tslib_1.__decorate([
30
+ (0, typeorm_1.RelationId)((bill) => bill.domain),
31
+ tslib_1.__metadata("design:type", String)
32
+ ], SaasBill.prototype, "domainId", void 0);
33
+ tslib_1.__decorate([
34
+ (0, typeorm_1.ManyToOne)(type => saas_account_1.SaasAccount, { onDelete: 'CASCADE' }),
35
+ (0, type_graphql_1.Field)(type => saas_account_1.SaasAccount, { nullable: true, description: 'The account billed' }),
36
+ tslib_1.__metadata("design:type", saas_account_1.SaasAccount)
37
+ ], SaasBill.prototype, "account", void 0);
38
+ tslib_1.__decorate([
39
+ (0, typeorm_1.RelationId)((bill) => bill.account),
40
+ tslib_1.__metadata("design:type", String)
41
+ ], SaasBill.prototype, "accountId", void 0);
42
+ tslib_1.__decorate([
43
+ (0, typeorm_1.Column)(),
44
+ (0, type_graphql_1.Field)({ description: 'The month it bills - YYYY-MM' }),
45
+ tslib_1.__metadata("design:type", String)
46
+ ], SaasBill.prototype, "month", void 0);
47
+ tslib_1.__decorate([
48
+ (0, typeorm_1.Column)({ nullable: true }),
49
+ (0, type_graphql_1.Field)({ nullable: true, description: 'The day the vendor billed it - YYYY-MM-DD' }),
50
+ tslib_1.__metadata("design:type", String)
51
+ ], SaasBill.prototype, "billedOn", void 0);
52
+ tslib_1.__decorate([
53
+ (0, typeorm_1.Column)({ default: 'KRW' }),
54
+ (0, type_graphql_1.Field)({ description: 'The currency it is in - the account’s when it was written' }),
55
+ tslib_1.__metadata("design:type", String)
56
+ ], SaasBill.prototype, "currency", void 0);
57
+ tslib_1.__decorate([
58
+ (0, typeorm_1.OneToMany)(type => SaasBillLine, line => line.bill),
59
+ (0, type_graphql_1.Field)(type => [SaasBillLine], { nullable: true, description: 'One line a subscription, and lines on none - tax, credits' }),
60
+ tslib_1.__metadata("design:type", Array)
61
+ ], SaasBill.prototype, "lines", void 0);
62
+ tslib_1.__decorate([
63
+ (0, type_graphql_1.Field)(type => type_graphql_1.Float, { nullable: true, description: 'The sum of its lines - filled by the query' }),
64
+ tslib_1.__metadata("design:type", Number)
65
+ ], SaasBill.prototype, "total", void 0);
66
+ tslib_1.__decorate([
67
+ (0, typeorm_1.Column)({ type: 'text', nullable: true }),
68
+ (0, type_graphql_1.Field)({ nullable: true, description: 'Notes' }),
69
+ tslib_1.__metadata("design:type", String)
70
+ ], SaasBill.prototype, "description", void 0);
71
+ tslib_1.__decorate([
72
+ (0, typeorm_1.CreateDateColumn)(),
73
+ (0, type_graphql_1.Field)({ nullable: true, description: 'When the bill was written' }),
74
+ tslib_1.__metadata("design:type", Date)
75
+ ], SaasBill.prototype, "createdAt", void 0);
76
+ tslib_1.__decorate([
77
+ (0, typeorm_1.UpdateDateColumn)(),
78
+ (0, type_graphql_1.Field)({ nullable: true, description: 'When the bill last changed' }),
79
+ tslib_1.__metadata("design:type", Date)
80
+ ], SaasBill.prototype, "updatedAt", void 0);
81
+ tslib_1.__decorate([
82
+ (0, typeorm_1.DeleteDateColumn)(),
83
+ (0, type_graphql_1.Field)({ nullable: true, description: 'When the bill was deleted' }),
84
+ tslib_1.__metadata("design:type", Date)
85
+ ], SaasBill.prototype, "deletedAt", void 0);
86
+ tslib_1.__decorate([
87
+ (0, typeorm_1.ManyToOne)(type => auth_base_1.User, { nullable: true }),
88
+ (0, type_graphql_1.Field)(type => auth_base_1.User, { nullable: true, description: 'Who wrote it' }),
89
+ tslib_1.__metadata("design:type", auth_base_1.User)
90
+ ], SaasBill.prototype, "creator", void 0);
91
+ tslib_1.__decorate([
92
+ (0, typeorm_1.RelationId)((bill) => bill.creator),
93
+ tslib_1.__metadata("design:type", String)
94
+ ], SaasBill.prototype, "creatorId", void 0);
95
+ tslib_1.__decorate([
96
+ (0, typeorm_1.ManyToOne)(type => auth_base_1.User, { nullable: true }),
97
+ (0, type_graphql_1.Field)(type => auth_base_1.User, { nullable: true, description: 'Who last changed it' }),
98
+ tslib_1.__metadata("design:type", auth_base_1.User)
99
+ ], SaasBill.prototype, "updater", void 0);
100
+ tslib_1.__decorate([
101
+ (0, typeorm_1.RelationId)((bill) => bill.updater),
102
+ tslib_1.__metadata("design:type", String)
103
+ ], SaasBill.prototype, "updaterId", void 0);
104
+ exports.SaasBill = SaasBill = tslib_1.__decorate([
105
+ (0, typeorm_1.Entity)(),
106
+ (0, typeorm_1.Index)('ix_saas_bill_0', (bill) => [bill.domain, bill.account, bill.month]),
107
+ (0, type_graphql_1.ObjectType)({ description: 'Entity for SaasBill — what an account was billed for a month' })
108
+ ], SaasBill);
109
+ /** One line of a bill - what one subscription cost that month, or tax and credits on none. */
110
+ let SaasBillLine = class SaasBillLine {
111
+ };
112
+ exports.SaasBillLine = SaasBillLine;
113
+ tslib_1.__decorate([
114
+ (0, typeorm_1.PrimaryGeneratedColumn)('uuid'),
115
+ (0, type_graphql_1.Field)(type => type_graphql_1.ID, { description: 'Unique identifier of the line' }),
116
+ tslib_1.__metadata("design:type", String)
117
+ ], SaasBillLine.prototype, "id", void 0);
118
+ tslib_1.__decorate([
119
+ (0, typeorm_1.ManyToOne)(type => shell_1.Domain),
120
+ (0, type_graphql_1.Field)(type => shell_1.Domain, { nullable: true, description: 'The domain the line belongs to' }),
121
+ tslib_1.__metadata("design:type", shell_1.Domain)
122
+ ], SaasBillLine.prototype, "domain", void 0);
123
+ tslib_1.__decorate([
124
+ (0, typeorm_1.RelationId)((line) => line.domain),
125
+ tslib_1.__metadata("design:type", String)
126
+ ], SaasBillLine.prototype, "domainId", void 0);
127
+ tslib_1.__decorate([
128
+ (0, typeorm_1.ManyToOne)(type => SaasBill, bill => bill.lines, { onDelete: 'CASCADE' }),
129
+ (0, type_graphql_1.Field)(type => SaasBill, { nullable: true, description: 'The bill it is a line of' }),
130
+ tslib_1.__metadata("design:type", SaasBill)
131
+ ], SaasBillLine.prototype, "bill", void 0);
132
+ tslib_1.__decorate([
133
+ (0, typeorm_1.RelationId)((line) => line.bill),
134
+ tslib_1.__metadata("design:type", String)
135
+ ], SaasBillLine.prototype, "billId", void 0);
136
+ tslib_1.__decorate([
137
+ (0, typeorm_1.ManyToOne)(type => saas_subscription_1.SaasSubscription, { nullable: true, onDelete: 'SET NULL' }),
138
+ (0, type_graphql_1.Field)(type => saas_subscription_1.SaasSubscription, { nullable: true, description: 'The subscription it is for; none for tax and credits' }),
139
+ tslib_1.__metadata("design:type", saas_subscription_1.SaasSubscription)
140
+ ], SaasBillLine.prototype, "subscription", void 0);
141
+ tslib_1.__decorate([
142
+ (0, typeorm_1.RelationId)((line) => line.subscription),
143
+ tslib_1.__metadata("design:type", String)
144
+ ], SaasBillLine.prototype, "subscriptionId", void 0);
145
+ tslib_1.__decorate([
146
+ (0, typeorm_1.Column)({ nullable: true }),
147
+ (0, type_graphql_1.Field)({ nullable: true, description: 'What the bill calls it - tax, a credit, a support fee' }),
148
+ tslib_1.__metadata("design:type", String)
149
+ ], SaasBillLine.prototype, "label", void 0);
150
+ tslib_1.__decorate([
151
+ (0, typeorm_1.Column)((0, shell_1.moneyColumn)()),
152
+ (0, type_graphql_1.Field)(type => type_graphql_1.Float, { description: 'What it cost; a credit is below zero' }),
153
+ tslib_1.__metadata("design:type", Number)
154
+ ], SaasBillLine.prototype, "amount", void 0);
155
+ exports.SaasBillLine = SaasBillLine = tslib_1.__decorate([
156
+ (0, typeorm_1.Entity)(),
157
+ (0, typeorm_1.Index)('ix_saas_bill_line_0', (line) => [line.domain, line.bill]),
158
+ (0, type_graphql_1.ObjectType)({ description: 'Entity for SaasBillLine — what one subscription cost in a bill, or tax and credits' })
159
+ ], SaasBillLine);
160
+ //# sourceMappingURL=saas-bill.js.map
@@ -0,0 +1 @@
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 @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"]}
@@ -0,0 +1,12 @@
1
+ import { SaasAccount } from './saas-account';
2
+ import { SaasBill } from './saas-bill';
3
+ import { SaasSeat } from './saas-seat';
4
+ import { SaasSubscription } from './saas-subscription';
5
+ import { SaasAccountPatch, SaasBillInput, SaasSeatPatch, SaasSubscriptionPatch } from './saas-type';
6
+ export declare class SaasMutation {
7
+ updateMultipleSaasAccount(patches: SaasAccountPatch[], context: ResolverContext): Promise<SaasAccount[]>;
8
+ updateMultipleSaasSubscription(accountId: string, patches: SaasSubscriptionPatch[], context: ResolverContext): Promise<SaasSubscription[]>;
9
+ updateMultipleSaasSeat(subscriptionId: string, patches: SaasSeatPatch[], context: ResolverContext): Promise<SaasSeat[]>;
10
+ saveSaasBill(accountId: string, bill: SaasBillInput, context: ResolverContext): Promise<SaasBill>;
11
+ deleteSaasBill(id: string, context: ResolverContext): Promise<boolean>;
12
+ }
@@ -0,0 +1,103 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SaasMutation = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const shell_1 = require("@things-factory/shell");
6
+ const type_graphql_1 = require("type-graphql");
7
+ const saas_access_1 = require("./saas-access");
8
+ const saas_account_1 = require("./saas-account");
9
+ const saas_bill_1 = require("./saas-bill");
10
+ const saas_service_1 = require("./saas-service");
11
+ const saas_seat_1 = require("./saas-seat");
12
+ const saas_subscription_1 = require("./saas-subscription");
13
+ const saas_type_1 = require("./saas-type");
14
+ /*
15
+ * The accounts are the keepers'. What is under an account - its subscriptions, their seats, its bills - is also its
16
+ * admins', whatever their seat (ADR-0177 Q4): those doors ask `saas-self`, and the service keeps an admin to their own.
17
+ */
18
+ let SaasMutation = class SaasMutation {
19
+ updateMultipleSaasAccount(patches, context) {
20
+ const { tx, domain, user } = context.state;
21
+ return (0, saas_service_1.saveSaasAccounts)(tx, domain, user, patches);
22
+ }
23
+ async updateMultipleSaasSubscription(accountId, patches, context) {
24
+ const { tx, domain, user } = context.state;
25
+ return (0, saas_service_1.saveSaasSubscriptions)(tx, domain, user, await (0, saas_access_1.scopeOf)(context.state, 'mutation', tx), accountId, patches);
26
+ }
27
+ async updateMultipleSaasSeat(subscriptionId, patches, context) {
28
+ const { tx, domain, user } = context.state;
29
+ return (0, saas_service_1.saveSaasSeats)(tx, domain, user, await (0, saas_access_1.scopeOf)(context.state, 'mutation', tx), subscriptionId, patches);
30
+ }
31
+ async saveSaasBill(accountId, bill, context) {
32
+ const { tx, domain, user } = context.state;
33
+ return (0, saas_service_1.saveSaasBill)(tx, domain, user, await (0, saas_access_1.scopeOf)(context.state, 'mutation', tx), accountId, bill);
34
+ }
35
+ async deleteSaasBill(id, context) {
36
+ const { tx, domain } = context.state;
37
+ return (0, saas_service_1.deleteSaasBill)(tx, domain, await (0, saas_access_1.scopeOf)(context.state, 'mutation', tx), id);
38
+ }
39
+ };
40
+ exports.SaasMutation = SaasMutation;
41
+ tslib_1.__decorate([
42
+ (0, type_graphql_1.Directive)('@transaction'),
43
+ (0, type_graphql_1.Directive)('@privilege(category: "saas", privilege: "mutation", domainOwnerGranted: true)'),
44
+ (0, type_graphql_1.Directive)('@auditTarget(kind: "SaasAccount", arg: "patches")'),
45
+ (0, type_graphql_1.Mutation)(type => [saas_account_1.SaasAccount], { description: 'To save the accounts grid - new, changed and deleted rows together' }),
46
+ tslib_1.__param(0, (0, type_graphql_1.Arg)('patches', type => [saas_type_1.SaasAccountPatch])),
47
+ tslib_1.__param(1, (0, type_graphql_1.Ctx)()),
48
+ tslib_1.__metadata("design:type", Function),
49
+ tslib_1.__metadata("design:paramtypes", [Array, Object]),
50
+ tslib_1.__metadata("design:returntype", void 0)
51
+ ], SaasMutation.prototype, "updateMultipleSaasAccount", null);
52
+ tslib_1.__decorate([
53
+ (0, type_graphql_1.Directive)('@transaction'),
54
+ (0, type_graphql_1.Directive)('@privilege(category: "saas-self", privilege: "mutation", domainOwnerGranted: true)'),
55
+ (0, type_graphql_1.Directive)('@auditTarget(kind: "SaasAccount", arg: "accountId")'),
56
+ (0, type_graphql_1.Mutation)(type => [saas_subscription_1.SaasSubscription], { description: "To save an account's subscriptions grid" }),
57
+ tslib_1.__param(0, (0, type_graphql_1.Arg)('accountId')),
58
+ tslib_1.__param(1, (0, type_graphql_1.Arg)('patches', type => [saas_type_1.SaasSubscriptionPatch])),
59
+ tslib_1.__param(2, (0, type_graphql_1.Ctx)()),
60
+ tslib_1.__metadata("design:type", Function),
61
+ tslib_1.__metadata("design:paramtypes", [String, Array, Object]),
62
+ tslib_1.__metadata("design:returntype", Promise)
63
+ ], SaasMutation.prototype, "updateMultipleSaasSubscription", null);
64
+ tslib_1.__decorate([
65
+ (0, type_graphql_1.Directive)('@transaction'),
66
+ (0, type_graphql_1.Directive)('@privilege(category: "saas-self", privilege: "mutation", domainOwnerGranted: true)'),
67
+ (0, type_graphql_1.Directive)('@auditTarget(kind: "SaasSubscription", arg: "subscriptionId")'),
68
+ (0, type_graphql_1.Mutation)(type => [saas_seat_1.SaasSeat], { description: "To save a subscription's seats grid" }),
69
+ tslib_1.__param(0, (0, type_graphql_1.Arg)('subscriptionId')),
70
+ tslib_1.__param(1, (0, type_graphql_1.Arg)('patches', type => [saas_type_1.SaasSeatPatch])),
71
+ tslib_1.__param(2, (0, type_graphql_1.Ctx)()),
72
+ tslib_1.__metadata("design:type", Function),
73
+ tslib_1.__metadata("design:paramtypes", [String, Array, Object]),
74
+ tslib_1.__metadata("design:returntype", Promise)
75
+ ], SaasMutation.prototype, "updateMultipleSaasSeat", null);
76
+ tslib_1.__decorate([
77
+ (0, type_graphql_1.Directive)('@transaction'),
78
+ (0, type_graphql_1.Directive)('@privilege(category: "saas-self", privilege: "mutation", domainOwnerGranted: true)'),
79
+ (0, type_graphql_1.Directive)('@auditTarget(kind: "SaasAccount", arg: "accountId")'),
80
+ (0, type_graphql_1.Mutation)(type => saas_bill_1.SaasBill, { description: "To write an account's bill for a month, its lines whole" }),
81
+ tslib_1.__param(0, (0, type_graphql_1.Arg)('accountId')),
82
+ tslib_1.__param(1, (0, type_graphql_1.Arg)('bill', type => saas_type_1.SaasBillInput)),
83
+ tslib_1.__param(2, (0, type_graphql_1.Ctx)()),
84
+ tslib_1.__metadata("design:type", Function),
85
+ tslib_1.__metadata("design:paramtypes", [String, saas_type_1.SaasBillInput, Object]),
86
+ tslib_1.__metadata("design:returntype", Promise)
87
+ ], SaasMutation.prototype, "saveSaasBill", null);
88
+ tslib_1.__decorate([
89
+ (0, type_graphql_1.Directive)('@transaction'),
90
+ (0, type_graphql_1.Directive)('@privilege(category: "saas-self", privilege: "mutation", domainOwnerGranted: true)'),
91
+ (0, type_graphql_1.Directive)('@auditTarget(kind: "SaasBill", arg: "id")'),
92
+ (0, type_graphql_1.Mutation)(type => Boolean, { description: 'To delete a bill' }),
93
+ tslib_1.__param(0, (0, type_graphql_1.Arg)('id')),
94
+ tslib_1.__param(1, (0, type_graphql_1.Ctx)()),
95
+ tslib_1.__metadata("design:type", Function),
96
+ tslib_1.__metadata("design:paramtypes", [String, Object]),
97
+ tslib_1.__metadata("design:returntype", Promise)
98
+ ], SaasMutation.prototype, "deleteSaasBill", null);
99
+ exports.SaasMutation = SaasMutation = tslib_1.__decorate([
100
+ (0, type_graphql_1.UseMiddleware)(shell_1.SpeakRefusals),
101
+ (0, type_graphql_1.Resolver)(saas_account_1.SaasAccount)
102
+ ], SaasMutation);
103
+ //# sourceMappingURL=saas-mutation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"saas-mutation.js","sourceRoot":"","sources":["../../server/service/saas-mutation.ts"],"names":[],"mappings":"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","sourcesContent":["import { 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 { deleteSaasBill, saveSaasAccounts, saveSaasBill, saveSaasSeats, saveSaasSubscriptions } from './saas-service'\nimport { SaasSeat } from './saas-seat'\nimport { SaasSubscription } from './saas-subscription'\nimport { SaasAccountPatch, SaasBillInput, SaasSeatPatch, SaasSubscriptionPatch } from './saas-type'\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 @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 @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"]}
@@ -0,0 +1,69 @@
1
+ import { BankAccount, Transaction } from '@things-factory/accounting';
2
+ import { User } from '@things-factory/auth-base';
3
+ import { Counterparty } from '@things-factory/biz-base';
4
+ import { Domain, ListParam } from '@things-factory/shell';
5
+ import { SaasAccount } from './saas-account';
6
+ import { SaasBill } from './saas-bill';
7
+ import { SaasSeat } from './saas-seat';
8
+ import { SaasSubscription } from './saas-subscription';
9
+ import { SaasAccountList, SaasChange } from './saas-type';
10
+ export declare class SaasAccountQuery {
11
+ saasAccounts(params: ListParam, context: ResolverContext): Promise<SaasAccountList>;
12
+ mySaasAccounts(context: ResolverContext): Promise<SaasAccount[]>;
13
+ saasAccount(id: string, context: ResolverContext): Promise<SaasAccount>;
14
+ saasSubscriptions(accountId: string, context: ResolverContext): Promise<SaasSubscription[]>;
15
+ saasSeats(subscriptionId: string, context: ResolverContext): Promise<SaasSeat[]>;
16
+ saasBills(accountId: string, context: ResolverContext): Promise<SaasBill[]>;
17
+ saasChanges(accountId: string, context: ResolverContext): Promise<SaasChange[]>;
18
+ saasPayments(accountId: string, context: ResolverContext): Promise<Transaction[]>;
19
+ saasCostTrend(from: string, to: string, context: ResolverContext): Promise<{
20
+ months: string[];
21
+ all: import("./saas-rules").TrendSeries[];
22
+ accounts: {
23
+ name: string;
24
+ key: string;
25
+ accountId?: string | null;
26
+ subscriptionId?: string | null;
27
+ currency: string;
28
+ amounts: number[];
29
+ total: number;
30
+ monthOverMonth: number | null;
31
+ yearOverYear: number | null;
32
+ }[];
33
+ subscriptions: {
34
+ name: string;
35
+ accountName: string;
36
+ key: string;
37
+ accountId?: string | null;
38
+ subscriptionId?: string | null;
39
+ currency: string;
40
+ amounts: number[];
41
+ total: number;
42
+ monthOverMonth: number | null;
43
+ yearOverYear: number | null;
44
+ }[];
45
+ departments: {
46
+ total: number;
47
+ key: string;
48
+ departmentId: string | null;
49
+ name: string | null;
50
+ currency: string;
51
+ amounts: number[];
52
+ }[];
53
+ alerts: {
54
+ accountName: string;
55
+ subscriptionName: string;
56
+ accountId: string;
57
+ month: string;
58
+ kind: import("./saas-rules").SaasAlertKind;
59
+ subscriptionId?: string;
60
+ amount: number;
61
+ limit: number;
62
+ }[];
63
+ }>;
64
+ counterparty(row: SaasAccount): Counterparty | Promise<Counterparty>;
65
+ parent(row: SaasAccount): SaasAccount | Promise<SaasAccount>;
66
+ paymentAccount(row: SaasAccount): BankAccount | Promise<BankAccount>;
67
+ domain(row: SaasAccount): Domain | Promise<Domain>;
68
+ updater(row: SaasAccount): User | Promise<User>;
69
+ }
@@ -0,0 +1,215 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SaasAccountQuery = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const accounting_1 = require("@things-factory/accounting");
6
+ const auth_base_1 = require("@things-factory/auth-base");
7
+ const biz_base_1 = require("@things-factory/biz-base");
8
+ const shell_1 = require("@things-factory/shell");
9
+ const type_graphql_1 = require("type-graphql");
10
+ const typeorm_1 = require("typeorm");
11
+ const saas_access_1 = require("./saas-access");
12
+ const saas_account_1 = require("./saas-account");
13
+ const saas_bill_1 = require("./saas-bill");
14
+ const saas_service_1 = require("./saas-service");
15
+ const saas_seat_1 = require("./saas-seat");
16
+ const saas_subscription_1 = require("./saas-subscription");
17
+ const saas_type_1 = require("./saas-type");
18
+ const today = () => new Date().toISOString().slice(0, 10);
19
+ /** The accounts with their admins and their months (decision 10) - the list's relations in one read each. */
20
+ async function withAdmins(tx, state, items) {
21
+ if (!items.length)
22
+ return items;
23
+ const { domain, user, unsafeIP, prohibitedPrivileges } = state;
24
+ const rows = await tx.getRepository(saas_account_1.SaasAccount).find({ where: { id: (0, typeorm_1.In)(items.map(one => one.id)) }, relations: ['admins'] });
25
+ /* What left the bank is the bank's fact (ADR-0139) - read into the months only for whoever reads bank lines. */
26
+ const withBank = await (0, auth_base_1.checkPermission)({ category: 'bank', privilege: 'query', owner: false }, user, domain, unsafeIP, prohibitedPrivileges);
27
+ const trends = await (0, saas_service_1.saasTrendsOf)(tx, domain, items, today(), withBank);
28
+ for (const one of items) {
29
+ one.admins = rows.find(row => row.id === one.id)?.admins ?? [];
30
+ one.trend = trends.get(one.id);
31
+ }
32
+ return items;
33
+ }
34
+ let SaasAccountQuery = class SaasAccountQuery {
35
+ async saasAccounts(params, context) {
36
+ const query = (0, shell_1.getQueryBuilderFromListParams)({ domain: context.state.domain, params, repository: (0, shell_1.getRepository)(saas_account_1.SaasAccount), searchables: ['name', 'identifier', 'purpose', 'billingEmail', 'description'] });
37
+ const [items, total] = await query.getManyAndCount();
38
+ return { items: await withAdmins((0, shell_1.getRepository)(saas_account_1.SaasAccount).manager, context.state, items), total };
39
+ }
40
+ async mySaasAccounts(context) {
41
+ const { domain, user } = context.state;
42
+ const manager = (0, shell_1.getRepository)(saas_account_1.SaasAccount).manager;
43
+ const ids = await (0, saas_access_1.administeredBy)(manager, domain, user?.id);
44
+ if (!ids.length)
45
+ return [];
46
+ return withAdmins(manager, context.state, await (0, shell_1.getRepository)(saas_account_1.SaasAccount).find({ where: { domain: { id: domain.id }, id: (0, typeorm_1.In)(ids) }, order: { name: 'ASC' } }));
47
+ }
48
+ async saasAccount(id, context) {
49
+ const manager = (0, shell_1.getRepository)(saas_account_1.SaasAccount).manager;
50
+ const account = await (0, saas_access_1.accountIn)(manager, context.state.domain, await (0, saas_access_1.scopeOf)(context.state, 'query', manager), id);
51
+ return (await withAdmins(manager, context.state, [account]))[0];
52
+ }
53
+ async saasSubscriptions(accountId, context) {
54
+ const manager = (0, shell_1.getRepository)(saas_account_1.SaasAccount).manager;
55
+ return (0, saas_service_1.saasSubscriptionsOf)(manager, context.state.domain, await (0, saas_access_1.scopeOf)(context.state, 'query', manager), accountId, today());
56
+ }
57
+ async saasSeats(subscriptionId, context) {
58
+ const manager = (0, shell_1.getRepository)(saas_account_1.SaasAccount).manager;
59
+ return (0, saas_service_1.saasSeatsOf)(manager, context.state.domain, await (0, saas_access_1.scopeOf)(context.state, 'query', manager), subscriptionId);
60
+ }
61
+ async saasBills(accountId, context) {
62
+ const manager = (0, shell_1.getRepository)(saas_account_1.SaasAccount).manager;
63
+ return (0, saas_service_1.saasBillsOf)(manager, context.state.domain, await (0, saas_access_1.scopeOf)(context.state, 'query', manager), accountId);
64
+ }
65
+ async saasChanges(accountId, context) {
66
+ const manager = (0, shell_1.getRepository)(saas_account_1.SaasAccount).manager;
67
+ const rows = await (0, saas_service_1.saasChangesOf)(manager, context.state.domain, await (0, saas_access_1.scopeOf)(context.state, 'query', manager), accountId);
68
+ return rows.map((one) => ({ subject: one.subject, factKind: one.factKind, field: one.field, fromValue: one.fromValue, toValue: one.toValue, at: one.at, changedBy: one.changedBy?.name }));
69
+ }
70
+ /* The bank lines are the bank's facts (ADR-0139): this door asks the bank's privilege, the account's scope on top. */
71
+ async saasPayments(accountId, context) {
72
+ const manager = (0, shell_1.getRepository)(saas_account_1.SaasAccount).manager;
73
+ return (0, saas_service_1.saasPaymentsOf)(manager, context.state.domain, await (0, saas_access_1.scopeOf)(context.state, 'query', manager), accountId);
74
+ }
75
+ saasCostTrend(from, to, context) {
76
+ return (0, saas_service_1.saasCostTrend)((0, shell_1.getRepository)(saas_account_1.SaasAccount).manager, context.state.domain, from, to);
77
+ }
78
+ counterparty(row) {
79
+ return row.counterparty ?? (row.counterpartyId ? (0, shell_1.getRepository)(biz_base_1.Counterparty).findOneBy({ id: row.counterpartyId }) : undefined);
80
+ }
81
+ parent(row) {
82
+ return row.parent ?? (row.parentId ? (0, shell_1.getRepository)(saas_account_1.SaasAccount).findOneBy({ id: row.parentId }) : undefined);
83
+ }
84
+ paymentAccount(row) {
85
+ return row.paymentAccount ?? (row.paymentAccountId ? (0, shell_1.getRepository)(accounting_1.BankAccount).findOneBy({ id: row.paymentAccountId }) : undefined);
86
+ }
87
+ domain(row) {
88
+ return row.domain ?? (row.domainId ? (0, shell_1.getRepository)(shell_1.Domain).findOneBy({ id: row.domainId }) : undefined);
89
+ }
90
+ updater(row) {
91
+ return row.updater ?? (row.updaterId ? (0, shell_1.getRepository)(auth_base_1.User).findOneBy({ id: row.updaterId }) : undefined);
92
+ }
93
+ };
94
+ exports.SaasAccountQuery = SaasAccountQuery;
95
+ tslib_1.__decorate([
96
+ (0, type_graphql_1.Directive)('@privilege(category: "saas", privilege: "query", domainOwnerGranted: true)'),
97
+ (0, type_graphql_1.Query)(type => saas_type_1.SaasAccountList, { description: 'To fetch a page of the accounts the domain holds with vendors' }),
98
+ tslib_1.__param(0, (0, type_graphql_1.Args)(type => shell_1.ListParam)),
99
+ tslib_1.__param(1, (0, type_graphql_1.Ctx)()),
100
+ tslib_1.__metadata("design:type", Function),
101
+ tslib_1.__metadata("design:paramtypes", [shell_1.ListParam, Object]),
102
+ tslib_1.__metadata("design:returntype", Promise)
103
+ ], SaasAccountQuery.prototype, "saasAccounts", null);
104
+ tslib_1.__decorate([
105
+ (0, type_graphql_1.Directive)('@privilege(category: "saas-self", privilege: "query", domainOwnerGranted: true)'),
106
+ (0, type_graphql_1.Query)(type => [saas_account_1.SaasAccount], { description: 'The accounts the signed-in person is named an admin of' }),
107
+ tslib_1.__param(0, (0, type_graphql_1.Ctx)()),
108
+ tslib_1.__metadata("design:type", Function),
109
+ tslib_1.__metadata("design:paramtypes", [Object]),
110
+ tslib_1.__metadata("design:returntype", Promise)
111
+ ], SaasAccountQuery.prototype, "mySaasAccounts", null);
112
+ tslib_1.__decorate([
113
+ (0, type_graphql_1.Directive)('@privilege(category: "saas-self", privilege: "query", domainOwnerGranted: true)'),
114
+ (0, type_graphql_1.Query)(type => saas_account_1.SaasAccount, { description: 'To fetch an account - a reader’s any, an admin’s own' }),
115
+ tslib_1.__param(0, (0, type_graphql_1.Arg)('id')),
116
+ tslib_1.__param(1, (0, type_graphql_1.Ctx)()),
117
+ tslib_1.__metadata("design:type", Function),
118
+ tslib_1.__metadata("design:paramtypes", [String, Object]),
119
+ tslib_1.__metadata("design:returntype", Promise)
120
+ ], SaasAccountQuery.prototype, "saasAccount", null);
121
+ tslib_1.__decorate([
122
+ (0, type_graphql_1.Directive)('@privilege(category: "saas-self", privilege: "query", domainOwnerGranted: true)'),
123
+ (0, type_graphql_1.Query)(type => [saas_subscription_1.SaasSubscription], { description: 'The subscriptions of an account, with the seats held today' }),
124
+ tslib_1.__param(0, (0, type_graphql_1.Arg)('accountId')),
125
+ tslib_1.__param(1, (0, type_graphql_1.Ctx)()),
126
+ tslib_1.__metadata("design:type", Function),
127
+ tslib_1.__metadata("design:paramtypes", [String, Object]),
128
+ tslib_1.__metadata("design:returntype", Promise)
129
+ ], SaasAccountQuery.prototype, "saasSubscriptions", null);
130
+ tslib_1.__decorate([
131
+ (0, type_graphql_1.Directive)('@privilege(category: "saas-self", privilege: "query", domainOwnerGranted: true)'),
132
+ (0, type_graphql_1.Query)(type => [saas_seat_1.SaasSeat], { description: 'The seats of a subscription' }),
133
+ tslib_1.__param(0, (0, type_graphql_1.Arg)('subscriptionId')),
134
+ tslib_1.__param(1, (0, type_graphql_1.Ctx)()),
135
+ tslib_1.__metadata("design:type", Function),
136
+ tslib_1.__metadata("design:paramtypes", [String, Object]),
137
+ tslib_1.__metadata("design:returntype", Promise)
138
+ ], SaasAccountQuery.prototype, "saasSeats", null);
139
+ tslib_1.__decorate([
140
+ (0, type_graphql_1.Directive)('@privilege(category: "saas-self", privilege: "query", domainOwnerGranted: true)'),
141
+ (0, type_graphql_1.Query)(type => [saas_bill_1.SaasBill], { description: 'The bills of an account, latest first, with their lines' }),
142
+ tslib_1.__param(0, (0, type_graphql_1.Arg)('accountId')),
143
+ tslib_1.__param(1, (0, type_graphql_1.Ctx)()),
144
+ tslib_1.__metadata("design:type", Function),
145
+ tslib_1.__metadata("design:paramtypes", [String, Object]),
146
+ tslib_1.__metadata("design:returntype", Promise)
147
+ ], SaasAccountQuery.prototype, "saasBills", null);
148
+ tslib_1.__decorate([
149
+ (0, type_graphql_1.Directive)('@privilege(category: "saas-self", privilege: "query", domainOwnerGranted: true)'),
150
+ (0, type_graphql_1.Query)(type => [saas_type_1.SaasChange], { description: 'What moved on an account and its subscriptions, newest first' }),
151
+ tslib_1.__param(0, (0, type_graphql_1.Arg)('accountId')),
152
+ tslib_1.__param(1, (0, type_graphql_1.Ctx)()),
153
+ tslib_1.__metadata("design:type", Function),
154
+ tslib_1.__metadata("design:paramtypes", [String, Object]),
155
+ tslib_1.__metadata("design:returntype", Promise)
156
+ ], SaasAccountQuery.prototype, "saasChanges", null);
157
+ tslib_1.__decorate([
158
+ (0, type_graphql_1.Directive)('@privilege(category: "bank", privilege: "query", domainOwnerGranted: false)'),
159
+ (0, type_graphql_1.Query)(type => [accounting_1.Transaction], { description: "The bank lines that paid an account's vendor, newest first" }),
160
+ tslib_1.__param(0, (0, type_graphql_1.Arg)('accountId')),
161
+ tslib_1.__param(1, (0, type_graphql_1.Ctx)()),
162
+ tslib_1.__metadata("design:type", Function),
163
+ tslib_1.__metadata("design:paramtypes", [String, Object]),
164
+ tslib_1.__metadata("design:returntype", Promise)
165
+ ], SaasAccountQuery.prototype, "saasPayments", null);
166
+ tslib_1.__decorate([
167
+ (0, type_graphql_1.Directive)('@privilege(category: "saas", privilege: "query", domainOwnerGranted: true)'),
168
+ (0, type_graphql_1.Query)(type => saas_type_1.SaasCostTrend, { description: 'The cost trend from the bills, month by month from one month to another (YYYY-MM)' }),
169
+ tslib_1.__param(0, (0, type_graphql_1.Arg)('from')),
170
+ tslib_1.__param(1, (0, type_graphql_1.Arg)('to')),
171
+ tslib_1.__param(2, (0, type_graphql_1.Ctx)()),
172
+ tslib_1.__metadata("design:type", Function),
173
+ tslib_1.__metadata("design:paramtypes", [String, String, Object]),
174
+ tslib_1.__metadata("design:returntype", void 0)
175
+ ], SaasAccountQuery.prototype, "saasCostTrend", null);
176
+ tslib_1.__decorate([
177
+ (0, type_graphql_1.FieldResolver)(type => biz_base_1.Counterparty, { nullable: true }),
178
+ tslib_1.__param(0, (0, type_graphql_1.Root)()),
179
+ tslib_1.__metadata("design:type", Function),
180
+ tslib_1.__metadata("design:paramtypes", [saas_account_1.SaasAccount]),
181
+ tslib_1.__metadata("design:returntype", void 0)
182
+ ], SaasAccountQuery.prototype, "counterparty", null);
183
+ tslib_1.__decorate([
184
+ (0, type_graphql_1.FieldResolver)(type => saas_account_1.SaasAccount, { nullable: true }),
185
+ tslib_1.__param(0, (0, type_graphql_1.Root)()),
186
+ tslib_1.__metadata("design:type", Function),
187
+ tslib_1.__metadata("design:paramtypes", [saas_account_1.SaasAccount]),
188
+ tslib_1.__metadata("design:returntype", void 0)
189
+ ], SaasAccountQuery.prototype, "parent", null);
190
+ tslib_1.__decorate([
191
+ (0, type_graphql_1.FieldResolver)(type => accounting_1.BankAccount, { nullable: true }),
192
+ tslib_1.__param(0, (0, type_graphql_1.Root)()),
193
+ tslib_1.__metadata("design:type", Function),
194
+ tslib_1.__metadata("design:paramtypes", [saas_account_1.SaasAccount]),
195
+ tslib_1.__metadata("design:returntype", void 0)
196
+ ], SaasAccountQuery.prototype, "paymentAccount", null);
197
+ tslib_1.__decorate([
198
+ (0, type_graphql_1.FieldResolver)(type => shell_1.Domain, { nullable: true }),
199
+ tslib_1.__param(0, (0, type_graphql_1.Root)()),
200
+ tslib_1.__metadata("design:type", Function),
201
+ tslib_1.__metadata("design:paramtypes", [saas_account_1.SaasAccount]),
202
+ tslib_1.__metadata("design:returntype", void 0)
203
+ ], SaasAccountQuery.prototype, "domain", null);
204
+ tslib_1.__decorate([
205
+ (0, type_graphql_1.FieldResolver)(type => auth_base_1.User, { nullable: true }),
206
+ tslib_1.__param(0, (0, type_graphql_1.Root)()),
207
+ tslib_1.__metadata("design:type", Function),
208
+ tslib_1.__metadata("design:paramtypes", [saas_account_1.SaasAccount]),
209
+ tslib_1.__metadata("design:returntype", void 0)
210
+ ], SaasAccountQuery.prototype, "updater", null);
211
+ exports.SaasAccountQuery = SaasAccountQuery = tslib_1.__decorate([
212
+ (0, type_graphql_1.UseMiddleware)(shell_1.SpeakRefusals),
213
+ (0, type_graphql_1.Resolver)(saas_account_1.SaasAccount)
214
+ ], SaasAccountQuery);
215
+ //# sourceMappingURL=saas-query.js.map