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

Flag licences removed from workflow for supp billing #1388

Merged
merged 22 commits into from
Oct 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
91804d5
Flag licences removed from workflow for supp billing
Beckyrose200 Oct 7, 2024
00d5642
WIP
Beckyrose200 Oct 7, 2024
dbda80d
Merge branch 'main' into flag-licences-removed-from-workflow
Beckyrose200 Oct 10, 2024
47ce223
WIP
Beckyrose200 Oct 10, 2024
2c89d25
Working version
Beckyrose200 Oct 11, 2024
00b774d
fetch-licence unit test WIP
Beckyrose200 Oct 17, 2024
6a4fd99
Fetch Licence Service working unit tests
Beckyrose200 Oct 17, 2024
9d3782f
unit tests for determine workflow years service
Beckyrose200 Oct 17, 2024
575743f
Update Process billing flags unit tests
Beckyrose200 Oct 17, 2024
cf111a5
Merge branch 'main' into flag-licences-removed-from-workflow
Beckyrose200 Oct 17, 2024
db599f6
Update comments and param names
Beckyrose200 Oct 18, 2024
8337c14
Fix unit test
Beckyrose200 Oct 18, 2024
5817f0b
Merge branch 'main' into flag-licences-removed-from-workflow
Beckyrose200 Oct 18, 2024
a8ee7ab
Merge branch 'main' into flag-licences-removed-from-workflow
Beckyrose200 Oct 18, 2024
78327af
Merge branch 'main' into flag-licences-removed-from-workflow
Beckyrose200 Oct 21, 2024
549bf57
Merge branch 'main' into flag-licences-removed-from-workflow
Beckyrose200 Oct 21, 2024
f577bca
Add additional unit tests to determine-workflow-years service
Beckyrose200 Oct 21, 2024
6cb1f24
Merge branch 'main' into flag-licences-removed-from-workflow
Beckyrose200 Oct 21, 2024
f98b3ec
Amend query to remove `CROSS JOIN`
Jozzey Oct 21, 2024
80cbb3d
Merge branch 'main' into flag-licences-removed-from-workflow
Beckyrose200 Oct 21, 2024
77d3c0f
Remove unnecessary async
Beckyrose200 Oct 21, 2024
d1b8b63
Remove unnecessary async
Beckyrose200 Oct 21, 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
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
'use strict'

/**
* Determines if a licence being removed from workflow should be flagged for supplementary billing
* @module DetermineWorkflowYearsService
*/

const FetchLicenceService = require('./fetch-licence.service.js')
const { determineCurrentFinancialYear } = require('../../../lib/general.lib.js')
const LicenceModel = require('../../../models/licence.model.js')

/**
* Determines if a licence being removed from workflow should be flagged for supplementary billing and two-part tariff
* supplementary billing.
*
* The service is passed the id of a workflow record and determines if it should be flagged for any supplementary
* billing. This is worked out based on the licences charge information data. If the licence has any charge versions
* that are sroc we can flag it for supplementary billing and two-part tariff then we set flagForBilling to true.
*
* The flags are then passed back to the service this was called from, where it works out which years the two-part
* tariff flags should be put on.
*
* @param {string} workflowId - The UUID for the workflow record to fetch
*
* @returns {object} - An object containing the related licence, charge information start and end date and if the
* licence should be flagged for two-part tariff supplementary billing
*/
async function go (workflowId) {
const licence = await FetchLicenceService.go(workflowId)
const { endDate } = determineCurrentFinancialYear()

// Due to the fact the database gives us the licence back in snake case, we need to convert the references to camel
// case so the other services can use the result
const result = {
licence: {
id: licence.id,
regionId: licence.region_id
},
startDate: licence.created_at,
endDate,
twoPartTariff: licence.two_part_tariff_charge_versions,
flagForBilling: false
}

if (!licence.include_in_sroc_billing && licence.sroc_charge_versions) {
await _flagForSrocSupplementary(licence.id)
}

result.flagForBilling = result.twoPartTariff

return result
}

async function _flagForSrocSupplementary (id) {
return LicenceModel.query().patch({ includeInSrocBilling: true }).where('id', id)
}

module.exports = {
go
}
72 changes: 72 additions & 0 deletions app/services/licences/supplementary/fetch-licence.service.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
'use strict'

