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

Create SROC two-part tariff flagging endpoint for new charge versions #1239

Merged
merged 49 commits into from
Aug 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
b401641
Create SROC two-part tariff flagging endpoint
Beckyrose200 Aug 7, 2024
5c3a9e1
Merge branch 'main' into supp-flag-end-point
Beckyrose200 Aug 7, 2024
53bbd47
WIP
Beckyrose200 Aug 9, 2024
d3e70fe
Merge branch 'main' into supp-flag-end-point
Beckyrose200 Aug 9, 2024
a1cba2c
WIP
Beckyrose200 Aug 12, 2024
6786a10
Merge branch 'main' into supp-flag-end-point
Beckyrose200 Aug 12, 2024
4044560
Flagging supplementary billing years on a charge version
Beckyrose200 Aug 12, 2024
5523ab9
Seperate the charge version flagging from the overall service
Beckyrose200 Aug 12, 2024
99a1e8a
Checking for s127 on adjustments
Beckyrose200 Aug 12, 2024
89db4ff
Charge Version Years service and unit tests
Beckyrose200 Aug 12, 2024
bb4b0ac
Flag for supplementary billing unit tests
Beckyrose200 Aug 12, 2024
680ddaa
Merge branch 'main' into supp-flag-end-point
Beckyrose200 Aug 12, 2024
c1be159
Refactor charge version service
Beckyrose200 Aug 13, 2024
aadf957
Rename functions in charge version service
Beckyrose200 Aug 13, 2024
3bf54a0
Fix charge version service
Beckyrose200 Aug 13, 2024
a444c57
Merge branch 'main' into supp-flag-end-point
Beckyrose200 Aug 13, 2024
e96ce7f
Add POST licence controller test
Beckyrose200 Aug 13, 2024
c057710
Merge branch 'main' into supp-flag-end-point
Beckyrose200 Aug 13, 2024
bdabe67
Refactor services to make them more generic
Beckyrose200 Aug 13, 2024
17c07d5
Update comment
Beckyrose200 Aug 13, 2024
c6a2046
Refactor code per suggestions
Beckyrose200 Aug 13, 2024
1a494a5
Update supplementary billing years service
Beckyrose200 Aug 13, 2024
2629802
Update private function on check supplementary billing flag
Beckyrose200 Aug 13, 2024
b666fbe
Rename private function on supplemental billing years service
Beckyrose200 Aug 13, 2024
50ba399
Remove await for supplementary flagging job
Beckyrose200 Aug 13, 2024
c1abe82
Add try catch and change supplementary billing years name to add dete…
Beckyrose200 Aug 14, 2024
2aece7a
Rename check supplementary billing flag service to process supplement…
Beckyrose200 Aug 14, 2024
e78d95c
Amend the determine supplementary years test to use Sinon clock
Beckyrose200 Aug 14, 2024
35a553f
Update unit tests
Beckyrose200 Aug 14, 2024
e4ee08e
Code refactor
Beckyrose200 Aug 14, 2024
ca5092e
Fix unit test
Beckyrose200 Aug 14, 2024
0eec3fd
WIP
Beckyrose200 Aug 14, 2024
2631a49
Merge branch 'main' into supp-flag-end-point
Beckyrose200 Aug 15, 2024
bc1deb4
WIP
Beckyrose200 Aug 15, 2024
29d95c0
Merge branch 'main' into supp-flag-end-point
Beckyrose200 Aug 15, 2024
54067ee
Licence controller and test using new function
Beckyrose200 Aug 16, 2024
69126e1
Determine charge versions years service and unit tests
Beckyrose200 Aug 16, 2024
bb092e7
Determine bill runs sent service and unit test
Beckyrose200 Aug 16, 2024
238c1fc
Determine billing years service and unit test
Beckyrose200 Aug 16, 2024
b7108b1
Process billing flag service and unit test
Beckyrose200 Aug 16, 2024
69dcdeb
Merge branch 'main' into supp-flag-end-point
Beckyrose200 Aug 16, 2024
757dd87
Updating comments and coding conventions
Beckyrose200 Aug 16, 2024
46785ad
Pass DetermineExistingBillRunService the bill run type
Beckyrose200 Aug 16, 2024
741d888
Feedback
Beckyrose200 Aug 16, 2024
373142f
Update comment
Beckyrose200 Aug 16, 2024
e58b01e
Merge branch 'main' into supp-flag-end-point
Beckyrose200 Aug 18, 2024
5e0e96f
Merge branch 'main' into supp-flag-end-point
Beckyrose200 Aug 19, 2024
42c2ab0
Merge branch 'main' into supp-flag-end-point
Beckyrose200 Aug 19, 2024
48cbcfd
Add annual bill run unit test to determine existing bill run years se…
Beckyrose200 Aug 19, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions app/controllers/licences.controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
* @module LicencesController
*/

