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

Persisting the results data from the two-part tariff match and allocate service #616

Merged
merged 26 commits into from
Jan 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
49c9d94
Persisting the results data from the two-part tariff match and alloca…
Beckyrose200 Dec 20, 2023
021dffd
Create `PersistAllocatedLicencesToResultsService`
Jozzey Dec 21, 2023
b3403a7
Merge branch 'main' into persist-two-part-tariff-results
Beckyrose200 Dec 21, 2023
552462e
Fix typos
Jozzey Dec 21, 2023
76ed69f
Merge branch 'main' into persist-two-part-tariff-results
Jozzey Dec 22, 2023
d59c054
Refactor `reviewReturnResultId` now it's generated in the prep service
Jozzey Dec 22, 2023
8991e0e
Merge branch 'main' into persist-two-part-tariff-results
Jozzey Dec 22, 2023
085404f
Update prepare service to generate the `reviewReturnResultId`
Jozzey Dec 22, 2023
373bd46
Add `public` schema to DB helper
Jozzey Dec 28, 2023
3a1e2ac
Create unit tests for persisting service
Jozzey Dec 28, 2023
d1381c6
Fix migration scripts
Jozzey Dec 28, 2023
98a057b
Tidy up
Jozzey Dec 28, 2023
1c0a4d0
Merge branch 'main' into persist-two-part-tariff-results
Jozzey Dec 29, 2023
e160f02
Merge branch 'main' into persist-two-part-tariff-results
Beckyrose200 Jan 3, 2024
aad4dfc
Updated comment
Beckyrose200 Jan 3, 2024
4ac3845
Merge branch 'main' into persist-two-part-tariff-results
Beckyrose200 Jan 3, 2024
acb3d3f
Merge branch 'main' into persist-two-part-tariff-results
Beckyrose200 Jan 4, 2024
f29f536
Add comment to migration to explain the decimal
Jozzey Jan 8, 2024
4df73d1
Add comment to migration to explain the decimal
Jozzey Jan 8, 2024
85b1600
Add Alan's comment
Jozzey Jan 8, 2024
a47b8c0
Merge branch 'main' into persist-two-part-tariff-results
Jozzey Jan 8, 2024
a68d696
Move where `reviewReturnResultId` gets set
Jozzey Jan 8, 2024
f30b909
Move where ID is generated
Cruikshanks Jan 8, 2024
f287c73
Update to use DB Id rather than pre-generated one
Cruikshanks Jan 8, 2024
8535cab
Add comment to explain process
Jozzey Jan 8, 2024
916ae1e
Merge branch 'main' into persist-two-part-tariff-results
Jozzey Jan 8, 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,168 @@
'use strict'

/**
* Persists the results from the `allocateReturnsToLicenceService` into the DB
* @module PersistAllocatedLicencesToResultsService
*/

const ReviewChargeElementResultModel = require('../../../models/review-charge-element-result.model.js')
const ReviewReturnResultModel = require('../../../models/review-return-result.model.js')
const ReviewResultModel = require('../../../models/review-result.model.js')

/**
* Persists results of matching and allocating return logs to licence charge elements for a two-part tariff bill run
*
* Each licence will have a `returnLogs` property that contains all return logs linked to the licence for the billing
* period of the bill run. It will also have a `chargeVersions` property, which within each one it will have details of
* which charge elements matched to which return logs and whether anything was allocated to the charge element from
* them.
*
* We need to persist all this information ready for use in the review screens that our users use to asses if the
* matching and allocating looks correct or if any issues need resolving first.
*
* @param {String} billRunId - the ID of the two-part tariff bill run being generated
* @param {Object[]} licences - the two-part tariff licences included in the bill run, along with their match and
* allocation results
*/
async function go (billRunId, licences) {
for (const licence of licences) {
const { chargeVersions, returnLogs } = licence

const reviewReturnResultIds = await _persistReturnLogs(returnLogs, billRunId, licence)

for (const chargeVersion of chargeVersions) {
const { chargeReferences } = chargeVersion

for (const chargeReference of chargeReferences) {
const { chargeElements } = chargeReference

for (const chargeElement of chargeElements) {
await _persistChargeElement(
billRunId,
licence,
chargeVersion,
chargeReference,
chargeElement,
reviewReturnResultIds
)
}
}
}
}
}

