Skip to content

Commit

Permalink
Feature/461 Settlement Transfer (mojaloop#150)
Browse files Browse the repository at this point in the history
* Added account type and seeds
* Updated DDL and seeds for settlement transfers
* Added SETTLEMENT_NET_ZERO ledgerEntryType enum
* Changed seeds
* Server cached enums (3.1) and create both accounts (6)
* Fixed unit tests for the previous commit
* Change cache from 5 secs to 5 mins
* All references to participantCurrencyId point to the Position Account
  • Loading branch information
ggrg authored Sep 28, 2018
1 parent 1fe920f commit 87c748d
Show file tree
Hide file tree
Showing 26 changed files with 490 additions and 124 deletions.
43 changes: 43 additions & 0 deletions migrations/110450_ledgerAccountType.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*****
License
--------------
Copyright © 2017 Bill & Melinda Gates Foundation
The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
Contributors
--------------
This is the official list of the Mojaloop project contributors for this file.
Names of the original copyright holders (individuals or organizations)
should be listed with a '*' in the first column. People who have
contributed from an organization can be listed under the organization
that actually holds the copyright for their contributions (see the
Gates Foundation organization for an example). Those individuals should have
their names indented and be marked with a '-'. Email address can be added
optionally within square brackets <email>.
* Gates Foundation
- Name Surname <name.surname@gatesfoundation.com>
* Georgi Georgiev <georgi.georgiev@modusbox.com>
--------------
******/

'use strict'

exports.up = async (knex, Promise) => {
return await knex.schema.hasTable('ledgerAccountType').then(function(exists) {
if (!exists) {
return knex.schema.createTable('ledgerAccountType', (t) => {
t.increments('ledgerAccountTypeId').primary().notNullable()
t.string('name', 50).notNullable()
t.string('description', 512).defaultTo(null).nullable()
t.boolean('isActive').defaultTo(true).notNullable()
t.dateTime('createdDate').defaultTo(knex.fn.now()).notNullable()
})
}
})
}

exports.down = function (knex, Promise) {
return knex.schema.dropTableIfExists('ledgerAccountType')
}
37 changes: 37 additions & 0 deletions migrations/110451_ledgerAccountType-indexes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*****
License
--------------
Copyright © 2017 Bill & Melinda Gates Foundation
The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
Contributors
--------------
This is the official list of the Mojaloop project contributors for this file.
Names of the original copyright holders (individuals or organizations)
should be listed with a '*' in the first column. People who have
contributed from an organization can be listed under the organization
that actually holds the copyright for their contributions (see the
Gates Foundation organization for an example). Those individuals should have
their names indented and be marked with a '-'. Email address can be added
optionally within square brackets <email>.
* Gates Foundation
- Name Surname <name.surname@gatesfoundation.com>
* Georgi Georgiev <georgi.georgiev@modusbox.com>
--------------
******/

'use strict'

exports.up = function (knex, Promise) {
return knex.schema.table('ledgerAccountType', (t) => {
t.unique('name')
})
}

exports.down = function (knex, Promise) {
return knex.schema.table('ledgerAccountType', (t) => {
t.dropUnique('name')
})
}
2 changes: 2 additions & 0 deletions migrations/310100_participantCurrency.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ exports.up = async (knex, Promise) => {
t.foreign('participantId').references('participantId').inTable('participant')
t.string('currencyId', 3).notNullable()
t.foreign('currencyId').references('currencyId').inTable('currency')
t.integer('ledgerAccountTypeId').unsigned().notNullable()
t.foreign('ledgerAccountTypeId').references('ledgerAccountTypeId').inTable('ledgerAccountType')
t.boolean('isActive').defaultTo(true).notNullable()
t.dateTime('createdDate').defaultTo(knex.fn.now()).notNullable()
t.string('createdBy', 128).notNullable()
Expand Down
4 changes: 2 additions & 2 deletions migrations/310101_participantCurrency-indexes.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,14 @@ exports.up = function (knex, Promise) {
return knex.schema.table('participantCurrency', (t) => {
t.index('participantId')
t.index('currencyId')
t.unique(['participantId', 'currencyId'])
t.unique(['participantId', 'currencyId', 'ledgerAccountTypeId'], 'participantcurrency_pcl_unique')
})
}

exports.down = function (knex, Promise) {
return knex.schema.table('participantCurrency', (t) => {
t.dropIndex('participantId')
t.dropIndex('currencyId')
t.dropUnique(['participantId', 'currencyId'])
t.dropUnique(['participantId', 'currencyId', 'ledgerAccountTypeId'], 'participantcurrency_pcl_unique')
})
}
1 change: 1 addition & 0 deletions migrations/400600_settlementParticipantCurrency.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ exports.up = async (knex, Promise) => {
t.decimal('netAmount', 18, 2).notNullable()
t.dateTime('createdDate').defaultTo(knex.fn.now()).notNullable()
t.bigInteger('currentStateChangeId').unsigned().nullable()
t.string('settlementTransferId', 36).nullable()
})
}
})
Expand Down
2 changes: 2 additions & 0 deletions migrations/400601_settlementParticipantCurrency-indexes.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,14 @@ exports.up = function (knex, Promise) {
return knex.schema.table('settlementParticipantCurrency', (t) => {
t.index('settlementId')
t.index('participantCurrencyId')
t.index('settlementTransferId')
})
}

