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

Fix and update time-limited job #908

Merged
merged 8 commits into from
Apr 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
@@ -1,14 +1,14 @@
'use strict'

/**
* Fetches licences that have a related `purpose` that is due to expire in less than 50 days
* Fetches licences that have a related charge element that is due to expire in less than 50 days
* @module FetchTimeLimitedLicencesService
*/

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

/**
* Fetch licences that have a related `purpose` that is due to expire in less than 50 days
* Fetches licences that have a related charge element that is due to expire in less than 50 days
*
* To be selected the licence must
*
Expand All @@ -20,13 +20,14 @@ const { db } = require('../../../../db/db.js')
* - not be linked to a licence in the workflow
* - have a related `purpose` that is due to expire in less than 50 days
*
* @returns {Promise<Object[]>} The licence IDs with time-limited elements & their current version ID (needed else we break the workflow)
* @returns {Promise<Object[]>} The licence IDs with time-limited elements and their current licence version ID (needed
* else we break the workflow). Also the ID of the charge version that has the time limited charge element
*/
async function go () {
// NOTE: We've resorted to Knex rather than Objection JS due to just how many JOINS we need to get from licence to
// charge purposes! Our Objection JS skills failed us as we could not get the query to work using innerJoinRelated()
return db
.distinct('l.id', 'lv.id AS licenceVersionId')
.distinct('l.id', 'lv.id AS licenceVersionId', 'cv.id AS chargeVersionId')
.from('licences as l')
.innerJoin('licenceVersions as lv', 'l.id', 'lv.licenceId')
.innerJoin('chargeVersions as cv', 'l.id', 'cv.licenceId')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,36 +6,41 @@
*/

const FetchTimeLimitedLicencesService = require('./fetch-time-limited-licences.service.js')
const { timestampForPostgres } = require('../../../lib/general.lib.js')
const { calculateAndLogTimeTaken, currentTimeInNanoseconds, timestampForPostgres } = require('../../../lib/general.lib.js')
const Workflow = require('../../../models/workflow.model.js')

/**
* Puts SROC licences into workflow that have a related `purpose` that is due to expire in less than 50 days
*/
async function go () {
try {
const licencesForWorkflow = await FetchTimeLimitedLicencesService.go()
const startTime = currentTimeInNanoseconds()

if (licencesForWorkflow.length) {
await _addLicenceToWorkflow(licencesForWorkflow)
}
const timeLimitedResults = await FetchTimeLimitedLicencesService.go()

await _addWorkflowRecords(timeLimitedResults)

calculateAndLogTimeTaken(startTime, 'Time limited job complete', { count: timeLimitedResults.length })
} catch (error) {
global.GlobalNotifier.omfg('ProcessTimeLimitedLicencesService failed to run', null, error)
global.GlobalNotifier.omfg('Time limited job failed', null, error)
}
}

async function _addLicenceToWorkflow (licencesForWorkflow) {
async function _addWorkflowRecords (timeLimitedResults) {
const timestamp = timestampForPostgres()

// Attach additional data to the array that the chargeVersionWorkflow table requires to create a valid record
licencesForWorkflow.forEach((licenceForWorkflow) => {
licenceForWorkflow.status = 'to_setup'
licenceForWorkflow.data = { chargeVersion: null }
licenceForWorkflow.createdAt = timestamp
licenceForWorkflow.updatedAt = timestamp
})

await Workflow.query().insert(licencesForWorkflow)
for (const timeLimitedResult of timeLimitedResults) {
const { id: licenceId, chargeVersionId: timeLimitedChargeVersionId, licenceVersionId } = timeLimitedResult

await Workflow.query().insert({
data: { chargeVersion: null, timeLimitedChargeVersionId },
licenceId,
licenceVersionId,
status: 'to_setup',
createdAt: timestamp,
updatedAt: timestamp
})
}
}

module.exports = {
Expand Down
128 changes: 0 additions & 128 deletions test/services/bill-runs/determine-billing-periods.service.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -285,132 +285,4 @@ describe('Determine Billing Periods service', () => {
})
})
})

// describe('and the date is in 2022 and falls within the 2022 financial year', () => {
// beforeEach(() => {
//
// expectedResult = {
// startDate: new Date('2022-04-01'),
// endDate: new Date('2023-03-31')
// }

// clock = Sinon.useFakeTimers(testDate)
// })

// it('returns the expected date range', () => {
// const result = DetermineBillingPeriodsService.go()

// expect(result).to.have.length(1)
// expect(result[0]).to.equal(expectedResult)
// })
// })

// describe('and the date is in 2023 and falls within the 2022 financial year', () => {
// beforeEach(() => {
// testDate = new Date('2023-03-01')
// expectedResult = {
// startDate: new Date('2022-04-01'),
// endDate: new Date('2023-03-31')
// }

// clock = Sinon.useFakeTimers(testDate)
// })

// it('returns the expected date range', () => {
// const result = DetermineBillingPeriodsService.go()

// expect(result).to.have.length(1)
// expect(result[0]).to.equal(expectedResult)
// })
// })

// describe('and the date is in 2023 and falls within the 2023 financial year', () => {
// beforeEach(() => {
// testDate = new Date('2023-10-10')
// expectedResult = [
// {
// startDate: new Date('2023-04-01'),
// endDate: new Date('2024-03-31')
// },
// {
// startDate: new Date('2022-04-01'),
// endDate: new Date('2023-03-31')
// }
// ]

// clock = Sinon.useFakeTimers(testDate)
// })

// it('returns the expected date range', () => {
// const result = DetermineBillingPeriodsService.go()

// expect(result).to.have.length(2)
// expect(result).to.equal(expectedResult)
// })
// })

