workshop, workshop types create and read

pull/14/head
leonnicolas 4 years ago
parent c26e9b78af
commit 77fd61194b
No known key found for this signature in database
GPG Key ID: 088D0743E2B65C07

@ -1,6 +1,7 @@
import { DataSource } from 'apollo-datasource'; import { DataSource } from 'apollo-datasource';
import { Connection, getConnection } from 'typeorm'; import { Connection, EntityManager, getConnection } from 'typeorm';
import { Provider } from '../../model/Provider'; import { Provider } from '../../model/Provider';
import { Organisation } from '../../model/Organisation';
export class ProviderAPI extends DataSource { export class ProviderAPI extends DataSource {
connection : Connection connection : Connection
@ -26,6 +27,30 @@ export class ProviderAPI extends DataSource {
.getMany(); .getMany();
} }
async providerByOrganisationId (id: number) {
return await this.connection.getRepository(Provider)
.createQueryBuilder('p')
.select()
.where('p."organisationId" = :id', { id: id })
.getOne();
}
async organisationByProviderId (id: number) {
return await this.connection.getRepository(Provider)
.createQueryBuilder()
.relation(Provider, 'organisationId')
.of(id)
.loadOne();
}
async contactInformationByOrganisationId (id: number) {
return await this.connection.getRepository(Organisation)
.createQueryBuilder('o')
.relation(Organisation, 'contactInformationId')
.of(id)
.loadOne();
}
async createProvider (provider: any) { async createProvider (provider: any) {
let inserts: any = null; let inserts: any = null;
await this.connection.transaction(async (entityManager: any) => { await this.connection.transaction(async (entityManager: any) => {
@ -40,15 +65,25 @@ export class ProviderAPI extends DataSource {
.relation(Provider, 'cargoBikes') .relation(Provider, 'cargoBikes')
.of(inserts.identifiers[0].id) .of(inserts.identifiers[0].id)
.add(provider.cargoBikeIds); .add(provider.cargoBikeIds);
await entityManager.getRepository(Provider)
.createQueryBuilder('provider')
.relation(Provider, 'contactPersons')
.of(inserts.identifiers[0].id)
.add(provider.contactPersonIds);
}); });
const ret = inserts.generatedMaps[0]; const ret = inserts.generatedMaps[0];
ret.id = inserts.identifiers[0].id; ret.id = inserts.identifiers[0].id;
return ret; return ret;
} }
async createOrganisation (organisation: any) {
let inserts: any = null;
await this.connection.transaction(async (entityManager: EntityManager) => {
inserts = await entityManager.getRepository(Organisation)
.createQueryBuilder('o')
.insert()
.values([organisation])
.execute();
await entityManager.getRepository(Organisation).createQueryBuilder()
.relation(Organisation, 'providerId')
.of(inserts.identifiers[0].id)
.set(organisation.providerId);
});
return inserts.generatedMaps[0];
}
} }

@ -0,0 +1,72 @@
import { DataSource } from 'apollo-datasource';
import { Connection, getConnection } from 'typeorm';
import { WorkshopType } from '../../model/WorkshopType';
import { Workshop } from '../../model/Workshop';
export class WorkshopAPI extends DataSource {
connection: Connection
constructor () {
super();
this.connection = getConnection();
}
async createWorkshop (workshop: any) {
const inserts = await this.connection.getRepository(Workshop)
.createQueryBuilder('w')
.insert()
.values([workshop])
.returning('*')
.execute();
return inserts.generatedMaps[0];
}
async createWorkshopType (workshopType: any) {
const inserts = await this.connection.getRepository(WorkshopType)
.createQueryBuilder('wt')
.insert()
.values([workshopType])
.returning('*')
.execute();
return inserts.generatedMaps[0];
}
async workshopTypes (offset: number, limit: number) {
return await this.connection.getRepository(WorkshopType)
.createQueryBuilder('w')
.select()
.skip(offset)
.take(limit)
.getMany();
}
/**
* finds workshops with pagination
* @param offset
* @param limit
*/
async workshops (offset: number, limit: number) {
return await this.connection.getRepository(Workshop)
.createQueryBuilder('w')
.select()
.skip(offset)
.take(limit)
.getMany();
}
async trainer1ByWorkshopId (id: number) {
return await this.connection.getRepository(Workshop)
.createQueryBuilder('w')
.relation(Workshop, 'trainer1Id')
.of(id)
.loadOne();
}
async trainer2ByWorkshopId (id: number) {
return await this.connection.getRepository(Workshop)
.createQueryBuilder('w')
.relation(Workshop, 'trainer2Id')
.of(id)
.loadOne();
}
}

