Skip to content

Commit 0c7b46d

Browse files
committed
add fields to Partner
1 parent ff451d8 commit 0c7b46d

File tree

7 files changed

+118
-0
lines changed

7 files changed

+118
-0
lines changed

src/components/partner/dto/create-partner.dto.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,14 @@ export abstract class CreatePartner {
5050
@IdField({ nullable: true })
5151
readonly languageOfWiderCommunicationId?: ID<'Language'> | null;
5252

53+
@IdField({ nullable: true })
54+
readonly parentId?: ID<'Partner'> | null;
55+
56+
@Field(() => [IDType], { nullable: true })
57+
@IsId({ each: true })
58+
@Transform(({ value }) => uniq(value))
59+
readonly strategicAlliances?: ReadonlyArray<ID<'Partner'>> = [];
60+
5361
@Field(() => [IDType], { nullable: true })
5462
@IsId({ each: true })
5563
@Transform(({ value }) => uniq(value))

src/components/partner/dto/partner.dto.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
SecuredBoolean,
1010
SecuredDateNullable,
1111
SecuredProperty,
12+
SecuredPropertyList,
1213
SecuredStringNullable,
1314
Sensitivity,
1415
SensitivityField,
@@ -66,6 +67,9 @@ export class Partner extends Interfaces {
6667
>;
6768

6869
readonly countries: Required<Secured<ReadonlyArray<LinkTo<'Location'>>>>;
70+
readonly strategicAlliances: Required<
71+
Secured<ReadonlyArray<LinkTo<'Partner'>>>
72+
>;
6973

7074
readonly languagesOfConsulting: Required<
7175
Secured<ReadonlyArray<LinkTo<'Language'>>>
@@ -87,13 +91,20 @@ export class Partner extends Interfaces {
8791

8892
@Field()
8993
readonly departmentIdBlock: SecuredFinanceDepartmentIdBlockNullable;
94+
95+
readonly parent: Secured<LinkTo<'Partner'> | null>;
9096
}
9197

9298
@ObjectType({
9399
description: SecuredProperty.descriptionFor('a partner'),
94100
})
95101
export class SecuredPartner extends SecuredProperty(Partner) {}
96102

103+
@ObjectType({
104+
description: SecuredPropertyList.descriptionFor('a list of partners'),
105+
})
106+
export class SecuredPartners extends SecuredPropertyList(Partner) {}
107+
97108
declare module '~/core/resources/map' {
98109
interface ResourceMap {
99110
Partner: typeof Partner;

src/components/partner/dto/update-partner.dto.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,13 @@ export abstract class UpdatePartner {
4848
@IdField({ nullable: true })
4949
readonly languageOfWiderCommunicationId?: ID<'Language'> | null;
5050

51+
@IdField({ nullable: true })
52+
readonly parentId?: ID<'Partner'> | null;
53+
54+
@ListField(() => IDType, { optional: true })
55+
@IsId({ each: true })
56+
readonly strategicAlliances?: ReadonlyArray<ID<'Partner'>>;
57+
5158
@ListField(() => IDType, { optional: true })
5259
@IsId({ each: true })
5360
readonly countries?: ReadonlyArray<ID<'Location'>>;

src/components/partner/partner.gel.repository.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ export class PartnerGelRepository
1818
countries: true,
1919
languagesOfConsulting: true,
2020
departmentIdBlock: departmentIdBlock.hydrate,
21+
strategicAlliances: true,
22+
parent: true,
2123
}),
2224
omit: ['create', 'update'],
2325
})

src/components/partner/partner.repository.ts

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,8 @@ export class PartnerRepository extends DtoRepository(Partner) {
9393
fieldRegions: ['FieldRegion', input.fieldRegions],
9494
countries: ['Location', input.countries],
9595
languagesOfConsulting: ['Language', input.languagesOfConsulting],
96+
strategicAlliances: ['Partner', input.strategicAlliances],
97+
parent: ['Partner', input.parentId],
9698
}),
9799
)
98100
.apply(departmentIdBlockUtils.createMaybe(input.departmentIdBlock))
@@ -118,11 +120,23 @@ export class PartnerRepository extends DtoRepository(Partner) {
118120
countries,
119121
languagesOfConsulting,
120122
departmentIdBlock,
123+
strategicAlliances,
124+
parentId,
121125
...simpleChanges
122126
} = changes;
123127

124128
await this.updateProperties({ id }, simpleChanges);
125129