// describe('and the date is in 2030 and falls within the 2030 financial year', () => {
// beforeEach(() => {
// testDate = new Date('2030-10-10')
// expectedResult = [
// {
// startDate: new Date('2030-04-01'),
// endDate: new Date('2031-03-31')
// },
// {
// startDate: new Date('2029-04-01'),
// endDate: new Date('2030-03-31')
// },
// {
// startDate: new Date('2028-04-01'),
// endDate: new Date('2029-03-31')
// },
// {
// startDate: new Date('2027-04-01'),
// endDate: new Date('2028-03-31')
// },
// {
// startDate: new Date('2026-04-01'),
// endDate: new Date('2027-03-31')
// },
// {
// startDate: new Date('2025-04-01'),
// endDate: new Date('2026-03-31')
// }
// ]

// clock = Sinon.useFakeTimers(testDate)
// })

// it('returns the expected date range', () => {
// const result = DetermineBillingPeriodsService.go()

// expect(result).to.have.length(6)
// expect(result).to.equal(expectedResult)
// })
// })
// })

// describe('when a financial year is provided', () => {
// const financialYearEnding = 2025

// beforeEach(() => {
// testDate = new Date('2024-10-10')
// expectedResult = [
// {
// startDate: new Date('2024-04-01'),
// endDate: new Date('2025-03-31')
// }
// ]

// clock = Sinon.useFakeTimers(testDate)
// })

// it('only returns the billing period for that financial year', () => {
// const result = DetermineBillingPeriodsService.go(financialYearEnding)

// expect(result).to.have.length(1)
// expect(result).to.equal(expectedResult)
// })
// })
})
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const FetchLicenceUpdatesService = require('../../../../app/services/jobs/licenc
// Thing under test
const ProcessLicenceUpdatesService = require('../../../../app/services/jobs/licence-updates/process-licence-updates.js')

describe('Process Time Limited Licences service', () => {
describe('Process Licence Updates service', () => {
let fetchResults
let notifierStub

Expand Down Expand Up @@ -61,15 +61,15 @@ describe('Process Time Limited Licences service', () => {

expect(results).to.have.length(2)

expect(results[0].licenceVersionId).to.equal(fetchResults[0].id)
expect(results[0].licenceId).to.equal(fetchResults[0].licenceId)
expect(results[0].licenceVersionId).to.equal('ece3a745-d7b8-451e-8434-9977fbaa3bc1')
expect(results[0].licenceId).to.equal('a3f0bdeb-edcb-427d-9f79-c345d19d8aa1')
expect(results[0].status).to.equal('to_setup')
expect(results[0].data).to.equal({ chargeVersion: null, chargeVersionExists: fetchResults[0].chargeVersionExists })
expect(results[0].data).to.equal({ chargeVersion: null, chargeVersionExists: false })

expect(results[1].licenceVersionId).to.equal(fetchResults[1].id)
expect(results[1].licenceId).to.equal(fetchResults[1].licenceId)
expect(results[1].licenceVersionId).to.equal('cbd2195f-17c4-407d-b7ed-c3cd729c3dca')
expect(results[1].licenceId).to.equal('fa25c580-710e-48f0-8932-b2d18e391994')
expect(results[1].status).to.equal('to_setup')
expect(results[1].data).to.equal({ chargeVersion: null, chargeVersionExists: fetchResults[1].chargeVersionExists })
expect(results[1].data).to.equal({ chargeVersion: null, chargeVersionExists: true })
})

it('logs the time taken in milliseconds and seconds', async () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ describe('Fetch Time Limited Licences service', () => {
})

describe('when there are licences with elements due to expire in < 50 days that should be added to workflow', () => {
let chargeVersionId
let licenceId
let licenceVersionId

Expand All @@ -42,33 +43,36 @@ describe('Fetch Time Limited Licences service', () => {
licenceVersionId = licenceVersion.id

// This creates a 'current' SROC charge version
const { id: chargeVersionId } = await ChargeVersionHelper.add({ licenceId })
const chargeVersion = await ChargeVersionHelper.add({ licenceId })
chargeVersionId = chargeVersion.id

const { id: chargeReferenceId } = await ChargeReferenceHelper.add({ chargeVersionId })

// This creates a charge element that is due to expire in less than 50 days (49 days)
await ChargeElementHelper.add({ chargeReferenceId, timeLimitedEndDate: _offSetCurrentDateByDays(49) })
})

it('returns the licenceId and licenceVersionId for the SROC licence with an expiring element', async () => {
it('returns the licenceId, licenceVersionId and chargeVersionId for the SROC licence with an expiring element', async () => {
const result = await FetchTimeLimitedLicencesService.go()

expect(result).to.have.length(1)
expect(result[0].id).to.equal(licenceId)
expect(result[0].licenceVersionId).to.equal(licenceVersionId)
expect(result[0].chargeVersionId).to.equal(chargeVersionId)
})

describe('including those linked to soft-deleted workflow records', () => {
beforeEach(async () => {
await WorkflowHelper.add({ licenceId, deletedAt: new Date('2022-04-01') })
})

it('returns the licenceId and licenceVersionId for the SROC licence with an expiring element', async () => {
it('returns the licenceId, licenceVersionId and chargeVersionId for the SROC licence with an expiring element', async () => {
const result = await FetchTimeLimitedLicencesService.go()

expect(result).to.have.length(1)
expect(result[0].id).to.equal(licenceId)
expect(result[0].licenceVersionId).to.equal(licenceVersionId)
expect(result[0].chargeVersionId).to.equal(chargeVersionId)
})
})
})
Expand Down
Loading
Loading