Update companyID and siteID in charging stations when updated elsewhere
MODIFY
src/migration/MigrationHandler.ts
src/migration/MigrationHandler.ts
@@ -2,6 +2,8 @@ import AddCompanyIDToChargingStationsTask from './tasks/AddCompanyIDToChargingSt
import AddCompanyIDToTransactionsTask from './tasks/AddCompanyIDToTransactionsTask';
import AddUserIDToCarsTask from './tasks/AddUserIDToCarsTask';
import Constants from '../utils/Constants';
+import FixChargingStationCompanyIDsTask from './tasks/FixChargingStationCompanyIDsTask';
+import FixChargingStationSiteIDsTask from './tasks/FixChargingStationSiteIDsTask';
import { LockEntity } from '../types/Locking';
import LockingManager from '../locking/LockingManager';
import Logging from '../utils/Logging';
@@ -148,6 +150,8 @@ export default class MigrationHandler {
currentMigrationTasks.push(new RepairTransactionPricedAtZero());
currentMigrationTasks.push(new UpdateEmailsToLowercaseTask());
currentMigrationTasks.push(new UserCleanUpTask());
+ currentMigrationTasks.push(new FixChargingStationSiteIDsTask());
+ currentMigrationTasks.push(new FixChargingStationCompanyIDsTask());
return currentMigrationTasks;
}
}

ADD
src/migration/tasks/FixChargingStationCompanyIDsTask.ts
+import Constants from '../../utils/Constants';
+import Logging from '../../utils/Logging';
+import { ServerAction } from '../../types/Server';
+import Tenant from '../../types/Tenant';
+import TenantMigrationTask from '../TenantMigrationTask';
+import Utils from '../../utils/Utils';
+import global from '../../types/GlobalType';
+
+const MODULE_NAME = 'FixChargingStationCompanyIDsTask';
+
+export default class FixChargingStationCompanyIDsTask extends TenantMigrationTask {
+ public async migrateTenant(tenant: Tenant): Promise<void> {
+ let updated = 0, siteArea, site;
+ // Get all the charging stations
+ const chargingStations = await global.database.getCollection<any>(tenant.id, 'chargingstations').find({})
+ .project({ siteAreaID: 1, _id: 1 })
+ .toArray();
+ if (!Utils.isEmptyArray(chargingStations)) {
+ for (const chargingStation of chargingStations) {
+ siteArea = await global.database.getCollection<any>(tenant.id, 'siteareas').findOne({ _id: chargingStation.siteAreaID });
+ site = await global.database.getCollection<any>(tenant.id, 'sites').findOne({ _id: siteArea.siteID });
+ await global.database.getCollection<any>(tenant.id, 'chargingstations').updateOne(
+ { _id: chargingStation._id },
+ {
+ $set: {
+ companyID: site.companyID
+ }
+ }
+ );
+ updated++;
+ }
+ }
+ // Log in the default tenant
+ if (updated > 0) {
+ await Logging.logDebug({
+ tenantID: Constants.DEFAULT_TENANT,
+ module: MODULE_NAME, method: 'migrateTenant',
+ action: ServerAction.MIGRATION,
+ message: `${updated} ChargingStation(s) have been updated with company ID in Tenant ${Utils.buildTenantName(tenant)}`
+ });
+ }
+ }
+
+ public getVersion(): string {
+ return '1.0';
+ }
+
+ public getName(): string {
+ return 'FixChargingStationCompanyIDsTask';
+ }
+
+ public isAsynchronous(): boolean {
+ return true;
+ }
+}

ADD
src/migration/tasks/FixChargingStationSiteIDsTask.ts
+import Constants from '../../utils/Constants';
+import Logging from '../../utils/Logging';
+import { ServerAction } from '../../types/Server';
+import Tenant from '../../types/Tenant';
+import TenantMigrationTask from '../TenantMigrationTask';
+import Utils from '../../utils/Utils';
+import global from '../../types/GlobalType';
+
+const MODULE_NAME = 'FixChargingStationSiteIDsTask';
+
+export default class FixChargingStationSiteIDsTask extends TenantMigrationTask {
+ public async migrateTenant(tenant: Tenant): Promise<void> {
+ let updated = 0; let siteArea;
+ // Get all the charging stations
+ const chargingStations = await global.database.getCollection<any>(tenant.id, 'chargingstations').find({})
+ .project({ siteAreaID: 1, _id: 1 })
+ .toArray();
+ if (!Utils.isEmptyArray(chargingStations)) {
+ for (const chargingStation of chargingStations) {
+ siteArea = await global.database.getCollection<any>(tenant.id, 'siteareas').findOne({ _id: chargingStation.siteAreaID });
+ await global.database.getCollection<any>(tenant.id, 'chargingstations').updateOne(
+ { _id: chargingStation._id },
+ {
+ $set: {
+ siteID: siteArea.siteID
+ }
+ }
+ );
+ updated++;
+ }
+ }
+ // Log in the default tenant
+ if (updated > 0) {
+ await Logging.logDebug({
+ tenantID: Constants.DEFAULT_TENANT,
+ module: MODULE_NAME, method: 'migrateTenant',
+ action: ServerAction.MIGRATION,
+ message: `${updated} ChargingStation(s) have been updated with site ID in Tenant ${Utils.buildTenantName(tenant)}`
+ });
+ }
+ }
+
+ public getVersion(): string {
+ return '1.0';
+ }
+
+ public getName(): string {
+ return 'FixChargingStationSiteIDsTask';
+ }
+
+ public isAsynchronous(): boolean {
+ return true;
+ }
+}

