Remove tags from Users list and Edit User, Ensure getter with one record in storage returns really one record + simplified issuer flag test
MODIFY
src/migration/tasks/AddLastChangePropertiesToBadgeTask.ts
src/migration/tasks/AddLastChangePropertiesToBadgeTask.ts
@@ -21,7 +21,6 @@ export default class AddLastChangePropertiesToBadgeTask extends MigrationTask {
async migrateTenant(tenant: Tenant): Promise<void> {
const users = await UserStorage.getUsers(tenant.id, {}, Constants.DB_PARAMS_MAX_LIMIT);
const tagCollection = global.database.getCollection<any>(tenant.id, 'tags');
-
let counter = 0;
for (const user of users.result) {
if (user.tags) {

MODIFY
src/server/rest/service/security/UserSecurity.ts
src/server/rest/service/security/UserSecurity.ts
@@ -125,7 +125,6 @@ export default class UserSecurity {
filteredUser.status = user.status;
filteredUser.eulaAcceptedOn = user.eulaAcceptedOn;
filteredUser.eulaAcceptedVersion = user.eulaAcceptedVersion;
- filteredUser.tags = user.tags;
filteredUser.plateID = user.plateID;
filteredUser.role = user.role;
if (Utils.objectHasProperty(user, 'errorCode')) {
@@ -160,7 +159,6 @@ export default class UserSecurity {
}
filteredUser.iNumber = user.iNumber;
filteredUser.costCenter = user.costCenter;
- filteredUser.tags = user.tags;
filteredUser.plateID = user.plateID;
filteredUser.role = user.role;
if (Utils.objectHasProperty(user, 'errorCode')) {

MODIFY
src/storage/mongodb/BillingStorage.ts
src/storage/mongodb/BillingStorage.ts
@@ -21,7 +21,7 @@ export default class BillingStorage {
Constants.DB_PARAMS_SINGLE_RECORD);
// Debug
Logging.traceEnd(MODULE_NAME, 'getInvoice', uniqueTimerID, { id });
- return invoicesMDB.count > 0 ? invoicesMDB.result[0] : null;
+ return invoicesMDB.count === 1 ? invoicesMDB.result[0] : null;
}
public static async getInvoiceByBillingInvoiceID(tenantID: string, billingInvoiceID: string): Promise<BillingInvoice> {
@@ -33,7 +33,7 @@ export default class BillingStorage {
Constants.DB_PARAMS_SINGLE_RECORD);
// Debug
Logging.traceEnd(MODULE_NAME, 'getInvoice', uniqueTimerID, { billingInvoiceID });
- return invoicesMDB.count > 0 ? invoicesMDB.result[0] : null;
+ return invoicesMDB.count === 1 ? invoicesMDB.result[0] : null;
}
public static async getInvoices(tenantID: string,

MODIFY
src/storage/mongodb/CarStorage.ts
src/storage/mongodb/CarStorage.ts
@@ -22,7 +22,7 @@ export default class CarStorage {
{ carCatalogIDs: [id] },
Constants.DB_PARAMS_SINGLE_RECORD, projectFields);
Logging.traceEnd(MODULE_NAME, 'getCarCatalog', uniqueTimerID, { id });
- return carCatalogsMDB.count > 0 ? carCatalogsMDB.result[0] : null;
+ return carCatalogsMDB.count === 1 ? carCatalogsMDB.result[0] : null;
}
public static async getCarCatalogs(
@@ -550,7 +550,7 @@ export default class CarStorage {
{ carIDs: [carID], ...params },
Constants.DB_PARAMS_SINGLE_RECORD, projectFields);
Logging.traceEnd(MODULE_NAME, 'getCar', uniqueTimerID, { carID });
- return carsMDB.count > 0 ? carsMDB.result[0] : null;
+ return carsMDB.count === 1 ? carsMDB.result[0] : null;
}
public static async getCarByVinLicensePlate(tenantID: string,
@@ -563,7 +563,7 @@ export default class CarStorage {
{ licensePlate: licensePlate, vin: vin, ...params },
Constants.DB_PARAMS_SINGLE_RECORD, projectFields);
Logging.traceEnd(MODULE_NAME, 'getCarByVinLicensePlate', uniqueTimerID, { vin, licensePlate });
- return carsMDB.count > 0 ? carsMDB.result[0] : null;
+ return carsMDB.count === 1 ? carsMDB.result[0] : null;
}
public static async getCars(tenantID: string,
@@ -742,7 +742,7 @@ export default class CarStorage {
Constants.DB_PARAMS_SINGLE_RECORD, projectFields);
Logging.traceEnd(MODULE_NAME, 'getCarUserByCarUser', uniqueTimerID, { userID, carID });
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
- return carUsersMDB.count > 0 ? carUsersMDB.result[0] : null;
+ return carUsersMDB.count === 1 ? carUsersMDB.result[0] : null;
}
public static async getCarUser(tenantID: string, carUserID: string = Constants.UNKNOWN_STRING_ID,
@@ -755,7 +755,7 @@ export default class CarStorage {
Constants.DB_PARAMS_SINGLE_RECORD, projectFields);
Logging.traceEnd(MODULE_NAME, 'getCarUser', uniqueTimerID, { carUserID });
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
- return carUsersMDB.count > 0 ? carUsersMDB.result[0] : null;
+ return carUsersMDB.count === 1 ? carUsersMDB.result[0] : null;
}
public static async deleteCarUser(tenantID: string, id: string): Promise<void> {

MODIFY
src/storage/mongodb/ChargingStationStorage.ts
src/storage/mongodb/ChargingStationStorage.ts
@@ -165,7 +165,7 @@ export default class ChargingStationStorage {
filters.lastHeartBeat = { $lte: params.offlineSince };
}
// Issuer
- if (params.issuer === true || params.issuer === false) {
+ if (Utils.objectHasProperty(params, 'issuer')) {
filters.issuer = params.issuer;
}
// Add Charging Station inactive flag
@@ -657,7 +657,7 @@ export default class ChargingStationStorage {
Constants.DB_PARAMS_SINGLE_RECORD);
// Debug
Logging.traceEnd(MODULE_NAME, 'getChargingProfile', uniqueTimerID, { id });
- return chargingProfilesMDB.count > 0 ? chargingProfilesMDB.result[0] : null;
+ return chargingProfilesMDB.count === 1 ? chargingProfilesMDB.result[0] : null;
}
public static async getChargingProfiles(tenantID: string,

MODIFY
src/storage/mongodb/CompanyStorage.ts
src/storage/mongodb/CompanyStorage.ts
@@ -133,7 +133,7 @@ export default class CompanyStorage {
$in: params.companyIDs.map((companyID) => Utils.convertToObjectID(companyID))
};
}
- if (params.issuer === true || params.issuer === false) {
+ if (Utils.objectHasProperty(params, 'issuer')) {
aggregation.push({
$match: {
'issuer': params.issuer

MODIFY
src/storage/mongodb/LoggingStorage.ts
src/storage/mongodb/LoggingStorage.ts
@@ -93,7 +93,7 @@ export default class LoggingStorage {
Constants.DB_PARAMS_SINGLE_RECORD);
// Debug
Logging.traceEnd(MODULE_NAME, 'getLog', uniqueTimerID, { id });
- return logsMDB.count > 0 ? logsMDB.result[0] : null;
+ return logsMDB.count === 1 ? logsMDB.result[0] : null;
}
public static async getLogs(tenantID: string, params: {

MODIFY
src/storage/mongodb/OCPIEndpointStorage.ts
src/storage/mongodb/OCPIEndpointStorage.ts
@@ -21,7 +21,7 @@ export default class OCPIEndpointStorage {
// Debug
Logging.traceEnd(MODULE_NAME, 'getOcpiEndpoint', uniqueTimerID, { id });
- return endpointsMDB.count > 0 ? endpointsMDB.result[0] : null;
+ return endpointsMDB.count === 1 ? endpointsMDB.result[0] : null;
}
static async getOcpiEndpointByLocalToken(tenantID: string, token: string): Promise<OCPIEndpoint> {
@@ -31,7 +31,7 @@ export default class OCPIEndpointStorage {
// Debug
Logging.traceEnd(MODULE_NAME, 'getOcpiEndpoinByLocalToken', uniqueTimerID, { token });
- return endpointsMDB.count > 0 ? endpointsMDB.result[0] : null;
+ return endpointsMDB.count === 1 ? endpointsMDB.result[0] : null;
}
static async saveOcpiEndpoint(tenantID: string, ocpiEndpointToSave: OCPIEndpoint): Promise<string> {

MODIFY
src/storage/mongodb/SettingStorage.ts
src/storage/mongodb/SettingStorage.ts
@@ -21,13 +21,13 @@ export default class SettingStorage {
const settingMDB = await SettingStorage.getSettings(tenantID, { settingID: id }, Constants.DB_PARAMS_SINGLE_RECORD);
// Debug
Logging.traceEnd(MODULE_NAME, 'getSetting', uniqueTimerID, { id });
- return settingMDB.count > 0 ? settingMDB.result[0] : null;
+ return settingMDB.count === 1 ? settingMDB.result[0] : null;
}
public static async getSettingByIdentifier(tenantID: string, identifier: string = Constants.UNKNOWN_STRING_ID): Promise<SettingDB> {
const settingResult = await SettingStorage.getSettings(
tenantID, { identifier: identifier }, Constants.DB_PARAMS_SINGLE_RECORD);
- return settingResult.count > 0 ? settingResult.result[0] : null;
+ return settingResult.count === 1 ? settingResult.result[0] : null;
}
public static async saveSettings(tenantID: string, settingToSave: Partial<SettingDB>): Promise<string> {

MODIFY
src/storage/mongodb/SiteAreaStorage.ts
src/storage/mongodb/SiteAreaStorage.ts
@@ -200,7 +200,7 @@ export default class SiteAreaStorage {
$in: params.siteIDs.map((siteID) => Utils.convertToObjectID(siteID))
};
}
- if (params.issuer === true || params.issuer === false) {
+ if (Utils.objectHasProperty(params, 'issuer')) {
filters.issuer = params.issuer;
}
if (params.smartCharging === true || params.smartCharging === false) {

MODIFY
src/storage/mongodb/SiteStorage.ts
src/storage/mongodb/SiteStorage.ts
@@ -26,7 +26,7 @@ export default class SiteStorage {
Constants.DB_PARAMS_SINGLE_RECORD);
// Debug
Logging.traceEnd(MODULE_NAME, 'getSite', uniqueTimerID, { id });
- return sitesMDB.count > 0 ? sitesMDB.result[0] : null;
+ return sitesMDB.count === 1 ? sitesMDB.result[0] : null;
}
public static async getSiteImage(tenantID: string, id: string): Promise<Image> {
@@ -362,7 +362,7 @@ export default class SiteStorage {
};
}
// Issuer
- if (params.issuer === true || params.issuer === false) {
+ if (Utils.objectHasProperty(params, 'issuer')) {
filters.issuer = params.issuer;
}
// Public Site

MODIFY
src/storage/mongodb/TenantStorage.ts
src/storage/mongodb/TenantStorage.ts
@@ -22,19 +22,19 @@ export default class TenantStorage {
const tenantsMDB = await TenantStorage.getTenants({ tenantIDs: [id] }, Constants.DB_PARAMS_SINGLE_RECORD);
// Debug
Logging.traceEnd(MODULE_NAME, 'getTenant', uniqueTimerID, { id });
- return tenantsMDB.count > 0 ? tenantsMDB.result[0] : null;
+ return tenantsMDB.count === 1 ? tenantsMDB.result[0] : null;
}
public static async getTenantByName(name: string): Promise<Tenant> {
// Delegate querying
const tenantsResult = await TenantStorage.getTenants({ tenantName: name }, Constants.DB_PARAMS_SINGLE_RECORD);
- return tenantsResult.count > 0 ? tenantsResult.result[0] : null;
+ return tenantsResult.count === 1 ? tenantsResult.result[0] : null;
}
public static async getTenantBySubdomain(subdomain: string): Promise<Tenant> {
// Delegate querying
const tenantsResult = await TenantStorage.getTenants({ tenantSubdomain: subdomain }, Constants.DB_PARAMS_SINGLE_RECORD);
- return tenantsResult.count > 0 ? tenantsResult.result[0] : null;
+ return tenantsResult.count === 1 ? tenantsResult.result[0] : null;
}
public static async saveTenant(tenantToSave: Partial<Tenant>, saveLogo = true): Promise<string> {

MODIFY
src/storage/mongodb/TransactionStorage.ts
src/storage/mongodb/TransactionStorage.ts
@@ -310,7 +310,7 @@ export default class TransactionStorage {
};
}
// Issuer
- if (params.issuer === true || params.issuer === false) {
+ if (Utils.objectHasProperty(params, 'issuer')) {
filters.issuer = params.issuer;
}
// Charge Box
@@ -747,7 +747,7 @@ export default class TransactionStorage {
];
}
// Issuer
- if (params.issuer === true || params.issuer === false) {
+ if (Utils.objectHasProperty(params, 'issuer')) {
match.issuer = params.issuer;
}
// User / Site Admin

MODIFY
src/storage/mongodb/UserStorage.ts
src/storage/mongodb/UserStorage.ts
@@ -95,10 +95,10 @@ export default class UserStorage {
// Debug
const uniqueTimerID = Logging.traceStart(MODULE_NAME, 'getUserByTagId');
// Get user
- const user = await UserStorage.getUsers(tenantID, { tagID: tagID }, Constants.DB_PARAMS_SINGLE_RECORD);
+ const user = await UserStorage.getUsers(tenantID, { tagIDs: [tagID] }, Constants.DB_PARAMS_SINGLE_RECORD);
// Debug
Logging.traceEnd(MODULE_NAME, 'getUserByTagId', uniqueTimerID, { tagID });
- return user.count > 0 ? user.result[0] : null;
+ return user.count === 1 ? user.result[0] : null;
}
public static async getUserByEmail(tenantID: string, email: string): Promise<User> {
@@ -112,7 +112,7 @@ export default class UserStorage {
const user = await UserStorage.getUsers(tenantID, { email: email }, Constants.DB_PARAMS_SINGLE_RECORD);
// Debug
Logging.traceEnd(MODULE_NAME, 'getUserByEmail', uniqueTimerID, { email });
- return user.count > 0 ? user.result[0] : null;
+ return user.count === 1 ? user.result[0] : null;
}
public static async getUserByPasswordResetHash(tenantID: string, passwordResetHash: string): Promise<User> {
@@ -122,7 +122,7 @@ export default class UserStorage {
const user = await UserStorage.getUsers(tenantID, { passwordResetHash: passwordResetHash }, Constants.DB_PARAMS_SINGLE_RECORD);
// Debug
Logging.traceEnd(MODULE_NAME, 'getUserByPasswordResetHash', uniqueTimerID, { passwordResetHash });
- return user.count > 0 ? user.result[0] : null;
+ return user.count === 1 ? user.result[0] : null;
}
public static async getUser(tenantID: string, id: string = Constants.UNKNOWN_OBJECT_ID): Promise<User> {
@@ -132,7 +132,7 @@ export default class UserStorage {
const user = await UserStorage.getUsers(tenantID, { userIDs: [id] }, Constants.DB_PARAMS_SINGLE_RECORD);
// Debug
Logging.traceEnd(MODULE_NAME, 'getUser', uniqueTimerID, { id });
- return user.count > 0 ? user.result[0] : null;
+ return user.count === 1 ? user.result[0] : null;
}
public static async getUserByBillingID(tenantID: string, billingID: string): Promise<User> {
@@ -142,7 +142,7 @@ export default class UserStorage {
const user = await UserStorage.getUsers(tenantID, { billingUserID: billingID }, Constants.DB_PARAMS_SINGLE_RECORD);
// Debug
Logging.traceEnd(MODULE_NAME, 'getUserByBillingID', uniqueTimerID, { customerID: billingID });
- return user.count > 0 ? user.result[0] : null;
+ return user.count === 1 ? user.result[0] : null;
}
public static async getUserImage(tenantID: string, id: string): Promise<Image> {
@@ -505,9 +505,9 @@ export default class UserStorage {
params: {
notificationsActive?: boolean; siteIDs?: string[]; excludeSiteID?: string; search?: string;
includeCarUserIDs?: string[]; excludeUserIDs?: string[]; notAssignedToCarID?: string;
- userIDs?: string[]; tagID?: string; email?: string; issuer?: boolean; passwordResetHash?: string; roles?: string[];
+ userIDs?: string[]; tagIDs?: string[]; email?: string; issuer?: boolean; passwordResetHash?: string; roles?: string[];
statuses?: string[]; withImage?: boolean; billingUserID?: string; notSynchronizedBillingData?: boolean;
- notifications?: any; noLoginSince?: Date;
+ notifications?: any; noLoginSince?: Date; withTag?: boolean;
},
dbParams: DbParams, projectFields?: string[]): Promise<DataResult<User>> {
// Debug
@@ -523,7 +523,15 @@ export default class UserStorage {
const filters: FilterParams = {
'$or': DatabaseUtils.getNotDeletedFilter()
};
- // Filter by other properties
+ // Create Aggregation
+ const aggregation = [];
+ // Tags
+ if (params.withTag) {
+ DatabaseUtils.pushTagLookupInAggregation({
+ tenantID, aggregation, localField: '_id', foreignField: 'userID', asField: 'tags'
+ });
+ }
+ // Filter
if (params.search) {
const searchRegex = Utils.escapeSpecialCharsInRegex(params.search);
filters.$or = [
@@ -534,18 +542,12 @@ export default class UserStorage {
{ 'plateID': { $regex: searchRegex, $options: 'i' } }
];
}
- // Create Aggregation
- const aggregation = [];
- // Add Tags
- DatabaseUtils.pushTagLookupInAggregation({
- tenantID, aggregation, localField: '_id', foreignField: 'userID', asField: 'tags'
- });
// Users
if (!Utils.isEmptyArray(params.userIDs)) {
filters._id = { $in: params.userIDs.map((userID) => Utils.convertToObjectID(userID)) };
}
// Issuer
- if (params.issuer === true || params.issuer === false) {
+ if (Utils.objectHasProperty(params, 'issuer')) {
filters.issuer = params.issuer;
}
// Exclude Users
@@ -557,8 +559,8 @@ export default class UserStorage {
filters.email = params.email;
}
// TagID
- if (params.tagID) {
- filters['tags.id'] = params.tagID;
+ if (!Utils.isEmptyArray(params.tagIDs)) {
+ filters['tags.id'] = { $in: params.tagIDs };
}
// Password Reset Hash
if (params.passwordResetHash) {
@@ -677,7 +679,7 @@ export default class UserStorage {
$limit: dbParams.limit
});
// Add Number of Session per Badge if one user only is requested
- if (dbParams.limit === 1) {
+ if (params.withTag && dbParams.limit === 1) {
// Transactions per Tag
DatabaseUtils.pushArrayLookupInAggregation('tags',
DatabaseUtils.pushTransactionsLookupInAggregation.bind(this), {
@@ -717,7 +719,7 @@ export default class UserStorage {
const tag = await UserStorage.getTags(tenantID, { tagIDs: [id] }, Constants.DB_PARAMS_SINGLE_RECORD);
// Debug
Logging.traceEnd(MODULE_NAME, 'getTag', uniqueTimerID, { id });
- return tag.count > 0 ? tag.result[0] : null;
+ return tag.count === 1 ? tag.result[0] : null;
}
public static async getTags(tenantID: string,
@@ -749,7 +751,7 @@ export default class UserStorage {
if (!Utils.isEmptyArray(params.userIDs)) {
filters.userID = { $in: params.userIDs.map((userID) => Utils.convertToObjectID(userID)) };
}
- if (params.issuer === true || params.issuer === false) {
+ if (Utils.objectHasProperty(params, 'issuer')) {
filters.issuer = params.issuer;
}
if (params.dateFrom && moment(params.dateFrom).isValid()) {

MODIFY
src/types/Server.ts
src/types/Server.ts
@@ -335,7 +335,6 @@ export enum ServerAction {
TAG = 'Tag',
TAG_CREATE = 'TagCreate',
TAG_UPDATE = 'TagUpdate',
- TAG_UPDATE_STATUS = 'TagUpdateStatus',
TAG_DELETE = 'TagDelete',
USER = 'User',

Remove tags from Users list and Edit User, Ensure getter with one record in storage returns really one record + simplified issuer flag test