diff --git a/docs/swagger.yaml b/docs/swagger.yaml index 62c5b6e8..8c36fdf2 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -1505,9 +1505,13 @@ paths: name: workPeriods.paymentStatus required: false schema: - type: string - enum: ["pending", "partially-completed", "completed", "cancelled"] - description: The payment status. + oneOf: + - type: array + items: + type: string + enum: ["pending", "partially-completed", "completed", "cancelled"] + - type: string + description: comma separated payment status. - in: query name: workPeriods.startDate required: false @@ -1956,9 +1960,13 @@ paths: name: paymentStatus required: false schema: - type: string - enum: ["pending", "partially-completed", "completed", "cancelled"] - description: The payment status. + oneOf: + - type: array + items: + type: string + enum: ["pending", "partially-completed", "completed", "cancelled"] + - type: string + description: comma separated payment status. - in: query name: startDate required: false diff --git a/src/services/ResourceBookingService.js b/src/services/ResourceBookingService.js index 7be3833e..a23c336e 100644 --- a/src/services/ResourceBookingService.js +++ b/src/services/ResourceBookingService.js @@ -454,6 +454,11 @@ async function searchResourceBookings (currentUser, criteria, options = { return return projectId }) } + // `criteria[workPeriods.paymentStatus]` could be array of paymentStatus, or comma separated string of paymentStatus + // in case it's comma separated string of paymentStatus we have to convert it to an array of paymentStatus + if ((typeof criteria['workPeriods.paymentStatus']) === 'string') { + criteria['workPeriods.paymentStatus'] = criteria['workPeriods.paymentStatus'].trim().split(',').map(ps => Joi.attempt({ paymentStatus: ps.trim() }, Joi.object().keys({ paymentStatus: Joi.paymentStatus() })).paymentStatus) + } const page = criteria.page let perPage if (options.returnAll) { @@ -535,13 +540,21 @@ async function searchResourceBookings (currentUser, criteria, options = { return if (!_.isEmpty(workPeriodFilters)) { const workPeriodsMust = [] _.each(workPeriodFilters, (value, key) => { - workPeriodsMust.push({ - term: { - [key]: { - value + if (key === 'workPeriods.paymentStatus') { + workPeriodsMust.push({ + terms: { + [key]: value } - } - }) + }) + } else { + workPeriodsMust.push({ + term: { + [key]: { + value + } + } + }) + } }) esQuery.body.query.bool.must.push({ @@ -560,7 +573,13 @@ async function searchResourceBookings (currentUser, criteria, options = { return _.each(_.omit(workPeriodFilters, 'workPeriods.userHandle'), (value, key) => { key = key.split('.')[1] _.each(resourceBookings, r => { - r.workPeriods = _.filter(r.workPeriods, { [key]: value }) + r.workPeriods = _.filter(r.workPeriods, wp => { + if (key === 'paymentStatus') { + return _.includes(value, wp[key]) + } else { + return wp[key] === value + } + }) }) }) @@ -664,7 +683,10 @@ searchResourceBookings.schema = Joi.object().keys({ Joi.string(), Joi.array().items(Joi.number().integer()) ), - 'workPeriods.paymentStatus': Joi.paymentStatus(), + 'workPeriods.paymentStatus': Joi.alternatives( + Joi.string(), + Joi.array().items(Joi.paymentStatus()) + ), 'workPeriods.startDate': Joi.date().format('YYYY-MM-DD'), 'workPeriods.endDate': Joi.date().format('YYYY-MM-DD'), 'workPeriods.userHandle': Joi.string() diff --git a/src/services/WorkPeriodService.js b/src/services/WorkPeriodService.js index 4070d88d..9e555b90 100644 --- a/src/services/WorkPeriodService.js +++ b/src/services/WorkPeriodService.js @@ -289,7 +289,6 @@ async function updateWorkPeriod (currentUser, id, data) { } } - // await helper.postEvent(config.TAAS_WORK_PERIOD_UPDATE_TOPIC, updated.toJSON(), { oldValue: oldValue }) await helper.postEvent(config.TAAS_WORK_PERIOD_UPDATE_TOPIC, updated.toJSON(), { oldValue: oldValue, key: `resourceBooking.id:${data.resourceBookingId}` }) return updated.dataValues } @@ -401,6 +400,11 @@ async function searchWorkPeriods (currentUser, criteria, options = { returnAll: return resourceBookingId }) } + // `criteria.paymentStatus` could be array of paymentStatus, or comma separated string of paymentStatus + // in case it's comma separated string of paymentStatus we have to convert it to an array of paymentStatus + if ((typeof criteria.paymentStatus) === 'string') { + criteria.paymentStatus = criteria.paymentStatus.trim().split(',').map(ps => Joi.attempt({ paymentStatus: ps.trim() }, Joi.object().keys({ paymentStatus: Joi.paymentStatus() })).paymentStatus) + } const page = criteria.page const perPage = criteria.perPage if (!criteria.sortBy) { @@ -436,7 +440,7 @@ async function searchWorkPeriods (currentUser, criteria, options = { returnAll: criteria.endDate = moment(criteria.endDate).format('YYYY-MM-DD') } // Apply filters - _.each(_.pick(criteria, ['resourceBookingId', 'userHandle', 'projectId', 'startDate', 'endDate', 'paymentStatus']), (value, key) => { + _.each(_.pick(criteria, ['resourceBookingId', 'userHandle', 'projectId', 'startDate', 'endDate']), (value, key) => { esQuery.body.query.nested.query.bool.must.push({ term: { [`workPeriods.${key}`]: { @@ -445,6 +449,13 @@ async function searchWorkPeriods (currentUser, criteria, options = { returnAll: } }) }) + if (criteria.paymentStatus) { + esQuery.body.query.nested.query.bool.must.push({ + terms: { + 'workPeriods.paymentStatus': criteria.paymentStatus + } + }) + } // if criteria contains resourceBookingIds, filter resourceBookingId with this value if (criteria.resourceBookingIds) { esQuery.body.query.nested.query.bool.filter = [{ @@ -459,9 +470,12 @@ async function searchWorkPeriods (currentUser, criteria, options = { returnAll: 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) => { + _.each(_.pick(criteria, ['startDate', 'endDate']), (value, key) => { workPeriods = _.filter(workPeriods, { [key]: value }) }) + if (criteria.paymentStatus) { + workPeriods = _.filter(workPeriods, wp => _.includes(criteria.paymentStatus, wp.paymentStatus)) + } workPeriods = _.sortBy(workPeriods, [criteria.sortBy]) if (criteria.sortOrder === 'desc') { workPeriods = _.reverse(workPeriods) @@ -522,7 +536,10 @@ searchWorkPeriods.schema = Joi.object().keys({ perPage: Joi.number().integer().min(1).max(10000).default(20), sortBy: Joi.string().valid('id', 'resourceBookingId', 'userHandle', 'projectId', 'startDate', 'endDate', 'daysWorked', 'customerRate', 'memberRate', 'paymentStatus'), sortOrder: Joi.string().valid('desc', 'asc'), - paymentStatus: Joi.paymentStatus(), + paymentStatus: Joi.alternatives( + Joi.string(), + Joi.array().items(Joi.paymentStatus()) + ), startDate: Joi.date().format('YYYY-MM-DD'), endDate: Joi.date().format('YYYY-MM-DD'), userHandle: Joi.string(),