From ca96923d3c688e71c0431512308f8506c9b573b9 Mon Sep 17 00:00:00 2001 From: leonnicolas Date: Tue, 24 Nov 2020 12:02:42 +0100 Subject: [PATCH 1/2] src/schema/*: added comment --- src/schema/type-defs.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/schema/type-defs.ts b/src/schema/type-defs.ts index fe125e0..7152e31 100644 --- a/src/schema/type-defs.ts +++ b/src/schema/type-defs.ts @@ -115,6 +115,7 @@ export default gql` """ Refers to unique equipment When set to null or [], no relations will be added. + When specified id is in a relation with another bike, this relation will be deleted. """ equipmentIds: [ID] "Sticker State" @@ -162,6 +163,7 @@ export default gql` When set to null, field will be ignored. When set to [], all relations will be deleted. Else all realtions will be deleted and the specified relations will be added. + When specified id is in a relation with another bike, this relation will be deleted. """ equipmentIds: [ID] "Sticker State" From 5011a29be86df606a5ea64fc9572e6ec3e622f08 Mon Sep 17 00:00:00 2001 From: leonnicolas Date: Wed, 25 Nov 2020 23:45:59 +0100 Subject: [PATCH 2/2] src: use range for dimensionAndLoad Changes in the schema: insead of _boxWidth_ etc. min and maxBoxWidth is used In the postgres db, this is saved as numrange. --- src/datasources/db/cargobikeAPI.ts | 7 ++-- src/datasources/db/lendingstationAPI.ts | 1 - src/datasources/db/utils.ts | 27 +++++++++++++++ src/model/CargoBike.ts | 31 ++++++++++------- src/resolvers/cargoBikeResolver.ts | 46 +++++++++++++++++++++++-- src/schema/type-defs.ts | 43 ++++++++++++++--------- 6 files changed, 120 insertions(+), 35 deletions(-) diff --git a/src/datasources/db/cargobikeAPI.ts b/src/datasources/db/cargobikeAPI.ts index 4f59e36..ff47082 100644 --- a/src/datasources/db/cargobikeAPI.ts +++ b/src/datasources/db/cargobikeAPI.ts @@ -26,7 +26,7 @@ import { Equipment } from '../../model/Equipment'; import { Engagement } from '../../model/Engagement'; import { Provider } from '../../model/Provider'; import { TimeFrame } from '../../model/TimeFrame'; -import { ActionLogger, DBUtils, LockUtils } from './utils'; +import { ActionLogger, DBUtils, genBoxDimensions, LockUtils } from './utils'; import { EquipmentType } from '../../model/EquipmentType'; import { BikeEventType } from '../../model/BikeEventType'; import { UserInputError } from 'apollo-server-express'; @@ -98,11 +98,13 @@ export class CargoBikeAPI extends DataSource { async updateCargoBike (cargoBike: any, userId:number) { const keepLock = cargoBike?.keepLock; delete cargoBike.keepLock; - delete cargoBike.lendingStationId; const equipmentTypeIds = cargoBike?.equipmentTypeIds; delete cargoBike?.equipmentTypeIds; const equipmentIds = cargoBike?.equipmentIds; delete cargoBike?.equipmentIds; + // generate ranges for box dimensions + genBoxDimensions(cargoBike); + await this.connection.transaction(async (entityManager: EntityManager) => { if (await LockUtils.isLocked(entityManager, CargoBike, 'cb', cargoBike.id, userId)) { throw new GraphQLError('CargoBike locked by other user'); @@ -150,6 +152,7 @@ export class CargoBikeAPI extends DataSource { */ async createCargoBike (cargoBike: any) { let inserts: any = {}; + genBoxDimensions(cargoBike); await this.connection.transaction(async (entityManager:any) => { inserts = await entityManager.getRepository(CargoBike) .createQueryBuilder('cb') diff --git a/src/datasources/db/lendingstationAPI.ts b/src/datasources/db/lendingstationAPI.ts index 97f2b6f..a0f84c6 100644 --- a/src/datasources/db/lendingstationAPI.ts +++ b/src/datasources/db/lendingstationAPI.ts @@ -19,7 +19,6 @@ This file is part of fLotte-API-Server. import { DataSource } from 'apollo-datasource'; import { UserInputError } from 'apollo-server-express'; -import { GraphQLError } from 'graphql'; import { Connection, EntityManager, getConnection } from 'typeorm'; import { CargoBike } from '../../model/CargoBike'; import { LendingStation } from '../../model/LendingStation'; diff --git a/src/datasources/db/utils.ts b/src/datasources/db/utils.ts index 962297f..be8fbf1 100644 --- a/src/datasources/db/utils.ts +++ b/src/datasources/db/utils.ts @@ -35,6 +35,33 @@ export function genDateRange (struct: any) { delete struct.to; } +/** + * This function prepares the cargoBike struct, to be used in an update or create. + * It creates the numrange attributes than can be understood by postgres. + * @param from + * @param to + */ +function genNumRange (from: number, to: number) { + if (from === null || from === undefined) { + from = to; + } else if (to === null || to === undefined) { + to = from; + } + return from ? '[' + from + ',' + to + ']' : null; +} + +export function genBoxDimensions (cargoBike: any) { + cargoBike.dimensionsAndLoad.boxLengthRange = genNumRange(cargoBike.dimensionsAndLoad.minBoxLength, cargoBike.dimensionsAndLoad.maxBoxLength); + cargoBike.dimensionsAndLoad.boxWidthRange = genNumRange(cargoBike.dimensionsAndLoad.minBoxWidth, cargoBike.dimensionsAndLoad.maxBoxWidth); + cargoBike.dimensionsAndLoad.boxHeightRange = genNumRange(cargoBike.dimensionsAndLoad.minBoxHeight, cargoBike.dimensionsAndLoad.maxBoxHeight); + // delete this so update cargo bike works + delete cargoBike.dimensionsAndLoad.minBoxLength; + delete cargoBike.dimensionsAndLoad.maxBoxLength; + delete cargoBike.dimensionsAndLoad.minBoxWidth; + delete cargoBike.dimensionsAndLoad.maxBoxWidth; + delete cargoBike.dimensionsAndLoad.minBoxHeight; + delete cargoBike.dimensionsAndLoad.maxBoxHeight; +} /** * Can be used in resolvers to specify, if entry is locked by other user. * Returns true if locked by other user. diff --git a/src/model/CargoBike.ts b/src/model/CargoBike.ts index da58bb9..4193a41 100644 --- a/src/model/CargoBike.ts +++ b/src/model/CargoBike.ts @@ -113,43 +113,50 @@ export class DimensionsAndLoad { lockable:boolean; @Column({ - type: 'decimal' + type: 'numrange', + nullable: true }) - boxLength: number; + boxLengthRange: string; @Column({ - type: 'decimal' + type: 'numrange', + nullable: true }) - boxWidth: number; + boxWidthRange: string; @Column({ - type: 'decimal' + type: 'numrange', + nullable: true }) - boxHeight: number; + boxHeightRange: string; @Column({ - type: 'decimal' + type: 'decimal', + nullable: true }) - maxWeightBox: number; + maxWeightBox: string; @Column({ - type: 'decimal' + type: 'decimal', + nullable: true }) maxWeightLuggageRack: number; @Column({ - type: 'decimal' + type: 'decimal', + nullable: true }) maxWeightTotal: number; @Column({ - type: 'decimal' + type: 'decimal', + nullable: true }) bikeLength: number; @Column({ nullable: true, - type: 'decimal' + type: 'numrange' }) bikeWidth: number; diff --git a/src/resolvers/cargoBikeResolver.ts b/src/resolvers/cargoBikeResolver.ts index 386cc36..502f181 100644 --- a/src/resolvers/cargoBikeResolver.ts +++ b/src/resolvers/cargoBikeResolver.ts @@ -137,8 +137,6 @@ export default { return new GraphQLError('Insufficient Permissions'); } }, - isLockedByMe: (parent: any, __: any, { req }: { req: any }) => isLockedByMe(parent, { req }), - isLocked: (parent: any, __: any, { req }: { req: any }) => isLocked(parent, { req }), timeFrames (parent: any, __: any, { dataSources, req }: { dataSources: any, req: any }) { if (req.permissions.includes(Permission.ReadTimeFrame)) { return dataSources.lendingStationAPI.timeFramesByCargoBikeId(parent.id); @@ -159,8 +157,50 @@ export default { } else { return new GraphQLError('Insufficient Permissions'); } + }, + isLockedByMe: (parent: any, __: any, { req }: { req: any }) => isLockedByMe(parent, { req }), + isLocked: (parent: any, __: any, { req }: { req: any }) => isLocked(parent, { req }) + }, + DimensionsAndLoad: { + minBoxLength: (parent: any) => { + if (!parent.boxLengthRange || parent.boxLengthRange === 'empty') { + return null; + } + return parent.boxLengthRange ? (parent.boxLengthRange as string).split(',')[0].replace('[', '') : null; + }, + maxBoxLength: (parent: any) => { + if (!parent.boxLengthRange || parent.boxLengthRange === 'empty') { + return null; + } + const str = (parent.boxLengthRange as string).split(',')[1].replace(']', ''); + return (str.length > 0) ? str : null; + }, + minBoxWidth: (parent: any) => { + if (!parent.boxWidthRange || parent.boxWidthRange === 'empty') { + return null; + } + return parent.boxWidthRange ? (parent.boxWidthRange as string).split(',')[0].replace('[', '') : null; + }, + maxBoxWidth: (parent: any) => { + if (!parent.boxWidthRange || parent.boxWidthRange === 'empty') { + return null; + } + const str = (parent.boxWidthRange as string).split(',')[1].replace(']', ''); + return (str.length > 0) ? str : null; + }, + minBoxHeight: (parent: any) => { + if (!parent.boxHeightRange || parent.boxHeightRange === 'empty') { + return null; + } + return parent.boxHeightRange ? (parent.boxHeightRange as string).split(',')[0].replace('[', '') : null; + }, + maxBoxHeight: (parent: any) => { + if (!parent.boxHeightRange || parent.boxHeightRange === 'empty') { + return null; + } + const str = (parent.boxHeightRange as string).split(',')[1].replace(']', ''); + return (str.length > 0) ? str : null; } - }, Equipment: { cargoBike (parent: any, __: any, { dataSources, req }: { dataSources: any, req: any }) { diff --git a/src/schema/type-defs.ts b/src/schema/type-defs.ts index 7152e31..d92729d 100644 --- a/src/schema/type-defs.ts +++ b/src/schema/type-defs.ts @@ -259,13 +259,16 @@ export default gql` hasCoverBox: Boolean! "cover box can be locked" lockable: Boolean! - boxLength: Float! - boxWidth: Float! - boxHeight: Float! - maxWeightBox: Float! - maxWeightLuggageRack: Float! - maxWeightTotal: Float! - bikeLength: Float! + minBoxLength: Float + maxBoxLength: Float + minBoxWidth: Float + maxBoxWidth: Float + minBoxHeight: Float + maxBoxHeight: Float + maxWeightBox: Float + maxWeightLuggageRack: Float + maxWeightTotal: Float + bikeLength: Float bikeWidth: Float bikeHeight: Float bikeWeight: Float @@ -274,13 +277,16 @@ export default gql` input DimensionsAndLoadCreateInput { hasCoverBox: Boolean! lockable: Boolean! - boxLength: Float! - boxWidth: Float! - boxHeight: Float! - maxWeightBox: Float! - maxWeightLuggageRack: Float! - maxWeightTotal: Float! - bikeLength: Float! + minBoxLength: Float + maxBoxLength: Float + minBoxWidth: Float + maxBoxWidth: Float + minBoxHeight: Float + maxBoxHeight: Float + maxWeightBox: Float + maxWeightLuggageRack: Float + maxWeightTotal: Float + bikeLength: Float bikeWidth: Float bikeHeight: Float bikeWeight: Float @@ -289,9 +295,12 @@ export default gql` input DimensionsAndLoadUpdateInput { hasCoverBox: Boolean lockable: Boolean - boxLength: Float - boxWidth: Float - boxHeight: Float + minBoxLength: Float + maxBoxLength: Float + minBoxWidth: Float + maxBoxWidth: Float + minBoxHeight: Float + maxBoxHeight: Float maxWeightBox: Float maxWeightLuggageRack: Float maxWeightTotal: Float