Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
Cruikshanks committed Feb 26, 2025
1 parent e57036d commit 8956c01
Show file tree
Hide file tree
Showing 8 changed files with 120 additions and 16 deletions.
19 changes: 17 additions & 2 deletions app/controllers/root.controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,23 @@
* @module RootController
*/

function index(_request, _h) {
return { status: 'alive' }
const FetchChargeVersionsService = require('../services/bill-runs/match/fetch-charge-versions.service.js')

const StartBillRunProcessService = require('../services/bill-runs/start-bill-run-process.service.js')

async function index(_request, h) {
const regionId = '4ccf3c5b-ab4e-48e1-afa8-3b18b5d07fab'
const batchType = 'two_part_supplementary'
const userEmail = '[email protected]'
const financialYearEnding = 2024
// const billingPeriod = { startDate: new Date('2023-04-01'), endDate: new Date('2024-03-31') }
// const chargeVersions = await FetchChargeVersionsService.go(, billingPeriod, false)

await StartBillRunProcessService.go(regionId, batchType, userEmail, financialYearEnding)

return h.response().code(204)

// return { status: 'alive' }
}

module.exports = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ function _billingPeriods(billRunType, financialYear) {
const years = { startYear: financialYear.startDate.getFullYear(), endYear: financialYear.endDate.getFullYear() }

// Annual and two-part-tariff bill runs will always be a single period
if (['annual', 'two_part_tariff'].includes(billRunType)) {
if (['annual', 'two_part_tariff', 'two_part_supplementary'].includes(billRunType)) {
_addBillingPeriod(billingPeriods, years.startYear, years.endYear)

return billingPeriods
Expand Down
19 changes: 16 additions & 3 deletions app/services/bill-runs/match/fetch-charge-versions.service.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const { ref } = require('objection')

const ChargeReferenceModel = require('../../../models/charge-reference.model.js')
const ChargeVersionModel = require('../../../models/charge-version.model.js')
const LicenceSupplementaryYears = require('../../../models/licence-supplementary-year.model.js')
const Workflow = require('../../../models/workflow.model.js')

/**
Expand All @@ -31,11 +32,11 @@ const Workflow = require('../../../models/workflow.model.js')
* @returns {Promise<object>} Contains an array of two-part tariff charge versions with linked licences, charge
* references, charge elements and related purpose
*/
async function go(regionId, billingPeriod) {
return _fetch(regionId, billingPeriod)
async function go(regionId, billingPeriod, supplementary = false) {
return _fetch(regionId, billingPeriod, supplementary)
}

async function _fetch(regionId, billingPeriod) {
async function _fetch(regionId, billingPeriod, supplementary) {
const chargeVersions = await ChargeVersionModel.query()
.select(['chargeVersions.id', 'chargeVersions.startDate', 'chargeVersions.endDate', 'chargeVersions.status'])
.innerJoinRelated('licence')
Expand Down Expand Up @@ -70,6 +71,18 @@ async function _fetch(regionId, billingPeriod) {
// rather than have to remember that quirk we stick with whereJsonPath() which works in all cases.
.whereJsonPath('chargeReferences.adjustments', '$.s127', '=', true)
)
.where((builder) => {
if (supplementary) {
builder.whereExists(
LicenceSupplementaryYears.query()
.select(1)
.whereColumn('licenceSupplementaryYears.licenceId', 'chargeVersions.licenceId')
.whereColumn('licenceSupplementaryYears.financialYearEnd', billingPeriod.endDate.getFullYear())
)
} else {
builder.whereRaw('1=1')
}
})
.orderBy('chargeVersions.licenceRef', 'asc')
.withGraphFetched('changeReason')
.modifyGraph('changeReason', (builder) => {
Expand Down
4 changes: 2 additions & 2 deletions app/services/bill-runs/match/fetch-licences.service.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ const FetchChargeVersionsService = require('./fetch-charge-versions.service.js')
* @returns {Promise<object[]>} the licences to be matched, each containing an array of charge versions applicable for
* two-part tariff
*/
async function go(regionId, billingPeriod) {
const chargeVersions = await FetchChargeVersionsService.go(regionId, billingPeriod)
async function go(regionId, billingPeriod, supplementary = false) {
const chargeVersions = await FetchChargeVersionsService.go(regionId, billingPeriod, supplementary)

const uniqueLicenceIds = _extractUniqueLicenceIds(chargeVersions)

Expand Down
3 changes: 2 additions & 1 deletion app/services/bill-runs/match/match-and-allocate.service.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ const PrepareReturnLogsService = require('./prepare-return-logs.service.js')
* @returns {Promise<boolean>} - True if there are any licences matched to returns, false otherwise
*/
async function go(billRun, billingPeriod) {
const licences = await FetchLicencesService.go(billRun.regionId, billingPeriod)
const supplementary = billRun.batchType === 'two_part_supplementary'
const licences = await FetchLicencesService.go(billRun.regionId, billingPeriod, supplementary)

if (licences.length > 0) {
await _process(licences, billingPeriod, billRun)
Expand Down
11 changes: 6 additions & 5 deletions app/services/bill-runs/setup/submit-check.service.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,12 @@ async function go(sessionId, auth) {
// blocking bill run was found. This is just protection against malicious use, or more likely, someone has left the
// page idle and another user has triggered a bill run that now blocks it.
if (blockingResults.trigger !== engineTriggers.neither) {
// Temporary code to end the journey if the bill run type is two-part supplementary as processing this bill run type
// is not currently possible
if (session.type !== 'two_part_supplementary') {
await CreateService.go(session, blockingResults, auth.credentials.user)
}
// // Temporary code to end the journey if the bill run type is two-part supplementary as processing this bill run type
// // is not currently possible
// if (session.type !== 'two_part_supplementary') {
// await CreateService.go(session, blockingResults, auth.credentials.user)
// }
await CreateService.go(session, blockingResults, auth.credentials.user)

return {}
}
Expand Down
7 changes: 5 additions & 2 deletions app/services/bill-runs/start-bill-run-process.service.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ const InitiateBillRunService = require('./initiate-bill-run.service.js')
const NoBillingPeriodsError = require('../../errors/no-billing-periods.error.js')
const SupplementaryProcessBillRunService = require('./supplementary/process-bill-run.service.js')
const TwoPartTariffProcessBillRunService = require('./two-part-tariff/process-bill-run.service.js')
const TwoPartTariffSupplementaryProcessBillRunService = require('./tpt-supplementary/process-bill-run.service.js')

/**
* Manages the creation of a new bill run
Expand All @@ -19,8 +20,6 @@ const TwoPartTariffProcessBillRunService = require('./two-part-tariff/process-bi
* @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 - The financial year end that will be used for the bill run
*
* @returns {Promise<object>} Object that will be the JSON response returned to the client
*/
async function go(regionId, batchType, userEmail, financialYearEnding) {
const billingPeriods = DetermineBillingPeriodsService.go(batchType, financialYearEnding)
Expand All @@ -31,6 +30,7 @@ async function go(regionId, batchType, userEmail, financialYearEnding) {

const financialYearEndings = _financialYearEndings(billingPeriods)
const billRun = await InitiateBillRunService.go(financialYearEndings, regionId, batchType, userEmail)
console.log('🚀 ~ go ~ billRun:', billRun)

_processBillRun(billRun, billingPeriods)
}
Expand All @@ -55,6 +55,9 @@ function _processBillRun(billRun, billingPeriods) {
case 'two_part_tariff':
TwoPartTariffProcessBillRunService.go(billRun, billingPeriods)
break
case 'two_part_supplementary':
TwoPartTariffSupplementaryProcessBillRunService.go(billRun, billingPeriods)
break
}
}

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

/**
* Process a two-part tariff supplementary bill run for the given billing period
* @module ProcessBillRunService
*/

const BillRunModel = require('../../../models/bill-run.model.js')
const { calculateAndLogTimeTaken, currentTimeInNanoseconds } = require('../../../lib/general.lib.js')
const HandleErroredBillRunService = require('../handle-errored-bill-run.service.js')
const MatchAndAllocateService = require('../match/match-and-allocate.service.js')

/**
* Process a two-part tariff supplementary bill run for the given billing period
*
* Matches and allocates licences to returns for a two-part tariff bill run
*
* The results of the matching process are then persisted to the database ready for the results to be reviewed. The bill
* run status is also updated to 'review'.
*
* In the unlikely event of no licences match to returns it will set the status to 'empty'. It will also handle updating
* the bill run if an error occurs during the process.
*
* @param {module:BillRunModel} billRun - The two-part tariff supplementary bill run being processed
* @param {object[]} billingPeriods - An array of billing periods each containing a `startDate` and `endDate`. For 2PT
* this will only ever contain a single period
*/
async function go(billRun, billingPeriods) {
const { id: billRunId } = billRun
// NOTE: billingPeriods come from `DetermineBillingPeriodsService` which always returns an array because it is used by
// all billing types. For two-part tariff we know it will only contain one because 2PT supplementary bill runs are
// only for a single financial year
const billingPeriod = billingPeriods[0]

try {
const startTime = currentTimeInNanoseconds()

await _updateStatus(billRunId, 'processing')

// `populated` will be set to true if `MatchAndAllocateService` processes at least one licence
const populated = await MatchAndAllocateService.go(billRun, billingPeriod)

await _setBillRunStatus(billRunId, populated)

calculateAndLogTimeTaken(startTime, 'Process bill run complete', { billRunId, type: 'two_part_supplementary' })
} catch (error) {
await HandleErroredBillRunService.go(billRunId)
global.GlobalNotifier.omfg('Process bill run failed', { billRun }, error)
}
}

async function _setBillRunStatus(billRunId, populated) {
// It is highly unlikely no licences were matched to returns. So we default status to 'review'
let status = 'review'

// Just in case no licences were found to be matched to returns we set the status to 'empty'
if (!populated) {
status = 'empty'
}

// Update the bill run's status
await _updateStatus(billRunId, status)
}

async function _updateStatus(billRunId, status) {
await BillRunModel.query().findById(billRunId).patch({ status })
}

module.exports = {
go
}

0 comments on commit 8956c01

Please sign in to comment.