async function _persistChargeElement (
billRunId,
licence,
chargeVersion,
chargeReference,
chargeElement,
reviewReturnResultIds
) {
const reviewChargeElementResultId = await _persistReviewChargeElementResult(chargeElement, chargeReference)

// Persisting the charge elements that have a matching return
if (chargeElement.returnLogs.length > 0) {
for (const returnLog of chargeElement.returnLogs) {
// When we persist the review result we need the Id's for both the charge element and return log's review result
// records. Though it looks like we're iterating return logs here, these are copies assigned during matching and
// allocation. We don't create `ReviewReturnResult` records until this service is called, and those are based
// on the `returnLogs` property of each licence. Hence, we need to pass in the ID's created and search them for
// a match in order to get the `reviewReturnResultId`.
const { reviewReturnResultId } = reviewReturnResultIds.find((reviewReturnResultIds) => {
return reviewReturnResultIds.returnId === returnLog.returnId
Jozzey marked this conversation as resolved.
Show resolved Hide resolved
})

await _persistReviewResult(
billRunId,
licence,
chargeVersion,
chargeReference,
reviewChargeElementResultId,
reviewReturnResultId
)
}
} else {
// Persisting the charge element without any matching returns
await _persistReviewResult(billRunId, licence, chargeVersion, chargeReference, reviewChargeElementResultId, null)
}
}

async function _persistReturnLogs (returnLogs, billRunId, licence) {
const reviewReturnResultIds = []

for (const returnLog of returnLogs) {
const reviewReturnResultId = await _persistReviewReturnResult(returnLog)
reviewReturnResultIds.push({ returnId: returnLog.id, reviewReturnResultId })

// Persisting the unmatched return logs
if (returnLog.matched === false) {
_persistReviewResult(billRunId, licence, null, null, null, reviewReturnResultId)
}
}

return reviewReturnResultIds
}

async function _persistReviewChargeElementResult (chargeElement, chargeReference) {
const data = {
chargeElementId: chargeElement.id,
allocated: chargeElement.allocatedQuantity,
aggregate: chargeReference.aggregate ?? 1,
chargeDatesOverlap: chargeElement.chargeDatesOverlap
}

const { id: reviewChargeElementResultId } = await ReviewChargeElementResultModel.query().insert(data).returning('id')

return reviewChargeElementResultId
}

async function _persistReviewResult (
billRunId,
licence,
chargeVersion,
chargeReference,
reviewChargeElementResultId,
reviewReturnResultId
) {
const data = {
billRunId,
licenceId: licence.id,
chargeVersionId: chargeVersion?.id,
chargeReferenceId: chargeReference?.id,
chargePeriodStartDate: chargeVersion?.chargePeriod.startDate,
chargePeriodEndDate: chargeVersion?.chargePeriod.endDate,
chargeVersionChangeReason: chargeVersion?.changeReason.description,
reviewChargeElementResultId,
reviewReturnResultId
}

await ReviewResultModel.query().insert(data)
}

async function _persistReviewReturnResult (returnLog) {
const data = {
returnId: returnLog.id,
returnReference: returnLog.returnRequirement,
startDate: returnLog.startDate,
endDate: returnLog.endDate,
dueDate: returnLog.dueDate,
receivedDate: returnLog.receivedDate,
status: returnLog.status,
underQuery: returnLog.underQuery,
nilReturn: returnLog.nilReturn,
description: returnLog.description,
purposes: returnLog.purposes,
quantity: returnLog.quantity,
allocated: returnLog.allocatedQuantity,
abstractionOutsidePeriod: returnLog.abstractionOutsidePeriod
}

const { id: reviewReturnResultId } = await ReviewReturnResultModel.query().insert(data).returning('id')

return reviewReturnResultId
}

module.exports = {
go
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@ exports.up = function (knex) {

// Data
table.uuid('charge_element_id').notNullable()
table.decimal('allocated').defaultTo(0)
table.decimal('aggregate').defaultTo(1)
// Specifying `null, null` creates a decimal column that can store numbers of any precision and scale
table.decimal('allocated', null, null).defaultTo(0)
table.decimal('aggregate', null, null).defaultTo(1)
Jozzey marked this conversation as resolved.
Show resolved Hide resolved
table.boolean('charge_dates_overlap').defaultTo(false)

// Automatic timestamps
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,9 @@ exports.up = function (knex) {
table.boolean('nil_return').defaultTo(false)
table.string('description')
table.jsonb('purposes')
table.decimal('quantity').defaultTo(0)
table.decimal('allocated').defaultTo(0)
// Specifying `null, null` creates a decimal column that can store numbers of any precision and scale
table.decimal('quantity', null, null).defaultTo(0)
table.decimal('allocated', null, null).defaultTo(0)
Jozzey marked this conversation as resolved.
Show resolved Hide resolved
table.boolean('abstraction_outside_period').defaultTo(false)

// Automatic timestamps
Expand Down
4 changes: 2 additions & 2 deletions db/migrations/public/20231122152504_create-review-results.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ exports.up = function (knex) {
// Data
table.uuid('bill_run_id').notNullable()
table.uuid('licence_id').notNullable()
table.uuid('charge_version_id').notNullable()
table.uuid('charge_reference_id').notNullable()
table.uuid('charge_version_id')
table.uuid('charge_reference_id')
table.date('charge_period_start_date')
table.date('charge_period_end_date')
table.string('charge_version_change_reason')
Expand Down
Loading
Loading