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

Handle create 2PT bill run requests #503

Merged
merged 15 commits into from
Nov 8, 2023
Merged
4 changes: 2 additions & 2 deletions app/controllers/bill-runs.controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ async function create (request, h) {
}

try {
const { region, type, user } = validatedData.value
const result = await StartBillRunProcessService.go(region, type, user)
const { region, type, user, financialYearEnding } = validatedData.value
const result = await StartBillRunProcessService.go(region, type, user, financialYearEnding)

return h.response(result).code(200)
} catch (error) {
Expand Down
27 changes: 22 additions & 5 deletions app/services/billing/determine-billing-periods.service.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,13 @@
* periods for the current year plus a maximum of the previous 5 years. Or to the earliest possible `endYear` for SROC
* which is 2023, whichever is the greatest.
*
* If a `financialYearEnding` is passed to this service a single billing period will be generated based on that value.
*
* @param {Number} financialYearEnding End year of the bill run. Only populated for two-part-tariff
*
* @returns {Object[]} An array of billing periods each containing a `startDate` and `endDate`.
*/
function go () {
function go (financialYearEnding) {
const SROC_FIRST_FIN_YEAR_END = 2023
const NO_OF_YEARS_TO_LOOK_BACK = 5

Expand All @@ -27,21 +31,34 @@ function go () {
end: { day: 31, month: 2 }
}

// Two-part-tariff bill runs will always be a single period and will provide a value for `financialYearEnding` so we
// just return a single period based on that value. `financialYearEnding` is null for other bill run types.
if (financialYearEnding) {
_addBillingPeriod(billingPeriods, financialPeriod, financialYearEnding - 1, financialYearEnding)

return billingPeriods
}

const years = _determineStartAndEndYear(financialPeriod)
const earliestSrocFinYearEnd = Math.max(SROC_FIRST_FIN_YEAR_END, (years.endYear - NO_OF_YEARS_TO_LOOK_BACK))

while (earliestSrocFinYearEnd <= years.endYear) {
billingPeriods.push({
startDate: new Date(years.startYear, financialPeriod.start.month, financialPeriod.start.day),
endDate: new Date(years.endYear, financialPeriod.end.month, financialPeriod.end.day)
})
_addBillingPeriod(billingPeriods, financialPeriod, years.startYear, years.endYear)

years.startYear--
years.endYear--
}

return billingPeriods
}

function _addBillingPeriod (billingPeriods, financialPeriod, startYear, endYear) {
billingPeriods.push({
startDate: new Date(startYear, financialPeriod.start.month, financialPeriod.start.day),
endDate: new Date(endYear, financialPeriod.end.month, financialPeriod.end.day)
})
}

function _determineStartAndEndYear (financialPeriod) {
const currentDate = new Date()
const currentYear = currentDate.getFullYear()
Expand Down
5 changes: 3 additions & 2 deletions app/services/billing/start-bill-run-process.service.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,12 @@ const TwoPartTariffProcessBillRunService = require('./two-part-tariff/process-bi
* @param {String} regionId Id of the region the bill run is for
* @param {String} batchType Type of bill run, for example, supplementary
* @param {String} userEmail Email address of the user who initiated the bill run
* @param {Number} financialYearEnding End year of the bill run. Only populated for two-part-tariff
*
* @returns {Object} Object that will be the JSON response returned to the client
*/
async function go (regionId, batchType, userEmail) {
const billingPeriods = DetermineBillingPeriodsService.go()
async function go (regionId, batchType, userEmail, financialYearEnding) {
const billingPeriods = DetermineBillingPeriodsService.go(financialYearEnding)
const financialYearEndings = _financialYearEndings(billingPeriods)

const billRun = await InitiateBillRunService.go(financialYearEndings, regionId, batchType, userEmail)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
/**
* Functionality not yet implemented
*/
async function go (_billRun, _billingPeriods) {
throw new Error('Two Part Tariff is not yet implemented')
async function go (_billRun, billingPeriods) {
throw new Error(`Two Part Tariff is not yet implemented for Financial Year Ending: ${billingPeriods[0].endDate.getFullYear()}`)
}

module.exports = {
Expand Down
1 change: 1 addition & 0 deletions app/validators/create-bill-run.validator.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ function go (data) {
scheme: Joi.string().valid('sroc').required(),
region: Joi.string().guid().required(),
user: Joi.string().email().required(),
financialYearEnding: Joi.number().integer().optional(),
previousBillRunId: Joi.string().guid().optional()
})

Expand Down
28 changes: 24 additions & 4 deletions test/services/billing/determine-billing-periods.service.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ describe('Billing Periods service', () => {
})

describe('when the date is in 2022 and falls within the 2022 financial year', () => {
beforeEach(async () => {
beforeEach(() => {
testDate = new Date('2022-04-01')
expectedResult = {
startDate: new Date('2022-04-01'),
Expand All @@ -41,7 +41,7 @@ describe('Billing Periods service', () => {
})

describe('when the date is in 2023 and falls within the 2022 financial year', () => {
beforeEach(async () => {
beforeEach(() => {
testDate = new Date('2023-03-01')
expectedResult = {
startDate: new Date('2022-04-01'),
Expand All @@ -60,7 +60,7 @@ describe('Billing Periods service', () => {
})

describe('when the date is in 2023 and falls within the 2023 financial year', () => {
beforeEach(async () => {
beforeEach(() => {
testDate = new Date('2023-10-10')
expectedResult = [
{
Expand All @@ -82,10 +82,30 @@ describe('Billing Periods service', () => {
expect(result).to.have.length(2)
expect(result).to.equal(expectedResult)
})

describe('when the `financialYearEnding` of 2023 is passed to the service', () => {
const financialYearEnding = 2023

beforeEach(() => {
expectedResult = [
{
startDate: new Date('2022-04-01'),
endDate: new Date('2023-03-31')
}
]
})

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

expect(result).to.have.length(1)
expect(result).to.equal(expectedResult)
})
})
})

describe('when the date is in 2030 and falls within the 2030 financial year', () => {
beforeEach(async () => {
beforeEach(() => {
testDate = new Date('2030-10-10')
expectedResult = [
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,13 @@ const TwoPartTariffProcessBillRunService = require('../../../../app/services/bil

describe('Two Part Tariff Process Bill Run service', () => {
describe('when the service is called', () => {
const billingPeriods = [{ endDate: new Date('2023-03-31') }]

it('throws an error', async () => {
const error = await expect(TwoPartTariffProcessBillRunService.go()).to.reject()
const error = await expect(TwoPartTariffProcessBillRunService.go('billRun', billingPeriods)).to.reject()

expect(error).to.be.an.instanceOf(Error)
expect(error.message).to.equal('Two Part Tariff is not yet implemented')
expect(error.message).to.equal('Two Part Tariff is not yet implemented for Financial Year Ending: 2023')
})
})
})
46 changes: 44 additions & 2 deletions test/validators/create-bill-run.validator.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ describe('Create Bill Run validator', () => {
scheme: 'sroc',
region: '07ae7f3a-2677-4102-b352-cc006828948c',
user: '[email protected]',
financialYearEnding: 2023,
previousBillRunId: '28a5fc2e-bdc9-4b48-96e7-5ee7b2f5d603'
}

Expand All @@ -28,17 +29,41 @@ describe('Create Bill Run validator', () => {
scheme: 'sroc',
region: '07ae7f3a-2677-4102-b352-cc006828948c',
user: '[email protected]',
financialYearEnding: 2023,
previousBillRunId: '28a5fc2e-bdc9-4b48-96e7-5ee7b2f5d603'
})
})

describe('which does not include `financialYearEnding`', () => {
it('returns validated data', async () => {
const validData = {
type: 'supplementary',
scheme: 'sroc',
region: '07ae7f3a-2677-4102-b352-cc006828948c',
user: '[email protected]',
previousBillRunId: '28a5fc2e-bdc9-4b48-96e7-5ee7b2f5d603'
}

const result = await CreateBillRunValidator.go(validData)

expect(result.value).to.equal({
type: 'supplementary',
scheme: 'sroc',
region: '07ae7f3a-2677-4102-b352-cc006828948c',
user: '[email protected]',
previousBillRunId: '28a5fc2e-bdc9-4b48-96e7-5ee7b2f5d603'
})
})
})

describe('which does not include `previousBillRunId`', () => {
it('returns validated data', async () => {
const validData = {
type: 'supplementary',
scheme: 'sroc',
region: '07ae7f3a-2677-4102-b352-cc006828948c',
user: '[email protected]'
user: '[email protected]',
financialYearEnding: 2023
}

const result = await CreateBillRunValidator.go(validData)
Expand All @@ -47,7 +72,8 @@ describe('Create Bill Run validator', () => {
type: 'supplementary',
scheme: 'sroc',
region: '07ae7f3a-2677-4102-b352-cc006828948c',
user: '[email protected]'
user: '[email protected]',
financialYearEnding: 2023
})
})
})
Expand Down Expand Up @@ -169,5 +195,21 @@ describe('Create Bill Run validator', () => {
expect(result.error).to.not.be.empty()
})
})

describe('because `financialYearEnding` has an invalid value', () => {
it('returns an error', async () => {
const invalidData = {
type: 'supplementary',
scheme: 'sroc',
region: '07ae7f3a-2677-4102-b352-cc006828948c',
user: '[email protected]',
financialYearEnding: 'INVALID'
}

const result = await CreateBillRunValidator.go(invalidData)

expect(result.error).to.not.be.empty()
})
})
})
})
Loading