exports.down = function (knex, Promise) {
return knex.schema.table('settlementParticipantCurrency', (t) => {
t.dropIndex('settlementId')
t.dropIndex('participantCurrencyId')
t.dropIndex('settlementTransferId')
})
}
52 changes: 52 additions & 0 deletions seeds/ledgerAccountType.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*****
License
--------------
Copyright © 2017 Bill & Melinda Gates Foundation
The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
Contributors
--------------
This is the official list of the Mojaloop project contributors for this file.
Names of the original copyright holders (individuals or organizations)
should be listed with a '*' in the first column. People who have
contributed from an organization can be listed under the organization
that actually holds the copyright for their contributions (see the
Gates Foundation organization for an example). Those individuals should have
their names indented and be marked with a '-'. Email address can be added
optionally within square brackets <email>.
* Gates Foundation
- Name Surname <name.surname@gatesfoundation.com>
* Georgi Georgiev <georgi.georgiev@modusbox.com>
--------------
******/

'use strict'

const ledgerAccountTypes = [
{
'name': 'POSITION',
'description': 'Typical accounts from which a DFSP provisions transfers '
},
{
'name': 'SETTLEMENT',
'description': 'Reflects the individual DFSP Settlement Accounts as held at the Settlement Bank'
},
{
'name': 'HUB_SETTLEMENT',
'description': 'A single account for each currency with which the hub operates. The account is "held" by the Participant representing the hub in the switch'
}
]

exports.seed = async function (knex) {
try {
return await knex('ledgerAccountType').insert(ledgerAccountTypes)
} catch (err) {
if (err.code === 'ER_DUP_ENTRY') return -1001
else {
console.log(`Uploading seeds for ledgerAccountType has failed with the following error: ${err}`)
return -1000
}
}
}
34 changes: 31 additions & 3 deletions seeds/ledgerEntryType.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,43 @@
const ledgerEntryTypes = [
{
'name': 'PRINCIPLE_VALUE',
'description': 'The principle amount to be settled between parties, derived on quotes between DFSPs'
'description': 'The principle amount to be settled between parties, derived on quotes between DFSPs (+/-///)'
},
{
'name': 'INTERCHANGE_FEE',
'description': 'Fees to be paid between DFSP'
'description': 'Fees to be paid between DFSP (±/±///)'
},
{
'name': 'HUB_FEE',
'description': 'Fees to be paid from the DFSPs to the Hub Operator'
'description': 'Fees to be paid from the DFSPs to the Hub Operator (-/-/+//)'
},
{
'name': 'POSITION_DEPOSIT',
'description': 'Used when increasing Net Debit Cap (///+/- more funds available)'
},
{
'name': 'POSITION_WITHDRAWAL',
'description': 'Used when decreasing Net Debit Cap (///-/+ less funds available - not to exceed NDC)'
},
{
'name': 'SETTLEMENT_NET_RECIPIENT',
'description': 'Participant is settlement net recipient (///-/+ negative position will be increased to show I have less position to operate with as it returns to zero)'
},
{
'name': 'SETTLEMENT_NET_SENDER',
'description': 'Participant is settlement net sender (///+/- reducing position, therefore increasing available position against NDC)'
},
{
'name': 'SETTLEMENT_NET_ZERO',
'description': 'Participant is settlement net sender (///+/- reducing position, therefore increasing available position against NDC)'
},
{
'name': 'SETTLEMENT_ACCOUNT_DEPOSIT',
'description': ''
},
{
'name': 'SETTLEMENT_ACCOUNT_WITHDRAWAL',
'description': ''
}
]

Expand Down
8 changes: 8 additions & 0 deletions seeds/transferParticipantRoleType.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,14 @@ const transferParticipantRoleTypes = [
{
'name': 'HUB',
'description': 'The participant is representing the Hub Operator'
},
{
'name': 'DFSP_SETTLEMENT_ACCOUNT',
'description': 'Indicates the settlement account'
},
{
'name': 'DFSP_POSITION_ACCOUNT',
'description': 'Indicates the position account'
}
]

Expand Down
9 changes: 6 additions & 3 deletions src/admin/participants/handler.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,10 @@ const entityItem = ({ name, createdDate, isActive, currencyList }) => {
}
}

const currencyEntityItem = ({ currencyId, isActive }) => {
const currencyEntityItem = ({ currencyId, isActive, ledgerAccountTypeId }) => {
return {
currency: currencyId,
ledgerAccountTypeId,
isActive
}
}
Expand Down Expand Up @@ -81,8 +82,10 @@ const create = async function (request, h) {
const participantId = await Participant.create(request.payload)
participant = await Participant.getById(participantId)
}
const participantCurrencyId = await Participant.createParticipantCurrency(participant.participantId, request.payload.currency)
participant.currencyList = [await Participant.getParticipantCurrencyById(participantCurrencyId)]
let ledgerAccountTypeEnum = await request.server.methods.enums('ledgerAccountType')
const participantCurrencyId1 = await Participant.createParticipantCurrency(participant.participantId, request.payload.currency, ledgerAccountTypeEnum.POSITION)
const participantCurrencyId2 = await Participant.createParticipantCurrency(participant.participantId, request.payload.currency, ledgerAccountTypeEnum.SETTLEMENT)
participant.currencyList = [await Participant.getParticipantCurrencyById(participantCurrencyId1), await Participant.getParticipantCurrencyById(participantCurrencyId2)]
return h.response(entityItem(participant)).code(201)
} catch (err) {
throw Boom.badRequest(err.message)
Expand Down
9 changes: 9 additions & 0 deletions src/admin/root/routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,14 @@ module.exports = [
return h.response({ status: 'OK' }).code(200)
},
options: RouteConfig.config(tags, 'Status of ledger admin api')
},
{
method: 'GET',
path: '/enums',
handler: async function (request, h) {
let enums = await request.server.methods.enums('all')
return h.response(enums).code(200)
},
options: RouteConfig.config(tags, 'List available enumerations')
}
]
Loading

0 comments on commit 87c748d

Please sign in to comment.