/**
* Fetches existing supplementary details about a licence being removed from workflow
* @module FetchLicenceService
*/

const { db } = require('../../../../db/db.js')

/**
* Fetches existing supplementary details about a licence being removed from workflow
*
* We need to get the `created at` date from the workflow record to determine which supplementary years we need to flag.
* The query also determines what sroc or two-part tariff charge versions the licence has.
*
* When processing the flags we have to work out whether to include the licence in sroc supplementary billing or in
* two-part tariff supplementary billing.
*
* NOTE: We do not care about pre sroc charge versions. We are not setting the `include_in_pre_sroc_billing` flag due to
* using the old billing engine that then generates £0 bill runs. Only our new sroc billing engines can handle £0 bill
* runs.
*
* @param {string} workflowId - The UUID for the workflow record related to the licence
*
* @returns {Promise<object>} - The data needed to determine which supplementary flags the licence needs
*/
async function go (workflowId) {
const query = _query()

const { rows: [row] } = await db.raw(query, [workflowId])

return row
}

function _query () {
return `
SELECT
l.include_in_sroc_billing,
l.id,
l.region_id,
EXISTS (
SELECT 1
FROM public.charge_versions cv
WHERE cv.licence_id = l.id
AND cv.start_date > '2022-03-31'
) AS sroc_charge_versions,
EXISTS (
SELECT 1
FROM public.charge_references cr
INNER JOIN public.charge_elements ce
ON ce.charge_reference_id = cr.id
WHERE cr.charge_version_id = (
SELECT cv.id
FROM public.charge_versions cv
WHERE cv.licence_id = l.id
AND cv.start_date > '2022-03-31'
LIMIT 1
)
AND ce.section_127_Agreement = TRUE
AND cr.adjustments->>'s127' = 'true'
) AS two_part_tariff_charge_versions,
w.created_at
FROM licences l
INNER JOIN workflows w
ON l.id = w.licence_id
WHERE w.id = ?
`
}

