From 0f094b4d1f56032ec8ddd07ad8b81ecbd449c656 Mon Sep 17 00:00:00 2001 From: praveenKDass Date: Mon, 22 Jan 2024 23:02:52 +0530 Subject: [PATCH 01/23] list assets type using orgId --- controllers/v1/assets.js | 31 +++++++++++ generics/constants/api-responses.js | 1 + module/assets/helper.js | 58 +++++++++++++++++++++ module/assets/validator/v1.js | 16 ++++++ module/programs/helper.js | 78 ++++++++++++++++++++++++++++ module/solutions/helper.js | 79 +++++++++++++++++++++++++++++ 6 files changed, 263 insertions(+) create mode 100644 controllers/v1/assets.js create mode 100644 module/assets/helper.js create mode 100644 module/assets/validator/v1.js diff --git a/controllers/v1/assets.js b/controllers/v1/assets.js new file mode 100644 index 00000000..feecb13b --- /dev/null +++ b/controllers/v1/assets.js @@ -0,0 +1,31 @@ + + + +const assetsHelper = require(MODULES_BASE_PATH + "/assets/helper.js"); + +module.exports = class Assets { + + + +list(req) { + return new Promise(async (resolve, reject) => { + try { + + let assestsData = + await assetsHelper.fetchPrograms( + req.query.type, + req.body, + ); + + return resolve(assestsData); + } catch (error) { + return reject({ + status: error.status || httpStatusCode.internal_server_error.status, + message: error.message || httpStatusCode.internal_server_error.message, + errorObject: error + }); + } + }); +} + +} \ No newline at end of file diff --git a/generics/constants/api-responses.js b/generics/constants/api-responses.js index 82f27c4a..6cfa18eb 100644 --- a/generics/constants/api-responses.js +++ b/generics/constants/api-responses.js @@ -204,4 +204,5 @@ module.exports = { "FAILED_TO_CREATE_DOWNLOADABLEURL" : "Failed to generate downloadableUrl", "KEYS_INDEXED_SUCCESSFULLY": 'Keys indexed successfully', "KEYS_ALREADY_INDEXED": 'Keys already indexed', + "ASSETS_SUCCESSFULLY": "Assets fetched successfully " }; diff --git a/module/assets/helper.js b/module/assets/helper.js new file mode 100644 index 00000000..bd7f1657 --- /dev/null +++ b/module/assets/helper.js @@ -0,0 +1,58 @@ + + + + +// Dependencies +const programsHelper = require(MODULES_BASE_PATH + "/programs/helper"); +const solutionsHelper = require(MODULES_BASE_PATH + "/solutions/helper"); + +module.exports = class AssetsHelper { + + static fetchPrograms(queryData,bodyData) { + return new Promise(async (resolve, reject) => { + try { + let organizationAssets; + + switch(queryData){ + case "program": + organizationAssets= await programsHelper.queryForOrganizationPrograms( + bodyData + ); + break; + case "solution": + organizationAssets= await solutionsHelper.queryForOrganizationSolutions( + bodyData + ) + + break; + case "": + let allOrganizationProgram =await programsHelper.queryForOrganizationPrograms( + bodyData + ); + let allOrganizationSolutions =await solutionsHelper.queryForOrganizationSolutions( + bodyData + ) + organizationAssets=[...allOrganizationProgram.data,...allOrganizationSolutions.data]; + + break; + } + + + if(queryData !== ""){ + return resolve({ + result: organizationAssets, + }); + }else{ + return resolve({ + success: true, + message: constants.apiResponses.ASSETS_SUCCESSFULLY, + result: organizationAssets, + + }); + } + } catch (error) { + return reject(error); + } + }); + } +} \ No newline at end of file diff --git a/module/assets/validator/v1.js b/module/assets/validator/v1.js new file mode 100644 index 00000000..ee2ecf81 --- /dev/null +++ b/module/assets/validator/v1.js @@ -0,0 +1,16 @@ + +module.exports = (req) => { + + let assetsValidator = { + + list : function () { + req.checkBody('filters').exists().withMessage("required filters"); + }, + + } + + if (assetsValidator[req.params.method]) { + assetsValidator[req.params.method](); + } + +}; \ No newline at end of file diff --git a/module/programs/helper.js b/module/programs/helper.js index 7280a0aa..cfa36e46 100644 --- a/module/programs/helper.js +++ b/module/programs/helper.js @@ -1218,6 +1218,84 @@ module.exports = class ProgramsHelper { } }); } + /** + * List Program using organization id. + * @method + * @name assets + * @query {String} type - Assets type (program/solutions). + * @returns {Object} - Details of the program under the organization. + */ + + static queryForOrganizationPrograms(bodyData){ + + return new Promise(async (resolve, reject) => { + try{ + let programDocument=[]; + let matchQuery={}; + let filterEmptyStringsFromArray; + + //if there is an empty string then remove from userids + if(!bodyData.filters.userId){ + filterEmptyStringsFromArray=[]; + }else{ + filterEmptyStringsFromArray= bodyData.filters.userId.filter(str => str !== ""); + } + + if(filterEmptyStringsFromArray.length > 0){ + matchQuery={ + $and: [ + {createdFor: {$in:[bodyData.filters.orgId]} }, + { + $or: [ + { owner: { $in: bodyData.filters.userId} }, + { owner: { $exists: false } } , + ] + } + ] + } + }else{ + + matchQuery = {createdFor:{$in:[bodyData.filters.orgId]}} + + } + + let projection1 = {}; + if (bodyData.fields && bodyData.fields.length > 0) { + bodyData.fields.forEach((projectedData) => { + if(projectedData === "objectType"){ + projection1["objectType"]="program" + }else{ + projection1[projectedData] = 1; + } + }); + } + let limitQuery =bodyData.limit; + programDocument.push( + { $match: matchQuery }, + { $project: projection1 }, + {$limit : limitQuery} + ); + let programDocuments = await database.models.programs.aggregate( + programDocument + ); + return resolve({ + success: true, + message: constants.apiResponses.PROGRAM_LIST, + data: programDocuments, + }); + + }catch(error) { + return resolve({ + success: false, + message: error.message, + data: [], + }); + } + }) + + } }; + + const solutionsHelper = require(MODULES_BASE_PATH + "/solutions/helper"); diff --git a/module/solutions/helper.js b/module/solutions/helper.js index c61648fe..ceb52ae5 100644 --- a/module/solutions/helper.js +++ b/module/solutions/helper.js @@ -2404,6 +2404,85 @@ module.exports = class SolutionsHelper { }); } + /** + * List Program using organization id. + * @method + * @name assets + * @query {String} type - Assets type (program/solutions). + * @returns {Object} - Details of the program under the organization. + */ + + static queryForOrganizationSolutions(bodyData){ + + return new Promise(async (resolve, reject) => { + try{ + let solutionDocument=[]; + let matchQuery={}; + let filterEmptyStringsFromArray; + + //if there is an empty string then remove from userids + if(!bodyData.filters.userId){ + filterEmptyStringsFromArray=[]; + }else{ + filterEmptyStringsFromArray= bodyData.filters.userId.filter(str => str !== ""); + } + + if(filterEmptyStringsFromArray.length > 0){ + matchQuery={ + $and: [ + {createdFor: {$in:[bodyData.filters.orgId]} }, + // { author: { $in: bodyData.filters.userId} }, + + // { + // $or: [ + // { author: { $in: bodyData.filters.userId} }, + // { author: { $exists: false } } , + // ] + // } + ] + } + }else{ + + matchQuery = {createdFor:{$in:[bodyData.filters.orgId]}} + + } + + let projection1 = {}; + if (bodyData.fields && bodyData.fields.length > 0) { + bodyData.fields.forEach((projectedData) => { + if(projectedData === "objectType"){ + projection1["objectType"]="solution" + }else{ + projection1[projectedData] = 1; + } + }); + } + let limitQuery =bodyData.limit; + solutionDocument.push( + { $match: matchQuery }, + { $project: projection1 }, + {$limit : limitQuery} + ); + let solutionDocuments = await database.models.solutions.aggregate( + solutionDocument + ); + return resolve({ + success: true, + message: constants.apiResponses.SOLUTIONS_LIST, + data: solutionDocuments, + }); + + }catch(error) { + return resolve({ + success: false, + message: error.message, + data: [], + }); + } + }) + + } + // moved this function to solutions helper to avoid circular dependency with users/helper /** * Create user program and solution From f8e6cdc35fa417c9de03dc08322e655bb80a4cd4 Mon Sep 17 00:00:00 2001 From: praveenKDass Date: Tue, 23 Jan 2024 15:26:05 +0530 Subject: [PATCH 02/23] fetch both assets when type undefined --- module/assets/helper.js | 13 ++++++++----- module/assets/validator/v1.js | 2 ++ module/programs/helper.js | 27 +++++++++++++++++---------- module/solutions/helper.js | 19 ++++++++++--------- 4 files changed, 37 insertions(+), 24 deletions(-) diff --git a/module/assets/helper.js b/module/assets/helper.js index bd7f1657..c9fd802d 100644 --- a/module/assets/helper.js +++ b/module/assets/helper.js @@ -11,12 +11,14 @@ module.exports = class AssetsHelper { static fetchPrograms(queryData,bodyData) { return new Promise(async (resolve, reject) => { try { + let organizationAssets; switch(queryData){ case "program": organizationAssets= await programsHelper.queryForOrganizationPrograms( - bodyData + bodyData, + queryData ); break; case "solution": @@ -25,9 +27,10 @@ module.exports = class AssetsHelper { ) break; - case "": + default: let allOrganizationProgram =await programsHelper.queryForOrganizationPrograms( - bodyData + bodyData, + queryData ); let allOrganizationSolutions =await solutionsHelper.queryForOrganizationSolutions( bodyData @@ -38,7 +41,7 @@ module.exports = class AssetsHelper { } - if(queryData !== ""){ + if(queryData !== "" && queryData !== undefined){ return resolve({ result: organizationAssets, }); @@ -48,7 +51,7 @@ module.exports = class AssetsHelper { message: constants.apiResponses.ASSETS_SUCCESSFULLY, result: organizationAssets, - }); + }); } } catch (error) { return reject(error); diff --git a/module/assets/validator/v1.js b/module/assets/validator/v1.js index ee2ecf81..69990302 100644 --- a/module/assets/validator/v1.js +++ b/module/assets/validator/v1.js @@ -5,6 +5,8 @@ module.exports = (req) => { list : function () { req.checkBody('filters').exists().withMessage("required filters"); + req.checkBody('filters.orgId').exists().withMessage("required orgId"); + }, } diff --git a/module/programs/helper.js b/module/programs/helper.js index cfa36e46..3d39135f 100644 --- a/module/programs/helper.js +++ b/module/programs/helper.js @@ -1226,8 +1226,7 @@ module.exports = class ProgramsHelper { * @returns {Object} - Details of the program under the organization. */ - static queryForOrganizationPrograms(bodyData){ - + static queryForOrganizationPrograms(bodyData,queryData){ return new Promise(async (resolve, reject) => { try{ let programDocument=[]; @@ -1245,14 +1244,11 @@ module.exports = class ProgramsHelper { matchQuery={ $and: [ {createdFor: {$in:[bodyData.filters.orgId]} }, - { - $or: [ - { owner: { $in: bodyData.filters.userId} }, - { owner: { $exists: false } } , - ] - } + { owner: { $in: bodyData.filters.userId} }, ] - } + + + } }else{ matchQuery = {createdFor:{$in:[bodyData.filters.orgId]}} @@ -1269,11 +1265,22 @@ module.exports = class ProgramsHelper { } }); } - let limitQuery =bodyData.limit; + let limitQuery; + //omit the limit if there is no type + if(queryData === "" || queryData === undefined){ + limitQuery =Number.MAX_SAFE_INTEGER; + }else{ + limitQuery =bodyData.limit; + + } + + + programDocument.push( { $match: matchQuery }, { $project: projection1 }, {$limit : limitQuery} + ); let programDocuments = await database.models.programs.aggregate( programDocument diff --git a/module/solutions/helper.js b/module/solutions/helper.js index ceb52ae5..5b1dc676 100644 --- a/module/solutions/helper.js +++ b/module/solutions/helper.js @@ -2431,14 +2431,8 @@ module.exports = class SolutionsHelper { matchQuery={ $and: [ {createdFor: {$in:[bodyData.filters.orgId]} }, - // { author: { $in: bodyData.filters.userId} }, - - // { - // $or: [ - // { author: { $in: bodyData.filters.userId} }, - // { author: { $exists: false } } , - // ] - // } + { author: { $in: bodyData.filters.userId} }, + {isAPrivateProgram:false} ] } }else{ @@ -2457,7 +2451,14 @@ module.exports = class SolutionsHelper { } }); } - let limitQuery =bodyData.limit; + let limitQuery; + //omit the limit if there is no type + if(queryData === "" || queryData === undefined){ + limitQuery =Number.MAX_SAFE_INTEGER; + }else{ + limitQuery =bodyData.limit; + + } solutionDocument.push( { $match: matchQuery }, { $project: projection1 }, From c2cc254f13e9134f51567f35816b5d20398996e4 Mon Sep 17 00:00:00 2001 From: praveenKDass Date: Tue, 23 Jan 2024 16:04:07 +0530 Subject: [PATCH 03/23] projection added --- module/programs/helper.js | 11 ++++++++++- module/solutions/helper.js | 11 ++++++++++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/module/programs/helper.js b/module/programs/helper.js index 3d39135f..891fe2bd 100644 --- a/module/programs/helper.js +++ b/module/programs/helper.js @@ -1264,7 +1264,16 @@ module.exports = class ProgramsHelper { projection1[projectedData] = 1; } }); - } + } else{ + projection1={ + "_id":1, + "name":1, + "status":1, + "owner":1, + "orgId":1, + "objectType":"program" + } + } let limitQuery; //omit the limit if there is no type if(queryData === "" || queryData === undefined){ diff --git a/module/solutions/helper.js b/module/solutions/helper.js index 5b1dc676..91a1407b 100644 --- a/module/solutions/helper.js +++ b/module/solutions/helper.js @@ -2450,7 +2450,16 @@ module.exports = class SolutionsHelper { projection1[projectedData] = 1; } }); - } + } else{ + projection1={ + "_id":1, + "name":1, + "status":1, + "owner":1, + "orgId":1, + "objectType":"solution" + } + } let limitQuery; //omit the limit if there is no type if(queryData === "" || queryData === undefined){ From 29aada4cb165a85c393e652cd692a2a6218b1bd1 Mon Sep 17 00:00:00 2001 From: praveenKDass Date: Wed, 24 Jan 2024 19:20:41 +0530 Subject: [PATCH 04/23] kafka event for owner transfer --- config/kafka.js | 10 +- generics/constants/common.js | 4 + generics/kafka/consumers/assetsTransfer.js | 45 +++ module/assets/helper.js | 390 ++++++++++++++++++--- module/user-extension/helper.js | 45 +++ module/user-roles/helper.js | 12 + 6 files changed, 456 insertions(+), 50 deletions(-) create mode 100644 generics/kafka/consumers/assetsTransfer.js diff --git a/config/kafka.js b/config/kafka.js index 5e0da409..9a2412d1 100644 --- a/config/kafka.js +++ b/config/kafka.js @@ -9,7 +9,8 @@ //dependencies const kafka = require('kafka-node'); const USER_DELETE_TOPIC = process.env.USER_DELETE_TOPIC; -const USER_DELETE_ON_OFF = process.env.USER_DELETE_ON_OFF +const USER_DELETE_ON_OFF = process.env.USER_DELETE_ON_OFF; +const TRANSFER_OWNERSHIP_JOB =process.env.TRANSFER_OWNERSHIP_JOB; /** * Kafka configurations. * @function @@ -81,12 +82,19 @@ const connect = function() { if (message && message.topic === USER_DELETE_TOPIC) { userDeleteConsumer.messageReceived(message); } + // call assets or ownership Transfer consumer + if (message && message.topic === TRANSFER_OWNERSHIP_JOB) { + assetsTransferConsumer.messageReceived(message); + } }); consumer.on("error", async function (error) { if (error.topics && error.topics[0] === USER_DELETE_TOPIC) { userDeleteConsumer.errorTriggered(error); } + if (error.topics && error.topics[0] === TRANSFER_OWNERSHIP_JOB) { + assetsTransferConsumer.errorTriggered(error); + } }); } }; diff --git a/generics/constants/common.js b/generics/constants/common.js index 1055ec57..f07e1d4b 100644 --- a/generics/constants/common.js +++ b/generics/constants/common.js @@ -88,9 +88,13 @@ TELEMTRY_EVENT_LOGGER: "TelemetryEventLogger", INFO_LEVEL: "INFO", DELETE_STATE: "Delete", + TRANSFER_STATE:"", USER_DELETE_TYPE: "DeleteUserStatus", AUDIT: "AUDIT", DELETE_USER: "delete-user", + TRANSFER_OWNERSHIP_JOB:"ownership-transfer", + OWNERSHIP_TRANSFER_TYPE:"", + OWNERSHIP_TRANSFER_MODULE:"", USER: "User", USER_DELETE_MODULE: "userDelete", OFF: "OFF" diff --git a/generics/kafka/consumers/assetsTransfer.js b/generics/kafka/consumers/assetsTransfer.js new file mode 100644 index 00000000..e97164b3 --- /dev/null +++ b/generics/kafka/consumers/assetsTransfer.js @@ -0,0 +1,45 @@ + + + + +const assetsHelper = require(MODULES_BASE_PATH + "/assets/helper.js"); + + + + + +var messageReceived = function (message) { + return new Promise(async function (resolve, reject) { + try { + let originalMessage = JSON.parse(message.value); + let parsedMessage = originalMessage.value; + if (parsedMessage.edata.action === constants.common.TRANSFER_OWNERSHIP_JOB) { + let ownershipTransferResponse = await assetsHelper.ownershipTransfer(parsedMessage); + + if (ownershipTransferResponse.success == true) { + return resolve("Message Processed."); + } else { + return resolve("Message Processed."); + } + } + } catch (error) { + return reject(error); + } + }); + }; + + var errorTriggered = function (error) { + return new Promise(function (resolve, reject) { + try { + return resolve(error); + } catch (error) { + return reject(error); + } + }); + }; + + module.exports = { + messageReceived: messageReceived, + errorTriggered: errorTriggered, + }; + \ No newline at end of file diff --git a/module/assets/helper.js b/module/assets/helper.js index c9fd802d..329a3cd2 100644 --- a/module/assets/helper.js +++ b/module/assets/helper.js @@ -1,61 +1,353 @@ - - - - // Dependencies const programsHelper = require(MODULES_BASE_PATH + "/programs/helper"); const solutionsHelper = require(MODULES_BASE_PATH + "/solutions/helper"); +const userExtensionsHelper = require(MODULES_BASE_PATH + + "/user-extension/helper"); +const userRolesHelper = require(MODULES_BASE_PATH + "/user-roles/helper"); +const kafkaProducersHelper = require(ROOT_PATH + "/generics/kafka/producers"); module.exports = class AssetsHelper { - - static fetchPrograms(queryData,bodyData) { - return new Promise(async (resolve, reject) => { - try { - - let organizationAssets; - - switch(queryData){ - case "program": - organizationAssets= await programsHelper.queryForOrganizationPrograms( - bodyData, - queryData + static fetchPrograms(queryData, bodyData) { + return new Promise(async (resolve, reject) => { + try { + let organizationAssets; + + switch (queryData) { + case "program": + organizationAssets = + await programsHelper.queryForOrganizationPrograms( + bodyData, + queryData + ); + break; + case "solution": + organizationAssets = + await solutionsHelper.queryForOrganizationSolutions(bodyData); + + break; + default: + let allOrganizationProgram = + await programsHelper.queryForOrganizationPrograms( + bodyData, + queryData + ); + let allOrganizationSolutions = + await solutionsHelper.queryForOrganizationSolutions(bodyData); + organizationAssets = [ + ...allOrganizationProgram.data, + ...allOrganizationSolutions.data, + ]; + + break; + } + + if (queryData !== "" && queryData !== undefined) { + return resolve({ + result: organizationAssets, + }); + } else { + return resolve({ + success: true, + message: constants.apiResponses.ASSETS_SUCCESSFULLY, + result: organizationAssets, + }); + } + } catch (error) { + return reject(error); + } + }); + } + + static ownershipTransfer(ownershipTransferEvent) { + return new Promise(async (resolve, reject) => { + try { + let reqData = ownershipTransferEvent.edata; + let fromFindQuery = { + userId: reqData.fromUserProfile.userId, + [programRoles]: { $exists: true }, + }; + let fromUpdateQuery = { + userId: reqData.fromUserProfile.userId, + $unset: { programRoles: [] }, + }; + let toFindQuery = { + userId: reqData.toUserProfile.userId, + [programRoles]: { $exists: true }, + }; + const newCollectionForUserExtension = { + roles: [], + status: "active", + isDeleted: false, + removedFromHomeScreen: [], + improvementProjects: [], + platformRoles: [ + { + roleId: userRoleId, + code: "PROGRAM_MANAGER", + programs: [], + }, + { + roleId: userRoleId, + code: "PROGRAM_DESIGNER", + entities: [], + isAPlatformRole: true, + programs: [], + }, + ], + deleted: false, + userId: toUserProfile.userId, + externalId: toUserProfile.userName, + updatedBy: reqData.actionBy.userId, + createdBy: reqData.actionBy.userId, + updatedAt: new Date(), + createdAt: new Date(), + __v: 0, + }; + if ( + reqData.actionBy.userId && + reqData.fromUserProfile.userId && + reqData.toUserProfile.userId + ) { + if (!reqData.assetInformation.objectType) { + let fromUserData = await userExtensionsHelper.findOne( + fromFindQuery + ); + let allAssetsData = fromUserData.programRoles; + if (fromUserData) { + let toUserData = await userExtensionsHelper.findOne(toFindQuery); + + let updateQuery = { + userId: reqData.toUserProfile.userId, + $set: { programRoles: allAssetsData }, + upsert: true, + }; + if (toUserData) { + if (!toUserData.programRoles) { + let insertProgramRolesQuery = { + userId: reqData.toUserProfile.userId, + programRoles: [], + }; + let insertProgram = await userExtensionsHelper.insertOne( + insertProgramRolesQuery + ); + + if (insertProgram) { + let updateProgram; + if ( + reqData.toUserProfile.role === "PROGRAM_MANAGER" || + reqData.toUserProfile.role === "PROGRAM_DESIGNER" + ) { + await userExtensionsHelper.updateOne(updateQuery); + } + if (updateProgram) { + let deleteProgram = await userExtensionsHelper.updateOne( + fromUpdateQuery + ); + // resData=updateProgram; + // return resolve(updateProgram); + } + } + } else { + let updateProgram; + if ( + reqData.toUserProfile.role === "PROGRAM_MANAGER" || + reqData.toUserProfile.role === "PROGRAM_DESIGNER" + ) { + await userExtensionsHelper.updateOne(updateQuery); + } + if (updateProgram) { + let deleteProgram = await userExtensionsHelper.updateOne( + fromUpdateQuery + ); + // resData=updateProgram; + + // return resolve(updateProgram); + } + } + } else { + let findProgramManagerQuery = { + code: { $in: reqData.toUserProfile.role }, + }; + let findProgramManagerId; + findProgramManagerId = await userRolesHelper.findOne( + findProgramManagerQuery ); - break; - case "solution": - organizationAssets= await solutionsHelper.queryForOrganizationSolutions( - bodyData - ) - - break; - default: - let allOrganizationProgram =await programsHelper.queryForOrganizationPrograms( - bodyData, - queryData + + const roleToUpdate = + newCollectionForUserExtension.platformRoles.find( + (role) => + role.code === + reqData.toUserProfile.role.includes(role.code) + ); + if (roleToUpdate) { + roleToUpdate.roleId = findProgramManagerId._id; + newCollectionForUserExtension.platformRoles = + newCollectionForUserExtension.platformRoles.filter( + (role) => + role.code !== + reqData.toUserProfile.role.includes(role.code) + ); + } + let createUserExtensions = await userExtensionsHelper.createOne( + newCollectionForUserExtension + ); + if (createUserExtensions) { + ownershipTransfer(ownershipTransferEvent); + } + } + } + } else { + const fromUserData = await userExtensionsHelper.findOne( + fromFindQuery + ); + let programRoleAssets = fromUserData.programRoles; + const typeOfAssetsToMove = reqData.assetInformation.objectType; + if (fromUserData) { + //update program or solution inside the programRoles + let toUserData = await userExtensionsHelper.findOne(toFindQuery); + if (toUserData) { + if (!toUserData.programRoles) { + let insertProgramRolesQuery = { + userId: reqData.toUserProfile.userId, + programRoles: [], + }; + let insertProgramRoles = await userExtensionsHelper.insertOne( + insertProgramRolesQuery + ); + if (insertProgramRoles) { + const arrayToMove = programRoleAssets.filter( + (role) => role[typeOfAssetsToMove] + ); + + let updateBasedonTypeQuery = { + userId: reqData.toUserProfile.userId, + $push: { programRoles: { $each: arrayToMove } }, + upsert: true, + }; + let updateFromUserBasedonTypeQuery = { + userId: reqData.fromUserProfile.userId, + $pull: { + programRoles: { + [typeOfAssetsToMove]: { $exists: true }, + }, + }, + upsert: true, + }; + let updateBasedonType; + if ( + reqData.toUserProfile.role === "PROGRAM_MANAGER" || + reqData.toUserProfile.role === "PROGRAM_DESIGNER" + ) { + updateBasedonType = await userExtensionsHelper.updateOne( + updateBasedonTypeQuery + ); + } + if (updateBasedonType) { + let deleteBasedonTypeinFromUser = + await userExtensionsHelper.updateOne( + updateFromUserBasedonTypeQuery + ); + // resData=updateBasedonType; + + // return resolve(updateBasedonType); + } + } + } + } else { + let findProgramManagerQuery = { + code: { $in: reqData.toUserProfile.role }, + }; + let findProgramManagerId; + findProgramManagerId = await userRolesHelper.findOne( + findProgramManagerQuery ); - let allOrganizationSolutions =await solutionsHelper.queryForOrganizationSolutions( - bodyData - ) - organizationAssets=[...allOrganizationProgram.data,...allOrganizationSolutions.data]; - break; + const roleToUpdate = + newCollectionForUserExtension.platformRoles.find((role) => + reqData.toUserProfile.role.includes(role.code) + ); + if (roleToUpdate) { + roleToUpdate.roleId = findProgramManagerId._id; + data.platformRoles = + newCollectionForUserExtension.platformRoles.filter( + (role) => + role.code !== + reqData.toUserProfile.role.includes(role.code) + ); + } + let createUserExtensions = await userExtensionsHelper.createOne( + newCollectionForUserExtension + ); + if (createUserExtensions) { + ownershipTransfer(ownershipTransferEvent); + } } - - - if(queryData !== "" && queryData !== undefined){ - return resolve({ - result: organizationAssets, - }); - }else{ - return resolve({ - success: true, - message: constants.apiResponses.ASSETS_SUCCESSFULLY, - result: organizationAssets, - - }); + } } - } catch (error) { - return reject(error); + } + + let solutionFilter = { + author: reqData.touserProfle.userId, + + } + let updateSolutions = { + $set: { + author:reqData. touserProfle.userId, + crator: reqData.touserProfile.firstname }, + }; + let solutionLicenseFilter = { + author:reqData. fromuserProfile.userId, + license: {$exists:true, $ne:""}, + } + let updateSolutionsLicense = { + $set: { + "license.author": toUserProfile.firstName, + "license.creator": toUserProfile.firstName + }, + }; + + let updateUserSolutions = [ solutionsHelper.updateMany(solutionFilter, updateSolutions), solutionsHelper.updateMany(solutionLicenseFilter, updateSolutionsLicense)] + let updateUserSolutionsDataResult = await Promise.all(updateUserSolutions); + + if (updateUserSolutionsDataResult && (updateUserSolutionsDataResult[0].nModified > 0 || updateUserSolutionsDataResult[1].nModified > 0 )) { + if(telemetryEventOnOff !== constants.common.OFF){ + /** + * Telemetry Raw Event + * {"eid":"","ets":1700188609568,"ver":"3.0","mid":"e55a91cd-7964-46bc-b756-18750787fb32","actor":{},"context":{"channel":"","pdata":{"id":"projectservice","pid":"manage-learn","ver":"7.0.0"},"env":"","cdata":[{"id":"adf3b621-619b-4195-a82d-d814eecdb21f","type":"Request"}],"rollup":{}},"object":{},"edata":{}} + */ + let rawEvent = await gen.utils.generateTelemetryEventSkeletonStructure(); + rawEvent.eid = constants.common.AUDIT; + rawEvent.context.channel = userDeleteEvent.context.channel; + rawEvent.context.env = constants.common.USER; + rawEvent.edata.state = constants.common.TRANSFER_STATE; + rawEvent.edata.type = constants.common.OWNERSHIP_TRANSFER_TYPE; + rawEvent.edata.props = []; + let userObject = { + id: reqData.toUserProfile.userId, + type: constants.common.USER, + }; + rawEvent.actor = userObject; + rawEvent.object = userObject; + rawEvent.context.pdata.pid = `${process.env.ID}.${constants.common.OWNERSHIP_TRANSFER_MODULE}` + + let telemetryEvent = await gen.utils.generateTelemetryEvent(rawEvent); + telemetryEvent.lname = constants.common.TELEMTRY_EVENT_LOGGER; + telemetryEvent.level = constants.common.INFO_LEVEL + + await kafkaProducersHelper.pushTelemetryEventToKafka(telemetryEvent); } - }); + return resolve({ + success: true, + }); + } else { + return resolve({ + success: true, + }); + } + + } catch (error) { + return reject(error); } -} \ No newline at end of file + }); + } +}; diff --git a/module/user-extension/helper.js b/module/user-extension/helper.js index 89c1d646..bb2a94f0 100644 --- a/module/user-extension/helper.js +++ b/module/user-extension/helper.js @@ -681,8 +681,53 @@ module.exports = class UserExtensionHelper { } }) } + + static findOne(query){ + return new Promise(async (resolve, reject) => { + try{ + let findUser =await database.models.userExtension.findOne(query) + resolve(findUser) + }catch(error){ + reject(error); + } + }) + } + + static InsertOne(query){ + return new Promise(async (resolve, reject) => { + try{ + let insertProgram =await database.models.userExtension.insertOne(query) + resolve(insertProgram) + }catch(error){ + reject(error); + } + }) + } + static updateOne(query){ + return new Promise(async (resolve, reject) => { + try{ + let updateProgram =await database.models.userExtension.updateOne(query) + resolve(updateProgram) + }catch(error){ + reject(error); + } + }) + } + static createOne(data){ + return new Promise(async (resolve, reject) => { + try{ + let createUserExtension=await database.models.userExtension.create(data) + resolve(createUserExtension) + }catch(error){ + reject(error); + } + }) + } + }; + + diff --git a/module/user-roles/helper.js b/module/user-roles/helper.js index a0bfafd2..56ddd04a 100644 --- a/module/user-roles/helper.js +++ b/module/user-roles/helper.js @@ -87,4 +87,16 @@ module.exports = class UserRolesHelper { }); } + + static findOne(query){ + return new Promise(async (resolve, reject) => { + try{ + let findUser =await database.models.userRoles.findOne(query) + resolve(findUser) + }catch(error){ + reject(error); + } + }) +} + }; \ No newline at end of file From 11aa228be7d1ead78914a6bd96ac6c3e568fa2e3 Mon Sep 17 00:00:00 2001 From: praveenKDass Date: Tue, 30 Jan 2024 03:49:35 +0530 Subject: [PATCH 05/23] worked on PR changes and fixed bugs on ownerassetsTransfer --- controllers/v1/assets.js | 105 ++++-- generics/constants/common.js | 9 +- generics/kafka/consumers/assetsTransfer.js | 49 ++- module/assets/helper.js | 380 ++++++++++----------- module/programs/helper.js | 2 +- module/user-extension/helper.js | 21 +- 6 files changed, 342 insertions(+), 224 deletions(-) diff --git a/controllers/v1/assets.js b/controllers/v1/assets.js index feecb13b..76315fec 100644 --- a/controllers/v1/assets.js +++ b/controllers/v1/assets.js @@ -1,31 +1,92 @@ - - - const assetsHelper = require(MODULES_BASE_PATH + "/assets/helper.js"); module.exports = class Assets { + /** + * Get organisation program and solution. + * @name list + * @api {get} /kendra/api/v1/assets/list?type=program or solution. + * @apiHeader {String} X-authenticated-user-token Authenticity token + * @apiSampleRequest v1/assets/list?type=program + * @apiParamExample {json} Request-Body: + { + "filters": { + "orgId": "01269934121990553633", + "userId":["5d7255bb-1216-460e-9228-59b60230b1c1","5d7255bb-1216-460e-9228-59b60230b1c2"] + }, + "fields": [ + "_id", + "name", + "status", + "owner", + "orgId", + "objectType" + ], + "limit": 1000 +} + * @apiUse successBody + * @apiUse errorBody + * @apiParamExample {json} Response: + * + * { + "message": "Assets fetched successfully ", + "status": 200, + "result": [ + { + "_id": "650be4aea302f0000807b2b0", + "status": "active", + "owner": "5d7255bb-1216-460e-9228-59b60230b1c1", + "name": "6.0 CSP 7 Program already expired", + "objectType": "program" + }, + { + "_id": "650be6c4a302f0000807b379", + "status": "active", + "owner": "5d7255bb-1216-460e-9228-59b60230b1c1", + "name": "6.0 CSP 2 Program expired in one day with no start date and end date ", + "objectType": "program" + }, + ] +} - + */ -list(req) { + list(req) { return new Promise(async (resolve, reject) => { - try { - - let assestsData = - await assetsHelper.fetchPrograms( - req.query.type, - req.body, + try { + let assestsData = await assetsHelper.fetchPrograms( + req.query.type, + req.body ); - - return resolve(assestsData); - } catch (error) { - return reject({ - status: error.status || httpStatusCode.internal_server_error.status, - message: error.message || httpStatusCode.internal_server_error.message, - errorObject: error - }); - } + + return resolve(assestsData); + } catch (error) { + return reject({ + status: error.status || httpStatusCode.internal_server_error.status, + message: + error.message || httpStatusCode.internal_server_error.message, + errorObject: error, + }); + } }); -} + } + + -} \ No newline at end of file + kafkaResponse(req) { + return new Promise(async (resolve, reject) => { + try { + let assestsData = await assetsTransferConsumer.messageReceived(req.body); +; + + return resolve(assestsData); + } catch (error) { + return reject({ + status: error.status || httpStatusCode.internal_server_error.status, + message: + error.message || httpStatusCode.internal_server_error.message, + errorObject: error, + }); + } + }); + } +}; diff --git a/generics/constants/common.js b/generics/constants/common.js index f07e1d4b..19096441 100644 --- a/generics/constants/common.js +++ b/generics/constants/common.js @@ -88,14 +88,15 @@ TELEMTRY_EVENT_LOGGER: "TelemetryEventLogger", INFO_LEVEL: "INFO", DELETE_STATE: "Delete", - TRANSFER_STATE:"", + TRANSFER_STATE:"Transfer", USER_DELETE_TYPE: "DeleteUserStatus", AUDIT: "AUDIT", DELETE_USER: "delete-user", TRANSFER_OWNERSHIP_JOB:"ownership-transfer", - OWNERSHIP_TRANSFER_TYPE:"", - OWNERSHIP_TRANSFER_MODULE:"", + OWNERSHIP_TRANSFER_TYPE:"OwnerTransferStatus", + OWNERSHIP_TRANSFER_MODULE:"ownerTransfer", USER: "User", USER_DELETE_MODULE: "userDelete", - OFF: "OFF" + OFF: "OFF", + PROGRAM_DESIGNER:"PROGRAM_DESIGNER", }; diff --git a/generics/kafka/consumers/assetsTransfer.js b/generics/kafka/consumers/assetsTransfer.js index e97164b3..70801fe6 100644 --- a/generics/kafka/consumers/assetsTransfer.js +++ b/generics/kafka/consumers/assetsTransfer.js @@ -4,7 +4,53 @@ const assetsHelper = require(MODULES_BASE_PATH + "/assets/helper.js"); - +/** + * Ownership transfer message received. + * @function + * @name messageReceived + * @param {Object} message - consumer data + * { + "highWaterOffset": 63, + "key": "", + "offset": 62, + "partition": 0, + "topic": "ownershiptransfer", + "edata": { + "action": "ownership-transfer", + "organisationId": "01269934121990553633", + "context": "Ownership Transfer", + "actionBy": { + "userId": "5d7255bb-1216-460e-9228-59b60230b1c1", + "userName": "" + }, + "fromUserProfile": { + "userId": "fca2925f-1eee-4654-9177-fece3fd6afc9", + "userName": "", + "channel": "", + "organisationId": "", + "roles": [ + "PROGRAM_MANAGER" + ] + }, + "toUserProfile": { + "userId": "289bc48c-0a74-4650-ac99-187575a3a8a9", + "userName": "", + "firstName": "", + "lastName": "", + "roles": [ + "PROGRAM_MANAGER" + ] + }, + "assetInformation": { + "objectType": "PROGRAM_MANAGER", + "identifier": "{{resource_identifier}}" + }, + "iteration": 1 + } +} +} + * @returns {Promise} return a Promise. + */ @@ -13,6 +59,7 @@ var messageReceived = function (message) { try { let originalMessage = JSON.parse(message.value); let parsedMessage = originalMessage.value; + // let parsedMessage = message; if (parsedMessage.edata.action === constants.common.TRANSFER_OWNERSHIP_JOB) { let ownershipTransferResponse = await assetsHelper.ownershipTransfer(parsedMessage); diff --git a/module/assets/helper.js b/module/assets/helper.js index 329a3cd2..94dacf1f 100644 --- a/module/assets/helper.js +++ b/module/assets/helper.js @@ -64,222 +64,189 @@ module.exports = class AssetsHelper { let reqData = ownershipTransferEvent.edata; let fromFindQuery = { userId: reqData.fromUserProfile.userId, - [programRoles]: { $exists: true }, + platformRoles: { $exists: true }, }; let fromUpdateQuery = { userId: reqData.fromUserProfile.userId, - $unset: { programRoles: [] }, + }; + let fromUpdateUnsetQuery = { + $set: { platformRoles: [] }, }; let toFindQuery = { userId: reqData.toUserProfile.userId, - [programRoles]: { $exists: true }, + platformRoles: { $exists: true }, }; const newCollectionForUserExtension = { - roles: [], - status: "active", - isDeleted: false, - removedFromHomeScreen: [], - improvementProjects: [], - platformRoles: [ - { - roleId: userRoleId, - code: "PROGRAM_MANAGER", - programs: [], - }, - { - roleId: userRoleId, - code: "PROGRAM_DESIGNER", - entities: [], - isAPlatformRole: true, - programs: [], - }, - ], - deleted: false, - userId: toUserProfile.userId, - externalId: toUserProfile.userName, + // roles: [], + // status: "active", + // isDeleted: false, + // removedFromHomeScreen: [], + // improvementProjects: [], + platformRoles: [], + // deleted: false, + userId: reqData.toUserProfile.userId, + externalId: reqData.toUserProfile.userName, updatedBy: reqData.actionBy.userId, createdBy: reqData.actionBy.userId, - updatedAt: new Date(), - createdAt: new Date(), - __v: 0, }; if ( reqData.actionBy.userId && reqData.fromUserProfile.userId && reqData.toUserProfile.userId ) { - if (!reqData.assetInformation.objectType) { - let fromUserData = await userExtensionsHelper.findOne( - fromFindQuery - ); - let allAssetsData = fromUserData.programRoles; - if (fromUserData) { - let toUserData = await userExtensionsHelper.findOne(toFindQuery); + let fromUserData = await userExtensionsHelper.findOne(fromFindQuery); + let allAssetsData = fromUserData.platformRoles; + const typeOfAssetsToMove = reqData.assetInformation.objectType; - let updateQuery = { - userId: reqData.toUserProfile.userId, - $set: { programRoles: allAssetsData }, - upsert: true, - }; - if (toUserData) { - if (!toUserData.programRoles) { - let insertProgramRolesQuery = { - userId: reqData.toUserProfile.userId, - programRoles: [], - }; - let insertProgram = await userExtensionsHelper.insertOne( - insertProgramRolesQuery - ); + //Query for object type not present on reqData.assetInformation.objectType - if (insertProgram) { - let updateProgram; - if ( - reqData.toUserProfile.role === "PROGRAM_MANAGER" || - reqData.toUserProfile.role === "PROGRAM_DESIGNER" - ) { - await userExtensionsHelper.updateOne(updateQuery); - } - if (updateProgram) { - let deleteProgram = await userExtensionsHelper.updateOne( - fromUpdateQuery - ); - // resData=updateProgram; - // return resolve(updateProgram); - } - } - } else { - let updateProgram; - if ( - reqData.toUserProfile.role === "PROGRAM_MANAGER" || - reqData.toUserProfile.role === "PROGRAM_DESIGNER" - ) { - await userExtensionsHelper.updateOne(updateQuery); - } - if (updateProgram) { - let deleteProgram = await userExtensionsHelper.updateOne( - fromUpdateQuery - ); - // resData=updateProgram; + let updateQuery = { + userId: reqData.toUserProfile.userId, + }; + let updateSetQuery = { + $push: { platformRoles: { $each: allAssetsData } }, + }; + //Query for object type present on reqData.assetInformation.objectType - // return resolve(updateProgram); - } + const arrayToMove = allAssetsData.filter( + (role) => role.code === typeOfAssetsToMove + ); + const updateToQuery = { + userId: reqData.toUserProfile.userId, + "platformRoles.code": typeOfAssetsToMove, + }; + + const updateToFields = { + $push: { + "platformRoles.$.programs": { $each: arrayToMove?.[0]?.programs }, + }, + }; + const arrayFilters = [{ "elem.code": typeOfAssetsToMove }]; + + let deleteProgramFromUserQuery = { + userId: reqData.fromUserProfile.userId, + "platformRoles.code": typeOfAssetsToMove, + }; + let deleteProgramFromUserField = { + $pull: { + "platformRoles.$.programs": { $in: arrayToMove?.[0]?.programs }, + }, + }; + if (fromUserData) { + if (!typeOfAssetsToMove || !typeOfAssetsToMove > 0) { + let toUserWithoutObjectTypeData = await userExtensionsHelper.findOne( + _.omit(updateToQuery, ["platformRoles.code"]) + ); + if (toUserWithoutObjectTypeData) { + let updateProgramRoles = await userExtensionsHelper.updateOne( + updateQuery, + updateSetQuery + ); + if (updateProgramRoles) { + let deleteProgram = await userExtensionsHelper.updateOne( + fromUpdateQuery, + fromUpdateUnsetQuery + ); } } else { let findProgramManagerQuery = { - code: { $in: reqData.toUserProfile.role }, + code: { $in: reqData.toUserProfile.roles }, }; - let findProgramManagerId; - findProgramManagerId = await userRolesHelper.findOne( + + let findProgramManagerId = await userRolesHelper.findOne( findProgramManagerQuery ); - - const roleToUpdate = - newCollectionForUserExtension.platformRoles.find( - (role) => - role.code === - reqData.toUserProfile.role.includes(role.code) - ); - if (roleToUpdate) { - roleToUpdate.roleId = findProgramManagerId._id; - newCollectionForUserExtension.platformRoles = - newCollectionForUserExtension.platformRoles.filter( - (role) => - role.code !== - reqData.toUserProfile.role.includes(role.code) - ); - } let createUserExtensions = await userExtensionsHelper.createOne( newCollectionForUserExtension ); if (createUserExtensions) { - ownershipTransfer(ownershipTransferEvent); + let updateProgramRolesForNewUser = + await userExtensionsHelper.updateOne( + updateQuery, + updateSetQuery + ); + if (updateProgramRolesForNewUser) { + let deleteProgram = await userExtensionsHelper.updateOne( + fromUpdateQuery, + fromUpdateUnsetQuery + ); + } } } - } - } else { - const fromUserData = await userExtensionsHelper.findOne( - fromFindQuery - ); - let programRoleAssets = fromUserData.programRoles; - const typeOfAssetsToMove = reqData.assetInformation.objectType; - if (fromUserData) { - //update program or solution inside the programRoles - let toUserData = await userExtensionsHelper.findOne(toFindQuery); + } else { + let toUserData = await userExtensionsHelper.findOne( + updateToQuery, + updateToFields + ); + if (toUserData) { - if (!toUserData.programRoles) { - let insertProgramRolesQuery = { - userId: reqData.toUserProfile.userId, - programRoles: [], - }; - let insertProgramRoles = await userExtensionsHelper.insertOne( - insertProgramRolesQuery - ); - if (insertProgramRoles) { - const arrayToMove = programRoleAssets.filter( - (role) => role[typeOfAssetsToMove] + //Move the data when typeOfAssetsToMove is present in to user data + const arrayToMoveInToUser = toUserData.platformRoles.filter( + (role) => role.code === typeOfAssetsToMove + ); + + if (arrayToMoveInToUser) { + let updateProgram = + await userExtensionsHelper.findOneandUpdate( + updateToQuery, + updateToFields, + arrayFilters ); + if (updateProgram) { + // let updateOperation = !reqData.assetInformation.objectType? fromUpdateQuery: updateFromUserBasedonTypeQuery - let updateBasedonTypeQuery = { - userId: reqData.toUserProfile.userId, - $push: { programRoles: { $each: arrayToMove } }, - upsert: true, - }; - let updateFromUserBasedonTypeQuery = { - userId: reqData.fromUserProfile.userId, - $pull: { - programRoles: { - [typeOfAssetsToMove]: { $exists: true }, - }, - }, - upsert: true, - }; - let updateBasedonType; - if ( - reqData.toUserProfile.role === "PROGRAM_MANAGER" || - reqData.toUserProfile.role === "PROGRAM_DESIGNER" - ) { - updateBasedonType = await userExtensionsHelper.updateOne( - updateBasedonTypeQuery + let deleteProgram = + await userExtensionsHelper.findOneandUpdate( + deleteProgramFromUserQuery, + deleteProgramFromUserField, + arrayFilters ); - } - if (updateBasedonType) { - let deleteBasedonTypeinFromUser = - await userExtensionsHelper.updateOne( - updateFromUserBasedonTypeQuery - ); - // resData=updateBasedonType; - - // return resolve(updateBasedonType); - } } } } else { let findProgramManagerQuery = { - code: { $in: reqData.toUserProfile.role }, + code: { $in: reqData.toUserProfile.roles }, }; - let findProgramManagerId; - findProgramManagerId = await userRolesHelper.findOne( + + let findProgramManagerId = await userRolesHelper.findOne( findProgramManagerQuery ); - - const roleToUpdate = - newCollectionForUserExtension.platformRoles.find((role) => - reqData.toUserProfile.role.includes(role.code) - ); - if (roleToUpdate) { - roleToUpdate.roleId = findProgramManagerId._id; - data.platformRoles = - newCollectionForUserExtension.platformRoles.filter( - (role) => - role.code !== - reqData.toUserProfile.role.includes(role.code) - ); + let setProgramRoles; + if (typeOfAssetsToMove === constants.common.PROGRAM_DESIGNER) { + setProgramRoles = { + roleId: findProgramManagerId._id, + isAPlatformRole: true, + entities: [], + code: typeOfAssetsToMove, + }; + } else { + setProgramRoles = { + roleId: findProgramManagerId._id, + code: typeOfAssetsToMove, + }; } + + newCollectionForUserExtension.platformRoles.push( + setProgramRoles + ); let createUserExtensions = await userExtensionsHelper.createOne( newCollectionForUserExtension ); if (createUserExtensions) { - ownershipTransfer(ownershipTransferEvent); + let updateProgram = + await userExtensionsHelper.findOneandUpdate( + updateToQuery, + updateToFields, + arrayFilters + ); + if (updateProgram) { + let deleteProgram = + await userExtensionsHelper.findOneandUpdate( + deleteProgramFromUserQuery, + deleteProgramFromUserField, + arrayFilters + ); + } } } } @@ -287,35 +254,48 @@ module.exports = class AssetsHelper { } let solutionFilter = { - author: reqData.touserProfle.userId, - - } - let updateSolutions = { + author: reqData.toUserProfle.userId, + }; + let updateSolutions = { $set: { - author:reqData. touserProfle.userId, - crator: reqData.touserProfile.firstname }, + author: reqData.toUserProfle.userId, + crator: reqData.toUserProfile.firstname, + }, }; let solutionLicenseFilter = { - author:reqData. fromuserProfile.userId, - license: {$exists:true, $ne:""}, - } - let updateSolutionsLicense = { + author: reqData.fromUserProfile.userId, + license: { $exists: true, $ne: "" }, + }; + let updateSolutionsLicense = { $set: { - "license.author": toUserProfile.firstName, - "license.creator": toUserProfile.firstName + "license.author": reqData.toUserProfile.firstName, + "license.creator": reqData.toUserProfile.firstName, }, }; - let updateUserSolutions = [ solutionsHelper.updateMany(solutionFilter, updateSolutions), solutionsHelper.updateMany(solutionLicenseFilter, updateSolutionsLicense)] - let updateUserSolutionsDataResult = await Promise.all(updateUserSolutions); + let updateUserSolutions = [ + solutionsHelper.updateMany(solutionFilter, updateSolutions), + solutionsHelper.updateMany( + solutionLicenseFilter, + updateSolutionsLicense + ), + ]; + let updateUserSolutionsDataResult = await Promise.all( + updateUserSolutions + ); - if (updateUserSolutionsDataResult && (updateUserSolutionsDataResult[0].nModified > 0 || updateUserSolutionsDataResult[1].nModified > 0 )) { - if(telemetryEventOnOff !== constants.common.OFF){ + if ( + updateUserSolutionsDataResult && + (updateUserSolutionsDataResult[0].nModified > 0 || + updateUserSolutionsDataResult[1].nModified > 0) + ) { + if (telemetryEventOnOff !== constants.common.OFF) { /** * Telemetry Raw Event * {"eid":"","ets":1700188609568,"ver":"3.0","mid":"e55a91cd-7964-46bc-b756-18750787fb32","actor":{},"context":{"channel":"","pdata":{"id":"projectservice","pid":"manage-learn","ver":"7.0.0"},"env":"","cdata":[{"id":"adf3b621-619b-4195-a82d-d814eecdb21f","type":"Request"}],"rollup":{}},"object":{},"edata":{}} */ - let rawEvent = await gen.utils.generateTelemetryEventSkeletonStructure(); + let rawEvent = + await gen.utils.generateTelemetryEventSkeletonStructure(); rawEvent.eid = constants.common.AUDIT; rawEvent.context.channel = userDeleteEvent.context.channel; rawEvent.context.env = constants.common.USER; @@ -323,18 +303,22 @@ module.exports = class AssetsHelper { rawEvent.edata.type = constants.common.OWNERSHIP_TRANSFER_TYPE; rawEvent.edata.props = []; let userObject = { - id: reqData.toUserProfile.userId, + id: reqData.toUserProfile.userId, type: constants.common.USER, }; rawEvent.actor = userObject; rawEvent.object = userObject; - rawEvent.context.pdata.pid = `${process.env.ID}.${constants.common.OWNERSHIP_TRANSFER_MODULE}` + rawEvent.context.pdata.pid = `${process.env.ID}.${constants.common.OWNERSHIP_TRANSFER_MODULE}`; - let telemetryEvent = await gen.utils.generateTelemetryEvent(rawEvent); + let telemetryEvent = await gen.utils.generateTelemetryEvent( + rawEvent + ); telemetryEvent.lname = constants.common.TELEMTRY_EVENT_LOGGER; - telemetryEvent.level = constants.common.INFO_LEVEL + telemetryEvent.level = constants.common.INFO_LEVEL; - await kafkaProducersHelper.pushTelemetryEventToKafka(telemetryEvent); + await kafkaProducersHelper.pushTelemetryEventToKafka( + telemetryEvent + ); } return resolve({ success: true, @@ -344,10 +328,22 @@ module.exports = class AssetsHelper { success: true, }); } - } catch (error) { return reject(error); } }); } + + static pushKafka(message) { + return new Promise(async (resolve, reject) => { + try { + const data = await kafkaProducersHelper.pushTransferAssetsToKafka( + message + ); + resolve(data); + } catch (error) { + reject(error); + } + }); + } }; diff --git a/module/programs/helper.js b/module/programs/helper.js index 891fe2bd..2e5bb45c 100644 --- a/module/programs/helper.js +++ b/module/programs/helper.js @@ -14,6 +14,7 @@ const programUsersHelper = require(MODULES_BASE_PATH + "/programUsers/helper"); const timeZoneDifference = process.env.TIMEZONE_DIFFRENECE_BETWEEN_LOCAL_TIME_AND_UTC; const validateEntity = process.env.VALIDATE_ENTITIES + /** * ProgramsHelper * @class @@ -1314,4 +1315,3 @@ module.exports = class ProgramsHelper { -const solutionsHelper = require(MODULES_BASE_PATH + "/solutions/helper"); diff --git a/module/user-extension/helper.js b/module/user-extension/helper.js index bb2a94f0..e5b9a119 100644 --- a/module/user-extension/helper.js +++ b/module/user-extension/helper.js @@ -693,20 +693,33 @@ module.exports = class UserExtensionHelper { }) } - static InsertOne(query){ + static insertOne(query){ return new Promise(async (resolve, reject) => { try{ - let insertProgram =await database.models.userExtension.insertOne(query) + let insertProgram =await database.models.userExtension.insertOne(query, { new: true, upsert: true }) resolve(insertProgram) }catch(error){ reject(error); } }) } - static updateOne(query){ + static findOneandUpdate(query,updateToFields,arrayFilter){ return new Promise(async (resolve, reject) => { try{ - let updateProgram =await database.models.userExtension.updateOne(query) + let insertProgram = await database.models.userExtension.findOneAndUpdate(query,updateToFields, { arrayFilter, upsert:true} + ) + resolve(insertProgram) + }catch(error){ + reject(error); + } + }) + } + static updateOne( query,setQuery){ + return new Promise(async (resolve, reject) => { + try{ + let updateProgram =await database.models.userExtension.updateOne( + query,setQuery,{upsert:true} + ) resolve(updateProgram) }catch(error){ reject(error); From 78b6de7e4649b6467fbff1ac409c61bd344450fc Mon Sep 17 00:00:00 2001 From: praveenKDass Date: Tue, 30 Jan 2024 20:07:40 +0530 Subject: [PATCH 06/23] handled ownership assets transfer PR changes --- generics/constants/common.js | 3 + module/assets/helper.js | 437 +++++++++++++++++++++-------------- module/user-roles/helper.js | 2 +- 3 files changed, 265 insertions(+), 177 deletions(-) diff --git a/generics/constants/common.js b/generics/constants/common.js index 19096441..9985d376 100644 --- a/generics/constants/common.js +++ b/generics/constants/common.js @@ -99,4 +99,7 @@ USER_DELETE_MODULE: "userDelete", OFF: "OFF", PROGRAM_DESIGNER:"PROGRAM_DESIGNER", + PROGRAM_MANAGER:"PROGRAM_MANAGER", + CONTENT_CREATOR:"Content_Creator", + SOULTION:"solution", }; diff --git a/module/assets/helper.js b/module/assets/helper.js index 94dacf1f..cae77a32 100644 --- a/module/assets/helper.js +++ b/module/assets/helper.js @@ -7,6 +7,7 @@ const userRolesHelper = require(MODULES_BASE_PATH + "/user-roles/helper"); const kafkaProducersHelper = require(ROOT_PATH + "/generics/kafka/producers"); module.exports = class AssetsHelper { + static fetchPrograms(queryData, bodyData) { return new Promise(async (resolve, reject) => { try { @@ -61,191 +62,306 @@ module.exports = class AssetsHelper { static ownershipTransfer(ownershipTransferEvent) { return new Promise(async (resolve, reject) => { try { + let reqData = ownershipTransferEvent.edata; let fromFindQuery = { userId: reqData.fromUserProfile.userId, platformRoles: { $exists: true }, }; - let fromUpdateQuery = { - userId: reqData.fromUserProfile.userId, - }; - let fromUpdateUnsetQuery = { - $set: { platformRoles: [] }, - }; - let toFindQuery = { - userId: reqData.toUserProfile.userId, - platformRoles: { $exists: true }, - }; + + let updateUserSolutionsDataResult; + //data for create user in user Extension const newCollectionForUserExtension = { - // roles: [], - // status: "active", - // isDeleted: false, - // removedFromHomeScreen: [], - // improvementProjects: [], platformRoles: [], - // deleted: false, userId: reqData.toUserProfile.userId, externalId: reqData.toUserProfile.userName, updatedBy: reqData.actionBy.userId, createdBy: reqData.actionBy.userId, }; + //filter for solution updates + let solutionFilter = { + author: reqData.toUserProfile.userId, + }; + let updateSolutions = { + $set: { + author: reqData.toUserProfile.userId, + crator: reqData.toUserProfile.firstname, + }, + }; + let solutionLicenseFilter = { + author: reqData.fromUserProfile.userId, + license: { $exists: true, $ne: "" }, + }; + let updateSolutionsLicense = { + $set: { + "license.author": reqData.toUserProfile.firstName, + "license.creator": reqData.toUserProfile.firstName, + }, + }; + if ( reqData.actionBy.userId && reqData.fromUserProfile.userId && reqData.toUserProfile.userId ) { + //get Fromuser details from user Extension + let fromUserData = await userExtensionsHelper.findOne(fromFindQuery); + //get Touser details from user Extension + let toFindQuery = { + userId: reqData.toUserProfile.userId, + }; + let toUserData = await userExtensionsHelper.findOne( + toFindQuery + ); let allAssetsData = fromUserData.platformRoles; const typeOfAssetsToMove = reqData.assetInformation.objectType; - //Query for object type not present on reqData.assetInformation.objectType + //condition for if there is no object type + if (!typeOfAssetsToMove && !typeOfAssetsToMove.length > 0) { + if (reqData.toUserProfile.roles.includes(constants.common.CONTENT_CREATOR)) { + let updateUserSolutions = [ + solutionsHelper.updateMany(solutionFilter, updateSolutions), + solutionsHelper.updateMany( + solutionLicenseFilter, + updateSolutionsLicense + ), + ]; + updateUserSolutionsDataResult = await Promise.all( + updateUserSolutions + ); + } else { + if (fromUserData) { + if ( + reqData.toUserProfile.roles.includes(constants.common.PROGRAM_MANAGER) || + reqData.toUserProfile.roles.includes(constants.common. PROGRAM_DESIGNER) + ) { + if (toUserData) { - let updateQuery = { - userId: reqData.toUserProfile.userId, - }; - let updateSetQuery = { - $push: { platformRoles: { $each: allAssetsData } }, - }; - //Query for object type present on reqData.assetInformation.objectType + let typeOfAssetsToMove = fromUserData.platformRoles.map(role => role.code); + typeOfAssetsToMove.forEach(async roleCodeToUpdate => { + + const arrayToMove = allAssetsData.filter( + (role) => role.code === roleCodeToUpdate + ); + const updateToQuery = { + userId: reqData.toUserProfile.userId, + "platformRoles.code": roleCodeToUpdate, + }; + + const updateToFields = { + $push: { + "platformRoles.$.programs": { $each: arrayToMove?.[0]?.programs }, + }, + }; + const arrayFilters = [{ "elem.code": roleCodeToUpdate }]; + + let deleteProgramFromUserQuery = { + userId: reqData.fromUserProfile.userId, + "platformRoles.code": roleCodeToUpdate, + }; + let deleteProgramFromUserField = { + $pull: { + "platformRoles.$.programs": { $in: arrayToMove?.[0]?.programs }, + }, + } + let updateProgram = + await userExtensionsHelper.findOneandUpdate( + updateToQuery, + updateToFields, + arrayFilters + ); - const arrayToMove = allAssetsData.filter( - (role) => role.code === typeOfAssetsToMove - ); - const updateToQuery = { - userId: reqData.toUserProfile.userId, - "platformRoles.code": typeOfAssetsToMove, - }; + if (updateProgram){ + let deleteProgram = + await userExtensionsHelper.findOneandUpdate( + deleteProgramFromUserQuery, + deleteProgramFromUserField, + arrayFilters + ); + } + }) - const updateToFields = { - $push: { - "platformRoles.$.programs": { $each: arrayToMove?.[0]?.programs }, - }, - }; - const arrayFilters = [{ "elem.code": typeOfAssetsToMove }]; + } else { + const filterCodes = fromUserData.platformRoles.map(role => role.code); - let deleteProgramFromUserQuery = { - userId: reqData.fromUserProfile.userId, - "platformRoles.code": typeOfAssetsToMove, - }; - let deleteProgramFromUserField = { - $pull: { - "platformRoles.$.programs": { $in: arrayToMove?.[0]?.programs }, - }, - }; - if (fromUserData) { - if (!typeOfAssetsToMove || !typeOfAssetsToMove > 0) { - let toUserWithoutObjectTypeData = await userExtensionsHelper.findOne( - _.omit(updateToQuery, ["platformRoles.code"]) - ); - if (toUserWithoutObjectTypeData) { - let updateProgramRoles = await userExtensionsHelper.updateOne( - updateQuery, - updateSetQuery - ); - if (updateProgramRoles) { - let deleteProgram = await userExtensionsHelper.updateOne( - fromUpdateQuery, - fromUpdateUnsetQuery - ); - } - } else { - let findProgramManagerQuery = { - code: { $in: reqData.toUserProfile.roles }, - }; - - let findProgramManagerId = await userRolesHelper.findOne( - findProgramManagerQuery - ); - let createUserExtensions = await userExtensionsHelper.createOne( - newCollectionForUserExtension - ); - if (createUserExtensions) { - let updateProgramRolesForNewUser = - await userExtensionsHelper.updateOne( - updateQuery, - updateSetQuery + let findProgramManagerQuery = { + code: { $in:filterCodes}, + }; + + let findProgramManagerId = await userRolesHelper.findOne( + findProgramManagerQuery ); - if (updateProgramRolesForNewUser) { - let deleteProgram = await userExtensionsHelper.updateOne( - fromUpdateQuery, - fromUpdateUnsetQuery + + const programRolesArray = []; + for (const roleCode of fromUserData.platformRoles) { + const matchingRole = findProgramManagerId.find( + (role) => role.code === roleCode.code + ); + if (matchingRole) { + const roleId = matchingRole._id; + if ( + roleCode.code === constants.common.PROGRAM_DESIGNER + ) { + programRolesArray.push({ + roleId: roleId, + isAPlatformRole: true, + entities: [], + code: roleCode.code, + programs: roleCode.programs, + }); + } else { + programRolesArray.push({ + roleId: roleId, + code: roleCode.code, + programs: roleCode.programs, + }); + } + } + } + newCollectionForUserExtension.platformRoles=programRolesArray; + //create new Touser if he is not available in the user extension + let createUserExtensions = await userExtensionsHelper.createOne( + newCollectionForUserExtension ); + if(createUserExtensions){ + let deleteProgramFromUserQuery={ + userId: reqData.fromUserProfile.userId, + } + let deleteProgramFromUserField={ + $set: { platformRoles: [] }, + } + let deleteProgram = await userExtensionsHelper.updateOne( + deleteProgramFromUserQuery, + deleteProgramFromUserField + ); + } } } } - } else { - let toUserData = await userExtensionsHelper.findOne( - updateToQuery, - updateToFields - ); + } - if (toUserData) { - //Move the data when typeOfAssetsToMove is present in to user data - const arrayToMoveInToUser = toUserData.platformRoles.filter( - (role) => role.code === typeOfAssetsToMove - ); + } else { + if ( + reqData.toUserProfile.roles.includes(constants.common.CONTENT_CREATOR) && + typeOfAssetsToMove === constants.common.SOULTION + ) { + let updateUserSolutions = [ + solutionsHelper.updateMany(solutionFilter, updateSolutions), + solutionsHelper.updateMany( + solutionLicenseFilter, + updateSolutionsLicense + ), + ]; + updateUserSolutionsDataResult = await Promise.all( + updateUserSolutions + ); + } else { + if (fromUserData) { + if ( + reqData.toUserProfile.roles.includes(constants.common.PROGRAM_MANAGER) || + reqData.toUserProfile.roles.includes(constants.common.PROGRAM_DESIGNER) + ) { + if (toUserData) { - if (arrayToMoveInToUser) { - let updateProgram = - await userExtensionsHelper.findOneandUpdate( + let typeOfAssetsToMove = fromUserData.platformRoles.map(role => role.code); + typeOfAssetsToMove.forEach(async roleCodeToUpdate => { + + const arrayToMove = allAssetsData.filter( + (role) => role.code === roleCodeToUpdate + ); + const updateToQuery = { + userId: reqData.toUserProfile.userId, + "platformRoles.code": roleCodeToUpdate, + }; + + const updateToFields = { + $push: { + "platformRoles.$.programs": { $each: arrayToMove?.[0]?.programs }, + }, + }; + const arrayFilters = [{ "elem.code": roleCodeToUpdate }]; + + let deleteProgramFromUserQuery = { + userId: reqData.fromUserProfile.userId, + "platformRoles.code": roleCodeToUpdate, + }; + let deleteProgramFromUserField = { + $pull: { + "platformRoles.$.programs": { $in: arrayToMove?.[0]?.programs }, + }, + } + let updateProgram = + await userExtensionsHelper.findOneandUpdate( updateToQuery, updateToFields, - arrayFilters - ); - if (updateProgram) { - // let updateOperation = !reqData.assetInformation.objectType? fromUpdateQuery: updateFromUserBasedonTypeQuery - - let deleteProgram = - await userExtensionsHelper.findOneandUpdate( - deleteProgramFromUserQuery, - deleteProgramFromUserField, arrayFilters ); - } - } - } else { - let findProgramManagerQuery = { - code: { $in: reqData.toUserProfile.roles }, - }; - let findProgramManagerId = await userRolesHelper.findOne( - findProgramManagerQuery - ); - let setProgramRoles; - if (typeOfAssetsToMove === constants.common.PROGRAM_DESIGNER) { - setProgramRoles = { - roleId: findProgramManagerId._id, - isAPlatformRole: true, - entities: [], - code: typeOfAssetsToMove, - }; - } else { - setProgramRoles = { - roleId: findProgramManagerId._id, - code: typeOfAssetsToMove, - }; - } + if (updateProgram){ + let deleteProgram = + await userExtensionsHelper.findOneandUpdate( + deleteProgramFromUserQuery, + deleteProgramFromUserField, + arrayFilters + ); + } + }) - newCollectionForUserExtension.platformRoles.push( - setProgramRoles - ); - let createUserExtensions = await userExtensionsHelper.createOne( - newCollectionForUserExtension - ); - if (createUserExtensions) { - let updateProgram = - await userExtensionsHelper.findOneandUpdate( - updateToQuery, - updateToFields, - arrayFilters + } else { + const filterCodes = fromUserData.platformRoles.map(role => role.code); + + let findProgramManagerQuery = { + code: { $in:filterCodes}, + }; + + let findProgramManagerId = await userRolesHelper.findOne( + findProgramManagerQuery ); - if (updateProgram) { - let deleteProgram = - await userExtensionsHelper.findOneandUpdate( - deleteProgramFromUserQuery, - deleteProgramFromUserField, - arrayFilters + + const programRolesArray = []; + for (const roleCode of fromUserData.platformRoles) { + const matchingRole = findProgramManagerId.find( + (role) => role.code === roleCode.code ); + if (matchingRole) { + const roleId = matchingRole._id; + if ( + roleCode.code === constants.common.PROGRAM_DESIGNER + ) { + programRolesArray.push({ + roleId: roleId, + isAPlatformRole: true, + entities: [], + code: roleCode.code, + programs: roleCode.programs, + }); + } else { + programRolesArray.push({ + roleId: roleId, + code: roleCode.code, + programs: roleCode.programs, + }); + } + } + } + newCollectionForUserExtension.platformRoles=programRolesArray; + //create new Touser if he is not available in the user extension + let createUserExtensions = await userExtensionsHelper.createOne( + newCollectionForUserExtension + ); + if(createUserExtensions){ + let deleteProgramFromUserQuery={ + userId: reqData.fromUserProfile.userId, + } + let deleteProgramFromUserField={ + $set: { platformRoles: [] }, + } + let deleteProgram = await userExtensionsHelper.updateOne( + deleteProgramFromUserQuery, + deleteProgramFromUserField + ); + } } } } @@ -253,37 +369,6 @@ module.exports = class AssetsHelper { } } - let solutionFilter = { - author: reqData.toUserProfle.userId, - }; - let updateSolutions = { - $set: { - author: reqData.toUserProfle.userId, - crator: reqData.toUserProfile.firstname, - }, - }; - let solutionLicenseFilter = { - author: reqData.fromUserProfile.userId, - license: { $exists: true, $ne: "" }, - }; - let updateSolutionsLicense = { - $set: { - "license.author": reqData.toUserProfile.firstName, - "license.creator": reqData.toUserProfile.firstName, - }, - }; - - let updateUserSolutions = [ - solutionsHelper.updateMany(solutionFilter, updateSolutions), - solutionsHelper.updateMany( - solutionLicenseFilter, - updateSolutionsLicense - ), - ]; - let updateUserSolutionsDataResult = await Promise.all( - updateUserSolutions - ); - if ( updateUserSolutionsDataResult && (updateUserSolutionsDataResult[0].nModified > 0 || diff --git a/module/user-roles/helper.js b/module/user-roles/helper.js index 56ddd04a..82883a5a 100644 --- a/module/user-roles/helper.js +++ b/module/user-roles/helper.js @@ -91,7 +91,7 @@ module.exports = class UserRolesHelper { static findOne(query){ return new Promise(async (resolve, reject) => { try{ - let findUser =await database.models.userRoles.findOne(query) + let findUser =await database.models.userRoles.find(query) resolve(findUser) }catch(error){ reject(error); From 45a65c9bcf3e0702fb36a896a1391d72e72e7c93 Mon Sep 17 00:00:00 2001 From: praveenKDass Date: Wed, 31 Jan 2024 23:57:09 +0530 Subject: [PATCH 07/23] Worked PR comments forowner asstes transfer --- config/kafka.js | 82 ++-- controllers/v1/assets.js | 50 +-- generics/constants/common.js | 4 +- generics/kafka/consumers/assetsTransfer.js | 6 +- generics/services/assetsTransfer.js | 164 +++++++ module/assets/helper.js | 481 ++++++++++----------- module/programs/helper.js | 11 +- module/user-extension/helper.js | 50 ++- module/user-roles/helper.js | 1 - 9 files changed, 473 insertions(+), 376 deletions(-) create mode 100644 generics/services/assetsTransfer.js diff --git a/config/kafka.js b/config/kafka.js index 9a2412d1..32d12bac 100644 --- a/config/kafka.js +++ b/config/kafka.js @@ -3,54 +3,55 @@ * author : vishnu * created-date : 10-Jan-2023 * Description : Kafka Configurations related information. -*/ - + */ //dependencies -const kafka = require('kafka-node'); +const kafka = require("kafka-node"); const USER_DELETE_TOPIC = process.env.USER_DELETE_TOPIC; const USER_DELETE_ON_OFF = process.env.USER_DELETE_ON_OFF; -const TRANSFER_OWNERSHIP_JOB =process.env.TRANSFER_OWNERSHIP_JOB; +const OWNERSHIP_TRANSFER_TOPIC = process.env.OWNERSHIP_TRANSFER_TOPIC; +const OWNERSHIP_TRANSFER_ON_OFF = process.env.USER_DELETE_ON_OFF; + /** - * Kafka configurations. - * @function - * @name connect -*/ - -const connect = function() { - - const Producer = kafka.Producer - KeyedMessage = kafka.KeyedMessage - - const client = new kafka.KafkaClient({ - kafkaHost : process.env.KAFKA_URL - }); + * Kafka configurations. + * @function + * @name connect + */ - client.on('error', function(error) { - console.log("kafka connection error!") - }); +const connect = function () { + const Producer = kafka.Producer; + KeyedMessage = kafka.KeyedMessage; - const producer = new Producer(client) + const client = new kafka.KafkaClient({ + kafkaHost: process.env.KAFKA_URL, + }); - producer.on('ready', function () { - console.log("Connected to Kafka"); - }); - - producer.on('error', function (err) { - console.log("kafka producer creation error!") - }) + client.on("error", function (error) { + console.log("kafka connection error!"); + }); - if(USER_DELETE_ON_OFF !== "OFF") { - _sendToKafkaConsumers(USER_DELETE_TOPIC, process.env.KAFKA_URL); - } + const producer = new Producer(client); - return { - kafkaProducer: producer, - kafkaClient: client - }; + producer.on("ready", function () { + console.log("Connected to Kafka"); + }); -}; + producer.on("error", function (err) { + console.log("kafka producer creation error!"); + }); + if (USER_DELETE_ON_OFF !== "OFF") { + _sendToKafkaConsumers(USER_DELETE_TOPIC, process.env.KAFKA_URL); + } + if (OWNERSHIP_TRANSFER_ON_OFF !== "OFF") { + _sendToKafkaConsumers(OWNERSHIP_TRANSFER_TOPIC, process.env.KAFKA_URL); + } + + return { + kafkaProducer: producer, + kafkaClient: client, + }; +}; /** * Send data based on topic to kafka consumers @@ -60,8 +61,7 @@ const connect = function() { * @param {String} host - kafka host */ - var _sendToKafkaConsumers = function (topic, host) { - +var _sendToKafkaConsumers = function (topic, host) { if (topic && topic != "") { let consumer = new kafka.ConsumerGroup( { @@ -82,8 +82,8 @@ const connect = function() { if (message && message.topic === USER_DELETE_TOPIC) { userDeleteConsumer.messageReceived(message); } - // call assets or ownership Transfer consumer - if (message && message.topic === TRANSFER_OWNERSHIP_JOB) { + // call assets or ownership Transfer consumer + if (message && message.topic === OWNERSHIP_TRANSFER_TOPIC) { assetsTransferConsumer.messageReceived(message); } }); @@ -92,7 +92,7 @@ const connect = function() { if (error.topics && error.topics[0] === USER_DELETE_TOPIC) { userDeleteConsumer.errorTriggered(error); } - if (error.topics && error.topics[0] === TRANSFER_OWNERSHIP_JOB) { + if (error.topics && error.topics[0] === OWNERSHIP_TRANSFER_TOPIC) { assetsTransferConsumer.errorTriggered(error); } }); diff --git a/controllers/v1/assets.js b/controllers/v1/assets.js index 76315fec..de3be698 100644 --- a/controllers/v1/assets.js +++ b/controllers/v1/assets.js @@ -1,13 +1,14 @@ const assetsHelper = require(MODULES_BASE_PATH + "/assets/helper.js"); module.exports = class Assets { + /** * Get organisation program and solution. * @name list * @api {get} /kendra/api/v1/assets/list?type=program or solution. * @apiHeader {String} X-authenticated-user-token Authenticity token * @apiSampleRequest v1/assets/list?type=program - * @apiParamExample {json} Request-Body: + * @apiParamExample {Object:} Request-Body: { "filters": { "orgId": "01269934121990553633", @@ -25,35 +26,13 @@ module.exports = class Assets { } * @apiUse successBody * @apiUse errorBody - * @apiParamExample {json} Response: - * - * { - "message": "Assets fetched successfully ", - "status": 200, - "result": [ - { - "_id": "650be4aea302f0000807b2b0", - "status": "active", - "owner": "5d7255bb-1216-460e-9228-59b60230b1c1", - "name": "6.0 CSP 7 Program already expired", - "objectType": "program" - }, - { - "_id": "650be6c4a302f0000807b379", - "status": "active", - "owner": "5d7255bb-1216-460e-9228-59b60230b1c1", - "name": "6.0 CSP 2 Program expired in one day with no start date and end date ", - "objectType": "program" - }, - ] -} - - */ + * @returns {JSON} - Details of the program or solution . + */ list(req) { return new Promise(async (resolve, reject) => { try { - let assestsData = await assetsHelper.fetchPrograms( + let assestsData = await assetsHelper.fetchAssets( req.query.type, req.body ); @@ -70,23 +49,4 @@ module.exports = class Assets { }); } - - - kafkaResponse(req) { - return new Promise(async (resolve, reject) => { - try { - let assestsData = await assetsTransferConsumer.messageReceived(req.body); -; - - return resolve(assestsData); - } catch (error) { - return reject({ - status: error.status || httpStatusCode.internal_server_error.status, - message: - error.message || httpStatusCode.internal_server_error.message, - errorObject: error, - }); - } - }); - } }; diff --git a/generics/constants/common.js b/generics/constants/common.js index 9985d376..00aac9d7 100644 --- a/generics/constants/common.js +++ b/generics/constants/common.js @@ -92,7 +92,7 @@ USER_DELETE_TYPE: "DeleteUserStatus", AUDIT: "AUDIT", DELETE_USER: "delete-user", - TRANSFER_OWNERSHIP_JOB:"ownership-transfer", + OWNERSHIP_TRANSFER_TOPIC:"ownership-transfer", OWNERSHIP_TRANSFER_TYPE:"OwnerTransferStatus", OWNERSHIP_TRANSFER_MODULE:"ownerTransfer", USER: "User", @@ -100,6 +100,6 @@ OFF: "OFF", PROGRAM_DESIGNER:"PROGRAM_DESIGNER", PROGRAM_MANAGER:"PROGRAM_MANAGER", - CONTENT_CREATOR:"Content_Creator", + CONTENT_CREATOR:"CONTENT_CREATOR", SOULTION:"solution", }; diff --git a/generics/kafka/consumers/assetsTransfer.js b/generics/kafka/consumers/assetsTransfer.js index 70801fe6..a2fe80d3 100644 --- a/generics/kafka/consumers/assetsTransfer.js +++ b/generics/kafka/consumers/assetsTransfer.js @@ -57,10 +57,8 @@ const assetsHelper = require(MODULES_BASE_PATH + "/assets/helper.js"); var messageReceived = function (message) { return new Promise(async function (resolve, reject) { try { - let originalMessage = JSON.parse(message.value); - let parsedMessage = originalMessage.value; - // let parsedMessage = message; - if (parsedMessage.edata.action === constants.common.TRANSFER_OWNERSHIP_JOB) { + let parsedMessage = JSON.parse(message.value); + if (parsedMessage.edata.action === constants.common.OWNERSHIP_TRANSFER_TOPIC) { let ownershipTransferResponse = await assetsHelper.ownershipTransfer(parsedMessage); if (ownershipTransferResponse.success == true) { diff --git a/generics/services/assetsTransfer.js b/generics/services/assetsTransfer.js new file mode 100644 index 00000000..b6237d3d --- /dev/null +++ b/generics/services/assetsTransfer.js @@ -0,0 +1,164 @@ + + + /** + * Get users assets based on Type . + * @method + * @name generateUpdateOperations + * @param {Object} fromUserData - from userData. + * @param {Object} reqData - request body data data. + * @param {Object} toUserData - to user Data from userExtension. + * @param {Array} allAssetsData - PlatformRoles of from user. + + * @returns {Array} returns array of queries to Update. + */ + +async function generateUpdateOperations(fromUserData,reqData, toUserData,allAssetsData) { + const bulkOperations = []; + + fromUserData.platformRoles.forEach(role => { + const roleCodeToUpdate = role.code; + const arrayToMove = allAssetsData.filter(roleData => roleData.code === roleCodeToUpdate); + const toUserRoleExists = toUserData.platformRoles.some(toRole => toRole.code === roleCodeToUpdate); + + + if (!toUserRoleExists) { + // If role code doesn't exist in toUserData, transfer the entire object + bulkOperations.push({ + updateOne: { + filter: { userId: reqData.toUserProfile.userId }, + update: { + $push: { + "platformRoles": role, + }, + }, + }, + }); + + // Remove the object from fromUserData + bulkOperations.push({ + updateOne: { + filter: { userId: reqData.fromUserProfile.userId }, + update: { + $pull: { + "platformRoles": { code: roleCodeToUpdate }, + }, + }, + }, + }); + }else { + + + const updateToQuery = { + userId: reqData.toUserProfile.userId, + "platformRoles.code": roleCodeToUpdate, + }; + + const updateToFields = { + $push: { + "platformRoles.$[elem].programs": { $each: arrayToMove?.[0]?.programs }, + }, + }; + + const arrayFilters = [{ "elem.code": roleCodeToUpdate }]; + + const deleteProgramFromUserQuery = { + userId: reqData.fromUserProfile.userId, + "platformRoles.code": roleCodeToUpdate, + }; + + const deleteProgramFromUserField = { + $pull: { + "platformRoles.$[elem].programs": { $in: arrayToMove?.[0]?.programs }, + }, + }; + + // Create bulk write operations + bulkOperations.push({ + updateOne: { + filter: updateToQuery, + update: updateToFields, + arrayFilters: arrayFilters, + }, + }); + + bulkOperations.push({ + updateOne: { + filter: deleteProgramFromUserQuery, + update: deleteProgramFromUserField, + arrayFilters: arrayFilters, + }, + }); + } + }); + + + return bulkOperations; + } + +/** + * Get users assets based on Type . + * @method + * @name createProgramRolesArray + * @param {Object} fromUserData - from userData. + * @param {String} findProgramManagerId - Id of Role. + * @param {Array} allAssetsData - PlatformRoles of from user. + + * @returns {Array} returns PlatformRoles array. + */ + +function createProgramRolesArray(fromUserData, findProgramManagerId) { + const programRolesArray = []; + + for (const roleCode of fromUserData.platformRoles) { + const matchingRole = findProgramManagerId.find(role => role.code === roleCode.code); + + if (matchingRole) { + const roleId = matchingRole._id; + + const roleDetails = { + roleId: roleId, + code: roleCode.code, + programs: roleCode.programs, + }; + + if (roleCode.code === constants.common.PROGRAM_DESIGNER) { + roleDetails.isAPlatformRole = true; + roleDetails.entities = []; + } + + programRolesArray.push(roleDetails); + } + } + + return programRolesArray; +} + + +/** + * Get users assets based on Type . + * @method + * @name createProgramRolesArray + * @param {Object} fromUserData - from array. + * @param {Object} toUserArray - to array. + * @returns {Array} returns missing roles as an array. + */ + +function checkRolesPresence(fromUserArray, toUserArray) { + const missingRoles = []; + + toUserArray.forEach(toRole => { + const isFromRolePresent = fromUserArray.some(fromRole => fromRole.code === toRole.code); + + if (!isFromRolePresent) { + missingRoles.push(toRole.code); + } + }); + return missingRoles; +} + + +module.exports={ + generateUpdateOperations:generateUpdateOperations, + createProgramRolesArray:createProgramRolesArray, + checkRolesPresence:checkRolesPresence, +} diff --git a/module/assets/helper.js b/module/assets/helper.js index cae77a32..e2c16e80 100644 --- a/module/assets/helper.js +++ b/module/assets/helper.js @@ -5,10 +5,19 @@ const userExtensionsHelper = require(MODULES_BASE_PATH + "/user-extension/helper"); const userRolesHelper = require(MODULES_BASE_PATH + "/user-roles/helper"); const kafkaProducersHelper = require(ROOT_PATH + "/generics/kafka/producers"); +const assetService = require(ROOT_PATH + "/generics/services/assetsTransfer"); module.exports = class AssetsHelper { - - static fetchPrograms(queryData, bodyData) { + + /** + * Get users assets based on Type . + * @method + * @name fetchAssets + * @param {String} queryData - query for type data. + * @param {Object} [bodyData] - request body data data. + * @returns {Promise} returns a promise. + */ + static fetchAssets(queryData, bodyData) { return new Promise(async (resolve, reject) => { try { let organizationAssets; @@ -59,45 +68,63 @@ module.exports = class AssetsHelper { }); } + /** + * Transfer ownership Kafka Event. + * @method + * @name deleteUownershipTransferserPIIData + * @param {ownershipTransferEvent} - userDeleteEvent message object + * { + "highWaterOffset": 63, + "key": "", + "offset": 62, + "partition": 0, + "topic": "ownershiptransfer", + "edata": { + "action": "ownership-transfer", + "organisationId": "01269934121990553633", + "context": "Ownership Transfer", + "actionBy": { + "userId": "86d2d978-5b20-4453-8a76-82b5a4c728c9", + "userName": "" + }, + "fromUserProfile": { + "userId": "19d81ef7-36ce-41fe-ae2d-c8365d977be4", + "userName": "", + "channel": "", + "organisationId": "", + "roles": [ + "PROGRAM_MANAGER" + ] + }, + "toUserProfile": { + "userId": "86d2d978-5b20-4453-8a76-82b5a4c728c9", + "userName": "test", + "firstName": "test", + "lastName": "", + "roles": [ + "PROGRAM_MANAGER", + "CONTENT_CREATOR" + ] + }, + "assetInformation": { + "objectType": "solution || program", + "identifier": "{{resource_identifier}}" + }, + "iteration": 1 + } +} + * @returns {Promise} success Data. + */ static ownershipTransfer(ownershipTransferEvent) { return new Promise(async (resolve, reject) => { try { - let reqData = ownershipTransferEvent.edata; let fromFindQuery = { userId: reqData.fromUserProfile.userId, platformRoles: { $exists: true }, }; - + let updateUserSolutionsDataResult; - //data for create user in user Extension - const newCollectionForUserExtension = { - platformRoles: [], - userId: reqData.toUserProfile.userId, - externalId: reqData.toUserProfile.userName, - updatedBy: reqData.actionBy.userId, - createdBy: reqData.actionBy.userId, - }; - //filter for solution updates - let solutionFilter = { - author: reqData.toUserProfile.userId, - }; - let updateSolutions = { - $set: { - author: reqData.toUserProfile.userId, - crator: reqData.toUserProfile.firstname, - }, - }; - let solutionLicenseFilter = { - author: reqData.fromUserProfile.userId, - license: { $exists: true, $ne: "" }, - }; - let updateSolutionsLicense = { - $set: { - "license.author": reqData.toUserProfile.firstName, - "license.creator": reqData.toUserProfile.firstName, - }, - }; if ( reqData.actionBy.userId && @@ -106,21 +133,49 @@ module.exports = class AssetsHelper { ) { //get Fromuser details from user Extension - let fromUserData = await userExtensionsHelper.findOne(fromFindQuery); + let fromUserData = await userExtensionsHelper.userExtensionDocument( + fromFindQuery + ); //get Touser details from user Extension let toFindQuery = { userId: reqData.toUserProfile.userId, }; - let toUserData = await userExtensionsHelper.findOne( + let toUserData = await userExtensionsHelper.userExtensionDocument( toFindQuery ); - let allAssetsData = fromUserData.platformRoles; - const typeOfAssetsToMove = reqData.assetInformation.objectType; + let allAssetsData = fromUserData?.platformRoles; + let typeOfAssetsToMove = reqData.assetInformation.objectType; + let checkAssetInformation = + reqData.hasOwnProperty("assetInformation"); //condition for if there is no object type - if (!typeOfAssetsToMove && !typeOfAssetsToMove.length > 0) { - if (reqData.toUserProfile.roles.includes(constants.common.CONTENT_CREATOR)) { - let updateUserSolutions = [ + if (!checkAssetInformation) { + if ( + reqData.toUserProfile.roles.includes( + constants.common.CONTENT_CREATOR + ) + ) { + //filter for solution updates + let solutionFilter = { + author: reqData.fromUserProfile.userId, + }; + let updateSolutions = { + $set: { + author: reqData.toUserProfile.userId, + creator: reqData.toUserProfile.firstname, + }, + }; + let solutionLicenseFilter = { + author: reqData.fromUserProfile.userId, + license: { $exists: true, $ne: "" }, + }; + let updateSolutionsLicense = { + $set: { + "license.author": reqData.toUserProfile.firstName, + "license.creator": reqData.toUserProfile.firstName, + }, + }; + let updateUserSolutions = [ solutionsHelper.updateMany(solutionFilter, updateSolutions), solutionsHelper.updateMany( solutionLicenseFilter, @@ -131,122 +186,104 @@ module.exports = class AssetsHelper { updateUserSolutions ); } else { - if (fromUserData) { - if ( - reqData.toUserProfile.roles.includes(constants.common.PROGRAM_MANAGER) || - reqData.toUserProfile.roles.includes(constants.common. PROGRAM_DESIGNER) - ) { - if (toUserData) { + if ( + reqData.toUserProfile.roles.includes( + constants.common.PROGRAM_MANAGER + ) || + reqData.toUserProfile.roles.includes( + constants.common.PROGRAM_DESIGNER + ) + ) { + if (toUserData) { + const updateQueries = + await assetService.generateUpdateOperations( + fromUserData, + reqData, + toUserData, + allAssetsData + ); + let updateProgram = + await userExtensionsHelper.findOneandUpdate(updateQueries); + } else { - let typeOfAssetsToMove = fromUserData.platformRoles.map(role => role.code); - typeOfAssetsToMove.forEach(async roleCodeToUpdate => { - - const arrayToMove = allAssetsData.filter( - (role) => role.code === roleCodeToUpdate - ); - const updateToQuery = { - userId: reqData.toUserProfile.userId, - "platformRoles.code": roleCodeToUpdate, - }; - - const updateToFields = { - $push: { - "platformRoles.$.programs": { $each: arrayToMove?.[0]?.programs }, - }, - }; - const arrayFilters = [{ "elem.code": roleCodeToUpdate }]; - - let deleteProgramFromUserQuery = { - userId: reqData.fromUserProfile.userId, - "platformRoles.code": roleCodeToUpdate, - }; - let deleteProgramFromUserField = { - $pull: { - "platformRoles.$.programs": { $in: arrayToMove?.[0]?.programs }, - }, - } - let updateProgram = - await userExtensionsHelper.findOneandUpdate( - updateToQuery, - updateToFields, - arrayFilters - ); + //data for create new user in user Extension + let newCollectionForUserExtension = { + platformRoles: [], + userId: reqData.toUserProfile.userId, + externalId: reqData.toUserProfile.userName, + updatedBy: reqData.actionBy.userId, + createdBy: reqData.actionBy.userId, + }; + const filterCodes = fromUserData.platformRoles.map( + (role) => role.code + ); - if (updateProgram){ - let deleteProgram = - await userExtensionsHelper.findOneandUpdate( - deleteProgramFromUserQuery, - deleteProgramFromUserField, - arrayFilters - ); - } - }) + let findProgramManagerQuery = { + code: { $in: filterCodes }, + }; - } else { - const filterCodes = fromUserData.platformRoles.map(role => role.code); + let findProgramManagerId = await userRolesHelper.findOne( + findProgramManagerQuery + ); - let findProgramManagerQuery = { - code: { $in:filterCodes}, - }; - - let findProgramManagerId = await userRolesHelper.findOne( - findProgramManagerQuery + const programRolesArray = + assetService.createProgramRolesArray( + fromUserData, + findProgramManagerId ); - const programRolesArray = []; - for (const roleCode of fromUserData.platformRoles) { - const matchingRole = findProgramManagerId.find( - (role) => role.code === roleCode.code - ); - if (matchingRole) { - const roleId = matchingRole._id; - if ( - roleCode.code === constants.common.PROGRAM_DESIGNER - ) { - programRolesArray.push({ - roleId: roleId, - isAPlatformRole: true, - entities: [], - code: roleCode.code, - programs: roleCode.programs, - }); - } else { - programRolesArray.push({ - roleId: roleId, - code: roleCode.code, - programs: roleCode.programs, - }); - } - } - } - newCollectionForUserExtension.platformRoles=programRolesArray; - //create new Touser if he is not available in the user extension - let createUserExtensions = await userExtensionsHelper.createOne( + newCollectionForUserExtension.platformRoles = + programRolesArray; + + //create new Touser if he is not available in the user extension + let createUserExtensions = + await userExtensionsHelper.createOne( newCollectionForUserExtension ); - if(createUserExtensions){ - let deleteProgramFromUserQuery={ - userId: reqData.fromUserProfile.userId, - } - let deleteProgramFromUserField={ - $set: { platformRoles: [] }, - } - let deleteProgram = await userExtensionsHelper.updateOne( - deleteProgramFromUserQuery, - deleteProgramFromUserField - ); - } + if (createUserExtensions) { + let deleteProgramFromUserQuery = { + userId: reqData.fromUserProfile.userId, + }; + let deleteProgramFromUserField = { + $set: { platformRoles: [] }, + }; + let deleteProgram = await userExtensionsHelper.updateOne( + deleteProgramFromUserQuery, + deleteProgramFromUserField + ); } } } } - } else { if ( - reqData.toUserProfile.roles.includes(constants.common.CONTENT_CREATOR) && + reqData.toUserProfile.roles.includes( + constants.common.CONTENT_CREATOR + ) && typeOfAssetsToMove === constants.common.SOULTION ) { - let updateUserSolutions = [ + //filter for solution updates + let solutionFilter = { + author: reqData.fromUserProfile.userId, + }; + let updateSolutions = { + $set: { + author: reqData.toUserProfile.userId, + creator: reqData.toUserProfile.firstname, + }, + }; + let solutionLicenseFilter = { + author: reqData.fromUserProfile.userId, + license: { $exists: true, $ne: "" }, + }; + let updateSolutionsLicense = { + $set: { + "license.author": reqData.toUserProfile.firstName, + "license.creator": reqData.toUserProfile.firstName, + }, + }; + + let updateUserSolutions = [ solutionsHelper.updateMany(solutionFilter, updateSolutions), solutionsHelper.updateMany( solutionLicenseFilter, @@ -257,111 +294,69 @@ module.exports = class AssetsHelper { updateUserSolutions ); } else { - if (fromUserData) { - if ( - reqData.toUserProfile.roles.includes(constants.common.PROGRAM_MANAGER) || - reqData.toUserProfile.roles.includes(constants.common.PROGRAM_DESIGNER) - ) { - if (toUserData) { - - let typeOfAssetsToMove = fromUserData.platformRoles.map(role => role.code); - typeOfAssetsToMove.forEach(async roleCodeToUpdate => { - - const arrayToMove = allAssetsData.filter( - (role) => role.code === roleCodeToUpdate - ); - const updateToQuery = { - userId: reqData.toUserProfile.userId, - "platformRoles.code": roleCodeToUpdate, - }; - - const updateToFields = { - $push: { - "platformRoles.$.programs": { $each: arrayToMove?.[0]?.programs }, - }, - }; - const arrayFilters = [{ "elem.code": roleCodeToUpdate }]; - - let deleteProgramFromUserQuery = { - userId: reqData.fromUserProfile.userId, - "platformRoles.code": roleCodeToUpdate, - }; - let deleteProgramFromUserField = { - $pull: { - "platformRoles.$.programs": { $in: arrayToMove?.[0]?.programs }, - }, - } - let updateProgram = - await userExtensionsHelper.findOneandUpdate( - updateToQuery, - updateToFields, - arrayFilters - ); + if ( + reqData.toUserProfile.roles.includes( + constants.common.PROGRAM_MANAGER + ) || + reqData.toUserProfile.roles.includes( + constants.common.PROGRAM_DESIGNER + ) + ) { + if (toUserData) { + const updateQueries = + await assetService.generateUpdateOperations( + fromUserData, + reqData, + toUserData, + allAssetsData + ); + let updateProgram = + await userExtensionsHelper.findOneandUpdate(updateQueries); + } else { + //data for create user in user Extension + let newCollectionForUserExtension = { + platformRoles: [], + userId: reqData.toUserProfile.userId, + externalId: reqData.toUserProfile.userName, + updatedBy: reqData.actionBy.userId, + createdBy: reqData.actionBy.userId, + }; + const filterCodes = fromUserData.platformRoles.map( + (role) => role.code + ); - if (updateProgram){ - let deleteProgram = - await userExtensionsHelper.findOneandUpdate( - deleteProgramFromUserQuery, - deleteProgramFromUserField, - arrayFilters - ); - } - }) + let findProgramManagerQuery = { + code: { $in: filterCodes }, + }; - } else { - const filterCodes = fromUserData.platformRoles.map(role => role.code); + let findProgramManagerId = await userRolesHelper.findOne( + findProgramManagerQuery + ); - let findProgramManagerQuery = { - code: { $in:filterCodes}, - }; - - let findProgramManagerId = await userRolesHelper.findOne( - findProgramManagerQuery + const programRolesArray = + assetService.createProgramRolesArray( + fromUserData, + findProgramManagerId ); - const programRolesArray = []; - for (const roleCode of fromUserData.platformRoles) { - const matchingRole = findProgramManagerId.find( - (role) => role.code === roleCode.code - ); - if (matchingRole) { - const roleId = matchingRole._id; - if ( - roleCode.code === constants.common.PROGRAM_DESIGNER - ) { - programRolesArray.push({ - roleId: roleId, - isAPlatformRole: true, - entities: [], - code: roleCode.code, - programs: roleCode.programs, - }); - } else { - programRolesArray.push({ - roleId: roleId, - code: roleCode.code, - programs: roleCode.programs, - }); - } - } - } - newCollectionForUserExtension.platformRoles=programRolesArray; - //create new Touser if he is not available in the user extension - let createUserExtensions = await userExtensionsHelper.createOne( + newCollectionForUserExtension.platformRoles = + programRolesArray; + //create new Touser if he is not available in the user extension + let createUserExtensions = + await userExtensionsHelper.createOne( newCollectionForUserExtension ); - if(createUserExtensions){ - let deleteProgramFromUserQuery={ - userId: reqData.fromUserProfile.userId, - } - let deleteProgramFromUserField={ - $set: { platformRoles: [] }, - } - let deleteProgram = await userExtensionsHelper.updateOne( - deleteProgramFromUserQuery, - deleteProgramFromUserField - ); - } + if (createUserExtensions) { + let deleteProgramFromUserQuery = { + userId: reqData.fromUserProfile.userId, + }; + let deleteProgramFromUserField = { + $set: { platformRoles: [] }, + }; + let deleteProgram = await userExtensionsHelper.updateOne( + deleteProgramFromUserQuery, + deleteProgramFromUserField + ); } } } @@ -419,16 +414,4 @@ module.exports = class AssetsHelper { }); } - static pushKafka(message) { - return new Promise(async (resolve, reject) => { - try { - const data = await kafkaProducersHelper.pushTransferAssetsToKafka( - message - ); - resolve(data); - } catch (error) { - reject(error); - } - }); - } }; diff --git a/module/programs/helper.js b/module/programs/helper.js index 2e5bb45c..41212ff1 100644 --- a/module/programs/helper.js +++ b/module/programs/helper.js @@ -1265,16 +1265,7 @@ module.exports = class ProgramsHelper { projection1[projectedData] = 1; } }); - } else{ - projection1={ - "_id":1, - "name":1, - "status":1, - "owner":1, - "orgId":1, - "objectType":"program" - } - } + } let limitQuery; //omit the limit if there is no type if(queryData === "" || queryData === undefined){ diff --git a/module/user-extension/helper.js b/module/user-extension/helper.js index e5b9a119..98deb76c 100644 --- a/module/user-extension/helper.js +++ b/module/user-extension/helper.js @@ -682,38 +682,33 @@ module.exports = class UserExtensionHelper { }) } - static findOne(query){ - return new Promise(async (resolve, reject) => { - try{ - let findUser =await database.models.userExtension.findOne(query) - resolve(findUser) - }catch(error){ - reject(error); - } - }) - } - - static insertOne(query){ - return new Promise(async (resolve, reject) => { - try{ - let insertProgram =await database.models.userExtension.insertOne(query, { new: true, upsert: true }) - resolve(insertProgram) - }catch(error){ - reject(error); - } - }) - } - static findOneandUpdate(query,updateToFields,arrayFilter){ + /** + * Transfer ownership from User to ToUser based on Roles + * @method + * @name findOneandUpdate + * @param {Array} query - Array of queries to update. + * @returns {Array} + */ + + static findOneandUpdate(query){ return new Promise(async (resolve, reject) => { try{ - let insertProgram = await database.models.userExtension.findOneAndUpdate(query,updateToFields, { arrayFilter, upsert:true} - ) + let insertProgram = await database.models.userExtension.bulkWrite(query) resolve(insertProgram) }catch(error){ reject(error); } }) } + + /** + * Remove programs Roles from FromUser when we create a newUser and Transfer + * @method + * @name updateOne + * @param {Object} query findMatchQuery. + * @param {Object} setQuery Remove programRoles from an FromUser. + * @returns {Array} + */ static updateOne( query,setQuery){ return new Promise(async (resolve, reject) => { try{ @@ -726,6 +721,13 @@ module.exports = class UserExtensionHelper { } }) } + /** + * Create a new User when toUser not available in the userExtension collection with transferred platformRoles from FromUser + * @method + * @name createOne + * @param {Object} data- newUserData. + * @returns {Array} + */ static createOne(data){ return new Promise(async (resolve, reject) => { try{ diff --git a/module/user-roles/helper.js b/module/user-roles/helper.js index 82883a5a..a95d02fa 100644 --- a/module/user-roles/helper.js +++ b/module/user-roles/helper.js @@ -87,7 +87,6 @@ module.exports = class UserRolesHelper { }); } - static findOne(query){ return new Promise(async (resolve, reject) => { try{ From 98858c9ef4af5fcc8e742b9c41e7b704134d7f3d Mon Sep 17 00:00:00 2001 From: praveenKDass Date: Thu, 1 Feb 2024 16:19:43 +0530 Subject: [PATCH 08/23] checking from and touser role identical --- generics/services/assetsTransfer.js | 189 +++++++++++++++------------- module/assets/helper.js | 11 +- 2 files changed, 106 insertions(+), 94 deletions(-) diff --git a/generics/services/assetsTransfer.js b/generics/services/assetsTransfer.js index b6237d3d..b730d39f 100644 --- a/generics/services/assetsTransfer.js +++ b/generics/services/assetsTransfer.js @@ -1,6 +1,4 @@ - - - /** +/** * Get users assets based on Type . * @method * @name generateUpdateOperations @@ -12,66 +10,74 @@ * @returns {Array} returns array of queries to Update. */ -async function generateUpdateOperations(fromUserData,reqData, toUserData,allAssetsData) { - const bulkOperations = []; +async function generateUpdateOperations( + fromUserData, + reqData, + toUserData, + allAssetsData +) { + const bulkOperations = []; + + fromUserData.platformRoles.forEach((role) => { + const roleCodeToUpdate = role.code; + const arrayToMove = allAssetsData.filter( + (roleData) => roleData.code === roleCodeToUpdate + ); + const toUserRoleExists = toUserData.platformRoles.some( + (toRole) => toRole.code === roleCodeToUpdate + ); - fromUserData.platformRoles.forEach(role => { - const roleCodeToUpdate = role.code; - const arrayToMove = allAssetsData.filter(roleData => roleData.code === roleCodeToUpdate); - const toUserRoleExists = toUserData.platformRoles.some(toRole => toRole.code === roleCodeToUpdate); - - - if (!toUserRoleExists) { - // If role code doesn't exist in toUserData, transfer the entire object - bulkOperations.push({ - updateOne: { - filter: { userId: reqData.toUserProfile.userId }, - update: { - $push: { - "platformRoles": role, - }, + if (!toUserRoleExists) { + // If role code doesn't exist in toUserData, transfer the entire object + bulkOperations.push({ + updateOne: { + filter: { userId: reqData.toUserProfile.userId }, + update: { + $push: { + platformRoles: role, }, }, - }); - - // Remove the object from fromUserData - bulkOperations.push({ - updateOne: { - filter: { userId: reqData.fromUserProfile.userId }, - update: { - $pull: { - "platformRoles": { code: roleCodeToUpdate }, - }, + }, + }); + + // Remove the object from fromUserData + bulkOperations.push({ + updateOne: { + filter: { userId: reqData.fromUserProfile.userId }, + update: { + $pull: { + platformRoles: { code: roleCodeToUpdate }, }, }, - }); - }else { - - + }, + }); + } else { const updateToQuery = { userId: reqData.toUserProfile.userId, "platformRoles.code": roleCodeToUpdate, }; - + const updateToFields = { $push: { - "platformRoles.$[elem].programs": { $each: arrayToMove?.[0]?.programs }, + "platformRoles.$[elem].programs": { + $each: arrayToMove?.[0]?.programs, + }, }, }; - + const arrayFilters = [{ "elem.code": roleCodeToUpdate }]; - + const deleteProgramFromUserQuery = { userId: reqData.fromUserProfile.userId, "platformRoles.code": roleCodeToUpdate, }; - + const deleteProgramFromUserField = { $pull: { "platformRoles.$[elem].programs": { $in: arrayToMove?.[0]?.programs }, }, }; - + // Create bulk write operations bulkOperations.push({ updateOne: { @@ -80,7 +86,7 @@ async function generateUpdateOperations(fromUserData,reqData, toUserData,allAsse arrayFilters: arrayFilters, }, }); - + bulkOperations.push({ updateOne: { filter: deleteProgramFromUserQuery, @@ -89,12 +95,11 @@ async function generateUpdateOperations(fromUserData,reqData, toUserData,allAsse }, }); } - }); - - - return bulkOperations; - } - + }); + + return bulkOperations; +} + /** * Get users assets based on Type . * @method @@ -107,58 +112,62 @@ async function generateUpdateOperations(fromUserData,reqData, toUserData,allAsse */ function createProgramRolesArray(fromUserData, findProgramManagerId) { - const programRolesArray = []; + const programRolesArray = []; - for (const roleCode of fromUserData.platformRoles) { - const matchingRole = findProgramManagerId.find(role => role.code === roleCode.code); + for (const roleCode of fromUserData.platformRoles) { + const matchingRole = findProgramManagerId.find( + (role) => role.code === roleCode.code + ); - if (matchingRole) { - const roleId = matchingRole._id; + if (matchingRole) { + const roleId = matchingRole._id; - const roleDetails = { - roleId: roleId, - code: roleCode.code, - programs: roleCode.programs, - }; + const roleDetails = { + roleId: roleId, + code: roleCode.code, + programs: roleCode.programs, + }; - if (roleCode.code === constants.common.PROGRAM_DESIGNER) { - roleDetails.isAPlatformRole = true; - roleDetails.entities = []; - } + if (roleCode.code === constants.common.PROGRAM_DESIGNER) { + roleDetails.isAPlatformRole = true; + roleDetails.entities = []; + } - programRolesArray.push(roleDetails); - } + programRolesArray.push(roleDetails); } + } - return programRolesArray; + return programRolesArray; } - /** - * Get users assets based on Type . - * @method - * @name createProgramRolesArray - * @param {Object} fromUserData - from array. - * @param {Object} toUserArray - to array. - * @returns {Array} returns missing roles as an array. - */ - -function checkRolesPresence(fromUserArray, toUserArray) { - const missingRoles = []; - - toUserArray.forEach(toRole => { - const isFromRolePresent = fromUserArray.some(fromRole => fromRole.code === toRole.code); - - if (!isFromRolePresent) { - missingRoles.push(toRole.code); - } - }); - return missingRoles; + * Check whether from and to user has Identical Roles. + * @method + * @name createProgramRolesArray + * @param {Array} fromUserData - from array. + * @param {Array} toUserArray - to array. + * @returns {Boolean} returns true or false. + + */ + +function checkRolesPresence(fromUserRoleArray, toUserRoleArray) { + const rolesToCheck = [ + constants.common.PROGRAM_MANAGER, + constants.common.PROGRAM_DESIGNER, + ]; + + const hasRolesInFromArray = rolesToCheck.some((role) => + fromUserRoleArray.includes(role) + ); + const hasRolesInToArray = rolesToCheck.some((role) => + toUserRoleArray.includes(role) + ); + + return hasRolesInFromArray && hasRolesInToArray; } - -module.exports={ - generateUpdateOperations:generateUpdateOperations, - createProgramRolesArray:createProgramRolesArray, - checkRolesPresence:checkRolesPresence, -} +module.exports = { + generateUpdateOperations: generateUpdateOperations, + createProgramRolesArray: createProgramRolesArray, + checkRolesPresence: checkRolesPresence, +}; diff --git a/module/assets/helper.js b/module/assets/helper.js index e2c16e80..0fce4ad9 100644 --- a/module/assets/helper.js +++ b/module/assets/helper.js @@ -21,7 +21,6 @@ module.exports = class AssetsHelper { return new Promise(async (resolve, reject) => { try { let organizationAssets; - switch (queryData) { case "program": organizationAssets = @@ -71,8 +70,8 @@ module.exports = class AssetsHelper { /** * Transfer ownership Kafka Event. * @method - * @name deleteUownershipTransferserPIIData - * @param {ownershipTransferEvent} - userDeleteEvent message object + * @name ownershipTransfer + * @param {ownershipTransferEvent} - OwenerShip transfer Event message object * { "highWaterOffset": 63, "key": "", @@ -125,11 +124,15 @@ module.exports = class AssetsHelper { }; let updateUserSolutionsDataResult; + let checkUsersRolesIsIdentical= assetService.checkRolesPresence( + reqData.fromUserProfile.roles, + reqData.fromUserProfile.roles + ); if ( reqData.actionBy.userId && reqData.fromUserProfile.userId && - reqData.toUserProfile.userId + reqData.toUserProfile.userId && checkUsersRolesIsIdentical ) { //get Fromuser details from user Extension From 1c1f9e76505a6243264586c722a3bdf50dd5a541 Mon Sep 17 00:00:00 2001 From: praveenKDass Date: Thu, 1 Feb 2024 16:35:19 +0530 Subject: [PATCH 09/23] bug fixes in assets for solution type --- module/assets/helper.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/module/assets/helper.js b/module/assets/helper.js index 0fce4ad9..f128f6c5 100644 --- a/module/assets/helper.js +++ b/module/assets/helper.js @@ -31,7 +31,7 @@ module.exports = class AssetsHelper { break; case "solution": organizationAssets = - await solutionsHelper.queryForOrganizationSolutions(bodyData); + await solutionsHelper.queryForOrganizationSolutions(bodyData,queryData); break; default: @@ -41,7 +41,7 @@ module.exports = class AssetsHelper { queryData ); let allOrganizationSolutions = - await solutionsHelper.queryForOrganizationSolutions(bodyData); + await solutionsHelper.queryForOrganizationSolutions(bodyData,queryData); organizationAssets = [ ...allOrganizationProgram.data, ...allOrganizationSolutions.data, From 6293706e88e6596c6859f21ba08cb04bb4372ea8 Mon Sep 17 00:00:00 2001 From: praveenKDass Date: Thu, 1 Feb 2024 17:31:29 +0530 Subject: [PATCH 10/23] fetch assets using list function for program and solution --- module/assets/helper.js | 22 +- module/programs/helper.js | 404 +++++++++++++++++-------------------- module/solutions/helper.js | 112 +++++----- 3 files changed, 245 insertions(+), 293 deletions(-) diff --git a/module/assets/helper.js b/module/assets/helper.js index f128f6c5..5f53c87d 100644 --- a/module/assets/helper.js +++ b/module/assets/helper.js @@ -42,25 +42,21 @@ module.exports = class AssetsHelper { ); let allOrganizationSolutions = await solutionsHelper.queryForOrganizationSolutions(bodyData,queryData); - organizationAssets = [ - ...allOrganizationProgram.data, - ...allOrganizationSolutions.data, - ]; + organizationAssets = { + success: true, + message: constants.apiResponses.ASSETS_SUCCESSFULLY, + data:{data:[ ...allOrganizationProgram.data.data, + ...allOrganizationSolutions.data.data]}, + count:allOrganizationProgram.data.count + allOrganizationSolutions.data.count + } break; } - if (queryData !== "" && queryData !== undefined) { - return resolve({ - result: organizationAssets, - }); - } else { - return resolve({ - success: true, - message: constants.apiResponses.ASSETS_SUCCESSFULLY, + return resolve({ result: organizationAssets, }); - } + } catch (error) { return reject(error); } diff --git a/module/programs/helper.js b/module/programs/helper.js index 41212ff1..e5afd06b 100644 --- a/module/programs/helper.js +++ b/module/programs/helper.js @@ -13,7 +13,7 @@ const kafkaProducersHelper = require(ROOT_PATH + "/generics/kafka/producers"); const programUsersHelper = require(MODULES_BASE_PATH + "/programUsers/helper"); const timeZoneDifference = process.env.TIMEZONE_DIFFRENECE_BETWEEN_LOCAL_TIME_AND_UTC; - const validateEntity = process.env.VALIDATE_ENTITIES +const validateEntity = process.env.VALIDATE_ENTITIES; /** * ProgramsHelper @@ -205,8 +205,7 @@ module.exports = class ProgramsHelper { } let scope = {}; - if(validateEntity !== constants.common.OFF){ - + if (validateEntity !== constants.common.OFF) { if (scopeData.entityType) { // Get entity details of type {scopeData.entityType} let bodyData = { @@ -268,7 +267,7 @@ module.exports = class ProgramsHelper { } scope["entities"] = entityIds; } - + if (scopeData.roles) { if (Array.isArray(scopeData.roles) && scopeData.roles.length > 0) { let userRoles = await userRolesHelper.roleDocuments( @@ -297,7 +296,7 @@ module.exports = class ProgramsHelper { } } } else { - scope = scopeData + scope = scopeData; } let updateProgram = await database.models.programs .findOneAndUpdate( @@ -450,7 +449,11 @@ module.exports = class ProgramsHelper { if (projection && projection.length > 0) { projection.forEach((projectedData) => { - projection1[projectedData] = 1; + if (projectedData === "objectType") { + projection1[projectedData] = "program"; + } else { + projection1[projectedData] = 1; + } }); } else { projection1 = { @@ -578,8 +581,8 @@ module.exports = class ProgramsHelper { let filterQuery = { isDeleted: false, status: constants.common.ACTIVE, - } - if(validateEntity !== constants.common.OFF){ + }; + if (validateEntity !== constants.common.OFF) { let locationIds = Object.values(_.omit(data, ["role", "filter"])).map( (locationId) => { return locationId; @@ -598,10 +601,12 @@ module.exports = class ProgramsHelper { "scope.entities": { $in: locationIds }, }; } else { - let userRoleInfo = _.omit(data, ['filter']) + let userRoleInfo = _.omit(data, ["filter"]); let userRoleKeys = Object.keys(userRoleInfo); - userRoleKeys.forEach(entities => { - filterQuery["scope."+entities] = {$in:userRoleInfo[entities].split(",")} + userRoleKeys.forEach((entities) => { + filterQuery["scope." + entities] = { + $in: userRoleInfo[entities].split(","), + }; }); } @@ -1039,175 +1044,173 @@ module.exports = class ProgramsHelper { ) { return new Promise(async (resolve, reject) => { try { - - let pushProgramUsersDetailsToKafka = false; - //Using programId fetch program details. Also checking the program status in the query. - let programData = await this.programDocuments( + let pushProgramUsersDetailsToKafka = false; + //Using programId fetch program details. Also checking the program status in the query. + let programData = await this.programDocuments( + { + _id: programId, + status: constants.common.ACTIVE, + isDeleted: false, + }, + ["name", "externalId", "requestForPIIConsent", "rootOrganisations"] + ); + + if (!programData.length > 0) { + throw { + status: httpStatusCode.bad_request.status, + message: constants.apiResponses.PROGRAM_NOT_FOUND, + }; + } + let programUsersData = {}; + let update = {}; + + // check if user already joined for program or not + const programUsersDetails = + await programUsersHelper.programUsersDocuments( { - _id: programId, - status: constants.common.ACTIVE, - isDeleted: false, + userId: userId, + programId: programId, }, - ["name", "externalId", "requestForPIIConsent", "rootOrganisations"] + ["_id", "consentShared"] ); - - if (!programData.length > 0) { + // if user not joined for program. we have add more key values to programUsersData + if (!programUsersDetails.length > 0) { + // Fetch user profile information by calling sunbird's user read api. + // !Important check specific fields of userProfile. + let userProfile = await userService.profile(userToken, userId); + if ( + !userProfile.success || + !userProfile.data || + !userProfile.data.profileUserTypes || + !userProfile.data.profileUserTypes.length > 0 || + !userProfile.data.userLocations || + !userProfile.data.userLocations.length > 0 + ) { throw { status: httpStatusCode.bad_request.status, - message: constants.apiResponses.PROGRAM_NOT_FOUND, + message: constants.apiResponses.PROGRAM_JOIN_FAILED, }; } - let programUsersData = {}; - let update = {}; + programUsersData = { + programId: programId, + userRoleInformation: data.userRoleInformation, + userId: userId, + userProfile: userProfile.data, + resourcesStarted: false, + }; + if (appName != "") { + programUsersData["appInformation.appName"] = appName; + } + if (appVersion != "") { + programUsersData["appInformation.appVersion"] = appVersion; + } - // check if user already joined for program or not - const programUsersDetails = - await programUsersHelper.programUsersDocuments( - { - userId: userId, - programId: programId, - }, - ["_id", "consentShared"] - ); - // if user not joined for program. we have add more key values to programUsersData - if (!programUsersDetails.length > 0) { - // Fetch user profile information by calling sunbird's user read api. - // !Important check specific fields of userProfile. - let userProfile = await userService.profile(userToken, userId); + //For internal calls add consent using sunbird api + if ( + callConsetAPIOnBehalfOfUser && + programData[0].hasOwnProperty("requestForPIIConsent") && + programData[0].requestForPIIConsent === true + ) { if ( - !userProfile.success || - !userProfile.data || - !userProfile.data.profileUserTypes || - !userProfile.data.profileUserTypes.length > 0 || - !userProfile.data.userLocations || - !userProfile.data.userLocations.length > 0 + !programData[0].rootOrganisations || + !programData[0].rootOrganisations.length > 0 ) { throw { - status: httpStatusCode.bad_request.status, message: constants.apiResponses.PROGRAM_JOIN_FAILED, + status: httpStatusCode.bad_request.status, }; } - programUsersData = { - programId: programId, - userRoleInformation: data.userRoleInformation, - userId: userId, - userProfile: userProfile.data, - resourcesStarted: false, + let userConsentRequestBody = { + request: { + consent: { + status: constants.common.REVOKED, + userId: userProfile.data.id, + consumerId: programData[0].rootOrganisations[0], + objectId: programId, + objectType: constants.common.PROGRAM, + }, + }, }; - if (appName != "") { - programUsersData["appInformation.appName"] = appName; - } - if (appVersion != "") { - programUsersData["appInformation.appVersion"] = appVersion; - } + let consentResponse = await userService.setUserConsent( + userToken, + userConsentRequestBody + ); - //For internal calls add consent using sunbird api - if ( - callConsetAPIOnBehalfOfUser && - programData[0].hasOwnProperty("requestForPIIConsent") && - programData[0].requestForPIIConsent === true - ) { - if ( - !programData[0].rootOrganisations || - !programData[0].rootOrganisations.length > 0 - ) { - throw { - message: constants.apiResponses.PROGRAM_JOIN_FAILED, - status: httpStatusCode.bad_request.status, - }; - } - let userConsentRequestBody = { - request: { - consent: { - status: constants.common.REVOKED, - userId: userProfile.data.id, - consumerId: programData[0].rootOrganisations[0], - objectId: programId, - objectType: constants.common.PROGRAM, - }, - }, + if (!consentResponse.success) { + throw { + message: constants.apiResponses.PROGRAM_JOIN_FAILED, + status: httpStatusCode.bad_request.status, }; - let consentResponse = await userService.setUserConsent( - userToken, - userConsentRequestBody - ); - - if (!consentResponse.success) { - throw { - message: constants.apiResponses.PROGRAM_JOIN_FAILED, - status: httpStatusCode.bad_request.status, - }; - } } } + } - // if requestForPIIConsent Is false and user not joined program till now then set pushProgramUsersDetailsToKafka = true; - // if requestForPIIConsent == true and data.consentShared value is true which means user interacted with the consent popup set pushProgramUsersDetailsToKafka = true; - // if programUsersDetails[0].consentShared === true which means the data is already pushed to Kafka once - if ( - (programData[0].hasOwnProperty("requestForPIIConsent") && - programData[0].requestForPIIConsent === false && - !programUsersDetails.length > 0) || - (programData[0].hasOwnProperty("requestForPIIConsent") && - programData[0].requestForPIIConsent === true && - data.hasOwnProperty("consentShared") && - data.consentShared == true && - ((programUsersDetails.length > 0 && - programUsersDetails[0].consentShared === false) || - !programUsersDetails.length > 0)) - ) { - pushProgramUsersDetailsToKafka = true; - } + // if requestForPIIConsent Is false and user not joined program till now then set pushProgramUsersDetailsToKafka = true; + // if requestForPIIConsent == true and data.consentShared value is true which means user interacted with the consent popup set pushProgramUsersDetailsToKafka = true; + // if programUsersDetails[0].consentShared === true which means the data is already pushed to Kafka once + if ( + (programData[0].hasOwnProperty("requestForPIIConsent") && + programData[0].requestForPIIConsent === false && + !programUsersDetails.length > 0) || + (programData[0].hasOwnProperty("requestForPIIConsent") && + programData[0].requestForPIIConsent === true && + data.hasOwnProperty("consentShared") && + data.consentShared == true && + ((programUsersDetails.length > 0 && + programUsersDetails[0].consentShared === false) || + !programUsersDetails.length > 0)) + ) { + pushProgramUsersDetailsToKafka = true; + } - //create or update query - const query = { - programId: programId, - userId: userId, - }; - //if a resource is started - if (data.isResource) { - programUsersData.resourcesStarted = true; - } - //if user interacted with the consent-popup - if (data.hasOwnProperty("consentShared")) { - programUsersData.consentShared = data.consentShared; - } - update["$set"] = programUsersData; + //create or update query + const query = { + programId: programId, + userId: userId, + }; + //if a resource is started + if (data.isResource) { + programUsersData.resourcesStarted = true; + } + //if user interacted with the consent-popup + if (data.hasOwnProperty("consentShared")) { + programUsersData.consentShared = data.consentShared; + } + update["$set"] = programUsersData; - // add record to programUsers collection - let joinProgram = await programUsersHelper.update(query, update, { - new: true, - upsert: true, - }); + // add record to programUsers collection + let joinProgram = await programUsersHelper.update(query, update, { + new: true, + upsert: true, + }); - if (!joinProgram._id) { - throw { - message: constants.apiResponses.PROGRAM_JOIN_FAILED, - status: httpStatusCode.bad_request.status, - }; - } + if (!joinProgram._id) { + throw { + message: constants.apiResponses.PROGRAM_JOIN_FAILED, + status: httpStatusCode.bad_request.status, + }; + } - let joinProgramDetails = joinProgram.toObject(); + let joinProgramDetails = joinProgram.toObject(); - if (pushProgramUsersDetailsToKafka) { - joinProgramDetails.programName = programData[0].name; - joinProgramDetails.programExternalId = programData[0].externalId; - joinProgramDetails.requestForPIIConsent = - programData[0].requestForPIIConsent; - // push programUsers details to kafka - await kafkaProducersHelper.pushProgramUsersToKafka( - joinProgramDetails - ); - } + if (pushProgramUsersDetailsToKafka) { + joinProgramDetails.programName = programData[0].name; + joinProgramDetails.programExternalId = programData[0].externalId; + joinProgramDetails.requestForPIIConsent = + programData[0].requestForPIIConsent; + // push programUsers details to kafka + await kafkaProducersHelper.pushProgramUsersToKafka( + joinProgramDetails + ); + } - return resolve({ - message: constants.apiResponses.JOINED_PROGRAM, - success: true, - data: { - _id: joinProgram._id, - }, - }); - + return resolve({ + message: constants.apiResponses.JOINED_PROGRAM, + success: true, + data: { + _id: joinProgram._id, + }, + }); } catch (error) { return resolve({ success: false, @@ -1227,82 +1230,51 @@ module.exports = class ProgramsHelper { * @returns {Object} - Details of the program under the organization. */ - static queryForOrganizationPrograms(bodyData,queryData){ + static queryForOrganizationPrograms(bodyData, queryData) { return new Promise(async (resolve, reject) => { - try{ - let programDocument=[]; - let matchQuery={}; + try { + let pageNo = ""; + let pageSize = ""; + let searchText = ""; + let matchQuery = {}; let filterEmptyStringsFromArray; //if there is an empty string then remove from userids - if(!bodyData.filters.userId){ - filterEmptyStringsFromArray=[]; - }else{ - filterEmptyStringsFromArray= bodyData.filters.userId.filter(str => str !== ""); + if (!bodyData.filters.userId) { + filterEmptyStringsFromArray = []; + } else { + filterEmptyStringsFromArray = bodyData.filters.userId.filter( + (str) => str !== "" + ); } - if(filterEmptyStringsFromArray.length > 0){ - matchQuery={ + if (filterEmptyStringsFromArray.length > 0) { + matchQuery = { $and: [ - {createdFor: {$in:[bodyData.filters.orgId]} }, - { owner: { $in: bodyData.filters.userId} }, - ] - - - } - }else{ - - matchQuery = {createdFor:{$in:[bodyData.filters.orgId]}} - - } - - let projection1 = {}; - if (bodyData.fields && bodyData.fields.length > 0) { - bodyData.fields.forEach((projectedData) => { - if(projectedData === "objectType"){ - projection1["objectType"]="program" - }else{ - projection1[projectedData] = 1; - } - }); - } - let limitQuery; - //omit the limit if there is no type - if(queryData === "" || queryData === undefined){ - limitQuery =Number.MAX_SAFE_INTEGER; - }else{ - limitQuery =bodyData.limit; - + { createdFor: { $in: [bodyData.filters.orgId] } }, + { owner: { $in: bodyData.filters.userId } }, + ], + }; + } else { + matchQuery = { createdFor: { $in: [bodyData.filters.orgId] } }; } - - - - programDocument.push( - { $match: matchQuery }, - { $project: projection1 }, - {$limit : limitQuery} - + let programDocuments = await this.list( + pageNo, + pageSize, + searchText, + matchQuery, + bodyData.fields + ); + return resolve( + programDocuments, ); - let programDocuments = await database.models.programs.aggregate( - programDocument - ); - return resolve({ - success: true, - message: constants.apiResponses.PROGRAM_LIST, - data: programDocuments, - }); - - }catch(error) { + } catch (error) { return resolve({ success: false, message: error.message, data: [], }); } - }) - + }); } }; - - - diff --git a/module/solutions/helper.js b/module/solutions/helper.js index 91a1407b..0526de50 100644 --- a/module/solutions/helper.js +++ b/module/solutions/helper.js @@ -661,7 +661,12 @@ module.exports = class SolutionsHelper { if (projection) { projection.forEach((projectedData) => { + if(projectedData === "objectType"){ + projection1[projectedData] = "solution"; + + }else{ projection1[projectedData] = 1; + } }); } else { projection1 = { @@ -675,11 +680,15 @@ module.exports = class SolutionsHelper { facetQuery["$facet"] = {}; facetQuery["$facet"]["totalCount"] = [{ $count: "count" }]; - + + if (pageSize === "" && pageNo === "") { + facetQuery["$facet"]["data"] = [{ $skip: 0 }]; + }else{ facetQuery["$facet"]["data"] = [ { $skip: pageSize * (pageNo - 1) }, { $limit: pageSize }, ]; + } let projection2 = {}; @@ -2405,83 +2414,58 @@ module.exports = class SolutionsHelper { } /** - * List Program using organization id. + * List Solutions using organization id. * @method - * @name assets + * @name queryForOrganizationSolutions * @query {String} type - Assets type (program/solutions). - * @returns {Object} - Details of the program under the organization. + * @returns {Object} - Details of the solution under the organization. */ - static queryForOrganizationSolutions(bodyData){ + static queryForOrganizationSolutions(bodyData,queryData){ return new Promise(async (resolve, reject) => { - try{ - let solutionDocument=[]; - let matchQuery={}; + try { + let pageNo = ""; + let pageSize = ""; + let searchText = ""; + let type = ""; + let subType = ""; + let matchQuery = {}; let filterEmptyStringsFromArray; //if there is an empty string then remove from userids - if(!bodyData.filters.userId){ - filterEmptyStringsFromArray=[]; - }else{ - filterEmptyStringsFromArray= bodyData.filters.userId.filter(str => str !== ""); + if (!bodyData.filters.userId) { + filterEmptyStringsFromArray = []; + } else { + filterEmptyStringsFromArray = bodyData.filters.userId.filter( + (str) => str !== "" + ); } - if(filterEmptyStringsFromArray.length > 0){ - matchQuery={ + if (filterEmptyStringsFromArray.length > 0) { + matchQuery = { $and: [ - {createdFor: {$in:[bodyData.filters.orgId]} }, - { author: { $in: bodyData.filters.userId} }, - {isAPrivateProgram:false} - ] - } - }else{ - - matchQuery = {createdFor:{$in:[bodyData.filters.orgId]}} - - } - - let projection1 = {}; - if (bodyData.fields && bodyData.fields.length > 0) { - bodyData.fields.forEach((projectedData) => { - if(projectedData === "objectType"){ - projection1["objectType"]="solution" - }else{ - projection1[projectedData] = 1; - } - }); - } else{ - projection1={ - "_id":1, - "name":1, - "status":1, - "owner":1, - "orgId":1, - "objectType":"solution" - } - } - let limitQuery; - //omit the limit if there is no type - if(queryData === "" || queryData === undefined){ - limitQuery =Number.MAX_SAFE_INTEGER; - }else{ - limitQuery =bodyData.limit; - + { createdFor: { $in: [bodyData.filters.orgId] } }, + { author: { $in: bodyData.filters.userId } }, + { isAPrivateProgram: false }, + ], + }; + } else { + matchQuery = { createdFor: { $in: [bodyData.filters.orgId] } }; } - solutionDocument.push( - { $match: matchQuery }, - { $project: projection1 }, - {$limit : limitQuery} + + let solutionDocuments = await this.list( + type, + subType, + matchQuery, + pageNo, + pageSize, + searchText, + bodyData.fields + ); + return resolve( + solutionDocuments, ); - let solutionDocuments = await database.models.solutions.aggregate( - solutionDocument - ); - return resolve({ - success: true, - message: constants.apiResponses.SOLUTIONS_LIST, - data: solutionDocuments, - }); - }catch(error) { return resolve({ success: false, From ba509c290df5c2e01c3942c2c1f174180336a81a Mon Sep 17 00:00:00 2001 From: praveenKDass Date: Fri, 2 Feb 2024 13:17:43 +0530 Subject: [PATCH 11/23] made changes on Feb1 PR comments --- config/kafka.js | 2 +- generics/services/assetsTransfer.js | 173 ----------- module/assets/helper.js | 426 ++++++++++++++++++++-------- module/programs/helper.js | 9 +- module/solutions/helper.js | 17 +- module/user-extension/helper.js | 22 +- module/user-roles/helper.js | 2 +- 7 files changed, 326 insertions(+), 325 deletions(-) delete mode 100644 generics/services/assetsTransfer.js diff --git a/config/kafka.js b/config/kafka.js index 32d12bac..82d8c3af 100644 --- a/config/kafka.js +++ b/config/kafka.js @@ -10,7 +10,7 @@ const kafka = require("kafka-node"); const USER_DELETE_TOPIC = process.env.USER_DELETE_TOPIC; const USER_DELETE_ON_OFF = process.env.USER_DELETE_ON_OFF; const OWNERSHIP_TRANSFER_TOPIC = process.env.OWNERSHIP_TRANSFER_TOPIC; -const OWNERSHIP_TRANSFER_ON_OFF = process.env.USER_DELETE_ON_OFF; +const OWNERSHIP_TRANSFER_ON_OFF = process.env.OWNERSHIP_TRANSFER_ON_OFF; /** * Kafka configurations. diff --git a/generics/services/assetsTransfer.js b/generics/services/assetsTransfer.js deleted file mode 100644 index b730d39f..00000000 --- a/generics/services/assetsTransfer.js +++ /dev/null @@ -1,173 +0,0 @@ -/** - * Get users assets based on Type . - * @method - * @name generateUpdateOperations - * @param {Object} fromUserData - from userData. - * @param {Object} reqData - request body data data. - * @param {Object} toUserData - to user Data from userExtension. - * @param {Array} allAssetsData - PlatformRoles of from user. - - * @returns {Array} returns array of queries to Update. - */ - -async function generateUpdateOperations( - fromUserData, - reqData, - toUserData, - allAssetsData -) { - const bulkOperations = []; - - fromUserData.platformRoles.forEach((role) => { - const roleCodeToUpdate = role.code; - const arrayToMove = allAssetsData.filter( - (roleData) => roleData.code === roleCodeToUpdate - ); - const toUserRoleExists = toUserData.platformRoles.some( - (toRole) => toRole.code === roleCodeToUpdate - ); - - if (!toUserRoleExists) { - // If role code doesn't exist in toUserData, transfer the entire object - bulkOperations.push({ - updateOne: { - filter: { userId: reqData.toUserProfile.userId }, - update: { - $push: { - platformRoles: role, - }, - }, - }, - }); - - // Remove the object from fromUserData - bulkOperations.push({ - updateOne: { - filter: { userId: reqData.fromUserProfile.userId }, - update: { - $pull: { - platformRoles: { code: roleCodeToUpdate }, - }, - }, - }, - }); - } else { - const updateToQuery = { - userId: reqData.toUserProfile.userId, - "platformRoles.code": roleCodeToUpdate, - }; - - const updateToFields = { - $push: { - "platformRoles.$[elem].programs": { - $each: arrayToMove?.[0]?.programs, - }, - }, - }; - - const arrayFilters = [{ "elem.code": roleCodeToUpdate }]; - - const deleteProgramFromUserQuery = { - userId: reqData.fromUserProfile.userId, - "platformRoles.code": roleCodeToUpdate, - }; - - const deleteProgramFromUserField = { - $pull: { - "platformRoles.$[elem].programs": { $in: arrayToMove?.[0]?.programs }, - }, - }; - - // Create bulk write operations - bulkOperations.push({ - updateOne: { - filter: updateToQuery, - update: updateToFields, - arrayFilters: arrayFilters, - }, - }); - - bulkOperations.push({ - updateOne: { - filter: deleteProgramFromUserQuery, - update: deleteProgramFromUserField, - arrayFilters: arrayFilters, - }, - }); - } - }); - - return bulkOperations; -} - -/** - * Get users assets based on Type . - * @method - * @name createProgramRolesArray - * @param {Object} fromUserData - from userData. - * @param {String} findProgramManagerId - Id of Role. - * @param {Array} allAssetsData - PlatformRoles of from user. - - * @returns {Array} returns PlatformRoles array. - */ - -function createProgramRolesArray(fromUserData, findProgramManagerId) { - const programRolesArray = []; - - for (const roleCode of fromUserData.platformRoles) { - const matchingRole = findProgramManagerId.find( - (role) => role.code === roleCode.code - ); - - if (matchingRole) { - const roleId = matchingRole._id; - - const roleDetails = { - roleId: roleId, - code: roleCode.code, - programs: roleCode.programs, - }; - - if (roleCode.code === constants.common.PROGRAM_DESIGNER) { - roleDetails.isAPlatformRole = true; - roleDetails.entities = []; - } - - programRolesArray.push(roleDetails); - } - } - - return programRolesArray; -} - -/** - * Check whether from and to user has Identical Roles. - * @method - * @name createProgramRolesArray - * @param {Array} fromUserData - from array. - * @param {Array} toUserArray - to array. - * @returns {Boolean} returns true or false. - - */ - -function checkRolesPresence(fromUserRoleArray, toUserRoleArray) { - const rolesToCheck = [ - constants.common.PROGRAM_MANAGER, - constants.common.PROGRAM_DESIGNER, - ]; - - const hasRolesInFromArray = rolesToCheck.some((role) => - fromUserRoleArray.includes(role) - ); - const hasRolesInToArray = rolesToCheck.some((role) => - toUserRoleArray.includes(role) - ); - - return hasRolesInFromArray && hasRolesInToArray; -} - -module.exports = { - generateUpdateOperations: generateUpdateOperations, - createProgramRolesArray: createProgramRolesArray, - checkRolesPresence: checkRolesPresence, -}; diff --git a/module/assets/helper.js b/module/assets/helper.js index 5f53c87d..107ba0af 100644 --- a/module/assets/helper.js +++ b/module/assets/helper.js @@ -5,10 +5,8 @@ const userExtensionsHelper = require(MODULES_BASE_PATH + "/user-extension/helper"); const userRolesHelper = require(MODULES_BASE_PATH + "/user-roles/helper"); const kafkaProducersHelper = require(ROOT_PATH + "/generics/kafka/producers"); -const assetService = require(ROOT_PATH + "/generics/services/assetsTransfer"); module.exports = class AssetsHelper { - /** * Get users assets based on Type . * @method @@ -31,7 +29,10 @@ module.exports = class AssetsHelper { break; case "solution": organizationAssets = - await solutionsHelper.queryForOrganizationSolutions(bodyData,queryData); + await solutionsHelper.queryForOrganizationSolutions( + bodyData, + queryData + ); break; default: @@ -41,22 +42,30 @@ module.exports = class AssetsHelper { queryData ); let allOrganizationSolutions = - await solutionsHelper.queryForOrganizationSolutions(bodyData,queryData); + await solutionsHelper.queryForOrganizationSolutions( + bodyData, + queryData + ); organizationAssets = { success: true, message: constants.apiResponses.ASSETS_SUCCESSFULLY, - data:{data:[ ...allOrganizationProgram.data.data, - ...allOrganizationSolutions.data.data]}, - count:allOrganizationProgram.data.count + allOrganizationSolutions.data.count - } + data: { + data: [ + ...allOrganizationProgram.data.data, + ...allOrganizationSolutions.data.data, + ], + }, + count: + allOrganizationProgram.data.count + + allOrganizationSolutions.data.count, + }; break; } return resolve({ - result: organizationAssets, - }); - + result: organizationAssets, + }); } catch (error) { return reject(error); } @@ -68,46 +77,6 @@ module.exports = class AssetsHelper { * @method * @name ownershipTransfer * @param {ownershipTransferEvent} - OwenerShip transfer Event message object - * { - "highWaterOffset": 63, - "key": "", - "offset": 62, - "partition": 0, - "topic": "ownershiptransfer", - "edata": { - "action": "ownership-transfer", - "organisationId": "01269934121990553633", - "context": "Ownership Transfer", - "actionBy": { - "userId": "86d2d978-5b20-4453-8a76-82b5a4c728c9", - "userName": "" - }, - "fromUserProfile": { - "userId": "19d81ef7-36ce-41fe-ae2d-c8365d977be4", - "userName": "", - "channel": "", - "organisationId": "", - "roles": [ - "PROGRAM_MANAGER" - ] - }, - "toUserProfile": { - "userId": "86d2d978-5b20-4453-8a76-82b5a4c728c9", - "userName": "test", - "firstName": "test", - "lastName": "", - "roles": [ - "PROGRAM_MANAGER", - "CONTENT_CREATOR" - ] - }, - "assetInformation": { - "objectType": "solution || program", - "identifier": "{{resource_identifier}}" - }, - "iteration": 1 - } -} * @returns {Promise} success Data. */ static ownershipTransfer(ownershipTransferEvent) { @@ -120,29 +89,19 @@ module.exports = class AssetsHelper { }; let updateUserSolutionsDataResult; - let checkUsersRolesIsIdentical= assetService.checkRolesPresence( + let checkUsersRolesIsIdentical = this.checkRolesPresence( reqData.fromUserProfile.roles, - reqData.fromUserProfile.roles + reqData.toUserProfile.roles ); if ( reqData.actionBy.userId && reqData.fromUserProfile.userId && - reqData.toUserProfile.userId && checkUsersRolesIsIdentical + reqData.toUserProfile.userId && + checkUsersRolesIsIdentical ) { //get Fromuser details from user Extension - let fromUserData = await userExtensionsHelper.userExtensionDocument( - fromFindQuery - ); - //get Touser details from user Extension - let toFindQuery = { - userId: reqData.toUserProfile.userId, - }; - let toUserData = await userExtensionsHelper.userExtensionDocument( - toFindQuery - ); - let allAssetsData = fromUserData?.platformRoles; let typeOfAssetsToMove = reqData.assetInformation.objectType; let checkAssetInformation = reqData.hasOwnProperty("assetInformation"); @@ -193,27 +152,33 @@ module.exports = class AssetsHelper { constants.common.PROGRAM_DESIGNER ) ) { + let fromUserData = + await userExtensionsHelper.userExtensionDocument( + fromFindQuery + ); + //get Touser details from user Extension + let toFindQuery = { + userId: reqData.toUserProfile.userId, + }; + let toUserData = + await userExtensionsHelper.userExtensionDocument(toFindQuery); + let allAssetsData = fromUserData?.platformRoles; if (toUserData) { - const updateQueries = - await assetService.generateUpdateOperations( - fromUserData, - reqData, - toUserData, - allAssetsData - ); - let updateProgram = - await userExtensionsHelper.findOneandUpdate(updateQueries); + let updateQueries = this.generateUpdateOperations( + fromUserData, + toUserData, + allAssetsData + ); + let updateProgram = await userExtensionsHelper.bulkWrite( + updateQueries + ); } else { - //data for create new user in user Extension let newCollectionForUserExtension = { - platformRoles: [], userId: reqData.toUserProfile.userId, - externalId: reqData.toUserProfile.userName, - updatedBy: reqData.actionBy.userId, - createdBy: reqData.actionBy.userId, + externalId: reqData.toUserProfile.userName, }; - const filterCodes = fromUserData.platformRoles.map( + let filterCodes = fromUserData.platformRoles.map( (role) => role.code ); @@ -221,35 +186,63 @@ module.exports = class AssetsHelper { code: { $in: filterCodes }, }; - let findProgramManagerId = await userRolesHelper.findOne( + let findProgramManagerId = await userRolesHelper.find( findProgramManagerQuery ); - const programRolesArray = - assetService.createProgramRolesArray( - fromUserData, - findProgramManagerId - ); - - newCollectionForUserExtension.platformRoles = - programRolesArray; - + let programRolesArray = this.createProgramRolesArray( + fromUserData, + findProgramManagerId + ); //create new Touser if he is not available in the user extension let createUserExtensions = - await userExtensionsHelper.createOne( + await userExtensionsHelper.createOrUpdate( + [], newCollectionForUserExtension ); if (createUserExtensions) { + let updateProgramRolesAndCreatedByMatchQuery={ + userId: reqData.toUserProfile.userId, + + } + let updateProgramRolesAndCreatedByFieldQuery; + if(programRolesArray.length >0){ + updateProgramRolesAndCreatedByFieldQuery={ + $push: { + platformRoles: { + $each: programRolesArray + } + }, + $set: { + updatedBy: reqData.actionBy.userId, + createdBy: reqData.actionBy.userId + }, + } + }else{ + updateProgramRolesAndCreatedByFieldQuery={ + $push: { + platformRoles: { + $each: programRolesArray + } + }, + } + } let deleteProgramFromUserQuery = { userId: reqData.fromUserProfile.userId, }; let deleteProgramFromUserField = { $set: { platformRoles: [] }, }; + let updateUserExtension = await userExtensionsHelper.updateOne( + updateProgramRolesAndCreatedByMatchQuery, + updateProgramRolesAndCreatedByFieldQuery + ); + if(updateUserExtension){ let deleteProgram = await userExtensionsHelper.updateOne( deleteProgramFromUserQuery, deleteProgramFromUserField ); + } } } } @@ -301,26 +294,34 @@ module.exports = class AssetsHelper { constants.common.PROGRAM_DESIGNER ) ) { + let fromUserData = + await userExtensionsHelper.userExtensionDocument( + fromFindQuery + ); + //get Touser details from user Extension + let toFindQuery = { + userId: reqData.toUserProfile.userId, + }; + let toUserData = + await userExtensionsHelper.userExtensionDocument(toFindQuery); + let allAssetsData = fromUserData?.platformRoles; if (toUserData) { - const updateQueries = - await assetService.generateUpdateOperations( - fromUserData, - reqData, - toUserData, - allAssetsData - ); - let updateProgram = - await userExtensionsHelper.findOneandUpdate(updateQueries); + let updateQueries = this.generateUpdateOperations( + fromUserData, + toUserData, + allAssetsData + ); + let updateProgram = await userExtensionsHelper.bulkWrite( + updateQueries + ); } else { //data for create user in user Extension let newCollectionForUserExtension = { - platformRoles: [], userId: reqData.toUserProfile.userId, - externalId: reqData.toUserProfile.userName, - updatedBy: reqData.actionBy.userId, - createdBy: reqData.actionBy.userId, + userName: reqData.toUserProfile.userName, + }; - const filterCodes = fromUserData.platformRoles.map( + let filterCodes = fromUserData.platformRoles.map( (role) => role.code ); @@ -328,34 +329,67 @@ module.exports = class AssetsHelper { code: { $in: filterCodes }, }; - let findProgramManagerId = await userRolesHelper.findOne( + let findProgramManagerId = await userRolesHelper.find( findProgramManagerQuery ); - const programRolesArray = - assetService.createProgramRolesArray( - fromUserData, - findProgramManagerId - ); + let programRolesArray = this.createProgramRolesArray( + fromUserData, + findProgramManagerId + ); - newCollectionForUserExtension.platformRoles = - programRolesArray; + //create new Touser if he is not available in the user extension let createUserExtensions = - await userExtensionsHelper.createOne( + await userExtensionsHelper.createOrUpdate( + [], // device data array newCollectionForUserExtension ); if (createUserExtensions) { + let updateProgramRolesAndCreatedByMatchQuery={ + userId: reqData.toUserProfile.userId, + + } + let updateProgramRolesAndCreatedByFieldQuery; + // update Created and UpdatedBy only when push the Roles + if(programRolesArray.length >0){ + updateProgramRolesAndCreatedByFieldQuery={ + $push: { + platformRoles: { + $each: programRolesArray + } + }, + $set: { + updatedBy: reqData.actionBy.userId, + createdBy: reqData.actionBy.userId + }, + } + }else{ + updateProgramRolesAndCreatedByFieldQuery={ + $push: { + platformRoles: { + $each: programRolesArray + } + }, + } + } + let deleteProgramFromUserQuery = { userId: reqData.fromUserProfile.userId, }; let deleteProgramFromUserField = { $set: { platformRoles: [] }, }; + let updateUserExtension = await userExtensionsHelper.updateOne( + updateProgramRolesAndCreatedByMatchQuery, + updateProgramRolesAndCreatedByFieldQuery + ); + if (updateUserExtension){ let deleteProgram = await userExtensionsHelper.updateOne( deleteProgramFromUserQuery, deleteProgramFromUserField ); + } } } } @@ -413,4 +447,168 @@ module.exports = class AssetsHelper { }); } + /** + * Get users assets based on Type . + * @method + * @name generateUpdateOperations + * @param {Object} fromUserData - from userData. + * @param {Object} reqData - request body data data. + * @param {Object} toUserData - to user Data from userExtension. + * @param {Array} allAssetsData - PlatformRoles of from user. + + * @returns {Array} returns array of queries to Update. + */ + + static generateUpdateOperations(fromUserData, toUserData, allAssetsData) { + let bulkOperations = []; + + fromUserData.platformRoles.forEach((role) => { + let roleCodeToUpdate = role.code; + let arrayToMove = allAssetsData.filter( + (roleData) => roleData.code === roleCodeToUpdate + ); + let toUserRoleExists = toUserData.platformRoles.some( + (toRole) => toRole.code === roleCodeToUpdate + ); + + if (!toUserRoleExists) { + // If role code doesn't exist in toUserData, transfer the entire object + bulkOperations.push({ + updateOne: { + filter: { userId: toUserData.userId }, + update: { + $push: { + platformRoles: role, + }, + }, + }, + }); + + // Remove the object from fromUserData + bulkOperations.push({ + updateOne: { + filter: { userId: fromUserData.userId }, + update: { + $pull: { + platformRoles: { code: roleCodeToUpdate }, + }, + }, + }, + }); + } else { + let updateToQuery = { + userId: toUserData.userId, + "platformRoles.code": roleCodeToUpdate, + }; + + let updateToFields = { + $push: { + "platformRoles.$[elem].programs": { + $each: arrayToMove?.[0]?.programs, + }, + }, + }; + + let arrayFilters = [{ "elem.code": roleCodeToUpdate }]; + + let deleteProgramFromUserQuery = { + userId: fromUserData.userId, + "platformRoles.code": roleCodeToUpdate, + }; + + let deleteProgramFromUserField = { + $pull: { + "platformRoles.$[elem].programs": { + $in: arrayToMove?.[0]?.programs, + }, + }, + }; + + // Create bulk write operations + bulkOperations.push({ + updateOne: { + filter: updateToQuery, + update: updateToFields, + arrayFilters: arrayFilters, + }, + }); + + bulkOperations.push({ + updateOne: { + filter: deleteProgramFromUserQuery, + update: deleteProgramFromUserField, + arrayFilters: arrayFilters, + }, + }); + } + }); + + return bulkOperations; + } + + /** + * Get users assets based on Type . + * @method + * @name createProgramRolesArray + * @param {Object} fromUserData - from userData. + * @param {String} findProgramManagerId - Id of Role. + * @param {Array} allAssetsData - PlatformRoles of from user. + + * @returns {Array} returns PlatformRoles array. + */ + + static createProgramRolesArray(fromUserData, findProgramManagerId) { + let programRolesArray = []; + + for (let roleCode of fromUserData.platformRoles) { + let matchingRole = findProgramManagerId.find( + (role) => role.code === roleCode.code + ); + + if (matchingRole) { + let roleId = matchingRole._id; + + let roleDetails = { + roleId: roleId, + code: roleCode.code, + programs: roleCode.programs, + }; + + if (roleCode.code === constants.common.PROGRAM_DESIGNER) { + roleDetails.isAPlatformRole = true; + roleDetails.entities = []; + } + + programRolesArray.push(roleDetails); + } + } + + return programRolesArray; + } + + /** + * Check whether from and to user has Identical Roles. + * @method + * @name createProgramRolesArray + * @param {Array} fromUserData - from array. + * @param {Array} toUserArray - to array. + * @returns {Boolean} returns true or false. + + */ + + static checkRolesPresence(fromUserRoleArray, toUserRoleArray) { + let rolesToCheck = [ + constants.common.PROGRAM_MANAGER, + constants.common.PROGRAM_DESIGNER, + ]; + + let hasRolesInFromArray = rolesToCheck.some((role) => + fromUserRoleArray.includes(role) + ); + let hasRolesInToArray = rolesToCheck.some((role) => + toUserRoleArray.includes(role) + ); + + return hasRolesInFromArray && hasRolesInToArray; + } }; diff --git a/module/programs/helper.js b/module/programs/helper.js index e5afd06b..6a53174d 100644 --- a/module/programs/helper.js +++ b/module/programs/helper.js @@ -1233,9 +1233,6 @@ module.exports = class ProgramsHelper { static queryForOrganizationPrograms(bodyData, queryData) { return new Promise(async (resolve, reject) => { try { - let pageNo = ""; - let pageSize = ""; - let searchText = ""; let matchQuery = {}; let filterEmptyStringsFromArray; @@ -1259,9 +1256,9 @@ module.exports = class ProgramsHelper { matchQuery = { createdFor: { $in: [bodyData.filters.orgId] } }; } let programDocuments = await this.list( - pageNo, - pageSize, - searchText, + "", // for pageNo + "", // for pageSize + "", // for searchText matchQuery, bodyData.fields ); diff --git a/module/solutions/helper.js b/module/solutions/helper.js index 0526de50..741058e5 100644 --- a/module/solutions/helper.js +++ b/module/solutions/helper.js @@ -2421,15 +2421,10 @@ module.exports = class SolutionsHelper { * @returns {Object} - Details of the solution under the organization. */ - static queryForOrganizationSolutions(bodyData,queryData){ + static queryForOrganizationSolutions(bodyData){ return new Promise(async (resolve, reject) => { try { - let pageNo = ""; - let pageSize = ""; - let searchText = ""; - let type = ""; - let subType = ""; let matchQuery = {}; let filterEmptyStringsFromArray; @@ -2455,12 +2450,12 @@ module.exports = class SolutionsHelper { } let solutionDocuments = await this.list( - type, - subType, + "", //for type + "", // for subType matchQuery, - pageNo, - pageSize, - searchText, + "",// for pageNo + "", // for pageSize + "", // for searchText bodyData.fields ); return resolve( diff --git a/module/user-extension/helper.js b/module/user-extension/helper.js index 98deb76c..f313739e 100644 --- a/module/user-extension/helper.js +++ b/module/user-extension/helper.js @@ -685,12 +685,12 @@ module.exports = class UserExtensionHelper { /** * Transfer ownership from User to ToUser based on Roles * @method - * @name findOneandUpdate + * @name bulkWrite * @param {Array} query - Array of queries to update. * @returns {Array} */ - static findOneandUpdate(query){ + static bulkWrite(query){ return new Promise(async (resolve, reject) => { try{ let insertProgram = await database.models.userExtension.bulkWrite(query) @@ -721,23 +721,7 @@ module.exports = class UserExtensionHelper { } }) } - /** - * Create a new User when toUser not available in the userExtension collection with transferred platformRoles from FromUser - * @method - * @name createOne - * @param {Object} data- newUserData. - * @returns {Array} - */ - static createOne(data){ - return new Promise(async (resolve, reject) => { - try{ - let createUserExtension=await database.models.userExtension.create(data) - resolve(createUserExtension) - }catch(error){ - reject(error); - } - }) - } + }; diff --git a/module/user-roles/helper.js b/module/user-roles/helper.js index a95d02fa..8ecb0c07 100644 --- a/module/user-roles/helper.js +++ b/module/user-roles/helper.js @@ -87,7 +87,7 @@ module.exports = class UserRolesHelper { }); } - static findOne(query){ + static find(query){ return new Promise(async (resolve, reject) => { try{ let findUser =await database.models.userRoles.find(query) From c0a81d2405b4213de7401ef128de253707009b1b Mon Sep 17 00:00:00 2001 From: praveenKDass Date: Fri, 2 Feb 2024 16:09:59 +0530 Subject: [PATCH 12/23] return key added for promises in user extension and roles helper functions --- module/user-extension/helper.js | 4 ++-- module/user-roles/helper.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/module/user-extension/helper.js b/module/user-extension/helper.js index f313739e..d5a81f10 100644 --- a/module/user-extension/helper.js +++ b/module/user-extension/helper.js @@ -694,7 +694,7 @@ module.exports = class UserExtensionHelper { return new Promise(async (resolve, reject) => { try{ let insertProgram = await database.models.userExtension.bulkWrite(query) - resolve(insertProgram) + return resolve(insertProgram) }catch(error){ reject(error); } @@ -715,7 +715,7 @@ module.exports = class UserExtensionHelper { let updateProgram =await database.models.userExtension.updateOne( query,setQuery,{upsert:true} ) - resolve(updateProgram) + return resolve(updateProgram) }catch(error){ reject(error); } diff --git a/module/user-roles/helper.js b/module/user-roles/helper.js index 8ecb0c07..edf933e9 100644 --- a/module/user-roles/helper.js +++ b/module/user-roles/helper.js @@ -91,7 +91,7 @@ module.exports = class UserRolesHelper { return new Promise(async (resolve, reject) => { try{ let findUser =await database.models.userRoles.find(query) - resolve(findUser) + return resolve(findUser) }catch(error){ reject(error); } From 39db1b68e967a56c50ce655a9d7ec6c07d33e895 Mon Sep 17 00:00:00 2001 From: praveenKDass Date: Fri, 2 Feb 2024 17:47:38 +0530 Subject: [PATCH 13/23] renaming functions from query to list --- generics/constants/api-responses.js | 2 +- module/assets/helper.js | 88 +++++++++++++++-------------- module/programs/helper.js | 4 +- module/solutions/helper.js | 4 +- 4 files changed, 50 insertions(+), 48 deletions(-) diff --git a/generics/constants/api-responses.js b/generics/constants/api-responses.js index 6cfa18eb..5d85c918 100644 --- a/generics/constants/api-responses.js +++ b/generics/constants/api-responses.js @@ -204,5 +204,5 @@ module.exports = { "FAILED_TO_CREATE_DOWNLOADABLEURL" : "Failed to generate downloadableUrl", "KEYS_INDEXED_SUCCESSFULLY": 'Keys indexed successfully', "KEYS_ALREADY_INDEXED": 'Keys already indexed', - "ASSETS_SUCCESSFULLY": "Assets fetched successfully " + "ASSETS_FETCHED_SUCCESSFULLY": "Assets fetched successfully " }; diff --git a/module/assets/helper.js b/module/assets/helper.js index 107ba0af..91cb5687 100644 --- a/module/assets/helper.js +++ b/module/assets/helper.js @@ -22,14 +22,14 @@ module.exports = class AssetsHelper { switch (queryData) { case "program": organizationAssets = - await programsHelper.queryForOrganizationPrograms( + await programsHelper.listOrganizationPrograms( bodyData, queryData ); break; case "solution": organizationAssets = - await solutionsHelper.queryForOrganizationSolutions( + await solutionsHelper.listOrganizationSolutions( bodyData, queryData ); @@ -37,18 +37,18 @@ module.exports = class AssetsHelper { break; default: let allOrganizationProgram = - await programsHelper.queryForOrganizationPrograms( + await programsHelper.listOrganizationPrograms( bodyData, queryData ); let allOrganizationSolutions = - await solutionsHelper.queryForOrganizationSolutions( + await solutionsHelper.listOrganizationSolutions( bodyData, queryData ); organizationAssets = { success: true, - message: constants.apiResponses.ASSETS_SUCCESSFULLY, + message: constants.apiResponses.ASSETS_FETCHED_SUCCESSFULLY, data: { data: [ ...allOrganizationProgram.data.data, @@ -100,8 +100,6 @@ module.exports = class AssetsHelper { reqData.toUserProfile.userId && checkUsersRolesIsIdentical ) { - //get Fromuser details from user Extension - let typeOfAssetsToMove = reqData.assetInformation.objectType; let checkAssetInformation = reqData.hasOwnProperty("assetInformation"); @@ -143,7 +141,7 @@ module.exports = class AssetsHelper { updateUserSolutionsDataResult = await Promise.all( updateUserSolutions ); - } else { + } if ( reqData.toUserProfile.roles.includes( constants.common.PROGRAM_MANAGER @@ -178,22 +176,8 @@ module.exports = class AssetsHelper { userId: reqData.toUserProfile.userId, externalId: reqData.toUserProfile.userName, }; - let filterCodes = fromUserData.platformRoles.map( - (role) => role.code - ); - - let findProgramManagerQuery = { - code: { $in: filterCodes }, - }; - - let findProgramManagerId = await userRolesHelper.find( - findProgramManagerQuery - ); + let programRolesArray = await this.fetchFromUserDataPlatformRoles(fromUserData) - let programRolesArray = this.createProgramRolesArray( - fromUserData, - findProgramManagerId - ); //create new Touser if he is not available in the user extension let createUserExtensions = await userExtensionsHelper.createOrUpdate( @@ -246,7 +230,7 @@ module.exports = class AssetsHelper { } } } - } + } else { if ( reqData.toUserProfile.roles.includes( @@ -321,25 +305,8 @@ module.exports = class AssetsHelper { userName: reqData.toUserProfile.userName, }; - let filterCodes = fromUserData.platformRoles.map( - (role) => role.code - ); - - let findProgramManagerQuery = { - code: { $in: filterCodes }, - }; - - let findProgramManagerId = await userRolesHelper.find( - findProgramManagerQuery - ); - - let programRolesArray = this.createProgramRolesArray( - fromUserData, - findProgramManagerId - ); - - - //create new Touser if he is not available in the user extension + let programRolesArray = await this.fetchFromUserDataPlatformRoles(fromUserData) + //create new user if to user not available in the user extension let createUserExtensions = await userExtensionsHelper.createOrUpdate( [], // device data array @@ -611,4 +578,39 @@ module.exports = class AssetsHelper { return hasRolesInFromArray && hasRolesInToArray; } + /** + * Query to Platform Roles for touser when user Not in UserExtension + * @method + * @name fetchFromUserDataPlatformRoles + * @param {Array} fromUserData - from array. + * @returns {Array} returns Array of Platform Roles to push to TOUSER + + */ + static fetchFromUserDataPlatformRoles(fromUserData){ + return new Promise(async (resolve, reject) => { + try{ + let filterCodes = fromUserData.platformRoles.map( + (role) => role.code + ); + + let findProgramManagerQuery = { + code: { $in: filterCodes }, + }; + + let findProgramManagerId = await userRolesHelper.find( + findProgramManagerQuery + ); + + let programRolesArray = this.createProgramRolesArray( + fromUserData, + findProgramManagerId + ); + return resolve(programRolesArray) + }catch(error){ + reject(error); + } + }) +} + + }; diff --git a/module/programs/helper.js b/module/programs/helper.js index 6a53174d..4dee9165 100644 --- a/module/programs/helper.js +++ b/module/programs/helper.js @@ -1225,12 +1225,12 @@ module.exports = class ProgramsHelper { /** * List Program using organization id. * @method - * @name assets + * @name listOrganizationPrograms * @query {String} type - Assets type (program/solutions). * @returns {Object} - Details of the program under the organization. */ - static queryForOrganizationPrograms(bodyData, queryData) { + static listOrganizationPrograms(bodyData, queryData) { return new Promise(async (resolve, reject) => { try { let matchQuery = {}; diff --git a/module/solutions/helper.js b/module/solutions/helper.js index 741058e5..508edc95 100644 --- a/module/solutions/helper.js +++ b/module/solutions/helper.js @@ -2416,12 +2416,12 @@ module.exports = class SolutionsHelper { /** * List Solutions using organization id. * @method - * @name queryForOrganizationSolutions + * @name listOrganizationSolutions * @query {String} type - Assets type (program/solutions). * @returns {Object} - Details of the solution under the organization. */ - static queryForOrganizationSolutions(bodyData){ + static listOrganizationSolutions(bodyData){ return new Promise(async (resolve, reject) => { try { From 125f9d051654bb151726adaa1abf1071c68fafc8 Mon Sep 17 00:00:00 2001 From: praveenKDass Date: Mon, 5 Feb 2024 23:03:36 +0530 Subject: [PATCH 14/23] file upload to the azure cloud --- controllers/v1/uploads.js | 33 ++++++++++++++++++++ module/fileUpload/helper.js | 61 +++++++++++++++++++++++++++++++++++++ 2 files changed, 94 insertions(+) create mode 100644 controllers/v1/uploads.js create mode 100644 module/fileUpload/helper.js diff --git a/controllers/v1/uploads.js b/controllers/v1/uploads.js new file mode 100644 index 00000000..b0c37059 --- /dev/null +++ b/controllers/v1/uploads.js @@ -0,0 +1,33 @@ +const fileUploadHelper = require(MODULES_BASE_PATH + "/fileUpload/helper.js"); + + + +module.exports = class Uploads { + /** + * Upload a image to azure cloud. + * @name cloudUpload + * @api {post} v1/uploads/cloudUpload + * @apiHeader {String} X-authenticated-user-token Authenticity token + * @apiParamExample {File} Req; + * @apiResponse {JSON} + * + **/ + async cloudUpload(req) { + return new Promise(async (resolve, reject) => { + try { + let assestsData = await fileUploadHelper.uploadFiles( + req + ); + return resolve(assestsData); + } catch (error) { + return reject({ + status: error.status || httpStatusCode.internal_server_error.status, + message: + error.message || httpStatusCode.internal_server_error.message, + errorObject: error, + }); + } + + }); + } + }; \ No newline at end of file diff --git a/module/fileUpload/helper.js b/module/fileUpload/helper.js new file mode 100644 index 00000000..71a66a48 --- /dev/null +++ b/module/fileUpload/helper.js @@ -0,0 +1,61 @@ +const multer = require("multer"); +const storage = multer.memoryStorage(); +const upload = multer({ storage: storage }); +const { BlobServiceClient } = require("@azure/storage-blob"); +const apiResponses = require("../../generics/constants/api-responses"); +const azureConnection = `DefaultEndpointsProtocol=https;AccountName=${process.env.CLOUD_STORAGE_ACCOUNTNAME};AccountKey=${process.env.CLOUD_STORAGE_SECRET};EndpointSuffix=core.windows.net`; + +module.exports = class fileUploadHelper { + static uploadFiles(req) { + return new Promise(async (resolve, reject) => { + // Apply the upload.single middleware to handle file uploads + upload.single("file")(req, null, async (err) => { + if (err) { + // Handle multer error, if any + return reject({ + status: httpStatusCode.bad_request.status, + errorObject: err, + }); + } + + try { + + // Upload the file to Azure Blob Storage + const blobServiceClient = BlobServiceClient.fromConnectionString( + azureConnection + ); + const containerClient = blobServiceClient.getContainerClient( + process.env.CLOUD_STORAGE_BUCKETNAME + ); + + const blobName = `uploadedFile/${req.files.file.name}`; + + const blockBlobClient = containerClient.getBlockBlobClient(blobName); + const data = Buffer.from(req.files.file.data); + + const uploadResponse = await blockBlobClient.upload( + data, + data.length + ); + + let uploadedData = { + azureURL: blockBlobClient.url, + uploadRes: uploadResponse, + }; + + return resolve({ + message: apiResponses.FILE_UPLOADED, + result: uploadedData, + }); + } catch (error) { + return reject({ + status: error.status || httpStatusCode.internal_server_error.status, + message: + error.message || httpStatusCode.internal_server_error.message, + errorObject: error, + }); + } + }); + }); + } +}; From b19e257b068a13477c5ce83bcab973cb2691c77e Mon Sep 17 00:00:00 2001 From: praveenKDass Date: Wed, 7 Feb 2024 16:09:04 +0530 Subject: [PATCH 15/23] wrote the conditon for assetinformation identifier' --- module/assets/helper.js | 363 ++++++++++++++++++++++++---------------- 1 file changed, 215 insertions(+), 148 deletions(-) diff --git a/module/assets/helper.js b/module/assets/helper.js index 91cb5687..3cb47cec 100644 --- a/module/assets/helper.js +++ b/module/assets/helper.js @@ -21,11 +21,10 @@ module.exports = class AssetsHelper { let organizationAssets; switch (queryData) { case "program": - organizationAssets = - await programsHelper.listOrganizationPrograms( - bodyData, - queryData - ); + organizationAssets = await programsHelper.listOrganizationPrograms( + bodyData, + queryData + ); break; case "solution": organizationAssets = @@ -76,7 +75,7 @@ module.exports = class AssetsHelper { * Transfer ownership Kafka Event. * @method * @name ownershipTransfer - * @param {ownershipTransferEvent} - OwenerShip transfer Event message object + * @param {ownershipTransferEvent} - OwenerShip transfer Event message object * @returns {Promise} success Data. */ static ownershipTransfer(ownershipTransferEvent) { @@ -141,96 +140,96 @@ module.exports = class AssetsHelper { updateUserSolutionsDataResult = await Promise.all( updateUserSolutions ); - } - if ( - reqData.toUserProfile.roles.includes( - constants.common.PROGRAM_MANAGER - ) || - reqData.toUserProfile.roles.includes( - constants.common.PROGRAM_DESIGNER - ) - ) { - let fromUserData = - await userExtensionsHelper.userExtensionDocument( - fromFindQuery - ); - //get Touser details from user Extension - let toFindQuery = { + } + if ( + reqData.toUserProfile.roles.includes( + constants.common.PROGRAM_MANAGER + ) || + reqData.toUserProfile.roles.includes( + constants.common.PROGRAM_DESIGNER + ) + ) { + let fromUserData = + await userExtensionsHelper.userExtensionDocument(fromFindQuery); + //get Touser details from user Extension + let toFindQuery = { + userId: reqData.toUserProfile.userId, + }; + let toUserData = await userExtensionsHelper.userExtensionDocument( + toFindQuery + ); + let allAssetsData = fromUserData?.platformRoles; + if (toUserData) { + let updateQueries = this.generateUpdateOperations( + fromUserData, + toUserData, + allAssetsData, + reqData, + ); + let updateProgram = await userExtensionsHelper.bulkWrite( + updateQueries + ); + } else { + //data for create new user in user Extension + let newCollectionForUserExtension = { userId: reqData.toUserProfile.userId, + externalId: reqData.toUserProfile.userName, }; - let toUserData = - await userExtensionsHelper.userExtensionDocument(toFindQuery); - let allAssetsData = fromUserData?.platformRoles; - if (toUserData) { - let updateQueries = this.generateUpdateOperations( - fromUserData, - toUserData, - allAssetsData - ); - let updateProgram = await userExtensionsHelper.bulkWrite( - updateQueries + let programRolesArray = + await this.fetchFromUserDataPlatformRoles(fromUserData); + + //create new Touser if he is not available in the user extension + let createUserExtensions = + await userExtensionsHelper.createOrUpdate( + [], + newCollectionForUserExtension ); - } else { - //data for create new user in user Extension - let newCollectionForUserExtension = { + if (createUserExtensions) { + let updateProgramRolesAndCreatedByMatchQuery = { userId: reqData.toUserProfile.userId, - externalId: reqData.toUserProfile.userName, }; - let programRolesArray = await this.fetchFromUserDataPlatformRoles(fromUserData) - - //create new Touser if he is not available in the user extension - let createUserExtensions = - await userExtensionsHelper.createOrUpdate( - [], - newCollectionForUserExtension - ); - if (createUserExtensions) { - let updateProgramRolesAndCreatedByMatchQuery={ - userId: reqData.toUserProfile.userId, - - } - let updateProgramRolesAndCreatedByFieldQuery; - if(programRolesArray.length >0){ - updateProgramRolesAndCreatedByFieldQuery={ + let updateProgramRolesAndCreatedByFieldQuery; + if (programRolesArray.length > 0) { + updateProgramRolesAndCreatedByFieldQuery = { $push: { platformRoles: { - $each: programRolesArray - } + $each: programRolesArray, + }, }, $set: { updatedBy: reqData.actionBy.userId, - createdBy: reqData.actionBy.userId + createdBy: reqData.actionBy.userId, }, - } - }else{ - updateProgramRolesAndCreatedByFieldQuery={ + }; + } else { + updateProgramRolesAndCreatedByFieldQuery = { $push: { platformRoles: { - $each: programRolesArray - } + $each: programRolesArray, + }, }, - } - } - let deleteProgramFromUserQuery = { - userId: reqData.fromUserProfile.userId, }; - let deleteProgramFromUserField = { - $set: { platformRoles: [] }, - }; - let updateUserExtension = await userExtensionsHelper.updateOne( + } + let deleteProgramFromUserQuery = { + userId: reqData.fromUserProfile.userId, + }; + let deleteProgramFromUserField = { + $set: { platformRoles: [] }, + }; + let updateUserExtension = + await userExtensionsHelper.updateOne( updateProgramRolesAndCreatedByMatchQuery, updateProgramRolesAndCreatedByFieldQuery ); - if(updateUserExtension){ + if (updateUserExtension) { let deleteProgram = await userExtensionsHelper.updateOne( deleteProgramFromUserQuery, deleteProgramFromUserField ); - } } } } - + } } else { if ( reqData.toUserProfile.roles.includes( @@ -241,6 +240,7 @@ module.exports = class AssetsHelper { //filter for solution updates let solutionFilter = { author: reqData.fromUserProfile.userId, + _id: reqData.assetInformation.identifier, }; let updateSolutions = { $set: { @@ -293,7 +293,9 @@ module.exports = class AssetsHelper { let updateQueries = this.generateUpdateOperations( fromUserData, toUserData, - allAssetsData + allAssetsData, + reqData, + checkAssetInformation ); let updateProgram = await userExtensionsHelper.bulkWrite( updateQueries @@ -303,9 +305,10 @@ module.exports = class AssetsHelper { let newCollectionForUserExtension = { userId: reqData.toUserProfile.userId, userName: reqData.toUserProfile.userName, - }; - let programRolesArray = await this.fetchFromUserDataPlatformRoles(fromUserData) + let programRolesArray = + await this.fetchFromUserDataPlatformRoles(fromUserData,reqData, + checkAssetInformation); //create new user if to user not available in the user extension let createUserExtensions = await userExtensionsHelper.createOrUpdate( @@ -313,33 +316,32 @@ module.exports = class AssetsHelper { newCollectionForUserExtension ); if (createUserExtensions) { - let updateProgramRolesAndCreatedByMatchQuery={ + let updateProgramRolesAndCreatedByMatchQuery = { userId: reqData.toUserProfile.userId, - - } + }; let updateProgramRolesAndCreatedByFieldQuery; // update Created and UpdatedBy only when push the Roles - if(programRolesArray.length >0){ - updateProgramRolesAndCreatedByFieldQuery={ - $push: { - platformRoles: { - $each: programRolesArray - } - }, - $set: { - updatedBy: reqData.actionBy.userId, - createdBy: reqData.actionBy.userId - }, - } - }else{ - updateProgramRolesAndCreatedByFieldQuery={ - $push: { - platformRoles: { - $each: programRolesArray - } - }, - } - } + if (programRolesArray.length > 0) { + updateProgramRolesAndCreatedByFieldQuery = { + $push: { + platformRoles: { + $each: programRolesArray, + }, + }, + $set: { + updatedBy: reqData.actionBy.userId, + createdBy: reqData.actionBy.userId, + }, + }; + } else { + updateProgramRolesAndCreatedByFieldQuery = { + $push: { + platformRoles: { + $each: programRolesArray, + }, + }, + }; + } let deleteProgramFromUserQuery = { userId: reqData.fromUserProfile.userId, @@ -347,15 +349,16 @@ module.exports = class AssetsHelper { let deleteProgramFromUserField = { $set: { platformRoles: [] }, }; - let updateUserExtension = await userExtensionsHelper.updateOne( - updateProgramRolesAndCreatedByMatchQuery, - updateProgramRolesAndCreatedByFieldQuery - ); - if (updateUserExtension){ - let deleteProgram = await userExtensionsHelper.updateOne( - deleteProgramFromUserQuery, - deleteProgramFromUserField - ); + let updateUserExtension = + await userExtensionsHelper.updateOne( + updateProgramRolesAndCreatedByMatchQuery, + updateProgramRolesAndCreatedByFieldQuery + ); + if (updateUserExtension) { + let deleteProgram = await userExtensionsHelper.updateOne( + deleteProgramFromUserQuery, + deleteProgramFromUserField + ); } } } @@ -426,7 +429,13 @@ module.exports = class AssetsHelper { * @returns {Array} returns array of queries to Update. */ - static generateUpdateOperations(fromUserData, toUserData, allAssetsData) { + static generateUpdateOperations( + fromUserData, + toUserData, + allAssetsData, + reqData = {}, + checkAssetInformation = false + ) { let bulkOperations = []; fromUserData.platformRoles.forEach((role) => { @@ -440,6 +449,37 @@ module.exports = class AssetsHelper { if (!toUserRoleExists) { // If role code doesn't exist in toUserData, transfer the entire object + if(checkAssetInformation){ + // add the program from toUserData + let newRole ={ + roleId:role.roleId, + code:role.code, + programs:role.programs.filter(eachProgram => eachProgram.equals(reqData.assetInformation.identifier)) + } + bulkOperations.push({ + updateOne: { + filter: { userId: toUserData.userId }, + update: { + $push: { + platformRoles: newRole, + }, + }, + }, + }); + + // Remove the program from fromUserData + bulkOperations.push({ + updateOne: { + filter: { userId: fromUserData.userId }, + update: { + $pull: { + "platformRoles.$[elem].programs": new ObjectId(reqData.assetInformation.identifier) , + }, + }, + arrayFilters:[{ "elem.code": roleCodeToUpdate }], + }, + }); + }else{ bulkOperations.push({ updateOne: { filter: { userId: toUserData.userId }, @@ -462,19 +502,46 @@ module.exports = class AssetsHelper { }, }, }); + } } else { let updateToQuery = { userId: toUserData.userId, "platformRoles.code": roleCodeToUpdate, }; - let updateToFields = { - $push: { - "platformRoles.$[elem].programs": { - $each: arrayToMove?.[0]?.programs, + let updateToFields; + let deleteProgramFromUserField; + if (checkAssetInformation) { + updateToFields = { + $push: { + "platformRoles.$[elem].programs": { + $each: arrayToMove[0].programs.filter(oneProgram =>{ + return oneProgram.equals(reqData.assetInformation.identifier) } + ) + }, }, - }, - }; + }; + deleteProgramFromUserField = { + $pull: { + "platformRoles.$[elem].programs": new ObjectId(reqData.assetInformation.identifier) , + }, + }; + } else { + updateToFields = { + $push: { + "platformRoles.$[elem].programs": { + $each: arrayToMove?.[0]?.programs, + }, + }, + }; + deleteProgramFromUserField = { + $pull: { + "platformRoles.$[elem].programs": { + $in: arrayToMove?.[0]?.programs, + }, + }, + }; + } let arrayFilters = [{ "elem.code": roleCodeToUpdate }]; @@ -483,14 +550,6 @@ module.exports = class AssetsHelper { "platformRoles.code": roleCodeToUpdate, }; - let deleteProgramFromUserField = { - $pull: { - "platformRoles.$[elem].programs": { - $in: arrayToMove?.[0]?.programs, - }, - }, - }; - // Create bulk write operations bulkOperations.push({ updateOne: { @@ -524,7 +583,7 @@ module.exports = class AssetsHelper { * @returns {Array} returns PlatformRoles array. */ - static createProgramRolesArray(fromUserData, findProgramManagerId) { + static createProgramRolesArray(fromUserData, findProgramManagerId,reqData={}, checkAssetInformation = false ) { let programRolesArray = []; for (let roleCode of fromUserData.platformRoles) { @@ -534,12 +593,21 @@ module.exports = class AssetsHelper { if (matchingRole) { let roleId = matchingRole._id; - - let roleDetails = { + let roleDetails + if(checkAssetInformation){ + roleDetails = { + roleId: roleId, + code: roleCode.code, + programs: roleCode.programs.filter(eachProgram => eachProgram.equals(reqData.assetInformation.identifier)), + }; + }else{ + roleDetails = { roleId: roleId, code: roleCode.code, programs: roleCode.programs, }; + } + if (roleCode.code === constants.common.PROGRAM_DESIGNER) { roleDetails.isAPlatformRole = true; @@ -586,31 +654,30 @@ module.exports = class AssetsHelper { * @returns {Array} returns Array of Platform Roles to push to TOUSER */ - static fetchFromUserDataPlatformRoles(fromUserData){ + static fetchFromUserDataPlatformRoles(fromUserData,reqData, + checkAssetInformation) { return new Promise(async (resolve, reject) => { - try{ - let filterCodes = fromUserData.platformRoles.map( - (role) => role.code - ); - - let findProgramManagerQuery = { - code: { $in: filterCodes }, - }; + try { + let filterCodes = fromUserData.platformRoles.map((role) => role.code); - let findProgramManagerId = await userRolesHelper.find( - findProgramManagerQuery - ); - - let programRolesArray = this.createProgramRolesArray( - fromUserData, - findProgramManagerId - ); - return resolve(programRolesArray) - }catch(error){ - reject(error); - } - }) -} + let findProgramManagerQuery = { + code: { $in: filterCodes }, + }; + let findProgramManagerId = await userRolesHelper.find( + findProgramManagerQuery + ); + let programRolesArray = this.createProgramRolesArray( + fromUserData, + findProgramManagerId, + reqData, + checkAssetInformation + ); + return resolve(programRolesArray); + } catch (error) { + reject(error); + } + }); + } }; From df5d903c28621a237602a9300c56b2bbb82640b8 Mon Sep 17 00:00:00 2001 From: praveenKDass Date: Wed, 7 Feb 2024 18:40:24 +0530 Subject: [PATCH 16/23] bug fixes on owner asstes tranfser --- module/assets/helper.js | 163 +++++++++++++++++++------------- module/user-extension/helper.js | 4 +- 2 files changed, 101 insertions(+), 66 deletions(-) diff --git a/module/assets/helper.js b/module/assets/helper.js index 3cb47cec..90c0fe0a 100644 --- a/module/assets/helper.js +++ b/module/assets/helper.js @@ -164,7 +164,7 @@ module.exports = class AssetsHelper { fromUserData, toUserData, allAssetsData, - reqData, + reqData ); let updateProgram = await userExtensionsHelper.bulkWrite( updateQueries @@ -307,8 +307,11 @@ module.exports = class AssetsHelper { userName: reqData.toUserProfile.userName, }; let programRolesArray = - await this.fetchFromUserDataPlatformRoles(fromUserData,reqData, - checkAssetInformation); + await this.fetchFromUserDataPlatformRoles( + fromUserData, + reqData, + checkAssetInformation + ); //create new user if to user not available in the user extension let createUserExtensions = await userExtensionsHelper.createOrUpdate( @@ -347,8 +350,14 @@ module.exports = class AssetsHelper { userId: reqData.fromUserProfile.userId, }; let deleteProgramFromUserField = { - $set: { platformRoles: [] }, + $pull: { + $pull: { + "platformRoles.$[elem].programs": new ObjectId(reqData.assetInformation.identifier) + }, + } }; + let arrayFilters = [{ "elem.code": programRolesArray[0].code}]; + let updateUserExtension = await userExtensionsHelper.updateOne( updateProgramRolesAndCreatedByMatchQuery, @@ -357,7 +366,8 @@ module.exports = class AssetsHelper { if (updateUserExtension) { let deleteProgram = await userExtensionsHelper.updateOne( deleteProgramFromUserQuery, - deleteProgramFromUserField + deleteProgramFromUserField, + arrayFilters ); } } @@ -449,60 +459,68 @@ module.exports = class AssetsHelper { if (!toUserRoleExists) { // If role code doesn't exist in toUserData, transfer the entire object - if(checkAssetInformation){ - // add the program from toUserData - let newRole ={ - roleId:role.roleId, - code:role.code, - programs:role.programs.filter(eachProgram => eachProgram.equals(reqData.assetInformation.identifier)) - } + if (checkAssetInformation) { + let checkRoleToUpdateProgram = role.programs.some((programId) => + programId.equals(reqData.assetInformation.identifier) + ); + if (checkRoleToUpdateProgram) { + let newRole = { + roleId: role.roleId, + code: role.code, + programs: role.programs.filter((eachProgram) => + eachProgram.equals(reqData.assetInformation.identifier) + ), + }; + bulkOperations.push({ + updateOne: { + filter: { userId: toUserData.userId }, + update: { + $push: { + platformRoles: newRole, + }, + }, + }, + }); + + // Remove the program from fromUserData + bulkOperations.push({ + updateOne: { + filter: { userId: fromUserData.userId }, + update: { + $pull: { + "platformRoles.$[elem].programs": new ObjectId( + reqData.assetInformation.identifier + ), + }, + }, + arrayFilters: [{ "elem.code": roleCodeToUpdate }], + }, + }); + } + } else { bulkOperations.push({ updateOne: { filter: { userId: toUserData.userId }, update: { $push: { - platformRoles: newRole, + platformRoles: role, }, }, }, }); - - // Remove the program from fromUserData + + // Remove the object from fromUserData bulkOperations.push({ updateOne: { filter: { userId: fromUserData.userId }, update: { $pull: { - "platformRoles.$[elem].programs": new ObjectId(reqData.assetInformation.identifier) , + platformRoles: { code: roleCodeToUpdate }, }, }, - arrayFilters:[{ "elem.code": roleCodeToUpdate }], }, }); - }else{ - bulkOperations.push({ - updateOne: { - filter: { userId: toUserData.userId }, - update: { - $push: { - platformRoles: role, - }, - }, - }, - }); - - // Remove the object from fromUserData - bulkOperations.push({ - updateOne: { - filter: { userId: fromUserData.userId }, - update: { - $pull: { - platformRoles: { code: roleCodeToUpdate }, - }, - }, - }, - }); - } + } } else { let updateToQuery = { userId: toUserData.userId, @@ -515,15 +533,17 @@ module.exports = class AssetsHelper { updateToFields = { $push: { "platformRoles.$[elem].programs": { - $each: arrayToMove[0].programs.filter(oneProgram =>{ - return oneProgram.equals(reqData.assetInformation.identifier) } - ) + $each: arrayToMove[0].programs.filter((oneProgram) => { + return oneProgram.equals(reqData.assetInformation.identifier); + }), }, }, }; deleteProgramFromUserField = { $pull: { - "platformRoles.$[elem].programs": new ObjectId(reqData.assetInformation.identifier) , + "platformRoles.$[elem].programs": new ObjectId( + reqData.assetInformation.identifier + ), }, }; } else { @@ -583,7 +603,12 @@ module.exports = class AssetsHelper { * @returns {Array} returns PlatformRoles array. */ - static createProgramRolesArray(fromUserData, findProgramManagerId,reqData={}, checkAssetInformation = false ) { + static createProgramRolesArray( + fromUserData, + findProgramManagerId, + reqData = {}, + checkAssetInformation = false + ) { let programRolesArray = []; for (let roleCode of fromUserData.platformRoles) { @@ -593,28 +618,35 @@ module.exports = class AssetsHelper { if (matchingRole) { let roleId = matchingRole._id; - let roleDetails - if(checkAssetInformation){ - roleDetails = { - roleId: roleId, - code: roleCode.code, - programs: roleCode.programs.filter(eachProgram => eachProgram.equals(reqData.assetInformation.identifier)), - }; - }else{ - roleDetails = { - roleId: roleId, - code: roleCode.code, - programs: roleCode.programs, - }; - } - + let roleDetails; + if (checkAssetInformation) { + let checkRoleToUpdateProgram = roleCode.programs.some((programId) => + programId.equals(reqData.assetInformation.identifier) + ); + if(checkRoleToUpdateProgram){ + roleDetails = { + roleId: roleId, + code: roleCode.code, + programs: roleCode.programs.filter((eachProgram) => + eachProgram.equals(reqData.assetInformation.identifier) + ), + }; + } + } else { + roleDetails = { + roleId: roleId, + code: roleCode.code, + programs: roleCode.programs, + }; + } if (roleCode.code === constants.common.PROGRAM_DESIGNER) { roleDetails.isAPlatformRole = true; roleDetails.entities = []; } - + if(roleDetails){ programRolesArray.push(roleDetails); + } } } @@ -654,8 +686,11 @@ module.exports = class AssetsHelper { * @returns {Array} returns Array of Platform Roles to push to TOUSER */ - static fetchFromUserDataPlatformRoles(fromUserData,reqData, - checkAssetInformation) { + static fetchFromUserDataPlatformRoles( + fromUserData, + reqData, + checkAssetInformation + ) { return new Promise(async (resolve, reject) => { try { let filterCodes = fromUserData.platformRoles.map((role) => role.code); diff --git a/module/user-extension/helper.js b/module/user-extension/helper.js index d5a81f10..328308e7 100644 --- a/module/user-extension/helper.js +++ b/module/user-extension/helper.js @@ -709,11 +709,11 @@ module.exports = class UserExtensionHelper { * @param {Object} setQuery Remove programRoles from an FromUser. * @returns {Array} */ - static updateOne( query,setQuery){ + static updateOne( query,setQuery,arrayFilters=[]){ return new Promise(async (resolve, reject) => { try{ let updateProgram =await database.models.userExtension.updateOne( - query,setQuery,{upsert:true} + query,setQuery,{arrayFilters,upsert:true} ) return resolve(updateProgram) }catch(error){ From 5440320ee190cd2f387505fa482d401968fd5a3a Mon Sep 17 00:00:00 2001 From: praveenKDass Date: Wed, 7 Feb 2024 18:54:09 +0530 Subject: [PATCH 17/23] bug fixes for owner asstes transfer --- module/assets/helper.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/module/assets/helper.js b/module/assets/helper.js index 90c0fe0a..1e19cebc 100644 --- a/module/assets/helper.js +++ b/module/assets/helper.js @@ -99,7 +99,7 @@ module.exports = class AssetsHelper { reqData.toUserProfile.userId && checkUsersRolesIsIdentical ) { - let typeOfAssetsToMove = reqData.assetInformation.objectType; + let typeOfAssetsToMove = reqData.assetInformation?.objectType; let checkAssetInformation = reqData.hasOwnProperty("assetInformation"); @@ -173,7 +173,7 @@ module.exports = class AssetsHelper { //data for create new user in user Extension let newCollectionForUserExtension = { userId: reqData.toUserProfile.userId, - externalId: reqData.toUserProfile.userName, + userName: reqData.toUserProfile.userName, }; let programRolesArray = await this.fetchFromUserDataPlatformRoles(fromUserData); From df8f28796dcfd185708273082a064a707db39186 Mon Sep 17 00:00:00 2001 From: praveenKDass Date: Wed, 7 Feb 2024 19:06:56 +0530 Subject: [PATCH 18/23] removed upload from PR --- controllers/v1/uploads.js | 33 -------------------- module/fileUpload/helper.js | 61 ------------------------------------- 2 files changed, 94 deletions(-) delete mode 100644 controllers/v1/uploads.js delete mode 100644 module/fileUpload/helper.js diff --git a/controllers/v1/uploads.js b/controllers/v1/uploads.js deleted file mode 100644 index b0c37059..00000000 --- a/controllers/v1/uploads.js +++ /dev/null @@ -1,33 +0,0 @@ -const fileUploadHelper = require(MODULES_BASE_PATH + "/fileUpload/helper.js"); - - - -module.exports = class Uploads { - /** - * Upload a image to azure cloud. - * @name cloudUpload - * @api {post} v1/uploads/cloudUpload - * @apiHeader {String} X-authenticated-user-token Authenticity token - * @apiParamExample {File} Req; - * @apiResponse {JSON} - * - **/ - async cloudUpload(req) { - return new Promise(async (resolve, reject) => { - try { - let assestsData = await fileUploadHelper.uploadFiles( - req - ); - return resolve(assestsData); - } catch (error) { - return reject({ - status: error.status || httpStatusCode.internal_server_error.status, - message: - error.message || httpStatusCode.internal_server_error.message, - errorObject: error, - }); - } - - }); - } - }; \ No newline at end of file diff --git a/module/fileUpload/helper.js b/module/fileUpload/helper.js deleted file mode 100644 index 71a66a48..00000000 --- a/module/fileUpload/helper.js +++ /dev/null @@ -1,61 +0,0 @@ -const multer = require("multer"); -const storage = multer.memoryStorage(); -const upload = multer({ storage: storage }); -const { BlobServiceClient } = require("@azure/storage-blob"); -const apiResponses = require("../../generics/constants/api-responses"); -const azureConnection = `DefaultEndpointsProtocol=https;AccountName=${process.env.CLOUD_STORAGE_ACCOUNTNAME};AccountKey=${process.env.CLOUD_STORAGE_SECRET};EndpointSuffix=core.windows.net`; - -module.exports = class fileUploadHelper { - static uploadFiles(req) { - return new Promise(async (resolve, reject) => { - // Apply the upload.single middleware to handle file uploads - upload.single("file")(req, null, async (err) => { - if (err) { - // Handle multer error, if any - return reject({ - status: httpStatusCode.bad_request.status, - errorObject: err, - }); - } - - try { - - // Upload the file to Azure Blob Storage - const blobServiceClient = BlobServiceClient.fromConnectionString( - azureConnection - ); - const containerClient = blobServiceClient.getContainerClient( - process.env.CLOUD_STORAGE_BUCKETNAME - ); - - const blobName = `uploadedFile/${req.files.file.name}`; - - const blockBlobClient = containerClient.getBlockBlobClient(blobName); - const data = Buffer.from(req.files.file.data); - - const uploadResponse = await blockBlobClient.upload( - data, - data.length - ); - - let uploadedData = { - azureURL: blockBlobClient.url, - uploadRes: uploadResponse, - }; - - return resolve({ - message: apiResponses.FILE_UPLOADED, - result: uploadedData, - }); - } catch (error) { - return reject({ - status: error.status || httpStatusCode.internal_server_error.status, - message: - error.message || httpStatusCode.internal_server_error.message, - errorObject: error, - }); - } - }); - }); - } -}; From 0f6ab28a88116ba4b168d97ac18c9fd99154f7e2 Mon Sep 17 00:00:00 2001 From: praveenKDass Date: Thu, 8 Feb 2024 13:05:04 +0530 Subject: [PATCH 19/23] bug fixes on ownerAssetTransfer one to one flow --- module/assets/helper.js | 35 ++++++++++++++++----------------- module/user-extension/helper.js | 4 ++-- 2 files changed, 19 insertions(+), 20 deletions(-) diff --git a/module/assets/helper.js b/module/assets/helper.js index 1e19cebc..d46d18c8 100644 --- a/module/assets/helper.js +++ b/module/assets/helper.js @@ -1,3 +1,4 @@ + // Dependencies const programsHelper = require(MODULES_BASE_PATH + "/programs/helper"); const solutionsHelper = require(MODULES_BASE_PATH + "/solutions/helper"); @@ -117,7 +118,7 @@ module.exports = class AssetsHelper { let updateSolutions = { $set: { author: reqData.toUserProfile.userId, - creator: reqData.toUserProfile.firstname, + creator: reqData.toUserProfile.firstName, }, }; let solutionLicenseFilter = { @@ -174,6 +175,8 @@ module.exports = class AssetsHelper { let newCollectionForUserExtension = { userId: reqData.toUserProfile.userId, userName: reqData.toUserProfile.userName, + updatedBy: reqData.actionBy.userId, + createdBy: reqData.actionBy.userId, }; let programRolesArray = await this.fetchFromUserDataPlatformRoles(fromUserData); @@ -196,10 +199,6 @@ module.exports = class AssetsHelper { $each: programRolesArray, }, }, - $set: { - updatedBy: reqData.actionBy.userId, - createdBy: reqData.actionBy.userId, - }, }; } else { updateProgramRolesAndCreatedByFieldQuery = { @@ -245,7 +244,7 @@ module.exports = class AssetsHelper { let updateSolutions = { $set: { author: reqData.toUserProfile.userId, - creator: reqData.toUserProfile.firstname, + creator: reqData.toUserProfile.firstName, }, }; let solutionLicenseFilter = { @@ -269,14 +268,15 @@ module.exports = class AssetsHelper { updateUserSolutionsDataResult = await Promise.all( updateUserSolutions ); - } else { + } + if ( reqData.toUserProfile.roles.includes( constants.common.PROGRAM_MANAGER ) || reqData.toUserProfile.roles.includes( constants.common.PROGRAM_DESIGNER - ) + ) && typeOfAssetsToMove === constants.common.PROGRAM ) { let fromUserData = await userExtensionsHelper.userExtensionDocument( @@ -305,6 +305,8 @@ module.exports = class AssetsHelper { let newCollectionForUserExtension = { userId: reqData.toUserProfile.userId, userName: reqData.toUserProfile.userName, + updatedBy: reqData.actionBy.userId, + createdBy: reqData.actionBy.userId, }; let programRolesArray = await this.fetchFromUserDataPlatformRoles( @@ -323,7 +325,7 @@ module.exports = class AssetsHelper { userId: reqData.toUserProfile.userId, }; let updateProgramRolesAndCreatedByFieldQuery; - // update Created and UpdatedBy only when push the Roles + // update and push the Roles if (programRolesArray.length > 0) { updateProgramRolesAndCreatedByFieldQuery = { $push: { @@ -331,10 +333,6 @@ module.exports = class AssetsHelper { $each: programRolesArray, }, }, - $set: { - updatedBy: reqData.actionBy.userId, - createdBy: reqData.actionBy.userId, - }, }; } else { updateProgramRolesAndCreatedByFieldQuery = { @@ -348,6 +346,7 @@ module.exports = class AssetsHelper { let deleteProgramFromUserQuery = { userId: reqData.fromUserProfile.userId, + 'platformRole.code': programRolesArray[0].code, }; let deleteProgramFromUserField = { $pull: { @@ -373,7 +372,7 @@ module.exports = class AssetsHelper { } } } - } + } } @@ -533,9 +532,9 @@ module.exports = class AssetsHelper { updateToFields = { $push: { "platformRoles.$[elem].programs": { - $each: arrayToMove[0].programs.filter((oneProgram) => { - return oneProgram.equals(reqData.assetInformation.identifier); - }), + $each: arrayToMove[0].programs.filter((oneProgram) => + oneProgram.equals(reqData.assetInformation.identifier) + ), }, }, }; @@ -640,7 +639,7 @@ module.exports = class AssetsHelper { }; } - if (roleCode.code === constants.common.PROGRAM_DESIGNER) { + if (roleCode.code === constants.common.PROGRAM_DESIGNER && roleDetails) { roleDetails.isAPlatformRole = true; roleDetails.entities = []; } diff --git a/module/user-extension/helper.js b/module/user-extension/helper.js index 328308e7..cf57ab83 100644 --- a/module/user-extension/helper.js +++ b/module/user-extension/helper.js @@ -115,8 +115,8 @@ module.exports = class UserExtensionHelper { "status": "active", "isDeleted": false, "devices": [deviceData], - "createdBy": "SYSTEM", - "updatedBy": "SYSTEM" + "createdBy":userDetails.createdBy?userDetails.createdBy: "SYSTEM", + "updatedBy":userDetails.updatedBy? userDetails.updatedBy:"SYSTEM" } ); From 133ecf80c45c1b258b93b7daec002ec66585cfc8 Mon Sep 17 00:00:00 2001 From: praveenKDass Date: Thu, 8 Feb 2024 16:44:44 +0530 Subject: [PATCH 20/23] program collection query added --- module/assets/helper.js | 253 +++++++++++++++++++++----------------- module/programs/helper.js | 27 ++++ 2 files changed, 170 insertions(+), 110 deletions(-) diff --git a/module/assets/helper.js b/module/assets/helper.js index d46d18c8..de54a14a 100644 --- a/module/assets/helper.js +++ b/module/assets/helper.js @@ -1,4 +1,3 @@ - // Dependencies const programsHelper = require(MODULES_BASE_PATH + "/programs/helper"); const solutionsHelper = require(MODULES_BASE_PATH + "/solutions/helper"); @@ -6,6 +5,7 @@ const userExtensionsHelper = require(MODULES_BASE_PATH + "/user-extension/helper"); const userRolesHelper = require(MODULES_BASE_PATH + "/user-roles/helper"); const kafkaProducersHelper = require(ROOT_PATH + "/generics/kafka/producers"); +const programUsersHelper = require(MODULES_BASE_PATH + "/programUsers/helper"); module.exports = class AssetsHelper { /** @@ -167,7 +167,7 @@ module.exports = class AssetsHelper { allAssetsData, reqData ); - let updateProgram = await userExtensionsHelper.bulkWrite( + let updateUserExtensionProgram = await userExtensionsHelper.bulkWrite( updateQueries ); } else { @@ -221,13 +221,25 @@ module.exports = class AssetsHelper { updateProgramRolesAndCreatedByFieldQuery ); if (updateUserExtension) { - let deleteProgram = await userExtensionsHelper.updateOne( + let deleteserExtensionProgram = await userExtensionsHelper.updateOne( deleteProgramFromUserQuery, deleteProgramFromUserField ); } } } + let programFilter = { + owner: reqData.fromUserProfile.userId, + }; + let updatePrograms = { + $set: { + owner: reqData.toUserProfile.userId, + }, + }; + let updatePartialPrograms = await programsHelper.updateMany( + programFilter, + updatePrograms + ); } } else { if ( @@ -239,7 +251,7 @@ module.exports = class AssetsHelper { //filter for solution updates let solutionFilter = { author: reqData.fromUserProfile.userId, - _id: reqData.assetInformation.identifier, + _id: new ObjectId(reqData.assetInformation.identifier), }; let updateSolutions = { $set: { @@ -268,111 +280,128 @@ module.exports = class AssetsHelper { updateUserSolutionsDataResult = await Promise.all( updateUserSolutions ); - } - - if ( - reqData.toUserProfile.roles.includes( - constants.common.PROGRAM_MANAGER - ) || - reqData.toUserProfile.roles.includes( - constants.common.PROGRAM_DESIGNER - ) && typeOfAssetsToMove === constants.common.PROGRAM - ) { - let fromUserData = - await userExtensionsHelper.userExtensionDocument( - fromFindQuery - ); - //get Touser details from user Extension - let toFindQuery = { + } + + if ( + reqData.toUserProfile.roles.includes( + constants.common.PROGRAM_MANAGER + ) || + (reqData.toUserProfile.roles.includes( + constants.common.PROGRAM_DESIGNER + ) && + typeOfAssetsToMove === constants.common.PROGRAM) + ) { + let fromUserData = + await userExtensionsHelper.userExtensionDocument(fromFindQuery); + //get Touser details from user Extension + let toFindQuery = { + userId: reqData.toUserProfile.userId, + }; + let toUserData = await userExtensionsHelper.userExtensionDocument( + toFindQuery + ); + let allAssetsData = fromUserData?.platformRoles; + if (toUserData) { + let updateQueries = this.generateUpdateOperations( + fromUserData, + toUserData, + allAssetsData, + reqData, + checkAssetInformation + ); + let updateUserExtensionProgram = await userExtensionsHelper.bulkWrite( + updateQueries + ); + } else { + //data for create user in user Extension + let newCollectionForUserExtension = { userId: reqData.toUserProfile.userId, + userName: reqData.toUserProfile.userName, + updatedBy: reqData.actionBy.userId, + createdBy: reqData.actionBy.userId, }; - let toUserData = - await userExtensionsHelper.userExtensionDocument(toFindQuery); - let allAssetsData = fromUserData?.platformRoles; - if (toUserData) { - let updateQueries = this.generateUpdateOperations( + let programRolesArray = + await this.fetchFromUserDataPlatformRoles( fromUserData, - toUserData, - allAssetsData, reqData, checkAssetInformation ); - let updateProgram = await userExtensionsHelper.bulkWrite( - updateQueries + //create new user if to user not available in the user extension + let createUserExtensions = + await userExtensionsHelper.createOrUpdate( + [], // device data array + newCollectionForUserExtension ); - } else { - //data for create user in user Extension - let newCollectionForUserExtension = { + if (createUserExtensions) { + let updateProgramRolesAndCreatedByMatchQuery = { userId: reqData.toUserProfile.userId, - userName: reqData.toUserProfile.userName, - updatedBy: reqData.actionBy.userId, - createdBy: reqData.actionBy.userId, }; - let programRolesArray = - await this.fetchFromUserDataPlatformRoles( - fromUserData, - reqData, - checkAssetInformation - ); - //create new user if to user not available in the user extension - let createUserExtensions = - await userExtensionsHelper.createOrUpdate( - [], // device data array - newCollectionForUserExtension - ); - if (createUserExtensions) { - let updateProgramRolesAndCreatedByMatchQuery = { - userId: reqData.toUserProfile.userId, - }; - let updateProgramRolesAndCreatedByFieldQuery; - // update and push the Roles - if (programRolesArray.length > 0) { - updateProgramRolesAndCreatedByFieldQuery = { - $push: { - platformRoles: { - $each: programRolesArray, - }, - }, - }; - } else { - updateProgramRolesAndCreatedByFieldQuery = { - $push: { - platformRoles: { - $each: programRolesArray, - }, + let updateProgramRolesAndCreatedByFieldQuery; + // update and push the Roles + if (programRolesArray.length > 0) { + updateProgramRolesAndCreatedByFieldQuery = { + $push: { + platformRoles: { + $each: programRolesArray, }, - }; - } - - let deleteProgramFromUserQuery = { - userId: reqData.fromUserProfile.userId, - 'platformRole.code': programRolesArray[0].code, + }, }; - let deleteProgramFromUserField = { - $pull: { - $pull: { - "platformRoles.$[elem].programs": new ObjectId(reqData.assetInformation.identifier) + } else { + updateProgramRolesAndCreatedByFieldQuery = { + $push: { + platformRoles: { + $each: programRolesArray, }, - } + }, }; - let arrayFilters = [{ "elem.code": programRolesArray[0].code}]; - - let updateUserExtension = - await userExtensionsHelper.updateOne( - updateProgramRolesAndCreatedByMatchQuery, - updateProgramRolesAndCreatedByFieldQuery - ); - if (updateUserExtension) { - let deleteProgram = await userExtensionsHelper.updateOne( - deleteProgramFromUserQuery, - deleteProgramFromUserField, - arrayFilters - ); - } + } + + let deleteProgramFromUserQuery = { + userId: reqData.fromUserProfile.userId, + "platformRole.code": programRolesArray[0].code, + }; + let deleteProgramFromUserField = { + $pull: { + $pull: { + "platformRoles.$[elem].programs": new ObjectId( + reqData.assetInformation.identifier + ), + }, + }, + }; + let arrayFilters = [ + { "elem.code": programRolesArray[0].code }, + ]; + + let updateUserExtension = + await userExtensionsHelper.updateOne( + updateProgramRolesAndCreatedByMatchQuery, + updateProgramRolesAndCreatedByFieldQuery + ); + if (updateUserExtension) { + let deleteuserExtensionProgram = await userExtensionsHelper.updateOne( + deleteProgramFromUserQuery, + deleteProgramFromUserField, + arrayFilters + ); } } } - + + let programFilter = { + owner: reqData.fromUserProfile.userId, + _id:new ObjectId(reqData.assetInformation.identifier), + }; + let updatePrograms = { + $set: { + owner: reqData.toUserProfile.userId, + }, + }; + let updateOneProgram= await programsHelper.updateMany( + programFilter, + updatePrograms + ); + } } } @@ -496,7 +525,8 @@ module.exports = class AssetsHelper { }, }); } - } else { + } + if(!checkAssetInformation){ bulkOperations.push({ updateOne: { filter: { userId: toUserData.userId }, @@ -533,7 +563,7 @@ module.exports = class AssetsHelper { $push: { "platformRoles.$[elem].programs": { $each: arrayToMove[0].programs.filter((oneProgram) => - oneProgram.equals(reqData.assetInformation.identifier) + oneProgram.equals(reqData.assetInformation.identifier) ), }, }, @@ -620,17 +650,17 @@ module.exports = class AssetsHelper { let roleDetails; if (checkAssetInformation) { let checkRoleToUpdateProgram = roleCode.programs.some((programId) => - programId.equals(reqData.assetInformation.identifier) - ); - if(checkRoleToUpdateProgram){ - roleDetails = { - roleId: roleId, - code: roleCode.code, - programs: roleCode.programs.filter((eachProgram) => - eachProgram.equals(reqData.assetInformation.identifier) - ), - }; - } + programId.equals(reqData.assetInformation.identifier) + ); + if (checkRoleToUpdateProgram) { + roleDetails = { + roleId: roleId, + code: roleCode.code, + programs: roleCode.programs.filter((eachProgram) => + eachProgram.equals(reqData.assetInformation.identifier) + ), + }; + } } else { roleDetails = { roleId: roleId, @@ -639,13 +669,16 @@ module.exports = class AssetsHelper { }; } - if (roleCode.code === constants.common.PROGRAM_DESIGNER && roleDetails) { + if ( + roleCode.code === constants.common.PROGRAM_DESIGNER && + roleDetails + ) { roleDetails.isAPlatformRole = true; roleDetails.entities = []; } - if(roleDetails){ - programRolesArray.push(roleDetails); - } + if (roleDetails) { + programRolesArray.push(roleDetails); + } } } diff --git a/module/programs/helper.js b/module/programs/helper.js index 4dee9165..b7972d17 100644 --- a/module/programs/helper.js +++ b/module/programs/helper.js @@ -1274,4 +1274,31 @@ module.exports = class ProgramsHelper { } }); } + /** + * Update program users + * @method + * @name updateMany + * @param {Object} query + * @param {Object} update + * @param {Object} options + * @returns {JSON} - update program. + */ + + static updateMany(query, update, options = {}) { + return new Promise(async (resolve, reject) => { + try { + + let updatedProgramCount = await database.models.programs.updateMany( + query, + update, + options + ); + if( updatedProgramCount) { + return resolve(updatedProgramCount); + } + } catch (error) { + return reject(error); + } + }) +} }; From f898c1b3615b53599691150a3e42d8b84bde437c Mon Sep 17 00:00:00 2001 From: praveenKDass Date: Thu, 8 Feb 2024 20:45:51 +0530 Subject: [PATCH 21/23] telementry event conditions added --- module/assets/helper.js | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/module/assets/helper.js b/module/assets/helper.js index de54a14a..5409e1a2 100644 --- a/module/assets/helper.js +++ b/module/assets/helper.js @@ -88,7 +88,7 @@ module.exports = class AssetsHelper { platformRoles: { $exists: true }, }; - let updateUserSolutionsDataResult; + let updateUserAssetDataResult=false; let checkUsersRolesIsIdentical = this.checkRolesPresence( reqData.fromUserProfile.roles, reqData.toUserProfile.roles @@ -100,7 +100,6 @@ module.exports = class AssetsHelper { reqData.toUserProfile.userId && checkUsersRolesIsIdentical ) { - let typeOfAssetsToMove = reqData.assetInformation?.objectType; let checkAssetInformation = reqData.hasOwnProperty("assetInformation"); @@ -138,9 +137,11 @@ module.exports = class AssetsHelper { updateSolutionsLicense ), ]; - updateUserSolutionsDataResult = await Promise.all( + let updatedSolution = await Promise.all( updateUserSolutions ); + + updatedSolution? updateUserAssetDataResult=true : updateUserAssetDataResult=false; } if ( reqData.toUserProfile.roles.includes( @@ -167,7 +168,7 @@ module.exports = class AssetsHelper { allAssetsData, reqData ); - let updateUserExtensionProgram = await userExtensionsHelper.bulkWrite( + await userExtensionsHelper.bulkWrite( updateQueries ); } else { @@ -240,8 +241,11 @@ module.exports = class AssetsHelper { programFilter, updatePrograms ); + updatePartialPrograms?updateUserAssetDataResult=true : updateUserAssetDataResult=false; } } else { + let typeOfAssetsToMove = reqData.assetInformation?.objectType; + if ( reqData.toUserProfile.roles.includes( constants.common.CONTENT_CREATOR @@ -277,9 +281,11 @@ module.exports = class AssetsHelper { updateSolutionsLicense ), ]; - updateUserSolutionsDataResult = await Promise.all( + let updatedOneToOneTransferSolution = await Promise.all( updateUserSolutions ); + updatedOneToOneTransferSolution? updateUserAssetDataResult=true : updateUserAssetDataResult=false; + } if ( @@ -397,18 +403,20 @@ module.exports = class AssetsHelper { owner: reqData.toUserProfile.userId, }, }; - let updateOneProgram= await programsHelper.updateMany( + + let updatedOneToOneTransferProgram= await programsHelper.updateMany( programFilter, updatePrograms ); + + updatedOneToOneTransferProgram? updateUserAssetDataResult=true : updateUserAssetDataResult=false; + } } } if ( - updateUserSolutionsDataResult && - (updateUserSolutionsDataResult[0].nModified > 0 || - updateUserSolutionsDataResult[1].nModified > 0) + updateUserAssetDataResult ) { if (telemetryEventOnOff !== constants.common.OFF) { /** From 1d38a43ebbd2cf808cd025e2d47fc0b612bf17a5 Mon Sep 17 00:00:00 2001 From: praveenKDass Date: Fri, 16 Feb 2024 02:29:36 +0530 Subject: [PATCH 22/23] working on file upload api --- controllers/v1/cloud-services/files.js | 70 +++++++++++++++++++++++++- module/cloud-services/files/helper.js | 52 +++++++++++++++++++ module/files/helper.js | 49 +++++++++++++++++- 3 files changed, 168 insertions(+), 3 deletions(-) diff --git a/controllers/v1/cloud-services/files.js b/controllers/v1/cloud-services/files.js index 215a58aa..10c36746 100644 --- a/controllers/v1/cloud-services/files.js +++ b/controllers/v1/cloud-services/files.js @@ -93,14 +93,14 @@ module.exports = class Files { return new Promise(async (resolve, reject) => { try { - - let signedUrl = + let signedUrl = await filesHelpers.preSignedUrls( req.body.request, req.body.ref, req.userDetails ? req.userDetails.userId : "" ); + signedUrl["result"] = signedUrl["data"]; return resolve(signedUrl); @@ -183,6 +183,72 @@ module.exports = class Files { }) } + + /** + * Get upload the file and Downloadable URL from cloud service. + * @method + * @name upload + * @param {Request} req request body. + * @returns {JSON} Response with status and message. + * @apiParamExample {json} Response: + * { + "message": "File uploaded successfully", + "status": 200, + "result": { + "url": { + "path": "uploadedFiles/industry.csv", + "downloadUrl": "https://sunbirddev.blob.core.windows.net/manage-learn-evidences/uploadedFiles/industry.csv?sv=2023-01-03&st=2024-02-15T11%3A54%3A41Z&se=2024-02-17T23%3A54%3A41Z&sr=b&sp=r&sig=LXLT8S4T2i2QUFPNLMbVMbp1fqhSznOSom4A3mh3KCk%3D" + }, + "payload": { + "sourcePath": "uploadedFiles/industry.csv" + }, + "cloudStorage": "AZURE" + } + } + */ + + async upload(req) { + return new Promise(async (resolve, reject) => { + + try { + + if (req.files) { + + let uploadResponse = + await filesHelpers.upload( + req.files.file, + ); + + return resolve({ + message: constants.apiResponses.FILE_UPLOADED, + result: uploadResponse.result + }) + + } else { + return reject({ + status: httpStatusCode["bad_request"].status, + message: httpStatusCode["bad_request"].message + + }); + } + + } catch (error) { + + return reject({ + status: + error.status || + httpStatusCode["internal_server_error"].status, + + message: + error.message + || httpStatusCode["internal_server_error"].message, + + errorObject: error + }) + + } + }) + } }; diff --git a/module/cloud-services/files/helper.js b/module/cloud-services/files/helper.js index e3f8f08a..984b9a5e 100644 --- a/module/cloud-services/files/helper.js +++ b/module/cloud-services/files/helper.js @@ -162,6 +162,58 @@ module.exports = class FilesHelper { }) } + + /** + * upload and get Url and path from Cloud . + * @method + * @name upload + * @param {Object} payloadData - payload of file data. + * @returns {JSON} - path and downloadUrl of the file. + */ + static upload(payloadData) { + return new Promise(async (resolve, reject) => { + + try { + // let folderName ="uploadedFiles/" + let folderName =process.env.CLOUD_FOLDER_NAME || ""; + + let downloadableUrl = await filesHelpers.upload( + payloadData.name, + folderName, + bucketName, + payloadData.data, + ); + if( !downloadableUrl.success ) { + return resolve({ + status : httpStatusCode['bad_request'].status, + message : constants.apiResponses.FAILED_TO_CREATE_DOWNLOADABLEURL, + result : {} + }); + } + + return resolve({ + message: constants.apiResponses.CLOUD_SERVICE_SUCCESS_MESSAGE, + result: downloadableUrl.result + }) + + } catch (error) { + + return reject({ + status: + error.status || + httpStatusCode["internal_server_error"].status, + + message: + error.message + || httpStatusCode["internal_server_error"].message, + + errorObject: error + }) + + } + }) + + } } diff --git a/module/files/helper.js b/module/files/helper.js index 84fb65aa..4bf5395c 100644 --- a/module/files/helper.js +++ b/module/files/helper.js @@ -116,6 +116,7 @@ module.exports = class FilesHelper { */ static preSignedUrls(fileNames, bucket, storageName = '',folderPath, expireIn = '', permission = '', addDruidFileUrlForIngestion = false) { + console.log(fileNames, bucket, storageName = '',folderPath,) return new Promise(async (resolve, reject) => { try { let actionPermission = constants.common.WRITE_PERMISSION; @@ -137,7 +138,7 @@ module.exports = class FilesHelper { if (expireIn !== '') { linkExpireTime = expireIn; } - + console.log(fileNames) // Create an array of promises for signed URLs // {sample response} : https://sunbirdstagingpublic.blob.core.windows.net/samiksha/reports/sample.pdf?sv=2020-10-02&st=2023-08-03T07%3A53%3A53Z&se=2023-08-03T08%3A53%3A53Z&sr=b&sp=w&sig=eZOHrBBH%2F55E93Sxq%2BHSrniCEmKrKc7LYnfNwz6BvWE%3D const signedUrlsPromises = fileNames.map(async (fileName) => { @@ -186,6 +187,52 @@ module.exports = class FilesHelper { } }) } + + /** + * Upload and get Download Url for a file. + * @method + * @name upload + * @param {String} fileName - name of the file. + * @param {String} folderPath - folderPath + * @param {String} bucket - name of the bucket + * @param {Array} data - Binary Value of file to upload. + * @returns {JSON} - Path and download Url for the file + */ + static upload(fileName,folderPath,bucket,data) { + return new Promise(async (resolve, reject) => { + try { + // {sample response} : ttps://mentoring-prod-storage.s3.ap-south-1.amazonaws.com/mentoring-prod-storage/uploadedFiles/download.jpeg" + let file = folderPath && folderPath !== '' ? folderPath + fileName : fileName; + + let signedUrlResponse = await cloudClient.upload( + bucket, // bucket name + file, // file path + data, //file content + ); + + let response = { + url: signedUrlResponse, + payload: { sourcePath: file }, + cloudStorage: cloudStorage.toUpperCase() + }; + + + // Return success response with the upload path and download URLs + return resolve({ + success: true, + message: constants.apiResponses.URL_GENERATED, + result: response + }); + + } catch (error) { + return reject({ + success: false, + message: constants.apiResponses.FAILED_TO_UPLOAD, + error: error + }) + } + }) + } /** * Unzip file * @method From d229f35654c8f7ab091a663ac51269cb7361ef3e Mon Sep 17 00:00:00 2001 From: praveenKDass Date: Fri, 16 Feb 2024 02:41:49 +0530 Subject: [PATCH 23/23] removing logs --- module/files/helper.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/module/files/helper.js b/module/files/helper.js index 4bf5395c..8ccac122 100644 --- a/module/files/helper.js +++ b/module/files/helper.js @@ -116,7 +116,6 @@ module.exports = class FilesHelper { */ static preSignedUrls(fileNames, bucket, storageName = '',folderPath, expireIn = '', permission = '', addDruidFileUrlForIngestion = false) { - console.log(fileNames, bucket, storageName = '',folderPath,) return new Promise(async (resolve, reject) => { try { let actionPermission = constants.common.WRITE_PERMISSION; @@ -138,7 +137,6 @@ module.exports = class FilesHelper { if (expireIn !== '') { linkExpireTime = expireIn; } - console.log(fileNames) // Create an array of promises for signed URLs // {sample response} : https://sunbirdstagingpublic.blob.core.windows.net/samiksha/reports/sample.pdf?sv=2020-10-02&st=2023-08-03T07%3A53%3A53Z&se=2023-08-03T08%3A53%3A53Z&sr=b&sp=w&sig=eZOHrBBH%2F55E93Sxq%2BHSrniCEmKrKc7LYnfNwz6BvWE%3D const signedUrlsPromises = fileNames.map(async (fileName) => {