Skip to content

Commit 14eb891

Browse files
authored
Move supplementary unflagging services (#1769)
https://eaflood.atlassian.net/browse/WATER-4201 > Part of the work to support two-part tariff supplementary bill runs In [Move reusable supplementary billing services](#1760) we shifted some existing supplementary billing services to make them reusable by the two-part tariff supplementary billing engine we're building. Then we spotted [some two-part tariff billing services we could remove and reuse](#1765). The final step of supporting two-part tariff supplementary, like standard supplementary, is the flagging. When changes are made to licences, they are flagged for supplementary billing, and it is these 'flags' that drive whether a licence is considered part of a supplementary bill run. Just as complex as setting the flags is unsetting them. Various actions, either driven by the users or from logic in the engines, trigger licences becoming unflagged. Two scenarios a two-part tariff supplementary shares with a standard supplementary, are - when a licence after processing is found _not_ to have generated a bill - when the bill has been sent and the licence can be considered as having been 'processed' for supplementary billing We already have services that handle these scenarios, which are called at the appropriate times. So, before adding the two-part tariff supplementary flagging logic, we prepare the existing services for reuse.
1 parent d7fc63d commit 14eb891

9 files changed

+73
-58
lines changed

app/services/bill-runs/send/update-invoice-numbers.service.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ const ExpandedError = require('../../../errors/expanded.error.js')
1111
const { calculateAndLogTimeTaken, timestampForPostgres } = require('../../../lib/general.lib.js')
1212
const ChargingModuleSendBillRunRequest = require('../../../requests/charging-module/send-bill-run.request.js')
1313
const ChargingModuleViewBillRunRequest = require('../../../requests/charging-module/view-bill-run.request.js')
14-
const UnflagBilledLicencesService = require('../supplementary/unflag-billed-licences.service.js')
14+
const UnflagBilledSupplementaryLicencesService = require('../unflag-billed-supplementary-licences.service.js')
1515

1616
/**
1717
* Updates a bill run and its bill records with the invoice numbers generated by the Charging Module API
@@ -41,7 +41,7 @@ async function go(billRun) {
4141
await _updateBillRun(billRunId, externalBillRun)
4242

4343
if (billRun.batchType === 'supplementary') {
44-
await UnflagBilledLicencesService.go(billRun)
44+
await UnflagBilledSupplementaryLicencesService.go(billRun)
4545
}
4646

4747
calculateAndLogTimeTaken(startTime, 'Send bill run complete', { billRun })

app/services/bill-runs/supplementary/process-bill-run.service.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ const { calculateAndLogTimeTaken, currentTimeInNanoseconds } = require('../../..
1313
const HandleErroredBillRunService = require('../handle-errored-bill-run.service.js')
1414
const LegacyRefreshBillRunRequest = require('../../../requests/legacy/refresh-bill-run.request.js')
1515
const ProcessBillingPeriodService = require('./process-billing-period.service.js')
16-
const UnflagUnbilledLicencesService = require('./unflag-unbilled-licences.service.js')
16+
const UnflagUnbilledSupplementaryLicencesService = require('../unflag-unbilled-supplementary-licences.service.js')
1717

1818
/**
1919
* Process a given bill run for the given billing periods. In this case, "process" means that we create the
@@ -81,7 +81,7 @@ async function _finaliseBillRun(billRun, accumulatedLicenceIds, resultsOfProcess
8181
// .findByIds() so we spread it into an array
8282
const allLicenceIds = [...new Set(accumulatedLicenceIds)]
8383

84-
await UnflagUnbilledLicencesService.go(billRun, allLicenceIds)
84+
await UnflagUnbilledSupplementaryLicencesService.go(billRun, allLicenceIds)
8585

8686
// We set `isPopulated` to `true` if at least one processing result was truthy
8787
const isPopulated = resultsOfProcessing.some((result) => {

app/services/bill-runs/supplementary/unflag-billed-licences.service.js renamed to app/services/bill-runs/unflag-billed-supplementary-licences.service.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@
22

33
/**
44
* Unflag all licences in a bill run that resulted in a billing invoice (they are billed)
5-
* @module UnflagBilledLicencesService
5+
* @module UnflagBilledSupplementaryLicencesService
66
*/
77

8-
const LicenceModel = require('../../../models/licence.model.js')
8+
const LicenceModel = require('../../models/licence.model.js')
99

1010
/**
1111
* Unflag any licences that were billed as part of a bill run

app/services/bill-runs/supplementary/unflag-unbilled-licences.service.js renamed to app/services/bill-runs/unflag-unbilled-supplementary-licences.service.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
* @module UnflagUnbilledLicencesService
66
*/
77

8-
const LicenceModel = require('../../../models/licence.model.js')
8+
const LicenceModel = require('../../models/licence.model.js')
99

1010
/**
1111
* Unflag any licences that were not billed as part of a bill run

test/services/bill-runs/send/update-invoice-numbers.service.test.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,12 @@ const ExpandedError = require('../../../../app/errors/expanded.error.js')
1515
// Things we need to stub
1616
const ChargingModuleSendBillRunRequest = require('../../../../app/requests/charging-module/send-bill-run.request.js')
1717
const ChargingModuleViewBillRunRequest = require('../../../../app/requests/charging-module/view-bill-run.request.js')
18-
const UnflagBilledLicencesService = require('../../../../app/services/bill-runs/supplementary/unflag-billed-licences.service.js')
18+
const UnflagBilledSupplementaryLicencesService = require('../../../../app/services/bill-runs/unflag-billed-supplementary-licences.service.js')
1919

2020
// Thing under test
2121
const UpdateInvoiceNumbersService = require('../../../../app/services/bill-runs/send/update-invoice-numbers.service.js')
2222

23-
describe('Bill Runs - Update Invoice Numbers service', () => {
23+
describe('Bill Runs - Send- Update Invoice Numbers service', () => {
2424
let billRun
2525
let chargingModuleSendBillRunRequestStub
2626
let chargingModuleViewBillRunRequestStub
@@ -33,7 +33,7 @@ describe('Bill Runs - Update Invoice Numbers service', () => {
3333
beforeEach(async () => {
3434
chargingModuleSendBillRunRequestStub = Sinon.stub(ChargingModuleSendBillRunRequest, 'send')
3535
chargingModuleViewBillRunRequestStub = Sinon.stub(ChargingModuleViewBillRunRequest, 'send')
36-
unflagBilledLicencesServiceStub = Sinon.stub(UnflagBilledLicencesService, 'go').resolves()
36+
unflagBilledLicencesServiceStub = Sinon.stub(UnflagBilledSupplementaryLicencesService, 'go').resolves()
3737

3838
billPatchStub = Sinon.stub().resolves()
3939
billRunPatchStub = Sinon.stub().resolves()

test/services/bill-runs/supplementary/process-bill-run.service.test.js

Lines changed: 43 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -10,35 +10,40 @@ const { expect } = Code
1010

1111
// Test helpers
1212
const BillRunError = require('../../../../app/errors/bill-run.error.js')
13-
const BillRunHelper = require('../../../support/helpers/bill-run.helper.js')
14-
const BillRunModel = require('../../../../app/models/bill-run.model.js')
1513

1614
// Things we need to stub
15+
const BillRunModel = require('../../../../app/models/bill-run.model.js')
1716
const ChargingModuleGenerateBillRunRequest = require('../../../../app/requests/charging-module/generate-bill-run.request.js')
1817
const FeatureFlagsConfig = require('../../../../config/feature-flags.config.js')
1918
const FetchChargeVersionsService = require('../../../../app/services/bill-runs/supplementary/fetch-charge-versions.service.js')
2019
const HandleErroredBillRunService = require('../../../../app/services/bill-runs/handle-errored-bill-run.service.js')
2120
const LegacyRefreshBillRunRequest = require('../../../../app/requests/legacy/refresh-bill-run.request.js')
2221
const ProcessBillingPeriodService = require('../../../../app/services/bill-runs/supplementary/process-billing-period.service.js')
23-
const UnflagUnbilledLicencesService = require('../../../../app/services/bill-runs/supplementary/unflag-unbilled-licences.service.js')
22+
const UnflagUnbilledSupplementaryLicencesService = require('../../../../app/services/bill-runs/unflag-unbilled-supplementary-licences.service.js')
2423

2524
// Thing under test
26-
const SupplementaryProcessBillRunService = require('../../../../app/services/bill-runs/supplementary/process-bill-run.service.js')
25+
const ProcessBillRunService = require('../../../../app/services/bill-runs/supplementary/process-bill-run.service.js')
2726

28-
describe('Supplementary Process Bill Run service', () => {
27+
describe('Bill Runs - Supplementary - Process Bill Run service', () => {
2928
const billingPeriods = [
3029
{ startDate: new Date('2023-04-01'), endDate: new Date('2024-03-31') },
3130
{ startDate: new Date('2022-04-01'), endDate: new Date('2023-03-31') }
3231
]
32+
const billRun = { id: '410c84a5-39d3-441a-97ca-6104e14d00a2' }
3333

34-
let billRun
34+
let billRunPatchStub
3535
let chargingModuleGenerateBillRunRequestStub
3636
let handleErroredBillRunStub
3737
let legacyRefreshBillRunRequestStub
3838
let notifierStub
3939

4040
beforeEach(async () => {
41-
billRun = await BillRunHelper.add()
41+
billRunPatchStub = Sinon.stub().resolves()
42+
43+
Sinon.stub(BillRunModel, 'query').returns({
44+
findById: Sinon.stub().returnsThis(),
45+
patch: billRunPatchStub
46+
})
4247

4348
handleErroredBillRunStub = Sinon.stub(HandleErroredBillRunService, 'go')
4449
chargingModuleGenerateBillRunRequestStub = Sinon.stub(ChargingModuleGenerateBillRunRequest, 'send')
@@ -62,20 +67,31 @@ describe('Supplementary Process Bill Run service', () => {
6267
describe('when the service is called', () => {
6368
beforeEach(() => {
6469
Sinon.stub(FetchChargeVersionsService, 'go').resolves({ chargeVersions: [], licenceIdsForPeriod: [] })
65-
Sinon.stub(UnflagUnbilledLicencesService, 'go')
70+
Sinon.stub(UnflagUnbilledSupplementaryLicencesService, 'go')
6671
})
6772

6873
describe('and nothing is billed', () => {
6974
beforeEach(() => {
7075
Sinon.stub(ProcessBillingPeriodService, 'go').resolves(false)
7176
})
7277

73-
it('sets the Bill Run status to empty', async () => {
74-
await SupplementaryProcessBillRunService.go(billRun, billingPeriods)
78+
it('sets the bill run status first to "processing" and then to "empty"', async () => {
79+
await ProcessBillRunService.go(billRun, billingPeriods)
80+
81+
expect(billRunPatchStub.calledTwice).to.be.true()
82+
expect(billRunPatchStub.firstCall.firstArg).to.equal({ status: 'processing' })
83+
expect(billRunPatchStub.secondCall.firstArg).to.equal({ status: 'empty' })
84+
})
85+
86+
it('logs the time taken', async () => {
87+
await ProcessBillRunService.go(billRun, billingPeriods)
7588

76-
const result = await BillRunModel.query().findById(billRun.id)
89+
const args = notifierStub.omg.firstCall.args
7790

78-
expect(result.status).to.equal('empty')
91+
expect(args[0]).to.equal('Process bill run complete')
92+
expect(args[1].timeTakenMs).to.exist()
93+
expect(args[1].billRunId).to.equal(billRun.id)
94+
expect(args[1].type).to.equal('supplementary')
7995
})
8096
})
8197

@@ -84,28 +100,27 @@ describe('Supplementary Process Bill Run service', () => {
84100
Sinon.stub(ProcessBillingPeriodService, 'go').resolves(true)
85101
})
86102

87-
it('sets the Bill Run status to processing', async () => {
88-
await SupplementaryProcessBillRunService.go(billRun, billingPeriods)
89-
90-
const result = await BillRunModel.query().findById(billRun.id)
103+
it('sets the bill run status to "processing"', async () => {
104+
await ProcessBillRunService.go(billRun, billingPeriods)
91105

92-
expect(result.status).to.equal('processing')
106+
expect(billRunPatchStub.calledOnce).to.be.true()
107+
expect(billRunPatchStub.firstCall.firstArg).to.equal({ status: 'processing' }, { skip: ['updatedAt'] })
93108
})
94109

95110
it('tells the charging module API to "generate" the bill run', async () => {
96-
await SupplementaryProcessBillRunService.go(billRun, billingPeriods)
111+
await ProcessBillRunService.go(billRun, billingPeriods)
97112

98113
expect(chargingModuleGenerateBillRunRequestStub.called).to.be.true()
99114
})
100115

101116
it('tells the legacy service to start its refresh job', async () => {
102-
await SupplementaryProcessBillRunService.go(billRun, billingPeriods)
117+
await ProcessBillRunService.go(billRun, billingPeriods)
103118

104119
expect(legacyRefreshBillRunRequestStub.called).to.be.true()
105120
})
106121

107-
it('it logs the time taken', async () => {
108-
await SupplementaryProcessBillRunService.go(billRun, billingPeriods)
122+
it('logs the time taken', async () => {
123+
await ProcessBillRunService.go(billRun, billingPeriods)
109124

110125
const args = notifierStub.omg.firstCall.args
111126

@@ -127,15 +142,15 @@ describe('Supplementary Process Bill Run service', () => {
127142
})
128143

129144
it('calls HandleErroredBillRunService with appropriate error code', async () => {
130-
await SupplementaryProcessBillRunService.go(billRun, billingPeriods)
145+
await ProcessBillRunService.go(billRun, billingPeriods)
131146

132147
const handlerArgs = handleErroredBillRunStub.firstCall.args
133148

134149
expect(handlerArgs[1]).to.equal(BillRunModel.errorCodes.failedToProcessChargeVersions)
135150
})
136151

137152
it('logs the error', async () => {
138-
await SupplementaryProcessBillRunService.go(billRun, billingPeriods)
153+
await ProcessBillRunService.go(billRun, billingPeriods)
139154

140155
const args = notifierStub.omfg.firstCall.args
141156

@@ -158,15 +173,15 @@ describe('Supplementary Process Bill Run service', () => {
158173
})
159174

160175
it('calls HandleErroredBillRunService with the error code', async () => {
161-
await SupplementaryProcessBillRunService.go(billRun, billingPeriods)
176+
await ProcessBillRunService.go(billRun, billingPeriods)
162177

163178
const handlerArgs = handleErroredBillRunStub.firstCall.args
164179

165180
expect(handlerArgs[1]).to.equal(BillRunModel.errorCodes.failedToPrepareTransactions)
166181
})
167182

168183
it('logs the error', async () => {
169-
await SupplementaryProcessBillRunService.go(billRun, billingPeriods)
184+
await ProcessBillRunService.go(billRun, billingPeriods)
170185

171186
const args = notifierStub.omfg.firstCall.args
172187

@@ -186,19 +201,19 @@ describe('Supplementary Process Bill Run service', () => {
186201

187202
Sinon.stub(FetchChargeVersionsService, 'go').resolves({ chargeVersions: [], licenceIdsForPeriod: [] })
188203
Sinon.stub(ProcessBillingPeriodService, 'go').resolves(false)
189-
Sinon.stub(UnflagUnbilledLicencesService, 'go').rejects(thrownError)
204+
Sinon.stub(UnflagUnbilledSupplementaryLicencesService, 'go').rejects(thrownError)
190205
})
191206

192207
it('calls HandleErroredBillRunService without an error code', async () => {
193-
await SupplementaryProcessBillRunService.go(billRun, billingPeriods)
208+
await ProcessBillRunService.go(billRun, billingPeriods)
194209

195210
const handlerArgs = handleErroredBillRunStub.firstCall.args
196211

197212
expect(handlerArgs[1]).to.be.undefined()
198213
})
199214

200215
it('logs the error', async () => {
201-
await SupplementaryProcessBillRunService.go(billRun, billingPeriods)
216+
await ProcessBillRunService.go(billRun, billingPeriods)
202217

203218
const args = notifierStub.omfg.firstCall.args
204219

test/services/bill-runs/supplementary/unflag-billed-licences.service.test.js renamed to test/services/bill-runs/unflag-billed-supplementary-licences.service.test.js

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,16 @@ const { describe, it, beforeEach } = (exports.lab = Lab.script())
88
const { expect } = Code
99

1010
// Test helpers
11-
const BillHelper = require('../../../support/helpers/bill.helper.js')
12-
const BillLicenceHelper = require('../../../support/helpers/bill-licence.helper.js')
13-
const LicenceHelper = require('../../../support/helpers/licence.helper.js')
14-
const RegionHelper = require('../../../support/helpers/region.helper.js')
15-
const WorkflowHelper = require('../../../support/helpers/workflow.helper.js')
11+
const BillHelper = require('../../support/helpers/bill.helper.js')
12+
const BillLicenceHelper = require('../../support/helpers/bill-licence.helper.js')
13+
const LicenceHelper = require('../../support/helpers/licence.helper.js')
14+
const RegionHelper = require('../../support/helpers/region.helper.js')
15+
const WorkflowHelper = require('../../support/helpers/workflow.helper.js')
1616

1717
// Thing under test
18-
const UnflagBilledLicencesService = require('../../../../app/services/bill-runs/supplementary/unflag-billed-licences.service.js')
18+
const UnflagBilledSupplementaryLicencesService = require('../../../app/services/bill-runs/unflag-billed-supplementary-licences.service.js')
1919

20-
describe('Unflag Billed Licences service', () => {
20+
describe('Bill Runs - Unflag Billed Supplementary Licences service', () => {
2121
const { id: regionId } = RegionHelper.select(RegionHelper.TEST_REGION_INDEX)
2222

2323
let billRun
@@ -64,7 +64,7 @@ describe('Unflag Billed Licences service', () => {
6464
})
6565

6666
it('unflags those in the same region, not in workflow, and that were last updated before the bill run was created', async () => {
67-
await UnflagBilledLicencesService.go(billRun)
67+
await UnflagBilledSupplementaryLicencesService.go(billRun)
6868

6969
let licenceBeingChecked
7070

@@ -120,7 +120,7 @@ describe('Unflag Billed Licences service', () => {
120120
})
121121

122122
it('unflags only those licences in the bill run that are not in workflow, and that were last updated before the bill run was created)', async () => {
123-
await UnflagBilledLicencesService.go(billRun)
123+
await UnflagBilledSupplementaryLicencesService.go(billRun)
124124

125125
let licenceBeingChecked
126126

test/services/bill-runs/supplementary/unflag-unbilled-licences.service.test.js renamed to test/services/bill-runs/unflag-unbilled-supplementary-licences.service.test.js

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,15 @@ const { describe, it, beforeEach } = (exports.lab = Lab.script())
88
const { expect } = Code
99

1010
// Test helpers
11-
const BillHelper = require('../../../support/helpers/bill.helper.js')
12-
const BillLicenceHelper = require('../../../support/helpers/bill-licence.helper.js')
13-
const LicenceHelper = require('../../../support/helpers/licence.helper.js')
14-
const WorkflowHelper = require('../../../support/helpers/workflow.helper.js')
11+
const BillHelper = require('../../support/helpers/bill.helper.js')
12+
const BillLicenceHelper = require('../../support/helpers/bill-licence.helper.js')
13+
const LicenceHelper = require('../../support/helpers/licence.helper.js')
14+
const WorkflowHelper = require('../../support/helpers/workflow.helper.js')
1515

1616
// Thing under test
17-
const UnflagUnbilledLicencesService = require('../../../../app/services/bill-runs/supplementary/unflag-unbilled-licences.service.js')
17+
const UnflagUnbilledSupplementaryLicencesService = require('../../../app/services/bill-runs/unflag-unbilled-supplementary-licences.service.js')
1818

19-
describe('Unflag unbilled licences service', () => {
19+
describe('Bill Runs - Unflag Unbilled Supplementary Licences service', () => {
2020
let billRun
2121

2222
describe('when there are licences flagged for SROC supplementary billing', () => {
@@ -59,7 +59,7 @@ describe('Unflag unbilled licences service', () => {
5959
describe('which were not billed', () => {
6060
describe('and are not in workflow or updated after the bill run was created', () => {
6161
it('unflags them for SROC supplementary billing', async () => {
62-
await UnflagUnbilledLicencesService.go(billRun, allLicenceIds)
62+
await UnflagUnbilledSupplementaryLicencesService.go(billRun, allLicenceIds)
6363

6464
const licenceToBeChecked = await licenceNotBilledInBillRun.$query()
6565

@@ -69,7 +69,7 @@ describe('Unflag unbilled licences service', () => {
6969

7070
describe('but are in workflow', () => {
7171
it('leaves flagged for SROC supplementary billing', async () => {
72-
await UnflagUnbilledLicencesService.go(billRun, allLicenceIds)
72+
await UnflagUnbilledSupplementaryLicencesService.go(billRun, allLicenceIds)
7373

7474
const licenceToBeChecked = await licenceNotBilledInBillRunAndWorkflow.$query()
7575

@@ -79,7 +79,7 @@ describe('Unflag unbilled licences service', () => {
7979

8080
describe('but were updated after the bill run was created', () => {
8181
it('leaves flagged for SROC supplementary billing', async () => {
82-
await UnflagUnbilledLicencesService.go(billRun, allLicenceIds)
82+
await UnflagUnbilledSupplementaryLicencesService.go(billRun, allLicenceIds)
8383

8484
const licenceToBeChecked = await licenceNotBilledInBillRunAndUpdated.$query()
8585

@@ -96,7 +96,7 @@ describe('Unflag unbilled licences service', () => {
9696
})
9797

9898
it('are left flagged (include_in_sroc_billing still true)', async () => {
99-
await UnflagUnbilledLicencesService.go(billRun, allLicenceIds)
99+
await UnflagUnbilledSupplementaryLicencesService.go(billRun, allLicenceIds)
100100

101101
const licenceToBeChecked = await licenceBilledInBillRun.$query()
102102

@@ -107,7 +107,7 @@ describe('Unflag unbilled licences service', () => {
107107

108108
describe('those licences not in the current bill run', () => {
109109
it('leaves flagged (include_in_sroc_billing still true)', async () => {
110-
await UnflagUnbilledLicencesService.go(billRun, allLicenceIds)
110+
await UnflagUnbilledSupplementaryLicencesService.go(billRun, allLicenceIds)
111111

112112
const licenceToBeChecked = await licenceNotInBillRun.$query()
113113

0 commit comments

Comments
 (0)