From b133459b879f0d6a7f4c9c0cd645c7e2d4fac555 Mon Sep 17 00:00:00 2001 From: Tushar Date: Thu, 8 Feb 2024 16:24:29 +0530 Subject: [PATCH 001/126] Get count of learners Api --- src/src/camp/camp.module.ts | 1 + src/src/camp/camp.service.ts | 110 +++++++++++++++++++++++++---------- 2 files changed, 81 insertions(+), 30 deletions(-) diff --git a/src/src/camp/camp.module.ts b/src/src/camp/camp.module.ts index ce92bbfb0..67bd17a66 100644 --- a/src/src/camp/camp.module.ts +++ b/src/src/camp/camp.module.ts @@ -75,6 +75,7 @@ export class CampModule implements NestModule { '/camp/:id/get-camp-sessions', '/camp/incomplete/camp-day-activity/:id', '/camp/random-attendance/:id', + '/camp/campday/campdetails', ) .forRoutes(CampController); } diff --git a/src/src/camp/camp.service.ts b/src/src/camp/camp.service.ts index c78c3dd7c..4a4d441de 100644 --- a/src/src/camp/camp.service.ts +++ b/src/src/camp/camp.service.ts @@ -4271,44 +4271,94 @@ export class CampService { let context_id = body?.context_id; const dateString = moment().startOf('day').format(); const endDate = moment().endOf('day').format(); + let errorMessage; + + if (body?.fields && !Array.isArray(body?.fields)) { + errorMessage = 'Fields Must Be Array'; + } + // Validate the request parameters if (!camp_id || !context_id) { + errorMessage = 'Required Camp-id and camp-day-activity-id'; + } + if (errorMessage) { return resp.status(422).json({ - message: 'Required Camp-id and camp-day-activity-id', + message: errorMessage, data: {}, }); } + let queryFields = []; + + // Determine which fields to include in the query + const fields = body?.fields; + if (!fields || fields?.length === 0 || fields.includes('leanerCount')) { + queryFields = [ + ...queryFields, + `leanerCount: group_users_aggregate(where: {camps: {id: {_eq: ${camp_id}}}, status: {_eq: "active"}}) { + aggregate { + count + } + }`, + ]; + } + if ( + !fields || + fields?.length === 0 || + fields.includes('attendaceCount') + ) { + queryFields = [ + ...queryFields, + `attendaceCount: group_users_aggregate(where: {camps: {id: {_eq: ${camp_id}}}, status: {_eq: "active"}, attendance: {context_id: {_eq: ${context_id}}, context: {_eq: "camp_days_activities_tracker"}, date_time: {_gte: "${dateString}", _lte: "${endDate}"}}}) { + aggregate { + count + } + }`, + ]; + } + if ( + !fields || + fields?.length === 0 || + fields.includes('presentAttendaceCount') + ) { + queryFields = [ + ...queryFields, + `presentAttendaceCount: group_users_aggregate(where: {camps: {id: {_eq: ${camp_id}}}, status: {_eq: "active"}, attendance: {context_id: {_eq: ${context_id}}, context: {_eq: "camp_days_activities_tracker"},status:{_eq:"present"}, date_time: {_gte: "${dateString}", _lte: "${endDate}"}}}) { + aggregate { + count + } + }`, + ]; + } + if ( + !fields || + fields?.length === 0 || + fields.includes('today_session_count') + ) { + queryFields = [ + ...queryFields, + `today_session_count:learning_sessions_tracker_aggregate(where: {camp_id: {_eq: ${camp_id}}, _or: [{created_at: {_gte: "${dateString}", _lte: "${endDate}"}}, {updated_at:{_gte: "${dateString}", _lte: "${endDate}"}}]}) { + aggregate{ + count + } + }`, + ]; + } + if ( + !fields || + fields?.length === 0 || + fields.includes('misc_activities') + ) { + queryFields = [ + ...queryFields, + `misc_activities:camp_days_activities_tracker(where:{id:{_eq:${context_id}}}){ + misc_activities + }`, + ]; + } + let data = { - query: `query MyQuery { - leanerCount: group_users_aggregate(where: {camps: {id: {_eq: ${camp_id}}}, status: {_eq: "active"}}) { - aggregate { - count - } - } - attendaceCount: group_users_aggregate(where: {camps: {id: {_eq: ${camp_id}}}, status: {_eq: "active"}, attendance: {context_id: {_eq: ${context_id}}, context: {_eq: "camp_days_activities_tracker"}, date_time: {_gte: "${dateString}", _lte: "${endDate}"}}}) { - aggregate { - count - } - } - learning_sessions_tracker_aggregate(where: {camp_id: {_eq: ${camp_id}}, - _or: [{ - created_at: {_gte: "${dateString}", _lte: "${endDate}"} - - },{ - updated_at:{_gte: "${dateString}", _lte: "${endDate}"} - } - ] - }) { - aggregate{ - count - } - } - camp_days_activities_tracker(where:{id:{_eq:${context_id}}}){ - misc_activities - } - } - `, + query: `query MyQuery { ${queryFields.join(' ')} }`, }; const hasura_response = await this.hasuraServiceFromServices.getData( From 7fe37776f079eb0cda3c46b48670c49779c89d8d Mon Sep 17 00:00:00 2001 From: Tusharmahajan12 <121154132+Tusharmahajan12@users.noreply.github.com> Date: Wed, 14 Feb 2024 17:34:56 +0530 Subject: [PATCH 002/126] In events added params for do_id (#776) --- src/src/events/events.service.ts | 7 ++- src/src/helper/queryGenerator.service.ts | 65 +++++++++++++++++++++++ src/src/services/hasura/hasura.service.ts | 33 ++++++++++++ 3 files changed, 103 insertions(+), 2 deletions(-) diff --git a/src/src/events/events.service.ts b/src/src/events/events.service.ts index f9cb44b88..8503c172b 100644 --- a/src/src/events/events.service.ts +++ b/src/src/events/events.service.ts @@ -42,6 +42,7 @@ export class EventsService { 'reminders', 'academic_year_id', 'program_id', + 'params', ]; public attendanceReturnFields = [ @@ -71,7 +72,6 @@ export class EventsService { let user_id_arr = req.attendees; let program_id = header?.mw_program_id; let academic_year_id = header?.mw_academic_year_id; - const userDetail = await this.userService.ipUserInfo(header); let user_id = userDetail.data.id; let obj = { @@ -92,12 +92,15 @@ export class EventsService { reminders: JSON.stringify(req.reminders).replace(/"/g, '\\"'), program_id: program_id, academic_year_id: academic_year_id, + params: req.params, }; - const eventResult = await this.hasuraService.create( + const eventResult = await this.hasuraService.createWithVariable( this.table, obj, this.returnFields, + [], + [{ key: 'params', type: 'json' }], ); if (eventResult) { diff --git a/src/src/helper/queryGenerator.service.ts b/src/src/helper/queryGenerator.service.ts index 9b798084c..68762888f 100644 --- a/src/src/helper/queryGenerator.service.ts +++ b/src/src/helper/queryGenerator.service.ts @@ -54,6 +54,71 @@ export class QueryGeneratorService { `; } + // create + createWithVariable( + tName: String, + item: any, + onlyFields: any = [], + fields: any = [], + variable = [], + ) { + let resultObject = {}; + let params = ''; + if (Array.isArray(variable) && variable?.length > 0) { + params = `(${variable + .map((newD) => `$${newD.key}: ${newD?.type}`) + .join(', ')})`; + + let vData = {}; + variable.forEach((e) => { + vData = { ...vData, [e.key]: item?.[e.key] }; + }); + resultObject = { ...resultObject, variables: vData }; + } + + let tableName = `insert_${tName}_one`; + const keys = Object.keys(item); + + const getObjStr = (item: any, type: String = '') => { + let str = 'object: {'; + let strArr = []; + keys.forEach((e, index) => { + if ( + e !== 'id' && + (onlyFields.length < 1 || onlyFields.includes(e)) + ) { + const data = variable.map((e) => e.key).filter((e) => e); + if (data.includes(e)) { + strArr = [...strArr, `${e}:$${e}`]; + } else { + strArr = [...strArr, `${e}:"${item[e]}"`]; + } + } + }); + str += strArr.join(); + str += `}`; + return str; + }; + + resultObject = { + query: `mutation MyQuery${params} { + ${tableName}(${getObjStr(item)}) { + ${this.getParam( + fields && fields.length > 0 + ? fields + : onlyFields + ? onlyFields + : keys, + )} + } + } + `, + ...resultObject, + }; + + return resultObject; + } + // update update( id: number, diff --git a/src/src/services/hasura/hasura.service.ts b/src/src/services/hasura/hasura.service.ts index c50c95483..6b23ccbf9 100644 --- a/src/src/services/hasura/hasura.service.ts +++ b/src/src/services/hasura/hasura.service.ts @@ -295,6 +295,39 @@ export class HasuraService { ); } + public async createWithVariable( + tableName: String, + item: Object, + onlyFields: any = [], + fields: any = [], + variable = [], + ) { + return this.getResponce( + await lastValueFrom( + this.httpService + .post( + this.url, + this.qgService.createWithVariable( + tableName, + item, + onlyFields, + fields, + variable, + ), + { + headers: { + 'x-hasura-admin-secret': + process.env.HASURA_ADMIN_SECRET, + 'Content-Type': 'application/json', + }, + }, + ) + .pipe(map((res) => res.data)), + ), + tableName, + ); + } + public async update( id: number, tableName: String, From de54cbf8fc7860ecdd7ef772c0d8fab9fbbd89cb Mon Sep 17 00:00:00 2001 From: Tusharmahajan12 <121154132+Tusharmahajan12@users.noreply.github.com> Date: Thu, 15 Feb 2024 14:42:03 +0530 Subject: [PATCH 003/126] Change in query (#780) --- src/src/camp/camp.service.ts | 36 +++++++++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/src/src/camp/camp.service.ts b/src/src/camp/camp.service.ts index 4a4d441de..4189e5896 100644 --- a/src/src/camp/camp.service.ts +++ b/src/src/camp/camp.service.ts @@ -4292,10 +4292,14 @@ export class CampService { // Determine which fields to include in the query const fields = body?.fields; - if (!fields || fields?.length === 0 || fields.includes('leanerCount')) { + if ( + !fields || + fields?.length === 0 || + fields.includes('beneficairesCount') + ) { queryFields = [ ...queryFields, - `leanerCount: group_users_aggregate(where: {camps: {id: {_eq: ${camp_id}}}, status: {_eq: "active"}}) { + `beneficairesCount: group_users_aggregate(where: {camps: {id: {_eq: ${camp_id}}}, status: {_eq: "active"},member_type:{_eq:"member"}}) { aggregate { count } @@ -4305,11 +4309,11 @@ export class CampService { if ( !fields || fields?.length === 0 || - fields.includes('attendaceCount') + fields.includes('beneficairesAttendaceCount') ) { queryFields = [ ...queryFields, - `attendaceCount: group_users_aggregate(where: {camps: {id: {_eq: ${camp_id}}}, status: {_eq: "active"}, attendance: {context_id: {_eq: ${context_id}}, context: {_eq: "camp_days_activities_tracker"}, date_time: {_gte: "${dateString}", _lte: "${endDate}"}}}) { + `beneficairesAttendaceCount: group_users_aggregate(where: {camps: {id: {_eq: ${camp_id}}}, status: {_eq: "active"},member_type:{_eq:"member"}, attendance: {context_id: {_eq: ${context_id}}, context: {_eq: "camp_days_activities_tracker"}, date_time: {_gte: "${dateString}", _lte: "${endDate}"}}}) { aggregate { count } @@ -4319,11 +4323,25 @@ export class CampService { if ( !fields || fields?.length === 0 || - fields.includes('presentAttendaceCount') + fields.includes('beneficairesPresentAttendaceCount') + ) { + queryFields = [ + ...queryFields, + `beneficairesPresentAttendaceCount: group_users_aggregate(where: {camps: {id: {_eq: ${camp_id}}}, status: {_eq: "active"},member_type:{_eq:"member"}, attendance: {context_id: {_eq: ${context_id}}, context: {_eq: "camp_days_activities_tracker"},status:{_eq:"present"}, date_time: {_gte: "${dateString}", _lte: "${endDate}"}}}) { + aggregate { + count + } + }`, + ]; + } + if ( + !fields || + fields?.length === 0 || + fields.includes('prerakPresentAttendaceCount') ) { queryFields = [ ...queryFields, - `presentAttendaceCount: group_users_aggregate(where: {camps: {id: {_eq: ${camp_id}}}, status: {_eq: "active"}, attendance: {context_id: {_eq: ${context_id}}, context: {_eq: "camp_days_activities_tracker"},status:{_eq:"present"}, date_time: {_gte: "${dateString}", _lte: "${endDate}"}}}) { + `prerakPresentAttendaceCount: group_users_aggregate(where: {camps: {id: {_eq: ${camp_id}}}, status: {_eq: "active"},member_type:{_eq:"owner"}, attendance: {context_id: {_eq: ${context_id}}, context: {_eq: "camp_days_activities_tracker"},status:{_eq:"present"}, date_time: {_gte: "${dateString}", _lte: "${endDate}"}}}) { aggregate { count } @@ -4351,9 +4369,9 @@ export class CampService { ) { queryFields = [ ...queryFields, - `misc_activities:camp_days_activities_tracker(where:{id:{_eq:${context_id}}}){ - misc_activities - }`, + `misc_activities:camp_days_activities_tracker_by_pk(id: ${context_id}){ + misc_activities + }`, ]; } From 27428202b962ecb0418d3bd4c6e7da3fe2a2436d Mon Sep 17 00:00:00 2001 From: Tusharmahajan12 <121154132+Tusharmahajan12@users.noreply.github.com> Date: Thu, 15 Feb 2024 16:07:15 +0530 Subject: [PATCH 004/126] Change in query (#780) (#782) --- src/src/camp/camp.service.ts | 36 +++++++++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/src/src/camp/camp.service.ts b/src/src/camp/camp.service.ts index 4a4d441de..4189e5896 100644 --- a/src/src/camp/camp.service.ts +++ b/src/src/camp/camp.service.ts @@ -4292,10 +4292,14 @@ export class CampService { // Determine which fields to include in the query const fields = body?.fields; - if (!fields || fields?.length === 0 || fields.includes('leanerCount')) { + if ( + !fields || + fields?.length === 0 || + fields.includes('beneficairesCount') + ) { queryFields = [ ...queryFields, - `leanerCount: group_users_aggregate(where: {camps: {id: {_eq: ${camp_id}}}, status: {_eq: "active"}}) { + `beneficairesCount: group_users_aggregate(where: {camps: {id: {_eq: ${camp_id}}}, status: {_eq: "active"},member_type:{_eq:"member"}}) { aggregate { count } @@ -4305,11 +4309,11 @@ export class CampService { if ( !fields || fields?.length === 0 || - fields.includes('attendaceCount') + fields.includes('beneficairesAttendaceCount') ) { queryFields = [ ...queryFields, - `attendaceCount: group_users_aggregate(where: {camps: {id: {_eq: ${camp_id}}}, status: {_eq: "active"}, attendance: {context_id: {_eq: ${context_id}}, context: {_eq: "camp_days_activities_tracker"}, date_time: {_gte: "${dateString}", _lte: "${endDate}"}}}) { + `beneficairesAttendaceCount: group_users_aggregate(where: {camps: {id: {_eq: ${camp_id}}}, status: {_eq: "active"},member_type:{_eq:"member"}, attendance: {context_id: {_eq: ${context_id}}, context: {_eq: "camp_days_activities_tracker"}, date_time: {_gte: "${dateString}", _lte: "${endDate}"}}}) { aggregate { count } @@ -4319,11 +4323,25 @@ export class CampService { if ( !fields || fields?.length === 0 || - fields.includes('presentAttendaceCount') + fields.includes('beneficairesPresentAttendaceCount') + ) { + queryFields = [ + ...queryFields, + `beneficairesPresentAttendaceCount: group_users_aggregate(where: {camps: {id: {_eq: ${camp_id}}}, status: {_eq: "active"},member_type:{_eq:"member"}, attendance: {context_id: {_eq: ${context_id}}, context: {_eq: "camp_days_activities_tracker"},status:{_eq:"present"}, date_time: {_gte: "${dateString}", _lte: "${endDate}"}}}) { + aggregate { + count + } + }`, + ]; + } + if ( + !fields || + fields?.length === 0 || + fields.includes('prerakPresentAttendaceCount') ) { queryFields = [ ...queryFields, - `presentAttendaceCount: group_users_aggregate(where: {camps: {id: {_eq: ${camp_id}}}, status: {_eq: "active"}, attendance: {context_id: {_eq: ${context_id}}, context: {_eq: "camp_days_activities_tracker"},status:{_eq:"present"}, date_time: {_gte: "${dateString}", _lte: "${endDate}"}}}) { + `prerakPresentAttendaceCount: group_users_aggregate(where: {camps: {id: {_eq: ${camp_id}}}, status: {_eq: "active"},member_type:{_eq:"owner"}, attendance: {context_id: {_eq: ${context_id}}, context: {_eq: "camp_days_activities_tracker"},status:{_eq:"present"}, date_time: {_gte: "${dateString}", _lte: "${endDate}"}}}) { aggregate { count } @@ -4351,9 +4369,9 @@ export class CampService { ) { queryFields = [ ...queryFields, - `misc_activities:camp_days_activities_tracker(where:{id:{_eq:${context_id}}}){ - misc_activities - }`, + `misc_activities:camp_days_activities_tracker_by_pk(id: ${context_id}){ + misc_activities + }`, ]; } From 2813049df0685ec87ab20154d6029ef6f5673891 Mon Sep 17 00:00:00 2001 From: Manoj L Date: Wed, 21 Feb 2024 12:59:16 +0530 Subject: [PATCH 005/126] Task #212709 feat: Add nodejs script for resizing existing images on S3 (#788) * Task #212709 feat: Add nodejs script for resizing existing images on S3 * Task #212709 fix: Sonarlint changes --- .../s3-images-resizing/.env.example | 9 + .../s3-images-resizing/.gitignore | 39 + .../s3-images-resizing/index.js | 234 ++ .../s3-images-resizing/package-lock.json | 2692 +++++++++++++++++ .../s3-images-resizing/package.json | 18 + .../s3-images-resizing/resized/.gitkeep | 0 .../resized/128x128/.gitkeep | 0 .../resized/256x256/.gitkeep | 0 .../s3-images-resizing/resized/32x32/.gitkeep | 0 .../s3-images-resizing/resized/64x64/.gitkeep | 0 .../s3-images-resizing/sample.csv | 2 + 11 files changed, 2994 insertions(+) create mode 100644 housekeeping-scripts/s3-images-resizing/.env.example create mode 100644 housekeeping-scripts/s3-images-resizing/.gitignore create mode 100644 housekeeping-scripts/s3-images-resizing/index.js create mode 100644 housekeeping-scripts/s3-images-resizing/package-lock.json create mode 100644 housekeeping-scripts/s3-images-resizing/package.json create mode 100644 housekeeping-scripts/s3-images-resizing/resized/.gitkeep create mode 100644 housekeeping-scripts/s3-images-resizing/resized/128x128/.gitkeep create mode 100644 housekeeping-scripts/s3-images-resizing/resized/256x256/.gitkeep create mode 100644 housekeeping-scripts/s3-images-resizing/resized/32x32/.gitkeep create mode 100644 housekeeping-scripts/s3-images-resizing/resized/64x64/.gitkeep create mode 100644 housekeeping-scripts/s3-images-resizing/sample.csv diff --git a/housekeeping-scripts/s3-images-resizing/.env.example b/housekeeping-scripts/s3-images-resizing/.env.example new file mode 100644 index 000000000..122b5224b --- /dev/null +++ b/housekeeping-scripts/s3-images-resizing/.env.example @@ -0,0 +1,9 @@ +## S3 +AWS_S3_REGION: ap-south-1 +AWS_S3_BUCKET: +AWS_ACCESS_KEY_ID: +AWS_SECRET_ACCESS_KEY: + +## CSV +CSV_INPUT_PATH: sample.csv +CSV_OUTPUT_PATH: \ No newline at end of file diff --git a/housekeeping-scripts/s3-images-resizing/.gitignore b/housekeeping-scripts/s3-images-resizing/.gitignore new file mode 100644 index 000000000..2de29a58d --- /dev/null +++ b/housekeeping-scripts/s3-images-resizing/.gitignore @@ -0,0 +1,39 @@ +# 3pd +*/bower_components/* +*/jspm_packages/* +*/node_modules/* + +# Cache files +.cache +.eslintcache +.parcel-cache +.npm +.yarn/cache +.yarn/unplugged +.yarn/install-state.gz + +# Dist / builds +*/build/* +*/builds/* +*/dist/* + +# G cloud config +educate-girls-*.json + +# Env files +.env +.env.* + +# Log files +lerna-debug.log +npm-debug.log +yarn-error.log +yarn-debug.log +.serverless + +# OS files +.DS_Store + +# VS editor-related files +.vscode +.vscode-test diff --git a/housekeeping-scripts/s3-images-resizing/index.js b/housekeeping-scripts/s3-images-resizing/index.js new file mode 100644 index 000000000..c47565b89 --- /dev/null +++ b/housekeeping-scripts/s3-images-resizing/index.js @@ -0,0 +1,234 @@ +const { S3Client, ListObjectsV2Command, PutObjectCommand, GetObjectCommand } = require('@aws-sdk/client-s3'); +const fs = require('fs'); +const path = require('path'); +const { parse } = require('csv-parse'); +const sharp = require('sharp'); +const util = require('util'); +require('dotenv').config() + +// Logger +const log_file = fs.createWriteStream(__dirname + '/debug-' + new Date().toISOString().replace(/T/, '_').replace(/\..+/, '') + '.log', { flags: 'w' }); +const log_stdout = process.stdout; +const add_log = function (d) { // + log_file.write(util.format(d) + '\n'); + log_stdout.write(util.format(d) + '\n'); +}; + +// CSV paths +/*SELECT id, name, provider, path, doument_type +FROM documents +WHERE doument_type IN ('profile', 'profile_photo', 'profile_photo_1', 'profile_photo_2', 'profile_photo_3') +AND provider = 's3' +AND name <> 'NULL' +ORDER BY id*/ +const CSV_INPUT_PATH = path.join(__dirname, process.env.CSV_INPUT_PATH); +let images_from_csv = []; + +// Configure AWS credentials (using environment variables or other preferred methods) +const BUCKET_NAME = `${process.env.AWS_S3_BUCKET}`; +const s3Client = new S3Client({ + region: `${process.env.AWS_S3_REGION}`, + credentials: { + accessKeyId: `${process.env.AWS_ACCESS_KEY_ID}`, + secretAccessKey: `${process.env.AWS_SECRET_ACCESS_KEY}`, + }, +}); + +// Optional prefix to filter images +const PREFIX = ''; + +// Resize to multiple widths in pixels +const imageResizeOptions = [32, 64, 128, 256]; + +// Function to check file mime type (no change) +async function getImagesFromCsv() { + add_log("START: Reading CSV"); + + fs.createReadStream(CSV_INPUT_PATH) + .pipe(parse({ delimiter: ",", from_line: 2 })) + .on("data", function (row) { + images_from_csv[images_from_csv.length] = row[1]; + }) + .on("end", function () { + add_log("END: Reading CSV"); + }) + .on("error", function (error) { + add_log("ERROR: Reading CSV: " + error.message); + }); +} + +// Get list of objects from S3 +async function getObjectsFromS3() { + let s3Files = []; + let continuationToken; + + const listObjectsV2CommandParams = { + Bucket: BUCKET_NAME, + Prefix: PREFIX, + MaxKeys: 1000, + }; + + // 2.1 Paginate through all objects in the bucket + add_log("START: Get objects list from S3"); + + let s3_get_objects_list_loop_counter = 0; + do { + s3_get_objects_list_loop_counter++; + add_log("INFO: Getting paginated objects list from S3, loop #" + s3_get_objects_list_loop_counter); + + listObjectsV2CommandParams.ContinuationToken = continuationToken; + let listObjectsCommand = new ListObjectsV2Command(listObjectsV2CommandParams); + let listObjectsResult = await s3Client.send(listObjectsCommand); + s3Files = s3Files.concat(listObjectsResult.Contents); + continuationToken = listObjectsResult.NextContinuationToken; + } while (continuationToken); + + add_log("END: Get objects list from S3"); + + return s3Files; +} + +// Function to check file mime type (no change) +async function isImage(object) { + const ext = path.extname(object.Key).toLowerCase(); + const imageExtensions = ['.gif', '.jpg', '.jpeg', '.png', '.webp']; + + return imageExtensions.includes(ext); +} + +// Function to download and resize image (updated for SDK v3) +async function resizeImage(object) { + // 1 - Get image from S3 + const getObjectCommandResponse = new GetObjectCommand({ Bucket: BUCKET_NAME, Key: object.Key }); + const data = await s3Client.send(getObjectCommandResponse); + + // 2 - Write image from S3 to temporary file + fs.writeFileSync(`temp-${object.Key}`, await data.Body.transformToByteArray()); + const image = await sharp(`temp-${object.Key}`); + + // 3 - Resize temp images into different dimensions + for (const size of imageResizeOptions) { + // 3.1 - Set new path for resized image + let newKey = `resized/${size}x${size}/${object.Key}`; + + let width = size; // Specify the desired width + let height = size; // Specify the desired height + let options = { + fit: sharp.fit.contain, // Specify the fit strategy (cover, contain, fill, inside, outside) + // position: sharp.strategy.entropy, // Specify the position strategy for cover + }; + + // 3.2 - Resize image using sharp + await image + .keepExif() + .resize(width, height, options) + .toFile(newKey, async (err, info) => { + if (err) { + add_log(`ERROR: SHARP - Error while resizig image: ${err}`); + } else { + add_log(`INFO: SHARP - Resized image : ${newKey}`); + + // 3.3 - Read resized image + // Read the file content + let fileContentToBeUploaded = fs.readFileSync(newKey); + + // 3.4 - Upload resized image to S3 + const putObjectCommandParams = { + Bucket: BUCKET_NAME, + Key: newKey, + Body: fileContentToBeUploaded + }; + + add_log(`INFO: S3 - Uploading resized image: ${newKey}`); + await s3Client.send(new PutObjectCommand(putObjectCommandParams)); + // add_log(`s3upload response:`, JSON.stringify(response, null, 2)) + + // Delete the temporary file + await deleteTempFile(newKey); + } + }); + } + + // Delete the temporary file + await deleteTempFile(`temp-${object.Key}`); +} + +async function deleteTempFile(fileName) { + // Delete the temporary file + setTimeout(() => { + add_log(`INFO: Delete local temp image: ${fileName}`); + fs.unlinkSync(`${fileName}`); + }, 3000); +} + +// Process objects from S3 +async function processS3Objects(s3Files) { + // 1 - Process all objects + let s3ImagesCounter = 0; + let s3NonImagesCounter = 0; + + for (const object of s3Files) { + // 1.1 - Only process objects that are there in CSV + if (!images_from_csv.includes(object.Key)) { + s3NonImagesCounter++; + + add_log(`INFO: Skipping image #${s3NonImagesCounter} which is not in CSV with name: ${object.Key}`); + + continue; + } + + // 1.2 - Only process images and skip other files + if (await isImage(object)) { + s3ImagesCounter++; + add_log(`INFO: Processing image #${s3ImagesCounter} with name: ${object.Key}`); + + await resizeImage(object); + } else { + s3NonImagesCounter++; + + add_log(`INFO: Skipping non-image #${s3NonImagesCounter} with name: ${object.Key}`); + } + } + + return [s3ImagesCounter, s3NonImagesCounter]; +} + +// Main function (updated for SDK v3) +async function main() { + let start = +new Date(); + add_log('START: Executing script'); + + try { + // 1 - Get image names to be processed from CSV + await getImagesFromCsv(); + + // 2 - Get S3 objects from S3 + let s3Files = await getObjectsFromS3(); + + // 2.1 Print info + add_log(`=======================================`); + add_log(`Found ${s3Files.length} files in bucket ${BUCKET_NAME}`); + add_log(`Found ${images_from_csv.length} files in CSV`); + add_log(`=======================================`); + + // 3 - Process all objects + let processedCounters = await processS3Objects(s3Files); + + // 3.1 Print info + add_log(`=======================================`); + add_log(`Found ${s3Files.length} files`); + add_log(`Processed ${processedCounters[0]} images`); + add_log(`Skipped ${processedCounters[1]} files`); + add_log(`=======================================`); + + } catch (error) { + add_log('ERROR: Executing script: ' + error); + } + + let end = +new Date(); + add_log('END: Executing script'); + add_log("Time taken " + (end - start) + " milliseconds"); +} + +// Execute the script +main(); diff --git a/housekeeping-scripts/s3-images-resizing/package-lock.json b/housekeeping-scripts/s3-images-resizing/package-lock.json new file mode 100644 index 000000000..8f112e09a --- /dev/null +++ b/housekeeping-scripts/s3-images-resizing/package-lock.json @@ -0,0 +1,2692 @@ +{ + "name": "eg-scripting", + "version": "1.0.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "eg-scripting", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "@aws-sdk/client-s3": "^3.496.0", + "csv": "^6.3.6", + "dotenv": "^16.4.1", + "sharp": "^0.33.2" + } + }, + "node_modules/@aws-crypto/crc32": { + "version": "3.0.0", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/util": "^3.0.0", + "@aws-sdk/types": "^3.222.0", + "tslib": "^1.11.1" + } + }, + "node_modules/@aws-crypto/crc32/node_modules/tslib": { + "version": "1.14.1", + "license": "0BSD" + }, + "node_modules/@aws-crypto/crc32c": { + "version": "3.0.0", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/util": "^3.0.0", + "@aws-sdk/types": "^3.222.0", + "tslib": "^1.11.1" + } + }, + "node_modules/@aws-crypto/crc32c/node_modules/tslib": { + "version": "1.14.1", + "license": "0BSD" + }, + "node_modules/@aws-crypto/ie11-detection": { + "version": "3.0.0", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^1.11.1" + } + }, + "node_modules/@aws-crypto/ie11-detection/node_modules/tslib": { + "version": "1.14.1", + "license": "0BSD" + }, + "node_modules/@aws-crypto/sha1-browser": { + "version": "3.0.0", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/ie11-detection": "^3.0.0", + "@aws-crypto/supports-web-crypto": "^3.0.0", + "@aws-crypto/util": "^3.0.0", + "@aws-sdk/types": "^3.222.0", + "@aws-sdk/util-locate-window": "^3.0.0", + "@aws-sdk/util-utf8-browser": "^3.0.0", + "tslib": "^1.11.1" + } + }, + "node_modules/@aws-crypto/sha1-browser/node_modules/tslib": { + "version": "1.14.1", + "license": "0BSD" + }, + "node_modules/@aws-crypto/sha256-browser": { + "version": "3.0.0", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/ie11-detection": "^3.0.0", + "@aws-crypto/sha256-js": "^3.0.0", + "@aws-crypto/supports-web-crypto": "^3.0.0", + "@aws-crypto/util": "^3.0.0", + "@aws-sdk/types": "^3.222.0", + "@aws-sdk/util-locate-window": "^3.0.0", + "@aws-sdk/util-utf8-browser": "^3.0.0", + "tslib": "^1.11.1" + } + }, + "node_modules/@aws-crypto/sha256-browser/node_modules/tslib": { + "version": "1.14.1", + "license": "0BSD" + }, + "node_modules/@aws-crypto/sha256-js": { + "version": "3.0.0", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/util": "^3.0.0", + "@aws-sdk/types": "^3.222.0", + "tslib": "^1.11.1" + } + }, + "node_modules/@aws-crypto/sha256-js/node_modules/tslib": { + "version": "1.14.1", + "license": "0BSD" + }, + "node_modules/@aws-crypto/supports-web-crypto": { + "version": "3.0.0", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^1.11.1" + } + }, + "node_modules/@aws-crypto/supports-web-crypto/node_modules/tslib": { + "version": "1.14.1", + "license": "0BSD" + }, + "node_modules/@aws-crypto/util": { + "version": "3.0.0", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "^3.222.0", + "@aws-sdk/util-utf8-browser": "^3.0.0", + "tslib": "^1.11.1" + } + }, + "node_modules/@aws-crypto/util/node_modules/tslib": { + "version": "1.14.1", + "license": "0BSD" + }, + "node_modules/@aws-sdk/client-s3": { + "version": "3.496.0", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha1-browser": "3.0.0", + "@aws-crypto/sha256-browser": "3.0.0", + "@aws-crypto/sha256-js": "3.0.0", + "@aws-sdk/client-sts": "3.496.0", + "@aws-sdk/core": "3.496.0", + "@aws-sdk/credential-provider-node": "3.496.0", + "@aws-sdk/middleware-bucket-endpoint": "3.496.0", + "@aws-sdk/middleware-expect-continue": "3.496.0", + "@aws-sdk/middleware-flexible-checksums": "3.496.0", + "@aws-sdk/middleware-host-header": "3.496.0", + "@aws-sdk/middleware-location-constraint": "3.496.0", + "@aws-sdk/middleware-logger": "3.496.0", + "@aws-sdk/middleware-recursion-detection": "3.496.0", + "@aws-sdk/middleware-sdk-s3": "3.496.0", + "@aws-sdk/middleware-signing": "3.496.0", + "@aws-sdk/middleware-ssec": "3.496.0", + "@aws-sdk/middleware-user-agent": "3.496.0", + "@aws-sdk/region-config-resolver": "3.496.0", + "@aws-sdk/signature-v4-multi-region": "3.496.0", + "@aws-sdk/types": "3.496.0", + "@aws-sdk/util-endpoints": "3.496.0", + "@aws-sdk/util-user-agent-browser": "3.496.0", + "@aws-sdk/util-user-agent-node": "3.496.0", + "@aws-sdk/xml-builder": "3.496.0", + "@smithy/config-resolver": "^2.1.1", + "@smithy/core": "^1.3.1", + "@smithy/eventstream-serde-browser": "^2.1.1", + "@smithy/eventstream-serde-config-resolver": "^2.1.1", + "@smithy/eventstream-serde-node": "^2.1.1", + "@smithy/fetch-http-handler": "^2.4.1", + "@smithy/hash-blob-browser": "^2.1.1", + "@smithy/hash-node": "^2.1.1", + "@smithy/hash-stream-node": "^2.1.1", + "@smithy/invalid-dependency": "^2.1.1", + "@smithy/md5-js": "^2.1.1", + "@smithy/middleware-content-length": "^2.1.1", + "@smithy/middleware-endpoint": "^2.4.1", + "@smithy/middleware-retry": "^2.1.1", + "@smithy/middleware-serde": "^2.1.1", + "@smithy/middleware-stack": "^2.1.1", + "@smithy/node-config-provider": "^2.2.1", + "@smithy/node-http-handler": "^2.3.1", + "@smithy/protocol-http": "^3.1.1", + "@smithy/smithy-client": "^2.3.1", + "@smithy/types": "^2.9.1", + "@smithy/url-parser": "^2.1.1", + "@smithy/util-base64": "^2.1.1", + "@smithy/util-body-length-browser": "^2.1.1", + "@smithy/util-body-length-node": "^2.2.1", + "@smithy/util-defaults-mode-browser": "^2.1.1", + "@smithy/util-defaults-mode-node": "^2.1.1", + "@smithy/util-endpoints": "^1.1.1", + "@smithy/util-retry": "^2.1.1", + "@smithy/util-stream": "^2.1.1", + "@smithy/util-utf8": "^2.1.1", + "@smithy/util-waiter": "^2.1.1", + "fast-xml-parser": "4.2.5", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-sso": { + "version": "3.496.0", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha256-browser": "3.0.0", + "@aws-crypto/sha256-js": "3.0.0", + "@aws-sdk/core": "3.496.0", + "@aws-sdk/middleware-host-header": "3.496.0", + "@aws-sdk/middleware-logger": "3.496.0", + "@aws-sdk/middleware-recursion-detection": "3.496.0", + "@aws-sdk/middleware-user-agent": "3.496.0", + "@aws-sdk/region-config-resolver": "3.496.0", + "@aws-sdk/types": "3.496.0", + "@aws-sdk/util-endpoints": "3.496.0", + "@aws-sdk/util-user-agent-browser": "3.496.0", + "@aws-sdk/util-user-agent-node": "3.496.0", + "@smithy/config-resolver": "^2.1.1", + "@smithy/core": "^1.3.1", + "@smithy/fetch-http-handler": "^2.4.1", + "@smithy/hash-node": "^2.1.1", + "@smithy/invalid-dependency": "^2.1.1", + "@smithy/middleware-content-length": "^2.1.1", + "@smithy/middleware-endpoint": "^2.4.1", + "@smithy/middleware-retry": "^2.1.1", + "@smithy/middleware-serde": "^2.1.1", + "@smithy/middleware-stack": "^2.1.1", + "@smithy/node-config-provider": "^2.2.1", + "@smithy/node-http-handler": "^2.3.1", + "@smithy/protocol-http": "^3.1.1", + "@smithy/smithy-client": "^2.3.1", + "@smithy/types": "^2.9.1", + "@smithy/url-parser": "^2.1.1", + "@smithy/util-base64": "^2.1.1", + "@smithy/util-body-length-browser": "^2.1.1", + "@smithy/util-body-length-node": "^2.2.1", + "@smithy/util-defaults-mode-browser": "^2.1.1", + "@smithy/util-defaults-mode-node": "^2.1.1", + "@smithy/util-endpoints": "^1.1.1", + "@smithy/util-retry": "^2.1.1", + "@smithy/util-utf8": "^2.1.1", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-sts": { + "version": "3.496.0", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha256-browser": "3.0.0", + "@aws-crypto/sha256-js": "3.0.0", + "@aws-sdk/core": "3.496.0", + "@aws-sdk/credential-provider-node": "3.496.0", + "@aws-sdk/middleware-host-header": "3.496.0", + "@aws-sdk/middleware-logger": "3.496.0", + "@aws-sdk/middleware-recursion-detection": "3.496.0", + "@aws-sdk/middleware-user-agent": "3.496.0", + "@aws-sdk/region-config-resolver": "3.496.0", + "@aws-sdk/types": "3.496.0", + "@aws-sdk/util-endpoints": "3.496.0", + "@aws-sdk/util-user-agent-browser": "3.496.0", + "@aws-sdk/util-user-agent-node": "3.496.0", + "@smithy/config-resolver": "^2.1.1", + "@smithy/core": "^1.3.1", + "@smithy/fetch-http-handler": "^2.4.1", + "@smithy/hash-node": "^2.1.1", + "@smithy/invalid-dependency": "^2.1.1", + "@smithy/middleware-content-length": "^2.1.1", + "@smithy/middleware-endpoint": "^2.4.1", + "@smithy/middleware-retry": "^2.1.1", + "@smithy/middleware-serde": "^2.1.1", + "@smithy/middleware-stack": "^2.1.1", + "@smithy/node-config-provider": "^2.2.1", + "@smithy/node-http-handler": "^2.3.1", + "@smithy/protocol-http": "^3.1.1", + "@smithy/smithy-client": "^2.3.1", + "@smithy/types": "^2.9.1", + "@smithy/url-parser": "^2.1.1", + "@smithy/util-base64": "^2.1.1", + "@smithy/util-body-length-browser": "^2.1.1", + "@smithy/util-body-length-node": "^2.2.1", + "@smithy/util-defaults-mode-browser": "^2.1.1", + "@smithy/util-defaults-mode-node": "^2.1.1", + "@smithy/util-endpoints": "^1.1.1", + "@smithy/util-middleware": "^2.1.1", + "@smithy/util-retry": "^2.1.1", + "@smithy/util-utf8": "^2.1.1", + "fast-xml-parser": "4.2.5", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/core": { + "version": "3.496.0", + "license": "Apache-2.0", + "dependencies": { + "@smithy/core": "^1.3.1", + "@smithy/protocol-http": "^3.1.1", + "@smithy/signature-v4": "^2.1.1", + "@smithy/smithy-client": "^2.3.1", + "@smithy/types": "^2.9.1", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-env": { + "version": "3.496.0", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.496.0", + "@smithy/property-provider": "^2.1.1", + "@smithy/types": "^2.9.1", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-ini": { + "version": "3.496.0", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/credential-provider-env": "3.496.0", + "@aws-sdk/credential-provider-process": "3.496.0", + "@aws-sdk/credential-provider-sso": "3.496.0", + "@aws-sdk/credential-provider-web-identity": "3.496.0", + "@aws-sdk/types": "3.496.0", + "@smithy/credential-provider-imds": "^2.2.1", + "@smithy/property-provider": "^2.1.1", + "@smithy/shared-ini-file-loader": "^2.3.1", + "@smithy/types": "^2.9.1", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-node": { + "version": "3.496.0", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/credential-provider-env": "3.496.0", + "@aws-sdk/credential-provider-ini": "3.496.0", + "@aws-sdk/credential-provider-process": "3.496.0", + "@aws-sdk/credential-provider-sso": "3.496.0", + "@aws-sdk/credential-provider-web-identity": "3.496.0", + "@aws-sdk/types": "3.496.0", + "@smithy/credential-provider-imds": "^2.2.1", + "@smithy/property-provider": "^2.1.1", + "@smithy/shared-ini-file-loader": "^2.3.1", + "@smithy/types": "^2.9.1", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-process": { + "version": "3.496.0", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.496.0", + "@smithy/property-provider": "^2.1.1", + "@smithy/shared-ini-file-loader": "^2.3.1", + "@smithy/types": "^2.9.1", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-sso": { + "version": "3.496.0", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/client-sso": "3.496.0", + "@aws-sdk/token-providers": "3.496.0", + "@aws-sdk/types": "3.496.0", + "@smithy/property-provider": "^2.1.1", + "@smithy/shared-ini-file-loader": "^2.3.1", + "@smithy/types": "^2.9.1", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-web-identity": { + "version": "3.496.0", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.496.0", + "@smithy/property-provider": "^2.1.1", + "@smithy/types": "^2.9.1", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/middleware-bucket-endpoint": { + "version": "3.496.0", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.496.0", + "@aws-sdk/util-arn-parser": "3.495.0", + "@smithy/node-config-provider": "^2.2.1", + "@smithy/protocol-http": "^3.1.1", + "@smithy/types": "^2.9.1", + "@smithy/util-config-provider": "^2.2.1", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/middleware-expect-continue": { + "version": "3.496.0", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.496.0", + "@smithy/protocol-http": "^3.1.1", + "@smithy/types": "^2.9.1", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/middleware-flexible-checksums": { + "version": "3.496.0", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/crc32": "3.0.0", + "@aws-crypto/crc32c": "3.0.0", + "@aws-sdk/types": "3.496.0", + "@smithy/is-array-buffer": "^2.1.1", + "@smithy/protocol-http": "^3.1.1", + "@smithy/types": "^2.9.1", + "@smithy/util-utf8": "^2.1.1", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/middleware-host-header": { + "version": "3.496.0", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.496.0", + "@smithy/protocol-http": "^3.1.1", + "@smithy/types": "^2.9.1", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/middleware-location-constraint": { + "version": "3.496.0", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.496.0", + "@smithy/types": "^2.9.1", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/middleware-logger": { + "version": "3.496.0", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.496.0", + "@smithy/types": "^2.9.1", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/middleware-recursion-detection": { + "version": "3.496.0", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.496.0", + "@smithy/protocol-http": "^3.1.1", + "@smithy/types": "^2.9.1", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/middleware-sdk-s3": { + "version": "3.496.0", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.496.0", + "@aws-sdk/util-arn-parser": "3.495.0", + "@smithy/node-config-provider": "^2.2.1", + "@smithy/protocol-http": "^3.1.1", + "@smithy/signature-v4": "^2.1.1", + "@smithy/smithy-client": "^2.3.1", + "@smithy/types": "^2.9.1", + "@smithy/util-config-provider": "^2.2.1", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/middleware-signing": { + "version": "3.496.0", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.496.0", + "@smithy/property-provider": "^2.1.1", + "@smithy/protocol-http": "^3.1.1", + "@smithy/signature-v4": "^2.1.1", + "@smithy/types": "^2.9.1", + "@smithy/util-middleware": "^2.1.1", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/middleware-ssec": { + "version": "3.496.0", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.496.0", + "@smithy/types": "^2.9.1", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/middleware-user-agent": { + "version": "3.496.0", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.496.0", + "@aws-sdk/util-endpoints": "3.496.0", + "@smithy/protocol-http": "^3.1.1", + "@smithy/types": "^2.9.1", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/region-config-resolver": { + "version": "3.496.0", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.496.0", + "@smithy/node-config-provider": "^2.2.1", + "@smithy/types": "^2.9.1", + "@smithy/util-config-provider": "^2.2.1", + "@smithy/util-middleware": "^2.1.1", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/signature-v4-multi-region": { + "version": "3.496.0", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/middleware-sdk-s3": "3.496.0", + "@aws-sdk/types": "3.496.0", + "@smithy/protocol-http": "^3.1.1", + "@smithy/signature-v4": "^2.1.1", + "@smithy/types": "^2.9.1", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/token-providers": { + "version": "3.496.0", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha256-browser": "3.0.0", + "@aws-crypto/sha256-js": "3.0.0", + "@aws-sdk/middleware-host-header": "3.496.0", + "@aws-sdk/middleware-logger": "3.496.0", + "@aws-sdk/middleware-recursion-detection": "3.496.0", + "@aws-sdk/middleware-user-agent": "3.496.0", + "@aws-sdk/region-config-resolver": "3.496.0", + "@aws-sdk/types": "3.496.0", + "@aws-sdk/util-endpoints": "3.496.0", + "@aws-sdk/util-user-agent-browser": "3.496.0", + "@aws-sdk/util-user-agent-node": "3.496.0", + "@smithy/config-resolver": "^2.1.1", + "@smithy/fetch-http-handler": "^2.4.1", + "@smithy/hash-node": "^2.1.1", + "@smithy/invalid-dependency": "^2.1.1", + "@smithy/middleware-content-length": "^2.1.1", + "@smithy/middleware-endpoint": "^2.4.1", + "@smithy/middleware-retry": "^2.1.1", + "@smithy/middleware-serde": "^2.1.1", + "@smithy/middleware-stack": "^2.1.1", + "@smithy/node-config-provider": "^2.2.1", + "@smithy/node-http-handler": "^2.3.1", + "@smithy/property-provider": "^2.1.1", + "@smithy/protocol-http": "^3.1.1", + "@smithy/shared-ini-file-loader": "^2.3.1", + "@smithy/smithy-client": "^2.3.1", + "@smithy/types": "^2.9.1", + "@smithy/url-parser": "^2.1.1", + "@smithy/util-base64": "^2.1.1", + "@smithy/util-body-length-browser": "^2.1.1", + "@smithy/util-body-length-node": "^2.2.1", + "@smithy/util-defaults-mode-browser": "^2.1.1", + "@smithy/util-defaults-mode-node": "^2.1.1", + "@smithy/util-endpoints": "^1.1.1", + "@smithy/util-retry": "^2.1.1", + "@smithy/util-utf8": "^2.1.1", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/types": { + "version": "3.496.0", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^2.9.1", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/util-arn-parser": { + "version": "3.495.0", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/util-endpoints": { + "version": "3.496.0", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.496.0", + "@smithy/types": "^2.9.1", + "@smithy/util-endpoints": "^1.1.1", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/util-locate-window": { + "version": "3.495.0", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/util-user-agent-browser": { + "version": "3.496.0", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.496.0", + "@smithy/types": "^2.9.1", + "bowser": "^2.11.0", + "tslib": "^2.5.0" + } + }, + "node_modules/@aws-sdk/util-user-agent-node": { + "version": "3.496.0", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.496.0", + "@smithy/node-config-provider": "^2.2.1", + "@smithy/types": "^2.9.1", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "aws-crt": ">=1.0.0" + }, + "peerDependenciesMeta": { + "aws-crt": { + "optional": true + } + } + }, + "node_modules/@aws-sdk/util-utf8-browser": { + "version": "3.259.0", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.3.1" + } + }, + "node_modules/@aws-sdk/xml-builder": { + "version": "3.496.0", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^2.9.1", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@img/sharp-darwin-arm64": { + "version": "0.33.2", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "glibc": ">=2.26", + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-arm64": "1.0.1" + } + }, + "node_modules/@img/sharp-libvips-darwin-arm64": { + "version": "1.0.1", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "macos": ">=11", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@smithy/abort-controller": { + "version": "2.1.1", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^2.9.1", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@smithy/chunked-blob-reader": { + "version": "2.1.1", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.5.0" + } + }, + "node_modules/@smithy/chunked-blob-reader-native": { + "version": "2.1.1", + "license": "Apache-2.0", + "dependencies": { + "@smithy/util-base64": "^2.1.1", + "tslib": "^2.5.0" + } + }, + "node_modules/@smithy/config-resolver": { + "version": "2.1.1", + "license": "Apache-2.0", + "dependencies": { + "@smithy/node-config-provider": "^2.2.1", + "@smithy/types": "^2.9.1", + "@smithy/util-config-provider": "^2.2.1", + "@smithy/util-middleware": "^2.1.1", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@smithy/core": { + "version": "1.3.1", + "license": "Apache-2.0", + "dependencies": { + "@smithy/middleware-endpoint": "^2.4.1", + "@smithy/middleware-retry": "^2.1.1", + "@smithy/middleware-serde": "^2.1.1", + "@smithy/protocol-http": "^3.1.1", + "@smithy/smithy-client": "^2.3.1", + "@smithy/types": "^2.9.1", + "@smithy/util-middleware": "^2.1.1", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@smithy/credential-provider-imds": { + "version": "2.2.1", + "license": "Apache-2.0", + "dependencies": { + "@smithy/node-config-provider": "^2.2.1", + "@smithy/property-provider": "^2.1.1", + "@smithy/types": "^2.9.1", + "@smithy/url-parser": "^2.1.1", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@smithy/eventstream-codec": { + "version": "2.1.1", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/crc32": "3.0.0", + "@smithy/types": "^2.9.1", + "@smithy/util-hex-encoding": "^2.1.1", + "tslib": "^2.5.0" + } + }, + "node_modules/@smithy/eventstream-serde-browser": { + "version": "2.1.1", + "license": "Apache-2.0", + "dependencies": { + "@smithy/eventstream-serde-universal": "^2.1.1", + "@smithy/types": "^2.9.1", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@smithy/eventstream-serde-config-resolver": { + "version": "2.1.1", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^2.9.1", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@smithy/eventstream-serde-node": { + "version": "2.1.1", + "license": "Apache-2.0", + "dependencies": { + "@smithy/eventstream-serde-universal": "^2.1.1", + "@smithy/types": "^2.9.1", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@smithy/eventstream-serde-universal": { + "version": "2.1.1", + "license": "Apache-2.0", + "dependencies": { + "@smithy/eventstream-codec": "^2.1.1", + "@smithy/types": "^2.9.1", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@smithy/fetch-http-handler": { + "version": "2.4.1", + "license": "Apache-2.0", + "dependencies": { + "@smithy/protocol-http": "^3.1.1", + "@smithy/querystring-builder": "^2.1.1", + "@smithy/types": "^2.9.1", + "@smithy/util-base64": "^2.1.1", + "tslib": "^2.5.0" + } + }, + "node_modules/@smithy/hash-blob-browser": { + "version": "2.1.1", + "license": "Apache-2.0", + "dependencies": { + "@smithy/chunked-blob-reader": "^2.1.1", + "@smithy/chunked-blob-reader-native": "^2.1.1", + "@smithy/types": "^2.9.1", + "tslib": "^2.5.0" + } + }, + "node_modules/@smithy/hash-node": { + "version": "2.1.1", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^2.9.1", + "@smithy/util-buffer-from": "^2.1.1", + "@smithy/util-utf8": "^2.1.1", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@smithy/hash-stream-node": { + "version": "2.1.1", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^2.9.1", + "@smithy/util-utf8": "^2.1.1", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@smithy/invalid-dependency": { + "version": "2.1.1", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^2.9.1", + "tslib": "^2.5.0" + } + }, + "node_modules/@smithy/is-array-buffer": { + "version": "2.1.1", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@smithy/md5-js": { + "version": "2.1.1", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^2.9.1", + "@smithy/util-utf8": "^2.1.1", + "tslib": "^2.5.0" + } + }, + "node_modules/@smithy/middleware-content-length": { + "version": "2.1.1", + "license": "Apache-2.0", + "dependencies": { + "@smithy/protocol-http": "^3.1.1", + "@smithy/types": "^2.9.1", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@smithy/middleware-endpoint": { + "version": "2.4.1", + "license": "Apache-2.0", + "dependencies": { + "@smithy/middleware-serde": "^2.1.1", + "@smithy/node-config-provider": "^2.2.1", + "@smithy/shared-ini-file-loader": "^2.3.1", + "@smithy/types": "^2.9.1", + "@smithy/url-parser": "^2.1.1", + "@smithy/util-middleware": "^2.1.1", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@smithy/middleware-retry": { + "version": "2.1.1", + "license": "Apache-2.0", + "dependencies": { + "@smithy/node-config-provider": "^2.2.1", + "@smithy/protocol-http": "^3.1.1", + "@smithy/service-error-classification": "^2.1.1", + "@smithy/smithy-client": "^2.3.1", + "@smithy/types": "^2.9.1", + "@smithy/util-middleware": "^2.1.1", + "@smithy/util-retry": "^2.1.1", + "tslib": "^2.5.0", + "uuid": "^8.3.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@smithy/middleware-retry/node_modules/uuid": { + "version": "8.3.2", + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/@smithy/middleware-serde": { + "version": "2.1.1", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^2.9.1", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@smithy/middleware-stack": { + "version": "2.1.1", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^2.9.1", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@smithy/node-config-provider": { + "version": "2.2.1", + "license": "Apache-2.0", + "dependencies": { + "@smithy/property-provider": "^2.1.1", + "@smithy/shared-ini-file-loader": "^2.3.1", + "@smithy/types": "^2.9.1", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@smithy/node-http-handler": { + "version": "2.3.1", + "license": "Apache-2.0", + "dependencies": { + "@smithy/abort-controller": "^2.1.1", + "@smithy/protocol-http": "^3.1.1", + "@smithy/querystring-builder": "^2.1.1", + "@smithy/types": "^2.9.1", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@smithy/property-provider": { + "version": "2.1.1", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^2.9.1", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@smithy/protocol-http": { + "version": "3.1.1", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^2.9.1", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@smithy/querystring-builder": { + "version": "2.1.1", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^2.9.1", + "@smithy/util-uri-escape": "^2.1.1", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@smithy/querystring-parser": { + "version": "2.1.1", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^2.9.1", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@smithy/service-error-classification": { + "version": "2.1.1", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^2.9.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@smithy/shared-ini-file-loader": { + "version": "2.3.1", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^2.9.1", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@smithy/signature-v4": { + "version": "2.1.1", + "license": "Apache-2.0", + "dependencies": { + "@smithy/eventstream-codec": "^2.1.1", + "@smithy/is-array-buffer": "^2.1.1", + "@smithy/types": "^2.9.1", + "@smithy/util-hex-encoding": "^2.1.1", + "@smithy/util-middleware": "^2.1.1", + "@smithy/util-uri-escape": "^2.1.1", + "@smithy/util-utf8": "^2.1.1", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@smithy/smithy-client": { + "version": "2.3.1", + "license": "Apache-2.0", + "dependencies": { + "@smithy/middleware-endpoint": "^2.4.1", + "@smithy/middleware-stack": "^2.1.1", + "@smithy/protocol-http": "^3.1.1", + "@smithy/types": "^2.9.1", + "@smithy/util-stream": "^2.1.1", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@smithy/types": { + "version": "2.9.1", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@smithy/url-parser": { + "version": "2.1.1", + "license": "Apache-2.0", + "dependencies": { + "@smithy/querystring-parser": "^2.1.1", + "@smithy/types": "^2.9.1", + "tslib": "^2.5.0" + } + }, + "node_modules/@smithy/util-base64": { + "version": "2.1.1", + "license": "Apache-2.0", + "dependencies": { + "@smithy/util-buffer-from": "^2.1.1", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@smithy/util-body-length-browser": { + "version": "2.1.1", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.5.0" + } + }, + "node_modules/@smithy/util-body-length-node": { + "version": "2.2.1", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@smithy/util-buffer-from": { + "version": "2.1.1", + "license": "Apache-2.0", + "dependencies": { + "@smithy/is-array-buffer": "^2.1.1", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@smithy/util-config-provider": { + "version": "2.2.1", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@smithy/util-defaults-mode-browser": { + "version": "2.1.1", + "license": "Apache-2.0", + "dependencies": { + "@smithy/property-provider": "^2.1.1", + "@smithy/smithy-client": "^2.3.1", + "@smithy/types": "^2.9.1", + "bowser": "^2.11.0", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/@smithy/util-defaults-mode-node": { + "version": "2.1.1", + "license": "Apache-2.0", + "dependencies": { + "@smithy/config-resolver": "^2.1.1", + "@smithy/credential-provider-imds": "^2.2.1", + "@smithy/node-config-provider": "^2.2.1", + "@smithy/property-provider": "^2.1.1", + "@smithy/smithy-client": "^2.3.1", + "@smithy/types": "^2.9.1", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/@smithy/util-endpoints": { + "version": "1.1.1", + "license": "Apache-2.0", + "dependencies": { + "@smithy/node-config-provider": "^2.2.1", + "@smithy/types": "^2.9.1", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@smithy/util-hex-encoding": { + "version": "2.1.1", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@smithy/util-middleware": { + "version": "2.1.1", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^2.9.1", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@smithy/util-retry": { + "version": "2.1.1", + "license": "Apache-2.0", + "dependencies": { + "@smithy/service-error-classification": "^2.1.1", + "@smithy/types": "^2.9.1", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@smithy/util-stream": { + "version": "2.1.1", + "license": "Apache-2.0", + "dependencies": { + "@smithy/fetch-http-handler": "^2.4.1", + "@smithy/node-http-handler": "^2.3.1", + "@smithy/types": "^2.9.1", + "@smithy/util-base64": "^2.1.1", + "@smithy/util-buffer-from": "^2.1.1", + "@smithy/util-hex-encoding": "^2.1.1", + "@smithy/util-utf8": "^2.1.1", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@smithy/util-uri-escape": { + "version": "2.1.1", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@smithy/util-utf8": { + "version": "2.1.1", + "license": "Apache-2.0", + "dependencies": { + "@smithy/util-buffer-from": "^2.1.1", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@smithy/util-waiter": { + "version": "2.1.1", + "license": "Apache-2.0", + "dependencies": { + "@smithy/abort-controller": "^2.1.1", + "@smithy/types": "^2.9.1", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/bowser": { + "version": "2.11.0", + "license": "MIT" + }, + "node_modules/color": { + "version": "4.2.3", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1", + "color-string": "^1.9.0" + }, + "engines": { + "node": ">=12.5.0" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "license": "MIT" + }, + "node_modules/color-string": { + "version": "1.9.1", + "license": "MIT", + "dependencies": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, + "node_modules/csv": { + "version": "6.3.6", + "resolved": "https://registry.npmjs.org/csv/-/csv-6.3.6.tgz", + "integrity": "sha512-jsEsX2HhGp7xiwrJu5srQavKsh+HUJcCi78Ar3m4jlmFKRoTkkMy7ZZPP+LnQChmaztW+uj44oyfMb59daAs/Q==", + "dependencies": { + "csv-generate": "^4.3.1", + "csv-parse": "^5.5.3", + "csv-stringify": "^6.4.5", + "stream-transform": "^3.3.0" + }, + "engines": { + "node": ">= 0.1.90" + } + }, + "node_modules/csv-generate": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/csv-generate/-/csv-generate-4.3.1.tgz", + "integrity": "sha512-7YeeJq+44/I/O5N2sr2qBMcHZXhpfe38eh7DOFxyMtYO+Pir7kIfgFkW5MPksqKqqR6+/wX7UGoZm1Ot11151w==" + }, + "node_modules/csv-parse": { + "version": "5.5.3", + "resolved": "https://registry.npmjs.org/csv-parse/-/csv-parse-5.5.3.tgz", + "integrity": "sha512-v0KW6C0qlZzoGjk6u5tLmVfyZxNgPGXZsWTXshpAgKVGmGXzaVWGdlCFxNx5iuzcXT/oJN1HHM9DZKwtAtYa+A==" + }, + "node_modules/csv-stringify": { + "version": "6.4.5", + "resolved": "https://registry.npmjs.org/csv-stringify/-/csv-stringify-6.4.5.tgz", + "integrity": "sha512-SPu1Vnh8U5EnzpNOi1NDBL5jU5Rx7DVHr15DNg9LXDTAbQlAVAmEbVt16wZvEW9Fu9Qt4Ji8kmeCJ2B1+4rFTQ==" + }, + "node_modules/detect-libc": { + "version": "2.0.2", + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/dotenv": { + "version": "16.4.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.1.tgz", + "integrity": "sha512-CjA3y+Dr3FyFDOAMnxZEGtnW9KBR2M0JvvUtXNW+dYJL5ROWxP9DUHCwgFqpMk0OXCc0ljhaNTr2w/kutYIcHQ==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/motdotla/dotenv?sponsor=1" + } + }, + "node_modules/fast-xml-parser": { + "version": "4.2.5", + "funding": [ + { + "type": "paypal", + "url": "https://paypal.me/naturalintelligence" + }, + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "license": "MIT", + "dependencies": { + "strnum": "^1.0.5" + }, + "bin": { + "fxparser": "src/cli/cli.js" + } + }, + "node_modules/is-arrayish": { + "version": "0.3.2", + "license": "MIT" + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver": { + "version": "7.5.4", + "license": "ISC", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/sharp": { + "version": "0.33.2", + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "color": "^4.2.3", + "detect-libc": "^2.0.2", + "semver": "^7.5.4" + }, + "engines": { + "libvips": ">=8.15.1", + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-darwin-arm64": "0.33.2", + "@img/sharp-darwin-x64": "0.33.2", + "@img/sharp-libvips-darwin-arm64": "1.0.1", + "@img/sharp-libvips-darwin-x64": "1.0.1", + "@img/sharp-libvips-linux-arm": "1.0.1", + "@img/sharp-libvips-linux-arm64": "1.0.1", + "@img/sharp-libvips-linux-s390x": "1.0.1", + "@img/sharp-libvips-linux-x64": "1.0.1", + "@img/sharp-libvips-linuxmusl-arm64": "1.0.1", + "@img/sharp-libvips-linuxmusl-x64": "1.0.1", + "@img/sharp-linux-arm": "0.33.2", + "@img/sharp-linux-arm64": "0.33.2", + "@img/sharp-linux-s390x": "0.33.2", + "@img/sharp-linux-x64": "0.33.2", + "@img/sharp-linuxmusl-arm64": "0.33.2", + "@img/sharp-linuxmusl-x64": "0.33.2", + "@img/sharp-wasm32": "0.33.2", + "@img/sharp-win32-ia32": "0.33.2", + "@img/sharp-win32-x64": "0.33.2" + } + }, + "node_modules/simple-swizzle": { + "version": "0.2.2", + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.3.1" + } + }, + "node_modules/stream-transform": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/stream-transform/-/stream-transform-3.3.0.tgz", + "integrity": "sha512-pG1NeDdmErNYKtvTpFayrEueAmL0xVU5wd22V7InGnatl4Ocq3HY7dcXIKj629kXvYQvglCC7CeDIGAlx1RNGA==" + }, + "node_modules/strnum": { + "version": "1.0.5", + "license": "MIT" + }, + "node_modules/tslib": { + "version": "2.6.2", + "license": "0BSD" + }, + "node_modules/yallist": { + "version": "4.0.0", + "license": "ISC" + } + }, + "dependencies": { + "@aws-crypto/crc32": { + "version": "3.0.0", + "requires": { + "@aws-crypto/util": "^3.0.0", + "@aws-sdk/types": "^3.222.0", + "tslib": "^1.11.1" + }, + "dependencies": { + "tslib": { + "version": "1.14.1" + } + } + }, + "@aws-crypto/crc32c": { + "version": "3.0.0", + "requires": { + "@aws-crypto/util": "^3.0.0", + "@aws-sdk/types": "^3.222.0", + "tslib": "^1.11.1" + }, + "dependencies": { + "tslib": { + "version": "1.14.1" + } + } + }, + "@aws-crypto/ie11-detection": { + "version": "3.0.0", + "requires": { + "tslib": "^1.11.1" + }, + "dependencies": { + "tslib": { + "version": "1.14.1" + } + } + }, + "@aws-crypto/sha1-browser": { + "version": "3.0.0", + "requires": { + "@aws-crypto/ie11-detection": "^3.0.0", + "@aws-crypto/supports-web-crypto": "^3.0.0", + "@aws-crypto/util": "^3.0.0", + "@aws-sdk/types": "^3.222.0", + "@aws-sdk/util-locate-window": "^3.0.0", + "@aws-sdk/util-utf8-browser": "^3.0.0", + "tslib": "^1.11.1" + }, + "dependencies": { + "tslib": { + "version": "1.14.1" + } + } + }, + "@aws-crypto/sha256-browser": { + "version": "3.0.0", + "requires": { + "@aws-crypto/ie11-detection": "^3.0.0", + "@aws-crypto/sha256-js": "^3.0.0", + "@aws-crypto/supports-web-crypto": "^3.0.0", + "@aws-crypto/util": "^3.0.0", + "@aws-sdk/types": "^3.222.0", + "@aws-sdk/util-locate-window": "^3.0.0", + "@aws-sdk/util-utf8-browser": "^3.0.0", + "tslib": "^1.11.1" + }, + "dependencies": { + "tslib": { + "version": "1.14.1" + } + } + }, + "@aws-crypto/sha256-js": { + "version": "3.0.0", + "requires": { + "@aws-crypto/util": "^3.0.0", + "@aws-sdk/types": "^3.222.0", + "tslib": "^1.11.1" + }, + "dependencies": { + "tslib": { + "version": "1.14.1" + } + } + }, + "@aws-crypto/supports-web-crypto": { + "version": "3.0.0", + "requires": { + "tslib": "^1.11.1" + }, + "dependencies": { + "tslib": { + "version": "1.14.1" + } + } + }, + "@aws-crypto/util": { + "version": "3.0.0", + "requires": { + "@aws-sdk/types": "^3.222.0", + "@aws-sdk/util-utf8-browser": "^3.0.0", + "tslib": "^1.11.1" + }, + "dependencies": { + "tslib": { + "version": "1.14.1" + } + } + }, + "@aws-sdk/client-s3": { + "version": "3.496.0", + "requires": { + "@aws-crypto/sha1-browser": "3.0.0", + "@aws-crypto/sha256-browser": "3.0.0", + "@aws-crypto/sha256-js": "3.0.0", + "@aws-sdk/client-sts": "3.496.0", + "@aws-sdk/core": "3.496.0", + "@aws-sdk/credential-provider-node": "3.496.0", + "@aws-sdk/middleware-bucket-endpoint": "3.496.0", + "@aws-sdk/middleware-expect-continue": "3.496.0", + "@aws-sdk/middleware-flexible-checksums": "3.496.0", + "@aws-sdk/middleware-host-header": "3.496.0", + "@aws-sdk/middleware-location-constraint": "3.496.0", + "@aws-sdk/middleware-logger": "3.496.0", + "@aws-sdk/middleware-recursion-detection": "3.496.0", + "@aws-sdk/middleware-sdk-s3": "3.496.0", + "@aws-sdk/middleware-signing": "3.496.0", + "@aws-sdk/middleware-ssec": "3.496.0", + "@aws-sdk/middleware-user-agent": "3.496.0", + "@aws-sdk/region-config-resolver": "3.496.0", + "@aws-sdk/signature-v4-multi-region": "3.496.0", + "@aws-sdk/types": "3.496.0", + "@aws-sdk/util-endpoints": "3.496.0", + "@aws-sdk/util-user-agent-browser": "3.496.0", + "@aws-sdk/util-user-agent-node": "3.496.0", + "@aws-sdk/xml-builder": "3.496.0", + "@smithy/config-resolver": "^2.1.1", + "@smithy/core": "^1.3.1", + "@smithy/eventstream-serde-browser": "^2.1.1", + "@smithy/eventstream-serde-config-resolver": "^2.1.1", + "@smithy/eventstream-serde-node": "^2.1.1", + "@smithy/fetch-http-handler": "^2.4.1", + "@smithy/hash-blob-browser": "^2.1.1", + "@smithy/hash-node": "^2.1.1", + "@smithy/hash-stream-node": "^2.1.1", + "@smithy/invalid-dependency": "^2.1.1", + "@smithy/md5-js": "^2.1.1", + "@smithy/middleware-content-length": "^2.1.1", + "@smithy/middleware-endpoint": "^2.4.1", + "@smithy/middleware-retry": "^2.1.1", + "@smithy/middleware-serde": "^2.1.1", + "@smithy/middleware-stack": "^2.1.1", + "@smithy/node-config-provider": "^2.2.1", + "@smithy/node-http-handler": "^2.3.1", + "@smithy/protocol-http": "^3.1.1", + "@smithy/smithy-client": "^2.3.1", + "@smithy/types": "^2.9.1", + "@smithy/url-parser": "^2.1.1", + "@smithy/util-base64": "^2.1.1", + "@smithy/util-body-length-browser": "^2.1.1", + "@smithy/util-body-length-node": "^2.2.1", + "@smithy/util-defaults-mode-browser": "^2.1.1", + "@smithy/util-defaults-mode-node": "^2.1.1", + "@smithy/util-endpoints": "^1.1.1", + "@smithy/util-retry": "^2.1.1", + "@smithy/util-stream": "^2.1.1", + "@smithy/util-utf8": "^2.1.1", + "@smithy/util-waiter": "^2.1.1", + "fast-xml-parser": "4.2.5", + "tslib": "^2.5.0" + } + }, + "@aws-sdk/client-sso": { + "version": "3.496.0", + "requires": { + "@aws-crypto/sha256-browser": "3.0.0", + "@aws-crypto/sha256-js": "3.0.0", + "@aws-sdk/core": "3.496.0", + "@aws-sdk/middleware-host-header": "3.496.0", + "@aws-sdk/middleware-logger": "3.496.0", + "@aws-sdk/middleware-recursion-detection": "3.496.0", + "@aws-sdk/middleware-user-agent": "3.496.0", + "@aws-sdk/region-config-resolver": "3.496.0", + "@aws-sdk/types": "3.496.0", + "@aws-sdk/util-endpoints": "3.496.0", + "@aws-sdk/util-user-agent-browser": "3.496.0", + "@aws-sdk/util-user-agent-node": "3.496.0", + "@smithy/config-resolver": "^2.1.1", + "@smithy/core": "^1.3.1", + "@smithy/fetch-http-handler": "^2.4.1", + "@smithy/hash-node": "^2.1.1", + "@smithy/invalid-dependency": "^2.1.1", + "@smithy/middleware-content-length": "^2.1.1", + "@smithy/middleware-endpoint": "^2.4.1", + "@smithy/middleware-retry": "^2.1.1", + "@smithy/middleware-serde": "^2.1.1", + "@smithy/middleware-stack": "^2.1.1", + "@smithy/node-config-provider": "^2.2.1", + "@smithy/node-http-handler": "^2.3.1", + "@smithy/protocol-http": "^3.1.1", + "@smithy/smithy-client": "^2.3.1", + "@smithy/types": "^2.9.1", + "@smithy/url-parser": "^2.1.1", + "@smithy/util-base64": "^2.1.1", + "@smithy/util-body-length-browser": "^2.1.1", + "@smithy/util-body-length-node": "^2.2.1", + "@smithy/util-defaults-mode-browser": "^2.1.1", + "@smithy/util-defaults-mode-node": "^2.1.1", + "@smithy/util-endpoints": "^1.1.1", + "@smithy/util-retry": "^2.1.1", + "@smithy/util-utf8": "^2.1.1", + "tslib": "^2.5.0" + } + }, + "@aws-sdk/client-sts": { + "version": "3.496.0", + "requires": { + "@aws-crypto/sha256-browser": "3.0.0", + "@aws-crypto/sha256-js": "3.0.0", + "@aws-sdk/core": "3.496.0", + "@aws-sdk/credential-provider-node": "3.496.0", + "@aws-sdk/middleware-host-header": "3.496.0", + "@aws-sdk/middleware-logger": "3.496.0", + "@aws-sdk/middleware-recursion-detection": "3.496.0", + "@aws-sdk/middleware-user-agent": "3.496.0", + "@aws-sdk/region-config-resolver": "3.496.0", + "@aws-sdk/types": "3.496.0", + "@aws-sdk/util-endpoints": "3.496.0", + "@aws-sdk/util-user-agent-browser": "3.496.0", + "@aws-sdk/util-user-agent-node": "3.496.0", + "@smithy/config-resolver": "^2.1.1", + "@smithy/core": "^1.3.1", + "@smithy/fetch-http-handler": "^2.4.1", + "@smithy/hash-node": "^2.1.1", + "@smithy/invalid-dependency": "^2.1.1", + "@smithy/middleware-content-length": "^2.1.1", + "@smithy/middleware-endpoint": "^2.4.1", + "@smithy/middleware-retry": "^2.1.1", + "@smithy/middleware-serde": "^2.1.1", + "@smithy/middleware-stack": "^2.1.1", + "@smithy/node-config-provider": "^2.2.1", + "@smithy/node-http-handler": "^2.3.1", + "@smithy/protocol-http": "^3.1.1", + "@smithy/smithy-client": "^2.3.1", + "@smithy/types": "^2.9.1", + "@smithy/url-parser": "^2.1.1", + "@smithy/util-base64": "^2.1.1", + "@smithy/util-body-length-browser": "^2.1.1", + "@smithy/util-body-length-node": "^2.2.1", + "@smithy/util-defaults-mode-browser": "^2.1.1", + "@smithy/util-defaults-mode-node": "^2.1.1", + "@smithy/util-endpoints": "^1.1.1", + "@smithy/util-middleware": "^2.1.1", + "@smithy/util-retry": "^2.1.1", + "@smithy/util-utf8": "^2.1.1", + "fast-xml-parser": "4.2.5", + "tslib": "^2.5.0" + } + }, + "@aws-sdk/core": { + "version": "3.496.0", + "requires": { + "@smithy/core": "^1.3.1", + "@smithy/protocol-http": "^3.1.1", + "@smithy/signature-v4": "^2.1.1", + "@smithy/smithy-client": "^2.3.1", + "@smithy/types": "^2.9.1", + "tslib": "^2.5.0" + } + }, + "@aws-sdk/credential-provider-env": { + "version": "3.496.0", + "requires": { + "@aws-sdk/types": "3.496.0", + "@smithy/property-provider": "^2.1.1", + "@smithy/types": "^2.9.1", + "tslib": "^2.5.0" + } + }, + "@aws-sdk/credential-provider-ini": { + "version": "3.496.0", + "requires": { + "@aws-sdk/credential-provider-env": "3.496.0", + "@aws-sdk/credential-provider-process": "3.496.0", + "@aws-sdk/credential-provider-sso": "3.496.0", + "@aws-sdk/credential-provider-web-identity": "3.496.0", + "@aws-sdk/types": "3.496.0", + "@smithy/credential-provider-imds": "^2.2.1", + "@smithy/property-provider": "^2.1.1", + "@smithy/shared-ini-file-loader": "^2.3.1", + "@smithy/types": "^2.9.1", + "tslib": "^2.5.0" + } + }, + "@aws-sdk/credential-provider-node": { + "version": "3.496.0", + "requires": { + "@aws-sdk/credential-provider-env": "3.496.0", + "@aws-sdk/credential-provider-ini": "3.496.0", + "@aws-sdk/credential-provider-process": "3.496.0", + "@aws-sdk/credential-provider-sso": "3.496.0", + "@aws-sdk/credential-provider-web-identity": "3.496.0", + "@aws-sdk/types": "3.496.0", + "@smithy/credential-provider-imds": "^2.2.1", + "@smithy/property-provider": "^2.1.1", + "@smithy/shared-ini-file-loader": "^2.3.1", + "@smithy/types": "^2.9.1", + "tslib": "^2.5.0" + } + }, + "@aws-sdk/credential-provider-process": { + "version": "3.496.0", + "requires": { + "@aws-sdk/types": "3.496.0", + "@smithy/property-provider": "^2.1.1", + "@smithy/shared-ini-file-loader": "^2.3.1", + "@smithy/types": "^2.9.1", + "tslib": "^2.5.0" + } + }, + "@aws-sdk/credential-provider-sso": { + "version": "3.496.0", + "requires": { + "@aws-sdk/client-sso": "3.496.0", + "@aws-sdk/token-providers": "3.496.0", + "@aws-sdk/types": "3.496.0", + "@smithy/property-provider": "^2.1.1", + "@smithy/shared-ini-file-loader": "^2.3.1", + "@smithy/types": "^2.9.1", + "tslib": "^2.5.0" + } + }, + "@aws-sdk/credential-provider-web-identity": { + "version": "3.496.0", + "requires": { + "@aws-sdk/types": "3.496.0", + "@smithy/property-provider": "^2.1.1", + "@smithy/types": "^2.9.1", + "tslib": "^2.5.0" + } + }, + "@aws-sdk/middleware-bucket-endpoint": { + "version": "3.496.0", + "requires": { + "@aws-sdk/types": "3.496.0", + "@aws-sdk/util-arn-parser": "3.495.0", + "@smithy/node-config-provider": "^2.2.1", + "@smithy/protocol-http": "^3.1.1", + "@smithy/types": "^2.9.1", + "@smithy/util-config-provider": "^2.2.1", + "tslib": "^2.5.0" + } + }, + "@aws-sdk/middleware-expect-continue": { + "version": "3.496.0", + "requires": { + "@aws-sdk/types": "3.496.0", + "@smithy/protocol-http": "^3.1.1", + "@smithy/types": "^2.9.1", + "tslib": "^2.5.0" + } + }, + "@aws-sdk/middleware-flexible-checksums": { + "version": "3.496.0", + "requires": { + "@aws-crypto/crc32": "3.0.0", + "@aws-crypto/crc32c": "3.0.0", + "@aws-sdk/types": "3.496.0", + "@smithy/is-array-buffer": "^2.1.1", + "@smithy/protocol-http": "^3.1.1", + "@smithy/types": "^2.9.1", + "@smithy/util-utf8": "^2.1.1", + "tslib": "^2.5.0" + } + }, + "@aws-sdk/middleware-host-header": { + "version": "3.496.0", + "requires": { + "@aws-sdk/types": "3.496.0", + "@smithy/protocol-http": "^3.1.1", + "@smithy/types": "^2.9.1", + "tslib": "^2.5.0" + } + }, + "@aws-sdk/middleware-location-constraint": { + "version": "3.496.0", + "requires": { + "@aws-sdk/types": "3.496.0", + "@smithy/types": "^2.9.1", + "tslib": "^2.5.0" + } + }, + "@aws-sdk/middleware-logger": { + "version": "3.496.0", + "requires": { + "@aws-sdk/types": "3.496.0", + "@smithy/types": "^2.9.1", + "tslib": "^2.5.0" + } + }, + "@aws-sdk/middleware-recursion-detection": { + "version": "3.496.0", + "requires": { + "@aws-sdk/types": "3.496.0", + "@smithy/protocol-http": "^3.1.1", + "@smithy/types": "^2.9.1", + "tslib": "^2.5.0" + } + }, + "@aws-sdk/middleware-sdk-s3": { + "version": "3.496.0", + "requires": { + "@aws-sdk/types": "3.496.0", + "@aws-sdk/util-arn-parser": "3.495.0", + "@smithy/node-config-provider": "^2.2.1", + "@smithy/protocol-http": "^3.1.1", + "@smithy/signature-v4": "^2.1.1", + "@smithy/smithy-client": "^2.3.1", + "@smithy/types": "^2.9.1", + "@smithy/util-config-provider": "^2.2.1", + "tslib": "^2.5.0" + } + }, + "@aws-sdk/middleware-signing": { + "version": "3.496.0", + "requires": { + "@aws-sdk/types": "3.496.0", + "@smithy/property-provider": "^2.1.1", + "@smithy/protocol-http": "^3.1.1", + "@smithy/signature-v4": "^2.1.1", + "@smithy/types": "^2.9.1", + "@smithy/util-middleware": "^2.1.1", + "tslib": "^2.5.0" + } + }, + "@aws-sdk/middleware-ssec": { + "version": "3.496.0", + "requires": { + "@aws-sdk/types": "3.496.0", + "@smithy/types": "^2.9.1", + "tslib": "^2.5.0" + } + }, + "@aws-sdk/middleware-user-agent": { + "version": "3.496.0", + "requires": { + "@aws-sdk/types": "3.496.0", + "@aws-sdk/util-endpoints": "3.496.0", + "@smithy/protocol-http": "^3.1.1", + "@smithy/types": "^2.9.1", + "tslib": "^2.5.0" + } + }, + "@aws-sdk/region-config-resolver": { + "version": "3.496.0", + "requires": { + "@aws-sdk/types": "3.496.0", + "@smithy/node-config-provider": "^2.2.1", + "@smithy/types": "^2.9.1", + "@smithy/util-config-provider": "^2.2.1", + "@smithy/util-middleware": "^2.1.1", + "tslib": "^2.5.0" + } + }, + "@aws-sdk/signature-v4-multi-region": { + "version": "3.496.0", + "requires": { + "@aws-sdk/middleware-sdk-s3": "3.496.0", + "@aws-sdk/types": "3.496.0", + "@smithy/protocol-http": "^3.1.1", + "@smithy/signature-v4": "^2.1.1", + "@smithy/types": "^2.9.1", + "tslib": "^2.5.0" + } + }, + "@aws-sdk/token-providers": { + "version": "3.496.0", + "requires": { + "@aws-crypto/sha256-browser": "3.0.0", + "@aws-crypto/sha256-js": "3.0.0", + "@aws-sdk/middleware-host-header": "3.496.0", + "@aws-sdk/middleware-logger": "3.496.0", + "@aws-sdk/middleware-recursion-detection": "3.496.0", + "@aws-sdk/middleware-user-agent": "3.496.0", + "@aws-sdk/region-config-resolver": "3.496.0", + "@aws-sdk/types": "3.496.0", + "@aws-sdk/util-endpoints": "3.496.0", + "@aws-sdk/util-user-agent-browser": "3.496.0", + "@aws-sdk/util-user-agent-node": "3.496.0", + "@smithy/config-resolver": "^2.1.1", + "@smithy/fetch-http-handler": "^2.4.1", + "@smithy/hash-node": "^2.1.1", + "@smithy/invalid-dependency": "^2.1.1", + "@smithy/middleware-content-length": "^2.1.1", + "@smithy/middleware-endpoint": "^2.4.1", + "@smithy/middleware-retry": "^2.1.1", + "@smithy/middleware-serde": "^2.1.1", + "@smithy/middleware-stack": "^2.1.1", + "@smithy/node-config-provider": "^2.2.1", + "@smithy/node-http-handler": "^2.3.1", + "@smithy/property-provider": "^2.1.1", + "@smithy/protocol-http": "^3.1.1", + "@smithy/shared-ini-file-loader": "^2.3.1", + "@smithy/smithy-client": "^2.3.1", + "@smithy/types": "^2.9.1", + "@smithy/url-parser": "^2.1.1", + "@smithy/util-base64": "^2.1.1", + "@smithy/util-body-length-browser": "^2.1.1", + "@smithy/util-body-length-node": "^2.2.1", + "@smithy/util-defaults-mode-browser": "^2.1.1", + "@smithy/util-defaults-mode-node": "^2.1.1", + "@smithy/util-endpoints": "^1.1.1", + "@smithy/util-retry": "^2.1.1", + "@smithy/util-utf8": "^2.1.1", + "tslib": "^2.5.0" + } + }, + "@aws-sdk/types": { + "version": "3.496.0", + "requires": { + "@smithy/types": "^2.9.1", + "tslib": "^2.5.0" + } + }, + "@aws-sdk/util-arn-parser": { + "version": "3.495.0", + "requires": { + "tslib": "^2.5.0" + } + }, + "@aws-sdk/util-endpoints": { + "version": "3.496.0", + "requires": { + "@aws-sdk/types": "3.496.0", + "@smithy/types": "^2.9.1", + "@smithy/util-endpoints": "^1.1.1", + "tslib": "^2.5.0" + } + }, + "@aws-sdk/util-locate-window": { + "version": "3.495.0", + "requires": { + "tslib": "^2.5.0" + } + }, + "@aws-sdk/util-user-agent-browser": { + "version": "3.496.0", + "requires": { + "@aws-sdk/types": "3.496.0", + "@smithy/types": "^2.9.1", + "bowser": "^2.11.0", + "tslib": "^2.5.0" + } + }, + "@aws-sdk/util-user-agent-node": { + "version": "3.496.0", + "requires": { + "@aws-sdk/types": "3.496.0", + "@smithy/node-config-provider": "^2.2.1", + "@smithy/types": "^2.9.1", + "tslib": "^2.5.0" + } + }, + "@aws-sdk/util-utf8-browser": { + "version": "3.259.0", + "requires": { + "tslib": "^2.3.1" + } + }, + "@aws-sdk/xml-builder": { + "version": "3.496.0", + "requires": { + "@smithy/types": "^2.9.1", + "tslib": "^2.5.0" + } + }, + "@img/sharp-darwin-arm64": { + "version": "0.33.2", + "optional": true, + "requires": { + "@img/sharp-libvips-darwin-arm64": "1.0.1" + } + }, + "@img/sharp-libvips-darwin-arm64": { + "version": "1.0.1", + "optional": true + }, + "@smithy/abort-controller": { + "version": "2.1.1", + "requires": { + "@smithy/types": "^2.9.1", + "tslib": "^2.5.0" + } + }, + "@smithy/chunked-blob-reader": { + "version": "2.1.1", + "requires": { + "tslib": "^2.5.0" + } + }, + "@smithy/chunked-blob-reader-native": { + "version": "2.1.1", + "requires": { + "@smithy/util-base64": "^2.1.1", + "tslib": "^2.5.0" + } + }, + "@smithy/config-resolver": { + "version": "2.1.1", + "requires": { + "@smithy/node-config-provider": "^2.2.1", + "@smithy/types": "^2.9.1", + "@smithy/util-config-provider": "^2.2.1", + "@smithy/util-middleware": "^2.1.1", + "tslib": "^2.5.0" + } + }, + "@smithy/core": { + "version": "1.3.1", + "requires": { + "@smithy/middleware-endpoint": "^2.4.1", + "@smithy/middleware-retry": "^2.1.1", + "@smithy/middleware-serde": "^2.1.1", + "@smithy/protocol-http": "^3.1.1", + "@smithy/smithy-client": "^2.3.1", + "@smithy/types": "^2.9.1", + "@smithy/util-middleware": "^2.1.1", + "tslib": "^2.5.0" + } + }, + "@smithy/credential-provider-imds": { + "version": "2.2.1", + "requires": { + "@smithy/node-config-provider": "^2.2.1", + "@smithy/property-provider": "^2.1.1", + "@smithy/types": "^2.9.1", + "@smithy/url-parser": "^2.1.1", + "tslib": "^2.5.0" + } + }, + "@smithy/eventstream-codec": { + "version": "2.1.1", + "requires": { + "@aws-crypto/crc32": "3.0.0", + "@smithy/types": "^2.9.1", + "@smithy/util-hex-encoding": "^2.1.1", + "tslib": "^2.5.0" + } + }, + "@smithy/eventstream-serde-browser": { + "version": "2.1.1", + "requires": { + "@smithy/eventstream-serde-universal": "^2.1.1", + "@smithy/types": "^2.9.1", + "tslib": "^2.5.0" + } + }, + "@smithy/eventstream-serde-config-resolver": { + "version": "2.1.1", + "requires": { + "@smithy/types": "^2.9.1", + "tslib": "^2.5.0" + } + }, + "@smithy/eventstream-serde-node": { + "version": "2.1.1", + "requires": { + "@smithy/eventstream-serde-universal": "^2.1.1", + "@smithy/types": "^2.9.1", + "tslib": "^2.5.0" + } + }, + "@smithy/eventstream-serde-universal": { + "version": "2.1.1", + "requires": { + "@smithy/eventstream-codec": "^2.1.1", + "@smithy/types": "^2.9.1", + "tslib": "^2.5.0" + } + }, + "@smithy/fetch-http-handler": { + "version": "2.4.1", + "requires": { + "@smithy/protocol-http": "^3.1.1", + "@smithy/querystring-builder": "^2.1.1", + "@smithy/types": "^2.9.1", + "@smithy/util-base64": "^2.1.1", + "tslib": "^2.5.0" + } + }, + "@smithy/hash-blob-browser": { + "version": "2.1.1", + "requires": { + "@smithy/chunked-blob-reader": "^2.1.1", + "@smithy/chunked-blob-reader-native": "^2.1.1", + "@smithy/types": "^2.9.1", + "tslib": "^2.5.0" + } + }, + "@smithy/hash-node": { + "version": "2.1.1", + "requires": { + "@smithy/types": "^2.9.1", + "@smithy/util-buffer-from": "^2.1.1", + "@smithy/util-utf8": "^2.1.1", + "tslib": "^2.5.0" + } + }, + "@smithy/hash-stream-node": { + "version": "2.1.1", + "requires": { + "@smithy/types": "^2.9.1", + "@smithy/util-utf8": "^2.1.1", + "tslib": "^2.5.0" + } + }, + "@smithy/invalid-dependency": { + "version": "2.1.1", + "requires": { + "@smithy/types": "^2.9.1", + "tslib": "^2.5.0" + } + }, + "@smithy/is-array-buffer": { + "version": "2.1.1", + "requires": { + "tslib": "^2.5.0" + } + }, + "@smithy/md5-js": { + "version": "2.1.1", + "requires": { + "@smithy/types": "^2.9.1", + "@smithy/util-utf8": "^2.1.1", + "tslib": "^2.5.0" + } + }, + "@smithy/middleware-content-length": { + "version": "2.1.1", + "requires": { + "@smithy/protocol-http": "^3.1.1", + "@smithy/types": "^2.9.1", + "tslib": "^2.5.0" + } + }, + "@smithy/middleware-endpoint": { + "version": "2.4.1", + "requires": { + "@smithy/middleware-serde": "^2.1.1", + "@smithy/node-config-provider": "^2.2.1", + "@smithy/shared-ini-file-loader": "^2.3.1", + "@smithy/types": "^2.9.1", + "@smithy/url-parser": "^2.1.1", + "@smithy/util-middleware": "^2.1.1", + "tslib": "^2.5.0" + } + }, + "@smithy/middleware-retry": { + "version": "2.1.1", + "requires": { + "@smithy/node-config-provider": "^2.2.1", + "@smithy/protocol-http": "^3.1.1", + "@smithy/service-error-classification": "^2.1.1", + "@smithy/smithy-client": "^2.3.1", + "@smithy/types": "^2.9.1", + "@smithy/util-middleware": "^2.1.1", + "@smithy/util-retry": "^2.1.1", + "tslib": "^2.5.0", + "uuid": "^8.3.2" + }, + "dependencies": { + "uuid": { + "version": "8.3.2" + } + } + }, + "@smithy/middleware-serde": { + "version": "2.1.1", + "requires": { + "@smithy/types": "^2.9.1", + "tslib": "^2.5.0" + } + }, + "@smithy/middleware-stack": { + "version": "2.1.1", + "requires": { + "@smithy/types": "^2.9.1", + "tslib": "^2.5.0" + } + }, + "@smithy/node-config-provider": { + "version": "2.2.1", + "requires": { + "@smithy/property-provider": "^2.1.1", + "@smithy/shared-ini-file-loader": "^2.3.1", + "@smithy/types": "^2.9.1", + "tslib": "^2.5.0" + } + }, + "@smithy/node-http-handler": { + "version": "2.3.1", + "requires": { + "@smithy/abort-controller": "^2.1.1", + "@smithy/protocol-http": "^3.1.1", + "@smithy/querystring-builder": "^2.1.1", + "@smithy/types": "^2.9.1", + "tslib": "^2.5.0" + } + }, + "@smithy/property-provider": { + "version": "2.1.1", + "requires": { + "@smithy/types": "^2.9.1", + "tslib": "^2.5.0" + } + }, + "@smithy/protocol-http": { + "version": "3.1.1", + "requires": { + "@smithy/types": "^2.9.1", + "tslib": "^2.5.0" + } + }, + "@smithy/querystring-builder": { + "version": "2.1.1", + "requires": { + "@smithy/types": "^2.9.1", + "@smithy/util-uri-escape": "^2.1.1", + "tslib": "^2.5.0" + } + }, + "@smithy/querystring-parser": { + "version": "2.1.1", + "requires": { + "@smithy/types": "^2.9.1", + "tslib": "^2.5.0" + } + }, + "@smithy/service-error-classification": { + "version": "2.1.1", + "requires": { + "@smithy/types": "^2.9.1" + } + }, + "@smithy/shared-ini-file-loader": { + "version": "2.3.1", + "requires": { + "@smithy/types": "^2.9.1", + "tslib": "^2.5.0" + } + }, + "@smithy/signature-v4": { + "version": "2.1.1", + "requires": { + "@smithy/eventstream-codec": "^2.1.1", + "@smithy/is-array-buffer": "^2.1.1", + "@smithy/types": "^2.9.1", + "@smithy/util-hex-encoding": "^2.1.1", + "@smithy/util-middleware": "^2.1.1", + "@smithy/util-uri-escape": "^2.1.1", + "@smithy/util-utf8": "^2.1.1", + "tslib": "^2.5.0" + } + }, + "@smithy/smithy-client": { + "version": "2.3.1", + "requires": { + "@smithy/middleware-endpoint": "^2.4.1", + "@smithy/middleware-stack": "^2.1.1", + "@smithy/protocol-http": "^3.1.1", + "@smithy/types": "^2.9.1", + "@smithy/util-stream": "^2.1.1", + "tslib": "^2.5.0" + } + }, + "@smithy/types": { + "version": "2.9.1", + "requires": { + "tslib": "^2.5.0" + } + }, + "@smithy/url-parser": { + "version": "2.1.1", + "requires": { + "@smithy/querystring-parser": "^2.1.1", + "@smithy/types": "^2.9.1", + "tslib": "^2.5.0" + } + }, + "@smithy/util-base64": { + "version": "2.1.1", + "requires": { + "@smithy/util-buffer-from": "^2.1.1", + "tslib": "^2.5.0" + } + }, + "@smithy/util-body-length-browser": { + "version": "2.1.1", + "requires": { + "tslib": "^2.5.0" + } + }, + "@smithy/util-body-length-node": { + "version": "2.2.1", + "requires": { + "tslib": "^2.5.0" + } + }, + "@smithy/util-buffer-from": { + "version": "2.1.1", + "requires": { + "@smithy/is-array-buffer": "^2.1.1", + "tslib": "^2.5.0" + } + }, + "@smithy/util-config-provider": { + "version": "2.2.1", + "requires": { + "tslib": "^2.5.0" + } + }, + "@smithy/util-defaults-mode-browser": { + "version": "2.1.1", + "requires": { + "@smithy/property-provider": "^2.1.1", + "@smithy/smithy-client": "^2.3.1", + "@smithy/types": "^2.9.1", + "bowser": "^2.11.0", + "tslib": "^2.5.0" + } + }, + "@smithy/util-defaults-mode-node": { + "version": "2.1.1", + "requires": { + "@smithy/config-resolver": "^2.1.1", + "@smithy/credential-provider-imds": "^2.2.1", + "@smithy/node-config-provider": "^2.2.1", + "@smithy/property-provider": "^2.1.1", + "@smithy/smithy-client": "^2.3.1", + "@smithy/types": "^2.9.1", + "tslib": "^2.5.0" + } + }, + "@smithy/util-endpoints": { + "version": "1.1.1", + "requires": { + "@smithy/node-config-provider": "^2.2.1", + "@smithy/types": "^2.9.1", + "tslib": "^2.5.0" + } + }, + "@smithy/util-hex-encoding": { + "version": "2.1.1", + "requires": { + "tslib": "^2.5.0" + } + }, + "@smithy/util-middleware": { + "version": "2.1.1", + "requires": { + "@smithy/types": "^2.9.1", + "tslib": "^2.5.0" + } + }, + "@smithy/util-retry": { + "version": "2.1.1", + "requires": { + "@smithy/service-error-classification": "^2.1.1", + "@smithy/types": "^2.9.1", + "tslib": "^2.5.0" + } + }, + "@smithy/util-stream": { + "version": "2.1.1", + "requires": { + "@smithy/fetch-http-handler": "^2.4.1", + "@smithy/node-http-handler": "^2.3.1", + "@smithy/types": "^2.9.1", + "@smithy/util-base64": "^2.1.1", + "@smithy/util-buffer-from": "^2.1.1", + "@smithy/util-hex-encoding": "^2.1.1", + "@smithy/util-utf8": "^2.1.1", + "tslib": "^2.5.0" + } + }, + "@smithy/util-uri-escape": { + "version": "2.1.1", + "requires": { + "tslib": "^2.5.0" + } + }, + "@smithy/util-utf8": { + "version": "2.1.1", + "requires": { + "@smithy/util-buffer-from": "^2.1.1", + "tslib": "^2.5.0" + } + }, + "@smithy/util-waiter": { + "version": "2.1.1", + "requires": { + "@smithy/abort-controller": "^2.1.1", + "@smithy/types": "^2.9.1", + "tslib": "^2.5.0" + } + }, + "bowser": { + "version": "2.11.0" + }, + "color": { + "version": "4.2.3", + "requires": { + "color-convert": "^2.0.1", + "color-string": "^1.9.0" + } + }, + "color-convert": { + "version": "2.0.1", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4" + }, + "color-string": { + "version": "1.9.1", + "requires": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, + "csv": { + "version": "6.3.6", + "resolved": "https://registry.npmjs.org/csv/-/csv-6.3.6.tgz", + "integrity": "sha512-jsEsX2HhGp7xiwrJu5srQavKsh+HUJcCi78Ar3m4jlmFKRoTkkMy7ZZPP+LnQChmaztW+uj44oyfMb59daAs/Q==", + "requires": { + "csv-generate": "^4.3.1", + "csv-parse": "^5.5.3", + "csv-stringify": "^6.4.5", + "stream-transform": "^3.3.0" + } + }, + "csv-generate": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/csv-generate/-/csv-generate-4.3.1.tgz", + "integrity": "sha512-7YeeJq+44/I/O5N2sr2qBMcHZXhpfe38eh7DOFxyMtYO+Pir7kIfgFkW5MPksqKqqR6+/wX7UGoZm1Ot11151w==" + }, + "csv-parse": { + "version": "5.5.3", + "resolved": "https://registry.npmjs.org/csv-parse/-/csv-parse-5.5.3.tgz", + "integrity": "sha512-v0KW6C0qlZzoGjk6u5tLmVfyZxNgPGXZsWTXshpAgKVGmGXzaVWGdlCFxNx5iuzcXT/oJN1HHM9DZKwtAtYa+A==" + }, + "csv-stringify": { + "version": "6.4.5", + "resolved": "https://registry.npmjs.org/csv-stringify/-/csv-stringify-6.4.5.tgz", + "integrity": "sha512-SPu1Vnh8U5EnzpNOi1NDBL5jU5Rx7DVHr15DNg9LXDTAbQlAVAmEbVt16wZvEW9Fu9Qt4Ji8kmeCJ2B1+4rFTQ==" + }, + "detect-libc": { + "version": "2.0.2" + }, + "dotenv": { + "version": "16.4.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.1.tgz", + "integrity": "sha512-CjA3y+Dr3FyFDOAMnxZEGtnW9KBR2M0JvvUtXNW+dYJL5ROWxP9DUHCwgFqpMk0OXCc0ljhaNTr2w/kutYIcHQ==" + }, + "fast-xml-parser": { + "version": "4.2.5", + "requires": { + "strnum": "^1.0.5" + } + }, + "is-arrayish": { + "version": "0.3.2" + }, + "lru-cache": { + "version": "6.0.0", + "requires": { + "yallist": "^4.0.0" + } + }, + "semver": { + "version": "7.5.4", + "requires": { + "lru-cache": "^6.0.0" + } + }, + "sharp": { + "version": "0.33.2", + "requires": { + "@img/sharp-darwin-arm64": "0.33.2", + "@img/sharp-darwin-x64": "0.33.2", + "@img/sharp-libvips-darwin-arm64": "1.0.1", + "@img/sharp-libvips-darwin-x64": "1.0.1", + "@img/sharp-libvips-linux-arm": "1.0.1", + "@img/sharp-libvips-linux-arm64": "1.0.1", + "@img/sharp-libvips-linux-s390x": "1.0.1", + "@img/sharp-libvips-linux-x64": "1.0.1", + "@img/sharp-libvips-linuxmusl-arm64": "1.0.1", + "@img/sharp-libvips-linuxmusl-x64": "1.0.1", + "@img/sharp-linux-arm": "0.33.2", + "@img/sharp-linux-arm64": "0.33.2", + "@img/sharp-linux-s390x": "0.33.2", + "@img/sharp-linux-x64": "0.33.2", + "@img/sharp-linuxmusl-arm64": "0.33.2", + "@img/sharp-linuxmusl-x64": "0.33.2", + "@img/sharp-wasm32": "0.33.2", + "@img/sharp-win32-ia32": "0.33.2", + "@img/sharp-win32-x64": "0.33.2", + "color": "^4.2.3", + "detect-libc": "^2.0.2", + "semver": "^7.5.4" + } + }, + "simple-swizzle": { + "version": "0.2.2", + "requires": { + "is-arrayish": "^0.3.1" + } + }, + "stream-transform": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/stream-transform/-/stream-transform-3.3.0.tgz", + "integrity": "sha512-pG1NeDdmErNYKtvTpFayrEueAmL0xVU5wd22V7InGnatl4Ocq3HY7dcXIKj629kXvYQvglCC7CeDIGAlx1RNGA==" + }, + "strnum": { + "version": "1.0.5" + }, + "tslib": { + "version": "2.6.2" + }, + "yallist": { + "version": "4.0.0" + } + } +} diff --git a/housekeeping-scripts/s3-images-resizing/package.json b/housekeeping-scripts/s3-images-resizing/package.json new file mode 100644 index 000000000..3e0584dff --- /dev/null +++ b/housekeeping-scripts/s3-images-resizing/package.json @@ -0,0 +1,18 @@ +{ + "name": "eg-scripting", + "version": "1.0.0", + "description": "Nodejs based scripts for EG", + "main": "index.js", + "scripts": { + "start": "node index.js", + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "Manoj L", + "license": "ISC", + "dependencies": { + "@aws-sdk/client-s3": "^3.496.0", + "csv": "^6.3.6", + "dotenv": "^16.4.1", + "sharp": "^0.33.2" + } +} diff --git a/housekeeping-scripts/s3-images-resizing/resized/.gitkeep b/housekeeping-scripts/s3-images-resizing/resized/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/housekeeping-scripts/s3-images-resizing/resized/128x128/.gitkeep b/housekeeping-scripts/s3-images-resizing/resized/128x128/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/housekeeping-scripts/s3-images-resizing/resized/256x256/.gitkeep b/housekeeping-scripts/s3-images-resizing/resized/256x256/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/housekeeping-scripts/s3-images-resizing/resized/32x32/.gitkeep b/housekeeping-scripts/s3-images-resizing/resized/32x32/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/housekeeping-scripts/s3-images-resizing/resized/64x64/.gitkeep b/housekeeping-scripts/s3-images-resizing/resized/64x64/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/housekeeping-scripts/s3-images-resizing/sample.csv b/housekeeping-scripts/s3-images-resizing/sample.csv new file mode 100644 index 000000000..8c0e74ff9 --- /dev/null +++ b/housekeeping-scripts/s3-images-resizing/sample.csv @@ -0,0 +1,2 @@ +"id","name","provider","path","doument_type" +52,"abc.jpeg","s3","/user/docs","profile" \ No newline at end of file From 0872754cd0cc7cbd34d0e886ef4af3c2dca24d26 Mon Sep 17 00:00:00 2001 From: Tusharmahajan12 <121154132+Tusharmahajan12@users.noreply.github.com> Date: Thu, 22 Feb 2024 15:34:49 +0530 Subject: [PATCH 006/126] Task #213168 added event batch validation and filter in event list (#814) * added event batch validation and filter in event list * added event batch validation and filter in event list * added event batch validation and filter in event list --- src/src/enum/enum.json | 100 +++++++++++++++++- src/src/events/events.service.ts | 114 ++++++++++++--------- src/src/facilitator/facilitator.service.ts | 82 +++++++++++++-- src/src/user/user.service.ts | 7 +- 4 files changed, 241 insertions(+), 62 deletions(-) diff --git a/src/src/enum/enum.json b/src/src/enum/enum.json index e5781ac73..e3f3a1fc2 100644 --- a/src/src/enum/enum.json +++ b/src/src/enum/enum.json @@ -429,12 +429,20 @@ "value": "prerak_orientation" }, { - "title": "FACILITATOR_EVENT_TYPE_PRERAK_FLN_TRAINING", - "value": "prerak_fln_training" + "title": "FACILITATOR_EVENT_TYPE_GKP_TRAINING", + "value": "gkp_training" }, { - "title": "FACILITATOR_EVENT_TYPE_PRERAK_CAMP_EXECUTION_TRAINING", - "value": "prerak_camp_execution_training" + "title": "FACILITATOR_EVENT_TYPE_PCR_TRAINING", + "value": "pcr_training" + }, + { + "title": "FACILITATOR_EVENT_TYPE_MAIN_CAMP_EXECUTION_TRAINING", + "value": "main_camp_execution_training" + }, + { + "title": "FACILITATOR_EVENT_TYPE_DRIP_TRAINING", + "value": "drip_training" } ], "BENEFICIARY_REASONS_FOR_REJECTING_LEARNER": [ @@ -1470,5 +1478,87 @@ "title": "SESSION_COMPLETED_SESSION_SUCCESSFULLY_IMPLEMENTED", "value": "session_completed_session_successfully_implemented" } + ], + "EVENT_BATCH_NAME": [ + { + "title": "EVENT_BATCH_NAME_BATCH_1", + "value": "batch_1" + }, + { + "title": "EVENT_BATCH_NAME_BATCH_2", + "value": "batch_2" + }, + { + "title": "EVENT_BATCH_NAME_BATCH_3", + "value": "batch_3" + }, + { + "title": "EVENT_BATCH_NAME_BATCH_4", + "value": "batch_4" + }, + { + "title": "EVENT_BATCH_NAME_BATCH_5", + "value": "batch_5" + }, + { + "title": "EVENT_BATCH_NAME_BATCH_6", + "value": "batch_6" + }, + { + "title": "EVENT_BATCH_NAME_BATCH_7", + "value": "batch_7" + }, + { + "title": "EVENT_BATCH_NAME_BATCH_8", + "value": "batch_8" + }, + { + "title": "EVENT_BATCH_NAME_BATCH_9", + "value": "batch_9" + }, + { + "title": "EVENT_BATCH_NAME_BATCH_10", + "value": "batch_10" + }, + { + "title": "EVENT_BATCH_NAME_BATCH_11", + "value": "batch_11" + }, + { + "title": "EVENT_BATCH_NAME_BATCH_12", + "value": "batch_12" + }, + { + "title": "EVENT_BATCH_NAME_BATCH_13", + "value": "batch_13" + }, + { + "title": "EVENT_BATCH_NAME_BATCH_14", + "value": "batch_14" + }, + { + "title": "EVENT_BATCH_NAME_BATCH_15", + "value": "batch_15" + }, + { + "title": "EVENT_BATCH_NAME_BATCH_16", + "value": "batch_16" + }, + { + "title": "EVENT_BATCH_NAME_BATCH_17", + "value": "batch_17" + }, + { + "title": "EVENT_BATCH_NAME_BATCH_18", + "value": "batch_18" + }, + { + "title": "EVENT_BATCH_NAME_BATCH_19", + "value": "batch_19" + }, + { + "title": "EVENT_BATCH_NAME_BATCH_20", + "value": "batch_20" + } ] -} \ No newline at end of file +} diff --git a/src/src/events/events.service.ts b/src/src/events/events.service.ts index 8503c172b..eb2a6b0a5 100644 --- a/src/src/events/events.service.ts +++ b/src/src/events/events.service.ts @@ -94,48 +94,76 @@ export class EventsService { academic_year_id: academic_year_id, params: req.params, }; + let data = { + query: `query MyQuery { + events_aggregate(where: {start_date: {_gte: "${req.start_date}", _lte: "${req.start_date}"}, end_date: {_gte: "${req.end_date}", _lte: "${req.end_date}"}, program_id: {_eq: ${program_id}}, academic_year_id: {_eq: ${academic_year_id}}, master_trainer: {_eq: "${req.master_trainer}"}, start_time: {_eq: "${req.start_time}"}, type: {_eq: "${req.type}"}, user_id: {_eq: ${user_id}}, name: {_eq: "${req.name}"}}) { + aggregate { + count + } + } + } + `, + }; - const eventResult = await this.hasuraService.createWithVariable( - this.table, - obj, - this.returnFields, - [], - [{ key: 'params', type: 'json' }], - ); + const geteventData = await this.hasuraServiceFromServices.getData(data); - if (eventResult) { - const promises = []; - const query = []; - for (const iterator of user_id_arr) { - let obj = { - user_id: iterator, - created_by: user_id, - context_id: eventResult.events.id, - context: 'events', - updated_by: user_id, - }; - query.push(obj); - } - for (const iterator of query) { - promises.push( - this.hasuraService.create( - 'attendance', - iterator, - this.attendanceReturnFields, - ), - ); - } - const createAttendees = await Promise.all(promises); - let mappedData = createAttendees.map((data) => data.attendance); - if (createAttendees) { - return response.status(200).send({ - success: true, - message: 'Event created successfully!', - data: { - events: eventResult.events, - attendance: mappedData, - }, - }); + const count = geteventData?.data?.events_aggregate?.aggregate?.count; + + if (count > 0) { + return response.status(200).send({ + success: true, + message: 'Event Already created!', + data: {}, + }); + } else { + const eventResult = await this.hasuraService.createWithVariable( + this.table, + obj, + this.returnFields, + [], + [{ key: 'params', type: 'json' }], + ); + + if (eventResult) { + const promises = []; + const query = []; + for (const iterator of user_id_arr) { + let obj = { + user_id: iterator, + created_by: user_id, + context_id: eventResult.events.id, + context: 'events', + updated_by: user_id, + }; + query.push(obj); + } + for (const iterator of query) { + promises.push( + this.hasuraService.create( + 'attendance', + iterator, + this.attendanceReturnFields, + ), + ); + } + const createAttendees = await Promise.all(promises); + let mappedData = createAttendees.map((data) => data.attendance); + if (createAttendees) { + return response.status(200).send({ + success: true, + message: 'Event created successfully!', + data: { + events: eventResult.events, + attendance: mappedData, + }, + }); + } else { + return response.status(500).send({ + success: false, + message: 'Unable to create Event!', + data: {}, + }); + } } else { return response.status(500).send({ success: false, @@ -143,12 +171,6 @@ export class EventsService { data: {}, }); } - } else { - return response.status(500).send({ - success: false, - message: 'Unable to create Event!', - data: {}, - }); } } diff --git a/src/src/facilitator/facilitator.service.ts b/src/src/facilitator/facilitator.service.ts index a1b92a0de..200352dcc 100644 --- a/src/src/facilitator/facilitator.service.ts +++ b/src/src/facilitator/facilitator.service.ts @@ -74,13 +74,83 @@ export class FacilitatorService { body: any, response: any, ) { - const user = await this.userService.ipUserInfo(request); const program_id = request.mw_program_id; const academic_year_id = request.mw_academic_year_id; + const user = await this.userService.getIpRoleUserById( + request.mw_userid, + { program_id, academic_year_id }, + ); + const page = isNaN(body.page) ? 1 : parseInt(body.page); const limit = isNaN(body.limit) ? 15 : parseInt(body.limit); let skip = page > 1 ? limit * (page - 1) : 0; + let filterQueryArray = []; + + let status; + switch (body?.type) { + case 'pragati_orientation': { + status = `status: { _in: ["applied" ]}`; + break; + } + case 'gkp_training': { + status = `status: { _in: ["pragati_mobilizer" ]}`; + break; + } + case 'pcr_training': { + status = `status: { _in: ["pragati_mobilizer","selected_for_onboarding" ]}`; + break; + } + case 'main_camp_execution_training': { + status = `status: { _in: ["selected_for_onboarding" ]}`; + break; + } + case 'drip_training': { + status = `status: { _in: ["applied","pragati_mobilizer","selected_for_onboarding" ]}`; + break; + } + } + + filterQueryArray.push( + ` program_faciltators: { + parent_ip: { _eq: "${user?.program_users[0]?.organisation_id}" },academic_year_id:{_eq:${academic_year_id}},program_id:{_eq:${program_id}}, + ${status}}`, + ); + + if (body.search && body.search !== '') { + let first_name = body.search.split(' ')[0]; + let last_name = body.search.split(' ')[1] || ''; + + if (last_name?.length > 0) { + filterQueryArray.push(` + first_name: { _ilike: "%${first_name}%" }, + last_name: { _ilike: "%${last_name}%" } + `); + } else { + filterQueryArray.push( + `first_name: { _ilike: "%${first_name}%" }`, + ); + } + } + + if (body?.district && body?.district.length > 0) { + filterQueryArray.push( + `district:{_in: ${JSON.stringify(body?.district)}}`, + ); + } + + if (body?.block && body?.block.length > 0) { + filterQueryArray.push( + `block:{_in: ${JSON.stringify(body?.block)}}`, + ); + } + if (body?.village && body?.village.length > 0) { + filterQueryArray.push( + `village:{_in: ${JSON.stringify(body?.village)}}`, + ); + } + + let filterQuery = '' + filterQueryArray.join(',') + ''; const data = { query: ` @@ -89,10 +159,7 @@ export class FacilitatorService { where: { _and: [ { - program_faciltators: { - parent_ip: { _eq: "${user?.data?.program_users[0]?.organisation_id}" },academic_year_id:{_eq:${academic_year_id}},program_id:{_eq:${program_id}}, - status: { _eq: "shortlisted_for_orientation" } - } + ${filterQuery} }, { attendances_aggregate: { @@ -114,10 +181,7 @@ export class FacilitatorService { where: { _and: [ { - program_faciltators: { - parent_ip: { _eq: "${user?.data?.program_users[0]?.organisation_id}" },academic_year_id:{_eq:${academic_year_id}},program_id:{_eq:${program_id}}, - status: { _eq: "shortlisted_for_orientation" } - } + ${filterQuery} }, { attendances_aggregate: { diff --git a/src/src/user/user.service.ts b/src/src/user/user.service.ts index c538e4459..1adaa8585 100644 --- a/src/src/user/user.service.ts +++ b/src/src/user/user.service.ts @@ -280,10 +280,13 @@ export class UserService { }; } - public async getIpRoleUserById(id: any) { + public async getIpRoleUserById( + id: any, + filter: any = { program_id: 1, academic_year_id: 1 }, + ) { const data = await this.hasuraServiceFromServices.getOne(id, 'users', [ 'id', - 'program_users{organisation_id}', + `program_users(where:{program_id:{_eq:${filter?.program_id}}, academic_year_id:{_eq:${filter?.academic_year_id}}}){organisation_id program_id academic_year_id}`, 'first_name', ]); return data?.users; From 1864f22575359ba88298e66006142191615ab76b Mon Sep 17 00:00:00 2001 From: Tusharmahajan12 <121154132+Tusharmahajan12@users.noreply.github.com> Date: Thu, 22 Feb 2024 15:37:51 +0530 Subject: [PATCH 007/126] Task #213882 Removed 3 status of prerak (#795) * Removed 3 status of prerak * Removed 3 status of prerak --- src/src/enum/enum.json | 12 ------------ src/src/facilitator/facilitator.service.ts | 4 ++-- src/src/user/user.service.ts | 2 -- 3 files changed, 2 insertions(+), 16 deletions(-) diff --git a/src/src/enum/enum.json b/src/src/enum/enum.json index 376a5965b..c1fff87c7 100644 --- a/src/src/enum/enum.json +++ b/src/src/enum/enum.json @@ -154,22 +154,10 @@ "title": "FACILITATOR_STATUS_APPLIED", "value": "applied" }, - { - "title": "FACILITATOR_STATUS_APPLICATION_SCREENED", - "value": "application_screened" - }, - { - "title": "FACILITATOR_STATUS_SHORTLISTED_FOR_ORIENTATION", - "value": "shortlisted_for_orientation" - }, { "title": "FACILITATOR_STATUS_PRAGATI_MOBILIZER", "value": "pragati_mobilizer" }, - { - "title": "FACILITATOR_STATUS_SELECTED_FOR_TRAINING", - "value": "selected_for_training" - }, { "title": "FACILITATOR_STATUS_SELECTED_FOR_ONBOARDING", "value": "selected_for_onboarding" diff --git a/src/src/facilitator/facilitator.service.ts b/src/src/facilitator/facilitator.service.ts index b80a1944b..dfedf4f9a 100644 --- a/src/src/facilitator/facilitator.service.ts +++ b/src/src/facilitator/facilitator.service.ts @@ -91,7 +91,7 @@ export class FacilitatorService { { program_faciltators: { parent_ip: { _eq: "${user?.data?.program_users[0]?.organisation_id}" },academic_year_id:{_eq:${academic_year_id}},program_id:{_eq:${program_id}}, - status: { _eq: "shortlisted_for_orientation" } + status: { _eq: "applied" } } }, { @@ -116,7 +116,7 @@ export class FacilitatorService { { program_faciltators: { parent_ip: { _eq: "${user?.data?.program_users[0]?.organisation_id}" },academic_year_id:{_eq:${academic_year_id}},program_id:{_eq:${program_id}}, - status: { _eq: "shortlisted_for_orientation" } + status: { _eq: "applied" } } }, { diff --git a/src/src/user/user.service.ts b/src/src/user/user.service.ts index c538e4459..780d632b9 100644 --- a/src/src/user/user.service.ts +++ b/src/src/user/user.service.ts @@ -45,8 +45,6 @@ export class UserService { ); const oldStatus = user?.program_faciltators?.status; const statusArray = [ - 'shortlisted_for_orientation', - 'selected_for_training', 'pragati_mobilizer', 'selected_for_onboarding', 'selected_prerak', From e7c5c504b859883c9c9b1bab8327e6100edf2a41 Mon Sep 17 00:00:00 2001 From: Tusharmahajan12 <121154132+Tusharmahajan12@users.noreply.github.com> Date: Fri, 23 Feb 2024 10:47:23 +0530 Subject: [PATCH 008/126] Added event exam do_id by event type (#820) --- src/src/events/events.service.ts | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/src/src/events/events.service.ts b/src/src/events/events.service.ts index eb2a6b0a5..81bb6e503 100644 --- a/src/src/events/events.service.ts +++ b/src/src/events/events.service.ts @@ -74,6 +74,33 @@ export class EventsService { let academic_year_id = header?.mw_academic_year_id; const userDetail = await this.userService.ipUserInfo(header); let user_id = userDetail.data.id; + //get do_id for event exam master data + let eventExamData = { + query: `query MyQuery { + event_exams_master(where: {academic_year_id: {_eq: ${academic_year_id}}, program_id: {_eq: ${program_id}}, event_type: {_eq: "${req.type}"}}){ + id + do_id + event_type + } + }`, + }; + + const getExamId = await this.hasuraServiceFromServices.getData( + eventExamData, + ); + + let doIds = getExamId?.data?.event_exams_master?.map( + (exam) => exam.do_id, + ); + let paramId = null; + + if (doIds && doIds.length > 0) { + paramId = { + attendance_type: 'day', + do_id: doIds, + }; + } + let obj = { ...(req?.context_id && { context_id: req?.context_id }), ...(req?.context && { context: req?.context }), @@ -92,8 +119,9 @@ export class EventsService { reminders: JSON.stringify(req.reminders).replace(/"/g, '\\"'), program_id: program_id, academic_year_id: academic_year_id, - params: req.params, + params: paramId, //set params to null if no param id found in the database }; + //checking the event already created let data = { query: `query MyQuery { events_aggregate(where: {start_date: {_gte: "${req.start_date}", _lte: "${req.start_date}"}, end_date: {_gte: "${req.end_date}", _lte: "${req.end_date}"}, program_id: {_eq: ${program_id}}, academic_year_id: {_eq: ${academic_year_id}}, master_trainer: {_eq: "${req.master_trainer}"}, start_time: {_eq: "${req.start_time}"}, type: {_eq: "${req.type}"}, user_id: {_eq: ${user_id}}, name: {_eq: "${req.name}"}}) { @@ -108,7 +136,7 @@ export class EventsService { const geteventData = await this.hasuraServiceFromServices.getData(data); const count = geteventData?.data?.events_aggregate?.aggregate?.count; - + //if event created show this message if (count > 0) { return response.status(200).send({ success: true, From 41dfda2d15a1acba556081358caf78ff72ab47ac Mon Sep 17 00:00:00 2001 From: Tusharmahajan12 <121154132+Tusharmahajan12@users.noreply.github.com> Date: Fri, 23 Feb 2024 15:40:50 +0530 Subject: [PATCH 009/126] Task #213167 Made optional field in create event (#822) * Added event exam do_id by event type * Made optional field in create event * Made optional field in create event --- src/src/events/dto/create-event.dto.ts | 62 +++++++++++++------------- src/src/events/events.service.ts | 15 +++++-- 2 files changed, 41 insertions(+), 36 deletions(-) diff --git a/src/src/events/dto/create-event.dto.ts b/src/src/events/dto/create-event.dto.ts index c5054948e..32029bbfe 100644 --- a/src/src/events/dto/create-event.dto.ts +++ b/src/src/events/dto/create-event.dto.ts @@ -1,46 +1,44 @@ // src/articles/dto/create-article.dto.ts -import { IsArray, IsNotEmpty, IsString } from 'class-validator'; +import { IsArray, IsNotEmpty, IsOptional, IsString } from 'class-validator'; export class CreateEventDto { + @IsString() + @IsNotEmpty() + public start_date: string; - @IsString() - @IsNotEmpty() - public start_date: string; + @IsString() + @IsNotEmpty() + public name: string; - @IsString() - @IsNotEmpty() - public name: string; - - @IsString() - @IsNotEmpty() - public end_date: string; + @IsString() + @IsNotEmpty() + public end_date: string; - @IsString() - @IsNotEmpty() - public end_time: string; + @IsString() + @IsNotEmpty() + public end_time: string; - @IsString() - @IsNotEmpty() - public location: string; + @IsString() + @IsOptional() + public location: string; - @IsString() - @IsNotEmpty() - public location_type: string; + @IsString() + @IsOptional() + public location_type: string; - @IsString() - @IsNotEmpty() - public start_time: string; + @IsString() + @IsNotEmpty() + public start_time: string; - public created_by: string; + public created_by: string; - public updated_by: string; + public updated_by: string; - @IsString() - @IsNotEmpty() - public type: string; + @IsString() + @IsNotEmpty() + public type: string; - @IsArray() - @IsNotEmpty() - public reminders: []; - + @IsArray() + @IsOptional() + public reminders: []; } diff --git a/src/src/events/events.service.ts b/src/src/events/events.service.ts index 81bb6e503..f1cd5f1ef 100644 --- a/src/src/events/events.service.ts +++ b/src/src/events/events.service.ts @@ -100,6 +100,15 @@ export class EventsService { do_id: doIds, }; } + let optional = {}; + if (req?.location && req?.location_type && req?.reminders) { + optional['location'] = req.location; + optional['reminders'] = JSON.stringify(req.reminders).replace( + /"/g, + '\\"', + ); + optional['location_type'] = req.location_type; + } let obj = { ...(req?.context_id && { context_id: req?.context_id }), @@ -110,17 +119,16 @@ export class EventsService { created_by: user_id, end_date: req.end_date, end_time: req.end_time, - location: req.location, - location_type: req.location_type, start_date: req.start_date, start_time: req.start_time, updated_by: user_id, type: req.type, - reminders: JSON.stringify(req.reminders).replace(/"/g, '\\"'), program_id: program_id, academic_year_id: academic_year_id, params: paramId, //set params to null if no param id found in the database + ...optional, //set optional for remainders,location,location_type }; + //checking the event already created let data = { query: `query MyQuery { @@ -151,7 +159,6 @@ export class EventsService { [], [{ key: 'params', type: 'json' }], ); - if (eventResult) { const promises = []; const query = []; From cee59d7b9acf5e98256ae97e714591c4a15d0166 Mon Sep 17 00:00:00 2001 From: sagar takle Date: Fri, 23 Feb 2024 15:42:27 +0530 Subject: [PATCH 010/126] Merge `Release 1.7.6` into `Release 2.0.0` (#821) * Added event exam do_id by event type (#820) * Task #213167 Made optional field in create event (#822) * Added event exam do_id by event type * Made optional field in create event * Made optional field in create event --------- Co-authored-by: Tusharmahajan12 <121154132+Tusharmahajan12@users.noreply.github.com> --- src/src/events/dto/create-event.dto.ts | 62 +++++++++++++------------- src/src/events/events.service.ts | 47 ++++++++++++++++--- 2 files changed, 71 insertions(+), 38 deletions(-) diff --git a/src/src/events/dto/create-event.dto.ts b/src/src/events/dto/create-event.dto.ts index c5054948e..32029bbfe 100644 --- a/src/src/events/dto/create-event.dto.ts +++ b/src/src/events/dto/create-event.dto.ts @@ -1,46 +1,44 @@ // src/articles/dto/create-article.dto.ts -import { IsArray, IsNotEmpty, IsString } from 'class-validator'; +import { IsArray, IsNotEmpty, IsOptional, IsString } from 'class-validator'; export class CreateEventDto { + @IsString() + @IsNotEmpty() + public start_date: string; - @IsString() - @IsNotEmpty() - public start_date: string; + @IsString() + @IsNotEmpty() + public name: string; - @IsString() - @IsNotEmpty() - public name: string; - - @IsString() - @IsNotEmpty() - public end_date: string; + @IsString() + @IsNotEmpty() + public end_date: string; - @IsString() - @IsNotEmpty() - public end_time: string; + @IsString() + @IsNotEmpty() + public end_time: string; - @IsString() - @IsNotEmpty() - public location: string; + @IsString() + @IsOptional() + public location: string; - @IsString() - @IsNotEmpty() - public location_type: string; + @IsString() + @IsOptional() + public location_type: string; - @IsString() - @IsNotEmpty() - public start_time: string; + @IsString() + @IsNotEmpty() + public start_time: string; - public created_by: string; + public created_by: string; - public updated_by: string; + public updated_by: string; - @IsString() - @IsNotEmpty() - public type: string; + @IsString() + @IsNotEmpty() + public type: string; - @IsArray() - @IsNotEmpty() - public reminders: []; - + @IsArray() + @IsOptional() + public reminders: []; } diff --git a/src/src/events/events.service.ts b/src/src/events/events.service.ts index eb2a6b0a5..f1cd5f1ef 100644 --- a/src/src/events/events.service.ts +++ b/src/src/events/events.service.ts @@ -74,6 +74,42 @@ export class EventsService { let academic_year_id = header?.mw_academic_year_id; const userDetail = await this.userService.ipUserInfo(header); let user_id = userDetail.data.id; + //get do_id for event exam master data + let eventExamData = { + query: `query MyQuery { + event_exams_master(where: {academic_year_id: {_eq: ${academic_year_id}}, program_id: {_eq: ${program_id}}, event_type: {_eq: "${req.type}"}}){ + id + do_id + event_type + } + }`, + }; + + const getExamId = await this.hasuraServiceFromServices.getData( + eventExamData, + ); + + let doIds = getExamId?.data?.event_exams_master?.map( + (exam) => exam.do_id, + ); + let paramId = null; + + if (doIds && doIds.length > 0) { + paramId = { + attendance_type: 'day', + do_id: doIds, + }; + } + let optional = {}; + if (req?.location && req?.location_type && req?.reminders) { + optional['location'] = req.location; + optional['reminders'] = JSON.stringify(req.reminders).replace( + /"/g, + '\\"', + ); + optional['location_type'] = req.location_type; + } + let obj = { ...(req?.context_id && { context_id: req?.context_id }), ...(req?.context && { context: req?.context }), @@ -83,17 +119,17 @@ export class EventsService { created_by: user_id, end_date: req.end_date, end_time: req.end_time, - location: req.location, - location_type: req.location_type, start_date: req.start_date, start_time: req.start_time, updated_by: user_id, type: req.type, - reminders: JSON.stringify(req.reminders).replace(/"/g, '\\"'), program_id: program_id, academic_year_id: academic_year_id, - params: req.params, + params: paramId, //set params to null if no param id found in the database + ...optional, //set optional for remainders,location,location_type }; + + //checking the event already created let data = { query: `query MyQuery { events_aggregate(where: {start_date: {_gte: "${req.start_date}", _lte: "${req.start_date}"}, end_date: {_gte: "${req.end_date}", _lte: "${req.end_date}"}, program_id: {_eq: ${program_id}}, academic_year_id: {_eq: ${academic_year_id}}, master_trainer: {_eq: "${req.master_trainer}"}, start_time: {_eq: "${req.start_time}"}, type: {_eq: "${req.type}"}, user_id: {_eq: ${user_id}}, name: {_eq: "${req.name}"}}) { @@ -108,7 +144,7 @@ export class EventsService { const geteventData = await this.hasuraServiceFromServices.getData(data); const count = geteventData?.data?.events_aggregate?.aggregate?.count; - + //if event created show this message if (count > 0) { return response.status(200).send({ success: true, @@ -123,7 +159,6 @@ export class EventsService { [], [{ key: 'params', type: 'json' }], ); - if (eventResult) { const promises = []; const query = []; From 55112887d842b75d89d1af569b22ed5a68de2568 Mon Sep 17 00:00:00 2001 From: Tusharmahajan12 <121154132+Tusharmahajan12@users.noreply.github.com> Date: Mon, 26 Feb 2024 17:18:36 +0530 Subject: [PATCH 011/126] Task #213168 [BE] Batch name, event duration limit and participant 0 to 50 validation (#823) * Added validation in event creation * Added validation in event creation * Added validation in event creation * Added validation in event creation * Added validation in event creation * Added validation in event creation * Added validation in event creation --- src/src/events/events.service.ts | 23 ++++ src/src/facilitator/facilitator.service.ts | 146 +-------------------- 2 files changed, 25 insertions(+), 144 deletions(-) diff --git a/src/src/events/events.service.ts b/src/src/events/events.service.ts index f1cd5f1ef..f62dfc6a8 100644 --- a/src/src/events/events.service.ts +++ b/src/src/events/events.service.ts @@ -128,6 +128,29 @@ export class EventsService { params: paramId, //set params to null if no param id found in the database ...optional, //set optional for remainders,location,location_type }; + // Check duration + const daysDiff = moment(req.end_date).diff( + moment(req.start_date), + 'days', + ); + // Check if the number of attendees falls within the configured limits + let errorMessage = ''; + const numAttendees = req.attendees.length; + const minParticipants = 0; // Example: Minimum number of participants allowed + const maxParticipants = 50; // Example: Maximum number of participants allowed + + if (numAttendees < minParticipants || numAttendees > maxParticipants) { + errorMessage += `Number of attendees must be between ${minParticipants} and ${maxParticipants}`; + } else if (daysDiff < 1 || daysDiff > 5) { + errorMessage += 'Event duration must be between 1 and 5 days.'; + } + if (errorMessage) { + return response.status(200).send({ + success: false, + message: errorMessage, + data: {}, + }); + } //checking the event already created let data = { diff --git a/src/src/facilitator/facilitator.service.ts b/src/src/facilitator/facilitator.service.ts index 200352dcc..46333494a 100644 --- a/src/src/facilitator/facilitator.service.ts +++ b/src/src/facilitator/facilitator.service.ts @@ -161,14 +161,6 @@ export class FacilitatorService { { ${filterQuery} }, - { - attendances_aggregate: { - count: { - predicate: {_eq: 0}, - filter: {event: {type: {_eq: "${body.type}"}}} - } - } - } ] } ) { @@ -183,14 +175,6 @@ export class FacilitatorService { { ${filterQuery} }, - { - attendances_aggregate: { - count: { - predicate: {_eq: 0}, - filter: {event: {type: {_eq: "${body.type}"}}} - } - } - } ] }, limit: $limit, @@ -201,138 +185,18 @@ export class FacilitatorService { first_name middle_name last_name - dob - aadhar_token - address - block_id - block_village_id - created_by - district_id - email_id gender - lat - long mobile - state_id - updated_by - profile_url state district block village grampanchayat - program_users { - id - organisation_id - academic_year_id - program_id - role_id - status - user_id - } - core_faciltator { - created_by - device_ownership - device_type + program_faciltators(where:{academic_year_id:{_eq:${academic_year_id}},program_id:{_eq:${program_id}}}) { id - pan_no - refreere - sourcing_channel - updated_by - user_id - } - experience { - description - end_year - experience_in_years - institution - start_year - organization - role_title user_id - type - } - program_faciltators { - parent_ip - availability - has_social_work_exp - id - police_verification_done - program_id - social_background_verified_by_neighbours - user_id - village_knowledge_test status - form_step_number - created_by - updated_by - academic_year_id - } - qualifications { - created_by - end_year - id - institution - qualification_master_id - start_year - updated_by - user_id - qualification_master { - context - context_id - created_by - id - name - type - updated_by - } - } - interviews { - id - title - user_id - owner_user_id - date - start_time - end_time - interviewer_name - status - comment - reminder - rsvp - location_type - location - created_at - created_by - updated_at - updated_by - owner { - first_name - last_name - id - } - } - events { - context - context_id - created_by - end_date - end_time - id - location - location_type - start_date - start_time - updated_by - user_id - } - documents(order_by: {id: desc}){ - id - user_id - name - doument_type - document_sub_type - } + } } } `, @@ -346,12 +210,6 @@ export class FacilitatorService { let usersList = hasuraResponse?.data?.users; - usersList = usersList.map((obj) => { - obj.program_faciltators = obj.program_faciltators?.[0] || {}; - obj.qualifications = obj.qualifications?.[0] || {}; - return obj; - }); - const count = hasuraResponse?.data?.users_aggregate?.aggregate?.count || 0; From 9a4e11f4e98f36102c689f27c1705aaaf5c1f354 Mon Sep 17 00:00:00 2001 From: Tusharmahajan12 <121154132+Tusharmahajan12@users.noreply.github.com> Date: Tue, 27 Feb 2024 11:02:59 +0530 Subject: [PATCH 012/126] Task #213168 event Enum changes and status changes for event already created (#825) * Added validation in event creation * Added validation in event creation * Added validation in event creation * Added validation in event creation * Added validation in event creation * Added validation in event creation * Added validation in event creation * enum change for event * enum change for event * enum change for event * enum change for event * enum change for event * enum change for event * enum change for event --- src/src/events/events.service.ts | 33 ++++++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/src/src/events/events.service.ts b/src/src/events/events.service.ts index f62dfc6a8..8e8bc4325 100644 --- a/src/src/events/events.service.ts +++ b/src/src/events/events.service.ts @@ -133,21 +133,36 @@ export class EventsService { moment(req.start_date), 'days', ); + + const currentDate = moment(); // Current date + // Check if the number of attendees falls within the configured limits - let errorMessage = ''; + let errorMessage = {}; + const numAttendees = req.attendees.length; const minParticipants = 0; // Example: Minimum number of participants allowed const maxParticipants = 50; // Example: Maximum number of participants allowed if (numAttendees < minParticipants || numAttendees > maxParticipants) { - errorMessage += `Number of attendees must be between ${minParticipants} and ${maxParticipants}`; - } else if (daysDiff < 1 || daysDiff > 5) { - errorMessage += 'Event duration must be between 1 and 5 days.'; + errorMessage = { + key: 'participants_limit', + massage: `Number of attendees must be between ${minParticipants} and ${maxParticipants}`, + }; + } else if (moment(req.start_date)?.isBefore(currentDate, 'day')) { + errorMessage = { + key: 'back_date', + message: 'start date is before the current date', + }; + } else if (daysDiff < 0 || daysDiff > 5) { + errorMessage = { + key: 'event_days', + message: 'Event duration must be between 1 and 5 days.', + }; } if (errorMessage) { - return response.status(200).send({ + return response.status(422).send({ success: false, - message: errorMessage, + ...errorMessage, data: {}, }); } @@ -169,9 +184,10 @@ export class EventsService { const count = geteventData?.data?.events_aggregate?.aggregate?.count; //if event created show this message if (count > 0) { - return response.status(200).send({ - success: true, + return response.status(422).send({ + success: false, message: 'Event Already created!', + key: 'batch_name', data: {}, }); } else { @@ -678,6 +694,7 @@ export class EventsService { }); } } + async getParticipants(req, id, body, res) { const auth_users = await this.userService.ipUserInfo(req, 'staff'); From 2b2b12f7c6f29b452cb90c8a01742cee3c50f27f Mon Sep 17 00:00:00 2001 From: Tusharmahajan12 <121154132+Tusharmahajan12@users.noreply.github.com> Date: Tue, 27 Feb 2024 11:48:28 +0530 Subject: [PATCH 013/126] Task #213882 event enum changes (#826) * Added validation in event creation * Added validation in event creation * Added validation in event creation * Added validation in event creation * Added validation in event creation * Added validation in event creation * Added validation in event creation * enum change for event * enum change for event * enum change for event * enum change for event * enum change for event * enum change for event * enum change for event * enum change for event * enum change for event --- src/src/enum/enum.json | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/src/enum/enum.json b/src/src/enum/enum.json index e3f3a1fc2..85b21c1d3 100644 --- a/src/src/enum/enum.json +++ b/src/src/enum/enum.json @@ -425,8 +425,8 @@ ], "FACILITATOR_EVENT_TYPE": [ { - "title": "FACILITATOR_EVENT_TYPE_PRERAK_ORIENTATION", - "value": "prerak_orientation" + "title": "FACILITATOR_EVENT_TYPE_PRAGATI_ORIENTATION", + "value": "pragati_orientation" }, { "title": "FACILITATOR_EVENT_TYPE_GKP_TRAINING", @@ -1393,6 +1393,10 @@ { "title": "MISCELLANEOUS_ACTIVITIES_SCHOOL_TEACHER_VISIT", "value": "miscellaneous_activities_school_teacher_visit" + }, + { + "title": "MISCELLANEOUS_ACTIVITIES_E_PCP_ACTIVITIES", + "value": "miscellaneous_activities_e_pcp_activities" } ], "KIT_MATERIALS_CHECKLISTS": [ From cc0055460d097660f6b6ada331d2cffe68de7c96 Mon Sep 17 00:00:00 2001 From: Tusharmahajan12 <121154132+Tusharmahajan12@users.noreply.github.com> Date: Tue, 27 Feb 2024 14:49:20 +0530 Subject: [PATCH 014/126] Task #213177 Mark Attendance validation (#827) * Mark Attendance validation * Mark Attendance validation --- src/src/events/events.service.ts | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/src/events/events.service.ts b/src/src/events/events.service.ts index 8e8bc4325..2fa83b41b 100644 --- a/src/src/events/events.service.ts +++ b/src/src/events/events.service.ts @@ -579,6 +579,7 @@ export class EventsService { } public async updateAttendanceDetail(id: number, req: any, response: any) { + let attendance_id = id; const tableName = 'attendance'; if (req?.status == 'present') { let checkStringResult = this.checkStrings({}); @@ -592,6 +593,35 @@ export class EventsService { } } try { + const format = 'YYYY-MM-DD'; + const dateString = moment().startOf('day').format(format); + const currentTime = moment().format('HH:mm'); + + let data = { + query: `query MyQuery1 { + events_aggregate(where: {attendances: {id: {_eq: ${attendance_id}}}, start_date: {_lte: "${dateString}"}, end_date: {_gte: "${dateString}"}, start_time: {_lte: "${currentTime}"}, end_time: {_gte: "${currentTime}"}}) { + aggregate { + count + } + } + } + `, + }; + + const getAttendanceData = + await this.hasuraServiceFromServices.getData(data); + const count = + getAttendanceData?.data?.events_aggregate?.aggregate?.count; + + if (count === 0) { + return response.status(422).send({ + success: false, + message: + 'Attendance cannot be marked as today is not within the event date range.', + data: {}, + }); + } + let result = await this.hasuraService.update( +id, tableName, From 03c9bc9a805b250102a820a342fc0a78de3a33e4 Mon Sep 17 00:00:00 2001 From: Tusharmahajan12 <121154132+Tusharmahajan12@users.noreply.github.com> Date: Wed, 28 Feb 2024 11:56:28 +0530 Subject: [PATCH 015/126] event error solved (#832) --- src/src/events/events.service.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/src/events/events.service.ts b/src/src/events/events.service.ts index 2fa83b41b..3a1903e9d 100644 --- a/src/src/events/events.service.ts +++ b/src/src/events/events.service.ts @@ -159,7 +159,8 @@ export class EventsService { message: 'Event duration must be between 1 and 5 days.', }; } - if (errorMessage) { + + if (Object.keys(errorMessage).length) { return response.status(422).send({ success: false, ...errorMessage, From d3beac177bb7bb6086b6aa461f24f7815bbc9ebb Mon Sep 17 00:00:00 2001 From: GitVivekHub Date: Wed, 28 Feb 2024 17:34:51 +0530 Subject: [PATCH 016/126] Userinfo api offline version --- src/src/userauth/userauth.controller.ts | 9 ++ src/src/userauth/userauth.module.ts | 22 ++- src/src/userauth/userauth.service.ts | 207 +++++++++++++++++++++++- 3 files changed, 235 insertions(+), 3 deletions(-) diff --git a/src/src/userauth/userauth.controller.ts b/src/src/userauth/userauth.controller.ts index e3c88c0ce..10cf7a5d4 100644 --- a/src/src/userauth/userauth.controller.ts +++ b/src/src/userauth/userauth.controller.ts @@ -35,4 +35,13 @@ export class UserauthController { public async isUserExists(@Body() body: Body, @Res() response: Response) { return this.userauthService.isUserExists(body, response); } + + @Get('/user-info') + @UsePipes(ValidationPipe) + public async getUserInfoDetails( + @Res() response: Response, + @Req() request: Request, + ) { + return this.userauthService.getUserInfoDetails(request, response); + } } diff --git a/src/src/userauth/userauth.module.ts b/src/src/userauth/userauth.module.ts index 87e9209be..7c91dae01 100644 --- a/src/src/userauth/userauth.module.ts +++ b/src/src/userauth/userauth.module.ts @@ -1,4 +1,9 @@ -import { Module } from '@nestjs/common'; +import { + Module, + MiddlewareConsumer, + NestModule, + RequestMethod, +} from '@nestjs/common'; import { UserauthController } from './userauth.controller'; import { UserauthService } from './userauth.service'; import { HelperModule } from 'src/helper/helper.module'; @@ -9,6 +14,8 @@ import { UserModule } from 'src/user/user.module'; import { AuthService } from 'src/modules/auth/auth.service'; import { Method } from '../common/method/method'; import { AcknowledgementModule } from '../modules/acknowledgement/acknowledgement.module'; +import { CohortMiddleware } from 'src/common/middlewares/cohort.middleware'; +import { AuthMiddleware } from '../common/middlewares/auth.middleware'; @Module({ imports: [ @@ -23,4 +30,15 @@ import { AcknowledgementModule } from '../modules/acknowledgement/acknowledgemen providers: [UserauthService, AuthService, Method], exports: [UserauthService], }) -export class UserauthModule {} +export class UserauthModule implements NestModule { + configure(consumer: MiddlewareConsumer) { + consumer + .apply(AuthMiddleware) + .exclude('/userauth/register/:role', 'userauth/is-user-exists') + .forRoutes(UserauthController); + consumer + .apply(CohortMiddleware) + .exclude('/userauth/register/:role', 'userauth/is-user-exists') + .forRoutes(UserauthController); + } +} diff --git a/src/src/userauth/userauth.service.ts b/src/src/userauth/userauth.service.ts index c9bf1a7ba..6451f168a 100644 --- a/src/src/userauth/userauth.service.ts +++ b/src/src/userauth/userauth.service.ts @@ -55,7 +55,6 @@ export class UserauthService { (user) => user.program_faciltators.length > 0, ); - if (facilitator_data.length > 0) { return response.status(422).send({ success: false, @@ -335,4 +334,210 @@ export class UserauthService { }); } } + + public async getUserInfoDetails(request, response) { + let user_id = request.mw_userid; //get user id from token + let program_id = request?.mw_program_id; // get program_id from token + let academic_year_id = request?.mw_academic_year_id; // get academic_year_id from token + + //query to get user details information + + let query = `query MyQuery { + users_by_pk(id:${user_id}) { + first_name + middle_name + last_name + dob + mobile + alternative_mobile_number + email_id + district + block + grampanchayat + village + pincode + gender + profile_photo_1 + profile_photo_1_documents: documents(where: {document_sub_type: {_eq: "profile_photo_1"}}) { + name + doument_type + document_sub_type + document_id: id + path + } + profile_photo_2 + profile_photo_2_documents: documents(where: {document_sub_type: {_eq: "profile_photo_2"}}) { + name + doument_type + document_sub_type + document_id: id + path + } + profile_photo_3 + profile_photo_3_documents: documents(where: {document_sub_type: {_eq: "profile_photo_3"}}) { + name + doument_type + document_sub_type + document_id: id + path + } + core_faciltator { + device_type + device_ownership + has_diploma + diploma_details + } + extended_users { + marital_status + social_category + designation + } + references(where: {context: {_eq: "users"}}) { + name + designation + contact_number + context + } + program_faciltators(where: {academic_year_id: {_eq:${academic_year_id}}, program_id: {_eq:${program_id}}}) { + availability + qualification_ids + } + experience(where: {type: {_eq: "experience"}}) { + id + type + role_title + organization + description + experience_in_years + related_to_teaching + references(where: {context: {_eq: "experience"}}) { + name + contact_number + type_of_document + document_reference { + document_id: id + name + document_sub_type + doument_type + } + } + } + qualifications{ + qualification_master_id + qualification_reference_document_id + document_reference{ + document_id:id + name + path + } + } + } + } + `; + + const hasura_response = await this.hasuraServiceFromServices.getData({ + query: query, + }); + + let user_data = hasura_response?.data; + + // get profile photo document details + let profilePhoto1Documents = + user_data?.users_by_pk?.profile_photo_1_documents; + + let profilePhoto2Documents = + user_data?.users_by_pk?.profile_photo_2_documents; + + let profilePhoto3Documents = + user_data?.users_by_pk?.profile_photo_3_documents; + + // modifiy individual profile photo document details as required + + let profile_photo_1 = { + name: user_data?.users_by_pk?.profile_photo_1, + documents: { + base64: null, + document_id: profilePhoto1Documents?.[0].document_id, + name: profilePhoto1Documents?.[0].name, + document_type: profilePhoto1Documents?.[0].doument_type, + document_sub_type: + profilePhoto1Documents?.[0].document_sub_type, + }, + }; + + let profile_photo_2 = { + name: user_data?.users_by_pk?.profile_photo_1, + documents: { + base64: null, + document_id: profilePhoto2Documents?.[0].document_id, + name: profilePhoto2Documents?.[0].name, + document_type: profilePhoto2Documents?.[0].doument_type, + document_sub_type: + profilePhoto2Documents?.[0].document_sub_type, + }, + }; + + let profile_photo_3 = { + name: user_data?.users_by_pk?.profile_photo_1, + documents: { + base64: null, + document_id: profilePhoto3Documents?.[0].document_id, + name: profilePhoto3Documents?.[0].name, + document_type: profilePhoto3Documents?.[0].doument_type || null, + document_sub_type: + profilePhoto3Documents?.[0].document_sub_type, + }, + }; + + // Replacing profile_photo_documents with profile_photo for all details + user_data.users_by_pk.profile_photo_1 = profile_photo_1; + user_data.users_by_pk.profile_photo_2 = profile_photo_2; + user_data.users_by_pk.profile_photo_3 = profile_photo_3; + + // Removing profile_photo_documents object + delete user_data.users_by_pk.profile_photo_1_documents; + delete user_data.users_by_pk.profile_photo_2_documents; + delete user_data.users_by_pk.profile_photo_3_documents; + + // Iterate through the experience array and update references document_reference to documents + user_data?.users_by_pk?.experience.forEach((exp) => { + exp.references.forEach((ref) => { + ref.documents = ref.document_reference + ? { + base64: null, + document_id: ref?.document_reference?.document_id, + name: ref?.document_reference?.name, + document_sub_type: + ref?.document_reference?.document_sub_type, + document_type: + ref?.document_reference?.doument_type, + } + : {}; + delete ref.document_reference; // Remove document_reference + }); + }); + + user_data?.users_by_pk?.qualifications.forEach((q) => { + q.documents = q.document_reference + ? { + qualification_master_id: q?.qualification_master_id, + qualification_reference_document_id: + q?.qualification_reference_document_id, + documents: { + base64: q?.document_reference?.base64, + document_id: q?.document_reference?.document_id, + name: q?.document_reference?.name, + }, + } + : {}; + delete q.document_reference; // Remove document_reference + }); + + if (user_data) { + return response.status(200).json({ + message: 'Data retrieved successfully!', + data: { users: user_data?.users_by_pk }, + }); + } + } } From 6af31c36b3da6ceb35e18fed163bd368d5b32759 Mon Sep 17 00:00:00 2001 From: Tusharmahajan12 <121154132+Tusharmahajan12@users.noreply.github.com> Date: Thu, 29 Feb 2024 12:09:54 +0530 Subject: [PATCH 017/126] Task #213177 Validation for attendance marking under event date (#837) * event error solved * Validation for attendance marking under event date --- src/src/events/events.service.ts | 86 +++++++++++++++++++++++++++++++- 1 file changed, 85 insertions(+), 1 deletion(-) diff --git a/src/src/events/events.service.ts b/src/src/events/events.service.ts index 3a1903e9d..0723f393d 100644 --- a/src/src/events/events.service.ts +++ b/src/src/events/events.service.ts @@ -835,9 +835,93 @@ export class EventsService { public async createEventAttendance(body: any, req: any, res: any) { (body.status = body?.status || null), - (body.context = body?.context || 'events'), + (body.context = 'events'), (body.created_by = req?.mw_userid), (body.updated_by = req?.mw_userid); + const presentDate = body?.date_time; + //Taking event date and attendances count + let data = { + query: `query MyQuery { + events(where: {id: {_eq: ${body.context_id}}}){ + start_date + start_time + end_date + end_time + id + } + attendance_aggregate(where:{ + context_id:{_eq:${body?.context_id}}, + context:{_eq:${body.context}}, + date_time:{_gte:"${body?.date_time}",_lte:"${body?.date_time}"}, + user_id:{_eq:${body?.user_id}} + }){ + aggregate{ + count + } + } + } + `, + }; + + const getAttendanceData = await this.hasuraServiceFromServices.getData( + data, + ); + + let event = getAttendanceData?.data?.events?.[0]; + let count = + getAttendanceData?.data?.attendance_aggregate?.aggregate?.count; + //if attendances is present for that date + if (count > 0) { + return res.status(422).json({ + success: false, + message: 'Attendance allready marked for this date', + }); + } + + const format = 'YYYY-MM-DD HH:mm'; + const currentDate = moment(); + let errorMessage = {}; + const startDate = moment( + `${event?.start_date} ${event?.start_time}`, + format, + ); + + const endDate = moment(`${event?.end_date} ${event?.end_time}`, format); + + const newPresentDate = moment( + `${presentDate} ${moment().format('HH:mm')}`, + format, + ); + //current date is after start date of event and presnt date is after event start date + if ( + startDate.isSameOrAfter(currentDate) || + startDate.isSameOrAfter(newPresentDate) + ) { + errorMessage = { + key: 'date_time', + message: 'ATTENDANCE_FUTURE_DATE_ERROR_MESSAGE', + }; + } else if ( + endDate.isSameOrBefore(currentDate) || + endDate.isSameOrBefore(newPresentDate) + ) { + errorMessage = { + key: 'date_time', + message: 'ATTENDANCE_PAST_DATE_ERROR_MESSAGE', + }; + } else if (!newPresentDate.isSameOrBefore(currentDate)) { + errorMessage = { + key: 'date_time', + message: 'ATTENDANCE_FUTURE_DATE_ERROR_MESSAGE', + }; + } + + if (Object.keys(errorMessage).length > 0) { + return res.status(422).json({ + success: false, + ...errorMessage, + }); + } let response = await this.hasuraService.q( 'attendance', From 26d3263641a0aa260d3a6fbfa09895c2c8606c55 Mon Sep 17 00:00:00 2001 From: GitVivekHub Date: Mon, 4 Mar 2024 14:11:18 +0530 Subject: [PATCH 018/126] User info get api format changes --- src/src/userauth/userauth.controller.ts | 12 + src/src/userauth/userauth.service.ts | 317 +++++++++++++++++++++++- 2 files changed, 322 insertions(+), 7 deletions(-) diff --git a/src/src/userauth/userauth.controller.ts b/src/src/userauth/userauth.controller.ts index 10cf7a5d4..294d5c22b 100644 --- a/src/src/userauth/userauth.controller.ts +++ b/src/src/userauth/userauth.controller.ts @@ -14,6 +14,7 @@ import { Response, } from '@nestjs/common'; +import { AuthGuard } from 'src/modules/auth/auth.guard'; import { UserauthService } from './userauth.service'; @Controller('userauth') @@ -44,4 +45,15 @@ export class UserauthController { ) { return this.userauthService.getUserInfoDetails(request, response); } + + // @Post('/onboarding') + // @UsePipes(ValidationPipe) + // @UseGuards(new AuthGuard()) + // public async userOnboarding( + // @Body() body: Body, + // @Res() response: Response, + // @Req() request: Request, + // ) { + // return this.userauthService.userOnboarding(body, response, request); + // } } diff --git a/src/src/userauth/userauth.service.ts b/src/src/userauth/userauth.service.ts index 6451f168a..4e77719ba 100644 --- a/src/src/userauth/userauth.service.ts +++ b/src/src/userauth/userauth.service.ts @@ -453,7 +453,7 @@ export class UserauthService { // modifiy individual profile photo document details as required - let profile_photo_1 = { + let profile_photo_1_info = { name: user_data?.users_by_pk?.profile_photo_1, documents: { base64: null, @@ -465,7 +465,7 @@ export class UserauthService { }, }; - let profile_photo_2 = { + let profile_photo_2_info = { name: user_data?.users_by_pk?.profile_photo_1, documents: { base64: null, @@ -477,7 +477,7 @@ export class UserauthService { }, }; - let profile_photo_3 = { + let profile_photo_3_info = { name: user_data?.users_by_pk?.profile_photo_1, documents: { base64: null, @@ -490,9 +490,9 @@ export class UserauthService { }; // Replacing profile_photo_documents with profile_photo for all details - user_data.users_by_pk.profile_photo_1 = profile_photo_1; - user_data.users_by_pk.profile_photo_2 = profile_photo_2; - user_data.users_by_pk.profile_photo_3 = profile_photo_3; + user_data.users_by_pk.profile_photo_1 = profile_photo_1_info; + user_data.users_by_pk.profile_photo_2 = profile_photo_2_info; + user_data.users_by_pk.profile_photo_3 = profile_photo_3_info; // Removing profile_photo_documents object delete user_data.users_by_pk.profile_photo_1_documents; @@ -533,11 +533,314 @@ export class UserauthService { delete q.document_reference; // Remove document_reference }); + const { + first_name, + middle_name, + last_name, + dob, + mobile, + alternative_mobile_number, + email_id, + district, + block, + grampanchayat, + village, + pincode, + gender, + profile_photo_1, + profile_photo_2, + profile_photo_3, + } = user_data?.users_by_pk || {}; + + const formattedData = { + users: { + first_name, + middle_name, + last_name, + dob, + mobile, + alternative_mobile_number, + email_id, + district, + block, + grampanchayat, + village, + pincode, + gender, + profile_photo_1, + profile_photo_2, + profile_photo_3, + }, + core_faciltator: user_data?.users_by_pk?.core_faciltator, + extended_users: user_data?.users_by_pk?.extended_users, + references: user_data?.users_by_pk?.references, + program_faciltators: user_data?.users_by_pk?.program_faciltators, + experience: user_data?.users_by_pk?.experience, + qualifications: user_data?.users_by_pk?.qualifications, + }; + if (user_data) { return response.status(200).json({ message: 'Data retrieved successfully!', - data: { users: user_data?.users_by_pk }, + data: formattedData, }); } } + + // public async userOnboarding(body: any, response: any, request: any) { + // //first check validations for all inputs + + // let user_id = request?.mw_userid; + + // let result = await this.processTable(body, user_id); + + // if (result) { + // return response.status(200).json({ + // success: true, + // message: 'Successfully updated data', + // }); + // } + // } + // private async processTable(json: any, user_id: any) { + // let tableFields; + // let tableName; + // let set_update; + // let update_id; + + // for (const key in json) { + // const value = json[key]; + + // if (typeof value === 'object') { + // tableName = key; + // tableFields = Object.keys(value); + // } + + // if (Array.isArray(value)) { + // // Handle array + // tableName = key; + + // await this.processJsonArray(value, tableName, user_id); + // } + + // if (tableName != 'users' && tableName != 'references') { + // value.user_id = user_id; + // tableFields.push('user_id'); + // } + + // if (tableName == 'references') { + // value.context_id = user_id; + // tableFields.push('context_id'); + // } + + // let response = await this.findExisitingReccord( + // tableName, + // value, + // user_id, + // ); + + // set_update = response?.set_update; + // update_id = response?.id; + + // await this.upsertRecords( + // set_update, + // tableName, + // tableFields, + // value, + // user_id, + // update_id, + // ); + // } + + // return true; + // } + + // public async processJsonArray(values, tableName, user_id) { + // let set_update; + // let update_id; + // for (const obj of values) { + // const tableFields = Object.keys(obj); + // tableFields.push('user_id'); + // obj.user_id = user_id; + + // let response = await this.findExisitingReccord( + // tableName, + // obj, + // user_id, + // ); + // set_update = response?.set_update; + // update_id = response?.id; + + // await this.upsertRecords( + // set_update, + // tableName, + // tableFields, + // obj, + // user_id, + // update_id, + // ); + // } + // } + + // public async findExisitingReccord(tablename, value, user_id) { + // let query; + // let response; + + // switch (tablename) { + // case 'users': { + // query = `query MyQuery { + // users(where: {mobile: {_eq:${value.mobile}}}){ + // id, + // mobile + // } + // }`; + + // response = await this.hasuraServiceFromServices.getData({ + // query: query, + // }); + + // return { + // set_update: response?.data?.users?.length > 0 ? 1 : 0, + // id: response?.data?.users?.[0]?.id, + // }; + // } + // case 'core_faciltators': { + // query = `query MyQuery { + // core_faciltators(where: {user_id: {_eq:${user_id}}}){ + // id + // } + // } + // `; + // response = await this.hasuraServiceFromServices.getData({ + // query: query, + // }); + + // return { + // set_update: + // response?.data?.core_faciltators?.length > 0 ? 1 : 0, + // id: response?.data?.core_faciltators?.[0]?.id, + // }; + // } + // case 'extended_users': { + // query = `query MyQuery { + // extended_users(where: {user_id: {_eq:${user_id}}}){ + // id + // } + // } + + // `; + // response = await this.hasuraServiceFromServices.getData({ + // query: query, + // }); + + // return { + // set_update: + // response?.data?.extended_users?.length > 0 ? 1 : 0, + // id: response?.data?.extended_users?.[0]?.id, + // }; + // } + // case 'program_faciltators': { + // query = `query MyQuery { + // program_faciltators(where: {user_id: {_eq:${user_id}},program_id:{_eq:${value?.program_id}},academic_year_id:{_eq:${value?.academic_year_id}}}){ + // id + // } + // } + + // `; + // response = await this.hasuraServiceFromServices.getData({ + // query: query, + // }); + + // return { + // set_update: + // response?.data?.program_faciltators?.length > 0 ? 1 : 0, + // id: response?.data?.program_faciltators?.[0]?.id, + // }; + // } + // case 'references': { + // query = `query MyQuery { + // references(where: {contact_number: {_eq:${value?.contact_number}},context_id:{_eq:${user_id}}}){ + // id + // } + // } + + // `; + // response = await this.hasuraServiceFromServices.getData({ + // query: query, + // }); + + // return { + // set_update: response?.data?.references?.length > 0 ? 1 : 0, + // id: response?.data?.references?.[0]?.id, + // }; + // } + // case 'qualifications': { + // query = `query MyQuery { + // qualifications(where: {user_id: {_eq:${user_id}}}){ + // id + // } + // } + // `; + // response = await this.hasuraServiceFromServices.getData({ + // query: query, + // }); + + // return { + // set_update: + // response?.data?.qualifications?.length > 0 ? 1 : 0, + // id: response?.data?.qualifications?.[0]?.id, + // }; + // } + // case 'experience': { + // query = `query MyQuery { + // experience(where: {id: {_eq:${value?.id}}}){ + // id + // } + // } + // `; + // response = await this.hasuraServiceFromServices.getData({ + // query: query, + // }); + + // return { + // set_update: response?.data?.experience?.length > 0 ? 1 : 0, + // id: response?.data?.experience?.[0]?.id, + // }; + // } + + // default: + // return undefined; + // } + // } + + // public async upsertRecords( + // set_update, + // tableName, + // tableFields, + // value, + // user_id, + // id?, + // ) { + // if (set_update == 1 && id) { + // await this.hasuraService.q( + // tableName, + // { + // ...value, + // id: id, + // }, + // tableFields, + // true, + // [tableFields], + // ); + // } else { + // await this.hasuraService.q( + // tableName, + // { + // ...value, + // }, + // tableFields, + // false, + // [tableFields], + // ); + // } + // } } From 628963e15f64ff5f4f12bc28afc1a35c5dc5d493 Mon Sep 17 00:00:00 2001 From: Tusharmahajan12 <121154132+Tusharmahajan12@users.noreply.github.com> Date: Mon, 4 Mar 2024 18:00:25 +0530 Subject: [PATCH 019/126] Bug #214942 Remove all attendees from event (#843) * Remove all attendees from event * Remove all attendees from event --- src/src/events/events.service.ts | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/src/src/events/events.service.ts b/src/src/events/events.service.ts index 0723f393d..d5d8f322f 100644 --- a/src/src/events/events.service.ts +++ b/src/src/events/events.service.ts @@ -434,9 +434,9 @@ export class EventsService { public async update(id: number, header: any, req: any, resp: any) { try { const userDetail = await this.userService.ipUserInfo(header); - let user_id = userDetail.data.id; - let attendees = req.attendees; - if (attendees && attendees.length > 0) { + const user_id = userDetail.data.id; + const attendees = req.attendees; + if (attendees) { const data = { query: `query MyQuery { events(where: {id: {_eq: ${id}}}){ @@ -456,16 +456,15 @@ export class EventsService { data, ); let eventDetails = response?.data.events[0]; - let mappedData = response?.data.events.map( - (data) => data.attendances, - ); - if (response) { + if (eventDetails?.id) { + let mappedData = eventDetails?.attendances; //remove attendees in current event const deletePromise = []; - const deleteAttendees = mappedData[0].filter( - (data) => !req.attendees.includes(data.user_id), + const deleteAttendees = mappedData.filter( + (data) => !attendees.includes(data.user_id), ); if (deleteAttendees && deleteAttendees.length > 0) { + //remove for and add delete multiple query for (const iterator of deleteAttendees) { deletePromise.push( this.hasuraService.delete('attendance', { @@ -479,8 +478,8 @@ export class EventsService { } //add new attendees in current event - const tempArray = mappedData[0].map((data) => data.user_id); - const addAttendees = req.attendees.filter( + const tempArray = mappedData.map((data) => data.user_id); + const addAttendees = attendees.filter( (data) => !tempArray.includes(data), ); if (addAttendees && addAttendees.length > 0) { From 09d879272ed9150615bd6c3f4a3dc413827065c9 Mon Sep 17 00:00:00 2001 From: Tusharmahajan12 <121154132+Tusharmahajan12@users.noreply.github.com> Date: Mon, 4 Mar 2024 18:25:47 +0530 Subject: [PATCH 020/126] Task #214920 Ip list and cohort list API (#844) * Ip list and cohort list API * Ip list and cohort list API * Ip list and cohort list API --- src/src/user/user.controller.ts | 20 +++++++++ src/src/user/user.module.ts | 2 + src/src/user/user.service.ts | 79 +++++++++++++++++++++++++++++++++ 3 files changed, 101 insertions(+) diff --git a/src/src/user/user.controller.ts b/src/src/user/user.controller.ts index dc8a2299b..d68dac032 100755 --- a/src/src/user/user.controller.ts +++ b/src/src/user/user.controller.ts @@ -233,6 +233,26 @@ export class UserController { return this.userService.validateOnBoardingLink(body, request, response); } + //get IP list + @Post('/ip/list') + @UseGuards(new AuthGuard()) + getIpList( + @Body() request: Record, + @Req() req: any, + @Res() response: Response, + ) { + return this.userService.getIpList(request, req, response); + } + //get cohort list of ip + @Post('/cohort/ip_list') + @UseGuards(new AuthGuard()) + getCohortIpList( + @Body() request: Record, + @Req() req: any, + @Res() response: Response, + ) { + return this.userService.getCohortIpList(request, req, response); + } /**************************************************************************/ /******************************* V2 APIs **********************************/ /**************************************************************************/ diff --git a/src/src/user/user.module.ts b/src/src/user/user.module.ts index 02a172e7d..54a8711b0 100644 --- a/src/src/user/user.module.ts +++ b/src/src/user/user.module.ts @@ -41,6 +41,8 @@ export class UserModule implements NestModule { '/users/cohorts/my/:type', '/users/onboarding/validate', 'v2/users/is_user_exist/:role', + 'users/ip/list', + 'users/cohort/ip_list', ) .forRoutes(UserController); } diff --git a/src/src/user/user.service.ts b/src/src/user/user.service.ts index 323b034d3..7295ae1cc 100644 --- a/src/src/user/user.service.ts +++ b/src/src/user/user.service.ts @@ -1691,4 +1691,83 @@ export class UserService { return hasura_response; } + + //Get IP lIST + public async getIpList(body: any, req: any, resp: any) { + try { + let data = { + query: `query MyQuery { + organisations(order_by: {id: asc}) + { + id + name + } + } + `, + }; + const response = await this.hasuraServiceFromServices.getData(data); + + const organisations = response?.data?.organisations || []; + + return resp.status(200).send({ + success: true, + message: 'Organisation list found successfully', + data: organisations, + }); + } catch (error) { + // Log error and return a generic error response + console.error('Error fetching organizations:', error); + return resp.status(500).send({ + success: false, + message: 'An error occurred while fetching organizations', + data: {}, + }); + } + } + + //Get Cohort wise ip list + public async getCohortIpList(body: any, req: any, resp: any) { + const organisationId = body?.organisation_id; + if (!organisationId) { + return resp.status(422).send({ + success: false, + message: 'organisation_id is required', + data: {}, + }); + } + try { + let data = { + query: `query MyQuery { + program_organisation(where: {organisation_id: {_eq: ${organisationId}}}, order_by: {id: asc}) { + academic_year_id + program_id + organisation_id + academic_year { + name + } + program{ + name + } + } + } + `, + }; + const response = await this.hasuraServiceFromServices.getData(data); + + const list = response?.data?.program_organisation || []; + + return resp.status(200).send({ + success: true, + message: 'Academic Year Id and Program Id found successfully', + data: list, + }); + } catch (error) { + console.error('Error fetching cohort IP list:', error); + return resp.status(500).send({ + success: false, + message: 'An error occurred while fetching cohort IP list', + data: {}, + }); + } + } } From b5569cc8f8730b5002b27f174887cc5dfd527f84 Mon Sep 17 00:00:00 2001 From: GitVivekHub Date: Tue, 5 Mar 2024 11:03:13 +0530 Subject: [PATCH 021/126] User info end point changes --- src/src/userauth/userauth.controller.ts | 2 +- src/src/userauth/userauth.service.ts | 512 ++++++++++++------------ 2 files changed, 257 insertions(+), 257 deletions(-) diff --git a/src/src/userauth/userauth.controller.ts b/src/src/userauth/userauth.controller.ts index 294d5c22b..e22d4b313 100644 --- a/src/src/userauth/userauth.controller.ts +++ b/src/src/userauth/userauth.controller.ts @@ -37,7 +37,7 @@ export class UserauthController { return this.userauthService.isUserExists(body, response); } - @Get('/user-info') + @Get('/facilitator/user-info') @UsePipes(ValidationPipe) public async getUserInfoDetails( @Res() response: Response, diff --git a/src/src/userauth/userauth.service.ts b/src/src/userauth/userauth.service.ts index 4e77719ba..ba20348dc 100644 --- a/src/src/userauth/userauth.service.ts +++ b/src/src/userauth/userauth.service.ts @@ -587,260 +587,260 @@ export class UserauthService { } } - // public async userOnboarding(body: any, response: any, request: any) { - // //first check validations for all inputs - - // let user_id = request?.mw_userid; - - // let result = await this.processTable(body, user_id); - - // if (result) { - // return response.status(200).json({ - // success: true, - // message: 'Successfully updated data', - // }); - // } - // } - // private async processTable(json: any, user_id: any) { - // let tableFields; - // let tableName; - // let set_update; - // let update_id; - - // for (const key in json) { - // const value = json[key]; - - // if (typeof value === 'object') { - // tableName = key; - // tableFields = Object.keys(value); - // } - - // if (Array.isArray(value)) { - // // Handle array - // tableName = key; - - // await this.processJsonArray(value, tableName, user_id); - // } - - // if (tableName != 'users' && tableName != 'references') { - // value.user_id = user_id; - // tableFields.push('user_id'); - // } - - // if (tableName == 'references') { - // value.context_id = user_id; - // tableFields.push('context_id'); - // } - - // let response = await this.findExisitingReccord( - // tableName, - // value, - // user_id, - // ); - - // set_update = response?.set_update; - // update_id = response?.id; - - // await this.upsertRecords( - // set_update, - // tableName, - // tableFields, - // value, - // user_id, - // update_id, - // ); - // } - - // return true; - // } - - // public async processJsonArray(values, tableName, user_id) { - // let set_update; - // let update_id; - // for (const obj of values) { - // const tableFields = Object.keys(obj); - // tableFields.push('user_id'); - // obj.user_id = user_id; - - // let response = await this.findExisitingReccord( - // tableName, - // obj, - // user_id, - // ); - // set_update = response?.set_update; - // update_id = response?.id; - - // await this.upsertRecords( - // set_update, - // tableName, - // tableFields, - // obj, - // user_id, - // update_id, - // ); - // } - // } - - // public async findExisitingReccord(tablename, value, user_id) { - // let query; - // let response; - - // switch (tablename) { - // case 'users': { - // query = `query MyQuery { - // users(where: {mobile: {_eq:${value.mobile}}}){ - // id, - // mobile - // } - // }`; - - // response = await this.hasuraServiceFromServices.getData({ - // query: query, - // }); - - // return { - // set_update: response?.data?.users?.length > 0 ? 1 : 0, - // id: response?.data?.users?.[0]?.id, - // }; - // } - // case 'core_faciltators': { - // query = `query MyQuery { - // core_faciltators(where: {user_id: {_eq:${user_id}}}){ - // id - // } - // } - // `; - // response = await this.hasuraServiceFromServices.getData({ - // query: query, - // }); - - // return { - // set_update: - // response?.data?.core_faciltators?.length > 0 ? 1 : 0, - // id: response?.data?.core_faciltators?.[0]?.id, - // }; - // } - // case 'extended_users': { - // query = `query MyQuery { - // extended_users(where: {user_id: {_eq:${user_id}}}){ - // id - // } - // } - - // `; - // response = await this.hasuraServiceFromServices.getData({ - // query: query, - // }); - - // return { - // set_update: - // response?.data?.extended_users?.length > 0 ? 1 : 0, - // id: response?.data?.extended_users?.[0]?.id, - // }; - // } - // case 'program_faciltators': { - // query = `query MyQuery { - // program_faciltators(where: {user_id: {_eq:${user_id}},program_id:{_eq:${value?.program_id}},academic_year_id:{_eq:${value?.academic_year_id}}}){ - // id - // } - // } - - // `; - // response = await this.hasuraServiceFromServices.getData({ - // query: query, - // }); - - // return { - // set_update: - // response?.data?.program_faciltators?.length > 0 ? 1 : 0, - // id: response?.data?.program_faciltators?.[0]?.id, - // }; - // } - // case 'references': { - // query = `query MyQuery { - // references(where: {contact_number: {_eq:${value?.contact_number}},context_id:{_eq:${user_id}}}){ - // id - // } - // } - - // `; - // response = await this.hasuraServiceFromServices.getData({ - // query: query, - // }); - - // return { - // set_update: response?.data?.references?.length > 0 ? 1 : 0, - // id: response?.data?.references?.[0]?.id, - // }; - // } - // case 'qualifications': { - // query = `query MyQuery { - // qualifications(where: {user_id: {_eq:${user_id}}}){ - // id - // } - // } - // `; - // response = await this.hasuraServiceFromServices.getData({ - // query: query, - // }); - - // return { - // set_update: - // response?.data?.qualifications?.length > 0 ? 1 : 0, - // id: response?.data?.qualifications?.[0]?.id, - // }; - // } - // case 'experience': { - // query = `query MyQuery { - // experience(where: {id: {_eq:${value?.id}}}){ - // id - // } - // } - // `; - // response = await this.hasuraServiceFromServices.getData({ - // query: query, - // }); - - // return { - // set_update: response?.data?.experience?.length > 0 ? 1 : 0, - // id: response?.data?.experience?.[0]?.id, - // }; - // } - - // default: - // return undefined; - // } - // } - - // public async upsertRecords( - // set_update, - // tableName, - // tableFields, - // value, - // user_id, - // id?, - // ) { - // if (set_update == 1 && id) { - // await this.hasuraService.q( - // tableName, - // { - // ...value, - // id: id, - // }, - // tableFields, - // true, - // [tableFields], - // ); - // } else { - // await this.hasuraService.q( - // tableName, - // { - // ...value, - // }, - // tableFields, - // false, - // [tableFields], - // ); - // } - // } + public async userOnboarding(body: any, response: any, request: any) { + //first check validations for all inputs + + let user_id = request?.mw_userid; + + let result = await this.processTable(body, user_id); + + if (result) { + return response.status(200).json({ + success: true, + message: 'Successfully updated data', + }); + } + } + private async processTable(json: any, user_id: any) { + let tableFields; + let tableName; + let set_update; + let update_id; + + for (const key in json) { + const value = json[key]; + + if (typeof value === 'object') { + tableName = key; + tableFields = Object.keys(value); + } + + if (Array.isArray(value)) { + // Handle array + tableName = key; + + await this.processJsonArray(value, tableName, user_id); + } + + if (tableName != 'users' && tableName != 'references') { + value.user_id = user_id; + tableFields.push('user_id'); + } + + if (tableName == 'references') { + value.context_id = user_id; + tableFields.push('context_id'); + } + + let response = await this.findExisitingReccord( + tableName, + value, + user_id, + ); + + set_update = response?.set_update; + update_id = response?.id; + + await this.upsertRecords( + set_update, + tableName, + tableFields, + value, + user_id, + update_id, + ); + } + + return true; + } + + public async processJsonArray(values, tableName, user_id) { + let set_update; + let update_id; + for (const obj of values) { + const tableFields = Object.keys(obj); + tableFields.push('user_id'); + obj.user_id = user_id; + + let response = await this.findExisitingReccord( + tableName, + obj, + user_id, + ); + set_update = response?.set_update; + update_id = response?.id; + + await this.upsertRecords( + set_update, + tableName, + tableFields, + obj, + user_id, + update_id, + ); + } + } + + public async findExisitingReccord(tablename, value, user_id) { + let query; + let response; + + switch (tablename) { + case 'users': { + query = `query MyQuery { + users(where: {mobile: {_eq:${value.mobile}}}){ + id, + mobile + } + }`; + + response = await this.hasuraServiceFromServices.getData({ + query: query, + }); + + return { + set_update: response?.data?.users?.length > 0 ? 1 : 0, + id: response?.data?.users?.[0]?.id, + }; + } + case 'core_faciltators': { + query = `query MyQuery { + core_faciltators(where: {user_id: {_eq:${user_id}}}){ + id + } + } + `; + response = await this.hasuraServiceFromServices.getData({ + query: query, + }); + + return { + set_update: + response?.data?.core_faciltators?.length > 0 ? 1 : 0, + id: response?.data?.core_faciltators?.[0]?.id, + }; + } + case 'extended_users': { + query = `query MyQuery { + extended_users(where: {user_id: {_eq:${user_id}}}){ + id + } + } + + `; + response = await this.hasuraServiceFromServices.getData({ + query: query, + }); + + return { + set_update: + response?.data?.extended_users?.length > 0 ? 1 : 0, + id: response?.data?.extended_users?.[0]?.id, + }; + } + case 'program_faciltators': { + query = `query MyQuery { + program_faciltators(where: {user_id: {_eq:${user_id}},program_id:{_eq:${value?.program_id}},academic_year_id:{_eq:${value?.academic_year_id}}}){ + id + } + } + + `; + response = await this.hasuraServiceFromServices.getData({ + query: query, + }); + + return { + set_update: + response?.data?.program_faciltators?.length > 0 ? 1 : 0, + id: response?.data?.program_faciltators?.[0]?.id, + }; + } + case 'references': { + query = `query MyQuery { + references(where: {contact_number: {_eq:${value?.contact_number}},context_id:{_eq:${user_id}}}){ + id + } + } + + `; + response = await this.hasuraServiceFromServices.getData({ + query: query, + }); + + return { + set_update: response?.data?.references?.length > 0 ? 1 : 0, + id: response?.data?.references?.[0]?.id, + }; + } + case 'qualifications': { + query = `query MyQuery { + qualifications(where: {user_id: {_eq:${user_id}}}){ + id + } + } + `; + response = await this.hasuraServiceFromServices.getData({ + query: query, + }); + + return { + set_update: + response?.data?.qualifications?.length > 0 ? 1 : 0, + id: response?.data?.qualifications?.[0]?.id, + }; + } + case 'experience': { + query = `query MyQuery { + experience(where: {id: {_eq:${value?.id}}}){ + id + } + } + `; + response = await this.hasuraServiceFromServices.getData({ + query: query, + }); + + return { + set_update: response?.data?.experience?.length > 0 ? 1 : 0, + id: response?.data?.experience?.[0]?.id, + }; + } + + default: + return undefined; + } + } + + public async upsertRecords( + set_update, + tableName, + tableFields, + value, + user_id, + id?, + ) { + if (set_update == 1 && id) { + await this.hasuraService.q( + tableName, + { + ...value, + id: id, + }, + tableFields, + true, + [tableFields], + ); + } else { + await this.hasuraService.q( + tableName, + { + ...value, + }, + tableFields, + false, + [tableFields], + ); + } + } } From 07d320b3f04586249b165175f5b8e57128a27f49 Mon Sep 17 00:00:00 2001 From: Tusharmahajan12 <121154132+Tusharmahajan12@users.noreply.github.com> Date: Tue, 5 Mar 2024 14:07:41 +0530 Subject: [PATCH 022/126] Task #214384 Middle ware changes for PO user (#846) * Ip list and cohort list API * Ip list and cohort list API * Ip list and cohort list API * Middle ware changes for PO user --- src/src/common/method/method.ts | 8 +++++ src/src/common/middlewares/auth.middleware.ts | 31 ++++++++++++++----- .../common/middlewares/cohort.middleware.ts | 17 ++++++++++ src/src/user/user.service.ts | 24 ++++++++++++-- 4 files changed, 69 insertions(+), 11 deletions(-) diff --git a/src/src/common/method/method.ts b/src/src/common/method/method.ts index 38f42c640..05cd5f092 100644 --- a/src/src/common/method/method.ts +++ b/src/src/common/method/method.ts @@ -20,6 +20,10 @@ export class Method { } public async isUserHasAccessForProgram(req: any) { + // if role is program_owner pass this access + if (req.mw_roles.includes('program_owner')) { + return true; + } // Set a table name let tableName; if (req.mw_roles.includes('staff')) { @@ -64,6 +68,10 @@ export class Method { } public async isUserHasAccessForAcademicYearId(req: any) { + // if role is program_owner pass this access + if (req.mw_roles.includes('program_owner')) { + return true; + } // Set a table name let tableName; if (req.mw_roles.includes('staff')) { diff --git a/src/src/common/middlewares/auth.middleware.ts b/src/src/common/middlewares/auth.middleware.ts index ca022fd8d..73b936f7b 100644 --- a/src/src/common/middlewares/auth.middleware.ts +++ b/src/src/common/middlewares/auth.middleware.ts @@ -6,6 +6,7 @@ import jwt_decode from 'jwt-decode'; @Injectable() export class AuthMiddleware implements NestMiddleware { constructor(private userService: UserService) {} + async use(req: any, res: Response, next: NextFunction) { req.mw_roles = []; req.mw_userid = null; @@ -47,16 +48,30 @@ export class AuthMiddleware implements NestMiddleware { try { const decoded: any = jwt_decode(authToken); let keycloak_id = decoded.sub; + let userId; - // const user = await this.userService.ipUserInfo(req); - const userId = await this.userService.getUserIdFromKeycloakId( - keycloak_id, - ); - - req.mw_userid = userId; - + const roles = decoded.resource_access.hasura.roles || []; + //check if role is program_owner set x-ip-org-id in userId + if (roles.includes('program_owner')) { + if (req?.headers && req?.headers?.['x-ip-org-id']) { + userId = req.headers['x-ip-org-id']; + const result = await this.userService.getIPuser( + req, + res, + ); + const data = result?.data?.program_users?.[0]; + req.mw_userid = data?.user_id; + } + req.mw_roles = roles; //pass role if x-ip-org-id is not send + } else { + // const user = await this.userService.ipUserInfo(req); + userId = await this.userService.getUserIdFromKeycloakId( + keycloak_id, + ); + req.mw_userid = userId; + } if (userId) { - req.mw_roles = decoded.resource_access.hasura.roles || []; + req.mw_roles = roles; } } catch (error) { req.mw_userid = null; diff --git a/src/src/common/middlewares/cohort.middleware.ts b/src/src/common/middlewares/cohort.middleware.ts index f18c9d8bf..eff33a6ca 100644 --- a/src/src/common/middlewares/cohort.middleware.ts +++ b/src/src/common/middlewares/cohort.middleware.ts @@ -11,6 +11,23 @@ export class CohortMiddleware implements NestMiddleware { constructor(private method: Method) {} async use(req: any, res: Response, next: () => void) { let goToNextMw = false; + //check IP User ID is present or not [x-ip-user-id] + if ( + (req?.headers && req?.headers?.['x-ip-org-id']) || + req?.mw_roles?.includes('program_owner') + ) { + req.mw_ip_user_id = req.headers['x-ip-org-id']; + + const ip_user_id = parseInt(req.mw_ip_user_id, 10); + if (isNaN(ip_user_id)) { + return res.json({ + success: false, + message: `${ + req.mw_ip_user_id ? 'Invalid' : 'Required' + } Ip org Id`, + }); + } + } if (req?.headers && req?.headers?.['x-program-id']) { req.mw_program_id = req.headers['x-program-id']; diff --git a/src/src/user/user.service.ts b/src/src/user/user.service.ts index 7295ae1cc..72ef34a57 100644 --- a/src/src/user/user.service.ts +++ b/src/src/user/user.service.ts @@ -1476,7 +1476,7 @@ export class UserService { let cohort_academic_year_id; if (cohort_type == 'academic_year') { - if (role.includes('staff')) { + if (role.includes('staff') || role.includes('program_owner')) { const user = await this.ipUserInfo(req); if (!user?.data?.program_users?.[0]?.organisation_id) { return res.status(404).send({ @@ -1513,7 +1513,7 @@ export class UserService { } if (cohort_type == 'program') { - if (role.includes('staff')) { + if (role.includes('staff') || role.includes('program_owner')) { const user = await this.ipUserInfo(req); if (!user?.data?.program_users?.[0]?.organisation_id) { return res.status(404).send({ @@ -1543,7 +1543,7 @@ export class UserService { )?.result; } if (cohort_type == 'program_academic_year_id') { - if (role.includes('staff')) { + if (role.includes('staff') || role.includes('program_owner')) { const user = await this.ipUserInfo(req); if (!user?.data?.program_users?.[0]?.organisation_id) { return res.status(404).send({ @@ -1770,4 +1770,22 @@ export class UserService { }); } } + + //get Ip-user user_id from organisation + public async getIPuser(req: any, res: any) { + let org_id = req.headers['x-ip-org-id']; + let data; + let tableName = 'program_users'; + data = { + query: `query MyQuery { + ${tableName}(where: {program_id: {_eq: ${req.mw_program_id}},academic_year_id: {_eq: ${req.mw_academic_year_id}},organisation_id:{_eq:${org_id}}, program_organisation: {status: {_eq: "active"}}}){ + id + user_id + } + }`, + }; + + const result = await this.hasuraServiceFromServices.getData(data); + return result; + } } From 40ab9c3bc9e8a5d8732db650d1366fb04577d6a4 Mon Sep 17 00:00:00 2001 From: Tusharmahajan12 <121154132+Tusharmahajan12@users.noreply.github.com> Date: Tue, 5 Mar 2024 15:52:46 +0530 Subject: [PATCH 023/126] Task #214384 middle ware changes for IPUserInfo api (#848) * Ip list and cohort list API * Ip list and cohort list API * Ip list and cohort list API * Middle ware changes for PO user * middle ware changes for IPUserInfo api * middle ware changes for IPUserInfo api --- src/src/common/middlewares/auth.middleware.ts | 6 ++++++ src/src/user/user.service.ts | 1 - 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/src/common/middlewares/auth.middleware.ts b/src/src/common/middlewares/auth.middleware.ts index 73b936f7b..c11a768e2 100644 --- a/src/src/common/middlewares/auth.middleware.ts +++ b/src/src/common/middlewares/auth.middleware.ts @@ -61,6 +61,12 @@ export class AuthMiddleware implements NestMiddleware { ); const data = result?.data?.program_users?.[0]; req.mw_userid = data?.user_id; + } else if (['/users/ip_user_info'].includes(req.baseUrl)) { + // const user = await this.userService.ipUserInfo(req); + userId = await this.userService.getUserIdFromKeycloakId( + keycloak_id, + ); + req.mw_userid = userId; } req.mw_roles = roles; //pass role if x-ip-org-id is not send } else { diff --git a/src/src/user/user.service.ts b/src/src/user/user.service.ts index 72ef34a57..292de7dc5 100644 --- a/src/src/user/user.service.ts +++ b/src/src/user/user.service.ts @@ -256,7 +256,6 @@ export class UserService { public async ipUserInfo(request: any, res?, role: any = '') { let userData = null; - if (request.mw_userid) { if (role === 'staff') { userData = await this.getIpRoleUserById(request.mw_userid); From df47a23bb55c2a52efafd13ba077c0241182b64c Mon Sep 17 00:00:00 2001 From: Tusharmahajan12 <121154132+Tusharmahajan12@users.noreply.github.com> Date: Wed, 6 Mar 2024 10:44:40 +0530 Subject: [PATCH 024/126] changes in PO API (#851) --- src/src/user/user.service.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/src/user/user.service.ts b/src/src/user/user.service.ts index 292de7dc5..a4a0bdedf 100644 --- a/src/src/user/user.service.ts +++ b/src/src/user/user.service.ts @@ -1773,11 +1773,13 @@ export class UserService { //get Ip-user user_id from organisation public async getIPuser(req: any, res: any) { let org_id = req.headers['x-ip-org-id']; - let data; + let mw_program_id = req.headers['x-program-id']; + let mw_academic_year_id = req.headers['x-academic-year-id']; let tableName = 'program_users'; - data = { + + const data = { query: `query MyQuery { - ${tableName}(where: {program_id: {_eq: ${req.mw_program_id}},academic_year_id: {_eq: ${req.mw_academic_year_id}},organisation_id:{_eq:${org_id}}, program_organisation: {status: {_eq: "active"}}}){ + ${tableName}(where: {program_id: {_eq: ${mw_program_id}},academic_year_id: {_eq: ${mw_academic_year_id}},organisation_id:{_eq:${org_id}}, program_organisation: {status: {_eq: "active"}}}){ id user_id } From 96051edd0e0b549c962be8781d32a702b8eb63e9 Mon Sep 17 00:00:00 2001 From: Tusharmahajan12 <121154132+Tusharmahajan12@users.noreply.github.com> Date: Wed, 6 Mar 2024 12:13:38 +0530 Subject: [PATCH 025/126] Task #214920 Added State name in Cohort Ip list (#853) * changes in PO API * Added State name in Cohort Ip list --- src/src/user/user.service.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/src/user/user.service.ts b/src/src/user/user.service.ts index a4a0bdedf..1bcd81a81 100644 --- a/src/src/user/user.service.ts +++ b/src/src/user/user.service.ts @@ -1746,6 +1746,10 @@ export class UserService { } program{ name + state_id + state{ + state_name + } } } } From 62292eadfd7933c2f99fdbbd359feee67c211796 Mon Sep 17 00:00:00 2001 From: GitVivekHub Date: Wed, 6 Mar 2024 12:39:59 +0530 Subject: [PATCH 026/126] latest commit --- src/src/userauth/userauth.controller.ts | 20 ++-- src/src/userauth/userauth.service.ts | 137 ++++++++++++++++++++---- 2 files changed, 129 insertions(+), 28 deletions(-) diff --git a/src/src/userauth/userauth.controller.ts b/src/src/userauth/userauth.controller.ts index e22d4b313..227e73322 100644 --- a/src/src/userauth/userauth.controller.ts +++ b/src/src/userauth/userauth.controller.ts @@ -46,14 +46,14 @@ export class UserauthController { return this.userauthService.getUserInfoDetails(request, response); } - // @Post('/onboarding') - // @UsePipes(ValidationPipe) - // @UseGuards(new AuthGuard()) - // public async userOnboarding( - // @Body() body: Body, - // @Res() response: Response, - // @Req() request: Request, - // ) { - // return this.userauthService.userOnboarding(body, response, request); - // } + @Post('/onboarding') + @UsePipes(ValidationPipe) + @UseGuards(new AuthGuard()) + public async userOnboarding( + @Body() body: Body, + @Res() response: Response, + @Req() request: Request, + ) { + return this.userauthService.userOnboarding(body, response, request); + } } diff --git a/src/src/userauth/userauth.service.ts b/src/src/userauth/userauth.service.ts index ba20348dc..ba2bbbeef 100644 --- a/src/src/userauth/userauth.service.ts +++ b/src/src/userauth/userauth.service.ts @@ -500,9 +500,9 @@ export class UserauthService { delete user_data.users_by_pk.profile_photo_3_documents; // Iterate through the experience array and update references document_reference to documents - user_data?.users_by_pk?.experience.forEach((exp) => { - exp.references.forEach((ref) => { - ref.documents = ref.document_reference + user_data?.users_by_pk?.experience?.forEach((exp) => { + exp.references = exp?.references?.reduce((acc, ref) => { + const documents = ref?.document_reference ? { base64: null, document_id: ref?.document_reference?.document_id, @@ -513,25 +513,27 @@ export class UserauthService { ref?.document_reference?.doument_type, } : {}; - delete ref.document_reference; // Remove document_reference - }); + + delete ref?.document_reference; // Remove document_reference + + return { ...acc, ...ref, documents }; + }, {}); }); - user_data?.users_by_pk?.qualifications.forEach((q) => { - q.documents = q.document_reference - ? { - qualification_master_id: q?.qualification_master_id, - qualification_reference_document_id: - q?.qualification_reference_document_id, - documents: { + user_data.users_by_pk.qualifications = + user_data?.users_by_pk?.qualifications.reduce((acc, q) => { + const documents = q.document_reference + ? { base64: q?.document_reference?.base64, document_id: q?.document_reference?.document_id, name: q?.document_reference?.name, - }, - } - : {}; - delete q.document_reference; // Remove document_reference - }); + } + : {}; + + delete q.document_reference; // Remove document_reference + + return { ...acc, ...q, documents }; + }, {}); const { first_name, @@ -606,6 +608,19 @@ export class UserauthService { let tableName; let set_update; let update_id; + let profile_photo_fields_1; + let documents_fields_1; + let profile_photo_fields_2; + let documents_fields_2; + let profile_photo_fields_3; + let documents_fields_3; + let profile_photo_1_value; + let documents_values_1; + let profile_photo_2_value; + let documents_values_2; + let profile_photo_3_value; + let documents_values_3; + let profile_documents_array = []; for (const key in json) { const value = json[key]; @@ -613,6 +628,67 @@ export class UserauthService { if (typeof value === 'object') { tableName = key; tableFields = Object.keys(value); + for (const subKey in value) { + const subValue = value[subKey]; + + if (typeof subValue === 'object') { + // Separate the subobjects of profile_photo_1 and documents + if (subKey === 'profile_photo_1') { + profile_photo_1_value = Object.values(subValue); + + documents_values_1 = Object.values( + subValue.documents, + ); + + profile_documents_array.push({ + document_id: documents_values_1?.[1], + name: documents_values_1?.[2], + doument_type: documents_values_1?.[3], + document_sub_type: documents_values_1?.[4], + }); + + // Add profile_photo_1 with its name value for inserting in users table + value['profile_photo_1'] = + profile_photo_1_value?.[0]; + } + if (subKey === 'profile_photo_2') { + profile_photo_2_value = Object.values(subValue); + + documents_values_2 = Object.values( + subValue.documents, + ); + + profile_documents_array.push({ + document_id: documents_values_2?.[1], + name: documents_values_2?.[2], + doument_type: documents_values_2?.[3], + document_sub_type: documents_values_2?.[4], + }); + + // Add profile_photo_2 with its name value for inserting in users table + value['profile_photo_2'] = + profile_photo_2_value?.[0]; + } + if (subKey === 'profile_photo_3') { + profile_photo_3_value = Object.values(subValue); + + documents_values_3 = Object.values( + subValue.documents, + ); + + profile_documents_array.push({ + document_id: documents_values_3?.[1], + name: documents_values_3?.[2], + doument_type: documents_values_3?.[3], + document_sub_type: documents_values_3?.[4], + }); + + // Add profile_photo_3 with its name value for inserting in users table + value['profile_photo_3'] = + profile_photo_3_value?.[0]; + } + } + } } if (Array.isArray(value)) { @@ -641,6 +717,8 @@ export class UserauthService { set_update = response?.set_update; update_id = response?.id; + console.log('update-->>', set_update, update_id); + await this.upsertRecords( set_update, tableName, @@ -649,6 +727,10 @@ export class UserauthService { user_id, update_id, ); + + if (tableName == 'users' && profile_documents_array?.length > 0) { + await this.upsertProfileDocuments(profile_documents_array); + } } return true; @@ -821,7 +903,7 @@ export class UserauthService { id?, ) { if (set_update == 1 && id) { - await this.hasuraService.q( + let result = await this.hasuraService.q( tableName, { ...value, @@ -831,6 +913,8 @@ export class UserauthService { true, [tableFields], ); + + console.log('result-->>', result); } else { await this.hasuraService.q( tableName, @@ -843,4 +927,21 @@ export class UserauthService { ); } } + + public async upsertProfileDocuments(profileDocumentArray) { + for (const profileDocument of profileDocumentArray) { + let result = await this.hasuraService.q( + 'documents', + { + ...profileDocument, + id: profileDocument.document_id, + }, + ['name', 'document_sub_type', 'doument_type', 'id'], + true, + ['name', 'document_sub_type', 'doument_type', 'id'], + ); + + console.log('resuklt-->>', result); + } + } } From 8cc26900e6de7b87291f5bd763837762f701a13e Mon Sep 17 00:00:00 2001 From: Rushi G Date: Wed, 6 Mar 2024 15:04:24 +0530 Subject: [PATCH 027/126] cron job fix --- src/src/cron/faAttendanceProcessing.cron.ts | 100 ++++++++++-------- .../aws-rekognition.service.ts | 12 ++- 2 files changed, 62 insertions(+), 50 deletions(-) diff --git a/src/src/cron/faAttendanceProcessing.cron.ts b/src/src/cron/faAttendanceProcessing.cron.ts index 28cc78605..19f2cb9b6 100644 --- a/src/src/cron/faAttendanceProcessing.cron.ts +++ b/src/src/cron/faAttendanceProcessing.cron.ts @@ -1,6 +1,6 @@ import { Injectable } from '@nestjs/common'; import { ConfigService } from '@nestjs/config'; -import { Cron } from '@nestjs/schedule'; +import { Cron, CronExpression } from '@nestjs/schedule'; import { AwsRekognitionService } from '../services/aws-rekognition/aws-rekognition.service'; import { HasuraService } from '../services/hasura/hasura.service'; @@ -20,7 +20,7 @@ export class FaAttendanceProcessingCron { //3rd cron runs for each hour's 25th minute eg: 10:25am, 11::25am @Cron('25 * * * *') - async markAttendanceCron() { + async markAttendanceCron() { try { /*----------------------- Mark attendance of from face index of users in collection -----------------------*/ console.log( @@ -41,7 +41,7 @@ export class FaAttendanceProcessingCron { //console.dir(usersForAttendance, { depth: 99 }); // Step-2 Iterate thorugh them for (const user of usersForAttendance) { - const userId = String(user.id); + const userId = String(user.id); // Iterate through attendance documents and mark attendance for (const attendanceObj of user.attendances) { if ( @@ -62,50 +62,56 @@ export class FaAttendanceProcessingCron { ); //console.log('matchedUser', matchedUser); // Check if the user matched - let matchingPercentage = null; - const isMatchFound = (matchedUser as any[]).some( - (obj) => { - //console.log('obj', obj); - if ( - obj?.User?.UserId.replace( - this.prefixed, - '', - ) === userId - ) { - matchingPercentage = obj.Similarity; - return true; - } - }, - ); - //console.log('matchingPercentage', matchingPercentage); - // Set attendance verified as true or false based on results - let isAttendanceVerified = false; - if (isMatchFound) isAttendanceVerified = true; - /*console.log( - '-------------------------------------------------------------------------', - ); - console.log( - `------------------------------ Verified: ${isMatchFound} ----------------------------`, - ); - console.log( - '-------------------------------------------------------------------------', - );*/ - // Update in attendance data in database - await this.markAttendance(attendanceObj.id, { - isAttendanceVerified, - matchingPercentage, - }); - // Set delay between two attendance process - await new Promise((resolve, reject) => - setTimeout( - resolve, - parseInt( - this.configService.get( - 'AWS_REKOGNITION_MARK_ATTENDANCE_PROCESS_INTERVAL_TIME', + if (matchedUser === false) { + console.log( + '------------------------------ Verified: ProvisionedThroughputExceededException', + ); + } else { + let matchingPercentage = null; + const isMatchFound = (matchedUser as any[]).some( + (obj) => { + //console.log('obj', obj); + if ( + obj?.User?.UserId.replace( + this.prefixed, + '', + ) === userId + ) { + matchingPercentage = obj.Similarity; + return true; + } + }, + ); + //console.log('matchingPercentage', matchingPercentage); + // Set attendance verified as true or false based on results + let isAttendanceVerified = false; + if (isMatchFound) isAttendanceVerified = true; + /*console.log( + '-------------------------------------------------------------------------', + ); + console.log( + `------------------------------ Verified: ${isMatchFound} ----------------------------`, + ); + console.log( + '-------------------------------------------------------------------------', + );*/ + // Update in attendance data in database + await this.markAttendance(attendanceObj.id, { + isAttendanceVerified, + matchingPercentage, + }); + // Set delay between two attendance process + await new Promise((resolve, reject) => + setTimeout( + resolve, + parseInt( + this.configService.get( + 'AWS_REKOGNITION_MARK_ATTENDANCE_PROCESS_INTERVAL_TIME', + ), ), ), - ), - ); + ); + } } else { // Update in attendance data in database await this.markProcessed(attendanceObj.id); @@ -191,14 +197,14 @@ export class FaAttendanceProcessingCron { _and: [ { fa_user_indexed: {_eq: true} }, { attendances_aggregate: {count: {predicate: {_gt: 0}}} }, - { attendances: { fa_is_processed: {_is_null: true} } }, + { attendances: { fa_is_processed: {_is_null: true}, photo_1: {_is_null: false,_neq: "-"} } }, ] }, limit: ${limit} ) { id attendances ( where: { - fa_is_processed: {_is_null: true}, + fa_is_processed: {_is_null: true}, photo_1: {_is_null: false,_neq: "-"}, }) { id photo_1 diff --git a/src/src/services/aws-rekognition/aws-rekognition.service.ts b/src/src/services/aws-rekognition/aws-rekognition.service.ts index 7d8dbaa66..eb0fe653c 100644 --- a/src/src/services/aws-rekognition/aws-rekognition.service.ts +++ b/src/src/services/aws-rekognition/aws-rekognition.service.ts @@ -251,7 +251,7 @@ export class AwsRekognitionService { Image: { S3Object: { Bucket: this.bucketName, - Name: modifiedImageName, + Name: originalImageName, }, }, ExternalImageId: modifiedImageName, @@ -345,8 +345,14 @@ export class AwsRekognitionService { //console.dir(compareResponse, { depth: 99 }); return compareResponse.UserMatches; } catch (error) { - console.log('searchUsersByImage:', error, error.stack); - return []; + console.log('code error ', error?.name); + if (error?.name == 'ProvisionedThroughputExceededException') { + console.log('ProvisionedThroughputExceededException'); + return false; + } else { + console.log('searchUsersByImage:', error, error.stack); + return []; + } } } From 37bfec731238b9df88f7e922fa84fa947e409f51 Mon Sep 17 00:00:00 2001 From: GitVivekHub Date: Wed, 6 Mar 2024 15:14:20 +0530 Subject: [PATCH 028/126] aadharno added --- src/src/userauth/userauth.service.ts | 75 ++++++++++++++++++++++------ 1 file changed, 61 insertions(+), 14 deletions(-) diff --git a/src/src/userauth/userauth.service.ts b/src/src/userauth/userauth.service.ts index ba2bbbeef..fc09747ba 100644 --- a/src/src/userauth/userauth.service.ts +++ b/src/src/userauth/userauth.service.ts @@ -348,6 +348,7 @@ export class UserauthService { middle_name last_name dob + aadhar_no mobile alternative_mobile_number email_id @@ -489,6 +490,9 @@ export class UserauthService { }, }; + if (!user_data.users_by_pk) { + user_data.users_by_pk = {}; // Initialize as an empty object if it doesn't exist + } // Replacing profile_photo_documents with profile_photo for all details user_data.users_by_pk.profile_photo_1 = profile_photo_1_info; user_data.users_by_pk.profile_photo_2 = profile_photo_2_info; @@ -521,7 +525,7 @@ export class UserauthService { }); user_data.users_by_pk.qualifications = - user_data?.users_by_pk?.qualifications.reduce((acc, q) => { + user_data?.users_by_pk?.qualifications?.reduce((acc, q) => { const documents = q.document_reference ? { base64: q?.document_reference?.base64, @@ -540,6 +544,7 @@ export class UserauthService { middle_name, last_name, dob, + aadhar_no, mobile, alternative_mobile_number, email_id, @@ -560,6 +565,7 @@ export class UserauthService { middle_name, last_name, dob, + aadhar_no, mobile, alternative_mobile_number, email_id, @@ -739,20 +745,47 @@ export class UserauthService { public async processJsonArray(values, tableName, user_id) { let set_update; let update_id; + let referenceFields; + let referenceData; + for (const obj of values) { - const tableFields = Object.keys(obj); + let tableFields = Object.keys(obj); tableFields.push('user_id'); obj.user_id = user_id; - let response = await this.findExisitingReccord( - tableName, - obj, - user_id, - ); - set_update = response?.set_update; - update_id = response?.id; + set_update = obj?.id ? 1 : 0; + update_id = obj?.id; - await this.upsertRecords( + console.log('set->.', set_update); + if (set_update == 1) { + tableFields.push('id'); + } + + if (tableName == 'experience') { + if ('references' in obj) { + // Process 'references' array differently + referenceFields = [ + 'name', + 'contact_number', + 'type_of_document', + 'user_id', + ]; + referenceData = { + name: obj?.references.name, + contact_number: obj?.references.contact_number, + type_of_document: obj?.references.type_of_document, + context: 'experience', + }; + + tableFields = tableFields.filter( + (field) => field !== 'references', + ); + delete obj.references; + } + } + + console.log('referenceData-->>', obj); + let result = await this.upsertRecords( set_update, tableName, tableFields, @@ -760,6 +793,19 @@ export class UserauthService { user_id, update_id, ); + + console.log('result in array-->>', result); + + // if (referenceData) { + // await this.upsertRecords( + // set_update, + // tableName, + // tableFields, + // obj, + // user_id, + // update_id, + // ); + // } } } @@ -902,8 +948,9 @@ export class UserauthService { user_id, id?, ) { + let result; if (set_update == 1 && id) { - let result = await this.hasuraService.q( + result = await this.hasuraService.q( tableName, { ...value, @@ -913,10 +960,8 @@ export class UserauthService { true, [tableFields], ); - - console.log('result-->>', result); } else { - await this.hasuraService.q( + result = await this.hasuraService.q( tableName, { ...value, @@ -926,6 +971,8 @@ export class UserauthService { [tableFields], ); } + + return result; } public async upsertProfileDocuments(profileDocumentArray) { From 877920ebd5ab7b665bd6bf8b727279f2121a2243 Mon Sep 17 00:00:00 2001 From: Manoj L Date: Wed, 6 Mar 2024 17:29:07 +0530 Subject: [PATCH 029/126] Update .env.example --- src/.env.example | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/.env.example b/src/.env.example index 823676203..5817618be 100644 --- a/src/.env.example +++ b/src/.env.example @@ -1,10 +1,18 @@ OTP_EXPIRY_IN_MINUTES=10 # Sentry -SENTRY_DSN_URL="" -SENTRY_ENVIRONMENT="local" +SENTRY_DSN_URL: +SENTRY_ENVIRONMENT: local # SMS Gateway -SMS_GATEWAY_BASE_URL="" -SMS_GATEWAY_API_KEY="" -SMS_GATEWAY_SENDER_ID="" \ No newline at end of file +SMS_GATEWAY_BASE_URL: +SMS_GATEWAY_API_KEY: +SMS_GATEWAY_SENDER_ID: + +# Caching +CACHE_SERVICE_HOST: localhost +CACHE_REDIS_PASSWORD: +CACHE_DEFAULT_TTL: 900 +CACHE_ACCESS_CONTROL_TTL: 300 +CACHE_ENUM_TTL: 900 +CACHE_GEOLOCATION_TTL: 900 From 300507d176b4af6bf4768b4c11d20ad9bf65d643 Mon Sep 17 00:00:00 2001 From: Tusharmahajan12 <121154132+Tusharmahajan12@users.noreply.github.com> Date: Wed, 6 Mar 2024 17:51:31 +0530 Subject: [PATCH 030/126] Organisation List API (#860) --- src/src/app.module.ts | 2 + .../dto/create-organisation.dto.ts | 1 + .../dto/update-organisation.dto.ts | 4 + .../entities/organisation.entity.ts | 1 + .../organisation.controller.spec.ts | 20 ++++ .../organisation/organisation.controller.ts | 54 +++++++++ src/src/organisation/organisation.module.ts | 21 ++++ .../organisation/organisation.service.spec.ts | 18 +++ src/src/organisation/organisation.service.ts | 104 ++++++++++++++++++ 9 files changed, 225 insertions(+) create mode 100644 src/src/organisation/dto/create-organisation.dto.ts create mode 100644 src/src/organisation/dto/update-organisation.dto.ts create mode 100644 src/src/organisation/entities/organisation.entity.ts create mode 100644 src/src/organisation/organisation.controller.spec.ts create mode 100644 src/src/organisation/organisation.controller.ts create mode 100644 src/src/organisation/organisation.module.ts create mode 100644 src/src/organisation/organisation.service.spec.ts create mode 100644 src/src/organisation/organisation.service.ts diff --git a/src/src/app.module.ts b/src/src/app.module.ts index 2680837cf..5100fbb7f 100755 --- a/src/src/app.module.ts +++ b/src/src/app.module.ts @@ -38,6 +38,7 @@ import { UploadFileModule } from './upload-file/upload-file.module'; import { UserModule } from './user/user.module'; import { UserauthModule } from './userauth/userauth.module'; import { BoardModule } from './modules/board/board.module'; +import { OrganisationModule } from './organisation/organisation.module'; @Module({ imports: [ ScheduleModule.forRoot(), @@ -85,6 +86,7 @@ import { BoardModule } from './modules/board/board.module'; UploadFileModule, UserModule, UserauthModule, + OrganisationModule, ], controllers: [], providers: [CacheCleanerProvider], diff --git a/src/src/organisation/dto/create-organisation.dto.ts b/src/src/organisation/dto/create-organisation.dto.ts new file mode 100644 index 000000000..92183745a --- /dev/null +++ b/src/src/organisation/dto/create-organisation.dto.ts @@ -0,0 +1 @@ +export class CreateOrganisationDto {} diff --git a/src/src/organisation/dto/update-organisation.dto.ts b/src/src/organisation/dto/update-organisation.dto.ts new file mode 100644 index 000000000..daaf56ca0 --- /dev/null +++ b/src/src/organisation/dto/update-organisation.dto.ts @@ -0,0 +1,4 @@ +import { PartialType } from '@nestjs/mapped-types'; +import { CreateOrganisationDto } from './create-organisation.dto'; + +export class UpdateOrganisationDto extends PartialType(CreateOrganisationDto) {} diff --git a/src/src/organisation/entities/organisation.entity.ts b/src/src/organisation/entities/organisation.entity.ts new file mode 100644 index 000000000..9dd7007a2 --- /dev/null +++ b/src/src/organisation/entities/organisation.entity.ts @@ -0,0 +1 @@ +export class Organisation {} diff --git a/src/src/organisation/organisation.controller.spec.ts b/src/src/organisation/organisation.controller.spec.ts new file mode 100644 index 000000000..bf7ca925f --- /dev/null +++ b/src/src/organisation/organisation.controller.spec.ts @@ -0,0 +1,20 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { OrganisationController } from './organisation.controller'; +import { OrganisationService } from './organisation.service'; + +describe('OrganisationController', () => { + let controller: OrganisationController; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + controllers: [OrganisationController], + providers: [OrganisationService], + }).compile(); + + controller = module.get(OrganisationController); + }); + + it('should be defined', () => { + expect(controller).toBeDefined(); + }); +}); diff --git a/src/src/organisation/organisation.controller.ts b/src/src/organisation/organisation.controller.ts new file mode 100644 index 000000000..37a4cd862 --- /dev/null +++ b/src/src/organisation/organisation.controller.ts @@ -0,0 +1,54 @@ +import { + Controller, + Get, + Post, + Body, + Patch, + Param, + Req, + Res, + Delete, + UseGuards, + Response, +} from '@nestjs/common'; +import { OrganisationService } from './organisation.service'; +import { CreateOrganisationDto } from './dto/create-organisation.dto'; +import { UpdateOrganisationDto } from './dto/update-organisation.dto'; +import { AuthGuard } from '../modules/auth/auth.guard'; +@Controller('organisation') +export class OrganisationController { + constructor(private readonly organisationService: OrganisationService) {} + + @Post() + create(@Body() createOrganisationDto: CreateOrganisationDto) { + return this.organisationService.create(createOrganisationDto); + } + + @Post('/org/list') + @UseGuards(new AuthGuard()) + getOrganisation( + @Body() request: Record, + @Req() req: any, + @Res() response: Response, + ) { + return this.organisationService.getOrganisation(request, req, response); + } + + @Get(':id') + findOne(@Param('id') id: string) { + return this.organisationService.findOne(+id); + } + + @Patch(':id') + update( + @Param('id') id: string, + @Body() updateOrganisationDto: UpdateOrganisationDto, + ) { + return this.organisationService.update(+id, updateOrganisationDto); + } + + @Delete(':id') + remove(@Param('id') id: string) { + return this.organisationService.remove(+id); + } +} diff --git a/src/src/organisation/organisation.module.ts b/src/src/organisation/organisation.module.ts new file mode 100644 index 000000000..dcb978b5f --- /dev/null +++ b/src/src/organisation/organisation.module.ts @@ -0,0 +1,21 @@ +import { Module, NestModule, MiddlewareConsumer } from '@nestjs/common'; +import { OrganisationService } from './organisation.service'; +import { OrganisationController } from './organisation.controller'; +import { HasuraModule as HasuraModuleFromServices } from '../services/hasura/hasura.module'; +import { CohortMiddleware } from 'src/common/middlewares/cohort.middleware'; +import { Method } from 'src/common/method/method'; + +@Module({ + imports: [HasuraModuleFromServices], + controllers: [OrganisationController], + providers: [OrganisationService, Method], + exports: [OrganisationService], +}) +export class OrganisationModule implements NestModule { + configure(consumer: MiddlewareConsumer) { + consumer + .apply(CohortMiddleware) + .exclude() + .forRoutes(OrganisationController); + } +} diff --git a/src/src/organisation/organisation.service.spec.ts b/src/src/organisation/organisation.service.spec.ts new file mode 100644 index 000000000..bf37c9a63 --- /dev/null +++ b/src/src/organisation/organisation.service.spec.ts @@ -0,0 +1,18 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { OrganisationService } from './organisation.service'; + +describe('OrganisationService', () => { + let service: OrganisationService; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [OrganisationService], + }).compile(); + + service = module.get(OrganisationService); + }); + + it('should be defined', () => { + expect(service).toBeDefined(); + }); +}); diff --git a/src/src/organisation/organisation.service.ts b/src/src/organisation/organisation.service.ts new file mode 100644 index 000000000..41f1b7edb --- /dev/null +++ b/src/src/organisation/organisation.service.ts @@ -0,0 +1,104 @@ +import { Injectable, Inject } from '@nestjs/common'; +import { CreateOrganisationDto } from './dto/create-organisation.dto'; +import { UpdateOrganisationDto } from './dto/update-organisation.dto'; + +import { HasuraService as HasuraServiceFromServices } from '../services/hasura/hasura.service'; + +@Injectable() +export class OrganisationService { + constructor(private hasuraServiceFromServices: HasuraServiceFromServices) {} + + create(createOrganisationDto: CreateOrganisationDto) { + return 'This action adds a new organisation'; + } + + public async getOrganisation(body: any, req: any, resp: any) { + const academic_year_id = req?.mw_academic_year_id; + const program_id = req?.mw_program_id; + + try { + const page = isNaN(body.page) ? 1 : parseInt(body.page); + const limit = isNaN(body.limit) ? 15 : parseInt(body.limit); + let offset = page > 1 ? limit * (page - 1) : 0; + let order_by = ''; + if (body?.order_by) { + let { name, id } = body?.order_by; + let errorData = {}; + if (name && !['asc', 'desc'].includes(name)) { + errorData = { + message: `Invalid value for order_by name ${name}`, + }; + } else if (id && !['asc', 'desc'].includes(id)) { + errorData = { + message: `Invalid value for order_by id ${id}`, + }; + } + if (Object.keys(errorData).length > 0) { + return resp.status(422).send({ + success: false, + ...errorData, + }); + } else { + const order = JSON.stringify({ name, id }).replace( + /"/g, + '', + ); + order_by = `, order_by:${order}`; + } + } + + let data = { + query: `query MyQuery($limit:Int, $offset:Int) { + organisations(where: { + program_organisations: { + program_id:{_eq:${program_id}}, + academic_year_id:{_eq:${academic_year_id}} + status:{_eq:"active"} + } + }limit: $limit, + offset: $offset ${order_by},) { + id + name + contact_person + mobile + } + } + `, + variables: { + limit: limit, + offset: offset, + }, + }; + + const response = await this.hasuraServiceFromServices.getData(data); + + const organisations = response?.data?.organisations || []; + + return resp.status(200).send({ + success: true, + message: 'Organisation list found successfully', + data: organisations, + }); + } catch (error) { + // Log error and return a generic error response + console.error('Error fetching organizations:', error); + return resp.status(422).send({ + success: false, + message: 'An error occurred while fetching organizations', + data: {}, + }); + } + } + + findOne(id: number) { + return `This action returns a #${id} organisation`; + } + + update(id: number, updateOrganisationDto: UpdateOrganisationDto) { + return `This action updates a #${id} organisation`; + } + + remove(id: number) { + return `This action removes a #${id} organisation`; + } +} From 6f7ae99eff0618cb37d9d9bc2adeadc09276c682 Mon Sep 17 00:00:00 2001 From: Tusharmahajan12 <121154132+Tusharmahajan12@users.noreply.github.com> Date: Thu, 7 Mar 2024 12:12:13 +0530 Subject: [PATCH 031/126] Task #215030 IP User Registration (#850) * Ip list and cohort list API * Ip list and cohort list API * Ip list and cohort list API * Middle ware changes for PO user * middle ware changes for IPUserInfo api * middle ware changes for IPUserInfo api * IP User Register --- src/src/modules/auth/auth.service.ts | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/src/modules/auth/auth.service.ts b/src/src/modules/auth/auth.service.ts index bfb20e381..826d7900d 100644 --- a/src/src/modules/auth/auth.service.ts +++ b/src/src/modules/auth/auth.service.ts @@ -500,6 +500,14 @@ export class AuthService { ) { misssingFieldsFlag = true; } + } else if (body.role === 'staff') { + if ( + !body.role_fields.organisation_id || + !body.role_fields.program_id || + !body.role_fields.academic_year_id + ) { + misssingFieldsFlag = true; + } } else { misssingFieldsFlag = true; } @@ -534,6 +542,10 @@ export class AuthService { group = `beneficiaries`; break; } + case 'staff': { + group = `staff`; + break; + } } let data_to_create_user = { @@ -613,6 +625,9 @@ export class AuthService { if (body.role_fields.facilitator_id) { body.facilitator_id = body.role_fields.facilitator_id; } + if (body.role_fields.organisation_id) { + body.organisation_id = body.role_fields.organisation_id; + } if (body.role === 'facilitator' && body.hasOwnProperty('dob')) { delete body.dob; } @@ -640,6 +655,8 @@ export class AuthService { ['status', 'reason_for_status_update'], ); } + if (body.role === 'staff' && result.data.program_users) { + } // Send login details SMS // नमस्कार, प्रगति प्लेटफॉर्म पर आपका अकाउंट बनाया गया है। आपका उपयोगकर्ता नाम है और पासवर्ड है। FEGG if (body.role === 'facilitator') { @@ -818,6 +835,14 @@ export class AuthService { req.academic_year_id = req.role_fields.academic_year_id; req.status = 'applied'; } + if (req.role === 'staff') { + programRoleTableName = 'program_users'; + groupId = 'organisation_id'; + req.organisation_id = `${req.role_fields.organisation_id}`; + req.program_id = req.role_fields.program_id; + req.academic_year_id = req.role_fields.academic_year_id; + req.status = null; + } console.log('tableName', programRoleTableName); console.log('groupId', groupId); From 110cef75408e6a0e33860316c2fae7e537ffc9a6 Mon Sep 17 00:00:00 2001 From: Tusharmahajan12 <121154132+Tusharmahajan12@users.noreply.github.com> Date: Thu, 7 Mar 2024 12:17:18 +0530 Subject: [PATCH 032/126] Task #215203 Create Organisation API (#862) * Organisation List API * Organisation List API --- .../organisation/organisation.controller.ts | 50 ++++++------ src/src/organisation/organisation.module.ts | 3 +- src/src/organisation/organisation.service.ts | 77 +++++++++++++++---- 3 files changed, 89 insertions(+), 41 deletions(-) diff --git a/src/src/organisation/organisation.controller.ts b/src/src/organisation/organisation.controller.ts index 37a4cd862..08258ec68 100644 --- a/src/src/organisation/organisation.controller.ts +++ b/src/src/organisation/organisation.controller.ts @@ -3,28 +3,32 @@ import { Get, Post, Body, - Patch, - Param, Req, Res, Delete, UseGuards, Response, + UsePipes, + ValidationPipe, } from '@nestjs/common'; import { OrganisationService } from './organisation.service'; -import { CreateOrganisationDto } from './dto/create-organisation.dto'; -import { UpdateOrganisationDto } from './dto/update-organisation.dto'; import { AuthGuard } from '../modules/auth/auth.guard'; @Controller('organisation') export class OrganisationController { constructor(private readonly organisationService: OrganisationService) {} - @Post() - create(@Body() createOrganisationDto: CreateOrganisationDto) { - return this.organisationService.create(createOrganisationDto); + @Post('/create') + @UsePipes(ValidationPipe) + @UseGuards(new AuthGuard()) + registerCamp( + @Body() body: any, + @Req() request: any, + @Res() response: Response, + ) { + return this.organisationService.create(body, request, response); } - @Post('/org/list') + @Post('/list') @UseGuards(new AuthGuard()) getOrganisation( @Body() request: Record, @@ -34,21 +38,21 @@ export class OrganisationController { return this.organisationService.getOrganisation(request, req, response); } - @Get(':id') - findOne(@Param('id') id: string) { - return this.organisationService.findOne(+id); - } + // @Get(':id') + // findOne(@Param('id') id: string) { + // return this.organisationService.findOne(+id); + // } - @Patch(':id') - update( - @Param('id') id: string, - @Body() updateOrganisationDto: UpdateOrganisationDto, - ) { - return this.organisationService.update(+id, updateOrganisationDto); - } + // @Patch(':id') + // update( + // @Param('id') id: string, + // @Body() updateOrganisationDto: UpdateOrganisationDto, + // ) { + // return this.organisationService.update(+id, updateOrganisationDto); + // } - @Delete(':id') - remove(@Param('id') id: string) { - return this.organisationService.remove(+id); - } + // @Delete(':id') + // remove(@Param('id') id: string) { + // return this.organisationService.remove(+id); + // } } diff --git a/src/src/organisation/organisation.module.ts b/src/src/organisation/organisation.module.ts index dcb978b5f..c35b235eb 100644 --- a/src/src/organisation/organisation.module.ts +++ b/src/src/organisation/organisation.module.ts @@ -2,11 +2,12 @@ import { Module, NestModule, MiddlewareConsumer } from '@nestjs/common'; import { OrganisationService } from './organisation.service'; import { OrganisationController } from './organisation.controller'; import { HasuraModule as HasuraModuleFromServices } from '../services/hasura/hasura.module'; +import { HasuraModule } from '../hasura/hasura.module'; import { CohortMiddleware } from 'src/common/middlewares/cohort.middleware'; import { Method } from 'src/common/method/method'; @Module({ - imports: [HasuraModuleFromServices], + imports: [HasuraModuleFromServices, HasuraModule], controllers: [OrganisationController], providers: [OrganisationService, Method], exports: [OrganisationService], diff --git a/src/src/organisation/organisation.service.ts b/src/src/organisation/organisation.service.ts index 41f1b7edb..f6a305183 100644 --- a/src/src/organisation/organisation.service.ts +++ b/src/src/organisation/organisation.service.ts @@ -1,15 +1,58 @@ -import { Injectable, Inject } from '@nestjs/common'; -import { CreateOrganisationDto } from './dto/create-organisation.dto'; -import { UpdateOrganisationDto } from './dto/update-organisation.dto'; - +import { Injectable } from '@nestjs/common'; +import { HasuraService } from '../hasura/hasura.service'; import { HasuraService as HasuraServiceFromServices } from '../services/hasura/hasura.service'; @Injectable() export class OrganisationService { - constructor(private hasuraServiceFromServices: HasuraServiceFromServices) {} + constructor( + private hasuraService: HasuraService, + private hasuraServiceFromServices: HasuraServiceFromServices, + ) {} + + async create(body: any, request: any, response: any) { + const organisationData = { + name: body?.name, + mobile: body?.mobile, + contact_person: body?.contact_person, + address: body?.address, + }; + + const tableName = 'organisations'; + const newOrganisation = await this.hasuraService.q( + tableName, + organisationData, + ['name', 'mobile', 'contact_person', 'address'], + ); + + if (!newOrganisation || !newOrganisation?.organisations.id) { + throw new Error('Failed to create organisation.'); + } + const organisation = newOrganisation?.organisations; - create(createOrganisationDto: CreateOrganisationDto) { - return 'This action adds a new organisation'; + // Step 2: Insert data into the 'program_organisation' table + const programOrganisationData = { + organisation_id: organisation?.id, + program_id: request.mw_program_id, + academic_year_id: request.mw_academic_year_id, + status: 'active', + // Other fields as needed + }; + + const programOrganisationTableName = 'program_organisation'; + const program_org = await this.hasuraService.q( + programOrganisationTableName, + programOrganisationData, + ); + + // Return success response + response.status(200).json({ + success: true, + message: 'Organisation created successfully.', + data: { + organisation, + program_org: program_org?.program_organisation, + }, + }); } public async getOrganisation(body: any, req: any, resp: any) { @@ -18,7 +61,7 @@ export class OrganisationService { try { const page = isNaN(body.page) ? 1 : parseInt(body.page); - const limit = isNaN(body.limit) ? 15 : parseInt(body.limit); + const limit = isNaN(body.limit) ? 10 : parseInt(body.limit); let offset = page > 1 ? limit * (page - 1) : 0; let order_by = ''; if (body?.order_by) { @@ -90,15 +133,15 @@ export class OrganisationService { } } - findOne(id: number) { - return `This action returns a #${id} organisation`; - } + // findOne(id: number) { + // return `This action returns a #${id} organisation`; + // } - update(id: number, updateOrganisationDto: UpdateOrganisationDto) { - return `This action updates a #${id} organisation`; - } + // update(id: number, updateOrganisationDto: UpdateOrganisationDto) { + // return `This action updates a #${id} organisation`; + // } - remove(id: number) { - return `This action removes a #${id} organisation`; - } + // remove(id: number) { + // return `This action removes a #${id} organisation`; + // } } From 00704da88210a291d052023b40c2889283ccc755 Mon Sep 17 00:00:00 2001 From: GitVivekHub Date: Thu, 7 Mar 2024 17:40:28 +0530 Subject: [PATCH 033/126] onbaording reference and experience nested nobject commit --- src/src/userauth/userauth.service.ts | 125 ++++++++++++++++++++++----- 1 file changed, 102 insertions(+), 23 deletions(-) diff --git a/src/src/userauth/userauth.service.ts b/src/src/userauth/userauth.service.ts index fc09747ba..de25d4cbc 100644 --- a/src/src/userauth/userauth.service.ts +++ b/src/src/userauth/userauth.service.ts @@ -415,6 +415,7 @@ export class UserauthService { name contact_number type_of_document + document_id document_reference { document_id: id name @@ -490,7 +491,7 @@ export class UserauthService { }, }; - if (!user_data.users_by_pk) { + if (!user_data?.users_by_pk) { user_data.users_by_pk = {}; // Initialize as an empty object if it doesn't exist } // Replacing profile_photo_documents with profile_photo for all details @@ -627,6 +628,7 @@ export class UserauthService { let profile_photo_3_value; let documents_values_3; let profile_documents_array = []; + let qualification_document_data; for (const key in json) { const value = json[key]; @@ -714,6 +716,24 @@ export class UserauthService { tableFields.push('context_id'); } + if (tableName == 'qualifications') { + console.log('qualvalue-->', value); + if (value?.documents) { + qualification_document_data = { + document_id: value?.documents?.document_id, + name: value?.documents?.name, + document_sub_type: 'qualifications', + doument_type: 'qualifications', + context: 'qualifications', + }; + } + tableFields = tableFields?.filter( + (field) => field !== 'documents', + ); + delete value?.documents; + console.log('qualvalue123-->', value); + } + let response = await this.findExisitingReccord( tableName, value, @@ -723,9 +743,7 @@ export class UserauthService { set_update = response?.set_update; update_id = response?.id; - console.log('update-->>', set_update, update_id); - - await this.upsertRecords( + let upsert_records_result = await this.upsertRecords( set_update, tableName, tableFields, @@ -734,9 +752,31 @@ export class UserauthService { update_id, ); + console.log('upsert_records_result-->>', upsert_records_result); + if (tableName == 'users' && profile_documents_array?.length > 0) { await this.upsertProfileDocuments(profile_documents_array); } + + if (tableName == 'qualifications' && qualification_document_data) { + let result = await this.upsertRecords( + 1, + 'documents', + [ + 'name', + 'document_sub_type', + 'doument_type', + 'context', + 'context_id', + 'user_id', + ], + qualification_document_data, + user_id, + qualification_document_data?.document_id, + ); + + console.log('result doc-->>.', result); + } } return true; @@ -747,6 +787,9 @@ export class UserauthService { let update_id; let referenceFields; let referenceData; + let documentFields; + let documentData; + let result; for (const obj of values) { let tableFields = Object.keys(obj); @@ -768,24 +811,45 @@ export class UserauthService { 'name', 'contact_number', 'type_of_document', - 'user_id', ]; referenceData = { name: obj?.references.name, contact_number: obj?.references.contact_number, type_of_document: obj?.references.type_of_document, + id: obj?.references?.id, context: 'experience', }; - tableFields = tableFields.filter( - (field) => field !== 'references', - ); - delete obj.references; + if (set_update == 1) { + referenceData.context_id = obj?.id; + } + } + + if ('documents' in obj.references) { + documentFields = [ + 'name', + 'document_sub_type', + 'doument_type', + 'context', + ]; + documentData = { + name: obj?.references?.documents?.name, + document_sub_type: + obj?.references?.documents?.document_sub_type, + doument_type: obj?.references?.documents?.document_type, + id: obj?.references?.documents?.document_id, + context: 'reference', + }; } + + // remove references object from the main object to process the experience object + tableFields = tableFields?.filter( + (field) => field !== 'references', + ); + delete obj?.references; } - console.log('referenceData-->>', obj); - let result = await this.upsertRecords( + result = await this.upsertRecords( set_update, tableName, tableFields, @@ -794,18 +858,33 @@ export class UserauthService { update_id, ); - console.log('result in array-->>', result); - - // if (referenceData) { - // await this.upsertRecords( - // set_update, - // tableName, - // tableFields, - // obj, - // user_id, - // update_id, - // ); - // } + if (tableName == 'experience' && referenceData) { + let update_id = referenceData?.id; + set_update = update_id ? 1 : 0; + if (!obj?.id) { + referenceData.context_id = result?.experience?.id; + } + let result1 = await this.upsertRecords( + set_update, + 'references', + referenceFields, + referenceData, + user_id, + update_id, + ); + + if (documentData) { + let update_id = documentData?.id; + let result2 = await this.upsertRecords( + 1, + 'documents', + documentFields, + documentData, + user_id, + update_id, + ); + } + } } } From 96084e57483e01ca06f7fc5558e82f47bc328625 Mon Sep 17 00:00:00 2001 From: Tusharmahajan12 <121154132+Tusharmahajan12@users.noreply.github.com> Date: Thu, 7 Mar 2024 18:07:46 +0530 Subject: [PATCH 034/126] Task #215227 Details view api for organisation (#864) * Organisation List API * Organisation List API * Details view api for organisation * Details view api for organisation * Details view api for organisation --- .../organisation/organisation.controller.ts | 35 ++++----- src/src/organisation/organisation.service.ts | 76 ++++++++++++++++--- 2 files changed, 82 insertions(+), 29 deletions(-) diff --git a/src/src/organisation/organisation.controller.ts b/src/src/organisation/organisation.controller.ts index 08258ec68..0915d1b15 100644 --- a/src/src/organisation/organisation.controller.ts +++ b/src/src/organisation/organisation.controller.ts @@ -10,6 +10,7 @@ import { Response, UsePipes, ValidationPipe, + Param, } from '@nestjs/common'; import { OrganisationService } from './organisation.service'; import { AuthGuard } from '../modules/auth/auth.guard'; @@ -31,28 +32,24 @@ export class OrganisationController { @Post('/list') @UseGuards(new AuthGuard()) getOrganisation( - @Body() request: Record, + @Body() body: Record, @Req() req: any, @Res() response: Response, ) { - return this.organisationService.getOrganisation(request, req, response); + return this.organisationService.getOrganisation(body, req, response); } - // @Get(':id') - // findOne(@Param('id') id: string) { - // return this.organisationService.findOne(+id); - // } - - // @Patch(':id') - // update( - // @Param('id') id: string, - // @Body() updateOrganisationDto: UpdateOrganisationDto, - // ) { - // return this.organisationService.update(+id, updateOrganisationDto); - // } - - // @Delete(':id') - // remove(@Param('id') id: string) { - // return this.organisationService.remove(+id); - // } + @Post('/:id') + @UseGuards(new AuthGuard()) + getOrganisationDetails( + @Req() req: any, + @Res() response: Response, + @Param('id') id: number, + ) { + return this.organisationService.getOrganisationDetails( + req, + response, + id, + ); + } } diff --git a/src/src/organisation/organisation.service.ts b/src/src/organisation/organisation.service.ts index f6a305183..2425a9913 100644 --- a/src/src/organisation/organisation.service.ts +++ b/src/src/organisation/organisation.service.ts @@ -90,9 +90,26 @@ export class OrganisationService { } } + let searchQuery = ''; + if (body.search && !isNaN(body.search)) { + let id = parseInt(body.search); + searchQuery = `id: {_eq: ${id}}`; + } else if (body.search) { + if (body.search && body.search !== '') { + let first_name = body.search.split(' ')[0]; + let last_name = body.search.split(' ')[1] || ''; + + if (last_name?.length > 0) { + searchQuery = `_and:[{name: { _ilike: "%${first_name}%" }}, {name: { _ilike: "%${last_name}%" }}],`; + } else { + searchQuery = `_or:[{name: { _ilike: "%${first_name}%" }}, {name: { _ilike: "%${first_name}%" }}],`; + } + } + } + let data = { query: `query MyQuery($limit:Int, $offset:Int) { - organisations(where: { + organisations(where: {${searchQuery} program_organisations: { program_id:{_eq:${program_id}}, academic_year_id:{_eq:${academic_year_id}} @@ -133,15 +150,54 @@ export class OrganisationService { } } - // findOne(id: number) { - // return `This action returns a #${id} organisation`; - // } + public async getOrganisationDetails(req: any, resp: any, id: any) { + const academic_year_id = req?.mw_academic_year_id; + const program_id = req?.mw_program_id; + const org_id = id; + try { + let data = { + query: `query MyQuery { + organisations(where: {id:{_eq:${org_id}} + }) { + id + name + contact_person + mobile + program_organisations(where:{program_id: {_eq: ${program_id}}, academic_year_id: {_eq: ${academic_year_id}}, status: {_eq: "active"}}){ + program_id + academic_year_id + status + } + } + } + `, + }; + + const response = await this.hasuraServiceFromServices.getData(data); - // update(id: number, updateOrganisationDto: UpdateOrganisationDto) { - // return `This action updates a #${id} organisation`; - // } + const organisations = response?.data?.organisations || []; - // remove(id: number) { - // return `This action removes a #${id} organisation`; - // } + if (organisations.length == 0) { + return resp.status(422).send({ + success: false, + message: 'Organisation Details Not found!', + data: organisations, + }); + } else { + return resp.status(200).send({ + success: true, + message: 'Organisation Details found successfully!', + data: organisations, + }); + } + } catch (error) { + // Log error and return a generic error response + console.error('Error fetching organizations:', error); + return resp.status(422).send({ + success: false, + message: 'An error occurred while fetching organizations', + data: {}, + }); + } + } } From 60530d91c309f562385e878e7d445183e536ea79 Mon Sep 17 00:00:00 2001 From: GitVivekHub Date: Fri, 8 Mar 2024 11:37:40 +0530 Subject: [PATCH 035/126] request imported in userauth controller --- src/src/userauth/userauth.controller.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/src/userauth/userauth.controller.ts b/src/src/userauth/userauth.controller.ts index 227e73322..94e929dad 100644 --- a/src/src/userauth/userauth.controller.ts +++ b/src/src/userauth/userauth.controller.ts @@ -12,6 +12,7 @@ import { UsePipes, ValidationPipe, Response, + Request, } from '@nestjs/common'; import { AuthGuard } from 'src/modules/auth/auth.guard'; From 9cddb0daa0a50cf2b0f43e309fd0f682d7d419cd Mon Sep 17 00:00:00 2001 From: GitVivekHub Date: Fri, 8 Mar 2024 11:43:29 +0530 Subject: [PATCH 036/126] request imported in controller --- src/src/userauth/userauth.controller.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/src/userauth/userauth.controller.ts b/src/src/userauth/userauth.controller.ts index 227e73322..94e929dad 100644 --- a/src/src/userauth/userauth.controller.ts +++ b/src/src/userauth/userauth.controller.ts @@ -12,6 +12,7 @@ import { UsePipes, ValidationPipe, Response, + Request, } from '@nestjs/common'; import { AuthGuard } from 'src/modules/auth/auth.guard'; From 69aa6ca081272cc5966fbc0564f654a82105d33c Mon Sep 17 00:00:00 2001 From: Tusharmahajan12 <121154132+Tusharmahajan12@users.noreply.github.com> Date: Fri, 8 Mar 2024 12:10:50 +0530 Subject: [PATCH 037/126] IP users Details (#871) --- src/src/organisation/organisation.service.ts | 18 +++++++- src/src/user/user.controller.ts | 11 +++++ src/src/user/user.service.ts | 44 ++++++++++++++++++++ 3 files changed, 72 insertions(+), 1 deletion(-) diff --git a/src/src/organisation/organisation.service.ts b/src/src/organisation/organisation.service.ts index 2425a9913..7a4be9140 100644 --- a/src/src/organisation/organisation.service.ts +++ b/src/src/organisation/organisation.service.ts @@ -109,6 +109,16 @@ export class OrganisationService { let data = { query: `query MyQuery($limit:Int, $offset:Int) { + organisations_aggregate(where: {${searchQuery} + program_organisations: { + program_id:{_eq:${program_id}}, + academic_year_id:{_eq:${academic_year_id}} + status:{_eq:"active"} + }}){ + aggregate{ + count + } + } organisations(where: {${searchQuery} program_organisations: { program_id:{_eq:${program_id}}, @@ -133,11 +143,17 @@ export class OrganisationService { const response = await this.hasuraServiceFromServices.getData(data); const organisations = response?.data?.organisations || []; - + const count = + response?.data?.organisations_aggregate?.aggregate?.count; + const totalPages = Math.ceil(count / limit); return resp.status(200).send({ success: true, message: 'Organisation list found successfully', data: organisations, + totalCount: count, + limit, + currentPage: page, + totalPages: totalPages, }); } catch (error) { // Log error and return a generic error response diff --git a/src/src/user/user.controller.ts b/src/src/user/user.controller.ts index d68dac032..bbb8cab52 100755 --- a/src/src/user/user.controller.ts +++ b/src/src/user/user.controller.ts @@ -253,6 +253,17 @@ export class UserController { ) { return this.userService.getCohortIpList(request, req, response); } + + @Post('/ip/:id') + @UseGuards(new AuthGuard()) + getIpDetails( + @Req() request: any, + @Body() body: any, + @Param('id') id: number, + @Res() response: any, + ) { + return this.userService.getIpDetails(id, body, request, response); + } /**************************************************************************/ /******************************* V2 APIs **********************************/ /**************************************************************************/ diff --git a/src/src/user/user.service.ts b/src/src/user/user.service.ts index 1bcd81a81..4e534dd5a 100644 --- a/src/src/user/user.service.ts +++ b/src/src/user/user.service.ts @@ -1793,4 +1793,48 @@ export class UserService { const result = await this.hasuraServiceFromServices.getData(data); return result; } + + public async getIpDetails(id: any, body: any, req: any, resp) { + const ip_id = id; + const program_id = req.mw_program_id; + const academic_year_id = req.mw_academic_year_id; + + let qury = `query MyQuery { + users(where: {id: {_eq: ${ip_id}}, program_users: {academic_year_id: {_eq: ${academic_year_id}}, program_id: {_eq: ${program_id}}}}){ + id + first_name + middle_name + last_name + mobile + program_users(where:{academic_year_id:{_eq:${academic_year_id}},program_id:{_eq:${program_id}}}){ + id + user_id + academic_year_id + program_id + role_id + organisation_id + + } + + } + } + `; + const data = { query: qury }; + const response = await this.hasuraServiceFromServices.getData(data); + const newQdata = response?.data?.users; + + if (newQdata.length == 0) { + return resp.status(422).json({ + success: false, + message: 'Data Not found!', + data: {}, + }); + } else { + return resp.status(200).json({ + success: true, + message: 'Data found successfully!', + data: newQdata || {}, + }); + } + } } From 2db2428cb35083b8e3095b3576f08beabb278457 Mon Sep 17 00:00:00 2001 From: GitVivekHub Date: Fri, 8 Mar 2024 13:33:45 +0530 Subject: [PATCH 038/126] get api changes --- src/src/userauth/userauth.controller.ts | 2 - src/src/userauth/userauth.service.ts | 61 +++++++++++++++++++++++++ 2 files changed, 61 insertions(+), 2 deletions(-) diff --git a/src/src/userauth/userauth.controller.ts b/src/src/userauth/userauth.controller.ts index 94e929dad..5d39e53e6 100644 --- a/src/src/userauth/userauth.controller.ts +++ b/src/src/userauth/userauth.controller.ts @@ -3,12 +3,10 @@ import { Controller, Get, Param, - Patch, Post, Req, Res, UseGuards, - UseInterceptors, UsePipes, ValidationPipe, Response, diff --git a/src/src/userauth/userauth.service.ts b/src/src/userauth/userauth.service.ts index de25d4cbc..dd612ad55 100644 --- a/src/src/userauth/userauth.service.ts +++ b/src/src/userauth/userauth.service.ts @@ -352,12 +352,25 @@ export class UserauthService { mobile alternative_mobile_number email_id + state district block grampanchayat village pincode gender + username + mobile_no_verified + long + lat + keycloak_id + is_deactivated + is_duplicate + email_verified + duplicate_reason + aadhar_verified + aadhar_token + aadhaar_verification_mode profile_photo_1 profile_photo_1_documents: documents(where: {document_sub_type: {_eq: "profile_photo_1"}}) { name @@ -387,11 +400,14 @@ export class UserauthService { device_ownership has_diploma diploma_details + pan_no + sourcing_channel } extended_users { marital_status social_category designation + qualification_id } references(where: {context: {_eq: "users"}}) { name @@ -400,6 +416,15 @@ export class UserauthService { context } program_faciltators(where: {academic_year_id: {_eq:${academic_year_id}}, program_id: {_eq:${program_id}}}) { + id + parent_ip + documents_status + has_social_work_exp + police_verification_done + social_background_verified_by_neighbours + village_knowledge_test + status + form_step_number availability qualification_ids } @@ -412,6 +437,7 @@ export class UserauthService { experience_in_years related_to_teaching references(where: {context: {_eq: "experience"}}) { + id name contact_number type_of_document @@ -421,19 +447,39 @@ export class UserauthService { name document_sub_type doument_type + path + provider + context + context_id } } } qualifications{ + id + end_year + institution + start_year qualification_master_id qualification_reference_document_id document_reference{ document_id:id name path + provider + context + context_id } + qualification_master{ + context + context_id + created_by + id + name + type + updated_by } } + } } `; @@ -540,6 +586,20 @@ export class UserauthService { return { ...acc, ...q, documents }; }, {}); + user_data.users_by_pk.program_faciltators = + user_data?.users_by_pk?.program_faciltators?.reduce((acc, pf) => { + pf ? pf : {}; + + return { ...acc, ...pf }; + }, {}); + + user_data.users_by_pk.references = + user_data?.users_by_pk?.references?.reduce((acc, rf) => { + rf ? rf : {}; + + return { ...acc, ...rf }; + }, {}); + const { first_name, middle_name, @@ -586,6 +646,7 @@ export class UserauthService { program_faciltators: user_data?.users_by_pk?.program_faciltators, experience: user_data?.users_by_pk?.experience, qualifications: user_data?.users_by_pk?.qualifications, + qualification_master: user_data?.users_by_pk?.qualification_master, }; if (user_data) { From ea9c1293acae33b04ff745477dc3ef77bb48ee27 Mon Sep 17 00:00:00 2001 From: Tusharmahajan12 <121154132+Tusharmahajan12@users.noreply.github.com> Date: Fri, 8 Mar 2024 13:45:23 +0530 Subject: [PATCH 039/126] Task #215242 IP users List (#869) * IP users List * Ip user list --- src/src/helper/queryGenerator.service.ts | 33 +++++++++++++++++---- src/src/user/user.controller.ts | 9 ++++++ src/src/user/user.service.ts | 37 ++++++++++++++++++++++++ 3 files changed, 74 insertions(+), 5 deletions(-) diff --git a/src/src/helper/queryGenerator.service.ts b/src/src/helper/queryGenerator.service.ts index 68762888f..29580aa7c 100644 --- a/src/src/helper/queryGenerator.service.ts +++ b/src/src/helper/queryGenerator.service.ts @@ -20,6 +20,17 @@ export class QueryGeneratorService { return str; }; + filterObjectByKeyArray = (obj: any, desiredKeys: []) => { + const filteredObject = desiredKeys.reduce((acc: any, key) => { + if (key in obj) { + acc[key] = obj[key]; + } + return acc; + }, {}); + + return filteredObject; + }; + // create create(tName: String, item: any, onlyFields: any = [], fields: any = []) { let tableName = `insert_${tName}_one`; @@ -242,7 +253,12 @@ export class QueryGeneratorService { request: any = { filters: {}, page: '0', limit: '0' }, ) { const getObjStr = (request: any) => { - const { filters, page, limit, order_by } = request; + const { filter, page, limit, order_by, onlyfilter } = request; + const filters = this.filterObjectByKeyArray( + filter || {}, + onlyfilter || [], + ); + let str = ''; if ( (limit && limit != '0') || @@ -251,20 +267,25 @@ export class QueryGeneratorService { ) { str += '('; let paramArr = []; + if (filters && Object.keys(filters).length > 0) { let filterStr = `where: {`; let strArr = Object.keys(filters).map((e) => { - if (this.isEmptyObject(filters[e])) { + let qData = ''; + if (e === 'core') { + qData = filters[e]; + } else if (this.isEmptyObject(filters[e])) { let data = this.objectConvert( filters[e], ([key, val]) => { return `${key}: "${val}"`; }, ); - return `${e}:{${data.join(',')}}`; + qData = `${e}:{${data.join(',')}}`; } else if (filters && filters[e] != '') { - return `${e}:{_eq:"${filters[e]}"}`; + qData = `${e}:{_eq:"${filters[e]}"}`; } + return qData; }); filterStr += strArr.join(); filterStr += `}`; @@ -292,7 +313,7 @@ export class QueryGeneratorService { return str; }; - return `query MyQuery { + const query = `query MyQuery { ${tableName}_aggregate${getObjStr(request)} { aggregate { count @@ -303,6 +324,8 @@ export class QueryGeneratorService { } } `; + + return query; } findOne(id: number, tName: String, onlyFields: any = []) { diff --git a/src/src/user/user.controller.ts b/src/src/user/user.controller.ts index bbb8cab52..c99c5be45 100755 --- a/src/src/user/user.controller.ts +++ b/src/src/user/user.controller.ts @@ -254,6 +254,15 @@ export class UserController { return this.userService.getCohortIpList(request, req, response); } + @Post('/ip_users/list') + @UseGuards(new AuthGuard()) + getIpUserList( + @Body() body: Record, + @Req() req: any, + @Res() response: Response, + ) { + return this.userService.getIpUserList(body, req, response); + } @Post('/ip/:id') @UseGuards(new AuthGuard()) getIpDetails( diff --git a/src/src/user/user.service.ts b/src/src/user/user.service.ts index 4e534dd5a..bc1c8521d 100644 --- a/src/src/user/user.service.ts +++ b/src/src/user/user.service.ts @@ -1794,6 +1794,43 @@ export class UserService { return result; } + public async getIpUserList(body: any, req: any, resp: any) { + const academic_year_id = req.mw_academic_year_id; + const program_id = req.mw_program_id; + let onlyfilter = [ + 'id', + 'first_name', + 'last_name', + 'email_id', + 'mobile', + ]; + body.filter = { + ...(body.filter || {}), + core: ` + program_users: { + academic_year_id: { _eq: ${academic_year_id} }, + program_id: { _eq: ${program_id} }, + }`, + }; + + const result = await this.hasuraServiceFromServices.getAll( + 'users', + [ + ...onlyfilter, + `program_users(where:{ + academic_year_id: { _eq: ${academic_year_id} }, + program_id: { _eq: ${program_id} } + }){academic_year_id program_id status organisation_id role_id}`, + ], + { ...body, onlyfilter: [...onlyfilter, 'core'] }, + ); + + return resp.status(200).send({ + ...result, + success: true, + message: 'IP User List Found Successfully', + }); + } public async getIpDetails(id: any, body: any, req: any, resp) { const ip_id = id; const program_id = req.mw_program_id; From 3dd7384f02c63da2e868049069d824da22fd06f6 Mon Sep 17 00:00:00 2001 From: GitVivekHub Date: Fri, 8 Mar 2024 14:34:29 +0530 Subject: [PATCH 040/126] userauth get user-info api change --- src/src/userauth/userauth.service.ts | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/src/userauth/userauth.service.ts b/src/src/userauth/userauth.service.ts index dd612ad55..287973ec8 100644 --- a/src/src/userauth/userauth.service.ts +++ b/src/src/userauth/userauth.service.ts @@ -344,6 +344,7 @@ export class UserauthService { let query = `query MyQuery { users_by_pk(id:${user_id}) { + id first_name middle_name last_name @@ -618,6 +619,19 @@ export class UserauthService { profile_photo_1, profile_photo_2, profile_photo_3, + username, + mobile_no_verified, + long, + lat, + keycloak_id, + is_deactivated, + is_duplicate, + email_verified, + duplicate_reason, + aadhar_verified, + aadhar_token, + aadhaar_verification_mode, + id, } = user_data?.users_by_pk || {}; const formattedData = { @@ -639,6 +653,19 @@ export class UserauthService { profile_photo_1, profile_photo_2, profile_photo_3, + username, + mobile_no_verified, + long, + lat, + keycloak_id, + is_deactivated, + is_duplicate, + email_verified, + duplicate_reason, + aadhar_verified, + aadhar_token, + aadhaar_verification_mode, + id, }, core_faciltator: user_data?.users_by_pk?.core_faciltator, extended_users: user_data?.users_by_pk?.extended_users, From 42ae0757f402c0f7d654d0608673e906f6438149 Mon Sep 17 00:00:00 2001 From: Tusharmahajan12 <121154132+Tusharmahajan12@users.noreply.github.com> Date: Fri, 8 Mar 2024 15:33:46 +0530 Subject: [PATCH 041/126] Task #215242 Filter with organisation_id (#879) * IP users List * Ip user list * Ip user list filter --- src/src/user/user.service.ts | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/src/user/user.service.ts b/src/src/user/user.service.ts index bc1c8521d..a7d524771 100644 --- a/src/src/user/user.service.ts +++ b/src/src/user/user.service.ts @@ -1797,6 +1797,15 @@ export class UserService { public async getIpUserList(body: any, req: any, resp: any) { const academic_year_id = req.mw_academic_year_id; const program_id = req.mw_program_id; + const organisation_id = body?.organisation_id; + if (!organisation_id) { + return resp.status(422).send({ + success: false, + message: 'Organisation ID required', + }); + } + const programUserFilter = `academic_year_id: { _eq: ${academic_year_id} }, + program_id: { _eq: ${program_id}},organisation_id:{_eq:${organisation_id}}`; let onlyfilter = [ 'id', 'first_name', @@ -1808,8 +1817,7 @@ export class UserService { ...(body.filter || {}), core: ` program_users: { - academic_year_id: { _eq: ${academic_year_id} }, - program_id: { _eq: ${program_id} }, + ${programUserFilter} }`, }; @@ -1818,8 +1826,7 @@ export class UserService { [ ...onlyfilter, `program_users(where:{ - academic_year_id: { _eq: ${academic_year_id} }, - program_id: { _eq: ${program_id} } + ${programUserFilter} }){academic_year_id program_id status organisation_id role_id}`, ], { ...body, onlyfilter: [...onlyfilter, 'core'] }, @@ -1831,6 +1838,7 @@ export class UserService { message: 'IP User List Found Successfully', }); } + public async getIpDetails(id: any, body: any, req: any, resp) { const ip_id = id; const program_id = req.mw_program_id; From aaf466b4dbe3a29e6dc8fd11e74b2666e192b027 Mon Sep 17 00:00:00 2001 From: GitVivekHub Date: Sat, 9 Mar 2024 12:23:06 +0530 Subject: [PATCH 042/126] vo_experience added to eperience --- src/src/userauth/userauth.service.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/src/userauth/userauth.service.ts b/src/src/userauth/userauth.service.ts index 287973ec8..f90d434ba 100644 --- a/src/src/userauth/userauth.service.ts +++ b/src/src/userauth/userauth.service.ts @@ -429,7 +429,7 @@ export class UserauthService { availability qualification_ids } - experience(where: {type: {_eq: "experience"}}) { + experience(where: {type: {_in: ["experience","vo_experience"]}}) { id type role_title From 7de4682d8adbf19aebbc49e99b5c039f5ccb560e Mon Sep 17 00:00:00 2001 From: GitVivekHub Date: Sun, 10 Mar 2024 18:13:29 +0530 Subject: [PATCH 043/126] Prerak user-info ger response change --- src/src/userauth/userauth.service.ts | 31 +++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/src/src/userauth/userauth.service.ts b/src/src/userauth/userauth.service.ts index 98d3e047f..89f944d89 100644 --- a/src/src/userauth/userauth.service.ts +++ b/src/src/userauth/userauth.service.ts @@ -401,6 +401,9 @@ export class UserauthService { document_sub_type document_id: id path + provider + context + context_id } profile_photo_2 profile_photo_2_documents: documents(where: {document_sub_type: {_eq: "profile_photo_2"}}) { @@ -409,6 +412,9 @@ export class UserauthService { document_sub_type document_id: id path + provider + context + context_id } profile_photo_3 profile_photo_3_documents: documents(where: {document_sub_type: {_eq: "profile_photo_3"}}) { @@ -417,6 +423,9 @@ export class UserauthService { document_sub_type document_id: id path + provider + context + context_id } core_faciltator { device_type @@ -533,6 +542,10 @@ export class UserauthService { document_type: profilePhoto1Documents?.[0].doument_type, document_sub_type: profilePhoto1Documents?.[0].document_sub_type, + path: profilePhoto1Documents?.[0]?.path, + provider: profilePhoto1Documents?.[0]?.provider, + context: profilePhoto1Documents?.[0]?.context, + context_id: profilePhoto1Documents?.[0]?.context_id, }, }; @@ -545,6 +558,10 @@ export class UserauthService { document_type: profilePhoto2Documents?.[0].doument_type, document_sub_type: profilePhoto2Documents?.[0].document_sub_type, + path: profilePhoto2Documents?.[0]?.path, + provider: profilePhoto2Documents?.[0]?.provider, + context: profilePhoto2Documents?.[0]?.context, + context_id: profilePhoto2Documents?.[0]?.context_id, }, }; @@ -557,6 +574,10 @@ export class UserauthService { document_type: profilePhoto3Documents?.[0].doument_type || null, document_sub_type: profilePhoto3Documents?.[0].document_sub_type, + path: profilePhoto3Documents?.[0]?.path, + provider: profilePhoto3Documents?.[0]?.provider, + context: profilePhoto3Documents?.[0]?.context, + context_id: profilePhoto3Documents?.[0]?.context_id, }, }; @@ -585,6 +606,10 @@ export class UserauthService { ref?.document_reference?.document_sub_type, document_type: ref?.document_reference?.doument_type, + path: ref?.document_reference?.path, + provider: ref?.document_reference?.provider, + context: ref?.document_reference?.context, + context_id: ref?.document_reference?.context_id, } : {}; @@ -601,6 +626,10 @@ export class UserauthService { base64: q?.document_reference?.base64, document_id: q?.document_reference?.document_id, name: q?.document_reference?.name, + path: q?.document_reference?.path, + provider: q?.document_reference?.provider, + context: q?.document_reference?.context, + context_id: q?.document_reference?.context_id, } : {}; @@ -1005,7 +1034,7 @@ export class UserauthService { switch (tablename) { case 'users': { query = `query MyQuery { - users(where: {mobile: {_eq:${value.mobile}}}){ + users(where: {id: {_eq:${user_id}}}){ id, mobile } From 6091963909dc70b937a4ce2df49b3bc6a60b9777 Mon Sep 17 00:00:00 2001 From: GitVivekHub Date: Sun, 10 Mar 2024 20:49:22 +0530 Subject: [PATCH 044/126] vcalidaton added to the onboarding api --- src/src/userauth/userauth.service.ts | 50 ++++++++++++++++++++++++---- 1 file changed, 44 insertions(+), 6 deletions(-) diff --git a/src/src/userauth/userauth.service.ts b/src/src/userauth/userauth.service.ts index 89f944d89..271d9b841 100644 --- a/src/src/userauth/userauth.service.ts +++ b/src/src/userauth/userauth.service.ts @@ -739,17 +739,29 @@ export class UserauthService { //first check validations for all inputs let user_id = request?.mw_userid; + let program_id = request?.mw_program_id; + let academic_year_id = request?.academic_year_id; + + let result = await this.processTable( + body, + user_id, + program_id, + academic_year_id, + ); - let result = await this.processTable(body, user_id); - + console.log('result-->>', result); if (result) { return response.status(200).json({ - success: true, - message: 'Successfully updated data', + result: result, }); } } - private async processTable(json: any, user_id: any) { + private async processTable( + json: any, + user_id: any, + program_id: any, + academic_year_id: any, + ) { let tableFields; let tableName; let set_update; @@ -768,6 +780,7 @@ export class UserauthService { let documents_values_3; let profile_documents_array = []; let qualification_document_data; + let resultArray = []; for (const key in json) { const value = json[key]; @@ -850,6 +863,13 @@ export class UserauthService { tableFields.push('user_id'); } + if (tableName == 'program_faciltators') { + value.program_id = program_id; + value.academic_year_id = academic_year_id; + tableFields.push('program_id'); + tableFields.push('academic_year_id'); + } + if (tableName == 'references') { value.context_id = user_id; tableFields.push('context_id'); @@ -891,6 +911,24 @@ export class UserauthService { update_id, ); + if ( + upsert_records_result?.[tableName]?.extensions?.code == + 'validation-failed' + ) { + console.log('herer'); + resultArray.push({ + [tableName]: { + status: false, + }, + }); + } else { + resultArray.push({ + [tableName]: { + status: true, + }, + }); + } + console.log('upsert_records_result-->>', upsert_records_result); if (tableName == 'users' && profile_documents_array?.length > 0) { @@ -918,7 +956,7 @@ export class UserauthService { } } - return true; + return resultArray; } public async processJsonArray(values, tableName, user_id) { From 8c1182ac37775b860046c4651a3a91811f5722a0 Mon Sep 17 00:00:00 2001 From: GitVivekHub Date: Sun, 10 Mar 2024 20:59:45 +0530 Subject: [PATCH 045/126] error/success message updated --- src/src/userauth/userauth.service.ts | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/src/userauth/userauth.service.ts b/src/src/userauth/userauth.service.ts index 271d9b841..c5b4e9e05 100644 --- a/src/src/userauth/userauth.service.ts +++ b/src/src/userauth/userauth.service.ts @@ -911,20 +911,18 @@ export class UserauthService { update_id, ); - if ( - upsert_records_result?.[tableName]?.extensions?.code == - 'validation-failed' - ) { - console.log('herer'); + if (upsert_records_result?.[tableName]?.extensions) { resultArray.push({ [tableName]: { status: false, + message: upsert_records_result?.[tableName]?.message, }, }); } else { resultArray.push({ [tableName]: { status: true, + message: 'successfully updated the value', }, }); } From 0f73c3dc3e597a2fcc17f19e5b8ff381653c67d8 Mon Sep 17 00:00:00 2001 From: GitVivekHub Date: Mon, 11 Mar 2024 11:55:06 +0530 Subject: [PATCH 046/126] state added to the response --- src/src/userauth/userauth.service.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/src/userauth/userauth.service.ts b/src/src/userauth/userauth.service.ts index c5b4e9e05..7a889a0e1 100644 --- a/src/src/userauth/userauth.service.ts +++ b/src/src/userauth/userauth.service.ts @@ -661,6 +661,7 @@ export class UserauthService { mobile, alternative_mobile_number, email_id, + state, district, block, grampanchayat, @@ -695,6 +696,7 @@ export class UserauthService { mobile, alternative_mobile_number, email_id, + state, district, block, grampanchayat, From b63f4189670ffc2a6d366317237d0b180166a443 Mon Sep 17 00:00:00 2001 From: GitVivekHub Date: Tue, 12 Mar 2024 12:46:51 +0530 Subject: [PATCH 047/126] result validation condition handled for the experience array for prerak onboarding --- src/src/userauth/userauth.service.ts | 73 +++++++++++++++++++--------- 1 file changed, 49 insertions(+), 24 deletions(-) diff --git a/src/src/userauth/userauth.service.ts b/src/src/userauth/userauth.service.ts index 7a889a0e1..958e893e7 100644 --- a/src/src/userauth/userauth.service.ts +++ b/src/src/userauth/userauth.service.ts @@ -783,6 +783,7 @@ export class UserauthService { let profile_documents_array = []; let qualification_document_data; let resultArray = []; + let upsert_records_result; for (const key in json) { const value = json[key]; @@ -857,7 +858,12 @@ export class UserauthService { // Handle array tableName = key; - await this.processJsonArray(value, tableName, user_id); + await this.processJsonArray( + value, + tableName, + user_id, + resultArray, + ); } if (tableName != 'users' && tableName != 'references') { @@ -904,29 +910,32 @@ export class UserauthService { set_update = response?.set_update; update_id = response?.id; - let upsert_records_result = await this.upsertRecords( - set_update, - tableName, - tableFields, - value, - user_id, - update_id, - ); + if (tableName != 'experience') { + upsert_records_result = await this.upsertRecords( + set_update, + tableName, + tableFields, + value, + user_id, + update_id, + ); - if (upsert_records_result?.[tableName]?.extensions) { - resultArray.push({ - [tableName]: { - status: false, - message: upsert_records_result?.[tableName]?.message, - }, - }); - } else { - resultArray.push({ - [tableName]: { - status: true, - message: 'successfully updated the value', - }, - }); + if (upsert_records_result?.[tableName]?.extensions) { + resultArray.push({ + [tableName]: { + status: false, + message: + upsert_records_result?.[tableName]?.message, + }, + }); + } else { + resultArray.push({ + [tableName]: { + status: true, + message: 'successfully updated the value', + }, + }); + } } console.log('upsert_records_result-->>', upsert_records_result); @@ -959,7 +968,7 @@ export class UserauthService { return resultArray; } - public async processJsonArray(values, tableName, user_id) { + public async processJsonArray(values, tableName, user_id, resultArray?) { let set_update; let update_id; let referenceFields; @@ -1062,6 +1071,22 @@ export class UserauthService { ); } } + + if (result?.[tableName]?.extensions) { + resultArray.push({ + [tableName]: { + status: false, + message: result?.[tableName]?.message, + }, + }); + } else { + resultArray.push({ + [tableName]: { + status: true, + message: 'successfully updated the value', + }, + }); + } } } From be8ad117999979d376d372c3946a3d25b89af8d1 Mon Sep 17 00:00:00 2001 From: Tusharmahajan12 <121154132+Tusharmahajan12@users.noreply.github.com> Date: Tue, 12 Mar 2024 15:09:06 +0530 Subject: [PATCH 048/126] Task #214384 change in middle ware (#889) * IP users List * Ip user list * Ip user list filter * Change in middle ware --- .../beneficiaries/beneficiaries.controller.ts | 16 ++++++- src/src/beneficiaries/beneficiaries.module.ts | 11 ++--- .../beneficiaries/beneficiaries.service.ts | 14 ++++-- src/src/camp/camp.service.ts | 21 +++++--- src/src/common/middlewares/auth.middleware.ts | 48 +++++++++---------- .../common/middlewares/cohort.middleware.ts | 6 +-- src/src/facilitator/facilitator.service.ts | 17 +++++-- 7 files changed, 84 insertions(+), 49 deletions(-) diff --git a/src/src/beneficiaries/beneficiaries.controller.ts b/src/src/beneficiaries/beneficiaries.controller.ts index 84a96b0f9..6a559be11 100644 --- a/src/src/beneficiaries/beneficiaries.controller.ts +++ b/src/src/beneficiaries/beneficiaries.controller.ts @@ -220,11 +220,25 @@ export class BeneficiariesController { @Get(':id') @UseGuards(new AuthGuard()) - findOne( + public async findOne( @Param('id') id: string, @Req() req: any, @Res() response: Response, ) { + if (req.mw_roles?.includes('program_owner')) { + req.parent_ip_id = req.mw_ip_user_id; + } else { + const user = await this.userService.ipUserInfo(req); + req.parent_ip_id = user?.data?.program_users?.[0]?.organisation_id; + } + if (!req.parent_ip_id) { + return response.status(404).send({ + success: false, + message: 'Invalid Ip', + data: {}, + }); + } + return this.beneficiariesService.findOne(+id, response); } diff --git a/src/src/beneficiaries/beneficiaries.module.ts b/src/src/beneficiaries/beneficiaries.module.ts index 7ee1ddd7b..8cd2464de 100644 --- a/src/src/beneficiaries/beneficiaries.module.ts +++ b/src/src/beneficiaries/beneficiaries.module.ts @@ -80,7 +80,7 @@ export class BeneficiariesModule implements NestModule { .exclude( '/beneficiaries/admin/list/duplicates-by-aadhaar', '/beneficiaries/:id/is_enrollment_exists', - { path: '/beneficiaries/:id', method: RequestMethod.GET }, + { path: '/beneficiaries/:id', method: RequestMethod.DELETE }, '/beneficiaries/register', '/beneficiaries/statusUpdate', @@ -88,10 +88,9 @@ export class BeneficiariesModule implements NestModule { ) .forRoutes(BeneficiariesController); - consumer - .apply(CohortMiddleware) - .forRoutes( - {path: '/beneficiaries/getStatusWiseCount', method: RequestMethod.GET,} - ); + consumer.apply(CohortMiddleware).forRoutes({ + path: '/beneficiaries/getStatusWiseCount', + method: RequestMethod.GET, + }); } } diff --git a/src/src/beneficiaries/beneficiaries.service.ts b/src/src/beneficiaries/beneficiaries.service.ts index a015cd99d..604095a3e 100644 --- a/src/src/beneficiaries/beneficiaries.service.ts +++ b/src/src/beneficiaries/beneficiaries.service.ts @@ -681,10 +681,16 @@ export class BeneficiariesService { } public async getList(body: any, req: any, resp: any) { - const user = await this.userService.ipUserInfo(req); const program_id = req.mw_program_id; const academic_year_id = req.mw_academic_year_id; - if (!user?.data?.program_users?.[0]?.organisation_id) { + if (req.mw_roles?.includes('program_owner')) { + body.parent_ip_id = req.mw_ip_user_id; + console.log('sss', body.parent_ip_id); + } else { + const user = await this.userService.ipUserInfo(req); + body.parent_ip_id = user?.data?.program_users?.[0]?.organisation_id; + } + if (!body.parent_ip_id) { return resp.status(404).send({ success: false, message: 'Invalid Ip', @@ -700,11 +706,11 @@ export class BeneficiariesService { if (body?.reassign) { filterQueryArray.push( - `{_not: {group_users: {status: {_eq: "active"}, group: {status: {_in: ["registered", "camp_ip_verified", "change_required"]}}}}},{ program_beneficiaries: {facilitator_user: { program_faciltators: { parent_ip: { _eq: "${user?.data?.program_users[0]?.organisation_id}" } ,program_id:{_eq:${program_id}},academic_year_id:{_eq:${academic_year_id}}} } } }`, + `{_not: {group_users: {status: {_eq: "active"}, group: {status: {_in: ["registered", "camp_ip_verified", "change_required"]}}}}},{ program_beneficiaries: {facilitator_user: { program_faciltators: { parent_ip: { _eq: "${body.parent_ip_id}" } ,program_id:{_eq:${program_id}},academic_year_id:{_eq:${academic_year_id}}} } } }`, ); } else { filterQueryArray.push( - `{ program_beneficiaries: {facilitator_user: { program_faciltators: { parent_ip: { _eq: "${user?.data?.program_users[0]?.organisation_id}" },program_id:{_eq:${program_id}},academic_year_id:{_eq:${academic_year_id}} }},academic_year_id:{_eq:${academic_year_id}},program_id:{_eq:${program_id}} } }`, + `{ program_beneficiaries: {facilitator_user: { program_faciltators: { parent_ip: { _eq: "${body.parent_ip_id}" },program_id:{_eq:${program_id}},academic_year_id:{_eq:${academic_year_id}} }},academic_year_id:{_eq:${academic_year_id}},program_id:{_eq:${program_id}} } }`, ); } diff --git a/src/src/camp/camp.service.ts b/src/src/camp/camp.service.ts index 94352fb61..192dcbe20 100644 --- a/src/src/camp/camp.service.ts +++ b/src/src/camp/camp.service.ts @@ -2229,15 +2229,19 @@ export class CampService { } async getCampList(body: any, req: any, resp: any) { - const user = await this.userService.ipUserInfo(req); - if (!user?.data?.program_users?.[0]?.organisation_id) { + if (req.mw_roles?.includes('program_owner')) { + body.parent_ip_id = req.mw_ip_user_id; + } else { + const user = await this.userService.ipUserInfo(req); + body.parent_ip_id = user?.data?.program_users?.[0]?.organisation_id; + } + if (!body.parent_ip_id) { return resp.status(404).send({ success: false, message: 'Invalid Ip', data: {}, }); } - body.parent_ip_id = user?.data?.program_users?.[0]?.organisation_id; const data = await this.campcoreservice.list(body, req); if (data) { @@ -2265,9 +2269,14 @@ export class CampService { data: [], }); } - const user = await this.userService.ipUserInfo(req); - - if (!user?.data?.program_users?.[0]?.organisation_id) { + if (req.mw_roles?.includes('program_owner')) { + req.parent_ip_id = req.mw_ip_user_id; + } else { + const user = await this.userService.ipUserInfo(req); + req.parent_ip_id = + user?.data?.program_users?.[0]?.organisation_id; + } + if (!req.parent_ip_id) { return resp.status(404).send({ success: false, message: 'Invalid Ip', diff --git a/src/src/common/middlewares/auth.middleware.ts b/src/src/common/middlewares/auth.middleware.ts index c11a768e2..8cf4c0afb 100644 --- a/src/src/common/middlewares/auth.middleware.ts +++ b/src/src/common/middlewares/auth.middleware.ts @@ -52,30 +52,30 @@ export class AuthMiddleware implements NestMiddleware { const roles = decoded.resource_access.hasura.roles || []; //check if role is program_owner set x-ip-org-id in userId - if (roles.includes('program_owner')) { - if (req?.headers && req?.headers?.['x-ip-org-id']) { - userId = req.headers['x-ip-org-id']; - const result = await this.userService.getIPuser( - req, - res, - ); - const data = result?.data?.program_users?.[0]; - req.mw_userid = data?.user_id; - } else if (['/users/ip_user_info'].includes(req.baseUrl)) { - // const user = await this.userService.ipUserInfo(req); - userId = await this.userService.getUserIdFromKeycloakId( - keycloak_id, - ); - req.mw_userid = userId; - } - req.mw_roles = roles; //pass role if x-ip-org-id is not send - } else { - // const user = await this.userService.ipUserInfo(req); - userId = await this.userService.getUserIdFromKeycloakId( - keycloak_id, - ); - req.mw_userid = userId; - } + // if (roles.includes('program_owner')) { + // if (req?.headers && req?.headers?.['x-ip-org-id']) { + // userId = req.headers['x-ip-org-id']; + // const result = await this.userService.getIPuser( + // req, + // res, + // ); + // const data = result?.data?.program_users?.[0]; + // req.mw_userid = data?.user_id; + // } else if (['/users/ip_user_info'].includes(req.baseUrl)) { + // // const user = await this.userService.ipUserInfo(req); + // userId = await this.userService.getUserIdFromKeycloakId( + // keycloak_id, + // ); + // req.mw_userid = userId; + // } + // req.mw_roles = roles; //pass role if x-ip-org-id is not send + // } else { + // const user = await this.userService.ipUserInfo(req); + userId = await this.userService.getUserIdFromKeycloakId( + keycloak_id, + ); + req.mw_userid = userId; + // } if (userId) { req.mw_roles = roles; } diff --git a/src/src/common/middlewares/cohort.middleware.ts b/src/src/common/middlewares/cohort.middleware.ts index eff33a6ca..d3e66a606 100644 --- a/src/src/common/middlewares/cohort.middleware.ts +++ b/src/src/common/middlewares/cohort.middleware.ts @@ -13,7 +13,7 @@ export class CohortMiddleware implements NestMiddleware { let goToNextMw = false; //check IP User ID is present or not [x-ip-user-id] if ( - (req?.headers && req?.headers?.['x-ip-org-id']) || + req?.headers?.['x-ip-org-id'] || req?.mw_roles?.includes('program_owner') ) { req.mw_ip_user_id = req.headers['x-ip-org-id']; @@ -29,7 +29,7 @@ export class CohortMiddleware implements NestMiddleware { } } - if (req?.headers && req?.headers?.['x-program-id']) { + if (req?.headers?.['x-program-id']) { req.mw_program_id = req.headers['x-program-id']; const program_id = parseInt(req.mw_program_id, 10); if (isNaN(program_id)) { @@ -51,7 +51,7 @@ export class CohortMiddleware implements NestMiddleware { }); } - if (req?.headers && req?.headers?.['x-academic-year-id']) { + if (req?.headers?.['x-academic-year-id']) { req.mw_academic_year_id = req.headers['x-academic-year-id']; const academic_year_id = parseInt(req.mw_academic_year_id, 10); if (isNaN(academic_year_id)) { diff --git a/src/src/facilitator/facilitator.service.ts b/src/src/facilitator/facilitator.service.ts index 84dfc633e..4e2c1ba9c 100644 --- a/src/src/facilitator/facilitator.service.ts +++ b/src/src/facilitator/facilitator.service.ts @@ -1567,16 +1567,23 @@ export class FacilitatorService { } async getFacilitators(req: any, body: any, resp: any) { - const user: any = await this.userService.ipUserInfo(req); const academic_year_id = req.mw_academic_year_id; const program_id = req.mw_program_id; - if (!user?.data?.program_users?.[0]?.organisation_id) { - return resp.status(400).send({ + + if (req.mw_roles?.includes('program_owner')) { + body.parent_ip_id = req.mw_ip_user_id; + } else { + const user = await this.userService.ipUserInfo(req); + body.parent_ip_id = user?.data?.program_users?.[0]?.organisation_id; + } + if (!body.parent_ip_id) { + return resp.status(404).send({ success: false, - message: 'Invalid User', + message: 'Invalid Ip', data: {}, }); } + const page = isNaN(body.page) ? 1 : parseInt(body.page); const limit = isNaN(body.limit) ? 15 : parseInt(body.limit); @@ -1648,7 +1655,7 @@ export class FacilitatorService { } filterQueryArray.unshift( - `{program_faciltators: {id: {_is_null: false}, parent_ip: {_eq: "${user?.data?.program_users[0]?.organisation_id}"}, academic_year_id: {_eq: ${academic_year_id}},program_id:{_eq:${program_id}}}}`, + `{program_faciltators: {id: {_is_null: false}, parent_ip: {_eq: "${body.parent_ip_id}"}, academic_year_id: {_eq: ${academic_year_id}},program_id:{_eq:${program_id}}}}`, ); let filterQuery = '{ _and: [' + filterQueryArray.join(',') + '] }'; From a9b4478524ec8c5765cc850da2f129d3b5cebe43 Mon Sep 17 00:00:00 2001 From: GitVivekHub Date: Wed, 13 Mar 2024 10:42:52 +0530 Subject: [PATCH 049/126] Learner offline onboarding get api --- src/src/userauth/userauth.controller.ts | 14 + src/src/userauth/userauth.service.ts | 329 +++++++++++++++++++++++- 2 files changed, 329 insertions(+), 14 deletions(-) diff --git a/src/src/userauth/userauth.controller.ts b/src/src/userauth/userauth.controller.ts index 5d39e53e6..6fcc8b24a 100644 --- a/src/src/userauth/userauth.controller.ts +++ b/src/src/userauth/userauth.controller.ts @@ -55,4 +55,18 @@ export class UserauthController { ) { return this.userauthService.userOnboarding(body, response, request); } + + @Get('/beneficiary/user-info/:id') + @UsePipes(ValidationPipe) + public async getUserInfoDetailsForBeneficiary( + @Res() response: Response, + @Req() request: Request, + @Param('id') id: number, + ) { + return this.userauthService.getUserInfoDetailsForBeneficiary( + request, + response, + id, + ); + } } diff --git a/src/src/userauth/userauth.service.ts b/src/src/userauth/userauth.service.ts index 958e893e7..3923d705f 100644 --- a/src/src/userauth/userauth.service.ts +++ b/src/src/userauth/userauth.service.ts @@ -537,11 +537,11 @@ export class UserauthService { name: user_data?.users_by_pk?.profile_photo_1, documents: { base64: null, - document_id: profilePhoto1Documents?.[0].document_id, - name: profilePhoto1Documents?.[0].name, - document_type: profilePhoto1Documents?.[0].doument_type, + document_id: profilePhoto1Documents?.[0]?.document_id, + name: profilePhoto1Documents?.[0]?.name, + document_type: profilePhoto1Documents?.[0]?.doument_type, document_sub_type: - profilePhoto1Documents?.[0].document_sub_type, + profilePhoto1Documents?.[0]?.document_sub_type, path: profilePhoto1Documents?.[0]?.path, provider: profilePhoto1Documents?.[0]?.provider, context: profilePhoto1Documents?.[0]?.context, @@ -550,14 +550,14 @@ export class UserauthService { }; let profile_photo_2_info = { - name: user_data?.users_by_pk?.profile_photo_1, + name: user_data?.users_by_pk?.profile_photo_2, documents: { base64: null, - document_id: profilePhoto2Documents?.[0].document_id, - name: profilePhoto2Documents?.[0].name, - document_type: profilePhoto2Documents?.[0].doument_type, + document_id: profilePhoto2Documents?.[0]?.document_id, + name: profilePhoto2Documents?.[0]?.name, + document_type: profilePhoto2Documents?.[0]?.doument_type, document_sub_type: - profilePhoto2Documents?.[0].document_sub_type, + profilePhoto2Documents?.[0]?.document_sub_type, path: profilePhoto2Documents?.[0]?.path, provider: profilePhoto2Documents?.[0]?.provider, context: profilePhoto2Documents?.[0]?.context, @@ -566,14 +566,15 @@ export class UserauthService { }; let profile_photo_3_info = { - name: user_data?.users_by_pk?.profile_photo_1, + name: user_data?.users_by_pk?.profile_photo_3, documents: { base64: null, - document_id: profilePhoto3Documents?.[0].document_id, - name: profilePhoto3Documents?.[0].name, - document_type: profilePhoto3Documents?.[0].doument_type || null, + document_id: profilePhoto3Documents?.[0]?.document_id, + name: profilePhoto3Documents?.[0]?.name, + document_type: + profilePhoto3Documents?.[0]?.doument_type || null, document_sub_type: - profilePhoto3Documents?.[0].document_sub_type, + profilePhoto3Documents?.[0]?.document_sub_type, path: profilePhoto3Documents?.[0]?.path, provider: profilePhoto3Documents?.[0]?.provider, context: profilePhoto3Documents?.[0]?.context, @@ -1272,4 +1273,304 @@ export class UserauthService { console.log('resuklt-->>', result); } } + + public async getUserInfoDetailsForBeneficiary( + request, + response, + userid: any, + ) { + let user_id = userid; //get user id from token + let program_id = request?.mw_program_id; // get program_id from token + let academic_year_id = request?.mw_academic_year_id; // get academic_year_id from token + + //query to get user details information + + let query = `query MyQuery { + users_by_pk(id:${user_id}) { + first_name + middle_name + last_name + dob + aadhar_no + mobile + alternative_mobile_number + email_id + state + district + block + grampanchayat + village + pincode + gender + profile_photo_1 + profile_photo_2 + profile_photo_3 + username + mobile_no_verified + long + lat + keycloak_id + is_deactivated + is_duplicate + email_verified + duplicate_reason + aadhar_verified + aadhar_token + aadhaar_verification_mode + id + profile_photo_1 + profile_photo_1_documents: documents(where: {document_sub_type: {_eq: "profile_photo_1"}}) { + name + doument_type + document_sub_type + document_id: id + path + provider + context + context_id + } + profile_photo_2 + profile_photo_2_documents: documents(where: {document_sub_type: {_eq: "profile_photo_2"}}) { + name + doument_type + document_sub_type + document_id: id + path + provider + context + context_id + } + profile_photo_3 + profile_photo_3_documents: documents(where: {document_sub_type: {_eq: "profile_photo_3"}}) { + name + doument_type + document_sub_type + document_id: id + path + provider + context + context_id + } + core_beneficiaries { + career_aspiration + career_aspiration_details + device_ownership + device_type + type_of_learner + last_standard_of_education_year + last_standard_of_education + previous_school_type + reason_of_leaving_education + education_10th_exam_year + alternative_device_ownership + alternative_device_type + mother_first_name + mother_middle_name + mother_last_name + father_first_name + father_middle_name + father_last_name + } + extended_users { + marital_status + social_category + } + program_beneficiaries(where: {academic_year_id: {_eq:${academic_year_id}}, program_id: {_eq:${program_id}}}) { + learning_level + learning_motivation + type_of_support_needed + facilitator_id + status + } + references { + first_name + last_name + middle_name + relation + contact_number + context + context_id + } + } + } + + + `; + + const hasura_response = await this.hasuraServiceFromServices.getData({ + query: query, + }); + + let user_data = hasura_response?.data; + + // get profile photo document details + let profilePhoto1Documents = + user_data?.users_by_pk?.profile_photo_1_documents; + + let profilePhoto2Documents = + user_data?.users_by_pk?.profile_photo_2_documents; + + let profilePhoto3Documents = + user_data?.users_by_pk?.profile_photo_3_documents; + + // modifiy individual profile photo document details as required + + let profile_photo_1_info = { + name: user_data?.users_by_pk?.profile_photo_1, + documents: { + base64: null, + document_id: profilePhoto1Documents?.[0]?.document_id, + name: profilePhoto1Documents?.[0]?.name, + document_type: profilePhoto1Documents?.[0]?.doument_type, + document_sub_type: + profilePhoto1Documents?.[0]?.document_sub_type, + path: profilePhoto1Documents?.[0]?.path, + provider: profilePhoto1Documents?.[0]?.provider, + context: profilePhoto1Documents?.[0]?.context, + context_id: profilePhoto1Documents?.[0]?.context_id, + }, + }; + + let profile_photo_2_info = { + name: user_data?.users_by_pk?.profile_photo_2, + documents: { + base64: null, + document_id: profilePhoto2Documents?.[0]?.document_id, + name: profilePhoto2Documents?.[0]?.name, + document_type: profilePhoto2Documents?.[0]?.doument_type, + document_sub_type: + profilePhoto2Documents?.[0]?.document_sub_type, + path: profilePhoto2Documents?.[0]?.path, + provider: profilePhoto2Documents?.[0]?.provider, + context: profilePhoto2Documents?.[0]?.context, + context_id: profilePhoto2Documents?.[0]?.context_id, + }, + }; + + let profile_photo_3_info = { + name: user_data?.users_by_pk?.profile_photo_3, + documents: { + base64: null, + document_id: profilePhoto3Documents?.[0]?.document_id, + name: profilePhoto3Documents?.[0]?.name, + document_type: + profilePhoto3Documents?.[0]?.doument_type || null, + document_sub_type: + profilePhoto3Documents?.[0]?.document_sub_type, + path: profilePhoto3Documents?.[0]?.path, + provider: profilePhoto3Documents?.[0]?.provider, + context: profilePhoto3Documents?.[0]?.context, + context_id: profilePhoto3Documents?.[0]?.context_id, + }, + }; + + if (!user_data?.users_by_pk) { + user_data.users_by_pk = {}; // Initialize as an empty object if it doesn't exist + } + // Replacing profile_photo_documents with profile_photo for all details + user_data.users_by_pk.profile_photo_1 = profile_photo_1_info; + user_data.users_by_pk.profile_photo_2 = profile_photo_2_info; + user_data.users_by_pk.profile_photo_3 = profile_photo_3_info; + + // Removing profile_photo_documents object + delete user_data.users_by_pk.profile_photo_1_documents; + delete user_data.users_by_pk.profile_photo_2_documents; + delete user_data.users_by_pk.profile_photo_3_documents; + + user_data.users_by_pk.program_beneficiaries = + user_data?.users_by_pk?.program_beneficiaries?.reduce((acc, pb) => { + pb ? pb : {}; + + return { ...acc, ...pb }; + }, {}); + + user_data.users_by_pk.references = + user_data?.users_by_pk?.references?.reduce((acc, rf) => { + rf ? rf : {}; + + return { ...acc, ...rf }; + }, {}); + + const { + first_name, + middle_name, + last_name, + dob, + aadhar_no, + mobile, + alternative_mobile_number, + email_id, + state, + district, + block, + grampanchayat, + village, + pincode, + gender, + profile_photo_1, + profile_photo_2, + profile_photo_3, + username, + mobile_no_verified, + long, + lat, + keycloak_id, + is_deactivated, + is_duplicate, + email_verified, + duplicate_reason, + aadhar_verified, + aadhar_token, + aadhaar_verification_mode, + id, + } = user_data?.users_by_pk || {}; + + const formattedData = { + users: { + first_name, + middle_name, + last_name, + dob, + aadhar_no, + mobile, + alternative_mobile_number, + email_id, + state, + district, + block, + grampanchayat, + village, + pincode, + gender, + profile_photo_1, + profile_photo_2, + profile_photo_3, + username, + mobile_no_verified, + long, + lat, + keycloak_id, + is_deactivated, + is_duplicate, + email_verified, + duplicate_reason, + aadhar_verified, + aadhar_token, + aadhaar_verification_mode, + id, + }, + core_beneficiaries: user_data?.users_by_pk?.core_beneficiaries, + extended_users: user_data?.users_by_pk?.extended_users, + references: user_data?.users_by_pk?.references, + program_beneficiaries: + user_data?.users_by_pk?.program_beneficiaries, + }; + + if (user_data) { + return response.status(200).json({ + message: 'Data retrieved successfully!', + data: formattedData, + }); + } + } } From e346a5315f734c9dfef7f97ffdf03200a913e19c Mon Sep 17 00:00:00 2001 From: Tusharmahajan12 <121154132+Tusharmahajan12@users.noreply.github.com> Date: Wed, 13 Mar 2024 11:07:50 +0530 Subject: [PATCH 050/126] Added role in IP user (#893) --- src/src/modules/auth/auth.service.ts | 11 +++++++-- src/src/user/user.controller.ts | 10 ++++++++ src/src/user/user.service.ts | 34 ++++++++++++++++++++++++++-- 3 files changed, 51 insertions(+), 4 deletions(-) diff --git a/src/src/modules/auth/auth.service.ts b/src/src/modules/auth/auth.service.ts index 826d7900d..66fdda24e 100644 --- a/src/src/modules/auth/auth.service.ts +++ b/src/src/modules/auth/auth.service.ts @@ -504,7 +504,8 @@ export class AuthService { if ( !body.role_fields.organisation_id || !body.role_fields.program_id || - !body.role_fields.academic_year_id + !body.role_fields.academic_year_id || + !body.role_fields.role_slug ) { misssingFieldsFlag = true; } @@ -628,6 +629,9 @@ export class AuthService { if (body.role_fields.organisation_id) { body.organisation_id = body.role_fields.organisation_id; } + if (body.role_fields.role_slug) { + body.role_slug = body.role_fields.role_slug; + } if (body.role === 'facilitator' && body.hasOwnProperty('dob')) { delete body.dob; } @@ -797,6 +801,7 @@ export class AuthService { async newCreate(req: any) { const tableName = 'users'; + let other = []; const newR = await this.hasuraService.q( tableName, { ...req, aadhar_verified: 'pending' }, @@ -841,7 +846,8 @@ export class AuthService { req.organisation_id = `${req.role_fields.organisation_id}`; req.program_id = req.role_fields.program_id; req.academic_year_id = req.role_fields.academic_year_id; - req.status = null; + req.role_slug = req.role_fields.role_slug; + other = [...other, 'role_slug']; } console.log('tableName', programRoleTableName); console.log('groupId', groupId); @@ -861,6 +867,7 @@ export class AuthService { 'program_id', 'academic_year_id', 'status', + ...(other || []), ], ); } diff --git a/src/src/user/user.controller.ts b/src/src/user/user.controller.ts index c99c5be45..a07904501 100755 --- a/src/src/user/user.controller.ts +++ b/src/src/user/user.controller.ts @@ -273,6 +273,16 @@ export class UserController { ) { return this.userService.getIpDetails(id, body, request, response); } + + @Post('/roles/list') + @UseGuards(new AuthGuard()) + getRoleList( + @Body() body: Record, + @Req() req: any, + @Res() response: Response, + ) { + return this.userService.getRoleList(body, req, response); + } /**************************************************************************/ /******************************* V2 APIs **********************************/ /**************************************************************************/ diff --git a/src/src/user/user.service.ts b/src/src/user/user.service.ts index a7d524771..04caff2fc 100644 --- a/src/src/user/user.service.ts +++ b/src/src/user/user.service.ts @@ -1786,6 +1786,7 @@ export class UserService { ${tableName}(where: {program_id: {_eq: ${mw_program_id}},academic_year_id: {_eq: ${mw_academic_year_id}},organisation_id:{_eq:${org_id}}, program_organisation: {status: {_eq: "active"}}}){ id user_id + role_slug } }`, }; @@ -1827,7 +1828,7 @@ export class UserService { ...onlyfilter, `program_users(where:{ ${programUserFilter} - }){academic_year_id program_id status organisation_id role_id}`, + }){academic_year_id program_id status organisation_id role_id role_slug}`, ], { ...body, onlyfilter: [...onlyfilter, 'core'] }, ); @@ -1858,7 +1859,7 @@ export class UserService { program_id role_id organisation_id - + role_slug } } @@ -1882,4 +1883,33 @@ export class UserService { }); } } + + public async getRoleList(body: any, req: any, resp) { + let qury = `query MyQuery { + roles { + id + role_type + slug + actions + } + } + `; + const data = { query: qury }; + const response = await this.hasuraServiceFromServices.getData(data); + const newQdata = response?.data?.roles; + + if (newQdata.length == 0) { + return resp.status(422).json({ + success: false, + message: 'Data Not found!', + data: {}, + }); + } else { + return resp.status(200).json({ + success: true, + message: 'Data found successfully!', + data: newQdata || {}, + }); + } + } } From f1654d2cd1d46149c65609dcbe7f7a525bca2034 Mon Sep 17 00:00:00 2001 From: Tusharmahajan12 <121154132+Tusharmahajan12@users.noreply.github.com> Date: Wed, 13 Mar 2024 11:36:34 +0530 Subject: [PATCH 051/126] Task #215324 [BE] Organisation Already exists and Task #215391 [BE] IP user exists List (#892) * IP users List * Ip user list * Ip user list filter * Change in middle ware * Organisation and IP users list exists api * Organisation and IP users list exists api * conflicts solve --- .../organisation/organisation.controller.ts | 14 ++++++ src/src/organisation/organisation.service.ts | 43 +++++++++++++++++++ src/src/user/user.controller.ts | 17 ++++++++ src/src/user/user.service.ts | 36 ++++++++++++++++ 4 files changed, 110 insertions(+) diff --git a/src/src/organisation/organisation.controller.ts b/src/src/organisation/organisation.controller.ts index 0915d1b15..80ea8edf4 100644 --- a/src/src/organisation/organisation.controller.ts +++ b/src/src/organisation/organisation.controller.ts @@ -52,4 +52,18 @@ export class OrganisationController { id, ); } + + @Get('/exist_list') + @UseGuards(new AuthGuard()) + getOrganisationExists( + @Body() body: Record, + @Req() req: any, + @Res() response: Response, + ) { + return this.organisationService.getOrganisationExists( + body, + req, + response, + ); + } } diff --git a/src/src/organisation/organisation.service.ts b/src/src/organisation/organisation.service.ts index 7a4be9140..9018ed1ab 100644 --- a/src/src/organisation/organisation.service.ts +++ b/src/src/organisation/organisation.service.ts @@ -216,4 +216,47 @@ export class OrganisationService { }); } } + + public async getOrganisationExists(body: any, req: any, resp: any) { + const academic_year_id = req?.mw_academic_year_id; + const program_id = req?.mw_program_id; + + try { + let data = { + query: `query MyQuery { + organisations(where: {_not: {program_organisations: {academic_year_id: {_eq: ${academic_year_id}}, program_id: {_eq: ${program_id}}}}}) { + id + name + } + } + `, + }; + + const response = await this.hasuraServiceFromServices.getData(data); + + const organisations = response?.data?.organisations || []; + + if (organisations.length > 0) { + return resp.status(200).send({ + success: true, + message: 'Organisation exists', + data: organisations, + }); + } else { + return resp.status(422).send({ + success: true, + message: 'Organisation not exists', + data: organisations, + }); + } + } catch (error) { + // Log error and return a generic error response + console.error('Error fetching organizations:', error); + return resp.status(422).send({ + success: false, + message: 'An error occurred while fetching organizations', + data: {}, + }); + } + } } diff --git a/src/src/user/user.controller.ts b/src/src/user/user.controller.ts index a07904501..0935c4d15 100755 --- a/src/src/user/user.controller.ts +++ b/src/src/user/user.controller.ts @@ -263,6 +263,7 @@ export class UserController { ) { return this.userService.getIpUserList(body, req, response); } + @Post('/ip/:id') @UseGuards(new AuthGuard()) getIpDetails( @@ -274,6 +275,22 @@ export class UserController { return this.userService.getIpDetails(id, body, request, response); } + @Get('/ip_users/exist_list') + @UseGuards(new AuthGuard()) + getIpUserListExists( + @Req() request: any, + @Body() body: any, + @Param('id') id: number, + @Res() response: any, + ) { + return this.userService.getIpUserListExists( + id, + body, + request, + response, + ); + } + @Post('/roles/list') @UseGuards(new AuthGuard()) getRoleList( diff --git a/src/src/user/user.service.ts b/src/src/user/user.service.ts index 04caff2fc..8ea0ed513 100644 --- a/src/src/user/user.service.ts +++ b/src/src/user/user.service.ts @@ -1884,6 +1884,41 @@ export class UserService { } } + public async getIpUserListExists(id: any, body: any, req: any, resp) { + const program_id = req.mw_program_id; + const academic_year_id = req.mw_academic_year_id; + + let qury = `query MyQuery { + users(where: {program_users:{},_not: {program_users: {academic_year_id: {_eq: ${academic_year_id}}, program_id: {_eq: ${program_id}}}}}) { + id + first_name + last_name + middle_name + program_users { + academic_year_id + program_id + user_id + } + + `; + const data = { query: qury }; + const response = await this.hasuraServiceFromServices.getData(data); + const newQdata = response?.data?.users; + if (newQdata.length == 0) { + return resp.status(422).json({ + success: false, + message: 'Data Not found!', + data: {}, + }); + } else { + return resp.status(200).json({ + success: true, + message: 'Data found successfully!', + data: newQdata || {}, + }); + } + } + public async getRoleList(body: any, req: any, resp) { let qury = `query MyQuery { roles { @@ -1896,6 +1931,7 @@ export class UserService { `; const data = { query: qury }; const response = await this.hasuraServiceFromServices.getData(data); + const newQdata = response?.data?.roles; if (newQdata.length == 0) { From b04ae556659fc84710b411ee7cfe362014681644 Mon Sep 17 00:00:00 2001 From: Tusharmahajan12 <121154132+Tusharmahajan12@users.noreply.github.com> Date: Wed, 13 Mar 2024 14:23:53 +0530 Subject: [PATCH 052/126] Task #214384 [BE] Add PO Role in Auth middle-ware (#896) * IP users List * Ip user list * Ip user list filter * Change in middle ware * Organisation and IP users list exists api * Organisation and IP users list exists api * conflicts solve * solved role base issue --- .../beneficiaries/beneficiaries.controller.ts | 8 +++++++- .../beneficiaries/beneficiaries.service.ts | 16 +++++++++------ src/src/camp/camp.core.service.ts | 2 +- src/src/camp/camp.service.ts | 20 ++++++++++++++----- src/src/facilitator/facilitator.service.ts | 13 ++++++++---- 5 files changed, 42 insertions(+), 17 deletions(-) diff --git a/src/src/beneficiaries/beneficiaries.controller.ts b/src/src/beneficiaries/beneficiaries.controller.ts index 6a559be11..ceb729bac 100644 --- a/src/src/beneficiaries/beneficiaries.controller.ts +++ b/src/src/beneficiaries/beneficiaries.controller.ts @@ -229,8 +229,14 @@ export class BeneficiariesController { req.parent_ip_id = req.mw_ip_user_id; } else { const user = await this.userService.ipUserInfo(req); - req.parent_ip_id = user?.data?.program_users?.[0]?.organisation_id; + if (req.mw_roles?.includes('staff')) { + req.parent_ip_id = + user?.data?.program_users?.[0]?.organisation_id; + } else if (req.mw_roles?.includes('facilitator')) { + req.parent_ip_id = user?.data?.program_faciltators?.parent_ip; + } } + if (!req.parent_ip_id) { return response.status(404).send({ success: false, diff --git a/src/src/beneficiaries/beneficiaries.service.ts b/src/src/beneficiaries/beneficiaries.service.ts index 604095a3e..3da786d98 100644 --- a/src/src/beneficiaries/beneficiaries.service.ts +++ b/src/src/beneficiaries/beneficiaries.service.ts @@ -684,13 +684,17 @@ export class BeneficiariesService { const program_id = req.mw_program_id; const academic_year_id = req.mw_academic_year_id; if (req.mw_roles?.includes('program_owner')) { - body.parent_ip_id = req.mw_ip_user_id; - console.log('sss', body.parent_ip_id); + req.parent_ip_id = req.mw_ip_user_id; } else { const user = await this.userService.ipUserInfo(req); - body.parent_ip_id = user?.data?.program_users?.[0]?.organisation_id; + if (req.mw_roles?.includes('staff')) { + req.parent_ip_id = + user?.data?.program_users?.[0]?.organisation_id; + } else if (req.mw_roles?.includes('facilitator')) { + req.parent_ip_id = user?.data?.program_faciltators?.parent_ip; + } } - if (!body.parent_ip_id) { + if (!req.parent_ip_id) { return resp.status(404).send({ success: false, message: 'Invalid Ip', @@ -706,11 +710,11 @@ export class BeneficiariesService { if (body?.reassign) { filterQueryArray.push( - `{_not: {group_users: {status: {_eq: "active"}, group: {status: {_in: ["registered", "camp_ip_verified", "change_required"]}}}}},{ program_beneficiaries: {facilitator_user: { program_faciltators: { parent_ip: { _eq: "${body.parent_ip_id}" } ,program_id:{_eq:${program_id}},academic_year_id:{_eq:${academic_year_id}}} } } }`, + `{_not: {group_users: {status: {_eq: "active"}, group: {status: {_in: ["registered", "camp_ip_verified", "change_required"]}}}}},{ program_beneficiaries: {facilitator_user: { program_faciltators: { parent_ip: { _eq: "${req.parent_ip_id}" } ,program_id:{_eq:${program_id}},academic_year_id:{_eq:${academic_year_id}}} } } }`, ); } else { filterQueryArray.push( - `{ program_beneficiaries: {facilitator_user: { program_faciltators: { parent_ip: { _eq: "${body.parent_ip_id}" },program_id:{_eq:${program_id}},academic_year_id:{_eq:${academic_year_id}} }},academic_year_id:{_eq:${academic_year_id}},program_id:{_eq:${program_id}} } }`, + `{ program_beneficiaries: {facilitator_user: { program_faciltators: { parent_ip: { _eq: "${req.parent_ip_id}" },program_id:{_eq:${program_id}},academic_year_id:{_eq:${academic_year_id}} }},academic_year_id:{_eq:${academic_year_id}},program_id:{_eq:${program_id}} } }`, ); } diff --git a/src/src/camp/camp.core.service.ts b/src/src/camp/camp.core.service.ts index 5d39ca188..096f7368a 100644 --- a/src/src/camp/camp.core.service.ts +++ b/src/src/camp/camp.core.service.ts @@ -82,7 +82,7 @@ export class CampCoreService { let offset = page > 1 ? limit * (page - 1) : 0; const program_id = req.mw_program_id; const academic_year_id = req.mw_academic_year_id; - let parent_ip_id = body?.parent_ip_id; + let parent_ip_id = req?.parent_ip_id; let status = body?.status; filterQueryArray.push( diff --git a/src/src/camp/camp.service.ts b/src/src/camp/camp.service.ts index 192dcbe20..88adf9c4d 100644 --- a/src/src/camp/camp.service.ts +++ b/src/src/camp/camp.service.ts @@ -2230,12 +2230,17 @@ export class CampService { async getCampList(body: any, req: any, resp: any) { if (req.mw_roles?.includes('program_owner')) { - body.parent_ip_id = req.mw_ip_user_id; + req.parent_ip_id = req.mw_ip_user_id; } else { const user = await this.userService.ipUserInfo(req); - body.parent_ip_id = user?.data?.program_users?.[0]?.organisation_id; + if (req.mw_roles?.includes('staff')) { + req.parent_ip_id = + user?.data?.program_users?.[0]?.organisation_id; + } else if (req.mw_roles?.includes('facilitator')) { + req.parent_ip_id = user?.data?.program_faciltators?.parent_ip; + } } - if (!body.parent_ip_id) { + if (!req.parent_ip_id) { return resp.status(404).send({ success: false, message: 'Invalid Ip', @@ -2273,8 +2278,13 @@ export class CampService { req.parent_ip_id = req.mw_ip_user_id; } else { const user = await this.userService.ipUserInfo(req); - req.parent_ip_id = - user?.data?.program_users?.[0]?.organisation_id; + if (req.mw_roles?.includes('staff')) { + req.parent_ip_id = + user?.data?.program_users?.[0]?.organisation_id; + } else if (req.mw_roles?.includes('facilitator')) { + req.parent_ip_id = + user?.data?.program_faciltators?.parent_ip; + } } if (!req.parent_ip_id) { return resp.status(404).send({ diff --git a/src/src/facilitator/facilitator.service.ts b/src/src/facilitator/facilitator.service.ts index 4e2c1ba9c..869ce4c4b 100644 --- a/src/src/facilitator/facilitator.service.ts +++ b/src/src/facilitator/facilitator.service.ts @@ -1571,12 +1571,17 @@ export class FacilitatorService { const program_id = req.mw_program_id; if (req.mw_roles?.includes('program_owner')) { - body.parent_ip_id = req.mw_ip_user_id; + req.parent_ip_id = req.mw_ip_user_id; } else { const user = await this.userService.ipUserInfo(req); - body.parent_ip_id = user?.data?.program_users?.[0]?.organisation_id; + if (req.mw_roles?.includes('staff')) { + req.parent_ip_id = + user?.data?.program_users?.[0]?.organisation_id; + } else if (req.mw_roles?.includes('facilitator')) { + req.parent_ip_id = user?.data?.program_faciltators?.parent_ip; + } } - if (!body.parent_ip_id) { + if (!req.parent_ip_id) { return resp.status(404).send({ success: false, message: 'Invalid Ip', @@ -1655,7 +1660,7 @@ export class FacilitatorService { } filterQueryArray.unshift( - `{program_faciltators: {id: {_is_null: false}, parent_ip: {_eq: "${body.parent_ip_id}"}, academic_year_id: {_eq: ${academic_year_id}},program_id:{_eq:${program_id}}}}`, + `{program_faciltators: {id: {_is_null: false}, parent_ip: {_eq: "${req.parent_ip_id}"}, academic_year_id: {_eq: ${academic_year_id}},program_id:{_eq:${program_id}}}}`, ); let filterQuery = '{ _and: [' + filterQueryArray.join(',') + '] }'; From d913ccd8ec88c716a95936fcc8670ccafb3266b0 Mon Sep 17 00:00:00 2001 From: Tusharmahajan12 <121154132+Tusharmahajan12@users.noreply.github.com> Date: Wed, 13 Mar 2024 17:56:46 +0530 Subject: [PATCH 053/126] Task #215454 [BE] Get Cohort List of Program ID Task #215443 [BE] Get Cohort List of Academic Year (#898) * Cohort list of academic year and program id * Change in query for role list --- src/src/user/user.controller.ts | 20 +++++++++++ src/src/user/user.module.ts | 2 ++ src/src/user/user.service.ts | 64 ++++++++++++++++++++++++++++++++- 3 files changed, 85 insertions(+), 1 deletion(-) diff --git a/src/src/user/user.controller.ts b/src/src/user/user.controller.ts index 0935c4d15..bcfcd9182 100755 --- a/src/src/user/user.controller.ts +++ b/src/src/user/user.controller.ts @@ -300,6 +300,26 @@ export class UserController { ) { return this.userService.getRoleList(body, req, response); } + + @Get('/cohort/academic_list') + @UseGuards(new AuthGuard()) + getCohortAcademicList( + @Body() request: Record, + @Req() req: any, + @Res() response: Response, + ) { + return this.userService.getCohortAcademicList(request, req, response); + } + + @Get('/cohort/program_list') + @UseGuards(new AuthGuard()) + getCohortProgramList( + @Body() request: Record, + @Req() req: any, + @Res() response: Response, + ) { + return this.userService.getCohortProgramList(request, req, response); + } /**************************************************************************/ /******************************* V2 APIs **********************************/ /**************************************************************************/ diff --git a/src/src/user/user.module.ts b/src/src/user/user.module.ts index 54a8711b0..f789a968d 100644 --- a/src/src/user/user.module.ts +++ b/src/src/user/user.module.ts @@ -43,6 +43,8 @@ export class UserModule implements NestModule { 'v2/users/is_user_exist/:role', 'users/ip/list', 'users/cohort/ip_list', + 'users/cohort/academic_list', + 'users/cohort/program_list', ) .forRoutes(UserController); } diff --git a/src/src/user/user.service.ts b/src/src/user/user.service.ts index 8ea0ed513..ece7e7337 100644 --- a/src/src/user/user.service.ts +++ b/src/src/user/user.service.ts @@ -1921,7 +1921,7 @@ export class UserService { public async getRoleList(body: any, req: any, resp) { let qury = `query MyQuery { - roles { + roles(where: {_not: {slug: {_in: ["program_owner","facilitator","beneficiary","staff"]}}}) { id role_type slug @@ -1948,4 +1948,66 @@ export class UserService { }); } } + + public async getCohortAcademicList(body: any, req: any, resp: any) { + try { + let data = { + query: `query MyQuery { + academic_years{ + id + name + } + } + `, + }; + const response = await this.hasuraServiceFromServices.getData(data); + + const list = response?.data?.academic_years || []; + + return resp.status(200).send({ + success: true, + message: 'Academic Year Id found successfully', + data: list, + }); + } catch (error) { + console.error('Error fetching cohort IP list:', error); + return resp.status(500).send({ + success: false, + message: 'An error occurred while fetching cohort IP list', + data: {}, + }); + } + } + + public async getCohortProgramList(body: any, req: any, resp: any) { + try { + let data = { + query: `query MyQuery { + programs{ + id name + state{ + state_name + } + } + } + `, + }; + const response = await this.hasuraServiceFromServices.getData(data); + + const list = response?.data?.programs || []; + + return resp.status(200).send({ + success: true, + message: 'Program Id found successfully', + data: list, + }); + } catch (error) { + console.error('Error fetching cohort IP list:', error); + return resp.status(500).send({ + success: false, + message: 'An error occurred while fetching cohort IP list', + data: {}, + }); + } + } } From c1481e34e078cc3d9d20ac9e1ab764560f8a9395 Mon Sep 17 00:00:00 2001 From: Tusharmahajan12 <121154132+Tusharmahajan12@users.noreply.github.com> Date: Wed, 13 Mar 2024 18:39:11 +0530 Subject: [PATCH 054/126] Task #215203 [BE] Create Organisation with Associated Cohort (#899) * Cohort list of academic year and program id * Change in query for role list * Added validation in Orgaisation create * Added validation in Orgaisation create --- src/src/camp/camp.service.ts | 1 + src/src/organisation/organisation.service.ts | 34 +++++++++++++++++++- 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/src/src/camp/camp.service.ts b/src/src/camp/camp.service.ts index 88adf9c4d..aa4f082c4 100644 --- a/src/src/camp/camp.service.ts +++ b/src/src/camp/camp.service.ts @@ -2247,6 +2247,7 @@ export class CampService { data: {}, }); } + const data = await this.campcoreservice.list(body, req); if (data) { diff --git a/src/src/organisation/organisation.service.ts b/src/src/organisation/organisation.service.ts index 9018ed1ab..6400f2fe0 100644 --- a/src/src/organisation/organisation.service.ts +++ b/src/src/organisation/organisation.service.ts @@ -10,18 +10,50 @@ export class OrganisationService { ) {} async create(body: any, request: any, response: any) { + let checkemail = { + query: `query MyQuery { + organisations_aggregate(where: {email_id: {_eq: "${body?.email_id}"}}){ + aggregate{ + count + } + } + }`, + }; + const emailcount = await this.hasuraServiceFromServices.getData( + checkemail, + ); + const count = + emailcount?.data?.organisations_aggregate?.aggregate?.count; + + if (count > 0) { + return response.status(422).send({ + success: false, + key: 'email_id', + message: 'Email ID Already Exists', + data: {}, + }); + } const organisationData = { name: body?.name, mobile: body?.mobile, contact_person: body?.contact_person, address: body?.address, + email_id: body?.email_id, + learner_target: body?.learner_target, }; const tableName = 'organisations'; const newOrganisation = await this.hasuraService.q( tableName, organisationData, - ['name', 'mobile', 'contact_person', 'address'], + [ + 'name', + 'mobile', + 'contact_person', + 'address', + 'email_id', + 'learner_target', + ], ); if (!newOrganisation || !newOrganisation?.organisations.id) { From ffeee785b3036819a31e3f688c40df7ce921bda3 Mon Sep 17 00:00:00 2001 From: GitVivekHub Date: Thu, 14 Mar 2024 17:45:54 +0530 Subject: [PATCH 055/126] Profile photos base64 values provided --- src/package-lock.json | 2 +- src/package.json | 2 +- src/src/upload-file/upload-file.service.ts | 2 + src/src/userauth/userauth.module.ts | 5 +- src/src/userauth/userauth.service.ts | 77 ++++++++++++++++++++-- 5 files changed, 81 insertions(+), 7 deletions(-) diff --git a/src/package-lock.json b/src/package-lock.json index 37f328d6c..f10bef8eb 100644 --- a/src/package-lock.json +++ b/src/package-lock.json @@ -23,7 +23,7 @@ "@sentry/node": "^7.52.1", "atob": "^2.1.2", "aws-sdk": "^2.1454.0", - "axios": "^1.3.4", + "axios": "^1.6.7", "cache-manager": "^3.6.0", "cache-manager-redis-store": "^2.0.0", "class-transformer": "^0.5.1", diff --git a/src/package.json b/src/package.json index f17bbb1ad..69f5f508c 100644 --- a/src/package.json +++ b/src/package.json @@ -34,7 +34,7 @@ "@sentry/node": "^7.52.1", "atob": "^2.1.2", "aws-sdk": "^2.1454.0", - "axios": "^1.3.4", + "axios": "^1.6.7", "cache-manager": "^3.6.0", "cache-manager-redis-store": "^2.0.0", "class-transformer": "^0.5.1", diff --git a/src/src/upload-file/upload-file.service.ts b/src/src/upload-file/upload-file.service.ts index 8d0aaa95f..1bf3cb765 100644 --- a/src/src/upload-file/upload-file.service.ts +++ b/src/src/upload-file/upload-file.service.ts @@ -230,6 +230,8 @@ export class UploadFileService { } } + console.log('name---->>', documentData.name); + const fileUrl = await this.s3Service.getFileUrl(documentData.name); let result; if (fileUrl) { diff --git a/src/src/userauth/userauth.module.ts b/src/src/userauth/userauth.module.ts index 7c91dae01..5d40e3e63 100644 --- a/src/src/userauth/userauth.module.ts +++ b/src/src/userauth/userauth.module.ts @@ -16,6 +16,8 @@ import { Method } from '../common/method/method'; import { AcknowledgementModule } from '../modules/acknowledgement/acknowledgement.module'; import { CohortMiddleware } from 'src/common/middlewares/cohort.middleware'; import { AuthMiddleware } from '../common/middlewares/auth.middleware'; +import { S3Module } from 'src/services/s3/s3.module'; +import { UploadFileService } from 'src/upload-file/upload-file.service'; @Module({ imports: [ @@ -25,9 +27,10 @@ import { AuthMiddleware } from '../common/middlewares/auth.middleware'; HelperModule, UserModule, AcknowledgementModule, + S3Module, ], controllers: [UserauthController], - providers: [UserauthService, AuthService, Method], + providers: [UserauthService, UploadFileService, AuthService, Method], exports: [UserauthService], }) export class UserauthModule implements NestModule { diff --git a/src/src/userauth/userauth.service.ts b/src/src/userauth/userauth.service.ts index 3923d705f..edfa92f87 100644 --- a/src/src/userauth/userauth.service.ts +++ b/src/src/userauth/userauth.service.ts @@ -8,6 +8,11 @@ import { AuthService } from 'src/modules/auth/auth.service'; import { Method } from '../common/method/method'; import { AcknowledgementService } from 'src/modules/acknowledgement/acknowledgement.service'; import { UserService } from 'src/user/user.service'; +import { S3Service } from 'src/services/s3/s3.service'; +const axios = require('axios'); +const fs = require('fs'); +const https = require('https'); +const path = require('path'); @Injectable() export class UserauthService { @@ -24,6 +29,7 @@ export class UserauthService { private authService: AuthService, private acknowledgementService: AcknowledgementService, private userService: UserService, + private readonly s3Service: S3Service, private method: Method, ) {} @@ -357,6 +363,24 @@ export class UserauthService { } } + async fetchFileAndConvertToBase64(fileUrl, agent) { + try { + const file = await axios.get(fileUrl, { + responseType: 'arraybuffer', + httpsAgent: agent, + }); + + const extension = path.extname(fileUrl.split('/').pop()).substr(1); + const base64 = Buffer.from(file?.data, 'binary').toString('base64'); + const dataUrl = `data:image/${extension};base64,${base64}`; + + return dataUrl; + } catch (error) { + console.error('Error fetching file and converting to base64:'); + return null; + } + } + public async getUserInfoDetails(request, response) { let user_id = request.mw_userid; //get user id from token let program_id = request?.mw_program_id; // get program_id from token @@ -533,10 +557,45 @@ export class UserauthService { // modifiy individual profile photo document details as required + const agent = new https.Agent({ + rejectUnauthorized: false, // Ignore SSL certificate validation + }); + + // get file url and convert to base64 + const profile_photo_1_file_Url = await this.s3Service.getFileUrl( + profilePhoto1Documents?.[0]?.name, + ); + + const profile_photo_2_file_Url = await this.s3Service.getFileUrl( + profilePhoto2Documents?.[0]?.name, + ); + + const profile_photo_3_file_Url = await this.s3Service.getFileUrl( + profilePhoto3Documents?.[0]?.name, + ); + + const profilePhotoUrls = [ + profile_photo_1_file_Url, + profile_photo_2_file_Url, + profile_photo_3_file_Url, + ]; + + const base64Profiles = await Promise.all( + profilePhotoUrls.map((url) => + this.fetchFileAndConvertToBase64(url, agent), + ), + ); + + const [ + data_base64_profile_1, + data_base64_profile_2, + data_base64_profile_3, + ] = base64Profiles; + let profile_photo_1_info = { name: user_data?.users_by_pk?.profile_photo_1, documents: { - base64: null, + base64: data_base64_profile_1, document_id: profilePhoto1Documents?.[0]?.document_id, name: profilePhoto1Documents?.[0]?.name, document_type: profilePhoto1Documents?.[0]?.doument_type, @@ -552,7 +611,7 @@ export class UserauthService { let profile_photo_2_info = { name: user_data?.users_by_pk?.profile_photo_2, documents: { - base64: null, + base64: data_base64_profile_2, document_id: profilePhoto2Documents?.[0]?.document_id, name: profilePhoto2Documents?.[0]?.name, document_type: profilePhoto2Documents?.[0]?.doument_type, @@ -568,7 +627,7 @@ export class UserauthService { let profile_photo_3_info = { name: user_data?.users_by_pk?.profile_photo_3, documents: { - base64: null, + base64: data_base64_profile_3, document_id: profilePhoto3Documents?.[0]?.document_id, name: profilePhoto3Documents?.[0]?.name, document_type: @@ -622,9 +681,18 @@ export class UserauthService { user_data.users_by_pk.qualifications = user_data?.users_by_pk?.qualifications?.reduce((acc, q) => { + const qualification_file_url = this.s3Service.getFileUrl( + q?.document_reference?.name, + ); + + const base64Qualifications = this.fetchFileAndConvertToBase64( + qualification_file_url, + agent, + ); + const documents = q.document_reference ? { - base64: q?.document_reference?.base64, + base64: null, document_id: q?.document_reference?.document_id, name: q?.document_reference?.name, path: q?.document_reference?.path, @@ -636,6 +704,7 @@ export class UserauthService { delete q.document_reference; // Remove document_reference + // Update accumulator with updated qualification object return { ...acc, ...q, documents }; }, {}); From 6a940f22e7443ed780e615f3dfe6767e282e9b13 Mon Sep 17 00:00:00 2001 From: Tusharmahajan12 <121154132+Tusharmahajan12@users.noreply.github.com> Date: Thu, 14 Mar 2024 18:50:43 +0530 Subject: [PATCH 056/126] Task #215203 [BE] Create Organisation with Associated Cohort added document_id (#903) * Cohort list of academic year and program id * Change in query for role list * Added validation in Orgaisation create * Added validation in Orgaisation create * Added document_id in organisation * Added document_id in organisation * Added exisiting Organisation * Added exisiting Organisation * Added exisiting Organisation * Added exisiting Organisation --- src/src/beneficiaries/beneficiaries.module.ts | 5 ++- src/src/camp/camp.module.ts | 4 +++ .../common/middlewares/cohort.middleware.ts | 30 ++++++++--------- src/src/common/middlewares/ip.middleware.ts | 33 +++++++++++++++++++ src/src/facilitator/facilitator.module.ts | 2 ++ .../organisation/organisation.controller.ts | 6 +--- src/src/organisation/organisation.service.ts | 11 +++++-- src/src/user/user.service.ts | 3 +- 8 files changed, 69 insertions(+), 25 deletions(-) create mode 100644 src/src/common/middlewares/ip.middleware.ts diff --git a/src/src/beneficiaries/beneficiaries.module.ts b/src/src/beneficiaries/beneficiaries.module.ts index 8cd2464de..791cb5e62 100644 --- a/src/src/beneficiaries/beneficiaries.module.ts +++ b/src/src/beneficiaries/beneficiaries.module.ts @@ -20,6 +20,7 @@ import { HasuraModule as HasuraModuleFromServices } from '../services/hasura/has import { KeycloakModule } from '../services/keycloak/keycloak.module'; import { BeneficiariesCoreService } from './beneficiaries.core.service'; import { BeneficiariesService } from './beneficiaries.service'; +import { IpMiddleware } from 'src/common/middlewares/ip.middleware'; @Module({ imports: [ UserModule, @@ -74,7 +75,9 @@ export class BeneficiariesModule implements NestModule { ); */ - + consumer + .apply(IpMiddleware) + .forRoutes('/beneficiaries/admin/list', '/beneficiaries/:id'); consumer .apply(CohortMiddleware) .exclude( diff --git a/src/src/camp/camp.module.ts b/src/src/camp/camp.module.ts index 67bd17a66..b8e3dc769 100644 --- a/src/src/camp/camp.module.ts +++ b/src/src/camp/camp.module.ts @@ -20,6 +20,7 @@ import { CampController } from './camp.controller'; import { CampCoreService } from './camp.core.service'; import { CampService } from './camp.service'; import { Method } from 'src/common/method/method'; +import { IpMiddleware } from 'src/common/middlewares/ip.middleware'; @Module({ imports: [ @@ -41,6 +42,9 @@ import { Method } from 'src/common/method/method'; }) export class CampModule implements NestModule { configure(consumer: MiddlewareConsumer) { + consumer + .apply(IpMiddleware) + .forRoutes('/camp/admin/camp-details/:id', '/camp/admin/camp-list'); consumer .apply(CohortMiddleware) .exclude( diff --git a/src/src/common/middlewares/cohort.middleware.ts b/src/src/common/middlewares/cohort.middleware.ts index d3e66a606..78b916dba 100644 --- a/src/src/common/middlewares/cohort.middleware.ts +++ b/src/src/common/middlewares/cohort.middleware.ts @@ -12,22 +12,22 @@ export class CohortMiddleware implements NestMiddleware { async use(req: any, res: Response, next: () => void) { let goToNextMw = false; //check IP User ID is present or not [x-ip-user-id] - if ( - req?.headers?.['x-ip-org-id'] || - req?.mw_roles?.includes('program_owner') - ) { - req.mw_ip_user_id = req.headers['x-ip-org-id']; + // if ( + // req?.headers?.['x-ip-org-id'] || + // req?.mw_roles?.includes('program_owner') + // ) { + // req.mw_ip_user_id = req.headers['x-ip-org-id']; - const ip_user_id = parseInt(req.mw_ip_user_id, 10); - if (isNaN(ip_user_id)) { - return res.json({ - success: false, - message: `${ - req.mw_ip_user_id ? 'Invalid' : 'Required' - } Ip org Id`, - }); - } - } + // const ip_user_id = parseInt(req.mw_ip_user_id, 10); + // if (isNaN(ip_user_id)) { + // return res.json({ + // success: false, + // message: `${ + // req.mw_ip_user_id ? 'Invalid' : 'Required' + // } Ip org Id`, + // }); + // } + // } if (req?.headers?.['x-program-id']) { req.mw_program_id = req.headers['x-program-id']; diff --git a/src/src/common/middlewares/ip.middleware.ts b/src/src/common/middlewares/ip.middleware.ts new file mode 100644 index 000000000..e305bcd7c --- /dev/null +++ b/src/src/common/middlewares/ip.middleware.ts @@ -0,0 +1,33 @@ +import { + BadRequestException, + Injectable, + NestMiddleware, +} from '@nestjs/common'; +import { Response } from 'express'; +import { Method } from '../method/method'; + +@Injectable() +export class IpMiddleware implements NestMiddleware { + constructor(private method: Method) {} + async use(req: any, res: Response, next: () => void) { + //check IP User ID is present or not [x-ip-user-id] + if ( + req?.headers?.['x-ip-org-id'] || + req?.mw_roles?.includes('program_owner') + ) { + req.mw_ip_user_id = req.headers['x-ip-org-id']; + + const ip_user_id = parseInt(req.mw_ip_user_id, 10); + if (isNaN(ip_user_id)) { + return res.json({ + success: false, + message: `${ + req.mw_ip_user_id ? 'Invalid' : 'Required' + } Ip org Id`, + }); + } + } + + next(); + } +} diff --git a/src/src/facilitator/facilitator.module.ts b/src/src/facilitator/facilitator.module.ts index b99baf1c7..1cdbb0112 100644 --- a/src/src/facilitator/facilitator.module.ts +++ b/src/src/facilitator/facilitator.module.ts @@ -19,6 +19,7 @@ import { FacilitatorCoreService } from './facilitator.core.service'; import { FacilitatorService } from './facilitator.service'; import { CohortMiddleware } from 'src/common/middlewares/cohort.middleware'; import { Method } from '../common/method/method'; +import { IpMiddleware } from 'src/common/middlewares/ip.middleware'; @Module({ imports: [ @@ -37,6 +38,7 @@ import { Method } from '../common/method/method'; export class FacilitatorModule implements NestModule { configure(consumer: MiddlewareConsumer) { consumer.apply(AuthMiddleware).forRoutes('*'); + consumer.apply(IpMiddleware).forRoutes('/facilitators'); consumer .apply(CohortMiddleware) .exclude( diff --git a/src/src/organisation/organisation.controller.ts b/src/src/organisation/organisation.controller.ts index 80ea8edf4..2413de44b 100644 --- a/src/src/organisation/organisation.controller.ts +++ b/src/src/organisation/organisation.controller.ts @@ -21,11 +21,7 @@ export class OrganisationController { @Post('/create') @UsePipes(ValidationPipe) @UseGuards(new AuthGuard()) - registerCamp( - @Body() body: any, - @Req() request: any, - @Res() response: Response, - ) { + create(@Body() body: any, @Req() request: any, @Res() response: Response) { return this.organisationService.create(body, request, response); } diff --git a/src/src/organisation/organisation.service.ts b/src/src/organisation/organisation.service.ts index 6400f2fe0..9cb685878 100644 --- a/src/src/organisation/organisation.service.ts +++ b/src/src/organisation/organisation.service.ts @@ -67,6 +67,9 @@ export class OrganisationService { program_id: request.mw_program_id, academic_year_id: request.mw_academic_year_id, status: 'active', + doc_per_cohort_id: body?.doc_per_cohort_id, + doc_per_monthly_id: body?.doc_per_monthly_id, + doc_quarterly_id: body?.doc_quarterly_id, // Other fields as needed }; @@ -88,8 +91,8 @@ export class OrganisationService { } public async getOrganisation(body: any, req: any, resp: any) { - const academic_year_id = req?.mw_academic_year_id; - const program_id = req?.mw_program_id; + const academic_year_id = req.mw_academic_year_id; + const program_id = req.mw_program_id; try { const page = isNaN(body.page) ? 1 : parseInt(body.page); @@ -171,7 +174,6 @@ export class OrganisationService { offset: offset, }, }; - const response = await this.hasuraServiceFromServices.getData(data); const organisations = response?.data?.organisations || []; @@ -215,6 +217,9 @@ export class OrganisationService { program_id academic_year_id status + doc_per_cohort_id + doc_per_monthly_id + doc_quarterly_id } } } diff --git a/src/src/user/user.service.ts b/src/src/user/user.service.ts index ece7e7337..359d10b7e 100644 --- a/src/src/user/user.service.ts +++ b/src/src/user/user.service.ts @@ -1852,6 +1852,7 @@ export class UserService { middle_name last_name mobile + username program_users(where:{academic_year_id:{_eq:${academic_year_id}},program_id:{_eq:${program_id}}}){ id user_id @@ -1899,7 +1900,7 @@ export class UserService { program_id user_id } - + }} `; const data = { query: qury }; const response = await this.hasuraServiceFromServices.getData(data); From 3fa3adf52f63050f7d48ee45d981aba7a0c20dad Mon Sep 17 00:00:00 2001 From: Tusharmahajan12 <121154132+Tusharmahajan12@users.noreply.github.com> Date: Thu, 14 Mar 2024 18:51:47 +0530 Subject: [PATCH 057/126] TASK#215507 [BE] Added exisiting Organisation (#906) * Added exisiting Organisation * Added exisiting Organisation --- .../organisation/organisation.controller.ts | 11 ++++++++ src/src/organisation/organisation.service.ts | 28 +++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/src/src/organisation/organisation.controller.ts b/src/src/organisation/organisation.controller.ts index 2413de44b..d001ef699 100644 --- a/src/src/organisation/organisation.controller.ts +++ b/src/src/organisation/organisation.controller.ts @@ -62,4 +62,15 @@ export class OrganisationController { response, ); } + + @Post('/add/existing') + @UsePipes(ValidationPipe) + @UseGuards(new AuthGuard()) + addExisting( + @Body() body: any, + @Req() request: any, + @Res() response: Response, + ) { + return this.organisationService.addExisting(body, request, response); + } } diff --git a/src/src/organisation/organisation.service.ts b/src/src/organisation/organisation.service.ts index 9cb685878..27208b510 100644 --- a/src/src/organisation/organisation.service.ts +++ b/src/src/organisation/organisation.service.ts @@ -296,4 +296,32 @@ export class OrganisationService { }); } } + + async addExisting(body: any, request: any, response: any) { + const org_id = body?.organisation_id; + + const programOrganisationData = { + organisation_id: org_id, + program_id: request.mw_program_id, + academic_year_id: request.mw_academic_year_id, + status: 'active', + doc_per_cohort_id: body?.doc_per_cohort_id, + doc_per_monthly_id: body?.doc_per_monthly_id, + doc_quarterly_id: body?.doc_quarterly_id, + // Other fields as needed + }; + + const programOrganisationTableName = 'program_organisation'; + const program_organisation = await this.hasuraService.q( + programOrganisationTableName, + programOrganisationData, + ); + + // Return success response + response.status(200).json({ + success: true, + message: 'Existing Organisation created successfully.', + data: program_organisation, + }); + } } From 3cfa94198b4e87e8bd7245f32fef887ab32ddbf9 Mon Sep 17 00:00:00 2001 From: YoginiTayade <134492849+YoginiTayade@users.noreply.github.com> Date: Fri, 15 Mar 2024 10:19:23 +0530 Subject: [PATCH 058/126] [BE] Task #215532 Download files from s3 bucket (#905) * download files from s3 bucket * resolved the comments by Manoj L * moved housekeeping to modules folder * resolved comments * Undo package-lock.json --------- Co-authored-by: YoginiTayade Co-authored-by: Manoj L --- .../housekeeping/housekeeping.controller.ts | 15 ++++++++ .../housekeeping/housekeeping.module.ts | 9 +++++ .../housekeeping/housekeeping.service.ts | 38 +++++++++++++++++++ 3 files changed, 62 insertions(+) create mode 100644 src/src/modules/housekeeping/housekeeping.controller.ts create mode 100644 src/src/modules/housekeeping/housekeeping.module.ts create mode 100644 src/src/modules/housekeeping/housekeeping.service.ts diff --git a/src/src/modules/housekeeping/housekeeping.controller.ts b/src/src/modules/housekeeping/housekeeping.controller.ts new file mode 100644 index 000000000..4e4ebaabe --- /dev/null +++ b/src/src/modules/housekeeping/housekeeping.controller.ts @@ -0,0 +1,15 @@ +import { HouseKeepingService } from './housekeeping.service'; +//import { Body, Controller, Post, UseGuards } from '@nestjs/common'; +//import { AuthGuard } from '../auth/auth.guard'; + +//@Controller('hk') +export class HouseKeepingController { + constructor(private houseKeepingService: HouseKeepingService) {} + /* + @Post('/download-files') + //@UseGuards(new AuthGuard()) + public async downloadFiles(@Body() body) { + await this.houseKeepingService.downloadFiles(body); + } + */ +} diff --git a/src/src/modules/housekeeping/housekeeping.module.ts b/src/src/modules/housekeeping/housekeeping.module.ts new file mode 100644 index 000000000..3842d91d4 --- /dev/null +++ b/src/src/modules/housekeeping/housekeeping.module.ts @@ -0,0 +1,9 @@ +import { Module } from '@nestjs/common'; +import { HouseKeepingService } from './housekeeping.service'; +import { HouseKeepingController } from './housekeeping.controller'; + +@Module({ + providers: [HouseKeepingService], + controllers: [HouseKeepingController], +}) +export class HouseKeepingModule {} diff --git a/src/src/modules/housekeeping/housekeeping.service.ts b/src/src/modules/housekeeping/housekeeping.service.ts new file mode 100644 index 000000000..300e86de3 --- /dev/null +++ b/src/src/modules/housekeeping/housekeeping.service.ts @@ -0,0 +1,38 @@ +import { GetObjectCommand, S3Client } from '@aws-sdk/client-s3'; +const fs = require('fs'); +export class HouseKeepingService { + async downloadFiles(body) { + const bucketName = process.env.S3_BUCKET; + const fileNames = body.fileNames; + const destinationFolder = body.destinationFolder; + + const s3 = new S3Client({ + region: process.env.S3_REGION, + credentials: { + secretAccessKey: process.env.SECRET_ACCESS_KEY, + accessKeyId: process.env.ACCESS_KEY_ID, + }, + }); + + try { + for (const fileName of fileNames) { + const getObjectCommand = new GetObjectCommand({ + Bucket: bucketName, + Key: fileName, + }); + + const getObjectCommandResponse = await s3.send( + getObjectCommand, + ); + + // 2 - Write image from S3 to temporary file + fs.writeFileSync( + destinationFolder + '/' + fileName, + await getObjectCommandResponse.Body.transformToByteArray(), + ); + } + } catch (error) { + console.error('Error:', error); + } + } +} From 5916e42cf11b84ba5a2e2dc473d73f0c933a3d01 Mon Sep 17 00:00:00 2001 From: Tusharmahajan12 <121154132+Tusharmahajan12@users.noreply.github.com> Date: Fri, 15 Mar 2024 10:28:20 +0530 Subject: [PATCH 059/126] Task #215507 [BE] Create Existing Organisation (#909) * Added exisiting Organisation * Added exisiting Organisation * Add existing Organisation validation * Add existing Organisation validation * Add existing Organisation validation * Add existing Organisation validation * Add existing Organisation validation --- src/src/organisation/organisation.service.ts | 95 +++++++++++++------- 1 file changed, 64 insertions(+), 31 deletions(-) diff --git a/src/src/organisation/organisation.service.ts b/src/src/organisation/organisation.service.ts index 27208b510..c79a11377 100644 --- a/src/src/organisation/organisation.service.ts +++ b/src/src/organisation/organisation.service.ts @@ -39,21 +39,13 @@ export class OrganisationService { contact_person: body?.contact_person, address: body?.address, email_id: body?.email_id, - learner_target: body?.learner_target, }; const tableName = 'organisations'; const newOrganisation = await this.hasuraService.q( tableName, organisationData, - [ - 'name', - 'mobile', - 'contact_person', - 'address', - 'email_id', - 'learner_target', - ], + ['name', 'mobile', 'contact_person', 'address', 'email_id'], ); if (!newOrganisation || !newOrganisation?.organisations.id) { @@ -67,6 +59,7 @@ export class OrganisationService { program_id: request.mw_program_id, academic_year_id: request.mw_academic_year_id, status: 'active', + learner_target: body?.learner_target, doc_per_cohort_id: body?.doc_per_cohort_id, doc_per_monthly_id: body?.doc_per_monthly_id, doc_quarterly_id: body?.doc_quarterly_id, @@ -166,6 +159,11 @@ export class OrganisationService { name contact_person mobile + email_id + program_organisations(where:{program_id: {_eq: ${program_id}}, academic_year_id: {_eq: ${academic_year_id}}, status: {_eq: "active"}}){ + learner_target + } + } } `, @@ -213,13 +211,23 @@ export class OrganisationService { name contact_person mobile + email_id + address program_organisations(where:{program_id: {_eq: ${program_id}}, academic_year_id: {_eq: ${academic_year_id}}, status: {_eq: "active"}}){ program_id academic_year_id status + organisation_id + learner_target doc_per_cohort_id doc_per_monthly_id doc_quarterly_id + program{ + name + state{ + state_name + } + } } } } @@ -240,7 +248,7 @@ export class OrganisationService { return resp.status(200).send({ success: true, message: 'Organisation Details found successfully!', - data: organisations, + data: organisations?.[0], }); } } catch (error) { @@ -299,29 +307,54 @@ export class OrganisationService { async addExisting(body: any, request: any, response: any) { const org_id = body?.organisation_id; - - const programOrganisationData = { - organisation_id: org_id, - program_id: request.mw_program_id, - academic_year_id: request.mw_academic_year_id, - status: 'active', - doc_per_cohort_id: body?.doc_per_cohort_id, - doc_per_monthly_id: body?.doc_per_monthly_id, - doc_quarterly_id: body?.doc_quarterly_id, - // Other fields as needed + let data = { + query: `query MyQuery { + program_organisation_aggregate(where: {academic_year_id: {_eq: ${request.mw_academic_year_id}}, program_id: {_eq: ${request.mw_program_id}}, organisation_id: {_eq: ${org_id}}}) + { + aggregate{ + count + } + } + }`, }; + const existing = await this.hasuraServiceFromServices.getData(data); - const programOrganisationTableName = 'program_organisation'; - const program_organisation = await this.hasuraService.q( - programOrganisationTableName, - programOrganisationData, - ); + const program_organisation = + existing?.data?.program_organisation_aggregate?.aggregate?.count; - // Return success response - response.status(200).json({ - success: true, - message: 'Existing Organisation created successfully.', - data: program_organisation, - }); + if (program_organisation == 0) { + const programOrganisationData = { + organisation_id: org_id, + program_id: request.mw_program_id, + academic_year_id: request.mw_academic_year_id, + status: 'active', + doc_per_cohort_id: body?.doc_per_cohort_id, + doc_per_monthly_id: body?.doc_per_monthly_id, + doc_quarterly_id: body?.doc_quarterly_id, + learner_target: body?.learner_target, + // Other fields as needed + }; + + const programOrganisationTableName = 'program_organisation'; + const program_organisation = await this.hasuraService.q( + programOrganisationTableName, + programOrganisationData, + ); + + // Return success response + response.status(200).json({ + success: true, + message: 'Existing Organisation created successfully.', + data: program_organisation, + }); + } else { + response.status(422).json({ + success: false, + key: 'organisation_id', + message: + 'Organisation ALready Exists for the Program and Academic Year.', + data: {}, + }); + } } } From 59f57c02d1e5483eb51b7c7984e3b3ce76f43d16 Mon Sep 17 00:00:00 2001 From: Tusharmahajan12 <121154132+Tusharmahajan12@users.noreply.github.com> Date: Fri, 15 Mar 2024 12:14:08 +0530 Subject: [PATCH 060/126] Task #215242 [BE] IP users LIST (#911) * Added exisiting Organisation * Added exisiting Organisation * Add existing Organisation validation * Add existing Organisation validation * Add existing Organisation validation * Add existing Organisation validation * Add existing Organisation validation * Limit set in list * Added state name in detail --- src/src/helper/queryGenerator.service.ts | 7 +++---- src/src/user/user.service.ts | 12 +++++++++--- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/src/helper/queryGenerator.service.ts b/src/src/helper/queryGenerator.service.ts index 29580aa7c..f0ee57c37 100644 --- a/src/src/helper/queryGenerator.service.ts +++ b/src/src/helper/queryGenerator.service.ts @@ -252,7 +252,7 @@ export class QueryGeneratorService { onlyFields: any = [], request: any = { filters: {}, page: '0', limit: '0' }, ) { - const getObjStr = (request: any) => { + const getObjStr = (request: any, is_aggregate = false) => { const { filter, page, limit, order_by, onlyfilter } = request; const filters = this.filterObjectByKeyArray( filter || {}, @@ -291,7 +291,7 @@ export class QueryGeneratorService { filterStr += `}`; paramArr = [...paramArr, filterStr]; } - if (limit) { + if (limit && !is_aggregate) { let offset = 0; if (page > 1 && limit) { offset = parseInt(limit) * (page - 1); @@ -312,9 +312,8 @@ export class QueryGeneratorService { } return str; }; - const query = `query MyQuery { - ${tableName}_aggregate${getObjStr(request)} { + ${tableName}_aggregate${getObjStr(request, true)} { aggregate { count } diff --git a/src/src/user/user.service.ts b/src/src/user/user.service.ts index 359d10b7e..b725978ab 100644 --- a/src/src/user/user.service.ts +++ b/src/src/user/user.service.ts @@ -1854,13 +1854,20 @@ export class UserService { mobile username program_users(where:{academic_year_id:{_eq:${academic_year_id}},program_id:{_eq:${program_id}}}){ - id user_id academic_year_id program_id - role_id organisation_id role_slug + programs{ + name + state{ + state_name + } + } + organisations{ + name + } } } @@ -1869,7 +1876,6 @@ export class UserService { const data = { query: qury }; const response = await this.hasuraServiceFromServices.getData(data); const newQdata = response?.data?.users; - if (newQdata.length == 0) { return resp.status(422).json({ success: false, From 2aa179bd21891ef964b98b4fc7f19197ebe6c7ee Mon Sep 17 00:00:00 2001 From: GitVivekHub Date: Fri, 15 Mar 2024 12:34:56 +0530 Subject: [PATCH 061/126] Observation and fields commit --- src/src/app.module.ts | 2 + .../observations.controller.spec.ts | 18 + .../observations/observations.controller.ts | 187 ++++++ src/src/observations/observations.module.ts | 13 + .../observations/observations.service.spec.ts | 18 + src/src/observations/observations.service.ts | 540 ++++++++++++++++++ 6 files changed, 778 insertions(+) create mode 100644 src/src/observations/observations.controller.spec.ts create mode 100644 src/src/observations/observations.controller.ts create mode 100644 src/src/observations/observations.module.ts create mode 100644 src/src/observations/observations.service.spec.ts create mode 100644 src/src/observations/observations.service.ts diff --git a/src/src/app.module.ts b/src/src/app.module.ts index 5100fbb7f..24019b357 100755 --- a/src/src/app.module.ts +++ b/src/src/app.module.ts @@ -39,6 +39,7 @@ import { UserModule } from './user/user.module'; import { UserauthModule } from './userauth/userauth.module'; import { BoardModule } from './modules/board/board.module'; import { OrganisationModule } from './organisation/organisation.module'; +import { ObservationsModule } from './observations/observations.module'; @Module({ imports: [ ScheduleModule.forRoot(), @@ -87,6 +88,7 @@ import { OrganisationModule } from './organisation/organisation.module'; UserModule, UserauthModule, OrganisationModule, + ObservationsModule, ], controllers: [], providers: [CacheCleanerProvider], diff --git a/src/src/observations/observations.controller.spec.ts b/src/src/observations/observations.controller.spec.ts new file mode 100644 index 000000000..54535557c --- /dev/null +++ b/src/src/observations/observations.controller.spec.ts @@ -0,0 +1,18 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { ObservationsController } from './observations.controller'; + +describe('ObservationsController', () => { + let controller: ObservationsController; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + controllers: [ObservationsController], + }).compile(); + + controller = module.get(ObservationsController); + }); + + it('should be defined', () => { + expect(controller).toBeDefined(); + }); +}); diff --git a/src/src/observations/observations.controller.ts b/src/src/observations/observations.controller.ts new file mode 100644 index 000000000..2892f21b3 --- /dev/null +++ b/src/src/observations/observations.controller.ts @@ -0,0 +1,187 @@ +import { + Body, + Controller, + Get, + Param, + Post, + Req, + Res, + UseGuards, + UsePipes, + ValidationPipe, + Response, + Request, + Patch, + Delete, +} from '@nestjs/common'; +import { AuthGuard } from 'src/modules/auth/auth.guard'; +import { ObservationsService } from './observations.service'; + +@Controller('observations') +export class ObservationsController { + constructor(public observationsService: ObservationsService) {} + + @Post('/') + @UsePipes(ValidationPipe) + @UseGuards(new AuthGuard()) + public async createObservation( + @Body() body: Body, + @Res() response: Response, + @Req() request: Request, + ) { + return this.observationsService.createObservation( + body, + response, + request, + ); + } + + @Patch('/:id') + @UsePipes(ValidationPipe) + @UseGuards(new AuthGuard()) + public async updateObservation( + @Body() body: Body, + @Res() response: Response, + @Req() request: Request, + @Param('id') id: number, + ) { + return this.observationsService.updateObservation( + body, + response, + request, + id, + ); + } + + @Get('/list') + @UsePipes(ValidationPipe) + @UseGuards(new AuthGuard()) + public async getObservationList( + @Body() body: Body, + @Res() response: Response, + @Req() request: Request, + ) { + return this.observationsService.getObservationList( + body, + response, + request, + ); + } + + @Get('/:id') + @UsePipes(ValidationPipe) + @UseGuards(new AuthGuard()) + public async getObservationById( + @Res() response: Response, + @Req() request: Request, + @Param('id') id: number, + ) { + return this.observationsService.getObservationById( + response, + request, + id, + ); + } + + @Delete('/:id') + @UsePipes(ValidationPipe) + @UseGuards(new AuthGuard()) + public async deleteObservationById( + @Res() response: Response, + @Req() request: Request, + @Param('id') id: number, + ) { + return this.observationsService.deleteObservationById( + response, + request, + id, + ); + } + + @Post('/list') + @UsePipes(ValidationPipe) + @UseGuards(new AuthGuard()) + public async getObservationListByName( + @Body() body: Body, + @Res() response: Response, + @Req() request: Request, + ) { + return this.observationsService.getObservationList( + body, + response, + request, + ); + } + + @Post('/fields') + @UsePipes(ValidationPipe) + @UseGuards(new AuthGuard()) + public async createFields( + @Body() body: Body, + @Res() response: Response, + @Req() request: Request, + ) { + return this.observationsService.createFields(body, response, request); + } + + @Patch('/fields/:id') + @UsePipes(ValidationPipe) + @UseGuards(new AuthGuard()) + public async updateFields( + @Body() body: Body, + @Res() response: Response, + @Req() request: Request, + @Param('id') id: number, + ) { + return this.observationsService.updateFields( + body, + response, + request, + id, + ); + } + + @Get('/fields/list') + @UsePipes(ValidationPipe) + @UseGuards(new AuthGuard()) + public async getFieldsList( + @Body() body: Body, + @Res() response: Response, + @Req() request: Request, + ) { + return this.observationsService.getFieldsList(body, response, request); + } + + @Get('/fields/:id') + @UsePipes(ValidationPipe) + @UseGuards(new AuthGuard()) + public async getFieldById( + @Res() response: Response, + @Req() request: Request, + @Param('id') id: number, + ) { + return this.observationsService.getFieldById(response, request, id); + } + + @Delete('/fields/:id') + @UsePipes(ValidationPipe) + @UseGuards(new AuthGuard()) + public async deleteFieldById( + @Res() response: Response, + @Req() request: Request, + @Param('id') id: number, + ) { + return this.observationsService.deleteFieldById(response, request, id); + } + + @Post('/fields/list') + @UsePipes(ValidationPipe) + @UseGuards(new AuthGuard()) + public async getFieldListByName( + @Body() body: Body, + @Res() response: Response, + @Req() request: Request, + ) { + return this.observationsService.getFieldsList(body, response, request); + } +} diff --git a/src/src/observations/observations.module.ts b/src/src/observations/observations.module.ts new file mode 100644 index 000000000..da1ed5d64 --- /dev/null +++ b/src/src/observations/observations.module.ts @@ -0,0 +1,13 @@ +import { Module } from '@nestjs/common'; +import { HasuraModule } from 'src/hasura/hasura.module'; +import { UserModule } from 'src/user/user.module'; +import { HasuraModule as HasuraModuleFromServices } from '../services/hasura/hasura.module'; +import { ObservationsService } from './observations.service'; +import { ObservationsController } from './observations.controller'; + +@Module({ + imports: [HasuraModule, HasuraModuleFromServices, UserModule], + providers: [ObservationsService], + controllers: [ObservationsController], +}) +export class ObservationsModule {} diff --git a/src/src/observations/observations.service.spec.ts b/src/src/observations/observations.service.spec.ts new file mode 100644 index 000000000..c6322f614 --- /dev/null +++ b/src/src/observations/observations.service.spec.ts @@ -0,0 +1,18 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { ObservationsService } from './observations.service'; + +describe('ObservationsService', () => { + let service: ObservationsService; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [ObservationsService], + }).compile(); + + service = module.get(ObservationsService); + }); + + it('should be defined', () => { + expect(service).toBeDefined(); + }); +}); diff --git a/src/src/observations/observations.service.ts b/src/src/observations/observations.service.ts new file mode 100644 index 000000000..e2606f750 --- /dev/null +++ b/src/src/observations/observations.service.ts @@ -0,0 +1,540 @@ +import { Injectable } from '@nestjs/common'; +import { HasuraService } from 'src/hasura/hasura.service'; +import { UserService } from 'src/user/user.service'; +import { HasuraService as HasuraServiceFromServices } from '../services/hasura/hasura.service'; + +@Injectable() +export class ObservationsService { + public tableName = 'observations'; + public fillable = [ + 'name', + 'created_by', + 'created_at', + 'updated_at', + 'updated_by', + ]; + public returnFields = [ + 'id', + 'name', + 'created_by', + 'created_at', + 'updated_at', + 'updated_by', + ]; + + public FieldTableName = 'fields'; + public FieldFillable = [ + 'name', + 'created_by', + 'created_at', + 'updated_at', + 'updated_by', + 'data_type', + 'description', + 'extra_all_info', + ]; + public FieldReturnFields = [ + 'id', + 'name', + 'created_by', + 'created_at', + 'updated_at', + 'updated_by', + 'data_type', + 'description', + 'extra_all_info', + ]; + constructor( + private readonly hasuraService: HasuraService, + private hasuraServiceFromServices: HasuraServiceFromServices, + private userService: UserService, + ) {} + + async createObservation(body: any, resp: any, request: any) { + let user_id = request?.mw_userid; + + body.created_by = user_id; + body.updated_by = user_id; + if (!user_id) { + return resp.status(422).json({ + message: 'Invalid User Entity', + data: null, + }); + } + + let result = await this.hasuraService.q( + this.tableName, + { + ...body, + }, + this.fillable, + false, + this.returnFields, + ); + + if (result) { + return resp.status(200).json({ + success: true, + message: 'Observation created successfully!', + data: result, + }); + } else { + return resp.status(500).json({ + success: false, + message: 'Unable to create obsevation !', + data: {}, + }); + } + } + + async createFields(body: any, resp: any, request: any) { + let user_id = request?.mw_userid; + + body.created_by = user_id; + body.updated_by = user_id; + if (!user_id) { + return resp.status(422).json({ + message: 'Invalid User Entity', + data: null, + }); + } + + let result = await this.hasuraService.q( + this.FieldTableName, + { + ...body, + }, + this.FieldFillable, + false, + this.FieldReturnFields, + ); + + if (result) { + return resp.status(200).json({ + success: true, + message: 'Field created successfully!', + data: result, + }); + } else { + return resp.status(500).json({ + success: false, + message: 'Unable to create Field !', + data: {}, + }); + } + } + + async updateObservation(body: any, resp: any, request: any, id: any) { + let user_id = request?.mw_userid; + + body.updated_by = user_id; + if (!user_id) { + return resp.status(422).json({ + message: 'Invalid User Entity', + data: null, + }); + } + + let result = await this.hasuraService.q( + this.tableName, + { + ...body, + id: id, + }, + this.fillable, + true, + this.returnFields, + ); + + if (result) { + return resp.status(200).json({ + success: true, + message: 'Observation updated successfully!', + data: result, + }); + } else { + return resp.status(500).json({ + success: false, + message: 'Unable to update obsevation !', + data: {}, + }); + } + } + + async updateFields(body: any, resp: any, request: any, id: any) { + let user_id = request?.mw_userid; + + body.updated_by = user_id; + if (!user_id) { + return resp.status(422).json({ + message: 'Invalid User Entity', + data: null, + }); + } + + let result = await this.hasuraService.q( + this.FieldTableName, + { + ...body, + id: id, + }, + this.FieldFillable, + true, + this.FieldReturnFields, + ); + + if (result) { + return resp.status(200).json({ + success: true, + message: 'Field updated successfully!', + data: result, + }); + } else { + return resp.status(500).json({ + success: false, + message: 'Unable to update Field !', + data: {}, + }); + } + } + + async getObservationList(body: any, resp: any, request: any) { + let response; + let newQdata; + let query; + let user_id = request?.mw_userid; + + if (!user_id) { + return resp.status(422).json({ + message: 'Invalid User Entity', + data: null, + }); + } + + if (body?.name) { + query = `query MyQuery { + observations(where: {name: {_ilike: "%${body?.name}%"}}) { + created_at + created_by + id + name + updated_at + updated_by + } + } + + + `; + } else { + query = `query MyQuery { + observations{ + id + name + created_at + created_by + updated_by + } + } + + `; + } + + response = await this.hasuraServiceFromServices.getData({ + query: query, + }); + newQdata = response?.data?.observations; + + if (newQdata.length > 0) { + return resp.status(200).json({ + success: true, + message: 'Data found successfully!', + data: newQdata, + }); + } else { + return resp.json({ + status: 400, + message: 'Data Not Found', + data: {}, + }); + } + } + + async getFieldsList(body: any, resp: any, request: any) { + let response; + let newQdata; + let query; + let user_id = request?.mw_userid; + + if (!user_id) { + return resp.status(422).json({ + message: 'Invalid User Entity', + data: null, + }); + } + + if (body?.name) { + query = `query MyQuery { + fields(where: {name: {_ilike: "%${body?.name}%"}}) { + created_at + created_by + id + name + updated_at + updated_by + data_type + description + extra_all_info + } + } + + + + `; + } else { + query = `query MyQuery { + fields { + created_at + created_by + id + name + updated_at + updated_by + data_type + description + extra_all_info + } + } + + + `; + } + + response = await this.hasuraServiceFromServices.getData({ + query: query, + }); + newQdata = response?.data?.fields; + + if (newQdata.length > 0) { + return resp.status(200).json({ + success: true, + message: 'Data found successfully!', + data: newQdata, + }); + } else { + return resp.json({ + status: 400, + message: 'Data Not Found', + data: {}, + }); + } + } + + async getObservationById(resp: any, request: any, id: any) { + let user_id = request?.mw_userid; + + if (!id) { + return resp.status(422).json({ + message: 'Please provide a valid get id', + data: null, + }); + } + + if (!user_id) { + return resp.status(422).json({ + message: 'Invalid User Entity', + data: null, + }); + } + + let query = `query MyQuery { + observations_by_pk(id:${id}) { + id + name + created_by + created_at + updated_at + updated_by + } + } + + + `; + + const response = await this.hasuraServiceFromServices.getData({ + query: query, + }); + const newQdata = response?.data?.observations_by_pk; + + if (newQdata) { + return resp.status(200).json({ + success: true, + message: 'Data found successfully!', + data: newQdata, + }); + } else { + return resp.json({ + status: 400, + message: 'Data Not Found', + data: {}, + }); + } + } + + async getFieldById(resp: any, request: any, id: any) { + let user_id = request?.mw_userid; + + if (!id) { + return resp.status(422).json({ + message: 'Please provide a valid get id', + data: null, + }); + } + + if (!user_id) { + return resp.status(422).json({ + message: 'Invalid User Entity', + data: null, + }); + } + + let query = `query MyQuery { + fields_by_pk(id:${id}) { + created_at + created_by + id + name + updated_at + updated_by + data_type + description + extra_all_info + } + } + + + + `; + + const response = await this.hasuraServiceFromServices.getData({ + query: query, + }); + const newQdata = response?.data?.fields_by_pk; + + if (newQdata) { + return resp.status(200).json({ + success: true, + message: 'Data found successfully!', + data: newQdata, + }); + } else { + return resp.json({ + status: 400, + message: 'Data Not Found', + data: {}, + }); + } + } + + async deleteObservationById(resp: any, request: any, id: any) { + let user_id = request?.mw_userid; + + if (!id) { + return resp.status(422).json({ + message: 'Please provide a valid get id', + data: null, + }); + } + + if (!user_id) { + return resp.status(422).json({ + message: 'Invalid User Entity', + data: null, + }); + } + + let query = `mutation MyMutation { + delete_observations_by_pk(id:${id}) { + id + created_by + name + updated_at + updated_by + created_at + } + } + + `; + + const response = await this.hasuraServiceFromServices.getData({ + query: query, + }); + const newQdata = response?.data?.delete_observations_by_pk; + + if (newQdata) { + return resp.status(200).json({ + success: true, + message: 'Data deleted successfully!', + data: newQdata, + }); + } else { + return resp.json({ + status: 400, + message: 'Data Not Found', + data: {}, + }); + } + } + + async deleteFieldById(resp: any, request: any, id: any) { + let user_id = request?.mw_userid; + + if (!id) { + return resp.status(422).json({ + message: 'Please provide a valid get id', + data: null, + }); + } + + if (!user_id) { + return resp.status(422).json({ + message: 'Invalid User Entity', + data: null, + }); + } + + let query = `mutation MyMutation { + delete_fields_by_pk(id:${id}) { + created_at + created_by + id + name + updated_at + updated_by + data_type + description + extra_all_info + } + } + + `; + + const response = await this.hasuraServiceFromServices.getData({ + query: query, + }); + const newQdata = response?.data?.delete_fields_by_pk; + + if (newQdata) { + return resp.status(200).json({ + success: true, + message: 'Data deleted successfully!', + data: newQdata, + }); + } else { + return resp.json({ + status: 400, + message: 'Data Not Found', + data: {}, + }); + } + } +} From 3cc92ae071edb6af40276500b9e0b767d9bfe7dd Mon Sep 17 00:00:00 2001 From: GitVivekHub Date: Fri, 15 Mar 2024 13:47:30 +0530 Subject: [PATCH 062/126] dto added --- src/src/observations/dto/create-field.dto.ts | 19 +++++++++++++++++++ .../dto/create-observation.dto.ts | 7 +++++++ src/src/observations/dto/update-field.dto.ts | 15 +++++++++++++++ .../dto/update-observation.dto.ts | 7 +++++++ .../observations/observations.controller.ts | 12 ++++++++---- 5 files changed, 56 insertions(+), 4 deletions(-) create mode 100644 src/src/observations/dto/create-field.dto.ts create mode 100644 src/src/observations/dto/create-observation.dto.ts create mode 100644 src/src/observations/dto/update-field.dto.ts create mode 100644 src/src/observations/dto/update-observation.dto.ts diff --git a/src/src/observations/dto/create-field.dto.ts b/src/src/observations/dto/create-field.dto.ts new file mode 100644 index 000000000..ae83b6907 --- /dev/null +++ b/src/src/observations/dto/create-field.dto.ts @@ -0,0 +1,19 @@ +import { IsNotEmpty, IsString } from 'class-validator'; + +export class CreateFieldDto { + @IsNotEmpty() + @IsString() + name: string; + + @IsNotEmpty() + @IsString() + data_type: string; + + @IsNotEmpty() + @IsString() + description: string; + + @IsNotEmpty() + @IsString() + extra_all_info: string; +} diff --git a/src/src/observations/dto/create-observation.dto.ts b/src/src/observations/dto/create-observation.dto.ts new file mode 100644 index 000000000..b6ecac56c --- /dev/null +++ b/src/src/observations/dto/create-observation.dto.ts @@ -0,0 +1,7 @@ +import { IsNotEmpty, IsString } from 'class-validator'; + +export class CreateObservationDto { + @IsNotEmpty() + @IsString() + name: string; +} diff --git a/src/src/observations/dto/update-field.dto.ts b/src/src/observations/dto/update-field.dto.ts new file mode 100644 index 000000000..2b6456da6 --- /dev/null +++ b/src/src/observations/dto/update-field.dto.ts @@ -0,0 +1,15 @@ +import { IsString } from 'class-validator'; + +export class UpdateFieldDto { + @IsString() + name: string; + + @IsString() + data_type: string; + + @IsString() + description: string; + + @IsString() + extra_all_info: string; +} diff --git a/src/src/observations/dto/update-observation.dto.ts b/src/src/observations/dto/update-observation.dto.ts new file mode 100644 index 000000000..1961668de --- /dev/null +++ b/src/src/observations/dto/update-observation.dto.ts @@ -0,0 +1,7 @@ +import { IsNotEmpty, IsString } from 'class-validator'; + +export class UpdateObservationDto { + @IsNotEmpty() + @IsString() + name: string; +} diff --git a/src/src/observations/observations.controller.ts b/src/src/observations/observations.controller.ts index 2892f21b3..65b88bd08 100644 --- a/src/src/observations/observations.controller.ts +++ b/src/src/observations/observations.controller.ts @@ -16,6 +16,10 @@ import { } from '@nestjs/common'; import { AuthGuard } from 'src/modules/auth/auth.guard'; import { ObservationsService } from './observations.service'; +import { CreateObservationDto } from './dto/create-observation.dto'; +import { UpdateObservationDto } from './dto/update-observation.dto'; +import { CreateFieldDto } from './dto/create-field.dto'; +import { UpdateFieldDto } from './dto/update-field.dto'; @Controller('observations') export class ObservationsController { @@ -25,7 +29,7 @@ export class ObservationsController { @UsePipes(ValidationPipe) @UseGuards(new AuthGuard()) public async createObservation( - @Body() body: Body, + @Body() body: CreateObservationDto, @Res() response: Response, @Req() request: Request, ) { @@ -40,7 +44,7 @@ export class ObservationsController { @UsePipes(ValidationPipe) @UseGuards(new AuthGuard()) public async updateObservation( - @Body() body: Body, + @Body() body: UpdateObservationDto, @Res() response: Response, @Req() request: Request, @Param('id') id: number, @@ -117,7 +121,7 @@ export class ObservationsController { @UsePipes(ValidationPipe) @UseGuards(new AuthGuard()) public async createFields( - @Body() body: Body, + @Body() body: CreateFieldDto, @Res() response: Response, @Req() request: Request, ) { @@ -128,7 +132,7 @@ export class ObservationsController { @UsePipes(ValidationPipe) @UseGuards(new AuthGuard()) public async updateFields( - @Body() body: Body, + @Body() body: UpdateFieldDto, @Res() response: Response, @Req() request: Request, @Param('id') id: number, From b9921c5df18b196e35e553347c256afef90ac8cc Mon Sep 17 00:00:00 2001 From: Tusharmahajan12 <121154132+Tusharmahajan12@users.noreply.github.com> Date: Fri, 15 Mar 2024 14:08:57 +0530 Subject: [PATCH 063/126] Task #215506 [BE] Create Existing IP user (#912) * Added exisiting Organisation * Added exisiting Organisation * Add existing Organisation validation * Add existing Organisation validation * Add existing Organisation validation * Add existing Organisation validation * Add existing Organisation validation * Limit set in list * Added state name in detail * Added Existing IP Users --- src/src/user/user.controller.ts | 11 +++++ src/src/user/user.service.ts | 74 +++++++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+) diff --git a/src/src/user/user.controller.ts b/src/src/user/user.controller.ts index bcfcd9182..3b3d21ffb 100755 --- a/src/src/user/user.controller.ts +++ b/src/src/user/user.controller.ts @@ -320,6 +320,17 @@ export class UserController { ) { return this.userService.getCohortProgramList(request, req, response); } + + @Post('/add/existing_ip') + @UsePipes(ValidationPipe) + @UseGuards(new AuthGuard()) + addExistingIp( + @Body() body: any, + @Req() request: any, + @Res() response: Response, + ) { + return this.userService.addExistingIp(body, request, response); + } /**************************************************************************/ /******************************* V2 APIs **********************************/ /**************************************************************************/ diff --git a/src/src/user/user.service.ts b/src/src/user/user.service.ts index b725978ab..ca48a7259 100644 --- a/src/src/user/user.service.ts +++ b/src/src/user/user.service.ts @@ -2017,4 +2017,78 @@ export class UserService { }); } } + + async addExistingIp(body: any, request: any, response: any) { + const user_id = body?.user_id; + const organisationId = body?.organisation_id; + const roleSlug = body?.role_slug; + // Check if required fields are present in the payload + if (!user_id) { + return response.status(422).send({ + success: false, + message: 'Required fields are missing in the payload.', + data: {}, + }); + } + let data = { + query: `query MyQuery { + program_users(where: {program_id: {_eq: ${request.mw_program_id}}, user_id: {_eq: ${user_id}}}) + { + academic_year_id + program_id + user_id + } + }`, + }; + + const existing = await this.hasuraServiceFromServices.getData(data); + + const pu_academic_year = + existing?.data?.program_users?.[0]?.academic_year_id; + + if (!pu_academic_year) { + response.status(422).json({ + success: false, + key: 'user_id', + message: 'IP Users Does Not Have state Access', + data: {}, + }); + } else if (pu_academic_year == request.mw_academic_year_id) { + response.status(422).json({ + success: false, + key: 'academic_year_id', + message: 'IP Users Already Exists in This Academic Year', + data: {}, + }); + } else { + // Check if required fields are present in the payload + if (!organisationId || !roleSlug || !user_id) { + return response.status(422).send({ + success: false, + message: 'Required fields are missing in the payload.', + data: {}, + }); + } + const programUsersData = { + organisation_id: body?.organisation_id, + program_id: request.mw_program_id, + academic_year_id: request.mw_academic_year_id, + user_id: user_id, + role_slug: body?.role_slug, + }; + + const programUserTableName = 'program_users'; + const program_users = await this.hasuraService.q( + programUserTableName, + programUsersData, + ); + + // // Return success response + response.status(200).json({ + success: true, + message: 'Existing IP User created successfully.', + data: program_users, + }); + } + } } From 4bc4657ce1431ed97cef15885bd3219acd94a2c9 Mon Sep 17 00:00:00 2001 From: GitVivekHub Date: Fri, 15 Mar 2024 15:48:39 +0530 Subject: [PATCH 064/126] new fields added to the fields table and dto modified --- src/src/observations/dto/create-field.dto.ts | 8 +++++--- src/src/observations/dto/update-field.dto.ts | 15 --------------- .../observations/dto/update-observation.dto.ts | 7 ------- src/src/observations/observations.controller.ts | 6 ++---- src/src/observations/observations.service.ts | 13 +++++++++++++ 5 files changed, 20 insertions(+), 29 deletions(-) delete mode 100644 src/src/observations/dto/update-field.dto.ts delete mode 100644 src/src/observations/dto/update-observation.dto.ts diff --git a/src/src/observations/dto/create-field.dto.ts b/src/src/observations/dto/create-field.dto.ts index ae83b6907..e89f5868f 100644 --- a/src/src/observations/dto/create-field.dto.ts +++ b/src/src/observations/dto/create-field.dto.ts @@ -9,11 +9,13 @@ export class CreateFieldDto { @IsString() data_type: string; - @IsNotEmpty() - @IsString() description: string; + extra_all_info: string; + @IsNotEmpty() @IsString() - extra_all_info: string; + title: string; + + enum: string; } diff --git a/src/src/observations/dto/update-field.dto.ts b/src/src/observations/dto/update-field.dto.ts deleted file mode 100644 index 2b6456da6..000000000 --- a/src/src/observations/dto/update-field.dto.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { IsString } from 'class-validator'; - -export class UpdateFieldDto { - @IsString() - name: string; - - @IsString() - data_type: string; - - @IsString() - description: string; - - @IsString() - extra_all_info: string; -} diff --git a/src/src/observations/dto/update-observation.dto.ts b/src/src/observations/dto/update-observation.dto.ts deleted file mode 100644 index 1961668de..000000000 --- a/src/src/observations/dto/update-observation.dto.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { IsNotEmpty, IsString } from 'class-validator'; - -export class UpdateObservationDto { - @IsNotEmpty() - @IsString() - name: string; -} diff --git a/src/src/observations/observations.controller.ts b/src/src/observations/observations.controller.ts index 65b88bd08..f755fcd84 100644 --- a/src/src/observations/observations.controller.ts +++ b/src/src/observations/observations.controller.ts @@ -17,9 +17,7 @@ import { import { AuthGuard } from 'src/modules/auth/auth.guard'; import { ObservationsService } from './observations.service'; import { CreateObservationDto } from './dto/create-observation.dto'; -import { UpdateObservationDto } from './dto/update-observation.dto'; import { CreateFieldDto } from './dto/create-field.dto'; -import { UpdateFieldDto } from './dto/update-field.dto'; @Controller('observations') export class ObservationsController { @@ -44,7 +42,7 @@ export class ObservationsController { @UsePipes(ValidationPipe) @UseGuards(new AuthGuard()) public async updateObservation( - @Body() body: UpdateObservationDto, + @Body() body: CreateObservationDto, @Res() response: Response, @Req() request: Request, @Param('id') id: number, @@ -132,7 +130,7 @@ export class ObservationsController { @UsePipes(ValidationPipe) @UseGuards(new AuthGuard()) public async updateFields( - @Body() body: UpdateFieldDto, + @Body() body: CreateFieldDto, @Res() response: Response, @Req() request: Request, @Param('id') id: number, diff --git a/src/src/observations/observations.service.ts b/src/src/observations/observations.service.ts index e2606f750..23070fd7c 100644 --- a/src/src/observations/observations.service.ts +++ b/src/src/observations/observations.service.ts @@ -32,6 +32,8 @@ export class ObservationsService { 'data_type', 'description', 'extra_all_info', + 'title', + 'enum', ]; public FieldReturnFields = [ 'id', @@ -43,6 +45,8 @@ export class ObservationsService { 'data_type', 'description', 'extra_all_info', + 'title', + 'enum', ]; constructor( private readonly hasuraService: HasuraService, @@ -92,6 +96,11 @@ export class ObservationsService { body.created_by = user_id; body.updated_by = user_id; + + body.enum = body?.enum + ? JSON.stringify(body?.enum).replace(/"/g, '\\"') + : ''; + if (!user_id) { return resp.status(422).json({ message: 'Invalid User Entity', @@ -172,6 +181,10 @@ export class ObservationsService { }); } + body.enum = body?.enum + ? JSON.stringify(body?.enum).replace(/"/g, '\\"') + : ''; + let result = await this.hasuraService.q( this.FieldTableName, { From 650e24241d11e55d0e89fa6b31286fadc6674974 Mon Sep 17 00:00:00 2001 From: Tusharmahajan12 <121154132+Tusharmahajan12@users.noreply.github.com> Date: Fri, 15 Mar 2024 17:17:24 +0530 Subject: [PATCH 065/126] Added username (#915) --- src/src/user/user.service.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/src/user/user.service.ts b/src/src/user/user.service.ts index ca48a7259..6029741b7 100644 --- a/src/src/user/user.service.ts +++ b/src/src/user/user.service.ts @@ -1813,6 +1813,7 @@ export class UserService { 'last_name', 'email_id', 'mobile', + 'username', ]; body.filter = { ...(body.filter || {}), From e4700ea6effd0c876492898de09ec343c4983f57 Mon Sep 17 00:00:00 2001 From: GitVivekHub Date: Sat, 16 Mar 2024 10:13:47 +0530 Subject: [PATCH 066/126] Search by name changes,create,update changes,dto changes --- src/src/observations/dto/field-search.dto.ts | 7 + .../dto/{create-field.dto.ts => field.dto.ts} | 4 +- .../dto/observation-search.dto.ts | 7 + ...-observation.dto.ts => observation.dto.ts} | 2 +- .../observations/observations.controller.ts | 18 +- src/src/observations/observations.service.ts | 247 ++++++++++++------ 6 files changed, 189 insertions(+), 96 deletions(-) create mode 100644 src/src/observations/dto/field-search.dto.ts rename src/src/observations/dto/{create-field.dto.ts => field.dto.ts} (69%) create mode 100644 src/src/observations/dto/observation-search.dto.ts rename src/src/observations/dto/{create-observation.dto.ts => observation.dto.ts} (73%) diff --git a/src/src/observations/dto/field-search.dto.ts b/src/src/observations/dto/field-search.dto.ts new file mode 100644 index 000000000..703c50d2d --- /dev/null +++ b/src/src/observations/dto/field-search.dto.ts @@ -0,0 +1,7 @@ +import { IsNotEmpty, IsString, IsObject } from 'class-validator'; + +export class FieldSearchDto { + @IsNotEmpty() + @IsObject() + filters: any; +} diff --git a/src/src/observations/dto/create-field.dto.ts b/src/src/observations/dto/field.dto.ts similarity index 69% rename from src/src/observations/dto/create-field.dto.ts rename to src/src/observations/dto/field.dto.ts index e89f5868f..e5aa8deb0 100644 --- a/src/src/observations/dto/create-field.dto.ts +++ b/src/src/observations/dto/field.dto.ts @@ -1,6 +1,6 @@ -import { IsNotEmpty, IsString } from 'class-validator'; +import { IsNotEmpty, IsString, IsObject } from 'class-validator'; -export class CreateFieldDto { +export class FieldDto { @IsNotEmpty() @IsString() name: string; diff --git a/src/src/observations/dto/observation-search.dto.ts b/src/src/observations/dto/observation-search.dto.ts new file mode 100644 index 000000000..fd2f51ac7 --- /dev/null +++ b/src/src/observations/dto/observation-search.dto.ts @@ -0,0 +1,7 @@ +import { IsNotEmpty, IsString, IsObject } from 'class-validator'; + +export class ObservationSearchDto { + @IsNotEmpty() + @IsObject() + filters: any; +} diff --git a/src/src/observations/dto/create-observation.dto.ts b/src/src/observations/dto/observation.dto.ts similarity index 73% rename from src/src/observations/dto/create-observation.dto.ts rename to src/src/observations/dto/observation.dto.ts index b6ecac56c..06629acc9 100644 --- a/src/src/observations/dto/create-observation.dto.ts +++ b/src/src/observations/dto/observation.dto.ts @@ -1,6 +1,6 @@ import { IsNotEmpty, IsString } from 'class-validator'; -export class CreateObservationDto { +export class ObservationDto { @IsNotEmpty() @IsString() name: string; diff --git a/src/src/observations/observations.controller.ts b/src/src/observations/observations.controller.ts index f755fcd84..82bcd5dec 100644 --- a/src/src/observations/observations.controller.ts +++ b/src/src/observations/observations.controller.ts @@ -16,8 +16,10 @@ import { } from '@nestjs/common'; import { AuthGuard } from 'src/modules/auth/auth.guard'; import { ObservationsService } from './observations.service'; -import { CreateObservationDto } from './dto/create-observation.dto'; -import { CreateFieldDto } from './dto/create-field.dto'; +import { ObservationDto } from './dto/observation.dto'; +import { FieldDto } from './dto/field.dto'; +import { FieldSearchDto } from './dto/field-search.dto'; +import { ObservationSearchDto } from './dto/observation-search.dto'; @Controller('observations') export class ObservationsController { @@ -27,7 +29,7 @@ export class ObservationsController { @UsePipes(ValidationPipe) @UseGuards(new AuthGuard()) public async createObservation( - @Body() body: CreateObservationDto, + @Body() body: ObservationDto, @Res() response: Response, @Req() request: Request, ) { @@ -42,7 +44,7 @@ export class ObservationsController { @UsePipes(ValidationPipe) @UseGuards(new AuthGuard()) public async updateObservation( - @Body() body: CreateObservationDto, + @Body() body: ObservationDto, @Res() response: Response, @Req() request: Request, @Param('id') id: number, @@ -104,7 +106,7 @@ export class ObservationsController { @UsePipes(ValidationPipe) @UseGuards(new AuthGuard()) public async getObservationListByName( - @Body() body: Body, + @Body() body: ObservationSearchDto, @Res() response: Response, @Req() request: Request, ) { @@ -119,7 +121,7 @@ export class ObservationsController { @UsePipes(ValidationPipe) @UseGuards(new AuthGuard()) public async createFields( - @Body() body: CreateFieldDto, + @Body() body: FieldDto, @Res() response: Response, @Req() request: Request, ) { @@ -130,7 +132,7 @@ export class ObservationsController { @UsePipes(ValidationPipe) @UseGuards(new AuthGuard()) public async updateFields( - @Body() body: CreateFieldDto, + @Body() body: FieldDto, @Res() response: Response, @Req() request: Request, @Param('id') id: number, @@ -180,7 +182,7 @@ export class ObservationsController { @UsePipes(ValidationPipe) @UseGuards(new AuthGuard()) public async getFieldListByName( - @Body() body: Body, + @Body() body: FieldSearchDto, @Res() response: Response, @Req() request: Request, ) { diff --git a/src/src/observations/observations.service.ts b/src/src/observations/observations.service.ts index 23070fd7c..8a3bf263d 100644 --- a/src/src/observations/observations.service.ts +++ b/src/src/observations/observations.service.ts @@ -56,7 +56,8 @@ export class ObservationsService { async createObservation(body: any, resp: any, request: any) { let user_id = request?.mw_userid; - + let response; + let data; body.created_by = user_id; body.updated_by = user_id; if (!user_id) { @@ -66,15 +67,33 @@ export class ObservationsService { }); } - let result = await this.hasuraService.q( - this.tableName, - { - ...body, - }, - this.fillable, - false, - this.returnFields, - ); + let query = ''; + Object.keys(body).forEach((e) => { + if (body[e] && body[e] != '') { + if (e === 'render') { + query += `${e}: ${body[e]}, `; + } else if (Array.isArray(body[e])) { + query += `${e}: "${JSON.stringify(body[e])}", `; + } else { + query += `${e}: "${body[e]}", `; + } + } + }); + + data = { + query: `mutation CreateObservations { + insert_observations_one(object: {${query}}) { + id + name + } + } + `, + variables: {}, + }; + + response = await this.hasuraServiceFromServices.queryWithVariable(data); + + let result = response?.data?.data?.insert_observations_one; if (result) { return resp.status(200).json({ @@ -92,6 +111,7 @@ export class ObservationsService { } async createFields(body: any, resp: any, request: any) { + let data; let user_id = request?.mw_userid; body.created_by = user_id; @@ -108,16 +128,39 @@ export class ObservationsService { }); } - let result = await this.hasuraService.q( - this.FieldTableName, - { - ...body, - }, - this.FieldFillable, - false, - this.FieldReturnFields, + let query = ''; + Object.keys(body).forEach((e) => { + if (body[e] && body[e] != '') { + if (e === 'render') { + query += `${e}: ${body[e]}, `; + } else if (Array.isArray(body[e])) { + query += `${e}: "${JSON.stringify(body[e])}", `; + } else { + query += `${e}: "${body[e]}", `; + } + } + }); + + data = { + query: `mutation CreateFields { + insert_fields_one(object: {${query}}) { + id + name + title + enum + + + } + } + `, + variables: {}, + }; + + let response = await this.hasuraServiceFromServices.queryWithVariable( + data, ); + let result = response?.data?.data?.insert_fields_one; if (result) { return resp.status(200).json({ success: true, @@ -215,6 +258,8 @@ export class ObservationsService { let response; let newQdata; let query; + let obj_filters; + let data; let user_id = request?.mw_userid; if (!user_id) { @@ -224,38 +269,52 @@ export class ObservationsService { }); } - if (body?.name) { - query = `query MyQuery { - observations(where: {name: {_ilike: "%${body?.name}%"}}) { - created_at - created_by - id - name - updated_at - updated_by - } - } - - - `; + if (body?.filters) { + let filters = new Object(body); + + Object.keys(body.filters).forEach((item) => { + Object.keys(body.filters[item]).forEach((e) => { + if (!e.startsWith('_')) { + filters[item][`_${e}`] = filters[item][e]; + delete filters[item][e]; + } + }); + }); + + data = { + query: `query Searchobservations($filters:observations_bool_exp) { + observations(where:$filters) { + created_at + created_by + id + name + updated_at + updated_by + } + }`, + variables: { + filters: body.filters, + }, + }; } else { - query = `query MyQuery { - observations{ - id - name - created_at - created_by - updated_by - } - } - - `; + data = { + query: `query MyQuery { + observations{ + id + name + created_at + created_by + updated_by + } + } + + `, + }; } - response = await this.hasuraServiceFromServices.getData({ - query: query, - }); - newQdata = response?.data?.observations; + response = await this.hasuraServiceFromServices.queryWithVariable(data); + + newQdata = response?.data?.data?.observations; if (newQdata.length > 0) { return resp.status(200).json({ @@ -277,6 +336,7 @@ export class ObservationsService { let newQdata; let query; let user_id = request?.mw_userid; + let data; if (!user_id) { return resp.status(422).json({ @@ -285,47 +345,64 @@ export class ObservationsService { }); } - if (body?.name) { - query = `query MyQuery { - fields(where: {name: {_ilike: "%${body?.name}%"}}) { - created_at - created_by - id - name - updated_at - updated_by - data_type - description - extra_all_info - } - } - - - - `; + if (body?.filters) { + let filters = new Object(body); + + Object.keys(body.filters).forEach((item) => { + Object.keys(body.filters[item]).forEach((e) => { + if (!e.startsWith('_')) { + filters[item][`_${e}`] = filters[item][e]; + delete filters[item][e]; + } + }); + }); + + data = { + query: `query Searchfields($filters:fields_bool_exp) { + fields(where:$filters) { + created_at + created_by + id + name + updated_at + updated_by + data_type + description + extra_all_info + title + enum + } + }`, + variables: { + filters: body.filters, + }, + }; } else { - query = `query MyQuery { - fields { - created_at - created_by - id - name - updated_at - updated_by - data_type - description - extra_all_info - } - } - - - `; + data = { + query: `query MyQuery { + fields { + created_at + created_by + id + name + updated_at + updated_by + data_type + description + extra_all_info + title + enum + } + } + + + `, + }; } - response = await this.hasuraServiceFromServices.getData({ - query: query, - }); - newQdata = response?.data?.fields; + response = await this.hasuraServiceFromServices.queryWithVariable(data); + + newQdata = response?.data?.data?.fields; if (newQdata.length > 0) { return resp.status(200).json({ From b59f5b8afda25ee9b411cef26f8939b7d3027faf Mon Sep 17 00:00:00 2001 From: Rushi G Date: Sat, 16 Mar 2024 14:35:08 +0530 Subject: [PATCH 067/126] Task #215534 base64 document added in experience and qualification docuemnts of users --- src/src/app.module.ts | 1 + src/src/main.ts | 2 +- src/src/userauth/userauth.service.ts | 137 +++++++++++++++++++-------- 3 files changed, 102 insertions(+), 38 deletions(-) diff --git a/src/src/app.module.ts b/src/src/app.module.ts index 2680837cf..13e836395 100755 --- a/src/src/app.module.ts +++ b/src/src/app.module.ts @@ -38,6 +38,7 @@ import { UploadFileModule } from './upload-file/upload-file.module'; import { UserModule } from './user/user.module'; import { UserauthModule } from './userauth/userauth.module'; import { BoardModule } from './modules/board/board.module'; + @Module({ imports: [ ScheduleModule.forRoot(), diff --git a/src/src/main.ts b/src/src/main.ts index 52cd72b3f..418df48e4 100755 --- a/src/src/main.ts +++ b/src/src/main.ts @@ -5,7 +5,7 @@ const Sentry = require('@sentry/node'); async function bootstrap() { const app = await NestFactory.create(AppModule, { cors: true }); - + console.log('password', process.env.CACHE_REDIS_PASSWORD); Sentry.init({ dsn: process.env.SENTRY_DSN_URL, environment: process.env.SENTRY_ENVIRONMENT, diff --git a/src/src/userauth/userauth.service.ts b/src/src/userauth/userauth.service.ts index edfa92f87..54eda015b 100644 --- a/src/src/userauth/userauth.service.ts +++ b/src/src/userauth/userauth.service.ts @@ -14,6 +14,10 @@ const fs = require('fs'); const https = require('https'); const path = require('path'); +//url to base64 +import fetch from 'node-fetch'; +import { Buffer } from 'buffer'; + @Injectable() export class UserauthService { public smsKey = this.configService.get('SMS_KEY'); @@ -380,6 +384,20 @@ export class UserauthService { return null; } } + public async fileUrlToBase64(imageUrl: string): Promise { + try { + const response = await fetch(imageUrl); + const arrayBuffer = await response.arrayBuffer(); + const buffer = Buffer.from(arrayBuffer); + const base64Data = buffer.toString('base64'); + const fileType = response.headers.get('content-type'); // Get the content type from the response headers + const base64String = `data:${fileType};base64,${base64Data}`; // Include the content type in the Base64 string + return base64String; + } catch (error) { + console.error('Error converting image to Base64:', error); + throw error; + } + } public async getUserInfoDetails(request, response) { let user_id = request.mw_userid; //get user id from token @@ -387,6 +405,7 @@ export class UserauthService { let academic_year_id = request?.mw_academic_year_id; // get academic_year_id from token //query to get user details information + //console.log('user_id', user_id); let query = `query MyQuery { users_by_pk(id:${user_id}) { @@ -545,6 +564,8 @@ export class UserauthService { let user_data = hasura_response?.data; + //console.log('user_data', JSON.stringify(user_data)); + // get profile photo document details let profilePhoto1Documents = user_data?.users_by_pk?.profile_photo_1_documents; @@ -581,8 +602,10 @@ export class UserauthService { ]; const base64Profiles = await Promise.all( - profilePhotoUrls.map((url) => - this.fetchFileAndConvertToBase64(url, agent), + profilePhotoUrls.map( + async (url) => + //this.fetchFileAndConvertToBase64(url, agent), + await this.fileUrlToBase64(url), ), ); @@ -654,45 +677,85 @@ export class UserauthService { delete user_data.users_by_pk.profile_photo_2_documents; delete user_data.users_by_pk.profile_photo_3_documents; - // Iterate through the experience array and update references document_reference to documents - user_data?.users_by_pk?.experience?.forEach((exp) => { - exp.references = exp?.references?.reduce((acc, ref) => { - const documents = ref?.document_reference - ? { - base64: null, - document_id: ref?.document_reference?.document_id, - name: ref?.document_reference?.name, - document_sub_type: - ref?.document_reference?.document_sub_type, - document_type: - ref?.document_reference?.doument_type, - path: ref?.document_reference?.path, - provider: ref?.document_reference?.provider, - context: ref?.document_reference?.context, - context_id: ref?.document_reference?.context_id, - } - : {}; - - delete ref?.document_reference; // Remove document_reference - - return { ...acc, ...ref, documents }; - }, {}); - }); - + // update experience format + let experience_format = []; + if (user_data?.users_by_pk?.experience) { + for ( + let i = 0; + i <= user_data?.users_by_pk?.experience.length; + i++ + ) { + let obj_experience = user_data?.users_by_pk?.experience[i]; + let obj_reference = obj_experience?.references[0]; + let temp_reference = {}; + if (obj_reference) { + let obj_document = obj_reference?.document_reference; + let temp_document = {}; + if (obj_document) { + let exp_document_base64 = null; + let obj_document_name = obj_document?.name; + if (obj_document_name) { + let obj_document_url = + await this.s3Service.getFileUrl( + obj_document_name, + ); + exp_document_base64 = await this.fileUrlToBase64( + obj_document_url, + ); + } + temp_document = { + base64: exp_document_base64, + document_id: obj_document?.document_id, + name: obj_document?.name, + document_sub_type: obj_document?.document_sub_type, + doument_type: obj_document?.doument_type, + path: obj_document?.path, + provider: obj_document?.provider, + context: obj_document?.context, + context_id: obj_document?.context_id, + }; + } + temp_reference = { + id: obj_reference?.id, + name: obj_reference?.name, + contact_number: obj_reference?.contact_number, + type_of_document: obj_reference?.type_of_document, + document_id: obj_reference?.document_id, + documents: temp_document, + }; + } + let temp_experience = { + id: obj_experience?.id, + type: obj_experience?.type, + role_title: obj_experience?.role_title, + organization: obj_experience?.organization, + description: obj_experience?.description, + experience_in_years: obj_experience?.experience_in_years, + related_to_teaching: obj_experience?.related_to_teaching, + references: temp_reference, + }; + experience_format.push(temp_experience); + } + } + user_data.users_by_pk.experience = experience_format; + + //update qualification format + let base64Qualifications = null; + let qualification_doc_name = + user_data.users_by_pk?.qualifications[0]?.document_reference?.name; + if (qualification_doc_name) { + let qualification_file_url = await this.s3Service.getFileUrl( + qualification_doc_name, + ); + base64Qualifications = await this.fileUrlToBase64( + qualification_file_url, + ); + } user_data.users_by_pk.qualifications = user_data?.users_by_pk?.qualifications?.reduce((acc, q) => { - const qualification_file_url = this.s3Service.getFileUrl( - q?.document_reference?.name, - ); - - const base64Qualifications = this.fetchFileAndConvertToBase64( - qualification_file_url, - agent, - ); - const documents = q.document_reference ? { - base64: null, + base64: base64Qualifications, document_id: q?.document_reference?.document_id, name: q?.document_reference?.name, path: q?.document_reference?.path, From 033dcc258d5594fbd6af355af42bf68bf24745fd Mon Sep 17 00:00:00 2001 From: Rushi G Date: Sat, 16 Mar 2024 15:33:33 +0530 Subject: [PATCH 068/126] Task #215534 base64 document added in experience and qualification docuemnts of users --- src/src/main.ts | 1 - src/src/userauth/userauth.service.ts | 186 ++++++++++++--------------- 2 files changed, 80 insertions(+), 107 deletions(-) diff --git a/src/src/main.ts b/src/src/main.ts index 418df48e4..63f74e7af 100755 --- a/src/src/main.ts +++ b/src/src/main.ts @@ -5,7 +5,6 @@ const Sentry = require('@sentry/node'); async function bootstrap() { const app = await NestFactory.create(AppModule, { cors: true }); - console.log('password', process.env.CACHE_REDIS_PASSWORD); Sentry.init({ dsn: process.env.SENTRY_DSN_URL, environment: process.env.SENTRY_ENVIRONMENT, diff --git a/src/src/userauth/userauth.service.ts b/src/src/userauth/userauth.service.ts index 54eda015b..169f6bafa 100644 --- a/src/src/userauth/userauth.service.ts +++ b/src/src/userauth/userauth.service.ts @@ -11,7 +11,6 @@ import { UserService } from 'src/user/user.service'; import { S3Service } from 'src/services/s3/s3.service'; const axios = require('axios'); const fs = require('fs'); -const https = require('https'); const path = require('path'); //url to base64 @@ -367,23 +366,6 @@ export class UserauthService { } } - async fetchFileAndConvertToBase64(fileUrl, agent) { - try { - const file = await axios.get(fileUrl, { - responseType: 'arraybuffer', - httpsAgent: agent, - }); - - const extension = path.extname(fileUrl.split('/').pop()).substr(1); - const base64 = Buffer.from(file?.data, 'binary').toString('base64'); - const dataUrl = `data:image/${extension};base64,${base64}`; - - return dataUrl; - } catch (error) { - console.error('Error fetching file and converting to base64:'); - return null; - } - } public async fileUrlToBase64(imageUrl: string): Promise { try { const response = await fetch(imageUrl); @@ -395,7 +377,7 @@ export class UserauthService { return base64String; } catch (error) { console.error('Error converting image to Base64:', error); - throw error; + return null; } } @@ -578,91 +560,83 @@ export class UserauthService { // modifiy individual profile photo document details as required - const agent = new https.Agent({ - rejectUnauthorized: false, // Ignore SSL certificate validation - }); - // get file url and convert to base64 - const profile_photo_1_file_Url = await this.s3Service.getFileUrl( - profilePhoto1Documents?.[0]?.name, - ); - - const profile_photo_2_file_Url = await this.s3Service.getFileUrl( - profilePhoto2Documents?.[0]?.name, - ); - - const profile_photo_3_file_Url = await this.s3Service.getFileUrl( - profilePhoto3Documents?.[0]?.name, - ); - - const profilePhotoUrls = [ - profile_photo_1_file_Url, - profile_photo_2_file_Url, - profile_photo_3_file_Url, - ]; - - const base64Profiles = await Promise.all( - profilePhotoUrls.map( - async (url) => - //this.fetchFileAndConvertToBase64(url, agent), - await this.fileUrlToBase64(url), - ), - ); - - const [ - data_base64_profile_1, - data_base64_profile_2, - data_base64_profile_3, - ] = base64Profiles; - - let profile_photo_1_info = { - name: user_data?.users_by_pk?.profile_photo_1, - documents: { - base64: data_base64_profile_1, - document_id: profilePhoto1Documents?.[0]?.document_id, - name: profilePhoto1Documents?.[0]?.name, - document_type: profilePhoto1Documents?.[0]?.doument_type, - document_sub_type: - profilePhoto1Documents?.[0]?.document_sub_type, - path: profilePhoto1Documents?.[0]?.path, - provider: profilePhoto1Documents?.[0]?.provider, - context: profilePhoto1Documents?.[0]?.context, - context_id: profilePhoto1Documents?.[0]?.context_id, - }, - }; - - let profile_photo_2_info = { - name: user_data?.users_by_pk?.profile_photo_2, - documents: { - base64: data_base64_profile_2, - document_id: profilePhoto2Documents?.[0]?.document_id, - name: profilePhoto2Documents?.[0]?.name, - document_type: profilePhoto2Documents?.[0]?.doument_type, - document_sub_type: - profilePhoto2Documents?.[0]?.document_sub_type, - path: profilePhoto2Documents?.[0]?.path, - provider: profilePhoto2Documents?.[0]?.provider, - context: profilePhoto2Documents?.[0]?.context, - context_id: profilePhoto2Documents?.[0]?.context_id, - }, - }; - - let profile_photo_3_info = { - name: user_data?.users_by_pk?.profile_photo_3, - documents: { - base64: data_base64_profile_3, - document_id: profilePhoto3Documents?.[0]?.document_id, - name: profilePhoto3Documents?.[0]?.name, - document_type: - profilePhoto3Documents?.[0]?.doument_type || null, - document_sub_type: - profilePhoto3Documents?.[0]?.document_sub_type, - path: profilePhoto3Documents?.[0]?.path, - provider: profilePhoto3Documents?.[0]?.provider, - context: profilePhoto3Documents?.[0]?.context, - context_id: profilePhoto3Documents?.[0]?.context_id, - }, - }; + let data_base64_profile_1 = null; + let profile_photo_1_info = {}; + if (profilePhoto1Documents?.[0]) { + const profile_photo_1_file_Url = await this.s3Service.getFileUrl( + profilePhoto1Documents?.[0]?.name, + ); + data_base64_profile_1 = await this.fileUrlToBase64( + profile_photo_1_file_Url, + ); + profile_photo_1_info = { + name: user_data?.users_by_pk?.profile_photo_1, + documents: { + base64: data_base64_profile_1, + document_id: profilePhoto1Documents?.[0]?.document_id, + name: profilePhoto1Documents?.[0]?.name, + document_type: profilePhoto1Documents?.[0]?.doument_type, + document_sub_type: + profilePhoto1Documents?.[0]?.document_sub_type, + path: profilePhoto1Documents?.[0]?.path, + provider: profilePhoto1Documents?.[0]?.provider, + context: profilePhoto1Documents?.[0]?.context, + context_id: profilePhoto1Documents?.[0]?.context_id, + }, + }; + } + let data_base64_profile_2 = null; + let profile_photo_2_info = {}; + if (profilePhoto2Documents?.[0]) { + const profile_photo_2_file_Url = await this.s3Service.getFileUrl( + profilePhoto2Documents?.[0]?.name, + ); + data_base64_profile_2 = await this.fileUrlToBase64( + profile_photo_2_file_Url, + ); + profile_photo_2_info = { + name: user_data?.users_by_pk?.profile_photo_2, + documents: { + base64: data_base64_profile_2, + document_id: profilePhoto2Documents?.[0]?.document_id, + name: profilePhoto2Documents?.[0]?.name, + document_type: profilePhoto2Documents?.[0]?.doument_type, + document_sub_type: + profilePhoto2Documents?.[0]?.document_sub_type, + path: profilePhoto2Documents?.[0]?.path, + provider: profilePhoto2Documents?.[0]?.provider, + context: profilePhoto2Documents?.[0]?.context, + context_id: profilePhoto2Documents?.[0]?.context_id, + }, + }; + } + let data_base64_profile_3 = null; + let profile_photo_3_info = {}; + if (profilePhoto3Documents?.[0]) { + const profile_photo_3_file_Url = await this.s3Service.getFileUrl( + profilePhoto3Documents?.[0]?.name, + ); + data_base64_profile_3 = await this.fileUrlToBase64( + profile_photo_3_file_Url, + ); + profile_photo_3_info = { + name: user_data?.users_by_pk?.profile_photo_3, + documents: { + base64: data_base64_profile_3, + document_id: profilePhoto3Documents?.[0]?.document_id, + name: profilePhoto3Documents?.[0]?.name, + document_type: + profilePhoto3Documents?.[0]?.doument_type || null, + document_sub_type: + profilePhoto3Documents?.[0]?.document_sub_type, + path: profilePhoto3Documents?.[0]?.path, + provider: profilePhoto3Documents?.[0]?.provider, + context: profilePhoto3Documents?.[0]?.context, + context_id: profilePhoto3Documents?.[0]?.context_id, + }, + }; + } if (!user_data?.users_by_pk) { user_data.users_by_pk = {}; // Initialize as an empty object if it doesn't exist @@ -679,7 +653,7 @@ export class UserauthService { // update experience format let experience_format = []; - if (user_data?.users_by_pk?.experience) { + if (user_data?.users_by_pk?.experience.length > 0) { for ( let i = 0; i <= user_data?.users_by_pk?.experience.length; @@ -853,8 +827,8 @@ export class UserauthService { aadhaar_verification_mode, id, }, - core_faciltator: user_data?.users_by_pk?.core_faciltator, - extended_users: user_data?.users_by_pk?.extended_users, + core_faciltator: user_data?.users_by_pk?.core_faciltator || {}, + extended_users: user_data?.users_by_pk?.extended_users || {}, references: user_data?.users_by_pk?.references, program_faciltators: user_data?.users_by_pk?.program_faciltators, experience: user_data?.users_by_pk?.experience, From 8a9847bb808e397080bcf9956ed93835ace83f08 Mon Sep 17 00:00:00 2001 From: GitVivekHub Date: Sat, 16 Mar 2024 16:20:10 +0530 Subject: [PATCH 069/126] observation-fields and fields-response commit --- .../dto/field-responses-search.dto.ts | 7 + .../observations/dto/field-responses.dto.ts | 23 + .../dto/observation-fields-search.dto.ts | 7 + .../dto/observation-fields.dto.ts | 19 + .../observations/observations.controller.ts | 190 ++++ src/src/observations/observations.service.ts | 808 ++++++++++++++++-- 6 files changed, 993 insertions(+), 61 deletions(-) create mode 100644 src/src/observations/dto/field-responses-search.dto.ts create mode 100644 src/src/observations/dto/field-responses.dto.ts create mode 100644 src/src/observations/dto/observation-fields-search.dto.ts create mode 100644 src/src/observations/dto/observation-fields.dto.ts diff --git a/src/src/observations/dto/field-responses-search.dto.ts b/src/src/observations/dto/field-responses-search.dto.ts new file mode 100644 index 000000000..71961e308 --- /dev/null +++ b/src/src/observations/dto/field-responses-search.dto.ts @@ -0,0 +1,7 @@ +import { IsNotEmpty, IsString, IsObject } from 'class-validator'; + +export class FieldResponsesSearchDto { + @IsNotEmpty() + @IsObject() + filters: any; +} diff --git a/src/src/observations/dto/field-responses.dto.ts b/src/src/observations/dto/field-responses.dto.ts new file mode 100644 index 000000000..ebc6c7c62 --- /dev/null +++ b/src/src/observations/dto/field-responses.dto.ts @@ -0,0 +1,23 @@ +import { IsNotEmpty, IsString, IsObject, IsNumber } from 'class-validator'; + +export class FieldResponsesDto { + @IsNotEmpty() + @IsNumber() + observation_id: number; + + @IsNotEmpty() + @IsNumber() + field_id: number; + + @IsNotEmpty() + @IsString() + response_value: string; + + @IsNotEmpty() + @IsString() + context: string; + + @IsNotEmpty() + @IsNumber() + context_id: number; +} diff --git a/src/src/observations/dto/observation-fields-search.dto.ts b/src/src/observations/dto/observation-fields-search.dto.ts new file mode 100644 index 000000000..cba2d1d62 --- /dev/null +++ b/src/src/observations/dto/observation-fields-search.dto.ts @@ -0,0 +1,7 @@ +import { IsNotEmpty, IsString, IsObject } from 'class-validator'; + +export class ObservationFieldSearchDto { + @IsNotEmpty() + @IsObject() + filters: any; +} diff --git a/src/src/observations/dto/observation-fields.dto.ts b/src/src/observations/dto/observation-fields.dto.ts new file mode 100644 index 000000000..15d3a1700 --- /dev/null +++ b/src/src/observations/dto/observation-fields.dto.ts @@ -0,0 +1,19 @@ +import { IsNotEmpty, IsString, IsNumber, IsObject } from 'class-validator'; + +export class ObservationFieldsDto { + @IsNotEmpty() + @IsNumber() + observation_id: number; + + @IsNotEmpty() + @IsString() + context: string; + + @IsNotEmpty() + @IsNumber() + context_id: number; + + @IsNotEmpty() + @IsNumber() + field_id: number; +} diff --git a/src/src/observations/observations.controller.ts b/src/src/observations/observations.controller.ts index 82bcd5dec..eb8c020de 100644 --- a/src/src/observations/observations.controller.ts +++ b/src/src/observations/observations.controller.ts @@ -20,6 +20,10 @@ import { ObservationDto } from './dto/observation.dto'; import { FieldDto } from './dto/field.dto'; import { FieldSearchDto } from './dto/field-search.dto'; import { ObservationSearchDto } from './dto/observation-search.dto'; +import { ObservationFieldsDto } from './dto/observation-fields.dto'; +import { ObservationFieldSearchDto } from './dto/observation-fields-search.dto'; +import { FieldResponsesDto } from './dto/field-responses.dto'; +import { FieldResponsesSearchDto } from './dto/field-responses-search.dto'; @Controller('observations') export class ObservationsController { @@ -40,6 +44,21 @@ export class ObservationsController { ); } + @Post('/observation-fields') + @UsePipes(ValidationPipe) + @UseGuards(new AuthGuard()) + public async createObservationFields( + @Body() body: ObservationFieldsDto, + @Res() response: Response, + @Req() request: Request, + ) { + return this.observationsService.createObservationFields( + body, + response, + request, + ); + } + @Patch('/:id') @UsePipes(ValidationPipe) @UseGuards(new AuthGuard()) @@ -57,6 +76,23 @@ export class ObservationsController { ); } + @Patch('/observation-fields/:id') + @UsePipes(ValidationPipe) + @UseGuards(new AuthGuard()) + public async updateObservationField( + @Body() body: ObservationFieldsDto, + @Res() response: Response, + @Req() request: Request, + @Param('id') id: number, + ) { + return this.observationsService.updateObservationField( + body, + response, + request, + id, + ); + } + @Get('/list') @UsePipes(ValidationPipe) @UseGuards(new AuthGuard()) @@ -72,6 +108,21 @@ export class ObservationsController { ); } + @Get('/observation-fields/list') + @UsePipes(ValidationPipe) + @UseGuards(new AuthGuard()) + public async getObservationFieldList( + @Body() body: Body, + @Res() response: Response, + @Req() request: Request, + ) { + return this.observationsService.getObservationFieldList( + body, + response, + request, + ); + } + @Get('/:id') @UsePipes(ValidationPipe) @UseGuards(new AuthGuard()) @@ -87,6 +138,21 @@ export class ObservationsController { ); } + @Get('/observation-fields/:id') + @UsePipes(ValidationPipe) + @UseGuards(new AuthGuard()) + public async getObservationFieldById( + @Res() response: Response, + @Req() request: Request, + @Param('id') id: number, + ) { + return this.observationsService.getObservationFieldById( + response, + request, + id, + ); + } + @Delete('/:id') @UsePipes(ValidationPipe) @UseGuards(new AuthGuard()) @@ -102,6 +168,21 @@ export class ObservationsController { ); } + @Delete('observation-fields/:id') + @UsePipes(ValidationPipe) + @UseGuards(new AuthGuard()) + public async deleteObservationFieldById( + @Res() response: Response, + @Req() request: Request, + @Param('id') id: number, + ) { + return this.observationsService.deleteObservationFieldById( + response, + request, + id, + ); + } + @Post('/list') @UsePipes(ValidationPipe) @UseGuards(new AuthGuard()) @@ -117,6 +198,21 @@ export class ObservationsController { ); } + @Post('observation-fields/list') + @UsePipes(ValidationPipe) + @UseGuards(new AuthGuard()) + public async getObservationFieldsListByName( + @Body() body: ObservationFieldSearchDto, + @Res() response: Response, + @Req() request: Request, + ) { + return this.observationsService.getObservationFieldList( + body, + response, + request, + ); + } + @Post('/fields') @UsePipes(ValidationPipe) @UseGuards(new AuthGuard()) @@ -188,4 +284,98 @@ export class ObservationsController { ) { return this.observationsService.getFieldsList(body, response, request); } + + // + + @Post('/field-responses') + @UsePipes(ValidationPipe) + @UseGuards(new AuthGuard()) + public async createFieldResponses( + @Body() body: FieldResponsesDto, + @Res() response: Response, + @Req() request: Request, + ) { + return this.observationsService.createFieldResponses( + body, + response, + request, + ); + } + + @Patch('/field-responses/:id') + @UsePipes(ValidationPipe) + @UseGuards(new AuthGuard()) + public async updateFieldResponses( + @Body() body: FieldResponsesDto, + @Res() response: Response, + @Req() request: Request, + @Param('id') id: number, + ) { + return this.observationsService.updateFieldResponses( + body, + response, + request, + id, + ); + } + + @Get('/field-responses/list') + @UsePipes(ValidationPipe) + @UseGuards(new AuthGuard()) + public async getFieldResponsesList( + @Body() body: Body, + @Res() response: Response, + @Req() request: Request, + ) { + return this.observationsService.getFieldResponsesList( + body, + response, + request, + ); + } + + @Get('/field-responses/:id') + @UsePipes(ValidationPipe) + @UseGuards(new AuthGuard()) + public async getFieldResponsesById( + @Res() response: Response, + @Req() request: Request, + @Param('id') id: number, + ) { + return this.observationsService.getFieldResponsesById( + response, + request, + id, + ); + } + + @Delete('/field-responses/:id') + @UsePipes(ValidationPipe) + @UseGuards(new AuthGuard()) + public async deleteFieldResponsesById( + @Res() response: Response, + @Req() request: Request, + @Param('id') id: number, + ) { + return this.observationsService.deleteFieldResponsesById( + response, + request, + id, + ); + } + + @Post('/field-responses/list') + @UsePipes(ValidationPipe) + @UseGuards(new AuthGuard()) + public async getFieldResponsesListByName( + @Body() body: FieldResponsesSearchDto, + @Res() response: Response, + @Req() request: Request, + ) { + return this.observationsService.getFieldResponsesList( + body, + response, + request, + ); + } } diff --git a/src/src/observations/observations.service.ts b/src/src/observations/observations.service.ts index 8a3bf263d..048939d1d 100644 --- a/src/src/observations/observations.service.ts +++ b/src/src/observations/observations.service.ts @@ -176,6 +176,124 @@ export class ObservationsService { } } + async createObservationFields(body: any, resp: any, request: any) { + let user_id = request?.mw_userid; + let response; + let data; + body.created_by = user_id; + body.updated_by = user_id; + if (!user_id) { + return resp.status(422).json({ + message: 'Invalid User Entity', + data: null, + }); + } + + let query = ''; + Object.keys(body).forEach((e) => { + if (body[e] && body[e] != '') { + if (e === 'render') { + query += `${e}: ${body[e]}, `; + } else if (Array.isArray(body[e])) { + query += `${e}: "${JSON.stringify(body[e])}", `; + } else { + query += `${e}: "${body[e]}", `; + } + } + }); + + data = { + query: `mutation CreateObservationFields { + insert_observation_fields_one(object: {${query}}) { + id + observation_id + context + context_id + field_id + } + } + `, + variables: {}, + }; + + response = await this.hasuraServiceFromServices.queryWithVariable(data); + + let result = response?.data?.data?.insert_observation_fields_one; + + if (result) { + return resp.status(200).json({ + success: true, + message: 'Observation Field created successfully!', + data: result, + }); + } else { + return resp.status(500).json({ + success: false, + message: 'Unable to create obsevation Field!', + data: {}, + }); + } + } + + async createFieldResponses(body: any, resp: any, request: any) { + let user_id = request?.mw_userid; + let response; + let data; + body.created_by = user_id; + body.updated_by = user_id; + if (!user_id) { + return resp.status(422).json({ + message: 'Invalid User Entity', + data: null, + }); + } + + let query = ''; + Object.keys(body).forEach((e) => { + if (body[e] && body[e] != '') { + if (e === 'render') { + query += `${e}: ${body[e]}, `; + } else if (Array.isArray(body[e])) { + query += `${e}: "${JSON.stringify(body[e])}", `; + } else { + query += `${e}: "${body[e]}", `; + } + } + }); + + data = { + query: `mutation CreateFieldsResponses { + insert_field_responses_one(object: {${query}}) { + id + observation_id + context + context_id + response_value + } + } + `, + variables: {}, + }; + + response = await this.hasuraServiceFromServices.queryWithVariable(data); + + let result = response?.data?.data?.insert_field_responses_one; + + if (result) { + return resp.status(200).json({ + success: true, + message: 'Observation Field created successfully!', + data: result, + }); + } else { + return resp.status(500).json({ + success: false, + message: 'Unable to create obsevation Field!', + data: {}, + }); + } + } + async updateObservation(body: any, resp: any, request: any, id: any) { let user_id = request?.mw_userid; @@ -187,17 +305,45 @@ export class ObservationsService { }); } - let result = await this.hasuraService.q( - this.tableName, - { - ...body, + let query = ''; + Object.keys(body).forEach((e) => { + if (body[e] && body[e] != '') { + if (e === 'render') { + query += `${e}: ${body[e]}, `; + } else if (Array.isArray(body[e])) { + query += `${e}: "${JSON.stringify(body[e])}", `; + } else { + query += `${e}: "${body[e]}", `; + } + } + }); + + var data = { + query: ` + mutation UpdateObservations($id:Int!) { + update_observations_by_pk( + pk_columns: { + id: $id + }, + _set: { + ${query} + } + ) { + id + } + } + `, + variables: { id: id, }, - this.fillable, - true, - this.returnFields, + }; + + let response = await this.hasuraServiceFromServices.queryWithVariable( + data, ); + let result = response?.data?.data?.update_observations_by_pk; + if (result) { return resp.status(200).json({ success: true, @@ -224,37 +370,360 @@ export class ObservationsService { }); } - body.enum = body?.enum - ? JSON.stringify(body?.enum).replace(/"/g, '\\"') - : ''; + body.enum = body?.enum + ? JSON.stringify(body?.enum).replace(/"/g, '\\"') + : ''; + + let query = ''; + Object.keys(body).forEach((e) => { + if (body[e] && body[e] != '') { + if (e === 'render') { + query += `${e}: ${body[e]}, `; + } else if (Array.isArray(body[e])) { + query += `${e}: "${JSON.stringify(body[e])}", `; + } else { + query += `${e}: "${body[e]}", `; + } + } + }); + + var data = { + query: ` + mutation UpdateFields($id:Int!) { + update_fields_by_pk( + pk_columns: { + id: $id + }, + _set: { + ${query} + } + ) { + id + } + } + `, + variables: { + id: id, + }, + }; + + let response = await this.hasuraServiceFromServices.queryWithVariable( + data, + ); + + let result = response?.data?.data?.update_fields_by_pk; + + if (result) { + return resp.status(200).json({ + success: true, + message: 'Field updated successfully!', + data: result, + }); + } else { + return resp.status(500).json({ + success: false, + message: 'Unable to update Field !', + data: {}, + }); + } + } + + async updateObservationField(body: any, resp: any, request: any, id: any) { + let user_id = request?.mw_userid; + + body.updated_by = user_id; + if (!user_id) { + return resp.status(422).json({ + message: 'Invalid User Entity', + data: null, + }); + } + + let query = ''; + Object.keys(body).forEach((e) => { + if (body[e] && body[e] != '') { + if (e === 'render') { + query += `${e}: ${body[e]}, `; + } else if (Array.isArray(body[e])) { + query += `${e}: "${JSON.stringify(body[e])}", `; + } else { + query += `${e}: "${body[e]}", `; + } + } + }); + + var data = { + query: ` + mutation UpdateObservationFields($id:Int!) { + update_observation_fields_by_pk( + pk_columns: { + id: $id + }, + _set: { + ${query} + } + ) { + id + } + } + `, + variables: { + id: id, + }, + }; + + let response = await this.hasuraServiceFromServices.queryWithVariable( + data, + ); + + let result = response?.data?.data?.update_observation_fields_by_pk; + + if (result) { + return resp.status(200).json({ + success: true, + message: 'Observation-Field updated successfully!', + data: result, + }); + } else { + return resp.status(500).json({ + success: false, + message: 'Unable to update obsevation-field !', + data: {}, + }); + } + } + + async updateFieldResponses(body: any, resp: any, request: any, id: any) { + let user_id = request?.mw_userid; + + body.updated_by = user_id; + if (!user_id) { + return resp.status(422).json({ + message: 'Invalid User Entity', + data: null, + }); + } + + let query = ''; + Object.keys(body).forEach((e) => { + if (body[e] && body[e] != '') { + if (e === 'render') { + query += `${e}: ${body[e]}, `; + } else if (Array.isArray(body[e])) { + query += `${e}: "${JSON.stringify(body[e])}", `; + } else { + query += `${e}: "${body[e]}", `; + } + } + }); + + var data = { + query: ` + mutation UpdateFieldResponses($id:Int!) { + update_field_responses_by_pk( + pk_columns: { + id: $id + }, + _set: { + ${query} + } + ) { + id + } + } + `, + variables: { + id: id, + }, + }; + + let response = await this.hasuraServiceFromServices.queryWithVariable( + data, + ); + + let result = response?.data?.data?.update_field_responses_by_pk; + + if (result) { + return resp.status(200).json({ + success: true, + message: 'Field Responses updated successfully!', + data: result, + }); + } else { + return resp.status(500).json({ + success: false, + message: 'Unable to update field Responses !', + data: {}, + }); + } + } + + async getObservationList(body: any, resp: any, request: any) { + let response; + let newQdata; + let query; + let obj_filters; + let data; + let user_id = request?.mw_userid; + + if (!user_id) { + return resp.status(422).json({ + message: 'Invalid User Entity', + data: null, + }); + } + + if (body?.filters) { + let filters = new Object(body); + + Object.keys(body.filters).forEach((item) => { + Object.keys(body.filters[item]).forEach((e) => { + if (!e.startsWith('_')) { + filters[item][`_${e}`] = filters[item][e]; + delete filters[item][e]; + } + }); + }); + + data = { + query: `query Searchobservations($filters:observations_bool_exp) { + observations(where:$filters) { + created_at + created_by + id + name + updated_at + updated_by + } + }`, + variables: { + filters: body.filters, + }, + }; + } else { + data = { + query: `query MyQuery { + observations{ + id + name + created_at + created_by + updated_by + } + } + + `, + }; + } + + response = await this.hasuraServiceFromServices.queryWithVariable(data); + + newQdata = response?.data?.data?.observations; + + if (newQdata.length > 0) { + return resp.status(200).json({ + success: true, + message: 'Data found successfully!', + data: newQdata, + }); + } else { + return resp.json({ + status: 400, + message: 'Data Not Found', + data: {}, + }); + } + } + + async getFieldsList(body: any, resp: any, request: any) { + let response; + let newQdata; + let query; + let user_id = request?.mw_userid; + let data; + + if (!user_id) { + return resp.status(422).json({ + message: 'Invalid User Entity', + data: null, + }); + } + + if (body?.filters) { + let filters = new Object(body); + + Object.keys(body.filters).forEach((item) => { + Object.keys(body.filters[item]).forEach((e) => { + if (!e.startsWith('_')) { + filters[item][`_${e}`] = filters[item][e]; + delete filters[item][e]; + } + }); + }); + + data = { + query: `query Searchfields($filters:fields_bool_exp) { + fields(where:$filters) { + created_at + created_by + id + name + updated_at + updated_by + data_type + description + extra_all_info + title + enum + } + }`, + variables: { + filters: body.filters, + }, + }; + } else { + data = { + query: `query MyQuery { + fields { + created_at + created_by + id + name + updated_at + updated_by + data_type + description + extra_all_info + title + enum + } + } + + + `, + }; + } + + response = await this.hasuraServiceFromServices.queryWithVariable(data); - let result = await this.hasuraService.q( - this.FieldTableName, - { - ...body, - id: id, - }, - this.FieldFillable, - true, - this.FieldReturnFields, - ); + newQdata = response?.data?.data?.fields; - if (result) { + if (newQdata.length > 0) { return resp.status(200).json({ success: true, - message: 'Field updated successfully!', - data: result, + message: 'Data found successfully!', + data: newQdata, }); } else { - return resp.status(500).json({ - success: false, - message: 'Unable to update Field !', + return resp.json({ + status: 400, + message: 'Data Not Found', data: {}, }); } } - async getObservationList(body: any, resp: any, request: any) { + async getObservationFieldList(body: any, resp: any, request: any) { let response; let newQdata; let query; @@ -282,12 +751,15 @@ export class ObservationsService { }); data = { - query: `query Searchobservations($filters:observations_bool_exp) { - observations(where:$filters) { + query: `query Searchobservation_fields($filters:observation_fields_bool_exp) { + observation_fields(where:$filters) { created_at created_by id - name + observation_id + context + context_id + field_id updated_at updated_by } @@ -299,12 +771,16 @@ export class ObservationsService { } else { data = { query: `query MyQuery { - observations{ - id - name - created_at - created_by - updated_by + observation_fields{ + created_at + created_by + id + observation_id + context + context_id + field_id + updated_at + updated_by } } @@ -314,7 +790,7 @@ export class ObservationsService { response = await this.hasuraServiceFromServices.queryWithVariable(data); - newQdata = response?.data?.data?.observations; + newQdata = response?.data?.data?.observation_fields; if (newQdata.length > 0) { return resp.status(200).json({ @@ -331,12 +807,13 @@ export class ObservationsService { } } - async getFieldsList(body: any, resp: any, request: any) { + async getFieldResponsesList(body: any, resp: any, request: any) { let response; let newQdata; let query; - let user_id = request?.mw_userid; + let obj_filters; let data; + let user_id = request?.mw_userid; if (!user_id) { return resp.status(422).json({ @@ -358,19 +835,17 @@ export class ObservationsService { }); data = { - query: `query Searchfields($filters:fields_bool_exp) { - fields(where:$filters) { + query: `query Searchfield_responses($filters:field_responses_bool_exp) { + field_responses(where:$filters) { created_at created_by id - name + observation_id + context + context_id + response_value updated_at updated_by - data_type - description - extra_all_info - title - enum } }`, variables: { @@ -380,29 +855,26 @@ export class ObservationsService { } else { data = { query: `query MyQuery { - fields { - created_at - created_by - id - name - updated_at - updated_by - data_type - description - extra_all_info - title - enum + field_responses{ + created_at + created_by + id + observation_id + context + context_id + response_value + updated_at + updated_by } } - `, }; } response = await this.hasuraServiceFromServices.queryWithVariable(data); - newQdata = response?.data?.data?.fields; + newQdata = response?.data?.data?.field_responses; if (newQdata.length > 0) { return resp.status(200).json({ @@ -525,6 +997,114 @@ export class ObservationsService { } } + async getObservationFieldById(resp: any, request: any, id: any) { + let user_id = request?.mw_userid; + + if (!id) { + return resp.status(422).json({ + message: 'Please provide a valid get id', + data: null, + }); + } + + if (!user_id) { + return resp.status(422).json({ + message: 'Invalid User Entity', + data: null, + }); + } + + let query = `query MyQuery { + observation_fields_by_pk(id:${id}) { + created_at + created_by + id + observation_id + context + context_id + field_id + updated_at + updated_by + } + } + + + `; + + const response = await this.hasuraServiceFromServices.getData({ + query: query, + }); + const newQdata = response?.data?.observation_fields_by_pk; + + if (newQdata) { + return resp.status(200).json({ + success: true, + message: 'Data found successfully!', + data: newQdata, + }); + } else { + return resp.json({ + status: 400, + message: 'Data Not Found', + data: {}, + }); + } + } + + async getFieldResponsesById(resp: any, request: any, id: any) { + let user_id = request?.mw_userid; + + if (!id) { + return resp.status(422).json({ + message: 'Please provide a valid get id', + data: null, + }); + } + + if (!user_id) { + return resp.status(422).json({ + message: 'Invalid User Entity', + data: null, + }); + } + + let query = `query MyQuery { + field_responses_by_pk(id:${id}) { + created_at + created_by + id + observation_id + context + context_id + response_value + updated_at + updated_by + } + } + + + `; + + const response = await this.hasuraServiceFromServices.getData({ + query: query, + }); + const newQdata = response?.data?.field_responses_by_pk; + + if (newQdata) { + return resp.status(200).json({ + success: true, + message: 'Data found successfully!', + data: newQdata, + }); + } else { + return resp.json({ + status: 400, + message: 'Data Not Found', + data: {}, + }); + } + } + async deleteObservationById(resp: any, request: any, id: any) { let user_id = request?.mw_userid; @@ -627,4 +1207,110 @@ export class ObservationsService { }); } } + + async deleteObservationFieldById(resp: any, request: any, id: any) { + let user_id = request?.mw_userid; + + if (!id) { + return resp.status(422).json({ + message: 'Please provide a valid get id', + data: null, + }); + } + + if (!user_id) { + return resp.status(422).json({ + message: 'Invalid User Entity', + data: null, + }); + } + + let query = `mutation MyMutation { + delete_observation_fields_by_pk(id:${id}) { + created_at + created_by + id + observation_id + context + context_id + field_id + updated_at + updated_by + } + } + + `; + + const response = await this.hasuraServiceFromServices.getData({ + query: query, + }); + const newQdata = response?.data?.delete_observation_fields_by_pk; + + if (newQdata) { + return resp.status(200).json({ + success: true, + message: 'Data deleted successfully!', + data: newQdata, + }); + } else { + return resp.json({ + status: 400, + message: 'Data Not Found', + data: {}, + }); + } + } + + async deleteFieldResponsesById(resp: any, request: any, id: any) { + let user_id = request?.mw_userid; + + if (!id) { + return resp.status(422).json({ + message: 'Please provide a valid get id', + data: null, + }); + } + + if (!user_id) { + return resp.status(422).json({ + message: 'Invalid User Entity', + data: null, + }); + } + + let query = `mutation MyMutation { + delete_fields_responses_by_pk(id:${id}) { + created_at + created_by + id + observation_id + context + context_id + response_value + updated_at + updated_by + } + } + + `; + + const response = await this.hasuraServiceFromServices.getData({ + query: query, + }); + const newQdata = response?.data?.delete_fields_responses_by_pk; + + if (newQdata) { + return resp.status(200).json({ + success: true, + message: 'Data deleted successfully!', + data: newQdata, + }); + } else { + return resp.json({ + status: 400, + message: 'Data Not Found', + data: {}, + }); + } + } } From c0948560062fe8bc41b6bf0d811a49f8d5493120 Mon Sep 17 00:00:00 2001 From: GitVivekHub Date: Sun, 17 Mar 2024 01:48:04 +0530 Subject: [PATCH 070/126] validation changes for add/update api's and create bulk api for fields repsonse --- .../observations/observations.controller.ts | 15 + src/src/observations/observations.service.ts | 356 +++++++++++++++++- 2 files changed, 362 insertions(+), 9 deletions(-) diff --git a/src/src/observations/observations.controller.ts b/src/src/observations/observations.controller.ts index eb8c020de..60a54abff 100644 --- a/src/src/observations/observations.controller.ts +++ b/src/src/observations/observations.controller.ts @@ -302,6 +302,21 @@ export class ObservationsController { ); } + @Post('/field-responses') + @UsePipes(ValidationPipe) + @UseGuards(new AuthGuard()) + public async createFieldResponsesMany( + @Body() body: FieldResponsesDto, + @Res() response: Response, + @Req() request: Request, + ) { + return this.observationsService.createFieldResponsesMany( + body, + response, + request, + ); + } + @Patch('/field-responses/:id') @UsePipes(ValidationPipe) @UseGuards(new AuthGuard()) diff --git a/src/src/observations/observations.service.ts b/src/src/observations/observations.service.ts index 048939d1d..368555e32 100644 --- a/src/src/observations/observations.service.ts +++ b/src/src/observations/observations.service.ts @@ -67,6 +67,31 @@ export class ObservationsService { }); } + //check for duplicate name validation + + let vquery = `query MyQuery { + observations_aggregate(where: {name: {_eq:"${body?.name}"}}) { + aggregate { + count + } + } + }`; + + const vresponse = await this.hasuraServiceFromServices.getData({ + query: vquery, + }); + const newQdata = + vresponse?.data?.observations_aggregate?.aggregate?.count; + + console.log('newQdata-->>', vresponse); + if (newQdata > 0) { + return resp.status(422).json({ + success: false, + message: 'Duplicate name encountered !', + data: {}, + }); + } + let query = ''; Object.keys(body).forEach((e) => { if (body[e] && body[e] != '') { @@ -128,6 +153,27 @@ export class ObservationsService { }); } + let vquery = `query MyQuery { + fields_aggregate(where: {title: {_eq:"${body?.title}"}}) { + aggregate { + count + } + } + }`; + + const vresponse = await this.hasuraServiceFromServices.getData({ + query: vquery, + }); + const newQdata = vresponse?.data?.fields_aggregate?.aggregate?.count; + + if (newQdata > 0) { + return resp.status(422).json({ + success: false, + message: 'Duplicate title encountered !', + data: {}, + }); + } + let query = ''; Object.keys(body).forEach((e) => { if (body[e] && body[e] != '') { @@ -189,6 +235,28 @@ export class ObservationsService { }); } + let vquery = `query MyQuery { + observation_fields_aggregate(where: {observation_id: {_eq:${body?.observation_id}}, field_id: {_eq:${body?.field_id}}, context_id: {_eq:${body?.context_id}}}) { + aggregate { + count + } + } + }`; + + const vresponse = await this.hasuraServiceFromServices.getData({ + query: vquery, + }); + const newQdata = + vresponse?.data?.observation_fields_aggregate?.aggregate?.count; + + if (newQdata > 0) { + return resp.status(422).json({ + success: false, + message: 'Duplicate observation field encountered !', + data: {}, + }); + } + let query = ''; Object.keys(body).forEach((e) => { if (body[e] && body[e] != '') { @@ -248,6 +316,28 @@ export class ObservationsService { }); } + let vquery = `query MyQuery { + field_responses_aggregate(where: {context_id: {_eq:${body?.context_id}},observation_fields_id:{_eq:${body?.observation_fields_id}}, field_id: {_eq:${body?.field_id}}, observation_id: {_eq:${body?.observation_id}}, response_value: {_eq:"${body?.response_value}"}}) { + aggregate { + count + } + } + }`; + + const vresponse = await this.hasuraServiceFromServices.getData({ + query: vquery, + }); + const newQdata = + vresponse?.data?.field_responses_aggregate?.aggregate?.count; + + if (newQdata > 0) { + return resp.status(422).json({ + success: false, + message: 'Duplicate field responses encountered !', + data: {}, + }); + } + let query = ''; Object.keys(body).forEach((e) => { if (body[e] && body[e] != '') { @@ -305,6 +395,28 @@ export class ObservationsService { }); } + let vquery = `query MyQuery { + observations_aggregate(where: {name: {_eq:"${body?.name}"}, id: {_neq:${id}}}) { + aggregate { + count + } + } + }`; + + const vresponse = await this.hasuraServiceFromServices.getData({ + query: vquery, + }); + const newQdata = + vresponse?.data?.observations_aggregate?.aggregate?.count; + + if (newQdata > 0) { + return resp.status(422).json({ + success: false, + message: 'Duplicate name encountered !', + data: {}, + }); + } + let query = ''; Object.keys(body).forEach((e) => { if (body[e] && body[e] != '') { @@ -374,6 +486,27 @@ export class ObservationsService { ? JSON.stringify(body?.enum).replace(/"/g, '\\"') : ''; + let vquery = `query MyQuery { + fields_aggregate(where: {title: {_eq:"${body?.title}"}, id: {_neq:${id}}}) { + aggregate { + count + } + } + }`; + + const vresponse = await this.hasuraServiceFromServices.getData({ + query: vquery, + }); + const newQdata = vresponse?.data?.fields_aggregate?.aggregate?.count; + + if (newQdata > 0) { + return resp.status(422).json({ + success: false, + message: 'Duplicate title encountered !', + data: {}, + }); + } + let query = ''; Object.keys(body).forEach((e) => { if (body[e] && body[e] != '') { @@ -439,6 +572,28 @@ export class ObservationsService { }); } + let vquery = `query MyQuery { + observation_fields_aggregate(where: {observation_id: {_eq:${body?.observation_id}}, field_id: {_eq:${body?.field_id}}, context_id: {_eq:${body?.context_id}}, id: {_neq:${id}}}) { + aggregate { + count + } + } + }`; + + const vresponse = await this.hasuraServiceFromServices.getData({ + query: vquery, + }); + const newQdata = + vresponse?.data?.observation_fields_aggregate?.aggregate?.count; + + if (newQdata > 0) { + return resp.status(422).json({ + success: false, + message: 'Duplicate observation field encountered !', + data: {}, + }); + } + let query = ''; Object.keys(body).forEach((e) => { if (body[e] && body[e] != '') { @@ -504,6 +659,28 @@ export class ObservationsService { }); } + let vquery = `query MyQuery { + field_responses_aggregate(where: {context_id: {_eq:${body?.context_id}},observation_fields_id:{_eq:${body?.observation_fields_id}}, field_id: {_eq:${body?.field_id}}, observation_id: {_eq:${body?.observation_id}}, response_value: {_eq:"${body?.response_value}"}, id: {_neq:${id}}}) { + aggregate { + count + } + } + }`; + + const vresponse = await this.hasuraServiceFromServices.getData({ + query: vquery, + }); + const newQdata = + vresponse?.data?.field_responses_aggregate?.aggregate?.count; + + if (newQdata > 0) { + return resp.status(422).json({ + success: false, + message: 'Duplicate field responses encountered !', + data: {}, + }); + } + let query = ''; Object.keys(body).forEach((e) => { if (body[e] && body[e] != '') { @@ -757,6 +934,17 @@ export class ObservationsService { created_by id observation_id + observations { + id + name + } + fields { + id + name + description + data_type + extra_all_info + } context context_id field_id @@ -771,19 +959,31 @@ export class ObservationsService { } else { data = { query: `query MyQuery { - observation_fields{ - created_at - created_by + observation_fields { + created_at + created_by + id + observation_id + observations{ id - observation_id - context - context_id - field_id - updated_at - updated_by + name + } + fields{ + id + name + description + data_type + extra_all_info + } + context + context_id + field_id + updated_at + updated_by } } + `, }; } @@ -841,6 +1041,20 @@ export class ObservationsService { created_by id observation_id + observation_fields_id + observation_fields{ + observations{ + id + name + } + fields{ + id + data_type + description + title + + } + } context context_id response_value @@ -860,6 +1074,20 @@ export class ObservationsService { created_by id observation_id + observation_fields_id + observation_fields{ + observations{ + id + name + } + fields{ + id + data_type + description + title + + } + } context context_id response_value @@ -1020,6 +1248,17 @@ export class ObservationsService { created_by id observation_id + observations { + id + name + } + fields { + id + name + description + data_type + extra_all_info + } context context_id field_id @@ -1074,6 +1313,19 @@ export class ObservationsService { created_by id observation_id + observation_fields_id + observation_fields { + observations { + id + name + } + fields { + id + data_type + description + title + } + } context context_id response_value @@ -1313,4 +1565,90 @@ export class ObservationsService { }); } } + + async createFieldResponsesMany(bodyArray: any, resp: any, request: any) { + let user_id = request?.mw_userid; + let response; + let data; + if (!user_id) { + return resp.status(422).json({ + message: 'Invalid User Entity', + data: null, + }); + } + + for (let body of bodyArray) { + body.created_by = user_id; + body.updated_by = user_id; + + let vquery = `query MyQuery { + field_responses_aggregate(where: {context_id: {_eq:${body?.context_id}},observation_fields_id:{_eq:${body?.observation_fields_id}}, field_id: {_eq:${body?.field_id}}, observation_id: {_eq:${body?.observation_id}}, response_value: {_eq:"${body?.response_value}"}}) { + aggregate { + count + } + } + }`; + + const vresponse = await this.hasuraServiceFromServices.getData({ + query: vquery, + }); + const newQdata = + vresponse?.data?.field_responses_aggregate?.aggregate?.count; + + if (newQdata > 0) { + return resp.status(422).json({ + success: false, + message: 'Duplicate field responses encountered !', + data: {}, + }); + } + + let query = ''; + Object.keys(body).forEach((e) => { + if (body[e] && body[e] !== '') { + if (e === 'render') { + query += `${e}: ${body[e]}, `; + } else if (Array.isArray(body[e])) { + query += `${e}: "${JSON.stringify(body[e])}", `; + } else { + query += `${e}: "${body[e]}", `; + } + } + }); + + data = { + query: `mutation CreateFieldsResponses { + insert_field_responses_one(object: {${query}}) { + id + observation_id + context + context_id + response_value + } + } + `, + variables: {}, + }; + + response = await this.hasuraServiceFromServices.queryWithVariable( + data, + ); + + let result = response?.data?.data?.insert_field_responses_one; + + if (!result) { + return resp.status(500).json({ + success: false, + message: 'Unable to create observation Field!', + data: {}, + }); + } + } + + return resp.status(200).json({ + success: true, + message: 'Observation Field(s) created successfully!', + data: response?.data?.data, + }); + } } From aacddfd044627136818a60ff5367647819ce1a70 Mon Sep 17 00:00:00 2001 From: GitVivekHub Date: Sun, 17 Mar 2024 10:48:15 +0530 Subject: [PATCH 071/126] Bulk field responses insert --- .../observations/observations.controller.ts | 4 ++-- src/src/observations/observations.service.ts | 22 ------------------- 2 files changed, 2 insertions(+), 24 deletions(-) diff --git a/src/src/observations/observations.controller.ts b/src/src/observations/observations.controller.ts index 60a54abff..e37d0d18f 100644 --- a/src/src/observations/observations.controller.ts +++ b/src/src/observations/observations.controller.ts @@ -302,11 +302,11 @@ export class ObservationsController { ); } - @Post('/field-responses') + @Post('/field-responses/bulk') @UsePipes(ValidationPipe) @UseGuards(new AuthGuard()) public async createFieldResponsesMany( - @Body() body: FieldResponsesDto, + @Body() body: Body, @Res() response: Response, @Req() request: Request, ) { diff --git a/src/src/observations/observations.service.ts b/src/src/observations/observations.service.ts index 368555e32..caf9f47bc 100644 --- a/src/src/observations/observations.service.ts +++ b/src/src/observations/observations.service.ts @@ -1581,28 +1581,6 @@ export class ObservationsService { body.created_by = user_id; body.updated_by = user_id; - let vquery = `query MyQuery { - field_responses_aggregate(where: {context_id: {_eq:${body?.context_id}},observation_fields_id:{_eq:${body?.observation_fields_id}}, field_id: {_eq:${body?.field_id}}, observation_id: {_eq:${body?.observation_id}}, response_value: {_eq:"${body?.response_value}"}}) { - aggregate { - count - } - } - }`; - - const vresponse = await this.hasuraServiceFromServices.getData({ - query: vquery, - }); - const newQdata = - vresponse?.data?.field_responses_aggregate?.aggregate?.count; - - if (newQdata > 0) { - return resp.status(422).json({ - success: false, - message: 'Duplicate field responses encountered !', - data: {}, - }); - } - let query = ''; Object.keys(body).forEach((e) => { if (body[e] && body[e] !== '') { From fd2b1c183bc177410f295f3927ee536f4f21fe6a Mon Sep 17 00:00:00 2001 From: Tusharmahajan12 <121154132+Tusharmahajan12@users.noreply.github.com> Date: Mon, 18 Mar 2024 16:09:40 +0530 Subject: [PATCH 072/126] Task #215203 [BE] Create Organisation with Associated Cohort Task #215507 [BE] Create Existing Organisation Added validation in both (#923) * Added username * Added validation --- src/src/organisation/organisation.service.ts | 62 ++++++++++++++++---- 1 file changed, 50 insertions(+), 12 deletions(-) diff --git a/src/src/organisation/organisation.service.ts b/src/src/organisation/organisation.service.ts index c79a11377..487c1e9a1 100644 --- a/src/src/organisation/organisation.service.ts +++ b/src/src/organisation/organisation.service.ts @@ -37,7 +37,7 @@ export class OrganisationService { name: body?.name, mobile: body?.mobile, contact_person: body?.contact_person, - address: body?.address, + address: body?.address || null, email_id: body?.email_id, }; @@ -53,19 +53,37 @@ export class OrganisationService { } const organisation = newOrganisation?.organisations; + const organisation_id = organisation?.id; + const learner_target = body?.learner_target; + const doc_per_cohort_id = body?.doc_per_cohort_id; + const doc_per_monthly_id = body?.doc_per_monthly_id; + const doc_quarterly_id = body?.doc_quarterly_id; + + if ( + !organisation_id || + !learner_target || + !doc_per_monthly_id || + !doc_per_cohort_id || + !doc_quarterly_id + ) { + return response.status(422).send({ + success: false, + message: 'Required fields are missing in the payload.', + data: {}, + }); + } // Step 2: Insert data into the 'program_organisation' table const programOrganisationData = { - organisation_id: organisation?.id, + organisation_id, program_id: request.mw_program_id, academic_year_id: request.mw_academic_year_id, status: 'active', - learner_target: body?.learner_target, - doc_per_cohort_id: body?.doc_per_cohort_id, - doc_per_monthly_id: body?.doc_per_monthly_id, - doc_quarterly_id: body?.doc_quarterly_id, + learner_target, + doc_per_cohort_id, + doc_per_monthly_id, + doc_quarterly_id, // Other fields as needed }; - const programOrganisationTableName = 'program_organisation'; const program_org = await this.hasuraService.q( programOrganisationTableName, @@ -322,16 +340,36 @@ export class OrganisationService { const program_organisation = existing?.data?.program_organisation_aggregate?.aggregate?.count; + const organisation_id = org_id; + const learner_target = body?.learner_target; + const doc_per_cohort_id = body?.doc_per_cohort_id; + const doc_per_monthly_id = body?.doc_per_monthly_id; + const doc_quarterly_id = body?.doc_quarterly_id; + + if ( + !organisation_id || + !learner_target || + !doc_per_monthly_id || + !doc_per_cohort_id || + !doc_quarterly_id + ) { + return response.status(422).send({ + success: false, + message: 'Required fields are missing in the payload.', + data: {}, + }); + } + if (program_organisation == 0) { const programOrganisationData = { - organisation_id: org_id, + organisation_id, program_id: request.mw_program_id, academic_year_id: request.mw_academic_year_id, status: 'active', - doc_per_cohort_id: body?.doc_per_cohort_id, - doc_per_monthly_id: body?.doc_per_monthly_id, - doc_quarterly_id: body?.doc_quarterly_id, - learner_target: body?.learner_target, + learner_target, + doc_per_cohort_id, + doc_per_monthly_id, + doc_quarterly_id, // Other fields as needed }; From ee2a9dc7f4cb26c8b787540265bf966d4a22b4dd Mon Sep 17 00:00:00 2001 From: Tushar Date: Mon, 18 Mar 2024 16:16:03 +0530 Subject: [PATCH 073/126] Added pagination to get concent --- src/src/camp/camp.service.ts | 44 +++++++++++++++++++++++++++--------- 1 file changed, 33 insertions(+), 11 deletions(-) diff --git a/src/src/camp/camp.service.ts b/src/src/camp/camp.service.ts index aa4f082c4..656ff346e 100644 --- a/src/src/camp/camp.service.ts +++ b/src/src/camp/camp.service.ts @@ -2019,9 +2019,19 @@ export class CampService { let facilitator_id = body?.facilitator_id; const program_id = request.mw_program_id; const academic_year_id = request.mw_academic_year_id; + const page = isNaN(body.page) ? 1 : parseInt(body.page); + const limit = isNaN(body.limit) ? 10 : parseInt(body.limit); + let offset = page > 1 ? limit * (page - 1) : 0; - let query = `query MyQuery { - consents(where: {facilitator_id: {_eq:${facilitator_id}},camp_id: {_eq:${camp_id}}, status: {_eq: "active"},academic_year_id: {_eq:${academic_year_id}},program_id: {_eq:${program_id}}}) { + let data = { + query: `query MyQuery($limit:Int, $offset:Int) { + consents_aggregate(where: {facilitator_id: {_eq:${facilitator_id}},camp_id: {_eq:${camp_id}}, status: {_eq: "active"},academic_year_id: {_eq:${academic_year_id}},program_id: {_eq:${program_id}}}) { + aggregate { + count + } + } + consents(limit: $limit, + offset: $offset,where: {facilitator_id: {_eq:${facilitator_id}},camp_id: {_eq:${camp_id}}, status: {_eq: "active"},academic_year_id: {_eq:${academic_year_id}},program_id: {_eq:${program_id}}}) { id document_id user_id @@ -2030,12 +2040,23 @@ export class CampService { name } } - }`; + }`, + variables: { + limit: limit, + offset: offset, + }, + }; - const hasura_response = await this.hasuraServiceFromServices.getData({ - query: query, - }); + const hasura_response = await this.hasuraServiceFromServices.getData( + data, + ); const consent_response = hasura_response?.data; + + const count = + hasura_response?.data?.consents_aggregate?.aggregate?.count; + + const totalPages = Math.ceil(count / limit); + if (!consent_response?.consents?.length) { return resp.status(200).json({ success: true, @@ -2057,13 +2078,16 @@ export class CampService { status: 200, message: 'Successfully updated consents details', data: resultData, + totalCount: count, + limit: limit, + currentPage: page, + totalPages: totalPages, }); } } async getAdminConsentBenficiaries(body: any, request: any, resp: any) { let camp_id = body?.camp_id; - const user = await this.userService.ipUserInfo(request); if (!user?.data?.program_users?.[0]?.organisation_id) { @@ -2080,15 +2104,13 @@ export class CampService { // get facilitator for the provided camp id - let query = `query MyQuery { + let query = `query MyQuery{ camps(where: {id: {_eq:${camp_id}}, group_users: {user: {program_faciltators: {parent_ip: {_eq: "${parent_ip_id}"}}}}}) { group_users(where: {member_type: {_eq: "owner"}, status: {_eq: "active"}}) { user_id } } - } - - `; + }`; const hasura_response = await this.hasuraServiceFromServices.getData({ query: query, From 0b91add28d609131c4e9fea031f594752e3ff635 Mon Sep 17 00:00:00 2001 From: Tushar Date: Mon, 18 Mar 2024 16:48:14 +0530 Subject: [PATCH 074/126] Added pagination to get concent --- src/src/camp/camp.service.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/src/camp/camp.service.ts b/src/src/camp/camp.service.ts index 656ff346e..136c0f61b 100644 --- a/src/src/camp/camp.service.ts +++ b/src/src/camp/camp.service.ts @@ -2020,7 +2020,7 @@ export class CampService { const program_id = request.mw_program_id; const academic_year_id = request.mw_academic_year_id; const page = isNaN(body.page) ? 1 : parseInt(body.page); - const limit = isNaN(body.limit) ? 10 : parseInt(body.limit); + const limit = isNaN(body.limit) ? 50 : parseInt(body.limit); let offset = page > 1 ? limit * (page - 1) : 0; let data = { From 24f4ffc059e7f8516b071797074dab28380e9ce7 Mon Sep 17 00:00:00 2001 From: GitVivekHub Date: Mon, 18 Mar 2024 18:22:14 +0530 Subject: [PATCH 075/126] Observations search query changes --- src/src/observations/observations.service.ts | 34 +++++++++++++++----- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/src/src/observations/observations.service.ts b/src/src/observations/observations.service.ts index caf9f47bc..ee20b03b0 100644 --- a/src/src/observations/observations.service.ts +++ b/src/src/observations/observations.service.ts @@ -751,16 +751,20 @@ export class ObservationsService { } if (body?.filters) { - let filters = new Object(body); - - Object.keys(body.filters).forEach((item) => { - Object.keys(body.filters[item]).forEach((e) => { - if (!e.startsWith('_')) { - filters[item][`_${e}`] = filters[item][e]; - delete filters[item][e]; + const traverseFilters = (filters) => { + Object.keys(filters).forEach((key) => { + if (typeof filters[key] === 'object') { + traverseFilters(filters[key]); + } else { + if (!key.startsWith('_')) { + filters[`_${key}`] = filters[key]; + delete filters[key]; + } } }); - }); + }; + + traverseFilters(body?.filters); data = { query: `query Searchobservations($filters:observations_bool_exp) { @@ -769,6 +773,20 @@ export class ObservationsService { created_by id name + observation_fields{ + id + observation_id + field_id + context + context_id + fields{ + id + data_type + description + title + enum + } + } updated_at updated_by } From 3e5b4f37eadaeaa7ad2ca48e2cbd2580f82b825b Mon Sep 17 00:00:00 2001 From: Tusharmahajan12 <121154132+Tusharmahajan12@users.noreply.github.com> Date: Tue, 19 Mar 2024 13:25:13 +0530 Subject: [PATCH 076/126] Task #215758 [BE] Add learner_per_cap and camp_target In Organisation (#927) * Added learner_per_camp * Added learner_per_camp * Added learner_per_camp * Added learner_per_camp * Added learner_per_camp * Added learner_per_camp --- src/src/organisation/organisation.service.ts | 154 ++++++++++++------- 1 file changed, 102 insertions(+), 52 deletions(-) diff --git a/src/src/organisation/organisation.service.ts b/src/src/organisation/organisation.service.ts index 487c1e9a1..a4f7767f8 100644 --- a/src/src/organisation/organisation.service.ts +++ b/src/src/organisation/organisation.service.ts @@ -54,40 +54,66 @@ export class OrganisationService { const organisation = newOrganisation?.organisations; const organisation_id = organisation?.id; - const learner_target = body?.learner_target; - const doc_per_cohort_id = body?.doc_per_cohort_id; - const doc_per_monthly_id = body?.doc_per_monthly_id; - const doc_quarterly_id = body?.doc_quarterly_id; + const { + learner_target, + doc_per_cohort_id, + doc_per_monthly_id, + doc_quarterly_id, + learner_per_camp, + camp_target, + } = body; + const missingFields = [ + 'learner_target', + 'doc_per_cohort_id', + 'doc_per_monthly_id', + 'doc_quarterly_id', + 'learner_per_camp', + 'camp_target', + ].filter((field) => !body[field] && body[field] != ''); + + if (missingFields.length > 0) { + return response.status(422).send({ + success: false, + key: missingFields?.[0], + message: `Required fields are missing in the payload. ${missingFields.join( + ',', + )}`, + data: {}, + }); + } - if ( - !organisation_id || - !learner_target || - !doc_per_monthly_id || - !doc_per_cohort_id || - !doc_quarterly_id - ) { + // Calculate learner_target per camp and round up to nearest whole number + if (Math.ceil(learner_target / learner_per_camp) !== camp_target) { return response.status(422).send({ success: false, - message: 'Required fields are missing in the payload.', + message: 'Camp target is wrong', data: {}, }); } + // Step 2: Insert data into the 'program_organisation' table - const programOrganisationData = { - organisation_id, - program_id: request.mw_program_id, - academic_year_id: request.mw_academic_year_id, - status: 'active', - learner_target, - doc_per_cohort_id, - doc_per_monthly_id, - doc_quarterly_id, - // Other fields as needed - }; const programOrganisationTableName = 'program_organisation'; const program_org = await this.hasuraService.q( programOrganisationTableName, - programOrganisationData, + { + organisation_id, + program_id: request.mw_program_id, + academic_year_id: request.mw_academic_year_id, + status: 'active', + ...body, + }, + [ + 'organisation_id', + 'program_id', + 'academic_year_id', + 'status', + 'learner_target', + 'doc_per_cohort_id', + 'doc_per_monthly_id', + 'doc_quarterly_id', + 'learner_per_camp', + 'camp_target', + ], ); // Return success response @@ -240,6 +266,8 @@ export class OrganisationService { doc_per_cohort_id doc_per_monthly_id doc_quarterly_id + learner_per_camp + camp_target program{ name state{ @@ -324,10 +352,18 @@ export class OrganisationService { } async addExisting(body: any, request: any, response: any) { - const org_id = body?.organisation_id; + const { + organisation_id, + learner_target, + doc_per_cohort_id, + doc_per_monthly_id, + doc_quarterly_id, + learner_per_camp, + camp_target, + } = body; let data = { query: `query MyQuery { - program_organisation_aggregate(where: {academic_year_id: {_eq: ${request.mw_academic_year_id}}, program_id: {_eq: ${request.mw_program_id}}, organisation_id: {_eq: ${org_id}}}) + program_organisation_aggregate(where: {academic_year_id: {_eq: ${request.mw_academic_year_id}}, program_id: {_eq: ${request.mw_program_id}}, organisation_id: {_eq: ${organisation_id}}}) { aggregate{ count @@ -340,43 +376,57 @@ export class OrganisationService { const program_organisation = existing?.data?.program_organisation_aggregate?.aggregate?.count; - const organisation_id = org_id; - const learner_target = body?.learner_target; - const doc_per_cohort_id = body?.doc_per_cohort_id; - const doc_per_monthly_id = body?.doc_per_monthly_id; - const doc_quarterly_id = body?.doc_quarterly_id; + const missingFields = [ + 'organisation_id', + 'learner_target', + 'doc_per_cohort_id', + 'doc_per_monthly_id', + 'doc_quarterly_id', + 'learner_per_camp', + 'camp_target', + ].filter((field) => !body[field] && body[field] != ''); - if ( - !organisation_id || - !learner_target || - !doc_per_monthly_id || - !doc_per_cohort_id || - !doc_quarterly_id - ) { + if (missingFields.length > 0) { return response.status(422).send({ success: false, - message: 'Required fields are missing in the payload.', + key: missingFields?.[0], + message: `Required fields are missing in the payload. ${missingFields.join( + ',', + )}`, + data: {}, + }); + } + // Calculate learner_target per camp and round up to nearest whole number + if (Math.ceil(learner_target / learner_per_camp) !== camp_target) { + return response.status(422).send({ + success: false, + message: 'Camp target is wrong', data: {}, }); } if (program_organisation == 0) { - const programOrganisationData = { - organisation_id, - program_id: request.mw_program_id, - academic_year_id: request.mw_academic_year_id, - status: 'active', - learner_target, - doc_per_cohort_id, - doc_per_monthly_id, - doc_quarterly_id, - // Other fields as needed - }; - const programOrganisationTableName = 'program_organisation'; const program_organisation = await this.hasuraService.q( programOrganisationTableName, - programOrganisationData, + { + program_id: request.mw_program_id, + academic_year_id: request.mw_academic_year_id, + status: 'active', + ...body, + }, + [ + 'organisation_id', + 'program_id', + 'academic_year_id', + 'status', + 'learner_target', + 'doc_per_cohort_id', + 'doc_per_monthly_id', + 'doc_quarterly_id', + 'learner_per_camp', + 'camp_target', + ], ); // Return success response From 25ef47adb716803050750a604ed8871bb0f0fc71 Mon Sep 17 00:00:00 2001 From: sagar takle Date: Tue, 19 Mar 2024 13:26:53 +0530 Subject: [PATCH 077/126] fix: existing list api (#932) --- src/src/user/user.controller.ts | 10 ++------ src/src/user/user.service.ts | 43 +++++++++++++++++++++------------ 2 files changed, 29 insertions(+), 24 deletions(-) diff --git a/src/src/user/user.controller.ts b/src/src/user/user.controller.ts index 3b3d21ffb..91fe5953c 100755 --- a/src/src/user/user.controller.ts +++ b/src/src/user/user.controller.ts @@ -275,20 +275,14 @@ export class UserController { return this.userService.getIpDetails(id, body, request, response); } - @Get('/ip_users/exist_list') + @Post('/ip_users/exist_list') @UseGuards(new AuthGuard()) getIpUserListExists( @Req() request: any, @Body() body: any, - @Param('id') id: number, @Res() response: any, ) { - return this.userService.getIpUserListExists( - id, - body, - request, - response, - ); + return this.userService.getIpUserListExists(body, request, response); } @Post('/roles/list') diff --git a/src/src/user/user.service.ts b/src/src/user/user.service.ts index 6029741b7..35e125a25 100644 --- a/src/src/user/user.service.ts +++ b/src/src/user/user.service.ts @@ -1892,25 +1892,36 @@ export class UserService { } } - public async getIpUserListExists(id: any, body: any, req: any, resp) { + public async getIpUserListExists(body: any, req: any, resp) { const program_id = req.mw_program_id; const academic_year_id = req.mw_academic_year_id; + if (!body?.organisation_id || body?.organisation_id == '') { + return resp.status(422).json({ + success: false, + key: 'organisation_id', + message: 'organisation_id Not found!', + data: {}, + }); + } - let qury = `query MyQuery { - users(where: {program_users:{},_not: {program_users: {academic_year_id: {_eq: ${academic_year_id}}, program_id: {_eq: ${program_id}}}}}) { - id - first_name - last_name - middle_name - program_users { - academic_year_id - program_id - user_id - } - }} - `; - const data = { query: qury }; - const response = await this.hasuraServiceFromServices.getData(data); + const query = `query MyQuery { + users(where: {program_users: {program_id: {_eq: ${program_id}},organisation_id:{_eq:${body?.organisation_id}}, academic_year_id: {_neq: ${academic_year_id}}}}) { + id + first_name + last_name + middle_name + program_users(where: {program_id: {_eq: ${program_id}},organisation_id:{_eq:${body?.organisation_id}}, academic_year_id: {_neq: ${academic_year_id}}}) { + academic_year_id + organisation_id + program_id + user_id + } + } + } + `; + const response = await this.hasuraServiceFromServices.getData({ + query, + }); const newQdata = response?.data?.users; if (newQdata.length == 0) { return resp.status(422).json({ From 388ff3c4cc968e016d7193bbcdd59c19cbefb3a9 Mon Sep 17 00:00:00 2001 From: GitVivekHub Date: Tue, 19 Mar 2024 16:48:44 +0530 Subject: [PATCH 078/126] observation by type api added --- .../observations/observations.controller.ts | 17 +++ src/src/observations/observations.service.ts | 121 ++++++++++++++++++ 2 files changed, 138 insertions(+) diff --git a/src/src/observations/observations.controller.ts b/src/src/observations/observations.controller.ts index e37d0d18f..421012cdf 100644 --- a/src/src/observations/observations.controller.ts +++ b/src/src/observations/observations.controller.ts @@ -198,6 +198,23 @@ export class ObservationsController { ); } + @Post('/list/type/:type') + @UsePipes(ValidationPipe) + @UseGuards(new AuthGuard()) + public async getObservationListByType( + @Body() body: ObservationSearchDto, + @Res() response: Response, + @Req() request: Request, + @Param('type') type: string, + ) { + return this.observationsService.getObservationByType( + body, + response, + request, + type, + ); + } + @Post('observation-fields/list') @UsePipes(ValidationPipe) @UseGuards(new AuthGuard()) diff --git a/src/src/observations/observations.service.ts b/src/src/observations/observations.service.ts index ee20b03b0..de67922e4 100644 --- a/src/src/observations/observations.service.ts +++ b/src/src/observations/observations.service.ts @@ -830,6 +830,127 @@ export class ObservationsService { } } + async getObservationByType(body: any, resp: any, request: any, type: any) { + let response; + let newQdata; + let query; + let obj_filters; + let data; + let user_id = request?.mw_userid; + + if (!user_id) { + return resp.status(422).json({ + message: 'Invalid User Entity', + data: null, + }); + } + + if (body?.filters) { + const traverseFilters = (filters) => { + Object.keys(filters).forEach((key) => { + if (typeof filters[key] === 'object') { + traverseFilters(filters[key]); + } else { + if (!key.startsWith('_')) { + filters[`_${key}`] = filters[key]; + delete filters[key]; + } + } + }); + }; + + traverseFilters(body?.filters); + + if (type == 'forms') { + data = { + query: `query Searchobservations($filters:observations_bool_exp) { + observations(where:$filters) { + created_at + created_by + id + name + title + observation_fields{ + id + observation_id + field_id + context + context_id + fields{ + id + data_type + description + title + enum + } + } + updated_at + updated_by + } + }`, + variables: { + filters: body.filters, + }, + }; + } else if (type == 'submissons') { + data = { + query: `query Searchobservations($filters:observations_bool_exp) { + observations(where:$filters) { + created_at + created_by + id + name + title + observation_fields{ + id + observation_id + field_id + context + context_id + fields{ + id + data_type + description + title + enum + } + field_responses { + id + context + context_id + observation_fields_id + } + } + updated_at + updated_by + } + }`, + variables: { + filters: body.filters, + }, + }; + } + } + + response = await this.hasuraServiceFromServices.queryWithVariable(data); + + newQdata = response?.data?.data?.observations; + + if (newQdata.length > 0) { + return resp.status(200).json({ + success: true, + message: 'Data found successfully!', + data: newQdata, + }); + } else { + return resp.json({ + status: 400, + message: 'Data Not Found', + data: {}, + }); + } + } + async getFieldsList(body: any, resp: any, request: any) { let response; let newQdata; From f642149abf21cdfba0ff7a023e847a49a8e0957c Mon Sep 17 00:00:00 2001 From: GitVivekHub Date: Tue, 19 Mar 2024 16:52:08 +0530 Subject: [PATCH 079/126] made title related changes into observation api's --- src/src/observations/dto/observation-fields.dto.ts | 4 ++++ src/src/observations/observations.service.ts | 3 +++ 2 files changed, 7 insertions(+) diff --git a/src/src/observations/dto/observation-fields.dto.ts b/src/src/observations/dto/observation-fields.dto.ts index 15d3a1700..f5eec9c19 100644 --- a/src/src/observations/dto/observation-fields.dto.ts +++ b/src/src/observations/dto/observation-fields.dto.ts @@ -9,6 +9,10 @@ export class ObservationFieldsDto { @IsString() context: string; + @IsNotEmpty() + @IsString() + title: string; + @IsNotEmpty() @IsNumber() context_id: number; diff --git a/src/src/observations/observations.service.ts b/src/src/observations/observations.service.ts index de67922e4..b84b57b47 100644 --- a/src/src/observations/observations.service.ts +++ b/src/src/observations/observations.service.ts @@ -773,6 +773,7 @@ export class ObservationsService { created_by id name + title observation_fields{ id observation_id @@ -801,6 +802,7 @@ export class ObservationsService { observations{ id name + title created_at created_by updated_by @@ -1279,6 +1281,7 @@ export class ObservationsService { observations_by_pk(id:${id}) { id name + title created_by created_at updated_at From cd40a38f07a4e15b766a223e163b4c1db14fa680 Mon Sep 17 00:00:00 2001 From: GitVivekHub Date: Tue, 19 Mar 2024 18:53:41 +0530 Subject: [PATCH 080/126] fields_sequence added to the observation_fields --- .../dto/observation-fields.dto.ts | 4 + src/src/observations/observations.service.ts | 76 ++++++++++++------- 2 files changed, 54 insertions(+), 26 deletions(-) diff --git a/src/src/observations/dto/observation-fields.dto.ts b/src/src/observations/dto/observation-fields.dto.ts index f5eec9c19..87e9f6d1f 100644 --- a/src/src/observations/dto/observation-fields.dto.ts +++ b/src/src/observations/dto/observation-fields.dto.ts @@ -13,6 +13,10 @@ export class ObservationFieldsDto { @IsString() title: string; + @IsNotEmpty() + @IsNumber() + fields_sequence: string; + @IsNotEmpty() @IsNumber() context_id: number; diff --git a/src/src/observations/observations.service.ts b/src/src/observations/observations.service.ts index b84b57b47..933de5b02 100644 --- a/src/src/observations/observations.service.ts +++ b/src/src/observations/observations.service.ts @@ -780,6 +780,7 @@ export class ObservationsService { field_id context context_id + fields_sequence fields{ id data_type @@ -803,6 +804,21 @@ export class ObservationsService { id name title + observation_fields{ + id + observation_id + field_id + context + context_id + fields_sequence + fields{ + id + data_type + description + title + enum + } + } created_at created_by updated_by @@ -878,6 +894,7 @@ export class ObservationsService { field_id context context_id + fields_sequence fields{ id data_type @@ -895,40 +912,44 @@ export class ObservationsService { }, }; } else if (type == 'submissons') { + let field_responses_filter = + body?.filters?.observation_fields?.field_responses; data = { - query: `query Searchobservations($filters:observations_bool_exp) { - observations(where:$filters) { - created_at - created_by - id - name - title - observation_fields{ + query: `query SearchObservations($filters: observations_bool_exp, $field_responses_filter: field_responses_bool_exp) { + observations(where: $filters) { + created_at + created_by id - observation_id - field_id - context - context_id - fields{ - id - data_type - description - title - enum - } - field_responses { + name + title + observation_fields { id + observation_id + field_id context context_id - observation_fields_id - } - } - updated_at - updated_by - } + fields_sequence + fields { + id + data_type + description + title + enum + } + field_responses(where: $field_responses_filter) { + id + context + context_id + observation_fields_id + } + } + updated_at + updated_by + } }`, variables: { filters: body.filters, + field_responses_filter: field_responses_filter, }, }; } @@ -1088,6 +1109,7 @@ export class ObservationsService { } context context_id + fields_sequence field_id updated_at updated_by @@ -1118,6 +1140,7 @@ export class ObservationsService { } context context_id + fields_sequence field_id updated_at updated_by @@ -1403,6 +1426,7 @@ export class ObservationsService { } context context_id + fields_sequence field_id updated_at updated_by From bbe5a456ac8033d48b6b4f954190849de4ecc861 Mon Sep 17 00:00:00 2001 From: GitVivekHub Date: Wed, 20 Mar 2024 14:39:59 +0530 Subject: [PATCH 081/126] insert field-responses in bulk --- src/src/observations/observations.service.ts | 97 ++++++++++++++++---- 1 file changed, 78 insertions(+), 19 deletions(-) diff --git a/src/src/observations/observations.service.ts b/src/src/observations/observations.service.ts index 933de5b02..008061b51 100644 --- a/src/src/observations/observations.service.ts +++ b/src/src/observations/observations.service.ts @@ -430,7 +430,7 @@ export class ObservationsService { } }); - var data = { + let data = { query: ` mutation UpdateObservations($id:Int!) { update_observations_by_pk( @@ -1736,6 +1736,7 @@ export class ObservationsService { let user_id = request?.mw_userid; let response; let data; + let result; if (!user_id) { return resp.status(422).json({ message: 'Invalid User Entity', @@ -1744,9 +1745,36 @@ export class ObservationsService { } for (let body of bodyArray) { + const { + observation_id, + context, + context_id, + field_id, + observation_fields_id, + ...rest + } = body; // Extract fields for querying body.created_by = user_id; body.updated_by = user_id; + data = { + query: ` query GetFieldResponse { + field_responses( + where: { observation_id: { _eq: ${observation_id} }, context: { _eq: ${context} }, context_id: { _eq: ${context_id} },field_id:{_eq:${field_id}},observation_fields_id:{_eq:${observation_fields_id}} } + ) { + id + } + } + `, + }; + + const existingData = + await this.hasuraServiceFromServices.queryWithVariable(data); + + const action = + existingData?.data?.data?.field_responses?.length > 0 + ? 'update' + : 'insert'; + let query = ''; Object.keys(body).forEach((e) => { if (body[e] && body[e] !== '') { @@ -1760,25 +1788,56 @@ export class ObservationsService { } }); - data = { - query: `mutation CreateFieldsResponses { - insert_field_responses_one(object: {${query}}) { - id - observation_id - context - context_id - response_value - } - } - `, - variables: {}, - }; + if (action == 'update') { + const id = existingData?.data?.data?.field_responses?.[0]?.id; - response = await this.hasuraServiceFromServices.queryWithVariable( - data, - ); + data = { + query: ` mutation UpdateObservations($id:Int!) { + update_field_responses_by_pk( + pk_columns: { + id: $id + }, + _set: { + ${query} + } + ) { + id + } + } + `, + variables: { + id: id, + }, + }; + + response = + await this.hasuraServiceFromServices.queryWithVariable( + data, + ); + + result = response?.data?.data?.update_field_responses_by_pk; + } else { + data = { + query: `mutation CreateFieldsResponses { + insert_field_responses_one(object: {${query}}) { + id + observation_id + context + context_id + response_value + } + } + `, + variables: {}, + }; - let result = response?.data?.data?.insert_field_responses_one; + response = + await this.hasuraServiceFromServices.queryWithVariable( + data, + ); + + result = response?.data?.data?.insert_field_responses_one; + } if (!result) { return resp.status(500).json({ @@ -1792,7 +1851,7 @@ export class ObservationsService { return resp.status(200).json({ success: true, message: 'Observation Field(s) created successfully!', - data: response?.data?.data, + data: result, }); } } From 0fdf0446380c801e6b6c16f61e35e36c63db01ad Mon Sep 17 00:00:00 2001 From: Tusharmahajan12 <121154132+Tusharmahajan12@users.noreply.github.com> Date: Wed, 20 Mar 2024 17:17:58 +0530 Subject: [PATCH 082/126] Bug #215839 [BE] : Prerak Reset password is not working (#936) * Added staff role in user create * bug solved * bug solved * bug solved * bug solved --- src/src/modules/auth/auth.module.ts | 7 ++++++- src/src/modules/auth/auth.service.ts | 12 ++++-------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/src/modules/auth/auth.module.ts b/src/src/modules/auth/auth.module.ts index e1d89282e..52cdc5702 100644 --- a/src/src/modules/auth/auth.module.ts +++ b/src/src/modules/auth/auth.module.ts @@ -7,6 +7,8 @@ import { KeycloakModule } from 'src/services/keycloak/keycloak.module'; import { UserModule } from 'src/user/user.module'; import { AuthController } from './auth.controller'; import { AuthService } from './auth.service'; +import { Method } from 'src/common/method/method'; +import { CohortMiddleware } from 'src/common/middlewares/cohort.middleware'; @Module({ imports: [ @@ -17,11 +19,14 @@ import { AuthService } from './auth.service'; UserModule, ], controllers: [AuthController], - providers: [AuthService], + providers: [AuthService, Method], exports: [AuthService], }) export class AuthModule implements NestModule { configure(consumer: MiddlewareConsumer) { consumer.apply(AuthMiddleware).forRoutes('*'); + consumer + .apply(CohortMiddleware) + .forRoutes('/auth/reset-password-admin'); } } diff --git a/src/src/modules/auth/auth.service.ts b/src/src/modules/auth/auth.service.ts index 66fdda24e..65a65c679 100644 --- a/src/src/modules/auth/auth.service.ts +++ b/src/src/modules/auth/auth.service.ts @@ -256,11 +256,11 @@ export class AuthService { } public async resetPasswordUsingId(req, header, response) { - console.log('req', req); + const { mw_roles } = header; const authToken = header.header('authorization'); const decoded: any = jwt_decode(authToken); let keycloak_id = decoded.sub; - console.log('keycloak_id', keycloak_id); + let query2 = { query: `query MyQuery { users(where: {keycloak_id: {_eq: "${keycloak_id}" }}) { @@ -276,12 +276,9 @@ export class AuthService { } }`, }; + const userRole = await this.hasuraService.postData(query2); - console.log( - 'userRole', - userRole.data.users[0].program_users[0].roles.role_type, - ); - if (userRole.data.users[0].program_users[0].roles.role_type === 'IP') { + if (mw_roles.includes('staff')) { let query = { query: `query MyQuery { users_by_pk(id: ${req.id}) { @@ -294,7 +291,6 @@ export class AuthService { }; const userRes = await this.hasuraService.postData(query); - console.log('userRes', userRes); if (userRes) { const token = From 1acfc045fdfefd7cfa75b931970a52087c867810 Mon Sep 17 00:00:00 2001 From: Tusharmahajan12 <121154132+Tusharmahajan12@users.noreply.github.com> Date: Wed, 20 Mar 2024 17:18:55 +0530 Subject: [PATCH 083/126] Change limit 15 to 10 (#937) --- src/src/beneficiaries/beneficiaries.service.ts | 2 +- src/src/camp/camp.core.service.ts | 2 +- src/src/facilitator/facilitator.service.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/src/beneficiaries/beneficiaries.service.ts b/src/src/beneficiaries/beneficiaries.service.ts index 3da786d98..7a691ac79 100644 --- a/src/src/beneficiaries/beneficiaries.service.ts +++ b/src/src/beneficiaries/beneficiaries.service.ts @@ -703,7 +703,7 @@ export class BeneficiariesService { } const sortType = body?.sortType ? body?.sortType : 'desc'; const page = isNaN(body.page) ? 1 : parseInt(body.page); - const limit = isNaN(body.limit) ? 15 : parseInt(body.limit); + const limit = isNaN(body.limit) ? 10 : parseInt(body.limit); let offset = page > 1 ? limit * (page - 1) : 0; let status = body?.status; let filterQueryArray = []; diff --git a/src/src/camp/camp.core.service.ts b/src/src/camp/camp.core.service.ts index 096f7368a..030eb0f62 100644 --- a/src/src/camp/camp.core.service.ts +++ b/src/src/camp/camp.core.service.ts @@ -78,7 +78,7 @@ export class CampCoreService { .data.map((item) => item.value); const page = isNaN(body.page) ? 1 : parseInt(body.page); - const limit = isNaN(body.limit) ? 15 : parseInt(body.limit); + const limit = isNaN(body.limit) ? 10 : parseInt(body.limit); let offset = page > 1 ? limit * (page - 1) : 0; const program_id = req.mw_program_id; const academic_year_id = req.mw_academic_year_id; diff --git a/src/src/facilitator/facilitator.service.ts b/src/src/facilitator/facilitator.service.ts index 869ce4c4b..088eee514 100644 --- a/src/src/facilitator/facilitator.service.ts +++ b/src/src/facilitator/facilitator.service.ts @@ -1590,7 +1590,7 @@ export class FacilitatorService { } const page = isNaN(body.page) ? 1 : parseInt(body.page); - const limit = isNaN(body.limit) ? 15 : parseInt(body.limit); + const limit = isNaN(body.limit) ? 10 : parseInt(body.limit); let skip = page > 1 ? limit * (page - 1) : 0; From 9b67aa18525da269277c0bfe4f8446764fc60b40 Mon Sep 17 00:00:00 2001 From: Tusharmahajan12 <121154132+Tusharmahajan12@users.noreply.github.com> Date: Thu, 21 Mar 2024 15:04:22 +0530 Subject: [PATCH 084/126] Task #216036 and Task #215959 [BE] Existing camp creation add param type as PCR and [BE] Add Enum for PCR camp miscellaneous activity (#939) * Added Type in camp Create and list API * Added Type in camp Create and list API * Added Type in camp Create and list API --- src/src/camp/camp.service.ts | 5 ++++ src/src/enum/enum.json | 50 ++++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+) diff --git a/src/src/camp/camp.service.ts b/src/src/camp/camp.service.ts index 136c0f61b..61eaddc94 100644 --- a/src/src/camp/camp.service.ts +++ b/src/src/camp/camp.service.ts @@ -36,6 +36,7 @@ export class CampService { 'kit_ratings', 'kit_feedback', 'group_id', + 'type', ]; public returnFieldsconsents = [ @@ -182,6 +183,7 @@ export class CampService { group_id: createresponse?.groups?.id, created_by: facilitator_id, updated_by: facilitator_id, + type: 'pcr', }; createcampResponse = await this.hasuraService.q( @@ -380,6 +382,7 @@ export class CampService { preferred_start_time preferred_end_time week_off + type group{ name description @@ -424,6 +427,7 @@ export class CampService { preferred_start_time preferred_end_time week_off + type group{ name description @@ -776,6 +780,7 @@ export class CampService { preferred_start_time preferred_end_time week_off + type properties { lat long diff --git a/src/src/enum/enum.json b/src/src/enum/enum.json index 4cf418195..338f3a9b2 100644 --- a/src/src/enum/enum.json +++ b/src/src/enum/enum.json @@ -1578,5 +1578,55 @@ "title": "EVENT_BATCH_NAME_BATCH_20", "value": "batch_20" } + ], + "PCR_MISCELLANEOUS_ACTIVITIES": [ + { + "title": "PCR_MISCELLANEOUS_ACTIVITIES_COMMUNICATION_SKILLS", + "value": "pcr_miscellaneous_activities_communication_skills" + }, + { + "title": "PCR_MISCELLANEOUS_ACTIVITIES_ROLE_MODEL_INTERVENTION", + "value": "pcr_miscellaneous_activities_role_model_intervention" + }, + { + "title": "PCR_MISCELLANEOUS_ACTIVITIES_ASPIRATION_MAPPING", + "value": "pcr_miscellaneous_activities_aspiration_mapping" + }, + { + "title": "PCR_MISCELLANEOUS_ACTIVITIES_DIGITAL_LITERACY", + "value": "pcr_miscellaneous_activities_digital_literacy" + }, + { + "title": "PCR_MISCELLANEOUS_ACTIVITIES_FINANCIAL_LITERACY", + "value": "pcr_miscellaneous_activities_financial_literacy" + }, + { + "title": "PCR_MISCELLANEOUS_ACTIVITIES_LINKAGES", + "value": "pcr_miscellaneous_activities_linkages" + }, + { + "title": "PCR_MISCELLANEOUS_ACTIVITIES_FAMILY_VISIT", + "value": "pcr_miscellaneous_activities_family_visit" + }, + { + "title": "PCR_MISCELLANEOUS_ACTIVITIES_ROLE_MODEL_VISIT", + "value": "pcr_miscellaneous_activities_role_model_visit" + }, + { + "title": "PCR_MISCELLANEOUS_ACTIVITIES_STAKEHOLDER_VISIT", + "value": "pcr_miscellaneous_activities_stakeholder_visit" + }, + { + "title": "PCR_MISCELLANEOUS_ACTIVITIES_SCHOOL_TEACHER_VISIT", + "value": "pcr_miscellaneous_activities_school_teacher_visit" + }, + { + "title": "PCR_MISCELLANEOUS_ACTIVITIES_E_PCP_ACTIVITIES", + "value": "pcr_miscellaneous_activities_e_pcp_activities" + }, + { + "title": "PCR_MISCELLANEOUS_ACTIVITIES_PCR", + "value": "pcr_miscellaneous_activities_pcr" + } ] } From 25ec9b991deae3fea0dfa8ce1098f668c5464d4b Mon Sep 17 00:00:00 2001 From: Tusharmahajan12 <121154132+Tusharmahajan12@users.noreply.github.com> Date: Thu, 21 Mar 2024 15:09:22 +0530 Subject: [PATCH 085/126] Task #216090 [BE] pcr camp list (#940) * pcr camp list and admin list filter * pcr camp list and admin list filter --- src/src/camp/camp.core.service.ts | 13 +++++++++++-- src/src/camp/camp.service.ts | 32 ++++++++++++++++++++++++++++--- 2 files changed, 40 insertions(+), 5 deletions(-) diff --git a/src/src/camp/camp.core.service.ts b/src/src/camp/camp.core.service.ts index 096f7368a..a92906820 100644 --- a/src/src/camp/camp.core.service.ts +++ b/src/src/camp/camp.core.service.ts @@ -84,11 +84,14 @@ export class CampCoreService { const academic_year_id = req.mw_academic_year_id; let parent_ip_id = req?.parent_ip_id; let status = body?.status; - + const type = []; filterQueryArray.push( `{group_users: {member_type: {_eq: "owner"}, group: {program_id: {_eq:${program_id}}, academic_year_id: {_eq:${academic_year_id}}},user:{program_faciltators:{parent_ip:{_eq:"${parent_ip_id}"}}}}}`, ); + if (body?.type && body?.type.length > 0) { + type.push(`type:{_in: ${JSON.stringify(body?.type)}}`); + } if (body?.state && body?.state.length > 0) { filterQueryArray.push( `{properties:{state:{_in: ${JSON.stringify(body?.state)}}}}`, @@ -133,7 +136,12 @@ export class CampCoreService { filterQueryArray.push(`{group:{status:{_eq:"${status}"}}}`); } - let filterQuery = '{ _and: [' + filterQueryArray.join(',') + '] }'; + let filterQuery = + '{' + + type.join(',') + + ' _and: [' + + filterQueryArray.join(',') + + '] }'; let data = { query: `query MyQuery($limit: Int, $offset: Int) { @@ -148,6 +156,7 @@ export class CampCoreService { kit_was_sufficient kit_ratings kit_feedback + type properties { district block diff --git a/src/src/camp/camp.service.ts b/src/src/camp/camp.service.ts index 61eaddc94..946555510 100644 --- a/src/src/camp/camp.service.ts +++ b/src/src/camp/camp.service.ts @@ -373,7 +373,7 @@ export class CampService { let status = 'active'; let qury = `query MyQuery { - camps(where: {group_users: {group: {academic_year_id: {_eq:${academic_year_id}}, program_id: {_eq:${program_id}}}, user: {}, member_type: {_eq:${member_type}}, status: {_eq:${status}}, user_id: {_eq:${facilitator_id}}}},order_by: {id: asc}) { + main_camp:camps(where: {group_users: {group: {academic_year_id: {_eq:${academic_year_id}}, program_id: {_eq:${program_id}}}, user: {}, member_type: {_eq:${member_type}}, status: {_eq:${status}}, user_id: {_eq:${facilitator_id}}},type:{_eq:"main"}},order_by: {id: asc}) { id kit_ratings kit_feedback @@ -396,16 +396,42 @@ export class CampService { } } + pcr_camp:camps(where: {group_users: {group: {academic_year_id: {_eq:${academic_year_id}}, program_id: {_eq:${program_id}}}, user: {}, member_type: {_eq:${member_type}}, status: {_eq:${status}}, user_id: {_eq:${facilitator_id}}},type:{_eq:"pcr"}},order_by: {id: asc}) { + id + kit_ratings + kit_feedback + kit_received + kit_was_sufficient + preferred_start_time + preferred_end_time + week_off + type + group{ + name + description + status + } + group_users(where: {member_type: {_neq: "owner"}}) { + user_id + status + member_type + + } + } }`; const data = { query: qury }; const response = await this.hasuraServiceFromServices.getData(data); - const newQdata = response?.data; + const main_camp = response?.data?.main_camp || []; + const pcr_camp = response?.data?.pcr_camp || []; return resp.status(200).json({ success: true, message: 'Data found successfully!', - data: newQdata || { camps: [] }, + data: { + main_camp, + pcr_camp, + }, }); } From 5cdf3c1ea3338334e5e53ae78b7647a127caa9ad Mon Sep 17 00:00:00 2001 From: Tusharmahajan12 <121154132+Tusharmahajan12@users.noreply.github.com> Date: Thu, 21 Mar 2024 16:52:29 +0530 Subject: [PATCH 086/126] Task #216036 [BE] Add Enum for PCR camp miscellaneous activity (#942) * Added Type in camp Create and list API * Added Type in camp Create and list API * Added Type in camp Create and list API * enum changes --- src/src/enum/enum.json | 48 +++++++++++++++++++++--------------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/src/src/enum/enum.json b/src/src/enum/enum.json index 338f3a9b2..9062f728a 100644 --- a/src/src/enum/enum.json +++ b/src/src/enum/enum.json @@ -1581,52 +1581,52 @@ ], "PCR_MISCELLANEOUS_ACTIVITIES": [ { - "title": "PCR_MISCELLANEOUS_ACTIVITIES_COMMUNICATION_SKILLS", - "value": "pcr_miscellaneous_activities_communication_skills" + "title": "MISCELLANEOUS_ACTIVITIES_COMMUNICATION_SKILLS", + "value": "miscellaneous_activities_communication_skills" }, { - "title": "PCR_MISCELLANEOUS_ACTIVITIES_ROLE_MODEL_INTERVENTION", - "value": "pcr_miscellaneous_activities_role_model_intervention" + "title": "MISCELLANEOUS_ACTIVITIES_ROLE_MODEL_INTERVENTION", + "value": "miscellaneous_activities_role_model_intervention" }, { - "title": "PCR_MISCELLANEOUS_ACTIVITIES_ASPIRATION_MAPPING", - "value": "pcr_miscellaneous_activities_aspiration_mapping" + "title": "MISCELLANEOUS_ACTIVITIES_ASPIRATION_MAPPING", + "value": "miscellaneous_activities_aspiration_mapping" }, { - "title": "PCR_MISCELLANEOUS_ACTIVITIES_DIGITAL_LITERACY", - "value": "pcr_miscellaneous_activities_digital_literacy" + "title": "MISCELLANEOUS_ACTIVITIES_DIGITAL_LITERACY", + "value": "miscellaneous_activities_digital_literacy" }, { - "title": "PCR_MISCELLANEOUS_ACTIVITIES_FINANCIAL_LITERACY", - "value": "pcr_miscellaneous_activities_financial_literacy" + "title": "MISCELLANEOUS_ACTIVITIES_FINANCIAL_LITERACY", + "value": "miscellaneous_activities_financial_literacy" }, { - "title": "PCR_MISCELLANEOUS_ACTIVITIES_LINKAGES", - "value": "pcr_miscellaneous_activities_linkages" + "title": "MISCELLANEOUS_ACTIVITIES_LINKAGES", + "value": "miscellaneous_activities_linkages" }, { - "title": "PCR_MISCELLANEOUS_ACTIVITIES_FAMILY_VISIT", - "value": "pcr_miscellaneous_activities_family_visit" + "title": "MISCELLANEOUS_ACTIVITIES_FAMILY_VISIT", + "value": "miscellaneous_activities_family_visit" }, { - "title": "PCR_MISCELLANEOUS_ACTIVITIES_ROLE_MODEL_VISIT", - "value": "pcr_miscellaneous_activities_role_model_visit" + "title": "MISCELLANEOUS_ACTIVITIES_ROLE_MODEL_VISIT", + "value": "miscellaneous_activities_role_model_visit" }, { - "title": "PCR_MISCELLANEOUS_ACTIVITIES_STAKEHOLDER_VISIT", - "value": "pcr_miscellaneous_activities_stakeholder_visit" + "title": "MISCELLANEOUS_ACTIVITIES_STAKEHOLDER_VISIT", + "value": "miscellaneous_activities_stakeholder_visit" }, { - "title": "PCR_MISCELLANEOUS_ACTIVITIES_SCHOOL_TEACHER_VISIT", - "value": "pcr_miscellaneous_activities_school_teacher_visit" + "title": "MISCELLANEOUS_ACTIVITIES_SCHOOL_TEACHER_VISIT", + "value": "miscellaneous_activities_school_teacher_visit" }, { - "title": "PCR_MISCELLANEOUS_ACTIVITIES_E_PCP_ACTIVITIES", - "value": "pcr_miscellaneous_activities_e_pcp_activities" + "title": "MISCELLANEOUS_ACTIVITIES_E_PCP_ACTIVITIES", + "value": "miscellaneous_activities_e_pcp_activities" }, { - "title": "PCR_MISCELLANEOUS_ACTIVITIES_PCR", - "value": "pcr_miscellaneous_activities_pcr" + "title": "MISCELLANEOUS_ACTIVITIES_PCR", + "value": "miscellaneous_activities_pcr" } ] } From fddd62777d1c38634d31b9a43c205a7058645e7c Mon Sep 17 00:00:00 2001 From: Tusharmahajan12 <121154132+Tusharmahajan12@users.noreply.github.com> Date: Thu, 21 Mar 2024 17:16:56 +0530 Subject: [PATCH 087/126] Task #216113 [BE] In Camp-day-activity Add camp_type (#943) * pcr camp list and admin list filter * pcr camp list and admin list filter * Added camp_type in campdayactivity * Added camp_type in campdayactivity --- src/src/camp/camp.service.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/src/camp/camp.service.ts b/src/src/camp/camp.service.ts index 946555510..9bfd73a31 100644 --- a/src/src/camp/camp.service.ts +++ b/src/src/camp/camp.service.ts @@ -3525,6 +3525,7 @@ export class CampService { let camp_day_happening = body?.camp_day_happening; let camp_day_not_happening_reason = body?.camp_day_not_happening_reason; let mood = body?.mood; + const camp_type = 'pcr'; let object; const currentDate = moment().format('YYYY-MM-DD HH:mm:ss'); @@ -3565,9 +3566,9 @@ export class CampService { } if (camp_day_happening === 'no') { - object = `{camp_id: ${camp_id}, camp_day_happening: "${camp_day_happening}", camp_day_not_happening_reason: "${camp_day_not_happening_reason}", created_by: ${created_by}, updated_by: ${updated_by}, start_date: "${currentDate}",end_date:"${currentDate}"}`; + object = `{camp_id: ${camp_id}, camp_day_happening: "${camp_day_happening}",camp_type:"${camp_type}", camp_day_not_happening_reason: "${camp_day_not_happening_reason}", created_by: ${created_by}, updated_by: ${updated_by}, start_date: "${currentDate}",end_date:"${currentDate}"}`; } else { - object = `{camp_id: ${camp_id}, camp_day_happening: "${camp_day_happening}", created_by: ${created_by}, updated_by: ${updated_by}, start_date: "${currentDate}", mood: "${mood}"}`; + object = `{camp_id: ${camp_id}, camp_day_happening: "${camp_day_happening}",camp_type:"${camp_type}", created_by: ${created_by}, updated_by: ${updated_by}, start_date: "${currentDate}", mood: "${mood}"}`; } const data = { @@ -3583,7 +3584,7 @@ export class CampService { mood start_date end_date - + camp_type } }`, }; From 19d87267bc3794932006ced2abc1c8ac2cf8553f Mon Sep 17 00:00:00 2001 From: GitVivekHub Date: Thu, 21 Mar 2024 17:32:40 +0530 Subject: [PATCH 088/126] Observations report api --- .../dto/observation-fields.dto.ts | 4 - .../observations/observations.controller.ts | 16 ++ src/src/observations/observations.service.ts | 168 ++++++++++++++++-- 3 files changed, 174 insertions(+), 14 deletions(-) diff --git a/src/src/observations/dto/observation-fields.dto.ts b/src/src/observations/dto/observation-fields.dto.ts index 87e9f6d1f..3e0b7f504 100644 --- a/src/src/observations/dto/observation-fields.dto.ts +++ b/src/src/observations/dto/observation-fields.dto.ts @@ -9,10 +9,6 @@ export class ObservationFieldsDto { @IsString() context: string; - @IsNotEmpty() - @IsString() - title: string; - @IsNotEmpty() @IsNumber() fields_sequence: string; diff --git a/src/src/observations/observations.controller.ts b/src/src/observations/observations.controller.ts index 421012cdf..271ec5377 100644 --- a/src/src/observations/observations.controller.ts +++ b/src/src/observations/observations.controller.ts @@ -215,6 +215,22 @@ export class ObservationsController { ); } + @Post('/report') + @UsePipes(ValidationPipe) + @UseGuards(new AuthGuard()) + public async getObservationReport( + @Body() body: ObservationSearchDto, + @Res() response: Response, + @Req() request: Request, + @Param('type') type: string, + ) { + return this.observationsService.getObservationReport( + body, + response, + request, + ); + } + @Post('observation-fields/list') @UsePipes(ValidationPipe) @UseGuards(new AuthGuard()) diff --git a/src/src/observations/observations.service.ts b/src/src/observations/observations.service.ts index 008061b51..1e856a87f 100644 --- a/src/src/observations/observations.service.ts +++ b/src/src/observations/observations.service.ts @@ -912,17 +912,15 @@ export class ObservationsService { }, }; } else if (type == 'submissons') { - let field_responses_filter = - body?.filters?.observation_fields?.field_responses; data = { - query: `query SearchObservations($filters: observations_bool_exp, $field_responses_filter: field_responses_bool_exp) { - observations(where: $filters) { + query: `query SearchObservations($observations: observations_bool_exp, $observation_fields: observation_fields_bool_exp,$field_responses: field_responses_bool_exp) { + observations(where: $observations) { created_at created_by id name title - observation_fields { + observation_fields(where: $observation_fields) { id observation_id field_id @@ -936,11 +934,12 @@ export class ObservationsService { title enum } - field_responses(where: $field_responses_filter) { + field_responses(where: $field_responses) { id context context_id observation_fields_id + response_value } } updated_at @@ -948,18 +947,21 @@ export class ObservationsService { } }`, variables: { - filters: body.filters, - field_responses_filter: field_responses_filter, + observations: body.filters?.observations, + observation_fields: body.filters?.observation_fields, + field_responses: body.filters?.field_responses, }, }; } + + console.log('query-->>', JSON.stringify(data)); } response = await this.hasuraServiceFromServices.queryWithVariable(data); newQdata = response?.data?.data?.observations; - if (newQdata.length > 0) { + if (newQdata?.length > 0) { return resp.status(200).json({ success: true, message: 'Data found successfully!', @@ -1757,7 +1759,7 @@ export class ObservationsService { body.updated_by = user_id; data = { - query: ` query GetFieldResponse { + query: ` query GetFieldResponse { field_responses( where: { observation_id: { _eq: ${observation_id} }, context: { _eq: ${context} }, context_id: { _eq: ${context_id} },field_id:{_eq:${field_id}},observation_fields_id:{_eq:${observation_fields_id}} } ) { @@ -1854,4 +1856,150 @@ export class ObservationsService { data: result, }); } + + async getObservationReport(body: any, resp: any, req: any) { + let sql; + let dataWithStatus; + let observationFieldsResultCount; + + //get observation data from filters + + let observation_body = body?.filters?.observations; + let observation_fields_body = body?.filters?.observation_fields; + + sql = `select * from observations where name = '${observation_body?.name}'`; + + const observationData = ( + await this.hasuraServiceFromServices.executeRawSql(sql) + ).result; + + let observationResult = + this.hasuraServiceFromServices.getFormattedData(observationData); + + let observation_id = observationResult?.[0]?.id; + + //get observation_fields_data; + + sql = `select * from observation_fields where observation_id='${observation_id}' and context = '${observation_fields_body?.context}' and context_id = '${observation_fields_body?.context_id}'`; + const observationFieldsData = ( + await this.hasuraServiceFromServices.executeRawSql(sql) + )?.result; + + if (observationFieldsData == undefined) { + return resp.status(422).json({ + message: 'Data Not Found', + data: [], + }); + } + + let observationFieldsResult = + this.hasuraServiceFromServices.getFormattedData( + observationFieldsData, + ); + + let observationFieldIds = ''; + + observationFieldsResult.forEach((item) => { + observationFieldIds += `'${item.id}',`; + }); + + observationFieldIds = observationFieldIds.slice(0, -1); // Remove the trailing comma + + //get count of observation_fields + sql = `SELECT COUNT(*) FROM observation_fields WHERE observation_id='${observation_id}' AND context = '${observation_fields_body?.context}' and context_id = '${observation_fields_body?.context_id}' + `; + + const observationFieldsDataCount = ( + await this.hasuraServiceFromServices.executeRawSql(sql) + )?.result; + + if (observationFieldsDataCount == undefined) { + return resp.status(422).json({ + message: 'Data Not Found', + data: [], + }); + } + + observationFieldsResultCount = + this.hasuraServiceFromServices.getFormattedData( + observationFieldsDataCount, + ); + + //get data for fields_response + + let fields_response_body = body?.filters?.field_responses; + let fields_response_context = fields_response_body?.context; + let field_responses_context_id = fields_response_body?.context_id; + + sql = `SELECT + COALESCE(COUNT(fr.observation_id), 0) AS count, + all_combinations.observation_id, + all_combinations.context, + all_combinations.context_id + FROM + ( + + SELECT DISTINCT + observation_id, + '${fields_response_context}' AS context, + unnest(ARRAY[${field_responses_context_id}]) AS context_id + FROM + field_responses + WHERE + observation_id = ${observation_id} + AND observation_fields_id IN (${observationFieldIds}) + ) AS all_combinations + LEFT JOIN + field_responses AS fr + ON + all_combinations.observation_id = fr.observation_id + AND all_combinations.context = fr.context + AND all_combinations.context_id = fr.context_id + GROUP BY + all_combinations.observation_id, + all_combinations.context, + all_combinations.context_id; + `; + + const fieldResponsesData = ( + await this.hasuraServiceFromServices.executeRawSql(sql) + )?.result; + + if (fieldResponsesData == undefined) { + return resp.status(422).json({ + message: 'Data Not Found', + data: [], + }); + } + let fieldResponsesResult = + this.hasuraServiceFromServices.getFormattedData(fieldResponsesData); + + if (fieldResponsesResult.length > 0) { + dataWithStatus = this.addStatus( + fieldResponsesResult, + observationFieldsResultCount?.[0]?.count, + ); + } + + if (fieldResponsesResult?.length > 0) { + return resp.status(200).json({ + message: 'Data retrieved', + data: dataWithStatus, + }); + } + } + + addStatus(data, observationFieldsResultCount) { + for (const item of data) { + const count = parseInt(item.count); + if (count == observationFieldsResultCount) { + item.status = 'completed'; + } else if (count == 0) { + item.status = 'not_started'; + } else { + item.status = 'incomplete'; + } + } + return data; + } } From 30134422f50f4619ef4512fa3aea160a1a3936bb Mon Sep 17 00:00:00 2001 From: GitVivekHub Date: Thu, 21 Mar 2024 17:46:12 +0530 Subject: [PATCH 089/126] code rabbit comments solved --- src/src/observations/dto/field.dto.ts | 8 +------- src/src/observations/dto/observation-fields.dto.ts | 2 +- src/src/observations/observations.service.ts | 1 - 3 files changed, 2 insertions(+), 9 deletions(-) diff --git a/src/src/observations/dto/field.dto.ts b/src/src/observations/dto/field.dto.ts index e5aa8deb0..c80c4a17c 100644 --- a/src/src/observations/dto/field.dto.ts +++ b/src/src/observations/dto/field.dto.ts @@ -1,4 +1,4 @@ -import { IsNotEmpty, IsString, IsObject } from 'class-validator'; +import { IsNotEmpty, IsString } from 'class-validator'; export class FieldDto { @IsNotEmpty() @@ -9,13 +9,7 @@ export class FieldDto { @IsString() data_type: string; - description: string; - - extra_all_info: string; - @IsNotEmpty() @IsString() title: string; - - enum: string; } diff --git a/src/src/observations/dto/observation-fields.dto.ts b/src/src/observations/dto/observation-fields.dto.ts index 3e0b7f504..b4d5430cc 100644 --- a/src/src/observations/dto/observation-fields.dto.ts +++ b/src/src/observations/dto/observation-fields.dto.ts @@ -11,7 +11,7 @@ export class ObservationFieldsDto { @IsNotEmpty() @IsNumber() - fields_sequence: string; + fields_sequence: number; @IsNotEmpty() @IsNumber() diff --git a/src/src/observations/observations.service.ts b/src/src/observations/observations.service.ts index 1e856a87f..dcbb8d140 100644 --- a/src/src/observations/observations.service.ts +++ b/src/src/observations/observations.service.ts @@ -83,7 +83,6 @@ export class ObservationsService { const newQdata = vresponse?.data?.observations_aggregate?.aggregate?.count; - console.log('newQdata-->>', vresponse); if (newQdata > 0) { return resp.status(422).json({ success: false, From 7058342658340af4d03c466a826907db7c9919a9 Mon Sep 17 00:00:00 2001 From: GitVivekHub Date: Thu, 21 Mar 2024 23:31:50 +0530 Subject: [PATCH 090/126] get camp learner list for epcp --- .../observations/observations.controller.ts | 13 ++++++ src/src/observations/observations.module.ts | 14 ++++-- src/src/observations/observations.service.ts | 44 +++++++++++++++++++ 3 files changed, 68 insertions(+), 3 deletions(-) diff --git a/src/src/observations/observations.controller.ts b/src/src/observations/observations.controller.ts index 271ec5377..e1fe08e90 100644 --- a/src/src/observations/observations.controller.ts +++ b/src/src/observations/observations.controller.ts @@ -426,4 +426,17 @@ export class ObservationsController { request, ); } + + @Post('/camp-learner-list') + @UsePipes(ValidationPipe) + @UseGuards(new AuthGuard()) + public async getCampLearnersListForEPCP( + @Res() response: Response, + @Req() request: Request, + ) { + return this.observationsService.getCampLearnersListForEPCP( + response, + request, + ); + } } diff --git a/src/src/observations/observations.module.ts b/src/src/observations/observations.module.ts index da1ed5d64..62261d1ff 100644 --- a/src/src/observations/observations.module.ts +++ b/src/src/observations/observations.module.ts @@ -1,13 +1,21 @@ -import { Module } from '@nestjs/common'; +import { Module, NestModule, MiddlewareConsumer } from '@nestjs/common'; import { HasuraModule } from 'src/hasura/hasura.module'; import { UserModule } from 'src/user/user.module'; import { HasuraModule as HasuraModuleFromServices } from '../services/hasura/hasura.module'; import { ObservationsService } from './observations.service'; import { ObservationsController } from './observations.controller'; +import { CohortMiddleware } from 'src/common/middlewares/cohort.middleware'; +import { Method } from 'src/common/method/method'; @Module({ imports: [HasuraModule, HasuraModuleFromServices, UserModule], - providers: [ObservationsService], + providers: [ObservationsService, Method], controllers: [ObservationsController], }) -export class ObservationsModule {} +export class ObservationsModule implements NestModule { + configure(consumer: MiddlewareConsumer) { + consumer + .apply(CohortMiddleware) + .forRoutes('/observations/camp-learner-list'); + } +} diff --git a/src/src/observations/observations.service.ts b/src/src/observations/observations.service.ts index dcbb8d140..7b7a5b190 100644 --- a/src/src/observations/observations.service.ts +++ b/src/src/observations/observations.service.ts @@ -2001,4 +2001,48 @@ export class ObservationsService { } return data; } + + async getCampLearnersListForEPCP(response: any, request: any) { + let program_id = request?.mw_program_id; + let academic_year_id = request?.mw_academic_year_id; + let user_id = request?.mw_userid; + let query = `query MyQuery { + camps(where: {group: {academic_year_id: {_eq:${academic_year_id}}, program_id: {_eq:${program_id}}, status: {_eq: "registered"}, group_users: {user_id: {_eq:${user_id}}, member_type: {_eq: "owner"}, status: {_eq: "active"}}}}) { + camp_id: id + group { + group_id: id + group_users(where: {member_type: {_eq: "member"}, status: {_eq: "active"}, user: {program_beneficiaries: {status: {_eq: "registered_in_camp"}}}}) { + user { + user_id: id + first_name + middle_name + last_name + } + } + } + } + } + + + `; + + const result = await this.hasuraServiceFromServices.getData({ + query: query, + }); + const newQdata = result?.data?.camps; + + if (newQdata) { + return response.status(200).json({ + success: true, + message: 'Data found successfully!', + data: newQdata, + }); + } else { + return response.json({ + status: 400, + message: 'Data Not Found', + data: {}, + }); + } + } } From f11a9b47c9ac9562c77ca1edd82f9729eef70ad0 Mon Sep 17 00:00:00 2001 From: GitVivekHub Date: Fri, 22 Mar 2024 12:40:17 +0530 Subject: [PATCH 091/126] camp status changes --- src/src/observations/observations.service.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/src/observations/observations.service.ts b/src/src/observations/observations.service.ts index 7b7a5b190..96b9f9157 100644 --- a/src/src/observations/observations.service.ts +++ b/src/src/observations/observations.service.ts @@ -2007,7 +2007,7 @@ export class ObservationsService { let academic_year_id = request?.mw_academic_year_id; let user_id = request?.mw_userid; let query = `query MyQuery { - camps(where: {group: {academic_year_id: {_eq:${academic_year_id}}, program_id: {_eq:${program_id}}, status: {_eq: "registered"}, group_users: {user_id: {_eq:${user_id}}, member_type: {_eq: "owner"}, status: {_eq: "active"}}}}) { + camps(where: {group: {academic_year_id: {_eq:${academic_year_id}}, program_id: {_eq:${program_id}},status: {_in: ["registered","camp_ip_verified","change_required"]}, group_users: {user_id: {_eq:${user_id}}, member_type: {_eq: "owner"}, status: {_eq: "active"}}}}) { camp_id: id group { group_id: id From aaf1a74e173614413bf51f3b164926aa0d7543a8 Mon Sep 17 00:00:00 2001 From: GitVivekHub Date: Mon, 25 Mar 2024 15:26:53 +0530 Subject: [PATCH 092/126] url changes to the api --- src/src/camp/camp.controller.ts | 10 +++++ src/src/camp/camp.service.ts | 45 +++++++++++++++++++ .../observations/observations.controller.ts | 13 ------ src/src/observations/observations.module.ts | 11 +---- src/src/observations/observations.service.ts | 45 +------------------ 5 files changed, 58 insertions(+), 66 deletions(-) diff --git a/src/src/camp/camp.controller.ts b/src/src/camp/camp.controller.ts index 10786f27e..d75117324 100644 --- a/src/src/camp/camp.controller.ts +++ b/src/src/camp/camp.controller.ts @@ -384,4 +384,14 @@ export class CampController { campDetails(@Req() request: any, @Body() body: any, @Res() response: any) { return this.campService.campDetails(body, request, response); } + + @Post('camp-info/learners') + @UsePipes(ValidationPipe) + @UseGuards(new AuthGuard()) + public async getCampLearnersListForEPCP( + @Res() response: Response, + @Req() request: Request, + ) { + return this.campService.getCampLearnersListForEPCP(response, request); + } } diff --git a/src/src/camp/camp.service.ts b/src/src/camp/camp.service.ts index aa4f082c4..4ed39b16a 100644 --- a/src/src/camp/camp.service.ts +++ b/src/src/camp/camp.service.ts @@ -4522,4 +4522,49 @@ export class CampService { }); } } + + async getCampLearnersListForEPCP(response: any, request: any) { + let program_id = request?.mw_program_id; + let academic_year_id = request?.mw_academic_year_id; + let user_id = request?.mw_userid; + let query = `query MyQuery { + camps(where: {group: {academic_year_id: {_eq:${academic_year_id}}, program_id: {_eq:${program_id}},status: {_in: ["registered","camp_ip_verified","change_required"]}, group_users: {user_id: {_eq:${user_id}}, member_type: {_eq: "owner"}, status: {_eq: "active"}}}}) { + camp_id: id + group { + group_id: id + group_users(where: {member_type: {_eq: "member"}, status: {_eq: "active"}, user: {program_beneficiaries: {status: {_eq: "registered_in_camp"}}}}) { + user { + user_id: id + first_name + middle_name + last_name + } + } + } + } + } + + + `; + + const result = await this.hasuraServiceFromServices.getData({ + query: query, + }); + + const newQdata = result?.data?.camps; + + if (newQdata) { + return response.status(200).json({ + success: true, + message: 'Data found successfully!', + data: newQdata, + }); + } else { + return response.json({ + status: 400, + message: 'Data Not Found', + data: {}, + }); + } + } } diff --git a/src/src/observations/observations.controller.ts b/src/src/observations/observations.controller.ts index e1fe08e90..271ec5377 100644 --- a/src/src/observations/observations.controller.ts +++ b/src/src/observations/observations.controller.ts @@ -426,17 +426,4 @@ export class ObservationsController { request, ); } - - @Post('/camp-learner-list') - @UsePipes(ValidationPipe) - @UseGuards(new AuthGuard()) - public async getCampLearnersListForEPCP( - @Res() response: Response, - @Req() request: Request, - ) { - return this.observationsService.getCampLearnersListForEPCP( - response, - request, - ); - } } diff --git a/src/src/observations/observations.module.ts b/src/src/observations/observations.module.ts index 62261d1ff..871795314 100644 --- a/src/src/observations/observations.module.ts +++ b/src/src/observations/observations.module.ts @@ -1,10 +1,9 @@ -import { Module, NestModule, MiddlewareConsumer } from '@nestjs/common'; +import { Module } from '@nestjs/common'; import { HasuraModule } from 'src/hasura/hasura.module'; import { UserModule } from 'src/user/user.module'; import { HasuraModule as HasuraModuleFromServices } from '../services/hasura/hasura.module'; import { ObservationsService } from './observations.service'; import { ObservationsController } from './observations.controller'; -import { CohortMiddleware } from 'src/common/middlewares/cohort.middleware'; import { Method } from 'src/common/method/method'; @Module({ @@ -12,10 +11,4 @@ import { Method } from 'src/common/method/method'; providers: [ObservationsService, Method], controllers: [ObservationsController], }) -export class ObservationsModule implements NestModule { - configure(consumer: MiddlewareConsumer) { - consumer - .apply(CohortMiddleware) - .forRoutes('/observations/camp-learner-list'); - } -} +export class ObservationsModule {} diff --git a/src/src/observations/observations.service.ts b/src/src/observations/observations.service.ts index 96b9f9157..9b6651cb2 100644 --- a/src/src/observations/observations.service.ts +++ b/src/src/observations/observations.service.ts @@ -1840,6 +1840,7 @@ export class ObservationsService { result = response?.data?.data?.insert_field_responses_one; } + console.log('result-->>', result); if (!result) { return resp.status(500).json({ success: false, @@ -2001,48 +2002,4 @@ export class ObservationsService { } return data; } - - async getCampLearnersListForEPCP(response: any, request: any) { - let program_id = request?.mw_program_id; - let academic_year_id = request?.mw_academic_year_id; - let user_id = request?.mw_userid; - let query = `query MyQuery { - camps(where: {group: {academic_year_id: {_eq:${academic_year_id}}, program_id: {_eq:${program_id}},status: {_in: ["registered","camp_ip_verified","change_required"]}, group_users: {user_id: {_eq:${user_id}}, member_type: {_eq: "owner"}, status: {_eq: "active"}}}}) { - camp_id: id - group { - group_id: id - group_users(where: {member_type: {_eq: "member"}, status: {_eq: "active"}, user: {program_beneficiaries: {status: {_eq: "registered_in_camp"}}}}) { - user { - user_id: id - first_name - middle_name - last_name - } - } - } - } - } - - - `; - - const result = await this.hasuraServiceFromServices.getData({ - query: query, - }); - const newQdata = result?.data?.camps; - - if (newQdata) { - return response.status(200).json({ - success: true, - message: 'Data found successfully!', - data: newQdata, - }); - } else { - return response.json({ - status: 400, - message: 'Data Not Found', - data: {}, - }); - } - } } From 50c03b6f46dff5ba6e0c907160c5fb5e0dda2d4b Mon Sep 17 00:00:00 2001 From: Tusharmahajan12 <121154132+Tusharmahajan12@users.noreply.github.com> Date: Mon, 25 Mar 2024 18:00:29 +0530 Subject: [PATCH 093/126] Task #216168 [BE] Close PCR Camp By IP (#946) * End PCR camp * End PCR camp * End PCR camp * End PCR camp * End PCR camp --- src/src/camp/camp.controller.ts | 6 +++ src/src/camp/camp.service.ts | 83 +++++++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+) diff --git a/src/src/camp/camp.controller.ts b/src/src/camp/camp.controller.ts index 10786f27e..4aafb50e6 100644 --- a/src/src/camp/camp.controller.ts +++ b/src/src/camp/camp.controller.ts @@ -384,4 +384,10 @@ export class CampController { campDetails(@Req() request: any, @Body() body: any, @Res() response: any) { return this.campService.campDetails(body, request, response); } + + @Post('admin/end_pcr') + @UseGuards(new AuthGuard()) + pcrCampEnd(@Req() request: any, @Body() body: any, @Res() response: any) { + return this.campService.pcrCampEnd(body, request, response); + } } diff --git a/src/src/camp/camp.service.ts b/src/src/camp/camp.service.ts index 9bfd73a31..e31732c34 100644 --- a/src/src/camp/camp.service.ts +++ b/src/src/camp/camp.service.ts @@ -2355,6 +2355,7 @@ export class CampService { kit_was_sufficient kit_ratings kit_feedback + type group { name status @@ -4576,4 +4577,86 @@ export class CampService { }); } } + + public async pcrCampEnd(body: any, request: any, response: any) { + const camp_id = body?.camp_id; + const user = await this.userService.ipUserInfo(request); + if (!user?.data?.program_users?.[0]?.organisation_id) { + return request.status(404).send({ + success: false, + message: 'Invalid Ip', + data: {}, + }); + } + let ip_id = user?.data?.program_users?.[0]?.organisation_id; + //validation check is camp type and camp-day-activity is PCR type + let data = { + query: `query MyQuery { + camps:camps(where: {id: {_eq: ${camp_id}}}){ + id + type + } + }`, + }; + + const pcr_response = await this.hasuraServiceFromServices.getData(data); + //check camps type is PCR or not! + const camps = pcr_response?.data?.camps[0]?.type; + const type = 'main'; + if (camps === 'pcr') { + let update_body = ['type']; + let camp_day_response = await this.hasuraService.q( + 'camps', + { + ...body, + id: camp_id, + type: 'main', + }, + update_body, + true, + ['id', 'type'], + ); + let camp = camp_day_response?.camps; + + // activity logs old camp to new camp + const auditData = { + userId: request?.mw_userid, + mw_userid: request?.mw_userid, + user_type: 'IP', + context: 'pcr_camp.update.camp_type', + context_id: camp_id, + oldData: { + camp_id: camp_id, + type: camps, + }, + newData: { + camp_id: camp_id, + type: 'main', + }, + subject: 'pcr_camp', + subject_id: camp_id, + log_transaction_text: `IP ${request.mw_userid} change pcr camps type pcr to ${type}.`, + tempArray: ['camp_id', 'camps'], + action: 'update', + sortedData: true, + }; + await this.userService.addAuditLogAction(auditData); + + if (camp) { + return response.status(200).json({ + success: true, + message: 'PCR camp updated successfully!', + data: { + camp, + }, + }); + } + } else { + return response.status(422).json({ + success: false, + message: 'PCR Camp is Already close', + data: {}, + }); + } + } } From 963d674f0ef4ed6077473fc1249596cd8d604b6c Mon Sep 17 00:00:00 2001 From: Tusharmahajan12 <121154132+Tusharmahajan12@users.noreply.github.com> Date: Tue, 26 Mar 2024 12:18:17 +0530 Subject: [PATCH 094/126] Change in response (#952) --- src/src/camp/camp.service.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/src/camp/camp.service.ts b/src/src/camp/camp.service.ts index e31732c34..202f4b319 100644 --- a/src/src/camp/camp.service.ts +++ b/src/src/camp/camp.service.ts @@ -373,7 +373,7 @@ export class CampService { let status = 'active'; let qury = `query MyQuery { - main_camp:camps(where: {group_users: {group: {academic_year_id: {_eq:${academic_year_id}}, program_id: {_eq:${program_id}}}, user: {}, member_type: {_eq:${member_type}}, status: {_eq:${status}}, user_id: {_eq:${facilitator_id}}},type:{_eq:"main"}},order_by: {id: asc}) { + camps:camps(where: {group_users: {group: {academic_year_id: {_eq:${academic_year_id}}, program_id: {_eq:${program_id}}}, user: {}, member_type: {_eq:${member_type}}, status: {_eq:${status}}, user_id: {_eq:${facilitator_id}}},type:{_eq:"main"}},order_by: {id: asc}) { id kit_ratings kit_feedback @@ -422,14 +422,14 @@ export class CampService { const data = { query: qury }; const response = await this.hasuraServiceFromServices.getData(data); - const main_camp = response?.data?.main_camp || []; + const camps = response?.data?.camps || []; const pcr_camp = response?.data?.pcr_camp || []; return resp.status(200).json({ success: true, message: 'Data found successfully!', data: { - main_camp, + camps, pcr_camp, }, }); From f53abb30afb3351b3a564b08d94b92df8be582a6 Mon Sep 17 00:00:00 2001 From: Tusharmahajan12 <121154132+Tusharmahajan12@users.noreply.github.com> Date: Tue, 26 Mar 2024 12:20:19 +0530 Subject: [PATCH 095/126] Task #216113 [BE] In Camp-day-activity Add camp_type (#951) * End PCR camp * End PCR camp * End PCR camp * End PCR camp * End PCR camp * Added in body camp_type --- src/src/camp/camp.service.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/src/camp/camp.service.ts b/src/src/camp/camp.service.ts index 202f4b319..5cc3fb8a7 100644 --- a/src/src/camp/camp.service.ts +++ b/src/src/camp/camp.service.ts @@ -3526,7 +3526,7 @@ export class CampService { let camp_day_happening = body?.camp_day_happening; let camp_day_not_happening_reason = body?.camp_day_not_happening_reason; let mood = body?.mood; - const camp_type = 'pcr'; + const camp_type = body?.camp_type; let object; const currentDate = moment().format('YYYY-MM-DD HH:mm:ss'); From 0cf87347687350e461e600aea21773ac0f3a5045 Mon Sep 17 00:00:00 2001 From: Tusharmahajan12 <121154132+Tusharmahajan12@users.noreply.github.com> Date: Tue, 26 Mar 2024 15:00:05 +0530 Subject: [PATCH 096/126] Scholarship id added (#954) --- .../beneficiaries/beneficiaries.controller.ts | 16 ++++++ .../beneficiaries/beneficiaries.service.ts | 53 +++++++++++++++++++ 2 files changed, 69 insertions(+) diff --git a/src/src/beneficiaries/beneficiaries.controller.ts b/src/src/beneficiaries/beneficiaries.controller.ts index 84a96b0f9..427335bf6 100644 --- a/src/src/beneficiaries/beneficiaries.controller.ts +++ b/src/src/beneficiaries/beneficiaries.controller.ts @@ -492,4 +492,20 @@ export class BeneficiariesController { response, ); } + + @Post(':id') + @UseGuards(new AuthGuard()) + public async updateScholarshipId( + @Param('id') id: string, + @Body() body: any, + @Req() request: any, + @Res() response: any, + ) { + return this.beneficiariesService.updateScholarshipId( + id, + body, + request, + response, + ); + } } diff --git a/src/src/beneficiaries/beneficiaries.service.ts b/src/src/beneficiaries/beneficiaries.service.ts index dff78454d..489dd6dcb 100644 --- a/src/src/beneficiaries/beneficiaries.service.ts +++ b/src/src/beneficiaries/beneficiaries.service.ts @@ -1418,6 +1418,7 @@ export class BeneficiariesService { parent_support education_10th_date education_10th_exam_year + scholarship_order_id } program_users { organisation_id @@ -3762,4 +3763,56 @@ export class BeneficiariesService { return updateResult; } + + //Update scolarship_order_id + public async updateScholarshipId( + id: any, + body: any, + request: any, + response: any, + ) { + const learner_id = id; + const scholarship_order_id = body?.scholarship_order_id; + + let check_id = { + query: `query MyQuery { + core_beneficiaries(where: {user_id: {_eq: ${learner_id}}}){ + id + user_id + } + }`, + }; + const response_data = await this.hasuraServiceFromServices.getData( + check_id, + ); + if (!response_data || !response_data.data?.core_beneficiaries[0]) { + return response.status(422).json({ + success: false, + message: 'Beneficiaries ID is not exists!', + data: {}, + }); + } + + let data = { + query: `mutation MyMutation { + update_core_beneficiaries(where: {user_id: {_eq: ${learner_id}}}, _set: {scholarship_order_id: ${scholarship_order_id}}) { + affected_rows + returning { + scholarship_order_id + id + user_id + } + } + }`, + }; + const newResult = await this.hasuraServiceFromServices.getData(data); + const updateResult = + newResult?.data?.update_core_beneficiaries?.returning[0]; + + return response.status(200).json({ + success: true, + message: 'Beneficiaries Scholarship Updated', + data: updateResult || {}, + }); + } } From 97dbe8eae486a64fe932921f7987c907ac030d0d Mon Sep 17 00:00:00 2001 From: Tusharmahajan12 <121154132+Tusharmahajan12@users.noreply.github.com> Date: Tue, 26 Mar 2024 16:30:27 +0530 Subject: [PATCH 097/126] Task #216283 [BE] Update Learner Scholarship API and Added in List API (#956) * Scholarship id added * Scholarship id added --- src/src/beneficiaries/beneficiaries.controller.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/src/beneficiaries/beneficiaries.controller.ts b/src/src/beneficiaries/beneficiaries.controller.ts index 427335bf6..f0475a01a 100644 --- a/src/src/beneficiaries/beneficiaries.controller.ts +++ b/src/src/beneficiaries/beneficiaries.controller.ts @@ -493,7 +493,7 @@ export class BeneficiariesController { ); } - @Post(':id') + @Post('/update-scholarship/:id') @UseGuards(new AuthGuard()) public async updateScholarshipId( @Param('id') id: string, From c87a6ff1b4d5437463d5f022645ab4cadd05bba5 Mon Sep 17 00:00:00 2001 From: Rushi G Date: Tue, 26 Mar 2024 16:44:55 +0530 Subject: [PATCH 098/126] Task #215567 observation report and bulk api bug fix --- src/src/observations/observations.service.ts | 45 ++++++++++++++++---- 1 file changed, 37 insertions(+), 8 deletions(-) diff --git a/src/src/observations/observations.service.ts b/src/src/observations/observations.service.ts index 9b6651cb2..e1f25c276 100644 --- a/src/src/observations/observations.service.ts +++ b/src/src/observations/observations.service.ts @@ -1770,22 +1770,20 @@ export class ObservationsService { const existingData = await this.hasuraServiceFromServices.queryWithVariable(data); - const action = existingData?.data?.data?.field_responses?.length > 0 ? 'update' : 'insert'; - let query = ''; Object.keys(body).forEach((e) => { - if (body[e] && body[e] !== '') { - if (e === 'render') { - query += `${e}: ${body[e]}, `; - } else if (Array.isArray(body[e])) { + if (body[e]) { + if (Array.isArray(body[e])) { query += `${e}: "${JSON.stringify(body[e])}", `; } else { query += `${e}: "${body[e]}", `; } + } else { + query += `${e}: "", `; } }); @@ -1979,9 +1977,40 @@ export class ObservationsService { fieldResponsesResult, observationFieldsResultCount?.[0]?.count, ); - } + return resp.status(200).json({ + message: 'Data retrieved', + data: dataWithStatus, + }); + } else { + //no data fouud + let fieldResponsesData = [ + ['count', 'observation_id', 'context', 'context_id'], + ]; + field_responses_context_id.forEach((item) => { + fieldResponsesData.push([ + '0', + `${observation_id}`, + `${fields_response_context}`, + `${item}`, + ]); + }); + + let fieldResponsesResult = + this.hasuraServiceFromServices.getFormattedData( + fieldResponsesData, + ); + + if (fieldResponsesResult.length > 0) { + dataWithStatus = this.addStatus( + fieldResponsesResult, + observationFieldsResultCount?.[0]?.count, + ); + return resp.status(200).json({ + message: 'Data retrieved', + data: dataWithStatus, + }); + } - if (fieldResponsesResult?.length > 0) { return resp.status(200).json({ message: 'Data retrieved', data: dataWithStatus, From 9b7638fa6969a4c499d572355a464387795b0b8c Mon Sep 17 00:00:00 2001 From: sagar takle Date: Tue, 26 Mar 2024 18:24:47 +0530 Subject: [PATCH 099/126] Task #216283 [BE] Update Learner Scholarship API and Added in List API (#959) (#960) * Scholarship id added * Scholarship id added * Scholarship id added Co-authored-by: Tusharmahajan12 <121154132+Tusharmahajan12@users.noreply.github.com> --- src/src/beneficiaries/beneficiaries.service.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/src/beneficiaries/beneficiaries.service.ts b/src/src/beneficiaries/beneficiaries.service.ts index 4ff544b0b..02ecae6f9 100644 --- a/src/src/beneficiaries/beneficiaries.service.ts +++ b/src/src/beneficiaries/beneficiaries.service.ts @@ -3783,6 +3783,13 @@ export class BeneficiariesService { ) { const learner_id = id; const scholarship_order_id = body?.scholarship_order_id; + if (!scholarship_order_id || scholarship_order_id === '') { + return response.status(422).json({ + success: false, + message: 'required scholarship Id!', + data: {}, + }); + } let check_id = { query: `query MyQuery { From 31c430e7fc4b30691087d0fee210073667c0b509 Mon Sep 17 00:00:00 2001 From: GitVivekHub Date: Wed, 27 Mar 2024 11:28:57 +0530 Subject: [PATCH 100/126] Observation submission api changes --- src/src/observations/observations.service.ts | 30 +++++++++++--------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/src/src/observations/observations.service.ts b/src/src/observations/observations.service.ts index dcbb8d140..c58cb134f 100644 --- a/src/src/observations/observations.service.ts +++ b/src/src/observations/observations.service.ts @@ -863,18 +863,24 @@ export class ObservationsService { } if (body?.filters) { - const traverseFilters = (filters) => { - Object.keys(filters).forEach((key) => { - if (typeof filters[key] === 'object') { - traverseFilters(filters[key]); - } else { - if (!key.startsWith('_')) { - filters[`_${key}`] = filters[key]; - delete filters[key]; + function traverseFilters(filters) { + if (typeof filters === 'object') { + Object.keys(filters).forEach((key) => { + if (Array.isArray(filters[key])) { + filters[key].forEach((item) => + traverseFilters(item), + ); + } else if (typeof filters[key] === 'object') { + traverseFilters(filters[key]); + } else { + if (!key.startsWith('_')) { + filters[`_${key}`] = filters[key]; + delete filters[key]; + } } - } - }); - }; + }); + } + } traverseFilters(body?.filters); @@ -952,8 +958,6 @@ export class ObservationsService { }, }; } - - console.log('query-->>', JSON.stringify(data)); } response = await this.hasuraServiceFromServices.queryWithVariable(data); From 8d03f840fc86337ec014e6897fbac26271cbd1ef Mon Sep 17 00:00:00 2001 From: Tusharmahajan12 <121154132+Tusharmahajan12@users.noreply.github.com> Date: Wed, 27 Mar 2024 14:58:07 +0530 Subject: [PATCH 101/126] Update in required message (#962) --- src/src/organisation/organisation.service.ts | 42 ++++++++++---------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/src/src/organisation/organisation.service.ts b/src/src/organisation/organisation.service.ts index a4f7767f8..40052b3a3 100644 --- a/src/src/organisation/organisation.service.ts +++ b/src/src/organisation/organisation.service.ts @@ -33,27 +33,6 @@ export class OrganisationService { data: {}, }); } - const organisationData = { - name: body?.name, - mobile: body?.mobile, - contact_person: body?.contact_person, - address: body?.address || null, - email_id: body?.email_id, - }; - - const tableName = 'organisations'; - const newOrganisation = await this.hasuraService.q( - tableName, - organisationData, - ['name', 'mobile', 'contact_person', 'address', 'email_id'], - ); - - if (!newOrganisation || !newOrganisation?.organisations.id) { - throw new Error('Failed to create organisation.'); - } - const organisation = newOrganisation?.organisations; - - const organisation_id = organisation?.id; const { learner_target, doc_per_cohort_id, @@ -81,6 +60,27 @@ export class OrganisationService { data: {}, }); } + const organisationData = { + name: body?.name, + mobile: body?.mobile, + contact_person: body?.contact_person, + address: body?.address || null, + email_id: body?.email_id, + }; + + const tableName = 'organisations'; + const newOrganisation = await this.hasuraService.q( + tableName, + organisationData, + ['name', 'mobile', 'contact_person', 'address', 'email_id'], + ); + + if (!newOrganisation || !newOrganisation?.organisations.id) { + throw new Error('Failed to create organisation.'); + } + const organisation = newOrganisation?.organisations; + + const organisation_id = organisation?.id; // Calculate learner_target per camp and round up to nearest whole number if (Math.ceil(learner_target / learner_per_camp) !== camp_target) { From d26be7bbab8c64e723584764802fc1513c16932e Mon Sep 17 00:00:00 2001 From: Tusharmahajan12 <121154132+Tusharmahajan12@users.noreply.github.com> Date: Thu, 28 Mar 2024 11:27:16 +0530 Subject: [PATCH 102/126] Changes for program_id taking from header (#967) --- src/src/camp/camp.service.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/src/camp/camp.service.ts b/src/src/camp/camp.service.ts index 5cc3fb8a7..3915edbf2 100644 --- a/src/src/camp/camp.service.ts +++ b/src/src/camp/camp.service.ts @@ -162,8 +162,8 @@ export class CampService { name: campName, type: 'camp', status: 'camp_initiated', - program_id: body?.program_id || 1, - academic_year_id: body?.academic_year_id || 1, + program_id: request.mw_program_id, + academic_year_id: request.mw_academic_year_id, created_by: facilitator_id, updated_by: facilitator_id, }; @@ -3953,8 +3953,8 @@ export class CampService { public async campLearnersById(id: any, body: any, req: any, resp) { const camp_id = id; const facilitator_id = req.mw_userid; - let program_id = body?.program_id || 1; - let academic_year_id = body?.academic_year_id || 1; + let program_id = req.mw_program_id; + let academic_year_id = req.mw_academic_year_id; const page = isNaN(body.page) ? 1 : parseInt(body.page); const limit = isNaN(body.limit) ? 5 : parseInt(body.limit); From dc076eadc19cd37039006faa001e203bd1289ff2 Mon Sep 17 00:00:00 2001 From: sagar takle Date: Thu, 28 Mar 2024 11:28:27 +0530 Subject: [PATCH 103/126] Changes for program_id taking from header (#967) (#968) Co-authored-by: Tusharmahajan12 <121154132+Tusharmahajan12@users.noreply.github.com> --- src/src/camp/camp.service.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/src/camp/camp.service.ts b/src/src/camp/camp.service.ts index 12fb9fa7c..a6f38a22c 100644 --- a/src/src/camp/camp.service.ts +++ b/src/src/camp/camp.service.ts @@ -162,8 +162,8 @@ export class CampService { name: campName, type: 'camp', status: 'camp_initiated', - program_id: body?.program_id || 1, - academic_year_id: body?.academic_year_id || 1, + program_id: request.mw_program_id, + academic_year_id: request.mw_academic_year_id, created_by: facilitator_id, updated_by: facilitator_id, }; @@ -3953,8 +3953,8 @@ export class CampService { public async campLearnersById(id: any, body: any, req: any, resp) { const camp_id = id; const facilitator_id = req.mw_userid; - let program_id = body?.program_id || 1; - let academic_year_id = body?.academic_year_id || 1; + let program_id = req.mw_program_id; + let academic_year_id = req.mw_academic_year_id; const page = isNaN(body.page) ? 1 : parseInt(body.page); const limit = isNaN(body.limit) ? 5 : parseInt(body.limit); From 22fced732d5a148de98130d2418ac8b4f8645d29 Mon Sep 17 00:00:00 2001 From: Tusharmahajan12 <121154132+Tusharmahajan12@users.noreply.github.com> Date: Thu, 28 Mar 2024 16:55:16 +0530 Subject: [PATCH 104/126] Task #216393 [BE] Multiple PCR camp Close (#969) * Changes for program_id taking from header * multiple close pcr --- src/src/camp/camp.controller.ts | 10 ++++ src/src/camp/camp.service.ts | 94 +++++++++++++++++++++++++++++++++ 2 files changed, 104 insertions(+) diff --git a/src/src/camp/camp.controller.ts b/src/src/camp/camp.controller.ts index 4aafb50e6..5b25fdd33 100644 --- a/src/src/camp/camp.controller.ts +++ b/src/src/camp/camp.controller.ts @@ -390,4 +390,14 @@ export class CampController { pcrCampEnd(@Req() request: any, @Body() body: any, @Res() response: any) { return this.campService.pcrCampEnd(body, request, response); } + + @Post('admin/multiple_end_pcr') + @UseGuards(new AuthGuard()) + multiplePcrCampEnd( + @Req() request: any, + @Body() body: any, + @Res() response: any, + ) { + return this.campService.multiplePcrCampEnd(body, request, response); + } } diff --git a/src/src/camp/camp.service.ts b/src/src/camp/camp.service.ts index 3915edbf2..b1c527e32 100644 --- a/src/src/camp/camp.service.ts +++ b/src/src/camp/camp.service.ts @@ -4659,4 +4659,98 @@ export class CampService { }); } } + + //multiple PCR camp END + public async multiplePcrCampEnd(body: any, request: any, response: any) { + const camp_id = body?.camp_id; + const user = await this.userService.ipUserInfo(request); + if (!user?.data?.program_users?.[0]?.organisation_id) { + return request.status(404).send({ + success: false, + message: 'Invalid Ip', + data: {}, + }); + } + let ip_id = user?.data?.program_users?.[0]?.organisation_id; + //validation check is camp type is PCR only + let data = { + query: `query MyQuery { + camps:camps(where: {id: {_in: [${camp_id}]}}){ + id + type + } +}`, + }; + const pcr_response = await this.hasuraServiceFromServices.getData(data); + //check camps type is PCR or not! + const camps = pcr_response?.data?.camps ?? []; + + // Check if all camps are of type PCR + const campIds = camps + .filter((camp: any) => camp.type != 'pcr') + .map((e) => e.id); + + if (campIds.length > 0) { + return response.status(422).json({ + success: false, + message: `${campIds} This ID are Not PCR Camp Ids`, + data: {}, + }); + } + const type = 'main'; + + let updatecamp = { + query: `mutation MyMutation { + update_camps_many(updates: {where: {id: {_in: [${camp_id}]}}, _set: {type: "main"}}) { + affected_rows + returning { + id + type + } + } + }`, + }; + const updateResponse = await this.hasuraServiceFromServices.getData( + updatecamp, + ); + const updatedCamps = + updateResponse?.data?.update_camps_many?.[0].returning ?? []; + + // activity logs old camp to new camp + const userData = await Promise.all( + updatedCamps?.map(async (item) => { + const auditData = { + userId: request?.mw_userid, + mw_userid: request?.mw_userid, + user_type: 'IP', + context: 'camps.update.camp_type', + context_id: item.id, + oldData: { + camp_id: item.id, + type: 'pcr', + }, + newData: { + camp_id: item.id, + type: item.type, + }, + subject: 'camps', + subject_id: item.id, + log_transaction_text: `IP ${request.mw_userid} change pcr camps type pcr to ${type}.`, + tempArray: ['camp_id', 'camps'], + action: 'update', + sortedData: true, + }; + await this.userService.addAuditLogAction(auditData); + }), + ); + if (updatedCamps) { + return response.status(200).json({ + success: true, + message: 'PCR camp updated successfully!', + data: { + updatedCamps, + }, + }); + } + } } From 1537c8957ff0c6d10aa8128397f053b21396d7b1 Mon Sep 17 00:00:00 2001 From: Tusharmahajan12 <121154132+Tusharmahajan12@users.noreply.github.com> Date: Thu, 28 Mar 2024 18:45:22 +0530 Subject: [PATCH 105/126] Task #213679 [BE] Update attedance details for learner at end camp cron-job (#971) * close camp cron * close camp cron --- src/src/cron/campEnd.cron.ts | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/src/src/cron/campEnd.cron.ts b/src/src/cron/campEnd.cron.ts index e38d5b606..286573eba 100644 --- a/src/src/cron/campEnd.cron.ts +++ b/src/src/cron/campEnd.cron.ts @@ -25,23 +25,15 @@ export class CampEndCron { .format('YYYY-MM-DDTHH:mm:ss'); let updateQuery = `mutation MyMutation { - update_camp_days_activities_tracker(where: {start_date: {_gte: "${yesterdayStartTime}", _lte: "${yesterdayEndTime}"}, end_date: {_is_null: true}}, _set: {end_date: "${today}", end_camp_marked_by: "system"}) { - affected_rows - returning { - id - end_date - camp_id - camp_day_not_happening_reason - camp_day_happening - created_by - start_date - updated_by - updated_at - misc_activities - mood - } + quit: update_camp_days_activities_tracker(where: {start_date: {_gte: "${yesterdayStartTime}", _lte: "${yesterdayEndTime}"}, end_date: {_is_null: true}, attendances: {status: {_neq: "present"},context:{_eq:"camp_days_activities_tracker"}}}, _set: {end_camp_marked_by: "quit", end_date: "${today}"}) { + affected_rows + + } + system: update_camp_days_activities_tracker(where: {start_date: {_gte: "${yesterdayStartTime}", _lte: "${yesterdayEndTime}"}, end_date: {_is_null: true}}, _set: {end_camp_marked_by: "system", end_date: "${today}"}) { + affected_rows + + } } - } `; let result = await this.hasuraService.getData({ query: updateQuery }); From 0056ff2f43ff13eb6e1e4f549a2bf1811537689d Mon Sep 17 00:00:00 2001 From: Tushar Date: Mon, 1 Apr 2024 12:30:42 +0530 Subject: [PATCH 106/126] substract time for attendance --- src/src/camp/camp.service.ts | 1 + src/src/events/events.service.ts | 7 +++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/src/camp/camp.service.ts b/src/src/camp/camp.service.ts index 94352fb61..e5401764b 100644 --- a/src/src/camp/camp.service.ts +++ b/src/src/camp/camp.service.ts @@ -2200,6 +2200,7 @@ export class CampService { } if (!group_id) { return resp.status(400).json({ + status: 400, message: 'CAMP_INVALID_ERROR', data: [], }); diff --git a/src/src/events/events.service.ts b/src/src/events/events.service.ts index d5d8f322f..e7b19583f 100644 --- a/src/src/events/events.service.ts +++ b/src/src/events/events.service.ts @@ -596,10 +596,13 @@ export class EventsService { const format = 'YYYY-MM-DD'; const dateString = moment().startOf('day').format(format); const currentTime = moment().format('HH:mm'); - + const currentTimeWithOffset = moment() + .subtract(5, 'hours') + .subtract(30, 'minutes') + .format('HH:mm'); let data = { query: `query MyQuery1 { - events_aggregate(where: {attendances: {id: {_eq: ${attendance_id}}}, start_date: {_lte: "${dateString}"}, end_date: {_gte: "${dateString}"}, start_time: {_lte: "${currentTime}"}, end_time: {_gte: "${currentTime}"}}) { + events_aggregate(where: {attendances: {id: {_eq: ${attendance_id}}}, start_date: {_lte: "${dateString}"}, end_date: {_gte: "${dateString}"}, start_time: {_lte: "${currentTimeWithOffset}"}, end_time: {_gte: "${currentTimeWithOffset}"}}) { aggregate { count } From f79cd448746854f501ee61e7f836869ab5c1d7cc Mon Sep 17 00:00:00 2001 From: Tusharmahajan12 <121154132+Tusharmahajan12@users.noreply.github.com> Date: Tue, 2 Apr 2024 11:44:57 +0530 Subject: [PATCH 107/126] removed gkp training (#975) --- src/src/enum/enum.json | 4 ---- src/src/facilitator/facilitator.service.ts | 4 ---- 2 files changed, 8 deletions(-) diff --git a/src/src/enum/enum.json b/src/src/enum/enum.json index 85b21c1d3..7a2aa4556 100644 --- a/src/src/enum/enum.json +++ b/src/src/enum/enum.json @@ -428,10 +428,6 @@ "title": "FACILITATOR_EVENT_TYPE_PRAGATI_ORIENTATION", "value": "pragati_orientation" }, - { - "title": "FACILITATOR_EVENT_TYPE_GKP_TRAINING", - "value": "gkp_training" - }, { "title": "FACILITATOR_EVENT_TYPE_PCR_TRAINING", "value": "pcr_training" diff --git a/src/src/facilitator/facilitator.service.ts b/src/src/facilitator/facilitator.service.ts index 84dfc633e..293b86e3c 100644 --- a/src/src/facilitator/facilitator.service.ts +++ b/src/src/facilitator/facilitator.service.ts @@ -93,10 +93,6 @@ export class FacilitatorService { status = `status: { _in: ["applied" ]}`; break; } - case 'gkp_training': { - status = `status: { _in: ["pragati_mobilizer" ]}`; - break; - } case 'pcr_training': { status = `status: { _in: ["pragati_mobilizer","selected_for_onboarding" ]}`; break; From bc36463feccd88536007e05a45270910fbffcd4a Mon Sep 17 00:00:00 2001 From: Tusharmahajan12 <121154132+Tusharmahajan12@users.noreply.github.com> Date: Tue, 2 Apr 2024 11:45:56 +0530 Subject: [PATCH 108/126] close camp cron (#973) --- src/src/camp/camp.service.ts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/src/camp/camp.service.ts b/src/src/camp/camp.service.ts index b1c527e32..0dbdd6853 100644 --- a/src/src/camp/camp.service.ts +++ b/src/src/camp/camp.service.ts @@ -4672,6 +4672,15 @@ export class CampService { }); } let ip_id = user?.data?.program_users?.[0]?.organisation_id; + // Check if camp_id is provided and is an array + if (!camp_id || !Array.isArray(camp_id) || camp_id.length === 0) { + return response.status(422).json({ + success: false, + message: + 'camp_id is required and must be an array and should not be empty', + data: {}, + }); + } //validation check is camp type is PCR only let data = { query: `query MyQuery { From c42fb3f315df0e022e075392acc5d39df1945dad Mon Sep 17 00:00:00 2001 From: GitVivekHub Date: Wed, 3 Apr 2024 17:17:10 +0530 Subject: [PATCH 109/126] Prerak-Offline-Onboarding-Changes --- src/src/upload-file/upload-file.service.ts | 7 +- src/src/userauth/userauth.service.ts | 244 ++++++++++++--------- 2 files changed, 143 insertions(+), 108 deletions(-) diff --git a/src/src/upload-file/upload-file.service.ts b/src/src/upload-file/upload-file.service.ts index 1bf3cb765..576811334 100644 --- a/src/src/upload-file/upload-file.service.ts +++ b/src/src/upload-file/upload-file.service.ts @@ -18,7 +18,9 @@ export class UploadFileService { document_type: string, document_sub_type: string, response: Response, + isCommonFunction?, ) { + console.log('file-->>', file); if (!file?.originalname) { return response.status(400).send({ success: false, @@ -116,7 +118,10 @@ export class UploadFileService { }; const res = await this.hasuraService.postData(query); - if (res) { + if (res && isCommonFunction) { + return { data: { key: key, fileUrl: fileUrl, data: res.data } }; + } else if (res) { + console.log('response file upload-->>', JSON.stringify(res)); return response.status(200).send({ success: true, status: 'Success', diff --git a/src/src/userauth/userauth.service.ts b/src/src/userauth/userauth.service.ts index 169f6bafa..535073db2 100644 --- a/src/src/userauth/userauth.service.ts +++ b/src/src/userauth/userauth.service.ts @@ -9,6 +9,8 @@ import { Method } from '../common/method/method'; import { AcknowledgementService } from 'src/modules/acknowledgement/acknowledgement.service'; import { UserService } from 'src/user/user.service'; import { S3Service } from 'src/services/s3/s3.service'; +import { UploadFileService } from 'src/upload-file/upload-file.service'; +const { Blob } = require('buffer'); const axios = require('axios'); const fs = require('fs'); const path = require('path'); @@ -34,6 +36,7 @@ export class UserauthService { private userService: UserService, private readonly s3Service: S3Service, private method: Method, + private uploadFileService: UploadFileService, ) {} public async userAuthRegister(body, response, role) { @@ -856,6 +859,7 @@ export class UserauthService { user_id, program_id, academic_year_id, + response, ); console.log('result-->>', result); @@ -870,6 +874,7 @@ export class UserauthService { user_id: any, program_id: any, academic_year_id: any, + resp?: any, ) { let tableFields; let tableName; @@ -891,7 +896,7 @@ export class UserauthService { let qualification_document_data; let resultArray = []; let upsert_records_result; - + let base64result; for (const key in json) { const value = json[key]; @@ -902,60 +907,28 @@ export class UserauthService { const subValue = value[subKey]; if (typeof subValue === 'object') { - // Separate the subobjects of profile_photo_1 and documents - if (subKey === 'profile_photo_1') { - profile_photo_1_value = Object.values(subValue); - - documents_values_1 = Object.values( - subValue.documents, - ); - - profile_documents_array.push({ - document_id: documents_values_1?.[1], - name: documents_values_1?.[2], - doument_type: documents_values_1?.[3], - document_sub_type: documents_values_1?.[4], - }); - - // Add profile_photo_1 with its name value for inserting in users table - value['profile_photo_1'] = - profile_photo_1_value?.[0]; - } - if (subKey === 'profile_photo_2') { - profile_photo_2_value = Object.values(subValue); - - documents_values_2 = Object.values( + if (subKey.startsWith('profile_photo_')) { + const profilePhotoValue = Object.values(subValue); + const documentsValues = Object.values( subValue.documents, ); + const base64 = documentsValues?.[0]; + const documentDetails = { + document_type: 'profile_photo', + document_sub_type: subKey, + }; + + if (base64) { + await this.base64ToBlob( + base64, + user_id, + resp, + documentDetails, + ); + } - profile_documents_array.push({ - document_id: documents_values_2?.[1], - name: documents_values_2?.[2], - doument_type: documents_values_2?.[3], - document_sub_type: documents_values_2?.[4], - }); - - // Add profile_photo_2 with its name value for inserting in users table - value['profile_photo_2'] = - profile_photo_2_value?.[0]; - } - if (subKey === 'profile_photo_3') { - profile_photo_3_value = Object.values(subValue); - - documents_values_3 = Object.values( - subValue.documents, - ); - - profile_documents_array.push({ - document_id: documents_values_3?.[1], - name: documents_values_3?.[2], - doument_type: documents_values_3?.[3], - document_sub_type: documents_values_3?.[4], - }); - - // Add profile_photo_3 with its name value for inserting in users table - value['profile_photo_3'] = - profile_photo_3_value?.[0]; + // Add profile photo with its name value for inserting in users table + value[subKey] = profilePhotoValue?.[0]; } } } @@ -970,6 +943,7 @@ export class UserauthService { tableName, user_id, resultArray, + resp, ); } @@ -993,14 +967,29 @@ export class UserauthService { if (tableName == 'qualifications') { console.log('qualvalue-->', value); if (value?.documents) { - qualification_document_data = { - document_id: value?.documents?.document_id, - name: value?.documents?.name, + let base64 = value?.documents?.base64; + + console.log('base64-->>', base64); + let document_details = { + document_type: 'qualifications', document_sub_type: 'qualifications', - doument_type: 'qualifications', context: 'qualifications', }; + + if (base64) { + base64result = await this.base64ToBlob( + base64, + user_id, + resp, + document_details, + ); + } } + + console.log('base64result-->.', base64result); + + value['qualification_reference_document_id'] = + base64result?.document_id; tableFields = tableFields?.filter( (field) => field !== 'documents', ); @@ -1046,36 +1035,18 @@ export class UserauthService { } console.log('upsert_records_result-->>', upsert_records_result); - - if (tableName == 'users' && profile_documents_array?.length > 0) { - await this.upsertProfileDocuments(profile_documents_array); - } - - if (tableName == 'qualifications' && qualification_document_data) { - let result = await this.upsertRecords( - 1, - 'documents', - [ - 'name', - 'document_sub_type', - 'doument_type', - 'context', - 'context_id', - 'user_id', - ], - qualification_document_data, - user_id, - qualification_document_data?.document_id, - ); - - console.log('result doc-->>.', result); - } } return resultArray; } - public async processJsonArray(values, tableName, user_id, resultArray?) { + public async processJsonArray( + values, + tableName, + user_id, + resultArray?, + resp?, + ) { let set_update; let update_id; let referenceFields; @@ -1083,6 +1054,7 @@ export class UserauthService { let documentFields; let documentData; let result; + let base64result; for (const obj of values) { let tableFields = Object.keys(obj); @@ -1104,35 +1076,47 @@ export class UserauthService { 'name', 'contact_number', 'type_of_document', + 'context', + 'context_id', ]; referenceData = { name: obj?.references.name, contact_number: obj?.references.contact_number, type_of_document: obj?.references.type_of_document, - id: obj?.references?.id, context: 'experience', + context_id: obj?.id, }; if (set_update == 1) { referenceData.context_id = obj?.id; + referenceData['id'] = obj?.references?.id; } } if ('documents' in obj.references) { - documentFields = [ - 'name', - 'document_sub_type', - 'doument_type', - 'context', - ]; - documentData = { - name: obj?.references?.documents?.name, - document_sub_type: - obj?.references?.documents?.document_sub_type, - doument_type: obj?.references?.documents?.document_type, - id: obj?.references?.documents?.document_id, - context: 'reference', + let base64 = obj.references?.documents?.base64; + + console.log('base64-->>', base64); + let document_details = { + document_type: 'reference', + document_sub_type: 'reference', + context: 'experience', }; + + if (base64) { + base64result = await this.base64ToBlob( + base64, + user_id, + resp, + document_details, + ); + } + + referenceData['document_id'] = base64result?.document_id; + + tableFields = tableFields?.filter( + (field) => field !== 'documents', + ); } // remove references object from the main object to process the experience object @@ -1142,6 +1126,8 @@ export class UserauthService { delete obj?.references; } + console.log('referenceData-->>', referenceData); + result = await this.upsertRecords( set_update, tableName, @@ -1166,17 +1152,7 @@ export class UserauthService { update_id, ); - if (documentData) { - let update_id = documentData?.id; - let result2 = await this.upsertRecords( - 1, - 'documents', - documentFields, - documentData, - user_id, - update_id, - ); - } + console.log('references result--->>', result1); } if (result?.[tableName]?.extensions) { @@ -1308,7 +1284,7 @@ export class UserauthService { } case 'experience': { query = `query MyQuery { - experience(where: {id: {_eq:${value?.id}}}){ + experience(where: {user_id: {_eq:${user_id}},type:{_eq:${value?.type}}}){ id } } @@ -1679,4 +1655,58 @@ export class UserauthService { }); } } + + public async base64ToBlob(base64, userId, res, documentDetails) { + console.log('here-->>'); + let fileObject; + const arr = base64.split(','); + const mime = arr[0].match(/:(.*?);/)[1]; + const buffer = Buffer.from(arr[1], 'base64'); + let { document_type, document_sub_type } = documentDetails; + + // Generate a unique filename with timestamp and userId + const now = new Date(); + const formattedDateTime = now + .toISOString() + .slice(0, 19) + .replace('T', '-'); // YYYY-MM-DD-HH-MM-SS format + const filename = `${userId}-${formattedDateTime}.${mime.split('/')[1]}`; // Extract file extension + + fileObject = { + fieldname: 'file', + mimetype: mime, + encoding: '7bit', + originalname: filename, + buffer: buffer, + }; + let uploadresponse = await this.uploadFileService.addFile( + fileObject, + userId, + document_type, + document_sub_type, + res, + true, + ); + + console.log( + 'response of file upload-->>', + JSON.stringify(uploadresponse), + ); + let document_id: any; // Adjust the type as per your requirement + + if ('data' in uploadresponse && uploadresponse.data) { + document_id = + uploadresponse.data.data?.insert_documents?.returning[0]?.id; + } else { + // Handle the case where 'data' property is not present + // or uploadresponse.data is null/undefined + document_id = null; // Or any other fallback value + } + return { + data: buffer, + filename, + mimeType: mime, + document_id: document_id, + }; + } } From 0170324be8d05fe482d26cee88c5e896b6254741 Mon Sep 17 00:00:00 2001 From: GitVivekHub Date: Thu, 4 Apr 2024 13:20:10 +0530 Subject: [PATCH 110/126] Address added during prerak registration --- src/src/modules/auth/auth.service.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/src/modules/auth/auth.service.ts b/src/src/modules/auth/auth.service.ts index 66fdda24e..d2e774ddf 100644 --- a/src/src/modules/auth/auth.service.ts +++ b/src/src/modules/auth/auth.service.ts @@ -815,6 +815,14 @@ export class AuthService { 'keycloak_id', 'username', 'aadhar_verified', + 'village', + 'state', + 'block', + 'district', + 'grampanchayat', + 'pincode', + 'lat', + 'long', ], ); From 6a3b76c68d51679e68c85c94945f3cd02bd573d3 Mon Sep 17 00:00:00 2001 From: GitVivekHub Date: Fri, 5 Apr 2024 12:21:55 +0530 Subject: [PATCH 111/126] Experience changes added to the core faciliator --- src/src/userauth/userauth.service.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/src/userauth/userauth.service.ts b/src/src/userauth/userauth.service.ts index 535073db2..3f0c10269 100644 --- a/src/src/userauth/userauth.service.ts +++ b/src/src/userauth/userauth.service.ts @@ -462,6 +462,8 @@ export class UserauthService { diploma_details pan_no sourcing_channel + has_job_exp + has_volunteer_exp } extended_users { marital_status From 7d1eaca55be1e015c86f5e913d7b6c33af55b153 Mon Sep 17 00:00:00 2001 From: Tusharmahajan12 <121154132+Tusharmahajan12@users.noreply.github.com> Date: Wed, 10 Apr 2024 16:58:18 +0530 Subject: [PATCH 112/126] Bug #216977 [BE] [WEB ADMIN] : Status is getting change after refreshing the page, Add status code from API (#988) * Add status code * Add status code --- src/src/camp/camp.service.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/src/camp/camp.service.ts b/src/src/camp/camp.service.ts index 0dbdd6853..c57167d9c 100644 --- a/src/src/camp/camp.service.ts +++ b/src/src/camp/camp.service.ts @@ -2253,6 +2253,7 @@ export class CampService { } if (!group_id) { return resp.status(400).json({ + status: 400, message: 'CAMP_INVALID_ERROR', data: [], }); @@ -2275,6 +2276,7 @@ export class CampService { ); return resp.status(200).json({ + status: 200, message: 'Successfully updated camp details', data: camp_id, }); From 166bc43203bb44c0f5d042a762800e5fc4f0938d Mon Sep 17 00:00:00 2001 From: Tusharmahajan12 <121154132+Tusharmahajan12@users.noreply.github.com> Date: Thu, 11 Apr 2024 10:28:20 +0530 Subject: [PATCH 113/126] Hide documnets upload (#994) --- src/src/organisation/organisation.service.ts | 36 ++++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/src/src/organisation/organisation.service.ts b/src/src/organisation/organisation.service.ts index 40052b3a3..35029b301 100644 --- a/src/src/organisation/organisation.service.ts +++ b/src/src/organisation/organisation.service.ts @@ -35,17 +35,17 @@ export class OrganisationService { } const { learner_target, - doc_per_cohort_id, - doc_per_monthly_id, - doc_quarterly_id, + // doc_per_cohort_id, + // doc_per_monthly_id, + // doc_quarterly_id, learner_per_camp, camp_target, } = body; const missingFields = [ 'learner_target', - 'doc_per_cohort_id', - 'doc_per_monthly_id', - 'doc_quarterly_id', + // 'doc_per_cohort_id', + // 'doc_per_monthly_id', + // 'doc_quarterly_id', 'learner_per_camp', 'camp_target', ].filter((field) => !body[field] && body[field] != ''); @@ -108,9 +108,9 @@ export class OrganisationService { 'academic_year_id', 'status', 'learner_target', - 'doc_per_cohort_id', - 'doc_per_monthly_id', - 'doc_quarterly_id', + // 'doc_per_cohort_id', + // 'doc_per_monthly_id', + // 'doc_quarterly_id', 'learner_per_camp', 'camp_target', ], @@ -355,9 +355,9 @@ export class OrganisationService { const { organisation_id, learner_target, - doc_per_cohort_id, - doc_per_monthly_id, - doc_quarterly_id, + // doc_per_cohort_id, + // doc_per_monthly_id, + // doc_quarterly_id, learner_per_camp, camp_target, } = body; @@ -379,9 +379,9 @@ export class OrganisationService { const missingFields = [ 'organisation_id', 'learner_target', - 'doc_per_cohort_id', - 'doc_per_monthly_id', - 'doc_quarterly_id', + // 'doc_per_cohort_id', + // 'doc_per_monthly_id', + // 'doc_quarterly_id', 'learner_per_camp', 'camp_target', ].filter((field) => !body[field] && body[field] != ''); @@ -421,9 +421,9 @@ export class OrganisationService { 'academic_year_id', 'status', 'learner_target', - 'doc_per_cohort_id', - 'doc_per_monthly_id', - 'doc_quarterly_id', + // 'doc_per_cohort_id', + // 'doc_per_monthly_id', + // 'doc_quarterly_id', 'learner_per_camp', 'camp_target', ], From 07ced039b16146ad95b60fd62a84114f47edd707 Mon Sep 17 00:00:00 2001 From: VivekB <136580365+GitVivekHub@users.noreply.github.com> Date: Thu, 11 Apr 2024 11:43:14 +0530 Subject: [PATCH 114/126] Default status for new cohort made applie for prerak (#995) --- src/src/facilitator/facilitator.service.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/src/facilitator/facilitator.service.ts b/src/src/facilitator/facilitator.service.ts index 869ce4c4b..7e7e883df 100644 --- a/src/src/facilitator/facilitator.service.ts +++ b/src/src/facilitator/facilitator.service.ts @@ -2536,6 +2536,7 @@ export class FacilitatorService { academic_year_id: academic_year_id, parent_ip: parent_ip, program_id: program_id, + status: 'applied', qualification_ids: JSON.stringify( JSON.parse(otherData.qualification_ids), ).replace(/"/g, '\\"'), From 0c36df7b96e5d95399db2fc1b648bd05c3f0c689 Mon Sep 17 00:00:00 2001 From: Tusharmahajan12 <121154132+Tusharmahajan12@users.noreply.github.com> Date: Thu, 11 Apr 2024 15:15:15 +0530 Subject: [PATCH 115/126] Bug #216803 [WEB ADMIN] ; Event | Prerak Attendance is not being marked as present (#997) * Added time zone * Added time zone * Added time zone * Added time zone * Added time zone --- src/src/events/events.service.ts | 37 ++++++++++++++++++++++---------- 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/src/src/events/events.service.ts b/src/src/events/events.service.ts index e7b19583f..2a9d03d8e 100644 --- a/src/src/events/events.service.ts +++ b/src/src/events/events.service.ts @@ -75,6 +75,23 @@ export class EventsService { const userDetail = await this.userService.ipUserInfo(header); let user_id = userDetail.data.id; //get do_id for event exam master data + // Convert start_date and end_date to UTC + const startDateTimeUTC = moment + .tz( + req.start_date + ' ' + req.start_time, + 'YYYY-MM-DD HH:mm', + 'Asia/Kolkata', + ) + .utc(); + + const endDateTimeUTC = moment + .tz( + req.end_date + ' ' + req.end_time, + 'YYYY-MM-DD HH:mm', + 'Asia/Kolkata', + ) + .utc(); + let eventExamData = { query: `query MyQuery { event_exams_master(where: {academic_year_id: {_eq: ${academic_year_id}}, program_id: {_eq: ${program_id}}, event_type: {_eq: "${req.type}"}}){ @@ -117,10 +134,10 @@ export class EventsService { name: req.name, master_trainer: req.master_trainer, created_by: user_id, - end_date: req.end_date, - end_time: req.end_time, - start_date: req.start_date, - start_time: req.start_time, + end_date: endDateTimeUTC.format('YYYY-MM-DD'), + end_time: endDateTimeUTC.format('HH:mm'), + start_time: startDateTimeUTC.format('HH:mm'), + start_date: startDateTimeUTC.format('YYYY-MM-DD'), updated_by: user_id, type: req.type, program_id: program_id, @@ -184,6 +201,7 @@ export class EventsService { const count = geteventData?.data?.events_aggregate?.aggregate?.count; //if event created show this message + if (count > 0) { return response.status(422).send({ success: false, @@ -594,15 +612,12 @@ export class EventsService { } try { const format = 'YYYY-MM-DD'; - const dateString = moment().startOf('day').format(format); - const currentTime = moment().format('HH:mm'); - const currentTimeWithOffset = moment() - .subtract(5, 'hours') - .subtract(30, 'minutes') - .format('HH:mm'); + const dateString = moment.utc().startOf('day').format(format); + const currentTime = moment.utc().format('HH:mm'); + let data = { query: `query MyQuery1 { - events_aggregate(where: {attendances: {id: {_eq: ${attendance_id}}}, start_date: {_lte: "${dateString}"}, end_date: {_gte: "${dateString}"}, start_time: {_lte: "${currentTimeWithOffset}"}, end_time: {_gte: "${currentTimeWithOffset}"}}) { + events_aggregate(where: {attendances: {id: {_eq: ${attendance_id}}}, start_date: {_lte: "${dateString}"}, end_date: {_gte: "${dateString}"}, start_time: {_lte: "${currentTime}"}, end_time: {_gte: "${currentTime}"}}) { aggregate { count } From a464771fade251f9b60c00ae0e01e38f0086f208 Mon Sep 17 00:00:00 2001 From: Tusharmahajan12 <121154132+Tusharmahajan12@users.noreply.github.com> Date: Thu, 11 Apr 2024 19:07:57 +0530 Subject: [PATCH 116/126] Task #217102 [BE] Add validation in edit event and add attendances in get-user-by-id (#1003) * Added time zone * Added time zone * Added time zone * Added time zone * Added time zone * Added validation in event edit * Added validation in event edit * Added validation in event edit --- src/src/events/events.service.ts | 74 ++++++++++++++++++++++++++------ 1 file changed, 61 insertions(+), 13 deletions(-) diff --git a/src/src/events/events.service.ts b/src/src/events/events.service.ts index 2a9d03d8e..056026f7a 100644 --- a/src/src/events/events.service.ts +++ b/src/src/events/events.service.ts @@ -453,6 +453,55 @@ export class EventsService { try { const userDetail = await this.userService.ipUserInfo(header); const user_id = userDetail.data.id; + // Validate start date + const daysDiff = moment + .utc(req.end_date) + .diff(moment.utc(req.start_date), 'days'); + const currentDateTime = moment.utc(); + + const startDateTime = moment( + req.start_date + ' ' + req.start_time, + 'YYYY-MM-DD HH:mm', + true, // Parse in strict mode + ).utc(); + + let errorMessage = {}; + if (startDateTime.isBefore(currentDateTime, 'day')) { + errorMessage = { + key: 'start_date', + message: 'Start date cannot be a back date.', + }; + } else if (daysDiff < 0 || daysDiff > 5) { + errorMessage = { + key: 'event_days', + message: 'Event duration must be between 1 and 5 days.', + }; + } + if (Object.keys(errorMessage).length) { + return resp.status(422).send({ + success: false, + ...errorMessage, + data: {}, + }); + } + + // Convert start_date and end_date to UTC + const startDateTimeUTC = moment + .tz( + req.start_date + ' ' + req.start_time, + 'YYYY-MM-DD HH:mm', + 'Asia/Kolkata', + ) + .utc(); + + const endDateTimeUTC = moment + .tz( + req.end_date + ' ' + req.end_time, + 'YYYY-MM-DD HH:mm', + 'Asia/Kolkata', + ) + .utc(); + const attendees = req.attendees; if (attendees) { const data = { @@ -527,8 +576,13 @@ export class EventsService { } } //update events fields + const newRequest = { - ...req, + ...req, // Spread req object first + end_date: endDateTimeUTC.format('YYYY-MM-DD'), + end_time: endDateTimeUTC.format('HH:mm'), + start_time: startDateTimeUTC.format('HH:mm'), + start_date: startDateTimeUTC.format('YYYY-MM-DD'), ...(req.reminders && { reminders: JSON.stringify(req.reminders).replace( /"/g, @@ -996,34 +1050,28 @@ export class EventsService { events(where: {end_date:{_gte:"${todayDate}"},academic_year_id: {_eq:${academic_year_id}}, program_id: {_eq:${program_id}},attendances: {context: {_eq: ${context}}, user_id: {_eq: ${id}}}}, limit: $limit, offset: $offset) { id user_id - context - context_id - created_by - updated_by - created_at - updated_at start_date start_time end_date end_time name - location - location_type type params master_trainer lms_test_tracking(where: {user_id: {_eq: ${id}},context:{_eq:${context}}}) { - context - context_id status - created_at - updated_at id test_id score user_id certificate_status } + attendances{ + id + user_id + status + date_time + } } }`, From 647a92f9f618745efac12760bd5f12c0d8ffcc60 Mon Sep 17 00:00:00 2001 From: Tusharmahajan12 <121154132+Tusharmahajan12@users.noreply.github.com> Date: Thu, 11 Apr 2024 19:23:34 +0530 Subject: [PATCH 117/126] Task #217102 [BE] Add validation in edit event and add attendances in get-user-by-id added condition in attendances (#1005) * Added time zone * Added time zone * Added time zone * Added time zone * Added time zone * Added validation in event edit * Added validation in event edit * Added validation in event edit * Added validation in event edit --- src/src/events/events.service.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/src/events/events.service.ts b/src/src/events/events.service.ts index 056026f7a..75f3228a8 100644 --- a/src/src/events/events.service.ts +++ b/src/src/events/events.service.ts @@ -1066,7 +1066,7 @@ export class EventsService { user_id certificate_status } - attendances{ + attendances(where: {context: {_eq: ${context}}, user_id: {_eq: ${id}}}){ id user_id status From c126df81d8bc41b5655c6177792ff816e878bacf Mon Sep 17 00:00:00 2001 From: Tusharmahajan12 <121154132+Tusharmahajan12@users.noreply.github.com> Date: Mon, 15 Apr 2024 16:19:43 +0530 Subject: [PATCH 118/126] Bug #217227 [BE] [WEB ADMIN] : Incorrect count is appearing on add selected removed attendances details from list (#1010) * Added time zone * Added time zone * Added time zone * Added time zone * Added time zone * Added validation in event edit * Added validation in event edit * Added validation in event edit * Added validation in event edit * remove attendense --- src/src/events/events.service.ts | 31 ------------------------------- 1 file changed, 31 deletions(-) diff --git a/src/src/events/events.service.ts b/src/src/events/events.service.ts index 75f3228a8..ab857ee64 100644 --- a/src/src/events/events.service.ts +++ b/src/src/events/events.service.ts @@ -396,37 +396,6 @@ export class EventsService { type updated_by user_id - attendances(order_by: { - created_at: asc - }) { - created_by - created_at - context - context_id - date_time - id - lat - user_id - updated_by - status - long - rsvp - fa_is_processed - fa_similarity_percentage - user{ - first_name - id - last_name - middle_name - profile_url - aadhar_verified - aadhaar_verification_mode - program_faciltators{ - documents_status - } - } - } - } } `, From f7f40673003fbdff23177f01a1671ee7125be287 Mon Sep 17 00:00:00 2001 From: GitVivekHub Date: Mon, 15 Apr 2024 18:14:48 +0530 Subject: [PATCH 119/126] Prerak offline onbaording file changes --- src/package-lock.json | 2 +- src/package.json | 2 +- src/src/userauth/userauth.controller.ts | 21 +- src/src/userauth/userauth.service.ts | 292 +++++++++++++----------- 4 files changed, 183 insertions(+), 134 deletions(-) diff --git a/src/package-lock.json b/src/package-lock.json index f10bef8eb..2c9153ceb 100644 --- a/src/package-lock.json +++ b/src/package-lock.json @@ -18,7 +18,7 @@ "@nestjs/config": "^2.3.1", "@nestjs/core": "^9.0.0", "@nestjs/mapped-types": "^1.2.2", - "@nestjs/platform-express": "^9.0.0", + "@nestjs/platform-express": "^9.4.3", "@nestjs/schedule": "^3.0.1", "@sentry/node": "^7.52.1", "atob": "^2.1.2", diff --git a/src/package.json b/src/package.json index 69f5f508c..62ef83d34 100644 --- a/src/package.json +++ b/src/package.json @@ -29,7 +29,7 @@ "@nestjs/config": "^2.3.1", "@nestjs/core": "^9.0.0", "@nestjs/mapped-types": "^1.2.2", - "@nestjs/platform-express": "^9.0.0", + "@nestjs/platform-express": "^9.4.3", "@nestjs/schedule": "^3.0.1", "@sentry/node": "^7.52.1", "atob": "^2.1.2", diff --git a/src/src/userauth/userauth.controller.ts b/src/src/userauth/userauth.controller.ts index 6fcc8b24a..4ff0e8ef7 100644 --- a/src/src/userauth/userauth.controller.ts +++ b/src/src/userauth/userauth.controller.ts @@ -11,10 +11,13 @@ import { ValidationPipe, Response, Request, + UploadedFile, + UseInterceptors, } from '@nestjs/common'; import { AuthGuard } from 'src/modules/auth/auth.guard'; import { UserauthService } from './userauth.service'; +import { FileInterceptor } from '@nestjs/platform-express/multer'; @Controller('userauth') export class UserauthController { @@ -45,15 +48,27 @@ export class UserauthController { return this.userauthService.getUserInfoDetails(request, response); } + // @Post('/onboarding') + // @UsePipes(ValidationPipe) + // @UseGuards(new AuthGuard()) + // public async userOnboarding( + // @Body() body: Body, + // @Res() response: Response, + // @Req() request: Request, + // ) { + // return this.userauthService.userOnboarding(body, response, request); + // } + @Post('/onboarding') - @UsePipes(ValidationPipe) @UseGuards(new AuthGuard()) + @UsePipes(ValidationPipe) + @UseInterceptors(FileInterceptor('jsonpayload')) // 'jsonpayload' is the name of the field for the uploaded file public async userOnboarding( - @Body() body: Body, + @UploadedFile() file: Express.Multer.File, @Res() response: Response, @Req() request: Request, ) { - return this.userauthService.userOnboarding(body, response, request); + return this.userauthService.userOnboarding(file, response, request); } @Get('/beneficiary/user-info/:id') diff --git a/src/src/userauth/userauth.service.ts b/src/src/userauth/userauth.service.ts index 3f0c10269..cdece6466 100644 --- a/src/src/userauth/userauth.service.ts +++ b/src/src/userauth/userauth.service.ts @@ -149,9 +149,9 @@ export class UserauthService { if (findUsername.length > 0 && group === 'beneficiaries') { let lastUsername = findUsername[findUsername.length - 1].username; - console.log('lastUsername', lastUsername); + // //console.log('lastUsername', lastUsername); let count = findUsername.length; - console.log('count', count); + //console.log('count', count); data_to_create_user.username = data_to_create_user.username + '_' + count; } @@ -390,7 +390,7 @@ export class UserauthService { let academic_year_id = request?.mw_academic_year_id; // get academic_year_id from token //query to get user details information - //console.log('user_id', user_id); + ////console.log('user_id', user_id); let query = `query MyQuery { users_by_pk(id:${user_id}) { @@ -551,7 +551,7 @@ export class UserauthService { let user_data = hasura_response?.data; - //console.log('user_data', JSON.stringify(user_data)); + ////console.log('user_data', JSON.stringify(user_data)); // get profile photo document details let profilePhoto1Documents = @@ -832,7 +832,7 @@ export class UserauthService { aadhaar_verification_mode, id, }, - core_faciltator: user_data?.users_by_pk?.core_faciltator || {}, + core_faciltators: user_data?.users_by_pk?.core_faciltator || {}, extended_users: user_data?.users_by_pk?.extended_users || {}, references: user_data?.users_by_pk?.references, program_faciltators: user_data?.users_by_pk?.program_faciltators, @@ -851,26 +851,40 @@ export class UserauthService { public async userOnboarding(body: any, response: any, request: any) { //first check validations for all inputs + let jsonContent; + //console.log('body-->', body); + + try { + // Convert buffer to JSON object + jsonContent = JSON.parse(body.buffer.toString('utf8')); + + // Process JSON content + + // Return success message + } catch (error) { + console.error('Error parsing JSON:', error); + } let user_id = request?.mw_userid; let program_id = request?.mw_program_id; - let academic_year_id = request?.academic_year_id; + let academic_year_id = request?.mw_academic_year_id; let result = await this.processTable( - body, + jsonContent, user_id, program_id, academic_year_id, response, ); - console.log('result-->>', result); + //console.log('result-->>', result); if (result) { return response.status(200).json({ result: result, }); } } + private async processTable( json: any, user_id: any, @@ -901,142 +915,161 @@ export class UserauthService { let base64result; for (const key in json) { const value = json[key]; - - if (typeof value === 'object') { - tableName = key; - tableFields = Object.keys(value); - for (const subKey in value) { - const subValue = value[subKey]; - - if (typeof subValue === 'object') { - if (subKey.startsWith('profile_photo_')) { - const profilePhotoValue = Object.values(subValue); - const documentsValues = Object.values( - subValue.documents, - ); - const base64 = documentsValues?.[0]; - const documentDetails = { - document_type: 'profile_photo', - document_sub_type: subKey, - }; - - if (base64) { - await this.base64ToBlob( - base64, - user_id, - resp, - documentDetails, + if (!(Object.keys(value).length === 0)) { + //console.log('value-->>', value); + if (typeof value === 'object') { + tableName = key; + tableFields = Object.keys(value); + for (const subKey in value) { + const subValue = value[subKey]; + + if (typeof subValue === 'object') { + if (subKey.startsWith('profile_photo_')) { + const profilePhotoValue = + Object.values(subValue); + const documentsValues = Object.values( + subValue.documents, ); + const base64 = documentsValues?.[0]; + const documentDetails = { + document_type: 'profile_photo', + document_sub_type: subKey, + }; + + if (base64) { + await this.base64ToBlob( + base64, + user_id, + resp, + documentDetails, + ); + } + + // Add profile photo with its name value for inserting in users table + value[subKey] = profilePhotoValue?.[0]; } - - // Add profile photo with its name value for inserting in users table - value[subKey] = profilePhotoValue?.[0]; } } } - } - - if (Array.isArray(value)) { - // Handle array - tableName = key; - await this.processJsonArray( - value, - tableName, - user_id, - resultArray, - resp, - ); - } + if (Array.isArray(value)) { + // Handle array + tableName = key; + let tempvalue = []; - if (tableName != 'users' && tableName != 'references') { - value.user_id = user_id; - tableFields.push('user_id'); - } + for (let i = 0; i < value.length; i++) { + let tempobj = value[i]; + delete tempobj.status; + delete tempobj.unique_key; + tempvalue.push(tempobj); + } + await this.processJsonArray( + tempvalue, + tableName, + user_id, + resultArray, + resp, + ); + } - if (tableName == 'program_faciltators') { - value.program_id = program_id; - value.academic_year_id = academic_year_id; - tableFields.push('program_id'); - tableFields.push('academic_year_id'); - } + if (tableName != 'users' && tableName != 'references') { + value.user_id = user_id; + tableFields.push('user_id'); + } - if (tableName == 'references') { - value.context_id = user_id; - tableFields.push('context_id'); - } + if (tableName == 'program_faciltators') { + //console.log('vlaues-->>', value); - if (tableName == 'qualifications') { - console.log('qualvalue-->', value); - if (value?.documents) { - let base64 = value?.documents?.base64; + value.program_id = program_id; + value.academic_year_id = academic_year_id; + try { + value.qualification_ids = JSON.stringify( + JSON.parse(value?.qualification_ids), + ).replace(/"/g, '\\"'); + } catch (e) {} - console.log('base64-->>', base64); - let document_details = { - document_type: 'qualifications', - document_sub_type: 'qualifications', - context: 'qualifications', - }; + tableFields.push('program_id'); + tableFields.push('academic_year_id'); + //console.log('vlaues123-->>', value); + } - if (base64) { - base64result = await this.base64ToBlob( - base64, - user_id, - resp, - document_details, - ); - } + if (tableName == 'references') { + value.context_id = user_id; + tableFields.push('context_id'); } - console.log('base64result-->.', base64result); + if (tableName == 'qualifications') { + //console.log('qualvalue-->', value); + if (value?.documents) { + let base64 = value?.documents?.base64; - value['qualification_reference_document_id'] = - base64result?.document_id; - tableFields = tableFields?.filter( - (field) => field !== 'documents', - ); - delete value?.documents; - console.log('qualvalue123-->', value); - } + //console.log('base64-->>', base64); + let document_details = { + document_type: 'qualifications', + document_sub_type: 'qualifications', + context: 'qualifications', + }; - let response = await this.findExisitingReccord( - tableName, - value, - user_id, - ); + if (base64) { + base64result = await this.base64ToBlob( + base64, + user_id, + resp, + document_details, + ); + } + } - set_update = response?.set_update; - update_id = response?.id; + //console.log('base64result-->.', base64result); - if (tableName != 'experience') { - upsert_records_result = await this.upsertRecords( - set_update, + value['qualification_reference_document_id'] = + base64result?.document_id; + tableFields = tableFields?.filter( + (field) => field !== 'documents', + ); + delete value?.documents; + //console.log('qualvalue123-->', value); + } + + let response = await this.findExisitingReccord( tableName, - tableFields, value, user_id, - update_id, ); - if (upsert_records_result?.[tableName]?.extensions) { - resultArray.push({ - [tableName]: { - status: false, - message: - upsert_records_result?.[tableName]?.message, - }, - }); - } else { - resultArray.push({ - [tableName]: { - status: true, - message: 'successfully updated the value', - }, - }); + set_update = response?.set_update; + update_id = response?.id; + + if (tableName != 'experience') { + upsert_records_result = await this.upsertRecords( + set_update, + tableName, + tableFields, + value, + user_id, + update_id, + ); + + if (upsert_records_result?.[tableName]?.extensions) { + resultArray.push({ + [tableName]: { + status: false, + message: + upsert_records_result?.[tableName]?.message, + }, + }); + } else { + resultArray.push({ + [tableName]: { + status: true, + message: 'successfully updated the value', + }, + }); + } } - } - console.log('upsert_records_result-->>', upsert_records_result); + //console.log('upsert_records_result-->>', upsert_records_result); + } } return resultArray; @@ -1066,7 +1099,7 @@ export class UserauthService { set_update = obj?.id ? 1 : 0; update_id = obj?.id; - console.log('set->.', set_update); + //console.log('set->.', set_update); if (set_update == 1) { tableFields.push('id'); } @@ -1098,7 +1131,7 @@ export class UserauthService { if ('documents' in obj.references) { let base64 = obj.references?.documents?.base64; - console.log('base64-->>', base64); + //console.log('base64-->>', base64); let document_details = { document_type: 'reference', document_sub_type: 'reference', @@ -1128,7 +1161,7 @@ export class UserauthService { delete obj?.references; } - console.log('referenceData-->>', referenceData); + //console.log('referenceData-->>', referenceData); result = await this.upsertRecords( set_update, @@ -1154,7 +1187,7 @@ export class UserauthService { update_id, ); - console.log('references result--->>', result1); + //console.log('references result--->>', result1); } if (result?.[tableName]?.extensions) { @@ -1315,6 +1348,7 @@ export class UserauthService { id?, ) { let result; + //console.log('value-->>', value); if (set_update == 1 && id) { result = await this.hasuraService.q( tableName, @@ -1354,7 +1388,7 @@ export class UserauthService { ['name', 'document_sub_type', 'doument_type', 'id'], ); - console.log('resuklt-->>', result); + //console.log('resuklt-->>', result); } } @@ -1659,7 +1693,7 @@ export class UserauthService { } public async base64ToBlob(base64, userId, res, documentDetails) { - console.log('here-->>'); + //console.log('here-->>'); let fileObject; const arr = base64.split(','); const mime = arr[0].match(/:(.*?);/)[1]; @@ -1690,10 +1724,10 @@ export class UserauthService { true, ); - console.log( - 'response of file upload-->>', - JSON.stringify(uploadresponse), - ); + //console.log( + // 'response of file upload-->>', + // JSON.stringify(uploadresponse), + // ); let document_id: any; // Adjust the type as per your requirement if ('data' in uploadresponse && uploadresponse.data) { From f486f18f468751497267917b6c50885bda25f648 Mon Sep 17 00:00:00 2001 From: GitVivekHub Date: Wed, 17 Apr 2024 10:01:11 +0530 Subject: [PATCH 120/126] references and alternative mobile number fix --- src/src/userauth/userauth.service.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/src/userauth/userauth.service.ts b/src/src/userauth/userauth.service.ts index cdece6466..fb9d60a2e 100644 --- a/src/src/userauth/userauth.service.ts +++ b/src/src/userauth/userauth.service.ts @@ -977,6 +977,12 @@ export class UserauthService { tableFields.push('user_id'); } + if (tableName === 'users') { + if (typeof value?.alternative_mobile_number === 'string') { + value.alternative_mobile_number = null; + } + } + if (tableName == 'program_faciltators') { //console.log('vlaues-->>', value); @@ -996,6 +1002,12 @@ export class UserauthService { if (tableName == 'references') { value.context_id = user_id; tableFields.push('context_id'); + value.context = 'users'; + tableFields.push('context'); + value.program_id = program_id; + value.academic_year_id = academic_year_id; + tableFields.push('program_id'); + tableFields.push('academic_year_id'); } if (tableName == 'qualifications') { From 789101f0f35668fa8f9bab482e02aca0c97277ea Mon Sep 17 00:00:00 2001 From: VivekB <136580365+GitVivekHub@users.noreply.github.com> Date: Wed, 17 Apr 2024 11:58:11 +0530 Subject: [PATCH 121/126] event list displayed as per start date and end date (#1017) --- src/src/events/events.controller.ts | 10 +++++++--- src/src/events/events.service.ts | 17 +++++++++++++++-- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/src/src/events/events.controller.ts b/src/src/events/events.controller.ts index eb8fd09ae..c28cb60b1 100644 --- a/src/src/events/events.controller.ts +++ b/src/src/events/events.controller.ts @@ -35,10 +35,14 @@ export class EventsController { return this.eventsService.create(createEventDto, header, response); } - @Get('/list') + @Post('/list') @UseGuards(new AuthGuard()) - getEventsList(@Req() header: Request, @Res() response: Response) { - return this.eventsService.getEventsList(header, response); + getEventsList( + @Body() body: Body, + @Req() header: Request, + @Res() response: Response, + ) { + return this.eventsService.getEventsList(body, header, response); } @Post() diff --git a/src/src/events/events.service.ts b/src/src/events/events.service.ts index ab857ee64..2ef4c47a2 100644 --- a/src/src/events/events.service.ts +++ b/src/src/events/events.service.ts @@ -267,7 +267,8 @@ export class EventsService { } } - public async getEventsList(header, response) { + public async getEventsList(body, header, response) { + let filter = []; let program_id = header?.mw_program_id; let academic_year_id = header?.mw_academic_year_id; const userDetail: any = await this.userService.ipUserInfo(header); @@ -295,6 +296,18 @@ export class EventsService { }); } + filter.push( + `{academic_year_id: {_eq:${academic_year_id}}, program_id: {_eq:${program_id}}`, + ); + + if (body?.start_date) { + filter.push(`start_date: {_eq:"${body?.start_date}"}`); + } + + if (body?.end_date) { + filter.push(`end_date: {_eq:"${body?.end_date}"}`); + } + const allIpList = getIps?.data?.users.map((curr) => curr.id); let getQuery = { query: `query MyQuery { @@ -311,7 +324,7 @@ export class EventsService { } } ], - _and: {academic_year_id: {_eq:${academic_year_id}}, program_id: {_eq:${program_id}} + _and: ${filter} }}) { id location From 9f38a7a6296f455fdd55cb7552b7faa5be19eb7f Mon Sep 17 00:00:00 2001 From: GitVivekHub Date: Wed, 17 Apr 2024 16:36:20 +0530 Subject: [PATCH 122/126] references documents issue resolved --- src/src/userauth/userauth.service.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/src/userauth/userauth.service.ts b/src/src/userauth/userauth.service.ts index fb9d60a2e..43cf57645 100644 --- a/src/src/userauth/userauth.service.ts +++ b/src/src/userauth/userauth.service.ts @@ -1160,6 +1160,7 @@ export class UserauthService { } referenceData['document_id'] = base64result?.document_id; + referenceFields.push('document_id'); tableFields = tableFields?.filter( (field) => field !== 'documents', @@ -1199,7 +1200,7 @@ export class UserauthService { update_id, ); - //console.log('references result--->>', result1); + console.log('references result--->>', result1); } if (result?.[tableName]?.extensions) { From 5cf974f939b6d70a9667df75c6eca8cba63880d0 Mon Sep 17 00:00:00 2001 From: GitVivekHub Date: Wed, 17 Apr 2024 16:44:44 +0530 Subject: [PATCH 123/126] console.log commented --- src/src/userauth/userauth.service.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/src/userauth/userauth.service.ts b/src/src/userauth/userauth.service.ts index 43cf57645..f31812811 100644 --- a/src/src/userauth/userauth.service.ts +++ b/src/src/userauth/userauth.service.ts @@ -379,7 +379,7 @@ export class UserauthService { const base64String = `data:${fileType};base64,${base64Data}`; // Include the content type in the Base64 string return base64String; } catch (error) { - console.error('Error converting image to Base64:', error); + //console.error('Error converting image to Base64:', error); return null; } } @@ -1200,7 +1200,7 @@ export class UserauthService { update_id, ); - console.log('references result--->>', result1); + //console.log('references result--->>', result1); } if (result?.[tableName]?.extensions) { From 53a5b144f64db84b3f05ebf2ee159b182f4d796a Mon Sep 17 00:00:00 2001 From: Tusharmahajan12 <121154132+Tusharmahajan12@users.noreply.github.com> Date: Thu, 18 Apr 2024 09:40:37 +0530 Subject: [PATCH 124/126] [CR] Task #217406 [BE] Certification Changes (#1021) * Added time zone * Added time zone * Added time zone * Added time zone * Added time zone * Added validation in event edit * Added validation in event edit * Added validation in event edit * Added validation in event edit * remove attendense * Certification genration --- src/src/cron/prepareCertificateHtml.cron.ts | 66 ++- src/src/lms/certificate_html.ts | 505 ++++++++++++-------- 2 files changed, 360 insertions(+), 211 deletions(-) diff --git a/src/src/cron/prepareCertificateHtml.cron.ts b/src/src/cron/prepareCertificateHtml.cron.ts index 249d20f31..961c727e9 100644 --- a/src/src/cron/prepareCertificateHtml.cron.ts +++ b/src/src/cron/prepareCertificateHtml.cron.ts @@ -26,6 +26,7 @@ export class PrepareCertificateHtmlCron { @Cron(CronExpression.EVERY_5_MINUTES) async prepareCertificateHtml() { console.log('cron job: issueCertificate started at time ' + new Date()); + //fetch all test tracking data which has certificate_status null const userForIssueCertificate = await this.fetchTestTrackingData( parseInt( @@ -48,25 +49,26 @@ export class PrepareCertificateHtmlCron { let test_id = userTestData?.test_id; let context = userTestData?.context; let context_id = userTestData?.context_id; - let getUserList = await this.userService.getUserName(user_id); - let user_name = ''; - if (getUserList.length > 0) { - user_name += getUserList[0]?.first_name - ? (await this.method.CapitalizeEachWord( - getUserList[0].first_name, - )) + ' ' - : ''; - user_name += getUserList[0]?.middle_name - ? (await this.method.CapitalizeEachWord( - getUserList[0].middle_name, - )) + ' ' - : ''; - user_name += getUserList[0]?.last_name - ? (await this.method.CapitalizeEachWord( - getUserList[0].last_name, - )) + ' ' - : ''; - } + + const user_name = await this.method.CapitalizeEachWord( + [ + userTestData?.user?.first_name, + userTestData?.user?.middle_name, + userTestData?.user?.last_name, + ] + .filter((e) => e) + .join(' '), + ); + + const event_start_date = moment( + userTestData?.events?.[0]?.start_date, + ).format('DD MMM YYYY'); + const event_end_date = moment( + userTestData?.events?.[0]?.end_date, + ).format('DD MMM YYYY'); + const academic_year = + userTestData?.events?.[0]?.academic_year?.name; + //get attendance status let attendance_valid = false; let usrAttendanceList = @@ -112,6 +114,18 @@ export class PrepareCertificateHtmlCron { let certificate_id = certificate_data?.id; let uid = 'P-' + certificate_id + '-' + user_id; //update html code + certificateTemplate = certificateTemplate.replace( + '{{academic_year}}', + academic_year, + ); + certificateTemplate = certificateTemplate.replace( + '{{event_start_date}}', + event_start_date, + ); + certificateTemplate = certificateTemplate.replace( + '{{event_end_date}}', + event_end_date, + ); certificateTemplate = certificateTemplate.replace( '{{name}}', user_name, @@ -247,6 +261,20 @@ export class PrepareCertificateHtmlCron { score context context_id + user{ + first_name + middle_name + last_name + } + events(where:{context:{_eq:"events"}}){ + id + start_date + end_date + academic_year{ + name + } + + } } } `; diff --git a/src/src/lms/certificate_html.ts b/src/src/lms/certificate_html.ts index aa1015e02..9c72c2e39 100644 --- a/src/src/lms/certificate_html.ts +++ b/src/src/lms/certificate_html.ts @@ -5,219 +5,340 @@ export const html_code = ` Certificate - - + +
-
+
-
+
-
-
-
यह प्रमाणित किया जाता है कि
+
+
+ +
+
+
+
सत्र   
+
{{academic_year}}
+
 के लिए
+
+
+
+
यह प्रमाणित किया जाता है कि
-
श्री / सुश्री   
{{name}}
-
ने प्रोजेक्ट प्रगति शिविर के संचालन हेतु आयोजित प्रशिक्षण में पूरे उत्साह और प्रतिबद्धता से
भाग लेकर आवश्यक ज्ञान एवं कौशल अर्जित किया है|
-
आपको प्रगति शिविर संचालन के लिए प्रेरक के रूप में प्रमाणित करते हुए हमें असीम हर्ष का अनुभव हो रहा है
-
प्रशिक्षण में अर्जित किए गए कौशल: -
-
-
- सीखने के सत्रों को सुगम बनाना +
+
श्री / सुश्री   
+
{{name}}
+
 ने
+
+
+
दिनांक :   
+
+ {{event_start_date}} +
+
 से 
+
+ {{event_end_date}}
-
- समस्या - समाधान +
 तक
+
+
+
+ 'प्रोजेक्ट प्रगति' के प्रशिक्षण को सफलतापूर्वक पूरा + किया है।
- सीखने में तकनीकी प्रयोग + इस प्रशिक्षण के दौरान आपने शिक्षा से वंचित शिक्षार्थियों की + पहचान, उनका मार्गदर्शन, दस्तावेजीकरण और
- -
- -
-
- पारस्परिक संबंध कौशल +
+ ओपन स्कूल के माध्यम से 10 वीं कक्षा में नामांकन की प्रक्रिया + के बारे में जानकारी प्राप्त की है।
-
- सामुदायिक प्रबंधन +
+ आपको 'प्रगति मोबिलाइजर' के रूप में प्रमाणित करते हुए + हमें असीम हर्ष का अनुभव हो रहा है। +
+
+
+
+ प्रशिक्षण में अर्जित किए गए कौशल: +
+
+
+
+
+ + समुदाय के साथ प्रभावी संवाद +
+
+ + शिक्षा से वंचित शिक्षार्थियों को मार्गदर्शन प्रदान करना +
-
- -
-
-
-
 
-
तिथि :  
{{issue_date}}
-
UID :  
{{user_id}}
-
-
- +
+
+ + समस्या समाधान +
+
+ + 10 वीं के नामांकन के लिए दस्तावेजीकरण की समझ +
+
+
-
- -
Safeena Hussain
-
(Founder and Board Member)
-
- -
-
-
-
- -
- +
+
+
 
+
+
दिनांक :  
+
+ {{issue_date}} +
+
+
+
UID :  
+
+ {{user_id}} +
+
+
+ * + यह प्रमाणपत्र सिर्फ प्रशिक्षण में भागीदारी के लिए दिया जा रहा + है। +
+
+
+ +
+
+
+ +
+
गीतिका टंडन हिगिंस
+
(एसोसिएट निदेशक, प्रोजेक्ट प्रगति)
+
+
+
+ +
+
-
- + `; From a644170fc440154f6b7a50d732fcfd9233477e74 Mon Sep 17 00:00:00 2001 From: Tusharmahajan12 <121154132+Tusharmahajan12@users.noreply.github.com> Date: Thu, 18 Apr 2024 10:24:32 +0530 Subject: [PATCH 125/126] Start date end date filter change (#1023) --- src/src/events/events.service.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/src/events/events.service.ts b/src/src/events/events.service.ts index 2ef4c47a2..6b159c6ab 100644 --- a/src/src/events/events.service.ts +++ b/src/src/events/events.service.ts @@ -301,11 +301,15 @@ export class EventsService { ); if (body?.start_date) { - filter.push(`start_date: {_eq:"${body?.start_date}"}`); + filter.push( + `start_date: {_gte:"${body?.start_date}",_lte:"${body?.start_date}"}`, + ); } if (body?.end_date) { - filter.push(`end_date: {_eq:"${body?.end_date}"}`); + filter.push( + `end_date: {_gte:"${body?.end_date}",_lte:"${body?.end_date}"}`, + ); } const allIpList = getIps?.data?.users.map((curr) => curr.id); From 6545d5068657382bd0e44a110444fefb41e1e05b Mon Sep 17 00:00:00 2001 From: Tusharmahajan12 <121154132+Tusharmahajan12@users.noreply.github.com> Date: Thu, 18 Apr 2024 16:41:38 +0530 Subject: [PATCH 126/126] Task #217406 [CR] [BE] Certification Changes and [BE] Task #217351 Event list displayed as per start date and end date (#1025) * Start date end date filter change * html file changes * change in cron --- .../attendances/attendances.core.service.ts | 11 +++- src/src/cron/prepareCertificateHtml.cron.ts | 47 ++++++++++---- src/src/events/events.service.ts | 32 ++-------- src/src/lms/certificate_html.ts | 64 +++++++++++-------- 4 files changed, 84 insertions(+), 70 deletions(-) diff --git a/src/src/attendances/attendances.core.service.ts b/src/src/attendances/attendances.core.service.ts index abd9c3c98..c69548b94 100644 --- a/src/src/attendances/attendances.core.service.ts +++ b/src/src/attendances/attendances.core.service.ts @@ -231,15 +231,22 @@ export class AttendancesCoreService { return result; } - async getUserAttendancePresentList(user_id, context, context_id) { + async getUserAttendancePresentList({ + user_id, + context, + context_id, + event_end_date, + event_start_date, + }) { const query = `query MyQuery { - attendance(where: {user_id: {_eq: ${user_id}}, context: {_eq: ${context}}, context_id: {_eq:${context_id}}, status: {_eq: "present"}}) { + attendance(where: {user_id: {_eq: ${user_id}}, context: {_eq: ${context}}, context_id: {_eq:${context_id}}, status: {_eq: "present"}, date_time: {_gte: "${event_start_date}", _lte: "${event_end_date}"}}, distinct_on: date_time) { id status context context_id } }`; + try { const result_response = await this.hasuraServiceFromServices.getData({ query }); diff --git a/src/src/cron/prepareCertificateHtml.cron.ts b/src/src/cron/prepareCertificateHtml.cron.ts index 961c727e9..b610ea63d 100644 --- a/src/src/cron/prepareCertificateHtml.cron.ts +++ b/src/src/cron/prepareCertificateHtml.cron.ts @@ -7,6 +7,7 @@ import { html_code } from 'src/lms/certificate_html'; import { LMSCertificateDto } from 'src/lms/dto/lms-certificate.dto'; import { UserService } from 'src/user/user.service'; import { HasuraService } from '../services/hasura/hasura.service'; +import { json } from 'stream/consumers'; const moment = require('moment'); const qr = require('qrcode'); @@ -71,21 +72,35 @@ export class PrepareCertificateHtmlCron { //get attendance status let attendance_valid = false; + const startMoment = moment( + userTestData?.events?.[0]?.start_date, + ); + const endMoment = moment(userTestData?.events?.[0]?.end_date); + let datesD = []; + while (startMoment.isSameOrBefore(endMoment)) { + datesD.push(startMoment.format('YYYY-MM-DD')); + startMoment.add(1, 'day'); + } + let usrAttendanceList = await this.attendanceCoreService.getUserAttendancePresentList( - user_id, - context, - context_id, + { + user_id, + context, + context_id, + event_start_date: `${userTestData?.events?.[0]?.start_date}T00:00:00`, + event_end_date: `${userTestData?.events?.[0]?.end_date}T23:59:59`, + }, ); + console.log('usrAttendanceList list', usrAttendanceList); - let minAttendance = parseInt( - this.configService.get( - 'LMS_CERTIFICATE_ISSUE_MIN_ATTENDANCE', - ), - ); + console.log('events-dates', JSON.stringify(datesD)); + let minAttendance = datesD.length; + if (usrAttendanceList.length >= minAttendance) { attendance_valid = true; } + //check certificate criteria if (userTestData?.score >= minPercentage && attendance_valid) { issue_status = 'true'; @@ -217,10 +232,19 @@ export class PrepareCertificateHtmlCron { if (issue_status == 'true') { testTrackingUpdateData['certificate_status'] = issue_status; } - await this.updateTestTrackingData( + const result = await this.updateTestTrackingData( userTestData?.id, testTrackingUpdateData, ); + if (issue_status === 'false') { + console.log( + `user_id ${user_id} name ${user_name} testID ${test_id} Not Genrated event date count ${minAttendance} attendance count ${usrAttendanceList.length}`, + ); + } else if (result) { + console.log( + `user_id ${user_id} name ${user_name} testID ${test_id} Certificate Genrated Sucssefully`, + ); + } } } } @@ -278,10 +302,9 @@ export class PrepareCertificateHtmlCron { } } `; - console.log('fetchTestTrackingData query', query); + try { const result_query = await this.hasuraService.getData({ query }); - console.log('result_query', result_query); const data_list = result_query?.data?.lms_test_tracking; if (data_list) { return data_list; @@ -382,8 +405,6 @@ export class PrepareCertificateHtmlCron { } } async updateTestTrackingData(id, testTrackingUpdateData) { - console.log('id', id); - console.log('testTrackingUpdateData', testTrackingUpdateData); let setQuery = ``; if (testTrackingUpdateData?.certificate_status) { setQuery += `certificate_status: ${testTrackingUpdateData.certificate_status}`; diff --git a/src/src/events/events.service.ts b/src/src/events/events.service.ts index 6b159c6ab..e0b564633 100644 --- a/src/src/events/events.service.ts +++ b/src/src/events/events.service.ts @@ -301,15 +301,13 @@ export class EventsService { ); if (body?.start_date) { - filter.push( - `start_date: {_gte:"${body?.start_date}",_lte:"${body?.start_date}"}`, - ); + filter.push(`start_date: {_gte:"${body?.start_date}"}`); } if (body?.end_date) { - filter.push( - `end_date: {_gte:"${body?.end_date}",_lte:"${body?.end_date}"}`, - ); + filter.push(`end_date: {_lte:"${body?.end_date}"}`); + } else if (body?.start_date) { + filter.push(`end_date: {_lte:"${body?.start_date}"}`); } const allIpList = getIps?.data?.users.map((curr) => curr.id); @@ -346,28 +344,6 @@ export class EventsService { created_by updated_by user_id - attendances { - context - context_id - created_by - date_time - id - lat - long - rsvp - status - updated_by - user_id - user { - first_name - id - last_name - middle_name - profile_url - aadhar_verified - aadhaar_verification_mode - } - } } }`, }; diff --git a/src/src/lms/certificate_html.ts b/src/src/lms/certificate_html.ts index 9c72c2e39..88e60000c 100644 --- a/src/src/lms/certificate_html.ts +++ b/src/src/lms/certificate_html.ts @@ -29,12 +29,12 @@ export const html_code = ` .font-600 { font-weight: 600; } - .font-size-13 { - font-size: 13px !important; - } .font-size-14 { font-size: 14px !important; } + .font-size-15 { + font-size: 15px !important; + } .center { padding: 20px; @@ -61,19 +61,17 @@ export const html_code = ` .px-10 { padding: 0 10px; } + .p-30 { + padding: 30px; + } body { - background-size: 100%; - height: 700px; + margin: 0; padding: 0; - margin: 0 auto; - font-size: 16px; - color: #5b5b5b; + background: #f2e4e1; } .color { background: #f2e4e1; -webkit-print-color-adjust: exact; - padding: 30px; - height: 200mm; } div { line-height: 1.8; @@ -100,11 +98,24 @@ export const html_code = ` font-weight: 700; background: #fff; /* Background color of the title */ } + .w-1140 { + min-width: 1140px !important; + } + .w-1080 { + width: 1080px !important; + } + .h-800 { + height: 800px !important; + } + .h-700 { + height: 700px !important; + } + .h-740 { + height: 740px !important; + } .bg-white { - width: 84%; margin: 0 auto; margin-top: 20px; - height: 675px; border-radius: 30px; background-color: #fff; background-repeat: repeat; @@ -118,8 +129,8 @@ export const html_code = ` width: 24.3%; float: left; } - .m-25px { - margin: -17px 7px; + .side-image { + margin: -17px 10px; } .pt-30 { padding-top: 30px; @@ -193,8 +204,8 @@ export const html_code = ` -
-
+
+
@@ -206,14 +217,14 @@ export const html_code = ` />
-
+
सत्र   
{{academic_year}}
 के लिए
-
यह प्रमाणित किया जाता है कि
+
यह प्रमाणित किया जाता है कि
श्री / सुश्री   
@@ -231,8 +242,8 @@ export const html_code = `
 तक
-
-
+
+
'प्रोजेक्ट प्रगति' के प्रशिक्षण को सफलतापूर्वक पूरा किया है।
@@ -251,12 +262,12 @@ export const html_code = `
- प्रशिक्षण में अर्जित किए गए कौशल:
-
+
-
+
-
+
 
दिनांक :  
@@ -316,7 +327,7 @@ export const html_code = ` width="100px" />
-
+