Skip to content

Commit

Permalink
Feature/414 416 dao and api (#20)
Browse files Browse the repository at this point in the history
* Merging functionality 6.2.2 & 6.2.5. done by @ggrg
  • Loading branch information
ggrg authored and mdebarros committed Sep 2, 2018
1 parent 061b0ed commit 6f813e9
Show file tree
Hide file tree
Showing 6 changed files with 171 additions and 46 deletions.
87 changes: 58 additions & 29 deletions src/domain/settlement/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
* Gates Foundation
- Name Surname <name.surname@gatesfoundation.com>
* Georgi Georgiev <georgi.georgiev@modusbox.com>
* Valentin Genev <valentin.genev@modusbox.com>
* Deon Botha <deon.botha@modusbox.com>
* Rajiv Mothilal <rajiv.mothilal@modusbox.com>
Expand Down Expand Up @@ -111,27 +112,29 @@ module.exports = {
let settlementAccountList = await settlementsModel.settlementParticipantCurrency.getParticipantCurrencyBySettlementId({settlementId}, enums)
let windowsList = await settlementWindowModel.getBySettlementId({settlementId}, enums)
let windowsAccountsList = await settlementsModel.getSettlementTransferParticipantBySettlementId({settlementId}, enums)

// seq-settlement-6.2.5, step 19
let pendingSettlementCount = 0
let settledCount = 0
let notSettledCount = 0
// let unknownCount = 0
let unknownCount = 0
let allAccounts = new Map()
let allWindows = new Map()
let windowsAccounts = new Map()
let accountsWindows = new Map()
for (let data of settlementAccountList) {
allAccounts[data.participantCurrencyId] = {
id: data.participantCurrencyId,
state: data.state,
reason: data.reason,
createDate: data.createdDate,
for (let account of settlementAccountList) {
allAccounts[account.participantCurrencyId] = {
id: account.participantCurrencyId,
state: account.state,
reason: account.reason,
createDate: account.createdDate,
netSettlementAmount: {
amount: data.netAmount,
currency: data.currency
amount: account.netAmount,
currency: account.currency
},
key: data.key
key: account.key
}
switch (data.state) {
switch (account.state) {
case 'PENDING_SETTLEMENT': {
pendingSettlementCount++
break
Expand All @@ -145,25 +148,30 @@ module.exports = {
break
}
default: {
// unknownCount++
unknownCount++
break
}
}
}
let settlementAccounts = {
pendingSettlementCount: pendingSettlementCount,
settledCount: settledCount,
notSettledCount: notSettledCount
pendingSettlementCount,
settledCount,
notSettledCount,
unknownCount
}
// let settlementAccountsInit = Object.assign({}, settlementAccounts)
let settlementAccountsInit = Object.assign({}, settlementAccounts)

// seq-settlement-6.2.5, step 23
for (let window of windowsList) {
allWindows[window.settlementWindowId] = {
id: window.settlementWindowId,
allWindows[window.id] = {
id: window.id,
state: window.state,
reason: window.reason,
createDate: window.createdDate
}
}

// seq-settlement-6.2.5, step 24
for (let record of windowsAccountsList) {
let wid = record.settlementWindowId
let aid = record.participantCurrencyId
Expand Down Expand Up @@ -197,18 +205,21 @@ module.exports = {
}
}
}
// let windowsAccountsInit = Object.assign({}, windowsAccounts)
let windowsAccountsInit = JSON.parse(JSON.stringify(windowsAccounts)) // TODO: switch to lodash cloneDeep
let participants = []
let settlementParticipantCurrencyStateChange = []
let processedAccounts = []
let affectedWindows = []
let transactionTimestamp = new Date()
for (let participant of payload.participants) {

// seq-settlement-6.2.5, step 26
for (let participant in payload.participants) {
let participantPayload = payload.participants[participant]
participants.push({id: participantPayload.id, accounts: []})
let pi = participants.length - 1
participant = participants[pi]
for (let account of participant.accounts) {
// seq-settlement-6.2.5, step 27
for (let account in participantPayload.accounts) {
let accountPayload = participantPayload.accounts[account]
if (allAccounts[accountPayload.id] === undefined) {
participant.accounts.push({
Expand All @@ -230,7 +241,7 @@ module.exports = {
errorDescription: 'Account already processed once'
}
})
} else if (allAccounts[account.id].state === accountPayload.state) {
} else if (allAccounts[accountPayload.id].state === accountPayload.state) {
processedAccounts.push(accountPayload.id)
participant.accounts.push({
id: accountPayload.id,
Expand All @@ -245,8 +256,8 @@ module.exports = {
reason: accountPayload.reason
})
allAccounts[accountPayload.id].reason = accountPayload.reason
allAccounts[accountPayload.id].createdDate = new Date()
} else if (allAccounts[account.id].state === 'PENDING_SETTLEMENT' && accountPayload.state === 'SETTLED') {
allAccounts[accountPayload.id].createdDate = transactionTimestamp
} else if (allAccounts[accountPayload.id].state === 'PENDING_SETTLEMENT' && accountPayload.state === 'SETTLED') {
processedAccounts.push(accountPayload.id)
participant.accounts.push({
id: accountPayload.id,
Expand All @@ -264,9 +275,9 @@ module.exports = {
settlementAccounts.settledCount++
allAccounts[accountPayload.id].state = accountPayload.state
allAccounts[accountPayload.id].reason = accountPayload.reason
allAccounts[accountPayload.id].createdDate = new Date()
allAccounts[accountPayload.id].createdDate = transactionTimestamp
let settlementWindowId
for (let aw of accountsWindows[accountPayload.id].windows) {
for (let aw in accountsWindows[accountPayload.id].windows) {
settlementWindowId = accountsWindows[accountPayload.id].windows[aw]
windowsAccounts[settlementWindowId].pendingSettlementCount--
windowsAccounts[settlementWindowId].settledCount++
Expand All @@ -289,9 +300,27 @@ module.exports = {
}
}
}
settlementId = await settlementsModel.putById(settlementParticipantCurrencyStateChange, payload, enums)
// TODO the transaction insert for everything
return true

let inputObj = {
settlementParticipantCurrencyStateChange,
affectedWindows,
windowsAccountsInit,
windowsAccounts,
allWindows,
settlementAccounts,
settlementAccountsInit,
settlementData,
transactionTimestamp
}
// seq-settlement-6.2.5, steps 33-47
let result = await settlementsModel.putById(inputObj, enums)
return {
id: settlementId,
state: result.settlementData.state,
createdDate: result.settlementData.createdDate,
settlementWindows: result.settlementWindows,
participants
}
} else {
let err = new Error('settlement window not found')
Logger('error', err)
Expand Down
2 changes: 1 addition & 1 deletion src/handlers/settlements.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
* Gates Foundation
- Name Surname <name.surname@gatesfoundation.com>
* Georgi Georgiev <georgi.georgiev@modusbox.com>
* Valentin Genev <valentin.genev@modusbox.com>
* Deon Botha <deon.botha@modusbox.com>
* Rajiv Mothilal <rajiv.mothilal@modusbox.com>
Expand Down Expand Up @@ -51,7 +52,6 @@ module.exports = {
* responses: 200, 400, 401, 404, 415, default
*/
get: async function getSettlementsByParams (request, h) {
// TODO
Logger.info('Here')
try {
const Enums = await request.server.methods.enums('settlementStates')
Expand Down
2 changes: 1 addition & 1 deletion src/handlers/settlements/{id}.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
* Gates Foundation
- Name Surname <name.surname@gatesfoundation.com>
* Georgi Georgiev <georgi.georgiev@modusbox.com>
* Valentin Genev <valentin.genev@modusbox.com>
* Deon Botha <deon.botha@modusbox.com>
* Rajiv Mothilal <rajiv.mothilal@modusbox.com>
Expand Down Expand Up @@ -73,7 +74,6 @@ module.exports = {
*/

put: async function updateSettlementById (request, h) {
// TODO
const settlementId = request.params.id
const Enums = await request.server.methods.enums('settlementStates')
try {
Expand Down
9 changes: 6 additions & 3 deletions src/interface/swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -161,10 +161,13 @@
"name": "state",
"type": "string",
"enum": [
"open",
"closed"
"OPEN",
"CLOSED",
"PENDING_SETTLEMENT",
"SETTLED",
"NOT_SETTLED"
],
"description": "A settlement window state (open or closed) to filter on. \n",
"description": "A settlement window state to filter on.\n",
"required": false
},
{
Expand Down
116 changes: 104 additions & 12 deletions src/models/settlement/facade.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
* Gates Foundation
- Name Surname <name.surname@gatesfoundation.com>
* Georgi Georgiev <georgi.georgiev@modusbox.com>
* Valentin Genev <valentin.genev@modusbox.com>
* Deon Botha <deon.botha@modusbox.com>
--------------
Expand All @@ -29,23 +30,114 @@ const Db = require('../index')

module.exports = {}

const settlementModel = require('./settlement')
// const settlementModel = require('./settlement')

const Facade = {

putById: async function (settlementParticipantCurrencyStateChange, enums = {}) {
putById: async function (obj, enums = {}) {
try {
let insertPromises
let updatePromises
const knex = await Db.getKnex()
// Open transaction
return await knex.transaction(async (trx) => {
const settlementParticipantCurrencyStateChangeIdList = await knex.batchInsert('settlementParticipantCurrencyStateChange', settlementParticipantCurrencyStateChange).transacting(trx)
if (settlementParticipantCurrencyStateChangeIdList) {
for (let id of settlementParticipantCurrencyStateChangeIdList) {
let temp = settlementParticipantCurrencyStateChange[id]
temp.settlementParticipantCurrencyStateChangeId = id
try {
// seq-settlement-6.2.5, step 33
insertPromises = []
for (let cpcsc of obj.settlementParticipantCurrencyStateChange) {
// Switched to insert from batchInsert because only last id is returned
insertPromises.push(
knex('settlementParticipantCurrencyStateChange')
.insert(cpcsc).returning('settlementParticipantCurrencyStateChangeId')
.transacting(trx)
)
}
let settlementParticipantCurrencyStateChangeIdList = (await Promise.all(insertPromises)).map(v => v[0])
if (settlementParticipantCurrencyStateChangeIdList) {
updatePromises = []
for (let i in settlementParticipantCurrencyStateChangeIdList) {
updatePromises.push(
knex('settlementParticipantCurrency')
.where('settlementParticipantCurrencyId', obj.settlementParticipantCurrencyStateChange[i].settlementParticipantCurrencyId)
.update({currentStateChangeId: settlementParticipantCurrencyStateChangeIdList[i]})
.transacting(trx)
)
}
await Promise.all(updatePromises)
}
} else {
throw new Error('insert failed')

// seq-settlement-6.2.5, step 38
let settlementWindowStateChange = []
obj.settlementWindows = [] // response object
let windowAccountsInit
let windowAccounts
for (let aw in obj.affectedWindows) {
windowAccountsInit = obj.windowsAccountsInit[obj.affectedWindows[aw]]
windowAccounts = obj.windowsAccounts[obj.affectedWindows[aw]]
if (windowAccounts.pendingSettlementCount !== windowAccountsInit.pendingSettlementCount ||
windowAccounts.settledCount !== windowAccountsInit.settledCount) {
if (windowAccounts.pendingSettlementCount === 0 &&
windowAccounts.notSettledCount === 0 &&
windowAccounts.settledCount > 0) {
obj.allWindows[obj.affectedWindows[aw]].settlementWindowStateId = 'SETTLED'
obj.allWindows[obj.affectedWindows[aw]].reason = 'All setlement accounts are settled'
obj.allWindows[obj.affectedWindows[aw]].createdDate = obj.transactionTimestamp
settlementWindowStateChange.push(obj.allWindows[obj.affectedWindows[aw]])
}
obj.settlementWindows.push(obj.allWindows[obj.affectedWindows[aw]])
}
}
if (settlementWindowStateChange.length) {
insertPromises = []
for (let swsc of settlementWindowStateChange) {
swsc.settlementWindowId = swsc.id
delete swsc.id // TODO: remote deletes
delete swsc.createDate
delete swsc.state
insertPromises.push(
knex('settlementWindowStateChange')
.insert(swsc).returning('settlementWindowStateChangeId')
.transacting(trx)
)
}
let settlementWindowStateChangeIdList = (await Promise.all(insertPromises)).map(v => v[0])
if (settlementWindowStateChangeIdList) {
updatePromises = []
for (let i in settlementWindowStateChangeIdList) {
updatePromises.push(
knex('settlementWindow')
.where('settlementWindowId', settlementWindowStateChange[i].settlementWindowId)
.update({currentStateChangeId: settlementWindowStateChangeIdList[i]})
.transacting(trx)
)
}
await Promise.all(updatePromises)
}
}
// seq-settlement-6.2.5, step 43
let settlementStateChange = []
if (obj.settlementAccounts.settledCount !== obj.settlementAccountsInit.settledCount &&
obj.settlementAccounts.pendingSettlementCount === 0 &&
obj.settlementAccounts.notSettledCount === 0) {
obj.settlementData.settlementStateId = 'SETTLED'
obj.settlementData.reason = 'All setlement accounts are settled'
obj.settlementData.createdDate = obj.transactionTimestamp
settlementStateChange.push(obj.settlementData)
}
if (settlementStateChange.length) {
delete settlementStateChange[0].state
let settlementStateChangeId = await knex('settlementStateChange')
.insert(settlementStateChange).returning('settlementStateChangeId')
.transacting(trx)
await knex('settlement')
.where('settlementId', settlementStateChange[0].settlementId)
.update({currentStateChangeId: settlementStateChangeId[0]})
.transacting(trx)
}
await trx.commit
return obj
} catch (err) {
await trx.rollback
throw err
}
})
} catch (err) {
Expand Down Expand Up @@ -130,7 +222,7 @@ const Facade = {
}
})
await knex.batchInsert('settlementSettlementWindow', settlementSettlementWindowList).transacting(trx)
let settlementTransferParticipantIdList = await knex
/* let settlementTransferParticipantIdList = */await knex
.from(knex.raw('settlementTransferParticipant (settlementId, settlementWindowId, participantCurrencyId, transferParticipantRoleTypeId, ledgerEntryTypeId, createdDate, amount)'))
.insert(function () {
this.from('settlementSettlementWindow AS ssw')
Expand Down Expand Up @@ -210,7 +302,7 @@ const Facade = {
.select('settlementWindowStateChangeId')
.whereIn('settlementWindowId', idList)
.andWhere('settlementWindowStateId', enums.settlementStates.PENDING_SETTLEMENT)
updatePromises = []
updatePromises = []
for (let index in idList) {
updatePromises.push(await knex('settlementWindow').transacting(trx)
.where('settlementWindowId', idList[index])
Expand Down
1 change: 1 addition & 0 deletions src/models/settlement/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
* Gates Foundation
- Name Surname <name.surname@gatesfoundation.com>
* Georgi Georgiev <georgi.georgiev@modusbox.com>
* Valentin Genev <valentin.genev@modusbox.com>
* Deon Botha <deon.botha@modusbox.com>
* Rajiv Mothilal <rajiv.mothilal@modusbox.com>
Expand Down

0 comments on commit 6f813e9

Please sign in to comment.