diff --git a/README.md b/README.md index d9481f21..5e3895c2 100644 --- a/README.md +++ b/README.md @@ -194,7 +194,6 @@ To be able to change and test `taas-es-processor` locally you can follow the nex | `npm run index:jobs ` | Indexes job data from db into ES, if jobId is not given all data is indexed. Use `-- --force` flag to skip confirmation | | `npm run index:job-candidates ` | Indexes job candidate data from db into ES, if jobCandidateId is not given all data is indexed. Use `-- --force` flag to skip confirmation | | `npm run index:resource-bookings ` | Indexes resource bookings data from db into ES, if resourceBookingsId is not given all data is indexed. Use `-- --force` flag to skip confirmation | -| `npm run index:work-periods ` | Indexes work periods data from db into ES, if workPeriodId is not given all data is indexed. Use `-- --force` flag to skip confirmation | | `npm run services:up` | Start services via docker-compose for local development. | | `npm run services:down` | Stop services via docker-compose for local development. | | `npm run services:logs -- -f ` | View logs of some service inside docker-compose. | diff --git a/config/default.js b/config/default.js index f7eddb93..2b5ca7ba 100644 --- a/config/default.js +++ b/config/default.js @@ -76,8 +76,6 @@ module.exports = { ES_INDEX_JOB_CANDIDATE: process.env.ES_INDEX_JOB_CANDIDATE || 'job_candidate', // the resource booking index ES_INDEX_RESOURCE_BOOKING: process.env.ES_INDEX_RESOURCE_BOOKING || 'resource_booking', - // the work period index - ES_INDEX_WORK_PERIOD: process.env.ES_INDEX_WORK_PERIOD || 'work_period', // the max bulk size in MB for ES indexing MAX_BULK_REQUEST_SIZE_MB: process.env.MAX_BULK_REQUEST_SIZE_MB || 20, diff --git a/data/demo-data.json b/data/demo-data.json index 2c7a94a7..e0733443 100644 --- a/data/demo-data.json +++ b/data/demo-data.json @@ -1,2394 +1,2056 @@ { - "Job": [ - { - "id": "b9887564-3d3d-4c70-8a7b-552576ef2e8d", - "projectId": 111, - "externalId": "0", - "description": "taas-demo-job1", - "title": "Demo Title", - "startDate": "2020-09-27T04:17:23.131Z", - "duration": null, - "numPositions": 13, - "resourceType": "Dummy Resource Type", - "rateType": "weekly", - "workload": "full-time", - "skills": [ - "ee4c50c1-c8c3-475e-b6b6-edbd136a19d6", - "89139c80-d0a2-47c2-aa16-14589d5afd10", - "9f2d9127-6a2e-4506-ad76-c4ab63577b09", - "9515e7ee-83b6-49d1-ba5c-6c59c5a8ef1b", - "c854ab55-5922-4be1-8ecc-b3bc1f8629af", - "8456002e-fa2d-44f0-b0e7-86b1c02b6e4c", - "114b4ec8-805e-4c60-b351-14a955a991a9", - "213408aa-f16f-46c8-bc57-9e569cee3f11", - "b37a48db-f775-4e4e-b403-8ad1d234cdea", - "99b930b5-1b91-4df1-8b17-d9307107bb51", - "6388a632-c3ad-4525-9a73-66a527c03672", - "23839f38-6f19-4de9-9d28-f020056bca73", - "289e42a3-23e9-49be-88e1-6deb93cd8c31", - "b403f209-63b5-42bc-9b5f-1564416640d8" - ], - "status": "sourcing", - "isApplicationPageActive": false, - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": null, - "createdAt": "2021-01-28T19:36:33.409Z", - "updatedAt": "2021-03-30T19:11:05.033Z" - }, - { - "id": "a5b3bf94-a8bf-4c7e-b685-70a29a4d7d6e", - "projectId": 111, - "externalId": "0", - "description": "taas-demo-job2", - "title": "Dummy title - at most 64 characters", - "startDate": "2020-09-27T04:17:23.131Z", - "duration": null, - "numPositions": 7, - "resourceType": "Dummy Resource Type", - "rateType": "weekly", - "workload": "full-time", - "skills": [ - "213408aa-f16f-46c8-bc57-9e569cee3f11", - "b37a48db-f775-4e4e-b403-8ad1d234cdea", - "99b930b5-1b91-4df1-8b17-d9307107bb51", - "6388a632-c3ad-4525-9a73-66a527c03672", - "23839f38-6f19-4de9-9d28-f020056bca73", - "289e42a3-23e9-49be-88e1-6deb93cd8c31", - "b403f209-63b5-42bc-9b5f-1564416640d8" - ], - "status": "in-review", - "isApplicationPageActive": false, - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "createdAt": "2021-01-28T19:36:44.975Z", - "updatedAt": "2021-01-28T19:38:17.463Z" - }, - { - "id": "2d5e2a52-e0dd-4cd9-8f4c-7cffa43951d0", - "projectId": 111, - "externalId": "0", - "description": "taas-demo-job3", - "title": "Dummy title - at most 64 characters", - "startDate": "2020-09-27T04:17:23.131Z", - "duration": null, - "numPositions": 7, - "resourceType": "Dummy Resource Type", - "rateType": "weekly", - "workload": "full-time", - "skills": [], - "status": "assigned", - "isApplicationPageActive": false, - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "createdAt": "2021-01-28T19:38:23.739Z", - "updatedAt": "2021-01-28T19:41:10.607Z" - }, - { - "id": "84b73f90-0fef-4507-887a-074578e5ef38", - "projectId": 111, - "externalId": "0", - "description": "taas-demo-job4", - "title": "Dummy title - at most 64 characters", - "startDate": "2020-09-27T04:17:23.131Z", - "duration": null, - "numPositions": 7, - "resourceType": "Dummy Resource Type", - "rateType": "weekly", - "workload": "full-time", - "skills": [ - "8456002e-fa2d-44f0-b0e7-86b1c02b6e4c", - "114b4ec8-805e-4c60-b351-14a955a991a9", - "213408aa-f16f-46c8-bc57-9e569cee3f11", - "b37a48db-f775-4e4e-b403-8ad1d234cdea", - "99b930b5-1b91-4df1-8b17-d9307107bb51", - "6388a632-c3ad-4525-9a73-66a527c03672" - ], - "status": "closed", - "isApplicationPageActive": false, - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "createdAt": "2021-01-28T19:41:21.892Z", - "updatedAt": "2021-01-28T19:41:28.849Z" - }, - { - "id": "62399aa0-b088-41fe-9e9b-0c8071f1934f", - "projectId": 111, - "externalId": "0", - "description": "taas-demo-job5", - "title": "Dummy title - at most 64 characters", - "startDate": "2020-09-27T04:17:23.131Z", - "duration": null, - "numPositions": 7, - "resourceType": "Dummy Resource Type", - "rateType": "weekly", - "workload": "full-time", - "skills": [ - "b37a48db-f775-4e4e-b403-8ad1d234cdea", - "99b930b5-1b91-4df1-8b17-d9307107bb51", - "6388a632-c3ad-4525-9a73-66a527c03672" - ], - "status": "cancelled", - "isApplicationPageActive": false, - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "createdAt": "2021-01-28T19:41:35.098Z", - "updatedAt": "2021-01-28T19:41:42.124Z" - }, - { - "id": "1324da27-9d7d-47d8-a04e-9fb3f35a67fa", - "projectId": 111, - "externalId": "88774632", - "description": "Dummy Description", - "title": "Dummy title - at most 64 characters", - "startDate": "2020-09-27T04:17:23.131Z", - "duration": 1, - "numPositions": 13, - "resourceType": "Dummy Resource Type", - "rateType": "hourly", - "workload": "full-time", - "skills": [ - "23e00d92-207a-4b5b-b3c9-4c5662644941", - "7d076384-ccf6-4e43-a45d-1b24b1e624aa", - "cbac57a3-7180-4316-8769-73af64893158", - "a2b4bc11-c641-4a19-9eb7-33980378f82e" - ], - "status": "in-review", - "isApplicationPageActive": false, - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": "00000000-0000-0000-0000-000000000000", - "createdAt": "2021-04-14T08:46:17.739Z", - "updatedAt": "2021-04-14T08:46:23.311Z" - } - ], - "JobCandidate": [ - { - "id": "debadcd8-64bf-4ab8-9cdb-297479eef6f5", - "jobId": "a5b3bf94-a8bf-4c7e-b685-70a29a4d7d6e", - "userId": "4dfc6090-4ba8-4387-b5c4-584fcef982ba", - "status": "open", - "externalId": null, - "resume": null, - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": null, - "createdAt": "2021-01-28T19:37:05.723Z", - "updatedAt": "2021-03-30T19:11:05.043Z", - "interviews": [] - }, - { - "id": "7ff45b8f-2b71-4510-b760-8dfa62e79504", - "jobId": "a5b3bf94-a8bf-4c7e-b685-70a29a4d7d6e", - "userId": "243517dd-77d7-4f70-8951-0bc66da83076", - "status": "open", - "externalId": null, - "resume": null, - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": null, - "createdAt": "2021-01-28T19:37:11.598Z", - "updatedAt": "2021-03-30T19:11:05.043Z", - "interviews": [] - }, - { - "id": "91d63d5f-01d5-419e-89df-6117ea92f535", - "jobId": "a5b3bf94-a8bf-4c7e-b685-70a29a4d7d6e", - "userId": "a2e28bf4-1147-41a6-a39f-e2509306f2a6", - "status": "open", - "externalId": null, - "resume": null, - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": null, - "createdAt": "2021-01-28T19:37:18.066Z", - "updatedAt": "2021-03-30T19:11:05.043Z", - "interviews": [] - }, - { - "id": "257f98d9-45f7-4e13-a6c2-d7e7b6efc9fe", - "jobId": "a5b3bf94-a8bf-4c7e-b685-70a29a4d7d6e", - "userId": "b8649393-d32f-4b7f-a156-12e9776acb0e", - "status": "open", - "externalId": null, - "resume": null, - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": null, - "createdAt": "2021-01-28T19:37:24.095Z", - "updatedAt": "2021-03-30T19:11:05.043Z", - "interviews": [] - }, - { - "id": "a01852d0-fa08-410c-b97b-67580ce62215", - "jobId": "a5b3bf94-a8bf-4c7e-b685-70a29a4d7d6e", - "userId": "a0a3a5ce-1de6-465d-91b2-518feb299851", - "status": "open", - "externalId": null, - "resume": null, - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": null, - "createdAt": "2021-01-28T19:37:29.734Z", - "updatedAt": "2021-03-30T19:11:05.043Z", - "interviews": [] - }, - { - "id": "2fd7ca69-c8ec-4bf3-a7f3-655fbfe3e7df", - "jobId": "a5b3bf94-a8bf-4c7e-b685-70a29a4d7d6e", - "userId": "e6958d77-ffaf-4d24-9cdb-6391506695a4", - "status": "open", - "externalId": null, - "resume": null, - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": null, - "createdAt": "2021-01-28T19:37:44.728Z", - "updatedAt": "2021-03-30T19:11:05.043Z", - "interviews": [] - }, - { - "id": "f0023058-2996-4bba-8c5f-d09a7023be38", - "jobId": "a5b3bf94-a8bf-4c7e-b685-70a29a4d7d6e", - "userId": "626bb327-e738-48e3-8f67-1fa2dc677d3c", - "status": "open", - "externalId": null, - "resume": null, - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": null, - "createdAt": "2021-01-28T19:37:50.619Z", - "updatedAt": "2021-03-30T19:11:05.043Z", - "interviews": [] - }, - { - "id": "a189b34d-acde-4633-b18b-f7a34d7c5a74", - "jobId": "a5b3bf94-a8bf-4c7e-b685-70a29a4d7d6e", - "userId": "b49a0adb-1565-4de1-9189-a763c77f5ed4", - "status": "open", - "externalId": null, - "resume": null, - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": null, - "createdAt": "2021-01-28T19:37:56.456Z", - "updatedAt": "2021-03-30T19:11:05.043Z", - "interviews": [] - }, - { - "id": "5191a860-4327-4c50-b76b-84beba04519b", - "jobId": "a5b3bf94-a8bf-4c7e-b685-70a29a4d7d6e", - "userId": "79ce2a3e-7679-48cf-8ac9-0a8ca4c4b463", - "status": "selected", - "externalId": null, - "resume": null, - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "createdAt": "2021-01-28T19:36:51.222Z", - "updatedAt": "2021-01-28T19:38:02.293Z", - "interviews": [] - }, - { - "id": "e6d9635c-b122-4f69-9285-09fb1ab30106", - "jobId": "a5b3bf94-a8bf-4c7e-b685-70a29a4d7d6e", - "userId": "98ec2c16-442e-4b61-8ad1-66123ee37d3c", - "status": "rejected - other", - "externalId": null, - "resume": null, - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "createdAt": "2021-01-28T19:36:58.774Z", - "updatedAt": "2021-01-28T19:38:13.553Z", - "interviews": [] - }, - { - "id": "f67b155e-0f09-4fdd-89a7-d79c5e46cac6", - "jobId": "2d5e2a52-e0dd-4cd9-8f4c-7cffa43951d0", - "userId": "05e988b7-7d54-4c10-ada1-1a04870a88a8", - "status": "open", - "externalId": null, - "resume": null, - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": null, - "createdAt": "2021-01-28T19:38:38.332Z", - "updatedAt": "2021-03-30T19:11:05.043Z", - "interviews": [] - }, - { - "id": "8ffd33d3-4a43-4719-aee4-8e46be1d8f1c", - "jobId": "2d5e2a52-e0dd-4cd9-8f4c-7cffa43951d0", - "userId": "a2ffdeed-704d-4cf7-b70a-93fcf61de598", - "status": "open", - "externalId": null, - "resume": null, - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": null, - "createdAt": "2021-01-28T19:38:43.967Z", - "updatedAt": "2021-03-30T19:11:05.043Z", - "interviews": [] - }, - { - "id": "2b8ba549-8878-43d6-ad5f-6a66e3b9d6c9", - "jobId": "2d5e2a52-e0dd-4cd9-8f4c-7cffa43951d0", - "userId": "4709473d-f060-4102-87f8-4d51ff0b34c1", - "status": "open", - "externalId": null, - "resume": null, - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": null, - "createdAt": "2021-01-28T19:38:50.106Z", - "updatedAt": "2021-03-30T19:11:05.043Z", - "interviews": [] - }, - { - "id": "ae5a81ec-5d05-43c4-8253-847d91a54711", - "jobId": "2d5e2a52-e0dd-4cd9-8f4c-7cffa43951d0", - "userId": "39c7376e-2d5c-4601-bc47-6b60f505814d", - "status": "open", - "externalId": null, - "resume": null, - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": null, - "createdAt": "2021-01-28T19:38:55.734Z", - "updatedAt": "2021-03-30T19:11:05.043Z", - "interviews": [] - }, - { - "id": "85d6649e-2682-4904-9480-a77b72fef27d", - "jobId": "2d5e2a52-e0dd-4cd9-8f4c-7cffa43951d0", - "userId": "213d2dd9-1fc3-4eda-ad97-2d56e2a84a1e", - "status": "placed", - "externalId": null, - "resume": null, - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": "00000000-0000-0000-0000-000000000000", - "createdAt": "2021-01-28T19:38:30.856Z", - "updatedAt": "2021-01-28T19:40:27.209Z", - "interviews": [] - }, - { - "id": "922dfce3-4e06-4387-9fdb-64f70675e86b", - "jobId": "2d5e2a52-e0dd-4cd9-8f4c-7cffa43951d0", - "userId": "dd5adacb-444d-4992-8b7b-0c349be598db", - "status": "placed", - "externalId": null, - "resume": null, - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": "00000000-0000-0000-0000-000000000000", - "createdAt": "2021-01-28T19:39:02.435Z", - "updatedAt": "2021-01-28T19:40:49.349Z", - "interviews": [] - }, - { - "id": "c26c38e2-a47d-405b-abc6-fe62a739561c", - "jobId": "2d5e2a52-e0dd-4cd9-8f4c-7cffa43951d0", - "userId": "6d0509c7-5f12-4d84-9a19-8e80ef7ddd66", - "status": "placed", - "externalId": null, - "resume": null, - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": "00000000-0000-0000-0000-000000000000", - "createdAt": "2021-01-28T19:39:08.233Z", - "updatedAt": "2021-01-28T19:40:53.659Z", - "interviews": [] - }, - { - "id": "7bef2b37-e1ee-4638-bfc1-c911787ac955", - "jobId": "2d5e2a52-e0dd-4cd9-8f4c-7cffa43951d0", - "userId": "f65e2104-2987-4136-839d-ee4632f0b2e5", - "status": "placed", - "externalId": null, - "resume": null, - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": "00000000-0000-0000-0000-000000000000", - "createdAt": "2021-01-28T19:39:13.469Z", - "updatedAt": "2021-01-28T19:40:57.999Z", - "interviews": [] - }, - { - "id": "e9716139-1f40-4bf1-9f8a-77ae4bcc621e", - "jobId": "2d5e2a52-e0dd-4cd9-8f4c-7cffa43951d0", - "userId": "e5e667ad-0950-43c2-8d1d-6e83ad7d1c7e", - "status": "placed", - "externalId": null, - "resume": null, - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": "00000000-0000-0000-0000-000000000000", - "createdAt": "2021-01-28T19:39:19.215Z", - "updatedAt": "2021-01-28T19:41:01.953Z", - "interviews": [] - }, - { - "id": "a1731d01-eac9-4eff-8e5a-8a3c99bc66e0", - "jobId": "2d5e2a52-e0dd-4cd9-8f4c-7cffa43951d0", - "userId": "bef43122-426b-4b2b-acdd-9b5b3bd1c0bf", - "status": "placed", - "externalId": null, - "resume": null, - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": "00000000-0000-0000-0000-000000000000", - "createdAt": "2021-01-28T19:39:24.625Z", - "updatedAt": "2021-01-28T19:41:06.370Z", - "interviews": [] - }, - { - "id": "25787cb2-d876-4883-b533-d5e628d213ce", - "jobId": "1324da27-9d7d-47d8-a04e-9fb3f35a67fa", - "userId": "95e7970f-12b4-43b7-ab35-38c34bf033c7", - "status": "interview", - "externalId": "88774631", - "resume": "http://example.com", - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": null, - "createdAt": "2021-04-14T08:46:23.250Z", - "updatedAt": "2021-04-14T08:46:23.250Z", - "interviews": [ + "Job": [ { - "id": "81f03238-1ce2-4d3d-80c5-5ecd5e7e94a2", - "jobCandidateId": "25787cb2-d876-4883-b533-d5e628d213ce", - "calendarEventId": "dummyId", - "templateUrl": "interview-30", - "round": 1, - "duration": 30, - "hostName": "John Doe", - "hostEmail": "testuserforemail@yopmail.com", - "guestNames": ["Customer Test"], - "guestEmails": ["testcustomer@yopmail.com"], - "status": "Scheduling", - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": null, - "createdAt": "2021-04-14T08:46:34.597Z", - "updatedAt": "2021-04-14T08:46:34.597Z" + "id": "36dad9f2-98ed-4d3a-9ea7-2cd3d0f8a51a", + "projectId": 111, + "externalId": "88774632", + "description": "Dummy Description", + "title": "Dummy title - at most 64 characters", + "startDate": "2020-09-27T00:00:00.000Z", + "duration": 1, + "numPositions": 13, + "resourceType": "Dummy Resource Type", + "rateType": "hourly", + "workload": "full-time", + "skills": [ + "23e00d92-207a-4b5b-b3c9-4c5662644941", + "7d076384-ccf6-4e43-a45d-1b24b1e624aa", + "cbac57a3-7180-4316-8769-73af64893158", + "a2b4bc11-c641-4a19-9eb7-33980378f82e" + ], + "status": "in-review", + "isApplicationPageActive": false, + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": "00000000-0000-0000-0000-000000000000", + "createdAt": "2021-05-09T21:21:10.394Z", + "updatedAt": "2021-05-09T21:21:14.010Z" }, { - "id": "75363f1d-46c3-4261-9c21-70019f90a61a", - "jobCandidateId": "25787cb2-d876-4883-b533-d5e628d213ce", - "calendarEventId": "dummyId", - "templateUrl": "interview-30", - "round": 2, - "duration": 30, - "hostName": "John Doe", - "hostEmail": "testuserforemail@yopmail.com", - "guestNames": ["Customer Test"], - "guestEmails": ["testcustomer@yopmail.com"], - "status": "Scheduling", - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": null, - "createdAt": "2021-04-14T08:50:15.109Z", - "updatedAt": "2021-04-14T08:50:15.109Z" + "id": "728ff056-63f6-4730-8a9f-3074acad8479", + "projectId": 111, + "externalId": "1212", + "description": "Dummy Description", + "title": "Dummy title - at most 64 characters", + "startDate": "2020-09-27T04:17:23.131Z", + "duration": 1, + "numPositions": 10, + "resourceType": "Dummy Resource Type", + "rateType": "hourly", + "workload": "full-time", + "skills": [ + "23e00d92-207a-4b5b-b3c9-4c5662644941", + "7d076384-ccf6-4e43-a45d-1b24b1e624aa", + "cbac57a3-7180-4316-8769-73af64893158", + "a2b4bc11-c641-4a19-9eb7-33980378f82e" + ], + "status": "in-review", + "isApplicationPageActive": false, + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": "00000000-0000-0000-0000-000000000000", + "createdAt": "2021-05-09T21:11:26.934Z", + "updatedAt": "2021-05-09T21:14:05.495Z" + }, + { + "id": "a8adb1f8-a6ee-48b1-8661-33bd851b726e", + "projectId": 111, + "externalId": "1212", + "description": "Dummy Description", + "title": "Dummy title - at most 64 characters", + "startDate": "2020-09-27T04:17:23.131Z", + "duration": 1, + "numPositions": 7, + "resourceType": "Dummy Resource Type", + "rateType": "hourly", + "workload": "full-time", + "skills": [ + "23e00d92-207a-4b5b-b3c9-4c5662644941", + "7d076384-ccf6-4e43-a45d-1b24b1e624aa", + "cbac57a3-7180-4316-8769-73af64893158", + "a2b4bc11-c641-4a19-9eb7-33980378f82e" + ], + "status": "in-review", + "isApplicationPageActive": false, + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": "00000000-0000-0000-0000-000000000000", + "createdAt": "2021-05-09T21:23:18.595Z", + "updatedAt": "2021-05-09T21:23:23.474Z" + }, + { + "id": "b28f4e67-324f-4ada-a23a-c27499053ed4", + "projectId": 111, + "externalId": "1212", + "description": "Dummy Description", + "title": "Dummy title - at most 64 characters", + "startDate": "2020-09-27T04:17:23.131Z", + "duration": 1, + "numPositions": 5, + "resourceType": "Dummy Resource Type", + "rateType": "hourly", + "workload": "full-time", + "skills": [ + "23e00d92-207a-4b5b-b3c9-4c5662644941", + "7d076384-ccf6-4e43-a45d-1b24b1e624aa", + "cbac57a3-7180-4316-8769-73af64893158", + "a2b4bc11-c641-4a19-9eb7-33980378f82e" + ], + "status": "in-review", + "isApplicationPageActive": false, + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": "00000000-0000-0000-0000-000000000000", + "createdAt": "2021-05-09T21:12:09.293Z", + "updatedAt": "2021-05-09T21:14:59.157Z" + } + ], + "JobCandidate": [ + { + "id": "b0fc417b-3f41-4c06-9f2b-8e680c3a03c6", + "jobId": "728ff056-63f6-4730-8a9f-3074acad8479", + "userId": "a55fe1bc-1754-45fa-9adc-cf3d6d7c377a", + "status": "open", + "externalId": "300234321", + "resume": "http://example.com", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-05-09T21:14:05.412Z", + "updatedAt": "2021-05-09T21:14:05.412Z", + "interviews": [] + }, + { + "id": "c637ecf3-8df5-42e7-80d6-daba422e371a", + "jobId": "728ff056-63f6-4730-8a9f-3074acad8479", + "userId": "a55fe1bc-1754-45fa-9adc-cf3d6d7c377a", + "status": "open", + "externalId": "300234321", + "resume": "http://example.com", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-05-09T21:14:41.500Z", + "updatedAt": "2021-05-09T21:14:41.500Z", + "interviews": [] + }, + { + "id": "02a622f4-7894-4ac0-a823-a952ffa1b3f3", + "jobId": "728ff056-63f6-4730-8a9f-3074acad8479", + "userId": "a55fe1bc-1754-45fa-9adc-cf3d6d7c377a", + "status": "open", + "externalId": "300234321", + "resume": "http://example.com", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-05-09T21:14:43.985Z", + "updatedAt": "2021-05-09T21:14:43.985Z", + "interviews": [] + }, + { + "id": "b32b4819-7bfa-49a8-851e-69cdddff8149", + "jobId": "728ff056-63f6-4730-8a9f-3074acad8479", + "userId": "a55fe1bc-1754-45fa-9adc-cf3d6d7c377a", + "status": "open", + "externalId": "300234321", + "resume": "http://example.com", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-05-09T21:14:46.310Z", + "updatedAt": "2021-05-09T21:14:46.310Z", + "interviews": [] + }, + { + "id": "08a67e4d-6857-492c-a3fa-cd7c64e76a69", + "jobId": "728ff056-63f6-4730-8a9f-3074acad8479", + "userId": "a55fe1bc-1754-45fa-9adc-cf3d6d7c377a", + "status": "open", + "externalId": "300234321", + "resume": "http://example.com", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-05-09T21:14:48.449Z", + "updatedAt": "2021-05-09T21:14:48.449Z", + "interviews": [] + }, + { + "id": "881a19de-2b0c-4bb9-b36a-4cb5e223bdb5", + "jobId": "728ff056-63f6-4730-8a9f-3074acad8479", + "userId": "a55fe1bc-1754-45fa-9adc-cf3d6d7c377a", + "status": "open", + "externalId": "300234321", + "resume": "http://example.com", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-05-09T21:14:50.595Z", + "updatedAt": "2021-05-09T21:14:50.595Z", + "interviews": [ + { + "id": "077aa2ca-5b60-4ad9-a965-1b37e08a5046", + "jobCandidateId": "881a19de-2b0c-4bb9-b36a-4cb5e223bdb5", + "googleCalendarId": null, + "customMessage": null, + "xaiTemplate": "interview-30", + "round": 1, + "startTimestamp": null, + "attendeesList": null, + "status": "Completed", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-05-09T21:16:10.887Z", + "updatedAt": "2021-05-09T21:16:10.887Z" + } + ] + }, + { + "id": "827ee401-df04-42e1-abbe-7b97ce7937ff", + "jobId": "728ff056-63f6-4730-8a9f-3074acad8479", + "userId": "95e7970f-12b4-43b7-ab35-38c34bf033c7", + "status": "open", + "externalId": "88774631", + "resume": "http://example.com", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-05-09T21:16:34.914Z", + "updatedAt": "2021-05-09T21:16:34.914Z", + "interviews": [ + { + "id": "b1f7ba76-640f-47e2-9463-59e51b51ec60", + "jobCandidateId": "827ee401-df04-42e1-abbe-7b97ce7937ff", + "googleCalendarId": "dummyId", + "customMessage": "This is a custom message", + "xaiTemplate": "interview-30", + "round": 2, + "startTimestamp": null, + "attendeesList": null, + "status": "Scheduling", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-05-09T21:17:23.517Z", + "updatedAt": "2021-05-09T21:17:23.517Z" + }, + { + "id": "3144fa65-ea1a-4bec-81b0-7cb1c8845826", + "jobCandidateId": "827ee401-df04-42e1-abbe-7b97ce7937ff", + "googleCalendarId": null, + "customMessage": null, + "xaiTemplate": "interview-30", + "round": 1, + "startTimestamp": null, + "attendeesList": null, + "status": "Completed", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-05-09T21:16:39.019Z", + "updatedAt": "2021-05-09T21:16:39.019Z" + } + ] + }, + { + "id": "a4ea7bcf-5b99-4381-b99c-a9bd05d83a36", + "jobId": "36dad9f2-98ed-4d3a-9ea7-2cd3d0f8a51a", + "userId": "95e7970f-12b4-43b7-ab35-38c34bf033c7", + "status": "open", + "externalId": "88774631", + "resume": "http://example.com", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-05-09T21:21:13.939Z", + "updatedAt": "2021-05-09T21:21:13.939Z", + "interviews": [ + { + "id": "976d23a9-5710-453f-99d9-f57a588bb610", + "jobCandidateId": "a4ea7bcf-5b99-4381-b99c-a9bd05d83a36", + "googleCalendarId": "dummyId", + "customMessage": "This is a custom message", + "xaiTemplate": "interview-30", + "round": 3, + "startTimestamp": null, + "attendeesList": [ + "attendee1@yopmail.com", + "attendee2@yopmail.com" + ], + "status": "Scheduling", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-05-09T21:21:28.713Z", + "updatedAt": "2021-05-09T21:21:28.713Z" + }, + { + "id": "a23e1bf2-1084-4cfe-a0d8-d83bc6fec655", + "jobCandidateId": "a4ea7bcf-5b99-4381-b99c-a9bd05d83a36", + "googleCalendarId": "dummyId", + "customMessage": "This is a custom message", + "xaiTemplate": "interview-30", + "round": 2, + "startTimestamp": null, + "attendeesList": [ + "attendee1@yopmail.com", + "attendee2@yopmail.com" + ], + "status": "Scheduling", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-05-09T21:21:22.428Z", + "updatedAt": "2021-05-09T21:21:22.428Z" + }, + { + "id": "9efd72c3-1dc7-4ce2-9869-8cca81d0adeb", + "jobCandidateId": "a4ea7bcf-5b99-4381-b99c-a9bd05d83a36", + "googleCalendarId": null, + "customMessage": null, + "xaiTemplate": "interview-30", + "round": 1, + "startTimestamp": null, + "attendeesList": null, + "status": "Completed", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-05-09T21:21:17.346Z", + "updatedAt": "2021-05-09T21:21:17.346Z" + } + ] + }, + { + "id": "a65b7ff1-8d79-4d6e-b29b-360473131273", + "jobId": "a8adb1f8-a6ee-48b1-8661-33bd851b726e", + "userId": "a55fe1bc-1754-45fa-9adc-cf3d6d7c377a", + "status": "placed", + "externalId": "300234321", + "resume": "http://example.com", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": "00000000-0000-0000-0000-000000000000", + "createdAt": "2021-05-09T21:23:23.420Z", + "updatedAt": "2021-05-09T21:25:46.850Z", + "interviews": [] + }, + { + "id": "0967d234-a11e-4af9-8f6c-b88d21277e15", + "jobId": "a8adb1f8-a6ee-48b1-8661-33bd851b726e", + "userId": "a55fe1bc-1754-45fa-9adc-cf3d6d7c377a", + "status": "placed", + "externalId": "300234321", + "resume": "http://example.com", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": "00000000-0000-0000-0000-000000000000", + "createdAt": "2021-05-09T21:23:41.691Z", + "updatedAt": "2021-05-09T21:25:46.861Z", + "interviews": [] + }, + { + "id": "9674672a-4bc8-454d-a0e8-cb4f1ce1411c", + "jobId": "a8adb1f8-a6ee-48b1-8661-33bd851b726e", + "userId": "a55fe1bc-1754-45fa-9adc-cf3d6d7c377a", + "status": "placed", + "externalId": "300234321", + "resume": "http://example.com", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": "00000000-0000-0000-0000-000000000000", + "createdAt": "2021-05-09T21:23:35.819Z", + "updatedAt": "2021-05-09T21:25:46.853Z", + "interviews": [] + }, + { + "id": "bab422c9-cf0f-485b-a734-dbb4e8bea4f0", + "jobId": "a8adb1f8-a6ee-48b1-8661-33bd851b726e", + "userId": "a55fe1bc-1754-45fa-9adc-cf3d6d7c377a", + "status": "placed", + "externalId": "300234321", + "resume": "http://example.com", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": "00000000-0000-0000-0000-000000000000", + "createdAt": "2021-05-09T21:23:39.914Z", + "updatedAt": "2021-05-09T21:25:46.858Z", + "interviews": [] + }, + { + "id": "292a25c4-a895-4983-a66d-fed44e57244e", + "jobId": "a8adb1f8-a6ee-48b1-8661-33bd851b726e", + "userId": "a55fe1bc-1754-45fa-9adc-cf3d6d7c377a", + "status": "placed", + "externalId": "300234321", + "resume": "http://example.com", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": "00000000-0000-0000-0000-000000000000", + "createdAt": "2021-05-09T21:23:37.962Z", + "updatedAt": "2021-05-09T21:25:46.855Z", + "interviews": [] + }, + { + "id": "68547eee-c130-42a4-bbec-dad62d7c6852", + "jobId": "a8adb1f8-a6ee-48b1-8661-33bd851b726e", + "userId": "a55fe1bc-1754-45fa-9adc-cf3d6d7c377a", + "status": "placed", + "externalId": "300234321", + "resume": "http://example.com", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": "00000000-0000-0000-0000-000000000000", + "createdAt": "2021-05-09T21:23:43.611Z", + "updatedAt": "2021-05-09T21:25:46.862Z", + "interviews": [] + }, + { + "id": "0e9996f1-2629-4115-9e23-dc57e23811b2", + "jobId": "a8adb1f8-a6ee-48b1-8661-33bd851b726e", + "userId": "a55fe1bc-1754-45fa-9adc-cf3d6d7c377a", + "status": "placed", + "externalId": "300234321", + "resume": "http://example.com", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": "00000000-0000-0000-0000-000000000000", + "createdAt": "2021-05-09T21:23:47.468Z", + "updatedAt": "2021-05-09T21:25:46.863Z", + "interviews": [] + }, + { + "id": "2cff52f7-4a2f-48b7-9fad-177745cc759b", + "jobId": "a8adb1f8-a6ee-48b1-8661-33bd851b726e", + "userId": "a55fe1bc-1754-45fa-9adc-cf3d6d7c377a", + "status": "placed", + "externalId": "300234321", + "resume": "http://example.com", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": "00000000-0000-0000-0000-000000000000", + "createdAt": "2021-05-09T21:23:45.506Z", + "updatedAt": "2021-05-09T21:25:46.864Z", + "interviews": [] + }, + { + "id": "74ed50a4-4082-48af-a2e5-33c3cc2e7f10", + "jobId": "a8adb1f8-a6ee-48b1-8661-33bd851b726e", + "userId": "a55fe1bc-1754-45fa-9adc-cf3d6d7c377a", + "status": "placed", + "externalId": "300234321", + "resume": "http://example.com", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": "00000000-0000-0000-0000-000000000000", + "createdAt": "2021-05-09T21:23:57.355Z", + "updatedAt": "2021-05-09T21:25:46.866Z", + "interviews": [] + }, + { + "id": "113b3e4d-3aed-4602-b952-3fb28e4bc908", + "jobId": "a8adb1f8-a6ee-48b1-8661-33bd851b726e", + "userId": "a55fe1bc-1754-45fa-9adc-cf3d6d7c377a", + "status": "placed", + "externalId": "300234321", + "resume": "http://example.com", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": "00000000-0000-0000-0000-000000000000", + "createdAt": "2021-05-09T21:23:49.415Z", + "updatedAt": "2021-05-09T21:25:46.867Z", + "interviews": [] + }, + { + "id": "c3f2bddb-39d1-4558-8052-c556b1436d3a", + "jobId": "a8adb1f8-a6ee-48b1-8661-33bd851b726e", + "userId": "a55fe1bc-1754-45fa-9adc-cf3d6d7c377a", + "status": "placed", + "externalId": "300234321", + "resume": "http://example.com", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": "00000000-0000-0000-0000-000000000000", + "createdAt": "2021-05-09T21:23:51.500Z", + "updatedAt": "2021-05-09T21:25:46.868Z", + "interviews": [] + }, + { + "id": "26fea152-9f15-437f-876a-a3ef211d60b9", + "jobId": "a8adb1f8-a6ee-48b1-8661-33bd851b726e", + "userId": "a55fe1bc-1754-45fa-9adc-cf3d6d7c377a", + "status": "placed", + "externalId": "300234321", + "resume": "http://example.com", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": "00000000-0000-0000-0000-000000000000", + "createdAt": "2021-05-09T21:23:53.297Z", + "updatedAt": "2021-05-09T21:25:46.869Z", + "interviews": [] + }, + { + "id": "fa137ab6-daee-4201-8cec-9e70086f9c4a", + "jobId": "a8adb1f8-a6ee-48b1-8661-33bd851b726e", + "userId": "a55fe1bc-1754-45fa-9adc-cf3d6d7c377a", + "status": "placed", + "externalId": "300234321", + "resume": "http://example.com", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": "00000000-0000-0000-0000-000000000000", + "createdAt": "2021-05-09T21:23:55.300Z", + "updatedAt": "2021-05-09T21:25:46.870Z", + "interviews": [] + }, + { + "id": "a591149a-d16a-4287-a520-d021a5c767b1", + "jobId": "a8adb1f8-a6ee-48b1-8661-33bd851b726e", + "userId": "a55fe1bc-1754-45fa-9adc-cf3d6d7c377a", + "status": "placed", + "externalId": "300234321", + "resume": "http://example.com", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": "00000000-0000-0000-0000-000000000000", + "createdAt": "2021-05-09T21:23:59.282Z", + "updatedAt": "2021-05-09T21:25:46.872Z", + "interviews": [] + }, + { + "id": "7ccb9a34-553e-427d-9f03-3b7caf0216e9", + "jobId": "a8adb1f8-a6ee-48b1-8661-33bd851b726e", + "userId": "a55fe1bc-1754-45fa-9adc-cf3d6d7c377a", + "status": "placed", + "externalId": "300234321", + "resume": "http://example.com", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": "00000000-0000-0000-0000-000000000000", + "createdAt": "2021-05-09T21:24:01.429Z", + "updatedAt": "2021-05-09T21:25:46.873Z", + "interviews": [] + }, + { + "id": "8845ae56-5291-4ce0-8cf6-9e684b152d03", + "jobId": "a8adb1f8-a6ee-48b1-8661-33bd851b726e", + "userId": "a55fe1bc-1754-45fa-9adc-cf3d6d7c377a", + "status": "placed", + "externalId": "300234321", + "resume": "http://example.com", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": "00000000-0000-0000-0000-000000000000", + "createdAt": "2021-05-09T21:24:03.511Z", + "updatedAt": "2021-05-09T21:25:46.874Z", + "interviews": [] + }, + { + "id": "85dddeda-a4cc-48dc-9a1d-8d96bf52bc5d", + "jobId": "a8adb1f8-a6ee-48b1-8661-33bd851b726e", + "userId": "a55fe1bc-1754-45fa-9adc-cf3d6d7c377a", + "status": "placed", + "externalId": "300234321", + "resume": "http://example.com", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": "00000000-0000-0000-0000-000000000000", + "createdAt": "2021-05-09T21:24:05.605Z", + "updatedAt": "2021-05-09T21:25:46.877Z", + "interviews": [] + }, + { + "id": "06450cf6-aafa-436f-8078-b0ced9f99432", + "jobId": "b28f4e67-324f-4ada-a23a-c27499053ed4", + "userId": "a55fe1bc-1754-45fa-9adc-cf3d6d7c377a", + "status": "placed", + "externalId": "300234321", + "resume": "http://example.com", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": "00000000-0000-0000-0000-000000000000", + "createdAt": "2021-05-09T21:15:05.339Z", + "updatedAt": "2021-05-09T21:25:50.517Z", + "interviews": [] + }, + { + "id": "d4b2fe37-e0ed-41db-9c31-561ea2a5fb63", + "jobId": "b28f4e67-324f-4ada-a23a-c27499053ed4", + "userId": "a55fe1bc-1754-45fa-9adc-cf3d6d7c377a", + "status": "placed", + "externalId": "300234321", + "resume": "http://example.com", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": "00000000-0000-0000-0000-000000000000", + "createdAt": "2021-05-09T21:15:03.606Z", + "updatedAt": "2021-05-09T21:25:50.519Z", + "interviews": [] + }, + { + "id": "aa72b3df-7c94-4a4a-a6cb-bd14d92aadfc", + "jobId": "b28f4e67-324f-4ada-a23a-c27499053ed4", + "userId": "a55fe1bc-1754-45fa-9adc-cf3d6d7c377a", + "status": "placed", + "externalId": "300234321", + "resume": "http://example.com", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": "00000000-0000-0000-0000-000000000000", + "createdAt": "2021-05-09T21:14:59.106Z", + "updatedAt": "2021-05-09T21:25:50.520Z", + "interviews": [] + }, + { + "id": "da1be4fc-21d3-4544-abeb-c3434c172cdf", + "jobId": "b28f4e67-324f-4ada-a23a-c27499053ed4", + "userId": "a55fe1bc-1754-45fa-9adc-cf3d6d7c377a", + "status": "placed", + "externalId": "300234321", + "resume": "http://example.com", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": "00000000-0000-0000-0000-000000000000", + "createdAt": "2021-05-09T21:15:02.183Z", + "updatedAt": "2021-05-09T21:25:50.521Z", + "interviews": [] + }, + { + "id": "e07848de-ecee-4eec-8163-4f17e40e756b", + "jobId": "b28f4e67-324f-4ada-a23a-c27499053ed4", + "userId": "a55fe1bc-1754-45fa-9adc-cf3d6d7c377a", + "status": "placed", + "externalId": "300234321", + "resume": "http://example.com", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": "00000000-0000-0000-0000-000000000000", + "createdAt": "2021-05-09T21:15:00.676Z", + "updatedAt": "2021-05-09T21:25:50.523Z", + "interviews": [] + }, + { + "id": "458de082-d5ea-495a-8939-e8da3bb00e90", + "jobId": "b28f4e67-324f-4ada-a23a-c27499053ed4", + "userId": "a55fe1bc-1754-45fa-9adc-cf3d6d7c377a", + "status": "placed", + "externalId": "300234321", + "resume": "http://example.com", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": "00000000-0000-0000-0000-000000000000", + "createdAt": "2021-05-09T21:15:06.739Z", + "updatedAt": "2021-05-09T21:25:50.525Z", + "interviews": [] + } + ], + "ResourceBooking": [ + { + "id": "c0a12936-77ef-46fa-8c75-6996339e79f6", + "projectId": 111, + "userId": "05e988b7-7d54-4c10-ada1-1a04870a88a8", + "jobId": "a8adb1f8-a6ee-48b1-8661-33bd851b726e", + "status": "placed", + "startDate": "2020-09-27", + "endDate": "2020-10-27", + "memberRate": 13.23, + "customerRate": 13, + "rateType": "hourly", + "billingAccountId": 80000071, + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-05-09T21:25:46.728Z", + "updatedAt": "2021-05-09T21:25:46.728Z", + "workPeriods": [ + { + "id": "1cdd1505-f6f4-40f6-acce-da7a4578dab5", + "resourceBookingId": "c0a12936-77ef-46fa-8c75-6996339e79f6", + "userHandle": "sachin-wipro", + "projectId": 111, + "startDate": "2020-09-27", + "endDate": "2020-10-03", + "daysWorked": 4, + "memberRate": 27.06, + "customerRate": 13.13, + "paymentStatus": "partially-completed", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "createdAt": "2021-05-09T21:25:47.813Z", + "updatedAt": "2021-05-09T21:45:32.659Z", + "payments": [ + { + "id": "03a0163c-472e-4ea6-b8ad-3dc86d418ecf", + "workPeriodId": "1cdd1505-f6f4-40f6-acce-da7a4578dab5", + "challengeId": "00000000-0000-0000-0000-000000000000", + "amount": 210.19, + "status": "cancelled", + "billingAccountId": 80000071, + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-05-09T21:31:36.932Z", + "updatedAt": "2021-05-09T21:31:36.932Z" + }, + { + "id": "14b266c6-e76a-4042-b439-74fe3e42c90f", + "workPeriodId": "1cdd1505-f6f4-40f6-acce-da7a4578dab5", + "challengeId": "00000000-0000-0000-0000-000000000000", + "amount": 417.42, + "status": "cancelled", + "billingAccountId": 80000071, + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-05-09T21:31:38.183Z", + "updatedAt": "2021-05-09T21:31:38.183Z" + }, + { + "id": "1c682ea9-ba63-4fcc-b00c-049d2458d3ac", + "workPeriodId": "1cdd1505-f6f4-40f6-acce-da7a4578dab5", + "challengeId": "00000000-0000-0000-0000-000000000000", + "amount": 57.79, + "status": "completed", + "billingAccountId": 80000071, + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-05-09T21:31:35.726Z", + "updatedAt": "2021-05-09T21:31:35.726Z" + } + ] + }, + { + "id": "e8346d7b-4ada-428d-a768-c2989306f63a", + "resourceBookingId": "c0a12936-77ef-46fa-8c75-6996339e79f6", + "userHandle": "sachin-wipro", + "projectId": 111, + "startDate": "2020-10-18", + "endDate": "2020-10-24", + "daysWorked": 4, + "memberRate": 4.08, + "customerRate": 3.89, + "paymentStatus": "cancelled", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "createdAt": "2021-05-09T21:25:47.834Z", + "updatedAt": "2021-05-09T21:45:37.647Z", + "payments": [ + { + "id": "e8f3d379-f5a0-47f6-b37b-cae24f5909e9", + "workPeriodId": "e8346d7b-4ada-428d-a768-c2989306f63a", + "challengeId": "00000000-0000-0000-0000-000000000000", + "amount": 494.46, + "status": "completed", + "billingAccountId": 80000071, + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-05-09T21:34:22.403Z", + "updatedAt": "2021-05-09T21:34:22.403Z" + }, + { + "id": "cc235aee-0911-4869-bb49-911507bb31e7", + "workPeriodId": "e8346d7b-4ada-428d-a768-c2989306f63a", + "challengeId": "00000000-0000-0000-0000-000000000000", + "amount": 494.46, + "status": "cancelled", + "billingAccountId": 80000071, + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-05-09T21:34:26.807Z", + "updatedAt": "2021-05-09T21:34:26.807Z" + } + ] + }, + { + "id": "a3bbd01d-535d-4f02-8524-0d61395b84e9", + "resourceBookingId": "c0a12936-77ef-46fa-8c75-6996339e79f6", + "userHandle": "sachin-wipro", + "projectId": 111, + "startDate": "2020-10-25", + "endDate": "2020-10-31", + "daysWorked": 3, + "memberRate": 15.61, + "customerRate": 9.76, + "paymentStatus": "pending", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "createdAt": "2021-05-09T21:25:47.824Z", + "updatedAt": "2021-05-09T21:45:48.727Z", + "payments": [ + { + "id": "7c27346e-a23f-46f3-b4d5-88a323fd437d", + "workPeriodId": "a3bbd01d-535d-4f02-8524-0d61395b84e9", + "challengeId": "00000000-0000-0000-0000-000000000000", + "amount": 210.19, + "status": "completed", + "billingAccountId": 80000071, + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-05-09T21:33:46.507Z", + "updatedAt": "2021-05-09T21:33:46.507Z" + } + ] + }, + { + "id": "fa030947-2f2f-4976-82ea-0a22ee96635a", + "resourceBookingId": "c0a12936-77ef-46fa-8c75-6996339e79f6", + "userHandle": "sachin-wipro", + "projectId": 111, + "startDate": "2020-10-11", + "endDate": "2020-10-17", + "daysWorked": 4, + "memberRate": 10.82, + "customerRate": 30.71, + "paymentStatus": "pending", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "createdAt": "2021-05-09T21:25:47.815Z", + "updatedAt": "2021-05-09T21:45:41.810Z", + "payments": [ + { + "id": "2a4d1488-d27b-4bc8-af68-1a2b893774de", + "workPeriodId": "fa030947-2f2f-4976-82ea-0a22ee96635a", + "challengeId": "00000000-0000-0000-0000-000000000000", + "amount": 477.97, + "status": "completed", + "billingAccountId": 80000071, + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-05-09T21:34:31.474Z", + "updatedAt": "2021-05-09T21:34:31.474Z" + } + ] + }, + { + "id": "61c1e7e3-5e0a-4892-9099-872bc4c11a22", + "resourceBookingId": "c0a12936-77ef-46fa-8c75-6996339e79f6", + "userHandle": "sachin-wipro", + "projectId": 111, + "startDate": "2020-10-04", + "endDate": "2020-10-10", + "daysWorked": 4, + "memberRate": 16.71, + "customerRate": 24.11, + "paymentStatus": "pending", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "createdAt": "2021-05-09T21:25:47.841Z", + "updatedAt": "2021-05-09T21:45:27.504Z", + "payments": [ + { + "id": "fcd10a26-3548-4f9b-9e2b-20397d057800", + "workPeriodId": "61c1e7e3-5e0a-4892-9099-872bc4c11a22", + "challengeId": "00000000-0000-0000-0000-000000000000", + "amount": 494.46, + "status": "cancelled", + "billingAccountId": 80000071, + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-05-09T21:32:41.381Z", + "updatedAt": "2021-05-09T21:32:41.381Z" + }, + { + "id": "40e862a0-8772-4587-88b4-23acff8eb2e0", + "workPeriodId": "61c1e7e3-5e0a-4892-9099-872bc4c11a22", + "challengeId": "00000000-0000-0000-0000-000000000000", + "amount": 417.42, + "status": "cancelled", + "billingAccountId": 80000071, + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-05-09T21:32:40.091Z", + "updatedAt": "2021-05-09T21:32:40.091Z" + } + ] + } + ] + }, + { + "id": "d5de4575-c977-4f4b-bd5b-bb82360dd365", + "projectId": 111, + "userId": "6d0509c7-5f12-4d84-9a19-8e80ef7ddd66", + "jobId": "a8adb1f8-a6ee-48b1-8661-33bd851b726e", + "status": "closed", + "startDate": "2021-03-27", + "endDate": "2021-04-27", + "memberRate": 13.23, + "customerRate": 13, + "rateType": "hourly", + "billingAccountId": 80000071, + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-05-09T21:26:16.403Z", + "updatedAt": "2021-05-09T21:26:16.403Z", + "workPeriods": [ + { + "id": "b0758857-0221-47a5-a444-e263e5d9e1cf", + "resourceBookingId": "d5de4575-c977-4f4b-bd5b-bb82360dd365", + "userHandle": "aaaa", + "projectId": 111, + "startDate": "2021-03-21", + "endDate": "2021-03-27", + "daysWorked": 5, + "memberRate": 27.06, + "customerRate": 22.77, + "paymentStatus": "pending", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "createdAt": "2021-05-09T21:26:17.187Z", + "updatedAt": "2021-05-09T21:46:59.354Z", + "payments": [ + { + "id": "c8be508d-2eb5-4712-8bd7-1b28e870abc2", + "workPeriodId": "b0758857-0221-47a5-a444-e263e5d9e1cf", + "challengeId": "00000000-0000-0000-0000-000000000000", + "amount": 448.51, + "status": "completed", + "billingAccountId": 80000071, + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-05-09T21:34:02.733Z", + "updatedAt": "2021-05-09T21:34:02.733Z" + }, + { + "id": "9785ae89-05dc-4bcc-a030-52bd0e681d41", + "workPeriodId": "b0758857-0221-47a5-a444-e263e5d9e1cf", + "challengeId": "00000000-0000-0000-0000-000000000000", + "amount": 168.54, + "status": "cancelled", + "billingAccountId": 80000071, + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-05-09T21:34:01.410Z", + "updatedAt": "2021-05-09T21:34:01.410Z" + } + ] + }, + { + "id": "176db0d0-474f-4590-831a-547d596c01b4", + "resourceBookingId": "d5de4575-c977-4f4b-bd5b-bb82360dd365", + "userHandle": "aaaa", + "projectId": 111, + "startDate": "2021-03-28", + "endDate": "2021-04-03", + "daysWorked": 5, + "memberRate": 6.11, + "customerRate": 14.63, + "paymentStatus": "cancelled", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "createdAt": "2021-05-09T21:26:17.168Z", + "updatedAt": "2021-05-09T21:47:05.373Z", + "payments": [ + { + "id": "c3b71f96-7680-459b-82b2-f6eb3c3f6c8f", + "workPeriodId": "176db0d0-474f-4590-831a-547d596c01b4", + "challengeId": "00000000-0000-0000-0000-000000000000", + "amount": 119.32, + "status": "completed", + "billingAccountId": 80000071, + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-05-09T21:31:18.342Z", + "updatedAt": "2021-05-09T21:31:18.342Z" + }, + { + "id": "3ed31706-0e99-4084-81f4-b126a1a68db6", + "workPeriodId": "176db0d0-474f-4590-831a-547d596c01b4", + "challengeId": "00000000-0000-0000-0000-000000000000", + "amount": 144.16, + "status": "completed", + "billingAccountId": 80000071, + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-05-09T21:31:17.193Z", + "updatedAt": "2021-05-09T21:31:17.193Z" + } + ] + }, + { + "id": "5a174833-cb08-49f5-b077-cffb8e60ca01", + "resourceBookingId": "d5de4575-c977-4f4b-bd5b-bb82360dd365", + "userHandle": "aaaa", + "projectId": 111, + "startDate": "2021-04-04", + "endDate": "2021-04-10", + "daysWorked": 5, + "memberRate": 4.91, + "customerRate": 24.11, + "paymentStatus": "pending", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "createdAt": "2021-05-09T21:26:17.165Z", + "updatedAt": "2021-05-09T21:47:12.015Z", + "payments": [ + { + "id": "69445cbf-6d94-49a5-b2aa-65459ec78594", + "workPeriodId": "5a174833-cb08-49f5-b077-cffb8e60ca01", + "challengeId": "00000000-0000-0000-0000-000000000000", + "amount": 417.42, + "status": "completed", + "billingAccountId": 80000071, + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-05-09T21:32:33.664Z", + "updatedAt": "2021-05-09T21:32:33.664Z" + }, + { + "id": "663f11df-7832-431a-a46e-ad8c890ae52b", + "workPeriodId": "5a174833-cb08-49f5-b077-cffb8e60ca01", + "challengeId": "00000000-0000-0000-0000-000000000000", + "amount": 55.6, + "status": "cancelled", + "billingAccountId": 80000071, + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-05-09T21:32:32.606Z", + "updatedAt": "2021-05-09T21:32:32.606Z" + } + ] + }, + { + "id": "8c9db4fd-78ad-4e59-acba-462487b74c3a", + "resourceBookingId": "d5de4575-c977-4f4b-bd5b-bb82360dd365", + "userHandle": "aaaa", + "projectId": 111, + "startDate": "2021-04-18", + "endDate": "2021-04-24", + "daysWorked": 2, + "memberRate": 27.46, + "customerRate": 25.57, + "paymentStatus": "completed", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "createdAt": "2021-05-09T21:26:17.200Z", + "updatedAt": "2021-05-09T21:47:25.687Z", + "payments": [ + { + "id": "8eb8fc37-5ab0-4480-8806-3d3c57ab38e1", + "workPeriodId": "8c9db4fd-78ad-4e59-acba-462487b74c3a", + "challengeId": "00000000-0000-0000-0000-000000000000", + "amount": 496.54, + "status": "completed", + "billingAccountId": 80000071, + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-05-09T21:33:07.419Z", + "updatedAt": "2021-05-09T21:33:07.419Z" + }, + { + "id": "f65930b7-d61d-4923-bdab-54848661f151", + "workPeriodId": "8c9db4fd-78ad-4e59-acba-462487b74c3a", + "challengeId": "00000000-0000-0000-0000-000000000000", + "amount": 57.79, + "status": "completed", + "billingAccountId": 80000071, + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-05-09T21:33:06.108Z", + "updatedAt": "2021-05-09T21:33:06.108Z" + } + ] + }, + { + "id": "18881107-cc17-4087-9b2b-a74f04187f73", + "resourceBookingId": "d5de4575-c977-4f4b-bd5b-bb82360dd365", + "userHandle": "aaaa", + "projectId": 111, + "startDate": "2021-04-11", + "endDate": "2021-04-17", + "daysWorked": 2, + "memberRate": 22.82, + "customerRate": 2.32, + "paymentStatus": "pending", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "createdAt": "2021-05-09T21:26:17.202Z", + "updatedAt": "2021-05-09T21:47:30.586Z", + "payments": [ + { + "id": "c456755e-0432-4656-848b-64f9c5dc8f25", + "workPeriodId": "18881107-cc17-4087-9b2b-a74f04187f73", + "challengeId": "00000000-0000-0000-0000-000000000000", + "amount": 32.92, + "status": "cancelled", + "billingAccountId": 80000071, + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-05-09T21:31:27.102Z", + "updatedAt": "2021-05-09T21:31:27.102Z" + }, + { + "id": "dd8f5c08-d6a1-4fd2-b6bd-85fb6425d13d", + "workPeriodId": "18881107-cc17-4087-9b2b-a74f04187f73", + "challengeId": "00000000-0000-0000-0000-000000000000", + "amount": 372.18, + "status": "completed", + "billingAccountId": 80000071, + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-05-09T21:31:25.690Z", + "updatedAt": "2021-05-09T21:31:25.690Z" + } + ] + }, + { + "id": "9b455e21-e186-4622-923a-f115d23549d1", + "resourceBookingId": "d5de4575-c977-4f4b-bd5b-bb82360dd365", + "userHandle": "aaaa", + "projectId": 111, + "startDate": "2021-04-25", + "endDate": "2021-05-01", + "daysWorked": 2, + "memberRate": 22.82, + "customerRate": 10.1, + "paymentStatus": "cancelled", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "createdAt": "2021-05-09T21:26:17.161Z", + "updatedAt": "2021-05-09T21:47:19.034Z", + "payments": [ + { + "id": "10584b23-5ab2-44e2-a927-e020c08e4f84", + "workPeriodId": "9b455e21-e186-4622-923a-f115d23549d1", + "challengeId": "00000000-0000-0000-0000-000000000000", + "amount": 293.79, + "status": "cancelled", + "billingAccountId": 80000071, + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-05-09T21:33:29.348Z", + "updatedAt": "2021-05-09T21:33:29.348Z" + }, + { + "id": "6d59a499-44e3-41e2-8368-5baee86dd8ab", + "workPeriodId": "9b455e21-e186-4622-923a-f115d23549d1", + "challengeId": "00000000-0000-0000-0000-000000000000", + "amount": 57.79, + "status": "cancelled", + "billingAccountId": 80000071, + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-05-09T21:33:28.108Z", + "updatedAt": "2021-05-09T21:33:28.108Z" + } + ] + } + ] + }, + { + "id": "c4e86eae-ead3-49b7-90ab-92c3b4a3be0c", + "projectId": 111, + "userId": "a2ffdeed-704d-4cf7-b70a-93fcf61de598", + "jobId": "b28f4e67-324f-4ada-a23a-c27499053ed4", + "status": "closed", + "startDate": "2021-05-10", + "endDate": "2021-06-15", + "memberRate": 13.23, + "customerRate": 13, + "rateType": "hourly", + "billingAccountId": 80000071, + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-05-09T21:27:15.093Z", + "updatedAt": "2021-05-09T21:27:15.093Z", + "workPeriods": [ + { + "id": "ac0ae325-8d77-4a73-bd85-5361165801cd", + "resourceBookingId": "c4e86eae-ead3-49b7-90ab-92c3b4a3be0c", + "userHandle": "lakshmiaconnmgr", + "projectId": 111, + "startDate": "2021-06-06", + "endDate": "2021-06-12", + "daysWorked": 3, + "memberRate": 13.74, + "customerRate": 14.57, + "paymentStatus": "pending", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "createdAt": "2021-05-09T21:27:15.951Z", + "updatedAt": "2021-05-09T21:46:12.086Z", + "payments": [ + { + "id": "00640d2d-8330-445a-b022-aa687033b2b3", + "workPeriodId": "ac0ae325-8d77-4a73-bd85-5361165801cd", + "challengeId": "00000000-0000-0000-0000-000000000000", + "amount": 275.73, + "status": "completed", + "billingAccountId": 80000071, + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-05-09T21:33:54.315Z", + "updatedAt": "2021-05-09T21:33:54.315Z" + }, + { + "id": "05d09e2b-02a0-4d33-b6db-0f69a98154c6", + "workPeriodId": "ac0ae325-8d77-4a73-bd85-5361165801cd", + "challengeId": "00000000-0000-0000-0000-000000000000", + "amount": 374.34, + "status": "completed", + "billingAccountId": 80000071, + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-05-09T21:33:53.131Z", + "updatedAt": "2021-05-09T21:33:53.131Z" + } + ] + }, + { + "id": "9d914249-82f2-422e-9ba6-c281da411266", + "resourceBookingId": "c4e86eae-ead3-49b7-90ab-92c3b4a3be0c", + "userHandle": "lakshmiaconnmgr", + "projectId": 111, + "startDate": "2021-05-16", + "endDate": "2021-05-22", + "daysWorked": 5, + "memberRate": null, + "customerRate": 9.46, + "paymentStatus": "cancelled", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "createdAt": "2021-05-09T21:27:16.017Z", + "updatedAt": "2021-05-09T21:46:21.053Z", + "payments": [ + { + "id": "6036c7cc-b180-4f50-8163-5fd2541c66b5", + "workPeriodId": "9d914249-82f2-422e-9ba6-c281da411266", + "challengeId": "00000000-0000-0000-0000-000000000000", + "amount": 494.46, + "status": "completed", + "billingAccountId": 80000071, + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-05-09T21:33:40.984Z", + "updatedAt": "2021-05-09T21:33:40.984Z" + } + ] + }, + { + "id": "4ae26d58-1910-4ace-9f09-4c62c8df6031", + "resourceBookingId": "c4e86eae-ead3-49b7-90ab-92c3b4a3be0c", + "userHandle": "lakshmiaconnmgr", + "projectId": 111, + "startDate": "2021-06-13", + "endDate": "2021-06-19", + "daysWorked": 3, + "memberRate": 15.61, + "customerRate": 2.1, + "paymentStatus": "partially-completed", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "createdAt": "2021-05-09T21:27:15.972Z", + "updatedAt": "2021-05-09T21:45:57.739Z", + "payments": [ + { + "id": "e623d9c7-caa9-4e58-83f1-44741b1169f8", + "workPeriodId": "4ae26d58-1910-4ace-9f09-4c62c8df6031", + "challengeId": "00000000-0000-0000-0000-000000000000", + "amount": 293.79, + "status": "completed", + "billingAccountId": 80000071, + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-05-09T21:32:19.371Z", + "updatedAt": "2021-05-09T21:32:19.371Z" + } + ] + }, + { + "id": "94dde794-b730-4e05-8ea6-dcc5b541d43e", + "resourceBookingId": "c4e86eae-ead3-49b7-90ab-92c3b4a3be0c", + "userHandle": "lakshmiaconnmgr", + "projectId": 111, + "startDate": "2021-05-23", + "endDate": "2021-05-29", + "daysWorked": 3, + "memberRate": 10.82, + "customerRate": 29.89, + "paymentStatus": "partially-completed", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "createdAt": "2021-05-09T21:27:15.991Z", + "updatedAt": "2021-05-09T21:46:02.038Z", + "payments": [ + { + "id": "be9706ac-c6cb-4fff-894b-8719bcf634dc", + "workPeriodId": "94dde794-b730-4e05-8ea6-dcc5b541d43e", + "challengeId": "00000000-0000-0000-0000-000000000000", + "amount": 275.73, + "status": "cancelled", + "billingAccountId": 80000071, + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-05-09T21:33:21.933Z", + "updatedAt": "2021-05-09T21:33:21.933Z" + }, + { + "id": "c7013bf0-17b5-4b15-826b-385fad41caf4", + "workPeriodId": "94dde794-b730-4e05-8ea6-dcc5b541d43e", + "challengeId": "00000000-0000-0000-0000-000000000000", + "amount": 144.16, + "status": "cancelled", + "billingAccountId": 80000071, + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-05-09T21:33:20.680Z", + "updatedAt": "2021-05-09T21:33:20.680Z" + } + ] + }, + { + "id": "fd6034b3-b6a0-4a3f-9a5d-fc077c08c680", + "resourceBookingId": "c4e86eae-ead3-49b7-90ab-92c3b4a3be0c", + "userHandle": "lakshmiaconnmgr", + "projectId": 111, + "startDate": "2021-05-30", + "endDate": "2021-06-05", + "daysWorked": 3, + "memberRate": 29.32, + "customerRate": 29.89, + "paymentStatus": "pending", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "createdAt": "2021-05-09T21:27:16.013Z", + "updatedAt": "2021-05-09T21:45:53.796Z", + "payments": [ + { + "id": "fc577d14-78e8-404c-a17b-ab496e4041d8", + "workPeriodId": "fd6034b3-b6a0-4a3f-9a5d-fc077c08c680", + "challengeId": "00000000-0000-0000-0000-000000000000", + "amount": 203.74, + "status": "completed", + "billingAccountId": 80000071, + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-05-09T21:34:41.520Z", + "updatedAt": "2021-05-09T21:34:41.520Z" + }, + { + "id": "fbc2d96f-f6c6-4a4d-b737-14a3564b7f70", + "workPeriodId": "fd6034b3-b6a0-4a3f-9a5d-fc077c08c680", + "challengeId": "00000000-0000-0000-0000-000000000000", + "amount": 448.51, + "status": "cancelled", + "billingAccountId": 80000071, + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-05-09T21:34:38.700Z", + "updatedAt": "2021-05-09T21:34:38.700Z" + }, + { + "id": "10fd3b3e-f5b2-42cc-91d4-54c73c003aae", + "workPeriodId": "fd6034b3-b6a0-4a3f-9a5d-fc077c08c680", + "challengeId": "00000000-0000-0000-0000-000000000000", + "amount": 477.97, + "status": "completed", + "billingAccountId": 80000071, + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-05-09T21:34:37.374Z", + "updatedAt": "2021-05-09T21:34:37.374Z" + }, + { + "id": "6e1a114f-bfac-4ab8-93d6-e47206200540", + "workPeriodId": "fd6034b3-b6a0-4a3f-9a5d-fc077c08c680", + "challengeId": "00000000-0000-0000-0000-000000000000", + "amount": 494.46, + "status": "completed", + "billingAccountId": 80000071, + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-05-09T21:34:40.036Z", + "updatedAt": "2021-05-09T21:34:40.036Z" + } + ] + }, + { + "id": "6a567293-7189-4b14-82c9-57bd3d0eab20", + "resourceBookingId": "c4e86eae-ead3-49b7-90ab-92c3b4a3be0c", + "userHandle": "lakshmiaconnmgr", + "projectId": 111, + "startDate": "2021-05-09", + "endDate": "2021-05-15", + "daysWorked": 3, + "memberRate": 24.03, + "customerRate": 24.11, + "paymentStatus": "completed", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "createdAt": "2021-05-09T21:27:15.959Z", + "updatedAt": "2021-05-09T21:46:07.315Z", + "payments": [ + { + "id": "e386f5a1-2856-4cc5-8304-1598e5683a0f", + "workPeriodId": "6a567293-7189-4b14-82c9-57bd3d0eab20", + "challengeId": "00000000-0000-0000-0000-000000000000", + "amount": 57.79, + "status": "cancelled", + "billingAccountId": 80000071, + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-05-09T21:32:47.852Z", + "updatedAt": "2021-05-09T21:32:47.852Z" + } + ] + } + ] + }, + { + "id": "d6103727-6615-4168-8169-0485577bfb3f", + "projectId": 111, + "userId": "bef43122-426b-4b2b-acdd-9b5b3bd1c0bf", + "jobId": "a8adb1f8-a6ee-48b1-8661-33bd851b726e", + "status": "placed", + "startDate": "2021-03-27", + "endDate": "2021-04-27", + "memberRate": 13.23, + "customerRate": 13, + "rateType": "hourly", + "billingAccountId": 80000071, + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-05-09T21:27:11.914Z", + "updatedAt": "2021-05-09T21:27:11.914Z", + "workPeriods": [ + { + "id": "d111a56f-593d-452e-9787-551bea504c92", + "resourceBookingId": "d6103727-6615-4168-8169-0485577bfb3f", + "userHandle": "testcat", + "projectId": 111, + "startDate": "2021-04-04", + "endDate": "2021-04-10", + "daysWorked": 4, + "memberRate": 23.2, + "customerRate": 30.71, + "paymentStatus": "pending", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "createdAt": "2021-05-09T21:27:12.731Z", + "updatedAt": "2021-05-09T21:48:08.381Z", + "payments": [ + { + "id": "fa9bd31c-6c83-4ee4-9d45-a833cfe821f5", + "workPeriodId": "d111a56f-593d-452e-9787-551bea504c92", + "challengeId": "00000000-0000-0000-0000-000000000000", + "amount": 271.42, + "status": "completed", + "billingAccountId": 80000071, + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-05-09T21:34:11.662Z", + "updatedAt": "2021-05-09T21:34:11.662Z" + }, + { + "id": "abb79afc-a370-4625-a067-a3b57c9b4700", + "workPeriodId": "d111a56f-593d-452e-9787-551bea504c92", + "challengeId": "00000000-0000-0000-0000-000000000000", + "amount": 448.51, + "status": "completed", + "billingAccountId": 80000071, + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-05-09T21:34:10.371Z", + "updatedAt": "2021-05-09T21:34:10.371Z" + } + ] + }, + { + "id": "061f31fb-4f8c-462f-92c2-e5d275c45fde", + "resourceBookingId": "d6103727-6615-4168-8169-0485577bfb3f", + "userHandle": "testcat", + "projectId": 111, + "startDate": "2021-03-28", + "endDate": "2021-04-03", + "daysWorked": 2, + "memberRate": 8.09, + "customerRate": 22.15, + "paymentStatus": "pending", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "createdAt": "2021-05-09T21:27:12.733Z", + "updatedAt": "2021-05-09T21:47:38.022Z", + "payments": [ + { + "id": "c658d66e-86e1-49c7-8051-2b9a017935ad", + "workPeriodId": "061f31fb-4f8c-462f-92c2-e5d275c45fde", + "challengeId": "00000000-0000-0000-0000-000000000000", + "amount": 248.38, + "status": "completed", + "billingAccountId": 80000071, + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-05-09T21:30:41.304Z", + "updatedAt": "2021-05-09T21:30:41.304Z" + }, + { + "id": "3770680c-8045-43d4-8baf-cb7b3b714d39", + "workPeriodId": "061f31fb-4f8c-462f-92c2-e5d275c45fde", + "challengeId": "00000000-0000-0000-0000-000000000000", + "amount": 477.97, + "status": "cancelled", + "billingAccountId": 80000071, + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-05-09T21:30:42.711Z", + "updatedAt": "2021-05-09T21:30:42.711Z" + } + ] + }, + { + "id": "5904b1d9-cb50-4b5d-8103-6741fec2f86b", + "resourceBookingId": "d6103727-6615-4168-8169-0485577bfb3f", + "userHandle": "testcat", + "projectId": 111, + "startDate": "2021-04-18", + "endDate": "2021-04-24", + "daysWorked": 2, + "memberRate": 22.82, + "customerRate": 4.07, + "paymentStatus": "cancelled", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "createdAt": "2021-05-09T21:27:12.746Z", + "updatedAt": "2021-05-09T21:47:44.291Z", + "payments": [ + { + "id": "be4d5099-8b8e-45e2-b6cd-ab1997f57e26", + "workPeriodId": "5904b1d9-cb50-4b5d-8103-6741fec2f86b", + "challengeId": "00000000-0000-0000-0000-000000000000", + "amount": 477.97, + "status": "completed", + "billingAccountId": 80000071, + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-05-09T21:32:26.174Z", + "updatedAt": "2021-05-09T21:32:26.174Z" + }, + { + "id": "dfc9bed6-78f2-407e-a7e4-abea9a3d3b46", + "workPeriodId": "5904b1d9-cb50-4b5d-8103-6741fec2f86b", + "challengeId": "00000000-0000-0000-0000-000000000000", + "amount": 48.51, + "status": "cancelled", + "billingAccountId": 80000071, + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-05-09T21:32:27.398Z", + "updatedAt": "2021-05-09T21:32:27.398Z" + } + ] + }, + { + "id": "6ed56eb5-cadc-45f8-bbdf-3f408948c274", + "resourceBookingId": "d6103727-6615-4168-8169-0485577bfb3f", + "userHandle": "testcat", + "projectId": 111, + "startDate": "2021-03-21", + "endDate": "2021-03-27", + "daysWorked": 4, + "memberRate": 22.85, + "customerRate": 29.89, + "paymentStatus": "completed", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "createdAt": "2021-05-09T21:27:12.737Z", + "updatedAt": "2021-05-09T21:47:58.216Z", + "payments": [ + { + "id": "3bf29da2-581c-4f9c-8b0f-ff3c876848a0", + "workPeriodId": "6ed56eb5-cadc-45f8-bbdf-3f408948c274", + "challengeId": "00000000-0000-0000-0000-000000000000", + "amount": 293.79, + "status": "cancelled", + "billingAccountId": 80000071, + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-05-09T21:32:59.500Z", + "updatedAt": "2021-05-09T21:32:59.500Z" + }, + { + "id": "ea3bdc7a-7c14-4ac1-955d-2540589fcfa6", + "workPeriodId": "6ed56eb5-cadc-45f8-bbdf-3f408948c274", + "challengeId": "00000000-0000-0000-0000-000000000000", + "amount": 448.51, + "status": "cancelled", + "billingAccountId": 80000071, + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-05-09T21:33:00.899Z", + "updatedAt": "2021-05-09T21:33:00.899Z" + } + ] + }, + { + "id": "6adbf80c-43aa-41ad-b7db-544dc76f9b1c", + "resourceBookingId": "d6103727-6615-4168-8169-0485577bfb3f", + "userHandle": "testcat", + "projectId": 111, + "startDate": "2021-04-25", + "endDate": "2021-05-01", + "daysWorked": 0, + "memberRate": 29.32, + "customerRate": 22.15, + "paymentStatus": "completed", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "createdAt": "2021-05-09T21:27:12.794Z", + "updatedAt": "2021-05-09T21:47:51.348Z", + "payments": [ + { + "id": "e85008c3-feff-40ab-bf4c-bc80f0bb5288", + "workPeriodId": "6adbf80c-43aa-41ad-b7db-544dc76f9b1c", + "challengeId": "00000000-0000-0000-0000-000000000000", + "amount": 460.88, + "status": "cancelled", + "billingAccountId": 80000071, + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-05-09T21:32:53.856Z", + "updatedAt": "2021-05-09T21:32:53.856Z" + } + ] + }, + { + "id": "0c825dec-6e7b-4dde-943a-f3f8354219cc", + "resourceBookingId": "d6103727-6615-4168-8169-0485577bfb3f", + "userHandle": "testcat", + "projectId": 111, + "startDate": "2021-04-11", + "endDate": "2021-04-17", + "daysWorked": 4, + "memberRate": 5.59, + "customerRate": 30.54, + "paymentStatus": "partially-completed", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "createdAt": "2021-05-09T21:27:12.783Z", + "updatedAt": "2021-05-09T21:48:03.740Z", + "payments": [ + { + "id": "5bdd5c22-d9b7-428c-b084-d0950a18bc37", + "workPeriodId": "0c825dec-6e7b-4dde-943a-f3f8354219cc", + "challengeId": "00000000-0000-0000-0000-000000000000", + "amount": 57.79, + "status": "cancelled", + "billingAccountId": 80000071, + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-05-09T21:30:49.123Z", + "updatedAt": "2021-05-09T21:30:49.123Z" + }, + { + "id": "78641310-ad51-40a3-a0fd-fdd8d15455b9", + "workPeriodId": "0c825dec-6e7b-4dde-943a-f3f8354219cc", + "challengeId": "00000000-0000-0000-0000-000000000000", + "amount": 417.42, + "status": "cancelled", + "billingAccountId": 80000071, + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-05-09T21:30:50.460Z", + "updatedAt": "2021-05-09T21:30:50.460Z" + } + ] + } + ] + }, + { + "id": "314084fc-e854-4b62-8901-03ea9bbf2ffa", + "projectId": 111, + "userId": "a55fe1bc-1754-45fa-9adc-cf3d6d7c377a", + "jobId": "b28f4e67-324f-4ada-a23a-c27499053ed4", + "status": "cancelled", + "startDate": "2020-12-27", + "endDate": "2021-01-27", + "memberRate": 13.23, + "customerRate": 13, + "rateType": "hourly", + "billingAccountId": 80000071, + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-05-09T21:25:50.450Z", + "updatedAt": "2021-05-09T21:25:50.450Z", + "workPeriods": [ + { + "id": "13f22f72-9240-43bb-ba0c-618d0b24ad8c", + "resourceBookingId": "314084fc-e854-4b62-8901-03ea9bbf2ffa", + "userHandle": "pshah_manager", + "projectId": 111, + "startDate": "2021-01-17", + "endDate": "2021-01-23", + "daysWorked": 5, + "memberRate": 24.35, + "customerRate": 4.79, + "paymentStatus": "pending", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "createdAt": "2021-05-09T21:25:51.398Z", + "updatedAt": "2021-05-09T21:45:01.792Z", + "payments": [ + { + "id": "381af41e-6b0a-49fe-987f-1bcb03fda571", + "workPeriodId": "13f22f72-9240-43bb-ba0c-618d0b24ad8c", + "challengeId": "00000000-0000-0000-0000-000000000000", + "amount": 460.88, + "status": "completed", + "billingAccountId": 80000071, + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-05-09T21:31:08.119Z", + "updatedAt": "2021-05-09T21:31:08.119Z" + }, + { + "id": "1d2b92e8-194f-477a-97f8-e104056e6b10", + "workPeriodId": "13f22f72-9240-43bb-ba0c-618d0b24ad8c", + "challengeId": "00000000-0000-0000-0000-000000000000", + "amount": 39.66, + "status": "completed", + "billingAccountId": 80000071, + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-05-09T21:31:09.459Z", + "updatedAt": "2021-05-09T21:31:09.459Z" + } + ] + }, + { + "id": "0cf74043-b432-41a5-99d9-83420a6ad8ef", + "resourceBookingId": "314084fc-e854-4b62-8901-03ea9bbf2ffa", + "userHandle": "pshah_manager", + "projectId": 111, + "startDate": "2021-01-03", + "endDate": "2021-01-09", + "daysWorked": 2, + "memberRate": 13.74, + "customerRate": 21.1, + "paymentStatus": "cancelled", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "createdAt": "2021-05-09T21:25:51.419Z", + "updatedAt": "2021-05-09T21:44:51.852Z", + "payments": [ + { + "id": "ef951baa-a007-48db-a658-495c6eeda9bc", + "workPeriodId": "0cf74043-b432-41a5-99d9-83420a6ad8ef", + "challengeId": "00000000-0000-0000-0000-000000000000", + "amount": 448.51, + "status": "completed", + "billingAccountId": 80000071, + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-05-09T21:30:59.323Z", + "updatedAt": "2021-05-09T21:30:59.323Z" + }, + { + "id": "f0f85e56-6bf4-4e1f-a1ef-c31529efe4cd", + "workPeriodId": "0cf74043-b432-41a5-99d9-83420a6ad8ef", + "challengeId": "00000000-0000-0000-0000-000000000000", + "amount": 466.42, + "status": "cancelled", + "billingAccountId": 80000071, + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-05-09T21:30:58.017Z", + "updatedAt": "2021-05-09T21:30:58.017Z" + } + ] + }, + { + "id": "028287bf-6999-4fef-bdfa-1229b4e23ac1", + "resourceBookingId": "314084fc-e854-4b62-8901-03ea9bbf2ffa", + "userHandle": "pshah_manager", + "projectId": 111, + "startDate": "2021-01-24", + "endDate": "2021-01-30", + "daysWorked": 4, + "memberRate": 27.06, + "customerRate": 2.54, + "paymentStatus": "pending", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "createdAt": "2021-05-09T21:25:51.432Z", + "updatedAt": "2021-05-09T21:45:16.298Z", + "payments": [ + { + "id": "1cb5129e-8d92-4280-a946-8cb0f5757abc", + "workPeriodId": "028287bf-6999-4fef-bdfa-1229b4e23ac1", + "challengeId": "00000000-0000-0000-0000-000000000000", + "amount": 460.88, + "status": "cancelled", + "billingAccountId": 80000071, + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-05-09T21:30:33.549Z", + "updatedAt": "2021-05-09T21:30:33.549Z" + }, + { + "id": "b576f845-7dea-4b56-b0de-6ce15fd2c245", + "workPeriodId": "028287bf-6999-4fef-bdfa-1229b4e23ac1", + "challengeId": "00000000-0000-0000-0000-000000000000", + "amount": 477.97, + "status": "cancelled", + "billingAccountId": 80000071, + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-05-09T21:30:25.688Z", + "updatedAt": "2021-05-09T21:30:25.688Z" + } + ] + }, + { + "id": "e71f17b2-acb4-4c14-a492-8cab071fe2b5", + "resourceBookingId": "314084fc-e854-4b62-8901-03ea9bbf2ffa", + "userHandle": "pshah_manager", + "projectId": 111, + "startDate": "2020-12-27", + "endDate": "2021-01-02", + "daysWorked": 4, + "memberRate": 15.61, + "customerRate": 2.54, + "paymentStatus": "pending", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "createdAt": "2021-05-09T21:25:51.383Z", + "updatedAt": "2021-05-09T21:45:22.801Z", + "payments": [ + { + "id": "a376dfdc-3330-417b-916d-3a7d4f9ab384", + "workPeriodId": "e71f17b2-acb4-4c14-a492-8cab071fe2b5", + "challengeId": "00000000-0000-0000-0000-000000000000", + "amount": 466.42, + "status": "cancelled", + "billingAccountId": 80000071, + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-05-09T21:34:17.363Z", + "updatedAt": "2021-05-09T21:34:17.363Z" + } + ] + }, + { + "id": "32b977c9-386a-4159-a1c3-08169ee12f6e", + "resourceBookingId": "314084fc-e854-4b62-8901-03ea9bbf2ffa", + "userHandle": "pshah_manager", + "projectId": 111, + "startDate": "2021-01-10", + "endDate": "2021-01-16", + "daysWorked": 3, + "memberRate": 13.74, + "customerRate": 22.37, + "paymentStatus": "cancelled", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "createdAt": "2021-05-09T21:25:51.435Z", + "updatedAt": "2021-05-09T21:45:08.968Z", + "payments": [ + { + "id": "fa4c7e24-470f-4aef-a269-59b7e0b2bc05", + "workPeriodId": "32b977c9-386a-4159-a1c3-08169ee12f6e", + "challengeId": "00000000-0000-0000-0000-000000000000", + "amount": 460.88, + "status": "cancelled", + "billingAccountId": 80000071, + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-05-09T21:31:56.152Z", + "updatedAt": "2021-05-09T21:31:56.152Z" + }, + { + "id": "99e4bffb-90f8-411e-9a49-fc7779bd2c07", + "workPeriodId": "32b977c9-386a-4159-a1c3-08169ee12f6e", + "challengeId": "00000000-0000-0000-0000-000000000000", + "amount": 416.38, + "status": "completed", + "billingAccountId": 80000071, + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-05-09T21:31:57.470Z", + "updatedAt": "2021-05-09T21:31:57.470Z" + } + ] + } + ] + }, + { + "id": "d4134cc8-d306-45e2-bb76-cf3707b6df3e", + "projectId": 111, + "userId": "dd5adacb-444d-4992-8b7b-0c349be598db", + "jobId": "b28f4e67-324f-4ada-a23a-c27499053ed4", + "status": "placed", + "startDate": "2021-05-10", + "endDate": "2021-06-15", + "memberRate": 13.23, + "customerRate": 13, + "rateType": "hourly", + "billingAccountId": 80000071, + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": null, + "createdAt": "2021-05-09T21:26:30.065Z", + "updatedAt": "2021-05-09T21:26:30.065Z", + "workPeriods": [ + { + "id": "28bd80ec-ef91-4516-90d6-6979e6cc341c", + "resourceBookingId": "d4134cc8-d306-45e2-bb76-cf3707b6df3e", + "userHandle": "amy_admin", + "projectId": 111, + "startDate": "2021-05-23", + "endDate": "2021-05-29", + "daysWorked": 5, + "memberRate": 28.4, + "customerRate": 12.25, + "paymentStatus": "partially-completed", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "createdAt": "2021-05-09T21:26:30.824Z", + "updatedAt": "2021-05-09T21:46:34.331Z", + "payments": [ + { + "id": "4892cd43-a132-4ca9-a511-8d10cdc22f5d", + "workPeriodId": "28bd80ec-ef91-4516-90d6-6979e6cc341c", + "challengeId": "00000000-0000-0000-0000-000000000000", + "amount": 374.34, + "status": "completed", + "billingAccountId": 80000071, + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-05-09T21:31:43.808Z", + "updatedAt": "2021-05-09T21:31:43.808Z" + } + ] + }, + { + "id": "355c7114-753a-4f99-b026-1d1430bf5530", + "resourceBookingId": "d4134cc8-d306-45e2-bb76-cf3707b6df3e", + "userHandle": "amy_admin", + "projectId": 111, + "startDate": "2021-05-16", + "endDate": "2021-05-22", + "daysWorked": 5, + "memberRate": 9.26, + "customerRate": 16.44, + "paymentStatus": "pending", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "createdAt": "2021-05-09T21:26:30.865Z", + "updatedAt": "2021-05-09T21:46:39.040Z", + "payments": [ + { + "id": "d0ebcc96-70f2-4716-92d4-74e40af04387", + "workPeriodId": "355c7114-753a-4f99-b026-1d1430bf5530", + "challengeId": "00000000-0000-0000-0000-000000000000", + "amount": 416.38, + "status": "completed", + "billingAccountId": 80000071, + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-05-09T21:32:04.463Z", + "updatedAt": "2021-05-09T21:32:04.463Z" + }, + { + "id": "71b3b7d4-129c-4348-9ead-6f22eafa6db8", + "workPeriodId": "355c7114-753a-4f99-b026-1d1430bf5530", + "challengeId": "00000000-0000-0000-0000-000000000000", + "amount": 416.38, + "status": "completed", + "billingAccountId": 80000071, + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-05-09T21:32:05.827Z", + "updatedAt": "2021-05-09T21:32:05.827Z" + } + ] + }, + { + "id": "9c024b6a-229a-4b8d-ac03-a53e4e412a73", + "resourceBookingId": "d4134cc8-d306-45e2-bb76-cf3707b6df3e", + "userHandle": "amy_admin", + "projectId": 111, + "startDate": "2021-05-09", + "endDate": "2021-05-15", + "daysWorked": 5, + "memberRate": 5.59, + "customerRate": 18.55, + "paymentStatus": "pending", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "createdAt": "2021-05-09T21:26:30.813Z", + "updatedAt": "2021-05-09T21:46:53.821Z", + "payments": [ + { + "id": "28f285ec-0965-4904-901d-7ae5c5d8e220", + "workPeriodId": "9c024b6a-229a-4b8d-ac03-a53e4e412a73", + "challengeId": "00000000-0000-0000-0000-000000000000", + "amount": 496.54, + "status": "cancelled", + "billingAccountId": 80000071, + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-05-09T21:33:35.441Z", + "updatedAt": "2021-05-09T21:33:35.441Z" + } + ] + }, + { + "id": "48c4b614-6588-46c9-8b4f-54d3175ae47d", + "resourceBookingId": "d4134cc8-d306-45e2-bb76-cf3707b6df3e", + "userHandle": "amy_admin", + "projectId": 111, + "startDate": "2021-06-06", + "endDate": "2021-06-12", + "daysWorked": 5, + "memberRate": 16.02, + "customerRate": 30.71, + "paymentStatus": "cancelled", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "createdAt": "2021-05-09T21:26:30.878Z", + "updatedAt": "2021-05-09T21:46:27.840Z", + "payments": [ + { + "id": "e1f9634a-4c3b-4dcd-ad81-3703c807a820", + "workPeriodId": "48c4b614-6588-46c9-8b4f-54d3175ae47d", + "challengeId": "00000000-0000-0000-0000-000000000000", + "amount": 293.79, + "status": "completed", + "billingAccountId": 80000071, + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-05-09T21:32:12.499Z", + "updatedAt": "2021-05-09T21:32:12.499Z" + } + ] + }, + { + "id": "91fcf91f-b2cf-4909-8f03-b5efc0732b28", + "resourceBookingId": "d4134cc8-d306-45e2-bb76-cf3707b6df3e", + "userHandle": "amy_admin", + "projectId": 111, + "startDate": "2021-06-13", + "endDate": "2021-06-19", + "daysWorked": 5, + "memberRate": 1.53, + "customerRate": 2.1, + "paymentStatus": "completed", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "createdAt": "2021-05-09T21:26:30.893Z", + "updatedAt": "2021-05-09T21:46:44.896Z", + "payments": [ + { + "id": "d36afd1d-1f76-4f2d-b630-69bf85796496", + "workPeriodId": "91fcf91f-b2cf-4909-8f03-b5efc0732b28", + "challengeId": "00000000-0000-0000-0000-000000000000", + "amount": 494.46, + "status": "cancelled", + "billingAccountId": 80000071, + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-05-09T21:33:12.838Z", + "updatedAt": "2021-05-09T21:33:12.838Z" + }, + { + "id": "71750282-0ffe-46ed-b8c2-37e36c148833", + "workPeriodId": "91fcf91f-b2cf-4909-8f03-b5efc0732b28", + "challengeId": "00000000-0000-0000-0000-000000000000", + "amount": 203.74, + "status": "cancelled", + "billingAccountId": 80000071, + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-05-09T21:33:14.202Z", + "updatedAt": "2021-05-09T21:33:14.202Z" + } + ] + }, + { + "id": "311a692f-18bc-4eb6-a6d0-06cf3dbd1637", + "resourceBookingId": "d4134cc8-d306-45e2-bb76-cf3707b6df3e", + "userHandle": "amy_admin", + "projectId": 111, + "startDate": "2021-05-30", + "endDate": "2021-06-05", + "daysWorked": 5, + "memberRate": 13.07, + "customerRate": 10.1, + "paymentStatus": "completed", + "createdBy": "00000000-0000-0000-0000-000000000000", + "updatedBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "createdAt": "2021-05-09T21:26:30.875Z", + "updatedAt": "2021-05-09T21:46:49.092Z", + "payments": [ + { + "id": "875c7250-50fa-453f-99d0-e76260648cd1", + "workPeriodId": "311a692f-18bc-4eb6-a6d0-06cf3dbd1637", + "challengeId": "00000000-0000-0000-0000-000000000000", + "amount": 248.38, + "status": "cancelled", + "billingAccountId": 80000071, + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-05-09T21:31:50.023Z", + "updatedAt": "2021-05-09T21:31:50.023Z" + } + ] + } + ] } - ] - } - ], - "ResourceBooking": [ - { - "id": "08f5e4b9-1088-496d-91a7-5b22a3583e3c", - "projectId": 111, - "userId": "213d2dd9-1fc3-4eda-ad97-2d56e2a84a1e", - "jobId": "2d5e2a52-e0dd-4cd9-8f4c-7cffa43951d0", - "status": "placed", - "startDate": "2021-01-25", - "endDate": "2021-01-31", - "memberRate": 1000, - "customerRate": 1200, - "rateType": "weekly", - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "createdAt": "2021-01-28T19:39:30.052Z", - "updatedAt": "2021-01-28T19:40:25.260Z" - }, - { - "id": "7d967fed-9792-4768-98a7-0b644aa84f2e", - "projectId": 111, - "userId": "05e988b7-7d54-4c10-ada1-1a04870a88a8", - "jobId": "2d5e2a52-e0dd-4cd9-8f4c-7cffa43951d0", - "status": "in-review", - "startDate": "2021-03-25", - "endDate": "2021-05-31", - "memberRate": 1000, - "customerRate": 1200, - "rateType": "weekly", - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "createdAt": "2021-01-28T19:39:35.571Z", - "updatedAt": "2021-01-28T19:40:30.291Z" - }, - { - "id": "0a6799d7-f5d1-456b-8bf1-90619284b295", - "projectId": 111, - "userId": "6d0509c7-5f12-4d84-9a19-8e80ef7ddd66", - "jobId": "2d5e2a52-e0dd-4cd9-8f4c-7cffa43951d0", - "status": "placed", - "startDate": "2021-02-27", - "endDate": "2021-03-15", - "memberRate": 2000, - "customerRate": 2500, - "rateType": "weekly", - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "createdAt": "2021-01-28T19:40:04.761Z", - "updatedAt": "2021-01-28T19:40:52.303Z" - }, - { - "id": "35e1abd8-1890-4664-bb52-aade382d7b66", - "projectId": 111, - "userId": "a2ffdeed-704d-4cf7-b70a-93fcf61de598", - "jobId": "2d5e2a52-e0dd-4cd9-8f4c-7cffa43951d0", - "status": "closed", - "startDate": "2021-02-25", - "endDate": "2021-04-01", - "memberRate": 1000, - "customerRate": 1200, - "rateType": "weekly", - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "createdAt": "2021-01-28T19:39:41.205Z", - "updatedAt": "2021-01-28T19:40:34.859Z" - }, - { - "id": "51b45f5d-5df2-46d5-9c3d-8a1323df38dd", - "projectId": 111, - "userId": "dd5adacb-444d-4992-8b7b-0c349be598db", - "jobId": "2d5e2a52-e0dd-4cd9-8f4c-7cffa43951d0", - "status": "placed", - "startDate": "2021-03-18", - "endDate": "2021-05-28", - "memberRate": 800, - "customerRate": 1000, - "rateType": "weekly", - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "createdAt": "2021-01-28T19:39:59.432Z", - "updatedAt": "2021-01-28T19:40:47.743Z" - }, - { - "id": "61f5d474-e41f-490b-ab58-9f983e3d4916", - "projectId": 111, - "userId": "f65e2104-2987-4136-839d-ee4632f0b2e5", - "jobId": "2d5e2a52-e0dd-4cd9-8f4c-7cffa43951d0", - "status": "placed", - "startDate": "2000-03-27", - "endDate": "2000-04-27", - "memberRate": 3000, - "customerRate": 3500, - "rateType": "weekly", - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "createdAt": "2021-01-28T19:40:09.879Z", - "updatedAt": "2021-01-28T19:40:56.381Z" - }, - { - "id": "8173579e-4b3c-418d-a9a1-c999caa38404", - "projectId": 111, - "userId": "bef43122-426b-4b2b-acdd-9b5b3bd1c0bf", - "jobId": "2d5e2a52-e0dd-4cd9-8f4c-7cffa43951d0", - "status": "placed", - "startDate": "2020-04-27", - "endDate": "2020-05-27", - "memberRate": 0, - "customerRate": 0, - "rateType": "weekly", - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "createdAt": "2021-01-28T19:40:20.627Z", - "updatedAt": "2021-01-28T19:41:04.919Z" - }, - { - "id": "a098e8d8-ce5b-47d9-afee-38b050d16745", - "projectId": 111, - "userId": "4709473d-f060-4102-87f8-4d51ff0b34c1", - "jobId": "2d5e2a52-e0dd-4cd9-8f4c-7cffa43951d0", - "status": "cancelled", - "startDate": "2021-04-25", - "endDate": "2021-04-30", - "memberRate": 1000, - "customerRate": 1200, - "rateType": "weekly", - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "createdAt": "2021-01-28T19:39:46.515Z", - "updatedAt": "2021-01-28T19:40:38.820Z" - }, - { - "id": "d38a6223-3f91-4300-9ecb-6e5fee173625", - "projectId": 111, - "userId": "39c7376e-2d5c-4601-bc47-6b60f505814d", - "jobId": "2d5e2a52-e0dd-4cd9-8f4c-7cffa43951d0", - "status": "sourcing", - "startDate": "2021-05-25", - "endDate": "2021-07-31", - "memberRate": 1000, - "customerRate": 1200, - "rateType": "weekly", - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "createdAt": "2021-01-28T19:39:52.063Z", - "updatedAt": "2021-01-28T19:40:43.021Z" - }, - { - "id": "dc4477ec-07f8-4c8e-a8fe-ffe38dd290fa", - "projectId": 111, - "userId": "e5e667ad-0950-43c2-8d1d-6e83ad7d1c7e", - "jobId": "2d5e2a52-e0dd-4cd9-8f4c-7cffa43951d0", - "status": "placed", - "startDate": "2021-07-27", - "endDate": "2021-09-27", - "memberRate": 1700, - "customerRate": 1900, - "rateType": "weekly", - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "createdAt": "2021-01-28T19:40:15.326Z", - "updatedAt": "2021-01-28T19:41:00.503Z" - } - ], - "WorkPeriod": [ - { - "id": "07783b60-b726-41c2-8955-7766a27c1ec5", - "resourceBookingId": "7d967fed-9792-4768-98a7-0b644aa84f2e", - "userHandle": "sachin-wipro", - "projectId": 111, - "startDate": "2021-03-21", - "endDate": "2021-03-27", - "daysWorked": 2, - "memberRate": 4.8, - "customerRate": 4.95, - "paymentStatus": "pending", - "createdBy": "00000000-0000-0000-0000-000000000000", - "updatedBy": null, - "createdAt": "2021-04-21T20:24:52.705Z", - "updatedAt": null - }, - { - "id": "6ed667a5-275e-4f27-984b-34dff5f8a1ff", - "resourceBookingId": "dc4477ec-07f8-4c8e-a8fe-ffe38dd290fa", - "userHandle": "nskumar278", - "projectId": 111, - "startDate": "2021-08-01", - "endDate": "2021-08-07", - "daysWorked": 5, - "memberRate": 25.21, - "customerRate": 10.05, - "paymentStatus": "pending", - "createdBy": "00000000-0000-0000-0000-000000000000", - "updatedBy": null, - "createdAt": "2021-04-21T20:24:52.703Z", - "updatedAt": null - }, - { - "id": "d049e7bc-c827-482b-9ec6-b87d9289d1cd", - "resourceBookingId": "8173579e-4b3c-418d-a9a1-c999caa38404", - "userHandle": "testcat", - "projectId": 111, - "startDate": "2020-05-24", - "endDate": "2020-05-30", - "daysWorked": 3, - "memberRate": 24.46, - "customerRate": 18.76, - "paymentStatus": "pending", - "createdBy": "00000000-0000-0000-0000-000000000000", - "updatedBy": null, - "createdAt": "2021-04-21T20:24:52.806Z", - "updatedAt": null - }, - { - "id": "1b633124-f62c-4026-b679-213cf5812689", - "resourceBookingId": "51b45f5d-5df2-46d5-9c3d-8a1323df38dd", - "userHandle": "amy_admin", - "projectId": 111, - "startDate": "2021-03-28", - "endDate": "2021-04-03", - "daysWorked": 5, - "memberRate": 23.35, - "customerRate": 18.76, - "paymentStatus": "pending", - "createdBy": "00000000-0000-0000-0000-000000000000", - "updatedBy": null, - "createdAt": "2021-04-21T20:24:52.704Z", - "updatedAt": null - }, - { - "id": "30c89d78-df85-44ed-92b2-b683d8960fc2", - "resourceBookingId": "51b45f5d-5df2-46d5-9c3d-8a1323df38dd", - "userHandle": "amy_admin", - "projectId": 111, - "startDate": "2021-04-04", - "endDate": "2021-04-10", - "daysWorked": 5, - "memberRate": 3.96, - "customerRate": 4.95, - "paymentStatus": "pending", - "createdBy": "00000000-0000-0000-0000-000000000000", - "updatedBy": null, - "createdAt": "2021-04-21T20:24:52.704Z", - "updatedAt": null - }, - { - "id": "531754f3-405e-42eb-932a-c1ce7b9386e7", - "resourceBookingId": "35e1abd8-1890-4664-bb52-aade382d7b66", - "userHandle": "lakshmiaconnmgr", - "projectId": 111, - "startDate": "2021-02-28", - "endDate": "2021-03-06", - "daysWorked": 5, - "memberRate": 3.62, - "customerRate": 10.05, - "paymentStatus": "pending", - "createdBy": "00000000-0000-0000-0000-000000000000", - "updatedBy": null, - "createdAt": "2021-04-21T20:24:52.695Z", - "updatedAt": null - }, - { - "id": "442b0543-e887-42be-9ff5-5fee825526be", - "resourceBookingId": "0a6799d7-f5d1-456b-8bf1-90619284b295", - "userHandle": "aaaa", - "projectId": 111, - "startDate": "2021-03-14", - "endDate": "2021-03-20", - "daysWorked": 1, - "memberRate": 23.81, - "customerRate": 15.49, - "paymentStatus": "pending", - "createdBy": "00000000-0000-0000-0000-000000000000", - "updatedBy": null, - "createdAt": "2021-04-21T20:24:52.694Z", - "updatedAt": null - }, - { - "id": "18a73600-5ee8-484b-9747-70ea80ce2bd9", - "resourceBookingId": "7d967fed-9792-4768-98a7-0b644aa84f2e", - "userHandle": "sachin-wipro", - "projectId": 111, - "startDate": "2021-05-16", - "endDate": "2021-05-22", - "daysWorked": 5, - "memberRate": 28.76, - "customerRate": 25.9, - "paymentStatus": "completed", - "createdBy": "00000000-0000-0000-0000-000000000000", - "updatedBy": null, - "createdAt": "2021-04-21T20:24:52.705Z", - "updatedAt": null - }, - { - "id": "5392acee-b504-4720-95fa-dab585acb607", - "resourceBookingId": "0a6799d7-f5d1-456b-8bf1-90619284b295", - "userHandle": "aaaa", - "projectId": 111, - "startDate": "2021-03-07", - "endDate": "2021-03-13", - "daysWorked": 5, - "memberRate": 14.77, - "customerRate": 26.72, - "paymentStatus": "pending", - "createdBy": "00000000-0000-0000-0000-000000000000", - "updatedBy": null, - "createdAt": "2021-04-21T20:24:52.693Z", - "updatedAt": null - }, - { - "id": "1bbc86c8-8c74-4d78-9706-25c4c99721f3", - "resourceBookingId": "35e1abd8-1890-4664-bb52-aade382d7b66", - "userHandle": "lakshmiaconnmgr", - "projectId": 111, - "startDate": "2021-03-21", - "endDate": "2021-03-27", - "daysWorked": 5, - "memberRate": 3.62, - "customerRate": 25.9, - "paymentStatus": "pending", - "createdBy": "00000000-0000-0000-0000-000000000000", - "updatedBy": null, - "createdAt": "2021-04-21T20:24:52.695Z", - "updatedAt": null - }, - { - "id": "8b7b49de-29b1-4a0c-bb67-e70cc700fcfd", - "resourceBookingId": "51b45f5d-5df2-46d5-9c3d-8a1323df38dd", - "userHandle": "amy_admin", - "projectId": 111, - "startDate": "2021-04-25", - "endDate": "2021-05-01", - "daysWorked": 5, - "memberRate": 24.68, - "customerRate": 23.15, - "paymentStatus": "pending", - "createdBy": "00000000-0000-0000-0000-000000000000", - "updatedBy": null, - "createdAt": "2021-04-21T20:24:52.704Z", - "updatedAt": null - }, - { - "id": "b8a8b558-0cb9-46d0-ba9d-2222f3fbdb63", - "resourceBookingId": "dc4477ec-07f8-4c8e-a8fe-ffe38dd290fa", - "userHandle": "nskumar278", - "projectId": 111, - "startDate": "2021-09-05", - "endDate": "2021-09-11", - "daysWorked": 5, - "memberRate": 27.42, - "customerRate": 27.91, - "paymentStatus": "pending", - "createdBy": "00000000-0000-0000-0000-000000000000", - "updatedBy": null, - "createdAt": "2021-04-21T20:24:52.703Z", - "updatedAt": null - }, - { - "id": "f70509c0-baed-4ff1-8022-12441251f7af", - "resourceBookingId": "51b45f5d-5df2-46d5-9c3d-8a1323df38dd", - "userHandle": "amy_admin", - "projectId": 111, - "startDate": "2021-03-14", - "endDate": "2021-03-20", - "daysWorked": 2, - "memberRate": 30.24, - "customerRate": 9.88, - "paymentStatus": "pending", - "createdBy": "00000000-0000-0000-0000-000000000000", - "updatedBy": null, - "createdAt": "2021-04-21T20:24:52.704Z", - "updatedAt": null - }, - { - "id": "da8abd64-2878-4e09-b3b1-41a27a0576d4", - "resourceBookingId": "dc4477ec-07f8-4c8e-a8fe-ffe38dd290fa", - "userHandle": "nskumar278", - "projectId": 111, - "startDate": "2021-09-12", - "endDate": "2021-09-18", - "daysWorked": 5, - "memberRate": 16.86, - "customerRate": 4.05, - "paymentStatus": "pending", - "createdBy": "00000000-0000-0000-0000-000000000000", - "updatedBy": null, - "createdAt": "2021-04-21T20:24:52.703Z", - "updatedAt": null - }, - { - "id": "b5261ee2-bc4d-4c3a-9d30-6703bfdcfbc5", - "resourceBookingId": "51b45f5d-5df2-46d5-9c3d-8a1323df38dd", - "userHandle": "amy_admin", - "projectId": 111, - "startDate": "2021-05-23", - "endDate": "2021-05-29", - "daysWorked": 5, - "memberRate": 24.68, - "customerRate": 27.91, - "paymentStatus": "completed", - "createdBy": "00000000-0000-0000-0000-000000000000", - "updatedBy": null, - "createdAt": "2021-04-21T20:24:52.704Z", - "updatedAt": null - }, - { - "id": "829165cb-0150-48e7-995c-f5b4d1a51d3b", - "resourceBookingId": "dc4477ec-07f8-4c8e-a8fe-ffe38dd290fa", - "userHandle": "nskumar278", - "projectId": 111, - "startDate": "2021-09-26", - "endDate": "2021-10-02", - "daysWorked": 1, - "memberRate": 4.8, - "customerRate": 10.59, - "paymentStatus": "pending", - "createdBy": "00000000-0000-0000-0000-000000000000", - "updatedBy": null, - "createdAt": "2021-04-21T20:24:52.703Z", - "updatedAt": null - }, - { - "id": "2430fb35-826a-4e9f-8fb6-8dbcb035d505", - "resourceBookingId": "dc4477ec-07f8-4c8e-a8fe-ffe38dd290fa", - "userHandle": "nskumar278", - "projectId": 111, - "startDate": "2021-08-22", - "endDate": "2021-08-28", - "daysWorked": 5, - "memberRate": 6.18, - "customerRate": 4.05, - "paymentStatus": "pending", - "createdBy": "00000000-0000-0000-0000-000000000000", - "updatedBy": null, - "createdAt": "2021-04-21T20:24:52.703Z", - "updatedAt": null - }, - { - "id": "c7ff2acc-a4c2-4e8b-a905-813dd9d1b293", - "resourceBookingId": "35e1abd8-1890-4664-bb52-aade382d7b66", - "userHandle": "lakshmiaconnmgr", - "projectId": 111, - "startDate": "2021-03-28", - "endDate": "2021-04-03", - "daysWorked": 4, - "memberRate": 24.46, - "customerRate": 4.05, - "paymentStatus": "pending", - "createdBy": "00000000-0000-0000-0000-000000000000", - "updatedBy": null, - "createdAt": "2021-04-21T20:24:52.695Z", - "updatedAt": null - }, - { - "id": "731db5d7-bb79-45f4-b1b2-9f60d30f7966", - "resourceBookingId": "08f5e4b9-1088-496d-91a7-5b22a3583e3c", - "userHandle": "ritesh_cs", - "projectId": 111, - "startDate": "2021-01-31", - "endDate": "2021-02-06", - "daysWorked": 0, - "memberRate": 27.42, - "customerRate": 4.4, - "paymentStatus": "pending", - "createdBy": "00000000-0000-0000-0000-000000000000", - "updatedBy": null, - "createdAt": "2021-04-21T20:24:52.775Z", - "updatedAt": null - }, - { - "id": "b682660e-488e-4033-aaf3-ef37248abc90", - "resourceBookingId": "0a6799d7-f5d1-456b-8bf1-90619284b295", - "userHandle": "aaaa", - "projectId": 111, - "startDate": "2021-02-21", - "endDate": "2021-02-27", - "daysWorked": 0, - "memberRate": 24.46, - "customerRate": 2.55, - "paymentStatus": "pending", - "createdBy": "00000000-0000-0000-0000-000000000000", - "updatedBy": null, - "createdAt": "2021-04-21T20:24:52.693Z", - "updatedAt": null - }, - { - "id": "b4566e24-4fa8-4e82-9950-f62134bb00df", - "resourceBookingId": "dc4477ec-07f8-4c8e-a8fe-ffe38dd290fa", - "userHandle": "nskumar278", - "projectId": 111, - "startDate": "2021-08-29", - "endDate": "2021-09-04", - "daysWorked": 5, - "memberRate": 4.8, - "customerRate": 4.4, - "paymentStatus": "pending", - "createdBy": "00000000-0000-0000-0000-000000000000", - "updatedBy": null, - "createdAt": "2021-04-21T20:24:52.703Z", - "updatedAt": null - }, - { - "id": "584c931b-da72-416e-a011-eac5fe34f42f", - "resourceBookingId": "dc4477ec-07f8-4c8e-a8fe-ffe38dd290fa", - "userHandle": "nskumar278", - "projectId": 111, - "startDate": "2021-07-25", - "endDate": "2021-07-31", - "daysWorked": 4, - "memberRate": 14.77, - "customerRate": 4.4, - "paymentStatus": "pending", - "createdBy": "00000000-0000-0000-0000-000000000000", - "updatedBy": null, - "createdAt": "2021-04-21T20:24:52.703Z", - "updatedAt": null - }, - { - "id": "703bc625-9144-4a9f-a91b-445e171d8ea9", - "resourceBookingId": "dc4477ec-07f8-4c8e-a8fe-ffe38dd290fa", - "userHandle": "nskumar278", - "projectId": 111, - "startDate": "2021-09-19", - "endDate": "2021-09-25", - "daysWorked": 5, - "memberRate": 27.42, - "customerRate": 5.77, - "paymentStatus": "pending", - "createdBy": "00000000-0000-0000-0000-000000000000", - "updatedBy": null, - "createdAt": "2021-04-21T20:24:52.703Z", - "updatedAt": null - }, - { - "id": "c9685cb2-9f4a-497e-ae99-deed7b16cc34", - "resourceBookingId": "35e1abd8-1890-4664-bb52-aade382d7b66", - "userHandle": "lakshmiaconnmgr", - "projectId": 111, - "startDate": "2021-03-07", - "endDate": "2021-03-13", - "daysWorked": 5, - "memberRate": 14.77, - "customerRate": 16.55, - "paymentStatus": "completed", - "createdBy": "00000000-0000-0000-0000-000000000000", - "updatedBy": null, - "createdAt": "2021-04-21T20:24:52.695Z", - "updatedAt": null - }, - { - "id": "428fec88-b305-4816-b5ef-be2b4e91c21a", - "resourceBookingId": "7d967fed-9792-4768-98a7-0b644aa84f2e", - "userHandle": "sachin-wipro", - "projectId": 111, - "startDate": "2021-04-04", - "endDate": "2021-04-10", - "daysWorked": 5, - "memberRate": 8.55, - "customerRate": 16.55, - "paymentStatus": "pending", - "createdBy": "00000000-0000-0000-0000-000000000000", - "updatedBy": null, - "createdAt": "2021-04-21T20:24:52.705Z", - "updatedAt": null - }, - { - "id": "374e2065-40cb-4651-a55c-81a0675dc00d", - "resourceBookingId": "8173579e-4b3c-418d-a9a1-c999caa38404", - "userHandle": "testcat", - "projectId": 111, - "startDate": "2020-05-17", - "endDate": "2020-05-23", - "daysWorked": 5, - "memberRate": 16.86, - "customerRate": 1.89, - "paymentStatus": "pending", - "createdBy": "00000000-0000-0000-0000-000000000000", - "updatedBy": null, - "createdAt": "2021-04-21T20:24:52.806Z", - "updatedAt": null - }, - { - "id": "4bfdc253-e39a-4cfa-9a45-2cfc6e93cc6f", - "resourceBookingId": "61f5d474-e41f-490b-ab58-9f983e3d4916", - "userHandle": "sonu628", - "projectId": 111, - "startDate": "2000-04-16", - "endDate": "2000-04-22", - "daysWorked": 5, - "memberRate": 20.16, - "customerRate": 13.92, - "paymentStatus": "pending", - "createdBy": "00000000-0000-0000-0000-000000000000", - "updatedBy": null, - "createdAt": "2021-04-21T20:24:52.858Z", - "updatedAt": null - }, - { - "id": "0ba1a0b3-7bee-4fe6-9083-d36d8ca9d052", - "resourceBookingId": "35e1abd8-1890-4664-bb52-aade382d7b66", - "userHandle": "lakshmiaconnmgr", - "projectId": 111, - "startDate": "2021-03-14", - "endDate": "2021-03-20", - "daysWorked": 5, - "memberRate": 24.46, - "customerRate": 1.44, - "paymentStatus": "pending", - "createdBy": "00000000-0000-0000-0000-000000000000", - "updatedBy": null, - "createdAt": "2021-04-21T20:24:52.695Z", - "updatedAt": null - }, - { - "id": "6da7d347-7492-43b1-a49d-8a6e1daf9b22", - "resourceBookingId": "51b45f5d-5df2-46d5-9c3d-8a1323df38dd", - "userHandle": "amy_admin", - "projectId": 111, - "startDate": "2021-04-18", - "endDate": "2021-04-24", - "daysWorked": 5, - "memberRate": 25.21, - "customerRate": 1.44, - "paymentStatus": "pending", - "createdBy": "00000000-0000-0000-0000-000000000000", - "updatedBy": null, - "createdAt": "2021-04-21T20:24:52.704Z", - "updatedAt": null - }, - { - "id": "8c8cedf3-0bb6-4063-8a3a-faf1626da384", - "resourceBookingId": "61f5d474-e41f-490b-ab58-9f983e3d4916", - "userHandle": "sonu628", - "projectId": 111, - "startDate": "2000-04-09", - "endDate": "2000-04-15", - "daysWorked": 5, - "memberRate": 14.77, - "customerRate": 4.95, - "paymentStatus": "pending", - "createdBy": "00000000-0000-0000-0000-000000000000", - "updatedBy": null, - "createdAt": "2021-04-21T20:24:52.858Z", - "updatedAt": null - }, - { - "id": "10394696-47f4-4761-8d14-ffdf012cde23", - "resourceBookingId": "d38a6223-3f91-4300-9ecb-6e5fee173625", - "userHandle": "nithyaasworld", - "projectId": 111, - "startDate": "2021-07-25", - "endDate": "2021-07-31", - "daysWorked": 5, - "memberRate": 3.62, - "customerRate": 4.95, - "paymentStatus": "pending", - "createdBy": "00000000-0000-0000-0000-000000000000", - "updatedBy": null, - "createdAt": "2021-04-21T20:24:52.706Z", - "updatedAt": null - }, - { - "id": "64de2244-6fcf-45ac-8a89-a9b3420e4476", - "resourceBookingId": "7d967fed-9792-4768-98a7-0b644aa84f2e", - "userHandle": "sachin-wipro", - "projectId": 111, - "startDate": "2021-04-18", - "endDate": "2021-04-24", - "daysWorked": 5, - "memberRate": 22.57, - "customerRate": 18.23, - "paymentStatus": "pending", - "createdBy": "00000000-0000-0000-0000-000000000000", - "updatedBy": null, - "createdAt": "2021-04-21T20:24:52.705Z", - "updatedAt": null - }, - { - "id": "2cbe3836-5961-4d58-b8f7-44b84ddf3fc5", - "resourceBookingId": "7d967fed-9792-4768-98a7-0b644aa84f2e", - "userHandle": "sachin-wipro", - "projectId": 111, - "startDate": "2021-04-11", - "endDate": "2021-04-17", - "daysWorked": 5, - "memberRate": 25.21, - "customerRate": 2.64, - "paymentStatus": "pending", - "createdBy": "00000000-0000-0000-0000-000000000000", - "updatedBy": null, - "createdAt": "2021-04-21T20:24:52.705Z", - "updatedAt": null - }, - { - "id": "bc8611f0-4ac2-49b2-b776-59ed2b759d1d", - "resourceBookingId": "d38a6223-3f91-4300-9ecb-6e5fee173625", - "userHandle": "nithyaasworld", - "projectId": 111, - "startDate": "2021-07-04", - "endDate": "2021-07-10", - "daysWorked": 5, - "memberRate": 16.86, - "customerRate": 5.77, - "paymentStatus": "pending", - "createdBy": "00000000-0000-0000-0000-000000000000", - "updatedBy": null, - "createdAt": "2021-04-21T20:24:52.706Z", - "updatedAt": null - }, - { - "id": "9b6fc85b-3694-4e6c-9ebf-fe9ccf7881ba", - "resourceBookingId": "d38a6223-3f91-4300-9ecb-6e5fee173625", - "userHandle": "nithyaasworld", - "projectId": 111, - "startDate": "2021-06-13", - "endDate": "2021-06-19", - "daysWorked": 5, - "memberRate": 14.77, - "customerRate": 15.86, - "paymentStatus": "pending", - "createdBy": "00000000-0000-0000-0000-000000000000", - "updatedBy": null, - "createdAt": "2021-04-21T20:24:52.706Z", - "updatedAt": null - }, - { - "id": "4a2c581f-c626-44cb-8ada-58f0172e8b4d", - "resourceBookingId": "d38a6223-3f91-4300-9ecb-6e5fee173625", - "userHandle": "nithyaasworld", - "projectId": 111, - "startDate": "2021-05-30", - "endDate": "2021-06-05", - "daysWorked": 5, - "memberRate": 28.76, - "customerRate": 15.49, - "paymentStatus": "pending", - "createdBy": "00000000-0000-0000-0000-000000000000", - "updatedBy": null, - "createdAt": "2021-04-21T20:24:52.706Z", - "updatedAt": null - }, - { - "id": "90d99323-ba57-4a18-b50f-78f387033c70", - "resourceBookingId": "61f5d474-e41f-490b-ab58-9f983e3d4916", - "userHandle": "sonu628", - "projectId": 111, - "startDate": "2000-04-02", - "endDate": "2000-04-08", - "daysWorked": 5, - "memberRate": 24.46, - "customerRate": 25.9, - "paymentStatus": "completed", - "createdBy": "00000000-0000-0000-0000-000000000000", - "updatedBy": null, - "createdAt": "2021-04-21T20:24:52.858Z", - "updatedAt": null - }, - { - "id": "5ddc132b-3205-45e3-bfe9-f1a4f939885e", - "resourceBookingId": "51b45f5d-5df2-46d5-9c3d-8a1323df38dd", - "userHandle": "amy_admin", - "projectId": 111, - "startDate": "2021-03-21", - "endDate": "2021-03-27", - "daysWorked": 5, - "memberRate": 21.53, - "customerRate": 25.9, - "paymentStatus": "completed", - "createdBy": "00000000-0000-0000-0000-000000000000", - "updatedBy": null, - "createdAt": "2021-04-21T20:24:52.704Z", - "updatedAt": null - }, - { - "id": "437d4281-43ec-4de3-85e4-51d298388ce5", - "resourceBookingId": "0a6799d7-f5d1-456b-8bf1-90619284b295", - "userHandle": "aaaa", - "projectId": 111, - "startDate": "2021-02-28", - "endDate": "2021-03-06", - "daysWorked": 5, - "memberRate": 26.19, - "customerRate": 28.03, - "paymentStatus": "completed", - "createdBy": "00000000-0000-0000-0000-000000000000", - "updatedBy": null, - "createdAt": "2021-04-21T20:24:52.693Z", - "updatedAt": null - }, - { - "id": "a35bb205-361b-4b2d-9828-55501ae9d190", - "resourceBookingId": "d38a6223-3f91-4300-9ecb-6e5fee173625", - "userHandle": "nithyaasworld", - "projectId": 111, - "startDate": "2021-07-11", - "endDate": "2021-07-17", - "daysWorked": 5, - "memberRate": 27.42, - "customerRate": 28.03, - "paymentStatus": "pending", - "createdBy": "00000000-0000-0000-0000-000000000000", - "updatedBy": null, - "createdAt": "2021-04-21T20:24:52.706Z", - "updatedAt": null - }, - { - "id": "40ae1e8f-24be-4b51-885c-51f08e15f0df", - "resourceBookingId": "08f5e4b9-1088-496d-91a7-5b22a3583e3c", - "userHandle": "ritesh_cs", - "projectId": 111, - "startDate": "2021-01-24", - "endDate": "2021-01-30", - "daysWorked": 5, - "memberRate": 16.86, - "customerRate": 28.03, - "paymentStatus": "pending", - "createdBy": "00000000-0000-0000-0000-000000000000", - "updatedBy": null, - "createdAt": "2021-04-21T20:24:52.775Z", - "updatedAt": null - }, - { - "id": "e19bddc5-38ac-43c9-8273-bc9069de26b3", - "resourceBookingId": "61f5d474-e41f-490b-ab58-9f983e3d4916", - "userHandle": "sonu628", - "projectId": 111, - "startDate": "2000-04-23", - "endDate": "2000-04-29", - "daysWorked": 5, - "memberRate": 6.18, - "customerRate": 9.12, - "paymentStatus": "pending", - "createdBy": "00000000-0000-0000-0000-000000000000", - "updatedBy": null, - "createdAt": "2021-04-21T20:24:52.858Z", - "updatedAt": null - }, - { - "id": "bf61dad8-841a-4913-93f6-b2ae516b8b11", - "resourceBookingId": "d38a6223-3f91-4300-9ecb-6e5fee173625", - "userHandle": "nithyaasworld", - "projectId": 111, - "startDate": "2021-06-06", - "endDate": "2021-06-12", - "daysWorked": 5, - "memberRate": 6.18, - "customerRate": 4.4, - "paymentStatus": "pending", - "createdBy": "00000000-0000-0000-0000-000000000000", - "updatedBy": null, - "createdAt": "2021-04-21T20:24:52.706Z", - "updatedAt": null - }, - { - "id": "93b0f03b-219b-41d5-bb1e-f125651b1b0e", - "resourceBookingId": "8173579e-4b3c-418d-a9a1-c999caa38404", - "userHandle": "testcat", - "projectId": 111, - "startDate": "2020-05-03", - "endDate": "2020-05-09", - "daysWorked": 5, - "memberRate": 24.46, - "customerRate": 1.89, - "paymentStatus": "pending", - "createdBy": "00000000-0000-0000-0000-000000000000", - "updatedBy": null, - "createdAt": "2021-04-21T20:24:52.806Z", - "updatedAt": null - }, - { - "id": "93e69f99-cb1c-418e-aa41-ab2181b4bcfd", - "resourceBookingId": "d38a6223-3f91-4300-9ecb-6e5fee173625", - "userHandle": "nithyaasworld", - "projectId": 111, - "startDate": "2021-06-27", - "endDate": "2021-07-03", - "daysWorked": 5, - "memberRate": 17.2, - "customerRate": 13.92, - "paymentStatus": "pending", - "createdBy": "00000000-0000-0000-0000-000000000000", - "updatedBy": null, - "createdAt": "2021-04-21T20:24:52.706Z", - "updatedAt": null - }, - { - "id": "619a0835-730f-47ec-820e-3959821aec51", - "resourceBookingId": "7d967fed-9792-4768-98a7-0b644aa84f2e", - "userHandle": "sachin-wipro", - "projectId": 111, - "startDate": "2021-05-30", - "endDate": "2021-06-05", - "daysWorked": 1, - "memberRate": 4.8, - "customerRate": 13.92, - "paymentStatus": "pending", - "createdBy": "00000000-0000-0000-0000-000000000000", - "updatedBy": null, - "createdAt": "2021-04-21T20:24:52.705Z", - "updatedAt": null - }, - { - "id": "558b4685-4932-492e-99e1-2830c10f8275", - "resourceBookingId": "7d967fed-9792-4768-98a7-0b644aa84f2e", - "userHandle": "sachin-wipro", - "projectId": 111, - "startDate": "2021-04-25", - "endDate": "2021-05-01", - "daysWorked": 5, - "memberRate": 4.8, - "customerRate": 13.92, - "paymentStatus": "pending", - "createdBy": "00000000-0000-0000-0000-000000000000", - "updatedBy": null, - "createdAt": "2021-04-21T20:24:52.705Z", - "updatedAt": null - }, - { - "id": "84431dac-019d-4987-9817-15f5f000d2db", - "resourceBookingId": "61f5d474-e41f-490b-ab58-9f983e3d4916", - "userHandle": "sonu628", - "projectId": 111, - "startDate": "2000-03-26", - "endDate": "2000-04-01", - "daysWorked": 5, - "memberRate": 27.42, - "customerRate": 4.05, - "paymentStatus": "partially-completed", - "createdBy": "00000000-0000-0000-0000-000000000000", - "updatedBy": null, - "createdAt": "2021-04-21T20:24:52.858Z", - "updatedAt": null - }, - { - "id": "f575df2d-f170-4251-9042-b17ca5e99ca5", - "resourceBookingId": "51b45f5d-5df2-46d5-9c3d-8a1323df38dd", - "userHandle": "amy_admin", - "projectId": 111, - "startDate": "2021-05-02", - "endDate": "2021-05-08", - "daysWorked": 5, - "memberRate": 4.82, - "customerRate": 4.05, - "paymentStatus": "completed", - "createdBy": "00000000-0000-0000-0000-000000000000", - "updatedBy": null, - "createdAt": "2021-04-21T20:24:52.704Z", - "updatedAt": null - }, - { - "id": "3829c216-ef3f-466c-93da-3a88a961442f", - "resourceBookingId": "51b45f5d-5df2-46d5-9c3d-8a1323df38dd", - "userHandle": "amy_admin", - "projectId": 111, - "startDate": "2021-05-09", - "endDate": "2021-05-15", - "daysWorked": 5, - "memberRate": 6.18, - "customerRate": 4.4, - "paymentStatus": "cancelled", - "createdBy": "00000000-0000-0000-0000-000000000000", - "updatedBy": null, - "createdAt": "2021-04-21T20:24:52.704Z", - "updatedAt": null - }, - { - "id": "bd54bcaf-5278-467f-a166-865048774d0e", - "resourceBookingId": "a098e8d8-ce5b-47d9-afee-38b050d16745", - "userHandle": "TCConnCopilot", - "projectId": 111, - "startDate": "2021-04-25", - "endDate": "2021-05-01", - "daysWorked": 5, - "memberRate": 16.86, - "customerRate": 1.89, - "paymentStatus": "partially-completed", - "createdBy": "00000000-0000-0000-0000-000000000000", - "updatedBy": null, - "createdAt": "2021-04-21T20:24:52.696Z", - "updatedAt": null - }, - { - "id": "7f8f3a25-b1d2-4e36-a543-fcaae57a32f5", - "resourceBookingId": "dc4477ec-07f8-4c8e-a8fe-ffe38dd290fa", - "userHandle": "nskumar278", - "projectId": 111, - "startDate": "2021-08-15", - "endDate": "2021-08-21", - "daysWorked": 5, - "memberRate": 8.13, - "customerRate": 1.89, - "paymentStatus": "cancelled", - "createdBy": "00000000-0000-0000-0000-000000000000", - "updatedBy": null, - "createdAt": "2021-04-21T20:24:52.703Z", - "updatedAt": null - }, - { - "id": "6e1dc024-d437-4d9f-92e9-561db713a19a", - "resourceBookingId": "dc4477ec-07f8-4c8e-a8fe-ffe38dd290fa", - "userHandle": "nskumar278", - "projectId": 111, - "startDate": "2021-08-08", - "endDate": "2021-08-14", - "daysWorked": 5, - "memberRate": 3.62, - "customerRate": 18.14, - "paymentStatus": "partially-completed", - "createdBy": "00000000-0000-0000-0000-000000000000", - "updatedBy": null, - "createdAt": "2021-04-21T20:24:52.703Z", - "updatedAt": null - }, - { - "id": "c5f6ae8f-2976-46d1-bd66-58eeb58ca045", - "resourceBookingId": "d38a6223-3f91-4300-9ecb-6e5fee173625", - "userHandle": "nithyaasworld", - "projectId": 111, - "startDate": "2021-06-20", - "endDate": "2021-06-26", - "daysWorked": 5, - "memberRate": 25.41, - "customerRate": 13.92, - "paymentStatus": "cancelled", - "createdBy": "00000000-0000-0000-0000-000000000000", - "updatedBy": null, - "createdAt": "2021-04-21T20:24:52.706Z", - "updatedAt": null - }, - { - "id": "0f480aa7-1c5d-42fe-aad6-c774e58c2e17", - "resourceBookingId": "7d967fed-9792-4768-98a7-0b644aa84f2e", - "userHandle": "sachin-wipro", - "projectId": 111, - "startDate": "2021-05-09", - "endDate": "2021-05-15", - "daysWorked": 5, - "memberRate": 4.82, - "customerRate": 4.95, - "paymentStatus": "cancelled", - "createdBy": "00000000-0000-0000-0000-000000000000", - "updatedBy": null, - "createdAt": "2021-04-21T20:24:52.705Z", - "updatedAt": null - }, - { - "id": "098ca553-6ea4-4cae-a18e-762f47e93d82", - "resourceBookingId": "51b45f5d-5df2-46d5-9c3d-8a1323df38dd", - "userHandle": "amy_admin", - "projectId": 111, - "startDate": "2021-05-16", - "endDate": "2021-05-22", - "daysWorked": 5, - "memberRate": 3.96, - "customerRate": 4.95, - "paymentStatus": "completed", - "createdBy": "00000000-0000-0000-0000-000000000000", - "updatedBy": null, - "createdAt": "2021-04-21T20:24:52.704Z", - "updatedAt": null - }, - { - "id": "729a2396-2b33-4185-8ce8-d929dbf4a472", - "resourceBookingId": "7d967fed-9792-4768-98a7-0b644aa84f2e", - "userHandle": "sachin-wipro", - "projectId": 111, - "startDate": "2021-05-23", - "endDate": "2021-05-29", - "daysWorked": 5, - "memberRate": 17.2, - "customerRate": 4.95, - "paymentStatus": "completed", - "createdBy": "00000000-0000-0000-0000-000000000000", - "updatedBy": null, - "createdAt": "2021-04-21T20:24:52.705Z", - "updatedAt": null - }, - { - "id": "9bfbd49a-e6bb-45c3-965d-ed4f95f0878a", - "resourceBookingId": "d38a6223-3f91-4300-9ecb-6e5fee173625", - "userHandle": "nithyaasworld", - "projectId": 111, - "startDate": "2021-07-18", - "endDate": "2021-07-24", - "daysWorked": 5, - "memberRate": 23.35, - "customerRate": 5.77, - "paymentStatus": "completed", - "createdBy": "00000000-0000-0000-0000-000000000000", - "updatedBy": null, - "createdAt": "2021-04-21T20:24:52.706Z", - "updatedAt": null - }, - { - "id": "dcc310cf-ea4a-4637-9bf5-5baaabea67b3", - "resourceBookingId": "d38a6223-3f91-4300-9ecb-6e5fee173625", - "userHandle": "nithyaasworld", - "projectId": 111, - "startDate": "2021-05-23", - "endDate": "2021-05-29", - "daysWorked": 4, - "memberRate": 14.77, - "customerRate": 1.44, - "paymentStatus": "partially-completed", - "createdBy": "00000000-0000-0000-0000-000000000000", - "updatedBy": null, - "createdAt": "2021-04-21T20:24:52.706Z", - "updatedAt": null - }, - { - "id": "309f65e8-b0b5-4cbb-ba60-9b36ccba4bd5", - "resourceBookingId": "51b45f5d-5df2-46d5-9c3d-8a1323df38dd", - "userHandle": "amy_admin", - "projectId": 111, - "startDate": "2021-04-11", - "endDate": "2021-04-17", - "daysWorked": 5, - "memberRate": 14.77, - "customerRate": 15.49, - "paymentStatus": "completed", - "createdBy": "00000000-0000-0000-0000-000000000000", - "updatedBy": null, - "createdAt": "2021-04-21T20:24:52.704Z", - "updatedAt": null - }, - { - "id": "1e2c732e-ac1f-47ad-939b-22b2078124e5", - "resourceBookingId": "7d967fed-9792-4768-98a7-0b644aa84f2e", - "userHandle": "sachin-wipro", - "projectId": 111, - "startDate": "2021-03-28", - "endDate": "2021-04-03", - "daysWorked": 5, - "memberRate": 17.2, - "customerRate": 15.49, - "paymentStatus": "partially-completed", - "createdBy": "00000000-0000-0000-0000-000000000000", - "updatedBy": null, - "createdAt": "2021-04-21T20:24:52.705Z", - "updatedAt": null - }, - { - "id": "2463003f-ee60-4aba-b989-b63babcd9b8b", - "resourceBookingId": "7d967fed-9792-4768-98a7-0b644aa84f2e", - "userHandle": "sachin-wipro", - "projectId": 111, - "startDate": "2021-05-02", - "endDate": "2021-05-08", - "daysWorked": 5, - "memberRate": 4.8, - "customerRate": 15.49, - "paymentStatus": "cancelled", - "createdBy": "00000000-0000-0000-0000-000000000000", - "updatedBy": null, - "createdAt": "2021-04-21T20:24:52.705Z", - "updatedAt": null - }, - { - "id": "6a1180b8-38af-4bd0-8a5f-a60626e0bc95", - "resourceBookingId": "8173579e-4b3c-418d-a9a1-c999caa38404", - "userHandle": "testcat", - "projectId": 111, - "startDate": "2020-04-26", - "endDate": "2020-05-02", - "daysWorked": 5, - "memberRate": 26.19, - "customerRate": 28.03, - "paymentStatus": "completed", - "createdBy": "00000000-0000-0000-0000-000000000000", - "updatedBy": null, - "createdAt": "2021-04-21T20:24:52.806Z", - "updatedAt": null - }, - { - "id": "b21f921a-4b23-423d-814b-d31f5cba7f64", - "resourceBookingId": "35e1abd8-1890-4664-bb52-aade382d7b66", - "userHandle": "lakshmiaconnmgr", - "projectId": 111, - "startDate": "2021-02-21", - "endDate": "2021-02-27", - "daysWorked": 2, - "memberRate": 15.77, - "customerRate": 28.03, - "paymentStatus": "partially-completed", - "createdBy": "00000000-0000-0000-0000-000000000000", - "updatedBy": null, - "createdAt": "2021-04-21T20:24:52.695Z", - "updatedAt": null - }, - { - "id": "4db82b0b-4d6f-4e9a-b957-ab405b2c2df2", - "resourceBookingId": "8173579e-4b3c-418d-a9a1-c999caa38404", - "userHandle": "testcat", - "projectId": 111, - "startDate": "2020-05-10", - "endDate": "2020-05-16", - "daysWorked": 5, - "memberRate": 24.46, - "customerRate": 28.03, - "paymentStatus": "partially-completed", - "createdBy": "00000000-0000-0000-0000-000000000000", - "updatedBy": null, - "createdAt": "2021-04-21T20:24:52.806Z", - "updatedAt": null - } - ], - "WorkPeriodPayment": [ - { - "id": "2c488b36-0868-4db6-8978-20b1ce174496", - "workPeriodId": "07783b60-b726-41c2-8955-7766a27c1ec5", - "challengeId": "0de972b8-6cc9-4625-9760-1c77561c29e9", - "amount": 200, - "status": "completed", - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": null, - "createdAt": "2021-04-14T19:13:23.714Z", - "updatedAt": "2021-04-21T20:19:56.934Z" - }, - { - "id": "d0f61c2d-271c-48b2-8416-50c1c32ad32b", - "workPeriodId": "098ca553-6ea4-4cae-a18e-762f47e93d82", - "challengeId": "aa8c1945-904c-42a7-9b00-1e4f9a49dcdb", - "amount": 450, - "status": "completed", - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": null, - "createdAt": "2021-04-14T22:01:45.361Z", - "updatedAt": "2021-04-21T20:19:56.934Z" - }, - { - "id": "90bb43bd-d9e7-4eab-a46b-ab03338be11a", - "workPeriodId": "0ba1a0b3-7bee-4fe6-9083-d36d8ca9d052", - "challengeId": "8b6f4040-d7ae-4264-b60b-b1171c9365e4", - "amount": 400, - "status": "completed", - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": null, - "createdAt": "2021-04-14T22:01:45.390Z", - "updatedAt": "2021-04-21T20:19:56.934Z" - }, - { - "id": "58681a3e-2266-4153-afd5-7be218966da2", - "workPeriodId": "0f480aa7-1c5d-42fe-aad6-c774e58c2e17", - "challengeId": "2bafdd9a-ab4a-4624-8a06-7b1adfb8dac2", - "amount": 1200, - "status": "completed", - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": null, - "createdAt": "2021-04-14T22:01:45.326Z", - "updatedAt": "2021-04-21T20:19:56.934Z" - }, - { - "id": "b342d615-d36d-48b2-a3e8-1f498b58ab68", - "workPeriodId": "10394696-47f4-4761-8d14-ffdf012cde23", - "challengeId": "0de972b8-6cc9-4625-9760-1c77561c29e9", - "amount": 400, - "status": "completed", - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": null, - "createdAt": "2021-04-16T19:13:23.714Z", - "updatedAt": "2021-04-21T20:19:56.934Z" - }, - { - "id": "63cec011-7714-4ab6-944f-e76b9fa2bd1a", - "workPeriodId": "18a73600-5ee8-484b-9747-70ea80ce2bd9", - "challengeId": "1bdf092e-e117-4d42-bb5d-e49816171c0d", - "amount": 500, - "status": "completed", - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": null, - "createdAt": "2021-04-14T22:01:45.523Z", - "updatedAt": "2021-04-21T20:19:56.934Z" - }, - { - "id": "8a0c0877-b88a-420b-a3f7-645c18793b4b", - "workPeriodId": "1b633124-f62c-4026-b679-213cf5812689", - "challengeId": "4332acc6-3a33-4b7b-af4c-bd2c1ffcfb8e", - "amount": 1400, - "status": "completed", - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": null, - "createdAt": "2021-04-14T22:01:45.325Z", - "updatedAt": "2021-04-21T20:19:56.934Z" - }, - { - "id": "04ef47ac-8f4d-402f-b9fd-48b2b1d9003d", - "workPeriodId": "1bbc86c8-8c74-4d78-9706-25c4c99721f3", - "challengeId": "fa909769-f5f7-41fb-94bb-80db62e21a5e", - "amount": 800, - "status": "cancelled", - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": null, - "createdAt": "2021-04-14T22:01:45.326Z", - "updatedAt": "2021-04-21T20:19:56.934Z" - }, - { - "id": "84c1c956-e03d-4e19-a5a8-a4086c9658eb", - "workPeriodId": "1e2c732e-ac1f-47ad-939b-22b2078124e5", - "challengeId": "604910b2-7644-4b9d-a185-0054e61c83fc", - "amount": 1800, - "status": "completed", - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": null, - "createdAt": "2021-04-14T22:01:45.324Z", - "updatedAt": "2021-04-21T20:19:56.934Z" - }, - { - "id": "c051c3da-34bb-4deb-8921-04e5d2fa0bcc", - "workPeriodId": "2430fb35-826a-4e9f-8fb6-8dbcb035d505", - "challengeId": "25fd805c-49cd-443f-ba0d-813c33a6d8ad", - "amount": 400, - "status": "completed", - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": null, - "createdAt": "2021-04-14T22:01:45.390Z", - "updatedAt": "2021-04-21T20:19:56.934Z" - }, - { - "id": "cc13acfd-fc06-40e5-aefe-5050429ee4f2", - "workPeriodId": "2463003f-ee60-4aba-b989-b63babcd9b8b", - "challengeId": "0de972b8-6cc9-4625-9760-1c77561c29e9", - "amount": 1200, - "status": "completed", - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": null, - "createdAt": "2021-04-14T19:13:23.714Z", - "updatedAt": "2021-04-21T20:19:56.934Z" - }, - { - "id": "58c6431a-061a-41bd-a3bd-c8effba62e11", - "workPeriodId": "2cbe3836-5961-4d58-b8f7-44b84ddf3fc5", - "challengeId": "0de972b8-6cc9-4625-9760-1c77561c29e9", - "amount": 900, - "status": "completed", - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": null, - "createdAt": "2021-04-14T19:13:23.714Z", - "updatedAt": "2021-04-21T20:19:56.934Z" - }, - { - "id": "efe0e4b5-e6dd-4c1a-a0e5-1f5e0ff91df9", - "workPeriodId": "309f65e8-b0b5-4cbb-ba60-9b36ccba4bd5", - "challengeId": "01332fa9-0505-416d-9084-39b136dbd300", - "amount": 1200, - "status": "completed", - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": null, - "createdAt": "2021-04-14T22:01:45.390Z", - "updatedAt": "2021-04-21T20:19:56.934Z" - }, - { - "id": "298ac627-e6d7-47b0-ad1d-83de291addf7", - "workPeriodId": "30c89d78-df85-44ed-92b2-b683d8960fc2", - "challengeId": "f7e40a0c-a302-4989-a3bd-7587fee3c367", - "amount": 300, - "status": "cancelled", - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "createdAt": "2021-04-14T19:13:23.714Z", - "updatedAt": "2021-04-16T19:13:23.714Z" - }, - { - "id": "bf80eca9-8323-4f96-9a3b-8553d6f1e0ce", - "workPeriodId": "374e2065-40cb-4651-a55c-81a0675dc00d", - "challengeId": "03c69d02-9188-436e-b4c9-08f39e46f413", - "amount": 800, - "status": "completed", - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": null, - "createdAt": "2021-04-14T22:01:45.390Z", - "updatedAt": "2021-04-21T20:19:56.934Z" - }, - { - "id": "338d2d7d-2c59-4513-b560-55e8982fd7c7", - "workPeriodId": "3829c216-ef3f-466c-93da-3a88a961442f", - "challengeId": "2a0db660-def2-4117-90e8-01cd1271c726", - "amount": 1400, - "status": "completed", - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": null, - "createdAt": "2021-04-14T22:01:45.390Z", - "updatedAt": "2021-04-21T20:19:56.934Z" - }, - { - "id": "491f6e93-e80f-46eb-9637-ee84fe7ace9b", - "workPeriodId": "40ae1e8f-24be-4b51-885c-51f08e15f0df", - "challengeId": "c2b7a2cc-4633-4f3a-ab39-f7122a6890b6", - "amount": 1600, - "status": "completed", - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": null, - "createdAt": "2021-04-14T22:01:45.390Z", - "updatedAt": "2021-04-21T20:19:56.934Z" - }, - { - "id": "cb94d710-fa3c-4333-b8a9-39ec053a665d", - "workPeriodId": "428fec88-b305-4816-b5ef-be2b4e91c21a", - "challengeId": "93f594e9-5396-416a-8212-87bee614a38f", - "amount": 1200, - "status": "completed", - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": null, - "createdAt": "2021-04-14T19:13:23.714Z", - "updatedAt": "2021-04-21T20:19:56.934Z" - }, - { - "id": "155eaab2-ef74-484c-b1d7-6534dde58b66", - "workPeriodId": "437d4281-43ec-4de3-85e4-51d298388ce5", - "challengeId": "5ba2d9df-b3ba-4f5f-bee5-228eb46b2c37", - "amount": 600, - "status": "completed", - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": null, - "createdAt": "2021-04-14T22:01:45.361Z", - "updatedAt": "2021-04-21T20:19:56.934Z" - }, - { - "id": "11c07a5c-a077-4719-83ba-c48db7e63c01", - "workPeriodId": "442b0543-e887-42be-9ff5-5fee825526be", - "challengeId": "d7c21199-a435-41b8-a2ac-5e5bdd021c5e", - "amount": 1400, - "status": "cancelled", - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": null, - "createdAt": "2021-04-14T19:13:23.714Z", - "updatedAt": "2021-04-21T20:19:56.934Z" - }, - { - "id": "4ce8cf4a-2585-4454-81d4-e5446c9a3f75", - "workPeriodId": "4a2c581f-c626-44cb-8ada-58f0172e8b4d", - "challengeId": "ee9bcdd0-0d0d-4414-88cb-d14255f996a5", - "amount": 350, - "status": "completed", - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "createdAt": "2021-04-14T19:13:23.714Z", - "updatedAt": "2021-04-16T19:13:23.714Z" - }, - { - "id": "8ff6188f-b4e6-4f6e-b2d4-2a622ae50c4f", - "workPeriodId": "4bfdc253-e39a-4cfa-9a45-2cfc6e93cc6f", - "challengeId": "f151a5a1-6b28-4f59-bdde-6e73498faa84", - "amount": 450, - "status": "cancelled", - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": null, - "createdAt": "2021-04-14T22:01:45.326Z", - "updatedAt": "2021-04-21T20:19:56.934Z" - }, - { - "id": "5192e519-30f5-42d6-877f-5c2b786d91c7", - "workPeriodId": "4db82b0b-4d6f-4e9a-b957-ab405b2c2df2", - "challengeId": "93f594e9-5396-416a-8212-87bee614a38f", - "amount": 600, - "status": "cancelled", - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "createdAt": "2021-04-14T19:13:23.714Z", - "updatedAt": "2021-04-16T19:13:23.714Z" - }, - { - "id": "8ca85158-a850-4cae-97f0-5873a9225ff8", - "workPeriodId": "531754f3-405e-42eb-932a-c1ce7b9386e7", - "challengeId": "b42b8f40-9a4d-45d1-814e-59da5c7a1fd9", - "amount": 1200, - "status": "completed", - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": null, - "createdAt": "2021-04-14T19:13:23.714Z", - "updatedAt": "2021-04-21T20:19:56.934Z" - }, - { - "id": "4a81c6a3-18d9-441b-ae64-3aa9def336ef", - "workPeriodId": "5392acee-b504-4720-95fa-dab585acb607", - "challengeId": "78154e5c-feed-4dbf-84ec-775395139211", - "amount": 200, - "status": "completed", - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "createdAt": "2021-04-14T19:13:23.714Z", - "updatedAt": "2021-04-16T19:13:23.714Z" - }, - { - "id": "a26b8cae-a1df-4843-a192-0735f235bf78", - "workPeriodId": "558b4685-4932-492e-99e1-2830c10f8275", - "challengeId": "0de972b8-6cc9-4625-9760-1c77561c29e9", - "amount": 600, - "status": "completed", - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": null, - "createdAt": "2021-04-14T19:13:23.714Z", - "updatedAt": "2021-04-21T20:19:56.934Z" - }, - { - "id": "a94b6f43-de89-4fd2-9a1d-d8a2cce02702", - "workPeriodId": "584c931b-da72-416e-a011-eac5fe34f42f", - "challengeId": "d55fae30-3072-462e-b8bd-eb2eec664e65", - "amount": 1600, - "status": "completed", - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": null, - "createdAt": "2021-04-14T22:01:45.324Z", - "updatedAt": "2021-04-21T20:19:56.934Z" - }, - { - "id": "eb63dfc7-14d7-4cae-a25e-3e33a04601cf", - "workPeriodId": "5ddc132b-3205-45e3-bfe9-f1a4f939885e", - "challengeId": "0de972b8-6cc9-4625-9760-1c77561c29e9", - "amount": 300, - "status": "completed", - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": null, - "createdAt": "2021-04-14T19:13:23.714Z", - "updatedAt": "2021-04-21T20:19:56.934Z" - }, - { - "id": "d827ed01-5153-4774-8450-bace2521a6d1", - "workPeriodId": "619a0835-730f-47ec-820e-3959821aec51", - "challengeId": "d40cb9c5-b3bd-45a1-802c-a50fefb020b9", - "amount": 1000, - "status": "completed", - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": null, - "createdAt": "2021-04-14T22:01:45.326Z", - "updatedAt": "2021-04-21T20:19:56.934Z" - }, - { - "id": "f950e52e-5a52-4ee8-af5f-e6c42e9b400b", - "workPeriodId": "64de2244-6fcf-45ac-8a89-a9b3420e4476", - "challengeId": "6c04d456-bb38-43c8-a538-f5cc6caaa540", - "amount": 800, - "status": "completed", - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": null, - "createdAt": "2021-04-14T19:13:23.714Z", - "updatedAt": "2021-04-21T20:19:56.934Z" - }, - { - "id": "283f9c3b-7f0a-4792-9661-ced7cbdb340d", - "workPeriodId": "6a1180b8-38af-4bd0-8a5f-a60626e0bc95", - "challengeId": "9a995b78-0542-41be-a926-f3df57c2f873", - "amount": 400, - "status": "completed", - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": null, - "createdAt": "2021-04-14T22:01:45.361Z", - "updatedAt": "2021-04-21T20:19:56.934Z" - }, - { - "id": "09ea6f03-4489-496c-817c-e9279a58c0ad", - "workPeriodId": "6da7d347-7492-43b1-a49d-8a6e1daf9b22", - "challengeId": "78154e5c-feed-4dbf-84ec-775395139211", - "amount": 400, - "status": "completed", - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": null, - "createdAt": "2021-04-14T19:13:23.714Z", - "updatedAt": "2021-04-21T20:19:56.934Z" - }, - { - "id": "7d782624-243e-497b-90ca-cc00ae29ebf2", - "workPeriodId": "6e1dc024-d437-4d9f-92e9-561db713a19a", - "challengeId": "afcbc3bc-9077-4978-bf9c-acddb48e6518", - "amount": 800, - "status": "completed", - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": null, - "createdAt": "2021-04-14T22:01:45.324Z", - "updatedAt": "2021-04-21T20:19:56.934Z" - }, - { - "id": "11918ff9-5f18-445d-ae90-762b3ebe44ca", - "workPeriodId": "6ed667a5-275e-4f27-984b-34dff5f8a1ff", - "challengeId": "c89d357f-afd1-4757-824f-2cf94e2890c6", - "amount": 250, - "status": "completed", - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": null, - "createdAt": "2021-04-14T22:01:45.361Z", - "updatedAt": "2021-04-21T20:19:56.934Z" - }, - { - "id": "9fe78619-5c1c-4b22-8d6f-ebf9a9502432", - "workPeriodId": "703bc625-9144-4a9f-a91b-445e171d8ea9", - "challengeId": "6c04d456-bb38-43c8-a538-f5cc6caaa540", - "amount": 400, - "status": "completed", - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": null, - "createdAt": "2021-04-14T19:13:23.714Z", - "updatedAt": "2021-04-21T20:19:56.934Z" - }, - { - "id": "7cf85ce0-ef8c-4152-8623-9a1325db6daa", - "workPeriodId": "729a2396-2b33-4185-8ce8-d929dbf4a472", - "challengeId": "fbf8efda-fe4b-4b72-99dd-573b79d27bd8", - "amount": 200, - "status": "cancelled", - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": null, - "createdAt": "2021-04-14T22:01:45.390Z", - "updatedAt": "2021-04-21T20:19:56.934Z" - }, - { - "id": "e8aee371-1f26-4475-8459-9c134fa6f3c6", - "workPeriodId": "731db5d7-bb79-45f4-b1b2-9f60d30f7966", - "challengeId": "ee9bcdd0-0d0d-4414-88cb-d14255f996a5", - "amount": 700, - "status": "cancelled", - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": null, - "createdAt": "2021-04-14T19:13:23.714Z", - "updatedAt": "2021-04-21T20:19:56.934Z" - }, - { - "id": "dec8615b-c823-4fff-bc77-fa0614b8d09c", - "workPeriodId": "7f8f3a25-b1d2-4e36-a543-fcaae57a32f5", - "challengeId": "fe3e4056-82e3-4df4-b699-a1f3d8ab5e53", - "amount": 700, - "status": "completed", - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": null, - "createdAt": "2021-04-14T22:01:45.390Z", - "updatedAt": "2021-04-21T20:19:56.934Z" - }, - { - "id": "c4e316ca-a46f-4fbc-96a6-6fe6665c3b49", - "workPeriodId": "829165cb-0150-48e7-995c-f5b4d1a51d3b", - "challengeId": "d937a822-4a9b-40db-afe6-fe1285e3f7f9", - "amount": 900, - "status": "completed", - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": null, - "createdAt": "2021-04-14T22:01:45.324Z", - "updatedAt": "2021-04-21T20:19:56.934Z" - }, - { - "id": "12b0bcfc-59ae-478c-bb32-cb18d1d0244c", - "workPeriodId": "84431dac-019d-4987-9817-15f5f000d2db", - "challengeId": "a07ea88f-c52b-4023-8730-c4364efd0dd2", - "amount": 600, - "status": "completed", - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": null, - "createdAt": "2021-04-14T22:01:45.361Z", - "updatedAt": "2021-04-21T20:19:56.934Z" - }, - { - "id": "8c9ed23c-12c7-4a8b-8e91-6fd3b3fc43a4", - "workPeriodId": "8b7b49de-29b1-4a0c-bb67-e70cc700fcfd", - "challengeId": "0de972b8-6cc9-4625-9760-1c77561c29e9", - "amount": 450, - "status": "completed", - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": null, - "createdAt": "2021-04-14T19:13:23.714Z", - "updatedAt": "2021-04-21T20:19:56.934Z" - }, - { - "id": "621d793b-0ead-4d99-a119-e32af526ece7", - "workPeriodId": "8c8cedf3-0bb6-4063-8a3a-faf1626da384", - "challengeId": "ad04dcee-9a3c-4345-b0b5-783ce98e94b2", - "amount": 900, - "status": "completed", - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": null, - "createdAt": "2021-04-14T22:01:45.390Z", - "updatedAt": "2021-04-21T20:19:56.934Z" - }, - { - "id": "56cb3aef-531b-4a26-817e-4b9629212c9a", - "workPeriodId": "90d99323-ba57-4a18-b50f-78f387033c70", - "challengeId": "0de972b8-6cc9-4625-9760-1c77561c29e9", - "amount": 450, - "status": "completed", - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": null, - "createdAt": "2021-04-14T19:13:23.714Z", - "updatedAt": "2021-04-21T20:19:56.934Z" - }, - { - "id": "a1ffc559-703a-4c35-8ba3-73a03c3454af", - "workPeriodId": "93b0f03b-219b-41d5-bb1e-f125651b1b0e", - "challengeId": "9fca67f9-3641-4982-8a82-e86b1850efc8", - "amount": 600, - "status": "completed", - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": null, - "createdAt": "2021-04-14T22:01:45.326Z", - "updatedAt": "2021-04-21T20:19:56.934Z" - }, - { - "id": "a5904ae3-7524-4709-b798-20c4a2193f10", - "workPeriodId": "93e69f99-cb1c-418e-aa41-ab2181b4bcfd", - "challengeId": "ed56a1c7-a965-4ab6-9cf0-0d7c14cd7db3", - "amount": 400, - "status": "completed", - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": null, - "createdAt": "2021-04-14T22:01:45.361Z", - "updatedAt": "2021-04-21T20:19:56.934Z" - }, - { - "id": "821b38e8-657d-4f72-b27a-dd975c506ced", - "workPeriodId": "9b6fc85b-3694-4e6c-9ebf-fe9ccf7881ba", - "challengeId": "61f5185b-4ee1-4df3-9c6f-52f5bf0cbfc5", - "amount": 500, - "status": "completed", - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": null, - "createdAt": "2021-04-14T22:01:45.361Z", - "updatedAt": "2021-04-21T20:19:56.934Z" - }, - { - "id": "2417df2c-8e29-4868-aeb8-5ec0ff67713e", - "workPeriodId": "9bfbd49a-e6bb-45c3-965d-ed4f95f0878a", - "challengeId": "f01ba8da-c891-472d-9ed6-74b91ed9b407", - "amount": 400, - "status": "completed", - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": null, - "createdAt": "2021-04-14T19:13:23.714Z", - "updatedAt": "2021-04-21T20:19:56.934Z" - }, - { - "id": "5116d4ea-2c1a-4be6-b335-bd531b8d5734", - "workPeriodId": "a35bb205-361b-4b2d-9828-55501ae9d190", - "challengeId": "b42b8f40-9a4d-45d1-814e-59da5c7a1fd9", - "amount": 600, - "status": "completed", - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "createdAt": "2021-04-14T19:13:23.714Z", - "updatedAt": "2021-04-16T19:13:23.714Z" - }, - { - "id": "8fdfe90b-2155-4a71-a610-4689106ced34", - "workPeriodId": "b21f921a-4b23-423d-814b-d31f5cba7f64", - "challengeId": "963784fd-4174-458c-a311-a5b8333d66ab", - "amount": 300, - "status": "completed", - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": null, - "createdAt": "2021-04-14T22:01:45.361Z", - "updatedAt": "2021-04-21T20:19:56.934Z" - }, - { - "id": "dd9c842a-f577-43c2-8f17-cc940f26f0d8", - "workPeriodId": "b4566e24-4fa8-4e82-9950-f62134bb00df", - "challengeId": "b67cbbc5-3384-4ea6-8504-d3fe83a6e238", - "amount": 700, - "status": "completed", - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": null, - "createdAt": "2021-04-14T22:01:45.326Z", - "updatedAt": "2021-04-21T20:19:56.934Z" - }, - { - "id": "7e41ca7f-d3c0-4d70-9daf-ee52c93695c7", - "workPeriodId": "b5261ee2-bc4d-4c3a-9d30-6703bfdcfbc5", - "challengeId": "9d49655f-99f6-4e67-9819-a117ef746272", - "amount": 500, - "status": "completed", - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": null, - "createdAt": "2021-04-14T22:01:45.361Z", - "updatedAt": "2021-04-21T20:19:56.934Z" - }, - { - "id": "b8d44e83-922c-4c2c-8567-5764794e03f3", - "workPeriodId": "b682660e-488e-4033-aaf3-ef37248abc90", - "challengeId": "d7c21199-a435-41b8-a2ac-5e5bdd021c5e", - "amount": 700, - "status": "completed", - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "createdAt": "2021-04-14T19:13:23.714Z", - "updatedAt": "2021-04-16T19:13:23.714Z" - }, - { - "id": "c117de76-965f-4069-aefb-8dd97f95112c", - "workPeriodId": "b8a8b558-0cb9-46d0-ba9d-2222f3fbdb63", - "challengeId": "59d08064-e1b4-4e78-82d8-b2d7ffa6f0b1", - "amount": 900, - "status": "completed", - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": null, - "createdAt": "2021-04-14T22:01:45.523Z", - "updatedAt": "2021-04-21T20:19:56.934Z" - }, - { - "id": "fda2013c-da68-4601-8d13-d0f4cffd081c", - "workPeriodId": "bc8611f0-4ac2-49b2-b776-59ed2b759d1d", - "challengeId": "0de972b8-6cc9-4625-9760-1c77561c29e9", - "amount": 800, - "status": "completed", - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": null, - "createdAt": "2021-04-14T19:13:23.714Z", - "updatedAt": "2021-04-21T20:19:56.934Z" - }, - { - "id": "be07bfc8-032c-41f7-a247-a4724f65617c", - "workPeriodId": "bd54bcaf-5278-467f-a166-865048774d0e", - "challengeId": "45e33cee-7c83-4288-8187-6858b0c759eb", - "amount": 800, - "status": "completed", - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": null, - "createdAt": "2021-04-14T22:01:45.361Z", - "updatedAt": "2021-04-21T20:19:56.934Z" - }, - { - "id": "efa8cd14-c93f-4e6c-be53-596f02db8c96", - "workPeriodId": "bf61dad8-841a-4913-93f6-b2ae516b8b11", - "challengeId": "0de972b8-6cc9-4625-9760-1c77561c29e9", - "amount": 800, - "status": "completed", - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": null, - "createdAt": "2021-04-14T19:13:23.714Z", - "updatedAt": "2021-04-21T20:19:56.934Z" - }, - { - "id": "eb9c9a83-fe94-4f51-b9f0-c2d9671e87f6", - "workPeriodId": "c5f6ae8f-2976-46d1-bd66-58eeb58ca045", - "challengeId": "68e6a32e-6c31-4266-ba3b-9d2f63be4274", - "amount": 900, - "status": "completed", - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": null, - "createdAt": "2021-04-14T22:01:45.361Z", - "updatedAt": "2021-04-21T20:19:56.934Z" - }, - { - "id": "c20796c8-76b0-40e8-9bee-db406c93daaf", - "workPeriodId": "c7ff2acc-a4c2-4e8b-a905-813dd9d1b293", - "challengeId": "513ab4c6-0aa4-482b-a184-87f8447b145b", - "amount": 1800, - "status": "completed", - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": null, - "createdAt": "2021-04-14T22:01:45.390Z", - "updatedAt": "2021-04-21T20:19:56.934Z" - }, - { - "id": "8fad32f7-cb40-416f-ab24-86cf1c7870ef", - "workPeriodId": "c9685cb2-9f4a-497e-ae99-deed7b16cc34", - "challengeId": "f7e40a0c-a302-4989-a3bd-7587fee3c367", - "amount": 600, - "status": "completed", - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": null, - "createdAt": "2021-04-14T19:13:23.714Z", - "updatedAt": "2021-04-21T20:19:56.934Z" - }, - { - "id": "310384cb-6e85-4f7d-a6d2-8c03ca27871d", - "workPeriodId": "d049e7bc-c827-482b-9ec6-b87d9289d1cd", - "challengeId": "0de972b8-6cc9-4625-9760-1c77561c29e9", - "amount": 900, - "status": "completed", - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": null, - "createdAt": "2021-04-14T19:13:23.714Z", - "updatedAt": "2021-04-21T20:19:56.934Z" - }, - { - "id": "2a122a93-e778-4eb9-868c-5f38b8b9bb4e", - "workPeriodId": "da8abd64-2878-4e09-b3b1-41a27a0576d4", - "challengeId": "25a7c442-427b-4b6d-9c41-112dbd420c0d", - "amount": 800, - "status": "completed", - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": null, - "createdAt": "2021-04-14T19:13:23.714Z", - "updatedAt": "2021-04-21T20:19:56.934Z" - }, - { - "id": "767897c3-bbc2-4b1a-9843-5a6bd82e29b0", - "workPeriodId": "dcc310cf-ea4a-4637-9bf5-5baaabea67b3", - "challengeId": "61044188-965e-40df-94c4-9fa9a9499b25", - "amount": 1000, - "status": "completed", - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": null, - "createdAt": "2021-04-14T22:01:45.523Z", - "updatedAt": "2021-04-21T20:19:56.934Z" - }, - { - "id": "50f7a6fa-a04d-4873-8fd0-037be2f14425", - "workPeriodId": "e19bddc5-38ac-43c9-8273-bc9069de26b3", - "challengeId": "419fbb3d-921d-4613-a87e-337f38d21885", - "amount": 600, - "status": "completed", - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": null, - "createdAt": "2021-04-14T22:01:45.523Z", - "updatedAt": "2021-04-21T20:19:56.934Z" - }, - { - "id": "11ea987f-f218-4d2b-b656-0741208539f2", - "workPeriodId": "f575df2d-f170-4251-9042-b17ca5e99ca5", - "challengeId": "0de972b8-6cc9-4625-9760-1c77561c29e9", - "amount": 600, - "status": "completed", - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": null, - "createdAt": "2021-04-16T19:13:23.714Z", - "updatedAt": "2021-04-21T20:19:56.934Z" - }, - { - "id": "2519d7f9-81c8-448c-aec2-aa78d6d6a962", - "workPeriodId": "f70509c0-baed-4ff1-8022-12441251f7af", - "challengeId": "fd051497-6050-4edf-b8f7-780128f64dc5", - "amount": 300, - "status": "cancelled", - "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", - "updatedBy": null, - "createdAt": "2021-04-14T22:01:45.324Z", - "updatedAt": "2021-04-21T20:19:56.934Z" - } - ] + ] } diff --git a/docs/Topcoder-bookings-api.postman_collection.json b/docs/Topcoder-bookings-api.postman_collection.json index a6afdc2b..a0518c50 100644 --- a/docs/Topcoder-bookings-api.postman_collection.json +++ b/docs/Topcoder-bookings-api.postman_collection.json @@ -1,6 +1,6 @@ { "info": { - "_postman_id": "3f80d93d-6ca3-4645-970d-a9e533394e2e", + "_postman_id": "58b277bb-0d1d-4bbf-919f-c5951ba0e1c0", "name": "Topcoder-bookings-api", "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json" }, @@ -7865,8 +7865,13 @@ "listen": "test", "script": { "exec": [ - "var data = JSON.parse(responseBody);\r", - "postman.setEnvironmentVariable(\"jobIdCreatedByM2M\",data.id);" + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", + " if(pm.response.status === \"OK\"){\r", + " const response = pm.response.json()\r", + " pm.environment.set(\"jobIdCreatedByM2M\", response.id);\r", + " }\r", + "});" ], "type": "text/javascript" } @@ -8182,6 +8187,55 @@ }, "response": [] }, + { + "name": "create resource booking with m2m all", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", + " if(pm.response.status === \"OK\"){\r", + " const response = pm.response.json()\r", + " pm.environment.set(\"resourceBookingIdCreatedByM2M\", response.id);\r", + " }\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_m2m_all_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-09-27\",\r\n \"endDate\": \"2020-10-27\",\r\n \"memberRate\": 13.23,\r\n \"customerRate\": 10,\r\n \"rateType\": \"hourly\",\r\n \"billingAccountId\": 80000071\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/resourceBookings", + "host": [ + "{{URL}}" + ], + "path": [ + "resourceBookings" + ] + } + }, + "response": [] + }, { "name": "create resource booking with connect user", "event": [ @@ -8564,7 +8618,7 @@ "response": [] }, { - "name": "search resource bookings with booking manager", + "name": "get resource booking with parameters 1", "event": [ { "listen": "test", @@ -8572,6 +8626,10 @@ "exec": [ "pm.test('Status code is 200', function () {\r", " pm.response.to.have.status(200);\r", + " const response = pm.response.json()\r", + " _.each(['id','projectId','status','startDate','endDate','billingAccountId','userId','jobId','rateType','memberRate','customerRate','createdBy','updatedBy','createdAt','updatedAt'], field => {\r", + " pm.expect(response).to.have.property(field)\r", + " })\r", "});" ], "type": "text/javascript" @@ -8588,58 +8646,18 @@ } ], "url": { - "raw": "{{URL}}/resourceBookings", + "raw": "{{URL}}/resourceBookings/{{resourceBookingId}}?fields=id,projectId,status,startDate,endDate,billingAccountId,userId,jobId,rateType,memberRate,customerRate,createdBy,updatedBy,createdAt,updatedAt,deletedAt", "host": [ "{{URL}}" ], "path": [ - "resourceBookings" + "resourceBookings", + "{{resourceBookingId}}" ], "query": [ { - "key": "page", - "value": "1", - "disabled": true - }, - { - "key": "perPage", - "value": "5", - "disabled": true - }, - { - "key": "sortBy", - "value": "id", - "disabled": true - }, - { - "key": "sortOrder", - "value": "desc", - "disabled": true - }, - { - "key": "startDate", - "value": "2020-09-27", - "disabled": true - }, - { - "key": "endDate", - "value": "2020-09-27", - "disabled": true - }, - { - "key": "rateType", - "value": "hourly", - "disabled": true - }, - { - "key": "status", - "value": "assigned", - "disabled": true - }, - { - "key": "projectIds", - "value": "111, 16705", - "disabled": true + "key": "fields", + "value": "id,projectId,status,startDate,endDate,billingAccountId,userId,jobId,rateType,memberRate,customerRate,createdBy,updatedBy,createdAt,updatedAt,deletedAt" } ] } @@ -8647,7 +8665,7 @@ "response": [] }, { - "name": "search resource bookings with m2m all", + "name": "get resource booking with parameters 1 fromDb", "event": [ { "listen": "test", @@ -8655,6 +8673,10 @@ "exec": [ "pm.test('Status code is 200', function () {\r", " pm.response.to.have.status(200);\r", + " const response = pm.response.json()\r", + " _.each(['id','projectId','status','startDate','endDate','billingAccountId','userId','jobId','rateType','memberRate','customerRate','createdBy','updatedBy','createdAt','updatedAt'], field => {\r", + " pm.expect(response).to.have.property(field)\r", + " })\r", "});" ], "type": "text/javascript" @@ -8667,57 +8689,26 @@ { "key": "Authorization", "type": "text", - "value": "Bearer {{token_m2m_all_resource_booking}}" + "value": "Bearer {{token_bookingManager}}" } ], "url": { - "raw": "{{URL}}/resourceBookings", + "raw": "{{URL}}/resourceBookings/{{resourceBookingId}}?fields=id,projectId,status,startDate,endDate,billingAccountId,userId,jobId,rateType,memberRate,customerRate,createdBy,updatedBy,createdAt,updatedAt,deletedAt&fromDb=true", "host": [ "{{URL}}" ], "path": [ - "resourceBookings" + "resourceBookings", + "{{resourceBookingId}}" ], "query": [ { - "key": "page", - "value": "1", - "disabled": true - }, - { - "key": "perPage", - "value": "5", - "disabled": true - }, - { - "key": "sortBy", - "value": "id", - "disabled": true - }, - { - "key": "sortOrder", - "value": "desc", - "disabled": true - }, - { - "key": "startDate", - "value": "2020-09-27", - "disabled": true - }, - { - "key": "endDate", - "value": "2020-09-27", - "disabled": true - }, - { - "key": "rateType", - "value": "hourly", - "disabled": true + "key": "fields", + "value": "id,projectId,status,startDate,endDate,billingAccountId,userId,jobId,rateType,memberRate,customerRate,createdBy,updatedBy,createdAt,updatedAt,deletedAt" }, { - "key": "status", - "value": "assigned", - "disabled": true + "key": "fromDb", + "value": "true" } ] } @@ -8725,7 +8716,7 @@ "response": [] }, { - "name": "search resource bookings with connect user", + "name": "get resource booking with parameters 2", "event": [ { "listen": "test", @@ -8733,6 +8724,13 @@ "exec": [ "pm.test('Status code is 200', function () {\r", " pm.response.to.have.status(200);\r", + " const response = pm.response.json()\r", + " _.each(['id','projectId','status','startDate','endDate','billingAccountId','userId','jobId','rateType','memberRate','customerRate','createdBy','updatedBy','createdAt','updatedAt','workPeriods'], field => {\r", + " pm.expect(response).to.have.property(field)\r", + " })\r", + " _.each(['id','projectId','paymentStatus','startDate','endDate','userHandle','resourceBookingId','daysWorked','memberRate','customerRate','createdBy','updatedBy','createdAt','updatedAt'], field => {\r", + " pm.expect(response.workPeriods[0]).to.have.property(field)\r", + " })\r", "});" ], "type": "text/javascript" @@ -8745,51 +8743,22 @@ { "key": "Authorization", "type": "text", - "value": "Bearer {{token_connectUser}}" + "value": "Bearer {{token_bookingManager}}" } ], "url": { - "raw": "{{URL}}/resourceBookings?sortOrder=desc", + "raw": "{{URL}}/resourceBookings/{{resourceBookingId}}?fields=workPeriods,id,projectId,status,startDate,endDate,billingAccountId,userId,jobId,rateType,memberRate,customerRate,createdBy,updatedBy,createdAt,updatedAt,deletedAt", "host": [ "{{URL}}" ], "path": [ - "resourceBookings" + "resourceBookings", + "{{resourceBookingId}}" ], "query": [ { - "key": "page", - "value": "4", - "disabled": true - }, - { - "key": "perPage", - "value": "3", - "disabled": true - }, - { - "key": "sortBy", - "value": "id", - "disabled": true - }, - { - "key": "startDate", - "value": "2020-09-27", - "disabled": true - }, - { - "key": "endDate", - "value": "2020-09-27", - "disabled": true - }, - { - "key": "rateType", - "value": "hourly", - "disabled": true - }, - { - "key": "sortOrder", - "value": "desc" + "key": "fields", + "value": "workPeriods,id,projectId,status,startDate,endDate,billingAccountId,userId,jobId,rateType,memberRate,customerRate,createdBy,updatedBy,createdAt,updatedAt,deletedAt" } ] } @@ -8797,13 +8766,22 @@ "response": [] }, { - "name": "search resource bookings with member", + "name": "get resource booking with parameters 2 fromDb", "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", + " _.each(['id','projectId','status','startDate','endDate','billingAccountId','userId','jobId','rateType','memberRate','customerRate','createdBy','updatedBy','createdAt','updatedAt','workPeriods'], field => {\r", + " pm.expect(response).to.have.property(field)\r", + " })\r", + " _.each(['id','projectId','paymentStatus','startDate','endDate','userHandle','resourceBookingId','daysWorked','memberRate','customerRate','createdBy','updatedBy','createdAt','updatedAt'], field => {\r", + " pm.expect(response.workPeriods[0]).to.have.property(field)\r", + " })\r", + "});" ], "type": "text/javascript" } @@ -8815,51 +8793,26 @@ { "key": "Authorization", "type": "text", - "value": "Bearer {{token_member}}" + "value": "Bearer {{token_bookingManager}}" } ], "url": { - "raw": "{{URL}}/resourceBookings?sortOrder=desc", + "raw": "{{URL}}/resourceBookings/{{resourceBookingId}}?fields=workPeriods,id,projectId,status,startDate,endDate,billingAccountId,userId,jobId,rateType,memberRate,customerRate,createdBy,updatedBy,createdAt,updatedAt,deletedAt&fromDb=true", "host": [ "{{URL}}" ], "path": [ - "resourceBookings" + "resourceBookings", + "{{resourceBookingId}}" ], "query": [ { - "key": "page", - "value": "4", - "disabled": true - }, - { - "key": "perPage", - "value": "3", - "disabled": true - }, - { - "key": "sortBy", - "value": "id", - "disabled": true - }, - { - "key": "startDate", - "value": "2020-09-27", - "disabled": true - }, - { - "key": "endDate", - "value": "2020-09-27", - "disabled": true - }, - { - "key": "rateType", - "value": "hourly", - "disabled": true + "key": "fields", + "value": "workPeriods,id,projectId,status,startDate,endDate,billingAccountId,userId,jobId,rateType,memberRate,customerRate,createdBy,updatedBy,createdAt,updatedAt,deletedAt" }, { - "key": "sortOrder", - "value": "desc" + "key": "fromDb", + "value": "true" } ] } @@ -8867,16 +8820,21 @@ "response": [] }, { - "name": "search resource bookings with invalid token", + "name": "get resource booking with parameters 3", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 401', function () {\r", - " pm.response.to.have.status(401);\r", + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"Invalid Token.\")\r", + " _.each(['id','projectId','status','startDate','endDate'], field => {\r", + " pm.expect(response).to.have.property(field)\r", + " })\r", + " _.each(['id','projectId','startDate','endDate','daysWorked'], field => {\r", + " pm.expect(response.workPeriods[0]).to.have.property(field)\r", + " })\r", "});" ], "type": "text/javascript" @@ -8889,51 +8847,1231 @@ { "key": "Authorization", "type": "text", - "value": "Bearer invalid_token" + "value": "Bearer {{token_bookingManager}}" } ], "url": { - "raw": "{{URL}}/resourceBookings?sortOrder=desc", + "raw": "{{URL}}/resourceBookings/{{resourceBookingId}}?fields=workPeriods.id,workPeriods.projectId,workPeriods.startDate,workPeriods.endDate,workPeriods.daysWorked,id,projectId,status,startDate,endDate", "host": [ "{{URL}}" ], "path": [ - "resourceBookings" + "resourceBookings", + "{{resourceBookingId}}" ], "query": [ { - "key": "page", - "value": "4", - "disabled": true - }, - { - "key": "perPage", - "value": "3", + "key": "fields", + "value": "workPeriods.id,workPeriods.projectId,workPeriods.startDate,workPeriods.endDate,workPeriods.daysWorked,id,projectId,status,startDate,endDate" + } + ] + } + }, + "response": [] + }, + { + "name": "get resource booking with parameters 3 fromDb", + "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", + " _.each(['id','projectId','status','startDate','endDate'], field => {\r", + " pm.expect(response).to.have.property(field)\r", + " })\r", + " _.each(['id','projectId','startDate','endDate','daysWorked'], field => {\r", + " pm.expect(response.workPeriods[0]).to.have.property(field)\r", + " })\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_bookingManager}}" + } + ], + "url": { + "raw": "{{URL}}/resourceBookings/{{resourceBookingId}}?fields=workPeriods.id,workPeriods.projectId,workPeriods.startDate,workPeriods.endDate,workPeriods.daysWorked,id,projectId,status,startDate,endDate&fromDb=true", + "host": [ + "{{URL}}" + ], + "path": [ + "resourceBookings", + "{{resourceBookingId}}" + ], + "query": [ + { + "key": "fields", + "value": "workPeriods.id,workPeriods.projectId,workPeriods.startDate,workPeriods.endDate,workPeriods.daysWorked,id,projectId,status,startDate,endDate" + }, + { + "key": "fromDb", + "value": "true" + } + ] + } + }, + "response": [] + }, + { + "name": "get resource booking with parameters 4", + "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 don't have access to view memberRate\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_connectUser}}" + } + ], + "url": { + "raw": "{{URL}}/resourceBookings/{{resourceBookingId}}?fields=memberRate", + "host": [ + "{{URL}}" + ], + "path": [ + "resourceBookings", + "{{resourceBookingId}}" + ], + "query": [ + { + "key": "fields", + "value": "memberRate" + } + ] + } + }, + "response": [] + }, + { + "name": "get resource booking with parameters 4 fromDb", + "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 don't have access to view memberRate\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_connectUser}}" + } + ], + "url": { + "raw": "{{URL}}/resourceBookings/{{resourceBookingId}}?fields=memberRate&fromDb=true", + "host": [ + "{{URL}}" + ], + "path": [ + "resourceBookings", + "{{resourceBookingId}}" + ], + "query": [ + { + "key": "fields", + "value": "memberRate" + }, + { + "key": "fromDb", + "value": "true" + } + ] + } + }, + "response": [] + }, + { + "name": "get resource booking with parameters 5", + "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 don't have access to view workPeriods\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_m2m_all_resource_booking}}" + } + ], + "url": { + "raw": "{{URL}}/resourceBookings/{{resourceBookingId}}?fields=workPeriods", + "host": [ + "{{URL}}" + ], + "path": [ + "resourceBookings", + "{{resourceBookingId}}" + ], + "query": [ + { + "key": "fields", + "value": "workPeriods" + } + ] + } + }, + "response": [] + }, + { + "name": "get resource booking with parameters 5 fromDb", + "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 don't have access to view workPeriods\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_m2m_all_resource_booking}}" + } + ], + "url": { + "raw": "{{URL}}/resourceBookings/{{resourceBookingId}}?fields=workPeriods&fromDb=true", + "host": [ + "{{URL}}" + ], + "path": [ + "resourceBookings", + "{{resourceBookingId}}" + ], + "query": [ + { + "key": "fields", + "value": "workPeriods" + }, + { + "key": "fromDb", + "value": "true" + } + ] + } + }, + "response": [] + }, + { + "name": "search resource bookings with booking manager", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_bookingManager}}" + } + ], + "url": { + "raw": "{{URL}}/resourceBookings", + "host": [ + "{{URL}}" + ], + "path": [ + "resourceBookings" + ], + "query": [ + { + "key": "page", + "value": "1", + "disabled": true + }, + { + "key": "perPage", + "value": "5", + "disabled": true + }, + { + "key": "sortBy", + "value": "id", + "disabled": true + }, + { + "key": "sortOrder", + "value": "desc", + "disabled": true + }, + { + "key": "startDate", + "value": "2020-09-27", + "disabled": true + }, + { + "key": "endDate", + "value": "2020-09-27", + "disabled": true + }, + { + "key": "rateType", + "value": "hourly", + "disabled": true + }, + { + "key": "status", + "value": "assigned", + "disabled": true + }, + { + "key": "projectIds", + "value": "111, 16705", + "disabled": true + } + ] + } + }, + "response": [] + }, + { + "name": "search resource bookings with m2m all", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_m2m_all_resource_booking}}" + } + ], + "url": { + "raw": "{{URL}}/resourceBookings", + "host": [ + "{{URL}}" + ], + "path": [ + "resourceBookings" + ], + "query": [ + { + "key": "page", + "value": "1", + "disabled": true + }, + { + "key": "perPage", + "value": "5", + "disabled": true + }, + { + "key": "sortBy", + "value": "id", + "disabled": true + }, + { + "key": "sortOrder", + "value": "desc", + "disabled": true + }, + { + "key": "startDate", + "value": "2020-09-27", + "disabled": true + }, + { + "key": "endDate", + "value": "2020-09-27", + "disabled": true + }, + { + "key": "rateType", + "value": "hourly", + "disabled": true + }, + { + "key": "status", + "value": "assigned", + "disabled": true + } + ] + } + }, + "response": [] + }, + { + "name": "search resource bookings with connect user", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_connectUser}}" + } + ], + "url": { + "raw": "{{URL}}/resourceBookings?sortOrder=desc", + "host": [ + "{{URL}}" + ], + "path": [ + "resourceBookings" + ], + "query": [ + { + "key": "page", + "value": "4", + "disabled": true + }, + { + "key": "perPage", + "value": "3", + "disabled": true + }, + { + "key": "sortBy", + "value": "id", + "disabled": true + }, + { + "key": "startDate", + "value": "2020-09-27", + "disabled": true + }, + { + "key": "endDate", + "value": "2020-09-27", + "disabled": true + }, + { + "key": "rateType", + "value": "hourly", + "disabled": true + }, + { + "key": "sortOrder", + "value": "desc" + } + ] + } + }, + "response": [] + }, + { + "name": "search resource bookings with member", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_member}}" + } + ], + "url": { + "raw": "{{URL}}/resourceBookings?sortOrder=desc", + "host": [ + "{{URL}}" + ], + "path": [ + "resourceBookings" + ], + "query": [ + { + "key": "page", + "value": "4", + "disabled": true + }, + { + "key": "perPage", + "value": "3", + "disabled": true + }, + { + "key": "sortBy", + "value": "id", + "disabled": true + }, + { + "key": "startDate", + "value": "2020-09-27", + "disabled": true + }, + { + "key": "endDate", + "value": "2020-09-27", + "disabled": true + }, + { + "key": "rateType", + "value": "hourly", + "disabled": true + }, + { + "key": "sortOrder", + "value": "desc" + } + ] + } + }, + "response": [] + }, + { + "name": "search resource bookings with invalid token", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 401', function () {\r", + " pm.response.to.have.status(401);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"Invalid Token.\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer invalid_token" + } + ], + "url": { + "raw": "{{URL}}/resourceBookings?sortOrder=desc", + "host": [ + "{{URL}}" + ], + "path": [ + "resourceBookings" + ], + "query": [ + { + "key": "page", + "value": "4", + "disabled": true + }, + { + "key": "perPage", + "value": "3", + "disabled": true + }, + { + "key": "sortBy", + "value": "id", + "disabled": true + }, + { + "key": "startDate", + "value": "2020-09-27", + "disabled": true + }, + { + "key": "endDate", + "value": "2020-09-27", + "disabled": true + }, + { + "key": "rateType", + "value": "hourly", "disabled": true }, { - "key": "sortBy", - "value": "id", - "disabled": true + "key": "sortOrder", + "value": "desc" + } + ] + } + }, + "response": [] + }, + { + "name": "search resource bookings with parameters 1", + "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", + " _.each(['id','projectId','status','startDate','endDate','billingAccountId','userId','jobId','rateType','memberRate','customerRate','createdBy','updatedBy','createdAt','updatedAt'], field => {\r", + " pm.expect(response[0]).to.have.property(field)\r", + " })\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_bookingManager}}" + } + ], + "url": { + "raw": "{{URL}}/resourceBookings?fields=id,projectId,status,startDate,endDate,billingAccountId,userId,jobId,rateType,memberRate,customerRate,createdBy,updatedBy,createdAt,updatedAt,deletedAt", + "host": [ + "{{URL}}" + ], + "path": [ + "resourceBookings" + ], + "query": [ + { + "key": "fields", + "value": "id,projectId,status,startDate,endDate,billingAccountId,userId,jobId,rateType,memberRate,customerRate,createdBy,updatedBy,createdAt,updatedAt,deletedAt" + } + ] + } + }, + "response": [] + }, + { + "name": "search resource bookings with parameters 2", + "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", + " _.each(['id','projectId','status','startDate','endDate','billingAccountId','userId','jobId','rateType','memberRate','customerRate','createdBy','updatedBy','createdAt','updatedAt','workPeriods'], field => {\r", + " pm.expect(response[0]).to.have.property(field)\r", + " })\r", + " _.each(['id','projectId','paymentStatus','startDate','endDate','userHandle','resourceBookingId','daysWorked','memberRate','customerRate','createdBy','updatedBy','createdAt','updatedAt'], field => {\r", + " pm.expect(response[0].workPeriods[0]).to.have.property(field)\r", + " })\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_bookingManager}}" + } + ], + "url": { + "raw": "{{URL}}/resourceBookings?fields=workPeriods,id,projectId,status,startDate,endDate,billingAccountId,userId,jobId,rateType,memberRate,customerRate,createdBy,updatedBy,createdAt,updatedAt,deletedAt", + "host": [ + "{{URL}}" + ], + "path": [ + "resourceBookings" + ], + "query": [ + { + "key": "fields", + "value": "workPeriods,id,projectId,status,startDate,endDate,billingAccountId,userId,jobId,rateType,memberRate,customerRate,createdBy,updatedBy,createdAt,updatedAt,deletedAt" + } + ] + } + }, + "response": [] + }, + { + "name": "search resource bookings with parameters 3", + "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", + " _.each(['id','projectId','status','startDate','endDate'], field => {\r", + " pm.expect(response[0]).to.have.property(field)\r", + " })\r", + " _.each(['id','projectId','startDate','endDate','daysWorked'], field => {\r", + " pm.expect(response[0].workPeriods[0]).to.have.property(field)\r", + " })\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_bookingManager}}" + } + ], + "url": { + "raw": "{{URL}}/resourceBookings?fields=workPeriods.id,workPeriods.projectId,workPeriods.startDate,workPeriods.endDate,workPeriods.daysWorked,id,projectId,status,startDate,endDate", + "host": [ + "{{URL}}" + ], + "path": [ + "resourceBookings" + ], + "query": [ + { + "key": "fields", + "value": "workPeriods.id,workPeriods.projectId,workPeriods.startDate,workPeriods.endDate,workPeriods.daysWorked,id,projectId,status,startDate,endDate" + } + ] + } + }, + "response": [] + }, + { + "name": "search resource bookings with parameters 4", + "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?fields=workPeriods.id,workPeriods.projectId,workPeriods.startDate,workPeriods.endDate,workPeriods.daysWorked,id,projectId,status,startDate,endDate,customerRate&workPeriods.startDate=2020-10-25&sortBy=customerRate&sortOrder=asc", + "host": [ + "{{URL}}" + ], + "path": [ + "resourceBookings" + ], + "query": [ + { + "key": "fields", + "value": "workPeriods.id,workPeriods.projectId,workPeriods.startDate,workPeriods.endDate,workPeriods.daysWorked,id,projectId,status,startDate,endDate,customerRate" + }, + { + "key": "workPeriods.startDate", + "value": "2020-10-25" + }, + { + "key": "sortBy", + "value": "customerRate" + }, + { + "key": "sortOrder", + "value": "asc" + } + ] + } + }, + "response": [] + }, + { + "name": "search resource bookings with parameters 5", + "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?fields=workPeriods.id,workPeriods.projectId,workPeriods.startDate,workPeriods.endDate,workPeriods.daysWorked,id,projectId,status,startDate,endDate,customerRate,memberRate&workPeriods.startDate=2020-10-25&sortBy=workPeriods.daysWorked&sortOrder=desc", + "host": [ + "{{URL}}" + ], + "path": [ + "resourceBookings" + ], + "query": [ + { + "key": "fields", + "value": "workPeriods.id,workPeriods.projectId,workPeriods.startDate,workPeriods.endDate,workPeriods.daysWorked,id,projectId,status,startDate,endDate,customerRate,memberRate" + }, + { + "key": "workPeriods.startDate", + "value": "2020-10-25" + }, + { + "key": "sortBy", + "value": "workPeriods.daysWorked" + }, + { + "key": "sortOrder", + "value": "desc" + } + ] + } + }, + "response": [] + }, + { + "name": "search resource bookings with parameters 6", + "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?fields=workPeriods.id,workPeriods.projectId,workPeriods.userHandle,workPeriods.startDate,workPeriods.endDate,workPeriods.daysWorked,id,projectId,status,startDate,endDate,customerRate,memberRate&projectId=111&workPeriods.startDate=2020-10-18&sortBy=workPeriods.userHandle&sortOrder=desc", + "host": [ + "{{URL}}" + ], + "path": [ + "resourceBookings" + ], + "query": [ + { + "key": "fields", + "value": "workPeriods.id,workPeriods.projectId,workPeriods.userHandle,workPeriods.startDate,workPeriods.endDate,workPeriods.daysWorked,id,projectId,status,startDate,endDate,customerRate,memberRate" + }, + { + "key": "projectId", + "value": "111" + }, + { + "key": "workPeriods.startDate", + "value": "2020-10-18" + }, + { + "key": "sortBy", + "value": "workPeriods.userHandle" + }, + { + "key": "sortOrder", + "value": "desc" + } + ] + } + }, + "response": [] + }, + { + "name": "search resource bookings with parameters 7", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"Can not filter or sort by some field which is not included in fields\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_bookingManager}}" + } + ], + "url": { + "raw": "{{URL}}/resourceBookings?fields=id&projectId=111", + "host": [ + "{{URL}}" + ], + "path": [ + "resourceBookings" + ], + "query": [ + { + "key": "fields", + "value": "id" }, { - "key": "startDate", - "value": "2020-09-27", - "disabled": true + "key": "projectId", + "value": "111" + } + ] + } + }, + "response": [] + }, + { + "name": "search resource bookings with parameters 8", + "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(\"Can not filter or sort by some field which is not included in fields\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_bookingManager}}" + } + ], + "url": { + "raw": "{{URL}}/resourceBookings?fields=workPeriods&sortBy=customerRate", + "host": [ + "{{URL}}" + ], + "path": [ + "resourceBookings" + ], + "query": [ + { + "key": "fields", + "value": "workPeriods" }, { - "key": "endDate", - "value": "2020-09-27", - "disabled": true + "key": "sortBy", + "value": "customerRate" + } + ] + } + }, + "response": [] + }, + { + "name": "search resource bookings with parameters 9", + "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(\"Can not filter or sort by some field which is not included in fields\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_bookingManager}}" + } + ], + "url": { + "raw": "{{URL}}/resourceBookings?sortBy=workPeriods.paymentStatus", + "host": [ + "{{URL}}" + ], + "path": [ + "resourceBookings" + ], + "query": [ + { + "key": "sortBy", + "value": "workPeriods.paymentStatus" + } + ] + } + }, + "response": [] + }, + { + "name": "search resource bookings with parameters 10", + "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(\"Can not sort by workPeriod field without filtering by workPeriods.startDate or workPeriods.endDate\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_bookingManager}}" + } + ], + "url": { + "raw": "{{URL}}/resourceBookings?fields=workPeriods&sortBy=workPeriods.paymentStatus", + "host": [ + "{{URL}}" + ], + "path": [ + "resourceBookings" + ], + "query": [ + { + "key": "fields", + "value": "workPeriods" }, { - "key": "rateType", - "value": "hourly", - "disabled": true + "key": "sortBy", + "value": "workPeriods.paymentStatus" + } + ] + } + }, + "response": [] + }, + { + "name": "search resource bookings with parameters 11", + "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 don't have access to view memberRate\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_connectUser}}" + } + ], + "url": { + "raw": "{{URL}}/resourceBookings?fields=memberRate,projectId&projectId=111", + "host": [ + "{{URL}}" + ], + "path": [ + "resourceBookings" + ], + "query": [ + { + "key": "fields", + "value": "memberRate,projectId" }, { - "key": "sortOrder", - "value": "desc" + "key": "projectId", + "value": "111" + } + ] + } + }, + "response": [] + }, + { + "name": "search resource bookings with parameters 12", + "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 don't have access to view workPeriods\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_m2m_all_resource_booking}}" + } + ], + "url": { + "raw": "{{URL}}/resourceBookings?fields=workPeriods", + "host": [ + "{{URL}}" + ], + "path": [ + "resourceBookings" + ], + "query": [ + { + "key": "fields", + "value": "workPeriods" } ] } @@ -25762,4 +26900,4 @@ ] } ] -} \ No newline at end of file +} diff --git a/docs/swagger.yaml b/docs/swagger.yaml index 0a9fe80d..a0b6064b 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -1385,6 +1385,12 @@ paths: security: - bearerAuth: [] parameters: + - in: query + name: fields + description: the field names to be returned from both ResourceBooking and WorkPeriod + required: false + schema: + type: string - in: query name: page required: false @@ -1414,6 +1420,11 @@ paths: "rateType", "customerRate", "memberRate", + "workPeriods.userHandle", + "workPeriods.daysWorked", + "workPeriods.customerRate", + "workPeriods.memberRate", + "workPeriods.paymentStatus", ] description: The sort by column. - in: query @@ -1477,6 +1488,35 @@ paths: schema: type: string description: comma separated project ids. + - in: query + name: workPeriods.paymentStatus + required: false + schema: + type: string + enum: ["pending", "partially-completed", "completed", "cancelled"] + description: The payment status. + - in: query + name: workPeriods.startDate + required: false + schema: + type: string + format: date + pattern: '^\d{4}-\d{2}-\d{2}$' + description: The work period start date. + - in: query + name: workPeriods.endDate + required: false + schema: + type: string + format: date + pattern: '^\d{4}-\d{2}-\d{2}$' + description: The work period end date. + - in: query + name: workPeriods.userHandle + required: false + schema: + type: string + description: The user handle. responses: "200": @@ -1565,6 +1605,12 @@ paths: required: false schema: type: boolean + - in: query + name: fields + description: the field names to be returned from both ResourceBooking and WorkPeriod + required: false + schema: + type: string responses: "200": description: OK @@ -3517,7 +3563,18 @@ components: description: "The user id." status: type: string - enum: ["open", "placed", "selected", "client rejected - screening", "client rejected - interview", "rejected - other", "cancelled", "interview", "topcoder-rejected"] + enum: + [ + "open", + "placed", + "selected", + "client rejected - screening", + "client rejected - interview", + "rejected - other", + "cancelled", + "interview", + "topcoder-rejected", + ] description: "The job candidate status." default: open externalId: @@ -3632,7 +3689,15 @@ components: description: "Interview end time." status: type: string - enum: ["Scheduling", "Scheduled", "Requested for reschedule", "Rescheduled", "Completed", "Cancelled"] + enum: + [ + "Scheduling", + "Scheduled", + "Requested for reschedule", + "Rescheduled", + "Completed", + "Cancelled", + ] description: "The interview status." rescheduleUrl: type: string @@ -3678,7 +3743,15 @@ components: format: email status: type: string - enum: ["Scheduling", "Scheduled", "Requested for reschedule", "Rescheduled", "Completed", "Cancelled"] + enum: + [ + "Scheduling", + "Scheduled", + "Requested for reschedule", + "Rescheduled", + "Completed", + "Cancelled", + ] default: "Scheduling" description: "The interview status." UpdateInterviewRequestBody: @@ -3737,7 +3810,15 @@ components: description: "Interview end time." status: type: string - enum: ["Scheduling", "Scheduled", "Requested for reschedule", "Rescheduled", "Completed", "Cancelled"] + enum: + [ + "Scheduling", + "Scheduled", + "Requested for reschedule", + "Rescheduled", + "Completed", + "Cancelled", + ] description: "The interview status." rescheduleUrl: type: string @@ -3845,7 +3926,12 @@ components: billingAccountId: type: integer example: 80000071 - description: 'the billing account id for payments' + description: "the billing account id for payments" + workPeriods: + type: array + description: "The work periods related with resource booking" + items: + $ref: "#/components/schemas/WorkPeriod" createdAt: type: string format: date-time @@ -3913,7 +3999,7 @@ components: billingAccountId: type: integer example: 80000071 - description: 'the billing account id for payments' + description: "the billing account id for payments" ResourceBookingPatchRequestBody: properties: status: @@ -3946,7 +4032,7 @@ components: billingAccountId: type: integer example: 80000071 - description: 'the billing account id for payments' + description: "the billing account id for payments" WorkPeriod: required: - id @@ -4130,7 +4216,7 @@ components: billingAccountId: type: integer example: 80000071 - description: 'the billing account id for payments' + description: "the billing account id for payments" createdAt: type: string format: date-time diff --git a/package.json b/package.json index 00d15b73..0fa24cca 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,6 @@ "index:jobs": "node scripts/es/reIndexJobs.js", "index:job-candidates": "node scripts/es/reIndexJobCandidates.js", "index:resource-bookings": "node scripts/es/reIndexResourceBookings.js", - "index:work-periods": "node scripts/es/reIndexWorkPeriods.js", "data:export": "node scripts/data/exportData.js", "data:import": "node scripts/data/importData.js", "migrate": "npx sequelize db:migrate", @@ -86,4 +85,4 @@ "test/unit/**" ] } -} +} \ No newline at end of file diff --git a/scripts/data/exportData.js b/scripts/data/exportData.js index 356fcfc6..4eee1ad5 100644 --- a/scripts/data/exportData.js +++ b/scripts/data/exportData.js @@ -2,7 +2,7 @@ * Export data to a json file */ const config = require('config') -const { Interview, WorkPeriodPayment } = require('../../src/models') +const { Interview, WorkPeriod, WorkPeriodPayment } = require('../../src/models') const logger = require('../../src/common/logger') const helper = require('../../src/common/helper') @@ -14,17 +14,21 @@ const jobCandidateModelOpts = { }] } -const workPeriodModelOpts = { - modelName: 'WorkPeriod', +const resourceBookingModelOpts = { + modelName: 'ResourceBooking', include: [{ - model: WorkPeriodPayment, - as: 'payments' + model: WorkPeriod, + as: 'workPeriods', + include: [{ + model: WorkPeriodPayment, + as: 'payments' + }] }] } const filePath = helper.getParamFromCliArgs() || config.DEFAULT_DATA_FILE_PATH const userPrompt = `WARNING: are you sure you want to export all data in the database to a json file with the path ${filePath}? This will overwrite the file.` -const dataModels = ['Job', jobCandidateModelOpts, 'ResourceBooking', workPeriodModelOpts] +const dataModels = ['Job', jobCandidateModelOpts, resourceBookingModelOpts] async function exportData () { await helper.promptUser(userPrompt, async () => { diff --git a/scripts/data/importData.js b/scripts/data/importData.js index 52b3feb8..2e9c168e 100644 --- a/scripts/data/importData.js +++ b/scripts/data/importData.js @@ -2,7 +2,7 @@ * Import data from a json file into the db and index it in Elasticsearch */ const config = require('config') -const { Interview, WorkPeriodPayment } = require('../../src/models') +const { Interview, WorkPeriod, WorkPeriodPayment } = require('../../src/models') const logger = require('../../src/common/logger') const helper = require('../../src/common/helper') @@ -14,17 +14,21 @@ const jobCandidateModelOpts = { }] } -const workPeriodModelOpts = { - modelName: 'WorkPeriod', +const resourceBookingModelOpts = { + modelName: 'ResourceBooking', include: [{ - model: WorkPeriodPayment, - as: 'payments' + model: WorkPeriod, + as: 'workPeriods', + include: [{ + model: WorkPeriodPayment, + as: 'payments' + }] }] } const filePath = helper.getParamFromCliArgs() || config.DEFAULT_DATA_FILE_PATH const userPrompt = `WARNING: this would remove existing data. Are you sure you want to import data from a json file with the path ${filePath}?` -const dataModels = ['Job', jobCandidateModelOpts, 'ResourceBooking', workPeriodModelOpts] +const dataModels = ['Job', jobCandidateModelOpts, resourceBookingModelOpts] async function importData () { await helper.promptUser(userPrompt, async () => { diff --git a/scripts/es/createIndex.js b/scripts/es/createIndex.js index 4591214a..d2c72943 100644 --- a/scripts/es/createIndex.js +++ b/scripts/es/createIndex.js @@ -8,8 +8,7 @@ const helper = require('../../src/common/helper') const indices = [ config.get('esConfig.ES_INDEX_JOB'), config.get('esConfig.ES_INDEX_JOB_CANDIDATE'), - config.get('esConfig.ES_INDEX_RESOURCE_BOOKING'), - config.get('esConfig.ES_INDEX_WORK_PERIOD') + config.get('esConfig.ES_INDEX_RESOURCE_BOOKING') ] const userPrompt = `WARNING: Are you sure want to create the following elasticsearch indices: ${indices}?` diff --git a/scripts/es/deleteIndex.js b/scripts/es/deleteIndex.js index 8acffe33..6e30995a 100644 --- a/scripts/es/deleteIndex.js +++ b/scripts/es/deleteIndex.js @@ -8,8 +8,7 @@ const helper = require('../../src/common/helper') const indices = [ config.get('esConfig.ES_INDEX_JOB'), config.get('esConfig.ES_INDEX_JOB_CANDIDATE'), - config.get('esConfig.ES_INDEX_RESOURCE_BOOKING'), - config.get('esConfig.ES_INDEX_WORK_PERIOD') + config.get('esConfig.ES_INDEX_RESOURCE_BOOKING') ] const userPrompt = `WARNING: this would remove existent data! Are you sure want to delete the following eleasticsearch indices: ${indices}?` diff --git a/scripts/es/reIndexAll.js b/scripts/es/reIndexAll.js index 6a7bdf3f..802695dd 100644 --- a/scripts/es/reIndexAll.js +++ b/scripts/es/reIndexAll.js @@ -2,7 +2,7 @@ * Reindex all data in Elasticsearch using data from database */ const config = require('config') -const { Interview, WorkPeriodPayment } = require('../../src/models') +const { Interview, WorkPeriod, WorkPeriodPayment } = require('../../src/models') const logger = require('../../src/common/logger') const helper = require('../../src/common/helper') @@ -16,11 +16,15 @@ const jobCandidateModelOpts = { }] } -const workPeriodModelOpts = { - modelName: 'JobCandidate', +const resourceBookingModelOpts = { + modelName: 'ResourceBooking', include: [{ - model: WorkPeriodPayment, - as: 'payments' + model: WorkPeriod, + as: 'workPeriods', + include: [{ + model: WorkPeriodPayment, + as: 'payments' + }] }] } @@ -29,8 +33,7 @@ async function indexAll () { try { await helper.indexBulkDataToES('Job', config.get('esConfig.ES_INDEX_JOB'), logger) await helper.indexBulkDataToES(jobCandidateModelOpts, config.get('esConfig.ES_INDEX_JOB_CANDIDATE'), logger) - await helper.indexBulkDataToES('ResourceBooking', config.get('esConfig.ES_INDEX_RESOURCE_BOOKING'), logger) - await helper.indexBulkDataToES(workPeriodModelOpts, config.get('esConfig.ES_INDEX_WORK_PERIOD'), logger) + await helper.indexBulkDataToES(resourceBookingModelOpts, config.get('esConfig.ES_INDEX_RESOURCE_BOOKING'), logger) process.exit(0) } catch (err) { logger.logFullError(err, { component: 'indexAll' }) diff --git a/scripts/es/reIndexResourceBookings.js b/scripts/es/reIndexResourceBookings.js index ef2bf940..b29e3600 100644 --- a/scripts/es/reIndexResourceBookings.js +++ b/scripts/es/reIndexResourceBookings.js @@ -2,6 +2,7 @@ * Reindex ResourceBookings data in Elasticsearch using data from database */ const config = require('config') +const { WorkPeriod, WorkPeriodPayment } = require('../../src/models') const logger = require('../../src/common/logger') const helper = require('../../src/common/helper') @@ -10,11 +11,23 @@ const index = config.get('esConfig.ES_INDEX_RESOURCE_BOOKING') const reIndexAllResourceBookingsPrompt = `WARNING: this would remove existent data! Are you sure you want to reindex the index ${index}` const reIndexResourceBookingPrompt = `WARNING: this would remove existent data! Are you sure you want to reindex the document with id ${resourceBookingId} in index ${index}?` +const resourceBookingModelOpts = { + modelName: 'ResourceBooking', + include: [{ + model: WorkPeriod, + as: 'workPeriods', + include: [{ + model: WorkPeriodPayment, + as: 'payments' + }] + }] +} + async function reIndexResourceBookings () { if (resourceBookingId === null) { await helper.promptUser(reIndexAllResourceBookingsPrompt, async () => { try { - await helper.indexBulkDataToES('ResourceBooking', index, logger) + await helper.indexBulkDataToES(resourceBookingModelOpts, index, logger) process.exit(0) } catch (err) { logger.logFullError(err, { component: 'reIndexResourceBookings' }) @@ -24,7 +37,7 @@ async function reIndexResourceBookings () { } else { await helper.promptUser(reIndexResourceBookingPrompt, async () => { try { - await helper.indexDataToEsById(resourceBookingId, 'ResourceBooking', index, logger) + await helper.indexDataToEsById(resourceBookingId, resourceBookingModelOpts, index, logger) process.exit(0) } catch (err) { logger.logFullError(err, { component: 'reIndexResourceBookings' }) diff --git a/scripts/es/reIndexWorkPeriods.js b/scripts/es/reIndexWorkPeriods.js deleted file mode 100644 index a6f30737..00000000 --- a/scripts/es/reIndexWorkPeriods.js +++ /dev/null @@ -1,46 +0,0 @@ -/** - * Reindex WorkPeriods data in Elasticsearch using data from database - */ -const config = require('config') -const { WorkPeriodPayment } = require('../../src/models') -const logger = require('../../src/common/logger') -const helper = require('../../src/common/helper') - -const workPeriodId = helper.getParamFromCliArgs() -const index = config.get('esConfig.ES_INDEX_WORK_PERIOD') -const reIndexAllWorkPeriodsPrompt = `WARNING: this would remove existent data! Are you sure you want to reindex the index ${index}` -const reIndexWorkPeriodPrompt = `WARNING: this would remove existent data! Are you sure you want to reindex the document with id ${workPeriodId} in index ${index}?` - -const workPeriodModelOpts = { - modelName: 'WorkPeriod', - include: [{ - model: WorkPeriodPayment, - as: 'payments' - }] -} - -async function reIndexWorkPeriods () { - if (workPeriodId === null) { - await helper.promptUser(reIndexAllWorkPeriodsPrompt, async () => { - try { - await helper.indexBulkDataToES(workPeriodModelOpts, index, logger) - process.exit(0) - } catch (err) { - logger.logFullError(err, { component: 'reIndexWorkPeriods' }) - process.exit(1) - } - }) - } else { - await helper.promptUser(reIndexWorkPeriodPrompt, async () => { - try { - await helper.indexDataToEsById(workPeriodId, workPeriodModelOpts, index, logger) - process.exit(0) - } catch (err) { - logger.logFullError(err, { component: 'reIndexWorkPeriods' }) - process.exit(1) - } - }) - } -} - -reIndexWorkPeriods() diff --git a/src/common/helper.js b/src/common/helper.js index 43c1453e..234e96fe 100644 --- a/src/common/helper.js +++ b/src/common/helper.js @@ -129,31 +129,35 @@ esIndexPropertyMapping[config.get('esConfig.ES_INDEX_RESOURCE_BOOKING')] = { customerRate: { type: 'float' }, rateType: { type: 'keyword' }, billingAccountId: { type: 'integer' }, - createdAt: { type: 'date' }, - createdBy: { type: 'keyword' }, - updatedAt: { type: 'date' }, - updatedBy: { type: 'keyword' } -} -esIndexPropertyMapping[config.get('esConfig.ES_INDEX_WORK_PERIOD')] = { - resourceBookingId: { type: 'keyword' }, - userHandle: { type: 'keyword' }, - projectId: { type: 'integer' }, - userId: { type: 'keyword' }, - startDate: { type: 'date', format: 'yyyy-MM-dd' }, - endDate: { type: 'date', format: 'yyyy-MM-dd' }, - daysWorked: { type: 'integer' }, - memberRate: { type: 'float' }, - customerRate: { type: 'float' }, - paymentStatus: { type: 'keyword' }, - payments: { + workPeriods: { type: 'nested', properties: { id: { type: 'keyword' }, - workPeriodId: { type: 'keyword' }, - challengeId: { type: 'keyword' }, - amount: { type: 'float' }, - status: { type: 'keyword' }, - billingAccountId: { type: 'integer' }, + resourceBookingId: { type: 'keyword' }, + userHandle: { type: 'keyword' }, + projectId: { type: 'integer' }, + userId: { type: 'keyword' }, + startDate: { type: 'date', format: 'yyyy-MM-dd' }, + endDate: { type: 'date', format: 'yyyy-MM-dd' }, + daysWorked: { type: 'integer' }, + memberRate: { type: 'float' }, + customerRate: { type: 'float' }, + paymentStatus: { type: 'keyword' }, + payments: { + type: 'nested', + properties: { + id: { type: 'keyword' }, + workPeriodId: { type: 'keyword' }, + challengeId: { type: 'keyword' }, + amount: { type: 'float' }, + status: { type: 'keyword' }, + billingAccountId: { type: 'integer' }, + createdAt: { type: 'date' }, + createdBy: { type: 'keyword' }, + updatedAt: { type: 'date' }, + updatedBy: { type: 'keyword' } + } + }, createdAt: { type: 'date' }, createdBy: { type: 'keyword' }, updatedAt: { type: 'date' }, @@ -430,17 +434,20 @@ async function importData (pathToFile, dataModels, logger) { as: 'interviews' }] } - const workPeriodModelOpts = { - modelName: 'WorkPeriod', + const resourceBookingModelOpts = { + modelName: 'ResourceBooking', include: [{ - model: models.WorkPeriodPayment, - as: 'payments' + model: models.WorkPeriod, + as: 'workPeriods', + include: [{ + model: models.WorkPeriodPayment, + as: 'payments' + }] }] } await indexBulkDataToES('Job', config.get('esConfig.ES_INDEX_JOB'), logger) await indexBulkDataToES(jobCandidateModelOpts, config.get('esConfig.ES_INDEX_JOB_CANDIDATE'), logger) - await indexBulkDataToES('ResourceBooking', config.get('esConfig.ES_INDEX_RESOURCE_BOOKING'), logger) - await indexBulkDataToES(workPeriodModelOpts, config.get('esConfig.ES_INDEX_WORK_PERIOD'), logger) + await indexBulkDataToES(resourceBookingModelOpts, config.get('esConfig.ES_INDEX_RESOURCE_BOOKING'), logger) } /** diff --git a/src/controllers/ResourceBookingController.js b/src/controllers/ResourceBookingController.js index 098fd8e5..f8d3d566 100644 --- a/src/controllers/ResourceBookingController.js +++ b/src/controllers/ResourceBookingController.js @@ -11,7 +11,7 @@ const helper = require('../common/helper') * @param res the response */ async function getResourceBooking (req, res) { - res.send(await service.getResourceBooking(req.authUser, req.params.id, req.query.fromDb)) + res.send(await service.getResourceBooking(req.authUser, req.params.id, req.query)) } /** diff --git a/src/eventHandlers/ResourceBookingEventHandler.js b/src/eventHandlers/ResourceBookingEventHandler.js index 7a4a7c0a..3e8c18c3 100644 --- a/src/eventHandlers/ResourceBookingEventHandler.js +++ b/src/eventHandlers/ResourceBookingEventHandler.js @@ -155,7 +155,7 @@ async function createWorkPeriods (payload) { /** * When a ResourceBooking is updated, workPeriods related to * that ResourceBooking should be updated also. - * This function finds aout which workPeriods should be deleted, + * This function finds out which workPeriods should be deleted, * which ones should be created and which ones should be updated * @param {object} payload the event payload * @returns {undefined} diff --git a/src/models/ResourceBooking.js b/src/models/ResourceBooking.js index 58dc5454..54a95b89 100644 --- a/src/models/ResourceBooking.js +++ b/src/models/ResourceBooking.js @@ -1,5 +1,6 @@ const { Sequelize, Model } = require('sequelize') const config = require('config') +const _ = require('lodash') const errors = require('../common/errors') module.exports = (sequelize) => { @@ -9,8 +10,9 @@ module.exports = (sequelize) => { * @param {Object} models the database models */ static associate (models) { + ResourceBooking._models = models ResourceBooking.belongsTo(models.Job, { foreignKey: 'jobId' }) - ResourceBooking.hasMany(models.WorkPeriod, { foreignKey: 'resourceBookingId' }) + ResourceBooking.hasMany(models.WorkPeriod, { as: 'workPeriods', foreignKey: 'resourceBookingId' }) } /** @@ -18,12 +20,36 @@ module.exports = (sequelize) => { * @param {String} id the resource booking id * @returns {ResourceBooking} the resource booking instance */ - static async findById (id) { - const resourceBooking = await ResourceBooking.findOne({ + static async findById (id, options) { + const criteria = { where: { id } - }) + } + if (!_.isUndefined(options)) { + // Select ResourceBooking fields + if (options.include && options.include.length > 0) { + criteria.attributes = options.fieldsRB + } else if (options.excludeRB && options.excludeRB.length > 0) { + criteria.attributes = { exclude: options.excludeRB } + } + // include WorkPeriod model + if (options.withWorkPeriods) { + criteria.include = [{ + model: ResourceBooking._models.WorkPeriod, + as: 'workPeriods', + required: false + }] + // Select WorkPeriod fields + if (!options.allWorkPeriods) { + criteria.include[0].attributes = _.map(options.fieldsWP, f => _.split(f, '.')[1]) + } else if (options.excludeWP && options.excludeWP.length > 0) { + criteria.include[0].attributes = { exclude: _.map(options.excludeWP, f => _.split(f, '.')[1]) } + } + } + } + + const resourceBooking = await ResourceBooking.findOne(criteria) if (!resourceBooking) { throw new errors.NotFoundError(`id: ${id} "ResourceBooking" doesn't exists.`) } diff --git a/src/models/WorkPeriod.js b/src/models/WorkPeriod.js index 455818b5..75ff0597 100644 --- a/src/models/WorkPeriod.js +++ b/src/models/WorkPeriod.js @@ -20,12 +20,15 @@ module.exports = (sequelize) => { * @param {Object} options { withPayments: true/false } whether contains payments * @returns {WorkPeriod} the work period instance */ - static async findById (id, options = { withPayments: false }) { + static async findById (id, options = { withPayments: false, exclude: [] }) { const criteria = { where: { id } } + if (options.exclude && options.exclude.length > 0) { + criteria.attributes = { exclude: options.exclude } + } if (options.withPayments) { criteria.include = [{ model: WorkPeriod._models.WorkPeriodPayment, diff --git a/src/services/ResourceBookingService.js b/src/services/ResourceBookingService.js index 3693f22c..81c21fda 100644 --- a/src/services/ResourceBookingService.js +++ b/src/services/ResourceBookingService.js @@ -12,23 +12,138 @@ 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 ResourceBooking = models.ResourceBooking const WorkPeriod = models.WorkPeriod const esClient = helper.getESClient() +const cachedModelFields = _cacheModelFields() /** - * filter fields of resource booking by user role. + * Get the fields of the ResourceBooking model and the nested WorkPeriod model + * @returns {Array} array of field names + */ +function _cacheModelFields () { + const resourceBookingFields = _.keys(ResourceBooking.rawAttributes) + const workPeriodFields = _.map(_.keys(WorkPeriod.rawAttributes), key => `workPeriods.${key}`) + return [...resourceBookingFields, 'workPeriods', ...workPeriodFields] +} + +/** + * Check user scopes for getting workPeriods * @param {Object} currentUser the user who perform this operation. - * @param {Object} resourceBooking the resourceBooking with all fields - * @returns {Object} the resourceBooking + * @returns {Boolean} true if user is machine and has read/all workPeriod scopes */ -async function _getResourceBookingFilteringFields (currentUser, resourceBooking) { - if (currentUser.hasManagePermission || currentUser.isMachine) { - return resourceBooking +function _checkUserScopesForGetWorkPeriods (currentUser) { + const getWorkPeriodsScopes = [constants.Scopes.READ_WORK_PERIOD, constants.Scopes.ALL_WORK_PERIOD] + return currentUser.isMachine && helper.checkIfExists(getWorkPeriodsScopes, currentUser.scopes) +} + +/** + * Evaluates the criterias and returns the fields + * to be returned as a result of GET endpoints + * @param {Object} currentUser the user who perform this operation. + * @param {Object} criteria the query criterias + * @returns {Object} result + * @returns {Array} result.include field names to include + * @returns {Array} result.fieldsRB ResourceBooking field names to include + * @returns {Array} result.fieldsWP WorkPeriod field names to include + * @returns {Array} result.excludeRB ResourceBooking field names to exclude + * @returns {Array} result.excludeWP WorkPeriod field names to exclude + * @returns {Boolean} result.regularUser is current user a regular user? + * @returns {Boolean} result.allWorkPeriods will all WorkPeriod fields be returned? + * @returns {Boolean} result.withWorkPeriods does fields include any WorkPeriod field? + * @returns {Boolean} result.sortByWP will the sorting be done by WorkPeriod field? + */ +function _checkCriteriaAndGetFields (currentUser, criteria) { + const result = { + include: [], + fieldsRB: [], + fieldsWP: [], + excludeRB: [], + excludeWP: [] } - return _.omit(resourceBooking, 'memberRate') + const fields = criteria.fields + const sort = criteria.sortBy + const onlyResourceBooking = _.isUndefined(fields) + const query = onlyResourceBooking ? [] : _.split(fields, ',') + const notAllowedFields = _.difference(query, cachedModelFields) + // Check if fields criteria has a field name that RB or WP models don't have + if (notAllowedFields.length > 0) { + throw new errors.BadRequestError(`${notAllowedFields} are not allowed`) + } + // Check if user is a regular user. Regular users can't get ResourceBookings for which they are not a member + result.regularUser = !currentUser.hasManagePermission && !currentUser.isMachine && !currentUser.isConnectManager + // Check if all WorkPeriod fields will be returned + result.allWorkPeriods = _.some(query, q => q === 'workPeriods') + // Split the fields criteria into ResourceBooking and WorkPeriod fields + _.forEach(query, q => { + if (_.includes(q, '.')) { result.fieldsWP.push(q) } else if (q !== 'workPeriods') { result.fieldsRB.push(q) } + }) + // Check if any WorkPeriod field will be returned + result.withWorkPeriods = result.allWorkPeriods || result.fieldsWP.length > 0 + // Extract the filters from criteria parameter + let filters = _.filter(Object.keys(criteria), key => _.indexOf(['fromDb', 'fields', 'page', 'perPage', 'sortBy', 'sortOrder'], key) === -1) + filters = _.map(filters, f => { + if (f === 'projectIds') { + return 'projectId' + } return f + }) + const filterRB = [] + const filterWP = [] + // Split the filters criteria into ResourceBooking and WorkPeriod filters + _.forEach(filters, q => { if (_.includes(q, '.')) { filterWP.push(q) } else { filterRB.push(q) } }) + // Check if filter criteria has any WorkPeriod filter + const filterHasWorkPeriods = filterWP.length > 0 + // Check if sorting will be done by WorkPeriod field + result.sortByWP = _.split(sort, '.')[0] === 'workPeriods' + // Check if the current user has the right to see the memberRate + const canSeeMemberRate = currentUser.hasManagePermission || currentUser.isMachine + // If current user has no right to see the memberRate then it's excluded + // "currentUser.isMachine" to be true is not enough to return "workPeriods.memberRate" + // but returning "workPeriod" will be evaluated later + if (!canSeeMemberRate) { + result.excludeRB.push('memberRate') + result.excludeWP.push('workPeriods.memberRate') + } + // if "fields" is not included in cretia, then only ResourceBooking model will be returned + // No further evaluation is required as long as the criteria does not include a WorkPeriod filter or a WorkPeriod sorting condition + if (onlyResourceBooking) { + if (filterHasWorkPeriods || result.sortByWP) { + throw new errors.BadRequestError('Can not filter or sort by some field which is not included in fields') + } + result.excludeWP.push('workPeriods') + return result + } + // Include sorting condition in filters + if (result.sortByWP) { + // It is required to filter by "workPeriods.startDate" or "workPeriods.endDate" if sorting will be done by WorkPeriod field + if (!_.some(filterWP, f => _.includes(['workPeriods.startDate', 'workPeriods.endDate'], f))) { + throw new errors.BadRequestError('Can not sort by workPeriod field without filtering by workPeriods.startDate or workPeriods.endDate') + } + filterWP.push(sort) + } else if (!_.isUndefined(sort) && sort !== 'id') { + filterRB.push(sort) + } + // Check If it's tried to filter or sort by some field which should not be included as per rules of fields param + if (_.difference(filterRB, result.fieldsRB).length > 0) { + throw new errors.BadRequestError('Can not filter or sort by some field which is not included in fields') + } + // Check If it's tried to filter or sort by some field which should not be included as per rules of fields param + if (!result.allWorkPeriods && _.difference(filterWP, result.fieldsWP).length > 0) { + throw new errors.BadRequestError('Can not filter or sort by some field which is not included in fields') + } + // Check if the current user has no right to see the memberRate and memberRate is included in fields parameter + if (!canSeeMemberRate && _.some(query, q => _.includes(['memberRate', 'workPeriods.memberRate'], q))) { + throw new errors.ForbiddenError('You don\'t have access to view memberRate') + } + // Check if the current user has no right to see the workPeriods and workPeriods is included in fields parameter + if (currentUser.isMachine && result.withWorkPeriods && !_checkUserScopesForGetWorkPeriods(currentUser)) { + throw new errors.ForbiddenError('You don\'t have access to view workPeriods') + } + result.include.push(...query) + return result } /** @@ -39,9 +154,7 @@ async function _getResourceBookingFilteringFields (currentUser, resourceBooking) * @returns {undefined} */ async function _checkUserPermissionForGetResourceBooking (currentUser, projectId) { - if (!currentUser.hasManagePermission && !currentUser.isMachine && !currentUser.isConnectManager) { - await helper.checkIsMemberOfProject(currentUser.userId, projectId) - } + await helper.checkIsMemberOfProject(currentUser.userId, projectId) } /** @@ -92,43 +205,53 @@ async function _ensurePaidWorkPeriodsNotDeleted (resourceBookingId, oldValue, ne * Get resourceBooking by id * @param {Object} currentUser the user who perform this operation. * @param {String} id the resourceBooking id - * @param {Boolean} fromDb flag if query db for data or not + * @param {Object} criteria object including fields and fromDb criteria * @returns {Object} the resourceBooking */ -async function getResourceBooking (currentUser, id, fromDb = false) { - if (!fromDb) { +async function getResourceBooking (currentUser, id, criteria) { + // Evaluate criteria and extract the fields to be included or excluded + const queryOpt = _checkCriteriaAndGetFields(currentUser, criteria) + // We don't allow regular user to exclude projectId from result + if (queryOpt.regularUser && queryOpt.include.length > 0 && !_.includes(queryOpt.include, 'projectId')) { + throw new errors.ForbiddenError('Not allowed without including "projectId"') + } + if (!criteria.fromDb) { try { const resourceBooking = await esClient.get({ index: config.esConfig.ES_INDEX_RESOURCE_BOOKING, - id + id, + _source_includes: [...queryOpt.include], + _source_excludes: ['workPeriods.payments', ...queryOpt.excludeRB, ...queryOpt.excludeWP] }) - - await _checkUserPermissionForGetResourceBooking(currentUser, resourceBooking.body._source.projectId) // check user permission - - const resourceBookingRecord = { id: resourceBooking.body._id, ...resourceBooking.body._source } - return _getResourceBookingFilteringFields(currentUser, resourceBookingRecord) + if (queryOpt.regularUser) { + await _checkUserPermissionForGetResourceBooking(currentUser, resourceBooking.body._source.projectId) // check user permission + } + return resourceBooking.body._source } catch (err) { if (helper.isDocumentMissingException(err)) { throw new errors.NotFoundError(`id: ${id} "ResourceBooking" not found`) } - if (err.httpStatus === HttpStatus.FORBIDDEN) { + if (err.httpStatus === HttpStatus.UNAUTHORIZED) { throw err } logger.logFullError(err, { component: 'ResourceBookingService', context: 'getResourceBooking' }) } } logger.info({ component: 'ResourceBookingService', context: 'getResourceBooking', message: 'try to query db for data' }) - const resourceBooking = await ResourceBooking.findById(id) - - await _checkUserPermissionForGetResourceBooking(currentUser, resourceBooking.projectId) // check user permission - - return _getResourceBookingFilteringFields(currentUser, resourceBooking.dataValues) + const resourceBooking = await ResourceBooking.findById(id, queryOpt) + if (queryOpt.regularUser) { + await _checkUserPermissionForGetResourceBooking(currentUser, resourceBooking.projectId) // check user permission + } + return resourceBooking.dataValues } getResourceBooking.schema = Joi.object().keys({ currentUser: Joi.object().required(), id: Joi.string().guid().required(), - fromDb: Joi.boolean() + criteria: Joi.object().keys({ + fromDb: Joi.boolean().default(false), + fields: Joi.string() + }) }).required() /** @@ -306,12 +429,14 @@ deleteResourceBooking.schema = Joi.object().keys({ * @returns {Object} the search result, contain total/page/perPage and result array */ async function searchResourceBookings (currentUser, criteria, options = { returnAll: false }) { + // Evaluate criteria and extract the fields to be included or excluded + const queryOpt = _checkCriteriaAndGetFields(currentUser, criteria) // check user permission - if (!currentUser.hasManagePermission && !currentUser.isMachine && !currentUser.isConnectManager && !options.returnAll) { + if (queryOpt.regularUser && !options.returnAll) { if (!criteria.projectId) { // regular user can only search with filtering by "projectId" throw new errors.ForbiddenError('Not allowed without filtering by "projectId"') } - await helper.checkIsMemberOfProject(currentUser.userId, criteria.projectId) + await _checkUserPermissionForGetResourceBooking(currentUser, criteria.projectId) } // `criteria`.projectIds` could be array of ids, or comma separated string of ids @@ -326,7 +451,7 @@ async function searchResourceBookings (currentUser, criteria, options = { return return projectId }) } - const page = criteria.page > 0 ? criteria.page : 1 + const page = criteria.page let perPage if (options.returnAll) { // To simplify the logic we are use a very large number for perPage @@ -335,7 +460,7 @@ async function searchResourceBookings (currentUser, criteria, options = { return // https://www.elastic.co/guide/en/elasticsearch/reference/current/index-modules.html#index-max-result-window perPage = 10000 } else { - perPage = criteria.perPage > 0 ? criteria.perPage : 20 + perPage = criteria.perPage } if (!criteria.sortBy) { @@ -345,21 +470,30 @@ async function searchResourceBookings (currentUser, criteria, options = { return criteria.sortOrder = 'desc' } try { - const sort = [{ [criteria.sortBy === 'id' ? '_id' : criteria.sortBy]: { order: criteria.sortOrder } }] - const esQuery = { index: config.get('esConfig.ES_INDEX_RESOURCE_BOOKING'), + _source_includes: queryOpt.include, + _source_excludes: ['workPeriods.payments', ...queryOpt.excludeRB, ...queryOpt.excludeWP], body: { query: { bool: { - must: [] + must: [ + { + nested: { + path: 'workPeriods', + query: { bool: { must: [] } } + } + } + ] } }, from: (page - 1) * perPage, - size: perPage, - sort + size: perPage } } + if (!queryOpt.sortByWP) { + esQuery.body.sort = [{ [criteria.sortBy === 'id' ? '_id' : criteria.sortBy]: { order: criteria.sortOrder } }] + } // change the date format to match with index schema if (criteria.startDate) { criteria.startDate = moment(criteria.startDate).format('YYYY-MM-DD') @@ -367,6 +501,13 @@ async function searchResourceBookings (currentUser, criteria, options = { return if (criteria.endDate) { criteria.endDate = moment(criteria.endDate).format('YYYY-MM-DD') } + if (criteria['workPeriods.startDate']) { + criteria['workPeriods.startDate'] = moment(criteria['workPeriods.startDate']).format('YYYY-MM-DD') + } + if (criteria['workPeriods.endDate']) { + criteria['workPeriods.endDate'] = moment(criteria['workPeriods.endDate']).format('YYYY-MM-DD') + } + // Apply ResourceBooking filters _.each(_.pick(criteria, ['status', 'startDate', 'endDate', 'rateType', 'projectId', 'jobId', 'userId']), (value, key) => { esQuery.body.query.bool.must.push({ term: { @@ -384,52 +525,110 @@ async function searchResourceBookings (currentUser, criteria, options = { return } }] } + // Apply WorkPeriod filters + _.each(_.pick(criteria, ['workPeriods.paymentStatus', 'workPeriods.startDate', 'workPeriods.endDate', 'workPeriods.userHandle']), (value, key) => { + esQuery.body.query.bool.must[0].nested.query.bool.must.push({ + term: { + [key]: { + value + } + } + }) + }) logger.debug({ component: 'ResourceBookingService', context: 'searchResourceBookings', message: `Query: ${JSON.stringify(esQuery)}` }) const { body } = await esClient.search(esQuery) - + let resourceBookings = _.map(body.hits.hits, '_source') + // ESClient will return ResourceBookings with it's all nested WorkPeriods + // We re-apply WorkPeriod filters + _.each(_.pick(criteria, ['workPeriods.startDate', 'workPeriods.endDate', 'workPeriods.userHandle', 'workPeriods.paymentStatus']), (value, key) => { + key = key.split('.')[1] + _.each(resourceBookings, r => { + r.workPeriods = _.filter(r.workPeriods, { [key]: value }) + }) + }) + // If sorting criteria is WorkPeriod field, we have to sort manually + if (queryOpt.sortByWP) { + const sorts = criteria.sortBy.split('.') + resourceBookings = _.sortBy(resourceBookings, [`${sorts[0]}[0].${sorts[1]}`]) + if (criteria.sortOrder === 'desc') { + resourceBookings = _.reverse(resourceBookings) + } + } return { total: body.hits.total.value, page, perPage, - result: _.map(body.hits.hits, (hit) => { - const obj = _.cloneDeep(hit._source) - obj.id = hit._id - return obj - }) + result: resourceBookings } } catch (err) { logger.logFullError(err, { component: 'ResourceBookingService', context: 'searchResourceBookings' }) } logger.info({ component: 'ResourceBookingService', context: 'searchResourceBookings', message: 'fallback to DB query' }) const filter = { [Op.and]: [] } + // Apply ResourceBooking filters _.each(_.pick(criteria, ['status', 'startDate', 'endDate', 'rateType', 'projectId', 'jobId', 'userId']), (value, key) => { filter[Op.and].push({ [key]: value }) }) if (criteria.projectIds) { filter[Op.and].push({ projectId: criteria.projectIds }) } - const resourceBookings = await ResourceBooking.findAll({ + const queryCriteria = { where: filter, offset: ((page - 1) * perPage), - limit: perPage, - order: [[criteria.sortBy, criteria.sortOrder]] - }) + limit: perPage + } + // Select ResourceBooking fields + if (queryOpt.include.length > 0) { + queryCriteria.attributes = queryOpt.fieldsRB + } else if (queryOpt.excludeRB && queryOpt.excludeRB.length > 0) { + queryCriteria.attributes = { exclude: queryOpt.excludeRB } + } + // Include WorkPeriod Model + if (queryOpt.withWorkPeriods) { + queryCriteria.include = [{ + model: WorkPeriod, + as: 'workPeriods', + required: false, + where: { [Op.and]: [] } + }] + // Select WorkPeriod fields + if (!queryOpt.allWorkPeriods) { + queryCriteria.include[0].attributes = _.map(queryOpt.fieldsWP, f => _.split(f, '.')[1]) + } else if (queryOpt.excludeWP && queryOpt.excludeWP.length > 0) { + queryCriteria.include[0].attributes = { exclude: _.map(queryOpt.excludeWP, f => _.split(f, '.')[1]) } + } + // Apply WorkPeriod filters + _.each(_.pick(criteria, ['workPeriods.startDate', 'workPeriods.endDate', 'workPeriods.userHandle', 'workPeriods.paymentStatus']), (value, key) => { + key = key.split('.')[1] + queryCriteria.include[0].where[Op.and].push({ [key]: value }) + queryCriteria.include[0].required = true + }) + } + // Apply sorting criteria + if (!queryOpt.sortByWP) { + queryCriteria.order = [[criteria.sortBy, criteria.sortOrder]] + } else { + queryCriteria.order = [[{ model: WorkPeriod, as: 'workPeriods' }, _.split(criteria.sortBy, '.')[1], criteria.sortOrder]] + } + const resourceBookings = await ResourceBooking.findAll(queryCriteria) return { fromDb: true, total: resourceBookings.length, page, perPage, - result: _.map(resourceBookings, resourceBooking => resourceBooking.dataValues) + result: resourceBookings } } searchResourceBookings.schema = Joi.object().keys({ currentUser: Joi.object().required(), criteria: Joi.object().keys({ - page: Joi.number().integer(), - perPage: Joi.number().integer(), - sortBy: Joi.string().valid('id', 'rateType', 'startDate', 'endDate', 'customerRate', 'memberRate', 'status'), + fields: Joi.string(), + page: Joi.page(), + perPage: Joi.perPage(), + sortBy: Joi.string().valid('id', 'rateType', 'startDate', 'endDate', 'customerRate', 'memberRate', 'status', + 'workPeriods.userHandle', 'workPeriods.daysWorked', 'workPeriods.customerRate', 'workPeriods.memberRate', 'workPeriods.paymentStatus'), sortOrder: Joi.string().valid('desc', 'asc'), status: Joi.resourceBookingStatus(), startDate: Joi.date().format('YYYY-MM-DD'), @@ -441,7 +640,11 @@ searchResourceBookings.schema = Joi.object().keys({ projectIds: Joi.alternatives( Joi.string(), Joi.array().items(Joi.number().integer()) - ) + ), + 'workPeriods.paymentStatus': Joi.paymentStatus(), + 'workPeriods.startDate': Joi.date().format('YYYY-MM-DD'), + 'workPeriods.endDate': Joi.date().format('YYYY-MM-DD'), + 'workPeriods.userHandle': Joi.string() }).required(), options: Joi.object() }).required() diff --git a/src/services/WorkPeriodPaymentService.js b/src/services/WorkPeriodPaymentService.js index e8694c76..c196f88e 100644 --- a/src/services/WorkPeriodPaymentService.js +++ b/src/services/WorkPeriodPaymentService.js @@ -44,25 +44,36 @@ async function getWorkPeriodPayment (currentUser, id, fromDb = false) { await _checkUserPermissionForCRUWorkPeriodPayment(currentUser) if (!fromDb) { try { - const workPeriod = await esClient.search({ - index: config.esConfig.ES_INDEX_WORK_PERIOD, - _source: 'payments', + const resourceBooking = await esClient.search({ + index: config.esConfig.ES_INDEX_RESOURCE_BOOKING, + _source: 'workPeriods.payments', body: { query: { nested: { - path: 'payments', + path: 'workPeriods.payments', query: { - match: { 'payments.id': id } + match: { 'workPeriods.payments.id': id } } } } } }) - if (!workPeriod.body.hits.total.value) { + if (!resourceBooking.body.hits.total.value) { throw new errors.NotFoundError() } - const workPeriodPaymentRecord = _.find(workPeriod.body.hits.hits[0]._source.payments, { id }) + let workPeriodPaymentRecord = null + _.forEach(resourceBooking.body.hits.hits[0]._source.workPeriods, wp => { + _.forEach(wp.payments, p => { + if (p.id === id) { + workPeriodPaymentRecord = p + return false + } + }) + if (workPeriodPaymentRecord) { + return false + } + }) return workPeriodPaymentRecord } catch (err) { if (err.httpStatus === HttpStatus.NOT_FOUND) { @@ -244,12 +255,12 @@ async function searchWorkPeriodPayments (currentUser, criteria, options = { retu const perPage = criteria.perPage try { const esQuery = { - index: config.get('esConfig.ES_INDEX_WORK_PERIOD'), - _source: 'payments', + index: config.get('esConfig.ES_INDEX_RESOURCE_BOOKING'), + _source: 'workPeriods.payments', body: { query: { nested: { - path: 'payments', + path: 'workPeriods.payments', query: { bool: { must: [] } } } }, @@ -263,7 +274,7 @@ async function searchWorkPeriodPayments (currentUser, criteria, options = { retu _.each(_.pick(criteria, ['status', 'workPeriodId']), (value, key) => { esQuery.body.query.nested.query.bool.must.push({ term: { - [`payments.${key}`]: { + [`workPeriods.payments.${key}`]: { value } } @@ -272,14 +283,20 @@ async function searchWorkPeriodPayments (currentUser, criteria, options = { retu if (criteria.workPeriodIds) { esQuery.body.query.nested.query.bool.filter = [{ terms: { - 'payments.workPeriodId': criteria.workPeriodIds + 'workPeriods.payments.workPeriodId': criteria.workPeriodIds } }] } logger.debug({ component: 'WorkPeriodPaymentService', context: 'searchWorkPeriodPayment', message: `Query: ${JSON.stringify(esQuery)}` }) const { body } = await esClient.search(esQuery) - let payments = _.reduce(body.hits.hits, (acc, workPeriod) => _.concat(acc, workPeriod._source.payments), []) + const workPeriods = _.reduce(body.hits.hits, (acc, resourceBooking) => _.concat(acc, resourceBooking._source.workPeriods), []) + let payments = _.reduce(workPeriods, (acc, workPeriod) => _.concat(acc, workPeriod.payments), []) + if (criteria.workPeriodId) { + payments = _.filter(payments, { workPeriodId: criteria.workPeriodId }) + } else if (criteria.workPeriodIds) { + payments = _.filter(payments, p => _.includes(criteria.workPeriodIds, p.workPeriodId)) + } if (criteria.status) { payments = _.filter(payments, { status: criteria.status }) } @@ -320,9 +337,7 @@ async function searchWorkPeriodPayments (currentUser, criteria, options = { retu total: workPeriodPayments.length, page, perPage, - result: _.map(workPeriodPayments, workPeriodPayment => { - return workPeriodPayment.dataValues - }) + result: workPeriodPayments } } diff --git a/src/services/WorkPeriodService.js b/src/services/WorkPeriodService.js index 92e1deb0..19346ff3 100644 --- a/src/services/WorkPeriodService.js +++ b/src/services/WorkPeriodService.js @@ -83,16 +83,27 @@ function _checkUserScopesForGetPayments (currentUser) { } /** - * filter fields of work period by user role. + * Get which fields to be excluded from result * @param {Object} currentUser the user who perform this operation. - * @param {Object} workPeriod the workPeriod with all fields - * @returns {Object} the workPeriod + * @returns {Object} queryOpt + * @returns {Object} queryOpt.excludeES excluded fields for ES query + * @returns {Object} queryOpt.excludeDB excluded fields for DB query + * @returns {Object} queryOpt.withPayments is payments field included? */ -async function _getWorkPeriodFilteringFields (currentUser, workPeriod) { - if (currentUser.hasManagePermission || _checkUserScopesForGetPayments(currentUser)) { - return workPeriod +function _getWorkPeriodFilteringFields (currentUser) { + const queryOpt = { + excludeES: [], + excludeDB: [], + withPayments: false } - return _.omit(workPeriod, ['memberRate', 'payments']) + if (!currentUser.hasManagePermission && !currentUser.isMachine) { + queryOpt.excludeES.push('workPeriods.memberRate') + queryOpt.excludeDB.push('memberRate') + } + if (currentUser.hasManagePermission || _checkUserScopesForGetPayments(currentUser)) { + queryOpt.withPayments = true + } else { queryOpt.excludeES.push('workPeriods.payments') } + return queryOpt } /** @@ -144,33 +155,45 @@ function _autoCalculateDates (data) { * @returns {Object} the workPeriod */ async function getWorkPeriod (currentUser, id, fromDb = false) { + // get query options according to currentUser + const queryOpt = _getWorkPeriodFilteringFields(currentUser) if (!fromDb) { try { - const workPeriod = await esClient.get({ - index: config.esConfig.ES_INDEX_WORK_PERIOD, - id + const resourceBooking = await esClient.search({ + index: config.esConfig.ES_INDEX_RESOURCE_BOOKING, + _source_includes: 'workPeriods', + _source_excludes: queryOpt.excludeES, + body: { + query: { + nested: { + path: 'workPeriods', + query: { + match: { 'workPeriods.id': id } + } + } + } + } }) - - await _checkUserPermissionForGetWorkPeriod(currentUser, workPeriod.body._source.projectId) // check user permission - - const workPeriodRecord = { id: workPeriod.body._id, ...workPeriod.body._source } - return _getWorkPeriodFilteringFields(currentUser, workPeriodRecord) + if (!resourceBooking.body.hits.total.value) { + throw new errors.NotFoundError() + } + await _checkUserPermissionForGetWorkPeriod(currentUser, resourceBooking.body.hits.hits[0]._source.workPeriods.projectId) // check user permission + return _.find(resourceBooking.body.hits.hits[0]._source.workPeriods, { id }) } catch (err) { if (helper.isDocumentMissingException(err)) { throw new errors.NotFoundError(`id: ${id} "WorkPeriod" not found`) } - if (err.httpStatus === HttpStatus.FORBIDDEN) { + if (err.httpStatus === HttpStatus.UNAUTHORIZED) { throw err } logger.logFullError(err, { component: 'WorkPeriodService', context: 'getWorkPeriod' }) } } logger.info({ component: 'WorkPeriodService', context: 'getWorkPeriod', message: 'try to query db for data' }) - const workPeriod = await WorkPeriod.findById(id, { withPayments: true }) + const workPeriod = await WorkPeriod.findById(id, { withPayments: queryOpt.withPayments, exclude: queryOpt.excludeDB }) await _checkUserPermissionForGetWorkPeriod(currentUser, workPeriod.projectId) // check user permission - // We should only return "memberRate" to Booking Manager, Administrator or M2M - return _getWorkPeriodFilteringFields(currentUser, workPeriod.dataValues) + return workPeriod.dataValues } getWorkPeriod.schema = Joi.object().keys({ @@ -364,7 +387,7 @@ async function searchWorkPeriods (currentUser, criteria, options = { returnAll: } await helper.checkIsMemberOfProject(currentUser.userId, criteria.projectId) } - + const queryOpt = _getWorkPeriodFilteringFields(currentUser) // `criteria.resourceBookingIds` could be array of ids, or comma separated string of ids // in case it's comma separated string of ids we have to convert it to an array of ids if ((typeof criteria.resourceBookingIds) === 'string') { @@ -377,17 +400,7 @@ async function searchWorkPeriods (currentUser, criteria, options = { returnAll: }) } const page = criteria.page - let perPage - if (options.returnAll) { - // To simplify the logic we are use a very large number for perPage - // because in practice there could hardly be so many records to be returned.(also consider we are using filters in the meantime) - // the number is limited by `index.max_result_window`, its default value is 10000, see - // https://www.elastic.co/guide/en/elasticsearch/reference/current/index-modules.html#index-max-result-window - perPage = 10000 - } else { - perPage = criteria.perPage - } - + const perPage = criteria.perPage if (!criteria.sortBy) { criteria.sortBy = 'id' } @@ -395,19 +408,22 @@ async function searchWorkPeriods (currentUser, criteria, options = { returnAll: criteria.sortOrder = 'desc' } try { - const sort = [{ [criteria.sortBy === 'id' ? '_id' : criteria.sortBy]: { order: criteria.sortOrder } }] - const esQuery = { - index: config.get('esConfig.ES_INDEX_WORK_PERIOD'), + index: config.get('esConfig.ES_INDEX_RESOURCE_BOOKING'), + _source_includes: 'workPeriods', + _source_excludes: queryOpt.excludeES, body: { query: { - bool: { - must: [] + nested: { + path: 'workPeriods', + query: { bool: { must: [] } } } }, - from: (page - 1) * perPage, - size: perPage, - sort + size: 10000 + // We use a very large number for size, because we can't paginate nested documents + // and in practice there could hardly be so many records to be returned.(also consider we are using filters in the meantime) + // the number is limited by `index.max_result_window`, its default value is 10000, see + // https://www.elastic.co/guide/en/elasticsearch/reference/current/index-modules.html#index-max-result-window } } // change the date format to match with database model @@ -417,10 +433,11 @@ async function searchWorkPeriods (currentUser, criteria, options = { returnAll: if (criteria.endDate) { criteria.endDate = moment(criteria.endDate).format('YYYY-MM-DD') } + // Apply filters _.each(_.pick(criteria, ['resourceBookingId', 'userHandle', 'projectId', 'startDate', 'endDate', 'paymentStatus']), (value, key) => { - esQuery.body.query.bool.must.push({ + esQuery.body.query.nested.query.bool.must.push({ term: { - [key]: { + [`workPeriods.${key}`]: { value } } @@ -428,30 +445,34 @@ async function searchWorkPeriods (currentUser, criteria, options = { returnAll: }) // if criteria contains resourceBookingIds, filter resourceBookingId with this value if (criteria.resourceBookingIds) { - esQuery.body.query.bool.filter = [{ + esQuery.body.query.nested.query.bool.filter = [{ terms: { - resourceBookingId: criteria.resourceBookingIds + 'workPeriods.resourceBookingId': criteria.resourceBookingIds } }] } logger.debug({ component: 'WorkPeriodService', context: 'searchWorkPeriods', message: `Query: ${JSON.stringify(esQuery)}` }) const { body } = await esClient.search(esQuery) - + let workPeriods = _.reduce(body.hits.hits, (acc, resourceBooking) => _.concat(acc, resourceBooking._source.workPeriods), []) + // ESClient will return ResourceBookings with it's all nested WorkPeriods + // We re-apply WorkPeriod filters + _.each(_.pick(criteria, ['startDate', 'endDate', 'paymentStatus']), (value, key) => { + workPeriods = _.filter(workPeriods, { [key]: value }) + }) + workPeriods = _.sortBy(workPeriods, [criteria.sortBy]) + if (criteria.sortOrder === 'desc') { + workPeriods = _.reverse(workPeriods) + } + const total = workPeriods.length + if (!options.returnAll) { + workPeriods = _.slice(workPeriods, (page - 1) * perPage, page * perPage) + } return { - total: body.hits.total.value, + total, page, perPage, - result: _.map(body.hits.hits, (hit) => { - const obj = _.cloneDeep(hit._source) - obj.id = hit._id - // We should only return "memberRate" to Booking Manager, Administrator or M2M - if (!currentUser.hasManagePermission && !_checkUserScopesForGetPayments(currentUser)) { - delete obj.memberRate - delete obj.payments - } - return obj - }) + result: workPeriods } } catch (err) { logger.logFullError(err, { component: 'WorkPeriodService', context: 'searchWorkPeriods' }) @@ -464,30 +485,31 @@ async function searchWorkPeriods (currentUser, criteria, options = { returnAll: if (criteria.resourceBookingIds) { filter[Op.and].push({ resourceBookingId: criteria.resourceBookingIds }) } - const workPeriods = await WorkPeriod.findAll({ + const queryCriteria = { where: filter, - include: [{ - model: models.WorkPeriodPayment, - as: 'payments', - required: false - }], offset: ((page - 1) * perPage), limit: perPage, order: [[criteria.sortBy, criteria.sortOrder]] - }) + } + // add excluded fields criteria + if (queryOpt.excludeDB.length > 0) { + queryCriteria.attributes = { exclude: queryOpt.excludeDB } + } + // include WorkPeriodPayment model + if (queryOpt.withPayments) { + queryCriteria.include = [{ + model: models.WorkPeriodPayment, + as: 'payments', + required: false + }] + } + const workPeriods = await WorkPeriod.findAll(queryCriteria) return { fromDb: true, total: workPeriods.length, page, perPage, - result: _.map(workPeriods, workPeriod => { - // We should only return "memberRate" to Booking Manager, Administrator or M2M - if (!currentUser.hasManagePermission && !_checkUserScopesForGetPayments(currentUser)) { - delete workPeriod.dataValues.memberRate - delete workPeriod.dataValues.payments - } - return workPeriod.dataValues - }) + result: workPeriods } } diff --git a/test/prepare.js b/test/prepare.js index 42277c70..c7e16a81 100644 --- a/test/prepare.js +++ b/test/prepare.js @@ -1,7 +1,10 @@ /* * Prepare for tests. */ - +const sinon = require('sinon') +const helper = require('../src/common/helper') +const commonData = require('./unit/common/CommonData') process.env.NODE_ENV = 'test' +sinon.stub(helper, 'getESClient').callsFake(() => commonData.ESClient) require('../src/bootstrap') require('../src/eventHandlers').init() diff --git a/test/unit/ResourceBookingService.test.js b/test/unit/ResourceBookingService.test.js index f557466e..64de1900 100644 --- a/test/unit/ResourceBookingService.test.js +++ b/test/unit/ResourceBookingService.test.js @@ -8,6 +8,7 @@ const workPeriodService = require('../../src/services/WorkPeriodService') const commonData = require('./common/CommonData') const testData = require('./common/ResourceBookingData') const helper = require('../../src/common/helper') +const errors = require('../../src/common/errors') const busApiClient = helper.getBusApiClient() const ResourceBooking = models.ResourceBooking const WorkPeriod = models.WorkPeriod @@ -353,4 +354,225 @@ describe('resourceBooking service test', () => { expect(stubDeleteWorkPeriodService.callCount).to.eq(0) }) }) + describe('Get resource booking with/without nested fields', () => { + it('T17:Get resource booking from ES', async () => { + const data = testData.T17 + const ESClient = commonData.ESClient + ESClient.get = () => {} + const esClientGet = sinon.stub(ESClient, 'get').callsFake(() => data.esClientGet) + const result = await service.getResourceBooking(commonData.userWithManagePermission, data.esClientGet.body._source.id, data.criteria) + expect(esClientGet.calledOnce).to.be.true + expect(result).to.deep.eq(data.esClientGet.body._source) + }) + it('T18:Get resource booking from DB', async () => { + const data = testData.T18 + const stubResourceBookingFindById = sinon.stub(ResourceBooking, 'findById').callsFake(async () => { + return data.resourceBooking.value + }) + const result = await service.getResourceBooking(commonData.userWithManagePermission, data.resourceBooking.value.dataValues.id, data.criteria) + expect(stubResourceBookingFindById.calledOnce).to.be.true + expect(result).to.deep.eq(data.resourceBooking.value.dataValues) + }) + it('T19:Fail to get resource booking with not allowed fields', async () => { + const data = testData.T19 + let error + try { + await service.getResourceBooking(commonData.userWithManagePermission, data.id, data.criteria) + } catch (err) { + error = err + } + expect(error.httpStatus).to.eq(data.error.httpStatus) + expect(error.message).to.eq(data.error.message) + }) + it('T20:Fail to get resource booking with memberRate', async () => { + const data = testData.T20 + let error + try { + await service.getResourceBooking(commonData.regularUser, data.id, data.criteria) + } catch (err) { + error = err + } + expect(error.httpStatus).to.eq(data.error.httpStatus) + expect(error.message).to.eq(data.error.message) + }) + it('T21:Fail to get resource booking with nested workPeriods', async () => { + const data = testData.T21 + let error + try { + await service.getResourceBooking(commonData.currentUser, data.id, data.criteria) + } catch (err) { + error = err + } + expect(error.httpStatus).to.eq(data.error.httpStatus) + expect(error.message).to.eq(data.error.message) + }) + it('T22:Fail to get resource booking without including projectId as a regularUser', async () => { + const data = testData.T22 + let error + try { + await service.getResourceBooking(commonData.regularUser, data.id, data.criteria) + } catch (err) { + error = err + } + expect(error.httpStatus).to.eq(data.error.httpStatus) + expect(error.message).to.eq(data.error.message) + }) + it('T23:Fail to get resource booking as a regularUser who is not member of project', async () => { + const data = testData.T23 + const ESClient = commonData.ESClient + ESClient.get = () => {} + const esClientGet = sinon.stub(ESClient, 'get').callsFake(() => data.esClientGet) + const checkIsMemberOfProject = sinon.stub(helper, 'checkIsMemberOfProject').callsFake(() => { + throw new errors.UnauthorizedError(data.error.message) + }) + let error + try { + await service.getResourceBooking(commonData.regularUser, data.id, data.criteria) + } catch (err) { + error = err + } + expect(esClientGet.calledOnce).to.be.true + expect(checkIsMemberOfProject.calledOnce).to.be.true + expect(error.httpStatus).to.eq(data.error.httpStatus) + expect(error.message).to.eq(data.error.message) + }) + }) + describe('Search resource booking with/without nested fields', () => { + it('T24:Search resource booking from ES', async () => { + const data = testData.T24 + const ESClient = commonData.ESClient + ESClient.search = () => {} + const esClientSearch = sinon.stub(ESClient, 'search').callsFake(() => data.esClientSearch) + const result = await service.searchResourceBookings(commonData.userWithManagePermission, data.criteria) + expect(esClientSearch.calledOnce).to.be.true + expect(result).to.deep.eq(data.result) + }) + it('T25:Search resource bookin from DB', async () => { + const data = testData.T25 + const ESClient = commonData.ESClient + ESClient.search = () => {} + const esClientSearch = sinon.stub(ESClient, 'search').callsFake(() => { throw new Error() }) + const stubResourceBookingFindAll = sinon.stub(ResourceBooking, 'findAll').callsFake(async () => { + return data.resourceBookingFindAll + }) + const result = await service.searchResourceBookings(commonData.userWithManagePermission, data.criteria) + expect(esClientSearch.calledOnce).to.be.true + expect(stubResourceBookingFindAll.calledOnce).to.be.true + expect(result).to.deep.eq(data.result) + }) + it('T26:Fail to search resource booking with not allowed fields', async () => { + const data = testData.T26 + let error + try { + await service.searchResourceBookings(commonData.userWithManagePermission, data.criteria) + } catch (err) { + error = err + } + expect(error.httpStatus).to.eq(data.error.httpStatus) + expect(error.message).to.eq(data.error.message) + }) + it('T27:Fail to search resource booking with memberRate', async () => { + const data = testData.T27 + let error + try { + await service.searchResourceBookings(commonData.regularUser, data.criteria) + } catch (err) { + error = err + } + expect(error.httpStatus).to.eq(data.error.httpStatus) + expect(error.message).to.eq(data.error.message) + }) + it('T28:Fail to search resource booking with nested workPeriods', async () => { + const data = testData.T28 + let error + try { + await service.searchResourceBookings(commonData.currentUser, data.criteria) + } catch (err) { + error = err + } + expect(error.httpStatus).to.eq(data.error.httpStatus) + expect(error.message).to.eq(data.error.message) + }) + it('T29:Fail to search resource booking without filtering by projectId as a regularUser', async () => { + const data = testData.T29 + let error + try { + await service.searchResourceBookings(commonData.regularUser, data.criteria) + } catch (err) { + error = err + } + expect(error.httpStatus).to.eq(data.error.httpStatus) + expect(error.message).to.eq(data.error.message) + }) + it('T30:Fail to search resource booking as a regularUser who is not member of project', async () => { + const data = testData.T30 + const checkIsMemberOfProject = sinon.stub(helper, 'checkIsMemberOfProject').callsFake(() => { + throw new errors.UnauthorizedError(data.error.message) + }) + let error + try { + await service.searchResourceBookings(commonData.regularUser, data.criteria) + } catch (err) { + error = err + } + expect(checkIsMemberOfProject.calledOnce).to.be.true + expect(error.httpStatus).to.eq(data.error.httpStatus) + expect(error.message).to.eq(data.error.message) + }) + it('T31:Fail to search resource booking with filtering by nested field', async () => { + const data = testData.T31 + let error + try { + await service.searchResourceBookings(commonData.userWithManagePermission, data.criteria) + } catch (err) { + error = err + } + expect(error.httpStatus).to.eq(data.error.httpStatus) + expect(error.message).to.eq(data.error.message) + }) + it('T32:Fail to search resource booking with sorting by not included field', async () => { + const data = testData.T32 + let error + try { + await service.searchResourceBookings(commonData.userWithManagePermission, data.criteria) + } catch (err) { + error = err + } + expect(error.httpStatus).to.eq(data.error.httpStatus) + expect(error.message).to.eq(data.error.message) + }) + it('T33:Fail to search resource booking with sorting by nested field', async () => { + const data = testData.T33 + let error + try { + await service.searchResourceBookings(commonData.userWithManagePermission, data.criteria) + } catch (err) { + error = err + } + expect(error.httpStatus).to.eq(data.error.httpStatus) + expect(error.message).to.eq(data.error.message) + }) + it('T34:Fail to search resource booking with filtering by not included field', async () => { + const data = testData.T34 + let error + try { + await service.searchResourceBookings(commonData.userWithManagePermission, data.criteria) + } catch (err) { + error = err + } + expect(error.httpStatus).to.eq(data.error.httpStatus) + expect(error.message).to.eq(data.error.message) + }) + it('T35:Fail to search resource booking with filtering by not included nested field', async () => { + const data = testData.T35 + let error + try { + await service.searchResourceBookings(commonData.userWithManagePermission, data.criteria) + } catch (err) { + error = err + } + expect(error.httpStatus).to.eq(data.error.httpStatus) + expect(error.message).to.eq(data.error.message) + }) + }) }) diff --git a/test/unit/common/CommonData.js b/test/unit/common/CommonData.js index 08f8aa66..2653e732 100644 --- a/test/unit/common/CommonData.js +++ b/test/unit/common/CommonData.js @@ -1,12 +1,23 @@ const currentUser = { userId: '00000000-0000-0000-0000-000000000000', - isMachine: true + isMachine: true, + scopes: [] } const UserTCConnCopilot = { userId: '4709473d-f060-4102-87f8-4d51ff0b34c1', handle: 'TCConnCopilot' } +const userWithManagePermission = { + hasManagePermission: true +} +const regularUser = { + userId: '222' +} +const ESClient = {} module.exports = { currentUser, - UserTCConnCopilot + UserTCConnCopilot, + userWithManagePermission, + regularUser, + ESClient } diff --git a/test/unit/common/ResourceBookingData.js b/test/unit/common/ResourceBookingData.js index 4679a835..b296a384 100644 --- a/test/unit/common/ResourceBookingData.js +++ b/test/unit/common/ResourceBookingData.js @@ -984,6 +984,371 @@ const T16 = { } } T16.resourceBooking.value.toJSON = () => T16.resourceBooking.value.dataValues +const T17 = { + esClientGet: { + body: { + _source: { + updatedBy: null, + endDate: '2020-10-27', + billingAccountId: 80000071, + userId: 'a55fe1bc-1754-45fa-9adc-cf3d6d7c377a', + jobId: '05232809-3693-44c1-a0cc-9a79f2672385', + rateType: 'hourly', + createdAt: '2021-05-08T18:47:37.268Z', + memberRate: 13.23, + createdBy: '57646ff9-1cd3-4d3c-88ba-eb09a395366c', + customerRate: 13, + id: '60e99790-8da0-4596-badc-29a06feb78a0', + projectId: 17234, + startDate: '2020-09-27', + status: 'placed', + updatedAt: '2021-05-08T18:47:37.268Z' + } + } + }, + criteria: {} +} +const T18 = { + resourceBooking: { + value: { + dataValues: { + id: '520bb632-a02a-415e-9857-93b2ecbf7d60', + projectId: 21, + userId: 'a55fe1bc-1754-45fa-9adc-cf3d6d7c377a', + jobId: '6093e58c-683d-4022-8482-5515e8345016', + startDate: '2021-04-05', + endDate: '2021-04-17', + memberRate: 13.23, + customerRate: 13, + rateType: 'hourly', + createdAt: '2020-10-09T04:24:01.048Z', + createdBy: '57646ff9-1cd3-4d3c-88ba-eb09a395366c', + status: 'sourcing', + billingAccountId: 68800079 + } + } + }, + criteria: { fromDb: true } +} +const T19 = { + id: '520bb632-a02a-415e-9857-93b2ecbf7d60', + criteria: { + fields: 'other' + }, + error: { + httpStatus: 400, + message: 'other are not allowed' + } +} +const T20 = { + id: '520bb632-a02a-415e-9857-93b2ecbf7d60', + criteria: { + fields: 'memberRate' + }, + error: { + httpStatus: 403, + message: 'You don\'t have access to view memberRate' + } +} +const T21 = { + id: '520bb632-a02a-415e-9857-93b2ecbf7d60', + criteria: { + fields: 'workPeriods' + }, + error: { + httpStatus: 403, + message: 'You don\'t have access to view workPeriods' + } +} +const T22 = { + id: '520bb632-a02a-415e-9857-93b2ecbf7d60', + criteria: { + fields: 'id' + }, + error: { + httpStatus: 403, + message: 'Not allowed without including "projectId"' + } +} +const T23 = { + id: '520bb632-a02a-415e-9857-93b2ecbf7d60', + criteria: {}, + esClientGet: { + body: { + _source: { + updatedBy: null, + endDate: '2020-10-27', + billingAccountId: 80000071, + userId: 'a55fe1bc-1754-45fa-9adc-cf3d6d7c377a', + jobId: '05232809-3693-44c1-a0cc-9a79f2672385', + rateType: 'hourly', + createdAt: '2021-05-08T18:47:37.268Z', + memberRate: 13.23, + createdBy: '57646ff9-1cd3-4d3c-88ba-eb09a395366c', + customerRate: 13, + id: '520bb632-a02a-415e-9857-93b2ecbf7d60', + projectId: 111, + startDate: '2020-09-27', + status: 'placed', + updatedAt: '2021-05-08T18:47:37.268Z' + } + } + }, + error: { + httpStatus: 401, + message: 'userId: 222 the user is not a member of project 111' + } +} +const T24 = { + esClientSearch: { + body: { + hits: { + total: { + value: 2 + }, + hits: [ + { + _source: { + updatedBy: null, + endDate: '2020-10-27', + billingAccountId: 80000071, + userId: 'a55fe1bc-1754-45fa-9adc-cf3d6d7c377a', + jobId: '05232809-3693-44c1-a0cc-9a79f2672385', + rateType: 'hourly', + createdAt: '2021-05-08T18:35:16.368Z', + memberRate: 13.23, + createdBy: '57646ff9-1cd3-4d3c-88ba-eb09a395366c', + customerRate: 13, + id: 'fbe133dd-0e36-4d0c-8197-49307b13ce75', + projectId: 17234, + startDate: '2020-09-27', + status: 'placed', + updatedAt: '2021-05-08T18:35:16.368Z' + } + }, + { + _source: { + updatedBy: null, + endDate: '2020-10-27', + billingAccountId: 80000071, + userId: 'a55fe1bc-1754-45fa-9adc-cf3d6d7c377a', + jobId: '05232809-3693-44c1-a0cc-9a79f2672385', + rateType: 'hourly', + createdAt: '2021-05-08T18:47:37.268Z', + memberRate: 13.23, + createdBy: '57646ff9-1cd3-4d3c-88ba-eb09a395366c', + customerRate: 13, + id: '60e99790-8da0-4596-badc-29a06feb78a0', + projectId: 17234, + startDate: '2020-09-27', + status: 'placed', + updatedAt: '2021-05-08T18:47:37.268Z' + } + } + ] + } + } + }, + criteria: {}, + result: { + total: 2, + page: 1, + perPage: 20, + result: [ + { + updatedBy: null, + endDate: '2020-10-27', + billingAccountId: 80000071, + userId: 'a55fe1bc-1754-45fa-9adc-cf3d6d7c377a', + jobId: '05232809-3693-44c1-a0cc-9a79f2672385', + rateType: 'hourly', + createdAt: '2021-05-08T18:35:16.368Z', + memberRate: 13.23, + createdBy: '57646ff9-1cd3-4d3c-88ba-eb09a395366c', + customerRate: 13, + id: 'fbe133dd-0e36-4d0c-8197-49307b13ce75', + projectId: 17234, + startDate: '2020-09-27', + status: 'placed', + updatedAt: '2021-05-08T18:35:16.368Z' + }, + { + updatedBy: null, + endDate: '2020-10-27', + billingAccountId: 80000071, + userId: 'a55fe1bc-1754-45fa-9adc-cf3d6d7c377a', + jobId: '05232809-3693-44c1-a0cc-9a79f2672385', + rateType: 'hourly', + createdAt: '2021-05-08T18:47:37.268Z', + memberRate: 13.23, + createdBy: '57646ff9-1cd3-4d3c-88ba-eb09a395366c', + customerRate: 13, + id: '60e99790-8da0-4596-badc-29a06feb78a0', + projectId: 17234, + startDate: '2020-09-27', + status: 'placed', + updatedAt: '2021-05-08T18:47:37.268Z' + } + ] + } +} +const T25 = { + resourceBookingFindAll: [ + { + updatedBy: null, + endDate: '2020-10-27', + billingAccountId: 80000071, + userId: 'a55fe1bc-1754-45fa-9adc-cf3d6d7c377a', + jobId: '05232809-3693-44c1-a0cc-9a79f2672385', + rateType: 'hourly', + createdAt: '2021-05-08T18:35:16.368Z', + memberRate: 13.23, + createdBy: '57646ff9-1cd3-4d3c-88ba-eb09a395366c', + customerRate: 13, + id: 'fbe133dd-0e36-4d0c-8197-49307b13ce75', + projectId: 17234, + startDate: '2020-09-27', + status: 'placed', + updatedAt: '2021-05-08T18:35:16.368Z' + }, + { + updatedBy: null, + endDate: '2020-10-27', + billingAccountId: 80000071, + userId: 'a55fe1bc-1754-45fa-9adc-cf3d6d7c377a', + jobId: '05232809-3693-44c1-a0cc-9a79f2672385', + rateType: 'hourly', + createdAt: '2021-05-08T18:47:37.268Z', + memberRate: 13.23, + createdBy: '57646ff9-1cd3-4d3c-88ba-eb09a395366c', + customerRate: 13, + id: '60e99790-8da0-4596-badc-29a06feb78a0', + projectId: 17234, + startDate: '2020-09-27', + status: 'placed', + updatedAt: '2021-05-08T18:47:37.268Z' + } + ], + criteria: {}, + result: { + fromDb: true, + total: 2, + page: 1, + perPage: 20, + result: [ + { + updatedBy: null, + endDate: '2020-10-27', + billingAccountId: 80000071, + userId: 'a55fe1bc-1754-45fa-9adc-cf3d6d7c377a', + jobId: '05232809-3693-44c1-a0cc-9a79f2672385', + rateType: 'hourly', + createdAt: '2021-05-08T18:35:16.368Z', + memberRate: 13.23, + createdBy: '57646ff9-1cd3-4d3c-88ba-eb09a395366c', + customerRate: 13, + id: 'fbe133dd-0e36-4d0c-8197-49307b13ce75', + projectId: 17234, + startDate: '2020-09-27', + status: 'placed', + updatedAt: '2021-05-08T18:35:16.368Z' + }, + { + updatedBy: null, + endDate: '2020-10-27', + billingAccountId: 80000071, + userId: 'a55fe1bc-1754-45fa-9adc-cf3d6d7c377a', + jobId: '05232809-3693-44c1-a0cc-9a79f2672385', + rateType: 'hourly', + createdAt: '2021-05-08T18:47:37.268Z', + memberRate: 13.23, + createdBy: '57646ff9-1cd3-4d3c-88ba-eb09a395366c', + customerRate: 13, + id: '60e99790-8da0-4596-badc-29a06feb78a0', + projectId: 17234, + startDate: '2020-09-27', + status: 'placed', + updatedAt: '2021-05-08T18:47:37.268Z' + } + ] + } +} +const T26 = { + criteria: { + fields: 'other' + }, + error: { + httpStatus: 400, + message: 'other are not allowed' + } +} +const T27 = { + criteria: { + fields: 'memberRate' + }, + error: { + httpStatus: 403, + message: 'You don\'t have access to view memberRate' + } +} +const T28 = { + criteria: { + fields: 'workPeriods' + }, + error: { + httpStatus: 403, + message: 'You don\'t have access to view workPeriods' + } +} +const T29 = { + criteria: {}, + error: { + httpStatus: 403, + message: 'Not allowed without filtering by "projectId"' + } +} +const T30 = { + criteria: { projectId: 111 }, + error: { + httpStatus: 401, + message: 'userId: 222 the user is not a member of project 111' + } +} +const T31 = { + criteria: { 'workPeriods.startDate': '2021-05-10' }, + error: { + httpStatus: 400, + message: 'Can not filter or sort by some field which is not included in fields' + } +} +const T32 = { + criteria: { sortBy: 'workPeriods.daysWorked' }, + error: { + httpStatus: 400, + message: 'Can not filter or sort by some field which is not included in fields' + } +} +const T33 = { + criteria: { fields: 'workPeriods', sortBy: 'workPeriods.daysWorked' }, + error: { + httpStatus: 400, + message: 'Can not sort by workPeriod field without filtering by workPeriods.startDate or workPeriods.endDate' + } +} +const T34 = { + criteria: { fields: 'id,startDate,endDate,workPeriods', status: 'closed' }, + error: { + httpStatus: 400, + message: 'Can not filter or sort by some field which is not included in fields' + } +} +const T35 = { + criteria: { fields: 'id,startDate,endDate', 'workPeriods.paymentStatus': 'completed' }, + error: { + httpStatus: 400, + message: 'Can not filter or sort by some field which is not included in fields' + } +} module.exports = { T01, T02, @@ -1000,5 +1365,24 @@ module.exports = { T13, T14, T15, - T16 + T16, + T17, + T18, + T19, + T20, + T21, + T22, + T23, + T24, + T25, + T26, + T27, + T28, + T29, + T30, + T31, + T32, + T33, + T34, + T35 }