Admin Create Tag with visualID
MODIFY
src/server/rest/v1/service/AuthorizationService.ts
src/server/rest/v1/service/AuthorizationService.ts
@@ -409,7 +409,7 @@ export default class AuthorizationService {
dataSources: new Map(),
projectFields: [
'id', 'userID', 'active', 'ocpiToken', 'description', 'issuer', 'default',
- 'createdOn', 'lastChangedOn'
+ 'createdOn', 'lastChangedOn', 'visualID'
],
authorized: userToken.role === UserRole.ADMIN || userToken.role === UserRole.SUPER_ADMIN,
};
@@ -431,7 +431,7 @@ export default class AuthorizationService {
const authorizationFilters: AuthorizationFilter = {
filters: {},
dataSources: new Map(),
- projectFields: ['id', 'userID', 'issuer', 'active', 'description', 'default', 'user.id', 'user.name', 'user.firstName', 'user.email'],
+ projectFields: ['id', 'userID', 'issuer', 'active', 'description', 'visualID', 'default', 'user.id', 'user.name', 'user.firstName', 'user.email'],
authorized: userToken.role === UserRole.ADMIN || userToken.role === UserRole.SUPER_ADMIN,
};
// Filter projected fields

MODIFY
src/server/rest/v1/service/TagService.ts
src/server/rest/v1/service/TagService.ts
@@ -132,7 +132,7 @@ export default class TagService {
// Check
UtilsService.checkIfUserTagIsValid(filteredRequest, req);
// Check Tag
- const tag = await TagStorage.getTag(req.user.tenantID, filteredRequest.id.toUpperCase());
+ let tag = await TagStorage.getTag(req.user.tenantID, filteredRequest.id.toUpperCase());
if (tag) {
throw new AppError({
source: Constants.CENTRAL_SERVER,
@@ -143,6 +143,18 @@ export default class TagService {
action: action
});
}
+ // Check Tag
+ tag = await TagStorage.getTagByVisualID(req.user.tenantID, filteredRequest.visualID);
+ if (tag) {
+ throw new AppError({
+ source: Constants.CENTRAL_SERVER,
+ errorCode: HTTPError.TAG_VISUAL_ID_ALREADY_EXIST_ERROR,
+ message: `Tag with ID '${filteredRequest.id}' already exists`,
+ module: MODULE_NAME, method: 'handleCreateTag',
+ user: req.user,
+ action: action
+ });
+ }
const transactions = await TransactionStorage.getTransactions(req.user.tenantID,
{ tagIDs: [filteredRequest.id.toUpperCase()], hasUserID: true }, Constants.DB_PARAMS_SINGLE_RECORD);
if (!Utils.isEmptyArray(transactions.result)) {
@@ -195,6 +207,7 @@ export default class TagService {
createdOn: new Date(),
userID: filteredRequest.userID,
default: filteredRequest.default,
+ visualID: filteredRequest.visualID
} as Tag;
// Save
await TagStorage.saveTag(req.user.tenantID, newTag);
@@ -699,16 +712,18 @@ export default class TagService {
if (writeHeader) {
headers = [
'id',
+ 'visual ID',
'description',
'firstName',
'name',
- 'email'
+ 'email',
].join(Constants.CSV_SEPARATOR);
}
// Content
const rows = tags.map((tag) => {
const row = [
tag.id,
+ tag.visualID,
tag.description,
tag.user?.firstName,
tag.user?.name,

MODIFY
src/server/rest/v1/service/UtilsService.ts
src/server/rest/v1/service/UtilsService.ts
@@ -1223,6 +1223,16 @@ export default class UtilsService {
user: req.user.id
});
}
+ // Check badge visual ID
+ if (!tag.visualID) {
+ throw new AppError({
+ source: Constants.CENTRAL_SERVER,
+ errorCode: HTTPError.GENERAL_ERROR,
+ message: 'Tag visual ID is mandatory',
+ module: MODULE_NAME, method: 'checkIfUserTagIsValid',
+ user: req.user.id
+ });
+ }
// Check description
if (!tag.description) {
tag.description = `Tag ID '${tag.id}'`;

MODIFY
src/server/rest/v1/service/security/TagSecurity.ts
src/server/rest/v1/service/security/TagSecurity.ts
@@ -39,6 +39,7 @@ export default class TagSecurity {
if (tag) {
filteredTag = {
id: sanitize(tag.id),
+ visualID: sanitize(tag.visualID),
description: sanitize(tag.description),
active: UtilsSecurity.filterBoolean(tag.active),
issuer: UtilsSecurity.filterBoolean(tag.issuer),

MODIFY
src/storage/mongodb/MongoDBStorage.ts
src/storage/mongodb/MongoDBStorage.ts
@@ -104,7 +104,8 @@ export default class MongoDBStorage {
await this.handleIndexesInCollection(tenantID, 'tags', [
{ fields: { deleted: 1, createdOn: 1 } },
{ fields: { issuer: 1, createdOn: 1 } },
- { fields: { userID: 1, issuer: 1 } }
+ { fields: { userID: 1, issuer: 1 } },
+ { fields: { visualID: 1 }, options: { unique: true } }
]);
// Sites/Users
await this.handleIndexesInCollection(tenantID, 'siteusers', [

MODIFY
src/storage/mongodb/TagStorage.ts
src/storage/mongodb/TagStorage.ts
@@ -24,6 +24,7 @@ export default class TagStorage {
issuer: Utils.convertToBoolean(tag.issuer),
active: Utils.convertToBoolean(tag.active),
default: Utils.convertToBoolean(tag.default),
+ visualID: tag.visualID,
ocpiToken: tag.ocpiToken,
description: tag.description
};
@@ -260,6 +261,16 @@ export default class TagStorage {
return tagMDB.count === 1 ? tagMDB.result[0] : null;
}
+ public static async getTagByVisualID(tenantID: string, visualID: string,
+ params: { withUser?: boolean; withNbrTransactions?: boolean } = {}, projectFields?: string[]): Promise<Tag> {
+ const tagMDB = await TagStorage.getTags(tenantID, {
+ visualID: [visualID],
+ withUser: params.withUser,
+ withNbrTransactions: params.withNbrTransactions,
+ }, Constants.DB_PARAMS_SINGLE_RECORD, projectFields);
+ return tagMDB.count === 1 ? tagMDB.result[0] : null;
+ }
+
public static async getFirstActiveUserTag(tenantID: string, userID: string,
params: { issuer?: boolean; } = {}, projectFields?: string[]): Promise<Tag> {
const tagMDB = await TagStorage.getTags(tenantID, {
@@ -284,7 +295,7 @@ export default class TagStorage {
public static async getTags(tenantID: string,
params: {
issuer?: boolean; tagIDs?: string[]; userIDs?: string[]; dateFrom?: Date; dateTo?: Date;
- withUser?: boolean; withUsersOnly?: boolean; withNbrTransactions?: boolean; search?: string, defaultTag?: boolean, active?: boolean
+ withUser?: boolean; withUsersOnly?: boolean; withNbrTransactions?: boolean; search?: string, defaultTag?: boolean, active?: boolean, visualID?: string[]
},
dbParams: DbParams, projectFields?: string[]): Promise<DataResult<Tag>> {
const uniqueTimerID = Logging.traceStart(tenantID, MODULE_NAME, 'getTags');
@@ -312,6 +323,10 @@ export default class TagStorage {
if (!Utils.isEmptyArray(params.tagIDs)) {
filters._id = { $in: params.tagIDs };
}
+ // Visual Tag IDs
+ if (!Utils.isEmptyArray(params.visualID)) {
+ filters.visualID = { $in: params.visualID };
+ }
// Users
if (!Utils.isEmptyArray(params.userIDs)) {
filters.userID = { $in: params.userIDs.map((userID) => Utils.convertToObjectID(userID)) };

MODIFY
src/types/HTTPError.ts
src/types/HTTPError.ts
@@ -27,6 +27,7 @@ export enum HTTPError {
TAG_HAS_TRANSACTIONS = 575,
TAG_ALREADY_EXIST_ERROR = 576,
+ TAG_VISUAL_ID_ALREADY_EXIST_ERROR = 577,
USER_ACCOUNT_LOCKED_ERROR = 590,
USER_ACCOUNT_ALREADY_ACTIVE_ERROR = 591,

Admin Create Tag with visualID