The Converter Type was not saved in update request, types renaming to not confuse CarConverter from Car Catalog and Converter in Car, Add check of mandatory converter props in Car creation/update requests
MODIFY
src/integration/car/ev-database/EVDabaseCarIntegration.ts
src/integration/car/ev-database/EVDabaseCarIntegration.ts
import { default as Axios, default as axios } from 'axios';
-import { CarCatalog, CarConverter, ChargeAlternativeTable, ChargeOptionTable } from '../../../types/Car';
-
import BackendError from '../../../exception/BackendError';
-import CarIntegration from '../CarIntegration';
+import { CarCatalog, CarCatalogChargeAlternativeTable, CarCatalogChargeOptionTable, CarCatalogConverter } from '../../../types/Car';
+import { ServerAction } from '../../../types/Server';
import Configuration from '../../../utils/Configuration';
import Constants from '../../../utils/Constants';
import Logging from '../../../utils/Logging';
-import { ServerAction } from '../../../types/Server';
+import CarIntegration from '../CarIntegration';
+
const MODULE_NAME = 'EVDabaseCar';
@@ -33,11 +33,11 @@ export default class EVDabaseCarIntegration extends CarIntegration {
}
// Build result
for (const data of response.data) {
- const chargeStandardTables: CarConverter[] = [];
- const chargeAlternativeTables: ChargeAlternativeTable[] = [];
- const chargeOptionTables: ChargeOptionTable[] = [];
+ const chargeStandardTables: CarCatalogConverter[] = [];
+ const chargeAlternativeTables: CarCatalogChargeAlternativeTable[] = [];
+ const chargeOptionTables: CarCatalogChargeOptionTable[] = [];
for (const chargeStandard of Object.keys(data.Charge_Standard_Table)) {
- const chargeStandardTable: CarConverter = {
+ const chargeStandardTable: CarCatalogConverter = {
type: chargeStandard,
evsePhaseVolt: data.Charge_Standard_Table[chargeStandard].EVSE_PhaseVolt,
evsePhaseAmp: data.Charge_Standard_Table[chargeStandard].EVSE_PhaseAmp,
@@ -54,7 +54,7 @@ export default class EVDabaseCarIntegration extends CarIntegration {
}
if (data.Charge_Alternative_Table) {
for (const chargeAlternative of Object.keys(data.Charge_Alternative_Table)) {
- const chargeAlternativeTable: ChargeAlternativeTable = {
+ const chargeAlternativeTable: CarCatalogChargeAlternativeTable = {
type: chargeAlternative,
evsePhaseVolt: data.Charge_Standard_Table[chargeAlternative].EVSE_PhaseVolt,
evsePhaseAmp: data.Charge_Standard_Table[chargeAlternative].EVSE_PhaseAmp,
@@ -71,7 +71,7 @@ export default class EVDabaseCarIntegration extends CarIntegration {
}
if (data.Charge_Option_Table) {
for (const chargeOption of Object.keys(data.Charge_Option_Table)) {
- const chargeAlternativeTable: ChargeOptionTable = {
+ const chargeAlternativeTable: CarCatalogChargeOptionTable = {
type: chargeOption,
evsePhaseVolt: data.Charge_Standard_Table[chargeOption].EVSE_PhaseVolt,
evsePhaseAmp: data.Charge_Standard_Table[chargeOption].EVSE_PhaseAmp,

MODIFY
src/server/rest/service/security/CarSecurity.ts
src/server/rest/service/security/CarSecurity.ts
@@ -187,10 +187,10 @@ export default class CarSecurity {
forced: UtilsSecurity.filterBoolean(request.forced),
type: sanitize(request.type),
converter: {
- ampPerPhase: Utils.convertToFloat(sanitize(request.converter.ampPerPhase)),
- numberOfPhases: Utils.convertToInt(sanitize(request.converter.numberOfPhases)),
+ amperagePerPhase: sanitize(request.converter.amperagePerPhase),
+ numberOfPhases: sanitize(request.converter.numberOfPhases),
type: sanitize(request.converter.type),
- powerWatts: Utils.convertToFloat(sanitize(request.converter.powerWatts))
+ powerWatts: sanitize(request.converter.powerWatts)
},
usersAdded: request.usersUpserted ? request.usersUpserted.map((userUpserted: UserCar) => ({
user: userUpserted.user,
@@ -208,10 +208,10 @@ export default class CarSecurity {
type: sanitize(request.type),
id: sanitize(request.id),
converter: {
- ampPerPhase: Utils.convertToFloat(sanitize(request.converter.ampPerPhase)),
- numberOfPhases: Utils.convertToInt(sanitize(request.converter.numberOfPhases)),
- type: sanitize(request.converterType.type),
- powerWatts: Utils.convertToFloat(sanitize(request.converter.powerWatts))
+ amperagePerPhase: sanitize(request.converter.amperagePerPhase),
+ numberOfPhases: sanitize(request.converter.numberOfPhases),
+ type: sanitize(request.converter.type),
+ powerWatts: sanitize(request.converter.powerWatts)
},
usersRemoved: request.usersRemoved ? request.usersRemoved.map((userRemoved: UserCar) => ({
id: userRemoved.id,

MODIFY
src/storage/mongodb/CarStorage.ts
src/storage/mongodb/CarStorage.ts
-import { Car, CarCatalog, CarConverter, CarMaker, ChargeAlternativeTable, ChargeOptionTable } from '../../types/Car';
+import { Car, CarCatalog, CarCatalogChargeAlternativeTable, CarCatalogChargeOptionTable, CarCatalogConverter, CarMaker } from '../../types/Car';
import global, { Image } from '../../types/GlobalType';
import Constants from '../../utils/Constants';
@@ -198,7 +198,7 @@ export default class CarStorage {
chargeStandardChargeSpeed: Utils.convertToInt(carToSave.chargeStandardChargeSpeed),
chargeStandardEstimate: carToSave.chargeStandardEstimate,
chargeStandardTables: carToSave.chargeStandardTables ?
- carToSave.chargeStandardTables.map((chargeStandardTable: CarConverter): CarConverter => ({
+ carToSave.chargeStandardTables.map((chargeStandardTable: CarCatalogConverter): CarCatalogConverter => ({
type: chargeStandardTable.type,
evsePhaseVolt: Utils.convertToInt(chargeStandardTable.evsePhaseVolt),
evsePhaseAmp: Utils.convertToInt(chargeStandardTable.evsePhaseAmp),
@@ -217,7 +217,7 @@ export default class CarStorage {
chargeAlternativeChargeTime: Utils.convertToInt(carToSave.chargeAlternativeChargeTime),
chargeAlternativeChargeSpeed: Utils.convertToInt(carToSave.chargeAlternativeChargeSpeed),
chargeAlternativeTables: carToSave.chargeAlternativeTables ?
- carToSave.chargeAlternativeTables.map((chargeAlternativeTable: ChargeAlternativeTable): ChargeAlternativeTable => ({
+ carToSave.chargeAlternativeTables.map((chargeAlternativeTable: CarCatalogChargeAlternativeTable): CarCatalogChargeAlternativeTable => ({
type: chargeAlternativeTable.type,
evsePhaseVolt: Utils.convertToInt(chargeAlternativeTable.evsePhaseVolt),
evsePhaseAmp: Utils.convertToInt(chargeAlternativeTable.evsePhaseAmp),
@@ -235,7 +235,7 @@ export default class CarStorage {
chargeOptionChargeTime: Utils.convertToInt(carToSave.chargeOptionChargeTime),
chargeOptionChargeSpeed: Utils.convertToInt(carToSave.chargeOptionChargeSpeed),
chargeOptionTables: carToSave.chargeOptionTables ?
- carToSave.chargeOptionTables.map((chargeOptionTables: ChargeOptionTable): ChargeOptionTable => ({
+ carToSave.chargeOptionTables.map((chargeOptionTables: CarCatalogChargeOptionTable): CarCatalogChargeOptionTable => ({
type: chargeOptionTables.type,
evsePhaseVolt: Utils.convertToInt(chargeOptionTables.evsePhaseVolt),
evsePhaseAmp: Utils.convertToInt(chargeOptionTables.evsePhaseAmp),
@@ -461,7 +461,12 @@ export default class CarStorage {
licensePlate: carToSave.licensePlate,
carCatalogID: Utils.convertToInt(carToSave.carCatalogID),
type: carToSave.type,
- converter: carToSave.converter
+ converter: {
+ powerWatts: Utils.convertToFloat(carToSave.converter.powerWatts),
+ amperagePerPhase: Utils.convertToInt(carToSave.converter.amperagePerPhase),
+ numberOfPhases: Utils.convertToFloat(carToSave.converter.numberOfPhases),
+ type: carToSave.converter.type
+ }
};
// Add Last Changed/Created props
DatabaseUtils.addLastChangedCreatedProps(carMDB, carToSave);

MODIFY
src/types/Car.ts
src/types/Car.ts
@@ -64,19 +64,19 @@ export interface CarCatalog extends CreatedUpdatedProps {
chargeStandardChargeTime: number;
chargeStandardChargeSpeed: number;
chargeStandardEstimate?: boolean;
- chargeStandardTables: CarConverter[];
+ chargeStandardTables: CarCatalogConverter[];
chargeAlternativePower: number;
chargeAlternativePhase: number;
chargeAlternativePhaseAmp: number;
chargeAlternativeChargeTime: number;
chargeAlternativeChargeSpeed: number;
- chargeAlternativeTables: ChargeAlternativeTable[];
+ chargeAlternativeTables: CarCatalogChargeAlternativeTable[];
chargeOptionPower?: number;
chargeOptionPhase?: number;
chargeOptionPhaseAmp?: number;
chargeOptionChargeTime?: number;
chargeOptionChargeSpeed?: number;
- chargeOptionTables: ChargeOptionTable[];
+ chargeOptionTables: CarCatalogChargeOptionTable[];
fastChargePlug?: string;
fastChargePlugEstimate?: boolean;
fastChargePlugLocation?: string;
@@ -137,17 +137,17 @@ export interface Car extends CreatedUpdatedProps {
userIDs?: string;
carUsers?: UserCar[];
type?: CarType;
- converter?: Converter;
+ converter?: CarConverter;
}
-export interface Converter {
+export interface CarConverter {
powerWatts: number;
- ampPerPhase: number;
+ amperagePerPhase: number;
numberOfPhases: number;
- type: ConverterType;
+ type: CarConverterType;
}
-export enum ConverterType {
+export enum CarConverterType {
STANDARD = 'S',
OPTION = 'O',
ALTERNATIVE = 'A',
@@ -166,7 +166,7 @@ export interface CarMaker {
carMaker: string;
}
-export interface ChargeOptionTable {
+export interface CarCatalogChargeOptionTable {
type: string;
evsePhaseVolt?: number;
evsePhaseAmp?: number;
@@ -178,7 +178,7 @@ export interface ChargeOptionTable {
chargeTime?: number;
chargeSpeed?: number;
}
-export interface ChargeAlternativeTable {
+export interface CarCatalogChargeAlternativeTable {
type: string;
evsePhaseVolt: number;
evsePhaseAmp: number;
@@ -190,7 +190,7 @@ export interface ChargeAlternativeTable {
chargeTime: number;
chargeSpeed: number;
}
-export interface CarConverter {
+export interface CarCatalogConverter {
type: string;
evsePhaseVolt: number;
evsePhaseVoltCalculated: number;

MODIFY
src/types/requests/HttpCarRequest.ts
src/types/requests/HttpCarRequest.ts
-import { CarType, Converter } from '../Car';
+import { CarConverter, CarType } from '../Car';
import HttpDatabaseRequest from './HttpDatabaseRequest';
import { UserCar } from '../User';
@@ -31,7 +31,7 @@ export interface HttpCarCreateRequest {
forced?: boolean;
type: CarType;
id?: string;
- converter?: Converter;
+ converter?: CarConverter;
usersAdded?: UserCar[];
}
@@ -42,7 +42,7 @@ export interface HttpCarUpdateRequest {
forced?: boolean;
type: CarType;
id?: string;
- converter?: Converter;
+ converter?: CarConverter;
usersRemoved?: UserCar[];
usersUpserted?: UserCar[];
}

MODIFY
src/utils/Utils.ts
src/utils/Utils.ts
@@ -1798,8 +1798,7 @@ export default class Utils {
source: Constants.CENTRAL_SERVER,
errorCode: HTTPError.GENERAL_ERROR,
message: 'Car ID is mandatory',
- module: MODULE_NAME,
- method: 'checkIfCarValid',
+ module: MODULE_NAME, method: 'checkIfCarValid',
user: req.user.id
});
}
@@ -1808,8 +1807,7 @@ export default class Utils {
source: Constants.CENTRAL_SERVER,
errorCode: HTTPError.GENERAL_ERROR,
message: 'Vin Car is mandatory',
- module: MODULE_NAME,
- method: 'checkIfCarValid',
+ module: MODULE_NAME, method: 'checkIfCarValid',
user: req.user.id
});
}
@@ -1818,8 +1816,7 @@ export default class Utils {
source: Constants.CENTRAL_SERVER,
errorCode: HTTPError.GENERAL_ERROR,
message: 'License Plate is mandatory',
- module: MODULE_NAME,
- method: 'checkIfCarValid',
+ module: MODULE_NAME, method: 'checkIfCarValid',
user: req.user.id
});
}
@@ -1828,8 +1825,7 @@ export default class Utils {
source: Constants.CENTRAL_SERVER,
errorCode: HTTPError.GENERAL_ERROR,
message: 'Car Catalog ID is mandatory',
- module: MODULE_NAME,
- method: 'checkIfCarValid',
+ module: MODULE_NAME, method: 'checkIfCarValid',
user: req.user.id
});
}
@@ -1838,8 +1834,7 @@ export default class Utils {
source: Constants.CENTRAL_SERVER,
errorCode: HTTPError.GENERAL_ERROR,
message: 'Car type is mandatory',
- module: MODULE_NAME,
- method: 'checkIfCarValid',
+ module: MODULE_NAME, method: 'checkIfCarValid',
user: req.user.id
});
}
@@ -1849,11 +1844,55 @@ export default class Utils {
source: Constants.CENTRAL_SERVER,
errorCode: HTTPError.GENERAL_ERROR,
message: 'Pool cars can only be created by admin',
- module: MODULE_NAME,
- method: 'checkIfCarValid',
+ module: MODULE_NAME, method: 'checkIfCarValid',
+ user: req.user.id
+ });
+ }
+ }
+ if (!car.converter) {
+ throw new AppError({
+ source: Constants.CENTRAL_SERVER,
+ errorCode: HTTPError.GENERAL_ERROR,
+ message: 'Car CarConverter is mandatory',
+ module: MODULE_NAME, method: 'checkIfCarValid',
+ user: req.user.id
+ });
+ }
+ if (!car.converter.amperagePerPhase) {
+ throw new AppError({
+ source: Constants.CENTRAL_SERVER,
+ errorCode: HTTPError.GENERAL_ERROR,
+ message: 'Car CarConverter amperage per phase is mandatory',
+ module: MODULE_NAME, method: 'checkIfCarValid',
+ user: req.user.id
+ });
+ }
+ if (!car.converter.numberOfPhases) {
+ throw new AppError({
+ source: Constants.CENTRAL_SERVER,
+ errorCode: HTTPError.GENERAL_ERROR,
+ message: 'Car CarConverter number of phases is mandatory',
+ module: MODULE_NAME, method: 'checkIfCarValid',
+ user: req.user.id
+ });
+ }
+ if (!car.converter.powerWatts) {
+ throw new AppError({
+ source: Constants.CENTRAL_SERVER,
+ errorCode: HTTPError.GENERAL_ERROR,
+ message: 'Car CarConverter power is mandatory',
+ module: MODULE_NAME, method: 'checkIfCarValid',
user: req.user.id
});
}
+ if (!car.converter.type) {
+ throw new AppError({
+ source: Constants.CENTRAL_SERVER,
+ errorCode: HTTPError.GENERAL_ERROR,
+ message: 'Car CarConverter type is mandatory',
+ module: MODULE_NAME, method: 'checkIfCarValid',
+ user: req.user.id
+ });
}
}

The Converter Type was not saved in update request, types renaming to not confuse CarConverter from Car Catalog and Converter in Car, Add check of mandatory converter props in Car creation/update requests