module.exports = {
go
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,15 @@ const DetermineBillingYearsService = require('./determine-billing-years.service.
const DetermineExistingBillRunYearsService = require('./determine-existing-bill-run-years.service.js')
const DetermineChargeVersionYearsService = require('./determine-charge-version-years.service.js')
const DetermineReturnLogYearsService = require('./determine-return-log-years.service.js')
const DetermineWorkflowYearsService = require('./determine-workflow-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
* Based on the ID the service receives (chargeVersionId, returnId, workflowId) it retrieves details of the related
* 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
Expand All @@ -42,6 +44,8 @@ async function go (payload) {
result = await DetermineChargeVersionYearsService.go(payload.chargeVersionId)
} else if (payload.returnId) {
result = await DetermineReturnLogYearsService.go(payload.returnId)
} else if (payload.workflowId) {
result = await DetermineWorkflowYearsService.go(payload.workflowId)
} else {
return
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
'use strict'

// Test framework dependencies
const Lab = require('@hapi/lab')
const Code = require('@hapi/code')
const Sinon = require('sinon')

const { describe, it, before, beforeEach, afterEach } = exports.lab = Lab.script()
const { expect } = Code

// Test helpers
const { determineCurrentFinancialYear } = require('../../../../app/lib/general.lib.js')
const LicenceHelper = require('../../../support/helpers/licence.helper.js')
const LicenceModel = require('../../../../app/models/licence.model.js')

// Things we need to stub
const FetchLicenceService = require('../../../../app/services/licences/supplementary/fetch-licence.service.js')

// Thing under test
const DetermineWorkflowYearsService = require('../../../../app/services/licences/supplementary/determine-workflow-years.service.js')

describe('Determine Workflow Years Service', () => {
const currentFinancialYear = determineCurrentFinancialYear()
const workflowId = '1c995768-35fe-45c4-bb80-dc242052e94d'

let licence
let licenceData

before(async () => {
licence = await LicenceHelper.add()
licenceData = {
include_in_sroc_billing: false,
id: licence.id,
region_id: licence.regionId,
sroc_charge_versions: false,
two_part_tariff_charge_versions: false,
created_at: new Date('2024-04-01')
}
})

afterEach(() => {
Sinon.restore()
})

describe('when passed a workflowId', () => {
describe('that relates to a licence with no sroc charge versions', () => {
beforeEach(async () => {
Sinon.stub(FetchLicenceService, 'go').resolves(licenceData)
})

it('returns flagForBilling and twoPartTariff as false', async () => {
const result = await DetermineWorkflowYearsService.go(workflowId)

expect(result.twoPartTariff).to.equal(false)
expect(result.flagForBilling).to.equal(false)
})

it('does not flag the licence for sroc supplementary billing', async () => {
await DetermineWorkflowYearsService.go(workflowId)

const result = await LicenceModel.query().findById(licence.id)

expect(result.includeInSrocBilling).to.equal(false)
})
})

describe('that relates to a licence with sroc charge versions', () => {
describe('but has no two-part tariff indicators', () => {
beforeEach(async () => {
licenceData.sroc_charge_versions = true

Sinon.stub(FetchLicenceService, 'go').resolves(licenceData)
})

it('flags the licence for sroc supplementary billing', async () => {
await DetermineWorkflowYearsService.go(workflowId)

const result = await LicenceModel.query().findById(licence.id)

expect(result.includeInSrocBilling).to.equal(true)
})

it('returns the licence data', async () => {
const result = await DetermineWorkflowYearsService.go(workflowId)

expect(result.licence.id).to.equal(licence.id)
expect(result.licence.regionId).to.equal(licence.regionId)
expect(result.startDate).to.equal(new Date('2024-04-01'))
expect(result.endDate).to.equal(currentFinancialYear.endDate)
})

it('returns the flagForBilling and twoPartTariff as false', async () => {
const result = await DetermineWorkflowYearsService.go(workflowId)

expect(result.twoPartTariff).to.equal(false)
expect(result.flagForBilling).to.equal(false)
})
})
})

describe('that relates to a licence with sroc two-part tariff charge versions', () => {
describe('and the licence is already flagged for sroc supplementary billing', () => {
before(async () => {
licenceData.two_part_tariff_charge_versions = true
licenceData.include_in_sroc_billing = true

Sinon.stub(FetchLicenceService, 'go').resolves(licenceData)
})

it('returns flagForBilling and twoPartTariff as true', async () => {
const result = await DetermineWorkflowYearsService.go(workflowId)

expect(result.twoPartTariff).to.equal(true)
expect(result.flagForBilling).to.equal(true)
})
})
})
})
})
58 changes: 58 additions & 0 deletions test/services/licences/supplementary/fetch-licence.service.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
'use strict'

// Test framework dependencies
const Lab = require('@hapi/lab')
const Code = require('@hapi/code')

const { describe, it, before } = exports.lab = Lab.script()
const { expect } = Code

// Test helpers
const ChargeElementHelper = require('../../../support/helpers/charge-element.helper.js')
const ChargeReferenceHelper = require('../../../support/helpers/charge-reference.helper.js')
const ChargeVersionHelper = require('../../../support/helpers/charge-version.helper.js')
const LicenceHelper = require('../../../support/helpers/licence.helper.js')
const WorkflowHelper = require('../../../support/helpers/workflow.helper.js')

// Thing under test
const FetchLicenceService = require('../../../../app/services/licences/supplementary/fetch-licence.service.js')

describe('Fetch Licence Service', () => {
let workflow

describe('when passed a valid workflow id', () => {
let licence

before(async () => {
licence = await LicenceHelper.add()

workflow = await WorkflowHelper.add({ licenceId: licence.id })

// sroc charge version
const chargeVersion = await ChargeVersionHelper.add({ licenceId: licence.id })

// two-part tariff indicators
const chargeReference = await ChargeReferenceHelper.add(
{ chargeVersionId: chargeVersion.id, adjustments: { s127: true } }
)

await ChargeElementHelper.add({ chargeReferenceId: chargeReference.id })
})

it('fetches the licence data related to that workflow record', async () => {
const result = await FetchLicenceService.go(workflow.id)

expect(result.id).to.equal(licence.id)
expect(result.region_id).to.equal(licence.regionId)
expect(result.include_in_sroc_billing).to.equal(licence.includeInSrocBilling)
expect(result.created_at).to.equal(workflow.createdAt)
})

it('outlines which charge versions the licence has', async () => {
const result = await FetchLicenceService.go(workflow.id)

expect(result.sroc_charge_versions).to.equal(true)
expect(result.two_part_tariff_charge_versions).to.equal(true)
})
})
})
Loading
Loading