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

Determine if licence is 'billed' #101

Merged
merged 15 commits into from
Jan 31, 2023
12 changes: 1 addition & 11 deletions app/presenters/check/supplementary-data.presenter.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,10 @@

function go (data) {
const licences = data.licences.map((licence) => {
const licenceExistsInBilling = _licenceExistsInBilling(licence.billingInvoiceLicences)

return {
licenceId: licence.licenceId,
licenceRef: licence.licenceRef,
licenceExistsInBilling
licenceExistsInBilling: licence.numberOfTimesBilled > 0
}
})
const chargeVersions = data.chargeVersions
Expand All @@ -24,14 +22,6 @@ function go (data) {
}
}

function _licenceExistsInBilling (billingInvoiceLicences) {
if (billingInvoiceLicences) {
return billingInvoiceLicences.some((billingInvoiceLicence) => billingInvoiceLicence.billingInvoice)
}

return false
}

module.exports = {
go
}
41 changes: 23 additions & 18 deletions app/services/supplementary-billing/fetch-licences.service.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* @module FetchLicencesService
*/

const LicenceModel = require('../../models/water/licence.model.js')
const { db } = require('../../../db/db.js')

/**
* Fetches licences flagged for supplementary billing that are linked to the selected region
Expand All @@ -24,24 +24,29 @@ async function go (region, billingPeriodFinancialYearEnding) {
}

async function _fetch (region, billingPeriodFinancialYearEnding) {
const result = await LicenceModel.query()
.distinctOn('licenceId')
.innerJoinRelated('chargeVersions')
.where('regionId', region.regionId)
.where('includeInSupplementaryBilling', 'yes')
.where('chargeVersions.scheme', 'sroc')
.withGraphFetched('billingInvoiceLicences.billingInvoice')
.modifyGraph('billingInvoiceLicences', builder => {
builder.select(
'billingInvoiceLicenceId'
)
})
.modifyGraph('billingInvoiceLicences.billingInvoice', builder => {
builder.select(
'financialYearEnding'
)
.where('financialYearEnding', billingPeriodFinancialYearEnding)
const result = db
.select('l.licenceId', 'l.licenceRef')
.count('billed.licenceId as numberOfTimesBilled')
.distinctOn('l.licenceId')
.from('water.licences as l')
.leftOuterJoin(
db
.select('bil.licenceId')
.from('water.billingInvoiceLicences as bil')
.innerJoin('water.billingInvoices as bi', 'bil.billingInvoiceId', 'bi.billingInvoiceId')
.innerJoin('water.billingBatches as bb', 'bi.billingBatchId', 'bb.billingBatchId')
.where({
'bi.financialYearEnding': billingPeriodFinancialYearEnding,
'bb.status': 'sent',
'bb.scheme': 'sroc'
}).as('billed'),
'l.licenceId', 'billed.licenceId'
)
.where({
'l.includeInSupplementaryBilling': 'yes',
'l.regionId': region.regionId
})
.groupBy('l.licenceId')

return result
}
Expand Down
22 changes: 2 additions & 20 deletions test/presenters/check/supplementary-data.presenter.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,30 +26,12 @@ describe('Supplementary presenter', () => {
{
licenceId: 'f1288f6c-8503-4dc1-b114-75c408a14bd0',
licenceRef: 'AT/SROC/SUPB/01',
billingInvoiceLicences: [
{
billingInvoiceLicenceId: '585135da-0879-400a-b329-4d94b214ca66',
billingInvoice: null
},
{
billingInvoiceLicenceId: '585135da-0879-400a-b329-4d94b214ca66',
billingInvoice: { financialYearEnding: 2023 }
}
]
numberOfTimesBilled: 1
},
{
licenceId: '81b50b35-459a-43f0-a48a-262028a34493',
licenceRef: 'AT/SROC/SUPB/02',
billingInvoiceLicences: [
{
billingInvoiceLicenceId: 'f2a4689f-1c6f-4388-8a42-c1daddcc7f2f',
billingInvoice: null
},
{
billingInvoiceLicenceId: '5846052d-2acf-43c3-8c5a-353debb1b8ed',
billingInvoice: null
}
]
numberOfTimesBilled: 0
}
],
chargeVersions: [
Expand Down
79 changes: 61 additions & 18 deletions test/services/supplementary-billing/fetch-licences.service.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ const { expect } = Code
// Test helpers
const BillingInvoiceHelper = require('../../support/helpers/water/billing-invoice.helper.js')
const BillingInvoiceLicenceHelper = require('../../support/helpers/water/billing-invoice-licence.helper.js')
const ChargeVersionHelper = require('../../support/helpers/water/charge-version.helper.js')
const DatabaseHelper = require('../../support/helpers/database.helper.js')
const LicenceHelper = require('../../support/helpers/water/licence.helper.js')

Expand All @@ -33,23 +32,38 @@ describe('Fetch Licences service', () => {
testLicence = await LicenceHelper.add({ includeInSupplementaryBilling: 'yes' })
})

describe('and that have an SROC charge version. Licence not previosly billed', () => {
describe('and that have not been previously billed', () => {
it('returns the expected results', async () => {
const result = await FetchLicencesService.go(region, billingPeriodFinancialYearEnding)

expect(result.length).to.equal(1)
expect(result[0].licenceId).to.equal(testLicence.licenceId)
expect(result[0].licenceRef).to.equal(testLicence.licenceRef)
expect(result[0].numberOfTimesBilled).to.equal(0)
})
})

describe('and that have been billed in the current period', () => {
beforeEach(async () => {
await ChargeVersionHelper.add({}, testLicence)
billingInvoice = await BillingInvoiceHelper.add(
{ financialYearEnding: billingPeriodFinancialYearEnding },
{ status: 'sent' }
)
await BillingInvoiceLicenceHelper.add({}, testLicence, billingInvoice)
})

it('returns results', async () => {
it('returns the expected results', async () => {
const result = await FetchLicencesService.go(region, billingPeriodFinancialYearEnding)

expect(result.length).to.equal(1)
expect(result[0].licenceId).to.equal(testLicence.licenceId)
expect(result[0].billingInvoiceLicences).to.equal([])
expect(result[0].licenceRef).to.equal(testLicence.licenceRef)
expect(result[0].numberOfTimesBilled).to.equal(1)
})
})

describe('and that have an SROC charge version. Licence previosly billed in current period 2023', () => {
describe("and that are included in an 'unsent' billing batch in the current period", () => {
beforeEach(async () => {
await ChargeVersionHelper.add({}, testLicence)
billingInvoice = await BillingInvoiceHelper.add({ financialYearEnding: billingPeriodFinancialYearEnding })
await BillingInvoiceLicenceHelper.add({}, testLicence, billingInvoice)
})
Expand All @@ -59,14 +73,17 @@ describe('Fetch Licences service', () => {

expect(result.length).to.equal(1)
expect(result[0].licenceId).to.equal(testLicence.licenceId)
expect(result[0].billingInvoiceLicences[0].billingInvoice.financialYearEnding).to.equal(billingPeriodFinancialYearEnding)
expect(result[0].licenceRef).to.equal(testLicence.licenceRef)
expect(result[0].numberOfTimesBilled).to.equal(0)
})
})

describe('and that have an SROC charge version. Licence previosly billed in previous period 2022', () => {
describe('and that have been billed in the previous period', () => {
beforeEach(async () => {
await ChargeVersionHelper.add({}, testLicence)
billingInvoice = await BillingInvoiceHelper.add({ financialYearEnding: 2022 })
billingInvoice = await BillingInvoiceHelper.add(
{ financialYearEnding: 2022 },
{ status: 'sent' }
)
await BillingInvoiceLicenceHelper.add({}, testLicence, billingInvoice)
})

Expand All @@ -75,29 +92,52 @@ describe('Fetch Licences service', () => {

expect(result.length).to.equal(1)
expect(result[0].licenceId).to.equal(testLicence.licenceId)
expect(result[0].billingInvoiceLicences[0].billingInvoice).to.equal(null)
expect(result[0].licenceRef).to.equal(testLicence.licenceRef)
expect(result[0].numberOfTimesBilled).to.equal(0)
})
})

describe('and that have multiple SROC charge versions', () => {
describe('and that have been billed twice in the current period', () => {
beforeEach(async () => {
await ChargeVersionHelper.add({}, testLicence)
await ChargeVersionHelper.add({}, testLicence)
billingInvoice = await BillingInvoiceHelper.add(
{ financialYearEnding: billingPeriodFinancialYearEnding },
{ status: 'sent' }
)
await BillingInvoiceLicenceHelper.add({}, testLicence, billingInvoice)
billingInvoice = await BillingInvoiceHelper.add(
{ financialYearEnding: billingPeriodFinancialYearEnding },
{ status: 'sent' }
)
await BillingInvoiceLicenceHelper.add({}, testLicence, billingInvoice)
})

it('returns a licence only once in the results', async () => {
const result = await FetchLicencesService.go(region, billingPeriodFinancialYearEnding)

expect(result.length).to.equal(1)
expect(result[0].licenceId).to.equal(testLicence.licenceId)
expect(result[0].licenceRef).to.equal(testLicence.licenceRef)
expect(result[0].numberOfTimesBilled).to.equal(2)
})
})

describe('but do not have an SROC charge version', () => {
// NOTE: This situation will not occur normally. But as the billing batch is filtered on `scheme` we wanted a test to ensure the filter worked
describe('and that have been billed in the current period under a different scheme', () => {
beforeEach(async () => {
billingInvoice = await BillingInvoiceHelper.add(
{ financialYearEnding: billingPeriodFinancialYearEnding },
{ status: 'sent', scheme: 'alcs' }
)
await BillingInvoiceLicenceHelper.add({}, testLicence, billingInvoice)
})

it('returns no results', async () => {
const result = await FetchLicencesService.go(region, billingPeriodFinancialYearEnding)

expect(result.length).to.equal(0)
expect(result.length).to.equal(1)
expect(result[0].licenceId).to.equal(testLicence.licenceId)
expect(result[0].licenceRef).to.equal(testLicence.licenceRef)
expect(result[0].numberOfTimesBilled).to.equal(0)
})
})
})
Expand All @@ -117,7 +157,10 @@ describe('Fetch Licences service', () => {

describe('when there are no licences for the matching region', () => {
beforeEach(async () => {
await LicenceHelper.add({ regionId: '000446bd-182a-4340-be6b-d719855ace1a' })
await LicenceHelper.add({
regionId: '000446bd-182a-4340-be6b-d719855ace1a',
includeInSupplementaryBilling: 'yes'
})
})

it('returns no results', async () => {
Expand Down
9 changes: 8 additions & 1 deletion test/support/helpers/water/billing-invoice.helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ const BillingBatchHelper = require('./billing-batch.helper.js')
* Add a new billing invoice
*
* A billing invoice is always linked to a billing batch. So, creating a billing invoice will automatically
* create a new billing batch and handle linking the two together by `billingBatchId`.
* create a new billing batch and handle linking the two together by `billingBatchId`. If a `financialYearEnding` has
* been provided for the billing invoice, but not for the billing batch. The billing batch will use the 'financialYearEnding'
* from the billing invoice to populate it's `fromFinancialYearEnding` & `toFinancialYearEnding` items.
*
* If no `data` is provided, default values will be used. These are
*
Expand All @@ -25,6 +27,11 @@ const BillingBatchHelper = require('./billing-batch.helper.js')
* @returns {module:BillingInvoiceModel} The instance of the newly created record
*/
async function add (data = {}, billingBatch = {}) {
if (data.financialYearEnding && !billingBatch.fromFinancialYearEnding) {
billingBatch.fromFinancialYearEnding = data.financialYearEnding
billingBatch.toFinancialYearEnding = data.financialYearEnding
}

const billingBatchId = await _billingBatchId(billingBatch)

const insertData = defaults({ ...data, billingBatchId })
Expand Down