const LicenceSupplementaryProcessBillingFlagService = require('../services/licences/supplementary/process-billing-flag.service.js')
const InitiateSessionService = require('../services/return-requirements/initiate-session.service.js')
const ViewLicenceBillsService = require('../services/licences/view-licence-bills.service.js')
const ViewLicenceCommunicationsService = require('../services/licences/view-licence-communications.service.js')
Expand Down Expand Up @@ -91,9 +92,16 @@ async function viewReturns (request, h) {
})
}

async function supplementary (request, h) {
LicenceSupplementaryProcessBillingFlagService.go(request.payload)

return h.response().code(204)
}

module.exports = {
noReturnsRequired,
returnsRequired,
supplementary,
viewBills,
viewCommunications,
viewContacts,
Expand Down
14 changes: 14 additions & 0 deletions app/routes/licence.routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,20 @@ const routes = [
}
}
}
},
{
method: 'POST',
path: '/licences/supplementary',
options: {
handler: LicencesController.supplementary,
app: {
plainOutput: true
},
auth: false,
plugins: {
crumb: false
}
}
}
]

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
'use strict'

/**
* Determines which financial year ends are between the date ranges
* @module DetermineBillingYearsService
*/

const APRIL = 3
const LAST_PRE_SROC_FINANCIAL_YEAR_END = 2022

/**
* Determines the financial years impacted by changes between the start date and end dates, considering only the
* financial year ends that are relevant for SROC supplementary billing.
*
* It determines the financial year ends for the given `startDate` and `endDate`, and returns
* an array of years that are greater than the last pre-SROC financial year end.
*
* @param {Date} startDate - The start date from which to begin calculating financial years.
* @param {Date} endDate - The end date up to which to calculate financial years. If not provided,
* the current date will be used.
*
* @returns {Object[]} - The financial year end that are impacted by the changes between the start and end dates and are
* relevant for SROC.
*/
function go (startDate, endDate) {
const years = []

const startYear = _adjustedFinancialYearEnd(startDate)
// As some changes don't have an end date we need to take this into consideration
const endYear = _adjustedFinancialYearEnd(endDate || new Date())

for (let year = startYear; year <= endYear; year++) {
// SROC supplementary billing started in the financial year 2022/2023. Anything before this year is not considered
// to be SROC
if (year > LAST_PRE_SROC_FINANCIAL_YEAR_END) {
years.push(year)
}
}

return years
}

/**
* When flagging a licence for the supplementary bill run, we need to consider which financial years have been
* impacted by the change. We only care about the financial year ends. So if the startDate for a new chargeVersion is
* `2022-05-31`, the financial year end is considered to be `2023` since the financial years run April to March. Same
* goes for if a charge versions endDate is `2023-03-05`, the financial year end is `2023`.
*/
function _adjustedFinancialYearEnd (date) {
let year = date.getFullYear()

if (date.getMonth() >= APRIL) {
year++
}

return year
}

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

/**
* Determines if a licence with a change in charge version should be flagged for supplementary billing
* @module DetermineChargeVersionYearsService
*/

const ChargeVersionModel = require('../../../models/charge-version.model.js')

/**
* Determines if a licence with a change in charge version should be flagged for supplementary billing.
*
* The service is passed the id of a new charge version and determines if it should be flagged for supplementary
* billing. This is worked out based on the charge versions scheme and if any related charge reference has a two-part
* tariff indicator. If they do, then flagForBilling is set to true.
*
* @param {String} chargeVersionId - The UUID for the charge version to fetch
*
* @returns {Object} - An object containing the related licence, charge version start and end date and if the licence
* should be flagged for two-part tariff supplementary billing
*/
async function go (chargeVersionId) {
const { chargeReferences, licence, endDate, startDate, scheme } = await _fetchChargeVersion(chargeVersionId)
const result = {
licence,
startDate,
endDate,
twoPartTariff: false,
flagForBilling: false
}

if (scheme === 'alcs') {
return result
}

result.twoPartTariff = _twoPartTariffIndicators(chargeReferences)

// When we can support non two-part tariff billing flags we can remove this line
result.flagForBilling = result.twoPartTariff

return result
}

async function _fetchChargeVersion (chargeVersionId) {
return ChargeVersionModel.query()
.findById(chargeVersionId)
.select([
'id',
'scheme',
'startDate',
'endDate'])
.withGraphFetched('chargeReferences')
.modifyGraph('chargeReferences', (builder) => {
builder.select([
'id',
'adjustments'
])
})
.withGraphFetched('licence')
.modifyGraph('licence', (builder) => {
builder.select([
'id',
'regionId'
])
})
}

function _twoPartTariffIndicators (chargeReferences) {
return chargeReferences.some((chargeReference) => {
return chargeReference.adjustments?.s127
})
}

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

/**
* Determines from the years provided which ones have an annual or two-part tariff bill run created
* @module DetermineExistingBillRunYearsService
*/

const BillRunModel = require('../../../models/bill-run.model.js')