MODIFY
src/server/rest/v1/service/SiteAreaService.ts
src/server/rest/v1/service/SiteAreaService.ts
@@ -7,6 +7,7 @@ import AppAuthError from '../../../../exception/AppAuthError';
import AppError from '../../../../exception/AppError';
import AuthorizationService from './AuthorizationService';
import { ChargingProfilePurposeType } from '../../../../types/ChargingProfile';
+import ChargingStationStorage from '../../../../storage/mongodb/ChargingStationStorage';
import Constants from '../../../../utils/Constants';
import ConsumptionStorage from '../../../../storage/mongodb/ConsumptionStorage';
import LockingHelper from '../../../../locking/LockingHelper';
@@ -364,7 +365,10 @@ export default class SiteAreaService {
}
siteArea.smartCharging = filteredRequest.smartCharging;
siteArea.accessControl = filteredRequest.accessControl;
+ if (siteArea.siteID !== filteredRequest.siteID) {
+ await ChargingStationStorage.updateChargingStationsSite(req.tenant, filteredRequest.id, filteredRequest.siteID);
siteArea.siteID = filteredRequest.siteID;
+ }
siteArea.lastChangedBy = { 'id': req.user.id };
siteArea.lastChangedOn = new Date();
// Save

MODIFY
src/server/rest/v1/service/SiteService.ts
src/server/rest/v1/service/SiteService.ts
@@ -400,7 +400,10 @@ export default class SiteService {
req.tenant, req.user, filteredRequest.companyID, Action.READ, action, filteredRequest);
// Update
site.name = filteredRequest.name;
+ if (site.companyID !== filteredRequest.companyID) {
+ await ChargingStationStorage.updateChargingStationsCompany(req.tenant, filteredRequest.id, filteredRequest.companyID);
site.companyID = filteredRequest.companyID;
+ }
if (Utils.objectHasProperty(filteredRequest, 'public')) {
if (!filteredRequest.public) {
// Check that there is no public charging stations

MODIFY
src/storage/mongodb/ChargingStationStorage.ts
src/storage/mongodb/ChargingStationStorage.ts
@@ -344,20 +344,19 @@ export default class ChargingStationStorage {
}, { sort: dbParams.sort });
}
// Site Area
- if (params.withSiteArea || params.withSite) {
+ if (params.withSiteArea) {
DatabaseUtils.pushSiteAreaLookupInAggregation({
tenantID: tenant.id, aggregation: aggregation, localField: 'siteAreaID', foreignField: '_id',
asField: 'siteArea', oneToOneCardinality: true
});
+ }
// Site
if (params.withSite) {
DatabaseUtils.pushSiteLookupInAggregation({
- tenantID: tenant.id, aggregation: aggregation, localField: 'siteArea.siteID', foreignField: '_id',
+ tenantID: tenant.id, aggregation: aggregation, localField: 'siteID', foreignField: '_id',
asField: 'site', oneToOneCardinality: true
});
}
- }
-
// Change ID
DatabaseUtils.pushRenameDatabaseID(aggregation);
// Convert siteID back to string after having queried the site
@@ -969,6 +968,32 @@ export default class ChargingStationStorage {
return firmware;
}
+ public static async updateChargingStationsSite(tenant: Tenant, siteAreaID: string, siteID: string): Promise<void> {
+ const startTime = Logging.traceDatabaseRequestStart();
+ DatabaseUtils.checkTenantObject(tenant);
+ await global.database.getCollection<any>(tenant.id, 'chargingstations').updateMany(
+ {
+ siteAreaID: DatabaseUtils.convertToObjectID(siteAreaID),
+ },
+ {
+ $set: { siteID: DatabaseUtils.convertToObjectID(siteAreaID) }
+ });
+ await Logging.traceDatabaseRequestEnd(tenant, MODULE_NAME, 'updateChargingStationsSite', startTime, { siteID });
+ }
+
+ public static async updateChargingStationsCompany(tenant: Tenant, siteID: string, companyID: string): Promise<void> {
+ const startTime = Logging.traceDatabaseRequestStart();
+ DatabaseUtils.checkTenantObject(tenant);
+ await global.database.getCollection<any>(tenant.id, 'chargingstations').updateMany(
+ {
+ siteID: DatabaseUtils.convertToObjectID(siteID),
+ },
+ {
+ $set: { companyID: DatabaseUtils.convertToObjectID(companyID) }
+ });
+ await Logging.traceDatabaseRequestEnd(tenant, MODULE_NAME, 'updateChargingStationsCompanies', startTime, { companyID });
+ }
+
private static getChargerInErrorFacet(errorType: string) {
switch (errorType) {
case ChargingStationInErrorType.MISSING_SETTINGS:

Update companyID and siteID in charging stations when updated elsewhere