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 new SROC Billing Period service #30

Merged
merged 11 commits into from
Nov 23, 2022
4 changes: 2 additions & 2 deletions app/controllers/test/supplementary.controller.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
'use strict'

const FindRegionService = require('../../services/test/find_region.service')
const SupplementaryService = require('../../services/test/supplementary.service.js')
const FindRegionService = require('../../services/supplementary_billing/find_region.service')
const SupplementaryService = require('../../services/supplementary_billing/supplementary.service.js')

class SupplementaryController {
static async index (request, h) {
Expand Down
58 changes: 58 additions & 0 deletions app/services/supplementary_billing/billing_period.service.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
'use strict'

/**
* @module BillingPeriodService
*/

class BillingPeriodService {
/**
* Returns the billing periods needed when generating a supplementary bill run
*
* **IMPORANT!** This service currently only handles SROC billing periods and only the 'current year'
*
* Using the current date at the time the service is called, it calculates the billing periods to use. We permit
* changes to charge versions to be retroactively applied up to 5 years. So, a bill run generated in 2022 would need
* to consider every financial year back to 2017.
*
* The exception to that is the change in charge scheme that happened in 2022, when we moved from ALCS (or PRESROC) to
* SROC. Changes prior to 2022 would only apply to a ALCS bill run and vice versa.
*
* @returns {Object[]} an array of billing periods each containing a `startDate` and `endDate`.
*/
static go () {
const currentDate = this._currentDate()
const currentYear = currentDate.getFullYear()

// 01-APR to 31-MAR
const financialPeriod = {
start: { day: 1, month: 3 },
end: { day: 31, month: 2 }
}

let startYear
let endYear

// IMPORANT! getMonth returns an integer (0-11). So, January is represented as 0 and December as 11. This is why
// financialPeriod.end.month is 2 rather than 3, even though we mean March
if (currentDate.getMonth() <= financialPeriod.end.month) {
// For example, if currentDate was 2022-02-15 it would fall in financial year 2021-04-01 to 2022-03-31
startYear = currentYear - 1
endYear = currentYear
} else {
// For example, if currentDate was 2022-06-15 it would fall in financial year 2022-04-01 to 2023-03-31
startYear = currentYear
endYear = currentYear + 1
}

return [{
startDate: new Date(startYear, financialPeriod.start.month, financialPeriod.start.day),
endDate: new Date(endYear, financialPeriod.end.month, financialPeriod.end.day)
}]
}

static _currentDate () {
return new Date()
}
}

module.exports = BillingPeriodService
Original file line number Diff line number Diff line change
@@ -1,24 +1,20 @@
'use strict'

/**
* @module SupplementaryService
* @module FetchChargeVersionsService
*
*/

const { db } = require('../../../db/db')

/**
* @module SupplementaryService
*/

class SupplementaryService {
class FetchChargeVersionsService {
static async go (regionId) {
const chargeVersions = await this._fetchChargeVersions(regionId)
const response = { chargeVersions }
const chargeVersions = await this._fetch(regionId)

return response
return chargeVersions
}

static async _fetchChargeVersions (regionId) {
static async _fetch (regionId) {
const chargeVersions = db
.select('chargeVersionId', 'licences.licenceRef')
.from('water.charge_versions')
Expand All @@ -36,4 +32,4 @@ class SupplementaryService {
}
}

module.exports = SupplementaryService
module.exports = FetchChargeVersionsService
20 changes: 20 additions & 0 deletions app/services/supplementary_billing/supplementary.service.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
'use strict'

/**
* @module SupplementaryService
*/

const FetchChargeVersionsService = require('./fetch_charge_versions.service.js')
const BillingPeriodService = require('./billing_period.service')

class SupplementaryService {
static async go (regionId) {
const chargeVersions = await FetchChargeVersionsService.go(regionId)
const financialYears = BillingPeriodService.go()
const response = { chargeVersions, financialYears }

return response
}
}

module.exports = SupplementaryService
4 changes: 2 additions & 2 deletions test/controllers/test/supplementary.controller.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ const { expect } = Code
const LicenceHelper = require('../../support/helpers/licence.helper.js')

// Things we need to stub
const FindRegionService = require('../../../app/services/test/find_region.service')
const SupplementaryService = require('../../../app/services/test/supplementary.service.js')
const FindRegionService = require('../../../app/services/supplementary_billing/find_region.service')
const SupplementaryService = require('../../../app/services/supplementary_billing/supplementary.service.js')

// For running our service
const { init } = require('../../../app/server')
Expand Down
83 changes: 83 additions & 0 deletions test/services/supplementary_billing/billing_period.service.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
'use strict'

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

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

// Thing under test
const BillingPeriodService = require('../../../app/services/supplementary_billing/billing_period.service')

describe('BillingPeriod service', () => {
afterEach(() => {
Sinon.restore()
})

describe('when the date is in 2022 and falls within the 2022 financial year', () => {
const testDate = new Date('2022-04-01')
const expectedResult = {
startDate: new Date('2022-04-01'),
endDate: new Date('2023-03-31')
}

beforeEach(async () => {
Sinon.stub(BillingPeriodService, '_currentDate').returns(testDate)
})

it('returns the expected date range', () => {
const result = BillingPeriodService.go()

expect(result.length).to.equal(1)
expect(result[0]).to.equal(expectedResult)
})
})

describe('when the date is in 2023 and falls within the 2022 financial year', () => {
const testDate = new Date('2023-03-01')
const expectedResult = {
startDate: new Date('2022-04-01'),
endDate: new Date('2023-03-31')
}

beforeEach(async () => {
Sinon.stub(BillingPeriodService, '_currentDate').returns(testDate)
})

it('returns the expected date range', () => {
const result = BillingPeriodService.go()

expect(result.length).to.equal(1)
expect(result[0]).to.equal(expectedResult)
})
})

describe('when the date is in 2023 and falls within the 2023 financial year', () => {
const testDate = new Date('2023-10-10')
const expectedResult = {
startDate: new Date('2023-04-01'),
endDate: new Date('2024-03-31')
}

beforeEach(async () => {
Sinon.stub(BillingPeriodService, '_currentDate').returns(testDate)
})

it('returns the expected date range', () => {
const result = BillingPeriodService.go()

expect(result.length).to.equal(1)
expect(result[0]).to.equal(expectedResult)
})
})

describe('when the _currentDate function is not stubbed', () => {
it('returns a date range', () => {
const result = BillingPeriodService.go()

expect(result.length).to.equal(1)
})
})
})
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ const DatabaseHelper = require('../../support/helpers/database.helper.js')
const LicenceHelper = require('../../support/helpers/licence.helper.js')

// Thing under test
const SupplementaryService = require('../../../app/services/test/supplementary.service.js')
const FetchChargeVersionsService = require('../../../app/services/supplementary_billing/fetch_charge_versions.service.js')

describe('Supplementary service', () => {
describe('FetchChargeVersions service', () => {
const { region_id: regionId } = LicenceHelper.defaults()
let testRecords

Expand All @@ -41,10 +41,10 @@ describe('Supplementary service', () => {
})

it('returns only the current SROC charge versions that are applicable', async () => {
const result = await SupplementaryService.go(regionId)
const result = await FetchChargeVersionsService.go(regionId)

expect(result.chargeVersions.length).to.equal(1)
expect(result.chargeVersions[0].charge_version_id).to.equal(testRecords[0].charge_version_id)
expect(result.length).to.equal(1)
expect(result[0].charge_version_id).to.equal(testRecords[0].charge_version_id)
})
})

Expand All @@ -58,9 +58,9 @@ describe('Supplementary service', () => {
})

it('returns no applicable charge versions', async () => {
const result = await SupplementaryService.go(regionId)
const result = await FetchChargeVersionsService.go(regionId)

expect(result.chargeVersions.length).to.equal(0)
expect(result.length).to.equal(0)
})
})

Expand All @@ -75,9 +75,9 @@ describe('Supplementary service', () => {
})

it('returns no applicable charge versions', async () => {
const result = await SupplementaryService.go(regionId)
const result = await FetchChargeVersionsService.go(regionId)

expect(result.chargeVersions.length).to.equal(0)
expect(result.length).to.equal(0)
})
})

Expand All @@ -92,9 +92,9 @@ describe('Supplementary service', () => {
})

it('returns no applicable charge versions', async () => {
const result = await SupplementaryService.go(regionId)
const result = await FetchChargeVersionsService.go(regionId)

expect(result.chargeVersions.length).to.equal(0)
expect(result.length).to.equal(0)
})
})

Expand All @@ -112,9 +112,9 @@ describe('Supplementary service', () => {
})

it('returns no applicable charge versions', async () => {
const result = await SupplementaryService.go(regionId)
const result = await FetchChargeVersionsService.go(regionId)

expect(result.chargeVersions.length).to.equal(0)
expect(result.length).to.equal(0)
})
})
})
Expand Down
48 changes: 48 additions & 0 deletions test/services/supplementary_billing/supplementary.service.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
'use strict'

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

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

// Things we need to stub
const FetchChargeVersionsService = require('../../../app/services/supplementary_billing/fetch_charge_versions.service.js')

// Thing under test
const SupplementaryService = require('../../../app/services/supplementary_billing/supplementary.service.js')

describe('Supplementary service', () => {
afterEach(() => {
Sinon.restore()
})

describe('when there are licences to be included in supplementary billing', () => {
const testRecords = [{ charge_version_id: '878bc903-836d-4549-83f5-4e20ccf87d2f' }]

beforeEach(async () => {
Sinon.stub(FetchChargeVersionsService, 'go').resolves(testRecords)
})

it('returns only the current SROC charge versions that are applicable', async () => {
const result = await SupplementaryService.go('regionId')

expect(result.chargeVersions.length).to.equal(1)
expect(result.chargeVersions[0].charge_version_id).to.equal(testRecords[0].charge_version_id)
})
})

describe('when there are no licences to be included in supplementary billing', () => {
beforeEach(async () => {
Sinon.stub(FetchChargeVersionsService, 'go').resolves([])
})

it('returns no charge versions', async () => {
const result = await SupplementaryService.go('regionId')

expect(result.chargeVersions).to.be.empty()
})
})
})