diff --git a/src/datasources/db/cargobikeAPI.ts b/src/datasources/db/cargobikeAPI.ts index 6cd8304..8206de8 100644 --- a/src/datasources/db/cargobikeAPI.ts +++ b/src/datasources/db/cargobikeAPI.ts @@ -181,7 +181,7 @@ export class CargoBikeAPI extends DataSource { * @param param0 cargoBike to be updated */ async updateCargoBike (cargoBike: any, req: any, dataSources: any) { - // TODO let lock cargoBike can return error to save one sql query, this will be a complex sql query + // TODO lock cargoBike can return error to save one sql query, this will be a complex sql query if (!await this.checkId(CargoBike, 'cargobike', cargoBike.id)) { return new GraphQLError('ID not found'); } @@ -196,7 +196,6 @@ export class CargoBikeAPI extends DataSource { .where('cargoBike.id = :id', { id: cargoBike.id }) .getOne(); if (bike.id) { - const lendingStationId = cargoBike.lendingStationId; delete cargoBike.lendingStationId; await this.connection.manager .createQueryBuilder() @@ -204,14 +203,7 @@ export class CargoBikeAPI extends DataSource { .set({ ...cargoBike }) .where('id = :id', { id: bike.id }) .execute(); - if (lendingStationId || lendingStationId === null) { - await this.connection.getRepository(CargoBike) - .createQueryBuilder() - .relation(CargoBike, 'lendingStation') - .of(cargoBike.id) - .set(lendingStationId); - } - !keepLock && this.unlockCargoBike(cargoBike.id, req, dataSources); + !keepLock && await this.unlockCargoBike(cargoBike.id, req, dataSources); return await this.findCargoBikeById(bike.id); } else { return new GraphQLError('ID not in database'); @@ -233,11 +225,6 @@ export class CargoBikeAPI extends DataSource { .values([cargoBike]) .returning('*') .execute(); - await entityManager.getRepository(CargoBike) - .createQueryBuilder('cargobike') - .relation(CargoBike, 'lendingStation') - .of(inserts.identifiers[0].id) - .set(cargoBike?.lendingStationId); await entityManager.getRepository(CargoBike) .createQueryBuilder('cargobike') .relation(CargoBike, 'provider') @@ -293,15 +280,6 @@ export class CargoBikeAPI extends DataSource { return result === 1; } - // think this can go - async findEquipmentJoinBikeById (id: number) { - return await this.connection.getRepository(Equipment) - .createQueryBuilder('equipment') - .leftJoinAndSelect('equipment.cargoBike', 'cargoBike') - .where('equipment.id = :id', { id: id }) - .getOne(); - } - async equipmentByCargoBikeId (offset: number, limit: number, id: number) { return await this.connection.getRepository(Equipment) .createQueryBuilder('equipment') @@ -324,7 +302,6 @@ export class CargoBikeAPI extends DataSource { .relation(Equipment, 'cargoBike') .of(equipment.id) .set(equipment.cargoBikeId); - // return this.findEquipmentJoinBikeById(inserts.identifiers[0].id); } return this.findEquipmentById(inserts.identifiers[0].id); } diff --git a/src/datasources/db/lendingstationAPI.ts b/src/datasources/db/lendingstationAPI.ts index b6c8f44..708a5f5 100644 --- a/src/datasources/db/lendingstationAPI.ts +++ b/src/datasources/db/lendingstationAPI.ts @@ -1,7 +1,7 @@ import { DataSource } from 'apollo-datasource'; import { ApolloError, UserInputError } from 'apollo-server'; import { GraphQLError } from 'graphql'; -import {Connection, EntityManager, getConnection, QueryFailedError} from 'typeorm'; +import { Connection, EntityManager, getConnection, QueryFailedError } from 'typeorm'; import { CargoBike } from '../../model/CargoBike'; import { LendingStation } from '../../model/LendingStation'; import { TimeFrame } from '../../model/TimeFrame'; @@ -35,17 +35,22 @@ export class LendingStationAPI extends DataSource { .getMany() || new GraphQLError('Internal Server Error: could not query data from table lendingStation'); } + /** + * Finds LendingStation of a cargoBike. It will check timeFrames that overlap with today and return these records + * @param id of cargoBike + */ async lendingStationByCargoBikeId (id: number) { - return await this.connection.getRepository(LendingStation) - .createQueryBuilder('lendingStation') - .leftJoinAndSelect('lendingStation.cargoBikes', 'cargoBikes') - .where('"cargoBikes".id = :id', { id: id }) - .getOne().catch(() => { return null; }); + return (await this.connection.getRepository(TimeFrame) + .createQueryBuilder('timeframe') + .leftJoinAndSelect('timeframe.lendingStation', 'lendingStation') + .where('timeframe."cargoBikeId" = :id', { id: id }) + .andWhere('timeframe."dateRange" && daterange(CURRENT_DATE,CURRENT_DATE,\'[]\')') + .getOne())?.lendingStation; } async lendingStationByTimeFrameId (id: number) { - await this.connection.getRepository(TimeFrame) - .createQueryBuilder('timeframe') + return await this.connection.getRepository(LendingStation) + .createQueryBuilder('lendingStation') .relation(TimeFrame, 'lendingStation') .of(id) .loadOne(); @@ -76,20 +81,32 @@ export class LendingStationAPI extends DataSource { .getMany().catch(() => { return []; }); } + /** + * Counts all timeframes with one lendingStation that overlap with today's date + * @param id of lendingStation + */ async numCargoBikesByLendingStationId (id: number) { - return await this.connection.getRepository(CargoBike) - .createQueryBuilder('cargoBike') + return await this.connection.getRepository(TimeFrame) + .createQueryBuilder('timeframe') .select() - .where('"cargoBike"."lendingStationId" = :id', { id: id }) + .where('"timeframe"."lendingStationId" = :id', { id: id }) + .andWhere('"timeframe"."dateRange" && daterange(CURRENT_DATE,CURRENT_DATE,\'[]\')') .getCount(); } + /** + * Finds cargoBikes that are currently at the lendingStation specified by id. + * It checks all timeFrames for that bike and checks whether today is within its timeRange. + * @param id of lendingStation + */ async cargoBikesByLendingStationId (id: number) { return await this.connection.getRepository(CargoBike) - .createQueryBuilder('cargoBike') - .select() - .where('"cargoBike"."lendingStationId" = :id', { id: id }) - .getMany().catch(() => { return []; }); + .createQueryBuilder('cargoBike') // .addFrom(TimeFrame, 'timeframe') + .leftJoinAndSelect('cargoBike.timeFrames', 'timeframes') + .where('timeframes."lendingStationId" = :id', { id: id }) + .andWhere('timeframes."dateRange" && daterange(CURRENT_DATE,CURRENT_DATE,\'[]\')') + .printSql() + .getMany(); // .catch(() => { return []; }); } /** diff --git a/src/model/CargoBike.ts b/src/model/CargoBike.ts index 459e73c..fed636c 100644 --- a/src/model/CargoBike.ts +++ b/src/model/CargoBike.ts @@ -5,7 +5,6 @@ import { Provider } from './Provider'; import { Participant } from './Participant'; import { InsuranceData } from './InsuranceData'; import { TimeFrame } from './TimeFrame'; -import { LendingStation } from './LendingStation'; import { Taxes } from './Taxes'; import { Equipment } from './Equipment'; import { Engagement } from './Engagement'; @@ -129,13 +128,6 @@ export class CargoBike extends Bike implements Lockable { }) timeFrames: TimeFrame[]; - // This relation is a little redundant because one could also check all LoanPeriods for current station - @ManyToOne(type => LendingStation, lendingStation => lendingStation.cargoBikes, { - nullable: true, - eager: true - }) - lendingStation: LendingStation; - @OneToMany(type => Engagement, engagement => engagement.cargoBike) engagement: Engagement[]; diff --git a/src/model/LendingStation.ts b/src/model/LendingStation.ts index 0acd267..068e7ee 100644 --- a/src/model/LendingStation.ts +++ b/src/model/LendingStation.ts @@ -1,6 +1,5 @@ import { Entity, PrimaryGeneratedColumn, Column, ManyToMany, JoinTable, OneToMany, ManyToOne } from 'typeorm'; import { TimeFrame } from './TimeFrame'; -import { CargoBike } from './CargoBike'; import { Organisation } from './Organisation'; import { Address } from './Provider'; import { ContactPerson } from './ContactPerson'; @@ -41,11 +40,6 @@ export class LendingStation { @OneToMany(type => TimeFrame, loanPeriod => loanPeriod.lendingStation) loanPeriods: TimeFrame[]; - @OneToMany(type => CargoBike, cargoBike => cargoBike.lendingStation, { - eager: false - }) - cargoBikes: CargoBike[]; - @ManyToOne(type => Organisation, organization => organization.lendingStations) organization: Organisation; } diff --git a/src/schema/type-defs.ts b/src/schema/type-defs.ts index 0955558..1bc79be 100644 --- a/src/schema/type-defs.ts +++ b/src/schema/type-defs.ts @@ -51,6 +51,9 @@ type CargoBike { lockedUntil: Date } +""" +if you want to add bike to a lending station, create a new timeFrame with to: Date = null +""" input CargoBikeCreateInput { "see column A in info tabelle" group: Group! @@ -81,10 +84,12 @@ input CargoBikeCreateInput { note: String providerId: ID insuranceData: InsuranceDataCreateInput! - lendingStationId: ID taxes: TaxesCreateInput! } +""" +if you want to add bike to a lending station, create a new timeFrame with to: Date = null +""" input CargoBikeUpdateInput { id: ID! "see column A in info tabelle" @@ -115,7 +120,6 @@ input CargoBikeUpdateInput { note: String provider: String insuranceData: InsuranceDataUpdateInput - lendingStationId: ID taxes: TaxesUpdateInput "will keep Bike locked if set to true, default = false" keepLock: Boolean @@ -604,22 +608,25 @@ type LendingStation { numCargoBikes: Int! } +""" +If you want to create LendingStation with cargoBikes, use createTimeFrame and set to: Date = null +""" input LendingStationCreateInput { name: String! contactPersonIds: [ID]! address: AddressCreateInput! loanPeriods: LoanPeriodsInput - timeFrameIds: [ID]! } +""" +If you want to create LendingStation with cargoBikes, use createTimeFrame and set to: Date = null +""" input LendingStationUpdateInput { id: ID! name: String contactInformation: [ContactInformationUpdateInput] address: AddressUpdateInput loanPeriods: LoanPeriodsInput - timeFrames: [TimeFrameUpdateInput] - } """