diff --git a/README.md b/README.md index 0aba9cf3..a7698cde 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,9 @@ AUTH0_AUDIENCE_UBAHN= AUTH0_CLIENT_ID= AUTH0_CLIENT_SECRET= - + # necessary if you'll utilize email functionality of interviews + INTERVIEW_INVITATION_SENDGRID_TEMPLATE_ID= + INTERVIEW_INVITATION_SENDER_EMAIL= # Locally deployed services (via docker-compose) ES_HOST=dockerhost:9200 DATABASE_URL=postgres://postgres:postgres@dockerhost:5432/postgres diff --git a/app-constants.js b/app-constants.js index 7ee4c5f5..534e46de 100644 --- a/app-constants.js +++ b/app-constants.js @@ -44,7 +44,30 @@ const Scopes = { READ_WORK_PERIOD_PAYMENT: 'read:taas-workPeriodPayments', CREATE_WORK_PERIOD_PAYMENT: 'create:taas-workPeriodPayments', UPDATE_WORK_PERIOD_PAYMENT: 'update:taas-workPeriodPayments', - ALL_WORK_PERIOD_PAYMENT: 'all:taas-workPeriodPayments' + ALL_WORK_PERIOD_PAYMENT: 'all:taas-workPeriodPayments', + // interview + READ_INTERVIEW: 'read:taas-interviews', + CREATE_INTERVIEW: 'create:taas-interviews', + UPDATE_INTERVIEW: 'update:taas-interviews', + ALL_INTERVIEW: 'all:taas-interviews' +} + +// Interview related constants +const Interviews = { + Status: { + Scheduling: 'Scheduling', + Scheduled: 'Scheduled', + RequestedForReschedule: 'Requested for reschedule', + Rescheduled: 'Rescheduled', + Completed: 'Completed', + Cancelled: 'Cancelled' + }, + // key: template name in x.ai, value: duration + XaiTemplate: { + 'interview-30': 30, + 'interview-60': 60 + }, + MaxAllowedCount: 3 } const ChallengeStatus = { @@ -62,6 +85,7 @@ module.exports = { UserRoles, FullManagePermissionRoles, Scopes, + Interviews, ChallengeStatus, PaymentProcessingSwitch } diff --git a/app.js b/app.js index fc52ee99..7f3d7d85 100644 --- a/app.js +++ b/app.js @@ -9,8 +9,10 @@ const express = require('express') const cors = require('cors') const HttpStatus = require('http-status-codes') const interceptor = require('express-interceptor') +const schedule = require('node-schedule') const logger = require('./src/common/logger') const eventHandlers = require('./src/eventHandlers') +const interviewService = require('./src/services/InterviewService') // setup express app const app = express() @@ -93,6 +95,8 @@ app.use((err, req, res, next) => { const server = app.listen(app.get('port'), () => { logger.info({ component: 'app', message: `Express server listening on port ${app.get('port')}` }) eventHandlers.init() + // schedule updateCompletedInterviews to run every hour + schedule.scheduleJob('0 0 * * * *', interviewService.updateCompletedInterviews) }) if (process.env.NODE_ENV === 'test') { diff --git a/config/default.js b/config/default.js index d959ba07..f7eddb93 100644 --- a/config/default.js +++ b/config/default.js @@ -126,6 +126,13 @@ module.exports = { TAAS_WORK_PERIOD_PAYMENT_UPDATE_TOPIC: process.env.TAAS_WORK_PERIOD_PAYMENT_UPDATE_TOPIC || 'taas.workperiodpayment.update', // the delete work period payment entity Kafka message topic TAAS_WORK_PERIOD_PAYMENT_DELETE_TOPIC: process.env.TAAS_WORK_PERIOD_PAYMENT_DELETE_TOPIC || 'taas.workperiodpayment.delete', + // topics for interview service + // the request interview Kafka message topic + TAAS_INTERVIEW_REQUEST_TOPIC: process.env.TAAS_INTERVIEW_REQUEST_TOPIC || 'taas.interview.requested', + // the interview update Kafka message topic + TAAS_INTERVIEW_UPDATE_TOPIC: process.env.TAAS_INTERVIEW_UPDATE_TOPIC || 'taas.interview.update', + // the interview bulk update Kafka message topic + TAAS_INTERVIEW_BULK_UPDATE_TOPIC: process.env.TAAS_INTERVIEW_BULK_UPDATE_TOPIC || 'taas.interview.bulkUpdate', // the Kafka message topic for sending email EMAIL_TOPIC: process.env.EMAIL_TOPIC || 'external.action.email', @@ -135,10 +142,20 @@ module.exports = { // the emails address for receiving the issue report // REPORT_ISSUE_EMAILS may contain comma-separated list of email which is converted to array REQUEST_EXTENSION_EMAILS: (process.env.REQUEST_EXTENSION_EMAILS || '').split(','), + // the emails address for interview invitation + // INTERVIEW_INVITATION_CC_LIST may contain comma-separated list of email which is converted to array + INTERVIEW_INVITATION_CC_LIST: (process.env.INTERVIEW_INVITATION_CC_LIST || '').split(','), + // INTERVIEW_INVITATION_RECIPIENTS_LIST may contain comma-separated list of email which is converted to array + // scheduler@x.ai should be in the RECIPIENTS list + INTERVIEW_INVITATION_RECIPIENTS_LIST: (process.env.INTERVIEW_INVITATION_RECIPIENTS_LIST || 'scheduler@topcoder.com').split(','), // SendGrid email template ID for reporting issue REPORT_ISSUE_SENDGRID_TEMPLATE_ID: process.env.REPORT_ISSUE_SENDGRID_TEMPLATE_ID, // SendGrid email template ID for requesting extension REQUEST_EXTENSION_SENDGRID_TEMPLATE_ID: process.env.REQUEST_EXTENSION_SENDGRID_TEMPLATE_ID, + // SendGrid email template ID for interview invitation + INTERVIEW_INVITATION_SENDGRID_TEMPLATE_ID: process.env.INTERVIEW_INVITATION_SENDGRID_TEMPLATE_ID, + // The sender (aka `from`) email for invitation. + INTERVIEW_INVITATION_SENDER_EMAIL: process.env.INTERVIEW_INVITATION_SENDER_EMAIL || 'talent@topcoder.com', // the URL where TaaS App is hosted TAAS_APP_URL: process.env.TAAS_APP_URL || 'https://platform.topcoder-dev.com/taas/myteams', // environment variables for Payment Service diff --git a/config/email_template.config.js b/config/email_template.config.js index bc2d803a..b7570a73 100644 --- a/config/email_template.config.js +++ b/config/email_template.config.js @@ -59,5 +59,44 @@ module.exports = { '{{text}}', recipients: config.REPORT_ISSUE_EMAILS, sendgridTemplateId: config.REQUEST_EXTENSION_SENDGRID_TEMPLATE_ID + }, + + /* Request interview for a job candidate + * + * - interviewType: the x.ai interview type. Example: "interview-30" + * - interviewRound: the round of the interview. Example: 2 + * - interviewDuration: duration of the interview, in minutes. Example: 30 + * - interviewerList: The list of interviewer email addresses. Example: "first@attendee.com, second@attendee.com" + * - candidateId: the id of the jobCandidate. Example: "cc562545-7b75-48bf-87e7-50b3c57e41b1" + * - candidateName: Full name of candidate. Example: "John Doe" + * - jobName: The title of the job. Example: "TaaS API Misc Updates" + * + * Template (defined in SendGrid): + * Subject: '{{interviewType}} tech interview with {{candidateName}} for {{jobName}} is requested by the Customer' + * Body: + * 'Hello! + *

+ * Congratulations, you have been selected to participate in a Topcoder Gig Work Interview! + *

+ * Please monitor your email for a response to this where you can coordinate your availability. + *

+ * Interviewee: {{candidateName}}
+ * Interviewer(s): {{interviewerList}}
+ * Interview Length: {{interviewDuration}} minutes + *

+ * /{{interviewType}} + *

+ * Topcoder Info:
+ * Note: "id: {{candidateId}}, round: {{interviewRound}}"' + * + * Note, that the template should be defined in SendGrid. + * The subject & body above (identical to actual SendGrid template) is for reference purposes. + * We won't pass subject & body but only substitutions (replacements in template subject/body). + */ + 'interview-invitation': { + from: config.INTERVIEW_INVITATION_SENDER_EMAIL, + cc: config.INTERVIEW_INVITATION_CC_LIST, + recipients: config.INTERVIEW_INVITATION_RECIPIENTS_LIST, + sendgridTemplateId: config.INTERVIEW_INVITATION_SENDGRID_TEMPLATE_ID } } diff --git a/data/demo-data.json b/data/demo-data.json index 78bfac23..5736c839 100644 --- a/data/demo-data.json +++ b/data/demo-data.json @@ -1 +1,2386 @@ -{"Job":[{"id":"b9887564-3d3d-4c70-8a7b-552576ef2e8d","projectId":111,"externalId":"0","description":"taas-demo-job1","title":"Demo Title","startDate":"2020-09-27T04:17:23.131Z","duration":null,"numPositions":13,"resourceType":"Dummy Resource Type","rateType":"weekly","workload":"full-time","skills":["ee4c50c1-c8c3-475e-b6b6-edbd136a19d6","89139c80-d0a2-47c2-aa16-14589d5afd10","9f2d9127-6a2e-4506-ad76-c4ab63577b09","9515e7ee-83b6-49d1-ba5c-6c59c5a8ef1b","c854ab55-5922-4be1-8ecc-b3bc1f8629af","8456002e-fa2d-44f0-b0e7-86b1c02b6e4c","114b4ec8-805e-4c60-b351-14a955a991a9","213408aa-f16f-46c8-bc57-9e569cee3f11","b37a48db-f775-4e4e-b403-8ad1d234cdea","99b930b5-1b91-4df1-8b17-d9307107bb51","6388a632-c3ad-4525-9a73-66a527c03672","23839f38-6f19-4de9-9d28-f020056bca73","289e42a3-23e9-49be-88e1-6deb93cd8c31","b403f209-63b5-42bc-9b5f-1564416640d8"],"status":"sourcing","isApplicationPageActive":false,"createdBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","updatedBy":null,"createdAt":"2021-01-28T19:36:33.409Z","updatedAt":"2021-03-30T19:11:05.033Z"},{"id":"a5b3bf94-a8bf-4c7e-b685-70a29a4d7d6e","projectId":111,"externalId":"0","description":"taas-demo-job2","title":"Dummy title - at most 64 characters","startDate":"2020-09-27T04:17:23.131Z","duration":null,"numPositions":7,"resourceType":"Dummy Resource Type","rateType":"weekly","workload":"full-time","skills":["213408aa-f16f-46c8-bc57-9e569cee3f11","b37a48db-f775-4e4e-b403-8ad1d234cdea","99b930b5-1b91-4df1-8b17-d9307107bb51","6388a632-c3ad-4525-9a73-66a527c03672","23839f38-6f19-4de9-9d28-f020056bca73","289e42a3-23e9-49be-88e1-6deb93cd8c31","b403f209-63b5-42bc-9b5f-1564416640d8"],"status":"in-review","isApplicationPageActive":false,"createdBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","updatedBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","createdAt":"2021-01-28T19:36:44.975Z","updatedAt":"2021-01-28T19:38:17.463Z"},{"id":"2d5e2a52-e0dd-4cd9-8f4c-7cffa43951d0","projectId":111,"externalId":"0","description":"taas-demo-job3","title":"Dummy title - at most 64 characters","startDate":"2020-09-27T04:17:23.131Z","duration":null,"numPositions":7,"resourceType":"Dummy Resource Type","rateType":"weekly","workload":"full-time","skills":[],"status":"assigned","isApplicationPageActive":false,"createdBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","updatedBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","createdAt":"2021-01-28T19:38:23.739Z","updatedAt":"2021-01-28T19:41:10.607Z"},{"id":"84b73f90-0fef-4507-887a-074578e5ef38","projectId":111,"externalId":"0","description":"taas-demo-job4","title":"Dummy title - at most 64 characters","startDate":"2020-09-27T04:17:23.131Z","duration":null,"numPositions":7,"resourceType":"Dummy Resource Type","rateType":"weekly","workload":"full-time","skills":["8456002e-fa2d-44f0-b0e7-86b1c02b6e4c","114b4ec8-805e-4c60-b351-14a955a991a9","213408aa-f16f-46c8-bc57-9e569cee3f11","b37a48db-f775-4e4e-b403-8ad1d234cdea","99b930b5-1b91-4df1-8b17-d9307107bb51","6388a632-c3ad-4525-9a73-66a527c03672"],"status":"closed","isApplicationPageActive":false,"createdBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","updatedBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","createdAt":"2021-01-28T19:41:21.892Z","updatedAt":"2021-01-28T19:41:28.849Z"},{"id":"62399aa0-b088-41fe-9e9b-0c8071f1934f","projectId":111,"externalId":"0","description":"taas-demo-job5","title":"Dummy title - at most 64 characters","startDate":"2020-09-27T04:17:23.131Z","duration":null,"numPositions":7,"resourceType":"Dummy Resource Type","rateType":"weekly","workload":"full-time","skills":["b37a48db-f775-4e4e-b403-8ad1d234cdea","99b930b5-1b91-4df1-8b17-d9307107bb51","6388a632-c3ad-4525-9a73-66a527c03672"],"status":"cancelled","isApplicationPageActive":false,"createdBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","updatedBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","createdAt":"2021-01-28T19:41:35.098Z","updatedAt":"2021-01-28T19:41:42.124Z"}],"JobCandidate":[{"id":"debadcd8-64bf-4ab8-9cdb-297479eef6f5","jobId":"a5b3bf94-a8bf-4c7e-b685-70a29a4d7d6e","userId":"4dfc6090-4ba8-4387-b5c4-584fcef982ba","status":"open","externalId":null,"resume":null,"createdBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","updatedBy":null,"createdAt":"2021-01-28T19:37:05.723Z","updatedAt":"2021-03-30T19:11:05.043Z"},{"id":"7ff45b8f-2b71-4510-b760-8dfa62e79504","jobId":"a5b3bf94-a8bf-4c7e-b685-70a29a4d7d6e","userId":"243517dd-77d7-4f70-8951-0bc66da83076","status":"open","externalId":null,"resume":null,"createdBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","updatedBy":null,"createdAt":"2021-01-28T19:37:11.598Z","updatedAt":"2021-03-30T19:11:05.043Z"},{"id":"91d63d5f-01d5-419e-89df-6117ea92f535","jobId":"a5b3bf94-a8bf-4c7e-b685-70a29a4d7d6e","userId":"a2e28bf4-1147-41a6-a39f-e2509306f2a6","status":"open","externalId":null,"resume":null,"createdBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","updatedBy":null,"createdAt":"2021-01-28T19:37:18.066Z","updatedAt":"2021-03-30T19:11:05.043Z"},{"id":"257f98d9-45f7-4e13-a6c2-d7e7b6efc9fe","jobId":"a5b3bf94-a8bf-4c7e-b685-70a29a4d7d6e","userId":"b8649393-d32f-4b7f-a156-12e9776acb0e","status":"open","externalId":null,"resume":null,"createdBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","updatedBy":null,"createdAt":"2021-01-28T19:37:24.095Z","updatedAt":"2021-03-30T19:11:05.043Z"},{"id":"a01852d0-fa08-410c-b97b-67580ce62215","jobId":"a5b3bf94-a8bf-4c7e-b685-70a29a4d7d6e","userId":"a0a3a5ce-1de6-465d-91b2-518feb299851","status":"open","externalId":null,"resume":null,"createdBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","updatedBy":null,"createdAt":"2021-01-28T19:37:29.734Z","updatedAt":"2021-03-30T19:11:05.043Z"},{"id":"2fd7ca69-c8ec-4bf3-a7f3-655fbfe3e7df","jobId":"a5b3bf94-a8bf-4c7e-b685-70a29a4d7d6e","userId":"e6958d77-ffaf-4d24-9cdb-6391506695a4","status":"open","externalId":null,"resume":null,"createdBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","updatedBy":null,"createdAt":"2021-01-28T19:37:44.728Z","updatedAt":"2021-03-30T19:11:05.043Z"},{"id":"f0023058-2996-4bba-8c5f-d09a7023be38","jobId":"a5b3bf94-a8bf-4c7e-b685-70a29a4d7d6e","userId":"626bb327-e738-48e3-8f67-1fa2dc677d3c","status":"open","externalId":null,"resume":null,"createdBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","updatedBy":null,"createdAt":"2021-01-28T19:37:50.619Z","updatedAt":"2021-03-30T19:11:05.043Z"},{"id":"a189b34d-acde-4633-b18b-f7a34d7c5a74","jobId":"a5b3bf94-a8bf-4c7e-b685-70a29a4d7d6e","userId":"b49a0adb-1565-4de1-9189-a763c77f5ed4","status":"open","externalId":null,"resume":null,"createdBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","updatedBy":null,"createdAt":"2021-01-28T19:37:56.456Z","updatedAt":"2021-03-30T19:11:05.043Z"},{"id":"5191a860-4327-4c50-b76b-84beba04519b","jobId":"a5b3bf94-a8bf-4c7e-b685-70a29a4d7d6e","userId":"79ce2a3e-7679-48cf-8ac9-0a8ca4c4b463","status":"shortlist","externalId":null,"resume":null,"createdBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","updatedBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","createdAt":"2021-01-28T19:36:51.222Z","updatedAt":"2021-01-28T19:38:02.293Z"},{"id":"e6d9635c-b122-4f69-9285-09fb1ab30106","jobId":"a5b3bf94-a8bf-4c7e-b685-70a29a4d7d6e","userId":"98ec2c16-442e-4b61-8ad1-66123ee37d3c","status":"rejected","externalId":null,"resume":null,"createdBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","updatedBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","createdAt":"2021-01-28T19:36:58.774Z","updatedAt":"2021-01-28T19:38:13.553Z"},{"id":"f67b155e-0f09-4fdd-89a7-d79c5e46cac6","jobId":"2d5e2a52-e0dd-4cd9-8f4c-7cffa43951d0","userId":"05e988b7-7d54-4c10-ada1-1a04870a88a8","status":"open","externalId":null,"resume":null,"createdBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","updatedBy":null,"createdAt":"2021-01-28T19:38:38.332Z","updatedAt":"2021-03-30T19:11:05.043Z"},{"id":"8ffd33d3-4a43-4719-aee4-8e46be1d8f1c","jobId":"2d5e2a52-e0dd-4cd9-8f4c-7cffa43951d0","userId":"a2ffdeed-704d-4cf7-b70a-93fcf61de598","status":"open","externalId":null,"resume":null,"createdBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","updatedBy":null,"createdAt":"2021-01-28T19:38:43.967Z","updatedAt":"2021-03-30T19:11:05.043Z"},{"id":"2b8ba549-8878-43d6-ad5f-6a66e3b9d6c9","jobId":"2d5e2a52-e0dd-4cd9-8f4c-7cffa43951d0","userId":"4709473d-f060-4102-87f8-4d51ff0b34c1","status":"open","externalId":null,"resume":null,"createdBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","updatedBy":null,"createdAt":"2021-01-28T19:38:50.106Z","updatedAt":"2021-03-30T19:11:05.043Z"},{"id":"ae5a81ec-5d05-43c4-8253-847d91a54711","jobId":"2d5e2a52-e0dd-4cd9-8f4c-7cffa43951d0","userId":"39c7376e-2d5c-4601-bc47-6b60f505814d","status":"open","externalId":null,"resume":null,"createdBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","updatedBy":null,"createdAt":"2021-01-28T19:38:55.734Z","updatedAt":"2021-03-30T19:11:05.043Z"},{"id":"85d6649e-2682-4904-9480-a77b72fef27d","jobId":"2d5e2a52-e0dd-4cd9-8f4c-7cffa43951d0","userId":"213d2dd9-1fc3-4eda-ad97-2d56e2a84a1e","status":"selected","externalId":null,"resume":null,"createdBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","updatedBy":"00000000-0000-0000-0000-000000000000","createdAt":"2021-01-28T19:38:30.856Z","updatedAt":"2021-01-28T19:40:27.209Z"},{"id":"922dfce3-4e06-4387-9fdb-64f70675e86b","jobId":"2d5e2a52-e0dd-4cd9-8f4c-7cffa43951d0","userId":"dd5adacb-444d-4992-8b7b-0c349be598db","status":"selected","externalId":null,"resume":null,"createdBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","updatedBy":"00000000-0000-0000-0000-000000000000","createdAt":"2021-01-28T19:39:02.435Z","updatedAt":"2021-01-28T19:40:49.349Z"},{"id":"c26c38e2-a47d-405b-abc6-fe62a739561c","jobId":"2d5e2a52-e0dd-4cd9-8f4c-7cffa43951d0","userId":"6d0509c7-5f12-4d84-9a19-8e80ef7ddd66","status":"selected","externalId":null,"resume":null,"createdBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","updatedBy":"00000000-0000-0000-0000-000000000000","createdAt":"2021-01-28T19:39:08.233Z","updatedAt":"2021-01-28T19:40:53.659Z"},{"id":"7bef2b37-e1ee-4638-bfc1-c911787ac955","jobId":"2d5e2a52-e0dd-4cd9-8f4c-7cffa43951d0","userId":"f65e2104-2987-4136-839d-ee4632f0b2e5","status":"selected","externalId":null,"resume":null,"createdBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","updatedBy":"00000000-0000-0000-0000-000000000000","createdAt":"2021-01-28T19:39:13.469Z","updatedAt":"2021-01-28T19:40:57.999Z"},{"id":"e9716139-1f40-4bf1-9f8a-77ae4bcc621e","jobId":"2d5e2a52-e0dd-4cd9-8f4c-7cffa43951d0","userId":"e5e667ad-0950-43c2-8d1d-6e83ad7d1c7e","status":"selected","externalId":null,"resume":null,"createdBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","updatedBy":"00000000-0000-0000-0000-000000000000","createdAt":"2021-01-28T19:39:19.215Z","updatedAt":"2021-01-28T19:41:01.953Z"},{"id":"a1731d01-eac9-4eff-8e5a-8a3c99bc66e0","jobId":"2d5e2a52-e0dd-4cd9-8f4c-7cffa43951d0","userId":"bef43122-426b-4b2b-acdd-9b5b3bd1c0bf","status":"selected","externalId":null,"resume":null,"createdBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","updatedBy":"00000000-0000-0000-0000-000000000000","createdAt":"2021-01-28T19:39:24.625Z","updatedAt":"2021-01-28T19:41:06.370Z"}],"ResourceBooking":[{"id":"08f5e4b9-1088-496d-91a7-5b22a3583e3c","projectId":111,"userId":"213d2dd9-1fc3-4eda-ad97-2d56e2a84a1e","jobId":"2d5e2a52-e0dd-4cd9-8f4c-7cffa43951d0","status":"assigned","startDate":"2021-01-25","endDate":"2021-01-31","memberRate":1000,"customerRate":1200,"rateType":"weekly","createdBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","updatedBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","createdAt":"2021-01-28T19:39:30.052Z","updatedAt":"2021-01-28T19:40:25.260Z"},{"id":"7d967fed-9792-4768-98a7-0b644aa84f2e","projectId":111,"userId":"05e988b7-7d54-4c10-ada1-1a04870a88a8","jobId":"2d5e2a52-e0dd-4cd9-8f4c-7cffa43951d0","status":"in-review","startDate":"2021-03-25","endDate":"2021-05-31","memberRate":1000,"customerRate":1200,"rateType":"weekly","createdBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","updatedBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","createdAt":"2021-01-28T19:39:35.571Z","updatedAt":"2021-01-28T19:40:30.291Z"},{"id":"0a6799d7-f5d1-456b-8bf1-90619284b295","projectId":111,"userId":"6d0509c7-5f12-4d84-9a19-8e80ef7ddd66","jobId":"2d5e2a52-e0dd-4cd9-8f4c-7cffa43951d0","status":"assigned","startDate":"2021-02-27","endDate":"2021-03-15","memberRate":2000,"customerRate":2500,"rateType":"weekly","createdBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","updatedBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","createdAt":"2021-01-28T19:40:04.761Z","updatedAt":"2021-01-28T19:40:52.303Z"},{"id":"35e1abd8-1890-4664-bb52-aade382d7b66","projectId":111,"userId":"a2ffdeed-704d-4cf7-b70a-93fcf61de598","jobId":"2d5e2a52-e0dd-4cd9-8f4c-7cffa43951d0","status":"closed","startDate":"2021-02-25","endDate":"2021-04-01","memberRate":1000,"customerRate":1200,"rateType":"weekly","createdBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","updatedBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","createdAt":"2021-01-28T19:39:41.205Z","updatedAt":"2021-01-28T19:40:34.859Z"},{"id":"51b45f5d-5df2-46d5-9c3d-8a1323df38dd","projectId":111,"userId":"dd5adacb-444d-4992-8b7b-0c349be598db","jobId":"2d5e2a52-e0dd-4cd9-8f4c-7cffa43951d0","status":"assigned","startDate":"2021-03-18","endDate":"2021-05-28","memberRate":800,"customerRate":1000,"rateType":"weekly","createdBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","updatedBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","createdAt":"2021-01-28T19:39:59.432Z","updatedAt":"2021-01-28T19:40:47.743Z"},{"id":"61f5d474-e41f-490b-ab58-9f983e3d4916","projectId":111,"userId":"f65e2104-2987-4136-839d-ee4632f0b2e5","jobId":"2d5e2a52-e0dd-4cd9-8f4c-7cffa43951d0","status":"assigned","startDate":"2000-03-27","endDate":"2000-04-28","memberRate":3000,"customerRate":3500,"rateType":"weekly","createdBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","updatedBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","createdAt":"2021-01-28T19:40:09.879Z","updatedAt":"2021-01-28T19:40:56.381Z"},{"id":"8173579e-4b3c-418d-a9a1-c999caa38404","projectId":111,"userId":"bef43122-426b-4b2b-acdd-9b5b3bd1c0bf","jobId":"2d5e2a52-e0dd-4cd9-8f4c-7cffa43951d0","status":"assigned","startDate":"2020-04-27","endDate":"2020-05-27","memberRate":0,"customerRate":0,"rateType":"weekly","createdBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","updatedBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","createdAt":"2021-01-28T19:40:20.627Z","updatedAt":"2021-01-28T19:41:04.919Z"},{"id":"a098e8d8-ce5b-47d9-afee-38b050d16745","projectId":111,"userId":"4709473d-f060-4102-87f8-4d51ff0b34c1","jobId":"2d5e2a52-e0dd-4cd9-8f4c-7cffa43951d0","status":"cancelled","startDate":"2021-04-25","endDate":"2021-05-01","memberRate":1000,"customerRate":1200,"rateType":"weekly","createdBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","updatedBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","createdAt":"2021-01-28T19:39:46.515Z","updatedAt":"2021-01-28T19:40:38.820Z"},{"id":"d38a6223-3f91-4300-9ecb-6e5fee173625","projectId":111,"userId":"39c7376e-2d5c-4601-bc47-6b60f505814d","jobId":"2d5e2a52-e0dd-4cd9-8f4c-7cffa43951d0","status":"sourcing","startDate":"2021-05-25","endDate":"2021-07-31","memberRate":1000,"customerRate":1200,"rateType":"weekly","createdBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","updatedBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","createdAt":"2021-01-28T19:39:52.063Z","updatedAt":"2021-01-28T19:40:43.021Z"},{"id":"dc4477ec-07f8-4c8e-a8fe-ffe38dd290fa","projectId":111,"userId":"e5e667ad-0950-43c2-8d1d-6e83ad7d1c7e","jobId":"2d5e2a52-e0dd-4cd9-8f4c-7cffa43951d0","status":"assigned","startDate":"2021-07-27","endDate":"2021-09-27","memberRate":1700,"customerRate":1900,"rateType":"weekly","createdBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","updatedBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","createdAt":"2021-01-28T19:40:15.326Z","updatedAt":"2021-01-28T19:41:00.503Z"}],"WorkPeriod":[{"id":"07783b60-b726-41c2-8955-7766a27c1ec5","resourceBookingId":"7d967fed-9792-4768-98a7-0b644aa84f2e","userHandle":"sachin-wipro","projectId":111,"startDate":"2021-03-21","endDate":"2021-03-27","daysWorked":2,"memberRate":4.8,"customerRate":4.95,"paymentStatus":"pending","createdBy":"00000000-0000-0000-0000-000000000000","updatedBy":null,"createdAt":"2021-04-21T20:24:52.705Z","updatedAt":null},{"id":"6ed667a5-275e-4f27-984b-34dff5f8a1ff","resourceBookingId":"dc4477ec-07f8-4c8e-a8fe-ffe38dd290fa","userHandle":"nskumar278","projectId":111,"startDate":"2021-08-01","endDate":"2021-08-07","daysWorked":5,"memberRate":25.21,"customerRate":10.05,"paymentStatus":"pending","createdBy":"00000000-0000-0000-0000-000000000000","updatedBy":null,"createdAt":"2021-04-21T20:24:52.703Z","updatedAt":null},{"id":"d049e7bc-c827-482b-9ec6-b87d9289d1cd","resourceBookingId":"8173579e-4b3c-418d-a9a1-c999caa38404","userHandle":"testcat","projectId":111,"startDate":"2020-05-24","endDate":"2020-05-30","daysWorked":3,"memberRate":24.46,"customerRate":18.76,"paymentStatus":"pending","createdBy":"00000000-0000-0000-0000-000000000000","updatedBy":null,"createdAt":"2021-04-21T20:24:52.806Z","updatedAt":null},{"id":"1b633124-f62c-4026-b679-213cf5812689","resourceBookingId":"51b45f5d-5df2-46d5-9c3d-8a1323df38dd","userHandle":"amy_admin","projectId":111,"startDate":"2021-03-28","endDate":"2021-04-03","daysWorked":5,"memberRate":23.35,"customerRate":18.76,"paymentStatus":"pending","createdBy":"00000000-0000-0000-0000-000000000000","updatedBy":null,"createdAt":"2021-04-21T20:24:52.704Z","updatedAt":null},{"id":"30c89d78-df85-44ed-92b2-b683d8960fc2","resourceBookingId":"51b45f5d-5df2-46d5-9c3d-8a1323df38dd","userHandle":"amy_admin","projectId":111,"startDate":"2021-04-04","endDate":"2021-04-10","daysWorked":5,"memberRate":3.96,"customerRate":4.95,"paymentStatus":"pending","createdBy":"00000000-0000-0000-0000-000000000000","updatedBy":null,"createdAt":"2021-04-21T20:24:52.704Z","updatedAt":null},{"id":"531754f3-405e-42eb-932a-c1ce7b9386e7","resourceBookingId":"35e1abd8-1890-4664-bb52-aade382d7b66","userHandle":"lakshmiaconnmgr","projectId":111,"startDate":"2021-02-28","endDate":"2021-03-06","daysWorked":5,"memberRate":3.62,"customerRate":10.05,"paymentStatus":"pending","createdBy":"00000000-0000-0000-0000-000000000000","updatedBy":null,"createdAt":"2021-04-21T20:24:52.695Z","updatedAt":null},{"id":"442b0543-e887-42be-9ff5-5fee825526be","resourceBookingId":"0a6799d7-f5d1-456b-8bf1-90619284b295","userHandle":"aaaa","projectId":111,"startDate":"2021-03-14","endDate":"2021-03-20","daysWorked":1,"memberRate":23.81,"customerRate":15.49,"paymentStatus":"pending","createdBy":"00000000-0000-0000-0000-000000000000","updatedBy":null,"createdAt":"2021-04-21T20:24:52.694Z","updatedAt":null},{"id":"18a73600-5ee8-484b-9747-70ea80ce2bd9","resourceBookingId":"7d967fed-9792-4768-98a7-0b644aa84f2e","userHandle":"sachin-wipro","projectId":111,"startDate":"2021-05-16","endDate":"2021-05-22","daysWorked":5,"memberRate":28.76,"customerRate":25.9,"paymentStatus":"completed","createdBy":"00000000-0000-0000-0000-000000000000","updatedBy":null,"createdAt":"2021-04-21T20:24:52.705Z","updatedAt":null},{"id":"5392acee-b504-4720-95fa-dab585acb607","resourceBookingId":"0a6799d7-f5d1-456b-8bf1-90619284b295","userHandle":"aaaa","projectId":111,"startDate":"2021-03-07","endDate":"2021-03-13","daysWorked":5,"memberRate":14.77,"customerRate":26.72,"paymentStatus":"pending","createdBy":"00000000-0000-0000-0000-000000000000","updatedBy":null,"createdAt":"2021-04-21T20:24:52.693Z","updatedAt":null},{"id":"1bbc86c8-8c74-4d78-9706-25c4c99721f3","resourceBookingId":"35e1abd8-1890-4664-bb52-aade382d7b66","userHandle":"lakshmiaconnmgr","projectId":111,"startDate":"2021-03-21","endDate":"2021-03-27","daysWorked":5,"memberRate":3.62,"customerRate":25.9,"paymentStatus":"pending","createdBy":"00000000-0000-0000-0000-000000000000","updatedBy":null,"createdAt":"2021-04-21T20:24:52.695Z","updatedAt":null},{"id":"8b7b49de-29b1-4a0c-bb67-e70cc700fcfd","resourceBookingId":"51b45f5d-5df2-46d5-9c3d-8a1323df38dd","userHandle":"amy_admin","projectId":111,"startDate":"2021-04-25","endDate":"2021-05-01","daysWorked":5,"memberRate":24.68,"customerRate":23.15,"paymentStatus":"pending","createdBy":"00000000-0000-0000-0000-000000000000","updatedBy":null,"createdAt":"2021-04-21T20:24:52.704Z","updatedAt":null},{"id":"b8a8b558-0cb9-46d0-ba9d-2222f3fbdb63","resourceBookingId":"dc4477ec-07f8-4c8e-a8fe-ffe38dd290fa","userHandle":"nskumar278","projectId":111,"startDate":"2021-09-05","endDate":"2021-09-11","daysWorked":5,"memberRate":27.42,"customerRate":27.91,"paymentStatus":"pending","createdBy":"00000000-0000-0000-0000-000000000000","updatedBy":null,"createdAt":"2021-04-21T20:24:52.703Z","updatedAt":null},{"id":"f70509c0-baed-4ff1-8022-12441251f7af","resourceBookingId":"51b45f5d-5df2-46d5-9c3d-8a1323df38dd","userHandle":"amy_admin","projectId":111,"startDate":"2021-03-14","endDate":"2021-03-20","daysWorked":2,"memberRate":30.24,"customerRate":9.88,"paymentStatus":"pending","createdBy":"00000000-0000-0000-0000-000000000000","updatedBy":null,"createdAt":"2021-04-21T20:24:52.704Z","updatedAt":null},{"id":"da8abd64-2878-4e09-b3b1-41a27a0576d4","resourceBookingId":"dc4477ec-07f8-4c8e-a8fe-ffe38dd290fa","userHandle":"nskumar278","projectId":111,"startDate":"2021-09-12","endDate":"2021-09-18","daysWorked":5,"memberRate":16.86,"customerRate":4.05,"paymentStatus":"pending","createdBy":"00000000-0000-0000-0000-000000000000","updatedBy":null,"createdAt":"2021-04-21T20:24:52.703Z","updatedAt":null},{"id":"b5261ee2-bc4d-4c3a-9d30-6703bfdcfbc5","resourceBookingId":"51b45f5d-5df2-46d5-9c3d-8a1323df38dd","userHandle":"amy_admin","projectId":111,"startDate":"2021-05-23","endDate":"2021-05-29","daysWorked":5,"memberRate":24.68,"customerRate":27.91,"paymentStatus":"completed","createdBy":"00000000-0000-0000-0000-000000000000","updatedBy":null,"createdAt":"2021-04-21T20:24:52.704Z","updatedAt":null},{"id":"829165cb-0150-48e7-995c-f5b4d1a51d3b","resourceBookingId":"dc4477ec-07f8-4c8e-a8fe-ffe38dd290fa","userHandle":"nskumar278","projectId":111,"startDate":"2021-09-26","endDate":"2021-10-02","daysWorked":1,"memberRate":4.8,"customerRate":10.59,"paymentStatus":"pending","createdBy":"00000000-0000-0000-0000-000000000000","updatedBy":null,"createdAt":"2021-04-21T20:24:52.703Z","updatedAt":null},{"id":"2430fb35-826a-4e9f-8fb6-8dbcb035d505","resourceBookingId":"dc4477ec-07f8-4c8e-a8fe-ffe38dd290fa","userHandle":"nskumar278","projectId":111,"startDate":"2021-08-22","endDate":"2021-08-28","daysWorked":5,"memberRate":6.18,"customerRate":4.05,"paymentStatus":"pending","createdBy":"00000000-0000-0000-0000-000000000000","updatedBy":null,"createdAt":"2021-04-21T20:24:52.703Z","updatedAt":null},{"id":"c7ff2acc-a4c2-4e8b-a905-813dd9d1b293","resourceBookingId":"35e1abd8-1890-4664-bb52-aade382d7b66","userHandle":"lakshmiaconnmgr","projectId":111,"startDate":"2021-03-28","endDate":"2021-04-03","daysWorked":4,"memberRate":24.46,"customerRate":4.05,"paymentStatus":"pending","createdBy":"00000000-0000-0000-0000-000000000000","updatedBy":null,"createdAt":"2021-04-21T20:24:52.695Z","updatedAt":null},{"id":"731db5d7-bb79-45f4-b1b2-9f60d30f7966","resourceBookingId":"08f5e4b9-1088-496d-91a7-5b22a3583e3c","userHandle":"ritesh_cs","projectId":111,"startDate":"2021-01-31","endDate":"2021-02-06","daysWorked":0,"memberRate":27.42,"customerRate":4.4,"paymentStatus":"pending","createdBy":"00000000-0000-0000-0000-000000000000","updatedBy":null,"createdAt":"2021-04-21T20:24:52.775Z","updatedAt":null},{"id":"b682660e-488e-4033-aaf3-ef37248abc90","resourceBookingId":"0a6799d7-f5d1-456b-8bf1-90619284b295","userHandle":"aaaa","projectId":111,"startDate":"2021-02-21","endDate":"2021-02-27","daysWorked":0,"memberRate":24.46,"customerRate":2.55,"paymentStatus":"pending","createdBy":"00000000-0000-0000-0000-000000000000","updatedBy":null,"createdAt":"2021-04-21T20:24:52.693Z","updatedAt":null},{"id":"b4566e24-4fa8-4e82-9950-f62134bb00df","resourceBookingId":"dc4477ec-07f8-4c8e-a8fe-ffe38dd290fa","userHandle":"nskumar278","projectId":111,"startDate":"2021-08-29","endDate":"2021-09-04","daysWorked":5,"memberRate":4.8,"customerRate":4.4,"paymentStatus":"pending","createdBy":"00000000-0000-0000-0000-000000000000","updatedBy":null,"createdAt":"2021-04-21T20:24:52.703Z","updatedAt":null},{"id":"584c931b-da72-416e-a011-eac5fe34f42f","resourceBookingId":"dc4477ec-07f8-4c8e-a8fe-ffe38dd290fa","userHandle":"nskumar278","projectId":111,"startDate":"2021-07-25","endDate":"2021-07-31","daysWorked":4,"memberRate":14.77,"customerRate":4.4,"paymentStatus":"pending","createdBy":"00000000-0000-0000-0000-000000000000","updatedBy":null,"createdAt":"2021-04-21T20:24:52.703Z","updatedAt":null},{"id":"703bc625-9144-4a9f-a91b-445e171d8ea9","resourceBookingId":"dc4477ec-07f8-4c8e-a8fe-ffe38dd290fa","userHandle":"nskumar278","projectId":111,"startDate":"2021-09-19","endDate":"2021-09-25","daysWorked":5,"memberRate":27.42,"customerRate":5.77,"paymentStatus":"pending","createdBy":"00000000-0000-0000-0000-000000000000","updatedBy":null,"createdAt":"2021-04-21T20:24:52.703Z","updatedAt":null},{"id":"c9685cb2-9f4a-497e-ae99-deed7b16cc34","resourceBookingId":"35e1abd8-1890-4664-bb52-aade382d7b66","userHandle":"lakshmiaconnmgr","projectId":111,"startDate":"2021-03-07","endDate":"2021-03-13","daysWorked":5,"memberRate":14.77,"customerRate":16.55,"paymentStatus":"completed","createdBy":"00000000-0000-0000-0000-000000000000","updatedBy":null,"createdAt":"2021-04-21T20:24:52.695Z","updatedAt":null},{"id":"428fec88-b305-4816-b5ef-be2b4e91c21a","resourceBookingId":"7d967fed-9792-4768-98a7-0b644aa84f2e","userHandle":"sachin-wipro","projectId":111,"startDate":"2021-04-04","endDate":"2021-04-10","daysWorked":5,"memberRate":8.55,"customerRate":16.55,"paymentStatus":"pending","createdBy":"00000000-0000-0000-0000-000000000000","updatedBy":null,"createdAt":"2021-04-21T20:24:52.705Z","updatedAt":null},{"id":"374e2065-40cb-4651-a55c-81a0675dc00d","resourceBookingId":"8173579e-4b3c-418d-a9a1-c999caa38404","userHandle":"testcat","projectId":111,"startDate":"2020-05-17","endDate":"2020-05-23","daysWorked":5,"memberRate":16.86,"customerRate":1.89,"paymentStatus":"pending","createdBy":"00000000-0000-0000-0000-000000000000","updatedBy":null,"createdAt":"2021-04-21T20:24:52.806Z","updatedAt":null},{"id":"4bfdc253-e39a-4cfa-9a45-2cfc6e93cc6f","resourceBookingId":"61f5d474-e41f-490b-ab58-9f983e3d4916","userHandle":"sonu628","projectId":111,"startDate":"2000-04-16","endDate":"2000-04-22","daysWorked":5,"memberRate":20.16,"customerRate":13.92,"paymentStatus":"pending","createdBy":"00000000-0000-0000-0000-000000000000","updatedBy":null,"createdAt":"2021-04-21T20:24:52.858Z","updatedAt":null},{"id":"0ba1a0b3-7bee-4fe6-9083-d36d8ca9d052","resourceBookingId":"35e1abd8-1890-4664-bb52-aade382d7b66","userHandle":"lakshmiaconnmgr","projectId":111,"startDate":"2021-03-14","endDate":"2021-03-20","daysWorked":5,"memberRate":24.46,"customerRate":1.44,"paymentStatus":"pending","createdBy":"00000000-0000-0000-0000-000000000000","updatedBy":null,"createdAt":"2021-04-21T20:24:52.695Z","updatedAt":null},{"id":"6da7d347-7492-43b1-a49d-8a6e1daf9b22","resourceBookingId":"51b45f5d-5df2-46d5-9c3d-8a1323df38dd","userHandle":"amy_admin","projectId":111,"startDate":"2021-04-18","endDate":"2021-04-24","daysWorked":5,"memberRate":25.21,"customerRate":1.44,"paymentStatus":"pending","createdBy":"00000000-0000-0000-0000-000000000000","updatedBy":null,"createdAt":"2021-04-21T20:24:52.704Z","updatedAt":null},{"id":"8c8cedf3-0bb6-4063-8a3a-faf1626da384","resourceBookingId":"61f5d474-e41f-490b-ab58-9f983e3d4916","userHandle":"sonu628","projectId":111,"startDate":"2000-04-09","endDate":"2000-04-15","daysWorked":5,"memberRate":14.77,"customerRate":4.95,"paymentStatus":"pending","createdBy":"00000000-0000-0000-0000-000000000000","updatedBy":null,"createdAt":"2021-04-21T20:24:52.858Z","updatedAt":null},{"id":"10394696-47f4-4761-8d14-ffdf012cde23","resourceBookingId":"d38a6223-3f91-4300-9ecb-6e5fee173625","userHandle":"nithyaasworld","projectId":111,"startDate":"2021-07-25","endDate":"2021-07-31","daysWorked":5,"memberRate":3.62,"customerRate":4.95,"paymentStatus":"pending","createdBy":"00000000-0000-0000-0000-000000000000","updatedBy":null,"createdAt":"2021-04-21T20:24:52.706Z","updatedAt":null},{"id":"64de2244-6fcf-45ac-8a89-a9b3420e4476","resourceBookingId":"7d967fed-9792-4768-98a7-0b644aa84f2e","userHandle":"sachin-wipro","projectId":111,"startDate":"2021-04-18","endDate":"2021-04-24","daysWorked":5,"memberRate":22.57,"customerRate":18.23,"paymentStatus":"pending","createdBy":"00000000-0000-0000-0000-000000000000","updatedBy":null,"createdAt":"2021-04-21T20:24:52.705Z","updatedAt":null},{"id":"2cbe3836-5961-4d58-b8f7-44b84ddf3fc5","resourceBookingId":"7d967fed-9792-4768-98a7-0b644aa84f2e","userHandle":"sachin-wipro","projectId":111,"startDate":"2021-04-11","endDate":"2021-04-17","daysWorked":5,"memberRate":25.21,"customerRate":2.64,"paymentStatus":"pending","createdBy":"00000000-0000-0000-0000-000000000000","updatedBy":null,"createdAt":"2021-04-21T20:24:52.705Z","updatedAt":null},{"id":"bc8611f0-4ac2-49b2-b776-59ed2b759d1d","resourceBookingId":"d38a6223-3f91-4300-9ecb-6e5fee173625","userHandle":"nithyaasworld","projectId":111,"startDate":"2021-07-04","endDate":"2021-07-10","daysWorked":5,"memberRate":16.86,"customerRate":5.77,"paymentStatus":"pending","createdBy":"00000000-0000-0000-0000-000000000000","updatedBy":null,"createdAt":"2021-04-21T20:24:52.706Z","updatedAt":null},{"id":"9b6fc85b-3694-4e6c-9ebf-fe9ccf7881ba","resourceBookingId":"d38a6223-3f91-4300-9ecb-6e5fee173625","userHandle":"nithyaasworld","projectId":111,"startDate":"2021-06-13","endDate":"2021-06-19","daysWorked":5,"memberRate":14.77,"customerRate":15.86,"paymentStatus":"pending","createdBy":"00000000-0000-0000-0000-000000000000","updatedBy":null,"createdAt":"2021-04-21T20:24:52.706Z","updatedAt":null},{"id":"4a2c581f-c626-44cb-8ada-58f0172e8b4d","resourceBookingId":"d38a6223-3f91-4300-9ecb-6e5fee173625","userHandle":"nithyaasworld","projectId":111,"startDate":"2021-05-30","endDate":"2021-06-05","daysWorked":5,"memberRate":28.76,"customerRate":15.49,"paymentStatus":"pending","createdBy":"00000000-0000-0000-0000-000000000000","updatedBy":null,"createdAt":"2021-04-21T20:24:52.706Z","updatedAt":null},{"id":"90d99323-ba57-4a18-b50f-78f387033c70","resourceBookingId":"61f5d474-e41f-490b-ab58-9f983e3d4916","userHandle":"sonu628","projectId":111,"startDate":"2000-04-02","endDate":"2000-04-08","daysWorked":5,"memberRate":24.46,"customerRate":25.9,"paymentStatus":"completed","createdBy":"00000000-0000-0000-0000-000000000000","updatedBy":null,"createdAt":"2021-04-21T20:24:52.858Z","updatedAt":null},{"id":"5ddc132b-3205-45e3-bfe9-f1a4f939885e","resourceBookingId":"51b45f5d-5df2-46d5-9c3d-8a1323df38dd","userHandle":"amy_admin","projectId":111,"startDate":"2021-03-21","endDate":"2021-03-27","daysWorked":5,"memberRate":21.53,"customerRate":25.9,"paymentStatus":"completed","createdBy":"00000000-0000-0000-0000-000000000000","updatedBy":null,"createdAt":"2021-04-21T20:24:52.704Z","updatedAt":null},{"id":"437d4281-43ec-4de3-85e4-51d298388ce5","resourceBookingId":"0a6799d7-f5d1-456b-8bf1-90619284b295","userHandle":"aaaa","projectId":111,"startDate":"2021-02-28","endDate":"2021-03-06","daysWorked":5,"memberRate":26.19,"customerRate":28.03,"paymentStatus":"completed","createdBy":"00000000-0000-0000-0000-000000000000","updatedBy":null,"createdAt":"2021-04-21T20:24:52.693Z","updatedAt":null},{"id":"a35bb205-361b-4b2d-9828-55501ae9d190","resourceBookingId":"d38a6223-3f91-4300-9ecb-6e5fee173625","userHandle":"nithyaasworld","projectId":111,"startDate":"2021-07-11","endDate":"2021-07-17","daysWorked":5,"memberRate":27.42,"customerRate":28.03,"paymentStatus":"pending","createdBy":"00000000-0000-0000-0000-000000000000","updatedBy":null,"createdAt":"2021-04-21T20:24:52.706Z","updatedAt":null},{"id":"40ae1e8f-24be-4b51-885c-51f08e15f0df","resourceBookingId":"08f5e4b9-1088-496d-91a7-5b22a3583e3c","userHandle":"ritesh_cs","projectId":111,"startDate":"2021-01-24","endDate":"2021-01-30","daysWorked":5,"memberRate":16.86,"customerRate":28.03,"paymentStatus":"pending","createdBy":"00000000-0000-0000-0000-000000000000","updatedBy":null,"createdAt":"2021-04-21T20:24:52.775Z","updatedAt":null},{"id":"e19bddc5-38ac-43c9-8273-bc9069de26b3","resourceBookingId":"61f5d474-e41f-490b-ab58-9f983e3d4916","userHandle":"sonu628","projectId":111,"startDate":"2000-04-23","endDate":"2000-04-29","daysWorked":5,"memberRate":6.18,"customerRate":9.12,"paymentStatus":"pending","createdBy":"00000000-0000-0000-0000-000000000000","updatedBy":null,"createdAt":"2021-04-21T20:24:52.858Z","updatedAt":null},{"id":"bf61dad8-841a-4913-93f6-b2ae516b8b11","resourceBookingId":"d38a6223-3f91-4300-9ecb-6e5fee173625","userHandle":"nithyaasworld","projectId":111,"startDate":"2021-06-06","endDate":"2021-06-12","daysWorked":5,"memberRate":6.18,"customerRate":4.4,"paymentStatus":"pending","createdBy":"00000000-0000-0000-0000-000000000000","updatedBy":null,"createdAt":"2021-04-21T20:24:52.706Z","updatedAt":null},{"id":"93b0f03b-219b-41d5-bb1e-f125651b1b0e","resourceBookingId":"8173579e-4b3c-418d-a9a1-c999caa38404","userHandle":"testcat","projectId":111,"startDate":"2020-05-03","endDate":"2020-05-09","daysWorked":5,"memberRate":24.46,"customerRate":1.89,"paymentStatus":"pending","createdBy":"00000000-0000-0000-0000-000000000000","updatedBy":null,"createdAt":"2021-04-21T20:24:52.806Z","updatedAt":null},{"id":"93e69f99-cb1c-418e-aa41-ab2181b4bcfd","resourceBookingId":"d38a6223-3f91-4300-9ecb-6e5fee173625","userHandle":"nithyaasworld","projectId":111,"startDate":"2021-06-27","endDate":"2021-07-03","daysWorked":5,"memberRate":17.2,"customerRate":13.92,"paymentStatus":"pending","createdBy":"00000000-0000-0000-0000-000000000000","updatedBy":null,"createdAt":"2021-04-21T20:24:52.706Z","updatedAt":null},{"id":"619a0835-730f-47ec-820e-3959821aec51","resourceBookingId":"7d967fed-9792-4768-98a7-0b644aa84f2e","userHandle":"sachin-wipro","projectId":111,"startDate":"2021-05-30","endDate":"2021-06-05","daysWorked":1,"memberRate":4.8,"customerRate":13.92,"paymentStatus":"pending","createdBy":"00000000-0000-0000-0000-000000000000","updatedBy":null,"createdAt":"2021-04-21T20:24:52.705Z","updatedAt":null},{"id":"558b4685-4932-492e-99e1-2830c10f8275","resourceBookingId":"7d967fed-9792-4768-98a7-0b644aa84f2e","userHandle":"sachin-wipro","projectId":111,"startDate":"2021-04-25","endDate":"2021-05-01","daysWorked":5,"memberRate":4.8,"customerRate":13.92,"paymentStatus":"pending","createdBy":"00000000-0000-0000-0000-000000000000","updatedBy":null,"createdAt":"2021-04-21T20:24:52.705Z","updatedAt":null},{"id":"84431dac-019d-4987-9817-15f5f000d2db","resourceBookingId":"61f5d474-e41f-490b-ab58-9f983e3d4916","userHandle":"sonu628","projectId":111,"startDate":"2000-03-26","endDate":"2000-04-01","daysWorked":5,"memberRate":27.42,"customerRate":4.05,"paymentStatus":"partially-completed","createdBy":"00000000-0000-0000-0000-000000000000","updatedBy":null,"createdAt":"2021-04-21T20:24:52.858Z","updatedAt":null},{"id":"f575df2d-f170-4251-9042-b17ca5e99ca5","resourceBookingId":"51b45f5d-5df2-46d5-9c3d-8a1323df38dd","userHandle":"amy_admin","projectId":111,"startDate":"2021-05-02","endDate":"2021-05-08","daysWorked":5,"memberRate":4.82,"customerRate":4.05,"paymentStatus":"completed","createdBy":"00000000-0000-0000-0000-000000000000","updatedBy":null,"createdAt":"2021-04-21T20:24:52.704Z","updatedAt":null},{"id":"3829c216-ef3f-466c-93da-3a88a961442f","resourceBookingId":"51b45f5d-5df2-46d5-9c3d-8a1323df38dd","userHandle":"amy_admin","projectId":111,"startDate":"2021-05-09","endDate":"2021-05-15","daysWorked":5,"memberRate":6.18,"customerRate":4.4,"paymentStatus":"cancelled","createdBy":"00000000-0000-0000-0000-000000000000","updatedBy":null,"createdAt":"2021-04-21T20:24:52.704Z","updatedAt":null},{"id":"bd54bcaf-5278-467f-a166-865048774d0e","resourceBookingId":"a098e8d8-ce5b-47d9-afee-38b050d16745","userHandle":"TCConnCopilot","projectId":111,"startDate":"2021-04-25","endDate":"2021-05-01","daysWorked":5,"memberRate":16.86,"customerRate":1.89,"paymentStatus":"partially-completed","createdBy":"00000000-0000-0000-0000-000000000000","updatedBy":null,"createdAt":"2021-04-21T20:24:52.696Z","updatedAt":null},{"id":"7f8f3a25-b1d2-4e36-a543-fcaae57a32f5","resourceBookingId":"dc4477ec-07f8-4c8e-a8fe-ffe38dd290fa","userHandle":"nskumar278","projectId":111,"startDate":"2021-08-15","endDate":"2021-08-21","daysWorked":5,"memberRate":8.13,"customerRate":1.89,"paymentStatus":"cancelled","createdBy":"00000000-0000-0000-0000-000000000000","updatedBy":null,"createdAt":"2021-04-21T20:24:52.703Z","updatedAt":null},{"id":"6e1dc024-d437-4d9f-92e9-561db713a19a","resourceBookingId":"dc4477ec-07f8-4c8e-a8fe-ffe38dd290fa","userHandle":"nskumar278","projectId":111,"startDate":"2021-08-08","endDate":"2021-08-14","daysWorked":5,"memberRate":3.62,"customerRate":18.14,"paymentStatus":"partially-completed","createdBy":"00000000-0000-0000-0000-000000000000","updatedBy":null,"createdAt":"2021-04-21T20:24:52.703Z","updatedAt":null},{"id":"c5f6ae8f-2976-46d1-bd66-58eeb58ca045","resourceBookingId":"d38a6223-3f91-4300-9ecb-6e5fee173625","userHandle":"nithyaasworld","projectId":111,"startDate":"2021-06-20","endDate":"2021-06-26","daysWorked":5,"memberRate":25.41,"customerRate":13.92,"paymentStatus":"cancelled","createdBy":"00000000-0000-0000-0000-000000000000","updatedBy":null,"createdAt":"2021-04-21T20:24:52.706Z","updatedAt":null},{"id":"0f480aa7-1c5d-42fe-aad6-c774e58c2e17","resourceBookingId":"7d967fed-9792-4768-98a7-0b644aa84f2e","userHandle":"sachin-wipro","projectId":111,"startDate":"2021-05-09","endDate":"2021-05-15","daysWorked":5,"memberRate":4.82,"customerRate":4.95,"paymentStatus":"cancelled","createdBy":"00000000-0000-0000-0000-000000000000","updatedBy":null,"createdAt":"2021-04-21T20:24:52.705Z","updatedAt":null},{"id":"098ca553-6ea4-4cae-a18e-762f47e93d82","resourceBookingId":"51b45f5d-5df2-46d5-9c3d-8a1323df38dd","userHandle":"amy_admin","projectId":111,"startDate":"2021-05-16","endDate":"2021-05-22","daysWorked":5,"memberRate":3.96,"customerRate":4.95,"paymentStatus":"completed","createdBy":"00000000-0000-0000-0000-000000000000","updatedBy":null,"createdAt":"2021-04-21T20:24:52.704Z","updatedAt":null},{"id":"729a2396-2b33-4185-8ce8-d929dbf4a472","resourceBookingId":"7d967fed-9792-4768-98a7-0b644aa84f2e","userHandle":"sachin-wipro","projectId":111,"startDate":"2021-05-23","endDate":"2021-05-29","daysWorked":5,"memberRate":17.2,"customerRate":4.95,"paymentStatus":"completed","createdBy":"00000000-0000-0000-0000-000000000000","updatedBy":null,"createdAt":"2021-04-21T20:24:52.705Z","updatedAt":null},{"id":"9bfbd49a-e6bb-45c3-965d-ed4f95f0878a","resourceBookingId":"d38a6223-3f91-4300-9ecb-6e5fee173625","userHandle":"nithyaasworld","projectId":111,"startDate":"2021-07-18","endDate":"2021-07-24","daysWorked":5,"memberRate":23.35,"customerRate":5.77,"paymentStatus":"completed","createdBy":"00000000-0000-0000-0000-000000000000","updatedBy":null,"createdAt":"2021-04-21T20:24:52.706Z","updatedAt":null},{"id":"dcc310cf-ea4a-4637-9bf5-5baaabea67b3","resourceBookingId":"d38a6223-3f91-4300-9ecb-6e5fee173625","userHandle":"nithyaasworld","projectId":111,"startDate":"2021-05-23","endDate":"2021-05-29","daysWorked":4,"memberRate":14.77,"customerRate":1.44,"paymentStatus":"partially-completed","createdBy":"00000000-0000-0000-0000-000000000000","updatedBy":null,"createdAt":"2021-04-21T20:24:52.706Z","updatedAt":null},{"id":"309f65e8-b0b5-4cbb-ba60-9b36ccba4bd5","resourceBookingId":"51b45f5d-5df2-46d5-9c3d-8a1323df38dd","userHandle":"amy_admin","projectId":111,"startDate":"2021-04-11","endDate":"2021-04-17","daysWorked":5,"memberRate":14.77,"customerRate":15.49,"paymentStatus":"completed","createdBy":"00000000-0000-0000-0000-000000000000","updatedBy":null,"createdAt":"2021-04-21T20:24:52.704Z","updatedAt":null},{"id":"1e2c732e-ac1f-47ad-939b-22b2078124e5","resourceBookingId":"7d967fed-9792-4768-98a7-0b644aa84f2e","userHandle":"sachin-wipro","projectId":111,"startDate":"2021-03-28","endDate":"2021-04-03","daysWorked":5,"memberRate":17.2,"customerRate":15.49,"paymentStatus":"partially-completed","createdBy":"00000000-0000-0000-0000-000000000000","updatedBy":null,"createdAt":"2021-04-21T20:24:52.705Z","updatedAt":null},{"id":"2463003f-ee60-4aba-b989-b63babcd9b8b","resourceBookingId":"7d967fed-9792-4768-98a7-0b644aa84f2e","userHandle":"sachin-wipro","projectId":111,"startDate":"2021-05-02","endDate":"2021-05-08","daysWorked":5,"memberRate":4.8,"customerRate":15.49,"paymentStatus":"cancelled","createdBy":"00000000-0000-0000-0000-000000000000","updatedBy":null,"createdAt":"2021-04-21T20:24:52.705Z","updatedAt":null},{"id":"6a1180b8-38af-4bd0-8a5f-a60626e0bc95","resourceBookingId":"8173579e-4b3c-418d-a9a1-c999caa38404","userHandle":"testcat","projectId":111,"startDate":"2020-04-26","endDate":"2020-05-02","daysWorked":5,"memberRate":26.19,"customerRate":28.03,"paymentStatus":"completed","createdBy":"00000000-0000-0000-0000-000000000000","updatedBy":null,"createdAt":"2021-04-21T20:24:52.806Z","updatedAt":null},{"id":"b21f921a-4b23-423d-814b-d31f5cba7f64","resourceBookingId":"35e1abd8-1890-4664-bb52-aade382d7b66","userHandle":"lakshmiaconnmgr","projectId":111,"startDate":"2021-02-21","endDate":"2021-02-27","daysWorked":2,"memberRate":15.77,"customerRate":28.03,"paymentStatus":"partially-completed","createdBy":"00000000-0000-0000-0000-000000000000","updatedBy":null,"createdAt":"2021-04-21T20:24:52.695Z","updatedAt":null},{"id":"4db82b0b-4d6f-4e9a-b957-ab405b2c2df2","resourceBookingId":"8173579e-4b3c-418d-a9a1-c999caa38404","userHandle":"testcat","projectId":111,"startDate":"2020-05-10","endDate":"2020-05-16","daysWorked":5,"memberRate":24.46,"customerRate":28.03,"paymentStatus":"partially-completed","createdBy":"00000000-0000-0000-0000-000000000000","updatedBy":null,"createdAt":"2021-04-21T20:24:52.806Z","updatedAt":null}],"WorkPeriodPayment":[{"id":"2c488b36-0868-4db6-8978-20b1ce174496","workPeriodId":"07783b60-b726-41c2-8955-7766a27c1ec5","challengeId":"0de972b8-6cc9-4625-9760-1c77561c29e9","amount":200,"status":"completed","createdBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","updatedBy":null,"createdAt":"2021-04-14T19:13:23.714Z","updatedAt":"2021-04-21T20:19:56.934Z"},{"id":"d0f61c2d-271c-48b2-8416-50c1c32ad32b","workPeriodId":"098ca553-6ea4-4cae-a18e-762f47e93d82","challengeId":"aa8c1945-904c-42a7-9b00-1e4f9a49dcdb","amount":450,"status":"completed","createdBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","updatedBy":null,"createdAt":"2021-04-14T22:01:45.361Z","updatedAt":"2021-04-21T20:19:56.934Z"},{"id":"90bb43bd-d9e7-4eab-a46b-ab03338be11a","workPeriodId":"0ba1a0b3-7bee-4fe6-9083-d36d8ca9d052","challengeId":"8b6f4040-d7ae-4264-b60b-b1171c9365e4","amount":400,"status":"completed","createdBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","updatedBy":null,"createdAt":"2021-04-14T22:01:45.390Z","updatedAt":"2021-04-21T20:19:56.934Z"},{"id":"58681a3e-2266-4153-afd5-7be218966da2","workPeriodId":"0f480aa7-1c5d-42fe-aad6-c774e58c2e17","challengeId":"2bafdd9a-ab4a-4624-8a06-7b1adfb8dac2","amount":1200,"status":"completed","createdBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","updatedBy":null,"createdAt":"2021-04-14T22:01:45.326Z","updatedAt":"2021-04-21T20:19:56.934Z"},{"id":"b342d615-d36d-48b2-a3e8-1f498b58ab68","workPeriodId":"10394696-47f4-4761-8d14-ffdf012cde23","challengeId":"0de972b8-6cc9-4625-9760-1c77561c29e9","amount":400,"status":"completed","createdBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","updatedBy":null,"createdAt":"2021-04-16T19:13:23.714Z","updatedAt":"2021-04-21T20:19:56.934Z"},{"id":"63cec011-7714-4ab6-944f-e76b9fa2bd1a","workPeriodId":"18a73600-5ee8-484b-9747-70ea80ce2bd9","challengeId":"1bdf092e-e117-4d42-bb5d-e49816171c0d","amount":500,"status":"completed","createdBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","updatedBy":null,"createdAt":"2021-04-14T22:01:45.523Z","updatedAt":"2021-04-21T20:19:56.934Z"},{"id":"8a0c0877-b88a-420b-a3f7-645c18793b4b","workPeriodId":"1b633124-f62c-4026-b679-213cf5812689","challengeId":"4332acc6-3a33-4b7b-af4c-bd2c1ffcfb8e","amount":1400,"status":"completed","createdBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","updatedBy":null,"createdAt":"2021-04-14T22:01:45.325Z","updatedAt":"2021-04-21T20:19:56.934Z"},{"id":"04ef47ac-8f4d-402f-b9fd-48b2b1d9003d","workPeriodId":"1bbc86c8-8c74-4d78-9706-25c4c99721f3","challengeId":"fa909769-f5f7-41fb-94bb-80db62e21a5e","amount":800,"status":"cancelled","createdBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","updatedBy":null,"createdAt":"2021-04-14T22:01:45.326Z","updatedAt":"2021-04-21T20:19:56.934Z"},{"id":"84c1c956-e03d-4e19-a5a8-a4086c9658eb","workPeriodId":"1e2c732e-ac1f-47ad-939b-22b2078124e5","challengeId":"604910b2-7644-4b9d-a185-0054e61c83fc","amount":1800,"status":"completed","createdBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","updatedBy":null,"createdAt":"2021-04-14T22:01:45.324Z","updatedAt":"2021-04-21T20:19:56.934Z"},{"id":"c051c3da-34bb-4deb-8921-04e5d2fa0bcc","workPeriodId":"2430fb35-826a-4e9f-8fb6-8dbcb035d505","challengeId":"25fd805c-49cd-443f-ba0d-813c33a6d8ad","amount":400,"status":"completed","createdBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","updatedBy":null,"createdAt":"2021-04-14T22:01:45.390Z","updatedAt":"2021-04-21T20:19:56.934Z"},{"id":"cc13acfd-fc06-40e5-aefe-5050429ee4f2","workPeriodId":"2463003f-ee60-4aba-b989-b63babcd9b8b","challengeId":"0de972b8-6cc9-4625-9760-1c77561c29e9","amount":1200,"status":"completed","createdBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","updatedBy":null,"createdAt":"2021-04-14T19:13:23.714Z","updatedAt":"2021-04-21T20:19:56.934Z"},{"id":"58c6431a-061a-41bd-a3bd-c8effba62e11","workPeriodId":"2cbe3836-5961-4d58-b8f7-44b84ddf3fc5","challengeId":"0de972b8-6cc9-4625-9760-1c77561c29e9","amount":900,"status":"completed","createdBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","updatedBy":null,"createdAt":"2021-04-14T19:13:23.714Z","updatedAt":"2021-04-21T20:19:56.934Z"},{"id":"efe0e4b5-e6dd-4c1a-a0e5-1f5e0ff91df9","workPeriodId":"309f65e8-b0b5-4cbb-ba60-9b36ccba4bd5","challengeId":"01332fa9-0505-416d-9084-39b136dbd300","amount":1200,"status":"completed","createdBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","updatedBy":null,"createdAt":"2021-04-14T22:01:45.390Z","updatedAt":"2021-04-21T20:19:56.934Z"},{"id":"298ac627-e6d7-47b0-ad1d-83de291addf7","workPeriodId":"30c89d78-df85-44ed-92b2-b683d8960fc2","challengeId":"f7e40a0c-a302-4989-a3bd-7587fee3c367","amount":300,"status":"cancelled","createdBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","updatedBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","createdAt":"2021-04-14T19:13:23.714Z","updatedAt":"2021-04-16T19:13:23.714Z"},{"id":"bf80eca9-8323-4f96-9a3b-8553d6f1e0ce","workPeriodId":"374e2065-40cb-4651-a55c-81a0675dc00d","challengeId":"03c69d02-9188-436e-b4c9-08f39e46f413","amount":800,"status":"completed","createdBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","updatedBy":null,"createdAt":"2021-04-14T22:01:45.390Z","updatedAt":"2021-04-21T20:19:56.934Z"},{"id":"338d2d7d-2c59-4513-b560-55e8982fd7c7","workPeriodId":"3829c216-ef3f-466c-93da-3a88a961442f","challengeId":"2a0db660-def2-4117-90e8-01cd1271c726","amount":1400,"status":"completed","createdBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","updatedBy":null,"createdAt":"2021-04-14T22:01:45.390Z","updatedAt":"2021-04-21T20:19:56.934Z"},{"id":"491f6e93-e80f-46eb-9637-ee84fe7ace9b","workPeriodId":"40ae1e8f-24be-4b51-885c-51f08e15f0df","challengeId":"c2b7a2cc-4633-4f3a-ab39-f7122a6890b6","amount":1600,"status":"completed","createdBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","updatedBy":null,"createdAt":"2021-04-14T22:01:45.390Z","updatedAt":"2021-04-21T20:19:56.934Z"},{"id":"cb94d710-fa3c-4333-b8a9-39ec053a665d","workPeriodId":"428fec88-b305-4816-b5ef-be2b4e91c21a","challengeId":"93f594e9-5396-416a-8212-87bee614a38f","amount":1200,"status":"completed","createdBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","updatedBy":null,"createdAt":"2021-04-14T19:13:23.714Z","updatedAt":"2021-04-21T20:19:56.934Z"},{"id":"155eaab2-ef74-484c-b1d7-6534dde58b66","workPeriodId":"437d4281-43ec-4de3-85e4-51d298388ce5","challengeId":"5ba2d9df-b3ba-4f5f-bee5-228eb46b2c37","amount":600,"status":"completed","createdBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","updatedBy":null,"createdAt":"2021-04-14T22:01:45.361Z","updatedAt":"2021-04-21T20:19:56.934Z"},{"id":"11c07a5c-a077-4719-83ba-c48db7e63c01","workPeriodId":"442b0543-e887-42be-9ff5-5fee825526be","challengeId":"d7c21199-a435-41b8-a2ac-5e5bdd021c5e","amount":1400,"status":"cancelled","createdBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","updatedBy":null,"createdAt":"2021-04-14T19:13:23.714Z","updatedAt":"2021-04-21T20:19:56.934Z"},{"id":"4ce8cf4a-2585-4454-81d4-e5446c9a3f75","workPeriodId":"4a2c581f-c626-44cb-8ada-58f0172e8b4d","challengeId":"ee9bcdd0-0d0d-4414-88cb-d14255f996a5","amount":350,"status":"completed","createdBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","updatedBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","createdAt":"2021-04-14T19:13:23.714Z","updatedAt":"2021-04-16T19:13:23.714Z"},{"id":"8ff6188f-b4e6-4f6e-b2d4-2a622ae50c4f","workPeriodId":"4bfdc253-e39a-4cfa-9a45-2cfc6e93cc6f","challengeId":"f151a5a1-6b28-4f59-bdde-6e73498faa84","amount":450,"status":"cancelled","createdBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","updatedBy":null,"createdAt":"2021-04-14T22:01:45.326Z","updatedAt":"2021-04-21T20:19:56.934Z"},{"id":"5192e519-30f5-42d6-877f-5c2b786d91c7","workPeriodId":"4db82b0b-4d6f-4e9a-b957-ab405b2c2df2","challengeId":"93f594e9-5396-416a-8212-87bee614a38f","amount":600,"status":"cancelled","createdBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","updatedBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","createdAt":"2021-04-14T19:13:23.714Z","updatedAt":"2021-04-16T19:13:23.714Z"},{"id":"8ca85158-a850-4cae-97f0-5873a9225ff8","workPeriodId":"531754f3-405e-42eb-932a-c1ce7b9386e7","challengeId":"b42b8f40-9a4d-45d1-814e-59da5c7a1fd9","amount":1200,"status":"completed","createdBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","updatedBy":null,"createdAt":"2021-04-14T19:13:23.714Z","updatedAt":"2021-04-21T20:19:56.934Z"},{"id":"4a81c6a3-18d9-441b-ae64-3aa9def336ef","workPeriodId":"5392acee-b504-4720-95fa-dab585acb607","challengeId":"78154e5c-feed-4dbf-84ec-775395139211","amount":200,"status":"completed","createdBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","updatedBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","createdAt":"2021-04-14T19:13:23.714Z","updatedAt":"2021-04-16T19:13:23.714Z"},{"id":"a26b8cae-a1df-4843-a192-0735f235bf78","workPeriodId":"558b4685-4932-492e-99e1-2830c10f8275","challengeId":"0de972b8-6cc9-4625-9760-1c77561c29e9","amount":600,"status":"completed","createdBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","updatedBy":null,"createdAt":"2021-04-14T19:13:23.714Z","updatedAt":"2021-04-21T20:19:56.934Z"},{"id":"a94b6f43-de89-4fd2-9a1d-d8a2cce02702","workPeriodId":"584c931b-da72-416e-a011-eac5fe34f42f","challengeId":"d55fae30-3072-462e-b8bd-eb2eec664e65","amount":1600,"status":"completed","createdBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","updatedBy":null,"createdAt":"2021-04-14T22:01:45.324Z","updatedAt":"2021-04-21T20:19:56.934Z"},{"id":"eb63dfc7-14d7-4cae-a25e-3e33a04601cf","workPeriodId":"5ddc132b-3205-45e3-bfe9-f1a4f939885e","challengeId":"0de972b8-6cc9-4625-9760-1c77561c29e9","amount":300,"status":"completed","createdBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","updatedBy":null,"createdAt":"2021-04-14T19:13:23.714Z","updatedAt":"2021-04-21T20:19:56.934Z"},{"id":"d827ed01-5153-4774-8450-bace2521a6d1","workPeriodId":"619a0835-730f-47ec-820e-3959821aec51","challengeId":"d40cb9c5-b3bd-45a1-802c-a50fefb020b9","amount":1000,"status":"completed","createdBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","updatedBy":null,"createdAt":"2021-04-14T22:01:45.326Z","updatedAt":"2021-04-21T20:19:56.934Z"},{"id":"f950e52e-5a52-4ee8-af5f-e6c42e9b400b","workPeriodId":"64de2244-6fcf-45ac-8a89-a9b3420e4476","challengeId":"6c04d456-bb38-43c8-a538-f5cc6caaa540","amount":800,"status":"completed","createdBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","updatedBy":null,"createdAt":"2021-04-14T19:13:23.714Z","updatedAt":"2021-04-21T20:19:56.934Z"},{"id":"283f9c3b-7f0a-4792-9661-ced7cbdb340d","workPeriodId":"6a1180b8-38af-4bd0-8a5f-a60626e0bc95","challengeId":"9a995b78-0542-41be-a926-f3df57c2f873","amount":400,"status":"completed","createdBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","updatedBy":null,"createdAt":"2021-04-14T22:01:45.361Z","updatedAt":"2021-04-21T20:19:56.934Z"},{"id":"09ea6f03-4489-496c-817c-e9279a58c0ad","workPeriodId":"6da7d347-7492-43b1-a49d-8a6e1daf9b22","challengeId":"78154e5c-feed-4dbf-84ec-775395139211","amount":400,"status":"completed","createdBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","updatedBy":null,"createdAt":"2021-04-14T19:13:23.714Z","updatedAt":"2021-04-21T20:19:56.934Z"},{"id":"7d782624-243e-497b-90ca-cc00ae29ebf2","workPeriodId":"6e1dc024-d437-4d9f-92e9-561db713a19a","challengeId":"afcbc3bc-9077-4978-bf9c-acddb48e6518","amount":800,"status":"completed","createdBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","updatedBy":null,"createdAt":"2021-04-14T22:01:45.324Z","updatedAt":"2021-04-21T20:19:56.934Z"},{"id":"11918ff9-5f18-445d-ae90-762b3ebe44ca","workPeriodId":"6ed667a5-275e-4f27-984b-34dff5f8a1ff","challengeId":"c89d357f-afd1-4757-824f-2cf94e2890c6","amount":250,"status":"completed","createdBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","updatedBy":null,"createdAt":"2021-04-14T22:01:45.361Z","updatedAt":"2021-04-21T20:19:56.934Z"},{"id":"9fe78619-5c1c-4b22-8d6f-ebf9a9502432","workPeriodId":"703bc625-9144-4a9f-a91b-445e171d8ea9","challengeId":"6c04d456-bb38-43c8-a538-f5cc6caaa540","amount":400,"status":"completed","createdBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","updatedBy":null,"createdAt":"2021-04-14T19:13:23.714Z","updatedAt":"2021-04-21T20:19:56.934Z"},{"id":"7cf85ce0-ef8c-4152-8623-9a1325db6daa","workPeriodId":"729a2396-2b33-4185-8ce8-d929dbf4a472","challengeId":"fbf8efda-fe4b-4b72-99dd-573b79d27bd8","amount":200,"status":"cancelled","createdBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","updatedBy":null,"createdAt":"2021-04-14T22:01:45.390Z","updatedAt":"2021-04-21T20:19:56.934Z"},{"id":"e8aee371-1f26-4475-8459-9c134fa6f3c6","workPeriodId":"731db5d7-bb79-45f4-b1b2-9f60d30f7966","challengeId":"ee9bcdd0-0d0d-4414-88cb-d14255f996a5","amount":700,"status":"cancelled","createdBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","updatedBy":null,"createdAt":"2021-04-14T19:13:23.714Z","updatedAt":"2021-04-21T20:19:56.934Z"},{"id":"dec8615b-c823-4fff-bc77-fa0614b8d09c","workPeriodId":"7f8f3a25-b1d2-4e36-a543-fcaae57a32f5","challengeId":"fe3e4056-82e3-4df4-b699-a1f3d8ab5e53","amount":700,"status":"completed","createdBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","updatedBy":null,"createdAt":"2021-04-14T22:01:45.390Z","updatedAt":"2021-04-21T20:19:56.934Z"},{"id":"c4e316ca-a46f-4fbc-96a6-6fe6665c3b49","workPeriodId":"829165cb-0150-48e7-995c-f5b4d1a51d3b","challengeId":"d937a822-4a9b-40db-afe6-fe1285e3f7f9","amount":900,"status":"completed","createdBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","updatedBy":null,"createdAt":"2021-04-14T22:01:45.324Z","updatedAt":"2021-04-21T20:19:56.934Z"},{"id":"12b0bcfc-59ae-478c-bb32-cb18d1d0244c","workPeriodId":"84431dac-019d-4987-9817-15f5f000d2db","challengeId":"a07ea88f-c52b-4023-8730-c4364efd0dd2","amount":600,"status":"completed","createdBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","updatedBy":null,"createdAt":"2021-04-14T22:01:45.361Z","updatedAt":"2021-04-21T20:19:56.934Z"},{"id":"8c9ed23c-12c7-4a8b-8e91-6fd3b3fc43a4","workPeriodId":"8b7b49de-29b1-4a0c-bb67-e70cc700fcfd","challengeId":"0de972b8-6cc9-4625-9760-1c77561c29e9","amount":450,"status":"completed","createdBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","updatedBy":null,"createdAt":"2021-04-14T19:13:23.714Z","updatedAt":"2021-04-21T20:19:56.934Z"},{"id":"621d793b-0ead-4d99-a119-e32af526ece7","workPeriodId":"8c8cedf3-0bb6-4063-8a3a-faf1626da384","challengeId":"ad04dcee-9a3c-4345-b0b5-783ce98e94b2","amount":900,"status":"completed","createdBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","updatedBy":null,"createdAt":"2021-04-14T22:01:45.390Z","updatedAt":"2021-04-21T20:19:56.934Z"},{"id":"56cb3aef-531b-4a26-817e-4b9629212c9a","workPeriodId":"90d99323-ba57-4a18-b50f-78f387033c70","challengeId":"0de972b8-6cc9-4625-9760-1c77561c29e9","amount":450,"status":"completed","createdBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","updatedBy":null,"createdAt":"2021-04-14T19:13:23.714Z","updatedAt":"2021-04-21T20:19:56.934Z"},{"id":"a1ffc559-703a-4c35-8ba3-73a03c3454af","workPeriodId":"93b0f03b-219b-41d5-bb1e-f125651b1b0e","challengeId":"9fca67f9-3641-4982-8a82-e86b1850efc8","amount":600,"status":"completed","createdBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","updatedBy":null,"createdAt":"2021-04-14T22:01:45.326Z","updatedAt":"2021-04-21T20:19:56.934Z"},{"id":"a5904ae3-7524-4709-b798-20c4a2193f10","workPeriodId":"93e69f99-cb1c-418e-aa41-ab2181b4bcfd","challengeId":"ed56a1c7-a965-4ab6-9cf0-0d7c14cd7db3","amount":400,"status":"completed","createdBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","updatedBy":null,"createdAt":"2021-04-14T22:01:45.361Z","updatedAt":"2021-04-21T20:19:56.934Z"},{"id":"821b38e8-657d-4f72-b27a-dd975c506ced","workPeriodId":"9b6fc85b-3694-4e6c-9ebf-fe9ccf7881ba","challengeId":"61f5185b-4ee1-4df3-9c6f-52f5bf0cbfc5","amount":500,"status":"completed","createdBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","updatedBy":null,"createdAt":"2021-04-14T22:01:45.361Z","updatedAt":"2021-04-21T20:19:56.934Z"},{"id":"2417df2c-8e29-4868-aeb8-5ec0ff67713e","workPeriodId":"9bfbd49a-e6bb-45c3-965d-ed4f95f0878a","challengeId":"f01ba8da-c891-472d-9ed6-74b91ed9b407","amount":400,"status":"completed","createdBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","updatedBy":null,"createdAt":"2021-04-14T19:13:23.714Z","updatedAt":"2021-04-21T20:19:56.934Z"},{"id":"5116d4ea-2c1a-4be6-b335-bd531b8d5734","workPeriodId":"a35bb205-361b-4b2d-9828-55501ae9d190","challengeId":"b42b8f40-9a4d-45d1-814e-59da5c7a1fd9","amount":600,"status":"completed","createdBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","updatedBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","createdAt":"2021-04-14T19:13:23.714Z","updatedAt":"2021-04-16T19:13:23.714Z"},{"id":"8fdfe90b-2155-4a71-a610-4689106ced34","workPeriodId":"b21f921a-4b23-423d-814b-d31f5cba7f64","challengeId":"963784fd-4174-458c-a311-a5b8333d66ab","amount":300,"status":"completed","createdBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","updatedBy":null,"createdAt":"2021-04-14T22:01:45.361Z","updatedAt":"2021-04-21T20:19:56.934Z"},{"id":"dd9c842a-f577-43c2-8f17-cc940f26f0d8","workPeriodId":"b4566e24-4fa8-4e82-9950-f62134bb00df","challengeId":"b67cbbc5-3384-4ea6-8504-d3fe83a6e238","amount":700,"status":"completed","createdBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","updatedBy":null,"createdAt":"2021-04-14T22:01:45.326Z","updatedAt":"2021-04-21T20:19:56.934Z"},{"id":"7e41ca7f-d3c0-4d70-9daf-ee52c93695c7","workPeriodId":"b5261ee2-bc4d-4c3a-9d30-6703bfdcfbc5","challengeId":"9d49655f-99f6-4e67-9819-a117ef746272","amount":500,"status":"completed","createdBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","updatedBy":null,"createdAt":"2021-04-14T22:01:45.361Z","updatedAt":"2021-04-21T20:19:56.934Z"},{"id":"b8d44e83-922c-4c2c-8567-5764794e03f3","workPeriodId":"b682660e-488e-4033-aaf3-ef37248abc90","challengeId":"d7c21199-a435-41b8-a2ac-5e5bdd021c5e","amount":700,"status":"completed","createdBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","updatedBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","createdAt":"2021-04-14T19:13:23.714Z","updatedAt":"2021-04-16T19:13:23.714Z"},{"id":"c117de76-965f-4069-aefb-8dd97f95112c","workPeriodId":"b8a8b558-0cb9-46d0-ba9d-2222f3fbdb63","challengeId":"59d08064-e1b4-4e78-82d8-b2d7ffa6f0b1","amount":900,"status":"completed","createdBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","updatedBy":null,"createdAt":"2021-04-14T22:01:45.523Z","updatedAt":"2021-04-21T20:19:56.934Z"},{"id":"fda2013c-da68-4601-8d13-d0f4cffd081c","workPeriodId":"bc8611f0-4ac2-49b2-b776-59ed2b759d1d","challengeId":"0de972b8-6cc9-4625-9760-1c77561c29e9","amount":800,"status":"completed","createdBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","updatedBy":null,"createdAt":"2021-04-14T19:13:23.714Z","updatedAt":"2021-04-21T20:19:56.934Z"},{"id":"be07bfc8-032c-41f7-a247-a4724f65617c","workPeriodId":"bd54bcaf-5278-467f-a166-865048774d0e","challengeId":"45e33cee-7c83-4288-8187-6858b0c759eb","amount":800,"status":"completed","createdBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","updatedBy":null,"createdAt":"2021-04-14T22:01:45.361Z","updatedAt":"2021-04-21T20:19:56.934Z"},{"id":"efa8cd14-c93f-4e6c-be53-596f02db8c96","workPeriodId":"bf61dad8-841a-4913-93f6-b2ae516b8b11","challengeId":"0de972b8-6cc9-4625-9760-1c77561c29e9","amount":800,"status":"completed","createdBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","updatedBy":null,"createdAt":"2021-04-14T19:13:23.714Z","updatedAt":"2021-04-21T20:19:56.934Z"},{"id":"eb9c9a83-fe94-4f51-b9f0-c2d9671e87f6","workPeriodId":"c5f6ae8f-2976-46d1-bd66-58eeb58ca045","challengeId":"68e6a32e-6c31-4266-ba3b-9d2f63be4274","amount":900,"status":"completed","createdBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","updatedBy":null,"createdAt":"2021-04-14T22:01:45.361Z","updatedAt":"2021-04-21T20:19:56.934Z"},{"id":"c20796c8-76b0-40e8-9bee-db406c93daaf","workPeriodId":"c7ff2acc-a4c2-4e8b-a905-813dd9d1b293","challengeId":"513ab4c6-0aa4-482b-a184-87f8447b145b","amount":1800,"status":"completed","createdBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","updatedBy":null,"createdAt":"2021-04-14T22:01:45.390Z","updatedAt":"2021-04-21T20:19:56.934Z"},{"id":"8fad32f7-cb40-416f-ab24-86cf1c7870ef","workPeriodId":"c9685cb2-9f4a-497e-ae99-deed7b16cc34","challengeId":"f7e40a0c-a302-4989-a3bd-7587fee3c367","amount":600,"status":"completed","createdBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","updatedBy":null,"createdAt":"2021-04-14T19:13:23.714Z","updatedAt":"2021-04-21T20:19:56.934Z"},{"id":"310384cb-6e85-4f7d-a6d2-8c03ca27871d","workPeriodId":"d049e7bc-c827-482b-9ec6-b87d9289d1cd","challengeId":"0de972b8-6cc9-4625-9760-1c77561c29e9","amount":900,"status":"completed","createdBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","updatedBy":null,"createdAt":"2021-04-14T19:13:23.714Z","updatedAt":"2021-04-21T20:19:56.934Z"},{"id":"2a122a93-e778-4eb9-868c-5f38b8b9bb4e","workPeriodId":"da8abd64-2878-4e09-b3b1-41a27a0576d4","challengeId":"25a7c442-427b-4b6d-9c41-112dbd420c0d","amount":800,"status":"completed","createdBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","updatedBy":null,"createdAt":"2021-04-14T19:13:23.714Z","updatedAt":"2021-04-21T20:19:56.934Z"},{"id":"767897c3-bbc2-4b1a-9843-5a6bd82e29b0","workPeriodId":"dcc310cf-ea4a-4637-9bf5-5baaabea67b3","challengeId":"61044188-965e-40df-94c4-9fa9a9499b25","amount":1000,"status":"completed","createdBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","updatedBy":null,"createdAt":"2021-04-14T22:01:45.523Z","updatedAt":"2021-04-21T20:19:56.934Z"},{"id":"50f7a6fa-a04d-4873-8fd0-037be2f14425","workPeriodId":"e19bddc5-38ac-43c9-8273-bc9069de26b3","challengeId":"419fbb3d-921d-4613-a87e-337f38d21885","amount":600,"status":"completed","createdBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","updatedBy":null,"createdAt":"2021-04-14T22:01:45.523Z","updatedAt":"2021-04-21T20:19:56.934Z"},{"id":"11ea987f-f218-4d2b-b656-0741208539f2","workPeriodId":"f575df2d-f170-4251-9042-b17ca5e99ca5","challengeId":"0de972b8-6cc9-4625-9760-1c77561c29e9","amount":600,"status":"completed","createdBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","updatedBy":null,"createdAt":"2021-04-16T19:13:23.714Z","updatedAt":"2021-04-21T20:19:56.934Z"},{"id":"2519d7f9-81c8-448c-aec2-aa78d6d6a962","workPeriodId":"f70509c0-baed-4ff1-8022-12441251f7af","challengeId":"fd051497-6050-4edf-b8f7-780128f64dc5","amount":300,"status":"cancelled","createdBy":"57646ff9-1cd3-4d3c-88ba-eb09a395366c","updatedBy":null,"createdAt":"2021-04-14T22:01:45.324Z","updatedAt":"2021-04-21T20:19:56.934Z"}]} \ No newline at end of file +{ + "Job": [ + { + "id": "b9887564-3d3d-4c70-8a7b-552576ef2e8d", + "projectId": 111, + "externalId": "0", + "description": "taas-demo-job1", + "title": "Demo Title", + "startDate": "2020-09-27T04:17:23.131Z", + "duration": null, + "numPositions": 13, + "resourceType": "Dummy Resource Type", + "rateType": "weekly", + "workload": "full-time", + "skills": [ + "ee4c50c1-c8c3-475e-b6b6-edbd136a19d6", + "89139c80-d0a2-47c2-aa16-14589d5afd10", + "9f2d9127-6a2e-4506-ad76-c4ab63577b09", + "9515e7ee-83b6-49d1-ba5c-6c59c5a8ef1b", + "c854ab55-5922-4be1-8ecc-b3bc1f8629af", + "8456002e-fa2d-44f0-b0e7-86b1c02b6e4c", + "114b4ec8-805e-4c60-b351-14a955a991a9", + "213408aa-f16f-46c8-bc57-9e569cee3f11", + "b37a48db-f775-4e4e-b403-8ad1d234cdea", + "99b930b5-1b91-4df1-8b17-d9307107bb51", + "6388a632-c3ad-4525-9a73-66a527c03672", + "23839f38-6f19-4de9-9d28-f020056bca73", + "289e42a3-23e9-49be-88e1-6deb93cd8c31", + "b403f209-63b5-42bc-9b5f-1564416640d8" + ], + "status": "sourcing", + "isApplicationPageActive": false, + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-01-28T19:36:33.409Z", + "updatedAt": "2021-03-30T19:11:05.033Z" + }, + { + "id": "a5b3bf94-a8bf-4c7e-b685-70a29a4d7d6e", + "projectId": 111, + "externalId": "0", + "description": "taas-demo-job2", + "title": "Dummy title - at most 64 characters", + "startDate": "2020-09-27T04:17:23.131Z", + "duration": null, + "numPositions": 7, + "resourceType": "Dummy Resource Type", + "rateType": "weekly", + "workload": "full-time", + "skills": [ + "213408aa-f16f-46c8-bc57-9e569cee3f11", + "b37a48db-f775-4e4e-b403-8ad1d234cdea", + "99b930b5-1b91-4df1-8b17-d9307107bb51", + "6388a632-c3ad-4525-9a73-66a527c03672", + "23839f38-6f19-4de9-9d28-f020056bca73", + "289e42a3-23e9-49be-88e1-6deb93cd8c31", + "b403f209-63b5-42bc-9b5f-1564416640d8" + ], + "status": "in-review", + "isApplicationPageActive": false, + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "createdAt": "2021-01-28T19:36:44.975Z", + "updatedAt": "2021-01-28T19:38:17.463Z" + }, + { + "id": "2d5e2a52-e0dd-4cd9-8f4c-7cffa43951d0", + "projectId": 111, + "externalId": "0", + "description": "taas-demo-job3", + "title": "Dummy title - at most 64 characters", + "startDate": "2020-09-27T04:17:23.131Z", + "duration": null, + "numPositions": 7, + "resourceType": "Dummy Resource Type", + "rateType": "weekly", + "workload": "full-time", + "skills": [], + "status": "assigned", + "isApplicationPageActive": false, + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "createdAt": "2021-01-28T19:38:23.739Z", + "updatedAt": "2021-01-28T19:41:10.607Z" + }, + { + "id": "84b73f90-0fef-4507-887a-074578e5ef38", + "projectId": 111, + "externalId": "0", + "description": "taas-demo-job4", + "title": "Dummy title - at most 64 characters", + "startDate": "2020-09-27T04:17:23.131Z", + "duration": null, + "numPositions": 7, + "resourceType": "Dummy Resource Type", + "rateType": "weekly", + "workload": "full-time", + "skills": [ + "8456002e-fa2d-44f0-b0e7-86b1c02b6e4c", + "114b4ec8-805e-4c60-b351-14a955a991a9", + "213408aa-f16f-46c8-bc57-9e569cee3f11", + "b37a48db-f775-4e4e-b403-8ad1d234cdea", + "99b930b5-1b91-4df1-8b17-d9307107bb51", + "6388a632-c3ad-4525-9a73-66a527c03672" + ], + "status": "closed", + "isApplicationPageActive": false, + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "createdAt": "2021-01-28T19:41:21.892Z", + "updatedAt": "2021-01-28T19:41:28.849Z" + }, + { + "id": "62399aa0-b088-41fe-9e9b-0c8071f1934f", + "projectId": 111, + "externalId": "0", + "description": "taas-demo-job5", + "title": "Dummy title - at most 64 characters", + "startDate": "2020-09-27T04:17:23.131Z", + "duration": null, + "numPositions": 7, + "resourceType": "Dummy Resource Type", + "rateType": "weekly", + "workload": "full-time", + "skills": [ + "b37a48db-f775-4e4e-b403-8ad1d234cdea", + "99b930b5-1b91-4df1-8b17-d9307107bb51", + "6388a632-c3ad-4525-9a73-66a527c03672" + ], + "status": "cancelled", + "isApplicationPageActive": false, + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "createdAt": "2021-01-28T19:41:35.098Z", + "updatedAt": "2021-01-28T19:41:42.124Z" + }, + { + "id": "1324da27-9d7d-47d8-a04e-9fb3f35a67fa", + "projectId": 111, + "externalId": "88774632", + "description": "Dummy Description", + "title": "Dummy title - at most 64 characters", + "startDate": "2020-09-27T04:17:23.131Z", + "duration": 1, + "numPositions": 13, + "resourceType": "Dummy Resource Type", + "rateType": "hourly", + "workload": "full-time", + "skills": [ + "23e00d92-207a-4b5b-b3c9-4c5662644941", + "7d076384-ccf6-4e43-a45d-1b24b1e624aa", + "cbac57a3-7180-4316-8769-73af64893158", + "a2b4bc11-c641-4a19-9eb7-33980378f82e" + ], + "status": "in-review", + "isApplicationPageActive": false, + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": "00000000-0000-0000-0000-000000000000", + "createdAt": "2021-04-14T08:46:17.739Z", + "updatedAt": "2021-04-14T08:46:23.311Z" + } + ], + "JobCandidate": [ + { + "id": "debadcd8-64bf-4ab8-9cdb-297479eef6f5", + "jobId": "a5b3bf94-a8bf-4c7e-b685-70a29a4d7d6e", + "userId": "4dfc6090-4ba8-4387-b5c4-584fcef982ba", + "status": "open", + "externalId": null, + "resume": null, + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-01-28T19:37:05.723Z", + "updatedAt": "2021-03-30T19:11:05.043Z", + "interviews": [] + }, + { + "id": "7ff45b8f-2b71-4510-b760-8dfa62e79504", + "jobId": "a5b3bf94-a8bf-4c7e-b685-70a29a4d7d6e", + "userId": "243517dd-77d7-4f70-8951-0bc66da83076", + "status": "open", + "externalId": null, + "resume": null, + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-01-28T19:37:11.598Z", + "updatedAt": "2021-03-30T19:11:05.043Z", + "interviews": [] + }, + { + "id": "91d63d5f-01d5-419e-89df-6117ea92f535", + "jobId": "a5b3bf94-a8bf-4c7e-b685-70a29a4d7d6e", + "userId": "a2e28bf4-1147-41a6-a39f-e2509306f2a6", + "status": "open", + "externalId": null, + "resume": null, + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-01-28T19:37:18.066Z", + "updatedAt": "2021-03-30T19:11:05.043Z", + "interviews": [] + }, + { + "id": "257f98d9-45f7-4e13-a6c2-d7e7b6efc9fe", + "jobId": "a5b3bf94-a8bf-4c7e-b685-70a29a4d7d6e", + "userId": "b8649393-d32f-4b7f-a156-12e9776acb0e", + "status": "open", + "externalId": null, + "resume": null, + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-01-28T19:37:24.095Z", + "updatedAt": "2021-03-30T19:11:05.043Z", + "interviews": [] + }, + { + "id": "a01852d0-fa08-410c-b97b-67580ce62215", + "jobId": "a5b3bf94-a8bf-4c7e-b685-70a29a4d7d6e", + "userId": "a0a3a5ce-1de6-465d-91b2-518feb299851", + "status": "open", + "externalId": null, + "resume": null, + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-01-28T19:37:29.734Z", + "updatedAt": "2021-03-30T19:11:05.043Z", + "interviews": [] + }, + { + "id": "2fd7ca69-c8ec-4bf3-a7f3-655fbfe3e7df", + "jobId": "a5b3bf94-a8bf-4c7e-b685-70a29a4d7d6e", + "userId": "e6958d77-ffaf-4d24-9cdb-6391506695a4", + "status": "open", + "externalId": null, + "resume": null, + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-01-28T19:37:44.728Z", + "updatedAt": "2021-03-30T19:11:05.043Z", + "interviews": [] + }, + { + "id": "f0023058-2996-4bba-8c5f-d09a7023be38", + "jobId": "a5b3bf94-a8bf-4c7e-b685-70a29a4d7d6e", + "userId": "626bb327-e738-48e3-8f67-1fa2dc677d3c", + "status": "open", + "externalId": null, + "resume": null, + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-01-28T19:37:50.619Z", + "updatedAt": "2021-03-30T19:11:05.043Z", + "interviews": [] + }, + { + "id": "a189b34d-acde-4633-b18b-f7a34d7c5a74", + "jobId": "a5b3bf94-a8bf-4c7e-b685-70a29a4d7d6e", + "userId": "b49a0adb-1565-4de1-9189-a763c77f5ed4", + "status": "open", + "externalId": null, + "resume": null, + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-01-28T19:37:56.456Z", + "updatedAt": "2021-03-30T19:11:05.043Z", + "interviews": [] + }, + { + "id": "5191a860-4327-4c50-b76b-84beba04519b", + "jobId": "a5b3bf94-a8bf-4c7e-b685-70a29a4d7d6e", + "userId": "79ce2a3e-7679-48cf-8ac9-0a8ca4c4b463", + "status": "selected", + "externalId": null, + "resume": null, + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "createdAt": "2021-01-28T19:36:51.222Z", + "updatedAt": "2021-01-28T19:38:02.293Z", + "interviews": [] + }, + { + "id": "e6d9635c-b122-4f69-9285-09fb1ab30106", + "jobId": "a5b3bf94-a8bf-4c7e-b685-70a29a4d7d6e", + "userId": "98ec2c16-442e-4b61-8ad1-66123ee37d3c", + "status": "rejected - other", + "externalId": null, + "resume": null, + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "createdAt": "2021-01-28T19:36:58.774Z", + "updatedAt": "2021-01-28T19:38:13.553Z", + "interviews": [] + }, + { + "id": "f67b155e-0f09-4fdd-89a7-d79c5e46cac6", + "jobId": "2d5e2a52-e0dd-4cd9-8f4c-7cffa43951d0", + "userId": "05e988b7-7d54-4c10-ada1-1a04870a88a8", + "status": "open", + "externalId": null, + "resume": null, + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-01-28T19:38:38.332Z", + "updatedAt": "2021-03-30T19:11:05.043Z", + "interviews": [] + }, + { + "id": "8ffd33d3-4a43-4719-aee4-8e46be1d8f1c", + "jobId": "2d5e2a52-e0dd-4cd9-8f4c-7cffa43951d0", + "userId": "a2ffdeed-704d-4cf7-b70a-93fcf61de598", + "status": "open", + "externalId": null, + "resume": null, + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-01-28T19:38:43.967Z", + "updatedAt": "2021-03-30T19:11:05.043Z", + "interviews": [] + }, + { + "id": "2b8ba549-8878-43d6-ad5f-6a66e3b9d6c9", + "jobId": "2d5e2a52-e0dd-4cd9-8f4c-7cffa43951d0", + "userId": "4709473d-f060-4102-87f8-4d51ff0b34c1", + "status": "open", + "externalId": null, + "resume": null, + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-01-28T19:38:50.106Z", + "updatedAt": "2021-03-30T19:11:05.043Z", + "interviews": [] + }, + { + "id": "ae5a81ec-5d05-43c4-8253-847d91a54711", + "jobId": "2d5e2a52-e0dd-4cd9-8f4c-7cffa43951d0", + "userId": "39c7376e-2d5c-4601-bc47-6b60f505814d", + "status": "open", + "externalId": null, + "resume": null, + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-01-28T19:38:55.734Z", + "updatedAt": "2021-03-30T19:11:05.043Z", + "interviews": [] + }, + { + "id": "85d6649e-2682-4904-9480-a77b72fef27d", + "jobId": "2d5e2a52-e0dd-4cd9-8f4c-7cffa43951d0", + "userId": "213d2dd9-1fc3-4eda-ad97-2d56e2a84a1e", + "status": "placed", + "externalId": null, + "resume": null, + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": "00000000-0000-0000-0000-000000000000", + "createdAt": "2021-01-28T19:38:30.856Z", + "updatedAt": "2021-01-28T19:40:27.209Z", + "interviews": [] + }, + { + "id": "922dfce3-4e06-4387-9fdb-64f70675e86b", + "jobId": "2d5e2a52-e0dd-4cd9-8f4c-7cffa43951d0", + "userId": "dd5adacb-444d-4992-8b7b-0c349be598db", + "status": "placed", + "externalId": null, + "resume": null, + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": "00000000-0000-0000-0000-000000000000", + "createdAt": "2021-01-28T19:39:02.435Z", + "updatedAt": "2021-01-28T19:40:49.349Z", + "interviews": [] + }, + { + "id": "c26c38e2-a47d-405b-abc6-fe62a739561c", + "jobId": "2d5e2a52-e0dd-4cd9-8f4c-7cffa43951d0", + "userId": "6d0509c7-5f12-4d84-9a19-8e80ef7ddd66", + "status": "placed", + "externalId": null, + "resume": null, + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": "00000000-0000-0000-0000-000000000000", + "createdAt": "2021-01-28T19:39:08.233Z", + "updatedAt": "2021-01-28T19:40:53.659Z", + "interviews": [] + }, + { + "id": "7bef2b37-e1ee-4638-bfc1-c911787ac955", + "jobId": "2d5e2a52-e0dd-4cd9-8f4c-7cffa43951d0", + "userId": "f65e2104-2987-4136-839d-ee4632f0b2e5", + "status": "placed", + "externalId": null, + "resume": null, + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": "00000000-0000-0000-0000-000000000000", + "createdAt": "2021-01-28T19:39:13.469Z", + "updatedAt": "2021-01-28T19:40:57.999Z", + "interviews": [] + }, + { + "id": "e9716139-1f40-4bf1-9f8a-77ae4bcc621e", + "jobId": "2d5e2a52-e0dd-4cd9-8f4c-7cffa43951d0", + "userId": "e5e667ad-0950-43c2-8d1d-6e83ad7d1c7e", + "status": "placed", + "externalId": null, + "resume": null, + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": "00000000-0000-0000-0000-000000000000", + "createdAt": "2021-01-28T19:39:19.215Z", + "updatedAt": "2021-01-28T19:41:01.953Z", + "interviews": [] + }, + { + "id": "a1731d01-eac9-4eff-8e5a-8a3c99bc66e0", + "jobId": "2d5e2a52-e0dd-4cd9-8f4c-7cffa43951d0", + "userId": "bef43122-426b-4b2b-acdd-9b5b3bd1c0bf", + "status": "placed", + "externalId": null, + "resume": null, + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": "00000000-0000-0000-0000-000000000000", + "createdAt": "2021-01-28T19:39:24.625Z", + "updatedAt": "2021-01-28T19:41:06.370Z", + "interviews": [] + }, + { + "id": "25787cb2-d876-4883-b533-d5e628d213ce", + "jobId": "1324da27-9d7d-47d8-a04e-9fb3f35a67fa", + "userId": "95e7970f-12b4-43b7-ab35-38c34bf033c7", + "status": "interview", + "externalId": "88774631", + "resume": "http://example.com", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-04-14T08:46:23.250Z", + "updatedAt": "2021-04-14T08:46:23.250Z", + "interviews": [ + { + "id": "81f03238-1ce2-4d3d-80c5-5ecd5e7e94a2", + "jobCandidateId": "25787cb2-d876-4883-b533-d5e628d213ce", + "googleCalendarId": "dummyId", + "customMessage": "This is a custom message", + "xaiTemplate": "30-min-interview", + "round": 1, + "status": "Scheduling", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-04-14T08:46:34.597Z", + "updatedAt": "2021-04-14T08:46:34.597Z" + }, + { + "id": "75363f1d-46c3-4261-9c21-70019f90a61a", + "jobCandidateId": "25787cb2-d876-4883-b533-d5e628d213ce", + "googleCalendarId": "dummyId", + "customMessage": "This is a custom message", + "xaiTemplate": "30-min-interview", + "round": 2, + "status": "Scheduling", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-04-14T08:50:15.109Z", + "updatedAt": "2021-04-14T08:50:15.109Z" + } + ] + } + ], + "ResourceBooking": [ + { + "id": "08f5e4b9-1088-496d-91a7-5b22a3583e3c", + "projectId": 111, + "userId": "213d2dd9-1fc3-4eda-ad97-2d56e2a84a1e", + "jobId": "2d5e2a52-e0dd-4cd9-8f4c-7cffa43951d0", + "status": "placed", + "startDate": "2021-01-25", + "endDate": "2021-01-31", + "memberRate": 1000, + "customerRate": 1200, + "rateType": "weekly", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "createdAt": "2021-01-28T19:39:30.052Z", + "updatedAt": "2021-01-28T19:40:25.260Z" + }, + { + "id": "7d967fed-9792-4768-98a7-0b644aa84f2e", + "projectId": 111, + "userId": "05e988b7-7d54-4c10-ada1-1a04870a88a8", + "jobId": "2d5e2a52-e0dd-4cd9-8f4c-7cffa43951d0", + "status": "in-review", + "startDate": "2021-03-25", + "endDate": "2021-05-31", + "memberRate": 1000, + "customerRate": 1200, + "rateType": "weekly", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "createdAt": "2021-01-28T19:39:35.571Z", + "updatedAt": "2021-01-28T19:40:30.291Z" + }, + { + "id": "0a6799d7-f5d1-456b-8bf1-90619284b295", + "projectId": 111, + "userId": "6d0509c7-5f12-4d84-9a19-8e80ef7ddd66", + "jobId": "2d5e2a52-e0dd-4cd9-8f4c-7cffa43951d0", + "status": "placed", + "startDate": "2021-02-27", + "endDate": "2021-03-15", + "memberRate": 2000, + "customerRate": 2500, + "rateType": "weekly", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "createdAt": "2021-01-28T19:40:04.761Z", + "updatedAt": "2021-01-28T19:40:52.303Z" + }, + { + "id": "35e1abd8-1890-4664-bb52-aade382d7b66", + "projectId": 111, + "userId": "a2ffdeed-704d-4cf7-b70a-93fcf61de598", + "jobId": "2d5e2a52-e0dd-4cd9-8f4c-7cffa43951d0", + "status": "closed", + "startDate": "2021-02-25", + "endDate": "2021-04-01", + "memberRate": 1000, + "customerRate": 1200, + "rateType": "weekly", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "createdAt": "2021-01-28T19:39:41.205Z", + "updatedAt": "2021-01-28T19:40:34.859Z" + }, + { + "id": "51b45f5d-5df2-46d5-9c3d-8a1323df38dd", + "projectId": 111, + "userId": "dd5adacb-444d-4992-8b7b-0c349be598db", + "jobId": "2d5e2a52-e0dd-4cd9-8f4c-7cffa43951d0", + "status": "placed", + "startDate": "2021-03-18", + "endDate": "2021-05-28", + "memberRate": 800, + "customerRate": 1000, + "rateType": "weekly", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "createdAt": "2021-01-28T19:39:59.432Z", + "updatedAt": "2021-01-28T19:40:47.743Z" + }, + { + "id": "61f5d474-e41f-490b-ab58-9f983e3d4916", + "projectId": 111, + "userId": "f65e2104-2987-4136-839d-ee4632f0b2e5", + "jobId": "2d5e2a52-e0dd-4cd9-8f4c-7cffa43951d0", + "status": "placed", + "startDate": "2000-03-27", + "endDate": "2000-04-27", + "memberRate": 3000, + "customerRate": 3500, + "rateType": "weekly", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "createdAt": "2021-01-28T19:40:09.879Z", + "updatedAt": "2021-01-28T19:40:56.381Z" + }, + { + "id": "8173579e-4b3c-418d-a9a1-c999caa38404", + "projectId": 111, + "userId": "bef43122-426b-4b2b-acdd-9b5b3bd1c0bf", + "jobId": "2d5e2a52-e0dd-4cd9-8f4c-7cffa43951d0", + "status": "placed", + "startDate": "2020-04-27", + "endDate": "2020-05-27", + "memberRate": 0, + "customerRate": 0, + "rateType": "weekly", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "createdAt": "2021-01-28T19:40:20.627Z", + "updatedAt": "2021-01-28T19:41:04.919Z" + }, + { + "id": "a098e8d8-ce5b-47d9-afee-38b050d16745", + "projectId": 111, + "userId": "4709473d-f060-4102-87f8-4d51ff0b34c1", + "jobId": "2d5e2a52-e0dd-4cd9-8f4c-7cffa43951d0", + "status": "cancelled", + "startDate": "2021-04-25", + "endDate": "2021-04-30", + "memberRate": 1000, + "customerRate": 1200, + "rateType": "weekly", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "createdAt": "2021-01-28T19:39:46.515Z", + "updatedAt": "2021-01-28T19:40:38.820Z" + }, + { + "id": "d38a6223-3f91-4300-9ecb-6e5fee173625", + "projectId": 111, + "userId": "39c7376e-2d5c-4601-bc47-6b60f505814d", + "jobId": "2d5e2a52-e0dd-4cd9-8f4c-7cffa43951d0", + "status": "sourcing", + "startDate": "2021-05-25", + "endDate": "2021-07-31", + "memberRate": 1000, + "customerRate": 1200, + "rateType": "weekly", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "createdAt": "2021-01-28T19:39:52.063Z", + "updatedAt": "2021-01-28T19:40:43.021Z" + }, + { + "id": "dc4477ec-07f8-4c8e-a8fe-ffe38dd290fa", + "projectId": 111, + "userId": "e5e667ad-0950-43c2-8d1d-6e83ad7d1c7e", + "jobId": "2d5e2a52-e0dd-4cd9-8f4c-7cffa43951d0", + "status": "placed", + "startDate": "2021-07-27", + "endDate": "2021-09-27", + "memberRate": 1700, + "customerRate": 1900, + "rateType": "weekly", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "createdAt": "2021-01-28T19:40:15.326Z", + "updatedAt": "2021-01-28T19:41:00.503Z" + } + ], + "WorkPeriod": [ + { + "id": "07783b60-b726-41c2-8955-7766a27c1ec5", + "resourceBookingId": "7d967fed-9792-4768-98a7-0b644aa84f2e", + "userHandle": "sachin-wipro", + "projectId": 111, + "startDate": "2021-03-21", + "endDate": "2021-03-27", + "daysWorked": 2, + "memberRate": 4.8, + "customerRate": 4.95, + "paymentStatus": "pending", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-21T20:24:52.705Z", + "updatedAt": null + }, + { + "id": "6ed667a5-275e-4f27-984b-34dff5f8a1ff", + "resourceBookingId": "dc4477ec-07f8-4c8e-a8fe-ffe38dd290fa", + "userHandle": "nskumar278", + "projectId": 111, + "startDate": "2021-08-01", + "endDate": "2021-08-07", + "daysWorked": 5, + "memberRate": 25.21, + "customerRate": 10.05, + "paymentStatus": "pending", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-21T20:24:52.703Z", + "updatedAt": null + }, + { + "id": "d049e7bc-c827-482b-9ec6-b87d9289d1cd", + "resourceBookingId": "8173579e-4b3c-418d-a9a1-c999caa38404", + "userHandle": "testcat", + "projectId": 111, + "startDate": "2020-05-24", + "endDate": "2020-05-30", + "daysWorked": 3, + "memberRate": 24.46, + "customerRate": 18.76, + "paymentStatus": "pending", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-21T20:24:52.806Z", + "updatedAt": null + }, + { + "id": "1b633124-f62c-4026-b679-213cf5812689", + "resourceBookingId": "51b45f5d-5df2-46d5-9c3d-8a1323df38dd", + "userHandle": "amy_admin", + "projectId": 111, + "startDate": "2021-03-28", + "endDate": "2021-04-03", + "daysWorked": 5, + "memberRate": 23.35, + "customerRate": 18.76, + "paymentStatus": "pending", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-21T20:24:52.704Z", + "updatedAt": null + }, + { + "id": "30c89d78-df85-44ed-92b2-b683d8960fc2", + "resourceBookingId": "51b45f5d-5df2-46d5-9c3d-8a1323df38dd", + "userHandle": "amy_admin", + "projectId": 111, + "startDate": "2021-04-04", + "endDate": "2021-04-10", + "daysWorked": 5, + "memberRate": 3.96, + "customerRate": 4.95, + "paymentStatus": "pending", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-21T20:24:52.704Z", + "updatedAt": null + }, + { + "id": "531754f3-405e-42eb-932a-c1ce7b9386e7", + "resourceBookingId": "35e1abd8-1890-4664-bb52-aade382d7b66", + "userHandle": "lakshmiaconnmgr", + "projectId": 111, + "startDate": "2021-02-28", + "endDate": "2021-03-06", + "daysWorked": 5, + "memberRate": 3.62, + "customerRate": 10.05, + "paymentStatus": "pending", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-21T20:24:52.695Z", + "updatedAt": null + }, + { + "id": "442b0543-e887-42be-9ff5-5fee825526be", + "resourceBookingId": "0a6799d7-f5d1-456b-8bf1-90619284b295", + "userHandle": "aaaa", + "projectId": 111, + "startDate": "2021-03-14", + "endDate": "2021-03-20", + "daysWorked": 1, + "memberRate": 23.81, + "customerRate": 15.49, + "paymentStatus": "pending", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-21T20:24:52.694Z", + "updatedAt": null + }, + { + "id": "18a73600-5ee8-484b-9747-70ea80ce2bd9", + "resourceBookingId": "7d967fed-9792-4768-98a7-0b644aa84f2e", + "userHandle": "sachin-wipro", + "projectId": 111, + "startDate": "2021-05-16", + "endDate": "2021-05-22", + "daysWorked": 5, + "memberRate": 28.76, + "customerRate": 25.9, + "paymentStatus": "completed", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-21T20:24:52.705Z", + "updatedAt": null + }, + { + "id": "5392acee-b504-4720-95fa-dab585acb607", + "resourceBookingId": "0a6799d7-f5d1-456b-8bf1-90619284b295", + "userHandle": "aaaa", + "projectId": 111, + "startDate": "2021-03-07", + "endDate": "2021-03-13", + "daysWorked": 5, + "memberRate": 14.77, + "customerRate": 26.72, + "paymentStatus": "pending", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-21T20:24:52.693Z", + "updatedAt": null + }, + { + "id": "1bbc86c8-8c74-4d78-9706-25c4c99721f3", + "resourceBookingId": "35e1abd8-1890-4664-bb52-aade382d7b66", + "userHandle": "lakshmiaconnmgr", + "projectId": 111, + "startDate": "2021-03-21", + "endDate": "2021-03-27", + "daysWorked": 5, + "memberRate": 3.62, + "customerRate": 25.9, + "paymentStatus": "pending", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-21T20:24:52.695Z", + "updatedAt": null + }, + { + "id": "8b7b49de-29b1-4a0c-bb67-e70cc700fcfd", + "resourceBookingId": "51b45f5d-5df2-46d5-9c3d-8a1323df38dd", + "userHandle": "amy_admin", + "projectId": 111, + "startDate": "2021-04-25", + "endDate": "2021-05-01", + "daysWorked": 5, + "memberRate": 24.68, + "customerRate": 23.15, + "paymentStatus": "pending", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-21T20:24:52.704Z", + "updatedAt": null + }, + { + "id": "b8a8b558-0cb9-46d0-ba9d-2222f3fbdb63", + "resourceBookingId": "dc4477ec-07f8-4c8e-a8fe-ffe38dd290fa", + "userHandle": "nskumar278", + "projectId": 111, + "startDate": "2021-09-05", + "endDate": "2021-09-11", + "daysWorked": 5, + "memberRate": 27.42, + "customerRate": 27.91, + "paymentStatus": "pending", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-21T20:24:52.703Z", + "updatedAt": null + }, + { + "id": "f70509c0-baed-4ff1-8022-12441251f7af", + "resourceBookingId": "51b45f5d-5df2-46d5-9c3d-8a1323df38dd", + "userHandle": "amy_admin", + "projectId": 111, + "startDate": "2021-03-14", + "endDate": "2021-03-20", + "daysWorked": 2, + "memberRate": 30.24, + "customerRate": 9.88, + "paymentStatus": "pending", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-21T20:24:52.704Z", + "updatedAt": null + }, + { + "id": "da8abd64-2878-4e09-b3b1-41a27a0576d4", + "resourceBookingId": "dc4477ec-07f8-4c8e-a8fe-ffe38dd290fa", + "userHandle": "nskumar278", + "projectId": 111, + "startDate": "2021-09-12", + "endDate": "2021-09-18", + "daysWorked": 5, + "memberRate": 16.86, + "customerRate": 4.05, + "paymentStatus": "pending", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-21T20:24:52.703Z", + "updatedAt": null + }, + { + "id": "b5261ee2-bc4d-4c3a-9d30-6703bfdcfbc5", + "resourceBookingId": "51b45f5d-5df2-46d5-9c3d-8a1323df38dd", + "userHandle": "amy_admin", + "projectId": 111, + "startDate": "2021-05-23", + "endDate": "2021-05-29", + "daysWorked": 5, + "memberRate": 24.68, + "customerRate": 27.91, + "paymentStatus": "completed", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-21T20:24:52.704Z", + "updatedAt": null + }, + { + "id": "829165cb-0150-48e7-995c-f5b4d1a51d3b", + "resourceBookingId": "dc4477ec-07f8-4c8e-a8fe-ffe38dd290fa", + "userHandle": "nskumar278", + "projectId": 111, + "startDate": "2021-09-26", + "endDate": "2021-10-02", + "daysWorked": 1, + "memberRate": 4.8, + "customerRate": 10.59, + "paymentStatus": "pending", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-21T20:24:52.703Z", + "updatedAt": null + }, + { + "id": "2430fb35-826a-4e9f-8fb6-8dbcb035d505", + "resourceBookingId": "dc4477ec-07f8-4c8e-a8fe-ffe38dd290fa", + "userHandle": "nskumar278", + "projectId": 111, + "startDate": "2021-08-22", + "endDate": "2021-08-28", + "daysWorked": 5, + "memberRate": 6.18, + "customerRate": 4.05, + "paymentStatus": "pending", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-21T20:24:52.703Z", + "updatedAt": null + }, + { + "id": "c7ff2acc-a4c2-4e8b-a905-813dd9d1b293", + "resourceBookingId": "35e1abd8-1890-4664-bb52-aade382d7b66", + "userHandle": "lakshmiaconnmgr", + "projectId": 111, + "startDate": "2021-03-28", + "endDate": "2021-04-03", + "daysWorked": 4, + "memberRate": 24.46, + "customerRate": 4.05, + "paymentStatus": "pending", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-21T20:24:52.695Z", + "updatedAt": null + }, + { + "id": "731db5d7-bb79-45f4-b1b2-9f60d30f7966", + "resourceBookingId": "08f5e4b9-1088-496d-91a7-5b22a3583e3c", + "userHandle": "ritesh_cs", + "projectId": 111, + "startDate": "2021-01-31", + "endDate": "2021-02-06", + "daysWorked": 0, + "memberRate": 27.42, + "customerRate": 4.4, + "paymentStatus": "pending", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-21T20:24:52.775Z", + "updatedAt": null + }, + { + "id": "b682660e-488e-4033-aaf3-ef37248abc90", + "resourceBookingId": "0a6799d7-f5d1-456b-8bf1-90619284b295", + "userHandle": "aaaa", + "projectId": 111, + "startDate": "2021-02-21", + "endDate": "2021-02-27", + "daysWorked": 0, + "memberRate": 24.46, + "customerRate": 2.55, + "paymentStatus": "pending", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-21T20:24:52.693Z", + "updatedAt": null + }, + { + "id": "b4566e24-4fa8-4e82-9950-f62134bb00df", + "resourceBookingId": "dc4477ec-07f8-4c8e-a8fe-ffe38dd290fa", + "userHandle": "nskumar278", + "projectId": 111, + "startDate": "2021-08-29", + "endDate": "2021-09-04", + "daysWorked": 5, + "memberRate": 4.8, + "customerRate": 4.4, + "paymentStatus": "pending", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-21T20:24:52.703Z", + "updatedAt": null + }, + { + "id": "584c931b-da72-416e-a011-eac5fe34f42f", + "resourceBookingId": "dc4477ec-07f8-4c8e-a8fe-ffe38dd290fa", + "userHandle": "nskumar278", + "projectId": 111, + "startDate": "2021-07-25", + "endDate": "2021-07-31", + "daysWorked": 4, + "memberRate": 14.77, + "customerRate": 4.4, + "paymentStatus": "pending", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-21T20:24:52.703Z", + "updatedAt": null + }, + { + "id": "703bc625-9144-4a9f-a91b-445e171d8ea9", + "resourceBookingId": "dc4477ec-07f8-4c8e-a8fe-ffe38dd290fa", + "userHandle": "nskumar278", + "projectId": 111, + "startDate": "2021-09-19", + "endDate": "2021-09-25", + "daysWorked": 5, + "memberRate": 27.42, + "customerRate": 5.77, + "paymentStatus": "pending", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-21T20:24:52.703Z", + "updatedAt": null + }, + { + "id": "c9685cb2-9f4a-497e-ae99-deed7b16cc34", + "resourceBookingId": "35e1abd8-1890-4664-bb52-aade382d7b66", + "userHandle": "lakshmiaconnmgr", + "projectId": 111, + "startDate": "2021-03-07", + "endDate": "2021-03-13", + "daysWorked": 5, + "memberRate": 14.77, + "customerRate": 16.55, + "paymentStatus": "completed", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-21T20:24:52.695Z", + "updatedAt": null + }, + { + "id": "428fec88-b305-4816-b5ef-be2b4e91c21a", + "resourceBookingId": "7d967fed-9792-4768-98a7-0b644aa84f2e", + "userHandle": "sachin-wipro", + "projectId": 111, + "startDate": "2021-04-04", + "endDate": "2021-04-10", + "daysWorked": 5, + "memberRate": 8.55, + "customerRate": 16.55, + "paymentStatus": "pending", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-21T20:24:52.705Z", + "updatedAt": null + }, + { + "id": "374e2065-40cb-4651-a55c-81a0675dc00d", + "resourceBookingId": "8173579e-4b3c-418d-a9a1-c999caa38404", + "userHandle": "testcat", + "projectId": 111, + "startDate": "2020-05-17", + "endDate": "2020-05-23", + "daysWorked": 5, + "memberRate": 16.86, + "customerRate": 1.89, + "paymentStatus": "pending", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-21T20:24:52.806Z", + "updatedAt": null + }, + { + "id": "4bfdc253-e39a-4cfa-9a45-2cfc6e93cc6f", + "resourceBookingId": "61f5d474-e41f-490b-ab58-9f983e3d4916", + "userHandle": "sonu628", + "projectId": 111, + "startDate": "2000-04-16", + "endDate": "2000-04-22", + "daysWorked": 5, + "memberRate": 20.16, + "customerRate": 13.92, + "paymentStatus": "pending", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-21T20:24:52.858Z", + "updatedAt": null + }, + { + "id": "0ba1a0b3-7bee-4fe6-9083-d36d8ca9d052", + "resourceBookingId": "35e1abd8-1890-4664-bb52-aade382d7b66", + "userHandle": "lakshmiaconnmgr", + "projectId": 111, + "startDate": "2021-03-14", + "endDate": "2021-03-20", + "daysWorked": 5, + "memberRate": 24.46, + "customerRate": 1.44, + "paymentStatus": "pending", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-21T20:24:52.695Z", + "updatedAt": null + }, + { + "id": "6da7d347-7492-43b1-a49d-8a6e1daf9b22", + "resourceBookingId": "51b45f5d-5df2-46d5-9c3d-8a1323df38dd", + "userHandle": "amy_admin", + "projectId": 111, + "startDate": "2021-04-18", + "endDate": "2021-04-24", + "daysWorked": 5, + "memberRate": 25.21, + "customerRate": 1.44, + "paymentStatus": "pending", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-21T20:24:52.704Z", + "updatedAt": null + }, + { + "id": "8c8cedf3-0bb6-4063-8a3a-faf1626da384", + "resourceBookingId": "61f5d474-e41f-490b-ab58-9f983e3d4916", + "userHandle": "sonu628", + "projectId": 111, + "startDate": "2000-04-09", + "endDate": "2000-04-15", + "daysWorked": 5, + "memberRate": 14.77, + "customerRate": 4.95, + "paymentStatus": "pending", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-21T20:24:52.858Z", + "updatedAt": null + }, + { + "id": "10394696-47f4-4761-8d14-ffdf012cde23", + "resourceBookingId": "d38a6223-3f91-4300-9ecb-6e5fee173625", + "userHandle": "nithyaasworld", + "projectId": 111, + "startDate": "2021-07-25", + "endDate": "2021-07-31", + "daysWorked": 5, + "memberRate": 3.62, + "customerRate": 4.95, + "paymentStatus": "pending", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-21T20:24:52.706Z", + "updatedAt": null + }, + { + "id": "64de2244-6fcf-45ac-8a89-a9b3420e4476", + "resourceBookingId": "7d967fed-9792-4768-98a7-0b644aa84f2e", + "userHandle": "sachin-wipro", + "projectId": 111, + "startDate": "2021-04-18", + "endDate": "2021-04-24", + "daysWorked": 5, + "memberRate": 22.57, + "customerRate": 18.23, + "paymentStatus": "pending", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-21T20:24:52.705Z", + "updatedAt": null + }, + { + "id": "2cbe3836-5961-4d58-b8f7-44b84ddf3fc5", + "resourceBookingId": "7d967fed-9792-4768-98a7-0b644aa84f2e", + "userHandle": "sachin-wipro", + "projectId": 111, + "startDate": "2021-04-11", + "endDate": "2021-04-17", + "daysWorked": 5, + "memberRate": 25.21, + "customerRate": 2.64, + "paymentStatus": "pending", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-21T20:24:52.705Z", + "updatedAt": null + }, + { + "id": "bc8611f0-4ac2-49b2-b776-59ed2b759d1d", + "resourceBookingId": "d38a6223-3f91-4300-9ecb-6e5fee173625", + "userHandle": "nithyaasworld", + "projectId": 111, + "startDate": "2021-07-04", + "endDate": "2021-07-10", + "daysWorked": 5, + "memberRate": 16.86, + "customerRate": 5.77, + "paymentStatus": "pending", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-21T20:24:52.706Z", + "updatedAt": null + }, + { + "id": "9b6fc85b-3694-4e6c-9ebf-fe9ccf7881ba", + "resourceBookingId": "d38a6223-3f91-4300-9ecb-6e5fee173625", + "userHandle": "nithyaasworld", + "projectId": 111, + "startDate": "2021-06-13", + "endDate": "2021-06-19", + "daysWorked": 5, + "memberRate": 14.77, + "customerRate": 15.86, + "paymentStatus": "pending", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-21T20:24:52.706Z", + "updatedAt": null + }, + { + "id": "4a2c581f-c626-44cb-8ada-58f0172e8b4d", + "resourceBookingId": "d38a6223-3f91-4300-9ecb-6e5fee173625", + "userHandle": "nithyaasworld", + "projectId": 111, + "startDate": "2021-05-30", + "endDate": "2021-06-05", + "daysWorked": 5, + "memberRate": 28.76, + "customerRate": 15.49, + "paymentStatus": "pending", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-21T20:24:52.706Z", + "updatedAt": null + }, + { + "id": "90d99323-ba57-4a18-b50f-78f387033c70", + "resourceBookingId": "61f5d474-e41f-490b-ab58-9f983e3d4916", + "userHandle": "sonu628", + "projectId": 111, + "startDate": "2000-04-02", + "endDate": "2000-04-08", + "daysWorked": 5, + "memberRate": 24.46, + "customerRate": 25.9, + "paymentStatus": "completed", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-21T20:24:52.858Z", + "updatedAt": null + }, + { + "id": "5ddc132b-3205-45e3-bfe9-f1a4f939885e", + "resourceBookingId": "51b45f5d-5df2-46d5-9c3d-8a1323df38dd", + "userHandle": "amy_admin", + "projectId": 111, + "startDate": "2021-03-21", + "endDate": "2021-03-27", + "daysWorked": 5, + "memberRate": 21.53, + "customerRate": 25.9, + "paymentStatus": "completed", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-21T20:24:52.704Z", + "updatedAt": null + }, + { + "id": "437d4281-43ec-4de3-85e4-51d298388ce5", + "resourceBookingId": "0a6799d7-f5d1-456b-8bf1-90619284b295", + "userHandle": "aaaa", + "projectId": 111, + "startDate": "2021-02-28", + "endDate": "2021-03-06", + "daysWorked": 5, + "memberRate": 26.19, + "customerRate": 28.03, + "paymentStatus": "completed", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-21T20:24:52.693Z", + "updatedAt": null + }, + { + "id": "a35bb205-361b-4b2d-9828-55501ae9d190", + "resourceBookingId": "d38a6223-3f91-4300-9ecb-6e5fee173625", + "userHandle": "nithyaasworld", + "projectId": 111, + "startDate": "2021-07-11", + "endDate": "2021-07-17", + "daysWorked": 5, + "memberRate": 27.42, + "customerRate": 28.03, + "paymentStatus": "pending", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-21T20:24:52.706Z", + "updatedAt": null + }, + { + "id": "40ae1e8f-24be-4b51-885c-51f08e15f0df", + "resourceBookingId": "08f5e4b9-1088-496d-91a7-5b22a3583e3c", + "userHandle": "ritesh_cs", + "projectId": 111, + "startDate": "2021-01-24", + "endDate": "2021-01-30", + "daysWorked": 5, + "memberRate": 16.86, + "customerRate": 28.03, + "paymentStatus": "pending", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-21T20:24:52.775Z", + "updatedAt": null + }, + { + "id": "e19bddc5-38ac-43c9-8273-bc9069de26b3", + "resourceBookingId": "61f5d474-e41f-490b-ab58-9f983e3d4916", + "userHandle": "sonu628", + "projectId": 111, + "startDate": "2000-04-23", + "endDate": "2000-04-29", + "daysWorked": 5, + "memberRate": 6.18, + "customerRate": 9.12, + "paymentStatus": "pending", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-21T20:24:52.858Z", + "updatedAt": null + }, + { + "id": "bf61dad8-841a-4913-93f6-b2ae516b8b11", + "resourceBookingId": "d38a6223-3f91-4300-9ecb-6e5fee173625", + "userHandle": "nithyaasworld", + "projectId": 111, + "startDate": "2021-06-06", + "endDate": "2021-06-12", + "daysWorked": 5, + "memberRate": 6.18, + "customerRate": 4.4, + "paymentStatus": "pending", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-21T20:24:52.706Z", + "updatedAt": null + }, + { + "id": "93b0f03b-219b-41d5-bb1e-f125651b1b0e", + "resourceBookingId": "8173579e-4b3c-418d-a9a1-c999caa38404", + "userHandle": "testcat", + "projectId": 111, + "startDate": "2020-05-03", + "endDate": "2020-05-09", + "daysWorked": 5, + "memberRate": 24.46, + "customerRate": 1.89, + "paymentStatus": "pending", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-21T20:24:52.806Z", + "updatedAt": null + }, + { + "id": "93e69f99-cb1c-418e-aa41-ab2181b4bcfd", + "resourceBookingId": "d38a6223-3f91-4300-9ecb-6e5fee173625", + "userHandle": "nithyaasworld", + "projectId": 111, + "startDate": "2021-06-27", + "endDate": "2021-07-03", + "daysWorked": 5, + "memberRate": 17.2, + "customerRate": 13.92, + "paymentStatus": "pending", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-21T20:24:52.706Z", + "updatedAt": null + }, + { + "id": "619a0835-730f-47ec-820e-3959821aec51", + "resourceBookingId": "7d967fed-9792-4768-98a7-0b644aa84f2e", + "userHandle": "sachin-wipro", + "projectId": 111, + "startDate": "2021-05-30", + "endDate": "2021-06-05", + "daysWorked": 1, + "memberRate": 4.8, + "customerRate": 13.92, + "paymentStatus": "pending", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-21T20:24:52.705Z", + "updatedAt": null + }, + { + "id": "558b4685-4932-492e-99e1-2830c10f8275", + "resourceBookingId": "7d967fed-9792-4768-98a7-0b644aa84f2e", + "userHandle": "sachin-wipro", + "projectId": 111, + "startDate": "2021-04-25", + "endDate": "2021-05-01", + "daysWorked": 5, + "memberRate": 4.8, + "customerRate": 13.92, + "paymentStatus": "pending", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-21T20:24:52.705Z", + "updatedAt": null + }, + { + "id": "84431dac-019d-4987-9817-15f5f000d2db", + "resourceBookingId": "61f5d474-e41f-490b-ab58-9f983e3d4916", + "userHandle": "sonu628", + "projectId": 111, + "startDate": "2000-03-26", + "endDate": "2000-04-01", + "daysWorked": 5, + "memberRate": 27.42, + "customerRate": 4.05, + "paymentStatus": "partially-completed", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-21T20:24:52.858Z", + "updatedAt": null + }, + { + "id": "f575df2d-f170-4251-9042-b17ca5e99ca5", + "resourceBookingId": "51b45f5d-5df2-46d5-9c3d-8a1323df38dd", + "userHandle": "amy_admin", + "projectId": 111, + "startDate": "2021-05-02", + "endDate": "2021-05-08", + "daysWorked": 5, + "memberRate": 4.82, + "customerRate": 4.05, + "paymentStatus": "completed", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-21T20:24:52.704Z", + "updatedAt": null + }, + { + "id": "3829c216-ef3f-466c-93da-3a88a961442f", + "resourceBookingId": "51b45f5d-5df2-46d5-9c3d-8a1323df38dd", + "userHandle": "amy_admin", + "projectId": 111, + "startDate": "2021-05-09", + "endDate": "2021-05-15", + "daysWorked": 5, + "memberRate": 6.18, + "customerRate": 4.4, + "paymentStatus": "cancelled", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-21T20:24:52.704Z", + "updatedAt": null + }, + { + "id": "bd54bcaf-5278-467f-a166-865048774d0e", + "resourceBookingId": "a098e8d8-ce5b-47d9-afee-38b050d16745", + "userHandle": "TCConnCopilot", + "projectId": 111, + "startDate": "2021-04-25", + "endDate": "2021-05-01", + "daysWorked": 5, + "memberRate": 16.86, + "customerRate": 1.89, + "paymentStatus": "partially-completed", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-21T20:24:52.696Z", + "updatedAt": null + }, + { + "id": "7f8f3a25-b1d2-4e36-a543-fcaae57a32f5", + "resourceBookingId": "dc4477ec-07f8-4c8e-a8fe-ffe38dd290fa", + "userHandle": "nskumar278", + "projectId": 111, + "startDate": "2021-08-15", + "endDate": "2021-08-21", + "daysWorked": 5, + "memberRate": 8.13, + "customerRate": 1.89, + "paymentStatus": "cancelled", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-21T20:24:52.703Z", + "updatedAt": null + }, + { + "id": "6e1dc024-d437-4d9f-92e9-561db713a19a", + "resourceBookingId": "dc4477ec-07f8-4c8e-a8fe-ffe38dd290fa", + "userHandle": "nskumar278", + "projectId": 111, + "startDate": "2021-08-08", + "endDate": "2021-08-14", + "daysWorked": 5, + "memberRate": 3.62, + "customerRate": 18.14, + "paymentStatus": "partially-completed", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-21T20:24:52.703Z", + "updatedAt": null + }, + { + "id": "c5f6ae8f-2976-46d1-bd66-58eeb58ca045", + "resourceBookingId": "d38a6223-3f91-4300-9ecb-6e5fee173625", + "userHandle": "nithyaasworld", + "projectId": 111, + "startDate": "2021-06-20", + "endDate": "2021-06-26", + "daysWorked": 5, + "memberRate": 25.41, + "customerRate": 13.92, + "paymentStatus": "cancelled", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-21T20:24:52.706Z", + "updatedAt": null + }, + { + "id": "0f480aa7-1c5d-42fe-aad6-c774e58c2e17", + "resourceBookingId": "7d967fed-9792-4768-98a7-0b644aa84f2e", + "userHandle": "sachin-wipro", + "projectId": 111, + "startDate": "2021-05-09", + "endDate": "2021-05-15", + "daysWorked": 5, + "memberRate": 4.82, + "customerRate": 4.95, + "paymentStatus": "cancelled", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-21T20:24:52.705Z", + "updatedAt": null + }, + { + "id": "098ca553-6ea4-4cae-a18e-762f47e93d82", + "resourceBookingId": "51b45f5d-5df2-46d5-9c3d-8a1323df38dd", + "userHandle": "amy_admin", + "projectId": 111, + "startDate": "2021-05-16", + "endDate": "2021-05-22", + "daysWorked": 5, + "memberRate": 3.96, + "customerRate": 4.95, + "paymentStatus": "completed", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-21T20:24:52.704Z", + "updatedAt": null + }, + { + "id": "729a2396-2b33-4185-8ce8-d929dbf4a472", + "resourceBookingId": "7d967fed-9792-4768-98a7-0b644aa84f2e", + "userHandle": "sachin-wipro", + "projectId": 111, + "startDate": "2021-05-23", + "endDate": "2021-05-29", + "daysWorked": 5, + "memberRate": 17.2, + "customerRate": 4.95, + "paymentStatus": "completed", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-21T20:24:52.705Z", + "updatedAt": null + }, + { + "id": "9bfbd49a-e6bb-45c3-965d-ed4f95f0878a", + "resourceBookingId": "d38a6223-3f91-4300-9ecb-6e5fee173625", + "userHandle": "nithyaasworld", + "projectId": 111, + "startDate": "2021-07-18", + "endDate": "2021-07-24", + "daysWorked": 5, + "memberRate": 23.35, + "customerRate": 5.77, + "paymentStatus": "completed", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-21T20:24:52.706Z", + "updatedAt": null + }, + { + "id": "dcc310cf-ea4a-4637-9bf5-5baaabea67b3", + "resourceBookingId": "d38a6223-3f91-4300-9ecb-6e5fee173625", + "userHandle": "nithyaasworld", + "projectId": 111, + "startDate": "2021-05-23", + "endDate": "2021-05-29", + "daysWorked": 4, + "memberRate": 14.77, + "customerRate": 1.44, + "paymentStatus": "partially-completed", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-21T20:24:52.706Z", + "updatedAt": null + }, + { + "id": "309f65e8-b0b5-4cbb-ba60-9b36ccba4bd5", + "resourceBookingId": "51b45f5d-5df2-46d5-9c3d-8a1323df38dd", + "userHandle": "amy_admin", + "projectId": 111, + "startDate": "2021-04-11", + "endDate": "2021-04-17", + "daysWorked": 5, + "memberRate": 14.77, + "customerRate": 15.49, + "paymentStatus": "completed", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-21T20:24:52.704Z", + "updatedAt": null + }, + { + "id": "1e2c732e-ac1f-47ad-939b-22b2078124e5", + "resourceBookingId": "7d967fed-9792-4768-98a7-0b644aa84f2e", + "userHandle": "sachin-wipro", + "projectId": 111, + "startDate": "2021-03-28", + "endDate": "2021-04-03", + "daysWorked": 5, + "memberRate": 17.2, + "customerRate": 15.49, + "paymentStatus": "partially-completed", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-21T20:24:52.705Z", + "updatedAt": null + }, + { + "id": "2463003f-ee60-4aba-b989-b63babcd9b8b", + "resourceBookingId": "7d967fed-9792-4768-98a7-0b644aa84f2e", + "userHandle": "sachin-wipro", + "projectId": 111, + "startDate": "2021-05-02", + "endDate": "2021-05-08", + "daysWorked": 5, + "memberRate": 4.8, + "customerRate": 15.49, + "paymentStatus": "cancelled", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-21T20:24:52.705Z", + "updatedAt": null + }, + { + "id": "6a1180b8-38af-4bd0-8a5f-a60626e0bc95", + "resourceBookingId": "8173579e-4b3c-418d-a9a1-c999caa38404", + "userHandle": "testcat", + "projectId": 111, + "startDate": "2020-04-26", + "endDate": "2020-05-02", + "daysWorked": 5, + "memberRate": 26.19, + "customerRate": 28.03, + "paymentStatus": "completed", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-21T20:24:52.806Z", + "updatedAt": null + }, + { + "id": "b21f921a-4b23-423d-814b-d31f5cba7f64", + "resourceBookingId": "35e1abd8-1890-4664-bb52-aade382d7b66", + "userHandle": "lakshmiaconnmgr", + "projectId": 111, + "startDate": "2021-02-21", + "endDate": "2021-02-27", + "daysWorked": 2, + "memberRate": 15.77, + "customerRate": 28.03, + "paymentStatus": "partially-completed", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-21T20:24:52.695Z", + "updatedAt": null + }, + { + "id": "4db82b0b-4d6f-4e9a-b957-ab405b2c2df2", + "resourceBookingId": "8173579e-4b3c-418d-a9a1-c999caa38404", + "userHandle": "testcat", + "projectId": 111, + "startDate": "2020-05-10", + "endDate": "2020-05-16", + "daysWorked": 5, + "memberRate": 24.46, + "customerRate": 28.03, + "paymentStatus": "partially-completed", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-21T20:24:52.806Z", + "updatedAt": null + } + ], + "WorkPeriodPayment": [ + { + "id": "2c488b36-0868-4db6-8978-20b1ce174496", + "workPeriodId": "07783b60-b726-41c2-8955-7766a27c1ec5", + "challengeId": "0de972b8-6cc9-4625-9760-1c77561c29e9", + "amount": 200, + "status": "completed", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-04-14T19:13:23.714Z", + "updatedAt": "2021-04-21T20:19:56.934Z" + }, + { + "id": "d0f61c2d-271c-48b2-8416-50c1c32ad32b", + "workPeriodId": "098ca553-6ea4-4cae-a18e-762f47e93d82", + "challengeId": "aa8c1945-904c-42a7-9b00-1e4f9a49dcdb", + "amount": 450, + "status": "completed", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-04-14T22:01:45.361Z", + "updatedAt": "2021-04-21T20:19:56.934Z" + }, + { + "id": "90bb43bd-d9e7-4eab-a46b-ab03338be11a", + "workPeriodId": "0ba1a0b3-7bee-4fe6-9083-d36d8ca9d052", + "challengeId": "8b6f4040-d7ae-4264-b60b-b1171c9365e4", + "amount": 400, + "status": "completed", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-04-14T22:01:45.390Z", + "updatedAt": "2021-04-21T20:19:56.934Z" + }, + { + "id": "58681a3e-2266-4153-afd5-7be218966da2", + "workPeriodId": "0f480aa7-1c5d-42fe-aad6-c774e58c2e17", + "challengeId": "2bafdd9a-ab4a-4624-8a06-7b1adfb8dac2", + "amount": 1200, + "status": "completed", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-04-14T22:01:45.326Z", + "updatedAt": "2021-04-21T20:19:56.934Z" + }, + { + "id": "b342d615-d36d-48b2-a3e8-1f498b58ab68", + "workPeriodId": "10394696-47f4-4761-8d14-ffdf012cde23", + "challengeId": "0de972b8-6cc9-4625-9760-1c77561c29e9", + "amount": 400, + "status": "completed", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-04-16T19:13:23.714Z", + "updatedAt": "2021-04-21T20:19:56.934Z" + }, + { + "id": "63cec011-7714-4ab6-944f-e76b9fa2bd1a", + "workPeriodId": "18a73600-5ee8-484b-9747-70ea80ce2bd9", + "challengeId": "1bdf092e-e117-4d42-bb5d-e49816171c0d", + "amount": 500, + "status": "completed", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-04-14T22:01:45.523Z", + "updatedAt": "2021-04-21T20:19:56.934Z" + }, + { + "id": "8a0c0877-b88a-420b-a3f7-645c18793b4b", + "workPeriodId": "1b633124-f62c-4026-b679-213cf5812689", + "challengeId": "4332acc6-3a33-4b7b-af4c-bd2c1ffcfb8e", + "amount": 1400, + "status": "completed", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-04-14T22:01:45.325Z", + "updatedAt": "2021-04-21T20:19:56.934Z" + }, + { + "id": "04ef47ac-8f4d-402f-b9fd-48b2b1d9003d", + "workPeriodId": "1bbc86c8-8c74-4d78-9706-25c4c99721f3", + "challengeId": "fa909769-f5f7-41fb-94bb-80db62e21a5e", + "amount": 800, + "status": "cancelled", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-04-14T22:01:45.326Z", + "updatedAt": "2021-04-21T20:19:56.934Z" + }, + { + "id": "84c1c956-e03d-4e19-a5a8-a4086c9658eb", + "workPeriodId": "1e2c732e-ac1f-47ad-939b-22b2078124e5", + "challengeId": "604910b2-7644-4b9d-a185-0054e61c83fc", + "amount": 1800, + "status": "completed", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-04-14T22:01:45.324Z", + "updatedAt": "2021-04-21T20:19:56.934Z" + }, + { + "id": "c051c3da-34bb-4deb-8921-04e5d2fa0bcc", + "workPeriodId": "2430fb35-826a-4e9f-8fb6-8dbcb035d505", + "challengeId": "25fd805c-49cd-443f-ba0d-813c33a6d8ad", + "amount": 400, + "status": "completed", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-04-14T22:01:45.390Z", + "updatedAt": "2021-04-21T20:19:56.934Z" + }, + { + "id": "cc13acfd-fc06-40e5-aefe-5050429ee4f2", + "workPeriodId": "2463003f-ee60-4aba-b989-b63babcd9b8b", + "challengeId": "0de972b8-6cc9-4625-9760-1c77561c29e9", + "amount": 1200, + "status": "completed", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-04-14T19:13:23.714Z", + "updatedAt": "2021-04-21T20:19:56.934Z" + }, + { + "id": "58c6431a-061a-41bd-a3bd-c8effba62e11", + "workPeriodId": "2cbe3836-5961-4d58-b8f7-44b84ddf3fc5", + "challengeId": "0de972b8-6cc9-4625-9760-1c77561c29e9", + "amount": 900, + "status": "completed", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-04-14T19:13:23.714Z", + "updatedAt": "2021-04-21T20:19:56.934Z" + }, + { + "id": "efe0e4b5-e6dd-4c1a-a0e5-1f5e0ff91df9", + "workPeriodId": "309f65e8-b0b5-4cbb-ba60-9b36ccba4bd5", + "challengeId": "01332fa9-0505-416d-9084-39b136dbd300", + "amount": 1200, + "status": "completed", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-04-14T22:01:45.390Z", + "updatedAt": "2021-04-21T20:19:56.934Z" + }, + { + "id": "298ac627-e6d7-47b0-ad1d-83de291addf7", + "workPeriodId": "30c89d78-df85-44ed-92b2-b683d8960fc2", + "challengeId": "f7e40a0c-a302-4989-a3bd-7587fee3c367", + "amount": 300, + "status": "cancelled", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "createdAt": "2021-04-14T19:13:23.714Z", + "updatedAt": "2021-04-16T19:13:23.714Z" + }, + { + "id": "bf80eca9-8323-4f96-9a3b-8553d6f1e0ce", + "workPeriodId": "374e2065-40cb-4651-a55c-81a0675dc00d", + "challengeId": "03c69d02-9188-436e-b4c9-08f39e46f413", + "amount": 800, + "status": "completed", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-04-14T22:01:45.390Z", + "updatedAt": "2021-04-21T20:19:56.934Z" + }, + { + "id": "338d2d7d-2c59-4513-b560-55e8982fd7c7", + "workPeriodId": "3829c216-ef3f-466c-93da-3a88a961442f", + "challengeId": "2a0db660-def2-4117-90e8-01cd1271c726", + "amount": 1400, + "status": "completed", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-04-14T22:01:45.390Z", + "updatedAt": "2021-04-21T20:19:56.934Z" + }, + { + "id": "491f6e93-e80f-46eb-9637-ee84fe7ace9b", + "workPeriodId": "40ae1e8f-24be-4b51-885c-51f08e15f0df", + "challengeId": "c2b7a2cc-4633-4f3a-ab39-f7122a6890b6", + "amount": 1600, + "status": "completed", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-04-14T22:01:45.390Z", + "updatedAt": "2021-04-21T20:19:56.934Z" + }, + { + "id": "cb94d710-fa3c-4333-b8a9-39ec053a665d", + "workPeriodId": "428fec88-b305-4816-b5ef-be2b4e91c21a", + "challengeId": "93f594e9-5396-416a-8212-87bee614a38f", + "amount": 1200, + "status": "completed", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-04-14T19:13:23.714Z", + "updatedAt": "2021-04-21T20:19:56.934Z" + }, + { + "id": "155eaab2-ef74-484c-b1d7-6534dde58b66", + "workPeriodId": "437d4281-43ec-4de3-85e4-51d298388ce5", + "challengeId": "5ba2d9df-b3ba-4f5f-bee5-228eb46b2c37", + "amount": 600, + "status": "completed", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-04-14T22:01:45.361Z", + "updatedAt": "2021-04-21T20:19:56.934Z" + }, + { + "id": "11c07a5c-a077-4719-83ba-c48db7e63c01", + "workPeriodId": "442b0543-e887-42be-9ff5-5fee825526be", + "challengeId": "d7c21199-a435-41b8-a2ac-5e5bdd021c5e", + "amount": 1400, + "status": "cancelled", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-04-14T19:13:23.714Z", + "updatedAt": "2021-04-21T20:19:56.934Z" + }, + { + "id": "4ce8cf4a-2585-4454-81d4-e5446c9a3f75", + "workPeriodId": "4a2c581f-c626-44cb-8ada-58f0172e8b4d", + "challengeId": "ee9bcdd0-0d0d-4414-88cb-d14255f996a5", + "amount": 350, + "status": "completed", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "createdAt": "2021-04-14T19:13:23.714Z", + "updatedAt": "2021-04-16T19:13:23.714Z" + }, + { + "id": "8ff6188f-b4e6-4f6e-b2d4-2a622ae50c4f", + "workPeriodId": "4bfdc253-e39a-4cfa-9a45-2cfc6e93cc6f", + "challengeId": "f151a5a1-6b28-4f59-bdde-6e73498faa84", + "amount": 450, + "status": "cancelled", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-04-14T22:01:45.326Z", + "updatedAt": "2021-04-21T20:19:56.934Z" + }, + { + "id": "5192e519-30f5-42d6-877f-5c2b786d91c7", + "workPeriodId": "4db82b0b-4d6f-4e9a-b957-ab405b2c2df2", + "challengeId": "93f594e9-5396-416a-8212-87bee614a38f", + "amount": 600, + "status": "cancelled", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "createdAt": "2021-04-14T19:13:23.714Z", + "updatedAt": "2021-04-16T19:13:23.714Z" + }, + { + "id": "8ca85158-a850-4cae-97f0-5873a9225ff8", + "workPeriodId": "531754f3-405e-42eb-932a-c1ce7b9386e7", + "challengeId": "b42b8f40-9a4d-45d1-814e-59da5c7a1fd9", + "amount": 1200, + "status": "completed", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-04-14T19:13:23.714Z", + "updatedAt": "2021-04-21T20:19:56.934Z" + }, + { + "id": "4a81c6a3-18d9-441b-ae64-3aa9def336ef", + "workPeriodId": "5392acee-b504-4720-95fa-dab585acb607", + "challengeId": "78154e5c-feed-4dbf-84ec-775395139211", + "amount": 200, + "status": "completed", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "createdAt": "2021-04-14T19:13:23.714Z", + "updatedAt": "2021-04-16T19:13:23.714Z" + }, + { + "id": "a26b8cae-a1df-4843-a192-0735f235bf78", + "workPeriodId": "558b4685-4932-492e-99e1-2830c10f8275", + "challengeId": "0de972b8-6cc9-4625-9760-1c77561c29e9", + "amount": 600, + "status": "completed", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-04-14T19:13:23.714Z", + "updatedAt": "2021-04-21T20:19:56.934Z" + }, + { + "id": "a94b6f43-de89-4fd2-9a1d-d8a2cce02702", + "workPeriodId": "584c931b-da72-416e-a011-eac5fe34f42f", + "challengeId": "d55fae30-3072-462e-b8bd-eb2eec664e65", + "amount": 1600, + "status": "completed", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-04-14T22:01:45.324Z", + "updatedAt": "2021-04-21T20:19:56.934Z" + }, + { + "id": "eb63dfc7-14d7-4cae-a25e-3e33a04601cf", + "workPeriodId": "5ddc132b-3205-45e3-bfe9-f1a4f939885e", + "challengeId": "0de972b8-6cc9-4625-9760-1c77561c29e9", + "amount": 300, + "status": "completed", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-04-14T19:13:23.714Z", + "updatedAt": "2021-04-21T20:19:56.934Z" + }, + { + "id": "d827ed01-5153-4774-8450-bace2521a6d1", + "workPeriodId": "619a0835-730f-47ec-820e-3959821aec51", + "challengeId": "d40cb9c5-b3bd-45a1-802c-a50fefb020b9", + "amount": 1000, + "status": "completed", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-04-14T22:01:45.326Z", + "updatedAt": "2021-04-21T20:19:56.934Z" + }, + { + "id": "f950e52e-5a52-4ee8-af5f-e6c42e9b400b", + "workPeriodId": "64de2244-6fcf-45ac-8a89-a9b3420e4476", + "challengeId": "6c04d456-bb38-43c8-a538-f5cc6caaa540", + "amount": 800, + "status": "completed", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-04-14T19:13:23.714Z", + "updatedAt": "2021-04-21T20:19:56.934Z" + }, + { + "id": "283f9c3b-7f0a-4792-9661-ced7cbdb340d", + "workPeriodId": "6a1180b8-38af-4bd0-8a5f-a60626e0bc95", + "challengeId": "9a995b78-0542-41be-a926-f3df57c2f873", + "amount": 400, + "status": "completed", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-04-14T22:01:45.361Z", + "updatedAt": "2021-04-21T20:19:56.934Z" + }, + { + "id": "09ea6f03-4489-496c-817c-e9279a58c0ad", + "workPeriodId": "6da7d347-7492-43b1-a49d-8a6e1daf9b22", + "challengeId": "78154e5c-feed-4dbf-84ec-775395139211", + "amount": 400, + "status": "completed", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-04-14T19:13:23.714Z", + "updatedAt": "2021-04-21T20:19:56.934Z" + }, + { + "id": "7d782624-243e-497b-90ca-cc00ae29ebf2", + "workPeriodId": "6e1dc024-d437-4d9f-92e9-561db713a19a", + "challengeId": "afcbc3bc-9077-4978-bf9c-acddb48e6518", + "amount": 800, + "status": "completed", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-04-14T22:01:45.324Z", + "updatedAt": "2021-04-21T20:19:56.934Z" + }, + { + "id": "11918ff9-5f18-445d-ae90-762b3ebe44ca", + "workPeriodId": "6ed667a5-275e-4f27-984b-34dff5f8a1ff", + "challengeId": "c89d357f-afd1-4757-824f-2cf94e2890c6", + "amount": 250, + "status": "completed", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-04-14T22:01:45.361Z", + "updatedAt": "2021-04-21T20:19:56.934Z" + }, + { + "id": "9fe78619-5c1c-4b22-8d6f-ebf9a9502432", + "workPeriodId": "703bc625-9144-4a9f-a91b-445e171d8ea9", + "challengeId": "6c04d456-bb38-43c8-a538-f5cc6caaa540", + "amount": 400, + "status": "completed", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-04-14T19:13:23.714Z", + "updatedAt": "2021-04-21T20:19:56.934Z" + }, + { + "id": "7cf85ce0-ef8c-4152-8623-9a1325db6daa", + "workPeriodId": "729a2396-2b33-4185-8ce8-d929dbf4a472", + "challengeId": "fbf8efda-fe4b-4b72-99dd-573b79d27bd8", + "amount": 200, + "status": "cancelled", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-04-14T22:01:45.390Z", + "updatedAt": "2021-04-21T20:19:56.934Z" + }, + { + "id": "e8aee371-1f26-4475-8459-9c134fa6f3c6", + "workPeriodId": "731db5d7-bb79-45f4-b1b2-9f60d30f7966", + "challengeId": "ee9bcdd0-0d0d-4414-88cb-d14255f996a5", + "amount": 700, + "status": "cancelled", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-04-14T19:13:23.714Z", + "updatedAt": "2021-04-21T20:19:56.934Z" + }, + { + "id": "dec8615b-c823-4fff-bc77-fa0614b8d09c", + "workPeriodId": "7f8f3a25-b1d2-4e36-a543-fcaae57a32f5", + "challengeId": "fe3e4056-82e3-4df4-b699-a1f3d8ab5e53", + "amount": 700, + "status": "completed", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-04-14T22:01:45.390Z", + "updatedAt": "2021-04-21T20:19:56.934Z" + }, + { + "id": "c4e316ca-a46f-4fbc-96a6-6fe6665c3b49", + "workPeriodId": "829165cb-0150-48e7-995c-f5b4d1a51d3b", + "challengeId": "d937a822-4a9b-40db-afe6-fe1285e3f7f9", + "amount": 900, + "status": "completed", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-04-14T22:01:45.324Z", + "updatedAt": "2021-04-21T20:19:56.934Z" + }, + { + "id": "12b0bcfc-59ae-478c-bb32-cb18d1d0244c", + "workPeriodId": "84431dac-019d-4987-9817-15f5f000d2db", + "challengeId": "a07ea88f-c52b-4023-8730-c4364efd0dd2", + "amount": 600, + "status": "completed", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-04-14T22:01:45.361Z", + "updatedAt": "2021-04-21T20:19:56.934Z" + }, + { + "id": "8c9ed23c-12c7-4a8b-8e91-6fd3b3fc43a4", + "workPeriodId": "8b7b49de-29b1-4a0c-bb67-e70cc700fcfd", + "challengeId": "0de972b8-6cc9-4625-9760-1c77561c29e9", + "amount": 450, + "status": "completed", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-04-14T19:13:23.714Z", + "updatedAt": "2021-04-21T20:19:56.934Z" + }, + { + "id": "621d793b-0ead-4d99-a119-e32af526ece7", + "workPeriodId": "8c8cedf3-0bb6-4063-8a3a-faf1626da384", + "challengeId": "ad04dcee-9a3c-4345-b0b5-783ce98e94b2", + "amount": 900, + "status": "completed", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-04-14T22:01:45.390Z", + "updatedAt": "2021-04-21T20:19:56.934Z" + }, + { + "id": "56cb3aef-531b-4a26-817e-4b9629212c9a", + "workPeriodId": "90d99323-ba57-4a18-b50f-78f387033c70", + "challengeId": "0de972b8-6cc9-4625-9760-1c77561c29e9", + "amount": 450, + "status": "completed", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-04-14T19:13:23.714Z", + "updatedAt": "2021-04-21T20:19:56.934Z" + }, + { + "id": "a1ffc559-703a-4c35-8ba3-73a03c3454af", + "workPeriodId": "93b0f03b-219b-41d5-bb1e-f125651b1b0e", + "challengeId": "9fca67f9-3641-4982-8a82-e86b1850efc8", + "amount": 600, + "status": "completed", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-04-14T22:01:45.326Z", + "updatedAt": "2021-04-21T20:19:56.934Z" + }, + { + "id": "a5904ae3-7524-4709-b798-20c4a2193f10", + "workPeriodId": "93e69f99-cb1c-418e-aa41-ab2181b4bcfd", + "challengeId": "ed56a1c7-a965-4ab6-9cf0-0d7c14cd7db3", + "amount": 400, + "status": "completed", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-04-14T22:01:45.361Z", + "updatedAt": "2021-04-21T20:19:56.934Z" + }, + { + "id": "821b38e8-657d-4f72-b27a-dd975c506ced", + "workPeriodId": "9b6fc85b-3694-4e6c-9ebf-fe9ccf7881ba", + "challengeId": "61f5185b-4ee1-4df3-9c6f-52f5bf0cbfc5", + "amount": 500, + "status": "completed", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-04-14T22:01:45.361Z", + "updatedAt": "2021-04-21T20:19:56.934Z" + }, + { + "id": "2417df2c-8e29-4868-aeb8-5ec0ff67713e", + "workPeriodId": "9bfbd49a-e6bb-45c3-965d-ed4f95f0878a", + "challengeId": "f01ba8da-c891-472d-9ed6-74b91ed9b407", + "amount": 400, + "status": "completed", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-04-14T19:13:23.714Z", + "updatedAt": "2021-04-21T20:19:56.934Z" + }, + { + "id": "5116d4ea-2c1a-4be6-b335-bd531b8d5734", + "workPeriodId": "a35bb205-361b-4b2d-9828-55501ae9d190", + "challengeId": "b42b8f40-9a4d-45d1-814e-59da5c7a1fd9", + "amount": 600, + "status": "completed", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "createdAt": "2021-04-14T19:13:23.714Z", + "updatedAt": "2021-04-16T19:13:23.714Z" + }, + { + "id": "8fdfe90b-2155-4a71-a610-4689106ced34", + "workPeriodId": "b21f921a-4b23-423d-814b-d31f5cba7f64", + "challengeId": "963784fd-4174-458c-a311-a5b8333d66ab", + "amount": 300, + "status": "completed", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-04-14T22:01:45.361Z", + "updatedAt": "2021-04-21T20:19:56.934Z" + }, + { + "id": "dd9c842a-f577-43c2-8f17-cc940f26f0d8", + "workPeriodId": "b4566e24-4fa8-4e82-9950-f62134bb00df", + "challengeId": "b67cbbc5-3384-4ea6-8504-d3fe83a6e238", + "amount": 700, + "status": "completed", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-04-14T22:01:45.326Z", + "updatedAt": "2021-04-21T20:19:56.934Z" + }, + { + "id": "7e41ca7f-d3c0-4d70-9daf-ee52c93695c7", + "workPeriodId": "b5261ee2-bc4d-4c3a-9d30-6703bfdcfbc5", + "challengeId": "9d49655f-99f6-4e67-9819-a117ef746272", + "amount": 500, + "status": "completed", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-04-14T22:01:45.361Z", + "updatedAt": "2021-04-21T20:19:56.934Z" + }, + { + "id": "b8d44e83-922c-4c2c-8567-5764794e03f3", + "workPeriodId": "b682660e-488e-4033-aaf3-ef37248abc90", + "challengeId": "d7c21199-a435-41b8-a2ac-5e5bdd021c5e", + "amount": 700, + "status": "completed", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "createdAt": "2021-04-14T19:13:23.714Z", + "updatedAt": "2021-04-16T19:13:23.714Z" + }, + { + "id": "c117de76-965f-4069-aefb-8dd97f95112c", + "workPeriodId": "b8a8b558-0cb9-46d0-ba9d-2222f3fbdb63", + "challengeId": "59d08064-e1b4-4e78-82d8-b2d7ffa6f0b1", + "amount": 900, + "status": "completed", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-04-14T22:01:45.523Z", + "updatedAt": "2021-04-21T20:19:56.934Z" + }, + { + "id": "fda2013c-da68-4601-8d13-d0f4cffd081c", + "workPeriodId": "bc8611f0-4ac2-49b2-b776-59ed2b759d1d", + "challengeId": "0de972b8-6cc9-4625-9760-1c77561c29e9", + "amount": 800, + "status": "completed", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-04-14T19:13:23.714Z", + "updatedAt": "2021-04-21T20:19:56.934Z" + }, + { + "id": "be07bfc8-032c-41f7-a247-a4724f65617c", + "workPeriodId": "bd54bcaf-5278-467f-a166-865048774d0e", + "challengeId": "45e33cee-7c83-4288-8187-6858b0c759eb", + "amount": 800, + "status": "completed", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-04-14T22:01:45.361Z", + "updatedAt": "2021-04-21T20:19:56.934Z" + }, + { + "id": "efa8cd14-c93f-4e6c-be53-596f02db8c96", + "workPeriodId": "bf61dad8-841a-4913-93f6-b2ae516b8b11", + "challengeId": "0de972b8-6cc9-4625-9760-1c77561c29e9", + "amount": 800, + "status": "completed", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-04-14T19:13:23.714Z", + "updatedAt": "2021-04-21T20:19:56.934Z" + }, + { + "id": "eb9c9a83-fe94-4f51-b9f0-c2d9671e87f6", + "workPeriodId": "c5f6ae8f-2976-46d1-bd66-58eeb58ca045", + "challengeId": "68e6a32e-6c31-4266-ba3b-9d2f63be4274", + "amount": 900, + "status": "completed", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-04-14T22:01:45.361Z", + "updatedAt": "2021-04-21T20:19:56.934Z" + }, + { + "id": "c20796c8-76b0-40e8-9bee-db406c93daaf", + "workPeriodId": "c7ff2acc-a4c2-4e8b-a905-813dd9d1b293", + "challengeId": "513ab4c6-0aa4-482b-a184-87f8447b145b", + "amount": 1800, + "status": "completed", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-04-14T22:01:45.390Z", + "updatedAt": "2021-04-21T20:19:56.934Z" + }, + { + "id": "8fad32f7-cb40-416f-ab24-86cf1c7870ef", + "workPeriodId": "c9685cb2-9f4a-497e-ae99-deed7b16cc34", + "challengeId": "f7e40a0c-a302-4989-a3bd-7587fee3c367", + "amount": 600, + "status": "completed", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-04-14T19:13:23.714Z", + "updatedAt": "2021-04-21T20:19:56.934Z" + }, + { + "id": "310384cb-6e85-4f7d-a6d2-8c03ca27871d", + "workPeriodId": "d049e7bc-c827-482b-9ec6-b87d9289d1cd", + "challengeId": "0de972b8-6cc9-4625-9760-1c77561c29e9", + "amount": 900, + "status": "completed", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-04-14T19:13:23.714Z", + "updatedAt": "2021-04-21T20:19:56.934Z" + }, + { + "id": "2a122a93-e778-4eb9-868c-5f38b8b9bb4e", + "workPeriodId": "da8abd64-2878-4e09-b3b1-41a27a0576d4", + "challengeId": "25a7c442-427b-4b6d-9c41-112dbd420c0d", + "amount": 800, + "status": "completed", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-04-14T19:13:23.714Z", + "updatedAt": "2021-04-21T20:19:56.934Z" + }, + { + "id": "767897c3-bbc2-4b1a-9843-5a6bd82e29b0", + "workPeriodId": "dcc310cf-ea4a-4637-9bf5-5baaabea67b3", + "challengeId": "61044188-965e-40df-94c4-9fa9a9499b25", + "amount": 1000, + "status": "completed", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-04-14T22:01:45.523Z", + "updatedAt": "2021-04-21T20:19:56.934Z" + }, + { + "id": "50f7a6fa-a04d-4873-8fd0-037be2f14425", + "workPeriodId": "e19bddc5-38ac-43c9-8273-bc9069de26b3", + "challengeId": "419fbb3d-921d-4613-a87e-337f38d21885", + "amount": 600, + "status": "completed", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-04-14T22:01:45.523Z", + "updatedAt": "2021-04-21T20:19:56.934Z" + }, + { + "id": "11ea987f-f218-4d2b-b656-0741208539f2", + "workPeriodId": "f575df2d-f170-4251-9042-b17ca5e99ca5", + "challengeId": "0de972b8-6cc9-4625-9760-1c77561c29e9", + "amount": 600, + "status": "completed", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-04-16T19:13:23.714Z", + "updatedAt": "2021-04-21T20:19:56.934Z" + }, + { + "id": "2519d7f9-81c8-448c-aec2-aa78d6d6a962", + "workPeriodId": "f70509c0-baed-4ff1-8022-12441251f7af", + "challengeId": "fd051497-6050-4edf-b8f7-780128f64dc5", + "amount": 300, + "status": "cancelled", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-04-14T22:01:45.324Z", + "updatedAt": "2021-04-21T20:19:56.934Z" + } + ] +} diff --git a/docs/Topcoder-bookings-api.postman_collection.json b/docs/Topcoder-bookings-api.postman_collection.json index d636cfc0..52000d57 100644 --- a/docs/Topcoder-bookings-api.postman_collection.json +++ b/docs/Topcoder-bookings-api.postman_collection.json @@ -1,6 +1,6 @@ { "info": { - "_postman_id": "fb3b4365-f23e-4e88-9fce-5dcd94c130b8", + "_postman_id": "059739c9-5726-44b6-876d-6d87940c9aff", "name": "Topcoder-bookings-api", "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json" }, @@ -1886,6 +1886,78 @@ }, "response": [] }, + { + "name": "get job candidate with m2m (read jobCandidate & interview) - included interviews", + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_m2m_read_jobCandidate_read_interviews}}" + } + ], + "url": { + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}", + "host": [ + "{{URL}}" + ], + "path": [ + "jobCandidates", + "{{jobCandidateId}}" + ] + } + }, + "response": [] + }, + { + "name": "get job candidate with m2m (read jobCandidate & all interview) - included interviews", + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_m2m_read_jobCandidates_all_interviews}}" + } + ], + "url": { + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}", + "host": [ + "{{URL}}" + ], + "path": [ + "jobCandidates", + "{{jobCandidateId}}" + ] + } + }, + "response": [] + }, + { + "name": "get job candidate with m2m (read jobCandidate) - interviews not included", + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_m2m_read_job_candidate}}" + } + ], + "url": { + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}", + "host": [ + "{{URL}}" + ], + "path": [ + "jobCandidates", + "{{jobCandidateId}}" + ] + } + }, + "response": [] + }, { "name": "get job candidate with booking manager from db", "request": { @@ -2016,7 +2088,7 @@ }, { "key": "status", - "value": "shortlist", + "value": "selected", "disabled": true }, { @@ -2081,7 +2153,202 @@ }, { "key": "status", - "value": "shortlist", + "value": "selected", + "disabled": true + }, + { + "key": "externalId", + "value": "300234321", + "disabled": true + } + ] + } + }, + "response": [] + }, + { + "name": "search job candidates with m2m (read jobCandidate & read interview) - included interviews", + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_m2m_read_jobCandidate_read_interviews}}" + } + ], + "url": { + "raw": "{{URL}}/jobCandidates", + "host": [ + "{{URL}}" + ], + "path": [ + "jobCandidates" + ], + "query": [ + { + "key": "page", + "value": "1", + "disabled": true + }, + { + "key": "perPage", + "value": "1", + "disabled": true + }, + { + "key": "sortBy", + "value": "id", + "disabled": true + }, + { + "key": "sortOrder", + "value": "asc", + "disabled": true + }, + { + "key": "jobId", + "value": "46225f4c-c2a3-4603-a141-0277e96fabfa", + "disabled": true + }, + { + "key": "userId", + "value": "a55fe1bc-1754-45fa-9adc-cf3d6d7c377a", + "disabled": true + }, + { + "key": "status", + "value": "selected", + "disabled": true + }, + { + "key": "externalId", + "value": "300234321", + "disabled": true + } + ] + } + }, + "response": [] + }, + { + "name": "search job candidates with m2m (read jobCandidate & all interview) - included interviews", + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_m2m_read_jobCandidates_all_interviews}}" + } + ], + "url": { + "raw": "{{URL}}/jobCandidates", + "host": [ + "{{URL}}" + ], + "path": [ + "jobCandidates" + ], + "query": [ + { + "key": "page", + "value": "1", + "disabled": true + }, + { + "key": "perPage", + "value": "1", + "disabled": true + }, + { + "key": "sortBy", + "value": "id", + "disabled": true + }, + { + "key": "sortOrder", + "value": "asc", + "disabled": true + }, + { + "key": "jobId", + "value": "46225f4c-c2a3-4603-a141-0277e96fabfa", + "disabled": true + }, + { + "key": "userId", + "value": "a55fe1bc-1754-45fa-9adc-cf3d6d7c377a", + "disabled": true + }, + { + "key": "status", + "value": "selected", + "disabled": true + }, + { + "key": "externalId", + "value": "300234321", + "disabled": true + } + ] + } + }, + "response": [] + }, + { + "name": "search job candidates with m2m (read jobCandidate) - interviews not included", + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_m2m_read_job_candidate}}" + } + ], + "url": { + "raw": "{{URL}}/jobCandidates", + "host": [ + "{{URL}}" + ], + "path": [ + "jobCandidates" + ], + "query": [ + { + "key": "page", + "value": "1", + "disabled": true + }, + { + "key": "perPage", + "value": "1", + "disabled": true + }, + { + "key": "sortBy", + "value": "id", + "disabled": true + }, + { + "key": "sortOrder", + "value": "asc", + "disabled": true + }, + { + "key": "jobId", + "value": "46225f4c-c2a3-4603-a141-0277e96fabfa", + "disabled": true + }, + { + "key": "userId", + "value": "a55fe1bc-1754-45fa-9adc-cf3d6d7c377a", + "disabled": true + }, + { + "key": "status", + "value": "selected", "disabled": true }, { @@ -2146,7 +2413,7 @@ }, { "key": "status", - "value": "shortlist", + "value": "selected", "disabled": true }, { @@ -2209,7 +2476,7 @@ }, { "key": "status", - "value": "shortlist", + "value": "selected", "disabled": true }, { @@ -2272,7 +2539,7 @@ }, { "key": "status", - "value": "shortlist", + "value": "selected", "disabled": true }, { @@ -2496,7 +2763,7 @@ ], "body": { "mode": "raw", - "raw": "{\n \"status\": \"shortlist\",\n \"externalId\": \"300234321\",\n \"resume\": \"http://example.com\"\n}", + "raw": "{\n \"status\": \"selected\",\n \"externalId\": \"300234321\",\n \"resume\": \"http://example.com\"\n}", "options": { "raw": { "language": "json" @@ -2529,7 +2796,7 @@ ], "body": { "mode": "raw", - "raw": "{\n \"status\": \"shortlist\",\n \"externalId\": \"300234321\",\n \"resume\": \"http://example.com\"\n}", + "raw": "{\n \"status\": \"selected\",\n \"externalId\": \"300234321\",\n \"resume\": \"http://example.com\"\n}", "options": { "raw": { "language": "json" @@ -2562,7 +2829,7 @@ ], "body": { "mode": "raw", - "raw": "{\n \"status\": \"shortlist\",\n \"externalId\": \"300234321\",\n \"resume\": \"http://example.com\"\n}", + "raw": "{\n \"status\": \"selected\",\n \"externalId\": \"300234321\",\n \"resume\": \"http://example.com\"\n}", "options": { "raw": { "language": "json" @@ -2595,7 +2862,7 @@ ], "body": { "mode": "raw", - "raw": "{\n \"status\": \"shortlist\",\n \"externalId\": \"300234321\",\n \"resume\": \"http://example.com\"\n}", + "raw": "{\n \"status\": \"selected\",\n \"externalId\": \"300234321\",\n \"resume\": \"http://example.com\"\n}", "options": { "raw": { "language": "json" @@ -2628,7 +2895,7 @@ ], "body": { "mode": "raw", - "raw": "{\n \"status\": \"shortlist\",\n \"externalId\": \"300234321\",\n \"resume\": \"http://example.com\"\n}", + "raw": "{\n \"status\": \"selected\",\n \"externalId\": \"300234321\",\n \"resume\": \"http://example.com\"\n}", "options": { "raw": { "language": "json" @@ -2661,7 +2928,7 @@ ], "body": { "mode": "raw", - "raw": "{\n \"status\": \"shortlist\",\n \"externalId\": \"300234321\",\n \"resume\": \"http://example.com\"\n}", + "raw": "{\n \"status\": \"selected\",\n \"externalId\": \"300234321\",\n \"resume\": \"http://example.com\"\n}", "options": { "raw": { "language": "json" @@ -2816,7 +3083,7 @@ ] }, { - "name": "Resource Bookings", + "name": "Interviews", "item": [ { "name": "Before Test", @@ -2829,7 +3096,7 @@ "script": { "exec": [ "pm.test('Status code is 200', function () {\r", - " pm.response.to.have.status(200);\r", + " pm.response.to.have.status(200)\r", " if(pm.response.status === \"OK\"){\r", " const response = pm.response.json()\r", " pm.environment.set(\"jobId\", response.id);\r", @@ -2851,7 +3118,7 @@ ], "body": { "mode": "raw", - "raw": "{\n \"projectId\": {{projectId}},\n \"externalId\": \"1212\",\n \"description\": \"Dummy Description\",\n \"startDate\": \"2020-09-27T04:17:23.131Z\",\n \"duration\": 1,\n \"numPositions\": 13,\n \"resourceType\": \"Dummy Resource Type\",\n \"rateType\": \"hourly\",\n \"workload\": \"full-time\",\n \"skills\": [\n \"23e00d92-207a-4b5b-b3c9-4c5662644941\",\n \"7d076384-ccf6-4e43-a45d-1b24b1e624aa\",\n \"cbac57a3-7180-4316-8769-73af64893158\",\n \"a2b4bc11-c641-4a19-9eb7-33980378f82e\"\n ],\n \"title\": \"Dummy title - at most 64 characters\"\n}", + "raw": "{\n \"projectId\": {{projectId}},\n \"externalId\": \"88774632\",\n \"description\": \"Dummy Description\",\n \"startDate\": \"2020-09-27\",\n \"duration\": 1,\n \"numPositions\": 13,\n \"resourceType\": \"Dummy Resource Type\",\n \"rateType\": \"hourly\",\n \"workload\": \"full-time\",\n \"skills\": [\n \"23e00d92-207a-4b5b-b3c9-4c5662644941\",\n \"7d076384-ccf6-4e43-a45d-1b24b1e624aa\",\n \"cbac57a3-7180-4316-8769-73af64893158\",\n \"a2b4bc11-c641-4a19-9eb7-33980378f82e\"\n ],\n \"title\": \"Dummy title - at most 64 characters\"\n}", "options": { "raw": { "language": "json" @@ -2871,14 +3138,19 @@ "response": [] }, { - "name": "create job with m2m", + "name": "create job candidate", "event": [ { "listen": "test", "script": { "exec": [ - "var data = JSON.parse(responseBody);\r", - "postman.setEnvironmentVariable(\"jobIdCreatedByM2M\",data.id);" + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200)\r", + " if(pm.response.status === \"OK\"){\r", + " const response = pm.response.json()\r", + " pm.environment.set(\"jobCandidateId\", response.id);\r", + " }\r", + "});" ], "type": "text/javascript" } @@ -2889,13 +3161,63 @@ "header": [ { "key": "Authorization", - "value": "Bearer {{token_m2m_create_job}}", + "type": "text", + "value": "Bearer {{token_bookingManager}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"jobId\": \"{{jobId}}\",\n \"userId\": \"95e7970f-12b4-43b7-ab35-38c34bf033c7\",\n \"externalId\": \"88774631\",\n \"resume\": \"http://example.com\"\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/jobCandidates", + "host": [ + "{{URL}}" + ], + "path": [ + "jobCandidates" + ] + } + }, + "response": [] + }, + { + "name": "Create completed interview", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200)\r", + " if(pm.response.status === \"OK\"){\r", + " const response = pm.response.json()\r", + " pm.environment.set(\"completedInterviewJobCandidateId\", response.jobCandidateId);\r", + " pm.environment.set(\"completedInterviewRound\", response.round);\r", + " }\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "PATCH", + "header": [ + { + "key": "Authorization", + "value": "Bearer {{token_bookingManager}}", "type": "text" } ], "body": { "mode": "raw", - "raw": "{\n \"projectId\": {{projectId}},\n \"externalId\": \"1212\",\n \"description\": \"Dummy Description\",\n \"startDate\": \"2020-09-27T04:17:23.131Z\",\n \"duration\": 1,\n \"numPositions\": 13,\n \"resourceType\": \"Dummy Resource Type\",\n \"rateType\": \"hourly\",\n \"workload\": \"full-time\",\n \"skills\": [\n \"23e00d92-207a-4b5b-b3c9-4c5662644941\",\n \"7d076384-ccf6-4e43-a45d-1b24b1e624aa\",\n \"cbac57a3-7180-4316-8769-73af64893158\",\n \"a2b4bc11-c641-4a19-9eb7-33980378f82e\"\n ],\n \"title\": \"Dummy title - at most 64 characters\"\n}", + "raw": "{\r\n \"xaiTemplate\": \"interview-30\",\r\n \"status\": \"Completed\"\r\n}", "options": { "raw": { "language": "json" @@ -2903,12 +3225,14 @@ } }, "url": { - "raw": "{{URL}}/jobs", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/requestInterview", "host": [ "{{URL}}" ], "path": [ - "jobs" + "jobCandidates", + "{{jobCandidateId}}", + "requestInterview" ] } }, @@ -2917,17 +3241,17 @@ ] }, { - "name": "create resource booking with booking manager", + "name": "Request interview", "event": [ { "listen": "test", "script": { "exec": [ "pm.test('Status code is 200', function () {\r", - " pm.response.to.have.status(200);\r", + " pm.response.to.have.status(200)\r", " if(pm.response.status === \"OK\"){\r", " const response = pm.response.json()\r", - " pm.environment.set(\"resourceBookingId\", response.id);\r", + " pm.environment.set(\"interviewRound\", response.round);\r", " }\r", "});" ], @@ -2936,17 +3260,17 @@ } ], "request": { - "method": "POST", + "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_bookingManager}}" + "value": "Bearer {{token_bookingManager}}", + "type": "text" } ], "body": { "mode": "raw", - "raw": "{\r\n \"projectId\": {{projectId}},\r\n \"userId\": \"a55fe1bc-1754-45fa-9adc-cf3d6d7c377a\",\r\n \"jobId\": \"{{jobId}}\",\r\n \"startDate\": \"2020-09-27\",\r\n \"endDate\": \"2020-10-27\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\",\r\n \"billingAccountId\": 80000071\r\n}", + "raw": "{\r\n \"xaiTemplate\": \"interview-30\",\r\n \"googleCalendarId\": \"dummyId\",\r\n \"customMessage\": \"This is a custom message\",\r\n \"attendeesList\": [\"attendee1@yopmail.com\", \"attendee2@yopmail.com\"],\r\n \"status\": \"Scheduling\"\r\n}", "options": { "raw": { "language": "json" @@ -2954,19 +3278,21 @@ } }, "url": { - "raw": "{{URL}}/resourceBookings", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/requestInterview", "host": [ "{{URL}}" ], "path": [ - "resourceBookings" + "jobCandidates", + "{{jobCandidateId}}", + "requestInterview" ] } }, "response": [] }, { - "name": "search work periods of newly created resource booking", + "name": "Request interview for the same jobCandidateId - should increment round", "event": [ { "listen": "test", @@ -2974,6 +3300,10 @@ "exec": [ "pm.test('Status code is 200', function () {\r", " pm.response.to.have.status(200);\r", + " const response = pm.response.json();\r", + " const lastRound = pm.environment.get(\"interviewRound\");\r", + " pm.expect(response.round).to.eq(lastRound + 1);\r", + " pm.environment.set(\"interviewRound\", response.round);\r", "});" ], "type": "text/javascript" @@ -2981,92 +3311,50 @@ } ], "request": { - "method": "GET", + "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_bookingManager}}" + "value": "Bearer {{token_bookingManager}}", + "type": "text" } ], + "body": { + "mode": "raw", + "raw": "{\r\n \"xaiTemplate\": \"interview-30\",\r\n \"googleCalendarId\": \"dummyId\",\r\n \"customMessage\": \"This is a custom message\",\r\n \"status\": \"Scheduling\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, "url": { - "raw": "{{URL}}/work-periods?sortBy=startDate&sortOrder=asc&resourceBookingId={{resourceBookingId}}", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/requestInterview", "host": [ "{{URL}}" ], "path": [ - "work-periods" - ], - "query": [ - { - "key": "page", - "value": "1", - "disabled": true - }, - { - "key": "perPage", - "value": "5", - "disabled": true - }, - { - "key": "sortBy", - "value": "startDate" - }, - { - "key": "sortOrder", - "value": "asc" - }, - { - "key": "resourceBookingId", - "value": "{{resourceBookingId}}" - }, - { - "key": "resourceBookingIds", - "value": "{{resourceBookingId}},{{resourceBookingId}}", - "disabled": true - }, - { - "key": "paymentStatus", - "value": "pending", - "disabled": true - }, - { - "key": "startDate", - "value": "2021-03-14", - "disabled": true - }, - { - "key": "endDate", - "value": "2021-03-20", - "disabled": true - }, - { - "key": "userHandle", - "value": "pshah_manager", - "disabled": true - }, - { - "key": "projectId", - "value": "16843", - "disabled": true - } + "jobCandidates", + "{{jobCandidateId}}", + "requestInterview" ] } }, "response": [] }, { - "name": "create resource booking with m2m create", + "name": "Request interview without status - should take default status", "event": [ { "listen": "test", "script": { "exec": [ "pm.test('Status code is 200', function () {\r", - " pm.response.to.have.status(200);\r", + " pm.response.to.have.status(200)\r", " if(pm.response.status === \"OK\"){\r", " const response = pm.response.json()\r", - " pm.environment.set(\"resourceBookingIdCreatedByM2M\", response.id);\r", + " pm.environment.set(\"interviewRound\", response.round);\r", + " pm.expect(response.status).to.eq(\"Scheduling\")\r", " }\r", "});" ], @@ -3075,17 +3363,17 @@ } ], "request": { - "method": "POST", + "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_m2m_create_resource_booking}}" + "value": "Bearer {{token_bookingManager}}", + "type": "text" } ], "body": { "mode": "raw", - "raw": "{\r\n \"projectId\": {{projectId}},\r\n \"userId\": \"a55fe1bc-1754-45fa-9adc-cf3d6d7c377a\",\r\n \"jobId\": \"{{jobIdCreatedByM2M}}\",\r\n \"startDate\": \"2020-12-27\",\r\n \"endDate\": \"2021-01-27\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\",\r\n \"billingAccountId\": 80000071\r\n}", + "raw": "{\r\n \"xaiTemplate\": \"interview-30\"\r\n}", "options": { "raw": { "language": "json" @@ -3093,26 +3381,30 @@ } }, "url": { - "raw": "{{URL}}/resourceBookings", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/requestInterview", "host": [ "{{URL}}" ], "path": [ - "resourceBookings" + "jobCandidates", + "{{jobCandidateId}}", + "requestInterview" ] } }, "response": [] }, { - "name": "search work periods of newly created resource booking", + "name": "Request interview with invalid status", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 200', function () {\r", - " pm.response.to.have.status(200);\r", + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"\\\"interview.status\\\" must be one of [Scheduling, Scheduled, Requested for reschedule, Rescheduled, Completed, Cancelled]\")\r", "});" ], "type": "text/javascript" @@ -3120,91 +3412,49 @@ } ], "request": { - "method": "GET", + "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_bookingManager}}" + "value": "Bearer {{token_bookingManager}}", + "type": "text" } ], + "body": { + "mode": "raw", + "raw": "{\r\n \"xaiTemplate\": \"interview-30\",\r\n \"status\": \"xxxx\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, "url": { - "raw": "{{URL}}/work-periods?sortBy=startDate&sortOrder=asc&resourceBookingId={{resourceBookingIdCreatedByM2M}}", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/requestInterview", "host": [ "{{URL}}" ], "path": [ - "work-periods" - ], - "query": [ - { - "key": "page", - "value": "1", - "disabled": true - }, - { - "key": "perPage", - "value": "5", - "disabled": true - }, - { - "key": "sortBy", - "value": "startDate" - }, - { - "key": "sortOrder", - "value": "asc" - }, - { - "key": "resourceBookingId", - "value": "{{resourceBookingIdCreatedByM2M}}" - }, - { - "key": "resourceBookingIds", - "value": "{{resourceBookingIdCreatedByM2M}},{{resourceBookingIdCreatedByM2M}}", - "disabled": true - }, - { - "key": "paymentStatus", - "value": "pending", - "disabled": true - }, - { - "key": "startDate", - "value": "2021-03-14", - "disabled": true - }, - { - "key": "endDate", - "value": "2021-03-20", - "disabled": true - }, - { - "key": "userHandle", - "value": "pshah_manager", - "disabled": true - }, - { - "key": "projectId", - "value": "16843", - "disabled": true - } + "jobCandidates", + "{{jobCandidateId}}", + "requestInterview" ] } }, "response": [] }, { - "name": "create resource booking with connect user", + "name": "Request interview with attendeesList", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 403', function () {\r", - " pm.response.to.have.status(403);\r", + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", + " pm.expect(response.attendeesList[0]).to.eq(\"attendee1@yopmail.com\")\r", + " pm.expect(response.attendeesList[1]).to.eq(\"attendee2@yopmail.com\")\r", "});" ], "type": "text/javascript" @@ -3212,17 +3462,17 @@ } ], "request": { - "method": "POST", + "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_connectUser}}" + "value": "Bearer {{token_bookingManager}}", + "type": "text" } ], "body": { "mode": "raw", - "raw": "{\r\n \"projectId\": {{projectId}},\r\n \"userId\": \"a55fe1bc-1754-45fa-9adc-cf3d6d7c377a\",\r\n \"jobId\": \"{{jobId}}\",\r\n \"startDate\": \"2020-09-27\",\r\n \"endDate\": \"2020-09-28\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\",\r\n \"billingAccountId\": 80000071\r\n}", + "raw": "{\r\n \"xaiTemplate\": \"interview-30\",\r\n \"attendeesList\": [\"attendee1@yopmail.com\", \"attendee2@yopmail.com\"]\r\n}", "options": { "raw": { "language": "json" @@ -3230,28 +3480,30 @@ } }, "url": { - "raw": "{{URL}}/resourceBookings", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/requestInterview", "host": [ "{{URL}}" ], "path": [ - "resourceBookings" + "jobCandidates", + "{{jobCandidateId}}", + "requestInterview" ] } }, "response": [] }, { - "name": "create resource booking with member", + "name": "Request interview with invalid attendeesList", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 403', function () {\r", - " pm.response.to.have.status(403);\r", + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", + " pm.expect(response.message).to.eq(\"\\\"interview.attendeesList\\\" must be an array\")\r", "});" ], "type": "text/javascript" @@ -3259,17 +3511,17 @@ } ], "request": { - "method": "POST", + "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_member}}" + "value": "Bearer {{token_bookingManager}}", + "type": "text" } ], "body": { "mode": "raw", - "raw": "{\r\n \"projectId\": {{projectId}},\r\n \"userId\": \"a55fe1bc-1754-45fa-9adc-cf3d6d7c377a\",\r\n \"jobId\": \"{{jobId}}\",\r\n \"startDate\": \"2020-09-27\",\r\n \"endDate\": \"2020-09-28\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\",\r\n \"billingAccountId\": 80000071\r\n}", + "raw": "{\r\n \"xaiTemplate\": \"interview-30\",\r\n \"attendeesList\": \"asddd\"\r\n}", "options": { "raw": { "language": "json" @@ -3277,19 +3529,21 @@ } }, "url": { - "raw": "{{URL}}/resourceBookings", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/requestInterview", "host": [ "{{URL}}" ], "path": [ - "resourceBookings" + "jobCandidates", + "{{jobCandidateId}}", + "requestInterview" ] } }, "response": [] }, { - "name": "create resource booking with user id not exist", + "name": "Request interview with invalid attendee email", "event": [ { "listen": "test", @@ -3298,7 +3552,7 @@ "pm.test('Status code is 400', function () {\r", " pm.response.to.have.status(400);\r", " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"Bad Request\")\r", + " pm.expect(response.message).to.eq(\"\\\"interview.attendeesList[0]\\\" must be a valid email\")\r", "});" ], "type": "text/javascript" @@ -3306,17 +3560,17 @@ } ], "request": { - "method": "POST", + "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_userId_not_exist}}" + "value": "Bearer {{token_bookingManager}}", + "type": "text" } ], "body": { "mode": "raw", - "raw": "{\r\n \"projectId\": {{projectId}},\r\n \"userId\": \"a55fe1bc-1754-45fa-9adc-cf3d6d7c377a\",\r\n \"jobId\": \"{{jobId}}\",\r\n \"startDate\": \"2020-09-27\",\r\n \"endDate\": \"2020-09-28\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\",\r\n \"billingAccountId\": 80000071\r\n}", + "raw": "{\r\n \"xaiTemplate\": \"interview-30\",\r\n \"attendeesList\": [\"asdas\"]\r\n}", "options": { "raw": { "language": "json" @@ -3324,28 +3578,30 @@ } }, "url": { - "raw": "{{URL}}/resourceBookings", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/requestInterview", "host": [ "{{URL}}" ], "path": [ - "resourceBookings" + "jobCandidates", + "{{jobCandidateId}}", + "requestInterview" ] } }, "response": [] }, { - "name": "create resource booking with invalid token", + "name": "Request interview with round - should not accept", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 401', function () {\r", - " pm.response.to.have.status(401);\r", + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"Invalid Token.\")\r", + " pm.expect(response.message).to.eq(\"\\\"interview.round\\\" is not allowed\")\r", "});" ], "type": "text/javascript" @@ -3353,17 +3609,17 @@ } ], "request": { - "method": "POST", + "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer invalid_token" + "value": "Bearer {{token_bookingManager}}", + "type": "text" } ], "body": { "mode": "raw", - "raw": "{\r\n \"projectId\": {{projectId}},\r\n \"userId\": \"a55fe1bc-1754-45fa-9adc-cf3d6d7c377a\",\r\n \"jobId\": \"{{jobId}}\",\r\n \"startDate\": \"2020-09-27\",\r\n \"endDate\": \"2020-09-27\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\",\r\n \"billingAccountId\": 80000071\r\n}", + "raw": "{\r\n \"xaiTemplate\": \"interview-30\",\r\n \"round\": 1\r\n}", "options": { "raw": { "language": "json" @@ -3371,26 +3627,30 @@ } }, "url": { - "raw": "{{URL}}/resourceBookings", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/requestInterview", "host": [ "{{URL}}" ], "path": [ - "resourceBookings" + "jobCandidates", + "{{jobCandidateId}}", + "requestInterview" ] } }, "response": [] }, { - "name": "get resource booking with booking manager", + "name": "Request interview with startTimestamp - should not accept", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 200', function () {\r", - " pm.response.to.have.status(200);\r", + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"\\\"interview.startTimestamp\\\" is not allowed\")\r", "});" ], "type": "text/javascript" @@ -3398,36 +3658,48 @@ } ], "request": { - "method": "GET", + "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_bookingManager}}" + "value": "Bearer {{token_bookingManager}}", + "type": "text" } ], + "body": { + "mode": "raw", + "raw": "{\r\n \"xaiTemplate\": \"interview-30\",\r\n \"startTimestamp\": \"2021-04-17\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, "url": { - "raw": "{{URL}}/resourceBookings/{{resourceBookingId}}", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/requestInterview", "host": [ "{{URL}}" ], "path": [ - "resourceBookings", - "{{resourceBookingId}}" + "jobCandidates", + "{{jobCandidateId}}", + "requestInterview" ] } }, "response": [] }, { - "name": "get resource booking with m2m read", + "name": "Request interview without xaiTemplate - should fail", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 200', function () {\r", - " pm.response.to.have.status(200);\r", + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"\\\"interview.xaiTemplate\\\" is required\")\r", "});" ], "type": "text/javascript" @@ -3435,36 +3707,48 @@ } ], "request": { - "method": "GET", + "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_m2m_read_resource_booking}}" + "value": "Bearer {{token_bookingManager}}", + "type": "text" } ], + "body": { + "mode": "raw", + "raw": "{\r\n \"status\": \"Requested\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, "url": { - "raw": "{{URL}}/resourceBookings/{{resourceBookingIdCreatedByM2M}}", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/requestInterview", "host": [ "{{URL}}" ], "path": [ - "resourceBookings", - "{{resourceBookingIdCreatedByM2M}}" + "jobCandidates", + "{{jobCandidateId}}", + "requestInterview" ] } }, "response": [] }, { - "name": "get resource booking with booking manager from db", + "name": "Request interview with invalid xaiTemplate", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 200', function () {\r", - " pm.response.to.have.status(200);\r", + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"\\\"interview.xaiTemplate\\\" must be one of [interview-30, interview-60]\")\r", "});" ], "type": "text/javascript" @@ -3472,42 +3756,48 @@ } ], "request": { - "method": "GET", + "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_bookingManager}}" + "value": "Bearer {{token_bookingManager}}", + "type": "text" } ], + "body": { + "mode": "raw", + "raw": "{\r\n \"xaiTemplate\": \"asdas\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, "url": { - "raw": "{{URL}}/resourceBookings/{{resourceBookingId}}?fromDb=true", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/requestInterview", "host": [ "{{URL}}" ], "path": [ - "resourceBookings", - "{{resourceBookingId}}" - ], - "query": [ - { - "key": "fromDb", - "value": "true" - } + "jobCandidates", + "{{jobCandidateId}}", + "requestInterview" ] } }, "response": [] }, { - "name": "get resource booking with connect user", + "name": "Request interview with non-existing jobCandidate", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 200', function () {\r", - " pm.response.to.have.status(200);\r", + "pm.test('Status code is 404', function () {\r", + " pm.response.to.have.status(404);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"The job candidate with id=9105f597-f9d5-49c0-9cbf-9a0cbda47260 doesn't exist.\")\r", "});" ], "type": "text/javascript" @@ -3515,38 +3805,48 @@ } ], "request": { - "method": "GET", + "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_connectUser}}" + "value": "Bearer {{token_bookingManager}}", + "type": "text" } ], + "body": { + "mode": "raw", + "raw": "{\r\n \"xaiTemplate\": \"interview-30\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, "url": { - "raw": "{{URL}}/resourceBookings/{{resourceBookingId}}", + "raw": "{{URL}}/jobCandidates/9105f597-f9d5-49c0-9cbf-9a0cbda47260/requestInterview", "host": [ "{{URL}}" ], "path": [ - "resourceBookings", - "{{resourceBookingId}}" + "jobCandidates", + "9105f597-f9d5-49c0-9cbf-9a0cbda47260", + "requestInterview" ] } }, "response": [] }, { - "name": "get resource booking with member", + "name": "Request interview with non-existing userId in token", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 401', function () {\r", - " pm.response.to.have.status(401);\r", + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"userId: 8547899 the user is not a member of project 111\")\r", + " pm.expect(response.message).to.eq(\"Bad Request\")\r", "});" ], "type": "text/javascript" @@ -3554,29 +3854,39 @@ } ], "request": { - "method": "GET", + "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_member}}" + "value": "Bearer {{token_userId_not_exist}}", + "type": "text" } ], + "body": { + "mode": "raw", + "raw": "{\r\n \"xaiTemplate\": \"interview-30\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, "url": { - "raw": "{{URL}}/resourceBookings/{{resourceBookingId}}", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/requestInterview", "host": [ "{{URL}}" ], "path": [ - "resourceBookings", - "{{resourceBookingId}}" + "jobCandidates", + "{{jobCandidateId}}", + "requestInterview" ] } }, "response": [] }, { - "name": "search resource bookings with booking manager", + "name": "Request interview with administrator", "event": [ { "listen": "test", @@ -3591,75 +3901,39 @@ } ], "request": { - "method": "GET", + "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_bookingManager}}" + "value": "Bearer {{token_administrator}}", + "type": "text" } ], + "body": { + "mode": "raw", + "raw": "{\r\n \"xaiTemplate\": \"interview-30\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, "url": { - "raw": "{{URL}}/resourceBookings", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/requestInterview", "host": [ "{{URL}}" ], "path": [ - "resourceBookings" - ], - "query": [ - { - "key": "page", - "value": "1", - "disabled": true - }, - { - "key": "perPage", - "value": "5", - "disabled": true - }, - { - "key": "sortBy", - "value": "id", - "disabled": true - }, - { - "key": "sortOrder", - "value": "desc", - "disabled": true - }, - { - "key": "startDate", - "value": "2020-09-27", - "disabled": true - }, - { - "key": "endDate", - "value": "2020-09-27", - "disabled": true - }, - { - "key": "rateType", - "value": "hourly", - "disabled": true - }, - { - "key": "status", - "value": "assigned", - "disabled": true - }, - { - "key": "projectIds", - "value": "111, 16705", - "disabled": true - } + "jobCandidates", + "{{jobCandidateId}}", + "requestInterview" ] } }, "response": [] }, { - "name": "search resource bookings with m2m all", + "name": "Request interview with booking manager", "event": [ { "listen": "test", @@ -3674,70 +3948,39 @@ } ], "request": { - "method": "GET", + "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_m2m_all_resource_booking}}" + "value": "Bearer {{token_bookingManager}}", + "type": "text" } ], + "body": { + "mode": "raw", + "raw": "{\r\n \"xaiTemplate\": \"interview-30\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, "url": { - "raw": "{{URL}}/resourceBookings", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/requestInterview", "host": [ "{{URL}}" ], "path": [ - "resourceBookings" - ], - "query": [ - { - "key": "page", - "value": "1", - "disabled": true - }, - { - "key": "perPage", - "value": "5", - "disabled": true - }, - { - "key": "sortBy", - "value": "id", - "disabled": true - }, - { - "key": "sortOrder", - "value": "desc", - "disabled": true - }, - { - "key": "startDate", - "value": "2020-09-27", - "disabled": true - }, - { - "key": "endDate", - "value": "2020-09-27", - "disabled": true - }, - { - "key": "rateType", - "value": "hourly", - "disabled": true - }, - { - "key": "status", - "value": "assigned", - "disabled": true - } + "jobCandidates", + "{{jobCandidateId}}", + "requestInterview" ] } }, "response": [] }, { - "name": "search resource bookings with connect user", + "name": "Request interview with m2m (all interview scope)", "event": [ { "listen": "test", @@ -3752,143 +3995,95 @@ } ], "request": { - "method": "GET", + "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_connectUser}}" + "value": "Bearer {{token_m2m_all_interviews}}", + "type": "text" } ], + "body": { + "mode": "raw", + "raw": "{\r\n \"xaiTemplate\": \"interview-30\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, "url": { - "raw": "{{URL}}/resourceBookings?sortOrder=desc", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/requestInterview", "host": [ "{{URL}}" ], "path": [ - "resourceBookings" - ], - "query": [ - { - "key": "page", - "value": "4", - "disabled": true - }, - { - "key": "perPage", - "value": "3", - "disabled": true - }, - { - "key": "sortBy", - "value": "id", - "disabled": true - }, - { - "key": "startDate", - "value": "2020-09-27", - "disabled": true - }, - { - "key": "endDate", - "value": "2020-09-27", - "disabled": true - }, - { - "key": "rateType", - "value": "hourly", - "disabled": true - }, - { - "key": "sortOrder", - "value": "desc" - } + "jobCandidates", + "{{jobCandidateId}}", + "requestInterview" ] } }, "response": [] }, { - "name": "search resource bookings with member", + "name": "Request interview with m2m (create interview scope)", "event": [ { "listen": "test", "script": { "exec": [ - "" + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", + "});" ], "type": "text/javascript" } } ], "request": { - "method": "GET", + "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_member}}" + "value": "Bearer {{token_m2m_create_interviews}}", + "type": "text" } ], + "body": { + "mode": "raw", + "raw": "{\r\n \"xaiTemplate\": \"interview-30\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, "url": { - "raw": "{{URL}}/resourceBookings?sortOrder=desc", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/requestInterview", "host": [ "{{URL}}" ], "path": [ - "resourceBookings" - ], - "query": [ - { - "key": "page", - "value": "4", - "disabled": true - }, - { - "key": "perPage", - "value": "3", - "disabled": true - }, - { - "key": "sortBy", - "value": "id", - "disabled": true - }, - { - "key": "startDate", - "value": "2020-09-27", - "disabled": true - }, - { - "key": "endDate", - "value": "2020-09-27", - "disabled": true - }, - { - "key": "rateType", - "value": "hourly", - "disabled": true - }, - { - "key": "sortOrder", - "value": "desc" - } + "jobCandidates", + "{{jobCandidateId}}", + "requestInterview" ] } }, "response": [] }, { - "name": "search resource bookings with invalid token", + "name": "Request interview with m2m (read interview scope) - should fail", "event": [ { "listen": "test", "script": { "exec": [ "pm.test('Status code is 401', function () {\r", - " pm.response.to.have.status(401);\r", + " pm.response.to.have.status(403);\r", " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"Invalid Token.\")\r", + " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", "});" ], "type": "text/javascript" @@ -3896,71 +4091,48 @@ } ], "request": { - "method": "GET", + "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer invalid_token" + "value": "Bearer {{token_m2m_read_interviews}}", + "type": "text" } ], + "body": { + "mode": "raw", + "raw": "{\r\n \"xaiTemplate\": \"interview-30\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, "url": { - "raw": "{{URL}}/resourceBookings?sortOrder=desc", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/requestInterview", "host": [ "{{URL}}" ], "path": [ - "resourceBookings" - ], - "query": [ - { - "key": "page", - "value": "4", - "disabled": true - }, - { - "key": "perPage", - "value": "3", - "disabled": true - }, - { - "key": "sortBy", - "value": "id", - "disabled": true - }, - { - "key": "startDate", - "value": "2020-09-27", - "disabled": true - }, - { - "key": "endDate", - "value": "2020-09-27", - "disabled": true - }, - { - "key": "rateType", - "value": "hourly", - "disabled": true - }, - { - "key": "sortOrder", - "value": "desc" - } + "jobCandidates", + "{{jobCandidateId}}", + "requestInterview" ] } }, "response": [] }, { - "name": "put resource booking with booking manager", + "name": "Request interview with m2m (update interview scope) - should fail", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 200', function () {\r", - " pm.response.to.have.status(200);\r", + "pm.test('Status code is 401', function () {\r", + " pm.response.to.have.status(403);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", "});" ], "type": "text/javascript" @@ -3968,17 +4140,17 @@ } ], "request": { - "method": "PUT", + "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_bookingManager}}" + "value": "Bearer {{token_m2m_update_interviews}}", + "type": "text" } ], "body": { "mode": "raw", - "raw": "{\r\n \"projectId\": {{projectId}},\r\n \"userId\": \"a55fe1bc-1754-45fa-9adc-cf3d6d7c377a\",\r\n \"jobId\": \"{{jobId}}\",\r\n \"startDate\": \"2020-09-26\",\r\n \"endDate\": \"2020-11-29\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\",\r\n \"status\": \"assigned\",\r\n \"billingAccountId\": 80000071\r\n}", + "raw": "{\r\n \"xaiTemplate\": \"interview-30\"\r\n}", "options": { "raw": { "language": "json" @@ -3986,27 +4158,30 @@ } }, "url": { - "raw": "{{URL}}/resourceBookings/{{resourceBookingId}}", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/requestInterview", "host": [ "{{URL}}" ], "path": [ - "resourceBookings", - "{{resourceBookingId}}" + "jobCandidates", + "{{jobCandidateId}}", + "requestInterview" ] } }, "response": [] }, { - "name": "search extended work periods of resource booking", + "name": "Request interview with connect manager", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 200', function () {\r", - " pm.response.to.have.status(200);\r", + "pm.test('Status code is 401', function () {\r", + " pm.response.to.have.status(403);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", "});" ], "type": "text/javascript" @@ -4014,89 +4189,48 @@ } ], "request": { - "method": "GET", + "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_bookingManager}}" + "value": "Bearer {{token_connect_manager_pshahcopmanag2}}", + "type": "text" } ], + "body": { + "mode": "raw", + "raw": "{\r\n \"xaiTemplate\": \"interview-30\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, "url": { - "raw": "{{URL}}/work-periods?sortBy=startDate&sortOrder=asc&resourceBookingId={{resourceBookingId}}", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/requestInterview", "host": [ "{{URL}}" ], "path": [ - "work-periods" - ], - "query": [ - { - "key": "page", - "value": "1", - "disabled": true - }, - { - "key": "perPage", - "value": "5", - "disabled": true - }, - { - "key": "sortBy", - "value": "startDate" - }, - { - "key": "sortOrder", - "value": "asc" - }, - { - "key": "resourceBookingId", - "value": "{{resourceBookingId}}" - }, - { - "key": "resourceBookingIds", - "value": "{{resourceBookingId}},{{resourceBookingId}}", - "disabled": true - }, - { - "key": "paymentStatus", - "value": "pending", - "disabled": true - }, - { - "key": "startDate", - "value": "2021-03-14", - "disabled": true - }, - { - "key": "endDate", - "value": "2021-03-20", - "disabled": true - }, - { - "key": "userHandle", - "value": "pshah_manager", - "disabled": true - }, - { - "key": "projectId", - "value": "16843", - "disabled": true - } + "jobCandidates", + "{{jobCandidateId}}", + "requestInterview" ] } }, "response": [] }, { - "name": "put resource booking with m2m update", + "name": "Request interview with connect user", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 200', function () {\r", - " pm.response.to.have.status(200);\r", + "pm.test('Status code is 401', function () {\r", + " pm.response.to.have.status(403);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", "});" ], "type": "text/javascript" @@ -4104,17 +4238,17 @@ } ], "request": { - "method": "PUT", + "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_m2m_update_resource_booking}}" + "value": "Bearer {{token_connectUser}}", + "type": "text" } ], "body": { "mode": "raw", - "raw": "{\r\n \"projectId\": {{projectId}},\r\n \"userId\": \"a55fe1bc-1754-45fa-9adc-cf3d6d7c377a\",\r\n \"jobId\": \"{{jobIdCreatedByM2M}}\",\r\n \"startDate\": \"2020-12-27\",\r\n \"endDate\": \"2021-01-10\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\",\r\n \"status\": \"assigned\",\r\n \"billingAccountId\": 80000071\r\n}", + "raw": "{\r\n \"xaiTemplate\": \"interview-30\"\r\n}", "options": { "raw": { "language": "json" @@ -4122,27 +4256,30 @@ } }, "url": { - "raw": "{{URL}}/resourceBookings/{{resourceBookingIdCreatedByM2M}}", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/requestInterview", "host": [ "{{URL}}" ], "path": [ - "resourceBookings", - "{{resourceBookingIdCreatedByM2M}}" + "jobCandidates", + "{{jobCandidateId}}", + "requestInterview" ] } }, "response": [] }, { - "name": "search reduced work periods of resource booking", + "name": "Request interview with member", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 200', function () {\r", - " pm.response.to.have.status(200);\r", + "pm.test('Status code is 401', function () {\r", + " pm.response.to.have.status(403);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", "});" ], "type": "text/javascript" @@ -4150,91 +4287,48 @@ } ], "request": { - "method": "GET", + "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_bookingManager}}" + "value": "Bearer {{token_member}}", + "type": "text" } ], + "body": { + "mode": "raw", + "raw": "{\r\n \"xaiTemplate\": \"interview-30\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, "url": { - "raw": "{{URL}}/work-periods?sortBy=startDate&sortOrder=asc&resourceBookingId={{resourceBookingIdCreatedByM2M}}", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/requestInterview", "host": [ "{{URL}}" ], "path": [ - "work-periods" - ], - "query": [ - { - "key": "page", - "value": "1", - "disabled": true - }, - { - "key": "perPage", - "value": "5", - "disabled": true - }, - { - "key": "sortBy", - "value": "startDate" - }, - { - "key": "sortOrder", - "value": "asc" - }, - { - "key": "resourceBookingId", - "value": "{{resourceBookingIdCreatedByM2M}}" - }, - { - "key": "resourceBookingIds", - "value": "{{resourceBookingIdCreatedByM2M}},{{resourceBookingIdCreatedByM2M}}", - "disabled": true - }, - { - "key": "paymentStatus", - "value": "pending", - "disabled": true - }, - { - "key": "startDate", - "value": "2021-03-14", - "disabled": true - }, - { - "key": "endDate", - "value": "2021-03-20", - "disabled": true - }, - { - "key": "userHandle", - "value": "pshah_manager", - "disabled": true - }, - { - "key": "projectId", - "value": "16843", - "disabled": true - } + "jobCandidates", + "{{jobCandidateId}}", + "requestInterview" ] } }, "response": [] }, { - "name": "put resource booking with connect user", + "name": "Request interview without token", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 403', function () {\r", - " pm.response.to.have.status(403);\r", + "pm.test('Status code is 401', function () {\r", + " pm.response.to.have.status(401);\r", " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", + " pm.expect(response.message).to.eq(\"No token provided.\")\r", "});" ], "type": "text/javascript" @@ -4242,17 +4336,11 @@ } ], "request": { - "method": "PUT", - "header": [ - { - "key": "Authorization", - "type": "text", - "value": "Bearer {{token_connectUser}}" - } - ], + "method": "PATCH", + "header": [], "body": { "mode": "raw", - "raw": "{\r\n \"projectId\": {{projectId}},\r\n \"userId\": \"a55fe1bc-1754-45fa-9adc-cf3d6d7c377a\",\r\n \"jobId\": \"{{jobId}}\",\r\n \"startDate\": \"2020-09-27\",\r\n \"endDate\": \"2020-09-28\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\",\r\n \"status\": \"assigned\",\r\n \"billingAccountId\": 80000071\r\n}", + "raw": "{\r\n \"xaiTemplate\": \"interview-30\"\r\n}", "options": { "raw": { "language": "json" @@ -4260,29 +4348,30 @@ } }, "url": { - "raw": "{{URL}}/resourceBookings/{{resourceBookingId}}", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/requestInterview", "host": [ "{{URL}}" ], "path": [ - "resourceBookings", - "{{resourceBookingId}}" + "jobCandidates", + "{{jobCandidateId}}", + "requestInterview" ] } }, "response": [] }, { - "name": "put resource booking with member", + "name": "Request interview with invalid token", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 403', function () {\r", - " pm.response.to.have.status(403);\r", + "pm.test('Status code is 401', function () {\r", + " pm.response.to.have.status(401);\r", " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", + " pm.expect(response.message).to.eq(\"Invalid Token.\")\r", "});" ], "type": "text/javascript" @@ -4290,17 +4379,17 @@ } ], "request": { - "method": "PUT", + "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_member}}" + "value": "Bearer invalid_token", + "type": "text" } ], "body": { "mode": "raw", - "raw": "{\r\n \"projectId\": {{projectId}},\r\n \"userId\": \"a55fe1bc-1754-45fa-9adc-cf3d6d7c377a\",\r\n \"jobId\": \"{{jobId}}\",\r\n \"startDate\": \"2020-09-27\",\r\n \"endDate\": \"2020-09-28\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\",\r\n \"status\": \"assigned\",\r\n \"billingAccountId\": 80000071\r\n}", + "raw": "{\r\n \"xaiTemplate\": \"interview-30\"\r\n}", "options": { "raw": { "language": "json" @@ -4308,29 +4397,28 @@ } }, "url": { - "raw": "{{URL}}/resourceBookings/{{resourceBookingId}}", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/requestInterview", "host": [ "{{URL}}" ], "path": [ - "resourceBookings", - "{{resourceBookingId}}" + "jobCandidates", + "{{jobCandidateId}}", + "requestInterview" ] } }, "response": [] }, { - "name": "put resource booking with user id not exist", + "name": "Get interview by round", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 400', function () {\r", - " pm.response.to.have.status(400);\r", - " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"Bad Request\")\r", + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200)\r", "});" ], "type": "text/javascript" @@ -4338,47 +4426,38 @@ } ], "request": { - "method": "PUT", + "method": "GET", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_userId_not_exist}}" + "value": "Bearer {{token_bookingManager}}", + "type": "text" } ], - "body": { - "mode": "raw", - "raw": "{\r\n \"projectId\": {{projectId}},\r\n \"userId\": \"a55fe1bc-1754-45fa-9adc-cf3d6d7c377a\",\r\n \"jobId\": \"{{jobId}}\",\r\n \"startDate\": \"2020-09-27\",\r\n \"endDate\": \"2020-09-28\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\",\r\n \"status\": \"assigned\",\r\n \"billingAccountId\": 80000071\r\n}", - "options": { - "raw": { - "language": "json" - } - } - }, "url": { - "raw": "{{URL}}/resourceBookings/{{resourceBookingId}}", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/interviews/{{interviewRound}}", "host": [ "{{URL}}" ], "path": [ - "resourceBookings", - "{{resourceBookingId}}" + "jobCandidates", + "{{jobCandidateId}}", + "interviews", + "{{interviewRound}}" ] } }, "response": [] }, { - "name": "put resource booking with invalid token", + "name": "Get interview fromDb by round", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 401', function () {\r", - " pm.response.to.have.status(401);\r", - " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"Invalid Token.\")\r", + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200)\r", "});" ], "type": "text/javascript" @@ -4386,45 +4465,46 @@ } ], "request": { - "method": "PUT", + "method": "GET", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer invalid_token" + "value": "Bearer {{token_bookingManager}}", + "type": "text" } ], - "body": { - "mode": "raw", - "raw": "{\r\n \"projectId\": {{projectId}},\r\n \"userId\": \"a55fe1bc-1754-45fa-9adc-cf3d6d7c377a\",\r\n \"jobId\": \"{{jobId}}\",\r\n \"startDate\": \"2020-09-27\",\r\n \"endDate\": \"2020-09-28\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\",\r\n \"status\": \"assigned\",\r\n \"billingAccountId\": 80000071\r\n}", - "options": { - "raw": { - "language": "json" - } - } - }, "url": { - "raw": "{{URL}}/resourceBookings/{{resourceBookingId}}", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/interviews/{{interviewRound}}?fromDb=true", "host": [ "{{URL}}" ], "path": [ - "resourceBookings", - "{{resourceBookingId}}" + "jobCandidates", + "{{jobCandidateId}}", + "interviews", + "{{interviewRound}}" + ], + "query": [ + { + "key": "fromDb", + "value": "true" + } ] } }, "response": [] }, { - "name": "patch resource booking with booking manager", + "name": "Get interview by negative round", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 200', function () {\r", - " pm.response.to.have.status(200);\r", + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"\\\"round\\\" must be a positive number\")\r", "});" ], "type": "text/javascript" @@ -4432,45 +4512,40 @@ } ], "request": { - "method": "PATCH", + "method": "GET", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_bookingManager}}" + "value": "Bearer {{token_bookingManager}}", + "type": "text" } ], - "body": { - "mode": "raw", - "raw": "{\r\n \"status\": \"assigned\",\r\n \"startDate\": \"2020-09-30\",\r\n \"endDate\": \"2020-11-28\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\",\r\n \"billingAccountId\": 80000071\r\n}", - "options": { - "raw": { - "language": "json" - } - } - }, "url": { - "raw": "{{URL}}/resourceBookings/{{resourceBookingId}}", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/interviews/-1", "host": [ "{{URL}}" ], "path": [ - "resourceBookings", - "{{resourceBookingId}}" + "jobCandidates", + "{{jobCandidateId}}", + "interviews", + "-1" ] } }, "response": [] }, { - "name": "patch resource booking with m2m update", + "name": "Get interview by round=0", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 200', function () {\r", - " pm.response.to.have.status(200);\r", + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"\\\"round\\\" must be a positive number\")\r", "});" ], "type": "text/javascript" @@ -4478,47 +4553,40 @@ } ], "request": { - "method": "PATCH", + "method": "GET", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_m2m_update_resource_booking}}" - } - ], - "body": { - "mode": "raw", - "raw": "{\r\n \"status\": \"assigned\",\r\n \"startDate\": \"2020-12-30\",\r\n \"endDate\": \"2021-02-10\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\",\r\n \"billingAccountId\": 80000071\r\n}", - "options": { - "raw": { - "language": "json" - } + "value": "Bearer {{token_bookingManager}}", + "type": "text" } - }, + ], "url": { - "raw": "{{URL}}/resourceBookings/{{resourceBookingIdCreatedByM2M}}", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/interviews/0", "host": [ "{{URL}}" ], "path": [ - "resourceBookings", - "{{resourceBookingIdCreatedByM2M}}" + "jobCandidates", + "{{jobCandidateId}}", + "interviews", + "0" ] } }, "response": [] }, { - "name": "patch resource booking with connect user", + "name": "Get interview by non-existing round", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 403', function () {\r", - " pm.response.to.have.status(403);\r", + "pm.test('Status code is 404', function () {\r", + " pm.response.to.have.status(404);\r", " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", + " pm.expect(response.message).to.eq(\"Interview doesn't exist with round: 999\")\r", "});" ], "type": "text/javascript" @@ -4526,47 +4594,38 @@ } ], "request": { - "method": "PATCH", + "method": "GET", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_connectUser}}" + "value": "Bearer {{token_bookingManager}}", + "type": "text" } ], - "body": { - "mode": "raw", - "raw": "{\r\n \"status\": \"assigned\",\r\n \"startDate\": \"2020-09-27\",\r\n \"endDate\": \"2020-09-28\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\",\r\n \"billingAccountId\": 80000071\r\n}", - "options": { - "raw": { - "language": "json" - } - } - }, "url": { - "raw": "{{URL}}/resourceBookings/{{resourceBookingId}}", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/interviews/999", "host": [ "{{URL}}" ], "path": [ - "resourceBookings", - "{{resourceBookingId}}" + "jobCandidates", + "{{jobCandidateId}}", + "interviews", + "999" ] } }, "response": [] }, { - "name": "patch resource booking with member", + "name": "Get interview with administrator", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 403', function () {\r", - " pm.response.to.have.status(403);\r", - " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", "});" ], "type": "text/javascript" @@ -4574,47 +4633,38 @@ } ], "request": { - "method": "PATCH", + "method": "GET", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_member}}" + "value": "Bearer {{token_administrator}}", + "type": "text" } ], - "body": { - "mode": "raw", - "raw": "{\r\n \"status\": \"assigned\",\r\n \"startDate\": \"2020-09-27\",\r\n \"endDate\": \"2020-09-28\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\",\r\n \"billingAccountId\": 80000071\r\n}", - "options": { - "raw": { - "language": "json" - } - } - }, "url": { - "raw": "{{URL}}/resourceBookings/{{resourceBookingId}}", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/interviews/{{interviewRound}}", "host": [ "{{URL}}" ], "path": [ - "resourceBookings", - "{{resourceBookingId}}" + "jobCandidates", + "{{jobCandidateId}}", + "interviews", + "{{interviewRound}}" ] } }, "response": [] }, { - "name": "patch resource booking with user id not exist", + "name": "Get interview with booking manager", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 400', function () {\r", - " pm.response.to.have.status(400);\r", - " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"Bad Request\")\r", + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", "});" ], "type": "text/javascript" @@ -4622,47 +4672,38 @@ } ], "request": { - "method": "PATCH", + "method": "GET", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_userId_not_exist}}" + "value": "Bearer {{token_bookingManager}}", + "type": "text" } ], - "body": { - "mode": "raw", - "raw": "{\r\n \"status\": \"assigned\",\r\n \"startDate\": \"2020-09-27\",\r\n \"endDate\": \"2020-09-28\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\",\r\n \"billingAccountId\": 80000071\r\n}", - "options": { - "raw": { - "language": "json" - } - } - }, "url": { - "raw": "{{URL}}/resourceBookings/{{resourceBookingId}}", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/interviews/{{interviewRound}}", "host": [ "{{URL}}" ], "path": [ - "resourceBookings", - "{{resourceBookingId}}" + "jobCandidates", + "{{jobCandidateId}}", + "interviews", + "{{interviewRound}}" ] } }, "response": [] }, { - "name": "patch resource booking with invalid token", + "name": "Get interview with m2m (all interview scope)", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 401', function () {\r", - " pm.response.to.have.status(401);\r", - " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"Invalid Token.\")\r", + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", "});" ], "type": "text/javascript" @@ -4670,38 +4711,31 @@ } ], "request": { - "method": "PATCH", + "method": "GET", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer invalid_token" + "value": "Bearer {{token_m2m_all_interviews}}", + "type": "text" } ], - "body": { - "mode": "raw", - "raw": "{\r\n \"status\": \"assigned\",\r\n \"startDate\": \"2020-09-27\",\r\n \"endDate\": \"2020-09-27\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\",\r\n \"billingAccountId\": 80000071\r\n}", - "options": { - "raw": { - "language": "json" - } - } - }, "url": { - "raw": "{{URL}}/resourceBookings/{{resourceBookingId}}", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/interviews/{{interviewRound}}", "host": [ "{{URL}}" ], "path": [ - "resourceBookings", - "{{resourceBookingId}}" + "jobCandidates", + "{{jobCandidateId}}", + "interviews", + "{{interviewRound}}" ] } }, "response": [] }, { - "name": "search work periods", + "name": "Get interview with m2m (read interview scope)", "event": [ { "listen": "test", @@ -4709,8 +4743,6 @@ "exec": [ "pm.test('Status code is 200', function () {\r", " pm.response.to.have.status(200);\r", - " const response = pm.response.json()\r", - " pm.environment.set(\"workPeriodIdForPaid\", response[0].id);\r", "});" ], "type": "text/javascript" @@ -4722,84 +4754,36 @@ "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_bookingManager}}" + "value": "Bearer {{token_m2m_read_interviews}}", + "type": "text" } ], "url": { - "raw": "{{URL}}/work-periods?perPage=1&sortBy=startDate&sortOrder=asc&resourceBookingId={{resourceBookingId}}", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/interviews/{{interviewRound}}", "host": [ "{{URL}}" ], "path": [ - "work-periods" - ], - "query": [ - { - "key": "page", - "value": "1", - "disabled": true - }, - { - "key": "perPage", - "value": "1" - }, - { - "key": "sortBy", - "value": "startDate" - }, - { - "key": "sortOrder", - "value": "asc" - }, - { - "key": "resourceBookingId", - "value": "{{resourceBookingId}}" - }, - { - "key": "resourceBookingIds", - "value": "{{resourceBookingId}},{{resourceBookingId}}", - "disabled": true - }, - { - "key": "paymentStatus", - "value": "pending", - "disabled": true - }, - { - "key": "startDate", - "value": "2021-03-14", - "disabled": true - }, - { - "key": "endDate", - "value": "2021-03-20", - "disabled": true - }, - { - "key": "userHandle", - "value": "pshah_manager", - "disabled": true - }, - { - "key": "projectId", - "value": "16843", - "disabled": true - } + "jobCandidates", + "{{jobCandidateId}}", + "interviews", + "{{interviewRound}}" ] } }, "response": [] }, { - "name": "patch work period set status to completed", + "name": "Get interview with m2m (create interview scope) - should fail", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 200', function () {\r", - " pm.response.to.have.status(200);\r", + "pm.test('Status code is 404', function () {\r", + " pm.response.to.have.status(403);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", "});" ], "type": "text/javascript" @@ -4807,45 +4791,40 @@ } ], "request": { - "method": "PATCH", + "method": "GET", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_bookingManager}}" + "value": "Bearer {{token_m2m_create_interviews}}", + "type": "text" } ], - "body": { - "mode": "raw", - "raw": "{\r\n \"paymentStatus\": \"completed\"\r\n}", - "options": { - "raw": { - "language": "json" - } - } - }, "url": { - "raw": "{{URL}}/work-periods/{{workPeriodIdForPaid}}", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/interviews/{{interviewRound}}", "host": [ "{{URL}}" ], "path": [ - "work-periods", - "{{workPeriodIdForPaid}}" + "jobCandidates", + "{{jobCandidateId}}", + "interviews", + "{{interviewRound}}" ] } }, "response": [] }, { - "name": "patch resource booking to cancelled", + "name": "Get interview with m2m (update interview scope) - should fail", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 400', function () {\r", - " pm.response.to.have.status(400);\r", + "pm.test('Status code is 404', function () {\r", + " pm.response.to.have.status(403);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", "});" ], "type": "text/javascript" @@ -4853,45 +4832,40 @@ } ], "request": { - "method": "PATCH", + "method": "GET", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_bookingManager}}" + "value": "Bearer {{token_m2m_update_interviews}}", + "type": "text" } ], - "body": { - "mode": "raw", - "raw": "{\r\n \"status\": \"cancelled\",\r\n \"billingAccountId\": 80000071\r\n}", - "options": { - "raw": { - "language": "json" - } - } - }, "url": { - "raw": "{{URL}}/resourceBookings/{{resourceBookingId}}", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/interviews/{{interviewRound}}", "host": [ "{{URL}}" ], "path": [ - "resourceBookings", - "{{resourceBookingId}}" + "jobCandidates", + "{{jobCandidateId}}", + "interviews", + "{{interviewRound}}" ] } }, "response": [] }, { - "name": "patch resource booking to reduce", + "name": "Get interview with connect manager", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 400', function () {\r", - " pm.response.to.have.status(400);\r", + "pm.test('Status code is 403', function () {\r", + " pm.response.to.have.status(403);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", "});" ], "type": "text/javascript" @@ -4899,38 +4873,31 @@ } ], "request": { - "method": "PATCH", + "method": "GET", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_bookingManager}}" + "value": "Bearer {{token_connect_manager_pshahcopmanag2}}", + "type": "text" } ], - "body": { - "mode": "raw", - "raw": "{\r\n \"startDate\": \"2020-10-04\",\r\n \"billingAccountId\": 80000071\r\n}", - "options": { - "raw": { - "language": "json" - } - } - }, "url": { - "raw": "{{URL}}/resourceBookings/{{resourceBookingId}}", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/interviews/{{interviewRound}}", "host": [ "{{URL}}" ], "path": [ - "resourceBookings", - "{{resourceBookingId}}" + "jobCandidates", + "{{jobCandidateId}}", + "interviews", + "{{interviewRound}}" ] } }, "response": [] }, { - "name": "delete resource booking with member", + "name": "Get interview with connect user", "event": [ { "listen": "test", @@ -4947,38 +4914,31 @@ } ], "request": { - "method": "DELETE", + "method": "GET", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_member}}" + "value": "Bearer {{token_connectUser}}", + "type": "text" } ], - "body": { - "mode": "raw", - "raw": "", - "options": { - "raw": { - "language": "json" - } - } - }, "url": { - "raw": "{{URL}}/resourceBookings/{{resourceBookingId}}", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/interviews/{{interviewRound}}", "host": [ "{{URL}}" ], "path": [ - "resourceBookings", - "{{resourceBookingId}}" + "jobCandidates", + "{{jobCandidateId}}", + "interviews", + "{{interviewRound}}" ] } }, "response": [] }, { - "name": "delete resource booking with connect user", + "name": "Get interview with member", "event": [ { "listen": "test", @@ -4995,45 +4955,40 @@ } ], "request": { - "method": "DELETE", + "method": "GET", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_connectUser}}" + "value": "Bearer {{token_member}}", + "type": "text" } ], - "body": { - "mode": "raw", - "raw": "", - "options": { - "raw": { - "language": "json" - } - } - }, "url": { - "raw": "{{URL}}/resourceBookings/{{resourceBookingId}}", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/interviews/{{interviewRound}}", "host": [ "{{URL}}" ], "path": [ - "resourceBookings", - "{{resourceBookingId}}" + "jobCandidates", + "{{jobCandidateId}}", + "interviews", + "{{interviewRound}}" ] } }, "response": [] }, { - "name": "delete resource booking with booking manager", + "name": "Get interview by round without token", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 400', function () {\r", - " pm.response.to.have.status(400);\r", + "pm.test('Status code is 401', function () {\r", + " pm.response.to.have.status(401);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"No token provided.\")\r", "});" ], "type": "text/javascript" @@ -5041,45 +4996,34 @@ } ], "request": { - "method": "DELETE", - "header": [ - { - "key": "Authorization", - "type": "text", - "value": "Bearer {{token_bookingManager}}" - } - ], - "body": { - "mode": "raw", - "raw": "", - "options": { - "raw": { - "language": "json" - } - } - }, + "method": "GET", + "header": [], "url": { - "raw": "{{URL}}/resourceBookings/{{resourceBookingId}}", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/interviews/1", "host": [ "{{URL}}" ], "path": [ - "resourceBookings", - "{{resourceBookingId}}" + "jobCandidates", + "{{jobCandidateId}}", + "interviews", + "1" ] } }, "response": [] }, { - "name": "delete resource booking with m2m delete", + "name": "Get interview by round with invalid token", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 204', function () {\r", - " pm.response.to.have.status(204);\r", + "pm.test('Status code is 401', function () {\r", + " pm.response.to.have.status(401);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"Invalid Token.\")\r", "});" ], "type": "text/javascript" @@ -5087,47 +5031,38 @@ } ], "request": { - "method": "DELETE", + "method": "GET", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_m2m_delete_resource_booking}}" + "value": "Bearer invalid_token", + "type": "text" } ], - "body": { - "mode": "raw", - "raw": "", - "options": { - "raw": { - "language": "json" - } - } - }, "url": { - "raw": "{{URL}}/resourceBookings/{{resourceBookingIdCreatedByM2M}}", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/interviews/1", "host": [ "{{URL}}" ], "path": [ - "resourceBookings", - "{{resourceBookingIdCreatedByM2M}}" + "jobCandidates", + "{{jobCandidateId}}", + "interviews", + "1" ] } }, "response": [] }, { - "name": "delete resource booking with invalid token", + "name": "Update interview", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 401', function () {\r", - " pm.response.to.have.status(401);\r", - " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"Invalid Token.\")\r", + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200)\r", "});" ], "type": "text/javascript" @@ -5135,17 +5070,17 @@ } ], "request": { - "method": "DELETE", + "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer invalid_token" + "value": "Bearer {{token_bookingManager}}", + "type": "text" } ], "body": { "mode": "raw", - "raw": "", + "raw": "{\r\n \"googleCalendarId\": \"dummyIdXX\",\r\n \"customMessage\": \"This is the updated message\"\r\n}", "options": { "raw": { "language": "json" @@ -5153,139 +5088,31 @@ } }, "url": { - "raw": "{{URL}}/resourceBookings/{{resourceBookingId}}", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/updateInterview/{{interviewRound}}", "host": [ "{{URL}}" ], "path": [ - "resourceBookings", - "{{resourceBookingId}}" + "jobCandidates", + "{{jobCandidateId}}", + "updateInterview", + "{{interviewRound}}" ] } }, "response": [] - } - ] - }, - { - "name": "Work Periods", - "item": [ - { - "name": "Before Test", - "item": [ - { - "name": "create job", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "pm.test('Status code is 200', function () {\r", - " pm.response.to.have.status(200);\r", - " if(pm.response.status === \"OK\"){\r", - " const response = pm.response.json()\r", - " pm.environment.set(\"jobId\", response.id);\r", - " }\r", - "});" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "POST", - "header": [ - { - "key": "Authorization", - "value": "Bearer {{token_bookingManager}}", - "type": "text" - } - ], - "body": { - "mode": "raw", - "raw": "{\n \"projectId\": {{projectId}},\n \"externalId\": \"1212\",\n \"description\": \"Dummy Description\",\n \"startDate\": \"2020-09-27T04:17:23.131Z\",\n \"duration\": 1,\n \"numPositions\": 13,\n \"resourceType\": \"Dummy Resource Type\",\n \"rateType\": \"hourly\",\n \"workload\": \"full-time\",\n \"skills\": [\n \"23e00d92-207a-4b5b-b3c9-4c5662644941\",\n \"7d076384-ccf6-4e43-a45d-1b24b1e624aa\",\n \"cbac57a3-7180-4316-8769-73af64893158\",\n \"a2b4bc11-c641-4a19-9eb7-33980378f82e\"\n ],\n \"title\": \"Dummy title - at most 64 characters\"\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "{{URL}}/jobs", - "host": [ - "{{URL}}" - ], - "path": [ - "jobs" - ] - } - }, - "response": [] - }, - { - "name": "create resource booking", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "pm.test('Status code is 200', function () {\r", - " pm.response.to.have.status(200);\r", - " if(pm.response.status === \"OK\"){\r", - " const response = pm.response.json()\r", - " pm.environment.set(\"resourceBookingId\", response.id);\r", - " }\r", - "});" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "POST", - "header": [ - { - "key": "Authorization", - "type": "text", - "value": "Bearer {{token_bookingManager}}" - } - ], - "body": { - "mode": "raw", - "raw": "{\r\n \"projectId\": {{projectId}},\r\n \"userId\": \"a55fe1bc-1754-45fa-9adc-cf3d6d7c377a\",\r\n \"jobId\": \"{{jobId}}\",\r\n \"startDate\": \"2020-09-27\",\r\n \"endDate\": \"2020-09-27\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\",\r\n \"billingAccountId\": 80000071\r\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "{{URL}}/resourceBookings", - "host": [ - "{{URL}}" - ], - "path": [ - "resourceBookings" - ] - } - }, - "response": [] - } - ] }, { - "name": "create work period with booking manager", + "name": "Update interview with empty payload", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 200', function () {\r", - " pm.response.to.have.status(200);\r", - " if(pm.response.status === \"OK\"){\r", - " const response = pm.response.json()\r", - " pm.environment.set(\"workPeriodId\", response.id);\r", - " }\r", + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"\\\"data\\\" must have at least 1 key\")\r", "});" ], "type": "text/javascript" @@ -5293,17 +5120,17 @@ } ], "request": { - "method": "POST", + "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_bookingManager}}" + "value": "Bearer {{token_bookingManager}}", + "type": "text" } ], "body": { "mode": "raw", - "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-07\",\r\n \"endDate\": \"2021-03-13\",\r\n \"daysWorked\": 2,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"pending\"\r\n}", + "raw": "{}", "options": { "raw": { "language": "json" @@ -5311,30 +5138,31 @@ } }, "url": { - "raw": "{{URL}}/work-periods", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/updateInterview/{{interviewRound}}", "host": [ "{{URL}}" ], "path": [ - "work-periods" + "jobCandidates", + "{{jobCandidateId}}", + "updateInterview", + "{{interviewRound}}" ] } }, "response": [] }, { - "name": "create work period with m2m create", + "name": "Update interview with invalid startTimestamp", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 200', function () {\r", - " pm.response.to.have.status(200);\r", - " if(pm.response.status === \"OK\"){\r", - " const response = pm.response.json()\r", - " pm.environment.set(\"workPeriodIdCreatedByM2M\", response.id);\r", - " }\r", + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"\\\"data.startTimestamp\\\" must be a valid date\")\r", "});" ], "type": "text/javascript" @@ -5342,17 +5170,17 @@ } ], "request": { - "method": "POST", + "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_m2m_create_work_period}}" + "value": "Bearer {{token_bookingManager}}", + "type": "text" } ], "body": { "mode": "raw", - "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-14\",\r\n \"endDate\": \"2021-03-20\",\r\n \"daysWorked\": 3,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"cancelled\"\r\n}", + "raw": "{\r\n \"startTimestamp\": \"xxx\"\r\n}", "options": { "raw": { "language": "json" @@ -5360,28 +5188,31 @@ } }, "url": { - "raw": "{{URL}}/work-periods", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/updateInterview/{{interviewRound}}", "host": [ "{{URL}}" ], "path": [ - "work-periods" + "jobCandidates", + "{{jobCandidateId}}", + "updateInterview", + "{{interviewRound}}" ] } }, "response": [] }, { - "name": "create work period with connect user", + "name": "Update interview with past startTimestamp", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 403', function () {\r", - " pm.response.to.have.status(403);\r", + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", + " pm.expect(response.message).to.eq(\"\\\"data.startTimestamp\\\" must be greater than \\\"now\\\"\")\r", "});" ], "type": "text/javascript" @@ -5389,17 +5220,17 @@ } ], "request": { - "method": "POST", + "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_connectUser}}" + "value": "Bearer {{token_bookingManager}}", + "type": "text" } ], "body": { "mode": "raw", - "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-21\",\r\n \"endDate\": \"2021-03-27\",\r\n \"daysWorked\": 3,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"cancelled\"\r\n}", + "raw": "{\r\n \"startTimestamp\": \"2021-04-01\"\r\n}", "options": { "raw": { "language": "json" @@ -5407,28 +5238,31 @@ } }, "url": { - "raw": "{{URL}}/work-periods", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/updateInterview/{{interviewRound}}", "host": [ "{{URL}}" ], "path": [ - "work-periods" + "jobCandidates", + "{{jobCandidateId}}", + "updateInterview", + "{{interviewRound}}" ] } }, "response": [] }, { - "name": "create work period with member", + "name": "Update interview with invalid status", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 403', function () {\r", - " pm.response.to.have.status(403);\r", + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", + " pm.expect(response.message).to.eq(\"\\\"data.status\\\" must be one of [Scheduling, Scheduled, Requested for reschedule, Rescheduled, Completed, Cancelled]\")\r", "});" ], "type": "text/javascript" @@ -5436,17 +5270,17 @@ } ], "request": { - "method": "POST", + "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_member}}" + "value": "Bearer {{token_bookingManager}}", + "type": "text" } ], "body": { "mode": "raw", - "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-21\",\r\n \"endDate\": \"2021-03-27\",\r\n \"daysWorked\": 3,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"cancelled\"\r\n}", + "raw": "{\r\n \"status\": \"xxx\"\r\n}", "options": { "raw": { "language": "json" @@ -5454,19 +5288,22 @@ } }, "url": { - "raw": "{{URL}}/work-periods", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/updateInterview/{{interviewRound}}", "host": [ "{{URL}}" ], "path": [ - "work-periods" + "jobCandidates", + "{{jobCandidateId}}", + "updateInterview", + "{{interviewRound}}" ] } }, "response": [] }, { - "name": "create work period with user id not exist", + "name": "Update interview with invalid xaiTemplate", "event": [ { "listen": "test", @@ -5475,7 +5312,7 @@ "pm.test('Status code is 400', function () {\r", " pm.response.to.have.status(400);\r", " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"Bad Request\")\r", + " pm.expect(response.message).to.eq(\"\\\"data.xaiTemplate\\\" must be one of [interview-30, interview-60]\")\r", "});" ], "type": "text/javascript" @@ -5483,17 +5320,17 @@ } ], "request": { - "method": "POST", + "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_userId_not_exist}}" + "value": "Bearer {{token_bookingManager}}", + "type": "text" } ], "body": { "mode": "raw", - "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-21\",\r\n \"endDate\": \"2021-03-27\",\r\n \"daysWorked\": 3,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"cancelled\"\r\n}", + "raw": "{\r\n \"xaiTemplate\": \"xxx\"\r\n}", "options": { "raw": { "language": "json" @@ -5501,28 +5338,31 @@ } }, "url": { - "raw": "{{URL}}/work-periods", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/updateInterview/{{interviewRound}}", "host": [ "{{URL}}" ], "path": [ - "work-periods" + "jobCandidates", + "{{jobCandidateId}}", + "updateInterview", + "{{interviewRound}}" ] } }, "response": [] }, { - "name": "create work period with invalid token", + "name": "Update interview status to Scheduled without googleCalendarId", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 401', function () {\r", - " pm.response.to.have.status(401);\r", + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"Invalid Token.\")\r", + " pm.expect(response.message).to.eq(\"\\\"data.googleCalendarId\\\" is required\")\r", "});" ], "type": "text/javascript" @@ -5530,17 +5370,17 @@ } ], "request": { - "method": "POST", + "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer invalid_token" + "value": "Bearer {{token_bookingManager}}", + "type": "text" } ], "body": { "mode": "raw", - "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-21\",\r\n \"endDate\": \"2021-03-27\",\r\n \"daysWorked\": 3,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"cancelled\"\r\n}", + "raw": "{\r\n \"startTimestamp\": \"2030-12-12\",\r\n \"status\": \"Scheduled\"\r\n}", "options": { "raw": { "language": "json" @@ -5548,19 +5388,22 @@ } }, "url": { - "raw": "{{URL}}/work-periods", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/updateInterview/{{interviewRound}}", "host": [ "{{URL}}" ], "path": [ - "work-periods" + "jobCandidates", + "{{jobCandidateId}}", + "updateInterview", + "{{interviewRound}}" ] } }, "response": [] }, { - "name": "create work period with missing parameter 1", + "name": "Update interview status to Scheduled without startTimestamp", "event": [ { "listen": "test", @@ -5569,7 +5412,7 @@ "pm.test('Status code is 400', function () {\r", " pm.response.to.have.status(400);\r", " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"\\\"workPeriod.resourceBookingId\\\" is required\")\r", + " pm.expect(response.message).to.eq(\"\\\"data.startTimestamp\\\" is required\")\r", "});" ], "type": "text/javascript" @@ -5577,17 +5420,17 @@ } ], "request": { - "method": "POST", + "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_bookingManager}}" + "value": "Bearer {{token_bookingManager}}", + "type": "text" } ], "body": { "mode": "raw", - "raw": "{\r\n \"startDate\": \"2021-03-07\",\r\n \"endDate\": \"2021-03-13\",\r\n \"daysWorked\": 2,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"pending\"\r\n}", + "raw": "{\r\n \"googleCalendarId\": \"sdsds\",\r\n \"status\": \"Scheduled\"\r\n}", "options": { "raw": { "language": "json" @@ -5595,19 +5438,22 @@ } }, "url": { - "raw": "{{URL}}/work-periods", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/updateInterview/{{interviewRound}}", "host": [ "{{URL}}" ], "path": [ - "work-periods" + "jobCandidates", + "{{jobCandidateId}}", + "updateInterview", + "{{interviewRound}}" ] } }, "response": [] }, { - "name": "create work period with missing parameter 2", + "name": "Update interview status to Rescheduled without googleCalendarId", "event": [ { "listen": "test", @@ -5616,7 +5462,7 @@ "pm.test('Status code is 400', function () {\r", " pm.response.to.have.status(400);\r", " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"\\\"workPeriod.endDate\\\" is required\")\r", + " pm.expect(response.message).to.eq(\"\\\"data.googleCalendarId\\\" is required\")\r", "});" ], "type": "text/javascript" @@ -5624,17 +5470,17 @@ } ], "request": { - "method": "POST", + "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_bookingManager}}" + "value": "Bearer {{token_bookingManager}}", + "type": "text" } ], "body": { "mode": "raw", - "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"daysWorked\": 2,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"pending\"\r\n}", + "raw": "{\r\n \"startTimestamp\": \"2030-12-12\",\r\n \"status\": \"Rescheduled\"\r\n}", "options": { "raw": { "language": "json" @@ -5642,19 +5488,22 @@ } }, "url": { - "raw": "{{URL}}/work-periods", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/updateInterview/{{interviewRound}}", "host": [ "{{URL}}" ], "path": [ - "work-periods" + "jobCandidates", + "{{jobCandidateId}}", + "updateInterview", + "{{interviewRound}}" ] } }, "response": [] }, { - "name": "create work period with missing parameter 3", + "name": "Update interview status to Rescheduled without startTimestamp", "event": [ { "listen": "test", @@ -5663,7 +5512,7 @@ "pm.test('Status code is 400', function () {\r", " pm.response.to.have.status(400);\r", " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"\\\"workPeriod.paymentStatus\\\" is required\")\r", + " pm.expect(response.message).to.eq(\"\\\"data.startTimestamp\\\" is required\")\r", "});" ], "type": "text/javascript" @@ -5671,17 +5520,17 @@ } ], "request": { - "method": "POST", + "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_bookingManager}}" + "value": "Bearer {{token_bookingManager}}", + "type": "text" } ], "body": { "mode": "raw", - "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-07\",\r\n \"endDate\": \"2021-03-13\",\r\n \"daysWorked\": 2,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13\r\n}", + "raw": "{\r\n \"googleCalendarId\": \"sdsds\",\r\n \"status\": \"Rescheduled\"\r\n}", "options": { "raw": { "language": "json" @@ -5689,19 +5538,22 @@ } }, "url": { - "raw": "{{URL}}/work-periods", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/updateInterview/{{interviewRound}}", "host": [ "{{URL}}" ], "path": [ - "work-periods" + "jobCandidates", + "{{jobCandidateId}}", + "updateInterview", + "{{interviewRound}}" ] } }, "response": [] }, { - "name": "create work period with invalid parameter 1", + "name": "Update Completed interview without status", "event": [ { "listen": "test", @@ -5710,7 +5562,7 @@ "pm.test('Status code is 400', function () {\r", " pm.response.to.have.status(400);\r", " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"\\\"workPeriod.resourceBookingId\\\" must be a valid GUID\")\r", + " pm.expect(response.message).to.eq(\"Only the \\\"status\\\" can be updated for Completed interviews.\")\r", "});" ], "type": "text/javascript" @@ -5718,17 +5570,17 @@ } ], "request": { - "method": "POST", + "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_bookingManager}}" + "value": "Bearer {{token_bookingManager}}", + "type": "text" } ], "body": { "mode": "raw", - "raw": "{\r\n \"resourceBookingId\": \"aaa-aaa\",\r\n \"startDate\": \"2021-03-07\",\r\n \"endDate\": \"2021-03-13\",\r\n \"daysWorked\": 2,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"pending\"\r\n}", + "raw": "{\r\n \"googleCalendarId\": \"sdsds\"\r\n}", "options": { "raw": { "language": "json" @@ -5736,19 +5588,22 @@ } }, "url": { - "raw": "{{URL}}/work-periods", + "raw": "{{URL}}/jobCandidates/{{completedInterviewJobCandidateId}}/updateInterview/{{completedInterviewRound}}", "host": [ "{{URL}}" ], "path": [ - "work-periods" + "jobCandidates", + "{{completedInterviewJobCandidateId}}", + "updateInterview", + "{{completedInterviewRound}}" ] } }, "response": [] }, { - "name": "create work period with invalid parameter 2", + "name": "Update Completed interview with additional fields", "event": [ { "listen": "test", @@ -5757,7 +5612,7 @@ "pm.test('Status code is 400', function () {\r", " pm.response.to.have.status(400);\r", " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"\\\"workPeriod.startDate\\\" must be in YYYY-MM-DD format\")\r", + " pm.expect(response.message).to.eq(\"Only the \\\"status\\\" can be updated for Completed interviews.\")\r", "});" ], "type": "text/javascript" @@ -5765,17 +5620,17 @@ } ], "request": { - "method": "POST", + "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_bookingManager}}" + "value": "Bearer {{token_bookingManager}}", + "type": "text" } ], "body": { "mode": "raw", - "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"07-03-2021\",\r\n \"endDate\": \"2021-03-13\",\r\n \"daysWorked\": 2,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"pending\"\r\n}", + "raw": "{\r\n \"googleCalendarId\": \"sdsds\",\r\n \"status\": \"Scheduling\"\r\n}", "options": { "raw": { "language": "json" @@ -5783,28 +5638,31 @@ } }, "url": { - "raw": "{{URL}}/work-periods", + "raw": "{{URL}}/jobCandidates/{{completedInterviewJobCandidateId}}/updateInterview/{{completedInterviewRound}}", "host": [ "{{URL}}" ], "path": [ - "work-periods" + "jobCandidates", + "{{completedInterviewJobCandidateId}}", + "updateInterview", + "{{completedInterviewRound}}" ] } }, "response": [] }, { - "name": "create work period with invalid parameter 3", + "name": "Update Completed interview with only status", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 400', function () {\r", - " pm.response.to.have.status(400);\r", + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"startDate should be always Sunday\")\r", + " pm.expect(response.status).to.eq(\"Scheduling\")\r", "});" ], "type": "text/javascript" @@ -5812,17 +5670,17 @@ } ], "request": { - "method": "POST", + "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_bookingManager}}" + "value": "Bearer {{token_bookingManager}}", + "type": "text" } ], "body": { "mode": "raw", - "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-06\",\r\n \"endDate\": \"2021-03-13\",\r\n \"daysWorked\": 2,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"pending\"\r\n}", + "raw": "{\r\n \"status\": \"Scheduling\"\r\n}", "options": { "raw": { "language": "json" @@ -5830,28 +5688,29 @@ } }, "url": { - "raw": "{{URL}}/work-periods", + "raw": "{{URL}}/jobCandidates/{{completedInterviewJobCandidateId}}/updateInterview/{{completedInterviewRound}}", "host": [ "{{URL}}" ], "path": [ - "work-periods" + "jobCandidates", + "{{completedInterviewJobCandidateId}}", + "updateInterview", + "{{completedInterviewRound}}" ] } }, "response": [] }, { - "name": "create work period with invalid parameter 4", + "name": "Update interview with booking manager", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 400', function () {\r", - " pm.response.to.have.status(400);\r", - " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"endDate should be always the next Saturday\")\r", + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", "});" ], "type": "text/javascript" @@ -5859,17 +5718,17 @@ } ], "request": { - "method": "POST", + "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_bookingManager}}" + "value": "Bearer {{token_bookingManager}}", + "type": "text" } ], "body": { "mode": "raw", - "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-07\",\r\n \"endDate\": \"2021-03-14\",\r\n \"daysWorked\": 2,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"pending\"\r\n}", + "raw": "{\r\n \"customMessage\": \"sdsds\"\r\n}", "options": { "raw": { "language": "json" @@ -5877,28 +5736,29 @@ } }, "url": { - "raw": "{{URL}}/work-periods", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/updateInterview/{{interviewRound}}", "host": [ "{{URL}}" ], "path": [ - "work-periods" + "jobCandidates", + "{{jobCandidateId}}", + "updateInterview", + "{{interviewRound}}" ] } }, "response": [] }, { - "name": "create work period with invalid parameter 5", + "name": "Update interview with administrator", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 400', function () {\r", - " pm.response.to.have.status(400);\r", - " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"\\\"workPeriod.daysWorked\\\" must be a number\")\r", + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", "});" ], "type": "text/javascript" @@ -5906,17 +5766,17 @@ } ], "request": { - "method": "POST", + "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_bookingManager}}" + "value": "Bearer {{token_administrator}}", + "type": "text" } ], "body": { "mode": "raw", - "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-07\",\r\n \"endDate\": \"2021-03-13\",\r\n \"daysWorked\": \"aa\",\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"pending\"\r\n}", + "raw": "{\r\n \"customMessage\": \"sdsds\"\r\n}", "options": { "raw": { "language": "json" @@ -5924,28 +5784,29 @@ } }, "url": { - "raw": "{{URL}}/work-periods", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/updateInterview/{{interviewRound}}", "host": [ "{{URL}}" ], "path": [ - "work-periods" + "jobCandidates", + "{{jobCandidateId}}", + "updateInterview", + "{{interviewRound}}" ] } }, "response": [] }, { - "name": "create work period with invalid parameter 6", + "name": "Update interview with m2m (all interview scope)", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 400', function () {\r", - " pm.response.to.have.status(400);\r", - " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(`Key (resource_booking_id, start_date, end_date)=(${pm.environment.get('resourceBookingId')}, 2021-03-07, 2021-03-13) already exists.`)\r", + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", "});" ], "type": "text/javascript" @@ -5953,17 +5814,17 @@ } ], "request": { - "method": "POST", + "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_bookingManager}}" + "value": "Bearer {{token_m2m_all_interviews}}", + "type": "text" } ], "body": { "mode": "raw", - "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-07\",\r\n \"endDate\": \"2021-03-13\",\r\n \"daysWorked\": 2,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"pending\"\r\n}", + "raw": "{\r\n \"customMessage\": \"sdsds\"\r\n}", "options": { "raw": { "language": "json" @@ -5971,28 +5832,29 @@ } }, "url": { - "raw": "{{URL}}/work-periods", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/updateInterview/{{interviewRound}}", "host": [ "{{URL}}" ], "path": [ - "work-periods" + "jobCandidates", + "{{jobCandidateId}}", + "updateInterview", + "{{interviewRound}}" ] } }, "response": [] }, { - "name": "create work period with invalid parameter 7", + "name": "Update interview with m2m (update interview scope)", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 400', function () {\r", - " pm.response.to.have.status(400);\r", - " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"\\\"workPeriod.paymentStatus\\\" must be one of [pending, partially-completed, completed, cancelled]\")\r", + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", "});" ], "type": "text/javascript" @@ -6000,17 +5862,17 @@ } ], "request": { - "method": "POST", + "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_bookingManager}}" + "value": "Bearer {{token_m2m_update_interviews}}", + "type": "text" } ], "body": { "mode": "raw", - "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-07\",\r\n \"endDate\": \"2021-03-13\",\r\n \"daysWorked\": 2,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"paid\"\r\n}", + "raw": "{\r\n \"customMessage\": \"sdsds\"\r\n}", "options": { "raw": { "language": "json" @@ -6018,26 +5880,31 @@ } }, "url": { - "raw": "{{URL}}/work-periods", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/updateInterview/{{interviewRound}}", "host": [ "{{URL}}" ], "path": [ - "work-periods" + "jobCandidates", + "{{jobCandidateId}}", + "updateInterview", + "{{interviewRound}}" ] } }, "response": [] }, { - "name": "get work period with booking manager", + "name": "Update interview with m2m (read interview scope) - should fail", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 200', function () {\r", - " pm.response.to.have.status(200);\r", + "pm.test('Status code is 403', function () {\r", + " pm.response.to.have.status(403);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", "});" ], "type": "text/javascript" @@ -6045,36 +5912,49 @@ } ], "request": { - "method": "GET", + "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_bookingManager}}" + "value": "Bearer {{token_m2m_read_interviews}}", + "type": "text" } ], + "body": { + "mode": "raw", + "raw": "{\r\n \"customMessage\": \"sdsds\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, "url": { - "raw": "{{URL}}/work-periods/{{workPeriodId}}", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/updateInterview/{{interviewRound}}", "host": [ "{{URL}}" ], "path": [ - "work-periods", - "{{workPeriodId}}" + "jobCandidates", + "{{jobCandidateId}}", + "updateInterview", + "{{interviewRound}}" ] } }, "response": [] }, { - "name": "get work period with m2m read 1", + "name": "Update interview with m2m (create interview scope) - should fail", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 200', function () {\r", - " pm.response.to.have.status(200);\r", + "pm.test('Status code is 403', function () {\r", + " pm.response.to.have.status(403);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", "});" ], "type": "text/javascript" @@ -6082,36 +5962,49 @@ } ], "request": { - "method": "GET", + "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_m2m_read_work_period}}" + "value": "Bearer {{token_m2m_create_interviews}}", + "type": "text" } ], + "body": { + "mode": "raw", + "raw": "{\r\n \"customMessage\": \"sdsds\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, "url": { - "raw": "{{URL}}/work-periods/{{workPeriodIdCreatedByM2M}}", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/updateInterview/{{interviewRound}}", "host": [ "{{URL}}" ], "path": [ - "work-periods", - "{{workPeriodIdCreatedByM2M}}" + "jobCandidates", + "{{jobCandidateId}}", + "updateInterview", + "{{interviewRound}}" ] } }, "response": [] }, { - "name": "get work period with m2m read 2", + "name": "Update interview with connect manager", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 200', function () {\r", - " pm.response.to.have.status(200);\r", + "pm.test('Status code is 403', function () {\r", + " pm.response.to.have.status(403);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", "});" ], "type": "text/javascript" @@ -6119,36 +6012,49 @@ } ], "request": { - "method": "GET", + "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_m2m_read_work_period_and_payment}}" + "value": "Bearer {{token_connect_manager_pshahcopmanag2}}", + "type": "text" } ], + "body": { + "mode": "raw", + "raw": "{\r\n \"customMessage\": \"sdsds\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, "url": { - "raw": "{{URL}}/work-periods/{{workPeriodIdCreatedByM2M}}", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/updateInterview/{{interviewRound}}", "host": [ "{{URL}}" ], "path": [ - "work-periods", - "{{workPeriodIdCreatedByM2M}}" + "jobCandidates", + "{{jobCandidateId}}", + "updateInterview", + "{{interviewRound}}" ] } }, "response": [] }, { - "name": "get work period with booking manager from db", + "name": "Update interview with connect user", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 200', function () {\r", - " pm.response.to.have.status(200);\r", + "pm.test('Status code is 403', function () {\r", + " pm.response.to.have.status(403);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", "});" ], "type": "text/javascript" @@ -6156,42 +6062,49 @@ } ], "request": { - "method": "GET", + "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_bookingManager}}" + "value": "Bearer {{token_connectUser}}", + "type": "text" } ], + "body": { + "mode": "raw", + "raw": "{\r\n \"customMessage\": \"sdsds\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, "url": { - "raw": "{{URL}}/work-periods/{{workPeriodId}}?fromDb=true", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/updateInterview/{{interviewRound}}", "host": [ "{{URL}}" ], "path": [ - "work-periods", - "{{workPeriodId}}" - ], - "query": [ - { - "key": "fromDb", - "value": "true" - } + "jobCandidates", + "{{jobCandidateId}}", + "updateInterview", + "{{interviewRound}}" ] } }, "response": [] }, { - "name": "get work period with connect user", + "name": "Update interview with member", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 200', function () {\r", - " pm.response.to.have.status(200);\r", + "pm.test('Status code is 403', function () {\r", + " pm.response.to.have.status(403);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", "});" ], "type": "text/javascript" @@ -6199,29 +6112,40 @@ } ], "request": { - "method": "GET", + "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_connectUser}}" + "value": "Bearer {{token_member}}", + "type": "text" } ], + "body": { + "mode": "raw", + "raw": "{\r\n \"customMessage\": \"sdsds\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, "url": { - "raw": "{{URL}}/work-periods/{{workPeriodId}}", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/updateInterview/{{interviewRound}}", "host": [ "{{URL}}" ], "path": [ - "work-periods", - "{{workPeriodId}}" + "jobCandidates", + "{{jobCandidateId}}", + "updateInterview", + "{{interviewRound}}" ] } }, "response": [] }, { - "name": "get work period with member", + "name": "Update interview without token", "event": [ { "listen": "test", @@ -6229,6 +6153,8 @@ "exec": [ "pm.test('Status code is 401', function () {\r", " pm.response.to.have.status(401);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"No token provided.\")\r", "});" ], "type": "text/javascript" @@ -6236,36 +6162,91 @@ } ], "request": { - "method": "GET", + "method": "PATCH", + "header": [], + "body": { + "mode": "raw", + "raw": "{\r\n \"customMessage\": \"sdsds\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/updateInterview/{{interviewRound}}", + "host": [ + "{{URL}}" + ], + "path": [ + "jobCandidates", + "{{jobCandidateId}}", + "updateInterview", + "{{interviewRound}}" + ] + } + }, + "response": [] + }, + { + "name": "Update interview with invalid token", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 401', function () {\r", + " pm.response.to.have.status(401);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"Invalid Token.\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_member}}" + "value": "Bearer invalid_key", + "type": "text" } ], + "body": { + "mode": "raw", + "raw": "{\r\n \"customMessage\": \"sdsds\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, "url": { - "raw": "{{URL}}/work-periods/{{workPeriodId}}", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/updateInterview/{{interviewRound}}", "host": [ "{{URL}}" ], "path": [ - "work-periods", - "{{workPeriodId}}" + "jobCandidates", + "{{jobCandidateId}}", + "updateInterview", + "{{interviewRound}}" ] } }, "response": [] }, { - "name": "search work periods with booking manager", + "name": "Search interviews", "event": [ { "listen": "test", "script": { "exec": [ "pm.test('Status code is 200', function () {\r", - " pm.response.to.have.status(200);\r", + " pm.response.to.have.status(200)\r", "});" ], "type": "text/javascript" @@ -6277,32 +6258,24 @@ "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_bookingManager}}" + "value": "Bearer {{token_bookingManager}}", + "type": "text" } ], "url": { - "raw": "{{URL}}/work-periods", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/interviews", "host": [ "{{URL}}" ], "path": [ - "work-periods" + "jobCandidates", + "{{jobCandidateId}}", + "interviews" ], "query": [ - { - "key": "page", - "value": "1", - "disabled": true - }, - { - "key": "perPage", - "value": "35", - "disabled": true - }, { "key": "sortBy", - "value": "id", + "value": "createdAt", "disabled": true }, { @@ -6311,38 +6284,18 @@ "disabled": true }, { - "key": "resourceBookingId", - "value": "{{resourceBookingId}}", - "disabled": true - }, - { - "key": "resourceBookingIds", - "value": "{{resourceBookingId}},{{resourceBookingIdCreatedByM2M}}", - "disabled": true - }, - { - "key": "paymentStatus", - "value": "pending", - "disabled": true - }, - { - "key": "startDate", - "value": "2021-03-14", - "disabled": true - }, - { - "key": "endDate", - "value": "2021-03-20", + "key": "createdAt", + "value": "2021-04-13T20:28:37.954Z", "disabled": true }, { - "key": "userHandle", - "value": "pshah_manager", + "key": "updatedAt", + "value": "2021-04-13T20:28:37.954Z", "disabled": true }, { - "key": "projectId", - "value": "16843", + "key": "status", + "value": "Scheduling", "disabled": true } ] @@ -6351,14 +6304,16 @@ "response": [] }, { - "name": "search work periods with m2m all 1", + "name": "Search interviews by invalid status", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 200', function () {\r", - " pm.response.to.have.status(200);\r", + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"\\\"criteria.status\\\" must be one of [Scheduling, Scheduled, Requested for reschedule, Rescheduled, Completed, Cancelled]\")\r", "});" ], "type": "text/javascript" @@ -6370,32 +6325,24 @@ "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_m2m_all_work_period}}" + "value": "Bearer {{token_bookingManager}}", + "type": "text" } ], "url": { - "raw": "{{URL}}/work-periods", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/interviews?status=xxx", "host": [ "{{URL}}" ], "path": [ - "work-periods" + "jobCandidates", + "{{jobCandidateId}}", + "interviews" ], "query": [ - { - "key": "page", - "value": "1", - "disabled": true - }, - { - "key": "perPage", - "value": "5", - "disabled": true - }, { "key": "sortBy", - "value": "id", + "value": "createdAt", "disabled": true }, { @@ -6404,39 +6351,18 @@ "disabled": true }, { - "key": "resourceBookingId", - "value": "{{resourceBookingId}}", - "disabled": true - }, - { - "key": "resourceBookingIds", - "value": "{{resourceBookingId}},{{resourceBookingIdCreatedByM2M}}", - "disabled": true - }, - { - "key": "paymentStatus", - "value": "pending", - "disabled": true - }, - { - "key": "startDate", - "value": "2021-03-14", - "disabled": true - }, - { - "key": "endDate", - "value": "2021-03-20", + "key": "createdAt", + "value": "2021-04-13T20:28:37.954Z", "disabled": true }, { - "key": "userHandle", - "value": "pshah_manager", + "key": "updatedAt", + "value": "2021-04-13T20:28:37.954Z", "disabled": true }, { - "key": "projectId", - "value": "16843", - "disabled": true + "key": "status", + "value": "xxx" } ] } @@ -6444,14 +6370,16 @@ "response": [] }, { - "name": "search work periods with m2m all 2", + "name": "Search interviews by invalid createdAt", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 200', function () {\r", - " pm.response.to.have.status(200);\r", + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"\\\"criteria.createdAt\\\" must be a valid date\")\r", "});" ], "type": "text/javascript" @@ -6463,32 +6391,24 @@ "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_m2m_all_work_period_and_payment}}" + "value": "Bearer {{token_bookingManager}}", + "type": "text" } ], "url": { - "raw": "{{URL}}/work-periods", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/interviews?createdAt=xxxx", "host": [ "{{URL}}" ], "path": [ - "work-periods" + "jobCandidates", + "{{jobCandidateId}}", + "interviews" ], "query": [ - { - "key": "page", - "value": "1", - "disabled": true - }, - { - "key": "perPage", - "value": "5", - "disabled": true - }, { "key": "sortBy", - "value": "id", + "value": "createdAt", "disabled": true }, { @@ -6497,38 +6417,17 @@ "disabled": true }, { - "key": "resourceBookingId", - "value": "{{resourceBookingId}}", - "disabled": true + "key": "createdAt", + "value": "xxxx" }, { - "key": "resourceBookingIds", - "value": "{{resourceBookingId}},{{resourceBookingIdCreatedByM2M}}", + "key": "updatedAt", + "value": "2021-04-13T20:28:37.954Z", "disabled": true }, { - "key": "paymentStatus", - "value": "pending", - "disabled": true - }, - { - "key": "startDate", - "value": "2021-03-14", - "disabled": true - }, - { - "key": "endDate", - "value": "2021-03-20", - "disabled": true - }, - { - "key": "userHandle", - "value": "pshah_manager", - "disabled": true - }, - { - "key": "projectId", - "value": "16843", + "key": "status", + "value": "Scheduling", "disabled": true } ] @@ -6537,14 +6436,16 @@ "response": [] }, { - "name": "search work periods with connect user", + "name": "Search interviews by invalid updatedAt", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 200', function () {\r", - " pm.response.to.have.status(200);\r", + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"\\\"criteria.updatedAt\\\" must be a valid date\")\r", "});" ], "type": "text/javascript" @@ -6556,32 +6457,24 @@ "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_connectUser}}" + "value": "Bearer {{token_bookingManager}}", + "type": "text" } ], "url": { - "raw": "{{URL}}/work-periods", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/interviews?updatedAt=xxx", "host": [ "{{URL}}" ], "path": [ - "work-periods" + "jobCandidates", + "{{jobCandidateId}}", + "interviews" ], "query": [ - { - "key": "page", - "value": "1", - "disabled": true - }, - { - "key": "perPage", - "value": "5", - "disabled": true - }, { "key": "sortBy", - "value": "id", + "value": "createdAt", "disabled": true }, { @@ -6590,38 +6483,17 @@ "disabled": true }, { - "key": "resourceBookingId", - "value": "{{resourceBookingId}}", - "disabled": true - }, - { - "key": "resourceBookingIds", - "value": "{{resourceBookingId}},{{resourceBookingIdCreatedByM2M}}", - "disabled": true - }, - { - "key": "paymentStatus", - "value": "pending", - "disabled": true - }, - { - "key": "startDate", - "value": "2021-03-14", - "disabled": true - }, - { - "key": "endDate", - "value": "2021-03-20", + "key": "createdAt", + "value": "2021-04-13T20:28:37.954Z", "disabled": true }, { - "key": "userHandle", - "value": "pshah_manager", - "disabled": true + "key": "updatedAt", + "value": "xxx" }, { - "key": "projectId", - "value": "16843", + "key": "status", + "value": "Scheduling", "disabled": true } ] @@ -6630,78 +6502,130 @@ "response": [] }, { - "name": "search work periods with member", + "name": "Search interviews by invalid sortOrder", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"\\\"criteria.sortOrder\\\" must be one of [desc, asc]\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], "request": { "method": "GET", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_member}}" + "value": "Bearer {{token_bookingManager}}", + "type": "text" } ], "url": { - "raw": "{{URL}}/work-periods", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/interviews?sortOrder=xxx", "host": [ "{{URL}}" ], "path": [ - "work-periods" + "jobCandidates", + "{{jobCandidateId}}", + "interviews" ], "query": [ - { - "key": "page", - "value": "1", - "disabled": true - }, - { - "key": "perPage", - "value": "5", - "disabled": true - }, { "key": "sortBy", - "value": "id", + "value": "createdAt", "disabled": true }, { "key": "sortOrder", - "value": "desc", - "disabled": true + "value": "xxx" }, { - "key": "resourceBookingId", - "value": "{{resourceBookingId}}", + "key": "createdAt", + "value": "2021-04-13T20:28:37.954Z", "disabled": true }, { - "key": "resourceBookingIds", - "value": "{{resourceBookingId}},{{resourceBookingIdCreatedByM2M}}", + "key": "updatedAt", + "value": "2021-04-13T20:28:37.954Z", "disabled": true }, { - "key": "paymentStatus", - "value": "pending", + "key": "status", + "value": "Scheduling", "disabled": true + } + ] + } + }, + "response": [] + }, + { + "name": "Search interviews by invalid sortBy", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"\\\"criteria.sortBy\\\" must be one of [round, createdAt, updatedAt]\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "value": "Bearer {{token_bookingManager}}", + "type": "text" + } + ], + "url": { + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/interviews?sortBy=xxx", + "host": [ + "{{URL}}" + ], + "path": [ + "jobCandidates", + "{{jobCandidateId}}", + "interviews" + ], + "query": [ + { + "key": "sortBy", + "value": "xxx" }, { - "key": "startDate", - "value": "2021-03-14", + "key": "sortOrder", + "value": "desc", "disabled": true }, { - "key": "endDate", - "value": "2021-03-20", + "key": "createdAt", + "value": "2021-04-13T20:28:37.954Z", "disabled": true }, { - "key": "userHandle", - "value": "pshah_manager", + "key": "updatedAt", + "value": "2021-04-13T20:28:37.954Z", "disabled": true }, { - "key": "projectId", - "value": "16843", + "key": "status", + "value": "Scheduling", "disabled": true } ] @@ -6710,14 +6634,14 @@ "response": [] }, { - "name": "search work periods with invalid token", + "name": "Search interviews with administrator", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 401', function () {\r", - " pm.response.to.have.status(401);\r", + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200)\r", "});" ], "type": "text/javascript" @@ -6729,32 +6653,24 @@ "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer invalid_token" + "value": "Bearer {{token_administrator}}", + "type": "text" } ], "url": { - "raw": "{{URL}}/work-periods", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/interviews", "host": [ "{{URL}}" ], "path": [ - "work-periods" + "jobCandidates", + "{{jobCandidateId}}", + "interviews" ], "query": [ - { - "key": "page", - "value": "1", - "disabled": true - }, - { - "key": "perPage", - "value": "5", - "disabled": true - }, { "key": "sortBy", - "value": "id", + "value": "createdAt", "disabled": true }, { @@ -6763,38 +6679,18 @@ "disabled": true }, { - "key": "resourceBookingId", - "value": "{{resourceBookingId}}", - "disabled": true - }, - { - "key": "resourceBookingIds", - "value": "{{resourceBookingId}},{{resourceBookingIdCreatedByM2M}}", - "disabled": true - }, - { - "key": "paymentStatus", - "value": "pending", - "disabled": true - }, - { - "key": "startDate", - "value": "2021-03-14", - "disabled": true - }, - { - "key": "endDate", - "value": "2021-03-20", + "key": "createdAt", + "value": "2021-04-13T20:28:37.954Z", "disabled": true }, { - "key": "userHandle", - "value": "pshah_manager", + "key": "updatedAt", + "value": "2021-04-13T20:28:37.954Z", "disabled": true }, { - "key": "projectId", - "value": "111", + "key": "status", + "value": "Scheduling", "disabled": true } ] @@ -6803,14 +6699,14 @@ "response": [] }, { - "name": "put work period with booking manager", + "name": "Search interviews with booking manager", "event": [ { "listen": "test", "script": { "exec": [ "pm.test('Status code is 200', function () {\r", - " pm.response.to.have.status(200);\r", + " pm.response.to.have.status(200)\r", "});" ], "type": "text/javascript" @@ -6818,45 +6714,64 @@ } ], "request": { - "method": "PUT", + "method": "GET", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_bookingManager}}" + "value": "Bearer {{token_bookingManager}}", + "type": "text" } ], - "body": { - "mode": "raw", - "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-07\",\r\n \"endDate\": \"2021-03-13\",\r\n \"daysWorked\": 2,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"pending\"\r\n}", - "options": { - "raw": { - "language": "json" - } - } - }, "url": { - "raw": "{{URL}}/work-periods/{{workPeriodId}}", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/interviews", "host": [ "{{URL}}" ], "path": [ - "work-periods", - "{{workPeriodId}}" + "jobCandidates", + "{{jobCandidateId}}", + "interviews" + ], + "query": [ + { + "key": "sortBy", + "value": "createdAt", + "disabled": true + }, + { + "key": "sortOrder", + "value": "desc", + "disabled": true + }, + { + "key": "createdAt", + "value": "2021-04-13T20:28:37.954Z", + "disabled": true + }, + { + "key": "updatedAt", + "value": "2021-04-13T20:28:37.954Z", + "disabled": true + }, + { + "key": "status", + "value": "Scheduling", + "disabled": true + } ] } }, "response": [] }, { - "name": "put work period with m2m update", + "name": "Search interviews with m2m (all interview scope)", "event": [ { "listen": "test", "script": { "exec": [ "pm.test('Status code is 200', function () {\r", - " pm.response.to.have.status(200);\r", + " pm.response.to.have.status(200)\r", "});" ], "type": "text/javascript" @@ -6864,47 +6779,64 @@ } ], "request": { - "method": "PUT", + "method": "GET", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_m2m_update_work_period}}" + "value": "Bearer {{token_m2m_all_interviews}}", + "type": "text" } ], - "body": { - "mode": "raw", - "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-14\",\r\n \"endDate\": \"2021-03-20\",\r\n \"daysWorked\": 2,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"pending\"\r\n}", - "options": { - "raw": { - "language": "json" - } - } - }, "url": { - "raw": "{{URL}}/work-periods/{{workPeriodIdCreatedByM2M}}", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/interviews", "host": [ "{{URL}}" ], "path": [ - "work-periods", - "{{workPeriodIdCreatedByM2M}}" + "jobCandidates", + "{{jobCandidateId}}", + "interviews" + ], + "query": [ + { + "key": "sortBy", + "value": "createdAt", + "disabled": true + }, + { + "key": "sortOrder", + "value": "desc", + "disabled": true + }, + { + "key": "createdAt", + "value": "2021-04-13T20:28:37.954Z", + "disabled": true + }, + { + "key": "updatedAt", + "value": "2021-04-13T20:28:37.954Z", + "disabled": true + }, + { + "key": "status", + "value": "Scheduling", + "disabled": true + } ] } }, "response": [] }, { - "name": "put work period with connect user", + "name": "Search interviews with m2m (read interview scope)", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 403', function () {\r", - " pm.response.to.have.status(403);\r", - " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200)\r", "});" ], "type": "text/javascript" @@ -6912,38 +6844,57 @@ } ], "request": { - "method": "PUT", + "method": "GET", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_connectUser}}" + "value": "Bearer {{token_m2m_read_interviews}}", + "type": "text" } ], - "body": { - "mode": "raw", - "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-21\",\r\n \"endDate\": \"2021-03-27\",\r\n \"daysWorked\": 3,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"cancelled\"\r\n}", - "options": { - "raw": { - "language": "json" - } - } - }, "url": { - "raw": "{{URL}}/work-periods/{{workPeriodId}}", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/interviews", "host": [ "{{URL}}" ], "path": [ - "work-periods", - "{{workPeriodId}}" + "jobCandidates", + "{{jobCandidateId}}", + "interviews" + ], + "query": [ + { + "key": "sortBy", + "value": "createdAt", + "disabled": true + }, + { + "key": "sortOrder", + "value": "desc", + "disabled": true + }, + { + "key": "createdAt", + "value": "2021-04-13T20:28:37.954Z", + "disabled": true + }, + { + "key": "updatedAt", + "value": "2021-04-13T20:28:37.954Z", + "disabled": true + }, + { + "key": "status", + "value": "Scheduling", + "disabled": true + } ] } }, "response": [] }, { - "name": "put work period with member", + "name": "Search interviews with m2m (create interview scope) - should fail", "event": [ { "listen": "test", @@ -6960,47 +6911,66 @@ } ], "request": { - "method": "PUT", + "method": "GET", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_member}}" + "value": "Bearer {{token_m2m_create_interviews}}", + "type": "text" } ], - "body": { - "mode": "raw", - "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-21\",\r\n \"endDate\": \"2021-03-27\",\r\n \"daysWorked\": 3,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"cancelled\"\r\n}", - "options": { - "raw": { - "language": "json" - } - } - }, "url": { - "raw": "{{URL}}/work-periods/{{workPeriodId}}", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/interviews", "host": [ "{{URL}}" ], "path": [ - "work-periods", - "{{workPeriodId}}" + "jobCandidates", + "{{jobCandidateId}}", + "interviews" + ], + "query": [ + { + "key": "sortBy", + "value": "createdAt", + "disabled": true + }, + { + "key": "sortOrder", + "value": "desc", + "disabled": true + }, + { + "key": "createdAt", + "value": "2021-04-13T20:28:37.954Z", + "disabled": true + }, + { + "key": "updatedAt", + "value": "2021-04-13T20:28:37.954Z", + "disabled": true + }, + { + "key": "status", + "value": "Scheduling", + "disabled": true + } ] } }, "response": [] }, { - "name": "put work period with user id not exist", + "name": "Search interviews with m2m (update interview scope) - should fail", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 400', function () {\r", - " pm.response.to.have.status(400);\r", + "pm.test('Status code is 403', function () {\r", + " pm.response.to.have.status(403);\r", " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"Bad Request\")\r", + " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", "});" ], "type": "text/javascript" @@ -7008,47 +6978,66 @@ } ], "request": { - "method": "PUT", + "method": "GET", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_userId_not_exist}}" + "value": "Bearer {{token_m2m_update_interviews}}", + "type": "text" } ], - "body": { - "mode": "raw", - "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-21\",\r\n \"endDate\": \"2021-03-27\",\r\n \"daysWorked\": 3,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"cancelled\"\r\n}", - "options": { - "raw": { - "language": "json" - } - } - }, "url": { - "raw": "{{URL}}/work-periods/{{workPeriodId}}", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/interviews", "host": [ "{{URL}}" ], "path": [ - "work-periods", - "{{workPeriodId}}" + "jobCandidates", + "{{jobCandidateId}}", + "interviews" + ], + "query": [ + { + "key": "sortBy", + "value": "createdAt", + "disabled": true + }, + { + "key": "sortOrder", + "value": "desc", + "disabled": true + }, + { + "key": "createdAt", + "value": "2021-04-13T20:28:37.954Z", + "disabled": true + }, + { + "key": "updatedAt", + "value": "2021-04-13T20:28:37.954Z", + "disabled": true + }, + { + "key": "status", + "value": "Scheduling", + "disabled": true + } ] } }, "response": [] }, { - "name": "put work period with invalid token", + "name": "Search interviews with connect manager", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 401', function () {\r", - " pm.response.to.have.status(401);\r", + "pm.test('Status code is 403', function () {\r", + " pm.response.to.have.status(403);\r", " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"Invalid Token.\")\r", + " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", "});" ], "type": "text/javascript" @@ -7056,47 +7045,66 @@ } ], "request": { - "method": "PUT", + "method": "GET", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer invalid_token" + "value": "Bearer {{token_connect_manager_pshahcopmanag2}}", + "type": "text" } ], - "body": { - "mode": "raw", - "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-21\",\r\n \"endDate\": \"2021-03-27\",\r\n \"daysWorked\": 3,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"cancelled\"\r\n}", - "options": { - "raw": { - "language": "json" - } - } - }, "url": { - "raw": "{{URL}}/work-periods/{{workPeriodId}}", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/interviews", "host": [ "{{URL}}" ], "path": [ - "work-periods", - "{{workPeriodId}}" + "jobCandidates", + "{{jobCandidateId}}", + "interviews" + ], + "query": [ + { + "key": "sortBy", + "value": "createdAt", + "disabled": true + }, + { + "key": "sortOrder", + "value": "desc", + "disabled": true + }, + { + "key": "createdAt", + "value": "2021-04-13T20:28:37.954Z", + "disabled": true + }, + { + "key": "updatedAt", + "value": "2021-04-13T20:28:37.954Z", + "disabled": true + }, + { + "key": "status", + "value": "Scheduling", + "disabled": true + } ] } }, "response": [] }, { - "name": "put work period with missing parameter 1", + "name": "Search interviews with connect user", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 400', function () {\r", - " pm.response.to.have.status(400);\r", + "pm.test('Status code is 403', function () {\r", + " pm.response.to.have.status(403);\r", " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"\\\"data.resourceBookingId\\\" is required\")\r", + " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", "});" ], "type": "text/javascript" @@ -7104,47 +7112,4528 @@ } ], "request": { - "method": "PUT", + "method": "GET", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_bookingManager}}" + "value": "Bearer {{token_connectUser}}", + "type": "text" } ], - "body": { - "mode": "raw", - "raw": "{\r\n \"startDate\": \"2021-03-07\",\r\n \"endDate\": \"2021-03-13\",\r\n \"daysWorked\": 2,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"pending\"\r\n}", - "options": { - "raw": { - "language": "json" - } - } - }, "url": { - "raw": "{{URL}}/work-periods/{{workPeriodId}}", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/interviews", "host": [ "{{URL}}" ], "path": [ - "work-periods", - "{{workPeriodId}}" - ] - } - }, - "response": [] - }, - { - "name": "put work period with missing parameter 2", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "pm.test('Status code is 400', function () {\r", - " pm.response.to.have.status(400);\r", - " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"\\\"data.endDate\\\" is required\")\r", + "jobCandidates", + "{{jobCandidateId}}", + "interviews" + ], + "query": [ + { + "key": "sortBy", + "value": "createdAt", + "disabled": true + }, + { + "key": "sortOrder", + "value": "desc", + "disabled": true + }, + { + "key": "createdAt", + "value": "2021-04-13T20:28:37.954Z", + "disabled": true + }, + { + "key": "updatedAt", + "value": "2021-04-13T20:28:37.954Z", + "disabled": true + }, + { + "key": "status", + "value": "Scheduling", + "disabled": true + } + ] + } + }, + "response": [] + }, + { + "name": "Search interviews with member", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 403', function () {\r", + " pm.response.to.have.status(403);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "value": "Bearer {{token_member}}", + "type": "text" + } + ], + "url": { + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/interviews", + "host": [ + "{{URL}}" + ], + "path": [ + "jobCandidates", + "{{jobCandidateId}}", + "interviews" + ], + "query": [ + { + "key": "sortBy", + "value": "createdAt", + "disabled": true + }, + { + "key": "sortOrder", + "value": "desc", + "disabled": true + }, + { + "key": "createdAt", + "value": "2021-04-13T20:28:37.954Z", + "disabled": true + }, + { + "key": "updatedAt", + "value": "2021-04-13T20:28:37.954Z", + "disabled": true + }, + { + "key": "status", + "value": "Scheduling", + "disabled": true + } + ] + } + }, + "response": [] + }, + { + "name": "Search interviews without token", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 401', function () {\r", + " pm.response.to.have.status(401);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"No token provided.\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/interviews", + "host": [ + "{{URL}}" + ], + "path": [ + "jobCandidates", + "{{jobCandidateId}}", + "interviews" + ] + } + }, + "response": [] + }, + { + "name": "Search interviews with invalid token", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 401', function () {\r", + " pm.response.to.have.status(401);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"Invalid Token.\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "value": "Bearer invalid_token", + "type": "text" + } + ], + "url": { + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/interviews", + "host": [ + "{{URL}}" + ], + "path": [ + "jobCandidates", + "{{jobCandidateId}}", + "interviews" + ] + } + }, + "response": [] + } + ] + }, + { + "name": "Resource Bookings", + "item": [ + { + "name": "Before Test", + "item": [ + { + "name": "create job", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", + " if(pm.response.status === \"OK\"){\r", + " const response = pm.response.json()\r", + " pm.environment.set(\"jobId\", response.id);\r", + " }\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Authorization", + "value": "Bearer {{token_bookingManager}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"projectId\": {{projectId}},\n \"externalId\": \"1212\",\n \"description\": \"Dummy Description\",\n \"startDate\": \"2020-09-27T04:17:23.131Z\",\n \"duration\": 1,\n \"numPositions\": 13,\n \"resourceType\": \"Dummy Resource Type\",\n \"rateType\": \"hourly\",\n \"workload\": \"full-time\",\n \"skills\": [\n \"23e00d92-207a-4b5b-b3c9-4c5662644941\",\n \"7d076384-ccf6-4e43-a45d-1b24b1e624aa\",\n \"cbac57a3-7180-4316-8769-73af64893158\",\n \"a2b4bc11-c641-4a19-9eb7-33980378f82e\"\n ],\n \"title\": \"Dummy title - at most 64 characters\"\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/jobs", + "host": [ + "{{URL}}" + ], + "path": [ + "jobs" + ] + } + }, + "response": [] + }, + { + "name": "create job with m2m", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var data = JSON.parse(responseBody);\r", + "postman.setEnvironmentVariable(\"jobIdCreatedByM2M\",data.id);" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Authorization", + "value": "Bearer {{token_m2m_create_job}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"projectId\": {{projectId}},\n \"externalId\": \"1212\",\n \"description\": \"Dummy Description\",\n \"startDate\": \"2020-09-27T04:17:23.131Z\",\n \"duration\": 1,\n \"numPositions\": 13,\n \"resourceType\": \"Dummy Resource Type\",\n \"rateType\": \"hourly\",\n \"workload\": \"full-time\",\n \"skills\": [\n \"23e00d92-207a-4b5b-b3c9-4c5662644941\",\n \"7d076384-ccf6-4e43-a45d-1b24b1e624aa\",\n \"cbac57a3-7180-4316-8769-73af64893158\",\n \"a2b4bc11-c641-4a19-9eb7-33980378f82e\"\n ],\n \"title\": \"Dummy title - at most 64 characters\"\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/jobs", + "host": [ + "{{URL}}" + ], + "path": [ + "jobs" + ] + } + }, + "response": [] + } + ] + }, + { + "name": "create resource booking with booking manager", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", + " if(pm.response.status === \"OK\"){\r", + " const response = pm.response.json()\r", + " pm.environment.set(\"resourceBookingId\", response.id);\r", + " }\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_bookingManager}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"projectId\": {{projectId}},\r\n \"userId\": \"a55fe1bc-1754-45fa-9adc-cf3d6d7c377a\",\r\n \"jobId\": \"{{jobId}}\",\r\n \"startDate\": \"2020-09-27\",\r\n \"endDate\": \"2020-10-27\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\",\r\n \"billingAccountId\": 80000071\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/resourceBookings", + "host": [ + "{{URL}}" + ], + "path": [ + "resourceBookings" + ] + } + }, + "response": [] + }, + { + "name": "search work periods of newly created resource booking", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_bookingManager}}" + } + ], + "url": { + "raw": "{{URL}}/work-periods?sortBy=startDate&sortOrder=asc&resourceBookingId={{resourceBookingId}}", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods" + ], + "query": [ + { + "key": "page", + "value": "1", + "disabled": true + }, + { + "key": "perPage", + "value": "5", + "disabled": true + }, + { + "key": "sortBy", + "value": "startDate" + }, + { + "key": "sortOrder", + "value": "asc" + }, + { + "key": "resourceBookingId", + "value": "{{resourceBookingId}}" + }, + { + "key": "resourceBookingIds", + "value": "{{resourceBookingId}},{{resourceBookingId}}", + "disabled": true + }, + { + "key": "paymentStatus", + "value": "pending", + "disabled": true + }, + { + "key": "startDate", + "value": "2021-03-14", + "disabled": true + }, + { + "key": "endDate", + "value": "2021-03-20", + "disabled": true + }, + { + "key": "userHandle", + "value": "pshah_manager", + "disabled": true + }, + { + "key": "projectId", + "value": "16843", + "disabled": true + } + ] + } + }, + "response": [] + }, + { + "name": "create resource booking with m2m create", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", + " if(pm.response.status === \"OK\"){\r", + " const response = pm.response.json()\r", + " pm.environment.set(\"resourceBookingIdCreatedByM2M\", response.id);\r", + " }\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_m2m_create_resource_booking}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"projectId\": {{projectId}},\r\n \"userId\": \"a55fe1bc-1754-45fa-9adc-cf3d6d7c377a\",\r\n \"jobId\": \"{{jobIdCreatedByM2M}}\",\r\n \"startDate\": \"2020-12-27\",\r\n \"endDate\": \"2021-01-27\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\",\r\n \"billingAccountId\": 80000071\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/resourceBookings", + "host": [ + "{{URL}}" + ], + "path": [ + "resourceBookings" + ] + } + }, + "response": [] + }, + { + "name": "search work periods of newly created resource booking", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_bookingManager}}" + } + ], + "url": { + "raw": "{{URL}}/work-periods?sortBy=startDate&sortOrder=asc&resourceBookingId={{resourceBookingIdCreatedByM2M}}", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods" + ], + "query": [ + { + "key": "page", + "value": "1", + "disabled": true + }, + { + "key": "perPage", + "value": "5", + "disabled": true + }, + { + "key": "sortBy", + "value": "startDate" + }, + { + "key": "sortOrder", + "value": "asc" + }, + { + "key": "resourceBookingId", + "value": "{{resourceBookingIdCreatedByM2M}}" + }, + { + "key": "resourceBookingIds", + "value": "{{resourceBookingIdCreatedByM2M}},{{resourceBookingIdCreatedByM2M}}", + "disabled": true + }, + { + "key": "paymentStatus", + "value": "pending", + "disabled": true + }, + { + "key": "startDate", + "value": "2021-03-14", + "disabled": true + }, + { + "key": "endDate", + "value": "2021-03-20", + "disabled": true + }, + { + "key": "userHandle", + "value": "pshah_manager", + "disabled": true + }, + { + "key": "projectId", + "value": "16843", + "disabled": true + } + ] + } + }, + "response": [] + }, + { + "name": "create resource booking with connect user", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 403', function () {\r", + " pm.response.to.have.status(403);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_connectUser}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"projectId\": {{projectId}},\r\n \"userId\": \"a55fe1bc-1754-45fa-9adc-cf3d6d7c377a\",\r\n \"jobId\": \"{{jobId}}\",\r\n \"startDate\": \"2020-09-27\",\r\n \"endDate\": \"2020-09-28\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\",\r\n \"billingAccountId\": 80000071\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/resourceBookings", + "host": [ + "{{URL}}" + ], + "path": [ + "resourceBookings" + ] + } + }, + "response": [] + }, + { + "name": "create resource booking with member", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 403', function () {\r", + " pm.response.to.have.status(403);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_member}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"projectId\": {{projectId}},\r\n \"userId\": \"a55fe1bc-1754-45fa-9adc-cf3d6d7c377a\",\r\n \"jobId\": \"{{jobId}}\",\r\n \"startDate\": \"2020-09-27\",\r\n \"endDate\": \"2020-09-28\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\",\r\n \"billingAccountId\": 80000071\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/resourceBookings", + "host": [ + "{{URL}}" + ], + "path": [ + "resourceBookings" + ] + } + }, + "response": [] + }, + { + "name": "create resource booking with user id not exist", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"Bad Request\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_userId_not_exist}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"projectId\": {{projectId}},\r\n \"userId\": \"a55fe1bc-1754-45fa-9adc-cf3d6d7c377a\",\r\n \"jobId\": \"{{jobId}}\",\r\n \"startDate\": \"2020-09-27\",\r\n \"endDate\": \"2020-09-28\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\",\r\n \"billingAccountId\": 80000071\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/resourceBookings", + "host": [ + "{{URL}}" + ], + "path": [ + "resourceBookings" + ] + } + }, + "response": [] + }, + { + "name": "create resource booking with invalid token", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 401', function () {\r", + " pm.response.to.have.status(401);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"Invalid Token.\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer invalid_token" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"projectId\": {{projectId}},\r\n \"userId\": \"a55fe1bc-1754-45fa-9adc-cf3d6d7c377a\",\r\n \"jobId\": \"{{jobId}}\",\r\n \"startDate\": \"2020-09-27\",\r\n \"endDate\": \"2020-09-27\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\",\r\n \"billingAccountId\": 80000071\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/resourceBookings", + "host": [ + "{{URL}}" + ], + "path": [ + "resourceBookings" + ] + } + }, + "response": [] + }, + { + "name": "get resource booking with booking manager", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_bookingManager}}" + } + ], + "url": { + "raw": "{{URL}}/resourceBookings/{{resourceBookingId}}", + "host": [ + "{{URL}}" + ], + "path": [ + "resourceBookings", + "{{resourceBookingId}}" + ] + } + }, + "response": [] + }, + { + "name": "get resource booking with m2m read", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_m2m_read_resource_booking}}" + } + ], + "url": { + "raw": "{{URL}}/resourceBookings/{{resourceBookingIdCreatedByM2M}}", + "host": [ + "{{URL}}" + ], + "path": [ + "resourceBookings", + "{{resourceBookingIdCreatedByM2M}}" + ] + } + }, + "response": [] + }, + { + "name": "get resource booking with booking manager from db", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_bookingManager}}" + } + ], + "url": { + "raw": "{{URL}}/resourceBookings/{{resourceBookingId}}?fromDb=true", + "host": [ + "{{URL}}" + ], + "path": [ + "resourceBookings", + "{{resourceBookingId}}" + ], + "query": [ + { + "key": "fromDb", + "value": "true" + } + ] + } + }, + "response": [] + }, + { + "name": "get resource booking with connect user", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_connectUser}}" + } + ], + "url": { + "raw": "{{URL}}/resourceBookings/{{resourceBookingId}}", + "host": [ + "{{URL}}" + ], + "path": [ + "resourceBookings", + "{{resourceBookingId}}" + ] + } + }, + "response": [] + }, + { + "name": "get resource booking with member", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 401', function () {\r", + " pm.response.to.have.status(401);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"userId: 8547899 the user is not a member of project 111\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_member}}" + } + ], + "url": { + "raw": "{{URL}}/resourceBookings/{{resourceBookingId}}", + "host": [ + "{{URL}}" + ], + "path": [ + "resourceBookings", + "{{resourceBookingId}}" + ] + } + }, + "response": [] + }, + { + "name": "search resource bookings with booking manager", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_bookingManager}}" + } + ], + "url": { + "raw": "{{URL}}/resourceBookings", + "host": [ + "{{URL}}" + ], + "path": [ + "resourceBookings" + ], + "query": [ + { + "key": "page", + "value": "1", + "disabled": true + }, + { + "key": "perPage", + "value": "5", + "disabled": true + }, + { + "key": "sortBy", + "value": "id", + "disabled": true + }, + { + "key": "sortOrder", + "value": "desc", + "disabled": true + }, + { + "key": "startDate", + "value": "2020-09-27", + "disabled": true + }, + { + "key": "endDate", + "value": "2020-09-27", + "disabled": true + }, + { + "key": "rateType", + "value": "hourly", + "disabled": true + }, + { + "key": "status", + "value": "assigned", + "disabled": true + }, + { + "key": "projectIds", + "value": "111, 16705", + "disabled": true + } + ] + } + }, + "response": [] + }, + { + "name": "search resource bookings with m2m all", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_m2m_all_resource_booking}}" + } + ], + "url": { + "raw": "{{URL}}/resourceBookings", + "host": [ + "{{URL}}" + ], + "path": [ + "resourceBookings" + ], + "query": [ + { + "key": "page", + "value": "1", + "disabled": true + }, + { + "key": "perPage", + "value": "5", + "disabled": true + }, + { + "key": "sortBy", + "value": "id", + "disabled": true + }, + { + "key": "sortOrder", + "value": "desc", + "disabled": true + }, + { + "key": "startDate", + "value": "2020-09-27", + "disabled": true + }, + { + "key": "endDate", + "value": "2020-09-27", + "disabled": true + }, + { + "key": "rateType", + "value": "hourly", + "disabled": true + }, + { + "key": "status", + "value": "assigned", + "disabled": true + } + ] + } + }, + "response": [] + }, + { + "name": "search resource bookings with connect user", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_connectUser}}" + } + ], + "url": { + "raw": "{{URL}}/resourceBookings?sortOrder=desc", + "host": [ + "{{URL}}" + ], + "path": [ + "resourceBookings" + ], + "query": [ + { + "key": "page", + "value": "4", + "disabled": true + }, + { + "key": "perPage", + "value": "3", + "disabled": true + }, + { + "key": "sortBy", + "value": "id", + "disabled": true + }, + { + "key": "startDate", + "value": "2020-09-27", + "disabled": true + }, + { + "key": "endDate", + "value": "2020-09-27", + "disabled": true + }, + { + "key": "rateType", + "value": "hourly", + "disabled": true + }, + { + "key": "sortOrder", + "value": "desc" + } + ] + } + }, + "response": [] + }, + { + "name": "search resource bookings with member", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_member}}" + } + ], + "url": { + "raw": "{{URL}}/resourceBookings?sortOrder=desc", + "host": [ + "{{URL}}" + ], + "path": [ + "resourceBookings" + ], + "query": [ + { + "key": "page", + "value": "4", + "disabled": true + }, + { + "key": "perPage", + "value": "3", + "disabled": true + }, + { + "key": "sortBy", + "value": "id", + "disabled": true + }, + { + "key": "startDate", + "value": "2020-09-27", + "disabled": true + }, + { + "key": "endDate", + "value": "2020-09-27", + "disabled": true + }, + { + "key": "rateType", + "value": "hourly", + "disabled": true + }, + { + "key": "sortOrder", + "value": "desc" + } + ] + } + }, + "response": [] + }, + { + "name": "search resource bookings with invalid token", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 401', function () {\r", + " pm.response.to.have.status(401);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"Invalid Token.\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer invalid_token" + } + ], + "url": { + "raw": "{{URL}}/resourceBookings?sortOrder=desc", + "host": [ + "{{URL}}" + ], + "path": [ + "resourceBookings" + ], + "query": [ + { + "key": "page", + "value": "4", + "disabled": true + }, + { + "key": "perPage", + "value": "3", + "disabled": true + }, + { + "key": "sortBy", + "value": "id", + "disabled": true + }, + { + "key": "startDate", + "value": "2020-09-27", + "disabled": true + }, + { + "key": "endDate", + "value": "2020-09-27", + "disabled": true + }, + { + "key": "rateType", + "value": "hourly", + "disabled": true + }, + { + "key": "sortOrder", + "value": "desc" + } + ] + } + }, + "response": [] + }, + { + "name": "put resource booking with booking manager", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "PUT", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_bookingManager}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"projectId\": {{projectId}},\r\n \"userId\": \"a55fe1bc-1754-45fa-9adc-cf3d6d7c377a\",\r\n \"jobId\": \"{{jobId}}\",\r\n \"startDate\": \"2020-09-26\",\r\n \"endDate\": \"2020-11-29\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\",\r\n \"status\": \"placed\",\r\n \"billingAccountId\": 80000071\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/resourceBookings/{{resourceBookingId}}", + "host": [ + "{{URL}}" + ], + "path": [ + "resourceBookings", + "{{resourceBookingId}}" + ] + } + }, + "response": [] + }, + { + "name": "search extended work periods of resource booking", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_bookingManager}}" + } + ], + "url": { + "raw": "{{URL}}/work-periods?sortBy=startDate&sortOrder=asc&resourceBookingId={{resourceBookingId}}", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods" + ], + "query": [ + { + "key": "page", + "value": "1", + "disabled": true + }, + { + "key": "perPage", + "value": "5", + "disabled": true + }, + { + "key": "sortBy", + "value": "startDate" + }, + { + "key": "sortOrder", + "value": "asc" + }, + { + "key": "resourceBookingId", + "value": "{{resourceBookingId}}" + }, + { + "key": "resourceBookingIds", + "value": "{{resourceBookingId}},{{resourceBookingId}}", + "disabled": true + }, + { + "key": "paymentStatus", + "value": "pending", + "disabled": true + }, + { + "key": "startDate", + "value": "2021-03-14", + "disabled": true + }, + { + "key": "endDate", + "value": "2021-03-20", + "disabled": true + }, + { + "key": "userHandle", + "value": "pshah_manager", + "disabled": true + }, + { + "key": "projectId", + "value": "16843", + "disabled": true + } + ] + } + }, + "response": [] + }, + { + "name": "put resource booking with m2m update", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "PUT", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_m2m_update_resource_booking}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"projectId\": {{projectId}},\r\n \"userId\": \"a55fe1bc-1754-45fa-9adc-cf3d6d7c377a\",\r\n \"jobId\": \"{{jobIdCreatedByM2M}}\",\r\n \"startDate\": \"2020-12-27\",\r\n \"endDate\": \"2021-01-10\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\",\r\n \"status\": \"placed\",\r\n \"billingAccountId\": 80000071\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/resourceBookings/{{resourceBookingIdCreatedByM2M}}", + "host": [ + "{{URL}}" + ], + "path": [ + "resourceBookings", + "{{resourceBookingIdCreatedByM2M}}" + ] + } + }, + "response": [] + }, + { + "name": "search reduced work periods of resource booking", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_bookingManager}}" + } + ], + "url": { + "raw": "{{URL}}/work-periods?sortBy=startDate&sortOrder=asc&resourceBookingId={{resourceBookingIdCreatedByM2M}}", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods" + ], + "query": [ + { + "key": "page", + "value": "1", + "disabled": true + }, + { + "key": "perPage", + "value": "5", + "disabled": true + }, + { + "key": "sortBy", + "value": "startDate" + }, + { + "key": "sortOrder", + "value": "asc" + }, + { + "key": "resourceBookingId", + "value": "{{resourceBookingIdCreatedByM2M}}" + }, + { + "key": "resourceBookingIds", + "value": "{{resourceBookingIdCreatedByM2M}},{{resourceBookingIdCreatedByM2M}}", + "disabled": true + }, + { + "key": "paymentStatus", + "value": "pending", + "disabled": true + }, + { + "key": "startDate", + "value": "2021-03-14", + "disabled": true + }, + { + "key": "endDate", + "value": "2021-03-20", + "disabled": true + }, + { + "key": "userHandle", + "value": "pshah_manager", + "disabled": true + }, + { + "key": "projectId", + "value": "16843", + "disabled": true + } + ] + } + }, + "response": [] + }, + { + "name": "put resource booking with connect user", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 403', function () {\r", + " pm.response.to.have.status(403);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "PUT", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_connectUser}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"projectId\": {{projectId}},\r\n \"userId\": \"a55fe1bc-1754-45fa-9adc-cf3d6d7c377a\",\r\n \"jobId\": \"{{jobId}}\",\r\n \"startDate\": \"2020-09-27\",\r\n \"endDate\": \"2020-09-28\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\",\r\n \"status\": \"placed\",\r\n \"billingAccountId\": 80000071\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/resourceBookings/{{resourceBookingId}}", + "host": [ + "{{URL}}" + ], + "path": [ + "resourceBookings", + "{{resourceBookingId}}" + ] + } + }, + "response": [] + }, + { + "name": "put resource booking with member", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 403', function () {\r", + " pm.response.to.have.status(403);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "PUT", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_member}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"projectId\": {{projectId}},\r\n \"userId\": \"a55fe1bc-1754-45fa-9adc-cf3d6d7c377a\",\r\n \"jobId\": \"{{jobId}}\",\r\n \"startDate\": \"2020-09-27\",\r\n \"endDate\": \"2020-09-28\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\",\r\n \"status\": \"placed\",\r\n \"billingAccountId\": 80000071\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/resourceBookings/{{resourceBookingId}}", + "host": [ + "{{URL}}" + ], + "path": [ + "resourceBookings", + "{{resourceBookingId}}" + ] + } + }, + "response": [] + }, + { + "name": "put resource booking with user id not exist", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"Bad Request\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "PUT", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_userId_not_exist}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"projectId\": {{projectId}},\r\n \"userId\": \"a55fe1bc-1754-45fa-9adc-cf3d6d7c377a\",\r\n \"jobId\": \"{{jobId}}\",\r\n \"startDate\": \"2020-09-27\",\r\n \"endDate\": \"2020-09-28\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\",\r\n \"status\": \"placed\",\r\n \"billingAccountId\": 80000071\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/resourceBookings/{{resourceBookingId}}", + "host": [ + "{{URL}}" + ], + "path": [ + "resourceBookings", + "{{resourceBookingId}}" + ] + } + }, + "response": [] + }, + { + "name": "put resource booking with invalid token", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 401', function () {\r", + " pm.response.to.have.status(401);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"Invalid Token.\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "PUT", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer invalid_token" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"projectId\": {{projectId}},\r\n \"userId\": \"a55fe1bc-1754-45fa-9adc-cf3d6d7c377a\",\r\n \"jobId\": \"{{jobId}}\",\r\n \"startDate\": \"2020-09-27\",\r\n \"endDate\": \"2020-09-28\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\",\r\n \"status\": \"placed\",\r\n \"billingAccountId\": 80000071\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/resourceBookings/{{resourceBookingId}}", + "host": [ + "{{URL}}" + ], + "path": [ + "resourceBookings", + "{{resourceBookingId}}" + ] + } + }, + "response": [] + }, + { + "name": "patch resource booking with booking manager", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "PATCH", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_bookingManager}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"status\": \"placed\",\r\n \"startDate\": \"2020-09-30\",\r\n \"endDate\": \"2020-11-28\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\",\r\n \"billingAccountId\": 80000071\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/resourceBookings/{{resourceBookingId}}", + "host": [ + "{{URL}}" + ], + "path": [ + "resourceBookings", + "{{resourceBookingId}}" + ] + } + }, + "response": [] + }, + { + "name": "patch resource booking with m2m update", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "PATCH", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_m2m_update_resource_booking}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"status\": \"placed\",\r\n \"startDate\": \"2020-12-30\",\r\n \"endDate\": \"2021-02-10\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\",\r\n \"billingAccountId\": 80000071\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/resourceBookings/{{resourceBookingIdCreatedByM2M}}", + "host": [ + "{{URL}}" + ], + "path": [ + "resourceBookings", + "{{resourceBookingIdCreatedByM2M}}" + ] + } + }, + "response": [] + }, + { + "name": "patch resource booking with connect user", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 403', function () {\r", + " pm.response.to.have.status(403);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "PATCH", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_connectUser}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"status\": \"placed\",\r\n \"startDate\": \"2020-09-27\",\r\n \"endDate\": \"2020-09-28\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\",\r\n \"billingAccountId\": 80000071\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/resourceBookings/{{resourceBookingId}}", + "host": [ + "{{URL}}" + ], + "path": [ + "resourceBookings", + "{{resourceBookingId}}" + ] + } + }, + "response": [] + }, + { + "name": "patch resource booking with member", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 403', function () {\r", + " pm.response.to.have.status(403);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "PATCH", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_member}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"status\": \"placed\",\r\n \"startDate\": \"2020-09-27\",\r\n \"endDate\": \"2020-09-28\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\",\r\n \"billingAccountId\": 80000071\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/resourceBookings/{{resourceBookingId}}", + "host": [ + "{{URL}}" + ], + "path": [ + "resourceBookings", + "{{resourceBookingId}}" + ] + } + }, + "response": [] + }, + { + "name": "patch resource booking with user id not exist", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"Bad Request\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "PATCH", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_userId_not_exist}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"status\": \"placed\",\r\n \"startDate\": \"2020-09-27\",\r\n \"endDate\": \"2020-09-28\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\",\r\n \"billingAccountId\": 80000071\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/resourceBookings/{{resourceBookingId}}", + "host": [ + "{{URL}}" + ], + "path": [ + "resourceBookings", + "{{resourceBookingId}}" + ] + } + }, + "response": [] + }, + { + "name": "patch resource booking with invalid token", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 401', function () {\r", + " pm.response.to.have.status(401);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"Invalid Token.\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "PATCH", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer invalid_token" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"status\": \"placed\",\r\n \"startDate\": \"2020-09-27\",\r\n \"endDate\": \"2020-09-27\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\",\r\n \"billingAccountId\": 80000071\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/resourceBookings/{{resourceBookingId}}", + "host": [ + "{{URL}}" + ], + "path": [ + "resourceBookings", + "{{resourceBookingId}}" + ] + } + }, + "response": [] + }, + { + "name": "search work periods", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", + " const response = pm.response.json()\r", + " pm.environment.set(\"workPeriodIdForPaid\", response[0].id);\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_bookingManager}}" + } + ], + "url": { + "raw": "{{URL}}/work-periods?perPage=1&sortBy=startDate&sortOrder=asc&resourceBookingId={{resourceBookingId}}", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods" + ], + "query": [ + { + "key": "page", + "value": "1", + "disabled": true + }, + { + "key": "perPage", + "value": "1" + }, + { + "key": "sortBy", + "value": "startDate" + }, + { + "key": "sortOrder", + "value": "asc" + }, + { + "key": "resourceBookingId", + "value": "{{resourceBookingId}}" + }, + { + "key": "resourceBookingIds", + "value": "{{resourceBookingId}},{{resourceBookingId}}", + "disabled": true + }, + { + "key": "paymentStatus", + "value": "pending", + "disabled": true + }, + { + "key": "startDate", + "value": "2021-03-14", + "disabled": true + }, + { + "key": "endDate", + "value": "2021-03-20", + "disabled": true + }, + { + "key": "userHandle", + "value": "pshah_manager", + "disabled": true + }, + { + "key": "projectId", + "value": "16843", + "disabled": true + } + ] + } + }, + "response": [] + }, + { + "name": "patch work period set status to completed", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "PATCH", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_bookingManager}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"paymentStatus\": \"completed\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/work-periods/{{workPeriodIdForPaid}}", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods", + "{{workPeriodIdForPaid}}" + ] + } + }, + "response": [] + }, + { + "name": "patch resource booking to cancelled", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "PATCH", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_bookingManager}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"status\": \"cancelled\",\r\n \"billingAccountId\": 80000071\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/resourceBookings/{{resourceBookingId}}", + "host": [ + "{{URL}}" + ], + "path": [ + "resourceBookings", + "{{resourceBookingId}}" + ] + } + }, + "response": [] + }, + { + "name": "patch resource booking to reduce", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "PATCH", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_bookingManager}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"startDate\": \"2020-10-04\",\r\n \"billingAccountId\": 80000071\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/resourceBookings/{{resourceBookingId}}", + "host": [ + "{{URL}}" + ], + "path": [ + "resourceBookings", + "{{resourceBookingId}}" + ] + } + }, + "response": [] + }, + { + "name": "delete resource booking with member", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 403', function () {\r", + " pm.response.to.have.status(403);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "DELETE", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_member}}" + } + ], + "body": { + "mode": "raw", + "raw": "", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/resourceBookings/{{resourceBookingId}}", + "host": [ + "{{URL}}" + ], + "path": [ + "resourceBookings", + "{{resourceBookingId}}" + ] + } + }, + "response": [] + }, + { + "name": "delete resource booking with connect user", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 403', function () {\r", + " pm.response.to.have.status(403);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "DELETE", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_connectUser}}" + } + ], + "body": { + "mode": "raw", + "raw": "", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/resourceBookings/{{resourceBookingId}}", + "host": [ + "{{URL}}" + ], + "path": [ + "resourceBookings", + "{{resourceBookingId}}" + ] + } + }, + "response": [] + }, + { + "name": "delete resource booking with booking manager", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "DELETE", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_bookingManager}}" + } + ], + "body": { + "mode": "raw", + "raw": "", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/resourceBookings/{{resourceBookingId}}", + "host": [ + "{{URL}}" + ], + "path": [ + "resourceBookings", + "{{resourceBookingId}}" + ] + } + }, + "response": [] + }, + { + "name": "delete resource booking with m2m delete", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 204', function () {\r", + " pm.response.to.have.status(204);\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "DELETE", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_m2m_delete_resource_booking}}" + } + ], + "body": { + "mode": "raw", + "raw": "", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/resourceBookings/{{resourceBookingIdCreatedByM2M}}", + "host": [ + "{{URL}}" + ], + "path": [ + "resourceBookings", + "{{resourceBookingIdCreatedByM2M}}" + ] + } + }, + "response": [] + }, + { + "name": "delete resource booking with invalid token", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 401', function () {\r", + " pm.response.to.have.status(401);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"Invalid Token.\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "DELETE", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer invalid_token" + } + ], + "body": { + "mode": "raw", + "raw": "", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/resourceBookings/{{resourceBookingId}}", + "host": [ + "{{URL}}" + ], + "path": [ + "resourceBookings", + "{{resourceBookingId}}" + ] + } + }, + "response": [] + } + ] + }, + { + "name": "Work Periods", + "item": [ + { + "name": "Before Test", + "item": [ + { + "name": "create job", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", + " if(pm.response.status === \"OK\"){\r", + " const response = pm.response.json()\r", + " pm.environment.set(\"jobId\", response.id);\r", + " }\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Authorization", + "value": "Bearer {{token_bookingManager}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"projectId\": {{projectId}},\n \"externalId\": \"1212\",\n \"description\": \"Dummy Description\",\n \"startDate\": \"2020-09-27T04:17:23.131Z\",\n \"duration\": 1,\n \"numPositions\": 13,\n \"resourceType\": \"Dummy Resource Type\",\n \"rateType\": \"hourly\",\n \"workload\": \"full-time\",\n \"skills\": [\n \"23e00d92-207a-4b5b-b3c9-4c5662644941\",\n \"7d076384-ccf6-4e43-a45d-1b24b1e624aa\",\n \"cbac57a3-7180-4316-8769-73af64893158\",\n \"a2b4bc11-c641-4a19-9eb7-33980378f82e\"\n ],\n \"title\": \"Dummy title - at most 64 characters\"\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/jobs", + "host": [ + "{{URL}}" + ], + "path": [ + "jobs" + ] + } + }, + "response": [] + }, + { + "name": "create resource booking", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", + " if(pm.response.status === \"OK\"){\r", + " const response = pm.response.json()\r", + " pm.environment.set(\"resourceBookingId\", response.id);\r", + " }\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_bookingManager}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"projectId\": {{projectId}},\r\n \"userId\": \"a55fe1bc-1754-45fa-9adc-cf3d6d7c377a\",\r\n \"jobId\": \"{{jobId}}\",\r\n \"startDate\": \"2020-09-27\",\r\n \"endDate\": \"2020-09-27\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\",\r\n \"billingAccountId\": 80000071\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/resourceBookings", + "host": [ + "{{URL}}" + ], + "path": [ + "resourceBookings" + ] + } + }, + "response": [] + } + ] + }, + { + "name": "create work period with booking manager", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", + " if(pm.response.status === \"OK\"){\r", + " const response = pm.response.json()\r", + " pm.environment.set(\"workPeriodId\", response.id);\r", + " }\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_bookingManager}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-07\",\r\n \"endDate\": \"2021-03-13\",\r\n \"daysWorked\": 2,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"pending\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/work-periods", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods" + ] + } + }, + "response": [] + }, + { + "name": "create work period with m2m create", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", + " if(pm.response.status === \"OK\"){\r", + " const response = pm.response.json()\r", + " pm.environment.set(\"workPeriodIdCreatedByM2M\", response.id);\r", + " }\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_m2m_create_work_period}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-14\",\r\n \"endDate\": \"2021-03-20\",\r\n \"daysWorked\": 3,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"cancelled\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/work-periods", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods" + ] + } + }, + "response": [] + }, + { + "name": "create work period with connect user", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 403', function () {\r", + " pm.response.to.have.status(403);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_connectUser}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-21\",\r\n \"endDate\": \"2021-03-27\",\r\n \"daysWorked\": 3,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"cancelled\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/work-periods", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods" + ] + } + }, + "response": [] + }, + { + "name": "create work period with member", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 403', function () {\r", + " pm.response.to.have.status(403);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_member}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-21\",\r\n \"endDate\": \"2021-03-27\",\r\n \"daysWorked\": 3,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"cancelled\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/work-periods", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods" + ] + } + }, + "response": [] + }, + { + "name": "create work period with user id not exist", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"Bad Request\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_userId_not_exist}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-21\",\r\n \"endDate\": \"2021-03-27\",\r\n \"daysWorked\": 3,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"cancelled\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/work-periods", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods" + ] + } + }, + "response": [] + }, + { + "name": "create work period with invalid token", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 401', function () {\r", + " pm.response.to.have.status(401);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"Invalid Token.\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer invalid_token" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-21\",\r\n \"endDate\": \"2021-03-27\",\r\n \"daysWorked\": 3,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"cancelled\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/work-periods", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods" + ] + } + }, + "response": [] + }, + { + "name": "create work period with missing parameter 1", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"\\\"workPeriod.resourceBookingId\\\" is required\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_bookingManager}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"startDate\": \"2021-03-07\",\r\n \"endDate\": \"2021-03-13\",\r\n \"daysWorked\": 2,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"pending\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/work-periods", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods" + ] + } + }, + "response": [] + }, + { + "name": "create work period with missing parameter 2", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"\\\"workPeriod.endDate\\\" is required\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_bookingManager}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"daysWorked\": 2,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"pending\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/work-periods", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods" + ] + } + }, + "response": [] + }, + { + "name": "create work period with missing parameter 3", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"\\\"workPeriod.paymentStatus\\\" is required\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_bookingManager}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-07\",\r\n \"endDate\": \"2021-03-13\",\r\n \"daysWorked\": 2,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/work-periods", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods" + ] + } + }, + "response": [] + }, + { + "name": "create work period with invalid parameter 1", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"\\\"workPeriod.resourceBookingId\\\" must be a valid GUID\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_bookingManager}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"resourceBookingId\": \"aaa-aaa\",\r\n \"startDate\": \"2021-03-07\",\r\n \"endDate\": \"2021-03-13\",\r\n \"daysWorked\": 2,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"pending\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/work-periods", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods" + ] + } + }, + "response": [] + }, + { + "name": "create work period with invalid parameter 2", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"\\\"workPeriod.startDate\\\" must be in YYYY-MM-DD format\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_bookingManager}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"07-03-2021\",\r\n \"endDate\": \"2021-03-13\",\r\n \"daysWorked\": 2,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"pending\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/work-periods", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods" + ] + } + }, + "response": [] + }, + { + "name": "create work period with invalid parameter 3", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"startDate should be always Sunday\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_bookingManager}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-06\",\r\n \"endDate\": \"2021-03-13\",\r\n \"daysWorked\": 2,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"pending\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/work-periods", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods" + ] + } + }, + "response": [] + }, + { + "name": "create work period with invalid parameter 4", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"endDate should be always the next Saturday\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_bookingManager}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-07\",\r\n \"endDate\": \"2021-03-14\",\r\n \"daysWorked\": 2,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"pending\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/work-periods", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods" + ] + } + }, + "response": [] + }, + { + "name": "create work period with invalid parameter 5", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"\\\"workPeriod.daysWorked\\\" must be a number\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_bookingManager}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-07\",\r\n \"endDate\": \"2021-03-13\",\r\n \"daysWorked\": \"aa\",\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"pending\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/work-periods", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods" + ] + } + }, + "response": [] + }, + { + "name": "create work period with invalid parameter 6", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(`Key (resource_booking_id, start_date, end_date)=(${pm.environment.get('resourceBookingId')}, 2021-03-07, 2021-03-13) already exists.`)\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_bookingManager}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-07\",\r\n \"endDate\": \"2021-03-13\",\r\n \"daysWorked\": 2,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"pending\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/work-periods", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods" + ] + } + }, + "response": [] + }, + { + "name": "create work period with invalid parameter 7", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"\\\"workPeriod.paymentStatus\\\" must be one of [pending, partially-completed, completed, cancelled]\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_bookingManager}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-07\",\r\n \"endDate\": \"2021-03-13\",\r\n \"daysWorked\": 2,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"paid\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/work-periods", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods" + ] + } + }, + "response": [] + }, + { + "name": "get work period with booking manager", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_bookingManager}}" + } + ], + "url": { + "raw": "{{URL}}/work-periods/{{workPeriodId}}", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods", + "{{workPeriodId}}" + ] + } + }, + "response": [] + }, + { + "name": "get work period with m2m read 1", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_m2m_read_work_period}}" + } + ], + "url": { + "raw": "{{URL}}/work-periods/{{workPeriodIdCreatedByM2M}}", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods", + "{{workPeriodIdCreatedByM2M}}" + ] + } + }, + "response": [] + }, + { + "name": "get work period with m2m read 2", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_m2m_read_work_period_and_payment}}" + } + ], + "url": { + "raw": "{{URL}}/work-periods/{{workPeriodIdCreatedByM2M}}", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods", + "{{workPeriodIdCreatedByM2M}}" + ] + } + }, + "response": [] + }, + { + "name": "get work period with booking manager from db", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_bookingManager}}" + } + ], + "url": { + "raw": "{{URL}}/work-periods/{{workPeriodId}}?fromDb=true", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods", + "{{workPeriodId}}" + ], + "query": [ + { + "key": "fromDb", + "value": "true" + } + ] + } + }, + "response": [] + }, + { + "name": "get work period with connect user", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_connectUser}}" + } + ], + "url": { + "raw": "{{URL}}/work-periods/{{workPeriodId}}", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods", + "{{workPeriodId}}" + ] + } + }, + "response": [] + }, + { + "name": "get work period with member", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 401', function () {\r", + " pm.response.to.have.status(401);\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_member}}" + } + ], + "url": { + "raw": "{{URL}}/work-periods/{{workPeriodId}}", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods", + "{{workPeriodId}}" + ] + } + }, + "response": [] + }, + { + "name": "search work periods with booking manager", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_bookingManager}}" + } + ], + "url": { + "raw": "{{URL}}/work-periods", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods" + ], + "query": [ + { + "key": "page", + "value": "1", + "disabled": true + }, + { + "key": "perPage", + "value": "35", + "disabled": true + }, + { + "key": "sortBy", + "value": "id", + "disabled": true + }, + { + "key": "sortOrder", + "value": "desc", + "disabled": true + }, + { + "key": "resourceBookingId", + "value": "{{resourceBookingId}}", + "disabled": true + }, + { + "key": "resourceBookingIds", + "value": "{{resourceBookingId}},{{resourceBookingIdCreatedByM2M}}", + "disabled": true + }, + { + "key": "paymentStatus", + "value": "pending", + "disabled": true + }, + { + "key": "startDate", + "value": "2021-03-14", + "disabled": true + }, + { + "key": "endDate", + "value": "2021-03-20", + "disabled": true + }, + { + "key": "userHandle", + "value": "pshah_manager", + "disabled": true + }, + { + "key": "projectId", + "value": "16843", + "disabled": true + } + ] + } + }, + "response": [] + }, + { + "name": "search work periods with m2m all 1", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_m2m_all_work_period}}" + } + ], + "url": { + "raw": "{{URL}}/work-periods", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods" + ], + "query": [ + { + "key": "page", + "value": "1", + "disabled": true + }, + { + "key": "perPage", + "value": "5", + "disabled": true + }, + { + "key": "sortBy", + "value": "id", + "disabled": true + }, + { + "key": "sortOrder", + "value": "desc", + "disabled": true + }, + { + "key": "resourceBookingId", + "value": "{{resourceBookingId}}", + "disabled": true + }, + { + "key": "resourceBookingIds", + "value": "{{resourceBookingId}},{{resourceBookingIdCreatedByM2M}}", + "disabled": true + }, + { + "key": "paymentStatus", + "value": "pending", + "disabled": true + }, + { + "key": "startDate", + "value": "2021-03-14", + "disabled": true + }, + { + "key": "endDate", + "value": "2021-03-20", + "disabled": true + }, + { + "key": "userHandle", + "value": "pshah_manager", + "disabled": true + }, + { + "key": "projectId", + "value": "16843", + "disabled": true + } + ] + } + }, + "response": [] + }, + { + "name": "search work periods with m2m all 2", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_m2m_all_work_period_and_payment}}" + } + ], + "url": { + "raw": "{{URL}}/work-periods", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods" + ], + "query": [ + { + "key": "page", + "value": "1", + "disabled": true + }, + { + "key": "perPage", + "value": "5", + "disabled": true + }, + { + "key": "sortBy", + "value": "id", + "disabled": true + }, + { + "key": "sortOrder", + "value": "desc", + "disabled": true + }, + { + "key": "resourceBookingId", + "value": "{{resourceBookingId}}", + "disabled": true + }, + { + "key": "resourceBookingIds", + "value": "{{resourceBookingId}},{{resourceBookingIdCreatedByM2M}}", + "disabled": true + }, + { + "key": "paymentStatus", + "value": "pending", + "disabled": true + }, + { + "key": "startDate", + "value": "2021-03-14", + "disabled": true + }, + { + "key": "endDate", + "value": "2021-03-20", + "disabled": true + }, + { + "key": "userHandle", + "value": "pshah_manager", + "disabled": true + }, + { + "key": "projectId", + "value": "16843", + "disabled": true + } + ] + } + }, + "response": [] + }, + { + "name": "search work periods with connect user", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_connectUser}}" + } + ], + "url": { + "raw": "{{URL}}/work-periods", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods" + ], + "query": [ + { + "key": "page", + "value": "1", + "disabled": true + }, + { + "key": "perPage", + "value": "5", + "disabled": true + }, + { + "key": "sortBy", + "value": "id", + "disabled": true + }, + { + "key": "sortOrder", + "value": "desc", + "disabled": true + }, + { + "key": "resourceBookingId", + "value": "{{resourceBookingId}}", + "disabled": true + }, + { + "key": "resourceBookingIds", + "value": "{{resourceBookingId}},{{resourceBookingIdCreatedByM2M}}", + "disabled": true + }, + { + "key": "paymentStatus", + "value": "pending", + "disabled": true + }, + { + "key": "startDate", + "value": "2021-03-14", + "disabled": true + }, + { + "key": "endDate", + "value": "2021-03-20", + "disabled": true + }, + { + "key": "userHandle", + "value": "pshah_manager", + "disabled": true + }, + { + "key": "projectId", + "value": "16843", + "disabled": true + } + ] + } + }, + "response": [] + }, + { + "name": "search work periods with member", + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_member}}" + } + ], + "url": { + "raw": "{{URL}}/work-periods", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods" + ], + "query": [ + { + "key": "page", + "value": "1", + "disabled": true + }, + { + "key": "perPage", + "value": "5", + "disabled": true + }, + { + "key": "sortBy", + "value": "id", + "disabled": true + }, + { + "key": "sortOrder", + "value": "desc", + "disabled": true + }, + { + "key": "resourceBookingId", + "value": "{{resourceBookingId}}", + "disabled": true + }, + { + "key": "resourceBookingIds", + "value": "{{resourceBookingId}},{{resourceBookingIdCreatedByM2M}}", + "disabled": true + }, + { + "key": "paymentStatus", + "value": "pending", + "disabled": true + }, + { + "key": "startDate", + "value": "2021-03-14", + "disabled": true + }, + { + "key": "endDate", + "value": "2021-03-20", + "disabled": true + }, + { + "key": "userHandle", + "value": "pshah_manager", + "disabled": true + }, + { + "key": "projectId", + "value": "16843", + "disabled": true + } + ] + } + }, + "response": [] + }, + { + "name": "search work periods with invalid token", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 401', function () {\r", + " pm.response.to.have.status(401);\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer invalid_token" + } + ], + "url": { + "raw": "{{URL}}/work-periods", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods" + ], + "query": [ + { + "key": "page", + "value": "1", + "disabled": true + }, + { + "key": "perPage", + "value": "5", + "disabled": true + }, + { + "key": "sortBy", + "value": "id", + "disabled": true + }, + { + "key": "sortOrder", + "value": "desc", + "disabled": true + }, + { + "key": "resourceBookingId", + "value": "{{resourceBookingId}}", + "disabled": true + }, + { + "key": "resourceBookingIds", + "value": "{{resourceBookingId}},{{resourceBookingIdCreatedByM2M}}", + "disabled": true + }, + { + "key": "paymentStatus", + "value": "pending", + "disabled": true + }, + { + "key": "startDate", + "value": "2021-03-14", + "disabled": true + }, + { + "key": "endDate", + "value": "2021-03-20", + "disabled": true + }, + { + "key": "userHandle", + "value": "pshah_manager", + "disabled": true + }, + { + "key": "projectId", + "value": "111", + "disabled": true + } + ] + } + }, + "response": [] + }, + { + "name": "put work period with booking manager", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "PUT", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_bookingManager}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-07\",\r\n \"endDate\": \"2021-03-13\",\r\n \"daysWorked\": 2,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"pending\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/work-periods/{{workPeriodId}}", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods", + "{{workPeriodId}}" + ] + } + }, + "response": [] + }, + { + "name": "put work period with m2m update", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "PUT", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_m2m_update_work_period}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-14\",\r\n \"endDate\": \"2021-03-20\",\r\n \"daysWorked\": 2,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"pending\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/work-periods/{{workPeriodIdCreatedByM2M}}", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods", + "{{workPeriodIdCreatedByM2M}}" + ] + } + }, + "response": [] + }, + { + "name": "put work period with connect user", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 403', function () {\r", + " pm.response.to.have.status(403);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "PUT", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_connectUser}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-21\",\r\n \"endDate\": \"2021-03-27\",\r\n \"daysWorked\": 3,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"cancelled\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/work-periods/{{workPeriodId}}", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods", + "{{workPeriodId}}" + ] + } + }, + "response": [] + }, + { + "name": "put work period with member", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 403', function () {\r", + " pm.response.to.have.status(403);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "PUT", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_member}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-21\",\r\n \"endDate\": \"2021-03-27\",\r\n \"daysWorked\": 3,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"cancelled\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/work-periods/{{workPeriodId}}", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods", + "{{workPeriodId}}" + ] + } + }, + "response": [] + }, + { + "name": "put work period with user id not exist", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"Bad Request\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "PUT", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_userId_not_exist}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-21\",\r\n \"endDate\": \"2021-03-27\",\r\n \"daysWorked\": 3,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"cancelled\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/work-periods/{{workPeriodId}}", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods", + "{{workPeriodId}}" + ] + } + }, + "response": [] + }, + { + "name": "put work period with invalid token", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 401', function () {\r", + " pm.response.to.have.status(401);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"Invalid Token.\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "PUT", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer invalid_token" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"resourceBookingId\": \"{{resourceBookingId}}\",\r\n \"startDate\": \"2021-03-21\",\r\n \"endDate\": \"2021-03-27\",\r\n \"daysWorked\": 3,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"cancelled\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/work-periods/{{workPeriodId}}", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods", + "{{workPeriodId}}" + ] + } + }, + "response": [] + }, + { + "name": "put work period with missing parameter 1", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"\\\"data.resourceBookingId\\\" is required\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "PUT", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_bookingManager}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"startDate\": \"2021-03-07\",\r\n \"endDate\": \"2021-03-13\",\r\n \"daysWorked\": 2,\r\n \"memberRate\": 13.13,\r\n \"customerRate\": 13.13,\r\n \"paymentStatus\": \"pending\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/work-periods/{{workPeriodId}}", + "host": [ + "{{URL}}" + ], + "path": [ + "work-periods", + "{{workPeriodId}}" + ] + } + }, + "response": [] + }, + { + "name": "put work period with missing parameter 2", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"\\\"data.endDate\\\" is required\")\r", "});" ], "type": "text/javascript" @@ -14620,7 +19109,156 @@ } ], "request": { - "method": "POST", + "method": "POST", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_administrator}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"jobId\": \"{{job_id_created_by_administrator}}\",\r\n \"userId\": \"a55fe1bc-1754-45fa-9adc-cf3d6d7c377a\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/jobCandidates", + "host": [ + "{{URL}}" + ], + "path": [ + "jobCandidates" + ] + } + }, + "response": [] + }, + { + "name": "✔ get job candidate with administrator", + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_administrator}}" + } + ], + "url": { + "raw": "{{URL}}/jobCandidates/{{job_candidate_id_created_by_administrator}}", + "host": [ + "{{URL}}" + ], + "path": [ + "jobCandidates", + "{{job_candidate_id_created_by_administrator}}" + ] + } + }, + "response": [] + }, + { + "name": "✔ search job candidates with administrator", + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_administrator}}" + } + ], + "url": { + "raw": "{{URL}}/jobCandidates", + "host": [ + "{{URL}}" + ], + "path": [ + "jobCandidates" + ], + "query": [ + { + "key": "page", + "value": "1", + "disabled": true + }, + { + "key": "perPage", + "value": "1", + "disabled": true + }, + { + "key": "sortBy", + "value": "id", + "disabled": true + }, + { + "key": "sortOrder", + "value": "asc", + "disabled": true + }, + { + "key": "jobId", + "value": "46225f4c-c2a3-4603-a141-0277e96fabfa", + "disabled": true + }, + { + "key": "userId", + "value": "a55fe1bc-1754-45fa-9adc-cf3d6d7c377a", + "disabled": true + }, + { + "key": "status", + "value": "selected", + "disabled": true + } + ] + } + }, + "response": [] + }, + { + "name": "✔ put job candidate with administrator", + "request": { + "method": "PUT", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_administrator}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"jobId\": \"{{job_id_created_by_administrator}}\",\r\n \"userId\": \"a55fe1bc-1754-45fa-9adc-cf3d6d7c377a\",\r\n \"status\": \"placed\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/jobCandidates/{{job_candidate_id_created_by_administrator}}", + "host": [ + "{{URL}}" + ], + "path": [ + "jobCandidates", + "{{job_candidate_id_created_by_administrator}}" + ] + } + }, + "response": [] + }, + { + "name": "✔ patch job candidate with administrator", + "request": { + "method": "PATCH", "header": [ { "key": "Authorization", @@ -14630,7 +19268,7 @@ ], "body": { "mode": "raw", - "raw": "{\r\n \"jobId\": \"{{job_id_created_by_administrator}}\",\r\n \"userId\": \"a55fe1bc-1754-45fa-9adc-cf3d6d7c377a\"\r\n}", + "raw": "{\r\n \"status\": \"selected\"\r\n}", "options": { "raw": { "language": "json" @@ -14638,21 +19276,22 @@ } }, "url": { - "raw": "{{URL}}/jobCandidates", + "raw": "{{URL}}/jobCandidates/{{job_candidate_id_created_by_administrator}}", "host": [ "{{URL}}" ], "path": [ - "jobCandidates" + "jobCandidates", + "{{job_candidate_id_created_by_administrator}}" ] } }, "response": [] }, { - "name": "✔ get job candidate with administrator", + "name": "✔ delete job candidate with administrator", "request": { - "method": "GET", + "method": "DELETE", "header": [ { "key": "Authorization", @@ -14660,6 +19299,15 @@ "value": "Bearer {{token_administrator}}" } ], + "body": { + "mode": "raw", + "raw": "", + "options": { + "raw": { + "language": "json" + } + } + }, "url": { "raw": "{{URL}}/jobCandidates/{{job_candidate_id_created_by_administrator}}", "host": [ @@ -14672,114 +19320,222 @@ } }, "response": [] + } + ] + }, + { + "name": "Interviews", + "item": [ + { + "name": "Before Test", + "item": [ + { + "name": "create job", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var data = JSON.parse(responseBody);\r", + "postman.setEnvironmentVariable(\"job_id_created_by_administrator\",data.id);" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Authorization", + "value": "Bearer {{token_administrator}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"projectId\": {{projectId}},\n \"externalId\": \"88774632\",\n \"description\": \"Dummy Description\",\n \"startDate\": \"2020-09-27\",\n \"duration\": 1,\n \"numPositions\": 13,\n \"resourceType\": \"Dummy Resource Type\",\n \"rateType\": \"hourly\",\n \"workload\": \"full-time\",\n \"skills\": [\n \"23e00d92-207a-4b5b-b3c9-4c5662644941\",\n \"7d076384-ccf6-4e43-a45d-1b24b1e624aa\",\n \"cbac57a3-7180-4316-8769-73af64893158\",\n \"a2b4bc11-c641-4a19-9eb7-33980378f82e\"\n ],\n \"title\": \"Dummy title - at most 64 characters\"\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/jobs", + "host": [ + "{{URL}}" + ], + "path": [ + "jobs" + ] + } + }, + "response": [] + }, + { + "name": "create job candidate", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var data = JSON.parse(responseBody);\r", + "postman.setEnvironmentVariable(\"job_candidate_id_created_by_administrator\",data.id);" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_administrator}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"jobId\": \"{{job_id_created_by_administrator}}\",\r\n \"userId\": \"95e7970f-12b4-43b7-ab35-38c34bf033c7\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/jobCandidates", + "host": [ + "{{URL}}" + ], + "path": [ + "jobCandidates" + ] + } + }, + "response": [] + } + ] }, { - "name": "✔ search job candidates with administrator", + "name": "✔ request interview with administrator", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", + " if(pm.response.status === \"OK\"){\r", + " const response = pm.response.json()\r", + " pm.environment.set(\"interview_round_created_by_administrator\", response.round);\r", + " }\r", + "});" + ], + "type": "text/javascript" + } + } + ], "request": { - "method": "GET", + "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_administrator}}" + "value": "Bearer {{token_administrator}}", + "type": "text" } ], + "body": { + "mode": "raw", + "raw": "{\r\n \"xaiTemplate\": \"interview-30\",\r\n \"googleCalendarId\": \"dummyId\",\r\n \"customMessage\": \"This is a custom message\",\r\n \"status\": \"Scheduling\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, "url": { - "raw": "{{URL}}/jobCandidates", + "raw": "{{URL}}/jobCandidates/{{job_candidate_id_created_by_administrator}}/requestInterview", "host": [ "{{URL}}" ], "path": [ - "jobCandidates" - ], - "query": [ - { - "key": "page", - "value": "1", - "disabled": true - }, - { - "key": "perPage", - "value": "1", - "disabled": true - }, - { - "key": "sortBy", - "value": "id", - "disabled": true - }, - { - "key": "sortOrder", - "value": "asc", - "disabled": true - }, - { - "key": "jobId", - "value": "46225f4c-c2a3-4603-a141-0277e96fabfa", - "disabled": true - }, - { - "key": "userId", - "value": "a55fe1bc-1754-45fa-9adc-cf3d6d7c377a", - "disabled": true - }, - { - "key": "status", - "value": "shortlist", - "disabled": true - } + "jobCandidates", + "{{job_candidate_id_created_by_administrator}}", + "requestInterview" ] } }, "response": [] }, { - "name": "✔ put job candidate with administrator", + "name": "✔ get interview with administrator", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", + "});" + ], + "type": "text/javascript" + } + } + ], "request": { - "method": "PUT", + "method": "GET", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_administrator}}" + "value": "Bearer {{token_administrator}}", + "type": "text" } ], - "body": { - "mode": "raw", - "raw": "{\r\n \"jobId\": \"{{job_id_created_by_administrator}}\",\r\n \"userId\": \"a55fe1bc-1754-45fa-9adc-cf3d6d7c377a\",\r\n \"status\": \"selected\"\r\n}", - "options": { - "raw": { - "language": "json" - } - } - }, "url": { - "raw": "{{URL}}/jobCandidates/{{job_candidate_id_created_by_administrator}}", + "raw": "{{URL}}/jobCandidates/{{job_candidate_id_created_by_administrator}}/interviews/{{interview_round_created_by_administrator}}", "host": [ "{{URL}}" ], "path": [ "jobCandidates", - "{{job_candidate_id_created_by_administrator}}" + "{{job_candidate_id_created_by_administrator}}", + "interviews", + "{{interview_round_created_by_administrator}}" ] } }, "response": [] }, { - "name": "✔ patch job candidate with administrator", + "name": "✔ update interview with administrator", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", + "});" + ], + "type": "text/javascript" + } + } + ], "request": { "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_administrator}}" + "value": "Bearer {{token_administrator}}", + "type": "text" } ], "body": { "mode": "raw", - "raw": "{\r\n \"status\": \"shortlist\"\r\n}", + "raw": "{\r\n \"customMessage\": \"updated\"\r\n}", "options": { "raw": { "language": "json" @@ -14787,46 +19543,53 @@ } }, "url": { - "raw": "{{URL}}/jobCandidates/{{job_candidate_id_created_by_administrator}}", + "raw": "{{URL}}/jobCandidates/{{job_candidate_id_created_by_administrator}}/updateInterview/{{interview_round_created_by_administrator}}", "host": [ "{{URL}}" ], "path": [ "jobCandidates", - "{{job_candidate_id_created_by_administrator}}" + "{{job_candidate_id_created_by_administrator}}", + "updateInterview", + "{{interview_round_created_by_administrator}}" ] } }, "response": [] }, { - "name": "✔ delete job candidate with administrator", + "name": "✔ search interviews with administrator", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", + "});" + ], + "type": "text/javascript" + } + } + ], "request": { - "method": "DELETE", + "method": "GET", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_administrator}}" + "value": "Bearer {{token_administrator}}", + "type": "text" } ], - "body": { - "mode": "raw", - "raw": "", - "options": { - "raw": { - "language": "json" - } - } - }, "url": { - "raw": "{{URL}}/jobCandidates/{{job_candidate_id_created_by_administrator}}", + "raw": "{{URL}}/jobCandidates/{{job_candidate_id_created_by_administrator}}/interviews", "host": [ "{{URL}}" ], "path": [ "jobCandidates", - "{{job_candidate_id_created_by_administrator}}" + "{{job_candidate_id_created_by_administrator}}", + "interviews" ] } }, @@ -15042,7 +19805,7 @@ ], "body": { "mode": "raw", - "raw": "{\r\n \"projectId\": {{projectId}},\r\n \"userId\": \"a55fe1bc-1754-45fa-9adc-cf3d6d7c377a\",\r\n \"jobId\": \"{{job_id_created_by_administrator}}\",\r\n \"startDate\": \"2020-09-27\",\r\n \"endDate\": \"2020-09-27\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\",\r\n \"status\": \"assigned\",\r\n \"billingAccountId\": 80000071\r\n}", + "raw": "{\r\n \"projectId\": {{projectId}},\r\n \"userId\": \"a55fe1bc-1754-45fa-9adc-cf3d6d7c377a\",\r\n \"jobId\": \"{{job_id_created_by_administrator}}\",\r\n \"startDate\": \"2020-09-27\",\r\n \"endDate\": \"2020-09-27\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\",\r\n \"status\": \"placed\",\r\n \"billingAccountId\": 80000071\r\n}", "options": { "raw": { "language": "json" @@ -15075,7 +19838,7 @@ ], "body": { "mode": "raw", - "raw": "{\r\n \"status\": \"assigned\",\r\n \"startDate\": \"2020-09-27\",\r\n \"endDate\": \"2020-09-27\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\",\r\n \"billingAccountId\": 80000071\r\n}", + "raw": "{\r\n \"status\": \"placed\",\r\n \"startDate\": \"2020-09-27\",\r\n \"endDate\": \"2020-09-27\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\",\r\n \"billingAccountId\": 80000071\r\n}", "options": { "raw": { "language": "json" @@ -16395,28 +21158,289 @@ }, { "key": "status", - "value": "shortlist", + "value": "selected", "disabled": true } ] } - }, - "response": [] - }, - { - "name": "✔ put job candidate with member", + }, + "response": [] + }, + { + "name": "✔ put job candidate with member", + "request": { + "method": "PUT", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_member_tester1234}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"jobId\": \"{{job_id_created_by_member}}\",\r\n \"userId\": \"fe38eed1-af73-41fd-85a2-ac4da1ff09a3\",\r\n \"status\": \"placed\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/jobCandidates/{{job_candidate_id_created_for_member}}", + "host": [ + "{{URL}}" + ], + "path": [ + "jobCandidates", + "{{job_candidate_id_created_for_member}}" + ] + } + }, + "response": [] + }, + { + "name": "✔ patch job candidate with member", + "request": { + "method": "PATCH", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_member_tester1234}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"status\": \"selected\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/jobCandidates/{{job_candidate_id_created_for_member}}", + "host": [ + "{{URL}}" + ], + "path": [ + "jobCandidates", + "{{job_candidate_id_created_for_member}}" + ] + } + }, + "response": [] + }, + { + "name": "✘ delete job candidate with member", + "request": { + "method": "DELETE", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_member_tester1234}}" + } + ], + "body": { + "mode": "raw", + "raw": "", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/jobCandidates/{{job_candidate_id_created_for_member}}", + "host": [ + "{{URL}}" + ], + "path": [ + "jobCandidates", + "{{job_candidate_id_created_for_member}}" + ] + } + }, + "response": [] + } + ] + }, + { + "name": "Interviews", + "item": [ + { + "name": "Before Test", + "item": [ + { + "name": "create job", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var data = JSON.parse(responseBody);\r", + "postman.setEnvironmentVariable(\"job_id_created_for_member\",data.id);" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Authorization", + "value": "Bearer {{token_administrator}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"projectId\": {{projectId}},\n \"externalId\": \"88774632\",\n \"description\": \"Dummy Description\",\n \"startDate\": \"2020-09-27\",\n \"duration\": 1,\n \"numPositions\": 13,\n \"resourceType\": \"Dummy Resource Type\",\n \"rateType\": \"hourly\",\n \"workload\": \"full-time\",\n \"skills\": [\n \"23e00d92-207a-4b5b-b3c9-4c5662644941\",\n \"7d076384-ccf6-4e43-a45d-1b24b1e624aa\",\n \"cbac57a3-7180-4316-8769-73af64893158\",\n \"a2b4bc11-c641-4a19-9eb7-33980378f82e\"\n ],\n \"title\": \"Dummy title - at most 64 characters\"\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/jobs", + "host": [ + "{{URL}}" + ], + "path": [ + "jobs" + ] + } + }, + "response": [] + }, + { + "name": "create job candidate", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var data = JSON.parse(responseBody);\r", + "postman.setEnvironmentVariable(\"job_candidate_id_created_for_member\",data.id);" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_administrator}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"jobId\": \"{{job_id_created_by_administrator}}\",\r\n \"userId\": \"95e7970f-12b4-43b7-ab35-38c34bf033c7\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/jobCandidates", + "host": [ + "{{URL}}" + ], + "path": [ + "jobCandidates" + ] + } + }, + "response": [] + }, + { + "name": "create interview", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", + " const response = pm.response.json()\r", + " pm.environment.set(\"interview_round_created_for_member\", response.round)\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "PATCH", + "header": [ + { + "key": "Authorization", + "value": "Bearer {{token_administrator}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"xaiTemplate\": \"interview-30\",\r\n \"googleCalendarId\": \"dummyId\",\r\n \"customMessage\": \"This is a custom message\",\r\n \"status\": \"Scheduling\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/jobCandidates/{{job_candidate_id_created_for_member}}/requestInterview", + "host": [ + "{{URL}}" + ], + "path": [ + "jobCandidates", + "{{job_candidate_id_created_for_member}}", + "requestInterview" + ] + } + }, + "response": [] + } + ] + }, + { + "name": "✘ request interview with member", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 403', function () {\r", + " pm.response.to.have.status(403);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], "request": { - "method": "PUT", + "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_member_tester1234}}" + "value": "Bearer {{token_member}}", + "type": "text" } ], "body": { "mode": "raw", - "raw": "{\r\n \"jobId\": \"{{job_id_created_by_member}}\",\r\n \"userId\": \"fe38eed1-af73-41fd-85a2-ac4da1ff09a3\",\r\n \"status\": \"selected\"\r\n}", + "raw": "{\r\n \"xaiTemplate\": \"interview-30\",\r\n \"googleCalendarId\": \"dummyId\",\r\n \"customMessage\": \"This is a custom message\",\r\n \"status\": \"Scheduling\"\r\n}", "options": { "raw": { "language": "json" @@ -16424,32 +21448,89 @@ } }, "url": { - "raw": "{{URL}}/jobCandidates/{{job_candidate_id_created_for_member}}", + "raw": "{{URL}}/jobCandidates/{{job_candidate_id_created_for_member}}/requestInterview", "host": [ "{{URL}}" ], "path": [ "jobCandidates", - "{{job_candidate_id_created_for_member}}" + "{{job_candidate_id_created_for_member}}", + "requestInterview" ] } }, "response": [] }, { - "name": "✔ patch job candidate with member", + "name": "✘ get interview with member", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 403', function () {\r", + " pm.response.to.have.status(403);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "value": "Bearer {{token_member}}", + "type": "text" + } + ], + "url": { + "raw": "{{URL}}/jobCandidates/{{job_candidate_id_created_for_member}}/interviews/{{interview_round_created_for_member}}", + "host": [ + "{{URL}}" + ], + "path": [ + "jobCandidates", + "{{job_candidate_id_created_for_member}}", + "interviews", + "{{interview_round_created_for_member}}" + ] + } + }, + "response": [] + }, + { + "name": "✘ update interview with member", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 403', function () {\r", + " pm.response.to.have.status(403);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], "request": { "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_member_tester1234}}" + "value": "Bearer {{token_member}}", + "type": "text" } ], "body": { "mode": "raw", - "raw": "{\r\n \"status\": \"shortlist\"\r\n}", + "raw": "{\r\n \"customMessage\": \"updated\"\r\n}", "options": { "raw": { "language": "json" @@ -16457,46 +21538,55 @@ } }, "url": { - "raw": "{{URL}}/jobCandidates/{{job_candidate_id_created_for_member}}", + "raw": "{{URL}}/jobCandidates/{{job_candidate_id_created_for_member}}/updateInterview/{{interview_round_created_for_member}}", "host": [ "{{URL}}" ], "path": [ "jobCandidates", - "{{job_candidate_id_created_for_member}}" + "{{job_candidate_id_created_for_member}}", + "updateInterview", + "{{interview_round_created_for_member}}" ] } }, "response": [] }, { - "name": "✘ delete job candidate with member", + "name": "✘ search interviews with member", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 403', function () {\r", + " pm.response.to.have.status(403);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], "request": { - "method": "DELETE", + "method": "GET", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_member_tester1234}}" + "value": "Bearer {{token_member}}", + "type": "text" } ], - "body": { - "mode": "raw", - "raw": "", - "options": { - "raw": { - "language": "json" - } - } - }, "url": { - "raw": "{{URL}}/jobCandidates/{{job_candidate_id_created_for_member}}", + "raw": "{{URL}}/jobCandidates/{{job_candidate_id_created_for_member}}/interviews", "host": [ "{{URL}}" ], "path": [ "jobCandidates", - "{{job_candidate_id_created_for_member}}" + "{{job_candidate_id_created_for_member}}", + "interviews" ] } }, @@ -16755,7 +21845,7 @@ ], "body": { "mode": "raw", - "raw": "{\r\n \"projectId\": {{project_id_16718}},\r\n \"userId\": \"fe38eed1-af73-41fd-85a2-ac4da1ff09a3\",\r\n \"jobId\": \"{{job_id_created_by_member}}\",\r\n \"startDate\": \"2020-09-27\",\r\n \"endDate\": \"2020-09-27\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\",\r\n \"status\": \"assigned\",\r\n \"billingAccountId\": 80000071\r\n}", + "raw": "{\r\n \"projectId\": {{project_id_16718}},\r\n \"userId\": \"fe38eed1-af73-41fd-85a2-ac4da1ff09a3\",\r\n \"jobId\": \"{{job_id_created_by_member}}\",\r\n \"startDate\": \"2020-09-27\",\r\n \"endDate\": \"2020-09-27\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\",\r\n \"status\": \"placed\",\r\n \"billingAccountId\": 80000071\r\n}", "options": { "raw": { "language": "json" @@ -16788,7 +21878,7 @@ ], "body": { "mode": "raw", - "raw": "{\r\n \"status\": \"assigned\",\r\n \"startDate\": \"2020-09-27\",\r\n \"endDate\": \"2020-09-27\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\",\r\n \"billingAccountId\": 80000071\r\n}", + "raw": "{\r\n \"status\": \"placed\",\r\n \"startDate\": \"2020-09-27\",\r\n \"endDate\": \"2020-09-27\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\",\r\n \"billingAccountId\": 80000071\r\n}", "options": { "raw": { "language": "json" @@ -17490,22 +22580,183 @@ } } }, - "url": { - "raw": "{{URL}}/work-period-payments", - "host": [ - "{{URL}}" - ], - "path": [ - "work-period-payments" - ] + "url": { + "raw": "{{URL}}/work-period-payments", + "host": [ + "{{URL}}" + ], + "path": [ + "work-period-payments" + ] + } + }, + "response": [] + } + ] + }, + { + "name": "✘ create work period payment with member", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 403', function () {\r", + " pm.response.to.have.status(403);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_member_tester1234}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"workPeriodId\": \"{{workPeriodId_created_for_member}}\",\r\n \"amount\": 600,\r\n \"status\": \"completed\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/work-period-payments", + "host": [ + "{{URL}}" + ], + "path": [ + "work-period-payments" + ] + } + }, + "response": [] + }, + { + "name": "✘ get work period payment with member", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 403', function () {\r", + " pm.response.to.have.status(403);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_member_tester1234}}" + } + ], + "url": { + "raw": "{{URL}}/work-period-payments/{{workPeriodPaymentId_created_for_member}}", + "host": [ + "{{URL}}" + ], + "path": [ + "work-period-payments", + "{{workPeriodPaymentId_created_for_member}}" + ] + } + }, + "response": [] + }, + { + "name": "✘ search work period payments with member", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 403', function () {\r", + " pm.response.to.have.status(403);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_member_tester1234}}" + } + ], + "url": { + "raw": "{{URL}}/work-period-payments", + "host": [ + "{{URL}}" + ], + "path": [ + "work-period-payments" + ], + "query": [ + { + "key": "page", + "value": "1", + "disabled": true + }, + { + "key": "perPage", + "value": "5", + "disabled": true + }, + { + "key": "sortBy", + "value": "status", + "disabled": true + }, + { + "key": "sortOrder", + "value": "desc", + "disabled": true + }, + { + "key": "workPeriodId", + "value": "{{workPeriodPaymentId_created_for_member}}", + "disabled": true + }, + { + "key": "workPeriodIds", + "value": "{{workPeriodPaymentId_created_for_member}},{{workPeriodPaymentId_created_for_member}}", + "disabled": true + }, + { + "key": "status", + "value": "completed", + "disabled": true } - }, - "response": [] + ] } - ] + }, + "response": [] }, { - "name": "✘ create work period payment with member", + "name": "✘ put work period payment with member", "event": [ { "listen": "test", @@ -17522,7 +22773,7 @@ } ], "request": { - "method": "POST", + "method": "PUT", "header": [ { "key": "Authorization", @@ -17532,7 +22783,7 @@ ], "body": { "mode": "raw", - "raw": "{\r\n \"workPeriodId\": \"{{workPeriodId_created_for_member}}\",\r\n \"amount\": 600,\r\n \"status\": \"completed\"\r\n}", + "raw": "{\r\n \"workPeriodId\": \"{{workPeriodId_created_for_member}}\",\r\n \"amount\": 1600,\r\n \"status\": \"completed\"\r\n}", "options": { "raw": { "language": "json" @@ -17540,19 +22791,20 @@ } }, "url": { - "raw": "{{URL}}/work-period-payments", + "raw": "{{URL}}/work-period-payments/{{workPeriodPaymentId_created_for_member}}", "host": [ "{{URL}}" ], "path": [ - "work-period-payments" + "work-period-payments", + "{{workPeriodPaymentId_created_for_member}}" ] } }, "response": [] }, { - "name": "✘ get work period payment with member", + "name": "✘ patch work period payment with member", "event": [ { "listen": "test", @@ -17569,7 +22821,7 @@ } ], "request": { - "method": "GET", + "method": "PATCH", "header": [ { "key": "Authorization", @@ -17577,6 +22829,15 @@ "value": "Bearer {{token_member_tester1234}}" } ], + "body": { + "mode": "raw", + "raw": "{\r\n \"workPeriodId\": \"{{workPeriodId_created_for_member}}\",\r\n \"amount\": 450,\r\n \"status\": \"cancelled\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, "url": { "raw": "{{URL}}/work-period-payments/{{workPeriodPaymentId_created_for_member}}", "host": [ @@ -17589,75 +22850,189 @@ } }, "response": [] - }, + } + ] + } + ] + }, + { + "name": "Request with Connect Manager Role", + "item": [ + { + "name": "README", + "item": [ { - "name": "✘ search work period payments with member", + "name": "[STUB] all operations except get/search cause 403 error if manager is not member of project", + "request": { + "method": "LOCK", + "header": [], + "url": { + "raw": "" + } + }, + "response": [] + } + ] + }, + { + "name": "Jobs", + "item": [ + { + "name": "✔ create job with connect manager", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 403', function () {\r", - " pm.response.to.have.status(403);\r", - " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", - "});" + "var data = JSON.parse(responseBody);\r", + "postman.setEnvironmentVariable(\"job_id_created_by_connect_manager\",data.id);" ], "type": "text/javascript" } } ], + "request": { + "method": "POST", + "header": [ + { + "key": "Authorization", + "value": "Bearer {{token_connect_manager_pshahcopmanag2}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"projectId\": {{project_id_16843}},\n \"externalId\": \"1212\",\n \"description\": \"Dummy Description\",\n \"startDate\": \"2020-09-27T04:17:23.131Z\",\n \"duration\": 1,\n \"numPositions\": 13,\n \"resourceType\": \"Dummy Resource Type\",\n \"rateType\": \"hourly\",\n \"workload\": \"full-time\",\n \"skills\": [\n \"23e00d92-207a-4b5b-b3c9-4c5662644941\",\n \"7d076384-ccf6-4e43-a45d-1b24b1e624aa\",\n \"cbac57a3-7180-4316-8769-73af64893158\",\n \"a2b4bc11-c641-4a19-9eb7-33980378f82e\"\n ],\n \"title\": \"Dummy title - at most 64 characters\"\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/jobs", + "host": [ + "{{URL}}" + ], + "path": [ + "jobs" + ] + } + }, + "response": [] + }, + { + "name": "✔ get job with connect manager", "request": { "method": "GET", "header": [ { "key": "Authorization", "type": "text", - "value": "Bearer {{token_member_tester1234}}" + "value": "Bearer {{token_connect_manager_pshahcopmanag2}}" } ], "url": { - "raw": "{{URL}}/work-period-payments", + "raw": "{{URL}}/jobs/{{job_id_created_by_connect_manager}}", "host": [ "{{URL}}" ], "path": [ - "work-period-payments" + "jobs", + "{{job_id_created_by_connect_manager}}" + ] + } + }, + "response": [] + }, + { + "name": "✔ search jobs with connect manager", + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_connect_manager_pshahcopmanag2}}" + } + ], + "url": { + "raw": "{{URL}}/jobs", + "host": [ + "{{URL}}" + ], + "path": [ + "jobs" ], "query": [ { "key": "page", - "value": "1", + "value": "0", "disabled": true }, { "key": "perPage", - "value": "5", + "value": "3", "disabled": true }, { "key": "sortBy", - "value": "status", + "value": "id", "disabled": true }, { "key": "sortOrder", - "value": "desc", + "value": "asc", "disabled": true }, { - "key": "workPeriodId", - "value": "{{workPeriodPaymentId_created_for_member}}", + "key": "projectId", + "value": "21", "disabled": true }, { - "key": "workPeriodIds", - "value": "{{workPeriodPaymentId_created_for_member}},{{workPeriodPaymentId_created_for_member}}", + "key": "externalId", + "value": "1212", + "disabled": true + }, + { + "key": "description", + "value": "Dummy", + "disabled": true + }, + { + "key": "startDate", + "value": "2020-09-27T04:17:23.131Z", + "disabled": true + }, + { + "key": "resourceType", + "value": "Dummy Resource Type", + "disabled": true + }, + { + "key": "skill", + "value": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "disabled": true + }, + { + "key": "rateType", + "value": "hourly", "disabled": true }, { "key": "status", - "value": "completed", + "value": "sourcing", + "disabled": true + }, + { + "key": "workload", + "value": "full-time", + "disabled": true + }, + { + "key": "title", + "value": "dummy", "disabled": true } ] @@ -17666,34 +23041,52 @@ "response": [] }, { - "name": "✘ put work period payment with member", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "pm.test('Status code is 403', function () {\r", - " pm.response.to.have.status(403);\r", - " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", - "});" - ], - "type": "text/javascript" + "name": "✔ put job with connect manager", + "request": { + "method": "PUT", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_connect_manager_pshahcopmanag2}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"projectId\": {{project_id_16843}},\n \"externalId\": \"1212\",\n \"description\": \"Dummy Description\",\n \"startDate\": \"2020-09-27T04:17:23.131Z\",\n \"duration\": 1,\n \"numPositions\": 13,\n \"resourceType\": \"Dummy Resource Type\",\n \"rateType\": \"hourly\",\n \"workload\": \"fractional\",\n \"skills\": [\n \"cbac57a3-7180-4316-8769-73af64893158\",\n \"a2b4bc11-c641-4a19-9eb7-33980378f82e\"\n ],\n \"status\": \"sourcing\",\n \"title\": \"Dummy title - at most 64 characters\"\n}", + "options": { + "raw": { + "language": "json" + } } + }, + "url": { + "raw": "{{URL}}/jobs/{{job_id_created_by_connect_manager}}", + "host": [ + "{{URL}}" + ], + "path": [ + "jobs", + "{{job_id_created_by_connect_manager}}" + ] } - ], + }, + "response": [] + }, + { + "name": "✔ patch job with connect manager", "request": { - "method": "PUT", + "method": "PATCH", "header": [ { "key": "Authorization", "type": "text", - "value": "Bearer {{token_member_tester1234}}" + "value": "Bearer {{token_connect_manager_pshahcopmanag2}}" } ], "body": { "mode": "raw", - "raw": "{\r\n \"workPeriodId\": \"{{workPeriodId_created_for_member}}\",\r\n \"amount\": 1600,\r\n \"status\": \"completed\"\r\n}", + "raw": "{\n \"description\": \"Dummy Description\",\n \"startDate\": \"2020-09-27T04:17:23.131Z\",\n \"duration\": 1,\n \"numPositions\": 13,\n \"resourceType\": \"Dummy Resource Type\",\n \"rateType\": \"hourly\",\n \"workload\": \"fractional\",\n \"skills\": [\n \"cbac57a3-7180-4316-8769-73af64893158\"\n ],\n \"status\": \"sourcing\",\n \"title\": \"Dummy title - at most 64 characters\"\n}", "options": { "raw": { "language": "json" @@ -17701,47 +23094,32 @@ } }, "url": { - "raw": "{{URL}}/work-period-payments/{{workPeriodPaymentId_created_for_member}}", + "raw": "{{URL}}/jobs/{{job_id_created_by_connect_manager}}", "host": [ "{{URL}}" ], "path": [ - "work-period-payments", - "{{workPeriodPaymentId_created_for_member}}" + "jobs", + "{{job_id_created_by_connect_manager}}" ] } }, "response": [] }, { - "name": "✘ patch work period payment with member", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "pm.test('Status code is 403', function () {\r", - " pm.response.to.have.status(403);\r", - " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", - "});" - ], - "type": "text/javascript" - } - } - ], + "name": "✘ delete job with connect manager", "request": { - "method": "PATCH", + "method": "DELETE", "header": [ { "key": "Authorization", "type": "text", - "value": "Bearer {{token_member_tester1234}}" + "value": "Bearer {{token_connect_manager_pshahcopmanag2}}" } ], "body": { "mode": "raw", - "raw": "{\r\n \"workPeriodId\": \"{{workPeriodId_created_for_member}}\",\r\n \"amount\": 450,\r\n \"status\": \"cancelled\"\r\n}", + "raw": "", "options": { "raw": { "language": "json" @@ -17749,53 +23127,81 @@ } }, "url": { - "raw": "{{URL}}/work-period-payments/{{workPeriodPaymentId_created_for_member}}", + "raw": "{{URL}}/jobs/{{job_id_created_by_connect_manager}}", "host": [ "{{URL}}" ], "path": [ - "work-period-payments", - "{{workPeriodPaymentId_created_for_member}}" + "jobs", + "{{job_id_created_by_connect_manager}}" ] } }, "response": [] } ] - } - ] - }, - { - "name": "Request with Connect Manager Role", - "item": [ + }, { - "name": "README", + "name": "Job Candidates", "item": [ { - "name": "[STUB] all operations except get/search cause 403 error if manager is not member of project", - "request": { - "method": "LOCK", - "header": [], - "url": { - "raw": "" + "name": "Before Test", + "item": [ + { + "name": "create job candidate", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var data = JSON.parse(responseBody);\r", + "postman.setEnvironmentVariable(\"job_candidate_id_created_for_connect_manager\",data.id);" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_administrator}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"jobId\": \"{{job_id_created_by_connect_manager}}\",\r\n \"userId\": \"fe38eed1-af73-41fd-85a2-ac4da1ff09a3\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/jobCandidates", + "host": [ + "{{URL}}" + ], + "path": [ + "jobCandidates" + ] + } + }, + "response": [] } - }, - "response": [] - } - ] - }, - { - "name": "Jobs", - "item": [ + ] + }, { - "name": "✔ create job with connect manager", + "name": "✘ create job candidate with connect manager", "event": [ { "listen": "test", "script": { "exec": [ "var data = JSON.parse(responseBody);\r", - "postman.setEnvironmentVariable(\"job_id_created_by_connect_manager\",data.id);" + "postman.setEnvironmentVariable(\"job_candidate_id_created_by_connect_manager\",data.id);" ], "type": "text/javascript" } @@ -17806,13 +23212,13 @@ "header": [ { "key": "Authorization", - "value": "Bearer {{token_connect_manager_pshahcopmanag2}}", - "type": "text" + "type": "text", + "value": "Bearer {{token_connect_manager_pshahcopmanag2}}" } ], "body": { "mode": "raw", - "raw": "{\n \"projectId\": {{project_id_16843}},\n \"externalId\": \"1212\",\n \"description\": \"Dummy Description\",\n \"startDate\": \"2020-09-27T04:17:23.131Z\",\n \"duration\": 1,\n \"numPositions\": 13,\n \"resourceType\": \"Dummy Resource Type\",\n \"rateType\": \"hourly\",\n \"workload\": \"full-time\",\n \"skills\": [\n \"23e00d92-207a-4b5b-b3c9-4c5662644941\",\n \"7d076384-ccf6-4e43-a45d-1b24b1e624aa\",\n \"cbac57a3-7180-4316-8769-73af64893158\",\n \"a2b4bc11-c641-4a19-9eb7-33980378f82e\"\n ],\n \"title\": \"Dummy title - at most 64 characters\"\n}", + "raw": "{\r\n \"jobId\": \"{{job_id_created_by_connect_manager}}\",\r\n \"userId\": \"fe38eed1-af73-41fd-85a2-ac4da1ff09a3\"\r\n}", "options": { "raw": { "language": "json" @@ -17820,19 +23226,19 @@ } }, "url": { - "raw": "{{URL}}/jobs", + "raw": "{{URL}}/jobCandidates", "host": [ "{{URL}}" ], "path": [ - "jobs" + "jobCandidates" ] } }, "response": [] }, { - "name": "✔ get job with connect manager", + "name": "✔ get job candidate with connect manager", "request": { "method": "GET", "header": [ @@ -17843,20 +23249,20 @@ } ], "url": { - "raw": "{{URL}}/jobs/{{job_id_created_by_connect_manager}}", + "raw": "{{URL}}/jobCandidates/{{job_candidate_id_created_for_connect_manager}}", "host": [ "{{URL}}" ], "path": [ - "jobs", - "{{job_id_created_by_connect_manager}}" + "jobCandidates", + "{{job_candidate_id_created_for_connect_manager}}" ] } }, "response": [] }, { - "name": "✔ search jobs with connect manager", + "name": "✔ search job candidates with connect manager", "request": { "method": "GET", "header": [ @@ -17867,22 +23273,22 @@ } ], "url": { - "raw": "{{URL}}/jobs", + "raw": "{{URL}}/jobCandidates", "host": [ "{{URL}}" ], "path": [ - "jobs" + "jobCandidates" ], "query": [ { "key": "page", - "value": "0", + "value": "1", "disabled": true }, { "key": "perPage", - "value": "3", + "value": "1", "disabled": true }, { @@ -17896,53 +23302,18 @@ "disabled": true }, { - "key": "projectId", - "value": "21", - "disabled": true - }, - { - "key": "externalId", - "value": "1212", - "disabled": true - }, - { - "key": "description", - "value": "Dummy", - "disabled": true - }, - { - "key": "startDate", - "value": "2020-09-27T04:17:23.131Z", - "disabled": true - }, - { - "key": "resourceType", - "value": "Dummy Resource Type", - "disabled": true - }, - { - "key": "skill", - "value": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "key": "jobId", + "value": "46225f4c-c2a3-4603-a141-0277e96fabfa", "disabled": true }, { - "key": "rateType", - "value": "hourly", + "key": "userId", + "value": "fe38eed1-af73-41fd-85a2-ac4da1ff09a3", "disabled": true }, { "key": "status", - "value": "sourcing", - "disabled": true - }, - { - "key": "workload", - "value": "full-time", - "disabled": true - }, - { - "key": "title", - "value": "dummy", + "value": "selected", "disabled": true } ] @@ -17951,7 +23322,7 @@ "response": [] }, { - "name": "✔ put job with connect manager", + "name": "✔ put job candidate with connect manager", "request": { "method": "PUT", "header": [ @@ -17963,7 +23334,7 @@ ], "body": { "mode": "raw", - "raw": "{\n \"projectId\": {{project_id_16843}},\n \"externalId\": \"1212\",\n \"description\": \"Dummy Description\",\n \"startDate\": \"2020-09-27T04:17:23.131Z\",\n \"duration\": 1,\n \"numPositions\": 13,\n \"resourceType\": \"Dummy Resource Type\",\n \"rateType\": \"hourly\",\n \"workload\": \"fractional\",\n \"skills\": [\n \"cbac57a3-7180-4316-8769-73af64893158\",\n \"a2b4bc11-c641-4a19-9eb7-33980378f82e\"\n ],\n \"status\": \"sourcing\",\n \"title\": \"Dummy title - at most 64 characters\"\n}", + "raw": "{\r\n \"jobId\": \"{{job_id_created_by_connect_manager}}\",\r\n \"userId\": \"fe38eed1-af73-41fd-85a2-ac4da1ff09a3\",\r\n \"status\": \"placed\"\r\n}", "options": { "raw": { "language": "json" @@ -17971,20 +23342,20 @@ } }, "url": { - "raw": "{{URL}}/jobs/{{job_id_created_by_connect_manager}}", + "raw": "{{URL}}/jobCandidates/{{job_candidate_id_created_for_connect_manager}}", "host": [ "{{URL}}" ], "path": [ - "jobs", - "{{job_id_created_by_connect_manager}}" + "jobCandidates", + "{{job_candidate_id_created_for_connect_manager}}" ] } }, "response": [] }, { - "name": "✔ patch job with connect manager", + "name": "✔ patch job candidate with connect manager", "request": { "method": "PATCH", "header": [ @@ -17996,7 +23367,7 @@ ], "body": { "mode": "raw", - "raw": "{\n \"description\": \"Dummy Description\",\n \"startDate\": \"2020-09-27T04:17:23.131Z\",\n \"duration\": 1,\n \"numPositions\": 13,\n \"resourceType\": \"Dummy Resource Type\",\n \"rateType\": \"hourly\",\n \"workload\": \"fractional\",\n \"skills\": [\n \"cbac57a3-7180-4316-8769-73af64893158\"\n ],\n \"status\": \"sourcing\",\n \"title\": \"Dummy title - at most 64 characters\"\n}", + "raw": "{\r\n \"status\": \"selected\"\r\n}", "options": { "raw": { "language": "json" @@ -18004,20 +23375,20 @@ } }, "url": { - "raw": "{{URL}}/jobs/{{job_id_created_by_connect_manager}}", + "raw": "{{URL}}/jobCandidates/{{job_candidate_id_created_for_connect_manager}}", "host": [ "{{URL}}" ], "path": [ - "jobs", - "{{job_id_created_by_connect_manager}}" + "jobCandidates", + "{{job_candidate_id_created_for_connect_manager}}" ] } }, "response": [] }, { - "name": "✘ delete job with connect manager", + "name": "✘ delete job candidate with connect manager", "request": { "method": "DELETE", "header": [ @@ -18034,29 +23405,73 @@ "raw": { "language": "json" } - } + } + }, + "url": { + "raw": "{{URL}}/jobCandidates/{{job_candidate_id_created_for_connect_manager}}", + "host": [ + "{{URL}}" + ], + "path": [ + "jobCandidates", + "{{job_candidate_id_created_for_connect_manager}}" + ] + } + }, + "response": [] + } + ] + }, + { + "name": "Interviews", + "item": [ + { + "name": "Before Test", + "item": [ + { + "name": "create job", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var data = JSON.parse(responseBody);\r", + "postman.setEnvironmentVariable(\"job_id_created_for_connect_manager\",data.id);" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Authorization", + "value": "Bearer {{token_administrator}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"projectId\": {{projectId}},\n \"externalId\": \"88774632\",\n \"description\": \"Dummy Description\",\n \"startDate\": \"2020-09-27\",\n \"duration\": 1,\n \"numPositions\": 13,\n \"resourceType\": \"Dummy Resource Type\",\n \"rateType\": \"hourly\",\n \"workload\": \"full-time\",\n \"skills\": [\n \"23e00d92-207a-4b5b-b3c9-4c5662644941\",\n \"7d076384-ccf6-4e43-a45d-1b24b1e624aa\",\n \"cbac57a3-7180-4316-8769-73af64893158\",\n \"a2b4bc11-c641-4a19-9eb7-33980378f82e\"\n ],\n \"title\": \"Dummy title - at most 64 characters\"\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/jobs", + "host": [ + "{{URL}}" + ], + "path": [ + "jobs" + ] + } + }, + "response": [] }, - "url": { - "raw": "{{URL}}/jobs/{{job_id_created_by_connect_manager}}", - "host": [ - "{{URL}}" - ], - "path": [ - "jobs", - "{{job_id_created_by_connect_manager}}" - ] - } - }, - "response": [] - } - ] - }, - { - "name": "Job Candidates", - "item": [ - { - "name": "Before Test", - "item": [ { "name": "create job candidate", "event": [ @@ -18082,7 +23497,7 @@ ], "body": { "mode": "raw", - "raw": "{\r\n \"jobId\": \"{{job_id_created_by_connect_manager}}\",\r\n \"userId\": \"fe38eed1-af73-41fd-85a2-ac4da1ff09a3\"\r\n}", + "raw": "{\r\n \"jobId\": \"{{job_id_created_by_administrator}}\",\r\n \"userId\": \"95e7970f-12b4-43b7-ab35-38c34bf033c7\"\r\n}", "options": { "raw": { "language": "json" @@ -18100,35 +23515,87 @@ } }, "response": [] + }, + { + "name": "create interview", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", + " const response = pm.response.json()\r", + " pm.environment.set(\"interview_round_created_for_connect_manager\", response.round)\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "PATCH", + "header": [ + { + "key": "Authorization", + "value": "Bearer {{token_administrator}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"xaiTemplate\": \"interview-30\",\r\n \"googleCalendarId\": \"dummyId\",\r\n \"customMessage\": \"This is a custom message\",\r\n \"status\": \"Scheduling\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/jobCandidates/{{job_candidate_id_created_for_connect_manager}}/requestInterview", + "host": [ + "{{URL}}" + ], + "path": [ + "jobCandidates", + "{{job_candidate_id_created_for_connect_manager}}", + "requestInterview" + ] + } + }, + "response": [] } ] }, { - "name": "✘ create job candidate with connect manager", + "name": "✘ request interview with connect manager", "event": [ { "listen": "test", "script": { "exec": [ - "var data = JSON.parse(responseBody);\r", - "postman.setEnvironmentVariable(\"job_candidate_id_created_by_connect_manager\",data.id);" + "pm.test('Status code is 403', function () {\r", + " pm.response.to.have.status(403);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", + "});" ], "type": "text/javascript" } } ], "request": { - "method": "POST", + "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_connect_manager_pshahcopmanag2}}" + "value": "Bearer {{token_connect_manager_pshahcopmanag2}}", + "type": "text" } ], "body": { "mode": "raw", - "raw": "{\r\n \"jobId\": \"{{job_id_created_by_connect_manager}}\",\r\n \"userId\": \"fe38eed1-af73-41fd-85a2-ac4da1ff09a3\"\r\n}", + "raw": "{\r\n \"xaiTemplate\": \"interview-30\",\r\n \"googleCalendarId\": \"dummyId\",\r\n \"customMessage\": \"This is a custom message\",\r\n \"status\": \"Scheduling\"\r\n}", "options": { "raw": { "language": "json" @@ -18136,148 +23603,89 @@ } }, "url": { - "raw": "{{URL}}/jobCandidates", + "raw": "{{URL}}/jobCandidates/{{job_candidate_id_created_for_connect_manager}}/requestInterview", "host": [ "{{URL}}" ], "path": [ - "jobCandidates" + "jobCandidates", + "{{job_candidate_id_created_for_connect_manager}}", + "requestInterview" ] } }, "response": [] }, { - "name": "✔ get job candidate with connect manager", - "request": { - "method": "GET", - "header": [ - { - "key": "Authorization", - "type": "text", - "value": "Bearer {{token_connect_manager_pshahcopmanag2}}" + "name": "✘ get interview with connect manager", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 403', function () {\r", + " pm.response.to.have.status(403);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", + "});" + ], + "type": "text/javascript" } - ], - "url": { - "raw": "{{URL}}/jobCandidates/{{job_candidate_id_created_for_connect_manager}}", - "host": [ - "{{URL}}" - ], - "path": [ - "jobCandidates", - "{{job_candidate_id_created_for_connect_manager}}" - ] } - }, - "response": [] - }, - { - "name": "✔ search job candidates with connect manager", + ], "request": { "method": "GET", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_connect_manager_pshahcopmanag2}}" + "value": "Bearer {{token_connect_manager_pshahcopmanag2}}", + "type": "text" } ], "url": { - "raw": "{{URL}}/jobCandidates", + "raw": "{{URL}}/jobCandidates/{{job_candidate_id_created_for_connect_manager}}/interviews/{{interview_round_created_for_connect_manager}}", "host": [ "{{URL}}" ], "path": [ - "jobCandidates" - ], - "query": [ - { - "key": "page", - "value": "1", - "disabled": true - }, - { - "key": "perPage", - "value": "1", - "disabled": true - }, - { - "key": "sortBy", - "value": "id", - "disabled": true - }, - { - "key": "sortOrder", - "value": "asc", - "disabled": true - }, - { - "key": "jobId", - "value": "46225f4c-c2a3-4603-a141-0277e96fabfa", - "disabled": true - }, - { - "key": "userId", - "value": "fe38eed1-af73-41fd-85a2-ac4da1ff09a3", - "disabled": true - }, - { - "key": "status", - "value": "shortlist", - "disabled": true - } + "jobCandidates", + "{{job_candidate_id_created_for_connect_manager}}", + "interviews", + "{{interview_round_created_for_connect_manager}}" ] } }, "response": [] }, { - "name": "✔ put job candidate with connect manager", - "request": { - "method": "PUT", - "header": [ - { - "key": "Authorization", - "type": "text", - "value": "Bearer {{token_connect_manager_pshahcopmanag2}}" - } - ], - "body": { - "mode": "raw", - "raw": "{\r\n \"jobId\": \"{{job_id_created_by_connect_manager}}\",\r\n \"userId\": \"fe38eed1-af73-41fd-85a2-ac4da1ff09a3\",\r\n \"status\": \"selected\"\r\n}", - "options": { - "raw": { - "language": "json" - } + "name": "✘ update interview with connect manager", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 403', function () {\r", + " pm.response.to.have.status(403);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", + "});" + ], + "type": "text/javascript" } - }, - "url": { - "raw": "{{URL}}/jobCandidates/{{job_candidate_id_created_for_connect_manager}}", - "host": [ - "{{URL}}" - ], - "path": [ - "jobCandidates", - "{{job_candidate_id_created_for_connect_manager}}" - ] } - }, - "response": [] - }, - { - "name": "✔ patch job candidate with connect manager", + ], "request": { "method": "PATCH", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_connect_manager_pshahcopmanag2}}" + "value": "Bearer {{token_connect_manager_pshahcopmanag2}}", + "type": "text" } ], "body": { "mode": "raw", - "raw": "{\r\n \"status\": \"shortlist\"\r\n}", + "raw": "{\r\n \"customMessage\": \"updated\"\r\n}", "options": { "raw": { "language": "json" @@ -18285,46 +23693,55 @@ } }, "url": { - "raw": "{{URL}}/jobCandidates/{{job_candidate_id_created_for_connect_manager}}", + "raw": "{{URL}}/jobCandidates/{{job_candidate_id_created_for_connect_manager}}/updateInterview/{{interview_round_created_for_connect_manager}}", "host": [ "{{URL}}" ], "path": [ "jobCandidates", - "{{job_candidate_id_created_for_connect_manager}}" + "{{job_candidate_id_created_for_connect_manager}}", + "updateInterview", + "{{interview_round_created_for_connect_manager}}" ] } }, "response": [] }, { - "name": "✘ delete job candidate with connect manager", + "name": "✘ search interviews with member", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 403', function () {\r", + " pm.response.to.have.status(403);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], "request": { - "method": "DELETE", + "method": "GET", "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_connect_manager_pshahcopmanag2}}" + "value": "Bearer {{token_connect_manager_pshahcopmanag2}}", + "type": "text" } ], - "body": { - "mode": "raw", - "raw": "", - "options": { - "raw": { - "language": "json" - } - } - }, "url": { - "raw": "{{URL}}/jobCandidates/{{job_candidate_id_created_for_connect_manager}}", + "raw": "{{URL}}/jobCandidates/{{job_candidate_id_created_for_connect_manager}}/interviews", "host": [ "{{URL}}" ], "path": [ "jobCandidates", - "{{job_candidate_id_created_for_connect_manager}}" + "{{job_candidate_id_created_for_connect_manager}}", + "interviews" ] } }, @@ -18579,7 +23996,7 @@ ], "body": { "mode": "raw", - "raw": "{\r\n \"projectId\": {{project_id_16843}},\r\n \"userId\": \"fe38eed1-af73-41fd-85a2-ac4da1ff09a3\",\r\n \"jobId\": \"{{job_id_created_by_connect_manager}}\",\r\n \"startDate\": \"2020-09-27\",\r\n \"endDate\": \"2020-09-27\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\",\r\n \"status\": \"assigned\",\r\n \"billingAccountId\": 80000071\r\n}", + "raw": "{\r\n \"projectId\": {{project_id_16843}},\r\n \"userId\": \"fe38eed1-af73-41fd-85a2-ac4da1ff09a3\",\r\n \"jobId\": \"{{job_id_created_by_connect_manager}}\",\r\n \"startDate\": \"2020-09-27\",\r\n \"endDate\": \"2020-09-27\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\",\r\n \"status\": \"placed\",\r\n \"billingAccountId\": 80000071\r\n}", "options": { "raw": { "language": "json" @@ -18612,7 +24029,7 @@ ], "body": { "mode": "raw", - "raw": "{\r\n \"status\": \"assigned\",\r\n \"startDate\": \"2020-09-27\",\r\n \"endDate\": \"2020-09-27\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\",\r\n \"billingAccountId\": 80000071\r\n}", + "raw": "{\r\n \"status\": \"placed\",\r\n \"startDate\": \"2020-09-27\",\r\n \"endDate\": \"2020-09-27\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\",\r\n \"billingAccountId\": 80000071\r\n}", "options": { "raw": { "language": "json" @@ -19586,4 +25003,4 @@ ] } ] -} +} \ No newline at end of file diff --git a/docs/swagger.yaml b/docs/swagger.yaml index 940be373..00dab590 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -5,6 +5,7 @@ info: version: 1.0.0 servers: - url: /api/{apiVersion}/ + - url: https://api.topcoder-dev.com/{apiVersion}/ variables: apiVersion: default: "v5" @@ -12,6 +13,7 @@ servers: tags: - name: Jobs - name: JobCandidates + - name: Interviews - name: ResourceBookings - name: Teams - name: WorkPeriods @@ -592,9 +594,11 @@ paths: enum: [ "open", + "placed", "selected", - "shortlist", - "rejected", + "client rejected - screening", + "client rejected - interview", + "rejected - other", "cancelled", "interview", "topcoder-rejected", @@ -614,7 +618,7 @@ paths: schema: type: array items: - $ref: "#/components/schemas/JobCandidate" + $ref: "#/components/schemas/JobCandidateInterviewsIncluded" headers: X-Next-Page: @@ -699,7 +703,7 @@ paths: content: application/json: schema: - $ref: "#/components/schemas/JobCandidate" + $ref: "#/components/schemas/JobCandidateInterviewsIncluded" "400": description: Bad request content: @@ -899,6 +903,306 @@ paths: application/json: schema: $ref: "#/components/schemas/Error" + /jobCandidates/{jobCandidateId}/requestInterview: + patch: + tags: + - Interviews + description: | + Request a new interview. + + **Authorization** Topcoder token with create interview scope is allowed + security: + - bearerAuth: [] + parameters: + - in: path + name: jobCandidateId + description: The job candidate id. + required: true + schema: + type: string + format: uuid + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/RequestInterviewBody" + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: "#/components/schemas/Interview" + "400": + description: Bad request + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + "401": + description: Not authenticated + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + "403": + description: Forbidden + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + "404": + description: Not Found + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + "500": + description: Internal Server Error + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + /jobCandidates/{jobCandidateId}/updateInterview/{round}: + patch: + tags: + - Interviews + description: | + Partially update interview. + + **Authorization** Topcoder token with update interview scope is allowed + security: + - bearerAuth: [] + parameters: + - in: path + name: jobCandidateId + description: The job candidate id. + required: true + schema: + type: string + format: uuid + - in: path + name: round + description: The interview round. + required: true + schema: + type: integer + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/UpdateInterviewRequestBody" + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: "#/components/schemas/Interview" + "400": + description: Bad request + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + "401": + description: Not authenticated + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + "403": + description: Forbidden + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + "404": + description: Not Found + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + "500": + description: Internal Server Error + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + /jobCandidates/{jobCandidateId}/interviews: + get: + tags: + - Interviews + description: | + Search interviews. + + **Authorization** Topcoder token with read interview scope is allowed + security: + - bearerAuth: [] + parameters: + - in: path + name: jobCandidateId + description: The job candidate id. + required: true + schema: + type: string + format: uuid + - in: query + name: page + required: false + schema: + type: integer + default: 1 + description: The page number. + - in: query + name: perPage + required: false + schema: + type: integer + default: 20 + description: The number of items to list per page. + - in: query + name: sortBy + required: false + schema: + type: string + default: createdAt + enum: ["round", "createdAt", "updatedAt"] + description: The sort by column. + - in: query + name: sortOrder + required: false + schema: + type: string + default: desc + enum: ["desc", "asc"] + - in: query + name: createdAt + required: false + schema: + type: string + format: date-time + description: The creation date/time of interview. + - in: query + name: updatedAt + required: false + schema: + type: string + format: date-time + description: The last update date/time of interview. + - in: query + name: status + required: false + schema: + type: string + enum: ["Requested"] + description: The interview status. + responses: + "200": + description: OK + content: + application/json: + schema: + type: array + items: + $ref: "#/components/schemas/Interview" + "400": + description: Bad request + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + "401": + description: Not authenticated + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + "403": + description: Forbidden + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + "404": + description: Not Found + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + "500": + description: Internal Server Error + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + /jobCandidates/{jobCandidateId}/interviews/{round}: + get: + tags: + - Interviews + description: | + Get interview by round. + + **Authorization** Topcoder token with read interview scope is allowed + security: + - bearerAuth: [] + parameters: + - in: path + name: jobCandidateId + description: The job candidate id. + required: true + schema: + type: string + format: uuid + - in: path + name: round + description: The interview round. + required: true + schema: + type: integer + - in: query + name: fromDb + description: get data from db or not. + required: false + schema: + type: boolean + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: "#/components/schemas/Interview" + "400": + description: Bad request + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + "401": + description: Not authenticated + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + "403": + description: Forbidden + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + "404": + description: Not Found + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + "500": + description: Internal Server Error + content: + application/json: + schema: + $ref: "#/components/schemas/Error" /resourceBookings: post: tags: @@ -1004,7 +1308,7 @@ paths: required: false schema: type: string - enum: ["assigned", "in-progress", "completed"] + enum: ["placed", "in-progress", "completed"] description: The status. - in: query name: startDate @@ -2958,6 +3262,65 @@ components: type: boolean default: false JobCandidate: + required: + - id + - jobId + - userId + - status + properties: + id: + type: string + format: uuid + description: "The job id." + jobId: + type: string + format: uuid + description: "The project id." + userId: + type: string + format: uuid + example: "a55fe1bc-1754-45fa-9adc-cf3d6d7c377a" + description: "The user id." + status: + type: string + enum: + [ + "open", + "placed", + "selected", + "client rejected - screening", + "client rejected - interview", + "rejected - other", + "cancelled", + "interview", + "topcoder-rejected", + ] + description: "The job candidate status." + externalId: + type: string + example: "1212" + description: "The external id." + resume: + type: string + example: "http://example.com" + description: "The resume link" + createdAt: + type: string + format: date-time + description: "The job created date." + createdBy: + type: string + example: "topocder user" + description: "The user who created the job.(Will get the user info from the token)" + updatedAt: + type: string + format: date-time + description: "The job last updated at." + updatedBy: + type: string + example: "topcoder user" + description: "The user who updated the job last time.(Will get the user info from the token)" + JobCandidateInterviewsIncluded: required: - id - jobId @@ -2987,7 +3350,6 @@ components: "rejected", "cancelled", "interview", - "topcoder-rejected", ] description: "The job candidate status." externalId: @@ -2998,6 +3360,11 @@ components: type: string example: "http://example.com" description: "The resume link" + interviews: + type: array + description: "Interviews associated to this job candidate." + items: + $ref: "#/components/schemas/Interview" createdAt: type: string format: date-time @@ -3030,7 +3397,7 @@ components: description: "The user id." status: type: string - enum: ["open", "selected", "shortlist", "rejected", "cancelled"] + enum: ["open", "placed", "selected", "client rejected - screening", "client rejected - interview", "rejected - other", "cancelled", "interview", "topcoder-rejected"] description: "The job candidate status." default: open externalId: @@ -3048,9 +3415,11 @@ components: enum: [ "open", + "placed", "selected", - "shortlist", - "rejected", + "client rejected - screening", + "client rejected - interview", + "rejected - other", "cancelled", "interview", "topcoder-rejected", @@ -3063,6 +3432,125 @@ components: type: string example: "http://example.com" description: "The resume link" + Interview: + required: + - id + - jobCandidateId + - xaiTemplate + - round + - status + - createdAt + - createdBy + properties: + id: + type: string + format: uuid + description: "The interview id." + jobCandidateId: + type: string + format: uuid + description: "The job candidate id." + googleCalendarId: + type: string + example: "dummyId" + description: "The google calendar id." + xaiTemplate: + type: string + example: "interview-30" + enum: ["interview-30", "interview-60"] + description: "The x.ai template name" + customMessage: + type: string + example: "This is a custom message" + description: "The custom message." + round: + type: integer + example: 1 + description: "The interview round." + attendeesList: + type: array + description: "Attendee list for this interview." + items: + type: string + format: email + startTimestamp: + type: string + format: date-time + description: "Interview start time." + status: + type: string + enum: ["Scheduling", "Scheduled", "Requested for reschedule", "Rescheduled", "Completed", "Cancelled"] + description: "The interview status." + createdAt: + type: string + format: date-time + description: "The interview created date." + createdBy: + type: string + format: uuid + description: "The user who created the interview.(Will get the user info from the token)" + updatedAt: + type: string + format: date-time + description: "The interview last updated at." + updatedBy: + type: string + format: uuid + description: "The user who updated the interview last time.(Will get the user info from the token)" + RequestInterviewBody: + required: + - xaiTemplate + properties: + googleCalendarId: + type: string + example: "dummyId" + description: "The google calendar id." + customMessage: + type: string + example: "This is a custom message" + description: "The custom message." + xaiTemplate: + type: string + enum: ["interview-30", "interview-60"] + example: "interview-30" + description: "The x.ai template name" + attendeesList: + type: array + items: + type: string + format: email + status: + type: string + enum: ["Scheduling", "Scheduled", "Requested for reschedule", "Rescheduled", "Completed", "Cancelled"] + default: "Scheduling" + description: "The interview status." + UpdateInterviewRequestBody: + properties: + googleCalendarId: + type: string + example: "dummyId" + description: "The google calendar id." + customMessage: + type: string + example: "This is a custom message" + description: "The custom message." + xaiTemplate: + type: string + enum: ["interview-30", "interview-60"] + example: "interview-30" + description: "The x.ai template name" + attendeesList: + type: array + items: + type: string + format: email + startTimestamp: + type: string + format: date-time + status: + type: string + enum: ["Scheduling", "Scheduled", "Requested for reschedule", "Rescheduled", "Completed", "Cancelled"] + description: "The interview status." JobPatchRequestBody: properties: status: @@ -3136,7 +3624,7 @@ components: description: "The external id." status: type: string - enum: ["assigned", "closed", "cancelled"] + enum: ["placed", "closed", "cancelled"] description: "The job status." startDate: type: string @@ -3203,7 +3691,7 @@ components: description: "The job id." status: type: string - enum: ["assigned", "closed", "cancelled"] + enum: ["placed", "closed", "cancelled"] description: "The job status." default: sourcing startDate: @@ -3238,7 +3726,7 @@ components: properties: status: type: string - enum: ["assigned", "closed", "cancelled"] + enum: ["placed", "closed", "cancelled"] startDate: type: string format: date @@ -3857,14 +4345,20 @@ components: type: string format: url description: "The link for the resume that can be downloaded" + interviews: + type: array + items: + $ref: "#/components/schemas/Interview" status: type: string enum: [ "open", + "placed", "selected", - "shortlist", - "rejected", + "client rejected - screening", + "client rejected - interview", + "rejected - other", "cancelled", "interview", "topcoder-rejected", diff --git a/docs/topcoder-bookings.postman_environment.json b/docs/topcoder-bookings.postman_environment.json index fc326e86..58304b6d 100644 --- a/docs/topcoder-bookings.postman_environment.json +++ b/docs/topcoder-bookings.postman_environment.json @@ -1,5 +1,5 @@ { - "id": "8df2004f-35bd-439c-93b2-0d999d88ec99", + "id": "cf10e077-1975-444a-b2d2-3e8e71080526", "name": "topcoder-bookings", "values": [ { @@ -341,9 +341,89 @@ "key": "workPeriodPaymentId_created_for_connect_manager", "value": "", "enabled": true + }, + { + "key": "interviewRound", + "value": "1", + "enabled": true + }, + { + "key": "interview_round_created_by_administrator", + "value": "1", + "enabled": true + }, + { + "key": "job_id_created_for_member", + "value": "", + "enabled": true + }, + { + "key": "job_candidate_id_created_for_member", + "value": "", + "enabled": true + }, + { + "key": "interview_round_created_for_member", + "value": "1", + "enabled": true + }, + { + "key": "job_id_created_for_connect_manager", + "value": "", + "enabled": true + }, + { + "key": "job_candidate_id_created_for_connect_manager", + "value": "", + "enabled": true + }, + { + "key": "interview_round_created_for_connect_manager", + "value": "1", + "enabled": true + }, + { + "key": "completedInterviewJobCandidateId", + "value": "", + "enabled": true + }, + { + "key": "completedInterviewRound", + "value": "", + "enabled": true + }, + { + "key": "token_m2m_create_interviews", + "value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL3RvcGNvZGVyLWRldi5hdXRoMC5jb20vIiwic3ViIjoiZW5qdzE4MTBlRHozWFR3U08yUm4yWTljUVRyc3BuM0JAY2xpZW50cyIsImF1ZCI6Imh0dHBzOi8vbTJtLnRvcGNvZGVyLWRldi5jb20vIiwiaWF0IjoxNTUwOTA2Mzg4LCJleHAiOjIxNDc0ODM2NDgsImF6cCI6ImVuancxODEwZUR6M1hUd1NPMlJuMlk5Y1FUcnNwbjNCIiwic2NvcGUiOiJjcmVhdGU6dGFhcy1pbnRlcnZpZXdzIiwiZ3R5IjoiY2xpZW50LWNyZWRlbnRpYWxzIn0.VD5j8qdgK3ZPctqD-Nb5KKfSeFIuyajc7Q-wQ_kabIk", + "enabled": true + }, + { + "key": "token_m2m_read_interviews", + "value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL3RvcGNvZGVyLWRldi5hdXRoMC5jb20vIiwic3ViIjoiZW5qdzE4MTBlRHozWFR3U08yUm4yWTljUVRyc3BuM0JAY2xpZW50cyIsImF1ZCI6Imh0dHBzOi8vbTJtLnRvcGNvZGVyLWRldi5jb20vIiwiaWF0IjoxNTUwOTA2Mzg4LCJleHAiOjIxNDc0ODM2NDgsImF6cCI6ImVuancxODEwZUR6M1hUd1NPMlJuMlk5Y1FUcnNwbjNCIiwic2NvcGUiOiJyZWFkOnRhYXMtaW50ZXJ2aWV3cyIsImd0eSI6ImNsaWVudC1jcmVkZW50aWFscyJ9.3Gf42TvkegVi9uiIro75G8-2MqkLdeSbuswVRuZf7t4", + "enabled": true + }, + { + "key": "token_m2m_all_interviews", + "value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL3RvcGNvZGVyLWRldi5hdXRoMC5jb20vIiwic3ViIjoiZW5qdzE4MTBlRHozWFR3U08yUm4yWTljUVRyc3BuM0JAY2xpZW50cyIsImF1ZCI6Imh0dHBzOi8vbTJtLnRvcGNvZGVyLWRldi5jb20vIiwiaWF0IjoxNTUwOTA2Mzg4LCJleHAiOjIxNDc0ODM2NDgsImF6cCI6ImVuancxODEwZUR6M1hUd1NPMlJuMlk5Y1FUcnNwbjNCIiwic2NvcGUiOiJhbGw6dGFhcy1pbnRlcnZpZXdzIiwiZ3R5IjoiY2xpZW50LWNyZWRlbnRpYWxzIn0.N79nfsZvGzX01hufnMzGG7wNCBqL8eceSpJnHS0lhqo", + "enabled": true + }, + { + "key": "token_m2m_update_interviews", + "value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL3RvcGNvZGVyLWRldi5hdXRoMC5jb20vIiwic3ViIjoiZW5qdzE4MTBlRHozWFR3U08yUm4yWTljUVRyc3BuM0JAY2xpZW50cyIsImF1ZCI6Imh0dHBzOi8vbTJtLnRvcGNvZGVyLWRldi5jb20vIiwiaWF0IjoxNTUwOTA2Mzg4LCJleHAiOjIxNDc0ODM2NDgsImF6cCI6ImVuancxODEwZUR6M1hUd1NPMlJuMlk5Y1FUcnNwbjNCIiwic2NvcGUiOiJ1cGRhdGU6dGFhcy1pbnRlcnZpZXdzIiwiZ3R5IjoiY2xpZW50LWNyZWRlbnRpYWxzIn0.qGPZrHL9ybzQEq_KlOMM6VfIPJttTVGa7KpVLNDdMHI", + "enabled": true + }, + { + "key": "token_m2m_read_jobCandidate_read_interviews", + "value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL3RvcGNvZGVyLWRldi5hdXRoMC5jb20vIiwic3ViIjoiZW5qdzE4MTBlRHozWFR3U08yUm4yWTljUVRyc3BuM0JAY2xpZW50cyIsImF1ZCI6Imh0dHBzOi8vbTJtLnRvcGNvZGVyLWRldi5jb20vIiwiaWF0IjoxNTUwOTA2Mzg4LCJleHAiOjIxNDc0ODM2NDgsImF6cCI6ImVuancxODEwZUR6M1hUd1NPMlJuMlk5Y1FUcnNwbjNCIiwic2NvcGUiOiJyZWFkOnRhYXMtam9iQ2FuZGlkYXRlcyByZWFkOnRhYXMtaW50ZXJ2aWV3cyIsImd0eSI6ImNsaWVudC1jcmVkZW50aWFscyJ9._HP8XEoY8eLQRK7K0jgqVPvTGrMS6OwutDU-nCPdopE", + "enabled": true + }, + { + "key": "token_m2m_read_jobCandidates_all_interviews", + "value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL3RvcGNvZGVyLWRldi5hdXRoMC5jb20vIiwic3ViIjoiZW5qdzE4MTBlRHozWFR3U08yUm4yWTljUVRyc3BuM0JAY2xpZW50cyIsImF1ZCI6Imh0dHBzOi8vbTJtLnRvcGNvZGVyLWRldi5jb20vIiwiaWF0IjoxNTUwOTA2Mzg4LCJleHAiOjIxNDc0ODM2NDgsImF6cCI6ImVuancxODEwZUR6M1hUd1NPMlJuMlk5Y1FUcnNwbjNCIiwic2NvcGUiOiJyZWFkOnRhYXMtam9iQ2FuZGlkYXRlcyBhbGw6dGFhcy1pbnRlcnZpZXdzIiwiZ3R5IjoiY2xpZW50LWNyZWRlbnRpYWxzIn0.XQj74JSHp98XKxa1eZnMMpHxGpHeZAHVhLvFAN7gHBY", + "enabled": true } ], "_postman_variable_scope": "environment", - "_postman_exported_at": "2021-04-09T20:23:10.418Z", - "_postman_exported_using": "Postman/8.2.1" + "_postman_exported_at": "2021-04-22T11:06:21.725Z", + "_postman_exported_using": "Postman/8.2.3" } \ No newline at end of file diff --git a/local/kafka-client/topics.txt b/local/kafka-client/topics.txt index dc37db59..8766a1b5 100644 --- a/local/kafka-client/topics.txt +++ b/local/kafka-client/topics.txt @@ -13,4 +13,7 @@ taas.jobcandidate.delete taas.resourcebooking.delete taas.workperiod.delete taas.workperiodpayment.delete +taas.interview.requested +taas.interview.update +taas.interview.bulkUpdate external.action.email diff --git a/migrations/2021-04-12-create-interviews-table.js b/migrations/2021-04-12-create-interviews-table.js new file mode 100644 index 00000000..53eaab1a --- /dev/null +++ b/migrations/2021-04-12-create-interviews-table.js @@ -0,0 +1,102 @@ +'use strict'; + +const config = require('config') +const _ = require('lodash') +const { Interviews } = require('../app-constants') + +// allowed status values +const statuses = _.values(Interviews.Status) + +/** + * Create `interviews` table & relations. + */ +module.exports = { + up: async (queryInterface, Sequelize) => { + const table = { schema: config.DB_SCHEMA_NAME, tableName: 'interviews' } + await queryInterface.createTable(table, { + id: { + type: Sequelize.UUID, + primaryKey: true, + allowNull: false, + defaultValue: Sequelize.UUIDV4 + }, + jobCandidateId: { + field: 'job_candidate_id', + type: Sequelize.UUID, + allowNull: false, + references: { + model: { + tableName: 'job_candidates', + schema: config.DB_SCHEMA_NAME + }, + key: 'id' + } + }, + googleCalendarId: { + field: 'google_calendar_id', + type: Sequelize.STRING(255) + }, + customMessage: { + field: 'custom_message', + type: Sequelize.TEXT + }, + xaiTemplate: { + field: 'xai_template', + type: Sequelize.STRING(255), + allowNull: false + }, + round: { + type: Sequelize.INTEGER, + allowNull: false + }, + startTimestamp: { + field: 'start_timestamp', + type: Sequelize.DATE + }, + attendeesList: { + field: 'attendees_list', + type: Sequelize.ARRAY(Sequelize.STRING) + }, + status: { + type: Sequelize.ENUM(statuses), + allowNull: false + }, + createdBy: { + field: 'created_by', + type: Sequelize.UUID, + allowNull: false + }, + updatedBy: { + field: 'updated_by', + type: Sequelize.UUID + }, + createdAt: { + field: 'created_at', + type: Sequelize.DATE + }, + updatedAt: { + field: 'updated_at', + type: Sequelize.DATE + }, + deletedAt: { + field: 'deleted_at', + type: Sequelize.DATE + } + }, { schema: config.DB_SCHEMA_NAME }) + }, + + down: async (queryInterface, Sequelize) => { + const table = { schema: config.DB_SCHEMA_NAME, tableName: 'interviews' } + const statusTypeName = `${table.schema}.enum_${table.tableName}_status` + const transaction = await queryInterface.sequelize.transaction() + try { + await queryInterface.dropTable(table, { transaction }) + // drop enum type for status column + await queryInterface.sequelize.query(`DROP TYPE ${statusTypeName}`, { transaction }) + await transaction.commit() + } catch (err) { + await transaction.rollback() + throw err + } + } +}; diff --git a/migrations/2021-04-27-172352-resource-booking-placed-status-migration.js b/migrations/2021-04-27-172352-resource-booking-placed-status-migration.js new file mode 100644 index 00000000..70ae3c6c --- /dev/null +++ b/migrations/2021-04-27-172352-resource-booking-placed-status-migration.js @@ -0,0 +1,18 @@ +'use strict'; + +const config = require('config') + +/** + * Migrate ResourceBooking status - from assigned to placed. + */ +module.exports = { + up: async (queryInterface, Sequelize) => { + const tableName = `${config.DB_SCHEMA_NAME}.resource_bookings` + await queryInterface.sequelize.query(`UPDATE ${tableName} SET status = 'placed' WHERE status = 'assigned'`) + }, + + down: async (queryInterface, Sequelize) => { + const tableName = `${config.DB_SCHEMA_NAME}.resource_bookings` + await queryInterface.sequelize.query(`UPDATE ${tableName} SET status = 'assigned' WHERE status = 'placed'`) + } +}; diff --git a/migrations/2021-04-27-172407-job-candidate-placed-status-migration.js b/migrations/2021-04-27-172407-job-candidate-placed-status-migration.js new file mode 100644 index 00000000..611184ee --- /dev/null +++ b/migrations/2021-04-27-172407-job-candidate-placed-status-migration.js @@ -0,0 +1,18 @@ +'use strict'; + +const config = require('config') + +/** + * Migrate JobCandidate status - from selected to placed. + */ +module.exports = { + up: async (queryInterface, Sequelize) => { + const tableName = `${config.DB_SCHEMA_NAME}.job_candidates` + await queryInterface.sequelize.query(`UPDATE ${tableName} SET status = 'placed' WHERE status = 'selected'`) + }, + + down: async (queryInterface, Sequelize) => { + const tableName = `${config.DB_SCHEMA_NAME}.job_candidates` + await queryInterface.sequelize.query(`UPDATE ${tableName} SET status = 'selected' WHERE status = 'placed'`) + } +}; diff --git a/migrations/2021-04-27-172422-job-candidate-selected-status-migration.js b/migrations/2021-04-27-172422-job-candidate-selected-status-migration.js new file mode 100644 index 00000000..2959e798 --- /dev/null +++ b/migrations/2021-04-27-172422-job-candidate-selected-status-migration.js @@ -0,0 +1,18 @@ +'use strict'; + +const config = require('config') + +/** + * Migrate JobCandidate status - from shortlist to selected. + */ +module.exports = { + up: async (queryInterface, Sequelize) => { + const tableName = `${config.DB_SCHEMA_NAME}.job_candidates` + await queryInterface.sequelize.query(`UPDATE ${tableName} SET status = 'interview' WHERE status = 'shortlist'`) + }, + + down: async (queryInterface, Sequelize) => { + const tableName = `${config.DB_SCHEMA_NAME}.job_candidates` + await queryInterface.sequelize.query(`UPDATE ${tableName} SET status = 'shortlist' WHERE status = 'interview'`) + } +}; diff --git a/migrations/2021-04-27-172437-job-candidate-rejected-other-status-migration.js b/migrations/2021-04-27-172437-job-candidate-rejected-other-status-migration.js new file mode 100644 index 00000000..9e8a2480 --- /dev/null +++ b/migrations/2021-04-27-172437-job-candidate-rejected-other-status-migration.js @@ -0,0 +1,22 @@ +'use strict'; + +const config = require('config') + +/** + * Migrate JobCandidate status - from rejected to rejected - other. + */ +module.exports = { + up: async (queryInterface, Sequelize) => { + const tableName = `${config.DB_SCHEMA_NAME}.job_candidates` + await queryInterface.sequelize.query( + `UPDATE ${tableName} SET status = 'rejected - other' WHERE status = 'rejected'` + ) + }, + + down: async (queryInterface, Sequelize) => { + const tableName = `${config.DB_SCHEMA_NAME}.job_candidates` + await queryInterface.sequelize.query( + `UPDATE ${tableName} SET status = 'rejected' WHERE status = 'rejected - other'` + ) + } +}; diff --git a/package-lock.json b/package-lock.json index 50293037..76b17135 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1500,6 +1500,15 @@ "write-file-atomic": "^3.0.0" } }, + "call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "requires": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + } + }, "callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -1891,6 +1900,15 @@ "vary": "^1" } }, + "cron-parser": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/cron-parser/-/cron-parser-3.3.0.tgz", + "integrity": "sha512-Tz5WxSrDVhR7YVuLuUxhXoMGHCWoe8I7g8APkyRZNaINXHQ3zcfK97av6hBYy9ue4sOLI7ZH7SeQqi/t4jR+5A==", + "requires": { + "is-nan": "^1.3.0", + "luxon": "^1.25.0" + } + }, "cross-spawn": { "version": "6.0.5", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", @@ -3098,6 +3116,16 @@ "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", "dev": true }, + "get-intrinsic": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", + "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "requires": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1" + } + }, "get-package-type": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", @@ -3201,25 +3229,6 @@ "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", "dev": true }, - "handlebars": { - "version": "4.7.6", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.6.tgz", - "integrity": "sha512-1f2BACcBfiwAfStCKZNrUCgqNZkGsAT7UM3kkYtXuLo0KnaVfjKOyf7PRzB6++aK9STyT1Pd2ZCPe3EGOXleXA==", - "requires": { - "minimist": "^1.2.5", - "neo-async": "^2.6.0", - "source-map": "^0.6.1", - "uglify-js": "^3.1.4", - "wordwrap": "^1.0.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, "har-schema": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", @@ -3693,6 +3702,15 @@ "integrity": "sha512-T/S49scO8plUiAOA2DBTBG3JHpn1yiw0kRp6dgiZ0v2/6twi5eiB0rHtHFH9ZIrvlWc6+4O+m4zg5+Z833aXgw==", "dev": true }, + "is-nan": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/is-nan/-/is-nan-1.3.2.tgz", + "integrity": "sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==", + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3" + } + }, "is-negative-zero": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.0.tgz", @@ -4567,6 +4585,11 @@ } } }, + "long-timeout": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/long-timeout/-/long-timeout-0.1.1.tgz", + "integrity": "sha1-lyHXiLR+C8taJMLivuGg2lXatRQ=" + }, "loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -4609,6 +4632,11 @@ "es5-ext": "~0.10.2" } }, + "luxon": { + "version": "1.26.0", + "resolved": "https://registry.npmjs.org/luxon/-/luxon-1.26.0.tgz", + "integrity": "sha512-+V5QIQ5f6CDXQpWNICELwjwuHdqeJM1UenlZWx5ujcRMc9venvluCjFb4t5NYLhb6IhkbMVOxzVuOqkgMxee2A==" + }, "make-dir": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", @@ -4963,11 +4991,6 @@ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" }, - "neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" - }, "next-tick": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", @@ -5018,6 +5041,16 @@ "process-on-spawn": "^1.0.0" } }, + "node-schedule": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/node-schedule/-/node-schedule-2.0.0.tgz", + "integrity": "sha512-cHc9KEcfiuXxYDU+HjsBVo2FkWL1jRAUoczFoMIzRBpOA4p/NRHuuLs85AWOLgKsHtSPjN8csvwIxc2SqMv+CQ==", + "requires": { + "cron-parser": "^3.1.0", + "long-timeout": "0.1.1", + "sorted-array-functions": "^1.3.0" + } + }, "nodemon": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.4.tgz", @@ -6773,6 +6806,11 @@ } } }, + "sorted-array-functions": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/sorted-array-functions/-/sorted-array-functions-1.3.0.tgz", + "integrity": "sha512-2sqgzeFlid6N4Z2fUQ1cvFmTOLRi/sEDzSQ0OKYchqgoPmQBVyM3959qYx3fpS6Esef80KjmpgPeEr028dP3OA==" + }, "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", @@ -7411,12 +7449,6 @@ "is-typedarray": "^1.0.0" } }, - "uglify-js": { - "version": "3.12.8", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.12.8.tgz", - "integrity": "sha512-fvBeuXOsvqjecUtF/l1dwsrrf5y2BCUk9AOJGzGcm6tE7vegku5u/YvqjyDaAGr422PLoLnrxg3EnRvTqsdC1w==", - "optional": true - }, "umzug": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/umzug/-/umzug-2.3.0.tgz", @@ -7814,11 +7846,6 @@ "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==" }, - "wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=" - }, "workerpool": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.0.0.tgz", diff --git a/package.json b/package.json index fac8d7fc..00d15b73 100644 --- a/package.json +++ b/package.json @@ -45,11 +45,11 @@ "express": "^4.17.1", "express-interceptor": "^1.2.0", "get-parameter-names": "^0.3.0", - "handlebars": "^4.7.6", "http-status": "^1.4.2", "http-status-codes": "^2.1.4", "joi": "^17.2.1", "lodash": "^4.17.20", + "node-schedule": "^2.0.0", "pg": "^8.4.0", "pg-hstore": "^2.3.3", "prompt-confirm": "^2.0.4", diff --git a/scripts/data/exportData.js b/scripts/data/exportData.js index 30529aa7..356fcfc6 100644 --- a/scripts/data/exportData.js +++ b/scripts/data/exportData.js @@ -2,12 +2,29 @@ * Export data to a json file */ const config = require('config') +const { Interview, WorkPeriodPayment } = require('../../src/models') const logger = require('../../src/common/logger') const helper = require('../../src/common/helper') +const jobCandidateModelOpts = { + modelName: 'JobCandidate', + include: [{ + model: Interview, + as: 'interviews' + }] +} + +const workPeriodModelOpts = { + modelName: 'WorkPeriod', + include: [{ + model: WorkPeriodPayment, + as: 'payments' + }] +} + const filePath = helper.getParamFromCliArgs() || config.DEFAULT_DATA_FILE_PATH const userPrompt = `WARNING: are you sure you want to export all data in the database to a json file with the path ${filePath}? This will overwrite the file.` -const dataModels = ['Job', 'JobCandidate', 'ResourceBooking', 'WorkPeriod', 'WorkPeriodPayment'] +const dataModels = ['Job', jobCandidateModelOpts, 'ResourceBooking', workPeriodModelOpts] async function exportData () { await helper.promptUser(userPrompt, async () => { diff --git a/scripts/data/importData.js b/scripts/data/importData.js index e4daa58d..52b3feb8 100644 --- a/scripts/data/importData.js +++ b/scripts/data/importData.js @@ -2,12 +2,29 @@ * Import data from a json file into the db and index it in Elasticsearch */ const config = require('config') +const { Interview, WorkPeriodPayment } = require('../../src/models') const logger = require('../../src/common/logger') const helper = require('../../src/common/helper') +const jobCandidateModelOpts = { + modelName: 'JobCandidate', + include: [{ + model: Interview, + as: 'interviews' + }] +} + +const workPeriodModelOpts = { + modelName: 'WorkPeriod', + include: [{ + model: WorkPeriodPayment, + as: 'payments' + }] +} + const filePath = helper.getParamFromCliArgs() || config.DEFAULT_DATA_FILE_PATH const userPrompt = `WARNING: this would remove existing data. Are you sure you want to import data from a json file with the path ${filePath}?` -const dataModels = ['Job', 'JobCandidate', 'ResourceBooking', 'WorkPeriod', 'WorkPeriodPayment'] +const dataModels = ['Job', jobCandidateModelOpts, 'ResourceBooking', workPeriodModelOpts] async function importData () { await helper.promptUser(userPrompt, async () => { diff --git a/scripts/es/reIndexAll.js b/scripts/es/reIndexAll.js index 215efaa2..6a7bdf3f 100644 --- a/scripts/es/reIndexAll.js +++ b/scripts/es/reIndexAll.js @@ -2,18 +2,35 @@ * Reindex all data in Elasticsearch using data from database */ const config = require('config') +const { Interview, WorkPeriodPayment } = require('../../src/models') const logger = require('../../src/common/logger') const helper = require('../../src/common/helper') const userPrompt = 'WARNING: this would remove existent data! Are you sure want to reindex all indices?' +const jobCandidateModelOpts = { + modelName: 'JobCandidate', + include: [{ + model: Interview, + as: 'interviews' + }] +} + +const workPeriodModelOpts = { + modelName: 'JobCandidate', + include: [{ + model: WorkPeriodPayment, + as: 'payments' + }] +} + async function indexAll () { await helper.promptUser(userPrompt, async () => { try { await helper.indexBulkDataToES('Job', config.get('esConfig.ES_INDEX_JOB'), logger) - await helper.indexBulkDataToES('JobCandidate', config.get('esConfig.ES_INDEX_JOB_CANDIDATE'), logger) + await helper.indexBulkDataToES(jobCandidateModelOpts, config.get('esConfig.ES_INDEX_JOB_CANDIDATE'), logger) await helper.indexBulkDataToES('ResourceBooking', config.get('esConfig.ES_INDEX_RESOURCE_BOOKING'), logger) - await helper.indexBulkDataToES('WorkPeriod', config.get('esConfig.ES_INDEX_WORK_PERIOD'), logger) + await helper.indexBulkDataToES(workPeriodModelOpts, config.get('esConfig.ES_INDEX_WORK_PERIOD'), logger) process.exit(0) } catch (err) { logger.logFullError(err, { component: 'indexAll' }) diff --git a/scripts/es/reIndexJobCandidates.js b/scripts/es/reIndexJobCandidates.js index 7e0aec22..585416a5 100644 --- a/scripts/es/reIndexJobCandidates.js +++ b/scripts/es/reIndexJobCandidates.js @@ -2,6 +2,7 @@ * Reindex JobCandidates data in Elasticsearch using data from database */ const config = require('config') +const { Interview } = require('../../src/models') const logger = require('../../src/common/logger') const helper = require('../../src/common/helper') @@ -10,11 +11,19 @@ const index = config.get('esConfig.ES_INDEX_JOB_CANDIDATE') const reIndexAllJobCandidatesPrompt = `WARNING: this would remove existent data! Are you sure you want to reindex the index ${index}?` const reIndexJobCandidatePrompt = `WARNING: this would remove existent data! Are you sure you want to reindex the document with id ${jobCandidateId} in index ${index}?` +const jobCandidateModelOpts = { + modelName: 'JobCandidate', + include: [{ + model: Interview, + as: 'interviews' + }] +} + async function reIndexJobCandidates () { if (jobCandidateId === null) { await helper.promptUser(reIndexAllJobCandidatesPrompt, async () => { try { - await helper.indexBulkDataToES('JobCandidate', index, logger) + await helper.indexBulkDataToES(jobCandidateModelOpts, index, logger) process.exit(0) } catch (err) { logger.logFullError(err, { component: 'reIndexJobCandidates' }) @@ -24,7 +33,7 @@ async function reIndexJobCandidates () { } else { await helper.promptUser(reIndexJobCandidatePrompt, async () => { try { - await helper.indexDataToEsById(jobCandidateId, 'JobCandidate', index, logger) + await helper.indexDataToEsById(jobCandidateId, jobCandidateModelOpts, index, logger) process.exit(0) } catch (err) { logger.logFullError(err, { component: 'reIndexJobCandidates' }) diff --git a/scripts/es/reIndexWorkPeriods.js b/scripts/es/reIndexWorkPeriods.js index a759d6c1..a6f30737 100644 --- a/scripts/es/reIndexWorkPeriods.js +++ b/scripts/es/reIndexWorkPeriods.js @@ -2,6 +2,7 @@ * Reindex WorkPeriods data in Elasticsearch using data from database */ const config = require('config') +const { WorkPeriodPayment } = require('../../src/models') const logger = require('../../src/common/logger') const helper = require('../../src/common/helper') @@ -10,11 +11,19 @@ const index = config.get('esConfig.ES_INDEX_WORK_PERIOD') const reIndexAllWorkPeriodsPrompt = `WARNING: this would remove existent data! Are you sure you want to reindex the index ${index}` const reIndexWorkPeriodPrompt = `WARNING: this would remove existent data! Are you sure you want to reindex the document with id ${workPeriodId} in index ${index}?` +const workPeriodModelOpts = { + modelName: 'WorkPeriod', + include: [{ + model: WorkPeriodPayment, + as: 'payments' + }] +} + async function reIndexWorkPeriods () { if (workPeriodId === null) { await helper.promptUser(reIndexAllWorkPeriodsPrompt, async () => { try { - await helper.indexBulkDataToES('WorkPeriod', index, logger) + await helper.indexBulkDataToES(workPeriodModelOpts, index, logger) process.exit(0) } catch (err) { logger.logFullError(err, { component: 'reIndexWorkPeriods' }) @@ -24,7 +33,7 @@ async function reIndexWorkPeriods () { } else { await helper.promptUser(reIndexWorkPeriodPrompt, async () => { try { - await helper.indexDataToEsById(workPeriodId, 'WorkPeriod', index, logger) + await helper.indexDataToEsById(workPeriodId, workPeriodModelOpts, index, logger) process.exit(0) } catch (err) { logger.logFullError(err, { component: 'reIndexWorkPeriods' }) diff --git a/scripts/recruit-crm-job-import/index.js b/scripts/recruit-crm-job-import/index.js index c82254ab..596ab680 100644 --- a/scripts/recruit-crm-job-import/index.js +++ b/scripts/recruit-crm-job-import/index.js @@ -89,7 +89,7 @@ async function processJob (job, info = []) { data.resourceBookingId = result.id } // update the resourceBooking based on startDate and endDate - const resourceBookingStatus = dateFNS.isBefore(data.endDate, dateFNS.startOfToday()) ? 'closed' : 'assigned' + const resourceBookingStatus = dateFNS.isBefore(data.endDate, dateFNS.startOfToday()) ? 'closed' : 'placed' logger.debug(`resourceBookingId: ${data.resourceBookingId} status: ${resourceBookingStatus}`) await helper.updateResourceBookingStatus(data.resourceBookingId, resourceBookingStatus) info.push({ text: `id: ${data.resourceBookingId} status: ${resourceBookingStatus} resource booking updated`, tag: 'resource_booking_status_updated' }) diff --git a/src/bootstrap.js b/src/bootstrap.js index bc5b0b47..6a364e8a 100644 --- a/src/bootstrap.js +++ b/src/bootstrap.js @@ -1,19 +1,26 @@ const fs = require('fs') const Joi = require('joi') const path = require('path') +const _ = require('lodash') +const { Interviews } = require('../app-constants') const logger = require('./common/logger') const constants = require('../app-constants') const config = require('config') +const allowedInterviewStatuses = _.values(Interviews.Status) +const allowedXAITemplate = _.keys(Interviews.XaiTemplate) + Joi.page = () => Joi.number().integer().min(1).default(1) Joi.perPage = () => Joi.number().integer().min(1).default(20) Joi.rateType = () => Joi.string().valid('hourly', 'daily', 'weekly', 'monthly') Joi.jobStatus = () => Joi.string().valid('sourcing', 'in-review', 'assigned', 'closed', 'cancelled') -Joi.resourceBookingStatus = () => Joi.string().valid('assigned', 'closed', 'cancelled') +Joi.resourceBookingStatus = () => Joi.string().valid('placed', 'closed', 'cancelled') Joi.workload = () => Joi.string().valid('full-time', 'fractional') -Joi.jobCandidateStatus = () => Joi.string().valid('open', 'selected', 'shortlist', 'rejected', 'cancelled', 'interview', 'topcoder-rejected') +Joi.jobCandidateStatus = () => Joi.string().valid('open', 'placed', 'selected', 'client rejected - screening', 'client rejected - interview', 'rejected - other', 'cancelled', 'interview', 'topcoder-rejected') Joi.title = () => Joi.string().max(128) Joi.paymentStatus = () => Joi.string().valid('pending', 'partially-completed', 'completed', 'cancelled') +Joi.xaiTemplate = () => Joi.string().valid(...allowedXAITemplate) +Joi.interviewStatus = () => Joi.string().valid(...allowedInterviewStatuses) Joi.workPeriodPaymentStatus = () => Joi.string().valid('completed', 'cancelled') // Empty string is not allowed by Joi by default and must be enabled with allow(''). // See https://joi.dev/api/?v=17.3.0#string fro details why it's like this. diff --git a/src/common/helper.js b/src/common/helper.js index c081467c..26caf51b 100644 --- a/src/common/helper.js +++ b/src/common/helper.js @@ -12,6 +12,7 @@ const HttpStatus = require('http-status-codes') const _ = require('lodash') const request = require('superagent') const elasticsearch = require('@elastic/elasticsearch') +const { ResponseError: ESResponseError } = require('@elastic/elasticsearch/lib/errors') const errors = require('../common/errors') const logger = require('./logger') const models = require('../models') @@ -83,6 +84,24 @@ esIndexPropertyMapping[config.get('esConfig.ES_INDEX_JOB_CANDIDATE')] = { status: { type: 'keyword' }, externalId: { type: 'keyword' }, resume: { type: 'text' }, + interviews: { + type: 'nested', + properties: { + id: { type: 'keyword' }, + jobCandidateId: { type: 'keyword' }, + googleCalendarId: { type: 'keyword' }, + customMessage: { type: 'text' }, + xaiTemplate: { type: 'keyword' }, + startTimestamp: { type: 'date' }, + attendeesList: [], + round: { type: 'integer' }, + status: { type: 'keyword' }, + createdAt: { type: 'date' }, + createdBy: { type: 'keyword' }, + updatedAt: { type: 'date' }, + updatedBy: { type: 'keyword' } + } + }, createdAt: { type: 'date' }, createdBy: { type: 'keyword' }, updatedAt: { type: 'date' }, @@ -248,11 +267,14 @@ function getBulksFromDocuments (data) { /** * Index records in bulk -* @param {Object} modelName the model name in db +* @param {Object | String} modelOpts the model name in db, or model options * @param {Object} indexName the index name * @param {Object} logger the logger object */ -async function indexBulkDataToES (modelName, indexName, logger) { +async function indexBulkDataToES (modelOpts, indexName, logger) { + const modelName = _.isString(modelOpts) ? modelOpts : modelOpts.modelName + const include = _.get(modelOpts, 'include', []) + logger.info({ component: 'indexBulkDataToES', message: `Reindexing of ${modelName}s started!` }) const esClient = getESClient() @@ -267,23 +289,13 @@ async function indexBulkDataToES (modelName, indexName, logger) { // get data from db logger.info({ component: 'indexBulkDataToES', message: 'Getting data from database' }) const model = models[modelName] - const criteria = { - raw: true - } - if (modelName === 'WorkPeriod') { - criteria.raw = false - criteria.include = [{ - model: models.WorkPeriodPayment, - as: 'payments', - required: false - }] - } - const data = await model.findAll(criteria) - if (_.isEmpty(data)) { + const data = await model.findAll({ include }) + const rawObjects = _.map(data, r => r.toJSON()) + if (_.isEmpty(rawObjects)) { logger.info({ component: 'indexBulkDataToES', message: `No data in database for ${modelName}` }) return } - const bulks = getBulksFromDocuments(data) + const bulks = getBulksFromDocuments(rawObjects) const startTime = Date.now() let doneCount = 0 @@ -307,19 +319,22 @@ async function indexBulkDataToES (modelName, indexName, logger) { /** * Index job by id - * @param {Object} modelName the model name in db + * @param {Object | String} modelOpts the model name in db, or model options * @param {Object} indexName the index name * @param {string} id the job id * @param {Object} logger the logger object */ -async function indexDataToEsById (id, modelName, indexName, logger) { +async function indexDataToEsById (id, modelOpts, indexName, logger) { + const modelName = _.isString(modelOpts) ? modelOpts : modelOpts.modelName + const include = _.get(modelOpts, 'include', []) + logger.info({ component: 'indexDataToEsById', message: `Reindexing of ${modelName} with id ${id} started!` }) const esClient = getESClient() logger.info({ component: 'indexDataToEsById', message: 'Getting data from database' }) const model = models[modelName] - const data = await model.findById(id, modelName === 'WorkPeriod') + const data = await model.findById(id, include) logger.info({ component: 'indexDataToEsById', message: 'Indexing data into Elasticsearch' }) await esClient.index({ index: indexName, @@ -353,7 +368,10 @@ async function importData (pathToFile, dataModels, logger) { const jsonData = JSON.parse(fs.readFileSync(pathToFile).toString()) for (let index = 0; index < dataModels.length; index += 1) { - const modelName = dataModels[index] + const modelOpts = dataModels[index] + const modelName = _.isString(modelOpts) ? modelOpts : modelOpts.modelName + const include = _.get(modelOpts, 'include', []) + currentModelName = modelName const model = models[modelName] const modelRecords = jsonData[modelName] @@ -361,7 +379,7 @@ async function importData (pathToFile, dataModels, logger) { if (modelRecords && modelRecords.length > 0) { logger.info({ component: 'importData', message: `Importing data for model: ${modelName}` }) - await model.bulkCreate(modelRecords, { transaction }) + await model.bulkCreate(modelRecords, { include, transaction }) logger.info({ component: 'importData', message: `Records imported for model: ${modelName} = ${modelRecords.length}` }) } else { logger.info({ component: 'importData', message: `No records to import for model: ${modelName}` }) @@ -394,10 +412,24 @@ async function importData (pathToFile, dataModels, logger) { } // after importing, index data + const jobCandidateModelOpts = { + modelName: 'JobCandidate', + include: [{ + model: models.Interview, + as: 'interviews' + }] + } + const workPeriodModelOpts = { + modelName: 'WorkPeriod', + include: [{ + model: models.WorkPeriodPayment, + as: 'payments' + }] + } await indexBulkDataToES('Job', config.get('esConfig.ES_INDEX_JOB'), logger) - await indexBulkDataToES('JobCandidate', config.get('esConfig.ES_INDEX_JOB_CANDIDATE'), logger) + await indexBulkDataToES(jobCandidateModelOpts, config.get('esConfig.ES_INDEX_JOB_CANDIDATE'), logger) await indexBulkDataToES('ResourceBooking', config.get('esConfig.ES_INDEX_RESOURCE_BOOKING'), logger) - await indexBulkDataToES('WorkPeriod', config.get('esConfig.ES_INDEX_WORK_PERIOD'), logger) + await indexBulkDataToES(workPeriodModelOpts, config.get('esConfig.ES_INDEX_WORK_PERIOD'), logger) } /** @@ -411,12 +443,13 @@ async function exportData (pathToFile, dataModels, logger) { const allModelsRecords = {} for (let index = 0; index < dataModels.length; index += 1) { - const modelName = dataModels[index] - const modelRecords = await models[modelName].findAll({ - raw: true - }) - allModelsRecords[modelName] = modelRecords - logger.info({ component: 'exportData', message: `Records loaded for model: ${modelName} = ${modelRecords.length}` }) + const modelOpts = dataModels[index] + const modelName = _.isString(modelOpts) ? modelOpts : modelOpts.modelName + const include = _.get(modelOpts, 'include', []) + const modelRecords = await models[modelName].findAll({ include }) + const rawRecords = _.map(modelRecords, r => r.toJSON()) + allModelsRecords[modelName] = rawRecords + logger.info({ component: 'exportData', message: `Records loaded for model: ${modelName} = ${rawRecords.length}` }) } fs.writeFileSync(pathToFile, JSON.stringify(allModelsRecords)) @@ -646,6 +679,11 @@ function encodeQueryString (queryObj, nesting = '') { * @returns {Array} the users found */ async function listUsersByExternalId (externalId) { + // return empty list if externalId is null or undefined + if (!!externalId !== true) { + return [] + } + const token = await getM2MUbahnToken() const q = { enrich: true, @@ -704,7 +742,7 @@ async function postEvent (topic, payload, options = {}) { * @returns {Boolean} the result */ function isDocumentMissingException (err) { - if (err.statusCode === 404) { + if (err.statusCode === 404 && err instanceof ESResponseError) { return true } return false @@ -782,6 +820,8 @@ async function getUserById (userId, enrich) { if (enrich) { user.skills = (res.body.skills || []).map((skillObj) => _.pick(skillObj.skill, ['id', 'name'])) + const attributes = _.get(res, 'body.attributes', []) + user.attributes = _.map(attributes, attr => _.pick(attr, ['id', 'value', 'attribute.id', 'attribute.name'])) } return user @@ -1069,7 +1109,7 @@ async function _getMemberDetailsByEmail (token, email) { .get(config.TOPCODER_USERS_API) .query({ filter: `email=${email}`, - fields: 'handle,id,email' + fields: 'handle,id,email,firstName,lastName' }) .set('Authorization', `Bearer ${token}`) .set('Accept', 'application/json') @@ -1180,6 +1220,18 @@ async function deleteProjectMember (currentUser, projectId, projectMemberId) { } } +/** + * Gets requested attribute value from user's attributes array. + * @param {Object} user The enriched (i.e. includes attributes) user object from users API. (check getUserById, getUserByExternalId functions) + * @param {String} attributeName Requested attribute name, e.g. "email" + * @returns attribute value + */ +function getUserAttributeValue (user, attributeName) { + const attributes = _.get(user, 'attributes', []) + const targetAttribute = _.find(attributes, a => a.attribute.name === attributeName) + return _.get(targetAttribute, 'value') +} + /** * Create a new challenge * @@ -1298,6 +1350,40 @@ function extractWorkPeriods (start, end) { return periods } +/** + * Returns the email address of specified (via handle) user. + * + * @param {String} userHandle user handle + * @returns {String} email address of the user + */ +async function getUserByHandle (userHandle) { + const token = await getM2MToken() + const url = `${config.TC_API}/members/${userHandle}` + const res = await request + .get(url) + .set('Authorization', `Bearer ${token}`) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json') + localLogger.debug({ context: 'getUserByHandle', message: `response body: ${JSON.stringify(res.body)}` }) + return _.get(res, 'body') +} + +/** + * + * @param {String} string that will be modifed + * @param {*} object of json that would be replaced in string + * @returns + */ +async function substituteStringByObject (string, object) { + for (var key in object) { + if (!object.hasOwnProperty(key)) { + continue; + } + string = string.replace(new RegExp("{{" + key + "}}", "g"), object[key]); + } + return string +} + module.exports = { getParamFromCliArgs, promptUser, @@ -1342,8 +1428,11 @@ module.exports = { listProjectMembers, listProjectMemberInvites, deleteProjectMember, + getUserAttributeValue, createChallenge, updateChallenge, createChallengeResource, - extractWorkPeriods + extractWorkPeriods, + getUserByHandle, + substituteStringByObject } diff --git a/src/controllers/InterviewController.js b/src/controllers/InterviewController.js new file mode 100644 index 00000000..d9ae8e44 --- /dev/null +++ b/src/controllers/InterviewController.js @@ -0,0 +1,52 @@ +/** + * Controller for Interview endpoints + */ +const service = require('../services/InterviewService') +const helper = require('../common/helper') + +/** + * Get interview by round + * @param req the request + * @param res the response + */ +async function getInterviewByRound (req, res) { + const { jobCandidateId, round } = req.params + res.send(await service.getInterviewByRound(req.authUser, jobCandidateId, round, req.query.fromDb)) +} + +/** + * Request interview + * @param req the request + * @param res the response + */ +async function requestInterview (req, res) { + res.send(await service.requestInterview(req.authUser, req.params.jobCandidateId, req.body)) +} + +/** + * Patch (partially update) interview + * @param req the request + * @param res the response + */ +async function partiallyUpdateInterview (req, res) { + const { jobCandidateId, round } = req.params + res.send(await service.partiallyUpdateInterview(req.authUser, jobCandidateId, round, req.body)) +} + +/** + * Search interviews + * @param req the request + * @param res the response + */ +async function searchInterviews (req, res) { + const result = await service.searchInterviews(req.authUser, req.params.jobCandidateId, req.query) + helper.setResHeaders(req, res, result) + res.send(result.result) +} + +module.exports = { + getInterviewByRound, + requestInterview, + partiallyUpdateInterview, + searchInterviews +} diff --git a/src/eventHandlers/InterviewEventHandler.js b/src/eventHandlers/InterviewEventHandler.js new file mode 100644 index 00000000..11d118b4 --- /dev/null +++ b/src/eventHandlers/InterviewEventHandler.js @@ -0,0 +1,59 @@ +/* + * Handle events for Interview. + */ + +const models = require('../models') +// const logger = require('../common/logger') +const helper = require('../common/helper') +const { Interviews } = require('../../app-constants') +const teamService = require('../services/TeamService') +const _ = require('lodash') + +/** + * Once we request Interview for a JobCandidate, the invitation emails to be sent out. + * + * @param {Object} payload the event payload + * @returns {undefined} + */ +async function sendInvitationEmail (payload) { + const interview = payload.value + // get the Interviewer + const interviewerUsers = await helper.getMemberDetailsByEmails(interview.attendeesList) + .then((members) => _.map(members, (member) => ({ ...member, emailLowerCase: member.email.toLowerCase() }))) + // get job candidate user details + const jobCandidate = await models.JobCandidate.findById(interview.jobCandidateId) + const jobCandidateUser = await helper.getUserById(jobCandidate.userId) + const jobCandidateMember = await helper.getUserByHandle(jobCandidateUser.handle) + // get customer details + const job = await jobCandidate.getJob() + + teamService.sendEmail({}, { + template: 'interview-invitation', + cc: [jobCandidateMember.email, ...interview.attendeesList], + data: { + job_candidate_id: interview.jobCandidateId, + interview_round: interview.round, + interviewee_name: `${jobCandidateMember.firstName} ${jobCandidateMember.lastName}`, + interviewer_name: `${interviewerUsers[0].firstName} ${interviewerUsers[0].lastName}`, + xai_template: '/' + interview.xaiTemplate, + additional_interviewers: (interview.attendeesList).join(','), + interview_length: Interviews.XaiTemplate[interview.xaiTemplate], + job_name: job.title, + interviewee_handle: jobCandidateMember.handle + } + }) +} + +/** + * Process interview request event. + * + * @param {Object} payload the event payload + * @returns {undefined} + */ +async function processRequest (payload) { + await sendInvitationEmail(payload) +} + +module.exports = { + processRequest +} diff --git a/src/eventHandlers/ResourceBookingEventHandler.js b/src/eventHandlers/ResourceBookingEventHandler.js index 8145ba49..7a4a7c0a 100644 --- a/src/eventHandlers/ResourceBookingEventHandler.js +++ b/src/eventHandlers/ResourceBookingEventHandler.js @@ -13,26 +13,26 @@ const WorkPeriodService = require('../services/WorkPeriodService') const WorkPeriod = models.WorkPeriod /** - * When ResourceBooking's status is changed to `assigned` + * When ResourceBooking's status is changed to `placed` * the corresponding JobCandidate record (with the same userId and jobId) - * should be updated with status `selected` + * should be updated with status `placed` * * @param {Object} payload the event payload * @returns {undefined} */ -async function selectJobCandidate (payload) { +async function placeJobCandidate (payload) { if (_.get(payload, 'options.oldValue') && payload.value.status === payload.options.oldValue.status) { logger.debug({ component: 'ResourceBookingEventHandler', - context: 'selectJobCandidate', + context: 'placeJobCandidate', message: 'status not changed' }) return } - if (payload.value.status !== 'assigned') { + if (payload.value.status !== 'placed') { logger.debug({ component: 'ResourceBookingEventHandler', - context: 'selectJobCandidate', + context: 'placeJobCandidate', message: `not interested resource booking - status: ${payload.value.status}` }) return @@ -41,7 +41,7 @@ async function selectJobCandidate (payload) { if (!resourceBooking.jobId) { logger.debug({ component: 'ResourceBookingEventHandler', - context: 'selectJobCandidate', + context: 'placeJobCandidate', message: `id: ${resourceBooking.id} resource booking without jobId - ignored` }) return @@ -51,25 +51,25 @@ async function selectJobCandidate (payload) { jobId: resourceBooking.jobId, userId: resourceBooking.userId, status: { - [Op.not]: 'selected' + [Op.not]: 'placed' } } }) await Promise.all(candidates.map(candidate => JobCandidateService.partiallyUpdateJobCandidate( helper.getAuditM2Muser(), candidate.id, - { status: 'selected' } + { status: 'placed' } ).then(result => { logger.info({ component: 'ResourceBookingEventHandler', - context: 'selectJobCandidate', + context: 'placeJobCandidate', message: `id: ${result.id} candidate got selected.` }) }))) } /** - * Update the status of the Job to assigned when it positions requirement is fullfilled. + * Update the status of the Job to assigned when it positions requirement is fulfilled. * * @param {Object} payload the event payload * @returns {undefined} @@ -83,7 +83,7 @@ async function assignJob (payload) { }) return } - if (payload.value.status !== 'assigned') { + if (payload.value.status !== 'placed') { logger.debug({ component: 'ResourceBookingEventHandler', context: 'assignJob', @@ -101,24 +101,24 @@ async function assignJob (payload) { return } const job = await models.Job.findById(resourceBooking.jobId) - if (job.status === 'assigned') { + if (job.status === 'placed') { logger.debug({ component: 'ResourceBookingEventHandler', context: 'assignJob', - message: `job with projectId ${job.projectId} is already assigned` + message: `job with projectId ${job.projectId} is already placed` }) return } const resourceBookings = await models.ResourceBooking.findAll({ where: { jobId: job.id, - status: 'assigned' + status: 'placed' } }) logger.debug({ component: 'ResourceBookingEventHandler', context: 'assignJob', - message: `the number of assigned resource bookings is ${resourceBookings.length} - the numPositions of the job is ${job.numPositions}` + message: `the number of placed resource bookings is ${resourceBookings.length} - the numPositions of the job is ${job.numPositions}` }) if (job.numPositions === resourceBookings.length) { await JobService.partiallyUpdateJob(helper.getAuditM2Muser(), job.id, { status: 'assigned' }) @@ -294,7 +294,7 @@ async function _deleteWorkPeriods (workPeriods) { * @returns {undefined} */ async function processCreate (payload) { - await selectJobCandidate(payload) + await placeJobCandidate(payload) await assignJob(payload) await createWorkPeriods(payload) } @@ -306,7 +306,7 @@ async function processCreate (payload) { * @returns {undefined} */ async function processUpdate (payload) { - await selectJobCandidate(payload) + await placeJobCandidate(payload) await assignJob(payload) await updateWorkPeriods(payload) } diff --git a/src/eventHandlers/index.js b/src/eventHandlers/index.js index 309b5f82..17445994 100644 --- a/src/eventHandlers/index.js +++ b/src/eventHandlers/index.js @@ -7,6 +7,7 @@ const eventDispatcher = require('../common/eventDispatcher') const JobEventHandler = require('./JobEventHandler') const JobCandidateEventHandler = require('./JobCandidateEventHandler') const ResourceBookingEventHandler = require('./ResourceBookingEventHandler') +const InterviewEventHandler = require('./InterviewEventHandler') const logger = require('../common/logger') const TopicOperationMapping = { @@ -14,7 +15,8 @@ const TopicOperationMapping = { [config.TAAS_JOB_CANDIDATE_CREATE_TOPIC]: JobCandidateEventHandler.processCreate, [config.TAAS_RESOURCE_BOOKING_CREATE_TOPIC]: ResourceBookingEventHandler.processCreate, [config.TAAS_RESOURCE_BOOKING_UPDATE_TOPIC]: ResourceBookingEventHandler.processUpdate, - [config.TAAS_RESOURCE_BOOKING_DELETE_TOPIC]: ResourceBookingEventHandler.processDelete + [config.TAAS_RESOURCE_BOOKING_DELETE_TOPIC]: ResourceBookingEventHandler.processDelete, + [config.TAAS_INTERVIEW_REQUEST_TOPIC]: InterviewEventHandler.processRequest } /** diff --git a/src/models/Interview.js b/src/models/Interview.js new file mode 100644 index 00000000..424251a3 --- /dev/null +++ b/src/models/Interview.js @@ -0,0 +1,124 @@ +const { Sequelize, Model } = require('sequelize') +const config = require('config') +const _ = require('lodash') +const { Interviews } = require('../../app-constants') +const errors = require('../common/errors') + +// allowed status values +const statuses = _.values(Interviews.Status) + +module.exports = (sequelize) => { + class Interview extends Model { + /** + * Create association between models + * @param {Object} models the database models + */ + static associate (models) { + Interview.belongsTo(models.JobCandidate, { foreignKey: 'jobCandidateId' }) + } + + /** + * Get interview by id + * @param {String} id the interview id + * @returns {Interview} the Interview instance + */ + static async findById (id) { + const interview = await Interview.findOne({ + where: { + id + } + }) + if (!interview) { + throw new errors.NotFoundError(`id: ${id} "Interview" doesn't exist.`) + } + return interview + } + } + Interview.init( + { + id: { + type: Sequelize.UUID, + primaryKey: true, + allowNull: false, + defaultValue: Sequelize.UUIDV4 + }, + jobCandidateId: { + field: 'job_candidate_id', + type: Sequelize.UUID, + allowNull: false + }, + googleCalendarId: { + field: 'google_calendar_id', + type: Sequelize.STRING(255) + }, + customMessage: { + field: 'custom_message', + type: Sequelize.TEXT + }, + xaiTemplate: { + field: 'xai_template', + type: Sequelize.STRING(255), + allowNull: false + }, + round: { + type: Sequelize.INTEGER, + allowNull: false + }, + startTimestamp: { + field: 'start_timestamp', + type: Sequelize.DATE + }, + attendeesList: { + field: 'attendees_list', + type: Sequelize.ARRAY(Sequelize.STRING) + }, + status: { + type: Sequelize.ENUM(statuses), + allowNull: false + }, + createdBy: { + field: 'created_by', + type: Sequelize.UUID, + allowNull: false + }, + updatedBy: { + field: 'updated_by', + type: Sequelize.UUID + }, + createdAt: { + field: 'created_at', + type: Sequelize.DATE + }, + updatedAt: { + field: 'updated_at', + type: Sequelize.DATE + }, + deletedAt: { + field: 'deleted_at', + type: Sequelize.DATE + } + }, + { + schema: config.DB_SCHEMA_NAME, + sequelize, + tableName: 'interviews', + paranoid: true, + deletedAt: 'deletedAt', + createdAt: 'createdAt', + updatedAt: 'updatedAt', + timestamps: true, + defaultScope: { + attributes: { + exclude: ['deletedAt'] + } + }, + hooks: { + afterCreate: (interview) => { + delete interview.dataValues.deletedAt + } + } + } + ) + + return Interview +} diff --git a/src/models/JobCandidate.js b/src/models/JobCandidate.js index 00e83991..819b9177 100644 --- a/src/models/JobCandidate.js +++ b/src/models/JobCandidate.js @@ -11,18 +11,21 @@ module.exports = (sequelize) => { static associate (models) { JobCandidate._models = models JobCandidate.belongsTo(models.Job, { foreignKey: 'jobId' }) + JobCandidate.hasMany(models.Interview, { foreignKey: 'jobCandidateId', as: 'interviews' }) } /** * Get job candidate by id * @param {String} id the job candidate id + * @param {Array} include include options * @returns {JobCandidate} the JobCandidate instance */ - static async findById (id) { + static async findById (id, include = []) { const jobCandidate = await JobCandidate.findOne({ where: { id - } + }, + include }) if (!jobCandidate) { throw new errors.NotFoundError(`id: ${id} "JobCandidate" doesn't exists.`) @@ -98,6 +101,13 @@ module.exports = (sequelize) => { hooks: { afterCreate: (jobCandidate) => { delete jobCandidate.dataValues.deletedAt + }, + afterDestroy: async (jobCandidate) => { + // cascade (soft) delete interviews associated with this jobCandidate + const jobCandidateId = jobCandidate.id + await sequelize.models.Interview.destroy({ + where: { jobCandidateId } + }) } } } diff --git a/src/routes/InterviewRoutes.js b/src/routes/InterviewRoutes.js new file mode 100644 index 00000000..e8f8e960 --- /dev/null +++ b/src/routes/InterviewRoutes.js @@ -0,0 +1,39 @@ +/** + * Contains interview routes + */ +const constants = require('../../app-constants') + +module.exports = { + '/jobCandidates/:jobCandidateId/requestInterview': { + patch: { + controller: 'InterviewController', + method: 'requestInterview', + auth: 'jwt', + scopes: [constants.Scopes.CREATE_INTERVIEW, constants.Scopes.ALL_INTERVIEW] + } + }, + '/jobCandidates/:jobCandidateId/updateInterview/:round': { + patch: { + controller: 'InterviewController', + method: 'partiallyUpdateInterview', + auth: 'jwt', + scopes: [constants.Scopes.UPDATE_INTERVIEW, constants.Scopes.ALL_INTERVIEW] + } + }, + '/jobCandidates/:jobCandidateId/interviews': { + get: { + controller: 'InterviewController', + method: 'searchInterviews', + auth: 'jwt', + scopes: [constants.Scopes.READ_INTERVIEW, constants.Scopes.ALL_INTERVIEW] + } + }, + '/jobCandidates/:jobCandidateId/interviews/:round': { + get: { + controller: 'InterviewController', + method: 'getInterviewByRound', + auth: 'jwt', + scopes: [constants.Scopes.READ_INTERVIEW, constants.Scopes.ALL_INTERVIEW] + } + } +} diff --git a/src/services/InterviewService.js b/src/services/InterviewService.js new file mode 100644 index 00000000..9d40cfeb --- /dev/null +++ b/src/services/InterviewService.js @@ -0,0 +1,402 @@ +/** + * This service provides operations of Interview. + */ + +const _ = require('lodash') +const Joi = require('joi') +const config = require('config') +const { Op, ForeignKeyConstraintError } = require('sequelize') +const { v4: uuid } = require('uuid') +const { Interviews: InterviewConstants } = require('../../app-constants') +const helper = require('../common/helper') +const logger = require('../common/logger') +const errors = require('../common/errors') +const models = require('../models') + +const Interview = models.Interview +const esClient = helper.getESClient() + +/** + * Ensures user is permitted for the operation. + * + * @param {Object} currentUser the user who perform this operation. + * @param {String} jobCandidateId the job candidate id + * @throws {errors.ForbiddenError} + */ +async function ensureUserIsPermitted (currentUser, jobCandidateId) { + if (!currentUser.hasManagePermission && !currentUser.isMachine) { + const jobCandidate = await models.JobCandidate.findById(jobCandidateId) + const job = await jobCandidate.getJob() + await helper.checkIsMemberOfProject(currentUser.userId, job.projectId) + } +} + +/** + * Handles common sequelize errors + * @param {Object} err error + * @param {String} jobCandidateId the job candidate id + */ +function handleSequelizeError (err, jobCandidateId) { + // jobCandidateId doesn't exist - gracefully handle + if (err instanceof ForeignKeyConstraintError) { + throw new errors.NotFoundError( + `The job candidate with id=${jobCandidateId} doesn't exist.` + ) + } + // another type of sequelize error - extract the details and throw + const errDetail = _.get(err, 'original.detail') + if (errDetail) { + throw new errors.BadRequestError(errDetail) + } +} + +/** + * Get interview by round + * @param {Object} currentUser the user who perform this operation. + * @param {String} jobCandidateId the job candidate id + * @param {Number} round the interview round + * @param {Boolean} fromDb flag if query db for data or not + * @returns {Object} the interview + */ +async function getInterviewByRound (currentUser, jobCandidateId, round, fromDb = false) { + // check permission + await ensureUserIsPermitted(currentUser, jobCandidateId) + if (!fromDb) { + try { + // get job candidate from ES + const jobCandidateES = await esClient.get({ + index: config.esConfig.ES_INDEX_JOB_CANDIDATE, + id: jobCandidateId + }) + // extract interviews from ES object + const jobCandidateInterviews = _.get(jobCandidateES, 'body._source.interviews', []) + // find interview by round + const interview = _.find(jobCandidateInterviews, interview => interview.round === round) + if (interview) { + return interview + } + // if reaches here, the interview with this round is not found + throw new errors.NotFoundError(`Interview doesn't exist with round: ${round}`) + } catch (err) { + if (helper.isDocumentMissingException(err)) { + throw new errors.NotFoundError(`id: ${jobCandidateId} "JobCandidate" not found`) + } + logger.logFullError(err, { component: 'InterviewService', context: 'getInterviewByRound' }) + throw err + } + } + // either ES query failed or `fromDb` is set - fallback to DB + logger.info({ component: 'InterviewService', context: 'getInterview', message: 'try to query db for data' }) + + const interview = await Interview.findOne({ + where: { jobCandidateId, round } + }) + // throw NotFound error if doesn't exist + if (!!interview !== true) { + throw new errors.NotFoundError(`Interview doesn't exist with jobCandidateId: ${jobCandidateId} and round: ${round}`) + } + + return interview.dataValues +} + +getInterviewByRound.schema = Joi.object().keys({ + currentUser: Joi.object().required(), + jobCandidateId: Joi.string().uuid().required(), + round: Joi.number().integer().positive().required(), + fromDb: Joi.boolean() +}).required() + +/** + * Request interview + * @param {Object} currentUser the user who perform this operation + * @param {String} jobCandidateId the job candidate id + * @param {Object} interview the interview to be created + * @returns {Object} the created/requested interview + */ +async function requestInterview (currentUser, jobCandidateId, interview) { + // check permission + await ensureUserIsPermitted(currentUser, jobCandidateId) + + interview.id = uuid() + interview.jobCandidateId = jobCandidateId + interview.createdBy = await helper.getUserId(currentUser.userId) + + // find the round count + const round = await Interview.count({ + where: { jobCandidateId } + }) + + // throw error if candidate has already had MaxAllowedCount interviews + if (round >= InterviewConstants.MaxAllowedCount) { + throw new errors.ConflictError(`You've reached the maximum allowed number (${InterviewConstants.MaxAllowedCount}) of interviews for this candidate.`) + } + interview.round = round + 1 + + try { + // create the interview + const created = await Interview.create(interview) + await helper.postEvent(config.TAAS_INTERVIEW_REQUEST_TOPIC, created.toJSON()) + // update jobCandidate.status to Interview + const [, affectedRows] = await models.JobCandidate.update( + { status: 'interview' }, + { where: { id: created.jobCandidateId }, returning: true } + ) + const updatedJobCandidate = _.omit(_.get(affectedRows, '0.dataValues'), 'deletedAt') + await helper.postEvent(config.TAAS_JOB_CANDIDATE_UPDATE_TOPIC, updatedJobCandidate) + // return created interview + return created.dataValues + } catch (err) { + // gracefully handle if one of the common sequelize errors + handleSequelizeError(err, jobCandidateId) + // if reaches here, it's not one of the common errors handled in `handleSequelizeError` + throw err + } +} + +requestInterview.schema = Joi.object().keys({ + currentUser: Joi.object().required(), + jobCandidateId: Joi.string().uuid().required(), + interview: Joi.object().keys({ + googleCalendarId: Joi.string().allow(null), + customMessage: Joi.string().allow(null), + xaiTemplate: Joi.xaiTemplate().required(), + attendeesList: Joi.array().items(Joi.string().email()).allow(null), + status: Joi.interviewStatus().default(InterviewConstants.Status.Scheduling) + }).required() +}).required() + +/** + * Patch (partially update) interview + * @param {Object} currentUser the user who perform this operation + * @param {String} jobCandidateId the job candidate id + * @param {Number} round the interview round + * @param {Object} data object containing patched fields + * @returns {Object} the patched interview object + */ +async function partiallyUpdateInterview (currentUser, jobCandidateId, round, data) { + // check permission + await ensureUserIsPermitted(currentUser, jobCandidateId) + + const interview = await Interview.findOne({ + where: { + jobCandidateId, round + } + }) + // throw NotFound error if doesn't exist + if (!!interview !== true) { + throw new errors.NotFoundError(`Interview doesn't exist with jobCandidateId: ${jobCandidateId} and round: ${round}`) + } + + const oldValue = interview.toJSON() + + // only status can be updated for Completed interviews + if (oldValue.status === InterviewConstants.Status.Completed) { + const updatedFields = _.keys(data) + if (updatedFields.length !== 1 || !_.includes(updatedFields, 'status')) { + throw new errors.BadRequestError('Only the "status" can be updated for Completed interviews.') + } + } + + data.updatedBy = await helper.getUserId(currentUser.userId) + try { + const updated = await interview.update(data) + await helper.postEvent(config.TAAS_INTERVIEW_UPDATE_TOPIC, updated.toJSON(), { oldValue: oldValue }) + return updated.dataValues + } catch (err) { + // gracefully handle if one of the common sequelize errors + handleSequelizeError(err, jobCandidateId) + // if reaches here, it's not one of the common errors handled in `handleSequelizeError` + throw err + } +} + +partiallyUpdateInterview.schema = Joi.object().keys({ + currentUser: Joi.object().required(), + jobCandidateId: Joi.string().uuid().required(), + round: Joi.number().integer().positive().required(), + data: Joi.object().keys({ + googleCalendarId: Joi.string().when('status', { + is: [InterviewConstants.Status.Scheduled, InterviewConstants.Status.Rescheduled], + then: Joi.required(), + otherwise: Joi.allow(null) + }), + customMessage: Joi.string().allow(null), + xaiTemplate: Joi.xaiTemplate(), + startTimestamp: Joi.date().greater('now').when('status', { + is: [InterviewConstants.Status.Scheduled, InterviewConstants.Status.Rescheduled], + then: Joi.required(), + otherwise: Joi.allow(null) + }), + attendeesList: Joi.array().items(Joi.string().email()).allow(null), + status: Joi.interviewStatus() + }).required().min(1) // at least one key - i.e. don't allow empty object +}).required() + +/** + * List interviews + * @param {Object} currentUser the user who perform this operation. + * @param {String} jobCandidateId the job candidate id + * @param {Object} criteria the search criteria + * @returns {Object} the search result, contain total/page/perPage and result array + */ +async function searchInterviews (currentUser, jobCandidateId, criteria) { + // check permission + await ensureUserIsPermitted(currentUser, jobCandidateId) + + const { page, perPage } = criteria + + try { + // construct query for nested search + const esQueryBody = { + _source: false, + query: { + nested: { + path: 'interviews', + query: { + bool: { + must: [] + } + }, + inner_hits: { + size: 100 // max. inner_hits size + } + } + } + } + // add filtering terms + // jobCandidateId + esQueryBody.query.nested.query.bool.must.push({ + term: { + 'interviews.jobCandidateId': { + value: jobCandidateId + } + } + }) + // criteria + _.each(_.pick(criteria, ['status', 'createdAt', 'updatedAt']), (value, key) => { + const innerKey = `interviews.${key}` + esQueryBody.query.nested.query.bool.must.push({ + term: { + [innerKey]: { + value + } + } + }) + }) + // search + const { body } = await esClient.search({ + index: config.esConfig.ES_INDEX_JOB_CANDIDATE, + body: esQueryBody + }) + // get jobCandidate hit from body - there's always one jobCandidate hit as we search via jobCandidateId + // extract inner interview hits from jobCandidate + const interviewHits = _.get(body, 'hits.hits[0].inner_hits.interviews.hits.hits', []) + const interviews = _.map(interviewHits, '_source') + + // we need to sort & paginate interviews manually + // as it's not possible with ES query on nested type + // (ES applies pagination & sorting on parent documents, not on the nested objects) + + // sort + const sortedInterviews = _.orderBy(interviews, criteria.sortBy, criteria.sortOrder) + // paginate + const start = (page - 1) * perPage + const end = start + perPage + const paginatedInterviews = _.slice(sortedInterviews, start, end) + + return { + total: sortedInterviews.length, + page, + perPage, + result: paginatedInterviews + } + } catch (err) { + logger.logFullError(err, { component: 'InterviewService', context: 'searchInterviews' }) + } + logger.info({ component: 'InterviewService', context: 'searchInterviews', message: 'fallback to DB query' }) + const filter = { + [Op.and]: [{ jobCandidateId }] + } + // apply filtering based on criteria + _.each(_.pick(criteria, ['status', 'createdAt', 'updatedAt']), (value, key) => { + filter[Op.and].push({ [key]: value }) + }) + const interviews = await Interview.findAll({ + where: filter, + offset: ((page - 1) * perPage), + limit: perPage, + order: [[criteria.sortBy, criteria.sortOrder]] + }) + return { + fromDb: true, + total: interviews.length, + page, + perPage, + result: _.map(interviews, interview => interview.dataValues) + } +} + +searchInterviews.schema = Joi.object().keys({ + currentUser: Joi.object().required(), + jobCandidateId: Joi.string().uuid().required(), + criteria: Joi.object().keys({ + page: Joi.page(), + perPage: Joi.perPage(), + sortBy: Joi.string().valid('round', 'createdAt', 'updatedAt').default('createdAt'), + sortOrder: Joi.string().valid('desc', 'asc').default('desc'), + createdAt: Joi.date(), + updatedAt: Joi.date(), + status: Joi.interviewStatus() + }).required() +}).required() + +/** + * Updates the status of completed (based on startTimestamp) interviews. + * If the startTimestamp of an interview is less than (or equal) the (currentDateTime - 1 hour) + * it's considered as completed. + */ +async function updateCompletedInterviews () { + logger.info({ component: 'InterviewService', context: 'updateCompletedInterviews', message: 'Running the scheduled job...' }) + const oneHourAgo = new Date(Date.now() - 60 * 60 * 1000) + const [affectedCount, updatedRows] = await Interview.update( + // '00000000-0000-0000-0000-000000000000' - to indicate it's updated by the system job + { status: InterviewConstants.Status.Completed, updatedBy: '00000000-0000-0000-0000-000000000000' }, + { + where: { + status: [InterviewConstants.Status.Scheduled, InterviewConstants.Status.Rescheduled], + startTimestamp: { + [Op.lte]: oneHourAgo + } + }, + returning: true + } + ) + + // post event if there are affected/updated interviews + if (affectedCount > 0) { + // payload format: + // { + // jobCandidateId: { interviewId: { affectedFields }, interviewId2: { affectedFields }, ... }, + // jobCandidateId2: { interviewId: { affectedFields }, interviewId2: { affectedFields }, ... }, + // ... + // } + const bulkUpdatePayload = {} + // construct payload + _.forEach(updatedRows, row => { + const interview = row.toJSON() + const affectedFields = _.pick(interview, ['status', 'updatedBy', 'updatedAt']) + _.set(bulkUpdatePayload, [interview.jobCandidateId, interview.id], affectedFields) + }) + // post event + await helper.postEvent(config.TAAS_INTERVIEW_BULK_UPDATE_TOPIC, bulkUpdatePayload) + } + logger.info({ component: 'InterviewService', context: 'updateCompletedInterviews', message: `Completed running. Updated ${affectedCount} interviews.` }) +} + +module.exports = { + getInterviewByRound, + requestInterview, + partiallyUpdateInterview, + searchInterviews, + updateCompletedInterviews +} diff --git a/src/services/JobCandidateService.js b/src/services/JobCandidateService.js index 0dec8a18..392d0af6 100644 --- a/src/services/JobCandidateService.js +++ b/src/services/JobCandidateService.js @@ -8,6 +8,7 @@ const config = require('config') const HttpStatus = require('http-status-codes') const { Op } = require('sequelize') const { v4: uuid } = require('uuid') +const { Scopes } = require('../../app-constants') const helper = require('../common/helper') const logger = require('../common/logger') const errors = require('../common/errors') @@ -31,6 +32,24 @@ async function _checkUserPermissionForGetJobCandidate (currentUser, jobId) { } } +/** + * Returns field omit list, based on user access level. + * + * @param {Object} currentUser the user who perform this operation. + * @returns {Array} the field list to omit from the jobCandidate object + */ +function getJobCandidateOmitList (currentUser) { + // check M2M scopes for Interviews + if (currentUser.isMachine) { + const interviewsAllowedScopes = [Scopes.READ_INTERVIEW, Scopes.ALL_INTERVIEW] + if (!currentUser.scopes || !helper.checkIfExists(interviewsAllowedScopes, currentUser.scopes)) { + return ['interviews'] + } + return [] + } + return currentUser.hasManagePermission ? [] : ['interviews'] +} + /** * Get jobCandidate by id * @param {Object} currentUser the user who perform this operation. @@ -39,6 +58,7 @@ async function _checkUserPermissionForGetJobCandidate (currentUser, jobId) { * @returns {Object} the jobCandidate */ async function getJobCandidate (currentUser, id, fromDb = false) { + const omitList = getJobCandidateOmitList(currentUser) if (!fromDb) { try { const jobCandidate = await esClient.get({ @@ -49,7 +69,7 @@ async function getJobCandidate (currentUser, id, fromDb = false) { await _checkUserPermissionForGetJobCandidate(currentUser, jobCandidate.body._source.jobId) // check user permisson const jobCandidateRecord = { id: jobCandidate.body._id, ...jobCandidate.body._source } - return jobCandidateRecord + return _.omit(jobCandidateRecord, omitList) } catch (err) { if (helper.isDocumentMissingException(err)) { throw new errors.NotFoundError(`id: ${id} "JobCandidate" not found`) @@ -61,7 +81,13 @@ async function getJobCandidate (currentUser, id, fromDb = false) { } } logger.info({ component: 'JobCandidateService', context: 'getJobCandidate', message: 'try to query db for data' }) - const jobCandidate = await JobCandidate.findById(id) + // include interviews if user has permission + const include = [] + const hasInterviewPermision = !_.includes(omitList, 'interviews') + if (hasInterviewPermision) { + include.push({ model: models.Interview, as: 'interviews' }) + } + const jobCandidate = await JobCandidate.findById(id, include) await _checkUserPermissionForGetJobCandidate(currentUser, jobCandidate.jobId) // check user permission @@ -215,6 +241,7 @@ async function searchJobCandidates (currentUser, criteria) { await JobService.getJob(currentUser, criteria.jobId) // check whether user can access the job associated with the jobCandidate } + const omitList = getJobCandidateOmitList(currentUser) const page = criteria.page > 0 ? criteria.page : 1 const perPage = criteria.perPage > 0 ? criteria.perPage : 20 if (!criteria.sortBy) { @@ -260,7 +287,7 @@ async function searchJobCandidates (currentUser, criteria) { result: _.map(body.hits.hits, (hit) => { const obj = _.cloneDeep(hit._source) obj.id = hit._id - return obj + return _.omit(obj, omitList) }) } } catch (err) { @@ -271,8 +298,17 @@ async function searchJobCandidates (currentUser, criteria) { _.each(_.pick(criteria, ['jobId', 'userId', 'status', 'externalId']), (value, key) => { filter[Op.and].push({ [key]: value }) }) + + // include interviews if user has permission + const include = [] + const hasInterviewPermision = !_.includes(omitList, 'interviews') + if (hasInterviewPermision) { + include.push({ model: models.Interview, as: 'interviews' }) + } + const jobCandidates = await JobCandidate.findAll({ where: filter, + include, offset: ((page - 1) * perPage), limit: perPage, order: [[criteria.sortBy, criteria.sortOrder]] @@ -282,7 +318,7 @@ async function searchJobCandidates (currentUser, criteria) { total: jobCandidates.length, page, perPage, - result: _.map(jobCandidates, jobCandidate => jobCandidate.dataValues) + result: _.map(jobCandidates, jobCandidate => _.omit(jobCandidate.dataValues, omitList)) } } diff --git a/src/services/ResourceBookingService.js b/src/services/ResourceBookingService.js index 4fef4e46..3693f22c 100644 --- a/src/services/ResourceBookingService.js +++ b/src/services/ResourceBookingService.js @@ -159,7 +159,7 @@ async function createResourceBooking (currentUser, resourceBooking) { createResourceBooking.schema = Joi.object().keys({ currentUser: Joi.object().required(), resourceBooking: Joi.object().keys({ - status: Joi.resourceBookingStatus().default('assigned'), + status: Joi.resourceBookingStatus().default('placed'), projectId: Joi.number().integer().required(), userId: Joi.string().uuid().required(), jobId: Joi.string().uuid().allow(null), diff --git a/src/services/TeamService.js b/src/services/TeamService.js index 0519543e..2f9b32c5 100644 --- a/src/services/TeamService.js +++ b/src/services/TeamService.js @@ -5,7 +5,6 @@ const _ = require('lodash') const Joi = require('joi') const dateFNS = require('date-fns') -const Handlebars = require('handlebars') const config = require('config') const emailTemplateConfig = require('../../config/email_template.config') const helper = require('../common/helper') @@ -16,21 +15,23 @@ const ResourceBookingService = require('./ResourceBookingService') const emailTemplates = _.mapValues(emailTemplateConfig, (template) => { return { - subjectTemplate: Handlebars.compile(template.subject), - bodyTemplate: Handlebars.compile(template.body), + subject: template.subject, + body: template.body, + from: template.from, recipients: template.recipients, + cc: template.cc, sendgridTemplateId: template.sendgridTemplateId } }) /** - * Function to get assigned resource bookings with specific projectIds + * Function to get placed resource bookings with specific projectIds * @param {Object} currentUser the user who perform this operation. * @param {Array} projectIds project ids * @returns the request result */ -async function _getAssignedResourceBookingsByProjectIds (currentUser, projectIds) { - const criteria = { status: 'assigned', projectIds } +async function _getPlacedResourceBookingsByProjectIds (currentUser, projectIds) { + const criteria = { status: 'placed', projectIds } const { result } = await ResourceBookingService.searchResourceBookings(currentUser, criteria, { returnAll: true }) return result } @@ -96,8 +97,8 @@ searchTeams.schema = Joi.object().keys({ */ async function getTeamDetail (currentUser, projects, isSearch = true) { const projectIds = _.map(projects, 'id') - // Get all assigned resourceBookings filtered by projectIds - const resourceBookings = await _getAssignedResourceBookingsByProjectIds(currentUser, projectIds) + // Get all placed resourceBookings filtered by projectIds + const resourceBookings = await _getPlacedResourceBookingsByProjectIds(currentUser, projectIds) // Get all jobs filtered by projectIds const jobs = await _getJobsByProjectIds(currentUser, projectIds) @@ -286,7 +287,7 @@ async function getTeamJob (currentUser, id, jobId) { const photoURLMap = _.groupBy(members, 'handleLower') result.candidates = _.map(job.candidates, candidate => { - const candidateData = _.pick(candidate, ['status', 'resume', 'userId', 'id']) + const candidateData = _.pick(candidate, ['status', 'resume', 'userId', 'interviews', 'id']) const userData = userMap[candidate.userId][0] // attach user data to the candidate Object.assign(candidateData, _.pick(userData, ['handle', 'firstName', 'lastName', 'skills'])) @@ -316,22 +317,38 @@ getTeamJob.schema = Joi.object().keys({ */ async function sendEmail (currentUser, data) { const template = emailTemplates[data.template] - await helper.postEvent(config.EMAIL_TOPIC, { - data: { - subject: template.subjectTemplate(data.data), - body: template.bodyTemplate(data.data) - }, + const dataCC = data.cc || [] + const templateCC = template.cc || [] + const dataRecipients = data.recipients || [] + const templateRecipients = template.recipients || [] + const subjectBody = { + subject: data.subject || template.subject, + body: data.body || template.body + } + for(var key in subjectBody) { + subjectBody[key] = await helper.substituteStringByObject(subjectBody[key], data.data) + } + const emailData = { + // override template if coming data already have the 'from' address + from: data.from || template.from, + // create a set of uniq. recipients & CCs, from both coming data & template + recipients: _.uniq([...dataRecipients, ...templateRecipients]), + cc: _.uniq([...dataCC, ...templateCC]), + data: { ...data.data, ...subjectBody }, sendgrid_template_id: template.sendgridTemplateId, - version: 'v3', - recipients: template.recipients - }) + version: 'v3' + } + await helper.postEvent(config.EMAIL_TOPIC, emailData) } sendEmail.schema = Joi.object().keys({ currentUser: Joi.object().required(), data: Joi.object().keys({ template: Joi.string().valid(...Object.keys(emailTemplates)).required(), - data: Joi.object().required() + data: Joi.object().required(), + from: Joi.string().email(), + recipients: Joi.array().items(Joi.string().email()).allow(null), + cc: Joi.array().items(Joi.string().email()).allow(null) }).required() }).required()