@ -4,7 +4,9 @@ export enum Permission {
WriteBike = 'BIKE_WRITE', WriteBike = 'BIKE_WRITE',
WriteEquipmentType = 'EQUIPMENT_TYPE_WRITE', WriteEquipmentType = 'EQUIPMENT_TYPE_WRITE',
WritePerson = 'PERSON_WRITE', WritePerson = 'PERSON_WRITE',
ReadPerson = 'PERSON_READ' ReadPerson = 'PERSON_READ',
WriteProvider = 'PROVIDER_WRITE',
WriteWorkshopType = 'WORKSHOP_TYPE_WRITE'
} }
// Permissions where the creation will be requested on startup // Permissions where the creation will be requested on startup
@ -28,5 +30,13 @@ export const requiredPermissions = [
{ {
name: Permission.ReadPerson, name: Permission.ReadPerson,
description: 'Allows reading of contact information' description: 'Allows reading of contact information'
},
{
name: Permission.WriteProvider,
description: 'Allows to modify providers and organisations'
},
{
name: Permission.WriteWorkshopType,
description: 'Allows to create and modify workshop types'
} }
]; ];

@ -31,6 +31,8 @@ import { WorkshopType } from './model/WorkshopType';
import { EngagementType } from './model/EngagementType'; import { EngagementType } from './model/EngagementType';
import { EquipmentType } from './model/EquipmentType'; import { EquipmentType } from './model/EquipmentType';
import { BikeEventType } from './model/BikeEventType'; import { BikeEventType } from './model/BikeEventType';
import { WorkshopAPI } from './datasources/db/workshopAPI';
import workshopResolvers from './resolvers/workshopResolvers';
require('dotenv').config(); require('dotenv').config();
@ -96,7 +98,8 @@ const server = new ApolloServer({
lendingstationResolvers, lendingstationResolvers,
participantResolvers, participantResolvers,
providerResolvers, providerResolvers,
contactinformationResolvers contactinformationResolvers,
workshopResolvers
], ],
typeDefs, typeDefs,
dataSources: () => ({ dataSources: () => ({
@ -105,6 +108,7 @@ const server = new ApolloServer({
participantAPI: new ParticipantAPI(), participantAPI: new ParticipantAPI(),
contactInformationAPI: new ContactInformationAPI(), contactInformationAPI: new ContactInformationAPI(),
providerAPI: new ProviderAPI(), providerAPI: new ProviderAPI(),
workshopAPI: new WorkshopAPI(),
userAPI userAPI
}), }),
context: (req: any) => { context: (req: any) => {

@ -1,26 +1,10 @@
import { Entity, PrimaryGeneratedColumn, Column, OneToMany, ManyToOne } from 'typeorm'; import { Entity, PrimaryGeneratedColumn, Column, OneToMany, ManyToOne, JoinColumn } from 'typeorm';
import { TimeFrame } from './TimeFrame'; import { TimeFrame } from './TimeFrame';
import { Organisation } from './Organisation'; import { Organisation } from './Organisation';
import { Address } from './Provider'; import { Address } from './Provider';
import { ContactInformation } from './ContactInformation'; import { ContactInformation } from './ContactInformation';
@Entity() export class LoanPeriod {
export class LendingStation {
@PrimaryGeneratedColumn()
id: number;
@Column()
name: string;
@ManyToOne(type => ContactInformation)
contactInformationIntern: ContactInformation;
@ManyToOne(type => ContactInformation)
contactInformationExtern: ContactInformation;
@Column(type => Address)
address: Address;
/** /**
* validity for loanPeriods * validity for loanPeriods
*/ */
@ -39,9 +23,44 @@ export class LendingStation {
}) })
to: Date; to: Date;
@OneToMany(type => TimeFrame, loanPeriod => loanPeriod.lendingStation) @Column({
loanPeriods: TimeFrame[]; type: 'simple-array'
})
loanTimes: string[];
}
@Entity()
export class LendingStation {
@PrimaryGeneratedColumn()
id: number;
@Column()
name: string;
@ManyToOne(type => ContactInformation)
@JoinColumn({
name: 'contactInformationInternId'
})
contactInformationInternId: number;
@ManyToOne(type => ContactInformation)
@JoinColumn({
name: 'contactInformationExternId'
})
contactInformationExternId: number;
@Column(type => Address)
address: Address;
@Column(type => LoanPeriod)
loanPeriod: LoanPeriod;
@OneToMany(type => TimeFrame, timeFrame => timeFrame.lendingStation)
timeFrames: TimeFrame[];
@ManyToOne(type => Organisation, organization => organization.lendingStations) @ManyToOne(type => Organisation, organization => organization.lendingStations)
organization: Organisation; @JoinColumn({
name: 'organisationId'
})
organisationId: number;
} }

@ -1,21 +1,31 @@
import { PrimaryGeneratedColumn, OneToOne, OneToMany, Column, Entity } from 'typeorm'; import { PrimaryGeneratedColumn, OneToOne, OneToMany, Column, Entity, JoinColumn, ManyToOne } from 'typeorm';
import { LendingStation } from './LendingStation'; import { LendingStation } from './LendingStation';
import { Address, Provider } from './Provider'; import { Address, Provider } from './Provider';
import { ContactInformation } from './ContactInformation';
@Entity() @Entity()
export class Organisation { export class Organisation {
@PrimaryGeneratedColumn() @PrimaryGeneratedColumn()
id: number; id: number;
@OneToMany(type => LendingStation, lendingStation => lendingStation.organization) @Column()
name: string;
@OneToMany(type => LendingStation, lendingStation => lendingStation.organisationId)
lendingStations: LendingStation[]; lendingStations: LendingStation[];
@OneToOne(type => Provider, provider => provider.organization, { @OneToOne(type => Provider, provider => provider.organisationId, {
nullable: true nullable: true
}) })
provider: Provider; providerId: number;
@ManyToOne(type => ContactInformation)
@JoinColumn({
name: 'contactInformationId'
})
contactInformationId: number;
// Court where association was registerd // Court where association was registered
@Column({ @Column({
nullable: true nullable: true
}) })

@ -45,11 +45,13 @@ export class Provider implements Lockable {
contactInformationId: number; contactInformationId: number;
// is null when Provider is a private Person // is null when Provider is a private Person
@OneToOne(type => Organisation, organization => organization.provider, { @OneToOne(type => Organisation, organization => organization.providerId, {
nullable: true nullable: true
}) })
@JoinColumn() @JoinColumn({
organization: Organisation; name: 'organisationId'
})
organisationId: number;
@OneToMany(type => CargoBike, cargoBike => cargoBike.provider) @OneToMany(type => CargoBike, cargoBike => cargoBike.provider)
cargoBikes: CargoBike[]; cargoBikes: CargoBike[];

@ -10,13 +10,12 @@ export class TimeFrame {
@PrimaryGeneratedColumn() @PrimaryGeneratedColumn()
id: number; id: number;
// I have to find out how typorm will map the datetange data type.
@Column({ @Column({
type: 'daterange' type: 'daterange'
}) })
dateRange: Date[]; dateRange: Date[];
@ManyToOne(type => LendingStation, lendingStation => lendingStation.loanPeriods) @ManyToOne(type => LendingStation, lendingStation => lendingStation.timeFrames)
lendingStation: LendingStation; lendingStation: LendingStation;
@Column({ @Column({

@ -1,4 +1,4 @@
import { Entity, PrimaryGeneratedColumn, Column, ManyToMany, ManyToOne } from 'typeorm'; import { Entity, PrimaryGeneratedColumn, Column, ManyToMany, ManyToOne, JoinColumn } from 'typeorm';
import { Participant } from './Participant'; import { Participant } from './Participant';
import { WorkshopType } from './WorkshopType'; import { WorkshopType } from './WorkshopType';
import { Lockable } from './CargoBike'; import { Lockable } from './CargoBike';
@ -30,11 +30,17 @@ export class Workshop implements Lockable {
@ManyToOne(type => Participant, { @ManyToOne(type => Participant, {
nullable: false nullable: false
}) })
@JoinColumn({
name: 'trainer1Id'
})
trainer1Id: number; trainer1Id: number;
@ManyToOne(type => Participant, { @ManyToOne(type => Participant, {
nullable: true nullable: true
}) })
@JoinColumn({
name: 'trainer2Id'
})
trainer2: Participant; trainer2: Participant;
@Column({ @Column({

@ -27,9 +27,6 @@ export default {
} }
}, },
LendingStation: { LendingStation: {
contactPersons (parent: any, __: any, { dataSources, req }: { dataSources: any, req: any }) {
return dataSources.contactInformationAPI.contactPersonsByLendingStationId(parent.id);
},
timeFrames (parent: any, __: any, { dataSources, req }: { dataSources: any, req: any }) { timeFrames (parent: any, __: any, { dataSources, req }: { dataSources: any, req: any }) {
return dataSources.lendingStationAPI.timeFramesByLendingStationId(parent.id); return dataSources.lendingStationAPI.timeFramesByLendingStationId(parent.id);
}, },

@ -25,6 +25,17 @@ export default {
} else { } else {
return new GraphQLError('Insufficient Permissions'); return new GraphQLError('Insufficient Permissions');
} }
},
organisation: (parent: any, __: any, { dataSources, req }: { dataSources: any, req: any }) => {
return dataSources.providerAPI.organisationByProviderId(parent.id);
}
},
Organisation: {
provider: (parent: any, __: any, { dataSources, req }: { dataSources: any, req: any }) => {
return dataSources.providerAPI.providerByOrganisationId(parent.id);
},
contactInformation: (parent: any, __: any, { dataSources, req }: { dataSources: any, req: any }) => {
return dataSources.providerAPI.contactInformationByOrganisationId(parent.id);
} }
}, },
Mutation: { Mutation: {
@ -34,6 +45,13 @@ export default {
} else { } else {
return new GraphQLError('Insufficient Permissions'); return new GraphQLError('Insufficient Permissions');
} }
},
createOrganisation: (_: any, { organisation }: { organisation: any }, { dataSources, req }: { dataSources: any, req: any }) => {
if (req.permissions.includes(Permission.WriteProvider)) {
return dataSources.providerAPI.createOrganisation(organisation);
} else {
return new GraphQLError('Insufficient Permissions');
}
} }
} }
}; };

@ -0,0 +1,45 @@
import { Permission } from '../datasources/userserver/permission';
import { GraphQLError } from 'graphql';
export default {
Query: {
workshopTypes: (_: any, { offset, limit }: { offset: number, limit: number }, { dataSources, req }: { dataSources: any, req: any }) => {
if (req.permissions.includes(Permission.ReadBike)) {
return dataSources.workshopAPI.workshopTypes(offset, limit);
} else {
return new GraphQLError('Insufficient Permissions');
}
},
workshops: (_: any, { offset, limit }: { offset: number, limit: number }, { dataSources, req }: { dataSources: any, req: any }) => {
if (req.permissions.includes(Permission.ReadBike)) {
return dataSources.workshopAPI.workshops(offset, limit);
} else {
return new GraphQLError('Insufficient Permissions');
}
}
},
Workshop: {
trainer1: (parent: any, __:any, { dataSources, req }: { dataSources: any, req: any }) => {
return dataSources.workshopAPI.trainer1ByWorkshopId(parent.id);
},
trainer2: (parent: any, __:any, { dataSources, req }: { dataSources: any, req: any }) => {
return dataSources.workshopAPI.trainer2ByWorkshopId(parent.id);
}
},
Mutation: {
createWorkshop: (_: any, { workshop }: { workshop: number }, { dataSources, req }: { dataSources: any, req: any }) => {
if (req.permissions.includes(Permission.WriteWorkshopType)) {
return dataSources.workshopAPI.createWorkshop(workshop);
} else {
return new GraphQLError('Insufficient Permissions');
}
},
createWorkshopType: (_: any, { workshopType }: { workshopType: number }, { dataSources, req }: { dataSources: any, req: any }) => {
if (req.permissions.includes(Permission.WriteWorkshopType)) {
return dataSources.workshopAPI.createWorkshopType(workshopType);
} else {
return new GraphQLError('Insufficient Permissions');
}
}
}
};

@ -242,6 +242,34 @@ input ParticipantCreateInput {
memberCoreTeam: Boolean memberCoreTeam: Boolean
} }
type Workshop {
id: ID!
title: String!
description: String!
date: Date!
workshopType: WorkshopType!
trainer1: Participant!
trainer2: Participant
}
input WorkshopCreateInput {
title: String!
description: String
date: Date!
workshopTypeId: ID!
trainer1Id: ID!
trainer2Id: ID
}
type WorkshopType {
id: ID!
name: String!
}
input WorkshopTypeCreateInput {
name: String!
}
type EngagementType { type EngagementType {
id: ID! id: ID!
name: String! name: String!
@ -295,20 +323,20 @@ input EngagementCreateInput {
type Taxes { type Taxes {
costCenter: String! costCenter: String!
organizationArea: OrganizationArea organisationArea: OrganisationArea
} }
input TaxesCreateInput { input TaxesCreateInput {
costCenter: String! costCenter: String!
organizationArea: OrganizationArea organisationArea: OrganisationArea
} }
input TaxesUpdateInput { input TaxesUpdateInput {
costCenter: String costCenter: String
organizationArea: OrganizationArea organisationArea: OrganisationArea
} }
enum OrganizationArea { enum OrganisationArea {
IB IB
ZB ZB
} }
@ -535,20 +563,17 @@ enum StickerBikeNameState {
type Provider { type Provider {
id: ID! id: ID!
formName: String formName: String
contactPersons: [ContactInformation]! privatePerson: ContactInformation
isPrivatePerson: Boolean!
organisation: Organisation organisation: Organisation
cargoBikes: [CargoBike]! cargoBikes: [CargoBike]
} }
"(dt. Anbieter)" "(dt. Anbieter)"
input ProviderCreateInput { input ProviderCreateInput {
formName: String! formName: String!
"i think it makes more sense to create Provider and then add new ContactPersons" privatePersonId: ID
contactPersonIds: [ID]!
isPrivatePerson: Boolean!
organisationId: ID organisationId: ID
cargoBikeIds: [ID]! cargoBikeIds: [ID]
} }
""" """
@ -616,6 +641,7 @@ input ContactPersonUpdateInput {
type Organisation { type Organisation {
id: ID! id: ID!
name: String!
address: Address address: Address
"(dt. Ausleihstation)" "(dt. Ausleihstation)"
lendingStations: [LendingStation] lendingStations: [LendingStation]
@ -624,6 +650,21 @@ type Organisation {
"If Club, at what court registered" "If Club, at what court registered"
registeredAt: String registeredAt: String
provider: Provider provider: Provider
contactInformation: ContactInformation
otherData: String
}
input OrganisationCreateInput {
address: AddressCreateInput!
name: String!
"(dt. Ausleihstation)"
lendingStationIds: [ID]
"registration number of association"
associationNo: String!
"If Club, at what court registered"
registeredAt: String
providerId: ID
contactInformationId: ID
otherData: String otherData: String
} }
@ -631,10 +672,11 @@ type Organisation {
type LendingStation { type LendingStation {
id: ID! id: ID!
name: String! name: String!
contactPersons: [ContactPerson]! contactInformationIntern: ContactInformation
contactInformationExtern: ContactInformation
address: Address! address: Address!
timeFrames: [TimeFrame]! timeFrames: [TimeFrame]!
loanPeriods: LoanPeriods loanPeriod: LoanPeriod
cargoBikes: [CargoBike] cargoBikes: [CargoBike]
"Total amount of cargoBikes currently assigned to the lending station" "Total amount of cargoBikes currently assigned to the lending station"
numCargoBikes: Int! numCargoBikes: Int!
@ -645,9 +687,10 @@ If you want to create LendingStation with cargoBikes, use createTimeFrame and se
""" """
input LendingStationCreateInput { input LendingStationCreateInput {
name: String! name: String!
contactPersonIds: [ID]! contactInformationInternId: ID
contactInformationExternId: ID
address: AddressCreateInput! address: AddressCreateInput!
loanPeriods: LoanPeriodsInput loanPeriod: LoanPeriodInput
} }
""" """
@ -658,13 +701,13 @@ input LendingStationUpdateInput {
name: String name: String
contactInformation: [ContactInformationUpdateInput] contactInformation: [ContactInformationUpdateInput]
address: AddressUpdateInput address: AddressUpdateInput
loanPeriods: LoanPeriodsInput loanPeriod: LoanPeriodInput
} }
""" """
(dt. Ausleihzeiten) not implemented (dt. Ausleihzeiten) not implemented
""" """
type LoanPeriods { type LoanPeriod {
generalRemark: String generalRemark: String
"notes for each day of the week, starting on Monday" "notes for each day of the week, starting on Monday"
notes: [String] notes: [String]
@ -678,7 +721,7 @@ type LoanPeriods {
""" """
(dt. Ausleihzeiten) (dt. Ausleihzeiten)
""" """
input LoanPeriodsInput { input LoanPeriodInput {
generalRemark: String generalRemark: String
"notes for each day of the week, starting on Monday" "notes for each day of the week, starting on Monday"
notes: [String] notes: [String]
@ -753,6 +796,8 @@ type Query {
participantById(id:ID!): Participant participantById(id:ID!): Participant
"p" "p"
participants(offset: Int!, limit: Int!): [ Participant]! participants(offset: Int!, limit: Int!): [ Participant]!
workshopTypes(offset: Int!, limit: Int!): [WorkshopType]
workshops(offset: Int!, limit: Int!): [Workshop]
lendingStationById(id:ID!): LendingStation lendingStationById(id:ID!): LendingStation
lendingStations(offset: Int!, limit: Int!): [LendingStation]! lendingStations(offset: Int!, limit: Int!): [LendingStation]!
timeframes(offset: Int!, limit: Int!): [TimeFrame]! timeframes(offset: Int!, limit: Int!): [TimeFrame]!
@ -789,6 +834,8 @@ type Mutation {
createBikeEvent(bikeEvent: BikeEventCreateInput): BikeEvent! createBikeEvent(bikeEvent: BikeEventCreateInput): BikeEvent!
"create participant" "create participant"
createParticipant(participant: ParticipantCreateInput!): Participant! createParticipant(participant: ParticipantCreateInput!): Participant!
createWorkshopType(workshopType: WorkshopTypeCreateInput!): WorkshopType!
createWorkshop(workshop: WorkshopCreateInput!): Workshop!
"create new contactInfo" "create new contactInfo"
createContactInformation(contactInformation: ContactInformationCreateInput!): ContactInformation! createContactInformation(contactInformation: ContactInformationCreateInput!): ContactInformation!
createPerson(person: PersonCreateInput!): Person! createPerson(person: PersonCreateInput!): Person!
@ -800,6 +847,7 @@ type Mutation {
updateContactPerson(contactPerson: ContactPersonUpdateInput): ContactPerson updateContactPerson(contactPerson: ContactPersonUpdateInput): ContactPerson
"create Provider, if cargoBikeIds or contactPersonIds are not valid, provider will still be created" "create Provider, if cargoBikeIds or contactPersonIds are not valid, provider will still be created"
createProvider(provider: ProviderCreateInput!): Provider! createProvider(provider: ProviderCreateInput!): Provider!
createOrganisation(organisation: OrganisationCreateInput!): Organisation!
} }

Loading…
Cancel
Save