Skip to content

Work periods automation #81

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jun 16, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/bootstrap.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ Joi.resourceBookingStatus = () => Joi.string().valid('placed', 'closed', 'cancel
Joi.jobCandidateStatus = () => Joi.string().valid('open', 'placed', 'selected', 'client rejected - screening', 'client rejected - interview', 'rejected - other', 'cancelled', 'interview', 'topcoder-rejected', 'applied', 'rejected-pre-screen', 'skills-test', 'skills-test', 'phone-screen', 'job-closed', 'offered')
Joi.workload = () => Joi.string().valid('full-time', 'fractional')
Joi.title = () => Joi.string().max(128)
Joi.paymentStatus = () => Joi.string().valid('pending', 'partially-completed', 'completed', 'cancelled')
Joi.paymentStatus = () => Joi.string().valid('pending', 'in-progress', 'partially-completed', 'completed', 'failed', 'no-days')
Joi.xaiTemplate = () => Joi.string().valid(...allowedXAITemplates)
Joi.interviewStatus = () => Joi.string().valid(...allowedInterviewStatuses)
Joi.workPeriodPaymentStatus = () => Joi.string().valid('completed', 'scheduled', 'in-progress', 'failed', 'cancelled')
Expand Down
7 changes: 5 additions & 2 deletions src/scripts/createIndex.js
Original file line number Diff line number Diff line change
Expand Up @@ -119,15 +119,18 @@ async function createIndex () {
startDate: { type: 'date', format: 'yyyy-MM-dd' },
endDate: { type: 'date', format: 'yyyy-MM-dd' },
daysWorked: { type: 'integer' },
memberRate: { type: 'float' },
customerRate: { type: 'float' },
daysPaid: { type: 'integer' },
paymentTotal: { type: 'float' },
paymentStatus: { type: 'keyword' },
payments: {
type: 'nested',
properties: {
id: { type: 'keyword' },
workPeriodId: { type: 'keyword' },
challengeId: { type: 'keyword' },
memberRate: { type: 'float' },
customerRate: { type: 'float' },
days: { type: 'integer' },
amount: { type: 'float' },
status: { type: 'keyword' },
statusDetails: {
Expand Down
138 changes: 32 additions & 106 deletions src/services/WorkPeriodPaymentProcessorService.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,53 +4,46 @@

const Joi = require('@hapi/joi')
const config = require('config')
const _ = require('lodash')
const logger = require('../common/logger')
const helper = require('../common/helper')
const constants = require('../common/constants')

const esClient = helper.getESClient()

/**
* Process create entity message
* @param {Object} message the kafka message
* @param {String} transactionId
*/
* Process create entity message
* @param {Object} message the kafka message
* @param {String} transactionId
*/
async function processCreate (message, transactionId) {
const data = message.payload
const workPeriodPayment = message.payload
// find related resourceBooking
const result = await esClient.search({
const resourceBooking = await esClient.search({
index: config.get('esConfig.ES_INDEX_RESOURCE_BOOKING'),
body: {
query: {
nested: {
path: 'workPeriods',
query: {
match: { 'workPeriods.id': data.workPeriodId }
match: { 'workPeriods.id': workPeriodPayment.workPeriodId }
}
}
}
}
})
if (!result.body.hits.total.value) {
throw new Error(`id: ${data.workPeriodId} "WorkPeriod" not found`)
if (!resourceBooking.body.hits.total.value) {
throw new Error(`id: ${workPeriodPayment.workPeriodId} "WorkPeriod" not found`)
}
const resourceBooking = result.body.hits.hits[0]._source
// find related workPeriod record
const workPeriod = _.find(resourceBooking.workPeriods, ['id', data.workPeriodId])
// Get workPeriod's existing payments
const payments = _.isArray(workPeriod.payments) ? workPeriod.payments : []
// Append new payment
payments.push(data)
// Assign new payments array to workPeriod
workPeriod.payments = payments
// Update ResourceBooking's workPeriods property
await esClient.updateExtra({
await esClient.update({
index: config.get('esConfig.ES_INDEX_RESOURCE_BOOKING'),
id: resourceBooking.id,
id: resourceBooking.body.hits.hits[0]._id,
transactionId,
body: {
doc: { workPeriods: resourceBooking.workPeriods }
script: {
lang: 'painless',
source: 'def wp = ctx._source.workPeriods.find(workPeriod -> workPeriod.id == params.workPeriodPayment.workPeriodId); if(!wp.containsKey("payments") || wp.payments == null){wp["payments"]=[]}wp.payments.add(params.workPeriodPayment)',
params: { workPeriodPayment }
}
},
refresh: constants.esRefreshOption
})
Expand All @@ -67,6 +60,9 @@ processCreate.schema = {
id: Joi.string().uuid().required(),
workPeriodId: Joi.string().uuid().required(),
challengeId: Joi.string().uuid().allow(null),
memberRate: Joi.number().required(),
customerRate: Joi.number().allow(null),
days: Joi.number().integer().min(1).max(5).required(),
amount: Joi.number().greater(0).allow(null),
status: Joi.workPeriodPaymentStatus().required(),
billingAccountId: Joi.number().allow(null),
Expand All @@ -87,14 +83,14 @@ processCreate.schema = {
}

/**
* Process update entity message
* @param {Object} message the kafka message
* @param {String} transactionId
*/
* Process update entity message
* @param {Object} message the kafka message
* @param {String} transactionId
*/
async function processUpdate (message, transactionId) {
const data = message.payload
// find workPeriodPayment in it's parent ResourceBooking
let result = await esClient.search({
const resourceBooking = await esClient.search({
index: config.get('esConfig.ES_INDEX_RESOURCE_BOOKING'),
body: {
query: {
Expand All @@ -107,89 +103,19 @@ async function processUpdate (message, transactionId) {
}
}
})
if (!result.body.hits.total.value) {
if (!resourceBooking.body.hits.total.value) {
throw new Error(`id: ${data.id} "WorkPeriodPayment" not found`)
}
const resourceBooking = _.cloneDeep(result.body.hits.hits[0]._source)
let workPeriod = null
let payment = null
let paymentIndex = null
// find workPeriod and workPeriodPayment records
_.forEach(resourceBooking.workPeriods, wp => {
_.forEach(wp.payments, (p, pi) => {
if (p.id === data.id) {
payment = p
paymentIndex = pi
return false
}
})
if (payment) {
workPeriod = wp
return false
}
})
let payments
// if WorkPeriodPayment's workPeriodId changed then it must be deleted from the old WorkPeriod
// and added to the new WorkPeriod
if (payment.workPeriodId !== data.workPeriodId) {
// remove payment from payments
payments = _.filter(workPeriod.payments, p => p.id !== data.id)
// assign payments to workPeriod record
workPeriod.payments = payments
// Update old ResourceBooking's workPeriods property
await esClient.updateExtra({
index: config.get('esConfig.ES_INDEX_RESOURCE_BOOKING'),
id: resourceBooking.id,
transactionId,
body: {
doc: { workPeriods: resourceBooking.workPeriods }
},
refresh: constants.esRefreshOption
})
// find workPeriodPayment's new parent WorkPeriod
result = await esClient.search({
index: config.get('esConfig.ES_INDEX_RESOURCE_BOOKING'),
body: {
query: {
nested: {
path: 'workPeriods',
query: {
match: { 'workPeriods.id': data.workPeriodId }
}
}
}
}
})
const newResourceBooking = result.body.hits.hits[0]._source
// find WorkPeriod record in ResourceBooking
const newWorkPeriod = _.find(newResourceBooking.workPeriods, ['id', data.workPeriodId])
// Get WorkPeriod's existing payments
const newPayments = _.isArray(newWorkPeriod.payments) ? newWorkPeriod.payments : []
// Append new payment
newPayments.push(data)
// Assign new payments array to workPeriod
newWorkPeriod.payments = newPayments
// Update new ResourceBooking's workPeriods property
await esClient.updateExtra({
index: config.get('esConfig.ES_INDEX_RESOURCE_BOOKING'),
id: newResourceBooking.id,
transactionId,
body: {
doc: { workPeriods: newResourceBooking.workPeriods }
},
refresh: constants.esRefreshOption
})
return
}
// update payment record
workPeriod.payments[paymentIndex] = data
// Update ResourceBooking's workPeriods property
await esClient.updateExtra({
await esClient.update({
index: config.get('esConfig.ES_INDEX_RESOURCE_BOOKING'),
id: resourceBooking.id,
id: resourceBooking.body.hits.hits[0]._id,
transactionId,
body: {
doc: { workPeriods: resourceBooking.workPeriods }
script: {
lang: 'painless',
source: 'def wp = ctx._source.workPeriods.find(workPeriod -> workPeriod.id == params.data.workPeriodId); wp.payments.removeIf(payment -> payment.id == params.data.id); wp.payments.add(params.data)',
params: { data }
}
},
refresh: constants.esRefreshOption
})
Expand Down
Loading