check activity status for engagements

when updating or creating engagements or participants dateRange of
particpant must include dateRange of engagement.
pull/27/head
leonnicolas 4 years ago
parent 6162758638
commit 8add40cd02
No known key found for this signature in database
GPG Key ID: 088D0743E2B65C07

1
.gitignore vendored

@ -2,3 +2,4 @@ node_modules
dist dist
.env .env
.idea .idea
.dockerignore

@ -130,7 +130,7 @@ export class ParticipantAPI extends DataSource {
} }
async engagementTypes (offset?: number, limit?: number) { async engagementTypes (offset?: number, limit?: number) {
return await DBUtils.getAllEntity(this.connection, Engagement, 'e', offset, limit); return await DBUtils.getAllEntity(this.connection, EngagementType, 'et', offset, limit);
} }
async engagementTypeByEngagementId (id: number) { async engagementTypeByEngagementId (id: number) {
@ -170,6 +170,7 @@ export class ParticipantAPI extends DataSource {
* @param participant to be created * @param participant to be created
*/ */
async createParticipant (participant: any) { async createParticipant (participant: any) {
genDateRange(participant);
let inserts: any; let inserts: any;
await this.connection.transaction(async (entityManager: EntityManager) => { await this.connection.transaction(async (entityManager: EntityManager) => {
inserts = await entityManager.getRepository(Participant) inserts = await entityManager.getRepository(Participant)
@ -201,8 +202,9 @@ export class ParticipantAPI extends DataSource {
delete participant.keepLock; delete participant.keepLock;
await this.connection.transaction(async (entityManager: EntityManager) => { await this.connection.transaction(async (entityManager: EntityManager) => {
if (await LockUtils.isLocked(entityManager, Participant, 'p', participant.id, userId)) { if (await LockUtils.isLocked(entityManager, Participant, 'p', participant.id, userId)) {
throw new GraphQLError('Participant is locked by another user'); throw new UserInputError('Attempting to update locked resource');
} }
genDateRange(participant);
const workshops = participant.workshopIds; const workshops = participant.workshopIds;
delete participant.workshopIds; delete participant.workshopIds;
await ActionLogger.log(entityManager, Participant, 'p', participant, userId); await ActionLogger.log(entityManager, Participant, 'p', participant, userId);
@ -212,6 +214,17 @@ export class ParticipantAPI extends DataSource {
.set({ ...participant }) .set({ ...participant })
.where('id = :id', { id: participant.id }) .where('id = :id', { id: participant.id })
.execute().then(value => { if (value.affected !== 1) { throw new UserInputError('ID not found'); } }); .execute().then(value => { if (value.affected !== 1) { throw new UserInputError('ID not found'); } });
// check for engagements before or after dateRange
const engagements = await entityManager.getRepository(Engagement)
.createQueryBuilder('e')
.select()
.where('e."participantId" = :pid', { pid: participant.id })
.andWhere('not :pdr @> e."dateRange"', { pdr: participant.dateRange })
.getMany();
if (engagements.length !== 0) {
throw new UserInputError('Engagements with ids: ' + engagements.map((e) => { return `${e.id} ,`; }) + ' are are outside of dataRange');
}
// add and remove workshop relations
workshops && await entityManager.getRepository(Participant) workshops && await entityManager.getRepository(Participant)
.createQueryBuilder('w') .createQueryBuilder('w')
.relation(Participant, 'workshopIds') .relation(Participant, 'workshopIds')
@ -241,6 +254,16 @@ export class ParticipantAPI extends DataSource {
if (overlapping.length > 0) { if (overlapping.length > 0) {
throw new UserInputError('Engagements with ids: ' + overlapping.map((e) => { return e.id + ', '; }) + 'are overlapping'); throw new UserInputError('Engagements with ids: ' + overlapping.map((e) => { return e.id + ', '; }) + 'are overlapping');
} }
// check if participant is active
const participant = await entityManager.getRepository(Participant)
.createQueryBuilder('p')
.select()
.where('p.id = :pid', { pid: engagement.participantId })
.andWhere('not p."dateRange" @> :edr', { edr: engagement.dateRange })
.getOne();
if (participant) {
throw new UserInputError('Participant ist not active in the specified dateRange');
}
inserts = await entityManager.getRepository(Engagement) inserts = await entityManager.getRepository(Engagement)
.createQueryBuilder('engagement') .createQueryBuilder('engagement')
.insert() .insert()
@ -280,6 +303,20 @@ export class ParticipantAPI extends DataSource {
if (overlapping.length > 0) { if (overlapping.length > 0) {
throw new UserInputError('Engagements with ids: ' + overlapping.map((e) => { return e.id + ', '; }) + 'are overlapping'); throw new UserInputError('Engagements with ids: ' + overlapping.map((e) => { return e.id + ', '; }) + 'are overlapping');
} }
// check if participant is active
if (engagement.dateRange && engagement.participantId) {
const participant = await entityManager.getRepository(Participant)
.createQueryBuilder('p')
.select()
.where('p.id = :pid', { pid: engagement.participantId })
.andWhere('not p."dateRange" @> :edr', { edr: engagement.dateRange })
.getOne();
if (participant) {
throw new UserInputError('Participant ist not active in the specified dateRange');
}
} else if (engagement.dateRange || engagement.dateRange) {
throw new UserInputError('Please specify participantId adn the dateRange');
}
await entityManager.getRepository(Engagement) await entityManager.getRepository(Engagement)
.createQueryBuilder('engagement') .createQueryBuilder('engagement')
.update() .update()

@ -29,16 +29,9 @@ export class Participant implements Lockable {
id: number; id: number;
@Column({ @Column({
type: 'date', type: 'daterange'
default: () => 'CURRENT_DATE'
}) })
start: Date; dateRange: Date[];
@Column({
type: 'date',
nullable: true
})
end: Date;
@OneToOne(type => ContactInformation, contactInformation => contactInformation.participantId, { @OneToOne(type => ContactInformation, contactInformation => contactInformation.participantId, {
nullable: false nullable: false

@ -410,8 +410,7 @@ export default gql`
""" """
type Participant { type Participant {
id: ID! id: ID!
start: Date! dateRange: DateRange!
end: Date
contactInformation: ContactInformation! contactInformation: ContactInformation!
usernamefLotte: String usernamefLotte: String
usernameSlack: String usernameSlack: String
@ -436,8 +435,7 @@ export default gql`
input ParticipantCreateInput { input ParticipantCreateInput {
"if not set, CURRENT_DATE will be used" "if not set, CURRENT_DATE will be used"
start: Date dateRange: DateRangeInput!
end: Date
"must create contactinformation first, if you want to use new" "must create contactinformation first, if you want to use new"
contactInformationId: ID! contactInformationId: ID!
usernamefLotte: String usernamefLotte: String
@ -452,9 +450,7 @@ export default gql`
input ParticipantUpdateInput { input ParticipantUpdateInput {
id: ID! id: ID!
"if not set, CURRENT_DATE will be used" dateRange: DateRangeInput
start: Date
end: Date
"must create contactinformation first, if you want to use new" "must create contactinformation first, if you want to use new"
contactInformationId: ID contactInformationId: ID
usernamefLotte: String usernamefLotte: String
@ -564,7 +560,7 @@ export default gql`
input EngagementCreateInput { input EngagementCreateInput {
engagementTypeId: ID! engagementTypeId: ID!
dateRange: DateRangeInput dateRange: DateRangeInput!
participantId: ID! participantId: ID!
cargoBikeId: ID! cargoBikeId: ID!
} }

Loading…
Cancel
Save