diff --git a/.gitignore b/.gitignore index 6ac5f84d..69ec29ae 100644 --- a/.gitignore +++ b/.gitignore @@ -53,6 +53,9 @@ web_modules/ # Optional eslint cache .eslintcache +# Optional eslint options +.eslintrc.y*ml + # Microbundle cache .rpt2_cache/ .rts2_cache_cjs/ diff --git a/README.md b/README.md index 88a1f961..e86242b2 100644 --- a/README.md +++ b/README.md @@ -90,12 +90,13 @@ tc-taas-es-processor | 2021-04-09T21:20:21.466Z DEBUG no-kafka-client Subscribed to taas.workperiod.delete:0 offset 0 leader kafka:9093 tc-taas-es-processor | 2021-04-09T21:20:21.468Z DEBUG no-kafka-client Subscribed to taas.workperiod.create:0 offset 0 leader kafka:9093 tc-taas-es-processor | 2021-04-09T21:20:21.469Z DEBUG no-kafka-client Subscribed to taas.workperiodpayment.update:0 offset 0 leader kafka:9093 - tc-taas-es-processor | 2021-04-09T21:20:21.470Z DEBUG no-kafka-client Subscribed to taas.workperiodpayment.create:0 offset 0 leader kafka:9093 - tc-taas-es-processor | 2021-04-09T21:20:21.471Z DEBUG no-kafka-client Subscribed to taas.job.update:0 offset 0 leader kafka:9093 - tc-taas-es-processor | 2021-04-09T21:20:21.472Z DEBUG no-kafka-client Subscribed to taas.resourcebooking.update:0 offset 0 leader kafka:9093 - tc-taas-es-processor | [2021-04-09T21:20:21.473Z] app INFO : Initialized....... - tc-taas-es-processor | [2021-04-09T21:20:21.479Z] app INFO : taas.job.create,taas.job.update,taas.job.delete,taas.jobcandidate.create,taas.jobcandidate.update,taas.jobcandidate.delete,taas.resourcebooking.create,taas.resourcebooking.update,taas.resourcebooking.delete,taas.workperiod.create,taas.workperiod.update,taas.workperiod.delete,taas.workperiodpayment.create,taas.workperiodpayment.update - tc-taas-es-processor | [2021-04-09T21:20:21.479Z] app INFO : Kick Start....... + tc-taas-es-processor | 2021-04-09T21:20:21.470Z DEBUG no-kafka-client Subscribed to taas.workperiodpayment.delete:0 offset 0 leader kafka:9093 + tc-taas-es-processor | 2021-04-09T21:20:21.471Z DEBUG no-kafka-client Subscribed to taas.workperiodpayment.create:0 offset 0 leader kafka:9093 + tc-taas-es-processor | 2021-04-09T21:20:21.473Z DEBUG no-kafka-client Subscribed to taas.job.update:0 offset 0 leader kafka:9093 + tc-taas-es-processor | 2021-04-09T21:20:21.474Z DEBUG no-kafka-client Subscribed to taas.resourcebooking.update:0 offset 0 leader kafka:9093 + tc-taas-es-processor | [2021-04-09T21:20:21.475Z] app INFO : Initialized....... + tc-taas-es-processor | [2021-04-09T21:20:21.479Z] app INFO : taas.job.create,taas.job.update,taas.job.delete,taas.jobcandidate.create,taas.jobcandidate.update,taas.jobcandidate.delete,taas.resourcebooking.create,taas.resourcebooking.update,taas.resourcebooking.delete,taas.workperiod.create,taas.workperiod.update,taas.workperiod.delete,taas.workperiodpayment.create,taas.workperiodpayment.update,taas.workperiodpayment.delete + tc-taas-es-processor | [2021-04-09T21:20:21.480Z] app INFO : Kick Start....... tc-taas-es-processor | ********** Topcoder Health Check DropIn listening on port 3001 tc-taas-es-processor | Topcoder Health Check DropIn started and ready to roll ``` diff --git a/config/default.js b/config/default.js index 04b460d4..c2ba03fe 100644 --- a/config/default.js +++ b/config/default.js @@ -113,7 +113,7 @@ module.exports = { // the delete resource booking entity Kafka message topic TAAS_RESOURCE_BOOKING_DELETE_TOPIC: process.env.TAAS_RESOURCE_BOOKING_DELETE_TOPIC || 'taas.resourcebooking.delete', // topics for work period service - // the create rwork period entity Kafka message topic + // the create work period entity Kafka message topic TAAS_WORK_PERIOD_CREATE_TOPIC: process.env.TAAS_WORK_PERIOD_CREATE_TOPIC || 'taas.workperiod.create', // the update work period entity Kafka message topic TAAS_WORK_PERIOD_UPDATE_TOPIC: process.env.TAAS_WORK_PERIOD_UPDATE_TOPIC || 'taas.workperiod.update', @@ -124,6 +124,8 @@ module.exports = { TAAS_WORK_PERIOD_PAYMENT_CREATE_TOPIC: process.env.TAAS_WORK_PERIOD_PAYMENT_CREATE_TOPIC || 'taas.workperiodpayment.create', // the update work period payment entity Kafka message topic 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', // the Kafka message topic for sending email EMAIL_TOPIC: process.env.EMAIL_TOPIC || 'external.action.email', @@ -143,6 +145,8 @@ module.exports = { ROLE_ID_SUBMITTER: process.env.ROLE_ID_SUBMITTER || '732339e7-8e30-49d7-9198-cccf9451e221', TYPE_ID_TASK: process.env.TYPE_ID_TASK || 'ecd58c69-238f-43a4-a4bb-d172719b9f31', DEFAULT_TIMELINE_TEMPLATE_ID: process.env.DEFAULT_TIMELINE_TEMPLATE_ID || '53a307ce-b4b3-4d6f-b9a1-3741a58f77e6', - DEFAULT_TRACK_ID: process.env.DEFAULT_TRACK_ID || '9b6fc876-f4d9-4ccb-9dfd-419247628825' + DEFAULT_TRACK_ID: process.env.DEFAULT_TRACK_ID || '9b6fc876-f4d9-4ccb-9dfd-419247628825', + // default time zone for Work Periods + WORK_PERIOD_TIME_ZONE: process.env.WORK_PERIOD_TIME_ZONE || 'America/New_York' } diff --git a/config/test.js b/config/test.js index 761b6ada..561ce3a3 100644 --- a/config/test.js +++ b/config/test.js @@ -4,5 +4,6 @@ module.exports = { AUTH0_AUDIENCE: 'http://example.com', AUTH0_AUDIENCE_UBAHN: 'http://example.com', AUTH0_CLIENT_ID: 'fake_id', - AUTH0_CLIENT_SECRET: 'fake_secret' + AUTH0_CLIENT_SECRET: 'fake_secret', + WORK_PERIOD_TIME_ZONE: 'America/New_York' } diff --git a/data/demo-data.json b/data/demo-data.json index f6f8a8b7..8b5c7211 100644 --- a/data/demo-data.json +++ b/data/demo-data.json @@ -400,8 +400,8 @@ "userId": "05e988b7-7d54-4c10-ada1-1a04870a88a8", "jobId": "2d5e2a52-e0dd-4cd9-8f4c-7cffa43951d0", "status": "in-review", - "startDate": "2021-01-25T19:39:34.000Z", - "endDate": "2021-01-31T19:39:34.000Z", + "startDate": "2021-03-25T19:39:34.000Z", + "endDate": "2021-05-31T19:39:34.000Z", "memberRate": 1000, "customerRate": 1200, "rateType": "weekly", @@ -410,14 +410,30 @@ "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-27T08:40:03.000Z", + "endDate": "2021-03-15T09:40:03.000Z", + "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-01-25T19:39:39.000Z", - "endDate": "2021-01-31T19:39:39.000Z", + "startDate": "2021-02-25T13:39:39.000Z", + "endDate": "2021-04-01T05:39:39.000Z", "memberRate": 1000, "customerRate": 1200, "rateType": "weekly", @@ -427,84 +443,84 @@ "updatedAt": "2021-01-28T19:40:34.859Z" }, { - "id": "a098e8d8-ce5b-47d9-afee-38b050d16745", + "id": "51b45f5d-5df2-46d5-9c3d-8a1323df38dd", "projectId": 111, - "userId": "4709473d-f060-4102-87f8-4d51ff0b34c1", + "userId": "dd5adacb-444d-4992-8b7b-0c349be598db", "jobId": "2d5e2a52-e0dd-4cd9-8f4c-7cffa43951d0", - "status": "cancelled", - "startDate": "2021-01-25T19:39:45.000Z", - "endDate": "2021-01-31T19:39:45.000Z", - "memberRate": 1000, - "customerRate": 1200, + "status": "assigned", + "startDate": "2021-03-18T04:39:58.000Z", + "endDate": "2021-05-28T09:39:58.000Z", + "memberRate": 800, + "customerRate": 1000, "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" + "createdAt": "2021-01-28T19:39:59.432Z", + "updatedAt": "2021-01-28T19:40:47.743Z" }, { - "id": "d38a6223-3f91-4300-9ecb-6e5fee173625", + "id": "61f5d474-e41f-490b-ab58-9f983e3d4916", "projectId": 111, - "userId": "39c7376e-2d5c-4601-bc47-6b60f505814d", + "userId": "f65e2104-2987-4136-839d-ee4632f0b2e5", "jobId": "2d5e2a52-e0dd-4cd9-8f4c-7cffa43951d0", - "status": "sourcing", - "startDate": "2021-01-25T19:39:50.000Z", - "endDate": "2021-01-31T19:39:50.000Z", - "memberRate": 1000, - "customerRate": 1200, + "status": "assigned", + "startDate": "2000-03-27T11:17:23.000Z", + "endDate": "2000-04-27T22:17:23.000Z", + "memberRate": 3000, + "customerRate": 3500, "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" + "createdAt": "2021-01-28T19:40:09.879Z", + "updatedAt": "2021-01-28T19:40:56.381Z" }, { - "id": "51b45f5d-5df2-46d5-9c3d-8a1323df38dd", + "id": "8173579e-4b3c-418d-a9a1-c999caa38404", "projectId": 111, - "userId": "dd5adacb-444d-4992-8b7b-0c349be598db", + "userId": "bef43122-426b-4b2b-acdd-9b5b3bd1c0bf", "jobId": "2d5e2a52-e0dd-4cd9-8f4c-7cffa43951d0", "status": "assigned", - "startDate": "2021-01-25T19:39:58.000Z", - "endDate": "2021-01-31T19:39:58.000Z", - "memberRate": 800, - "customerRate": 1000, + "startDate": "2020-04-27T14:17:23.000Z", + "endDate": "2020-05-27T04:17:23.000Z", + "memberRate": 0, + "customerRate": 0, "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" + "createdAt": "2021-01-28T19:40:20.627Z", + "updatedAt": "2021-01-28T19:41:04.919Z" }, { - "id": "0a6799d7-f5d1-456b-8bf1-90619284b295", + "id": "a098e8d8-ce5b-47d9-afee-38b050d16745", "projectId": 111, - "userId": "6d0509c7-5f12-4d84-9a19-8e80ef7ddd66", + "userId": "4709473d-f060-4102-87f8-4d51ff0b34c1", "jobId": "2d5e2a52-e0dd-4cd9-8f4c-7cffa43951d0", - "status": "assigned", - "startDate": "2021-01-25T19:40:03.000Z", - "endDate": "2021-01-31T19:40:03.000Z", - "memberRate": 2000, - "customerRate": 2500, + "status": "cancelled", + "startDate": "2021-04-25T20:39:45.000Z", + "endDate": "2021-04-30T21:39:45.000Z", + "memberRate": 1000, + "customerRate": 1200, "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" + "createdAt": "2021-01-28T19:39:46.515Z", + "updatedAt": "2021-01-28T19:40:38.820Z" }, { - "id": "61f5d474-e41f-490b-ab58-9f983e3d4916", + "id": "d38a6223-3f91-4300-9ecb-6e5fee173625", "projectId": 111, - "userId": "f65e2104-2987-4136-839d-ee4632f0b2e5", + "userId": "39c7376e-2d5c-4601-bc47-6b60f505814d", "jobId": "2d5e2a52-e0dd-4cd9-8f4c-7cffa43951d0", - "status": "assigned", - "startDate": "2000-07-27T04:17:23.131Z", - "endDate": "2000-09-27T04:17:23.131Z", - "memberRate": 3000, - "customerRate": 3500, + "status": "sourcing", + "startDate": "2021-05-25T16:39:50.000Z", + "endDate": "2021-07-31T17:39:50.000Z", + "memberRate": 1000, + "customerRate": 1200, "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" + "createdAt": "2021-01-28T19:39:52.063Z", + "updatedAt": "2021-01-28T19:40:43.021Z" }, { "id": "dc4477ec-07f8-4c8e-a8fe-ffe38dd290fa", @@ -512,8 +528,8 @@ "userId": "e5e667ad-0950-43c2-8d1d-6e83ad7d1c7e", "jobId": "2d5e2a52-e0dd-4cd9-8f4c-7cffa43951d0", "status": "assigned", - "startDate": "2022-07-27T04:17:23.131Z", - "endDate": "2022-09-27T04:17:23.131Z", + "startDate": "2021-07-27T08:17:23.131Z", + "endDate": "2021-09-27T02:17:23.000Z", "memberRate": 1700, "customerRate": 1900, "rateType": "weekly", @@ -521,512 +537,1765 @@ "updatedBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", "createdAt": "2021-01-28T19:40:15.326Z", "updatedAt": "2021-01-28T19:41:00.503Z" - }, - { - "id": "8173579e-4b3c-418d-a9a1-c999caa38404", - "projectId": 111, - "userId": "bef43122-426b-4b2b-acdd-9b5b3bd1c0bf", - "jobId": "2d5e2a52-e0dd-4cd9-8f4c-7cffa43951d0", - "status": "assigned", - "startDate": "2020-09-27T04:17:23.131Z", - "endDate": "2020-09-27T04:17:23.131Z", - "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" } ], "WorkPeriod": [ { - "id": "80b85cbb-3064-45aa-bb75-9dc010848fc1", - "resourceBookingId": "dc4477ec-07f8-4c8e-a8fe-ffe38dd290fa", - "userHandle": "nskumar278", + "id": "db3ac57b-8e78-4b68-a0f7-4e928f3059af", + "resourceBookingId": "08f5e4b9-1088-496d-91a7-5b22a3583e3c", + "userHandle": "ritesh_cs", "projectId": 111, - "startDate": "2021-03-07", - "endDate": "2021-03-13", - "daysWorked": 2, - "memberRate": 13.13, - "customerRate": 13.13, + "startDate": "2021-01-24", + "endDate": "2021-01-30", + "daysWorked": 5, + "memberRate": null, + "customerRate": null, "paymentStatus": "pending", - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "createdBy": "00000000-0000-0000-0000-000000000000", "updatedBy": null, - "createdAt": "2021-03-30T19:13:23.714Z", - "updatedAt": "2021-03-30T19:13:23.714Z" + "createdAt": "2021-04-14T22:01:45.105Z", + "updatedAt": null }, { - "id": "9b0765ef-4e20-4cb2-91f1-ce8d7bcd8062", - "resourceBookingId": "d38a6223-3f91-4300-9ecb-6e5fee173625", - "userHandle": "nithyaasworld", + "id": "a6c83e0d-de12-42f2-b689-85ad56470941", + "resourceBookingId": "08f5e4b9-1088-496d-91a7-5b22a3583e3c", + "userHandle": "ritesh_cs", "projectId": 111, - "startDate": "2021-03-07", - "endDate": "2021-03-13", - "daysWorked": 2, - "memberRate": 13.13, - "customerRate": 13.13, - "paymentStatus": "cancelled", - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "startDate": "2021-01-31", + "endDate": "2021-02-06", + "daysWorked": 0, + "memberRate": null, + "customerRate": null, + "paymentStatus": "pending", + "createdBy": "00000000-0000-0000-0000-000000000000", "updatedBy": null, - "createdAt": "2021-03-30T19:14:17.109Z", - "updatedAt": "2021-03-30T19:14:17.109Z" + "createdAt": "2021-04-14T22:01:45.105Z", + "updatedAt": null }, { - "id": "5796eecf-cc4f-42c2-a25b-7af4710847d6", - "resourceBookingId": "a098e8d8-ce5b-47d9-afee-38b050d16745", - "userHandle": "TCConnCopilot", + "id": "5342924e-a1ed-4164-a885-7ebb87215aa5", + "resourceBookingId": "8173579e-4b3c-418d-a9a1-c999caa38404", + "userHandle": "testcat", "projectId": 111, - "startDate": "2021-03-14", - "endDate": "2021-03-20", + "startDate": "2020-04-26", + "endDate": "2020-05-02", "daysWorked": 5, - "memberRate": 15.13, - "customerRate": 17.13, - "paymentStatus": "completed", - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "memberRate": null, + "customerRate": null, + "paymentStatus": "pending", + "createdBy": "00000000-0000-0000-0000-000000000000", "updatedBy": null, - "createdAt": "2021-03-30T19:14:43.498Z", - "updatedAt": "2021-03-30T19:14:43.498Z" + "createdAt": "2021-04-14T22:01:45.117Z", + "updatedAt": null }, { - "id": "dba9dc5a-afaa-43b2-9b7d-f0f03af81211", - "resourceBookingId": "a098e8d8-ce5b-47d9-afee-38b050d16745", - "userHandle": "TCConnCopilot", + "id": "b8390807-8ea7-4824-9f17-4500f46f893c", + "resourceBookingId": "8173579e-4b3c-418d-a9a1-c999caa38404", + "userHandle": "testcat", "projectId": 111, - "startDate": "2021-03-07", - "endDate": "2021-03-13", + "startDate": "2020-05-03", + "endDate": "2020-05-09", "daysWorked": 5, - "memberRate": 15.13, - "customerRate": 17.13, + "memberRate": null, + "customerRate": null, "paymentStatus": "pending", - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "createdBy": "00000000-0000-0000-0000-000000000000", "updatedBy": null, - "createdAt": "2021-03-30T19:14:56.991Z", - "updatedAt": "2021-03-30T19:14:56.991Z" + "createdAt": "2021-04-14T22:01:45.117Z", + "updatedAt": null }, { - "id": "d694bbea-707d-41d5-a3f4-14884ff6fbf6", + "id": "da056ecd-6660-4fd8-aba4-acc7ec089926", "resourceBookingId": "8173579e-4b3c-418d-a9a1-c999caa38404", "userHandle": "testcat", "projectId": 111, - "startDate": "2021-03-07", - "endDate": "2021-03-13", - "daysWorked": 1, - "memberRate": 10.13, - "customerRate": 18.13, + "startDate": "2020-05-10", + "endDate": "2020-05-16", + "daysWorked": 5, + "memberRate": null, + "customerRate": null, "paymentStatus": "pending", - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "createdBy": "00000000-0000-0000-0000-000000000000", "updatedBy": null, - "createdAt": "2021-03-30T19:15:16.106Z", - "updatedAt": "2021-03-30T19:15:16.106Z" + "createdAt": "2021-04-14T22:01:45.117Z", + "updatedAt": null }, { - "id": "30ff1dbe-3434-45c7-806b-0c52a41652b5", + "id": "2cd7a726-9909-4764-9f24-8d9a8f3d011a", "resourceBookingId": "8173579e-4b3c-418d-a9a1-c999caa38404", "userHandle": "testcat", "projectId": 111, - "startDate": "2021-03-14", - "endDate": "2021-03-20", - "daysWorked": 7, - "memberRate": 5.13, - "customerRate": 7.13, - "paymentStatus": "completed", - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "startDate": "2020-05-24", + "endDate": "2020-05-30", + "daysWorked": 3, + "memberRate": null, + "customerRate": null, + "paymentStatus": "pending", + "createdBy": "00000000-0000-0000-0000-000000000000", "updatedBy": null, - "createdAt": "2021-03-30T19:15:32.338Z", - "updatedAt": "2021-03-30T19:15:32.338Z" + "createdAt": "2021-04-14T22:01:45.117Z", + "updatedAt": null }, { - "id": "a974b73d-12a3-464e-ac97-a939f10a0726", - "resourceBookingId": "7d967fed-9792-4768-98a7-0b644aa84f2e", - "userHandle": "sachin-wipro", + "id": "7f646975-f984-4967-8788-f10c8db86b25", + "resourceBookingId": "d38a6223-3f91-4300-9ecb-6e5fee173625", + "userHandle": "nithyaasworld", "projectId": 111, - "startDate": "2021-03-14", - "endDate": "2021-03-20", - "daysWorked": 7, - "memberRate": 5.13, - "customerRate": 7.13, - "paymentStatus": "completed", - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "startDate": "2021-05-23", + "endDate": "2021-05-29", + "daysWorked": 4, + "memberRate": null, + "customerRate": null, + "paymentStatus": "pending", + "createdBy": "00000000-0000-0000-0000-000000000000", "updatedBy": null, - "createdAt": "2021-03-30T19:15:54.822Z", - "updatedAt": "2021-03-30T19:15:54.822Z" + "createdAt": "2021-04-14T22:01:45.120Z", + "updatedAt": null }, { - "id": "db66b486-157b-4c0c-9a6c-03bd46c0f1d1", - "resourceBookingId": "7d967fed-9792-4768-98a7-0b644aa84f2e", - "userHandle": "sachin-wipro", + "id": "459e0127-7f1b-41f6-9d62-d354ed537779", + "resourceBookingId": "d38a6223-3f91-4300-9ecb-6e5fee173625", + "userHandle": "nithyaasworld", "projectId": 111, - "startDate": "2021-03-21", - "endDate": "2021-03-27", + "startDate": "2021-05-30", + "endDate": "2021-06-05", "daysWorked": 5, - "memberRate": 2.13, - "customerRate": 7.13, + "memberRate": null, + "customerRate": null, "paymentStatus": "pending", - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "createdBy": "00000000-0000-0000-0000-000000000000", "updatedBy": null, - "createdAt": "2021-03-30T19:16:12.235Z", - "updatedAt": "2021-03-30T19:16:12.235Z" + "createdAt": "2021-04-14T22:01:45.120Z", + "updatedAt": null }, { - "id": "ec9195a6-cc81-4c7d-aa7b-5ac80a6926e8", - "resourceBookingId": "61f5d474-e41f-490b-ab58-9f983e3d4916", - "userHandle": "sonu628", + "id": "42f757a6-7bb3-48c2-a6cb-455d27a8821b", + "resourceBookingId": "d38a6223-3f91-4300-9ecb-6e5fee173625", + "userHandle": "nithyaasworld", "projectId": 111, - "startDate": "2021-03-21", - "endDate": "2021-03-27", + "startDate": "2021-06-06", + "endDate": "2021-06-12", "daysWorked": 5, - "memberRate": 2.13, - "customerRate": 7.13, + "memberRate": null, + "customerRate": null, "paymentStatus": "pending", - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "createdBy": "00000000-0000-0000-0000-000000000000", "updatedBy": null, - "createdAt": "2021-03-30T19:16:25.772Z", - "updatedAt": "2021-03-30T19:16:25.772Z" + "createdAt": "2021-04-14T22:01:45.120Z", + "updatedAt": null }, { - "id": "fd59ab02-75be-4d78-bc48-2ec35af61d41", - "resourceBookingId": "61f5d474-e41f-490b-ab58-9f983e3d4916", - "userHandle": "sonu628", + "id": "c17d9081-c442-4d55-be58-65916662653e", + "resourceBookingId": "d38a6223-3f91-4300-9ecb-6e5fee173625", + "userHandle": "nithyaasworld", "projectId": 111, - "startDate": "2021-03-28", - "endDate": "2021-04-03", - "daysWorked": 2, - "memberRate": 2.13, - "customerRate": 6.13, + "startDate": "2021-06-20", + "endDate": "2021-06-26", + "daysWorked": 5, + "memberRate": null, + "customerRate": null, "paymentStatus": "pending", - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "createdBy": "00000000-0000-0000-0000-000000000000", "updatedBy": null, - "createdAt": "2021-03-30T19:16:43.007Z", - "updatedAt": "2021-03-30T19:16:43.007Z" + "createdAt": "2021-04-14T22:01:45.120Z", + "updatedAt": null }, { - "id": "4bafda13-3319-4c46-8a31-0b9279a6e633", - "resourceBookingId": "51b45f5d-5df2-46d5-9c3d-8a1323df38dd", - "userHandle": "amy_admin", + "id": "6768d502-5510-49d0-873f-346390ccf14d", + "resourceBookingId": "d38a6223-3f91-4300-9ecb-6e5fee173625", + "userHandle": "nithyaasworld", "projectId": 111, - "startDate": "2021-03-28", - "endDate": "2021-04-03", - "daysWorked": 2, - "memberRate": 2.13, - "customerRate": 6.13, + "startDate": "2021-06-27", + "endDate": "2021-07-03", + "daysWorked": 5, + "memberRate": null, + "customerRate": null, "paymentStatus": "pending", - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "createdBy": "00000000-0000-0000-0000-000000000000", "updatedBy": null, - "createdAt": "2021-03-30T19:16:54.483Z", - "updatedAt": "2021-03-30T19:16:54.483Z" + "createdAt": "2021-04-14T22:01:45.120Z", + "updatedAt": null }, { - "id": "c4dfb0d7-1a3a-4d1a-8fa5-9fc4b555b724", - "resourceBookingId": "51b45f5d-5df2-46d5-9c3d-8a1323df38dd", - "userHandle": "amy_admin", + "id": "7808d9ac-3c93-4c3f-ad35-12a0a45d51c6", + "resourceBookingId": "d38a6223-3f91-4300-9ecb-6e5fee173625", + "userHandle": "nithyaasworld", "projectId": 111, - "startDate": "2021-04-04", - "endDate": "2021-04-10", - "daysWorked": 2, - "memberRate": 2.13, - "customerRate": 6.13, + "startDate": "2021-07-04", + "endDate": "2021-07-10", + "daysWorked": 5, + "memberRate": null, + "customerRate": null, "paymentStatus": "pending", - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "createdBy": "00000000-0000-0000-0000-000000000000", "updatedBy": null, - "createdAt": "2021-03-30T19:17:07.537Z", - "updatedAt": "2021-03-30T19:17:07.537Z" + "createdAt": "2021-04-14T22:01:45.120Z", + "updatedAt": null }, { - "id": "0d92396b-040b-43d3-b816-7fdc9d888864", - "resourceBookingId": "35e1abd8-1890-4664-bb52-aade382d7b66", - "userHandle": "lakshmiaconnmgr", + "id": "724815e6-5a66-44c7-8dd6-7a5005ec4367", + "resourceBookingId": "d38a6223-3f91-4300-9ecb-6e5fee173625", + "userHandle": "nithyaasworld", "projectId": 111, - "startDate": "2021-04-04", - "endDate": "2021-04-10", - "daysWorked": 2, - "memberRate": 2.13, - "customerRate": 6.13, + "startDate": "2021-07-11", + "endDate": "2021-07-17", + "daysWorked": 5, + "memberRate": null, + "customerRate": null, "paymentStatus": "pending", - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "createdBy": "00000000-0000-0000-0000-000000000000", "updatedBy": null, - "createdAt": "2021-03-30T19:17:20.639Z", - "updatedAt": "2021-03-30T19:17:20.639Z" + "createdAt": "2021-04-14T22:01:45.120Z", + "updatedAt": null }, { - "id": "073e179b-dae7-4dd7-9cb6-a35fd1370fca", - "resourceBookingId": "35e1abd8-1890-4664-bb52-aade382d7b66", - "userHandle": "lakshmiaconnmgr", + "id": "57210895-2e2a-46f1-a0cc-05af4c30b188", + "resourceBookingId": "d38a6223-3f91-4300-9ecb-6e5fee173625", + "userHandle": "nithyaasworld", "projectId": 111, - "startDate": "2021-04-11", - "endDate": "2021-04-17", - "daysWorked": 2, - "memberRate": 2.13, - "customerRate": 6.13, - "paymentStatus": "cancelled", - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "startDate": "2021-07-25", + "endDate": "2021-07-31", + "daysWorked": 5, + "memberRate": null, + "customerRate": null, + "paymentStatus": "pending", + "createdBy": "00000000-0000-0000-0000-000000000000", "updatedBy": null, - "createdAt": "2021-03-30T19:17:36.581Z", - "updatedAt": "2021-03-30T19:17:36.581Z" + "createdAt": "2021-04-14T22:01:45.120Z", + "updatedAt": null }, { - "id": "03b2d6e3-0448-4fbf-9f17-576b3dd94405", - "resourceBookingId": "0a6799d7-f5d1-456b-8bf1-90619284b295", - "userHandle": "aaaa", + "id": "3534343e-5b06-4299-b657-11b3b5175dce", + "resourceBookingId": "7d967fed-9792-4768-98a7-0b644aa84f2e", + "userHandle": "sachin-wipro", "projectId": 111, - "startDate": "2021-04-11", - "endDate": "2021-04-17", - "daysWorked": 4, - "memberRate": 2.13, - "customerRate": 6.13, - "paymentStatus": "cancelled", - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "startDate": "2021-03-21", + "endDate": "2021-03-27", + "daysWorked": 2, + "memberRate": null, + "customerRate": null, + "paymentStatus": "pending", + "createdBy": "00000000-0000-0000-0000-000000000000", "updatedBy": null, - "createdAt": "2021-03-30T19:17:53.085Z", - "updatedAt": "2021-03-30T19:17:53.085Z" + "createdAt": "2021-04-14T22:01:45.122Z", + "updatedAt": null }, { - "id": "99c1dba2-a70c-4f73-b19b-9e1a66fa5fd5", - "resourceBookingId": "0a6799d7-f5d1-456b-8bf1-90619284b295", - "userHandle": "aaaa", + "id": "50788ef6-73d9-455c-a5ea-44028d7b3bf2", + "resourceBookingId": "7d967fed-9792-4768-98a7-0b644aa84f2e", + "userHandle": "sachin-wipro", "projectId": 111, - "startDate": "2021-04-04", - "endDate": "2021-04-10", - "daysWorked": 4, - "memberRate": 2.13, - "customerRate": 6.13, + "startDate": "2021-03-28", + "endDate": "2021-04-03", + "daysWorked": 5, + "memberRate": null, + "customerRate": null, "paymentStatus": "pending", - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "createdBy": "00000000-0000-0000-0000-000000000000", "updatedBy": null, - "createdAt": "2021-03-30T19:18:10.763Z", - "updatedAt": "2021-03-30T19:18:10.763Z" + "createdAt": "2021-04-14T22:01:45.122Z", + "updatedAt": null }, { - "id": "854804e0-e698-424c-8cb9-cbbf885db0b6", - "resourceBookingId": "08f5e4b9-1088-496d-91a7-5b22a3583e3c", - "userHandle": "ritesh_cs", + "id": "2b2df620-fd88-4233-a0b8-242e0bb6ecb7", + "resourceBookingId": "7d967fed-9792-4768-98a7-0b644aa84f2e", + "userHandle": "sachin-wipro", "projectId": 111, "startDate": "2021-04-04", "endDate": "2021-04-10", - "daysWorked": 4, - "memberRate": 2.13, - "customerRate": 6.13, + "daysWorked": 5, + "memberRate": null, + "customerRate": null, "paymentStatus": "pending", - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "createdBy": "00000000-0000-0000-0000-000000000000", "updatedBy": null, - "createdAt": "2021-03-30T19:18:23.704Z", - "updatedAt": "2021-03-30T19:18:23.704Z" + "createdAt": "2021-04-14T22:01:45.122Z", + "updatedAt": null }, { - "id": "a2242b3d-026a-493b-b186-ca16587e5701", - "resourceBookingId": "08f5e4b9-1088-496d-91a7-5b22a3583e3c", - "userHandle": "ritesh_cs", + "id": "970a2bbc-c5b7-4be5-ae63-3d9009ccf83b", + "resourceBookingId": "7d967fed-9792-4768-98a7-0b644aa84f2e", + "userHandle": "sachin-wipro", "projectId": 111, "startDate": "2021-04-11", "endDate": "2021-04-17", - "daysWorked": 6, - "memberRate": 12.13, - "customerRate": 16.13, - "paymentStatus": "completed", - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "daysWorked": 5, + "memberRate": null, + "customerRate": null, + "paymentStatus": "pending", + "createdBy": "00000000-0000-0000-0000-000000000000", "updatedBy": null, - "createdAt": "2021-03-30T19:18:36.729Z", - "updatedAt": "2021-03-30T19:18:36.729Z" - } - ], - "WorkPeriodPayment": [ + "createdAt": "2021-04-14T22:01:45.122Z", + "updatedAt": null + }, + { + "id": "c3b83d2b-f27b-4e4d-8f87-9f324f80a9bc", + "resourceBookingId": "7d967fed-9792-4768-98a7-0b644aa84f2e", + "userHandle": "sachin-wipro", + "projectId": 111, + "startDate": "2021-04-25", + "endDate": "2021-05-01", + "daysWorked": 5, + "memberRate": null, + "customerRate": null, + "paymentStatus": "pending", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-14T22:01:45.122Z", + "updatedAt": null + }, + { + "id": "8dd12749-ef1d-4295-b050-8c3ecee1f846", + "resourceBookingId": "7d967fed-9792-4768-98a7-0b644aa84f2e", + "userHandle": "sachin-wipro", + "projectId": 111, + "startDate": "2021-05-09", + "endDate": "2021-05-15", + "daysWorked": 5, + "memberRate": null, + "customerRate": null, + "paymentStatus": "pending", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-14T22:01:45.122Z", + "updatedAt": null + }, + { + "id": "db0d8eab-13b0-4fd6-98fd-d2a82cd566ad", + "resourceBookingId": "7d967fed-9792-4768-98a7-0b644aa84f2e", + "userHandle": "sachin-wipro", + "projectId": 111, + "startDate": "2021-05-02", + "endDate": "2021-05-08", + "daysWorked": 5, + "memberRate": null, + "customerRate": null, + "paymentStatus": "completed", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-14T22:01:45.122Z", + "updatedAt": null + }, + { + "id": "278bc7a0-a242-41a4-9d00-086f5d48d5da", + "resourceBookingId": "7d967fed-9792-4768-98a7-0b644aa84f2e", + "userHandle": "sachin-wipro", + "projectId": 111, + "startDate": "2021-04-18", + "endDate": "2021-04-24", + "daysWorked": 5, + "memberRate": null, + "customerRate": null, + "paymentStatus": "cancelled", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-14T22:01:45.122Z", + "updatedAt": null + }, + { + "id": "0679b699-520b-4f8b-8eb6-a6aa53ec473c", + "resourceBookingId": "8173579e-4b3c-418d-a9a1-c999caa38404", + "userHandle": "testcat", + "projectId": 111, + "startDate": "2020-05-17", + "endDate": "2020-05-23", + "daysWorked": 5, + "memberRate": null, + "customerRate": null, + "paymentStatus": "completed", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-14T22:01:45.117Z", + "updatedAt": null + }, + { + "id": "c73aa1a0-cb32-4301-af96-5b33bdbda20f", + "resourceBookingId": "d38a6223-3f91-4300-9ecb-6e5fee173625", + "userHandle": "nithyaasworld", + "projectId": 111, + "startDate": "2021-06-13", + "endDate": "2021-06-19", + "daysWorked": 5, + "memberRate": null, + "customerRate": null, + "paymentStatus": "partially-completed", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-14T22:01:45.120Z", + "updatedAt": null + }, + { + "id": "5b0eefe1-e45d-4150-b14e-a83ce19599eb", + "resourceBookingId": "d38a6223-3f91-4300-9ecb-6e5fee173625", + "userHandle": "nithyaasworld", + "projectId": 111, + "startDate": "2021-07-18", + "endDate": "2021-07-24", + "daysWorked": 5, + "memberRate": null, + "customerRate": null, + "paymentStatus": "partially-completed", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-14T22:01:45.120Z", + "updatedAt": null + }, + { + "id": "651a97b2-8019-49b7-9a8e-4c384c0615b7", + "resourceBookingId": "7d967fed-9792-4768-98a7-0b644aa84f2e", + "userHandle": "sachin-wipro", + "projectId": 111, + "startDate": "2021-05-16", + "endDate": "2021-05-22", + "daysWorked": 5, + "memberRate": null, + "customerRate": null, + "paymentStatus": "pending", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-14T22:01:45.122Z", + "updatedAt": null + }, + { + "id": "fcdedc90-7c76-47ed-bb95-fb05ec3cd53a", + "resourceBookingId": "7d967fed-9792-4768-98a7-0b644aa84f2e", + "userHandle": "sachin-wipro", + "projectId": 111, + "startDate": "2021-05-23", + "endDate": "2021-05-29", + "daysWorked": 5, + "memberRate": null, + "customerRate": null, + "paymentStatus": "pending", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-14T22:01:45.122Z", + "updatedAt": null + }, + { + "id": "0b65d948-0232-4f32-a455-b480da63320d", + "resourceBookingId": "7d967fed-9792-4768-98a7-0b644aa84f2e", + "userHandle": "sachin-wipro", + "projectId": 111, + "startDate": "2021-05-30", + "endDate": "2021-06-05", + "daysWorked": 1, + "memberRate": null, + "customerRate": null, + "paymentStatus": "pending", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-14T22:01:45.122Z", + "updatedAt": null + }, + { + "id": "1f106c81-7a0d-4fb1-9bf4-851d450709d8", + "resourceBookingId": "61f5d474-e41f-490b-ab58-9f983e3d4916", + "userHandle": "sonu628", + "projectId": 111, + "startDate": "2000-03-26", + "endDate": "2000-04-01", + "daysWorked": 5, + "memberRate": null, + "customerRate": null, + "paymentStatus": "pending", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-14T22:01:45.324Z", + "updatedAt": null + }, + { + "id": "84a9d3e9-ee3f-495b-98de-f9fe0f6a9371", + "resourceBookingId": "61f5d474-e41f-490b-ab58-9f983e3d4916", + "userHandle": "sonu628", + "projectId": 111, + "startDate": "2000-04-09", + "endDate": "2000-04-15", + "daysWorked": 5, + "memberRate": null, + "customerRate": null, + "paymentStatus": "pending", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-14T22:01:45.324Z", + "updatedAt": null + }, + { + "id": "5f9dce2b-9426-4287-b3ab-7507ff3a2671", + "resourceBookingId": "61f5d474-e41f-490b-ab58-9f983e3d4916", + "userHandle": "sonu628", + "projectId": 111, + "startDate": "2000-04-16", + "endDate": "2000-04-22", + "daysWorked": 5, + "memberRate": null, + "customerRate": null, + "paymentStatus": "pending", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-14T22:01:45.324Z", + "updatedAt": null + }, + { + "id": "724b2338-c5bb-46ec-8e99-2417929eeab9", + "resourceBookingId": "61f5d474-e41f-490b-ab58-9f983e3d4916", + "userHandle": "sonu628", + "projectId": 111, + "startDate": "2000-04-23", + "endDate": "2000-04-29", + "daysWorked": 4, + "memberRate": null, + "customerRate": null, + "paymentStatus": "pending", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-14T22:01:45.324Z", + "updatedAt": null + }, + { + "id": "10de7920-5e12-4284-b95f-08adc0ff1c17", + "resourceBookingId": "a098e8d8-ce5b-47d9-afee-38b050d16745", + "userHandle": "TCConnCopilot", + "projectId": 111, + "startDate": "2021-04-25", + "endDate": "2021-05-01", + "daysWorked": 5, + "memberRate": null, + "customerRate": null, + "paymentStatus": "pending", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-14T22:01:45.325Z", + "updatedAt": null + }, + { + "id": "c0fb6f01-7b71-471a-b85b-ea470d4dbd85", + "resourceBookingId": "35e1abd8-1890-4664-bb52-aade382d7b66", + "userHandle": "lakshmiaconnmgr", + "projectId": 111, + "startDate": "2021-02-21", + "endDate": "2021-02-27", + "daysWorked": 2, + "memberRate": null, + "customerRate": null, + "paymentStatus": "pending", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-14T22:01:45.326Z", + "updatedAt": null + }, + { + "id": "0a3df77a-7841-4256-bb2c-d7e0fa17dc3f", + "resourceBookingId": "35e1abd8-1890-4664-bb52-aade382d7b66", + "userHandle": "lakshmiaconnmgr", + "projectId": 111, + "startDate": "2021-02-28", + "endDate": "2021-03-06", + "daysWorked": 5, + "memberRate": null, + "customerRate": null, + "paymentStatus": "pending", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-14T22:01:45.326Z", + "updatedAt": null + }, + { + "id": "9e0d10c3-f4c8-4ba6-8c11-333d9cdab634", + "resourceBookingId": "35e1abd8-1890-4664-bb52-aade382d7b66", + "userHandle": "lakshmiaconnmgr", + "projectId": 111, + "startDate": "2021-03-14", + "endDate": "2021-03-20", + "daysWorked": 5, + "memberRate": null, + "customerRate": null, + "paymentStatus": "pending", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-14T22:01:45.326Z", + "updatedAt": null + }, + { + "id": "66d47a95-a4f8-43a5-bfe2-af8f5a2b64ac", + "resourceBookingId": "35e1abd8-1890-4664-bb52-aade382d7b66", + "userHandle": "lakshmiaconnmgr", + "projectId": 111, + "startDate": "2021-03-21", + "endDate": "2021-03-27", + "daysWorked": 5, + "memberRate": null, + "customerRate": null, + "paymentStatus": "pending", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-14T22:01:45.326Z", + "updatedAt": null + }, + { + "id": "c10cca56-b0c4-4e87-a64f-9a14d7445436", + "resourceBookingId": "51b45f5d-5df2-46d5-9c3d-8a1323df38dd", + "userHandle": "amy_admin", + "projectId": 111, + "startDate": "2021-03-21", + "endDate": "2021-03-27", + "daysWorked": 5, + "memberRate": null, + "customerRate": null, + "paymentStatus": "pending", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-14T22:01:45.361Z", + "updatedAt": null + }, + { + "id": "c8d38387-b4a2-49f8-bbba-2f10f50c99db", + "resourceBookingId": "51b45f5d-5df2-46d5-9c3d-8a1323df38dd", + "userHandle": "amy_admin", + "projectId": 111, + "startDate": "2021-03-28", + "endDate": "2021-04-03", + "daysWorked": 5, + "memberRate": null, + "customerRate": null, + "paymentStatus": "pending", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-14T22:01:45.361Z", + "updatedAt": null + }, + { + "id": "07dd0d62-e5cc-49a8-8b4c-966a2348095f", + "resourceBookingId": "51b45f5d-5df2-46d5-9c3d-8a1323df38dd", + "userHandle": "amy_admin", + "projectId": 111, + "startDate": "2021-04-04", + "endDate": "2021-04-10", + "daysWorked": 5, + "memberRate": null, + "customerRate": null, + "paymentStatus": "pending", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-14T22:01:45.361Z", + "updatedAt": null + }, + { + "id": "c3c4593a-2a06-4ee8-8cbb-5a3ffad8ad7d", + "resourceBookingId": "51b45f5d-5df2-46d5-9c3d-8a1323df38dd", + "userHandle": "amy_admin", + "projectId": 111, + "startDate": "2021-04-11", + "endDate": "2021-04-17", + "daysWorked": 5, + "memberRate": null, + "customerRate": null, + "paymentStatus": "pending", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-14T22:01:45.361Z", + "updatedAt": null + }, + { + "id": "9f117273-bb2f-48ab-bf3a-c13652483ea3", + "resourceBookingId": "51b45f5d-5df2-46d5-9c3d-8a1323df38dd", + "userHandle": "amy_admin", + "projectId": 111, + "startDate": "2021-04-18", + "endDate": "2021-04-24", + "daysWorked": 5, + "memberRate": null, + "customerRate": null, + "paymentStatus": "pending", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-14T22:01:45.361Z", + "updatedAt": null + }, + { + "id": "3a909050-444a-4a82-9961-d390212e86f5", + "resourceBookingId": "51b45f5d-5df2-46d5-9c3d-8a1323df38dd", + "userHandle": "amy_admin", + "projectId": 111, + "startDate": "2021-04-25", + "endDate": "2021-05-01", + "daysWorked": 5, + "memberRate": null, + "customerRate": null, + "paymentStatus": "pending", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-14T22:01:45.361Z", + "updatedAt": null + }, + { + "id": "b9a8ac04-5b06-4093-ac50-ce556d25b421", + "resourceBookingId": "51b45f5d-5df2-46d5-9c3d-8a1323df38dd", + "userHandle": "amy_admin", + "projectId": 111, + "startDate": "2021-05-02", + "endDate": "2021-05-08", + "daysWorked": 5, + "memberRate": null, + "customerRate": null, + "paymentStatus": "pending", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-14T22:01:45.361Z", + "updatedAt": null + }, + { + "id": "a2b708d1-e234-4573-b5ca-7dc36a20c0d7", + "resourceBookingId": "51b45f5d-5df2-46d5-9c3d-8a1323df38dd", + "userHandle": "amy_admin", + "projectId": 111, + "startDate": "2021-05-16", + "endDate": "2021-05-22", + "daysWorked": 5, + "memberRate": null, + "customerRate": null, + "paymentStatus": "pending", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-14T22:01:45.361Z", + "updatedAt": null + }, + { + "id": "768051e3-9765-498f-9b58-17c3377eced8", + "resourceBookingId": "51b45f5d-5df2-46d5-9c3d-8a1323df38dd", + "userHandle": "amy_admin", + "projectId": 111, + "startDate": "2021-05-23", + "endDate": "2021-05-29", + "daysWorked": 5, + "memberRate": null, + "customerRate": null, + "paymentStatus": "pending", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-14T22:01:45.361Z", + "updatedAt": null + }, + { + "id": "d94e0c2f-15de-4d07-a098-200daaa05f54", + "resourceBookingId": "dc4477ec-07f8-4c8e-a8fe-ffe38dd290fa", + "userHandle": "nskumar278", + "projectId": 111, + "startDate": "2021-07-25", + "endDate": "2021-07-31", + "daysWorked": 4, + "memberRate": null, + "customerRate": null, + "paymentStatus": "pending", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-14T22:01:45.390Z", + "updatedAt": null + }, + { + "id": "93910ea8-28ac-40a3-91b0-35eab59405da", + "resourceBookingId": "dc4477ec-07f8-4c8e-a8fe-ffe38dd290fa", + "userHandle": "nskumar278", + "projectId": 111, + "startDate": "2021-08-01", + "endDate": "2021-08-07", + "daysWorked": 5, + "memberRate": null, + "customerRate": null, + "paymentStatus": "pending", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-14T22:01:45.390Z", + "updatedAt": null + }, + { + "id": "33561804-7a27-4cff-9e57-c09c914bbf12", + "resourceBookingId": "dc4477ec-07f8-4c8e-a8fe-ffe38dd290fa", + "userHandle": "nskumar278", + "projectId": 111, + "startDate": "2021-08-15", + "endDate": "2021-08-21", + "daysWorked": 5, + "memberRate": null, + "customerRate": null, + "paymentStatus": "pending", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-14T22:01:45.390Z", + "updatedAt": null + }, + { + "id": "2e874752-81e1-451d-b5c9-7455135daee9", + "resourceBookingId": "dc4477ec-07f8-4c8e-a8fe-ffe38dd290fa", + "userHandle": "nskumar278", + "projectId": 111, + "startDate": "2021-08-22", + "endDate": "2021-08-28", + "daysWorked": 5, + "memberRate": null, + "customerRate": null, + "paymentStatus": "pending", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-14T22:01:45.390Z", + "updatedAt": null + }, + { + "id": "3313e61b-8733-496e-9c79-9b1e3ff5e074", + "resourceBookingId": "dc4477ec-07f8-4c8e-a8fe-ffe38dd290fa", + "userHandle": "nskumar278", + "projectId": 111, + "startDate": "2021-09-12", + "endDate": "2021-09-18", + "daysWorked": 5, + "memberRate": null, + "customerRate": null, + "paymentStatus": "pending", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-14T22:01:45.390Z", + "updatedAt": null + }, + { + "id": "8019e0c4-201a-469f-901b-8e84f43f577b", + "resourceBookingId": "dc4477ec-07f8-4c8e-a8fe-ffe38dd290fa", + "userHandle": "nskumar278", + "projectId": 111, + "startDate": "2021-09-19", + "endDate": "2021-09-25", + "daysWorked": 5, + "memberRate": null, + "customerRate": null, + "paymentStatus": "pending", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-14T22:01:45.390Z", + "updatedAt": null + }, + { + "id": "2b660631-fbd0-47fb-9ab4-f4e809650e44", + "resourceBookingId": "dc4477ec-07f8-4c8e-a8fe-ffe38dd290fa", + "userHandle": "nskumar278", + "projectId": 111, + "startDate": "2021-09-26", + "endDate": "2021-10-02", + "daysWorked": 0, + "memberRate": null, + "customerRate": null, + "paymentStatus": "pending", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-14T22:01:45.390Z", + "updatedAt": null + }, + { + "id": "f93b73e0-25eb-4c67-a6f0-1b658186ae29", + "resourceBookingId": "0a6799d7-f5d1-456b-8bf1-90619284b295", + "userHandle": "aaaa", + "projectId": 111, + "startDate": "2021-02-21", + "endDate": "2021-02-27", + "daysWorked": 0, + "memberRate": null, + "customerRate": null, + "paymentStatus": "pending", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-14T22:01:45.523Z", + "updatedAt": null + }, + { + "id": "e2d7651c-b8b6-453a-b472-478fe679a22f", + "resourceBookingId": "0a6799d7-f5d1-456b-8bf1-90619284b295", + "userHandle": "aaaa", + "projectId": 111, + "startDate": "2021-02-28", + "endDate": "2021-03-06", + "daysWorked": 5, + "memberRate": null, + "customerRate": null, + "paymentStatus": "pending", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-14T22:01:45.523Z", + "updatedAt": null + }, + { + "id": "0ed89458-ab82-485e-9727-858e7c25d477", + "resourceBookingId": "0a6799d7-f5d1-456b-8bf1-90619284b295", + "userHandle": "aaaa", + "projectId": 111, + "startDate": "2021-03-14", + "endDate": "2021-03-20", + "daysWorked": 1, + "memberRate": null, + "customerRate": null, + "paymentStatus": "pending", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-14T22:01:45.523Z", + "updatedAt": null + }, + { + "id": "c1de1dd6-64b9-4dc6-b463-48c280a01465", + "resourceBookingId": "0a6799d7-f5d1-456b-8bf1-90619284b295", + "userHandle": "aaaa", + "projectId": 111, + "startDate": "2021-03-07", + "endDate": "2021-03-13", + "daysWorked": 5, + "memberRate": null, + "customerRate": null, + "paymentStatus": "completed", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-14T22:01:45.523Z", + "updatedAt": null + }, + { + "id": "4b5ce032-7c8d-423a-bec3-f469cb869088", + "resourceBookingId": "35e1abd8-1890-4664-bb52-aade382d7b66", + "userHandle": "lakshmiaconnmgr", + "projectId": 111, + "startDate": "2021-03-28", + "endDate": "2021-04-03", + "daysWorked": 4, + "memberRate": null, + "customerRate": null, + "paymentStatus": "partially-completed", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-14T22:01:45.326Z", + "updatedAt": null + }, + { + "id": "1b5e7460-c197-4f38-8f53-80e651ee32fe", + "resourceBookingId": "35e1abd8-1890-4664-bb52-aade382d7b66", + "userHandle": "lakshmiaconnmgr", + "projectId": 111, + "startDate": "2021-03-07", + "endDate": "2021-03-13", + "daysWorked": 5, + "memberRate": null, + "customerRate": null, + "paymentStatus": "cancelled", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-14T22:01:45.326Z", + "updatedAt": null + }, + { + "id": "6aae6de0-0f64-4af6-a4a4-a9920cf873fa", + "resourceBookingId": "51b45f5d-5df2-46d5-9c3d-8a1323df38dd", + "userHandle": "amy_admin", + "projectId": 111, + "startDate": "2021-03-14", + "endDate": "2021-03-20", + "daysWorked": 2, + "memberRate": null, + "customerRate": null, + "paymentStatus": "completed", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-14T22:01:45.361Z", + "updatedAt": null + }, + { + "id": "87f41144-95d3-427d-b5bf-161250a6b9e4", + "resourceBookingId": "51b45f5d-5df2-46d5-9c3d-8a1323df38dd", + "userHandle": "amy_admin", + "projectId": 111, + "startDate": "2021-05-09", + "endDate": "2021-05-15", + "daysWorked": 5, + "memberRate": null, + "customerRate": null, + "paymentStatus": "completed", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-14T22:01:45.361Z", + "updatedAt": null + }, + { + "id": "06fda3ca-e583-4466-baeb-70dac8952151", + "resourceBookingId": "61f5d474-e41f-490b-ab58-9f983e3d4916", + "userHandle": "sonu628", + "projectId": 111, + "startDate": "2000-04-02", + "endDate": "2000-04-08", + "daysWorked": 5, + "memberRate": null, + "customerRate": null, + "paymentStatus": "partially-completed", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-14T22:01:45.324Z", + "updatedAt": null + }, + { + "id": "2530239e-fcd7-43a1-81ca-1df38e8744fc", + "resourceBookingId": "dc4477ec-07f8-4c8e-a8fe-ffe38dd290fa", + "userHandle": "nskumar278", + "projectId": 111, + "startDate": "2021-08-29", + "endDate": "2021-09-04", + "daysWorked": 5, + "memberRate": null, + "customerRate": null, + "paymentStatus": "completed", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-14T22:01:45.390Z", + "updatedAt": null + }, + { + "id": "7f58f304-800f-4304-9aa1-21c7c5aad882", + "resourceBookingId": "dc4477ec-07f8-4c8e-a8fe-ffe38dd290fa", + "userHandle": "nskumar278", + "projectId": 111, + "startDate": "2021-09-05", + "endDate": "2021-09-11", + "daysWorked": 5, + "memberRate": null, + "customerRate": null, + "paymentStatus": "cancelled", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-14T22:01:45.390Z", + "updatedAt": null + }, + { + "id": "08b5fc47-0e40-48d5-be46-24ecfd9031b5", + "resourceBookingId": "dc4477ec-07f8-4c8e-a8fe-ffe38dd290fa", + "userHandle": "nskumar278", + "projectId": 111, + "startDate": "2021-08-08", + "endDate": "2021-08-14", + "daysWorked": 5, + "memberRate": null, + "customerRate": null, + "paymentStatus": "completed", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-04-14T22:01:45.390Z", + "updatedAt": null + } + ], + "WorkPeriodPayment": [ { "id": "2a122a93-e778-4eb9-868c-5f38b8b9bb4e", - "workPeriodId": "80b85cbb-3064-45aa-bb75-9dc010848fc1", + "workPeriodId": "db3ac57b-8e78-4b68-a0f7-4e928f3059af", "challengeId": "25a7c442-427b-4b6d-9c41-112dbd420c0d", "amount": 800, "status": "completed", "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", "updatedBy": null, - "createdAt": "2021-04-12T19:13:23.714Z", - "updatedAt": "2021-04-12T19:13:23.714Z" + "createdAt": "2021-04-14T19:13:23.714Z", + "updatedAt": null + }, + { + "id": "2417df2c-8e29-4868-aeb8-5ec0ff67713e", + "workPeriodId": "a6c83e0d-de12-42f2-b689-85ad56470941", + "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": null + }, + { + "id": "8ca85158-a850-4cae-97f0-5873a9225ff8", + "workPeriodId": "5342924e-a1ed-4164-a885-7ebb87215aa5", + "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": null + }, + { + "id": "5116d4ea-2c1a-4be6-b335-bd531b8d5734", + "workPeriodId": "b8390807-8ea7-4824-9f17-4500f46f893c", + "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": "8fad32f7-cb40-416f-ab24-86cf1c7870ef", + "workPeriodId": "da056ecd-6660-4fd8-aba4-acc7ec089926", + "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": null + }, + { + "id": "298ac627-e6d7-47b0-ad1d-83de291addf7", + "workPeriodId": "2cd7a726-9909-4764-9f24-8d9a8f3d011a", + "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": "e8aee371-1f26-4475-8459-9c134fa6f3c6", + "workPeriodId": "7f646975-f984-4967-8788-f10c8db86b25", + "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": null + }, + { + "id": "4ce8cf4a-2585-4454-81d4-e5446c9a3f75", + "workPeriodId": "459e0127-7f1b-41f6-9d62-d354ed537779", + "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": "11c07a5c-a077-4719-83ba-c48db7e63c01", + "workPeriodId": "42f757a6-7bb3-48c2-a6cb-455d27a8821b", + "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": null + }, + { + "id": "b8d44e83-922c-4c2c-8567-5764794e03f3", + "workPeriodId": "c17d9081-c442-4d55-be58-65916662653e", + "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": "f950e52e-5a52-4ee8-af5f-e6c42e9b400b", + "workPeriodId": "6768d502-5510-49d0-873f-346390ccf14d", + "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": null + }, + { + "id": "9fe78619-5c1c-4b22-8d6f-ebf9a9502432", + "workPeriodId": "7808d9ac-3c93-4c3f-ad35-12a0a45d51c6", + "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": null + }, + { + "id": "09ea6f03-4489-496c-817c-e9279a58c0ad", + "workPeriodId": "724815e6-5a66-44c7-8dd6-7a5005ec4367", + "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": null + }, + { + "id": "4a81c6a3-18d9-441b-ae64-3aa9def336ef", + "workPeriodId": "57210895-2e2a-46f1-a0cc-05af4c30b188", + "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": "cb94d710-fa3c-4333-b8a9-39ec053a665d", + "workPeriodId": "3534343e-5b06-4299-b657-11b3b5175dce", + "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": null + }, + { + "id": "5192e519-30f5-42d6-877f-5c2b786d91c7", + "workPeriodId": "50788ef6-73d9-455c-a5ea-44028d7b3bf2", + "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": "58c6431a-061a-41bd-a3bd-c8effba62e11", + "workPeriodId": "2b2df620-fd88-4233-a0b8-242e0bb6ecb7", + "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": null + }, + { + "id": "56cb3aef-531b-4a26-817e-4b9629212c9a", + "workPeriodId": "970a2bbc-c5b7-4be5-ae63-3d9009ccf83b", + "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": null + }, + { + "id": "fda2013c-da68-4601-8d13-d0f4cffd081c", + "workPeriodId": "c3b83d2b-f27b-4e4d-8f87-9f324f80a9bc", + "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": null }, { - "id": "2417df2c-8e29-4868-aeb8-5ec0ff67713e", - "workPeriodId": "9b0765ef-4e20-4cb2-91f1-ce8d7bcd8062", - "challengeId": "f01ba8da-c891-472d-9ed6-74b91ed9b407", - "amount": 400, + "id": "8c9ed23c-12c7-4a8b-8e91-6fd3b3fc43a4", + "workPeriodId": "8dd12749-ef1d-4295-b050-8c3ecee1f846", + "challengeId": "0de972b8-6cc9-4625-9760-1c77561c29e9", + "amount": 450, "status": "completed", "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", "updatedBy": null, - "createdAt": "2021-04-12T19:13:23.714Z", - "updatedAt": "2021-04-12T19:13:23.714Z" + "createdAt": "2021-04-14T19:13:23.714Z", + "updatedAt": null }, { - "id": "8ca85158-a850-4cae-97f0-5873a9225ff8", - "workPeriodId": "5796eecf-cc4f-42c2-a25b-7af4710847d6", - "challengeId": "b42b8f40-9a4d-45d1-814e-59da5c7a1fd9", + "id": "310384cb-6e85-4f7d-a6d2-8c03ca27871d", + "workPeriodId": "db0d8eab-13b0-4fd6-98fd-d2a82cd566ad", + "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": null + }, + { + "id": "cc13acfd-fc06-40e5-aefe-5050429ee4f2", + "workPeriodId": "278bc7a0-a242-41a4-9d00-086f5d48d5da", + "challengeId": "0de972b8-6cc9-4625-9760-1c77561c29e9", "amount": 1200, "status": "completed", "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", "updatedBy": null, - "createdAt": "2021-04-12T19:13:23.714Z", - "updatedAt": "2021-04-12T19:13:23.714Z" + "createdAt": "2021-04-14T19:13:23.714Z", + "updatedAt": null }, { - "id": "5116d4ea-2c1a-4be6-b335-bd531b8d5734", - "workPeriodId": "dba9dc5a-afaa-43b2-9b7d-f0f03af81211", - "challengeId": "b42b8f40-9a4d-45d1-814e-59da5c7a1fd9", - "amount": 600, + "id": "2c488b36-0868-4db6-8978-20b1ce174496", + "workPeriodId": "0679b699-520b-4f8b-8eb6-a6aa53ec473c", + "challengeId": "0de972b8-6cc9-4625-9760-1c77561c29e9", + "amount": 200, "status": "completed", "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "createdAt": "2021-04-12T19:13:23.714Z", - "updatedAt": "2021-04-14T19:13:23.714Z" + "updatedBy": null, + "createdAt": "2021-04-14T19:13:23.714Z", + "updatedAt": null }, { - "id": "8fad32f7-cb40-416f-ab24-86cf1c7870ef", - "workPeriodId": "d694bbea-707d-41d5-a3f4-14884ff6fbf6", - "challengeId": "f7e40a0c-a302-4989-a3bd-7587fee3c367", + "id": "efa8cd14-c93f-4e6c-be53-596f02db8c96", + "workPeriodId": "c73aa1a0-cb32-4301-af96-5b33bdbda20f", + "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": null + }, + { + "id": "a26b8cae-a1df-4843-a192-0735f235bf78", + "workPeriodId": "5b0eefe1-e45d-4150-b14e-a83ce19599eb", + "challengeId": "0de972b8-6cc9-4625-9760-1c77561c29e9", "amount": 600, "status": "completed", "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", "updatedBy": null, - "createdAt": "2021-04-12T19:13:23.714Z", - "updatedAt": "2021-04-12T19:13:23.714Z" + "createdAt": "2021-04-14T19:13:23.714Z", + "updatedAt": null }, { - "id": "298ac627-e6d7-47b0-ad1d-83de291addf7", - "workPeriodId": "30ff1dbe-3434-45c7-806b-0c52a41652b5", - "challengeId": "f7e40a0c-a302-4989-a3bd-7587fee3c367", + "id": "eb63dfc7-14d7-4cae-a25e-3e33a04601cf", + "workPeriodId": "651a97b2-8019-49b7-9a8e-4c384c0615b7", + "challengeId": "0de972b8-6cc9-4625-9760-1c77561c29e9", "amount": 300, - "status": "cancelled", + "status": "completed", "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "createdAt": "2021-04-12T19:13:23.714Z", - "updatedAt": "2021-04-14T19:13:23.714Z" + "updatedBy": null, + "createdAt": "2021-04-14T19:13:23.714Z", + "updatedAt": null }, { - "id": "e8aee371-1f26-4475-8459-9c134fa6f3c6", - "workPeriodId": "a974b73d-12a3-464e-ac97-a939f10a0726", - "challengeId": "ee9bcdd0-0d0d-4414-88cb-d14255f996a5", - "amount": 700, - "status": "cancelled", + "id": "11ea987f-f218-4d2b-b656-0741208539f2", + "workPeriodId": "fcdedc90-7c76-47ed-bb95-fb05ec3cd53a", + "challengeId": "0de972b8-6cc9-4625-9760-1c77561c29e9", + "amount": 600, + "status": "completed", "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", "updatedBy": null, - "createdAt": "2021-04-12T19:13:23.714Z", - "updatedAt": "2021-04-12T19:13:23.714Z" + "createdAt": "2021-04-16T19:13:23.714Z", + "updatedAt": null }, { - "id": "4ce8cf4a-2585-4454-81d4-e5446c9a3f75", - "workPeriodId": "db66b486-157b-4c0c-9a6c-03bd46c0f1d1", - "challengeId": "ee9bcdd0-0d0d-4414-88cb-d14255f996a5", - "amount": 350, + "id": "b342d615-d36d-48b2-a3e8-1f498b58ab68", + "workPeriodId": "0b65d948-0232-4f32-a455-b480da63320d", + "challengeId": "0de972b8-6cc9-4625-9760-1c77561c29e9", + "amount": 400, "status": "completed", "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "createdAt": "2021-04-12T19:13:23.714Z", - "updatedAt": "2021-04-14T19:13:23.714Z" + "updatedBy": null, + "createdAt": "2021-04-16T19:13:23.714Z", + "updatedAt": null }, { - "id": "11c07a5c-a077-4719-83ba-c48db7e63c01", - "workPeriodId": "ec9195a6-cc81-4c7d-aa7b-5ac80a6926e8", - "challengeId": "d7c21199-a435-41b8-a2ac-5e5bdd021c5e", + "id": "84c1c956-e03d-4e19-a5a8-a4086c9658eb", + "workPeriodId": "1f106c81-7a0d-4fb1-9bf4-851d450709d8", + "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": null + }, + { + "id": "c4e316ca-a46f-4fbc-96a6-6fe6665c3b49", + "workPeriodId": "84a9d3e9-ee3f-495b-98de-f9fe0f6a9371", + "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": null + }, + { + "id": "a94b6f43-de89-4fd2-9a1d-d8a2cce02702", + "workPeriodId": "5f9dce2b-9426-4287-b3ab-7507ff3a2671", + "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": null + }, + { + "id": "7d782624-243e-497b-90ca-cc00ae29ebf2", + "workPeriodId": "724b2338-c5bb-46ec-8e99-2417929eeab9", + "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": null + }, + { + "id": "8a0c0877-b88a-420b-a3f7-645c18793b4b", + "workPeriodId": "10de7920-5e12-4284-b95f-08adc0ff1c17", + "challengeId": "4332acc6-3a33-4b7b-af4c-bd2c1ffcfb8e", "amount": 1400, - "status": "cancelled", + "status": "completed", "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", "updatedBy": null, - "createdAt": "2021-04-12T19:13:23.714Z", - "updatedAt": "2021-04-12T19:13:23.714Z" + "createdAt": "2021-04-14T22:01:45.325Z", + "updatedAt": null }, { - "id": "b8d44e83-922c-4c2c-8567-5764794e03f3", - "workPeriodId": "fd59ab02-75be-4d78-bc48-2ec35af61d41", - "challengeId": "d7c21199-a435-41b8-a2ac-5e5bdd021c5e", + "id": "dd9c842a-f577-43c2-8f17-cc940f26f0d8", + "workPeriodId": "c0fb6f01-7b71-471a-b85b-ea470d4dbd85", + "challengeId": "b67cbbc5-3384-4ea6-8504-d3fe83a6e238", "amount": 700, "status": "completed", "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "createdAt": "2021-04-12T19:13:23.714Z", - "updatedAt": "2021-04-14T19:13:23.714Z" + "updatedBy": null, + "createdAt": "2021-04-14T22:01:45.326Z", + "updatedAt": null }, { - "id": "f950e52e-5a52-4ee8-af5f-e6c42e9b400b", - "workPeriodId": "4bafda13-3319-4c46-8a31-0b9279a6e633", - "challengeId": "6c04d456-bb38-43c8-a538-f5cc6caaa540", + "id": "58681a3e-2266-4153-afd5-7be218966da2", + "workPeriodId": "0a3df77a-7841-4256-bb2c-d7e0fa17dc3f", + "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": null + }, + { + "id": "a1ffc559-703a-4c35-8ba3-73a03c3454af", + "workPeriodId": "9e0d10c3-f4c8-4ba6-8c11-333d9cdab634", + "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": null + }, + { + "id": "d827ed01-5153-4774-8450-bace2521a6d1", + "workPeriodId": "66d47a95-a4f8-43a5-bfe2-af8f5a2b64ac", + "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": null + }, + { + "id": "7e41ca7f-d3c0-4d70-9daf-ee52c93695c7", + "workPeriodId": "c10cca56-b0c4-4e87-a64f-9a14d7445436", + "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": null + }, + { + "id": "eb9c9a83-fe94-4f51-b9f0-c2d9671e87f6", + "workPeriodId": "c8d38387-b4a2-49f8-bbba-2f10f50c99db", + "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": null + }, + { + "id": "d0f61c2d-271c-48b2-8416-50c1c32ad32b", + "workPeriodId": "07dd0d62-e5cc-49a8-8b4c-966a2348095f", + "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": null + }, + { + "id": "be07bfc8-032c-41f7-a247-a4724f65617c", + "workPeriodId": "c3c4593a-2a06-4ee8-8cbb-5a3ffad8ad7d", + "challengeId": "45e33cee-7c83-4288-8187-6858b0c759eb", "amount": 800, "status": "completed", "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", "updatedBy": null, - "createdAt": "2021-04-12T19:13:23.714Z", - "updatedAt": "2021-04-12T19:13:23.714Z" + "createdAt": "2021-04-14T22:01:45.361Z", + "updatedAt": null }, { - "id": "9fe78619-5c1c-4b22-8d6f-ebf9a9502432", - "workPeriodId": "c4dfb0d7-1a3a-4d1a-8fa5-9fc4b555b724", - "challengeId": "6c04d456-bb38-43c8-a538-f5cc6caaa540", + "id": "a5904ae3-7524-4709-b798-20c4a2193f10", + "workPeriodId": "9f117273-bb2f-48ab-bf3a-c13652483ea3", + "challengeId": "ed56a1c7-a965-4ab6-9cf0-0d7c14cd7db3", "amount": 400, "status": "completed", "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", "updatedBy": null, - "createdAt": "2021-04-12T19:13:23.714Z", - "updatedAt": "2021-04-12T19:13:23.714Z" + "createdAt": "2021-04-14T22:01:45.361Z", + "updatedAt": null }, { - "id": "09ea6f03-4489-496c-817c-e9279a58c0ad", - "workPeriodId": "0d92396b-040b-43d3-b816-7fdc9d888864", - "challengeId": "78154e5c-feed-4dbf-84ec-775395139211", - "amount": 400, + "id": "155eaab2-ef74-484c-b1d7-6534dde58b66", + "workPeriodId": "3a909050-444a-4a82-9961-d390212e86f5", + "challengeId": "5ba2d9df-b3ba-4f5f-bee5-228eb46b2c37", + "amount": 600, "status": "completed", "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", "updatedBy": null, - "createdAt": "2021-04-12T19:13:23.714Z", - "updatedAt": "2021-04-12T19:13:23.714Z" + "createdAt": "2021-04-14T22:01:45.361Z", + "updatedAt": null }, { - "id": "4a81c6a3-18d9-441b-ae64-3aa9def336ef", - "workPeriodId": "073e179b-dae7-4dd7-9cb6-a35fd1370fca", - "challengeId": "78154e5c-feed-4dbf-84ec-775395139211", - "amount": 200, + "id": "8fdfe90b-2155-4a71-a610-4689106ced34", + "workPeriodId": "b9a8ac04-5b06-4093-ac50-ce556d25b421", + "challengeId": "963784fd-4174-458c-a311-a5b8333d66ab", + "amount": 300, "status": "completed", "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "createdAt": "2021-04-12T19:13:23.714Z", - "updatedAt": "2021-04-14T19:13:23.714Z" + "updatedBy": null, + "createdAt": "2021-04-14T22:01:45.361Z", + "updatedAt": null }, { - "id": "cb94d710-fa3c-4333-b8a9-39ec053a665d", - "workPeriodId": "03b2d6e3-0448-4fbf-9f17-576b3dd94405", - "challengeId": "93f594e9-5396-416a-8212-87bee614a38f", + "id": "821b38e8-657d-4f72-b27a-dd975c506ced", + "workPeriodId": "a2b708d1-e234-4573-b5ca-7dc36a20c0d7", + "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": null + }, + { + "id": "11918ff9-5f18-445d-ae90-762b3ebe44ca", + "workPeriodId": "768051e3-9765-498f-9b58-17c3377eced8", + "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": null + }, + { + "id": "c20796c8-76b0-40e8-9bee-db406c93daaf", + "workPeriodId": "d94e0c2f-15de-4d07-a098-200daaa05f54", + "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": null + }, + { + "id": "621d793b-0ead-4d99-a119-e32af526ece7", + "workPeriodId": "93910ea8-28ac-40a3-91b0-35eab59405da", + "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": null + }, + { + "id": "491f6e93-e80f-46eb-9637-ee84fe7ace9b", + "workPeriodId": "33561804-7a27-4cff-9e57-c09c914bbf12", + "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": null + }, + { + "id": "bf80eca9-8323-4f96-9a3b-8553d6f1e0ce", + "workPeriodId": "2e874752-81e1-451d-b5c9-7455135daee9", + "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": null + }, + { + "id": "338d2d7d-2c59-4513-b560-55e8982fd7c7", + "workPeriodId": "3313e61b-8733-496e-9c79-9b1e3ff5e074", + "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": null + }, + { + "id": "dec8615b-c823-4fff-bc77-fa0614b8d09c", + "workPeriodId": "8019e0c4-201a-469f-901b-8e84f43f577b", + "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": null + }, + { + "id": "efe0e4b5-e6dd-4c1a-a0e5-1f5e0ff91df9", + "workPeriodId": "2b660631-fbd0-47fb-9ab4-f4e809650e44", + "challengeId": "01332fa9-0505-416d-9084-39b136dbd300", "amount": 1200, "status": "completed", "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", "updatedBy": null, - "createdAt": "2021-04-12T19:13:23.714Z", - "updatedAt": "2021-04-12T19:13:23.714Z" + "createdAt": "2021-04-14T22:01:45.390Z", + "updatedAt": null }, { - "id": "5192e519-30f5-42d6-877f-5c2b786d91c7", - "workPeriodId": "99c1dba2-a70c-4f73-b19b-9e1a66fa5fd5", - "challengeId": "93f594e9-5396-416a-8212-87bee614a38f", + "id": "50f7a6fa-a04d-4873-8fd0-037be2f14425", + "workPeriodId": "f93b73e0-25eb-4c67-a6f0-1b658186ae29", + "challengeId": "419fbb3d-921d-4613-a87e-337f38d21885", "amount": 600, - "status": "cancelled", + "status": "completed", "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "createdAt": "2021-04-12T19:13:23.714Z", - "updatedAt": "2021-04-14T19:13:23.714Z" + "updatedBy": null, + "createdAt": "2021-04-14T22:01:45.523Z", + "updatedAt": null }, { - "id": "58c6431a-061a-41bd-a3bd-c8effba62e11", - "workPeriodId": "854804e0-e698-424c-8cb9-cbbf885db0b6", - "challengeId": "0de972b8-6cc9-4625-9760-1c77561c29e9", + "id": "767897c3-bbc2-4b1a-9843-5a6bd82e29b0", + "workPeriodId": "e2d7651c-b8b6-453a-b472-478fe679a22f", + "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": null + }, + { + "id": "63cec011-7714-4ab6-944f-e76b9fa2bd1a", + "workPeriodId": "0ed89458-ab82-485e-9727-858e7c25d477", + "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": null + }, + { + "id": "c117de76-965f-4069-aefb-8dd97f95112c", + "workPeriodId": "c1de1dd6-64b9-4dc6-b463-48c280a01465", + "challengeId": "59d08064-e1b4-4e78-82d8-b2d7ffa6f0b1", "amount": 900, "status": "completed", "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", "updatedBy": null, - "createdAt": "2021-04-12T19:13:23.714Z", - "updatedAt": "2021-04-12T19:13:23.714Z" + "createdAt": "2021-04-14T22:01:45.523Z", + "updatedAt": null }, { - "id": "56cb3aef-531b-4a26-817e-4b9629212c9a", - "workPeriodId": "a2242b3d-026a-493b-b186-ca16587e5701", - "challengeId": "0de972b8-6cc9-4625-9760-1c77561c29e9", + "id": "8ff6188f-b4e6-4f6e-b2d4-2a622ae50c4f", + "workPeriodId": "4b5ce032-7c8d-423a-bec3-f469cb869088", + "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": null + }, + { + "id": "04ef47ac-8f4d-402f-b9fd-48b2b1d9003d", + "workPeriodId": "1b5e7460-c197-4f38-8f53-80e651ee32fe", + "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": null + }, + { + "id": "283f9c3b-7f0a-4792-9661-ced7cbdb340d", + "workPeriodId": "6aae6de0-0f64-4af6-a4a4-a9920cf873fa", + "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": null + }, + { + "id": "12b0bcfc-59ae-478c-bb32-cb18d1d0244c", + "workPeriodId": "87f41144-95d3-427d-b5bf-161250a6b9e4", + "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": null + }, + { + "id": "2519d7f9-81c8-448c-aec2-aa78d6d6a962", + "workPeriodId": "06fda3ca-e583-4466-baeb-70dac8952151", + "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": null + }, + { + "id": "c051c3da-34bb-4deb-8921-04e5d2fa0bcc", + "workPeriodId": "2530239e-fcd7-43a1-81ca-1df38e8744fc", + "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": null + }, + { + "id": "7cf85ce0-ef8c-4152-8623-9a1325db6daa", + "workPeriodId": "7f58f304-800f-4304-9aa1-21c7c5aad882", + "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": null + }, + { + "id": "90bb43bd-d9e7-4eab-a46b-ab03338be11a", + "workPeriodId": "08b5fc47-0e40-48d5-be46-24ecfd9031b5", + "challengeId": "8b6f4040-d7ae-4264-b60b-b1171c9365e4", + "amount": 400, "status": "completed", "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", "updatedBy": null, - "createdAt": "2021-04-12T19:13:23.714Z", - "updatedAt": "2021-04-12T19:13:23.714Z" + "createdAt": "2021-04-14T22:01:45.390Z", + "updatedAt": null } ] } \ No newline at end of file diff --git a/docs/Topcoder-bookings-api.postman_collection.json b/docs/Topcoder-bookings-api.postman_collection.json index a9656ae2..6cdbf90d 100644 --- a/docs/Topcoder-bookings-api.postman_collection.json +++ b/docs/Topcoder-bookings-api.postman_collection.json @@ -1,6 +1,6 @@ { "info": { - "_postman_id": "52663e69-16cf-4008-a2db-f38843466ac5", + "_postman_id": "32005d60-0e18-458a-805a-643b477d08c4", "name": "Topcoder-bookings-api", "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json" }, @@ -2819,58 +2819,117 @@ "name": "Resource Bookings", "item": [ { - "name": "create resource booking with booking manager", - "event": [ + "name": "Before Test", + "item": [ { - "listen": "test", - "script": { - "exec": [ - "var data = JSON.parse(responseBody);\r", - "postman.setEnvironmentVariable(\"resourceBookingId\",data.id);" + "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" + } ], - "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-27T04:17:23.131Z\",\r\n \"endDate\": \"2020-09-27T04:17:23.131Z\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\"\r\n}", - "options": { - "raw": { - "language": "json" + "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": [] }, - "url": { - "raw": "{{URL}}/resourceBookings", - "host": [ - "{{URL}}" + { + "name": "create job with m2m", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var data = JSON.parse(responseBody);\r", + "postman.setEnvironmentVariable(\"jobIdCreatedByM2M\",data.id);" + ], + "type": "text/javascript" + } + } ], - "path": [ - "resourceBookings" - ] + "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": [] } - }, - "response": [] + ] }, { - "name": "create resource booking with m2m create", + "name": "create resource booking with booking manager", "event": [ { "listen": "test", "script": { "exec": [ - "var data = JSON.parse(responseBody);\r", - "postman.setEnvironmentVariable(\"resourceBookingIdCreatedByM2M\",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(\"resourceBookingId\", response.id);\r", + " }\r", + "});" ], "type": "text/javascript" } @@ -2882,12 +2941,12 @@ { "key": "Authorization", "type": "text", - "value": "Bearer {{token_m2m_create_resource_booking}}" + "value": "Bearer {{token_bookingManager}}" } ], "body": { "mode": "raw", - "raw": "{\r\n \"projectId\": {{projectId}},\r\n \"userId\": \"a55fe1bc-1754-45fa-9adc-cf3d6d7c377a\",\r\n \"jobId\": \"{{jobIdCreatedByM2M}}\",\r\n \"startDate\": \"2020-09-27T04:17:23.131Z\",\r\n \"endDate\": \"2020-09-27T04:17:23.131Z\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\"\r\n}", + "raw": "{\r\n \"projectId\": {{projectId}},\r\n \"userId\": \"a55fe1bc-1754-45fa-9adc-cf3d6d7c377a\",\r\n \"jobId\": \"{{jobId}}\",\r\n \"startDate\": \"2020-09-27T04:17:23.131Z\",\r\n \"endDate\": \"2020-10-27T04:17:23.131Z\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\"\r\n}", "options": { "raw": { "language": "json" @@ -2907,57 +2966,109 @@ "response": [] }, { - "name": "create resource booking with connect user", + "name": "search work periods of newly created resource booking", "event": [ { "listen": "test", "script": { "exec": [ - "var data = JSON.parse(responseBody);\r", - "postman.setEnvironmentVariable(\"resourceBookingId\",data.id);" + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", + "});" ], "type": "text/javascript" } } ], "request": { - "method": "POST", + "method": "GET", "header": [ { "key": "Authorization", "type": "text", - "value": "Bearer {{token_connectUser}}" + "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-27T04:17:23.131Z\",\r\n \"endDate\": \"2020-09-27T04:17:23.131Z\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\"\r\n}", - "options": { - "raw": { - "language": "json" - } - } - }, "url": { - "raw": "{{URL}}/resourceBookings", + "raw": "{{URL}}/work-periods?sortBy=startDate&sortOrder=asc&resourceBookingId={{resourceBookingId}}", "host": [ "{{URL}}" ], "path": [ - "resourceBookings" + "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 member", + "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" } @@ -2969,12 +3080,12 @@ { "key": "Authorization", "type": "text", - "value": "Bearer {{token_member}}" + "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\": \"{{jobId}}\",\r\n \"startDate\": \"2020-09-27T04:17:23.131Z\",\r\n \"endDate\": \"2020-09-27T04:17:23.131Z\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\"\r\n}", + "raw": "{\r\n \"projectId\": {{projectId}},\r\n \"userId\": \"a55fe1bc-1754-45fa-9adc-cf3d6d7c377a\",\r\n \"jobId\": \"{{jobIdCreatedByM2M}}\",\r\n \"startDate\": \"2020-12-27T04:17:23.131Z\",\r\n \"endDate\": \"2021-01-27T04:17:23.131Z\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\"\r\n}", "options": { "raw": { "language": "json" @@ -2994,73 +3105,124 @@ "response": [] }, { - "name": "create resource booking with user id not exist", + "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": "POST", + "method": "GET", "header": [ { "key": "Authorization", "type": "text", - "value": "Bearer {{token_userId_not_exist}}" + "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-27T04:17:23.131Z\",\r\n \"endDate\": \"2020-09-27T04:17:23.131Z\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\"\r\n}", - "options": { - "raw": { - "language": "json" - } - } - }, "url": { - "raw": "{{URL}}/resourceBookings", + "raw": "{{URL}}/work-periods?sortBy=startDate&sortOrder=asc&resourceBookingId={{resourceBookingIdCreatedByM2M}}", "host": [ "{{URL}}" ], "path": [ - "resourceBookings" - ] - } - }, - "response": [] - }, - { - "name": "create resource booking with invalid token", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "POST", + "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 invalid_token" + "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-27T04:17:23.131Z\",\r\n \"endDate\": \"2020-09-27T04:17:23.131Z\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\"\r\n}", + "raw": "{\r\n \"projectId\": {{projectId}},\r\n \"userId\": \"a55fe1bc-1754-45fa-9adc-cf3d6d7c377a\",\r\n \"jobId\": \"{{jobId}}\",\r\n \"startDate\": \"2020-09-27T04:17:23.131Z\",\r\n \"endDate\": \"2020-09-28T04:17:23.131Z\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\"\r\n}", "options": { "raw": { "language": "json" @@ -3080,92 +3242,168 @@ "response": [] }, { - "name": "get resource booking with booking manager", + "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": "GET", + "method": "POST", "header": [ { "key": "Authorization", "type": "text", - "value": "Bearer {{token_bookingManager}}" + "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-27T04:17:23.131Z\",\r\n \"endDate\": \"2020-09-28T04:17:23.131Z\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, "url": { - "raw": "{{URL}}/resourceBookings/{{resourceBookingId}}", + "raw": "{{URL}}/resourceBookings", "host": [ "{{URL}}" ], "path": [ - "resourceBookings", - "{{resourceBookingId}}" + "resourceBookings" ] } }, "response": [] }, { - "name": "get resource booking with m2m read", + "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": "GET", + "method": "POST", "header": [ { "key": "Authorization", "type": "text", - "value": "Bearer {{token_m2m_read_resource_booking}}" + "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-27T04:17:23.131Z\",\r\n \"endDate\": \"2020-09-28T04:17:23.131Z\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, "url": { - "raw": "{{URL}}/resourceBookings/{{resourceBookingIdCreatedByM2M}}", + "raw": "{{URL}}/resourceBookings", "host": [ "{{URL}}" ], "path": [ - "resourceBookings", - "{{resourceBookingIdCreatedByM2M}}" + "resourceBookings" ] } }, "response": [] }, { - "name": "get resource booking with booking manager from db", + "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": "GET", + "method": "POST", "header": [ { "key": "Authorization", "type": "text", - "value": "Bearer {{token_bookingManager}}" + "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-27T04:17:23.131Z\",\r\n \"endDate\": \"2020-09-27T04:17:23.131Z\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, "url": { - "raw": "{{URL}}/resourceBookings/{{resourceBookingId}}?fromDb=true", + "raw": "{{URL}}/resourceBookings", "host": [ "{{URL}}" ], "path": [ - "resourceBookings", - "{{resourceBookingId}}" - ], - "query": [ - { - "key": "fromDb", - "value": "true" - } + "resourceBookings" ] } }, "response": [] }, { - "name": "get resource booking with connect user", + "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_connectUser}}" + "value": "Bearer {{token_bookingManager}}" } ], "url": { @@ -3182,31 +3420,57 @@ "response": [] }, { - "name": "get resource booking with member", + "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_member}}" + "value": "Bearer {{token_m2m_read_resource_booking}}" } ], "url": { - "raw": "{{URL}}/resourceBookings/{{resourceBookingId}}", + "raw": "{{URL}}/resourceBookings/{{resourceBookingIdCreatedByM2M}}", "host": [ "{{URL}}" ], "path": [ "resourceBookings", - "{{resourceBookingId}}" + "{{resourceBookingIdCreatedByM2M}}" ] } }, "response": [] }, { - "name": "search resource bookings with booking manager", + "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": [ @@ -3217,26 +3481,145 @@ } ], "url": { - "raw": "{{URL}}/resourceBookings", + "raw": "{{URL}}/resourceBookings/{{resourceBookingId}}?fromDb=true", "host": [ "{{URL}}" ], "path": [ - "resourceBookings" + "resourceBookings", + "{{resourceBookingId}}" ], "query": [ { - "key": "page", - "value": "1", - "disabled": true - }, - { - "key": "perPage", - "value": "5", - "disabled": true - }, - { - "key": "sortBy", + "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 }, @@ -3262,7 +3645,7 @@ }, { "key": "status", - "value": "sourcing", + "value": "assigned", "disabled": true }, { @@ -3277,6 +3660,19 @@ }, { "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": [ @@ -3332,7 +3728,7 @@ }, { "key": "status", - "value": "sourcing", + "value": "assigned", "disabled": true } ] @@ -3342,6 +3738,19 @@ }, { "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": [ @@ -3401,6 +3810,17 @@ }, { "name": "search resource bookings with member", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "" + ], + "type": "text/javascript" + } + } + ], "request": { "method": "GET", "header": [ @@ -3460,6 +3880,21 @@ }, { "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": [ @@ -3514,23 +3949,406 @@ } ] } - }, - "response": [] - }, - { - "name": "put resource booking with booking manager", + }, + "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-26T04:17:23.131Z\",\r\n \"endDate\": \"2020-11-29T04:17:23.131Z\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\",\r\n \"status\": \"assigned\"\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-27T04:17:23.131Z\",\r\n \"endDate\": \"2021-01-10T04:17:23.131Z\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\",\r\n \"status\": \"assigned\"\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-27T04:17:23.131Z\",\r\n \"endDate\": \"2020-09-28T04:17:23.131Z\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\",\r\n \"status\": \"assigned\"\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-27T04:17:23.131Z\",\r\n \"endDate\": \"2020-09-28T04:17:23.131Z\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\",\r\n \"status\": \"assigned\"\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_bookingManager}}" + "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-27T04:17:23.131Z\",\r\n \"endDate\": \"2020-09-27T04:17:23.131Z\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\",\r\n \"status\": \"assigned\"\r\n}", + "raw": "{\r\n \"projectId\": {{projectId}},\r\n \"userId\": \"a55fe1bc-1754-45fa-9adc-cf3d6d7c377a\",\r\n \"jobId\": \"{{jobId}}\",\r\n \"startDate\": \"2020-09-27T04:17:23.131Z\",\r\n \"endDate\": \"2020-09-28T04:17:23.131Z\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\",\r\n \"status\": \"assigned\"\r\n}", "options": { "raw": { "language": "json" @@ -3551,19 +4369,34 @@ "response": [] }, { - "name": "put resource booking with m2m update", + "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 {{token_m2m_update_resource_booking}}" + "value": "Bearer invalid_token" } ], "body": { "mode": "raw", - "raw": "{\r\n \"projectId\": {{projectId}},\r\n \"userId\": \"a55fe1bc-1754-45fa-9adc-cf3d6d7c377a\",\r\n \"jobId\": \"{{jobIdCreatedByM2M}}\",\r\n \"startDate\": \"2020-09-27T04:17:23.131Z\",\r\n \"endDate\": \"2020-09-27T04:17:23.131Z\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\",\r\n \"status\": \"assigned\"\r\n}", + "raw": "{\r\n \"projectId\": {{projectId}},\r\n \"userId\": \"a55fe1bc-1754-45fa-9adc-cf3d6d7c377a\",\r\n \"jobId\": \"{{jobId}}\",\r\n \"startDate\": \"2020-09-27T04:17:23.131Z\",\r\n \"endDate\": \"2020-09-28T04:17:23.131Z\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\",\r\n \"status\": \"assigned\"\r\n}", "options": { "raw": { "language": "json" @@ -3571,32 +4404,45 @@ } }, "url": { - "raw": "{{URL}}/resourceBookings/{{resourceBookingIdCreatedByM2M}}", + "raw": "{{URL}}/resourceBookings/{{resourceBookingId}}", "host": [ "{{URL}}" ], "path": [ "resourceBookings", - "{{resourceBookingIdCreatedByM2M}}" + "{{resourceBookingId}}" ] } }, "response": [] }, { - "name": "put resource booking with connect user", + "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": "PUT", + "method": "PATCH", "header": [ { "key": "Authorization", "type": "text", - "value": "Bearer {{token_connectUser}}" + "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-27T04:17:23.131Z\",\r\n \"endDate\": \"2020-09-27T04:17:23.131Z\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\",\r\n \"status\": \"assigned\"\r\n}", + "raw": "{\r\n \"status\": \"assigned\",\r\n \"startDate\": \"2020-09-30T04:17:23.131Z\",\r\n \"endDate\": \"2020-11-28T04:17:23.131Z\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\"\r\n}", "options": { "raw": { "language": "json" @@ -3617,19 +4463,32 @@ "response": [] }, { - "name": "put resource booking with member", + "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": "PUT", + "method": "PATCH", "header": [ { "key": "Authorization", "type": "text", - "value": "Bearer {{token_member}}" + "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\": \"{{jobId}}\",\r\n \"startDate\": \"2020-09-27T04:17:23.131Z\",\r\n \"endDate\": \"2020-09-27T04:17:23.131Z\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\",\r\n \"status\": \"assigned\"\r\n}", + "raw": "{\r\n \"status\": \"assigned\",\r\n \"startDate\": \"2020-12-30T04:17:23.131Z\",\r\n \"endDate\": \"2021-02-10T04:17:23.131Z\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\"\r\n}", "options": { "raw": { "language": "json" @@ -3637,32 +4496,47 @@ } }, "url": { - "raw": "{{URL}}/resourceBookings/{{resourceBookingId}}", + "raw": "{{URL}}/resourceBookings/{{resourceBookingIdCreatedByM2M}}", "host": [ "{{URL}}" ], "path": [ "resourceBookings", - "{{resourceBookingId}}" + "{{resourceBookingIdCreatedByM2M}}" ] } }, "response": [] }, { - "name": "put resource booking with user id not exist", + "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": "PUT", + "method": "PATCH", "header": [ { "key": "Authorization", "type": "text", - "value": "Bearer {{token_userId_not_exist}}" + "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-27T04:17:23.131Z\",\r\n \"endDate\": \"2020-09-27T04:17:23.131Z\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\",\r\n \"status\": \"assigned\"\r\n}", + "raw": "{\r\n \"status\": \"assigned\",\r\n \"startDate\": \"2020-09-27T04:17:23.131Z\",\r\n \"endDate\": \"2020-09-28T04:17:23.131Z\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\"\r\n}", "options": { "raw": { "language": "json" @@ -3683,19 +4557,34 @@ "response": [] }, { - "name": "put resource booking with invalid token", + "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": "PUT", + "method": "PATCH", "header": [ { "key": "Authorization", "type": "text", - "value": "Bearer invalid_token" + "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-27T04:17:23.131Z\",\r\n \"endDate\": \"2020-09-27T04:17:23.131Z\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\",\r\n \"status\": \"assigned\"\r\n}", + "raw": "{\r\n \"status\": \"assigned\",\r\n \"startDate\": \"2020-09-27T04:17:23.131Z\",\r\n \"endDate\": \"2020-09-28T04:17:23.131Z\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\"\r\n}", "options": { "raw": { "language": "json" @@ -3716,19 +4605,34 @@ "response": [] }, { - "name": "patch resource booking with booking manager", + "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_bookingManager}}" + "value": "Bearer {{token_userId_not_exist}}" } ], "body": { "mode": "raw", - "raw": "{\r\n \"status\": \"assigned\",\r\n \"startDate\": \"2020-09-27T04:17:23.131Z\",\r\n \"endDate\": \"2020-09-27T04:17:23.131Z\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\"\r\n}", + "raw": "{\r\n \"status\": \"assigned\",\r\n \"startDate\": \"2020-09-27T04:17:23.131Z\",\r\n \"endDate\": \"2020-09-28T04:17:23.131Z\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\"\r\n}", "options": { "raw": { "language": "json" @@ -3749,14 +4653,29 @@ "response": [] }, { - "name": "patch resource booking with m2m update", + "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 {{token_m2m_update_resource_booking}}" + "value": "Bearer invalid_token" } ], "body": { @@ -3769,65 +4688,136 @@ } }, "url": { - "raw": "{{URL}}/resourceBookings/{{resourceBookingIdCreatedByM2M}}", + "raw": "{{URL}}/resourceBookings/{{resourceBookingId}}", "host": [ "{{URL}}" ], "path": [ "resourceBookings", - "{{resourceBookingIdCreatedByM2M}}" + "{{resourceBookingId}}" ] } }, "response": [] }, { - "name": "patch resource booking with connect user", + "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": "PATCH", + "method": "GET", "header": [ { "key": "Authorization", "type": "text", - "value": "Bearer {{token_connectUser}}" + "value": "Bearer {{token_bookingManager}}" } ], - "body": { - "mode": "raw", - "raw": "{\r\n \"status\": \"assigned\",\r\n \"startDate\": \"2020-09-27T04:17:23.131Z\",\r\n \"endDate\": \"2020-09-27T04:17:23.131Z\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\"\r\n}", - "options": { - "raw": { - "language": "json" - } - } - }, "url": { - "raw": "{{URL}}/resourceBookings/{{resourceBookingId}}", + "raw": "{{URL}}/work-periods?perPage=1&sortBy=startDate&sortOrder=asc&resourceBookingId={{resourceBookingId}}", "host": [ "{{URL}}" ], "path": [ - "resourceBookings", - "{{resourceBookingId}}" + "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 resource booking with member", + }, + "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_member}}" + "value": "Bearer {{token_bookingManager}}" } ], "body": { "mode": "raw", - "raw": "{\r\n \"status\": \"assigned\",\r\n \"startDate\": \"2020-09-27T04:17:23.131Z\",\r\n \"endDate\": \"2020-09-27T04:17:23.131Z\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\"\r\n}", + "raw": "{\r\n \"paymentStatus\": \"completed\"\r\n}", "options": { "raw": { "language": "json" @@ -3835,32 +4825,45 @@ } }, "url": { - "raw": "{{URL}}/resourceBookings/{{resourceBookingId}}", + "raw": "{{URL}}/work-periods/{{workPeriodIdForPaid}}", "host": [ "{{URL}}" ], "path": [ - "resourceBookings", - "{{resourceBookingId}}" + "work-periods", + "{{workPeriodIdForPaid}}" ] } }, "response": [] }, { - "name": "patch resource booking with user id not exist", + "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_userId_not_exist}}" + "value": "Bearer {{token_bookingManager}}" } ], "body": { "mode": "raw", - "raw": "{\r\n \"status\": \"assigned\",\r\n \"startDate\": \"2020-09-27T04:17:23.131Z\",\r\n \"endDate\": \"2020-09-27T04:17:23.131Z\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\"\r\n}", + "raw": "{\r\n \"status\": \"cancelled\"\r\n}", "options": { "raw": { "language": "json" @@ -3881,19 +4884,32 @@ "response": [] }, { - "name": "patch resource booking with invalid token", + "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 invalid_token" + "value": "Bearer {{token_bookingManager}}" } ], "body": { "mode": "raw", - "raw": "{\r\n \"status\": \"assigned\",\r\n \"startDate\": \"2020-09-27T04:17:23.131Z\",\r\n \"endDate\": \"2020-09-27T04:17:23.131Z\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\"\r\n}", + "raw": "{\r\n \"startDate\": \"2020-10-04T04:17:23.131Z\"\r\n}", "options": { "raw": { "language": "json" @@ -3915,6 +4931,21 @@ }, { "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": [ @@ -3948,6 +4979,21 @@ }, { "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": [ @@ -3981,6 +5027,19 @@ }, { "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": [ @@ -4014,6 +5073,19 @@ }, { "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": [ @@ -4047,6 +5119,21 @@ }, { "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": [ @@ -4224,12 +5311,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriods", + "raw": "{{URL}}/work-periods", "host": [ "{{URL}}" ], "path": [ - "workPeriods" + "work-periods" ] } }, @@ -4273,12 +5360,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriods", + "raw": "{{URL}}/work-periods", "host": [ "{{URL}}" ], "path": [ - "workPeriods" + "work-periods" ] } }, @@ -4320,12 +5407,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriods", + "raw": "{{URL}}/work-periods", "host": [ "{{URL}}" ], "path": [ - "workPeriods" + "work-periods" ] } }, @@ -4367,12 +5454,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriods", + "raw": "{{URL}}/work-periods", "host": [ "{{URL}}" ], "path": [ - "workPeriods" + "work-periods" ] } }, @@ -4414,12 +5501,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriods", + "raw": "{{URL}}/work-periods", "host": [ "{{URL}}" ], "path": [ - "workPeriods" + "work-periods" ] } }, @@ -4461,12 +5548,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriods", + "raw": "{{URL}}/work-periods", "host": [ "{{URL}}" ], "path": [ - "workPeriods" + "work-periods" ] } }, @@ -4508,12 +5595,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriods", + "raw": "{{URL}}/work-periods", "host": [ "{{URL}}" ], "path": [ - "workPeriods" + "work-periods" ] } }, @@ -4555,12 +5642,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriods", + "raw": "{{URL}}/work-periods", "host": [ "{{URL}}" ], "path": [ - "workPeriods" + "work-periods" ] } }, @@ -4602,12 +5689,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriods", + "raw": "{{URL}}/work-periods", "host": [ "{{URL}}" ], "path": [ - "workPeriods" + "work-periods" ] } }, @@ -4649,12 +5736,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriods", + "raw": "{{URL}}/work-periods", "host": [ "{{URL}}" ], "path": [ - "workPeriods" + "work-periods" ] } }, @@ -4696,12 +5783,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriods", + "raw": "{{URL}}/work-periods", "host": [ "{{URL}}" ], "path": [ - "workPeriods" + "work-periods" ] } }, @@ -4743,12 +5830,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriods", + "raw": "{{URL}}/work-periods", "host": [ "{{URL}}" ], "path": [ - "workPeriods" + "work-periods" ] } }, @@ -4790,12 +5877,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriods", + "raw": "{{URL}}/work-periods", "host": [ "{{URL}}" ], "path": [ - "workPeriods" + "work-periods" ] } }, @@ -4837,12 +5924,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriods", + "raw": "{{URL}}/work-periods", "host": [ "{{URL}}" ], "path": [ - "workPeriods" + "work-periods" ] } }, @@ -4884,12 +5971,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriods", + "raw": "{{URL}}/work-periods", "host": [ "{{URL}}" ], "path": [ - "workPeriods" + "work-periods" ] } }, @@ -4931,12 +6018,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriods", + "raw": "{{URL}}/work-periods", "host": [ "{{URL}}" ], "path": [ - "workPeriods" + "work-periods" ] } }, @@ -4967,12 +6054,12 @@ } ], "url": { - "raw": "{{URL}}/workPeriods/{{workPeriodId}}", + "raw": "{{URL}}/work-periods/{{workPeriodId}}", "host": [ "{{URL}}" ], "path": [ - "workPeriods", + "work-periods", "{{workPeriodId}}" ] } @@ -4980,7 +6067,7 @@ "response": [] }, { - "name": "get work period with m2m read", + "name": "get work period with m2m read 1", "event": [ { "listen": "test", @@ -5004,12 +6091,49 @@ } ], "url": { - "raw": "{{URL}}/workPeriods/{{workPeriodIdCreatedByM2M}}", + "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": [ - "workPeriods", + "work-periods", "{{workPeriodIdCreatedByM2M}}" ] } @@ -5041,12 +6165,12 @@ } ], "url": { - "raw": "{{URL}}/workPeriods/{{workPeriodId}}?fromDb=true", + "raw": "{{URL}}/work-periods/{{workPeriodId}}?fromDb=true", "host": [ "{{URL}}" ], "path": [ - "workPeriods", + "work-periods", "{{workPeriodId}}" ], "query": [ @@ -5084,12 +6208,12 @@ } ], "url": { - "raw": "{{URL}}/workPeriods/{{workPeriodId}}", + "raw": "{{URL}}/work-periods/{{workPeriodId}}", "host": [ "{{URL}}" ], "path": [ - "workPeriods", + "work-periods", "{{workPeriodId}}" ] } @@ -5121,12 +6245,12 @@ } ], "url": { - "raw": "{{URL}}/workPeriods/{{workPeriodId}}", + "raw": "{{URL}}/work-periods/{{workPeriodId}}", "host": [ "{{URL}}" ], "path": [ - "workPeriods", + "work-periods", "{{workPeriodId}}" ] } @@ -5158,12 +6282,12 @@ } ], "url": { - "raw": "{{URL}}/workPeriods", + "raw": "{{URL}}/work-periods", "host": [ "{{URL}}" ], "path": [ - "workPeriods" + "work-periods" ], "query": [ { @@ -5173,7 +6297,7 @@ }, { "key": "perPage", - "value": "5", + "value": "35", "disabled": true }, { @@ -5227,7 +6351,7 @@ "response": [] }, { - "name": "search work periods with m2m all", + "name": "search work periods with m2m all 1", "event": [ { "listen": "test", @@ -5251,12 +6375,105 @@ } ], "url": { - "raw": "{{URL}}/workPeriods", + "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": [ - "workPeriods" + "work-periods" ], "query": [ { @@ -5344,12 +6561,12 @@ } ], "url": { - "raw": "{{URL}}/workPeriods", + "raw": "{{URL}}/work-periods", "host": [ "{{URL}}" ], "path": [ - "workPeriods" + "work-periods" ], "query": [ { @@ -5424,12 +6641,12 @@ } ], "url": { - "raw": "{{URL}}/workPeriods", + "raw": "{{URL}}/work-periods", "host": [ "{{URL}}" ], "path": [ - "workPeriods" + "work-periods" ], "query": [ { @@ -5517,12 +6734,12 @@ } ], "url": { - "raw": "{{URL}}/workPeriods", + "raw": "{{URL}}/work-periods", "host": [ "{{URL}}" ], "path": [ - "workPeriods" + "work-periods" ], "query": [ { @@ -5619,12 +6836,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriods/{{workPeriodId}}", + "raw": "{{URL}}/work-periods/{{workPeriodId}}", "host": [ "{{URL}}" ], "path": [ - "workPeriods", + "work-periods", "{{workPeriodId}}" ] } @@ -5665,12 +6882,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriods/{{workPeriodIdCreatedByM2M}}", + "raw": "{{URL}}/work-periods/{{workPeriodIdCreatedByM2M}}", "host": [ "{{URL}}" ], "path": [ - "workPeriods", + "work-periods", "{{workPeriodIdCreatedByM2M}}" ] } @@ -5713,12 +6930,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriods/{{workPeriodId}}", + "raw": "{{URL}}/work-periods/{{workPeriodId}}", "host": [ "{{URL}}" ], "path": [ - "workPeriods", + "work-periods", "{{workPeriodId}}" ] } @@ -5761,12 +6978,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriods/{{workPeriodId}}", + "raw": "{{URL}}/work-periods/{{workPeriodId}}", "host": [ "{{URL}}" ], "path": [ - "workPeriods", + "work-periods", "{{workPeriodId}}" ] } @@ -5809,12 +7026,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriods/{{workPeriodId}}", + "raw": "{{URL}}/work-periods/{{workPeriodId}}", "host": [ "{{URL}}" ], "path": [ - "workPeriods", + "work-periods", "{{workPeriodId}}" ] } @@ -5857,12 +7074,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriods/{{workPeriodId}}", + "raw": "{{URL}}/work-periods/{{workPeriodId}}", "host": [ "{{URL}}" ], "path": [ - "workPeriods", + "work-periods", "{{workPeriodId}}" ] } @@ -5905,12 +7122,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriods/{{workPeriodId}}", + "raw": "{{URL}}/work-periods/{{workPeriodId}}", "host": [ "{{URL}}" ], "path": [ - "workPeriods", + "work-periods", "{{workPeriodId}}" ] } @@ -5953,12 +7170,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriods/{{workPeriodId}}", + "raw": "{{URL}}/work-periods/{{workPeriodId}}", "host": [ "{{URL}}" ], "path": [ - "workPeriods", + "work-periods", "{{workPeriodId}}" ] } @@ -6001,12 +7218,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriods/{{workPeriodId}}", + "raw": "{{URL}}/work-periods/{{workPeriodId}}", "host": [ "{{URL}}" ], "path": [ - "workPeriods", + "work-periods", "{{workPeriodId}}" ] } @@ -6049,12 +7266,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriods/{{workPeriodId}}", + "raw": "{{URL}}/work-periods/{{workPeriodId}}", "host": [ "{{URL}}" ], "path": [ - "workPeriods", + "work-periods", "{{workPeriodId}}" ] } @@ -6097,12 +7314,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriods/{{workPeriodId}}", + "raw": "{{URL}}/work-periods/{{workPeriodId}}", "host": [ "{{URL}}" ], "path": [ - "workPeriods", + "work-periods", "{{workPeriodId}}" ] } @@ -6145,12 +7362,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriods/{{workPeriodId}}", + "raw": "{{URL}}/work-periods/{{workPeriodId}}", "host": [ "{{URL}}" ], "path": [ - "workPeriods", + "work-periods", "{{workPeriodId}}" ] } @@ -6193,12 +7410,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriods/{{workPeriodId}}", + "raw": "{{URL}}/work-periods/{{workPeriodId}}", "host": [ "{{URL}}" ], "path": [ - "workPeriods", + "work-periods", "{{workPeriodId}}" ] } @@ -6241,12 +7458,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriods/{{workPeriodId}}", + "raw": "{{URL}}/work-periods/{{workPeriodId}}", "host": [ "{{URL}}" ], "path": [ - "workPeriods", + "work-periods", "{{workPeriodId}}" ] } @@ -6289,12 +7506,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriods/{{workPeriodId}}", + "raw": "{{URL}}/work-periods/{{workPeriodId}}", "host": [ "{{URL}}" ], "path": [ - "workPeriods", + "work-periods", "{{workPeriodId}}" ] } @@ -6337,12 +7554,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriods/{{workPeriodId}}", + "raw": "{{URL}}/work-periods/{{workPeriodId}}", "host": [ "{{URL}}" ], "path": [ - "workPeriods", + "work-periods", "{{workPeriodId}}" ] } @@ -6383,12 +7600,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriods/{{workPeriodId}}", + "raw": "{{URL}}/work-periods/{{workPeriodId}}", "host": [ "{{URL}}" ], "path": [ - "workPeriods", + "work-periods", "{{workPeriodId}}" ] } @@ -6429,12 +7646,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriods/{{workPeriodIdCreatedByM2M}}", + "raw": "{{URL}}/work-periods/{{workPeriodIdCreatedByM2M}}", "host": [ "{{URL}}" ], "path": [ - "workPeriods", + "work-periods", "{{workPeriodIdCreatedByM2M}}" ] } @@ -6477,12 +7694,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriods/{{workPeriodId}}", + "raw": "{{URL}}/work-periods/{{workPeriodId}}", "host": [ "{{URL}}" ], "path": [ - "workPeriods", + "work-periods", "{{workPeriodId}}" ] } @@ -6525,12 +7742,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriods/{{workPeriodId}}", + "raw": "{{URL}}/work-periods/{{workPeriodId}}", "host": [ "{{URL}}" ], "path": [ - "workPeriods", + "work-periods", "{{workPeriodId}}" ] } @@ -6573,12 +7790,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriods/{{workPeriodId}}", + "raw": "{{URL}}/work-periods/{{workPeriodId}}", "host": [ "{{URL}}" ], "path": [ - "workPeriods", + "work-periods", "{{workPeriodId}}" ] } @@ -6621,12 +7838,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriods/{{workPeriodId}}", + "raw": "{{URL}}/work-periods/{{workPeriodId}}", "host": [ "{{URL}}" ], "path": [ - "workPeriods", + "work-periods", "{{workPeriodId}}" ] } @@ -6669,12 +7886,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriods/{{workPeriodId}}", + "raw": "{{URL}}/work-periods/{{workPeriodId}}", "host": [ "{{URL}}" ], "path": [ - "workPeriods", + "work-periods", "{{workPeriodId}}" ] } @@ -6717,12 +7934,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriods/{{workPeriodId}}", + "raw": "{{URL}}/work-periods/{{workPeriodId}}", "host": [ "{{URL}}" ], "path": [ - "workPeriods", + "work-periods", "{{workPeriodId}}" ] } @@ -6765,12 +7982,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriods/{{workPeriodId}}", + "raw": "{{URL}}/work-periods/{{workPeriodId}}", "host": [ "{{URL}}" ], "path": [ - "workPeriods", + "work-periods", "{{workPeriodId}}" ] } @@ -6813,12 +8030,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriods/{{workPeriodId}}", + "raw": "{{URL}}/work-periods/{{workPeriodId}}", "host": [ "{{URL}}" ], "path": [ - "workPeriods", + "work-periods", "{{workPeriodId}}" ] } @@ -6861,12 +8078,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriods/{{workPeriodId}}", + "raw": "{{URL}}/work-periods/{{workPeriodId}}", "host": [ "{{URL}}" ], "path": [ - "workPeriods", + "work-periods", "{{workPeriodId}}" ] } @@ -6909,12 +8126,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriods/{{workPeriodId}}", + "raw": "{{URL}}/work-periods/{{workPeriodId}}", "host": [ "{{URL}}" ], "path": [ - "workPeriods", + "work-periods", "{{workPeriodId}}" ] } @@ -6957,12 +8174,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriods/{{workPeriodId}}", + "raw": "{{URL}}/work-periods/{{workPeriodId}}", "host": [ "{{URL}}" ], "path": [ - "workPeriods", + "work-periods", "{{workPeriodId}}" ] } @@ -7005,12 +8222,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriods/{{workPeriodId}}", + "raw": "{{URL}}/work-periods/{{workPeriodId}}", "host": [ "{{URL}}" ], "path": [ - "workPeriods", + "work-periods", "{{workPeriodId}}" ] } @@ -7053,12 +8270,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriods/{{workPeriodId}}", + "raw": "{{URL}}/work-periods/{{workPeriodId}}", "host": [ "{{URL}}" ], "path": [ - "workPeriods", + "work-periods", "{{workPeriodId}}" ] } @@ -7099,12 +8316,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriods/{{workPeriodId}}", + "raw": "{{URL}}/work-periods/{{workPeriodId}}", "host": [ "{{URL}}" ], "path": [ - "workPeriods", + "work-periods", "{{workPeriodId}}" ] } @@ -7145,12 +8362,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriods/{{workPeriodIdCreatedByM2M}}", + "raw": "{{URL}}/work-periods/{{workPeriodIdCreatedByM2M}}", "host": [ "{{URL}}" ], "path": [ - "workPeriods", + "work-periods", "{{workPeriodIdCreatedByM2M}}" ] } @@ -7193,12 +8410,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriods/{{workPeriodId}}", + "raw": "{{URL}}/work-periods/{{workPeriodId}}", "host": [ "{{URL}}" ], "path": [ - "workPeriods", + "work-periods", "{{workPeriodId}}" ] } @@ -7239,12 +8456,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriods/{{workPeriodId}}", + "raw": "{{URL}}/work-periods/{{workPeriodId}}", "host": [ "{{URL}}" ], "path": [ - "workPeriods", + "work-periods", "{{workPeriodId}}" ] } @@ -7338,7 +8555,7 @@ ], "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-27T04:17:23.131Z\",\r\n \"endDate\": \"2020-09-27T04:17:23.131Z\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\"\r\n}", + "raw": "{\r\n \"projectId\": {{project_id_17234}},\r\n \"userId\": \"a55fe1bc-1754-45fa-9adc-cf3d6d7c377a\",\r\n \"jobId\": \"{{jobId}}\",\r\n \"startDate\": \"2020-09-27T04:17:23.131Z\",\r\n \"endDate\": \"2020-10-27T04:17:23.131Z\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\"\r\n}", "options": { "raw": { "language": "json" @@ -7395,12 +8612,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriods", + "raw": "{{URL}}/work-periods", "host": [ "{{URL}}" ], "path": [ - "workPeriods" + "work-periods" ] } }, @@ -7446,12 +8663,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriodPayments", + "raw": "{{URL}}/work-period-payments", "host": [ "{{URL}}" ], "path": [ - "workPeriodPayments" + "work-period-payments" ] } }, @@ -7495,12 +8712,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriodPayments", + "raw": "{{URL}}/work-period-payments", "host": [ "{{URL}}" ], "path": [ - "workPeriodPayments" + "work-period-payments" ] } }, @@ -7542,12 +8759,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriodPayments", + "raw": "{{URL}}/work-period-payments", "host": [ "{{URL}}" ], "path": [ - "workPeriodPayments" + "work-period-payments" ] } }, @@ -7589,12 +8806,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriodPayments", + "raw": "{{URL}}/work-period-payments", "host": [ "{{URL}}" ], "path": [ - "workPeriodPayments" + "work-period-payments" ] } }, @@ -7636,12 +8853,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriodPayments", + "raw": "{{URL}}/work-period-payments", "host": [ "{{URL}}" ], "path": [ - "workPeriodPayments" + "work-period-payments" ] } }, @@ -7683,12 +8900,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriodPayments", + "raw": "{{URL}}/work-period-payments", "host": [ "{{URL}}" ], "path": [ - "workPeriodPayments" + "work-period-payments" ] } }, @@ -7730,12 +8947,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriodPayments", + "raw": "{{URL}}/work-period-payments", "host": [ "{{URL}}" ], "path": [ - "workPeriodPayments" + "work-period-payments" ] } }, @@ -7777,12 +8994,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriodPayments", + "raw": "{{URL}}/work-period-payments", "host": [ "{{URL}}" ], "path": [ - "workPeriodPayments" + "work-period-payments" ] } }, @@ -7824,12 +9041,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriodPayments", + "raw": "{{URL}}/work-period-payments", "host": [ "{{URL}}" ], "path": [ - "workPeriodPayments" + "work-period-payments" ] } }, @@ -7871,12 +9088,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriodPayments", + "raw": "{{URL}}/work-period-payments", "host": [ "{{URL}}" ], "path": [ - "workPeriodPayments" + "work-period-payments" ] } }, @@ -7918,12 +9135,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriodPayments", + "raw": "{{URL}}/work-period-payments", "host": [ "{{URL}}" ], "path": [ - "workPeriodPayments" + "work-period-payments" ] } }, @@ -7965,12 +9182,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriodPayments", + "raw": "{{URL}}/work-period-payments", "host": [ "{{URL}}" ], "path": [ - "workPeriodPayments" + "work-period-payments" ] } }, @@ -8012,12 +9229,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriodPayments", + "raw": "{{URL}}/work-period-payments", "host": [ "{{URL}}" ], "path": [ - "workPeriodPayments" + "work-period-payments" ] } }, @@ -8048,12 +9265,12 @@ } ], "url": { - "raw": "{{URL}}/workPeriodPayments/{{workPeriodPaymentId}}", + "raw": "{{URL}}/work-period-payments/{{workPeriodPaymentId}}", "host": [ "{{URL}}" ], "path": [ - "workPeriodPayments", + "work-period-payments", "{{workPeriodPaymentId}}" ] } @@ -8085,12 +9302,12 @@ } ], "url": { - "raw": "{{URL}}/workPeriodPayments/{{workPeriodPaymentIdCreatedByM2M}}", + "raw": "{{URL}}/work-period-payments/{{workPeriodPaymentIdCreatedByM2M}}", "host": [ "{{URL}}" ], "path": [ - "workPeriodPayments", + "work-period-payments", "{{workPeriodPaymentIdCreatedByM2M}}" ] } @@ -8122,12 +9339,12 @@ } ], "url": { - "raw": "{{URL}}/workPeriodPayments/{{workPeriodPaymentId}}?fromDb=true", + "raw": "{{URL}}/work-period-payments/{{workPeriodPaymentId}}?fromDb=true", "host": [ "{{URL}}" ], "path": [ - "workPeriodPayments", + "work-period-payments", "{{workPeriodPaymentId}}" ], "query": [ @@ -8167,12 +9384,12 @@ } ], "url": { - "raw": "{{URL}}/workPeriodPayments/{{workPeriodPaymentId}}", + "raw": "{{URL}}/work-period-payments/{{workPeriodPaymentId}}", "host": [ "{{URL}}" ], "path": [ - "workPeriodPayments", + "work-period-payments", "{{workPeriodPaymentId}}" ] } @@ -8206,12 +9423,12 @@ } ], "url": { - "raw": "{{URL}}/workPeriodPayments/{{workPeriodPaymentId}}", + "raw": "{{URL}}/work-period-payments/{{workPeriodPaymentId}}", "host": [ "{{URL}}" ], "path": [ - "workPeriodPayments", + "work-period-payments", "{{workPeriodPaymentId}}" ] } @@ -8243,12 +9460,12 @@ } ], "url": { - "raw": "{{URL}}/workPeriodPayments", + "raw": "{{URL}}/work-period-payments", "host": [ "{{URL}}" ], "path": [ - "workPeriodPayments" + "work-period-payments" ], "query": [ { @@ -8316,12 +9533,12 @@ } ], "url": { - "raw": "{{URL}}/workPeriodPayments", + "raw": "{{URL}}/work-period-payments", "host": [ "{{URL}}" ], "path": [ - "workPeriodPayments" + "work-period-payments" ], "query": [ { @@ -8391,12 +9608,12 @@ } ], "url": { - "raw": "{{URL}}/workPeriodPayments", + "raw": "{{URL}}/work-period-payments", "host": [ "{{URL}}" ], "path": [ - "workPeriodPayments" + "work-period-payments" ], "query": [ { @@ -8466,12 +9683,12 @@ } ], "url": { - "raw": "{{URL}}/workPeriodPayments", + "raw": "{{URL}}/work-period-payments", "host": [ "{{URL}}" ], "path": [ - "workPeriodPayments" + "work-period-payments" ], "query": [ { @@ -8541,12 +9758,12 @@ } ], "url": { - "raw": "{{URL}}/workPeriodPayments", + "raw": "{{URL}}/work-period-payments", "host": [ "{{URL}}" ], "path": [ - "workPeriodPayments" + "work-period-payments" ], "query": [ { @@ -8623,12 +9840,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriodPayments/{{workPeriodPaymentId}}", + "raw": "{{URL}}/work-period-payments/{{workPeriodPaymentId}}", "host": [ "{{URL}}" ], "path": [ - "workPeriodPayments", + "work-period-payments", "{{workPeriodPaymentId}}" ] } @@ -8669,12 +9886,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriodPayments/{{workPeriodPaymentIdCreatedByM2M}}", + "raw": "{{URL}}/work-period-payments/{{workPeriodPaymentIdCreatedByM2M}}", "host": [ "{{URL}}" ], "path": [ - "workPeriodPayments", + "work-period-payments", "{{workPeriodPaymentIdCreatedByM2M}}" ] } @@ -8717,12 +9934,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriodPayments/{{workPeriodPaymentId}}", + "raw": "{{URL}}/work-period-payments/{{workPeriodPaymentId}}", "host": [ "{{URL}}" ], "path": [ - "workPeriodPayments", + "work-period-payments", "{{workPeriodPaymentId}}" ] } @@ -8765,12 +9982,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriodPayments/{{workPeriodPaymentId}}", + "raw": "{{URL}}/work-period-payments/{{workPeriodPaymentId}}", "host": [ "{{URL}}" ], "path": [ - "workPeriodPayments", + "work-period-payments", "{{workPeriodPaymentId}}" ] } @@ -8813,12 +10030,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriodPayments/{{workPeriodPaymentId}}", + "raw": "{{URL}}/work-period-payments/{{workPeriodPaymentId}}", "host": [ "{{URL}}" ], "path": [ - "workPeriodPayments", + "work-period-payments", "{{workPeriodPaymentId}}" ] } @@ -8861,12 +10078,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriodPayments/{{workPeriodPaymentId}}", + "raw": "{{URL}}/work-period-payments/{{workPeriodPaymentId}}", "host": [ "{{URL}}" ], "path": [ - "workPeriodPayments", + "work-period-payments", "{{workPeriodPaymentId}}" ] } @@ -8909,12 +10126,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriodPayments/{{workPeriodPaymentId}}", + "raw": "{{URL}}/work-period-payments/{{workPeriodPaymentId}}", "host": [ "{{URL}}" ], "path": [ - "workPeriodPayments", + "work-period-payments", "{{workPeriodPaymentId}}" ] } @@ -8957,12 +10174,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriodPayments/{{workPeriodPaymentId}}", + "raw": "{{URL}}/work-period-payments/{{workPeriodPaymentId}}", "host": [ "{{URL}}" ], "path": [ - "workPeriodPayments", + "work-period-payments", "{{workPeriodPaymentId}}" ] } @@ -9005,12 +10222,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriodPayments/{{workPeriodPaymentId}}", + "raw": "{{URL}}/work-period-payments/{{workPeriodPaymentId}}", "host": [ "{{URL}}" ], "path": [ - "workPeriodPayments", + "work-period-payments", "{{workPeriodPaymentId}}" ] } @@ -9053,12 +10270,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriodPayments/{{workPeriodPaymentId}}", + "raw": "{{URL}}/work-period-payments/{{workPeriodPaymentId}}", "host": [ "{{URL}}" ], "path": [ - "workPeriodPayments", + "work-period-payments", "{{workPeriodPaymentId}}" ] } @@ -9101,12 +10318,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriodPayments/{{workPeriodPaymentId}}", + "raw": "{{URL}}/work-period-payments/{{workPeriodPaymentId}}", "host": [ "{{URL}}" ], "path": [ - "workPeriodPayments", + "work-period-payments", "{{workPeriodPaymentId}}" ] } @@ -9149,12 +10366,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriodPayments/{{workPeriodPaymentId}}", + "raw": "{{URL}}/work-period-payments/{{workPeriodPaymentId}}", "host": [ "{{URL}}" ], "path": [ - "workPeriodPayments", + "work-period-payments", "{{workPeriodPaymentId}}" ] } @@ -9197,12 +10414,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriodPayments/{{workPeriodPaymentId}}", + "raw": "{{URL}}/work-period-payments/{{workPeriodPaymentId}}", "host": [ "{{URL}}" ], "path": [ - "workPeriodPayments", + "work-period-payments", "{{workPeriodPaymentId}}" ] } @@ -9243,12 +10460,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriodPayments/{{workPeriodPaymentId}}", + "raw": "{{URL}}/work-period-payments/{{workPeriodPaymentId}}", "host": [ "{{URL}}" ], "path": [ - "workPeriodPayments", + "work-period-payments", "{{workPeriodPaymentId}}" ] } @@ -9289,12 +10506,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriodPayments/{{workPeriodPaymentIdCreatedByM2M}}", + "raw": "{{URL}}/work-period-payments/{{workPeriodPaymentIdCreatedByM2M}}", "host": [ "{{URL}}" ], "path": [ - "workPeriodPayments", + "work-period-payments", "{{workPeriodPaymentIdCreatedByM2M}}" ] } @@ -9337,12 +10554,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriodPayments/{{workPeriodPaymentId}}", + "raw": "{{URL}}/work-period-payments/{{workPeriodPaymentId}}", "host": [ "{{URL}}" ], "path": [ - "workPeriodPayments", + "work-period-payments", "{{workPeriodPaymentId}}" ] } @@ -9385,12 +10602,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriodPayments/{{workPeriodPaymentId}}", + "raw": "{{URL}}/work-period-payments/{{workPeriodPaymentId}}", "host": [ "{{URL}}" ], "path": [ - "workPeriodPayments", + "work-period-payments", "{{workPeriodPaymentId}}" ] } @@ -9433,12 +10650,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriodPayments/{{workPeriodPaymentId}}", + "raw": "{{URL}}/work-period-payments/{{workPeriodPaymentId}}", "host": [ "{{URL}}" ], "path": [ - "workPeriodPayments", + "work-period-payments", "{{workPeriodPaymentId}}" ] } @@ -9481,12 +10698,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriodPayments/{{workPeriodPaymentId}}", + "raw": "{{URL}}/work-period-payments/{{workPeriodPaymentId}}", "host": [ "{{URL}}" ], "path": [ - "workPeriodPayments", + "work-period-payments", "{{workPeriodPaymentId}}" ] } @@ -9529,12 +10746,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriodPayments/{{workPeriodPaymentId}}", + "raw": "{{URL}}/work-period-payments/{{workPeriodPaymentId}}", "host": [ "{{URL}}" ], "path": [ - "workPeriodPayments", + "work-period-payments", "{{workPeriodPaymentId}}" ] } @@ -9577,12 +10794,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriodPayments/{{workPeriodPaymentId}}", + "raw": "{{URL}}/work-period-payments/{{workPeriodPaymentId}}", "host": [ "{{URL}}" ], "path": [ - "workPeriodPayments", + "work-period-payments", "{{workPeriodPaymentId}}" ] } @@ -9625,12 +10842,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriodPayments/{{workPeriodPaymentId}}", + "raw": "{{URL}}/work-period-payments/{{workPeriodPaymentId}}", "host": [ "{{URL}}" ], "path": [ - "workPeriodPayments", + "work-period-payments", "{{workPeriodPaymentId}}" ] } @@ -9673,12 +10890,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriodPayments/{{workPeriodPaymentId}}", + "raw": "{{URL}}/work-period-payments/{{workPeriodPaymentId}}", "host": [ "{{URL}}" ], "path": [ - "workPeriodPayments", + "work-period-payments", "{{workPeriodPaymentId}}" ] } @@ -9721,12 +10938,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriodPayments/{{workPeriodPaymentId}}", + "raw": "{{URL}}/work-period-payments/{{workPeriodPaymentId}}", "host": [ "{{URL}}" ], "path": [ - "workPeriodPayments", + "work-period-payments", "{{workPeriodPaymentId}}" ] } @@ -9769,12 +10986,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriodPayments/{{workPeriodPaymentId}}", + "raw": "{{URL}}/work-period-payments/{{workPeriodPaymentId}}", "host": [ "{{URL}}" ], "path": [ - "workPeriodPayments", + "work-period-payments", "{{workPeriodPaymentId}}" ] } @@ -13954,12 +15171,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriods", + "raw": "{{URL}}/work-periods", "host": [ "{{URL}}" ], "path": [ - "workPeriods" + "work-periods" ] } }, @@ -13977,12 +15194,12 @@ } ], "url": { - "raw": "{{URL}}/workPeriods/{{workPeriodId_created_by_administrator}}", + "raw": "{{URL}}/work-periods/{{workPeriodId_created_by_administrator}}", "host": [ "{{URL}}" ], "path": [ - "workPeriods", + "work-periods", "{{workPeriodId_created_by_administrator}}" ] } @@ -14001,12 +15218,12 @@ } ], "url": { - "raw": "{{URL}}/workPeriods", + "raw": "{{URL}}/work-periods", "host": [ "{{URL}}" ], "path": [ - "workPeriods" + "work-periods" ], "query": [ { @@ -14103,12 +15320,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriods/{{workPeriodId_created_by_administrator}}", + "raw": "{{URL}}/work-periods/{{workPeriodId_created_by_administrator}}", "host": [ "{{URL}}" ], "path": [ - "workPeriods", + "work-periods", "{{workPeriodId_created_by_administrator}}" ] } @@ -14149,12 +15366,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriods/{{workPeriodId_created_by_administrator}}", + "raw": "{{URL}}/work-periods/{{workPeriodId_created_by_administrator}}", "host": [ "{{URL}}" ], "path": [ - "workPeriods", + "work-periods", "{{workPeriodId_created_by_administrator}}" ] } @@ -14195,12 +15412,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriods/{{workPeriodId_created_by_administrator}}", + "raw": "{{URL}}/work-periods/{{workPeriodId_created_by_administrator}}", "host": [ "{{URL}}" ], "path": [ - "workPeriods", + "work-periods", "{{workPeriodId_created_by_administrator}}" ] } @@ -14245,7 +15462,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\": {{project_id_17234}},\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" @@ -14294,7 +15511,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-27T04:17:23.131Z\",\r\n \"endDate\": \"2020-09-27T04:17:23.131Z\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\"\r\n}", + "raw": "{\r\n \"projectId\": {{project_id_17234}},\r\n \"userId\": \"a55fe1bc-1754-45fa-9adc-cf3d6d7c377a\",\r\n \"jobId\": \"{{job_id_created_by_administrator}}\",\r\n \"startDate\": \"2020-09-27T04:17:23.131Z\",\r\n \"endDate\": \"2020-09-27T04:17:23.131Z\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 13,\r\n \"rateType\": \"hourly\"\r\n}", "options": { "raw": { "language": "json" @@ -14351,12 +15568,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriods", + "raw": "{{URL}}/work-periods", "host": [ "{{URL}}" ], "path": [ - "workPeriods" + "work-periods" ] } }, @@ -14402,12 +15619,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriodPayments", + "raw": "{{URL}}/work-period-payments", "host": [ "{{URL}}" ], "path": [ - "workPeriodPayments" + "work-period-payments" ] } }, @@ -14438,12 +15655,12 @@ } ], "url": { - "raw": "{{URL}}/workPeriodPayments/{{workPeriodPaymentId_created_by_administrator}}", + "raw": "{{URL}}/work-period-payments/{{workPeriodPaymentId_created_by_administrator}}", "host": [ "{{URL}}" ], "path": [ - "workPeriodPayments", + "work-period-payments", "{{workPeriodPaymentId_created_by_administrator}}" ] } @@ -14475,12 +15692,12 @@ } ], "url": { - "raw": "{{URL}}/workPeriodPayments", + "raw": "{{URL}}/work-period-payments", "host": [ "{{URL}}" ], "path": [ - "workPeriodPayments" + "work-period-payments" ], "query": [ { @@ -14557,12 +15774,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriodPayments/{{workPeriodPaymentId_created_by_administrator}}", + "raw": "{{URL}}/work-period-payments/{{workPeriodPaymentId_created_by_administrator}}", "host": [ "{{URL}}" ], "path": [ - "workPeriodPayments", + "work-period-payments", "{{workPeriodPaymentId_created_by_administrator}}" ] } @@ -14603,12 +15820,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriodPayments/{{workPeriodPaymentId_created_by_administrator}}", + "raw": "{{URL}}/work-period-payments/{{workPeriodPaymentId_created_by_administrator}}", "host": [ "{{URL}}" ], "path": [ - "workPeriodPayments", + "work-period-payments", "{{workPeriodPaymentId_created_by_administrator}}" ] } @@ -15621,12 +16838,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriods", + "raw": "{{URL}}/work-periods", "host": [ "{{URL}}" ], "path": [ - "workPeriods" + "work-periods" ] } }, @@ -15670,12 +16887,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriods", + "raw": "{{URL}}/work-periods", "host": [ "{{URL}}" ], "path": [ - "workPeriods" + "work-periods" ] } }, @@ -15693,13 +16910,19 @@ } ], "url": { - "raw": "{{URL}}/workPeriods/{{workPeriodId_created_for_member}}", + "raw": "{{URL}}/work-periods/{{workPeriodId_created_for_member}}?projectId=16718", "host": [ "{{URL}}" ], "path": [ - "workPeriods", + "work-periods", "{{workPeriodId_created_for_member}}" + ], + "query": [ + { + "key": "projectId", + "value": "16718" + } ] } }, @@ -15717,12 +16940,12 @@ } ], "url": { - "raw": "{{URL}}/workPeriods?projectId=16718", + "raw": "{{URL}}/work-periods?projectId=16718", "host": [ "{{URL}}" ], "path": [ - "workPeriods" + "work-periods" ], "query": [ { @@ -15820,12 +17043,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriods/{{workPeriodId_created_for_member}}", + "raw": "{{URL}}/work-periods/{{workPeriodId_created_for_member}}", "host": [ "{{URL}}" ], "path": [ - "workPeriods", + "work-periods", "{{workPeriodId_created_for_member}}" ] } @@ -15868,12 +17091,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriods/{{workPeriodId_created_for_member}}", + "raw": "{{URL}}/work-periods/{{workPeriodId_created_for_member}}", "host": [ "{{URL}}" ], "path": [ - "workPeriods", + "work-periods", "{{workPeriodId_created_for_member}}" ] } @@ -15916,12 +17139,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriods/{{workPeriodId_created_for_member}}", + "raw": "{{URL}}/work-periods/{{workPeriodId_created_for_member}}", "host": [ "{{URL}}" ], "path": [ - "workPeriods", + "work-periods", "{{workPeriodId_created_for_member}}" ] } @@ -16072,12 +17295,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriods", + "raw": "{{URL}}/work-periods", "host": [ "{{URL}}" ], "path": [ - "workPeriods" + "work-periods" ] } }, @@ -16121,12 +17344,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriodPayments", + "raw": "{{URL}}/work-period-payments", "host": [ "{{URL}}" ], "path": [ - "workPeriodPayments" + "work-period-payments" ] } }, @@ -16170,12 +17393,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriodPayments", + "raw": "{{URL}}/work-period-payments", "host": [ "{{URL}}" ], "path": [ - "workPeriodPayments" + "work-period-payments" ] } }, @@ -16208,12 +17431,12 @@ } ], "url": { - "raw": "{{URL}}/workPeriodPayments/{{workPeriodPaymentId_created_for_member}}", + "raw": "{{URL}}/work-period-payments/{{workPeriodPaymentId_created_for_member}}", "host": [ "{{URL}}" ], "path": [ - "workPeriodPayments", + "work-period-payments", "{{workPeriodPaymentId_created_for_member}}" ] } @@ -16247,12 +17470,12 @@ } ], "url": { - "raw": "{{URL}}/workPeriodPayments", + "raw": "{{URL}}/work-period-payments", "host": [ "{{URL}}" ], "path": [ - "workPeriodPayments" + "work-period-payments" ], "query": [ { @@ -16331,12 +17554,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriodPayments/{{workPeriodPaymentId_created_for_member}}", + "raw": "{{URL}}/work-period-payments/{{workPeriodPaymentId_created_for_member}}", "host": [ "{{URL}}" ], "path": [ - "workPeriodPayments", + "work-period-payments", "{{workPeriodPaymentId_created_for_member}}" ] } @@ -16379,12 +17602,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriodPayments/{{workPeriodPaymentId_created_for_member}}", + "raw": "{{URL}}/work-period-payments/{{workPeriodPaymentId_created_for_member}}", "host": [ "{{URL}}" ], "path": [ - "workPeriodPayments", + "work-period-payments", "{{workPeriodPaymentId_created_for_member}}" ] } @@ -17395,12 +18618,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriods", + "raw": "{{URL}}/work-periods", "host": [ "{{URL}}" ], "path": [ - "workPeriods" + "work-periods" ] } }, @@ -17444,12 +18667,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriods", + "raw": "{{URL}}/work-periods", "host": [ "{{URL}}" ], "path": [ - "workPeriods" + "work-periods" ] } }, @@ -17467,12 +18690,12 @@ } ], "url": { - "raw": "{{URL}}/workPeriods/{{workPeriodId_created_for_connect_manager}}", + "raw": "{{URL}}/work-periods/{{workPeriodId_created_for_connect_manager}}", "host": [ "{{URL}}" ], "path": [ - "workPeriods", + "work-periods", "{{workPeriodId_created_for_connect_manager}}" ] } @@ -17491,12 +18714,12 @@ } ], "url": { - "raw": "{{URL}}/workPeriods?projectId=16843", + "raw": "{{URL}}/work-periods?projectId=16843", "host": [ "{{URL}}" ], "path": [ - "workPeriods" + "work-periods" ], "query": [ { @@ -17594,12 +18817,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriods/{{workPeriodId_created_for_connect_manager}}", + "raw": "{{URL}}/work-periods/{{workPeriodId_created_for_connect_manager}}", "host": [ "{{URL}}" ], "path": [ - "workPeriods", + "work-periods", "{{workPeriodId_created_for_connect_manager}}" ] } @@ -17642,12 +18865,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriods/{{workPeriodId_created_for_connect_manager}}", + "raw": "{{URL}}/work-periods/{{workPeriodId_created_for_connect_manager}}", "host": [ "{{URL}}" ], "path": [ - "workPeriods", + "work-periods", "{{workPeriodId_created_for_connect_manager}}" ] } @@ -17690,12 +18913,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriods/{{workPeriodId_created_for_connect_manager}}", + "raw": "{{URL}}/work-periods/{{workPeriodId_created_for_connect_manager}}", "host": [ "{{URL}}" ], "path": [ - "workPeriods", + "work-periods", "{{workPeriodId_created_for_connect_manager}}" ] } @@ -17846,12 +19069,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriods", + "raw": "{{URL}}/work-periods", "host": [ "{{URL}}" ], "path": [ - "workPeriods" + "work-periods" ] } }, @@ -17895,12 +19118,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriodPayments", + "raw": "{{URL}}/work-period-payments", "host": [ "{{URL}}" ], "path": [ - "workPeriodPayments" + "work-period-payments" ] } }, @@ -17944,12 +19167,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriodPayments", + "raw": "{{URL}}/work-period-payments", "host": [ "{{URL}}" ], "path": [ - "workPeriodPayments" + "work-period-payments" ] } }, @@ -17982,12 +19205,12 @@ } ], "url": { - "raw": "{{URL}}/workPeriodPayments/{{workPeriodPaymentId_created_for_connect_manager}}", + "raw": "{{URL}}/work-period-payments/{{workPeriodPaymentId_created_for_connect_manager}}", "host": [ "{{URL}}" ], "path": [ - "workPeriodPayments", + "work-period-payments", "{{workPeriodPaymentId_created_for_connect_manager}}" ] } @@ -18021,12 +19244,12 @@ } ], "url": { - "raw": "{{URL}}/workPeriodPayments", + "raw": "{{URL}}/work-period-payments", "host": [ "{{URL}}" ], "path": [ - "workPeriodPayments" + "work-period-payments" ], "query": [ { @@ -18105,12 +19328,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriodPayments/{{workPeriodPaymentId_created_for_connect_manager}}", + "raw": "{{URL}}/work-period-payments/{{workPeriodPaymentId_created_for_connect_manager}}", "host": [ "{{URL}}" ], "path": [ - "workPeriodPayments", + "work-period-payments", "{{workPeriodPaymentId_created_for_connect_manager}}" ] } @@ -18153,12 +19376,12 @@ } }, "url": { - "raw": "{{URL}}/workPeriodPayments/{{workPeriodPaymentId_created_for_connect_manager}}", + "raw": "{{URL}}/work-period-payments/{{workPeriodPaymentId_created_for_connect_manager}}", "host": [ "{{URL}}" ], "path": [ - "workPeriodPayments", + "work-period-payments", "{{workPeriodPaymentId_created_for_connect_manager}}" ] } diff --git a/docs/swagger.yaml b/docs/swagger.yaml index 6a81a28f..af8c680a 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -589,15 +589,7 @@ paths: required: false schema: type: string - enum: - [ - "open", - "selected", - "shortlist", - "rejected", - "cancelled", - "interview", - ] + enum: ['open', 'selected', 'shortlist', 'rejected', 'cancelled', 'interview', 'topcoder-rejected'] description: The job candidate status. - in: query name: externalId @@ -1347,7 +1339,7 @@ paths: application/json: schema: $ref: "#/components/schemas/Error" - /workPeriods: + /work-periods: post: tags: - WorkPeriods @@ -1565,7 +1557,7 @@ paths: application/json: schema: $ref: "#/components/schemas/Error" - /workPeriods/{id}: + /work-periods/{id}: get: tags: - WorkPeriods @@ -1795,7 +1787,7 @@ paths: application/json: schema: $ref: "#/components/schemas/Error" - /workPeriodPayments: + /work-period-payments: post: tags: - WorkPeriodPayments @@ -1979,7 +1971,7 @@ paths: application/json: schema: $ref: "#/components/schemas/Error" - /workPeriodPayments/{id}: + /work-period-payments/{id}: get: tags: - WorkPeriodPayments @@ -2984,15 +2976,7 @@ components: description: "The user id." status: type: string - enum: - [ - "open", - "selected", - "shortlist", - "rejected", - "cancelled", - "interview", - ] + enum: ['open', 'selected', 'shortlist', 'rejected', 'cancelled', 'interview', 'topcoder-rejected'] description: "The job candidate status." externalId: type: string @@ -3049,15 +3033,7 @@ components: properties: status: type: string - enum: - [ - "open", - "selected", - "shortlist", - "rejected", - "cancelled", - "interview", - ] + enum: ['open', 'selected', 'shortlist', 'rejected', 'cancelled', 'interview', 'topcoder-rejected'] externalId: type: string example: "1212" @@ -3139,7 +3115,7 @@ components: description: "The external id." status: type: string - enum: ["sourcing", "in-review", "assigned", "closed", "cancelled"] + enum: ["assigned", "closed", "cancelled"] description: "The job status." startDate: type: string @@ -3149,7 +3125,7 @@ components: endDate: type: string format: date-time - example: "2020-09-27T04:17:23.131Z" + example: "2020-09-28T04:17:23.131Z" description: "The job end date." memberRate: type: integer @@ -3202,7 +3178,7 @@ components: description: "The job id." status: type: string - enum: ["sourcing", "in-review", "assigned", "closed", "cancelled"] + enum: ["assigned", "closed", "cancelled"] description: "The job status." default: sourcing startDate: @@ -3213,7 +3189,7 @@ components: endDate: type: string format: date-time - example: "2020-09-27T04:17:23.131Z" + example: "2020-09-28T04:17:23.131Z" description: "The job end date." memberRate: type: number @@ -3233,7 +3209,7 @@ components: properties: status: type: string - enum: ["sourcing", "in-review", "assigned", "closed", "cancelled"] + enum: ["assigned", "closed", "cancelled"] startDate: type: string format: date-time @@ -3242,7 +3218,7 @@ components: endDate: type: string format: date-time - example: "2020-09-27T04:17:23.131Z" + example: "2020-09-28T04:17:23.131Z" description: "The job end date." memberRate: type: number @@ -3846,15 +3822,7 @@ components: description: "The link for the resume that can be downloaded" status: type: string - enum: - [ - "open", - "selected", - "shortlist", - "rejected", - "cancelled", - "interview", - ] + enum: ['open', 'selected', 'shortlist', 'rejected', 'cancelled', 'interview', 'topcoder-rejected'] description: "The job candidate status." skills: type: array diff --git a/docs/topcoder-bookings.postman_environment.json b/docs/topcoder-bookings.postman_environment.json index 4775bcee..fc326e86 100644 --- a/docs/topcoder-bookings.postman_environment.json +++ b/docs/topcoder-bookings.postman_environment.json @@ -137,6 +137,11 @@ "value": "16843", "enabled": true }, + { + "key": "project_id_17234", + "value": "17234", + "enabled": true + }, { "key": "jobId", "value": "", @@ -192,6 +197,11 @@ "value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL3RvcGNvZGVyLWRldi5hdXRoMC5jb20vIiwic3ViIjoiZW5qdzE4MTBlRHozWFR3U08yUm4yWTljUVRyc3BuM0JAY2xpZW50cyIsImF1ZCI6Imh0dHBzOi8vbTJtLnRvcGNvZGVyLWRldi5jb20vIiwiaWF0IjoxNTUwOTA2Mzg4LCJleHAiOjIxNDc0ODM2NDgsImF6cCI6ImVuancxODEwZUR6M1hUd1NPMlJuMlk5Y1FUcnNwbjNCIiwic2NvcGUiOiJyZWFkOnRhYXMtd29ya1BlcmlvZHMiLCJndHkiOiJjbGllbnQtY3JlZGVudGlhbHMifQ.y0-mysWkSf6YnUw9jKhxzg65ngPWNhfXzGQGCVWhXrk", "enabled": true }, + { + "key": "token_m2m_read_work_period_and_payment", + "value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL3RvcGNvZGVyLWRldi5hdXRoMC5jb20vIiwic3ViIjoiZW5qdzE4MTBlRHozWFR3U08yUm4yWTljUVRyc3BuM0JAY2xpZW50cyIsImF1ZCI6Imh0dHBzOi8vbTJtLnRvcGNvZGVyLWRldi5jb20vIiwiaWF0IjoxNTUwOTA2Mzg4LCJleHAiOjIxNDc0ODM2NDgsImF6cCI6ImVuancxODEwZUR6M1hUd1NPMlJuMlk5Y1FUcnNwbjNCIiwic2NvcGUiOiJyZWFkOnRhYXMtd29ya1BlcmlvZHMgcmVhZDp0YWFzLXdvcmtQZXJpb2RQYXltZW50cyIsImd0eSI6ImNsaWVudC1jcmVkZW50aWFscyJ9.9BEieQDP5totqvwriBozy8cgFQRiLXQ6xA6IJT9SD8s", + "enabled": true + }, { "key": "token_m2m_update_work_period", "value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL3RvcGNvZGVyLWRldi5hdXRoMC5jb20vIiwic3ViIjoiZW5qdzE4MTBlRHozWFR3U08yUm4yWTljUVRyc3BuM0JAY2xpZW50cyIsImF1ZCI6Imh0dHBzOi8vbTJtLnRvcGNvZGVyLWRldi5jb20vIiwiaWF0IjoxNTUwOTA2Mzg4LCJleHAiOjIxNDc0ODM2NDgsImF6cCI6ImVuancxODEwZUR6M1hUd1NPMlJuMlk5Y1FUcnNwbjNCIiwic2NvcGUiOiJ1cGRhdGU6dGFhcy13b3JrUGVyaW9kcyIsImd0eSI6ImNsaWVudC1jcmVkZW50aWFscyJ9.TU4vUcrQylzIyB6hDMqqC5NucpDSRMHWd-PZ6uW_lEc", @@ -207,6 +217,11 @@ "value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL3RvcGNvZGVyLWRldi5hdXRoMC5jb20vIiwic3ViIjoiZW5qdzE4MTBlRHozWFR3U08yUm4yWTljUVRyc3BuM0JAY2xpZW50cyIsImF1ZCI6Imh0dHBzOi8vbTJtLnRvcGNvZGVyLWRldi5jb20vIiwiaWF0IjoxNTUwOTA2Mzg4LCJleHAiOjIxNDc0ODM2NDgsImF6cCI6ImVuancxODEwZUR6M1hUd1NPMlJuMlk5Y1FUcnNwbjNCIiwic2NvcGUiOiJhbGw6dGFhcy13b3JrUGVyaW9kcyIsImd0eSI6ImNsaWVudC1jcmVkZW50aWFscyJ9.0gEgjGsG4ftTOlfN1bTZQXw3YIvxBiCGJEBzD0bmyUE", "enabled": true }, + { + "key": "token_m2m_all_work_period_and_payment", + "value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL3RvcGNvZGVyLWRldi5hdXRoMC5jb20vIiwic3ViIjoiZW5qdzE4MTBlRHozWFR3U08yUm4yWTljUVRyc3BuM0JAY2xpZW50cyIsImF1ZCI6Imh0dHBzOi8vbTJtLnRvcGNvZGVyLWRldi5jb20vIiwiaWF0IjoxNTUwOTA2Mzg4LCJleHAiOjIxNDc0ODM2NDgsImF6cCI6ImVuancxODEwZUR6M1hUd1NPMlJuMlk5Y1FUcnNwbjNCIiwic2NvcGUiOiJhbGw6dGFhcy13b3JrUGVyaW9kcyBhbGw6dGFhcy13b3JrUGVyaW9kUGF5bWVudHMiLCJndHkiOiJjbGllbnQtY3JlZGVudGlhbHMifQ.3y9Rij_PH5V9DgX5SxMKN6_RaxtbpDGPz-rTbzdVM4Q", + "enabled": true + }, { "key": "token_m2m_create_work_period_payment", "value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL3RvcGNvZGVyLWRldi5hdXRoMC5jb20vIiwic3ViIjoiZW5qdzE4MTBlRHozWFR3U08yUm4yWTljUVRyc3BuM0JAY2xpZW50cyIsImF1ZCI6Imh0dHBzOi8vbTJtLnRvcGNvZGVyLWRldi5jb20vIiwiaWF0IjoxNTUwOTA2Mzg4LCJleHAiOjIxNDc0ODM2NDgsImF6cCI6ImVuancxODEwZUR6M1hUd1NPMlJuMlk5Y1FUcnNwbjNCIiwic2NvcGUiOiJjcmVhdGU6dGFhcy13b3JrUGVyaW9kUGF5bWVudHMiLCJndHkiOiJjbGllbnQtY3JlZGVudGlhbHMifQ.9XELn_QXS6zk8XEvusiIe42xddUO29oW0QbqljOlj18", diff --git a/local/kafka-client/topics.txt b/local/kafka-client/topics.txt index 30aa51ae..dc37db59 100644 --- a/local/kafka-client/topics.txt +++ b/local/kafka-client/topics.txt @@ -12,4 +12,5 @@ taas.job.delete taas.jobcandidate.delete taas.resourcebooking.delete taas.workperiod.delete +taas.workperiodpayment.delete external.action.email diff --git a/migrations/2021-03-30-work-period-table-create.js b/migrations/2021-03-30-work-period-table-create.js index bf6cdb0f..04a0c66c 100644 --- a/migrations/2021-03-30-work-period-table-create.js +++ b/migrations/2021-03-30-work-period-table-create.js @@ -28,7 +28,7 @@ module.exports = { key: 'id' }, onUpdate: 'CASCADE', - onDelete: 'CASCADE', + onDelete: 'CASCADE' }, userHandle: { field: 'user_handle', @@ -89,7 +89,7 @@ module.exports = { type: Sequelize.DATE } }, { - schema: 'bookings', + schema: config.DB_SCHEMA_NAME, transaction }) await queryInterface.addIndex( diff --git a/migrations/2021-04-10-populate-work-periods-for-resource-bookings.js b/migrations/2021-04-10-populate-work-periods-for-resource-bookings.js new file mode 100644 index 00000000..a15d64cd --- /dev/null +++ b/migrations/2021-04-10-populate-work-periods-for-resource-bookings.js @@ -0,0 +1,81 @@ +const config = require('config') +const ResourceBooking = require('../src/models').ResourceBooking +const _ = require('lodash') +const helper = require('../src/common/helper') +const { v4: uuid } = require('uuid') + +// maximum start date of resource bookings when populating work periods from existing resource bookings in migration script +const MAX_START_DATE = process.env.MAX_START_DATE || '2100-12-31' +// maximum end date of resource bookings when populating work periods from existing resource bookings in migration script +const MAX_END_DATE = process.env.MAX_END_DATE || '2100-12-31' + +/* + * Populate WorkPeriods for ResourceBookings + */ + +module.exports = { + up: async (queryInterface, Sequelize) => { + const transaction = await queryInterface.sequelize.transaction() + const Op = Sequelize.Op + try { + const resourceBookings = await ResourceBooking.findAll({ + where: { + start_date: { [Op.lt]: new Date(MAX_START_DATE) }, + end_date: { [Op.lt]: new Date(MAX_END_DATE) } + } + }) + if (resourceBookings.length === 0) { + await transaction.rollback() + return + } + const workPeriodData = [] + await Promise.all(resourceBookings.map(async rb => { + if (!_.isNil(rb.startDate) && !_.isNil(rb.endDate)) { + const periods = helper.extractWorkPeriods(rb.startDate, rb.endDate) + const user = await helper.ensureUserById(rb.userId) + _.forEach(periods, period => { + workPeriodData.push({ + id: uuid(), + resource_booking_id: rb.id, + project_id: rb.projectId, + user_handle: user.handle, + start_date: period.startDate, + end_date: period.endDate, + days_worked: period.daysWorked, + payment_status: 'pending', + created_by: config.m2m.M2M_AUDIT_USER_ID, + created_at: new Date() + }) + }) + } + })) + await queryInterface.bulkInsert({ tableName: 'work_periods', schema: config.DB_SCHEMA_NAME }, workPeriodData, { transaction }) + await transaction.commit() + } catch (err) { + await transaction.rollback() + throw err + } + }, + down: async (queryInterface, Sequelize) => { + const transaction = await queryInterface.sequelize.transaction() + try { + const Op = Sequelize.Op + const resourceBookings = await ResourceBooking.findAll({ + where: { + start_date: { [Op.lt]: new Date(MAX_START_DATE) }, + end_date: { [Op.lt]: new Date(MAX_END_DATE) } + }, + // include soft-deleted resourceBookings + paranoid: false + }) + const resourceBookingIds = _.map(resourceBookings, rb => rb.dataValues.id) + + await queryInterface.bulkDelete({ tableName: 'work_periods', schema: config.DB_SCHEMA_NAME }, + { resource_booking_id: { [Op.in]: resourceBookingIds } }, { transaction }) + await transaction.commit() + } catch (err) { + await transaction.rollback() + throw err + } + } +} diff --git a/migrations/2021-04-10-work-period-payment-table-create.js b/migrations/2021-04-10-work-period-payment-table-create.js index 97e629e2..03f9752a 100644 --- a/migrations/2021-04-10-work-period-payment-table-create.js +++ b/migrations/2021-04-10-work-period-payment-table-create.js @@ -30,8 +30,7 @@ module.exports = { challengeId: { field: 'challenge_id', type: Sequelize.UUID, - allowNull: false, - defaultValue: '00000000-0000-0000-0000-000000000000' + allowNull: false }, amount: { type: Sequelize.DOUBLE @@ -65,7 +64,7 @@ module.exports = { type: Sequelize.DATE } }, { - schema: 'bookings', + schema: config.DB_SCHEMA_NAME, transaction }) }, diff --git a/package-lock.json b/package-lock.json index 225069c1..50293037 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4889,9 +4889,9 @@ "integrity": "sha512-z6IJ5HXYiuxvFTI6eiQ9dm77uE0gyy1yXNApVHqTcnIKfY9tIwEjlzsZ6u1LQXvVgKeTnv9Xm7NDvJ7lso3MtA==" }, "moment-timezone": { - "version": "0.5.32", - "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.32.tgz", - "integrity": "sha512-Z8QNyuQHQAmWucp8Knmgei8YNo28aLjJq6Ma+jy1ZSpSk5nyfRT8xgUbSQvD2+2UajISfenndwvFuH3NGS+nvA==", + "version": "0.5.33", + "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.33.tgz", + "integrity": "sha512-PTc2vcT8K9J5/9rDEPe5czSIKgLoGsH8UNpA4qZTVw0Vd/Uz19geE9abbIOQKaAQFcnQ3v5YEXrbSc5BpshH+w==", "requires": { "moment": ">= 2.9.0" } diff --git a/package.json b/package.json index 7955d353..3625c1bf 100644 --- a/package.json +++ b/package.json @@ -50,6 +50,7 @@ "http-status-codes": "^2.1.4", "joi": "^17.2.1", "lodash": "^4.17.20", + "moment-timezone": "^0.5.33", "pg": "^8.4.0", "pg-hstore": "^2.3.3", "prompt-confirm": "^2.0.4", diff --git a/src/bootstrap.js b/src/bootstrap.js index e8f2eee9..337ace6b 100644 --- a/src/bootstrap.js +++ b/src/bootstrap.js @@ -7,8 +7,9 @@ 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.workload = () => Joi.string().valid('full-time', 'fractional') -Joi.jobCandidateStatus = () => Joi.string().valid('open', 'selected', 'shortlist', 'rejected', 'cancelled', 'interview') +Joi.jobCandidateStatus = () => Joi.string().valid('open', 'selected', 'shortlist', 'rejected', 'cancelled', 'interview', 'topcoder-rejected') Joi.title = () => Joi.string().max(128) Joi.paymentStatus = () => Joi.string().valid('pending', 'partially-completed', 'completed', 'cancelled') Joi.workPeriodPaymentStatus = () => Joi.string().valid('completed', 'cancelled') diff --git a/src/common/helper.js b/src/common/helper.js index 773017c6..00353bed 100644 --- a/src/common/helper.js +++ b/src/common/helper.js @@ -17,6 +17,7 @@ const logger = require('./logger') const models = require('../models') const eventDispatcher = require('./eventDispatcher') const busApi = require('@topcoder-platform/topcoder-bus-api-wrapper') +const moment = require('moment-timezone') const localLogger = { debug: (message) => logger.debug({ component: 'helper', context: message.context, message: message.message }), @@ -116,6 +117,7 @@ esIndexPropertyMapping[config.get('esConfig.ES_INDEX_WORK_PERIOD')] = { payments: { type: 'nested', properties: { + id: { type: 'keyword' }, workPeriodId: { type: 'keyword' }, challengeId: { type: 'keyword' }, amount: { type: 'float' }, @@ -1252,6 +1254,50 @@ async function createChallengeResource (data, token) { return resource } +/** + * Populates workPeriods from start and end date of resource booking + * @param {Date} start start date of the resource booking + * @param {Date} end end date of the resource booking + * @returns {Array} information about workPeriods + */ +function extractWorkPeriods (start, end) { + // canculate daysWorked for a week + function getDaysWorked (week) { + if (weeks === 1) { + return Math.min(endDay, 5) - Math.max(startDay, 1) + 1 + } else if (week === 0) { + return Math.min(6 - startDay, 5) + } else if (week === (weeks - 1)) { + return Math.min(endDay, 5) + } else return 5 + } + const periods = [] + if (_.isNil(start) || _.isNil(end)) { + return periods + } + const startDate = moment(start) + startDate.tz(config.WORK_PERIOD_TIME_ZONE, false) + const startDay = startDate.get('day') + startDate.set('day', 0).startOf('day') + + const endDate = moment(end) + endDate.tz(config.WORK_PERIOD_TIME_ZONE, false) + const endDay = endDate.get('day') + endDate.set('day', 6).endOf('day') + + const weeks = Math.round(moment.duration(endDate - startDate).asDays()) / 7 + + for (let i = 0; i < weeks; i++) { + periods.push({ + startDate: startDate.format('YYYY-MM-DD'), + endDate: startDate.add(6, 'day').format('YYYY-MM-DD'), + daysWorked: getDaysWorked(i) + }) + startDate.add(1, 'day') + } + return periods +} + module.exports = { getParamFromCliArgs, promptUser, @@ -1298,5 +1344,6 @@ module.exports = { deleteProjectMember, createChallenge, updateChallenge, - createChallengeResource + createChallengeResource, + extractWorkPeriods } diff --git a/src/eventHandlers/ResourceBookingEventHandler.js b/src/eventHandlers/ResourceBookingEventHandler.js index 69dbe1dd..95947436 100644 --- a/src/eventHandlers/ResourceBookingEventHandler.js +++ b/src/eventHandlers/ResourceBookingEventHandler.js @@ -9,6 +9,8 @@ const logger = require('../common/logger') const helper = require('../common/helper') const JobService = require('../services/JobService') const JobCandidateService = require('../services/JobCandidateService') +const WorkPeriodService = require('../services/WorkPeriodService') +const WorkPeriod = models.WorkPeriod /** * When ResourceBooking's status is changed to `assigned` @@ -124,6 +126,167 @@ async function assignJob (payload) { } } +/** + * When a ResourceBooking is created, workPeriods that cover each weeks + * of resource booking should be also created + * @param {object} payload the event payload + * @returns {undefined} + */ +async function createWorkPeriods (payload) { + // if startDate or endDate is not provided then we can't create work period + if (_.isNil(payload.value.startDate) || _.isNil(payload.value.endDate)) { + logger.debug({ + component: 'ResourceBookingEventHandler', + context: 'createWorkPeriods', + message: `id: ${payload.value.id} resource booking without endDate or startDate - ignored` + }) + return + } + // collect dates of work periods + const workPeriodDates = helper.extractWorkPeriods(payload.value.startDate, payload.value.endDate) + await _createWorkPeriods(workPeriodDates, payload.value.id) + logger.debug({ + component: 'ResourceBookingEventHandler', + context: 'createWorkPeriods', + message: `WorkPeriods created for resource booking with id: ${payload.value.id}` + }) +} + +/** + * When a ResourceBooking is updated, workPeriods related to + * that ResourceBooking should be updated also. + * This function finds aout which workPeriods should be deleted, + * which ones should be created and which ones should be updated + * @param {object} payload the event payload + * @returns {undefined} + */ +async function updateWorkPeriods (payload) { + // find related workPeriods to evaluate the changes + const workPeriods = await WorkPeriod.findAll({ + where: { + resourceBookingId: payload.value.id + }, + raw: true + }) + // gather workPeriod dates + const newWorkPeriods = helper.extractWorkPeriods(payload.value.startDate || payload.options.oldValue.startDate, payload.value.endDate || payload.options.oldValue.endDate) + // find which workPeriods should be removed + const workPeriodsToRemove = _.differenceBy(workPeriods, newWorkPeriods, 'startDate') + // find which workperiods should be created + const workPeriodsToAdd = _.differenceBy(newWorkPeriods, workPeriods, 'startDate') + // find which workperiods' daysWorked propery should be updated + let workPeriodsToUpdate = _.intersectionBy(newWorkPeriods, workPeriods, 'startDate') + workPeriodsToUpdate = _.differenceWith(workPeriodsToUpdate, workPeriods, (a, b) => b.startDate === a.startDate && b.daysWorked === a.daysWorked) + // include id + workPeriodsToUpdate = _.map(workPeriodsToUpdate, wpu => { + wpu.id = _.filter(workPeriods, ['startDate', wpu.startDate])[0].id + return wpu + }) + if (workPeriodsToRemove.length === 0 && workPeriodsToAdd.length === 0 && workPeriodsToUpdate.length === 0) { + logger.debug({ + component: 'ResourceBookingEventHandler', + context: 'updateWorkPeriods', + message: `id: ${payload.value.id} resource booking has no change in dates - ignored` + }) + return + } + if (workPeriodsToRemove.length > 0) { + await _deleteWorkPeriods(workPeriodsToRemove) + logger.debug({ + component: 'ResourceBookingEventHandler', + context: 'updateWorkPeriods', + message: `Old WorkPeriods deleted for resource booking with id: ${payload.value.id}` + }) + } + if (workPeriodsToAdd.length > 0) { + await _createWorkPeriods(workPeriodsToAdd, payload.value.id) + logger.debug({ + component: 'ResourceBookingEventHandler', + context: 'updateWorkPeriods', + message: `New WorkPeriods created for resource booking with id: ${payload.value.id}` + }) + } + if (workPeriodsToUpdate.length > 0) { + await _updateWorkPeriods(workPeriodsToUpdate) + logger.debug({ + component: 'ResourceBookingEventHandler', + context: 'updateWorkPeriods', + message: `WorkPeriods updated for resource booking with id: ${payload.value.id}` + }) + } +} + +/** + * When a ResourceBooking is deleted, workPeriods related to + * that ResourceBooking should also be deleted + * @param {object} payload the event payload + * @returns {undefined} + */ +async function deleteWorkPeriods (payload) { + // find related workPeriods to delete + const workPeriods = await WorkPeriod.findAll({ + where: { + resourceBookingId: payload.value.id + }, + raw: true + }) + if (workPeriods.length === 0) { + logger.debug({ + component: 'ResourceBookingEventHandler', + context: 'deleteWorkPeriods', + message: `id: ${payload.value.id} resource booking has no workPeriods - ignored` + }) + return + } + await _deleteWorkPeriods(workPeriods) + logger.debug({ + component: 'ResourceBookingEventHandler', + context: 'deleteWorkPeriods', + message: `WorkPeriods deleted for resource booking with id: ${payload.value.id}` + }) +} + +/** + * Calls WorkPeriodService to create workPeriods + * @param {Array<{startDate:Date, + * endDate:Date, daysWorked:number}>} periods work period data + * @param {string} resourceBookingId resourceBookingId of work period + * @returns {undefined} + */ +async function _createWorkPeriods (periods, resourceBookingId) { + await Promise.all(_.map(periods, async period => await WorkPeriodService.createWorkPeriod(helper.getAuditM2Muser(), + { + resourceBookingId: resourceBookingId, + startDate: period.startDate, + endDate: period.endDate, + daysWorked: period.daysWorked, + paymentStatus: 'pending' + }))) +} + +/** + * Calls WorkPeriodService to update workPeriods + * @param {Array<{daysWorked:number}>} periods work period data + * @returns {undefined} + */ +async function _updateWorkPeriods (periods) { + await Promise.all(_.map(periods, async period => await WorkPeriodService.partiallyUpdateWorkPeriod(helper.getAuditM2Muser(), + period.id, + { + daysWorked: period.daysWorked + }))) +} + +/** + * Calls WorkPeriodService to delete workPeriods + * @param {Array<{id:string}>} workPeriods work period objects + * @returns {undefined} + */ +async function _deleteWorkPeriods (workPeriods) { + await Promise.all(_.map(workPeriods, + async workPeriod => await WorkPeriodService.deleteWorkPeriod(helper.getAuditM2Muser(), workPeriod.id))) +} + /** * Process resource booking create event. * @@ -133,6 +296,7 @@ async function assignJob (payload) { async function processCreate (payload) { await selectJobCandidate(payload) await assignJob(payload) + await createWorkPeriods(payload) } /** @@ -144,9 +308,21 @@ async function processCreate (payload) { async function processUpdate (payload) { await selectJobCandidate(payload) await assignJob(payload) + await updateWorkPeriods(payload) +} + +/** + * Process resource booking delete event. + * + * @param {Object} payload the event payload + * @returns {undefined} + */ +async function processDelete (payload) { + await deleteWorkPeriods(payload) } module.exports = { processCreate, - processUpdate + processUpdate, + processDelete } diff --git a/src/eventHandlers/index.js b/src/eventHandlers/index.js index f4089ea0..309b5f82 100644 --- a/src/eventHandlers/index.js +++ b/src/eventHandlers/index.js @@ -13,7 +13,8 @@ const TopicOperationMapping = { [config.TAAS_JOB_UPDATE_TOPIC]: JobEventHandler.processUpdate, [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_UPDATE_TOPIC]: ResourceBookingEventHandler.processUpdate, + [config.TAAS_RESOURCE_BOOKING_DELETE_TOPIC]: ResourceBookingEventHandler.processDelete } /** diff --git a/src/models/WorkPeriod.js b/src/models/WorkPeriod.js index 124a2a03..455818b5 100644 --- a/src/models/WorkPeriod.js +++ b/src/models/WorkPeriod.js @@ -17,16 +17,16 @@ module.exports = (sequelize) => { /** * Get work period by id * @param {String} id the work period id - * @param {Boolean} withPayments whether contains payments + * @param {Object} options { withPayments: true/false } whether contains payments * @returns {WorkPeriod} the work period instance */ - static async findById (id, withPayments) { + static async findById (id, options = { withPayments: false }) { const criteria = { where: { id } } - if (withPayments) { + if (options.withPayments) { criteria.include = [{ model: WorkPeriod._models.WorkPeriodPayment, as: 'payments', diff --git a/src/models/WorkPeriodPayment.js b/src/models/WorkPeriodPayment.js index 90055e50..6b9e37fa 100644 --- a/src/models/WorkPeriodPayment.js +++ b/src/models/WorkPeriodPayment.js @@ -45,8 +45,7 @@ module.exports = (sequelize) => { challengeId: { field: 'challenge_id', type: Sequelize.UUID, - allowNull: false, - defaultValue: '00000000-0000-0000-0000-000000000000' + allowNull: false }, amount: { type: Sequelize.DOUBLE diff --git a/src/routes/WorkPeriodPaymentRoutes.js b/src/routes/WorkPeriodPaymentRoutes.js index b3debf66..dcc284eb 100644 --- a/src/routes/WorkPeriodPaymentRoutes.js +++ b/src/routes/WorkPeriodPaymentRoutes.js @@ -4,7 +4,7 @@ const constants = require('../../app-constants') module.exports = { - '/workPeriodPayments': { + '/work-period-payments': { post: { controller: 'WorkPeriodPaymentController', method: 'createWorkPeriodPayment', @@ -18,7 +18,7 @@ module.exports = { scopes: [constants.Scopes.READ_WORK_PERIOD_PAYMENT, constants.Scopes.ALL_WORK_PERIOD_PAYMENT] } }, - '/workPeriodPayments/:id': { + '/work-period-payments/:id': { get: { controller: 'WorkPeriodPaymentController', method: 'getWorkPeriodPayment', diff --git a/src/routes/WorkPeriodRoutes.js b/src/routes/WorkPeriodRoutes.js index 42e61de4..7f84b5b0 100644 --- a/src/routes/WorkPeriodRoutes.js +++ b/src/routes/WorkPeriodRoutes.js @@ -4,7 +4,7 @@ const constants = require('../../app-constants') module.exports = { - '/workPeriods': { + '/work-periods': { post: { controller: 'WorkPeriodController', method: 'createWorkPeriod', @@ -18,7 +18,7 @@ module.exports = { scopes: [constants.Scopes.READ_WORK_PERIOD, constants.Scopes.ALL_WORK_PERIOD] } }, - '/workPeriods/:id': { + '/work-periods/:id': { get: { controller: 'WorkPeriodController', method: 'getWorkPeriod', diff --git a/src/services/ResourceBookingService.js b/src/services/ResourceBookingService.js index 120b9539..972729f1 100644 --- a/src/services/ResourceBookingService.js +++ b/src/services/ResourceBookingService.js @@ -14,6 +14,7 @@ const errors = require('../common/errors') const models = require('../models') const ResourceBooking = models.ResourceBooking +const WorkPeriod = models.WorkPeriod const esClient = helper.getESClient() /** @@ -42,6 +43,50 @@ async function _checkUserPermissionForGetResourceBooking (currentUser, projectId } } +/** + * Check if any work period is paid and tried to be deleted + * + * @param {string} resourceBookingId workPeriod object array. + * @param {Object} [oldValue] old value of resourceBooking object. + * @param {Object} [newValue] new value of resourceBooking object. + * @throws {BadRequestError} + */ +async function _ensurePaidWorkPeriodsNotDeleted (resourceBookingId, oldValue, newValue) { + function _checkForPaidWorkPeriods (workPeriods) { + const paidWorkPeriods = _.filter(workPeriods + , workPeriod => _.includes(['completed', 'partially-completed'], workPeriod.paymentStatus)) + if (paidWorkPeriods.length > 0) { + throw new errors.BadRequestError(`WorkPeriods with id of ${_.map(paidWorkPeriods, workPeriod => workPeriod.id)} + has completed or partially-completed payment status.`) + } + } + // find related workPeriods to evaluate the changes + const workPeriods = await WorkPeriod.findAll({ + where: { + resourceBookingId: resourceBookingId + }, + raw: true + }) + // oldValue and newValue are not provided at deleteResourceBooking process + if (_.isUndefined(oldValue) || _.isUndefined(newValue)) { + _checkForPaidWorkPeriods(workPeriods) + return + } + // We should not be able to change status of ResourceBooking to 'cancelled' + // if there is at least one associated Work Period with paymentStatus 'partially-completed' or 'completed'. + if (oldValue.status !== 'cancelled' && newValue.status === 'cancelled') { + _checkForPaidWorkPeriods(workPeriods) + // we have already checked all existing workPeriods + return + } + // gather workPeriod dates from provided dates + const newWorkPeriods = helper.extractWorkPeriods(newValue.startDate || oldValue.startDate, newValue.endDate || oldValue.endDate) + // find which workPeriods should be removed + const workPeriodsToRemove = _.differenceBy(workPeriods, newWorkPeriods, 'startDate') + // we can't delete workperiods with paymentStatus 'partially-completed' or 'completed'. + _checkForPaidWorkPeriods(workPeriodsToRemove) +} + /** * Get resourceBooking by id * @param {Object} currentUser the user who perform this operation. @@ -113,12 +158,19 @@ async function createResourceBooking (currentUser, resourceBooking) { createResourceBooking.schema = Joi.object().keys({ currentUser: Joi.object().required(), resourceBooking: Joi.object().keys({ - status: Joi.jobStatus().default('sourcing'), + status: Joi.resourceBookingStatus().default('assigned'), projectId: Joi.number().integer().required(), userId: Joi.string().uuid().required(), jobId: Joi.string().uuid().allow(null), startDate: Joi.date().allow(null), - endDate: Joi.date().allow(null), + endDate: Joi.date().when('startDate', { + is: Joi.exist(), + then: Joi.date().allow(null).min(Joi.ref('startDate') + ).messages({ + 'date.min': 'endDate cannot be earlier than startDate' + }), + otherwise: Joi.date().allow(null) + }), memberRate: Joi.number().allow(null), customerRate: Joi.number().allow(null), rateType: Joi.rateType().required() @@ -127,9 +179,9 @@ createResourceBooking.schema = Joi.object().keys({ /** * Update resourceBooking - * @params {Object} currentUser the user who perform this operation - * @params {String} id the resourceBooking id - * @params {Object} data the data to be updated + * @param {Object} currentUser the user who perform this operation + * @param {String} id the resourceBooking id + * @param {Object} data the data to be updated * @returns {Object} the updated resourceBooking */ async function updateResourceBooking (currentUser, id, data) { @@ -140,6 +192,8 @@ async function updateResourceBooking (currentUser, id, data) { const resourceBooking = await ResourceBooking.findById(id) const oldValue = resourceBooking.toJSON() + // before updating the record, we need to check if any paid work periods tried to be deleted + await _ensurePaidWorkPeriodsNotDeleted(id, oldValue, data) data.updatedBy = await helper.getUserId(currentUser.userId) @@ -151,9 +205,9 @@ async function updateResourceBooking (currentUser, id, data) { /** * Partially update resourceBooking by id - * @params {Object} currentUser the user who perform this operation - * @params {String} id the resourceBooking id - * @params {Object} data the data to be updated + * @param {Object} currentUser the user who perform this operation + * @param {String} id the resourceBooking id + * @param {Object} data the data to be updated * @returns {Object} the updated resourceBooking */ async function partiallyUpdateResourceBooking (currentUser, id, data) { @@ -164,9 +218,16 @@ partiallyUpdateResourceBooking.schema = Joi.object().keys({ currentUser: Joi.object().required(), id: Joi.string().uuid().required(), data: Joi.object().keys({ - status: Joi.jobStatus(), + status: Joi.resourceBookingStatus(), startDate: Joi.date().allow(null), - endDate: Joi.date().allow(null), + endDate: Joi.date().when('startDate', { + is: Joi.exist(), + then: Joi.date().allow(null).min(Joi.ref('startDate') + ).messages({ + 'date.min': 'endDate cannot be earlier than startDate' + }), + otherwise: Joi.date().allow(null) + }), memberRate: Joi.number().allow(null), customerRate: Joi.number().allow(null), rateType: Joi.rateType() @@ -175,9 +236,9 @@ partiallyUpdateResourceBooking.schema = Joi.object().keys({ /** * Fully update resourceBooking by id - * @params {Object} currentUser the user who perform this operation - * @params {String} id the resourceBooking id - * @params {Object} data the data to be updated + * @param {Object} currentUser the user who perform this operation + * @param {String} id the resourceBooking id + * @param {Object} data the data to be updated * @returns {Object} the updated resourceBooking */ async function fullyUpdateResourceBooking (currentUser, id, data) { @@ -196,18 +257,25 @@ fullyUpdateResourceBooking.schema = Joi.object().keys({ userId: Joi.string().uuid().required(), jobId: Joi.string().uuid().allow(null).default(null), startDate: Joi.date().allow(null).default(null), - endDate: Joi.date().allow(null).default(null), + endDate: Joi.date().when('startDate', { + is: Joi.exist(), + then: Joi.date().allow(null).default(null).min(Joi.ref('startDate') + ).messages({ + 'date.min': 'endDate cannot be earlier than startDate' + }), + otherwise: Joi.date().allow(null).default(null) + }), memberRate: Joi.number().allow(null).default(null), customerRate: Joi.number().allow(null).default(null), rateType: Joi.rateType().required(), - status: Joi.jobStatus().default('sourcing') + status: Joi.resourceBookingStatus().required() }).required() }).required() /** * Delete resourceBooking by id - * @params {Object} currentUser the user who perform this operation - * @params {String} id the resourceBooking id + * @param {Object} currentUser the user who perform this operation + * @param {String} id the resourceBooking id */ async function deleteResourceBooking (currentUser, id) { // check permission @@ -215,6 +283,8 @@ async function deleteResourceBooking (currentUser, id) { throw new errors.ForbiddenError('You are not allowed to perform this action!') } + // we can't delete workperiods with paymentStatus 'partially-completed' or 'completed'. + await _ensurePaidWorkPeriodsNotDeleted(id) const resourceBooking = await ResourceBooking.findById(id) await resourceBooking.destroy() await helper.postEvent(config.TAAS_RESOURCE_BOOKING_DELETE_TOPIC, { id }) @@ -228,8 +298,8 @@ deleteResourceBooking.schema = Joi.object().keys({ /** * List resourceBookings * @param {Object} currentUser the user who perform this operation. - * @params {Object} criteria the search criteria - * @params {Object} options the extra options to control the function + * @param {Object} criteria the search criteria + * @param {Object} options the extra options to control the function * @returns {Object} the search result, contain total/page/perPage and result array */ async function searchResourceBookings (currentUser, criteria, options = { returnAll: false }) { @@ -323,7 +393,7 @@ async function searchResourceBookings (currentUser, criteria, options = { return logger.logFullError(err, { component: 'ResourceBookingService', context: 'searchResourceBookings' }) } logger.info({ component: 'ResourceBookingService', context: 'searchResourceBookings', message: 'fallback to DB query' }) - const filter = {} + const filter = { [Op.and]: [] } _.each(_.pick(criteria, ['status', 'startDate', 'endDate', 'rateType', 'projectId', 'jobId', 'userId']), (value, key) => { filter[Op.and].push({ [key]: value }) }) @@ -352,7 +422,7 @@ searchResourceBookings.schema = Joi.object().keys({ perPage: Joi.number().integer(), sortBy: Joi.string().valid('id', 'rateType', 'startDate', 'endDate', 'customerRate', 'memberRate', 'status'), sortOrder: Joi.string().valid('desc', 'asc'), - status: Joi.jobStatus(), + status: Joi.resourceBookingStatus(), startDate: Joi.date(), endDate: Joi.date(), rateType: Joi.rateType(), diff --git a/src/services/WorkPeriodPaymentService.js b/src/services/WorkPeriodPaymentService.js index a769edb1..9c2dbdfd 100644 --- a/src/services/WorkPeriodPaymentService.js +++ b/src/services/WorkPeriodPaymentService.js @@ -8,10 +8,12 @@ const config = require('config') const HttpStatus = require('http-status-codes') const { Op } = require('sequelize') const uuid = require('uuid') +const moment = require('moment') const helper = require('../common/helper') const logger = require('../common/logger') const errors = require('../common/errors') const models = require('../models') +const { createPayment } = require('./PaymentService') const WorkPeriodPayment = models.WorkPeriodPayment const esClient = helper.getESClient() @@ -56,11 +58,14 @@ async function getWorkPeriodPayment (currentUser, id, fromDb = false) { } }) + if (!workPeriod.body.hits.total.value) { + throw new errors.NotFoundError() + } const workPeriodPaymentRecord = _.find(workPeriod.body.hits.hits[0]._source.payments, { id }) return workPeriodPaymentRecord } catch (err) { - if (helper.isDocumentMissingException(err)) { - throw new errors.NotFountError(`id: ${id} "WorkPeriodPayment" not found`) + if (err.httpStatus === HttpStatus.NOT_FOUND) { + throw new errors.NotFoundError(`id: ${id} "WorkPeriodPayment" not found`) } if (err.httpStatus === HttpStatus.FORBIDDEN) { throw err @@ -90,8 +95,16 @@ async function createWorkPeriodPayment (currentUser, workPeriodPayment) { // check permission await _checkUserPermissionForCRUWorkPeriodPayment(currentUser) - await helper.ensureWorkPeriodById(workPeriodPayment.workPeriodId) // ensure work period exists + const { projectId, userHandle, endDate } = await helper.ensureWorkPeriodById(workPeriodPayment.workPeriodId) // ensure work period exists + const paymentChallenge = await createPayment({ + projectId, + userHandle, + amount: workPeriodPayment.amount, + name: `TaaS Payment - ${userHandle} - Week Ending ${moment(endDate).format('DD/MM/YYYY')}}`, + description: `TaaS Payment - ${userHandle} - Week Ending ${moment(endDate).format('DD/MM/YYYY')}}` + }) workPeriodPayment.id = uuid.v4() + workPeriodPayment.challengeId = paymentChallenge.id workPeriodPayment.createdBy = await helper.getUserId(currentUser.userId) let created = null @@ -169,7 +182,7 @@ partiallyUpdateWorkPeriodPayment.schema = Joi.object().keys({ data: Joi.object().keys({ workPeriodId: Joi.string().uuid(), amount: Joi.number().greater(0).allow(null), - status: Joi.workPeriodPaymentStatus().default('completed') + status: Joi.workPeriodPaymentStatus() }).required() }).required() @@ -261,12 +274,13 @@ async function searchWorkPeriodPayments (currentUser, criteria, options = { retu if (criteria.sortOrder === 'desc') { payments = _.reverse(payments) } + const total = payments.length if (!options.returnAll) { payments = _.slice(payments, (page - 1) * perPage, page * perPage) } return { - total: payments.length, + total, page, perPage, result: payments diff --git a/src/services/WorkPeriodService.js b/src/services/WorkPeriodService.js index 9179329c..92e1deb0 100644 --- a/src/services/WorkPeriodService.js +++ b/src/services/WorkPeriodService.js @@ -12,6 +12,7 @@ const helper = require('../common/helper') const logger = require('../common/logger') const errors = require('../common/errors') const models = require('../models') +const constants = require('../../app-constants') const moment = require('moment') const WorkPeriod = models.WorkPeriod @@ -71,6 +72,16 @@ Joi.workPeriodEndDateOptional = () => Joi.date() }) }) +/** + * Check user scopes for getting payments + * @param {Object} currentUser the user who perform this operation. + * @returns {Boolean} true if user is machine and has read/all payment scopes + */ +function _checkUserScopesForGetPayments (currentUser) { + const getPaymentsScopes = [constants.Scopes.READ_WORK_PERIOD_PAYMENT, constants.Scopes.ALL_WORK_PERIOD_PAYMENT] + return currentUser.isMachine && helper.checkIfExists(getPaymentsScopes, currentUser.scopes) +} + /** * filter fields of work period by user role. * @param {Object} currentUser the user who perform this operation. @@ -78,7 +89,7 @@ Joi.workPeriodEndDateOptional = () => Joi.date() * @returns {Object} the workPeriod */ async function _getWorkPeriodFilteringFields (currentUser, workPeriod) { - if (currentUser.hasManagePermission || currentUser.isMachine) { + if (currentUser.hasManagePermission || _checkUserScopesForGetPayments(currentUser)) { return workPeriod } return _.omit(workPeriod, ['memberRate', 'payments']) @@ -155,7 +166,7 @@ async function getWorkPeriod (currentUser, id, fromDb = false) { } } logger.info({ component: 'WorkPeriodService', context: 'getWorkPeriod', message: 'try to query db for data' }) - const workPeriod = await WorkPeriod.findById(id, true) + const workPeriod = await WorkPeriod.findById(id, { withPayments: true }) await _checkUserPermissionForGetWorkPeriod(currentUser, workPeriod.projectId) // check user permission // We should only return "memberRate" to Booking Manager, Administrator or M2M @@ -319,8 +330,16 @@ async function deleteWorkPeriod (currentUser, id) { throw new errors.ForbiddenError('You are not allowed to perform this action!') } - const workPeriod = await WorkPeriod.findById(id, true) - await Promise.all(workPeriod.payments.map((payment) => payment.destroy())) + const workPeriod = await WorkPeriod.findById(id, { withPayments: true }) + if (_.includes(['completed', 'partially-completed'], workPeriod.paymentStatus)) { + throw new errors.BadRequestError("Can't delete WorkPeriod with paymentStatus completed or partially-completed") + } + await models.WorkPeriodPayment.destroy({ + where: { + workPeriodId: id + } + }) + await Promise.all(workPeriod.payments.map(({ id }) => helper.postEvent(config.TAAS_WORK_PERIOD_PAYMENT_DELETE_TOPIC, { id }))) await workPeriod.destroy() await helper.postEvent(config.TAAS_WORK_PERIOD_DELETE_TOPIC, { id }) } @@ -427,8 +446,9 @@ async function searchWorkPeriods (currentUser, criteria, options = { returnAll: const obj = _.cloneDeep(hit._source) obj.id = hit._id // We should only return "memberRate" to Booking Manager, Administrator or M2M - if (!currentUser.hasManagePermission && !currentUser.isMachine) { + if (!currentUser.hasManagePermission && !_checkUserScopesForGetPayments(currentUser)) { delete obj.memberRate + delete obj.payments } return obj }) @@ -462,8 +482,9 @@ async function searchWorkPeriods (currentUser, criteria, options = { returnAll: perPage, result: _.map(workPeriods, workPeriod => { // We should only return "memberRate" to Booking Manager, Administrator or M2M - if (!currentUser.hasManagePermission && !currentUser.isMachine) { + if (!currentUser.hasManagePermission && !_checkUserScopesForGetPayments(currentUser)) { delete workPeriod.dataValues.memberRate + delete workPeriod.dataValues.payments } return workPeriod.dataValues }) diff --git a/test/unit/JobCandidateService.test.js b/test/unit/JobCandidateService.test.js deleted file mode 100644 index bfa7b9c2..00000000 --- a/test/unit/JobCandidateService.test.js +++ /dev/null @@ -1,392 +0,0 @@ -/* eslint-disable no-unused-expressions */ -process.env.NODE_ENV = 'test' -require('../../src/bootstrap') - -const expect = require('chai').expect -const sinon = require('sinon') -const _ = require('lodash') -const models = require('../../src/models') -const service = require('../../src/services/JobCandidateService') -const { - bookingManagerUser, connectUser, topCoderUser, jobCandidateRequestBody, - jobResponseBody, jobCandidateResponseBody, fullyUpdateJobCandidateRequestBody, partiallyUpdateJobCandidateRequestBody, unexpected -} = require('./common/testData') - -const helper = require('../../src/common/helper') -const esClient = helper.getESClient() -const busApiClient = helper.getBusApiClient() - -const JobCandidate = models.JobCandidate -const Job = models.Job - -describe('jobCandidate service test', () => { - let isConnectMember - let userId - let stubIsConnectMember - let stubGetUserId - let stubPostEvent - beforeEach(() => { - isConnectMember = true - stubIsConnectMember = sinon.stub(helper, 'isConnectMember').callsFake(() => { - return isConnectMember - }) - - userId = 'a55fe1bc-1754-45fa-9adc-cf3d6d7c377a' - stubGetUserId = sinon.stub(helper, 'getUserId').callsFake(() => { - return userId - }) - stubPostEvent = sinon.stub(busApiClient, 'postEvent').callsFake(async () => {}) - }) - - afterEach(() => { - sinon.restore() - }) - - describe('create job candidate test', () => { - it('create job candidate with booking manager success ', async () => { - const jobCandidateRes = _.cloneDeep(jobCandidateResponseBody) - const stubDBCreate = sinon.stub(JobCandidate, 'create').callsFake(() => { - return jobCandidateResponseBody - }) - - const entity = await service.createJobCandidate(bookingManagerUser, jobCandidateRequestBody) - expect(entity).to.deep.eql(jobCandidateRes.dataValues) - expect(stubDBCreate.calledOnce).to.be.true - expect(stubPostEvent.calledOnce).to.be.true - expect(stubGetUserId.calledOnce).to.be.true - }) - - it('create job candidate with connect user success ', async () => { - const jobCandidateRes = _.cloneDeep(jobCandidateResponseBody) - const stubDBCreate = sinon.stub(JobCandidate, 'create').callsFake(() => { - return jobCandidateRes - }) - const entity = await service.createJobCandidate(connectUser, jobCandidateRequestBody) - expect(entity).to.deep.eql(jobCandidateRes.dataValues) - expect(stubDBCreate.calledOnce).to.be.true - expect(stubPostEvent.calledOnce).to.be.true - expect(stubGetUserId.calledOnce).to.be.true - }) - - it('create job candidate with topcoder user success', async () => { - const jobCandidateRes = _.cloneDeep(jobCandidateResponseBody) - const stubDBCreate = sinon.stub(JobCandidate, 'create').callsFake(() => { - return jobCandidateRes - }) - const entity = await service.createJobCandidate(topCoderUser, jobCandidateRequestBody) - expect(entity).to.deep.eql(jobCandidateRes.dataValues) - expect(stubDBCreate.calledOnce).to.be.true - expect(stubDBCreate.calledOnce).to.be.true - }) - }) - - describe('get job candidate test', () => { - it('get job candidate success', async () => { - const jobCandidateRes = _.cloneDeep(jobCandidateResponseBody) - const stub = sinon.stub(esClient, 'get').callsFake(async () => { - return { - body: { - _id: jobCandidateRes.dataValues.id, - _source: _.omit(jobCandidateRes.dataValues, ['id']) - } - } - }) - const entity = await service.getJobCandidate(jobCandidateResponseBody.dataValues.id) - expect(entity).to.deep.eql(jobCandidateRes.dataValues) - expect(stub.calledOnce).to.be.true - }) - - it('get job candidate with candidate not exist success', async () => { - const stub = sinon.stub(esClient, 'get').callsFake(async () => { - const err = new Error() - err.statusCode = 404 - throw err - }) - try { - await service.getJobCandidate(jobCandidateResponseBody.dataValues.id) - unexpected() - } catch (error) { - expect(error.message).to.equal(`id: ${jobCandidateResponseBody.dataValues.id} "JobCandidate" not found`) - expect(stub.calledOnce).to.be.true - } - }) - - it('get job candidate from db success', async () => { - const jobCandidateRes = _.cloneDeep(jobCandidateResponseBody) - const stubJobCandidateFindOne = sinon.stub(JobCandidate, 'findOne').callsFake(() => { - return jobCandidateRes - }) - const entity = await service.getJobCandidate(jobCandidateResponseBody.dataValues.id, true) - expect(entity).to.deep.eql(jobCandidateRes.dataValues) - expect(stubJobCandidateFindOne.calledOnce).to.be.true - }) - - it('get job candidate from db with candidate not exist success', async () => { - const stubJobCandidateFindOne = sinon.stub(JobCandidate, 'findOne').callsFake(() => { - return null - }) - try { - await service.getJobCandidate(jobCandidateResponseBody.dataValues.id, true) - unexpected() - } catch (error) { - expect(error.message).to.equal(`id: ${jobCandidateResponseBody.dataValues.id} "JobCandidate" doesn't exists.`) - expect(stubJobCandidateFindOne.calledOnce).to.be.true - } - }) - }) - - describe('fully update job candidate test', () => { - it('fully update job candidate test with booking manager success', async () => { - const jobCandidateRes = _.cloneDeep(jobCandidateResponseBody) - const stubJobCandidateFindOne = sinon.stub(JobCandidate, 'findOne').callsFake(() => { - return { - ...jobCandidateRes, - update: () => { return null } - } - }) - - const stubJobFindOne = sinon.stub(Job, 'findOne').callsFake(() => { - return _.cloneDeep(jobResponseBody) - }) - const entity = await service.fullyUpdateJobCandidate(bookingManagerUser, jobCandidateResponseBody.dataValues.id, fullyUpdateJobCandidateRequestBody) - expect(entity).to.deep.eql(jobCandidateRes.dataValues) - expect(stubJobCandidateFindOne.calledOnce).to.be.true - expect(stubJobFindOne.calledOnce).to.be.true - expect(stubPostEvent.calledOnce).to.be.true - }) - - it('fully update job candidate test with connect user success', async () => { - const jobCandidateRes = _.cloneDeep(jobCandidateResponseBody) - const stubJobCandidateFindOne = sinon.stub(JobCandidate, 'findOne').callsFake(() => { - return { - ...jobCandidateRes, - update: () => { return null } - } - }) - const stubJobFindOne = sinon.stub(Job, 'findOne').callsFake(() => { - return _.cloneDeep(jobResponseBody) - }) - - const entity = await service.fullyUpdateJobCandidate(connectUser, jobCandidateResponseBody.dataValues.id, fullyUpdateJobCandidateRequestBody) - expect(entity).to.deep.eql(jobCandidateRes.dataValues) - expect(stubJobCandidateFindOne.calledOnce).to.be.true - expect(stubJobFindOne.calledOnce).to.be.true - expect(stubPostEvent.calledOnce).to.be.true - expect(stubIsConnectMember.calledOnce).to.be.true - }) - - it('fully update job candidate test with topcoder user success', async () => { - const jobCandidateRes = _.cloneDeep(jobCandidateResponseBody) - const stubJobCandidateFindOne = sinon.stub(JobCandidate, 'findOne').callsFake(() => { - return { - ...jobCandidateRes, - update: () => { return null } - } - }) - const stubJobFindOne = sinon.stub(Job, 'findOne').callsFake(() => { - return _.cloneDeep(jobResponseBody) - }) - const user = _.assign({}, topCoderUser, { userId: 40152856 }) - - const entity = await service.fullyUpdateJobCandidate(user, jobCandidateResponseBody.dataValues.id, fullyUpdateJobCandidateRequestBody) - expect(entity).to.deep.eql(jobCandidateRes.dataValues) - expect(stubJobCandidateFindOne.calledOnce).to.be.true - expect(stubJobFindOne.calledOnce).to.be.true - expect(stubPostEvent.calledOnce).to.be.true - }) - - it('fully update job candidate test with topcoder user failed', async () => { - userId = '544e281f-62a0-4e45-8cc1-bac434bb3a54' - isConnectMember = false - const jobCandidateRes = _.cloneDeep(jobCandidateResponseBody) - const stubJobCandidateFindOne = sinon.stub(JobCandidate, 'findOne').callsFake(() => { - return { - ...jobCandidateRes, - update: () => { return null } - } - }) - const stubJobFindOne = sinon.stub(Job, 'findOne').callsFake(() => { - return _.cloneDeep(jobResponseBody) - }) - try { - await service.fullyUpdateJobCandidate(topCoderUser, jobCandidateResponseBody.dataValues.id, fullyUpdateJobCandidateRequestBody) - unexpected() - } catch (error) { - expect(error.message).to.equal('You are not allowed to perform this action!') - } - expect(stubJobCandidateFindOne.calledOnce).to.be.true - expect(stubJobFindOne.calledOnce).to.be.true - }) - }) - - describe('partially update job candidate test', () => { - it('partially update job candidate test with booking manager success', async () => { - const jobCandidateRes = _.cloneDeep(jobCandidateResponseBody) - const stubJobCandidateFindOne = sinon.stub(JobCandidate, 'findOne').callsFake(() => { - return { - ...jobCandidateRes, - update: () => { return null } - } - }) - const stubJobFindOne = sinon.stub(Job, 'findOne').callsFake(() => { - return _.cloneDeep(jobResponseBody) - }) - - const entity = await service.partiallyUpdateJobCandidate(bookingManagerUser, jobCandidateResponseBody.dataValues.id, partiallyUpdateJobCandidateRequestBody) - expect(entity).to.deep.eql(jobCandidateRes.dataValues) - expect(stubJobCandidateFindOne.calledOnce).to.be.true - expect(stubJobFindOne.calledOnce).to.be.true - expect(stubPostEvent.calledOnce).to.be.true - }) - - it('partially update job candidate test with connect user success', async () => { - const jobCandidateRes = _.cloneDeep(jobCandidateResponseBody) - const stubJobCandidateFindOne = sinon.stub(JobCandidate, 'findOne').callsFake(() => { - return { - ...jobCandidateRes, - update: () => { return null } - } - }) - const stubJobFindOne = sinon.stub(Job, 'findOne').callsFake(() => { - return _.cloneDeep(jobResponseBody) - }) - - const entity = await service.partiallyUpdateJobCandidate(connectUser, jobCandidateResponseBody.dataValues.id, partiallyUpdateJobCandidateRequestBody) - expect(entity).to.deep.eql(jobCandidateRes.dataValues) - expect(stubJobCandidateFindOne.calledOnce).to.be.true - expect(stubJobFindOne.calledOnce).to.be.true - expect(stubPostEvent.calledOnce).to.be.true - expect(stubIsConnectMember.calledOnce).to.be.true - }) - - it('partially update job candidate test with topcoder user failed', async () => { - isConnectMember = false - userId = '544e281f-62a0-4e45-8cc1-bac434bb3a54' - const jobCandidateRes = _.cloneDeep(jobCandidateResponseBody) - const stubJobCandidateFindOne = sinon.stub(JobCandidate, 'findOne').callsFake(() => { - return { - ...jobCandidateRes, - update: () => { return null } - } - }) - const stubJobFindOne = sinon.stub(Job, 'findOne').callsFake(() => { - return _.cloneDeep(jobResponseBody) - }) - try { - await service.partiallyUpdateJobCandidate(topCoderUser, jobCandidateResponseBody.dataValues.id, partiallyUpdateJobCandidateRequestBody) - unexpected() - } catch (error) { - expect(error.message).to.equal('You are not allowed to perform this action!') - } - expect(stubJobCandidateFindOne.calledOnce).to.be.true - expect(stubJobFindOne.calledOnce).to.be.true - }) - - it('partially update job candidate test with job not exist', async () => { - const stubJobCandidateFindOne = sinon.stub(JobCandidate, 'findOne').callsFake(() => { - return { - ..._.cloneDeep(jobCandidateResponseBody), - update: () => { return null } - } - }) - const stubJobFindOne = sinon.stub(Job, 'findOne').callsFake(() => { - return null - }) - - await service.partiallyUpdateJobCandidate(bookingManagerUser, jobCandidateResponseBody.dataValues.id, partiallyUpdateJobCandidateRequestBody) - expect(stubJobCandidateFindOne.calledOnce).to.be.true - expect(stubJobFindOne.calledOnce).to.be.true - expect(stubPostEvent.calledOnce).to.be.true - }) - }) - - describe('delete job candidate test', () => { - it('delete job candidate test with booking manager success', async () => { - const stubJobCandidateFindOne = sinon.stub(JobCandidate, 'findOne').callsFake(() => { - return { - ..._.cloneDeep(jobCandidateResponseBody), - update: () => { return null } - } - }) - await service.deleteJobCandidate(bookingManagerUser, jobCandidateResponseBody.dataValues.id) - expect(stubJobCandidateFindOne.calledOnce).to.be.true - expect(stubPostEvent.calledOnce).to.be.true - }) - - it('delete job candidate test with connect user success', async () => { - try { - await service.deleteJobCandidate(connectUser, jobCandidateResponseBody.dataValues.id) - unexpected() - } catch (error) { - expect(error.message).to.equal('You are not allowed to perform this action!') - } - }) - - it('delete job candidate test with topcoder user failed', async () => { - try { - await service.deleteJobCandidate(topCoderUser, jobCandidateResponseBody.dataValues.id) - unexpected() - } catch (error) { - expect(error.message).to.equal('You are not allowed to perform this action!') - } - }) - }) - - describe('search job candidates test', () => { - it('search job candidates success', async () => { - const stub = sinon.stub(esClient, 'search').callsFake(() => { - return { - body: { - hits: { - total: { - value: 1 - }, - hits: [{ - _id: jobCandidateResponseBody.dataValues.id, - _source: _.omit(jobCandidateResponseBody.dataValues, ['id']) - }] - } - } - } - }) - const entity = await service.searchJobCandidates({ sortBy: 'id', sortOrder: 'asc', page: 1, perPage: 1, jobId: '36762910-4efa-4db4-9b2a-c9ab54c232ed' }) - expect(entity.result[0]).to.deep.eql(jobCandidateResponseBody.dataValues) - expect(stub.calledOnce).to.be.true - }) - - it('search job candidates without query parameters success', async () => { - const stub = sinon.stub(esClient, 'search').callsFake(() => { - return { - body: { - hits: { - total: { - value: 1 - }, - hits: [{ - _id: jobCandidateResponseBody.dataValues.id, - _source: _.omit(jobCandidateResponseBody.dataValues, ['id']) - }] - } - } - } - }) - const entity = await service.searchJobCandidates({}) - expect(entity.result[0]).to.deep.eql(jobCandidateResponseBody.dataValues) - expect(stub.calledOnce).to.be.true - }) - - it('search job candidates success when es search fails', async () => { - const stubESSearch = sinon.stub(esClient, 'search').callsFake(() => { - throw new Error('dedicated es failure') - }) - - const stubDBSearch = sinon.stub(JobCandidate, 'findAll').callsFake(() => { - return [jobCandidateResponseBody] - }) - const entity = await service.searchJobCandidates({ sortBy: 'id', sortOrder: 'asc', page: 1, perPage: 1, jobId: '36762910-4efa-4db4-9b2a-c9ab54c232ed' }) - expect(entity.result[0]).to.deep.eql(jobCandidateResponseBody.dataValues) - expect(stubESSearch.calledOnce).to.be.true - expect(stubDBSearch.calledOnce).to.be.true - }) - }) -}) diff --git a/test/unit/JobService.test.js b/test/unit/JobService.test.js deleted file mode 100644 index 0f0d7ef2..00000000 --- a/test/unit/JobService.test.js +++ /dev/null @@ -1,415 +0,0 @@ -/* eslint-disable no-unused-expressions */ -process.env.NODE_ENV = 'test' -const _ = require('lodash') -require('../../src/bootstrap') - -const expect = require('chai').expect -const sinon = require('sinon') -const models = require('../../src/models') -const service = require('../../src/services/JobService') -const { - bookingManagerUser, connectUser, topCoderUser, jobRequestBody, - jobResponseBody, fullyUpdateJobRequestBody, partiallyUpdateJobRequestBody, unexpected -} = require('./common/testData') -const helper = require('../../src/common/helper') -const errors = require('../../src/common/errors') - -const esClient = helper.getESClient() -const busApiClient = helper.getBusApiClient() - -const Job = models.Job - -describe('job service test', () => { - let isConnectMember - let userId - let stubIsConnectMember - let stubGetUserId - let stubPostEvent - beforeEach(() => { - isConnectMember = true - stubIsConnectMember = sinon.stub(helper, 'isConnectMember').callsFake(() => { - return isConnectMember - }) - - userId = 'a55fe1bc-1754-45fa-9adc-cf3d6d7c377a' - stubGetUserId = sinon.stub(helper, 'getUserId').callsFake(() => { - return userId - }) - stubPostEvent = sinon.stub(busApiClient, 'postEvent').callsFake(async () => {}) - }) - - afterEach(() => { - sinon.restore() - }) - - describe('create job test', () => { - it('create job with booking manager user success ', async () => { - const stubDBCreate = sinon.stub(Job, 'create').callsFake(() => { - return _.cloneDeep(jobResponseBody) - }) - - const entity = await service.createJob(bookingManagerUser, jobRequestBody) - expect(entity).to.deep.eql(jobResponseBody.dataValues) - expect(stubDBCreate.calledOnce).to.be.true - expect(stubPostEvent.calledOnce).to.be.true - expect(stubGetUserId.calledOnce).to.be.true - }) - - it('create job with connect user success ', async () => { - const stubDBCreate = sinon.stub(Job, 'create').callsFake(() => { - return _.cloneDeep(jobResponseBody) - }) - const entity = await service.createJob(connectUser, jobRequestBody) - expect(entity).to.deep.eql(jobResponseBody.dataValues) - expect(stubDBCreate.calledOnce).to.be.true - expect(stubPostEvent.calledOnce).to.be.true - expect(stubIsConnectMember.calledOnce).to.be.true - expect(stubGetUserId.calledOnce).to.be.true - }) - - it('create job with connect user failed user id not exist ', async () => { - stubGetUserId.restore() - stubGetUserId = sinon.stub(helper, 'getUserId').callsFake(() => { - throw new errors.NotFoundError('user id not found') - }) - - try { - await service.createJob(_.assign({}, connectUser, { userId: 'not_exist' }), jobRequestBody) - unexpected() - } catch (err) { - expect(err.message).to.equal('user id not found') - } - expect(stubIsConnectMember.calledOnce).to.be.true - expect(stubGetUserId.calledOnce).to.be.true - }) - - it('create job with connect user failed ', async () => { - isConnectMember = false - try { - await service.createJob(topCoderUser, jobRequestBody) - unexpected() - } catch (error) { - expect(error.message).to.equal('You are not allowed to perform this action!') - } - }) - }) - - describe('get job test', () => { - it('get job success', async () => { - const jobResBody = _.cloneDeep(jobResponseBody) - const stub = sinon.stub(esClient, 'get').callsFake(async () => { - return { - body: { - _id: jobResponseBody.dataValues.id, - _source: _.omit(jobResponseBody.dataValues, ['id']) - } - } - }) - const stubSearchCandidates = sinon.stub(esClient, 'search').callsFake(() => { - return { - body: { - hits: { - total: { - value: 1 - }, - hits: [{ - _id: jobResponseBody.dataValues.candidates[0].id, - _source: _.omit(jobResponseBody.dataValues.candidates[0], ['id']) - }] - } - } - } - }) - const entity = await service.getJob(jobResponseBody.dataValues.id) - expect(entity).to.deep.eql(jobResBody.dataValues) - expect(stub.calledOnce).to.be.true - expect(stubSearchCandidates.calledOnce).to.be.true - }) - - it('get job with job not exist failed', async () => { - const stub = sinon.stub(esClient, 'get').callsFake(async () => { - const err = new Error() - err.statusCode = 404 - throw err - }) - try { - await service.getJob(jobResponseBody.dataValues.id) - unexpected() - } catch (error) { - expect(error.message).to.equal(`id: ${jobResponseBody.dataValues.id} "Job" not found`) - expect(stub.calledOnce).to.be.true - } - }) - - it('get job from db success', async () => { - const jobResBody = _.cloneDeep(jobResponseBody) - const stub = sinon.stub(Job, 'findOne').callsFake(() => { - return jobResBody - }) - const entity = await service.getJob(jobResponseBody.dataValues.id, true) - expect(entity).to.deep.eql(jobResBody.dataValues) - expect(stub.calledOnce).to.be.true - }) - - it('get job from db with job not exist failed', async () => { - const stub = sinon.stub(Job, 'findOne').callsFake(() => { - return null - }) - try { - await service.getJob(jobResponseBody.dataValues.id, true) - unexpected() - } catch (error) { - expect(error.message).to.equal(`id: ${jobResponseBody.dataValues.id} "Job" doesn't exists.`) - expect(stub.calledOnce).to.be.true - } - }) - }) - - describe('fully update job test', () => { - it('fully update job test with booking manager success', async () => { - const jobResBody = _.cloneDeep(jobResponseBody) - const stub = sinon.stub(Job, 'findOne').onFirstCall().callsFake(() => { - return { - dataValues: { - projectId: '352123' - }, - update: () => { - return null - } - } - }).onSecondCall().callsFake(() => { - return jobResBody - }) - - const entity = await service.fullyUpdateJob(bookingManagerUser, jobResponseBody.dataValues.id, fullyUpdateJobRequestBody) - expect(entity).to.deep.eql(jobResBody.dataValues) - expect(stub.calledTwice).to.be.true - expect(stubPostEvent.calledOnce).to.be.true - expect(stubGetUserId.calledOnce).to.be.true - }) - - it('fully update job test with connect user success', async () => { - const jobResBody = _.cloneDeep(jobResponseBody) - const stub = sinon.stub(Job, 'findOne').onFirstCall().callsFake(() => { - return { - dataValues: { - projectId: '352123' - }, - update: () => { - return null - } - } - }).onSecondCall().callsFake(() => { - return jobResBody - }) - - const entity = await service.fullyUpdateJob(connectUser, jobResponseBody.dataValues.id, fullyUpdateJobRequestBody) - expect(entity).to.deep.eql(jobResBody.dataValues) - expect(stub.calledTwice).to.be.true - expect(stubPostEvent.calledOnce).to.be.true - expect(stubIsConnectMember.calledOnce).to.be.true - expect(stubGetUserId.calledOnce).to.be.true - }) - - it('fully update job test with topcoder user failed', async () => { - isConnectMember = false - const stub = sinon.stub(Job, 'findOne').callsFake(() => { - return { - dataValues: { - projectId: 'not_exist' - } - } - }) - try { - await service.fullyUpdateJob(topCoderUser, jobResponseBody.dataValues.id, fullyUpdateJobRequestBody) - unexpected() - } catch (error) { - expect(error.message).to.equal('You are not allowed to perform this action!') - } - expect(stub.calledOnce).to.be.true - }) - }) - - describe('partially update job test', () => { - it('partially update job with booking manager success', async () => { - const jobResBody = _.cloneDeep(jobResponseBody) - const stub = sinon.stub(Job, 'findOne').onFirstCall().callsFake(() => { - return { - dataValues: { - projectId: '352123' - }, - update: () => { - return null - } - } - }).onSecondCall().callsFake(() => { - return jobResBody - }) - - const entity = await service.partiallyUpdateJob(bookingManagerUser, jobResponseBody.dataValues.id, partiallyUpdateJobRequestBody) - expect(entity).to.deep.eql(jobResBody.dataValues) - expect(stub.calledTwice).to.be.true - expect(stubPostEvent.calledOnce).to.be.true - expect(stubGetUserId.calledOnce).to.be.true - }) - - it('partially update job with connect user success', async () => { - const jobResBody = _.cloneDeep(jobResponseBody) - const stub = sinon.stub(Job, 'findOne').onFirstCall().callsFake(() => { - return { - dataValues: { - projectId: '352123' - }, - update: () => { - return null - } - } - }).onSecondCall().callsFake(() => { - return jobResBody - }) - const entity = await service.partiallyUpdateJob(connectUser, jobResponseBody.dataValues.id, partiallyUpdateJobRequestBody) - expect(entity).to.deep.eql(jobResBody.dataValues) - expect(stub.calledTwice).to.be.true - expect(stubPostEvent.calledOnce).to.be.true - expect(stubIsConnectMember.calledOnce).to.be.true - expect(stubGetUserId.calledOnce).to.be.true - }) - - it('partially update job with topcoder user failed', async () => { - isConnectMember = false - const stub = sinon.stub(Job, 'findOne').onFirstCall().callsFake(() => { - return { - dataValues: { - projectId: 'not_exist' - } - } - }) - try { - await service.partiallyUpdateJob(topCoderUser, jobResponseBody.dataValues.id, partiallyUpdateJobRequestBody) - } catch (error) { - expect(error.message).to.equal('You are not allowed to perform this action!') - } - expect(stub.calledOnce).to.be.true - }) - }) - - describe('delete job test', () => { - it('delete job test with booking manager success', async () => { - const stub = sinon.stub(Job, 'findOne').callsFake(() => { - return { - dataValues: { - projectId: '352123' - }, - update: () => { - return null - } - } - }) - await service.deleteJob(bookingManagerUser, jobResponseBody.dataValues.id) - expect(stub.calledOnce).to.be.true - expect(stubPostEvent.calledOnce).to.be.true - }) - - it('delete job test with connect user failed', async () => { - try { - await service.deleteJob(connectUser, jobResponseBody.dataValues.id) - unexpected() - } catch (error) { - expect(error.message).to.equal('You are not allowed to perform this action!') - } - }) - - it('delete job test with topcoder user failed', async () => { - try { - await service.deleteJob(topCoderUser, jobResponseBody.dataValues.id) - unexpected() - } catch (error) { - expect(error.message).to.equal('You are not allowed to perform this action!') - } - }) - }) - - describe('search jobs test', () => { - it('search jobs success', async () => { - const stub = sinon.stub(esClient, 'search').onFirstCall().callsFake(() => { - return { - body: { - hits: { - total: { - value: 1 - }, - hits: [{ - _id: jobResponseBody.dataValues.id, - _source: _.omit(jobResponseBody.dataValues, ['id']) - }] - } - } - } - }).onSecondCall().callsFake(() => { - return { - body: { - hits: { - total: { - value: 1 - }, - hits: [{ - _id: jobResponseBody.dataValues.candidates[0].id, - _source: _.omit(jobResponseBody.dataValues.candidates[0], ['id']) - }] - } - } - } - }) - const entity = await service.searchJobs({ sortBy: 'id', sortOrder: 'asc', page: 1, perPage: 1, skill: '56fdc405-eccc-4189-9e83-c78abf844f50', description: 'description 1', rateType: 'hourly' }) - expect(entity.result[0]).to.deep.eql(jobResponseBody.dataValues) - expect(stub.calledTwice).to.be.true - }) - - it('search jobs without query parameters success', async () => { - const stub = sinon.stub(esClient, 'search').onFirstCall().callsFake(() => { - return { - body: { - hits: { - total: { - value: 1 - }, - hits: [{ - _id: jobResponseBody.dataValues.id, - _source: _.omit(jobResponseBody.dataValues, ['id']) - }] - } - } - } - }).onSecondCall().callsFake(() => { - return { - body: { - hits: { - total: { - value: 0 - }, - hits: [] - } - } - } - }) - const entity = await service.searchJobs({}) - expect(entity.result[0]).to.deep.eql(jobResponseBody.dataValues) - expect(stub.calledTwice).to.be.true - }) - - it('search jobs success when es search fails', async () => { - const stubESSearch = sinon.stub(esClient, 'search').callsFake(() => { - throw new Error('dedicated es failure') - }) - - const stubDBSearch = sinon.stub(Job, 'findAll').callsFake(() => { - return [jobResponseBody] - }) - - const entity = await service.searchJobs({ sortBy: 'id', sortOrder: 'asc', page: 1, perPage: 1, skill: '56fdc405-eccc-4189-9e83-c78abf844f50', description: 'description 1', rateType: 'hourly' }) - expect(entity.result[0]).to.deep.eql(jobResponseBody.dataValues) - expect(stubESSearch.calledOnce).to.be.true - expect(stubDBSearch.calledOnce).to.be.true - }) - }) -}) diff --git a/test/unit/ResourceBookingService.test.js b/test/unit/ResourceBookingService.test.js index fba2415a..08d219ba 100644 --- a/test/unit/ResourceBookingService.test.js +++ b/test/unit/ResourceBookingService.test.js @@ -2,42 +2,34 @@ process.env.NODE_ENV = 'test' require('../../src/bootstrap') -const _ = require('lodash') +// const _ = require('lodash') const expect = require('chai').expect const sinon = require('sinon') const models = require('../../src/models') const service = require('../../src/services/ResourceBookingService') -const { - bookingManagerUser, connectUser, topCoderUser, - jobCandidateResponseBody, resourceBookingRequestBody, - resourceBookingResponseBody, unexpected, - partiallyUpdateResourceBookingRequestBody, fullyUpdateResourceBookingRequestBody -} = require('./common/testData') - +const workPeriodService = require('../../src/services/WorkPeriodService') +const testData = require('./common/testData') const helper = require('../../src/common/helper') - -const esClient = helper.getESClient() +const eventHandlers = require('../../src/eventHandlers') +// const esClient = helper.getESClient() const busApiClient = helper.getBusApiClient() - const ResourceBooking = models.ResourceBooking - +const WorkPeriod = models.WorkPeriod +eventHandlers.init() describe('resourceBooking service test', () => { - let isConnectMember - let userId - let stubIsConnectMember - let stubGetUserId + let stubEnsureJobById + let stubEnsureUserById let stubPostEvent + let stubCreateWorkPeriodService + let stubUpdateWorkPeriodService + let stubDeleteWorkPeriodService beforeEach(() => { - isConnectMember = true - stubIsConnectMember = sinon.stub(helper, 'isConnectMember').callsFake(() => { - return isConnectMember - }) - - userId = 'a55fe1bc-1754-45fa-9adc-cf3d6d7c377a' - stubGetUserId = sinon.stub(helper, 'getUserId').callsFake(() => { - return userId - }) + stubEnsureJobById = sinon.stub(helper, 'ensureJobById').callsFake(async () => {}) + stubEnsureUserById = sinon.stub(helper, 'ensureUserById').callsFake(async () => testData.UserTCConnCopilot) stubPostEvent = sinon.stub(busApiClient, 'postEvent').callsFake(async () => {}) + stubCreateWorkPeriodService = sinon.stub(workPeriodService, 'createWorkPeriod').callsFake(async () => {}) + stubUpdateWorkPeriodService = sinon.stub(workPeriodService, 'partiallyUpdateWorkPeriod').callsFake(async () => {}) + stubDeleteWorkPeriodService = sinon.stub(workPeriodService, 'deleteWorkPeriod').callsFake(async () => {}) }) afterEach(() => { @@ -45,335 +37,210 @@ describe('resourceBooking service test', () => { }) describe('create resource booking test', () => { - it('create resource booking with booking manager success ', async () => { + it('create resource booking and auto populate work periods for 5 weeks', async () => { const stubDBCreate = sinon.stub(ResourceBooking, 'create').callsFake(() => { - return resourceBookingResponseBody + return testData.resourceBooking5Week.response }) - const entity = await service.createResourceBooking(bookingManagerUser, resourceBookingRequestBody) - expect(entity).to.deep.eql(resourceBookingResponseBody.dataValues) + const entity = await service.createResourceBooking(testData.currentUser, testData.resourceBooking5Week.request) + expect(entity).to.deep.eql(testData.resourceBooking5Week.response.toJSON()) + expect(stubEnsureJobById.calledOnce).to.be.true + expect(stubEnsureUserById.calledOnce).to.be.true expect(stubDBCreate.calledOnce).to.be.true expect(stubPostEvent.calledOnce).to.be.true - }) - - it('create resource booking with connect user success ', async () => { - const stubDBCreate = sinon.stub(ResourceBooking, 'create').callsFake(() => { - return resourceBookingResponseBody - }) - - const entity = await service.createResourceBooking(connectUser, resourceBookingRequestBody) - expect(entity).to.deep.eql(resourceBookingResponseBody.dataValues) + expect(stubCreateWorkPeriodService.callCount).to.eq(5) + expect(stubCreateWorkPeriodService.getCall(0).args[1]).to.deep.eq(testData.resourceBooking5Week.workPeriodRequests[0]) + expect(stubCreateWorkPeriodService.getCall(1).args[1]).to.deep.eq(testData.resourceBooking5Week.workPeriodRequests[1]) + expect(stubCreateWorkPeriodService.getCall(2).args[1]).to.deep.eq(testData.resourceBooking5Week.workPeriodRequests[2]) + expect(stubCreateWorkPeriodService.getCall(3).args[1]).to.deep.eq(testData.resourceBooking5Week.workPeriodRequests[3]) + expect(stubCreateWorkPeriodService.getCall(4).args[1]).to.deep.eq(testData.resourceBooking5Week.workPeriodRequests[4]) + }) + it('create resource booking and auto populate work periods for 1 week', async () => { + const stubDBCreate = sinon.stub(ResourceBooking, 'create').callsFake(async () => { + return testData.resourceBooking1Week.response + }) + + const entity = await service.createResourceBooking(testData.currentUser, testData.resourceBooking1Week.request) + expect(entity).to.deep.eql(testData.resourceBooking1Week.response.toJSON()) + expect(stubEnsureJobById.calledOnce).to.be.true + expect(stubEnsureUserById.calledOnce).to.be.true expect(stubDBCreate.calledOnce).to.be.true expect(stubPostEvent.calledOnce).to.be.true - expect(stubIsConnectMember.calledOnce).to.be.true - expect(stubGetUserId.calledOnce).to.be.true - }) - - it('create resource booking with topcoder user failed ', async () => { - isConnectMember = false - try { - await service.createResourceBooking(topCoderUser, resourceBookingRequestBody) - } catch (error) { - expect(error.message).to.equal('You are not allowed to perform this action!') - } - }) - }) - - describe('get resource booking test', () => { - it('get resource booking with booking manager success', async () => { - const resourceBookingRes = _.cloneDeep(resourceBookingResponseBody) - const stub = sinon.stub(esClient, 'get').callsFake(async () => { - return { - body: { - _id: resourceBookingRes.dataValues.id, - _source: _.omit(resourceBookingRes.dataValues, ['id']) - } - } - }) - const entity = await service.getResourceBooking(bookingManagerUser, resourceBookingResponseBody.dataValues.id) - expect(entity).to.deep.eql(resourceBookingRes.dataValues) - expect(stub.calledOnce).to.be.true - }) - - it('get resource booking with connect user success', async () => { - const resourceBookingRes = _.cloneDeep(resourceBookingResponseBody) - const stub = sinon.stub(esClient, 'get').callsFake(async () => { - return { - body: { - _id: resourceBookingRes.dataValues.id, - _source: _.omit(resourceBookingRes.dataValues, ['id']) - } - } - }) - - const entity = await service.getResourceBooking(connectUser, resourceBookingResponseBody.dataValues.id) - expect(entity).to.deep.eql(_.omit(resourceBookingRes.dataValues, ['memberRate'])) - expect(stub.calledOnce).to.be.true - expect(stubIsConnectMember.calledOnce).to.be.true - }) - - it('get resource booking with topcoder user success', async () => { - isConnectMember = false - const resourceBookingRes = _.cloneDeep(resourceBookingResponseBody) - const stub = sinon.stub(esClient, 'get').callsFake(async () => { - return { - body: { - _id: resourceBookingRes.dataValues.id, - _source: _.omit(resourceBookingRes.dataValues, ['id']) - } - } - }) - const entity = await service.getResourceBooking(topCoderUser, resourceBookingResponseBody.dataValues.id) - expect(entity).to.deep.eql(_.omit(resourceBookingRes.dataValues, ['customerRate'])) - expect(stub.calledOnce).to.be.true - }) - - it('get resource booking with resource booking not exist success', async () => { - const stub = sinon.stub(esClient, 'get').callsFake(async () => { - const err = new Error() - err.statusCode = 404 - throw err - }) - try { - await service.getResourceBooking(bookingManagerUser, resourceBookingResponseBody.dataValues.id) - } catch (error) { - expect(error.message).to.equal(`id: ${resourceBookingResponseBody.dataValues.id} "ResourceBooking" not found`) - expect(stub.calledOnce).to.be.true - } + expect(stubCreateWorkPeriodService.callCount).to.eq(1) + expect(stubUpdateWorkPeriodService.callCount).to.eq(0) + expect(stubDeleteWorkPeriodService.callCount).to.eq(0) + expect(stubCreateWorkPeriodService.getCall(0).args[1]).to.deep.eq(testData.resourceBooking1Week.workPeriodRequests[0]) }) - - it('get resource booking from db with booking manager success', async () => { - const resourceBookingRes = _.cloneDeep(resourceBookingResponseBody) - const stub = sinon.stub(ResourceBooking, 'findOne').callsFake(() => { - return resourceBookingRes + it('update resource booking and cause daysWorked to change', async () => { + const stubResourceBookingFindById = sinon.stub(ResourceBooking, 'findById').callsFake(async () => { + return testData.resourceBooking1Week.response }) - const entity = await service.getResourceBooking(bookingManagerUser, resourceBookingResponseBody.dataValues.id, true) - expect(entity).to.deep.eql(resourceBookingRes.dataValues) - expect(stub.calledOnce).to.be.true - }) - - it('get resource booking from db with connect user success', async () => { - const resourceBookingRes = _.cloneDeep(resourceBookingResponseBody) - const stub = sinon.stub(ResourceBooking, 'findOne').callsFake(() => { - return resourceBookingRes + const stubWorkPeriodFindAll = sinon.stub(WorkPeriod, 'findAll').callsFake(async () => { + return testData.resourceBooking1Week.workPeriodResponse }) - - const entity = await service.getResourceBooking(connectUser, resourceBookingResponseBody.dataValues.id, true) - expect(entity).to.deep.eql(_.omit(resourceBookingRes.dataValues, ['memberRate'])) - expect(stub.calledOnce).to.be.true - expect(stubIsConnectMember.calledOnce).to.be.true - }) - - it('get resource booking from db with topcoder user success', async () => { - isConnectMember = false - const resourceBookingRes = _.cloneDeep(resourceBookingResponseBody) - const stub = sinon.stub(ResourceBooking, 'findOne').callsFake(() => { - return resourceBookingRes - }) - const entity = await service.getResourceBooking(topCoderUser, resourceBookingResponseBody.dataValues.id, true) - expect(entity).to.deep.eql(_.omit(resourceBookingRes.dataValues, ['customerRate'])) - expect(stub.calledOnce).to.be.true - }) - - it('get resource booking from db with resource booking not exist success', async () => { - const stub = sinon.stub(ResourceBooking, 'findOne').callsFake(() => { - return null - }) - try { - await service.getResourceBooking(bookingManagerUser, resourceBookingResponseBody.dataValues.id, true) - } catch (error) { - expect(error.message).to.equal(`id: ${resourceBookingResponseBody.dataValues.id} "ResourceBooking" doesn't exists.`) - expect(stub.calledOnce).to.be.true - } - }) - }) - - describe('fully update resource booking test', () => { - it('fully update resource booking test with booking manager success', async () => { - const resourceBookingRes = _.cloneDeep(resourceBookingResponseBody) - const stubResourceBookingFindOne = sinon.stub(ResourceBooking, 'findOne').callsFake(() => { - return { - ...resourceBookingRes, - update: () => { return null } - } - }) - const entity = await service.fullyUpdateResourceBooking(bookingManagerUser, resourceBookingResponseBody.dataValues.id, fullyUpdateResourceBookingRequestBody) - expect(entity).to.deep.eql(resourceBookingRes.dataValues) - expect(stubResourceBookingFindOne.calledOnce).to.be.true + const entity = await service.partiallyUpdateResourceBooking(testData.currentUser, testData.resourceBooking1Week.response.dataValues.id, testData.resourceBooking1Week.updateRequest) + expect(entity).to.deep.eql(testData.resourceBooking1Week.updateResponse.toJSON()) + expect(stubResourceBookingFindById.calledOnce).to.be.true expect(stubPostEvent.calledOnce).to.be.true - }) - - it('fully update resource booking test with connect user success', async () => { - const resourceBookingRes = _.cloneDeep(resourceBookingResponseBody) - const stubResourceBookingFindOne = sinon.stub(ResourceBooking, 'findOne').callsFake(() => { - return { - ...resourceBookingRes, - update: () => { return null } - } - }) - - const entity = await service.fullyUpdateResourceBooking(connectUser, resourceBookingResponseBody.dataValues.id, fullyUpdateResourceBookingRequestBody) - expect(entity).to.deep.eql(resourceBookingRes.dataValues) - expect(stubResourceBookingFindOne.calledOnce).to.be.true + expect(stubWorkPeriodFindAll.called).to.be.true + expect(stubCreateWorkPeriodService.callCount).to.eq(0) + expect(stubUpdateWorkPeriodService.callCount).to.eq(1) + expect(stubDeleteWorkPeriodService.callCount).to.eq(0) + expect(stubUpdateWorkPeriodService.getCall(0).args[2]).to.deep.eq(testData.resourceBooking1Week.workPeriodUpdateRequests[0]) + }) + it('update resource booking and cause daysWorked to change', async () => { + const stubResourceBookingFindById = sinon.stub(ResourceBooking, 'findById').callsFake(async () => { + return testData.resourceBookingUpdate.response + }) + const stubWorkPeriodFindAll = sinon.stub(WorkPeriod, 'findAll').callsFake(async () => { + return testData.resourceBookingUpdate.workPeriodResponse + }) + const entity = await service.partiallyUpdateResourceBooking(testData.currentUser, testData.resourceBookingUpdate.response.dataValues.id, testData.resourceBookingUpdate.updateRequest) + expect(entity).to.deep.eql(testData.resourceBookingUpdate.updateResponse.toJSON()) + expect(stubResourceBookingFindById.calledOnce).to.be.true expect(stubPostEvent.calledOnce).to.be.true - expect(stubIsConnectMember.calledOnce).to.be.true - }) - - it('fully update resource booking test with topcoder user failed', async () => { - isConnectMember = false - const resourceBookingRes = _.cloneDeep(resourceBookingResponseBody) - const stubResourceBookingFindOne = sinon.stub(ResourceBooking, 'findOne').callsFake(() => { - return { - ...resourceBookingRes, - update: () => { return null } - } - }) - try { - await service.fullyUpdateResourceBooking(topCoderUser, resourceBookingResponseBody.dataValues.id, fullyUpdateResourceBookingRequestBody) - unexpected() - } catch (error) { - expect(stubResourceBookingFindOne.calledOnce).to.be.true - expect(error.message).to.equal('You are not allowed to perform this action!') - } - }) - }) - - describe('partially update resource booking test', () => { - it('partially update resource booking test with booking manager success', async () => { - const resourceBookingRes = _.cloneDeep(resourceBookingResponseBody) - const stubResourceBookingFindOne = sinon.stub(ResourceBooking, 'findOne').callsFake(() => { - return { - ...resourceBookingRes, - update: () => { return null } - } - }) - const entity = await service.partiallyUpdateResourceBooking(bookingManagerUser, resourceBookingResponseBody.dataValues.id, partiallyUpdateResourceBookingRequestBody) - expect(entity).to.deep.eql(resourceBookingRes.dataValues) - expect(stubResourceBookingFindOne.calledOnce).to.be.true + expect(stubWorkPeriodFindAll.called).to.be.true + expect(stubCreateWorkPeriodService.callCount).to.eq(0) + expect(stubUpdateWorkPeriodService.callCount).to.eq(1) + expect(stubDeleteWorkPeriodService.callCount).to.eq(0) + expect(stubUpdateWorkPeriodService.getCall(0).args[2]).to.deep.eq(testData.resourceBookingUpdate.workPeriodUpdateRequests[0]) + }) + it('update resource booking and cause workPeriod to create', async () => { + const stubResourceBookingFindById = sinon.stub(ResourceBooking, 'findById').callsFake(async () => { + return testData.resourceBookingUpdate.response2 + }) + const stubWorkPeriodFindAll = sinon.stub(WorkPeriod, 'findAll').callsFake(async () => { + return testData.resourceBookingUpdate.workPeriodResponse + }) + const entity = await service.partiallyUpdateResourceBooking(testData.currentUser, testData.resourceBookingUpdate.response2.dataValues.id, testData.resourceBookingUpdate.updateRequest2) + expect(entity).to.deep.eql(testData.resourceBookingUpdate.updateResponse2.toJSON()) + expect(stubResourceBookingFindById.calledOnce).to.be.true expect(stubPostEvent.calledOnce).to.be.true - }) - - it('partially update resource booking test with connect user success', async () => { - const resourceBookingRes = _.cloneDeep(resourceBookingResponseBody) - const stubResourceBookingFindOne = sinon.stub(ResourceBooking, 'findOne').callsFake(() => { - return { - ...resourceBookingRes, - update: () => { return null } - } - }) - - const entity = await service.partiallyUpdateResourceBooking(connectUser, resourceBookingResponseBody.dataValues.id, partiallyUpdateResourceBookingRequestBody) - expect(entity).to.deep.eql(resourceBookingRes.dataValues) - expect(stubResourceBookingFindOne.calledOnce).to.be.true + expect(stubWorkPeriodFindAll.called).to.be.true + expect(stubCreateWorkPeriodService.callCount).to.eq(1) + expect(stubUpdateWorkPeriodService.callCount).to.eq(1) + expect(stubDeleteWorkPeriodService.callCount).to.eq(0) + expect(stubUpdateWorkPeriodService.getCall(0).args[2]).to.deep.eq(testData.resourceBookingUpdate.workPeriodUpdateRequests2[0]) + expect(stubCreateWorkPeriodService.getCall(0).args[1]).to.deep.eq(testData.resourceBookingUpdate.workPeriodUpdateRequests2[1]) + }) + it('update resource booking and cause workPeriod to delete', async () => { + const stubResourceBookingFindById = sinon.stub(ResourceBooking, 'findById').callsFake(async () => { + return testData.resourceBookingUpdate.response3 + }) + const stubWorkPeriodFindAll = sinon.stub(WorkPeriod, 'findAll').callsFake(async () => { + return testData.resourceBookingUpdate.workPeriodResponse + }) + const entity = await service.partiallyUpdateResourceBooking(testData.currentUser, testData.resourceBookingUpdate.response3.dataValues.id, testData.resourceBookingUpdate.updateRequest3) + expect(entity).to.deep.eql(testData.resourceBookingUpdate.updateResponse3.toJSON()) + expect(stubResourceBookingFindById.calledOnce).to.be.true expect(stubPostEvent.calledOnce).to.be.true - expect(stubIsConnectMember.calledOnce).to.be.true - }) - - it('partially update resource booking test with topcoder user failed', async () => { - isConnectMember = false - const resourceBookingRes = _.cloneDeep(resourceBookingResponseBody) - const stubResourceBookingFindOne = sinon.stub(ResourceBooking, 'findOne').callsFake(() => { - return { - ...resourceBookingRes, - update: () => { return null } - } - }) + expect(stubWorkPeriodFindAll.called).to.be.true + expect(stubCreateWorkPeriodService.callCount).to.eq(0) + expect(stubUpdateWorkPeriodService.callCount).to.eq(1) + expect(stubDeleteWorkPeriodService.callCount).to.eq(1) + expect(stubUpdateWorkPeriodService.getCall(0).args[1]).to.deep.eq(testData.resourceBookingUpdate.workPeriodUpdateRequests3[0]) + expect(stubUpdateWorkPeriodService.getCall(0).args[2]).to.deep.eq(testData.resourceBookingUpdate.workPeriodUpdateRequests3[1]) + expect(stubDeleteWorkPeriodService.getCall(0).args[1]).to.deep.eq(testData.resourceBookingUpdate.workPeriodUpdateRequests3[2]) + }) + it('delete resource booking and cause workPeriod to delete', async () => { + const stubResourceBookingFindById = sinon.stub(ResourceBooking, 'findById').callsFake(async () => { + return testData.resourceBookingUpdate.response3 + }) + const stubWorkPeriodFindAll = sinon.stub(WorkPeriod, 'findAll').callsFake(async () => { + return testData.resourceBookingUpdate.workPeriodResponse + }) + await service.deleteResourceBooking(testData.currentUser, testData.resourceBookingUpdate.response3.dataValues.id) + expect(stubResourceBookingFindById.calledOnce).to.be.true + expect(stubPostEvent.calledOnce).to.be.true + expect(stubWorkPeriodFindAll.called).to.be.true + expect(stubCreateWorkPeriodService.callCount).to.eq(0) + expect(stubUpdateWorkPeriodService.callCount).to.eq(0) + expect(stubDeleteWorkPeriodService.callCount).to.eq(4) + expect(stubDeleteWorkPeriodService.getCall(0).args[1]).to.deep.eq(testData.resourceBookingUpdate.workPeriodUpdateRequests3[3]) + expect(stubDeleteWorkPeriodService.getCall(1).args[1]).to.deep.eq(testData.resourceBookingUpdate.workPeriodUpdateRequests3[4]) + expect(stubDeleteWorkPeriodService.getCall(2).args[1]).to.deep.eq(testData.resourceBookingUpdate.workPeriodUpdateRequests3[5]) + expect(stubDeleteWorkPeriodService.getCall(3).args[1]).to.deep.eq(testData.resourceBookingUpdate.workPeriodUpdateRequests3[6]) + }) + it('update resource booking with paid weeks and cause workPeriod to delete', async () => { + const stubResourceBookingFindById = sinon.stub(ResourceBooking, 'findById').callsFake(async () => { + return testData.resourceBookingUpdate.response4 + }) + const stubWorkPeriodFindAll = sinon.stub(WorkPeriod, 'findAll').callsFake(async () => { + return testData.resourceBookingUpdate.workPeriodResponse4 + }) + const entity = await service.partiallyUpdateResourceBooking(testData.currentUser, testData.resourceBookingUpdate.response4.dataValues.id, testData.resourceBookingUpdate.updateRequest4) + expect(entity).to.deep.eql(testData.resourceBookingUpdate.updateResponse4.toJSON()) + expect(stubResourceBookingFindById.calledOnce).to.be.true + expect(stubPostEvent.calledOnce).to.be.true + expect(stubWorkPeriodFindAll.called).to.be.true + expect(stubCreateWorkPeriodService.callCount).to.eq(0) + expect(stubUpdateWorkPeriodService.callCount).to.eq(1) + expect(stubDeleteWorkPeriodService.callCount).to.eq(2) + expect(stubUpdateWorkPeriodService.getCall(0).args[2]).to.deep.eq(testData.resourceBookingUpdate.workPeriodUpdateRequests4[0]) + expect(stubDeleteWorkPeriodService.getCall(0).args[1]).to.deep.eq(testData.resourceBookingUpdate.workPeriodUpdateRequests4[1]) + expect(stubDeleteWorkPeriodService.getCall(1).args[1]).to.deep.eq(testData.resourceBookingUpdate.workPeriodUpdateRequests4[2]) + }) + it('fail to update resource booking with paid weeks when try to delete paid weeks', async () => { + const stubResourceBookingFindById = sinon.stub(ResourceBooking, 'findById').callsFake(async () => { + return testData.resourceBookingUpdate.response4 + }) + const stubWorkPeriodFindAll = sinon.stub(WorkPeriod, 'findAll').callsFake(async () => { + return testData.resourceBookingUpdate.workPeriodResponse4 + }) + let httpStatus try { - await service.partiallyUpdateResourceBooking(topCoderUser, resourceBookingResponseBody.dataValues.id, partiallyUpdateResourceBookingRequestBody) - unexpected() - } catch (error) { - expect(error.message).to.equal('You are not allowed to perform this action!') + await service.partiallyUpdateResourceBooking(testData.currentUser, testData.resourceBookingUpdate.response4.dataValues.id, testData.resourceBookingUpdate.updateRequest5) + } catch (err) { + httpStatus = err.httpStatus } - expect(stubResourceBookingFindOne.calledOnce).to.be.true - }) - }) - - describe('delete resource booking test', () => { - it('delete resource booking test with booking manager success', async () => { - const stubResourceBookingFindOne = sinon.stub(ResourceBooking, 'findOne').callsFake(() => { - return { - ..._.cloneDeep(resourceBookingResponseBody), - update: () => { return null } - } - }) - await service.deleteResourceBooking(bookingManagerUser, resourceBookingResponseBody.dataValues.id) - expect(stubResourceBookingFindOne.calledOnce).to.be.true - expect(stubPostEvent.calledOnce).to.be.true - }) - - it('delete resource booking test with connect user failed', async () => { + expect(httpStatus).to.eq(400) + expect(stubResourceBookingFindById.calledOnce).to.be.true + expect(stubPostEvent.calledOnce).to.be.false + expect(stubWorkPeriodFindAll.called).to.be.true + expect(stubCreateWorkPeriodService.callCount).to.eq(0) + expect(stubUpdateWorkPeriodService.callCount).to.eq(0) + expect(stubDeleteWorkPeriodService.callCount).to.eq(0) + }) + it('fail to update resource booking with paid weeks when try to set status cancelled', async () => { + const stubResourceBookingFindById = sinon.stub(ResourceBooking, 'findById').callsFake(async () => { + return testData.resourceBookingUpdate.response4 + }) + const stubWorkPeriodFindAll = sinon.stub(WorkPeriod, 'findAll').callsFake(async () => { + return testData.resourceBookingUpdate.workPeriodResponse4 + }) + let httpStatus try { - await service.deleteResourceBooking(connectUser, resourceBookingResponseBody.dataValues.id) - unexpected() - } catch (error) { - expect(error.message).to.equal('You are not allowed to perform this action!') + await service.partiallyUpdateResourceBooking(testData.currentUser, testData.resourceBookingUpdate.response4.dataValues.id, testData.resourceBookingUpdate.updateRequest6) + } catch (err) { + httpStatus = err.httpStatus } - }) - - it('delete resource booking test with topcoder user failed', async () => { + expect(httpStatus).to.eq(400) + expect(stubResourceBookingFindById.calledOnce).to.be.true + expect(stubPostEvent.calledOnce).to.be.false + expect(stubWorkPeriodFindAll.called).to.be.true + expect(stubCreateWorkPeriodService.callCount).to.eq(0) + expect(stubUpdateWorkPeriodService.callCount).to.eq(0) + expect(stubDeleteWorkPeriodService.callCount).to.eq(0) + }) + it('fail to delete resource booking with paid weeks', async () => { + const stubResourceBookingFindById = sinon.stub(ResourceBooking, 'findById').callsFake(async () => { + return testData.resourceBookingUpdate.response4 + }) + const stubWorkPeriodFindAll = sinon.stub(WorkPeriod, 'findAll').callsFake(async () => { + return testData.resourceBookingUpdate.workPeriodResponse4 + }) + let httpStatus try { - await service.deleteResourceBooking(topCoderUser, jobCandidateResponseBody.dataValues.id) - unexpected() - } catch (error) { - expect(error.message).to.equal('You are not allowed to perform this action!') + await service.deleteResourceBooking(testData.currentUser, testData.resourceBookingUpdate.response4.dataValues.id) + } catch (err) { + httpStatus = err.httpStatus } - }) - }) - - describe('search resource booking test', () => { - it('search resource booking success', async () => { - const stub = sinon.stub(esClient, 'search').callsFake(() => { - return { - body: { - hits: { - total: { - value: 1 - }, - hits: [{ - _id: resourceBookingResponseBody.dataValues.id, - _source: _.omit(resourceBookingResponseBody.dataValues, ['id']) - }] - } - } - } - }) - const entity = await service.searchResourceBookings({ sortBy: 'id', sortOrder: 'asc', page: 1, perPage: 1, status: 'sourcing' }) - expect(entity.result[0]).to.deep.eql(resourceBookingResponseBody.dataValues) - expect(stub.calledOnce).to.be.true - }) - - it('search resource booking without query parameters success', async () => { - const stub = sinon.stub(esClient, 'search').callsFake(() => { - return { - body: { - hits: { - total: { - value: 1 - }, - hits: [{ - _id: resourceBookingResponseBody.dataValues.id, - _source: _.omit(resourceBookingResponseBody.dataValues, ['id']) - }] - } - } - } - }) - const entity = await service.searchResourceBookings({}) - expect(entity.result[0]).to.deep.eql(resourceBookingResponseBody.dataValues) - expect(stub.calledOnce).to.be.true - }) - - it('search resource booking success when es search fails', async () => { - const stubESSearch = sinon.stub(esClient, 'search').callsFake(() => { - throw new Error('dedicated es failure') - }) - - const stubDBSearch = sinon.stub(ResourceBooking, 'findAll').callsFake(() => { - return [resourceBookingResponseBody] - }) - const entity = await service.searchResourceBookings({ sortBy: 'id', sortOrder: 'asc', page: 1, perPage: 1, status: 'sourcing' }) - expect(entity.result[0]).to.deep.eql(resourceBookingResponseBody.dataValues) - expect(stubESSearch.calledOnce).to.be.true - expect(stubDBSearch.calledOnce).to.be.true + expect(httpStatus).to.eq(400) + expect(stubResourceBookingFindById.calledOnce).to.be.false + expect(stubPostEvent.calledOnce).to.be.false + expect(stubWorkPeriodFindAll.called).to.be.true + expect(stubCreateWorkPeriodService.callCount).to.eq(0) + expect(stubUpdateWorkPeriodService.callCount).to.eq(0) + expect(stubDeleteWorkPeriodService.callCount).to.eq(0) }) }) }) diff --git a/test/unit/TeamService.test.js b/test/unit/TeamService.test.js deleted file mode 100644 index 01244d75..00000000 --- a/test/unit/TeamService.test.js +++ /dev/null @@ -1,293 +0,0 @@ -/* eslint-disable no-unused-expressions */ -process.env.NODE_ENV = 'test' -require('../../src/bootstrap') - -const expect = require('chai').expect -const sinon = require('sinon') - -const service = require('../../src/services/TeamService') -const JobService = require('../../src/services/JobService') -const ResourceBookingService = require('../../src/services/ResourceBookingService') -const { - bookingManagerUser, - unexpected, - projectRequestBody, - userRequestBody, - memberRequestBody, - skillsRequestBody, - userSkillsRequestBody, - resourceBookingsRequestBody, - jobsRequestBody, - taasTeamItem0ResponseBody, - taasTeam9050ResponseBody, - jobDetailResponseBody -} = require('./common/testData') -const helper = require('../../src/common/helper') - -describe('Team service test', () => { - let stubGetProjects - let stubGetProjectById - let stubGetUsers - let stubGetMembers - let stubGetSkills - let stubGetUserSkill - let stubGetAssignedResourceBookings - let stubGetJobs - beforeEach(() => { - stubGetProjects = sinon.stub(helper, 'getProjects').callsFake(() => { - return projectRequestBody - }) - - stubGetProjectById = sinon.stub(helper, 'getProjectById').callsFake(() => { - return projectRequestBody[0] - }) - - stubGetUsers = sinon.stub(helper, 'getUsers').callsFake(() => { - return userRequestBody - }) - - stubGetMembers = sinon.stub(helper, 'getMembers').callsFake(() => { - return memberRequestBody - }) - - stubGetSkills = sinon.stub(helper, 'getSkills').callsFake(() => { - return skillsRequestBody - }) - - stubGetUserSkill = sinon.stub(helper, 'getUserSkill').callsFake(() => { - return userSkillsRequestBody - }) - - stubGetAssignedResourceBookings = sinon.stub(ResourceBookingService, 'searchResourceBookings').callsFake(() => { - return { result: resourceBookingsRequestBody } - }) - - stubGetJobs = sinon.stub(JobService, 'searchJobs').callsFake(() => { - return { result: jobsRequestBody } - }) - }) - - afterEach(() => { - sinon.restore() - }) - - describe('search teams test', () => { - beforeEach(() => { - stubGetAssignedResourceBookings.restore() - stubGetAssignedResourceBookings = sinon.stub(ResourceBookingService, 'searchResourceBookings').callsFake(() => { - return { result: resourceBookingsRequestBody } - }) - stubGetJobs.restore() - stubGetJobs = sinon.stub(JobService, 'searchJobs').callsFake(() => { - return { result: jobsRequestBody } - }) - }) - - it('search teams success ', async () => { - const entity = await service.searchTeams(bookingManagerUser) - expect(entity.length).to.equal(20) - expect(entity[0]).to.deep.eql(taasTeamItem0ResponseBody) - expect(stubGetProjects.calledOnce).to.be.true - expect(stubGetUsers.calledOnce).to.be.true - expect(stubGetMembers.called).to.be.true - expect(stubGetAssignedResourceBookings.calledOnce).to.be.true - expect(stubGetJobs.calledOnce).to.be.true - }) - - it('search teams success with no resourceBooking ', async () => { - stubGetAssignedResourceBookings.restore() - stubGetAssignedResourceBookings = sinon.stub(ResourceBookingService, 'searchResourceBookings').callsFake(() => { - return { result: [] } - }) - stubGetJobs.restore() - stubGetJobs = sinon.stub(JobService, 'searchJobs').callsFake(() => { - return { result: [] } - }) - - const entity = await service.searchTeams(bookingManagerUser) - expect(entity.length).to.equal(20) - expect(entity[0]).to.deep.eql({ - id: 9050, - name: 'sample', - weeklyCost: 0, - resources: [] - }) - expect(stubGetProjects.calledOnce).to.be.true - expect(stubGetAssignedResourceBookings.calledOnce).to.be.true - expect(stubGetJobs.calledOnce).to.be.true - }) - - it('search teams success with no null start date', async () => { - stubGetAssignedResourceBookings.restore() - stubGetAssignedResourceBookings = sinon.stub(ResourceBookingService, 'searchResourceBookings').callsFake(() => { - return { - result: [{ - projectId: 9050, - userId: '1b88e433-828b-4e0d-9fb5-ef75b9dcca6e', - jobId: '1d9e8c1a-e653-4d31-a799-2685e41da212', - startDate: null, - endDate: null, - memberRate: 13.23, - customerRate: 13, - rateType: 'hourly', - status: 'assigned', - createdAt: '2020-11-11T04:17:23.131Z', - createdBy: 'a55fe1bc-1754-45fa-9adc-cf3d6d7c377a', - id: '3d9e8c1a-e653-4d31-a799-2685e41da212' - }] - } - }) - - const entity = await service.searchTeams(bookingManagerUser) - expect(entity.length).to.equal(20) - expect(stubGetProjects.calledOnce).to.be.true - expect(stubGetAssignedResourceBookings.calledOnce).to.be.true - expect(stubGetJobs.calledOnce).to.be.true - }) - - it('search teams success with no empty user infos', async () => { - stubGetAssignedResourceBookings.restore() - stubGetAssignedResourceBookings = sinon.stub(ResourceBookingService, 'searchResourceBookings').callsFake(() => { - return { - result: [{ - projectId: 9050, - userId: 'not exist', - jobId: '1d9e8c1a-e653-4d31-a799-2685e41da212', - startDate: null, - endDate: null, - memberRate: 13.23, - customerRate: 13, - rateType: 'hourly', - status: 'assigned', - createdAt: '2020-11-11T04:17:23.131Z', - createdBy: 'a55fe1bc-1754-45fa-9adc-cf3d6d7c377a', - id: '3d9e8c1a-e653-4d31-a799-2685e41da212' - }] - } - }) - - const entity = await service.searchTeams(bookingManagerUser) - expect(entity.length).to.equal(20) - expect(stubGetProjects.calledOnce).to.be.true - expect(stubGetAssignedResourceBookings.calledOnce).to.be.true - expect(stubGetJobs.calledOnce).to.be.true - }) - }) - - describe('get team by id test', () => { - beforeEach(() => { - stubGetUserSkill.restore() - stubGetUserSkill = sinon.stub(helper, 'getUserSkill').callsFake(() => { - return userSkillsRequestBody - }) - }) - - it('get team by id success ', async () => { - const entity = await service.getTeam(bookingManagerUser, 9050) - expect(entity).to.deep.eql(taasTeam9050ResponseBody) - expect(stubGetProjectById.calledOnce).to.be.true - expect(stubGetUsers.calledOnce).to.be.true - expect(stubGetMembers.called).to.be.true - expect(stubGetAssignedResourceBookings.calledOnce).to.be.true - expect(stubGetJobs.calledOnce).to.be.true - expect(stubGetSkills.calledOnce).to.be.true - expect(stubGetUserSkill.called).to.be.true - }) - - it('get team by id with no user skills', async () => { - stubGetUserSkill.restore() - stubGetUserSkill = sinon.stub(helper, 'getUserSkill').callsFake(() => { - return [] - }) - - const entity = await service.getTeam(bookingManagerUser, 9050) - expect(entity.resources[0].skillMatched).to.equal(0) - expect(stubGetProjectById.calledOnce).to.be.true - expect(stubGetAssignedResourceBookings.calledOnce).to.be.true - expect(stubGetJobs.calledOnce).to.be.true - }) - }) - - describe('get job by team id and job id test', () => { - beforeEach(() => { - stubGetUserSkill.restore() - stubGetUserSkill = sinon.stub(helper, 'getUserSkill').callsFake(() => { - return userSkillsRequestBody - }) - stubGetMembers.restore() - stubGetMembers = sinon.stub(helper, 'getMembers').callsFake(() => { - return memberRequestBody - }) - stubGetUsers.restore() - stubGetUsers = sinon.stub(helper, 'getUsers').callsFake(() => { - return userRequestBody - }) - }) - - it('get job detail by id success ', async () => { - const entity = await service.getTeamJob(bookingManagerUser, 9050, '1d9e8c1a-e653-4d31-a799-2685e41da212') - expect(entity).to.deep.eql(jobDetailResponseBody) - expect(stubGetJobs.calledOnce).to.be.true - expect(stubGetUsers.called).to.be.true - expect(stubGetMembers.called).to.be.true - expect(stubGetUserSkill.called).to.be.true - }) - - it('get job detail by not exist id success ', async () => { - const entity = await service.getTeamJob(bookingManagerUser, 9050, '1d9e8c1a-e653-4d31-a799-2685e41da999') - expect(entity).to.be.a('object') - expect(stubGetJobs.calledOnce).to.be.true - }) - - it('get job detail by invalid id ', async () => { - try { - await service.getTeamJob(bookingManagerUser, 9050, 'invalid') - unexpected() - } catch (error) { - expect(error.message).to.equal('"jobId" must be a valid GUID') - } - }) - - it('get team by id with no user skills', async () => { - stubGetUserSkill.restore() - stubGetUserSkill = sinon.stub(helper, 'getUserSkill').callsFake(() => { - return [] - }) - - const entity = await service.getTeamJob(bookingManagerUser, 9050, '1d9e8c1a-e653-4d31-a799-2685e41da212') - expect(entity.candidates[0].skillMatched).to.equal(0) - expect(stubGetJobs.calledOnce).to.be.true - expect(stubGetUsers.called).to.be.true - expect(stubGetMembers.called).to.be.true - expect(stubGetUserSkill.called).to.be.true - }) - - it('get job detail by id with photoURL ', async () => { - stubGetMembers.restore() - stubGetMembers = sinon.stub(helper, 'getMembers').callsFake(() => { - return [{ - userId: 8547893, - handleLower: 'sandrine_kuvalis98', - photoURL: 'https://topcoder-dev-media.s3.amazonaws.com/member/profile/TonyJ-1604301092491.jpeg' - }] - }) - - const entity = await service.getTeamJob(bookingManagerUser, 9050, '1d9e8c1a-e653-4d31-a799-2685e41da212') - expect(entity.candidates[0].photo_url).to.be.a('string') - expect(stubGetJobs.calledOnce).to.be.true - expect(stubGetUsers.called).to.be.true - expect(stubGetMembers.called).to.be.true - expect(stubGetUserSkill.called).to.be.true - }) - - it('get job detail by id empty users ', async () => { - stubGetUsers.restore() - stubGetUsers = sinon.stub(helper, 'getUsers').callsFake(() => { - return [] - }) - - const entity = await service.getTeamJob(bookingManagerUser, 9050, '1d9e8c1a-e653-4d31-a799-2685e41da212') - expect(entity.candidates.length).to.equal(0) - }) - }) -}) diff --git a/test/unit/common/testData.js b/test/unit/common/testData.js index dc607ba5..8c145247 100644 --- a/test/unit/common/testData.js +++ b/test/unit/common/testData.js @@ -1,789 +1,505 @@ -const bookingManagerUser = { - roles: [ - 'Topcoder User', - 'copilot', - 'Connect Manager', - 'bookingmanager', - 'u-bahn' - ], - iss: 'https://api.topcoder.com', - handle: 'pshah_manager', - exp: 55530199259, - userId: '40152856', - iat: 1602136970, - email: 'vikas.agarwal+pshah_manager@topcoder.com', - jti: '83a7b1cd-15b7-4529-b3a1-7c2282bbc750', - isBookingManager: true, - jwtToken: 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6Ik5VSkZORGd4UlRVME5EWTBOVVkzTlRkR05qTXlRamxETmpOQk5UYzVRVUV3UlRFeU56TTJRUSJ9.eyJodHRwczovL3RvcGNvZGVyLWRldi5jb20vcm9sZXMiOlsiVG9wY29kZXIgVXNlciIsImNvcGlsb3QiLCJDb25uZWN0IE1hbmFnZXIiLCJib29raW5nbWFuYWdlciIsInUtYmFobiJdLCJodHRwczovL3RvcGNvZGVyLWRldi5jb20vdXNlcklkIjoiNDAxNTI4NTYiLCJodHRwczovL3RvcGNvZGVyLWRldi5jb20vaGFuZGxlIjoicHNoYWhfbWFuYWdlciIsImh0dHBzOi8vdG9wY29kZXItZGV2LmNvbS91c2VyX2lkIjoiYXV0aDB8NDAxNTI4NTYiLCJodHRwczovL3RvcGNvZGVyLWRldi5jb20vdGNzc28iOiI0MDE1Mjg1Nnw4MTM0ZjQ4ZWJlMTFhODQ4YTM3NTllNWVmOWU5MmYyMTQ2OTJlMjExMzA0MGM4MmI1ZDhmNTgxYzZkZmNjYzg4IiwiaHR0cHM6Ly90b3Bjb2Rlci1kZXYuY29tL2FjdGl2ZSI6dHJ1ZSwibmlja25hbWUiOiJwc2hhaF9tYW5hZ2VyIiwibmFtZSI6InZpa2FzLmFnYXJ3YWwrcHNoYWhfbWFuYWdlckB0b3Bjb2Rlci5jb20iLCJwaWN0dXJlIjoiaHR0cHM6Ly9zLmdyYXZhdGFyLmNvbS9hdmF0YXIvOTJhZmIyZjBlZDUyZmRmYWUxZjM3MTAyMWFlNjUwMTM_cz00ODAmcj1wZyZkPWh0dHBzJTNBJTJGJTJGY2RuLmF1dGgwLmNvbSUyRmF2YXRhcnMlMkZ2aS5wbmciLCJ1cGRhdGVkX2F0IjoiMjAyMC0xMC0yNFQwODoyODoyNC4xODRaIiwiZW1haWwiOiJ2aWthcy5hZ2Fyd2FsK3BzaGFoX21hbmFnZXJAdG9wY29kZXIuY29tIiwiZW1haWxfdmVyaWZpZWQiOnRydWUsImlzcyI6Imh0dHBzOi8vYXV0aC50b3Bjb2Rlci1kZXYuY29tLyIsInN1YiI6ImF1dGgwfDQwMTUyODU2IiwiYXVkIjoiQlhXWFVXbmlsVlVQZE4wMXQyU2UyOVR3MlpZTkdadkgiLCJpYXQiOjE2MDM1NDMzMzgsImV4cCI6MzMxNjA0NTI3MzgsIm5vbmNlIjoiUjFBMmN6WXVWVFptYmpaSFJHOTJWbDlEU1VKNlVsbHZRWGMzUkhoNVMzWldkV1pEY0ROWE1FWjFYdz09In0.2gPsqZTgS1rtiNa1USm3KPA6Xsv3TcHxuDFofgIbeOM' -} - -const connectUser = { - roles: [ - 'Topcoder User', - 'copilot', - 'Connect Manager', - 'u-bahn' - ], - iss: 'https://api.topcoder.com', - sub: 'connect_user', - exp: 55530199259, - userId: '8547899', - iat: 1602136970, - email: 'connectUser@topcoder.com', - jti: '83a7b1cd-15b7-4529-b3a1-7c2282bbc750', - isBookingManager: false, - jwtToken: 'Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJyb2xlcyI6WyJDb25uZWN0IFVzZXIiXSwiaXNzIjoiaHR0cHM6Ly9hcGkudG9wY29kZXIuY29tIiwic3ViIjoiY29ubmVjdF91c2VyIiwiZXhwIjo1NTUzMDE5OTI1OSwidXNlcklkIjoiMzUyNjc5ODMiLCJpYXQiOjE2MDIxMzY5NzAsImVtYWlsIjoiY29ubmVjdFVzZXJAdG9wY29kZXIuY29tIiwianRpIjoiODNhN2IxY2QtMTViNy00NTI5LWIzYTEtN2MyMjgyYmJjNzUwIn0.-rtF-_QhU-jDbxBqs79AP_4xFKp_gfVtptcuOmI7RUM' -} - -const topCoderUser = { - roles: [ - 'Topcoder User' - ], - iss: 'https://api.topcoder.com', - handle: 'topcoder_user', - exp: 55530199259, - userId: '8547899', - iat: 1602136970, - email: 'topcoderUser@topcoder.com', - jti: '83a7b1cd-15b7-4529-b3a1-7c2282bbc750', - isBookingManager: false, - jwtToken: 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6Ik5VSkZORGd4UlRVME5EWTBOVVkzTlRkR05qTXlRamxETmpOQk5UYzVRVUV3UlRFeU56TTJRUSJ9.eyJodHRwczovL3RvcGNvZGVyLWRldi5jb20vcm9sZXMiOlsiVG9wY29kZXIgVXNlciJdLCJodHRwczovL3RvcGNvZGVyLWRldi5jb20vdXNlcklkIjoiODU0Nzg5OSIsImh0dHBzOi8vdG9wY29kZXItZGV2LmNvbS9oYW5kbGUiOiJwc2hhaF9tYW5hZ2VyIiwiaHR0cHM6Ly90b3Bjb2Rlci1kZXYuY29tL3VzZXJfaWQiOiJhdXRoMHw0MDE1Mjg1NiIsImh0dHBzOi8vdG9wY29kZXItZGV2LmNvbS90Y3NzbyI6IjQwMTUyODU2fDgxMzRmNDhlYmUxMWE4NDhhMzc1OWU1ZWY5ZTkyZjIxNDY5MmUyMTEzMDQwYzgyYjVkOGY1ODFjNmRmY2NjODgiLCJodHRwczovL3RvcGNvZGVyLWRldi5jb20vYWN0aXZlIjp0cnVlLCJuaWNrbmFtZSI6InBzaGFoX21hbmFnZXIiLCJuYW1lIjoidmlrYXMuYWdhcndhbCtwc2hhaF9tYW5hZ2VyQHRvcGNvZGVyLmNvbSIsInBpY3R1cmUiOiJodHRwczovL3MuZ3JhdmF0YXIuY29tL2F2YXRhci85MmFmYjJmMGVkNTJmZGZhZTFmMzcxMDIxYWU2NTAxMz9zPTQ4MCZyPXBnJmQ9aHR0cHMlM0ElMkYlMkZjZG4uYXV0aDAuY29tJTJGYXZhdGFycyUyRnZpLnBuZyIsInVwZGF0ZWRfYXQiOiIyMDIwLTEwLTI0VDA4OjI4OjI0LjE4NFoiLCJlbWFpbCI6InZpa2FzLmFnYXJ3YWwrcHNoYWhfbWFuYWdlckB0b3Bjb2Rlci5jb20iLCJlbWFpbF92ZXJpZmllZCI6dHJ1ZSwiaXNzIjoiaHR0cHM6Ly9hdXRoLnRvcGNvZGVyLWRldi5jb20vIiwic3ViIjoiYXV0aDB8NDAxNTI4NTYiLCJhdWQiOiJCWFdYVVduaWxWVVBkTjAxdDJTZTI5VHcyWllOR1p2SCIsImlhdCI6MTYwMzU0MzMzOCwiZXhwIjozMzE2MDQ1MjczOCwibm9uY2UiOiJSMUEyY3pZdVZUWm1ialpIUkc5MlZsOURTVUo2VWxsdlFYYzNSSGg1UzNaV2RXWkRjRE5YTUVaMVh3PT0ifQ.HbAisH30DLcbFNQeIifSzk1yhDmlGHNpPi9LSZbAowo' +const currentUser = { + userId: '00000000-0000-0000-0000-000000000000', + isMachine: true } - -const jobRequestBody = { - projectId: 21, - externalId: '1212', - description: 'Dummy Description', - startDate: '2020-09-27T04:17:23.131Z', - endDate: '2020-09-27T04:17:23.131Z', - numPositions: 13, - resourceType: 'Dummy Resource Type', - rateType: 'hourly', - skills: [ - '56fdc405-eccc-4189-9e83-c78abf844f50', - 'f91ae184-aba2-4485-a8cb-9336988c05ab', - 'edfc7b4f-636f-44bd-96fc-949ffc58e38b', - '4ca63bb6-f515-4ab0-a6bc-c2d8531e084f', - 'ee03c041-d53b-4c08-b7d9-80d7461da3e4' - ] +const UserTCConnCopilot = { + userId: '4709473d-f060-4102-87f8-4d51ff0b34c1', + handle: 'TCConnCopilot' } - -const jobResponseBody = { - dataValues: { - id: '36762910-4efa-4db4-9b2a-c9ab54c232ed', +const resourceBooking5Week = { + request: { projectId: 21, - externalId: '1212', - description: 'Dummy Description', - startDate: '2020-09-27T04:17:23.131Z', - endDate: '2020-09-27T04:17:23.131Z', - numPositions: 13, - resourceType: 'Dummy Resource Type', - rateType: 'hourly', - skills: [ - '56fdc405-eccc-4189-9e83-c78abf844f50', - 'f91ae184-aba2-4485-a8cb-9336988c05ab', - 'edfc7b4f-636f-44bd-96fc-949ffc58e38b', - '4ca63bb6-f515-4ab0-a6bc-c2d8531e084f', - 'ee03c041-d53b-4c08-b7d9-80d7461da3e4' - ], - status: 'sourcing', - createdAt: '2020-10-08T12:58:28.321Z', - createdBy: 'pshah_manager', - candidates: [ - { - id: '5d09b0fb-5164-4b8c-9d04-525e840741e9', - jobId: '36762910-4efa-4db4-9b2a-c9ab54c232ed', - userId: 'a55fe1bc-1754-45fa-9adc-cf3d6d7c377a', - status: 'open', - createdAt: '2020-10-08T12:59:16.426Z', - createdBy: 'pshah_manager' - } - ] - } -} - -const fullyUpdateJobRequestBody = { - projectId: 21, - externalId: '1212', - description: 'Dummy Description', - startDate: '2020-09-27T04:17:23.131Z', - endDate: '2020-09-27T04:17:23.131Z', - numPositions: 13, - resourceType: 'Dummy Resource Type', - rateType: 'hourly', - skills: [ - '3fa85f64-5717-4562-b3fc-2c963f66afa6', - 'cc41ddc4-cacc-4570-9bdb-1229c12b9784' - ], - status: 'sourcing' -} - -const partiallyUpdateJobRequestBody = { - description: 'Dummy Description', - startDate: '2020-09-27T04:17:23.131Z', - endDate: '2020-09-27T04:17:23.131Z', - numPositions: 13, - resourceType: 'Dummy Resource Type', - rateType: 'hourly', - skills: [ - '3fa85f64-5717-4562-b3fc-2c963f66afa6' - ], - status: 'sourcing' -} - -const jobCandidateRequestBody = { - jobId: jobResponseBody.dataValues.id, - userId: 'a55fe1bc-1754-45fa-9adc-cf3d6d7c377a' -} - -const jobCandidateResponseBody = { - dataValues: { - id: '6e69b20f-144e-4edd-b68e-bd21f37f4b3e', - jobId: '6093e58c-683d-4022-8482-5515e8345016', userId: 'a55fe1bc-1754-45fa-9adc-cf3d6d7c377a', - createdAt: '2020-10-09T00:51:38.663Z', - createdBy: 'pshah_manager', - status: 'open' - } -} - -const fullyUpdateJobCandidateRequestBody = { - jobId: jobResponseBody.dataValues.id, - userId: 'a55fe1bc-1754-45fa-9adc-cf3d6d7c377a', - status: 'selected' -} - -const partiallyUpdateJobCandidateRequestBody = { - status: 'shortlist' -} - -const resourceBookingRequestBody = { - projectId: 21, - userId: 'a55fe1bc-1754-45fa-9adc-cf3d6d7c377a', - jobId: jobResponseBody.dataValues.id, - startDate: '2020-09-27T04:17:23.131Z', - endDate: '2020-09-27T04:17:23.131Z', - memberRate: 13.23, - customerRate: 13, - rateType: 'hourly' -} - -const resourceBookingResponseBody = { - dataValues: { - id: '520bb632-a02a-415e-9857-93b2ecbf7d60', - projectId: 21, - userId: 'a55fe1bc-1754-45fa-9adc-cf3d6d7c377a', - jobId: '6093e58c-683d-4022-8482-5515e8345016', + jobId: '36762910-4efa-4db4-9b2a-c9ab54c232ed', startDate: '2020-09-27T04:17:23.131Z', - endDate: '2020-09-27T04:17:23.131Z', + endDate: '2020-10-27T04:17:23.131Z', memberRate: 13.23, customerRate: 13, - rateType: 'hourly', - createdAt: '2020-10-09T04:24:01.048Z', - createdBy: 'pshah_manager', - status: 'sourcing' - } -} - -const fullyUpdateResourceBookingRequestBody = { - projectId: 21, - userId: 'a55fe1bc-1754-45fa-9adc-cf3d6d7c377a', - jobId: resourceBookingResponseBody.dataValues.jobId, - startDate: '2020-09-27T04:17:23.131Z', - endDate: '2020-09-27T04:17:23.131Z', - memberRate: 13.23, - customerRate: 13, - rateType: 'hourly', - status: 'assigned' -} - -const partiallyUpdateResourceBookingRequestBody = { - status: 'assigned', - startDate: '2020-09-27T04:17:23.131Z', - endDate: '2020-09-27T04:17:23.131Z', - memberRate: 13.23, - customerRate: 13, - rateType: 'hourly' -} - -const unexpected = () => { throw new Error('should not reach here') } - -const projectRequestBody = [ - { id: 9050, name: 'sample' }, - { id: 9056, name: 'Invitation Test Max' }, - { id: 9063, name: 'Project001{codejam}' }, - { id: 9072, name: 'Project Name Edited' }, - { id: 9080, name: 'sdfdf' }, - { id: 9081, name: 'Test' }, - { id: 9091, name: 'Test 1 Max' }, - { id: 9096, name: 'test 1' }, - { id: 9097, name: 'test 2' }, - { id: 9099, name: 'Test' }, - { id: 9101, name: 'testin vikasverma' }, - { id: 9102, name: 'Test' }, - { id: 9132, name: 'Copilot Invite Test Max' }, - { id: 9133, name: 'Test' }, - { id: 9138, name: 'Update node versions 5 {codejam}' }, - { id: 9153, name: 'y' }, - { id: 9155, name: 'error' }, - { id: 9157, name: '3950-vikasverma' }, - { id: 9175, name: 'project' }, - { id: 9176, name: 'Testing 4-24-20 at 4-20' } -] - -const userRequestBody = [ - { - id: '1b88e433-828b-4e0d-9fb5-ef75b9dcca6e', - handle: 'PE335869', - firstName: ' Peddaram', - lastName: ' Varalakshmi' - }, - { - id: '10803918-ded0-4906-9442-65dc8819de91', - handle: 'Gayathri_1994', - firstName: 'Gayathri', - lastName: 'Sekar' - }, - { - id: '5bd69a82-c2cb-476f-9462-0883d3b28b90', - handle: 'Sandrine_Kuvalis98', - firstName: 'Mekhi', - lastName: 'Tremblay' + rateType: 'hourly' }, - { - id: '460bddcd-3580-4f2a-bfe8-5ba6d8f6f6af', - handle: 'Lourdes0', - firstName: 'Larissa', - lastName: 'Sporer' - }, - { - id: '4f2dc463-e24b-4b4a-8cde-c0122fbfb8ac', - handle: 'Demond39', - firstName: 'Domenic', - lastName: 'Casper' - }, - { - id: '39203872-707a-41b8-a587-18cab2557632', - handle: 'testkeychng204', - firstName: 'Testing', - lastName: 'Mithun' - }, - { - id: 'b074236c-bb33-449f-9320-72437a064c38', - handle: 'MA40018690', - firstName: 'Mangasamudram', - lastName: 'Teja' - }, - { - id: 'cdaeb417-e400-4df1-b484-f99ae10b4800', - handle: 'Leilani_Fahey35', - firstName: 'Godfrey', - lastName: 'Morar' - }, - { - id: 'ecec4ad8-3a1d-4646-8641-25054e8f2d33', - handle: 'Bernadine17', - firstName: 'Elmore', - lastName: 'Sanford' - }, - { - id: '28df7acf-d7b1-467c-8ee5-594c7bace8dc', - handle: 'Sylvan_Gorczany', - firstName: 'Samara', - lastName: 'Schultz' - }, - { - id: '6910d2f4-a50a-4494-8f46-6de1f3d032c2', - handle: 'Aditya65', - firstName: 'Clemens', - lastName: 'Rodriguez' - }, - { - id: '9bf08a13-29b6-4ef9-a2b6-d967c1c50fb4', - handle: 'Abirami_S', - firstName: 'Abirami', - lastName: 'SenthilNathan' + response: { + dataValues: { + id: '520bb632-a02a-415e-9857-93b2ecbf7d60', + projectId: 21, + userId: 'a55fe1bc-1754-45fa-9adc-cf3d6d7c377a', + jobId: '6093e58c-683d-4022-8482-5515e8345016', + startDate: '2020-09-27T04:17:23.131Z', + endDate: '2020-10-27T04:17:23.131Z', + memberRate: 13.23, + customerRate: 13, + rateType: 'hourly', + createdAt: '2020-10-09T04:24:01.048Z', + createdBy: '57646ff9-1cd3-4d3c-88ba-eb09a395366c', + status: 'sourcing' + } }, - { - id: '25f7b0e8-10a1-4bbc-b2f9-dacb1c72f1e9', - handle: 'Gaurav..Kumar', - firstName: 'Gaurav', - lastName: 'Kumar' + workPeriodRequests: [{ + resourceBookingId: '520bb632-a02a-415e-9857-93b2ecbf7d60', + startDate: '2020-09-27', + endDate: '2020-10-03', + daysWorked: 5, + paymentStatus: 'pending' }, { - id: '6fa6d708-68a6-47be-9591-4b5100921b3a', - handle: 'Kian.DuBuque', - firstName: 'Myles', - lastName: 'Connelly' + resourceBookingId: '520bb632-a02a-415e-9857-93b2ecbf7d60', + startDate: '2020-10-04', + endDate: '2020-10-10', + daysWorked: 5, + paymentStatus: 'pending' }, { - id: '8edca7c4-0e71-4688-952a-42227f73ca32', - handle: 'BinoyVipin', - firstName: 'Binoy', - lastName: 'V' + resourceBookingId: '520bb632-a02a-415e-9857-93b2ecbf7d60', + startDate: '2020-10-11', + endDate: '2020-10-17', + daysWorked: 5, + paymentStatus: 'pending' }, { - id: '247aaea8-f7e0-4ac8-b89e-4d78b76226b0', - handle: 'saikrupa87', - firstName: 'Miriyala', - lastName: 'Saikrupa reddy' + resourceBookingId: '520bb632-a02a-415e-9857-93b2ecbf7d60', + startDate: '2020-10-18', + endDate: '2020-10-24', + daysWorked: 5, + paymentStatus: 'pending' }, { - id: 'cc7a694c-44a0-412b-9d1d-f98f7fe26a21', - handle: 'SriV_1672', - firstName: 'Srinivas', - lastName: 'Merugu' + resourceBookingId: '520bb632-a02a-415e-9857-93b2ecbf7d60', + startDate: '2020-10-25', + endDate: '2020-10-31', + daysWorked: 2, + paymentStatus: 'pending' + }] +} +resourceBooking5Week.response.toJSON = function () { + return resourceBooking5Week.response.dataValues +} +const resourceBooking1Week = { + request: { + projectId: 21, + userId: 'a55fe1bc-1754-45fa-9adc-cf3d6d7c377a', + jobId: '36762910-4efa-4db4-9b2a-c9ab54c232ed', + startDate: '2020-11-20T04:17:23.131Z', + endDate: '2020-11-21T04:17:23.131Z', + memberRate: 13.23, + customerRate: 13, + rateType: 'hourly' }, - { - id: '07744775-eff1-443d-b56b-9d09ed02e599', - handle: 'Aachal', - firstName: 'Aachal ', - lastName: 'Jain' + response: { + dataValues: { + id: '520bb632-a02a-415e-9857-93b2ecbf7d60', + projectId: 21, + userId: 'a55fe1bc-1754-45fa-9adc-cf3d6d7c377a', + jobId: '6093e58c-683d-4022-8482-5515e8345016', + startDate: '2020-11-20T04:17:23.131Z', + endDate: '2020-11-21T04:17:23.131Z', + memberRate: 13.23, + customerRate: 13, + rateType: 'hourly', + createdAt: '2020-10-09T04:24:01.048Z', + createdBy: '57646ff9-1cd3-4d3c-88ba-eb09a395366c', + status: 'sourcing' + } }, - { - id: '0668fe37-b9cf-481b-8769-c3615833f80a', - handle: 'satadipa', - firstName: 'Satadipa', - lastName: 'Datta' + workPeriodRequests: [{ + resourceBookingId: '520bb632-a02a-415e-9857-93b2ecbf7d60', + startDate: '2020-11-15', + endDate: '2020-11-21', + daysWorked: 2, + paymentStatus: 'pending' + }], + workPeriodResponse: [{ + id: '10faf505-d0e3-4d13-a817-7f1319625e91', + resourceBookingId: '520bb632-a02a-415e-9857-93b2ecbf7d60', + userHandle: 'pshah_manager', + projectId: 21, + startDate: '2020-11-15', + endDate: '2020-11-21', + daysWorked: 2, + memberRate: null, + customerRate: null, + paymentStatus: 'pending', + createdBy: '00000000-0000-0000-0000-000000000000', + updatedBy: null, + createdAt: '2021-04-10T22:25:08.289Z', + updatedAt: '2021-04-10T22:25:08.289Z' + }], + updateRequest: { + startDate: '2020-11-18T04:17:23.131Z' }, - { - id: '844fad5d-f19e-444b-be2e-ba9c36d34265', - handle: 'BA249730', - firstName: 'Balamurali', - lastName: 'B' - } -] - -const memberRequestBody = [ - { - userId: 305384, - handleLower: 'mess', - photoURL: 'https://topcoder-dev-media.s3.us-east-1.amazonaws.com/member/profile/mess-1601487458118.jpeg' + updateResponse: { + dataValues: { + id: '520bb632-a02a-415e-9857-93b2ecbf7d60', + projectId: 21, + userId: 'a55fe1bc-1754-45fa-9adc-cf3d6d7c377a', + jobId: '6093e58c-683d-4022-8482-5515e8345016', + startDate: new Date('2020-11-18T04:17:23.131Z'), + endDate: '2020-11-21T04:17:23.131Z', + memberRate: 13.23, + customerRate: 13, + rateType: 'hourly', + createdAt: '2020-10-09T04:24:01.048Z', + createdBy: '57646ff9-1cd3-4d3c-88ba-eb09a395366c', + updatedBy: '00000000-0000-0000-0000-000000000000', + status: 'sourcing' + } }, - { - userId: 88773829, - handleLower: 'pe335869' + workPeriodUpdateRequests: [{ + daysWorked: 4 + }] +} +resourceBooking1Week.response.toJSON = function () { + return resourceBooking1Week.response.dataValues +} +resourceBooking1Week.updateResponse.toJSON = function () { + return resourceBooking1Week.updateResponse.dataValues +} +resourceBooking1Week.response.update = function () { + return resourceBooking1Week.updateResponse +} +const resourceBookingUpdate = { + response: { + dataValues: { + id: '520bb632-a02a-415e-9857-93b2ecbf7d60', + projectId: 21, + userId: 'a55fe1bc-1754-45fa-9adc-cf3d6d7c377a', + jobId: '6093e58c-683d-4022-8482-5515e8345016', + startDate: '2020-08-20T04:17:23.131Z', + endDate: '2020-09-10T04:17:23.131Z', + memberRate: 13.23, + customerRate: 13, + rateType: 'hourly', + createdAt: '2020-10-09T04:24:01.048Z', + createdBy: '57646ff9-1cd3-4d3c-88ba-eb09a395366c', + status: 'sourcing' + } }, - { - userId: 8547899, - handleLower: 'tonyj', - photoURL: 'https://topcoder-dev-media.s3.amazonaws.com/member/profile/TonyJ-1604301092491.jpeg' + workPeriodResponse: [{ + id: '10faf505-d0e3-4d13-a817-7f1319625e91', + resourceBookingId: '520bb632-a02a-415e-9857-93b2ecbf7d60', + userHandle: 'pshah_manager', + projectId: 21, + startDate: '2020-08-16', + endDate: '2020-08-22', + daysWorked: 2, + memberRate: null, + customerRate: null, + paymentStatus: 'pending', + createdBy: '00000000-0000-0000-0000-000000000000', + updatedBy: null, + createdAt: '2021-04-10T22:25:08.289Z', + updatedAt: '2021-04-10T22:25:08.289Z' + }, { + id: 'b18398fe-09d0-4671-95b9-a4f56e6c6879', + resourceBookingId: '520bb632-a02a-415e-9857-93b2ecbf7d60', + userHandle: 'pshah_manager', + projectId: 21, + startDate: '2020-08-23', + endDate: '2020-08-29', + daysWorked: 5, + memberRate: null, + customerRate: null, + paymentStatus: 'pending', + createdBy: '00000000-0000-0000-0000-000000000000', + updatedBy: null, + createdAt: '2021-04-10T22:25:08.289Z', + updatedAt: '2021-04-10T22:25:08.289Z' + }, { + id: 'de811f42-cae7-4cb7-8893-d1e1f83b998f', + resourceBookingId: '520bb632-a02a-415e-9857-93b2ecbf7d60', + userHandle: 'pshah_manager', + projectId: 21, + startDate: '2020-08-30', + endDate: '2020-09-05', + daysWorked: 5, + memberRate: null, + customerRate: null, + paymentStatus: 'pending', + createdBy: '00000000-0000-0000-0000-000000000000', + updatedBy: null, + createdAt: '2021-04-10T22:25:08.289Z', + updatedAt: '2021-04-10T22:25:08.289Z' + }, { + id: '171e7f32-36fd-4969-9a99-036ced807d53', + resourceBookingId: '520bb632-a02a-415e-9857-93b2ecbf7d60', + userHandle: 'pshah_manager', + projectId: 21, + startDate: '2020-09-06', + endDate: '2020-09-12', + daysWorked: 4, + memberRate: null, + customerRate: null, + paymentStatus: 'pending', + createdBy: '00000000-0000-0000-0000-000000000000', + updatedBy: null, + createdAt: '2021-04-10T22:25:08.289Z', + updatedAt: '2021-04-10T22:25:08.289Z' + }], + updateRequest: { + endDate: '2020-09-12T04:17:23.131Z' }, - { - userId: 8547893, - handleLower: 'gayathri_1994', - photoURL: 'https://topcoder-dev-media.s3.amazonaws.com/member/profile/TonyJ-1604301092491.jpeg' - } -] - -const skillsRequestBody = [ - { id: 'cb01fd31-e8d2-4e34-8bf3-b149705de3e1', name: 'ACI Concrete Strength Testing Technician' }, - { id: '59ee7b42-f3f3-48c9-bdca-e8396b241793', name: '2D Computer Graphics' }, - { id: '1b585c26-2649-4078-8369-b599fe6a9d75', name: 'ACCP Certified' }, - { id: '8b757998-ff7d-4b3a-9fee-a49d3e41da03', name: '3D Projection' }, - { id: 'bcfc8806-cae6-47ff-b0c9-f604acfc8c99', name: '35 Mm Films' }, - { id: 'db4358f3-c9a3-4afd-94a4-2d352d6bfa60', name: 'Nintex Workflow for SharePoint' }, - { id: '077533be-8029-4585-8b8e-9efc2dc43f53', name: 'CA Service Virtualization' }, - { id: 'f682838c-a9a7-4b47-8c2e-45d5132c04d7', name: 'SOAP UI Testing' }, - { id: '13dda8dc-4c34-4751-bbab-aab76d757cbb', name: 'JavaBean' }, - { id: '99b930b5-1b91-4df1-8b17-d9307107bb51', name: 'Excel' }, - { id: '513ba597-5ad1-4177-8556-35583e0cc6ac', name: 'Microsoft Dynamics 365 Portals' }, - { id: 'ee4c50c1-c8c3-475e-b6b6-edbd136a19d6', name: 'SFDC Lightening Components' }, - { id: '1c67b60d-32a3-4dcd-8bc4-947bc476fcd1', name: 'Performance Point' }, - { id: '70834003-3eba-452c-9bc4-a6d9d637a10e', name: 'AI/ML App Testing' }, - { id: '89139c80-d0a2-47c2-aa16-14589d5afd10', name: 'User Testing' }, - { id: '866ee344-5328-4c1d-b9ae-1c003f8fef16', name: 'DB2 Testing' }, - { id: '9f2d9127-6a2e-4506-ad76-c4ab63577b09', name: 'IndexedDB' }, - { id: 'c854ab55-5922-4be1-8ecc-b3bc1f8629af', name: 'InVision' }, - { id: '9515e7ee-83b6-49d1-ba5c-6c59c5a8ef1b', name: 'List' }, - { id: '57ef43c2-4227-4ea1-bc5a-287321f3f8b2', name: 'Microsoft Dynamics AX 2012 - Retail' } -] - -const userSkillsRequestBody = [ - { id: '5d313a7b-795b-42a2-9e7e-dc5e81c2f2b5', name: 'Java' }, - { id: 'cb01fd31-e8d2-4e34-8bf3-b149705de3e1', name: 'ACI Concrete Strength Testing Technician' } -] - -const resourceBookingsRequestBody = [ - { - projectId: 9063, - userId: '4f2dc463-e24b-4b4a-8cde-c0122fbfb8ac', - jobId: '1d9e8c1a-e653-4d31-a799-2685e41da216', - startDate: '2020-09-28T04:17:23.131Z', - endDate: '2020-12-30T04:17:23.131Z', - memberRate: 13.23, - customerRate: 11.11, - rateType: 'hourly', - status: 'assigned', - createdAt: '2020-11-11T04:17:23.131Z', - createdBy: 'a55fe1bc-1754-45fa-9adc-cf3d6d7c377a', - id: '3d9e8c1a-e653-4d31-a799-2685e41da216' + updateResponse: { + dataValues: { + id: '520bb632-a02a-415e-9857-93b2ecbf7d60', + projectId: 21, + userId: 'a55fe1bc-1754-45fa-9adc-cf3d6d7c377a', + jobId: '6093e58c-683d-4022-8482-5515e8345016', + startDate: '2020-08-20T04:17:23.131Z', + endDate: new Date('2020-09-12T04:17:23.131Z'), + memberRate: 13.23, + customerRate: 13, + rateType: 'hourly', + createdAt: '2020-10-09T04:24:01.048Z', + createdBy: '57646ff9-1cd3-4d3c-88ba-eb09a395366c', + updatedBy: '00000000-0000-0000-0000-000000000000', + status: 'sourcing' + } }, - { - projectId: 9056, - userId: '460bddcd-3580-4f2a-bfe8-5ba6d8f6f6af', - jobId: '1d9e8c1a-e653-4d31-a799-2685e41da215', - startDate: '2020-09-28T04:17:23.131Z', - endDate: '2020-12-30T04:17:23.131Z', - memberRate: 13.23, - customerRate: 156.7, - rateType: 'hourly', - status: 'assigned', - createdAt: '2020-11-11T04:17:23.131Z', - createdBy: 'a55fe1bc-1754-45fa-9adc-cf3d6d7c377a', - id: '3d9e8c1a-e653-4d31-a799-2685e41da215' + workPeriodUpdateRequests: [{ + daysWorked: 5 + }], + response2: { + dataValues: { + id: '520bb632-a02a-415e-9857-93b2ecbf7d60', + projectId: 21, + userId: 'a55fe1bc-1754-45fa-9adc-cf3d6d7c377a', + jobId: '6093e58c-683d-4022-8482-5515e8345016', + startDate: '2020-08-20T04:17:23.131Z', + endDate: '2020-09-10T04:17:23.131Z', + memberRate: 13.23, + customerRate: 13, + rateType: 'hourly', + createdAt: '2020-10-09T04:24:01.048Z', + createdBy: '57646ff9-1cd3-4d3c-88ba-eb09a395366c', + status: 'sourcing' + } }, - { - projectId: 9050, - userId: '5bd69a82-c2cb-476f-9462-0883d3b28b90', - jobId: '1d9e8c1a-e653-4d31-a799-2685e41da214', - startDate: '2020-09-28T04:17:23.131Z', - endDate: '2020-12-30T04:17:23.131Z', - memberRate: 13.23, - customerRate: 16.7, - rateType: 'hourly', - status: 'assigned', - createdAt: '2020-11-11T04:17:23.131Z', - createdBy: 'a55fe1bc-1754-45fa-9adc-cf3d6d7c377a', - id: '3d9e8c1a-e653-4d31-a799-2685e41da214' + updateRequest2: { + endDate: '2020-09-15T04:17:23.131Z' }, - { - projectId: 9050, - userId: '10803918-ded0-4906-9442-65dc8819de91', - jobId: '1d9e8c1a-e653-4d31-a799-2685e41da213', - startDate: '2020-09-22T04:17:23.131Z', - endDate: '2020-10-27T04:17:23.131Z', - memberRate: 13.23, - customerRate: 14.5, - rateType: 'hourly', - status: 'assigned', - createdAt: '2020-11-11T04:17:23.131Z', - createdBy: 'a55fe1bc-1754-45fa-9adc-cf3d6d7c377a', - id: '3d9e8c1a-e653-4d31-a799-2685e41da213' + updateResponse2: { + dataValues: { + id: '520bb632-a02a-415e-9857-93b2ecbf7d60', + projectId: 21, + userId: 'a55fe1bc-1754-45fa-9adc-cf3d6d7c377a', + jobId: '6093e58c-683d-4022-8482-5515e8345016', + startDate: '2020-08-20T04:17:23.131Z', + endDate: new Date('2020-09-15T04:17:23.131Z'), + memberRate: 13.23, + customerRate: 13, + rateType: 'hourly', + createdAt: '2020-10-09T04:24:01.048Z', + createdBy: '57646ff9-1cd3-4d3c-88ba-eb09a395366c', + updatedBy: '00000000-0000-0000-0000-000000000000', + status: 'sourcing' + } }, - { - projectId: 9050, - userId: '1b88e433-828b-4e0d-9fb5-ef75b9dcca6e', - jobId: '1d9e8c1a-e653-4d31-a799-2685e41da212', - startDate: '2020-09-27T04:17:23.131Z', - endDate: '2021-11-11T04:17:23.131Z', - memberRate: 13.23, - customerRate: 13, - rateType: 'hourly', - status: 'assigned', - createdAt: '2020-11-11T04:17:23.131Z', - createdBy: 'a55fe1bc-1754-45fa-9adc-cf3d6d7c377a', - id: '3d9e8c1a-e653-4d31-a799-2685e41da212' - } -] - -const jobsRequestBody = [ - { - projectId: 9063, - externalId: '1212', - description: 'Dummy Description', - startDate: '2020-09-27T04:17:23.131Z', - endDate: '2020-10-09T04:17:23.131Z', - numPositions: 10, - resourceType: 'Dummy Resource Type', - rateType: 'hourly', - skills: [ - '1b585c26-2649-4078-8369-b599fe6a9d75', - 'bcfc8806-cae6-47ff-b0c9-f604acfc8c99' - ], - status: 'sourcing', - createdAt: '2020-11-11T04:17:23.131Z', - createdBy: 'a55fe1bc-1754-45fa-9adc-cf3d6d7c377a', - id: '1d9e8c1a-e653-4d31-a799-2685e41da215' + workPeriodUpdateRequests2: [{ + daysWorked: 5 + }, { + resourceBookingId: '520bb632-a02a-415e-9857-93b2ecbf7d60', + startDate: '2020-09-13', + endDate: '2020-09-19', + daysWorked: 2, + paymentStatus: 'pending' + }], + response3: { + dataValues: { + id: '520bb632-a02a-415e-9857-93b2ecbf7d60', + projectId: 21, + userId: 'a55fe1bc-1754-45fa-9adc-cf3d6d7c377a', + jobId: '6093e58c-683d-4022-8482-5515e8345016', + startDate: '2020-08-20T04:17:23.131Z', + endDate: '2020-09-10T04:17:23.131Z', + memberRate: 13.23, + customerRate: 13, + rateType: 'hourly', + createdAt: '2020-10-09T04:24:01.048Z', + createdBy: '57646ff9-1cd3-4d3c-88ba-eb09a395366c', + status: 'sourcing' + } }, - { - projectId: 9063, - externalId: '1212', - description: 'Dummy Description', - startDate: '2020-09-17T04:17:23.131Z', - endDate: '2020-10-19T04:17:23.131Z', - numPositions: 20, - resourceType: 'Dummy Resource Type', - rateType: 'hourly', - skills: [ - '8b757998-ff7d-4b3a-9fee-a49d3e41da03', - 'bcfc8806-cae6-47ff-b0c9-f604acfc8c99' - ], - status: 'sourcing', - createdAt: '2020-11-11T04:17:23.131Z', - createdBy: 'a55fe1bc-1754-45fa-9adc-cf3d6d7c377a', - id: '1d9e8c1a-e653-4d31-a799-2685e41da214', - candidates: [ - { - jobId: '1d9e8c1a-e653-4d31-a799-2685e41da214', - userId: 'a55fe1bc-1754-45fa-9adc-cf3d6d7c377a', - status: 'open', - createdAt: '2020-11-11T04:17:23.131Z', - createdBy: 'a55fe1bc-1754-45fa-9adc-cf3d6d7c377a', - id: '2d9e8c1a-e653-4d31-a799-2685e41da214' - } - ] + updateRequest3: { + startDate: '2020-08-25T04:17:23.131Z' }, - { - projectId: 9056, - externalId: '1212', - description: 'Dummy Description', - startDate: '2020-09-29T04:17:23.131Z', - endDate: '2020-10-17T04:17:23.131Z', - numPositions: 11, - resourceType: 'Dummy Resource Type', - rateType: 'hourly', - skills: [ - 'cb01fd31-e8d2-4e34-8bf3-b149705de3e1', - '59ee7b42-f3f3-48c9-bdca-e8396b241793', - 'bcfc8806-cae6-47ff-b0c9-f604acfc8c99' - ], - status: 'sourcing', - createdAt: '2020-11-11T04:17:23.131Z', - createdBy: 'a55fe1bc-1754-45fa-9adc-cf3d6d7c377a', - id: '1d9e8c1a-e653-4d31-a799-2685e41da213', - candidates: [ - { - jobId: '1d9e8c1a-e653-4d31-a799-2685e41da213', - userId: 'a55fe1bc-1754-45fa-9adc-cf3d6d7c377a', - status: 'open', - createdAt: '2020-11-11T04:17:23.131Z', - createdBy: 'a55fe1bc-1754-45fa-9adc-cf3d6d7c377a', - id: '2d9e8c1a-e653-4d31-a799-2685e41da213' - } - ] + updateResponse3: { + dataValues: { + id: '520bb632-a02a-415e-9857-93b2ecbf7d60', + projectId: 21, + userId: 'a55fe1bc-1754-45fa-9adc-cf3d6d7c377a', + jobId: '6093e58c-683d-4022-8482-5515e8345016', + startDate: new Date('2020-08-25T04:17:23.131Z'), + endDate: '2020-09-10T04:17:23.131Z', + memberRate: 13.23, + customerRate: 13, + rateType: 'hourly', + createdAt: '2020-10-09T04:24:01.048Z', + createdBy: '57646ff9-1cd3-4d3c-88ba-eb09a395366c', + updatedBy: '00000000-0000-0000-0000-000000000000', + status: 'sourcing' + } }, - { - projectId: 9050, - externalId: '1212', - description: 'Dummy Description', - startDate: '2020-09-27T04:17:23.131Z', - endDate: '2020-10-17T04:17:23.131Z', - numPositions: 13, - resourceType: 'Dummy Resource Type', - rateType: 'hourly', - skills: [ - 'cb01fd31-e8d2-4e34-8bf3-b149705de3e1', - '59ee7b42-f3f3-48c9-bdca-e8396b241793', - '1b585c26-2649-4078-8369-b599fe6a9d75', - '8b757998-ff7d-4b3a-9fee-a49d3e41da03', - 'bcfc8806-cae6-47ff-b0c9-f604acfc8c99' - ], - status: 'sourcing', - createdAt: '2020-11-11T04:17:23.131Z', - createdBy: 'a55fe1bc-1754-45fa-9adc-cf3d6d7c377a', - id: '1d9e8c1a-e653-4d31-a799-2685e41da212', - candidates: [ - { - jobId: '1d9e8c1a-e653-4d31-a799-2685e41da212', - userId: '5bd69a82-c2cb-476f-9462-0883d3b28b90', - status: 'open', - createdAt: '2020-11-11T04:17:23.131Z', - createdBy: 'a55fe1bc-1754-45fa-9adc-cf3d6d7c377a', - id: '2d9e8c1a-e653-4d31-a799-2685e41da212' - } - ] - } -] - -const taasTeamItem0ResponseBody = { - id: 9050, - name: 'sample', - weeklyCost: 29.7, - resources: [ - { - id: '1b88e433-828b-4e0d-9fb5-ef75b9dcca6e', - handle: 'PE335869', - firstName: ' Peddaram', - lastName: ' Varalakshmi' + workPeriodUpdateRequests3: [ + 'b18398fe-09d0-4671-95b9-a4f56e6c6879', { + daysWorked: 4 }, - { - id: '10803918-ded0-4906-9442-65dc8819de91', - handle: 'Gayathri_1994', - firstName: 'Gayathri', - lastName: 'Sekar', - photo_url: 'https://topcoder-dev-media.s3.amazonaws.com/member/profile/TonyJ-1604301092491.jpeg' - }, - { - id: '5bd69a82-c2cb-476f-9462-0883d3b28b90', - handle: 'Sandrine_Kuvalis98', - firstName: 'Mekhi', - lastName: 'Tremblay' - } + '10faf505-d0e3-4d13-a817-7f1319625e91', + '10faf505-d0e3-4d13-a817-7f1319625e91', + 'b18398fe-09d0-4671-95b9-a4f56e6c6879', + 'de811f42-cae7-4cb7-8893-d1e1f83b998f', + '171e7f32-36fd-4969-9a99-036ced807d53' ], - startDate: new Date('2020-09-22T04:17:23.131Z'), - endDate: new Date('2021-11-11T04:17:23.131Z'), - totalPositions: 13 -} - -const taasTeam9050ResponseBody = { - id: 9050, - name: 'sample', - weeklyCost: 29.7, - resources: [ - { - id: '1b88e433-828b-4e0d-9fb5-ef75b9dcca6e', - handle: 'PE335869', - firstName: ' Peddaram', - lastName: ' Varalakshmi', + response4: { + dataValues: { + id: '520bb632-a02a-415e-9857-93b2ecbf7d60', + projectId: 21, + userId: 'a55fe1bc-1754-45fa-9adc-cf3d6d7c377a', + jobId: '6093e58c-683d-4022-8482-5515e8345016', + startDate: '2020-08-20T04:17:23.131Z', + endDate: '2020-09-10T04:17:23.131Z', + memberRate: 13.23, customerRate: 13, - job: { - id: '1d9e8c1a-e653-4d31-a799-2685e41da212', - name: 'Dummy Description' - }, - skills: [ - { - id: '5d313a7b-795b-42a2-9e7e-dc5e81c2f2b5', - name: 'Java' - }, - { - id: 'cb01fd31-e8d2-4e34-8bf3-b149705de3e1', - name: 'ACI Concrete Strength Testing Technician' - } - - ], - skillMatched: 1 - }, - { - id: '10803918-ded0-4906-9442-65dc8819de91', - handle: 'Gayathri_1994', - firstName: 'Gayathri', - lastName: 'Sekar', - customerRate: 14.5, - photo_url: 'https://topcoder-dev-media.s3.amazonaws.com/member/profile/TonyJ-1604301092491.jpeg', - job: { - id: '1d9e8c1a-e653-4d31-a799-2685e41da213', - name: 'Dummy Description' - }, - skills: [ - { - id: '5d313a7b-795b-42a2-9e7e-dc5e81c2f2b5', - name: 'Java' - }, - { - id: 'cb01fd31-e8d2-4e34-8bf3-b149705de3e1', - name: 'ACI Concrete Strength Testing Technician' - } - ], - skillMatched: 1 - }, - { - id: '5bd69a82-c2cb-476f-9462-0883d3b28b90', - handle: 'Sandrine_Kuvalis98', - firstName: 'Mekhi', - lastName: 'Tremblay', - customerRate: 16.7, - job: { - id: '1d9e8c1a-e653-4d31-a799-2685e41da214', - name: 'Dummy Description' - }, - skills: [ - { - id: '5d313a7b-795b-42a2-9e7e-dc5e81c2f2b5', - name: 'Java' - }, - { - id: 'cb01fd31-e8d2-4e34-8bf3-b149705de3e1', - name: 'ACI Concrete Strength Testing Technician' - } - ], - skillMatched: 1 + rateType: 'hourly', + createdAt: '2020-10-09T04:24:01.048Z', + createdBy: '57646ff9-1cd3-4d3c-88ba-eb09a395366c', + status: 'sourcing' } - ], - startDate: new Date('2020-09-22T04:17:23.131Z'), - endDate: new Date('2021-11-11T04:17:23.131Z'), - jobs: [ - { - id: '1d9e8c1a-e653-4d31-a799-2685e41da212', - description: 'Dummy Description', - startDate: '2020-09-27T04:17:23.131Z', - endDate: '2020-10-17T04:17:23.131Z', - numPositions: 13, + }, + workPeriodResponse4: [{ + id: '10faf505-d0e3-4d13-a817-7f1319625e91', + resourceBookingId: '520bb632-a02a-415e-9857-93b2ecbf7d60', + userHandle: 'pshah_manager', + projectId: 21, + startDate: '2020-08-16', + endDate: '2020-08-22', + daysWorked: 2, + memberRate: null, + customerRate: null, + paymentStatus: 'pending', + createdBy: '00000000-0000-0000-0000-000000000000', + updatedBy: null, + createdAt: '2021-04-10T22:25:08.289Z', + updatedAt: '2021-04-10T22:25:08.289Z' + }, { + id: 'b18398fe-09d0-4671-95b9-a4f56e6c6879', + resourceBookingId: '520bb632-a02a-415e-9857-93b2ecbf7d60', + userHandle: 'pshah_manager', + projectId: 21, + startDate: '2020-08-23', + endDate: '2020-08-29', + daysWorked: 5, + memberRate: null, + customerRate: null, + paymentStatus: 'completed', + createdBy: '00000000-0000-0000-0000-000000000000', + updatedBy: null, + createdAt: '2021-04-10T22:25:08.289Z', + updatedAt: '2021-04-10T22:25:08.289Z' + }, { + id: '89f89450-201c-42e3-a868-a87177b82584', + resourceBookingId: '520bb632-a02a-415e-9857-93b2ecbf7d60', + userHandle: 'pshah_manager', + projectId: 21, + startDate: '2020-08-30', + endDate: '2020-09-05', + daysWorked: 5, + memberRate: null, + customerRate: null, + paymentStatus: 'partially-completed', + createdBy: '00000000-0000-0000-0000-000000000000', + updatedBy: null, + createdAt: '2021-04-10T22:25:08.289Z', + updatedAt: '2021-04-10T22:25:08.289Z' + }, { + id: '3907e916-efdc-49d3-b0ef-970ccf7d78b0', + resourceBookingId: '520bb632-a02a-415e-9857-93b2ecbf7d60', + userHandle: 'pshah_manager', + projectId: 21, + startDate: '2020-09-06', + endDate: '2020-09-12', + daysWorked: 4, + memberRate: null, + customerRate: null, + paymentStatus: 'pending', + createdBy: '00000000-0000-0000-0000-000000000000', + updatedBy: null, + createdAt: '2021-04-10T22:25:08.289Z', + updatedAt: '2021-04-10T22:25:08.289Z' + }], + updateRequest4: { + startDate: '2020-08-25T04:17:23.131Z', + endDate: '2020-09-05T04:17:23.131Z' + }, + updateResponse4: { + dataValues: { + id: '520bb632-a02a-415e-9857-93b2ecbf7d60', + projectId: 21, + userId: 'a55fe1bc-1754-45fa-9adc-cf3d6d7c377a', + jobId: '6093e58c-683d-4022-8482-5515e8345016', + startDate: new Date('2020-08-25T04:17:23.131Z'), + endDate: new Date('2020-09-05T04:17:23.131Z'), + memberRate: 13.23, + customerRate: 13, rateType: 'hourly', - skills: [ - { - id: 'cb01fd31-e8d2-4e34-8bf3-b149705de3e1', - name: 'ACI Concrete Strength Testing Technician' - }, - { - id: '59ee7b42-f3f3-48c9-bdca-e8396b241793', - name: '2D Computer Graphics' - }, - { - id: '1b585c26-2649-4078-8369-b599fe6a9d75', - name: 'ACCP Certified' - }, - { - id: '8b757998-ff7d-4b3a-9fee-a49d3e41da03', - name: '3D Projection' - }, - { - id: 'bcfc8806-cae6-47ff-b0c9-f604acfc8c99', - name: '35 Mm Films' - } - ], + createdAt: '2020-10-09T04:24:01.048Z', + createdBy: '57646ff9-1cd3-4d3c-88ba-eb09a395366c', + updatedBy: '00000000-0000-0000-0000-000000000000', status: 'sourcing' } - ] + }, + workPeriodUpdateRequests4: [{ + daysWorked: 4 + }, '10faf505-d0e3-4d13-a817-7f1319625e91', '3907e916-efdc-49d3-b0ef-970ccf7d78b0'], + updateRequest5: { + startDate: '2020-08-24T04:17:23.131Z', + endDate: '2020-08-29T04:17:23.131Z' + }, + updateRequest6: { + status: 'cancelled' + } } - -const jobDetailResponseBody = { - id: '1d9e8c1a-e653-4d31-a799-2685e41da212', - description: 'Dummy Description', - candidates: [ - { - id: '5bd69a82-c2cb-476f-9462-0883d3b28b90', - handle: 'Sandrine_Kuvalis98', - firstName: 'Mekhi', - lastName: 'Tremblay', - resumeLink: null, - status: 'open', - skills: [ - { - id: '5d313a7b-795b-42a2-9e7e-dc5e81c2f2b5', - name: 'Java' - }, - { - id: 'cb01fd31-e8d2-4e34-8bf3-b149705de3e1', - name: 'ACI Concrete Strength Testing Technician' - } - ], - job: { - id: '1d9e8c1a-e653-4d31-a799-2685e41da214', - name: 'Dummy Description' - }, - skillMatched: 1, - customerRate: 16.7 - } - ] +resourceBookingUpdate.response.toJSON = function () { + return resourceBookingUpdate.response.dataValues +} +resourceBookingUpdate.updateResponse.toJSON = function () { + return resourceBookingUpdate.updateResponse.dataValues } +resourceBookingUpdate.response.update = function () { + return resourceBookingUpdate.updateResponse +} +resourceBookingUpdate.response2.toJSON = function () { + return resourceBookingUpdate.response2.dataValues +} +resourceBookingUpdate.updateResponse2.toJSON = function () { + return resourceBookingUpdate.updateResponse2.dataValues +} +resourceBookingUpdate.response2.update = function () { + return resourceBookingUpdate.updateResponse2 +} +resourceBookingUpdate.response3.toJSON = function () { + return resourceBookingUpdate.response3.dataValues +} +resourceBookingUpdate.updateResponse3.toJSON = function () { + return resourceBookingUpdate.updateResponse3.dataValues +} +resourceBookingUpdate.response3.update = function () { + return resourceBookingUpdate.updateResponse3 +} +resourceBookingUpdate.response3.destroy = function () { +} +resourceBookingUpdate.response4.toJSON = function () { + return resourceBookingUpdate.response4.dataValues +} +resourceBookingUpdate.updateResponse4.toJSON = function () { + return resourceBookingUpdate.updateResponse4.dataValues +} +resourceBookingUpdate.response4.update = function () { + return resourceBookingUpdate.updateResponse4 +} module.exports = { - bookingManagerUser, - connectUser, - topCoderUser, - jobRequestBody, - jobResponseBody, - fullyUpdateJobRequestBody, - partiallyUpdateJobRequestBody, - jobCandidateRequestBody, - jobCandidateResponseBody, - fullyUpdateJobCandidateRequestBody, - partiallyUpdateJobCandidateRequestBody, - resourceBookingRequestBody, - resourceBookingResponseBody, - fullyUpdateResourceBookingRequestBody, - partiallyUpdateResourceBookingRequestBody, - unexpected, - projectRequestBody, - userRequestBody, - memberRequestBody, - skillsRequestBody, - userSkillsRequestBody, - resourceBookingsRequestBody, - jobsRequestBody, - taasTeamItem0ResponseBody, - taasTeam9050ResponseBody, - jobDetailResponseBody + currentUser, + UserTCConnCopilot, + resourceBooking5Week, + resourceBooking1Week, + resourceBookingUpdate } diff --git a/test/unit/helper.test.js b/test/unit/helper.test.js index 5c4b3141..49d880cd 100644 --- a/test/unit/helper.test.js +++ b/test/unit/helper.test.js @@ -2,10 +2,8 @@ process.env.NODE_ENV = 'test' require('../../src/bootstrap') -const _ = require('lodash') const sinon = require('sinon') const rewire = require('rewire') -const request = require('superagent') const expect = require('chai').expect const helper = rewire('../../src/common/helper') @@ -17,101 +15,6 @@ describe('helper test', () => { sinon.restore() }) - describe('setResHeaders test', () => { - const req = { - protocol: 'http', - baseUrl: 'api/v5', - path: '/jobs', - get: () => { - return 'localhost:3000' - } - } - const res = { - set (key, value) { - this[key] = value - }, - get (key) { - return 'test' - } - } - - const result = { - total: 4, - page: 2, - perPage: 2 - - } - it('setResHeaders test', () => { - const temp = _.cloneDeep(res) - helper.setResHeaders(req, temp, result) - expect(_.omit(temp, ['get', 'set'])).to.eql({ - 'X-Prev-Page': 1, - 'X-Page': 2, - 'X-Per-Page': 2, - 'X-Total': 4, - 'X-Total-Pages': 2, - Link: '; rel="first", ; rel="last", ; rel="prev"', - 'Access-Control-Expose-Headers': 'test, X-Page, X-Per-Page, X-Total, X-Total-Pages, X-Prev-Page, X-Next-Page' - }) - }) - - it('setResHeaders test with totalPages > 0', () => { - const temp1 = _.assign({}, result, { total: 40 }) - const temp2 = _.cloneDeep(res) - helper.setResHeaders(req, temp2, temp1) - expect(_.omit(temp2, ['get', 'set'])).to.eql({ - 'X-Prev-Page': 1, - 'X-Next-Page': 3, - 'X-Page': 2, - 'X-Per-Page': 2, - 'X-Total': 40, - 'X-Total-Pages': 20, - Link: '; rel="first", ; rel="last", ; rel="prev", ; rel="next"', - 'Access-Control-Expose-Headers': 'test, X-Page, X-Per-Page, X-Total, X-Total-Pages, X-Prev-Page, X-Next-Page' - }) - }) - - it('setResHeaders test with page = 1 and res.get returns null', () => { - const temp1 = _.assign({}, result, { total: 40, page: 1 }) - const temp2 = _.assign({}, res, { get (key) { return null } }) - helper.setResHeaders(req, temp2, temp1) - expect(_.omit(temp2, ['get', 'set'])).to.eql({ - 'X-Next-Page': 2, - 'X-Page': 1, - 'X-Per-Page': 2, - 'X-Total': 40, - 'X-Total-Pages': 20, - Link: '; rel="first", ; rel="last", ; rel="next"', - 'Access-Control-Expose-Headers': 'X-Page, X-Per-Page, X-Total, X-Total-Pages, X-Prev-Page, X-Next-Page' - }) - }) - - it('setResHeaders test with total = 0', () => { - const temp1 = _.assign({}, result, { total: 0 }) - const temp2 = _.assign({}, res, { get (key) { return null } }) - helper.setResHeaders(req, temp2, temp1) - expect(_.omit(temp2, ['get', 'set'])).to.eql({ - 'X-Prev-Page': 1, - 'X-Page': 2, - 'X-Per-Page': 2, - 'X-Total': 0, - 'X-Total-Pages': 0, - 'Access-Control-Expose-Headers': 'X-Page, X-Per-Page, X-Total, X-Total-Pages, X-Prev-Page, X-Next-Page' - }) - }) - }) - - describe('clearObject test', () => { - it('clearObject test with null', () => { - expect(helper.clearObject(null)).to.be.undefined - }) - - it('clearObject test with array', () => { - const arr = [{ test: 'ok' }, { test: 'ok' }, { test: 'ok' }] - expect(helper.clearObject(arr)).to.eql(arr) - }) - }) - describe('autoWrapExpress test', () => { it('autoWrapExpress with sync function', () => { const fn = () => { return null } @@ -141,218 +44,4 @@ describe('helper test', () => { expect(res.fn).to.be.a('function') }) }) - - describe('isConnectMember test', () => { - it('isConnectMember return true', async () => { - sinon.stub(request, 'get').callsFake(() => { - return { - set: function () { - return this - } - } - }) - const res = await helper.isConnectMember() - expect(res).to.be.true - }) - - it('isConnectMember return false', async () => { - let i = 0 - sinon.stub(request, 'get').callsFake(() => { - return { - set: function () { - i++ - if (i === 3) { - throw new Error() - } - return this - } - } - }) - const res = await helper.isConnectMember() - expect(res).to.be.false - }) - }) - - describe('getUserId test', () => { - const id = '9966a0cf-c1c9-457b-9a4b-e6d1f4cec88d' - it('getUserId return id', async () => { - let i = 0 - sinon.stub(request, 'get').callsFake(() => { - return { - set: function () { - i++ - if (i === 3) { - return { - body: [{ id }] - } - } - return this - } - } - }) - helper.__set__('m2m', { - getMachineToken: function () { - return 'm2mToken' - } - }) - const res = await helper.getUserId(8547899) - expect(res).to.equal(id) - }) - - it('getUserId catch not found', async () => { - let i = 0 - sinon.stub(request, 'get').callsFake(() => { - return { - set: function () { - i++ - if (i === 3) { - return { - body: [] - } - } - return this - } - } - }) - helper.__set__('m2m', { - getMachineToken: function () { - return 'm2mToken' - } - }) - try { - await helper.getUserId(44532) - } catch (err) { - expect(err.message).to.equal('userId: 44532 "user" not found') - } - }) - }) - - describe('getProjects test', () => { - it('getProjects return entity result', async () => { - let i = 0 - sinon.stub(request, 'get').callsFake(() => { - return { - set: function () { - i++ - if (i === 3) { - return { - body: [{ id: 1001, name: 'name' }] - } - } - return this - } - } - }) - const res = await helper.getProjects('token') - expect(res).to.be.a('array') - }) - }) - - describe('getProjectById test', () => { - it('getProjectById return entity result', async () => { - let i = 0 - sinon.stub(request, 'get').callsFake(() => { - return { - set: function () { - i++ - if (i === 3) { - return { - body: { id: 1001, name: 'name' } - } - } - return this - } - } - }) - - const res = await helper.getProjectById('token', 1001) - expect(res).to.be.a('object') - }) - }) - - describe('getUsers test', () => { - it('getUsers return entity result', async () => { - let i = 0 - sinon.stub(request, 'get').callsFake(() => { - return { - set: function () { - i++ - if (i === 3) { - return { - body: [{ id: '1001', handle: 'handle', firstName: 'Bill', lastName: 'Gate' }] - } - } - return this - } - } - }) - - const res = await helper.getUsers('token') - expect(res).to.be.a('array') - }) - }) - - describe('getMembers test', () => { - it('getMembers return entity result', async () => { - let i = 0 - sinon.stub(request, 'get').callsFake(() => { - return { - set: function () { - i++ - if (i === 3) { - return { - body: { id: '1001', name: 'name' } - } - } - return this - } - } - }) - - const res = await helper.getMembers('token', ['name1', 'name2']) - expect(res).to.be.a('object') - }) - }) - - describe('getSkills test', () => { - it('getSkills return entity result', async () => { - let i = 0 - sinon.stub(request, 'get').callsFake(() => { - return { - set: function () { - i++ - if (i === 3) { - return { - body: [{ id: 1001, name: 'name' }] - } - } - return this - } - } - }) - const res = await helper.getSkills('token') - expect(res).to.be.a('array') - }) - }) - - describe('getUserSkill test', () => { - it('getUserSkill return entity result', async () => { - let i = 0 - sinon.stub(request, 'get').callsFake(() => { - return { - set: function () { - i++ - if (i === 3) { - return { - body: [{ id: 1001, skill: { name: 'name' } }] - } - } - return this - } - } - }) - const res = await helper.getUserSkill('token', '1001') - expect(res).to.be.a('array') - }) - }) })