Skip to content
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

Add transaction service to water-abstraction-system #109

Merged
merged 10 commits into from
Feb 13, 2023
13 changes: 13 additions & 0 deletions app/services/check/supplementary-data.service.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
*/

const BillingPeriodService = require('../supplementary-billing/billing-period.service.js')
const CreateTransactionsService = require('../supplementary-billing/create-transactions.service.js')
const FetchChargeVersionsService = require('../supplementary-billing/fetch-charge-versions.service.js')
const FetchLicencesService = require('../supplementary-billing/fetch-licences.service.js')
const FetchRegionService = require('../supplementary-billing/fetch-region.service.js')
Expand All @@ -23,9 +24,21 @@ async function go (naldRegionId) {
// This is why we are only passing through the first billing period; we know there is only one!
const chargeVersions = await FetchChargeVersionsService.go(region.regionId, billingPeriods[0])

_addTransactionLines(billingPeriods, chargeVersions)

return _response({ billingPeriods, licences, chargeVersions })
}

function _addTransactionLines (billingPeriods, chargeVersions) {
const billingPeriod = billingPeriods[0]

for (const chargeVersion of chargeVersions) {
if (chargeVersion.chargeElements) {
chargeVersion.transactionLines = CreateTransactionsService.go(billingPeriod, chargeVersion.chargeElements)
}
}
}

function _response (data) {
return SupplementaryDataPresenter.go(data)
}
Expand Down
49 changes: 49 additions & 0 deletions app/services/supplementary-billing/create-transactions.service.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
'use strict'

/**
* Generates the transaction lines for a supplementary bill run
* @module CreateTransactionsService
*/

const AbstractionBillingPeriodService = require('./abstraction-billing-period.service.js')

/**
* Creates a transaction line and calculates the billable days for each charge element
*
* Each SROC charge version linked to a licence will have one or more charge elements that are linked to a charge reference.
*
* A transaction line is needed for each of these charge references. Linked to the charge element are one or more abstraction periods.
*
* We need to calculate the sum of the billable days for these periods and apply it to the transaction line.
*
* @param {Object} billingPeriod Object that has a `startDate` and `endDate` that defines the billing period
* @param {Object[]} chargeElements An array of `chargeElements` containing an array of `chargePurposes` which define
* the abstraction periods
*
* @returns {Object[]} An array that has the `reference` and `billableDays` for each charge element on a charge version
Jozzey marked this conversation as resolved.
Show resolved Hide resolved
*/
function go (billingPeriod, chargeElements) {
const transactionLines = chargeElements.map((chargeElement) => {
return {
reference: chargeElement.billingChargeCategory.reference,
billableDays: _calculateBillableDays(billingPeriod, chargeElement.chargePurposes)
}
})

return transactionLines
}

function _calculateBillableDays (billingPeriod, chargePurposes) {
let billableDays = 0
for (const chargePurpose of chargePurposes) {
const abstractionPeriods = AbstractionBillingPeriodService.go(billingPeriod, chargePurpose)
for (const abstractionPeriod of abstractionPeriods) {
billableDays = billableDays + abstractionPeriod.billableDays
}
}
return billableDays
}

module.exports = {
go
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
'use strict'

// Test framework dependencies
const Lab = require('@hapi/lab')
const Code = require('@hapi/code')

const { describe, it, beforeEach } = exports.lab = Lab.script()
const { expect } = Code

// Thing under test
const CreateTransactionsService = require('../../../app/services/supplementary-billing/create-transactions.service.js')

describe('Create Transactions service', () => {
const billingPeriod = {
startDate: new Date('2022-04-01'),
endDate: new Date('2023-03-31')
}
let chargeElements

describe('when there is one chargeElement', () => {
describe('containing one chargePurpose', () => {
beforeEach(() => {
chargeElements = [
{
billingChargeCategory: { reference: '1.2.3' },
chargePurposes: [
{
abstractionPeriodStartDay: 1,
abstractionPeriodStartMonth: 4,
abstractionPeriodEndDay: 30,
abstractionPeriodEndMonth: 9
}
]
}
]
})

it('returns a correctly calculated array of transaction lines', () => {
const result = CreateTransactionsService.go(billingPeriod, chargeElements)

expect(result).to.be.an.array()

expect(result[0].reference).to.equal(chargeElements[0].billingChargeCategory.reference)
expect(result[0].billableDays).to.equal(183)
})
})

describe('containing two chargePurposes', () => {
beforeEach(() => {
chargeElements = [
{
billingChargeCategory: { reference: '1.2.3' },
chargePurposes: [
{
abstractionPeriodStartDay: 1,
abstractionPeriodStartMonth: 4,
abstractionPeriodEndDay: 30,
abstractionPeriodEndMonth: 9
},
{
abstractionPeriodStartDay: 1,
abstractionPeriodStartMonth: 10,
abstractionPeriodEndDay: 31,
abstractionPeriodEndMonth: 3
}
]
}
]
})

it('returns a correctly calculated array of transaction lines', () => {
const result = CreateTransactionsService.go(billingPeriod, chargeElements)

expect(result).to.be.an.array()

expect(result[0].reference).to.equal(chargeElements[0].billingChargeCategory.reference)
expect(result[0].billableDays).to.equal(365)
})
})
})

describe('when there are multiple chargeElements', () => {
beforeEach(() => {
chargeElements = [
{
billingChargeCategory: { reference: '1.2.3' },
chargePurposes: [
{
abstractionPeriodStartDay: 1,
abstractionPeriodStartMonth: 4,
abstractionPeriodEndDay: 30,
abstractionPeriodEndMonth: 9
},
{
abstractionPeriodStartDay: 1,
abstractionPeriodStartMonth: 10,
abstractionPeriodEndDay: 31,
abstractionPeriodEndMonth: 3
}
]
},
{
billingChargeCategory: { reference: '4.5.6' },
chargePurposes: [
{
abstractionPeriodStartDay: 1,
abstractionPeriodStartMonth: 4,
abstractionPeriodEndDay: 28,
abstractionPeriodEndMonth: 2
}
]
}
]
})

it('returns a correctly calculated array of transaction lines', () => {
const result = CreateTransactionsService.go(billingPeriod, chargeElements)

expect(result).to.be.an.array()

expect(result[0].reference).to.equal(chargeElements[0].billingChargeCategory.reference)
expect(result[0].billableDays).to.equal(365)

expect(result[1].reference).to.equal(chargeElements[1].billingChargeCategory.reference)
expect(result[1].billableDays).to.equal(334)
})
})
})