/**
* Determines from the years provided which ones have an annual or two-part tariff bill run created
*
* This service is responsible for determining the years an annual or two part tariff bill run has been created for.
* This allows those years to be flagged on the licence for supplementary billing.
*
* The service has been passed an array of years that the change on the licence covers. It then verify whether an annual
* or two-part tariff bill run has already been sent for those years. If it has then the year is returned. We do not
* want to flag any years on the licence that hasn't had a bill run already created, as the change on the licence will
* get picked up when the annual/ two-part tariff bill run is created for that year.
*
* @param {String} regionId - The UUID of the region to search for
* @param {Object[]} years - The years that the licence can be flagged for
* @param {Boolean} twoPartTariff - If there are two-part tariff indicators on the licence
*
* @returns {Object[]} - The years that can be flagged for supplementary billing
*/
async function go (regionId, years, twoPartTariff) {
return _supplementaryBillingYears(regionId, years, twoPartTariff)
}

/**
* We need to verify which years annual two-part tariff bill runs have been sent. A year shouldn't be flagged for a
* supplementary bill run if the annual bill run hasn't been sent yet, as any licence changes will be handled in the
* annual run.
*/
async function _supplementaryBillingYears (regionId, years, twoPartTariff) {
const batchType = twoPartTariff ? 'two_part_tariff' : 'annual'

const billRuns = await BillRunModel.query()
.distinct('toFinancialYearEnding')
.where('regionId', regionId)
.where('batchType', batchType)
.whereIn('toFinancialYearEnding', years)

return billRuns.map((billRun) => {
return billRun.toFinancialYearEnding
})
}

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

/**
* Orchestrates flagging a licence for supplementary billing
* @module ProcessBillingFlagService
*/

const CreateLicenceSupplementaryYearService = require('./create-licence-supplementary-year.service.js')
const DetermineBillingYearsService = require('./determine-billing-years.service.js')
const DetermineExistingBillRunYearsService = require('./determine-existing-bill-run-years.service.js')
const DetermineChargeVersionYearsService = require('./determine-charge-version-years.service.js')
const { calculateAndLogTimeTaken, currentTimeInNanoseconds } = require('../../../lib/general.lib.js')

/**
* Orchestrates flagging a licence for supplementary billing
*
* This service orchestrates the process of flagging a licence for supplementary billing.
* It retrieves details of the charge version, including the licence information, start and end dates, whether the
* charge version has two-part tariff indicators, and if it should be flagged for supplementary billing.
*
* If the licence qualifies for flagging, the relevant dates are passed to the `DetermineBillingYearsService`, which
* calculates the years affected by the changes to the licence.
*
* If any SROC years are affected, they are passed to the `DetermineExistingBillRunYearsService`. This service checks
* the affected years to see if they have had an annual or two-part tariff bill runs created. We avoid flagging any
* years that haven't had an annual or two-part tariff bill run, as those changes will be captured when the bill run is
* created.
*
* Finally, we call the `CreateLicenceSupplementaryYearService`, which persists our final list of years along with the
* licence ID and whether two-part tariff is true.
*
* @param {Object} payload - The payload from the request
*/
async function go (payload) {
try {
const startTime = currentTimeInNanoseconds()

let result

if (payload.chargeVersionId) {
result = await DetermineChargeVersionYearsService.go(payload.chargeVersionId)
} else {
return
}

const { licence, startDate, endDate, twoPartTariff, flagForBilling } = result

if (!flagForBilling) {
return
}

const years = DetermineBillingYearsService.go(startDate, endDate)

if (!years) {
return
}

const financialYearEnds = await DetermineExistingBillRunYearsService.go(licence.regionId, years, twoPartTariff)

if (financialYearEnds.length === 0) {
return
}

await CreateLicenceSupplementaryYearService.go(licence.id, financialYearEnds, twoPartTariff)

calculateAndLogTimeTaken(startTime, 'Supplementary Billing Flag complete', { licenceId: licence.id })
} catch (error) {
global.GlobalNotifier.omfg('Supplementary Billing Flag failed', payload, error)
}
}

module.exports = {
go
}
19 changes: 19 additions & 0 deletions test/controllers/licences.controller.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ const Boom = require('@hapi/boom')

// Things we need to stub
const InitiateSessionService = require('../../app/services/return-requirements/initiate-session.service.js')
const LicenceSupplementaryProcessBillingFlagService = require('../../app/services/licences/supplementary/process-billing-flag.service.js')
const ViewLicenceBillsService = require('../../app/services/licences/view-licence-bills.service.js')
const ViewLicenceCommunicationsService = require('../../app/services/licences/view-licence-communications.service.js')
const ViewLicenceContactDetailsService = require('../../app/services/licences/view-licence-contact-details.service.js')
Expand Down Expand Up @@ -437,6 +438,24 @@ describe('Licences controller', () => {
})
})
})

describe('POST /licences/supplementary', () => {
beforeEach(() => {
options = { method: 'POST', url: '/licences/supplementary' }
})

describe('when the request succeeds', () => {
beforeEach(async () => {
Sinon.stub(LicenceSupplementaryProcessBillingFlagService, 'go').resolves()
})

it('returns a 204 response', async () => {
const response = await server.inject(options)

expect(response.statusCode).to.equal(204)
})
})
})
})

function _viewLicenceBills () {
Expand Down
Loading
Loading