130+
if (parentId !== undefined) {
131+
if (parentId === id) {
132+
throw new InputException(
133+
'A partner cannot be its own parent organization',
134+
'partner.parent',
135+
);
136+
}
137+
await this.updateRelation('parent', 'Partner', changes.id, parentId);
138+
}
139+
126140
if (pointOfContactId !== undefined) {
127141
await this.updateRelation(
128142
'pointOfContact',
@@ -169,6 +183,26 @@ export class PartnerRepository extends DtoRepository(Partner) {
169183
}
170184
}
171185

186+
if (strategicAlliances) {
187+
if (strategicAlliances.includes(changes.id)) {
188+
throw new InputException(
189+
'A partner cannot be its own strategic ally',
190+
'partner.strategicAlliances',
191+
);
192+
}
193+
try {
194+
await this.updateRelationList({
195+
id: changes.id,
196+
relation: 'strategicAlliances',
197+
newList: strategicAlliances,
198+
});
199+
} catch (e) {
200+
throw e instanceof InputException
201+
? e.withField('partner.strategicAlliances')
202+
: e;
203+
}
204+
}
205+
172206
if (languagesOfConsulting) {
173207
try {
174208
await this.updateRelationList({
@@ -257,6 +291,26 @@ export class PartnerRepository extends DtoRepository(Partner) {
257291
),
258292
),
259293
)
294+
.subQuery('node', (sub) =>
295+
sub
296+
.match([
297+
node('node'),
298+
relation('out', '', 'strategicAlliances'),
299+
node('strategicAlliances', 'Partner'),
300+
])
301+
.return(
302+
collect('strategicAlliances { .id }').as('strategicAlliances'),
303+
),
304+
)
305+
.subQuery('node', (sub) =>
306+
sub
307+
.optionalMatch([
308+
node('node'),
309+
relation('out', '', 'parent', ACTIVE),
310+
node('parent', 'Partner'),
311+
])
312+
.return('parent { .id } as parent'),
313+
)
260314
.apply(matchProps())
261315
.optionalMatch([
262316
node('node'),
@@ -288,6 +342,8 @@ export class PartnerRepository extends DtoRepository(Partner) {
288342
departmentIdBlock: 'departmentIdBlock',
289343
scope: 'scopedRoles',
290344
pinned,
345+
parent: 'parent { .id }',
346+
strategicAlliances: 'strategicAlliances',
291347
}).as('dto'),
292348
);
293349
}

src/components/partner/partner.resolver.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ import {
4242
Partner,
4343
PartnerListInput,
4444
PartnerListOutput,
45+
SecuredPartner,
46+
SecuredPartners,
4547
UpdatePartnerInput,
4648
UpdatePartnerOutput,
4749
} from './dto';
@@ -60,6 +62,25 @@ export class PartnerResolver {
6062
return await partners.load(id);
6163
}
6264

65+
@ResolveField(() => SecuredPartner)
66+
async parent(
67+
@Parent() partner: Partner,
68+
@Loader(PartnerLoader) partners: LoaderOf<PartnerLoader>,
69+
): Promise<SecuredPartner> {
70+
return await mapSecuredValue(partner.parent, ({ id }) => partners.load(id));
71+
}
72+
73+
@ResolveField(() => SecuredPartners)
74+
async strategicAlliances(
75+
@Parent() partner: Partner,
76+
@Loader(PartnerLoader) loader: LoaderOf<PartnerLoader>,
77+
): Promise<SecuredPartners> {
78+
return await loadSecuredIds(loader, {
79+
...partner.strategicAlliances,
80+
value: partner.strategicAlliances.value?.map((alliance) => alliance.id),
81+
});
82+
}
83+
6384
@Query(() => PartnerListOutput, {
6485
description: 'Look up partners',
6586
})

src/components/partner/partner.service.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,19 @@ export class PartnerService {
111111
};
112112
}
113113

114+
if (input.strategicAlliances?.includes(input.id)) {
115+
throw new InputException(
116+
'A partner cannot be its own strategic ally',
117+
'partner.strategicAlliances',
118+
);
119+
}
120+
if (input.parentId && input.parentId === input.id) {
121+
throw new InputException(
122+
'A partner cannot be its own parent organization',
123+
'partner.parent',
124+
);
125+
}
126+
114127
const { departmentIdBlock, ...simpleInput } = input;
115128
const simpleChanges = this.repo.getActualChanges(partner, simpleInput);
116129
const changes = {

0 commit comments

Comments
 (0)