-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Handle empty supplementary bill runs (#153)
https://eaflood.atlassian.net/browse/WATER-3923 From the charge version, we generate transaction lines. For each charge element (reference) we look at the charge purposes connected to it and calculate the billable days. If that result is 0, we skip adding the transaction to the bill run. This means there is often a case where having calculated and rejected all the transaction lines, the bill run is 'empty'. The legacy process will update the status of the bill run to `empty`, and remove any `billing_invoice` and `billing_invoice_licence` records created. We need to do the same, though we intend to take a different approach. We'll process all the transaction lines first and only create `billing_invoice` and `billing_invoice_licence` records for those that remain. Should there be none, we'll go straight to marking the bill run as `empty` and stop the process there. Our intent is to remove needless calls to the DB and simplify the process.
- Loading branch information
1 parent
7b18e8d
commit b3d9b0d
Showing
11 changed files
with
445 additions
and
317 deletions.
There are no files selected for viewing
44 changes: 0 additions & 44 deletions
44
app/services/supplementary-billing/create-billing-invoice-licence.service.js
This file was deleted.
Oops, something went wrong.
55 changes: 0 additions & 55 deletions
55
app/services/supplementary-billing/create-billing-invoice.service.js
This file was deleted.
Oops, something went wrong.
31 changes: 0 additions & 31 deletions
31
app/services/supplementary-billing/fetch-invoice-account.service.js
This file was deleted.
Oops, something went wrong.
70 changes: 70 additions & 0 deletions
70
app/services/supplementary-billing/generate-billing-invoice-licence.service.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
'use strict' | ||
|
||
/** | ||
* Generates a billing invoice licence record ready for persisting | ||
* @module GenerateBillingInvoiceLicenceService | ||
*/ | ||
|
||
const { randomUUID } = require('crypto') | ||
|
||
/** | ||
* Return either a new billing invoice licence object ready for persisting or an existing one if it exists | ||
* | ||
* This first checks whether a billing invoice licence with the same invoice and licence ID exists in | ||
* `generatedBillingInvoiceLicences`. The calling service is expected to provide and keep track of this variable | ||
* between calls. If it does, it returns that instance along with the original array unchanged. | ||
* | ||
* If it doesn't, we generate a new instance and create a new array, based on the one provided plus our new instance. | ||
* We then return the instance and the new array as the result. | ||
* | ||
* For context, this is all to avoid creating `billing_invoice` and `billing_invoice_licence` records unnecessarily. | ||
* The legacy service will create them first, then determine if there are any transactions to be billed. If there | ||
* aren't, it then has to go back and delete the records it created. | ||
* | ||
* Our intent is to only call the DB when we have records that need persisting. So, we start at the transaction level | ||
* and only persist `billing_invoice` and `billing_invoice_licence` records that are linked to billable transactions. | ||
* But to persist the billing transactions we need the foreign keys. So, we generate our billing invoice and billing | ||
* licence data in memory along with ID's, and use this service to provide the right record when persisting the | ||
* transaction. | ||
* | ||
* @param {Object[]} generatedBillingInvoiceLicences An array of previously generated billing invoice licence objects | ||
* @param {string} billingInvoiceId UUID of the billing invoice this billing invoice licence will be linked to if | ||
* persisted | ||
* @param {module:LicenceModel} licence the licence this billing invoice licence will be linked to | ||
* | ||
* @returns {Object} A result object containing either the found or generated billing invoice licence object, and an | ||
* array of generated billing invoice licences which includes the one being returned | ||
*/ | ||
function go (generatedBillingInvoiceLicences, billingInvoiceId, licence) { | ||
let billingInvoiceLicence = _existing(generatedBillingInvoiceLicences, billingInvoiceId, licence.licenceId) | ||
|
||
if (billingInvoiceLicence) { | ||
return { | ||
billingInvoiceLicence, | ||
billingInvoiceLicences: generatedBillingInvoiceLicences | ||
} | ||
} | ||
|
||
billingInvoiceLicence = { | ||
billingInvoiceId, | ||
billingInvoiceLicenceId: randomUUID({ disableEntropyCache: true }), | ||
licenceRef: licence.licenceRef, | ||
licenceId: licence.licenceId | ||
} | ||
const updatedBillingInvoiceLicences = [...generatedBillingInvoiceLicences, billingInvoiceLicence] | ||
|
||
return { | ||
billingInvoiceLicence, | ||
billingInvoiceLicences: updatedBillingInvoiceLicences | ||
} | ||
} | ||
|
||
function _existing (generatedBillingInvoiceLicences, billingInvoiceId, licenceId) { | ||
return generatedBillingInvoiceLicences.find((invoiceLicence) => { | ||
return (billingInvoiceId === invoiceLicence.billingInvoiceId && licenceId === invoiceLicence.licenceId) | ||
}) | ||
} | ||
|
||
module.exports = { | ||
go | ||
} |
77 changes: 77 additions & 0 deletions
77
app/services/supplementary-billing/generate-billing-invoice.service.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
'use strict' | ||
|
||
/** | ||
* Generates a billing invoice record ready for persisting | ||
* @module GenerateBillingInvoiceService | ||
*/ | ||
|
||
const { randomUUID } = require('crypto') | ||
|
||
const InvoiceAccountModel = require('../../models/crm-v2/invoice-account.model.js') | ||
|
||
/** | ||
* Return either a new billing invoice object ready for persisting or an existing one if it exists | ||
* | ||
* This first checks whether a billing invoice with the same invoice account ID exists in | ||
* `generatedBillingInvoices`. The calling service is expected to provide and keep track of this variable between | ||
* between calls. If it does, it returns that instance along with the original array unchanged. | ||
* | ||
* If it doesn't, we generate a new instance and create a new array, based on the one provided plus our new instance. | ||
* We then return the instance and the new array as the result. | ||
* | ||
* For context, this is all to avoid creating `billing_invoice` and `billing_invoice_licence` records unnecessarily. | ||
* The legacy service will create them first, then determine if there are any transactions to be billed. If there | ||
* aren't, it then has to go back and delete the records it created. | ||
* | ||
* Our intent is to only call the DB when we have records that need persisting. So, we start at the transaction level | ||
* and only persist `billing_invoice` and `billing_invoice_licence` records that are linked to billable transactions. | ||
* But to persist the billing transactions we need the foreign keys. So, we generate our billing invoice and billing | ||
* licence data in memory along with ID's, and use this service to provide the right record when persisting the | ||
* transaction. | ||
* | ||
* @param {Object[]} generatedBillingInvoices An array of previously generated billing invoice objects | ||
* @param {*} invoiceAccountId UUID of the invoice account this billing invoice will be linked to if persisted | ||
* @param {*} billingBatchId UUID of the billing batch this billing invoice will be linked to if persisted | ||
* @param {*} financialYearEnding a value that must exist in the persisted record | ||
* | ||
* @returns {Object} A result object containing either the found or generated billing invoice object, and an array of | ||
* generated billing invoices which includes the one being returned | ||
*/ | ||
async function go (generatedBillingInvoices, invoiceAccountId, billingBatchId, financialYearEnding) { | ||
let billingInvoice = _existing(generatedBillingInvoices, invoiceAccountId) | ||
|
||
if (billingInvoice) { | ||
return { | ||
billingInvoice, | ||
billingInvoices: generatedBillingInvoices | ||
} | ||
} | ||
|
||
const invoiceAccount = await InvoiceAccountModel.query().findById(invoiceAccountId) | ||
|
||
billingInvoice = { | ||
billingBatchId, | ||
financialYearEnding, | ||
invoiceAccountId, | ||
billingInvoiceId: randomUUID({ disableEntropyCache: true }), | ||
address: {}, // Address is set to an empty object for SROC billing invoices | ||
invoiceAccountNumber: invoiceAccount.invoiceAccountNumber, | ||
isCredit: false | ||
} | ||
const updatedBillingInvoices = [...generatedBillingInvoices, billingInvoice] | ||
|
||
return { | ||
billingInvoice, | ||
billingInvoices: updatedBillingInvoices | ||
} | ||
} | ||
|
||
function _existing (generatedBillingInvoices, invoiceAccountId) { | ||
return generatedBillingInvoices.find((invoice) => { | ||
return invoiceAccountId === invoice.invoiceAccountId | ||
}) | ||
} | ||
|
||
module.exports = { | ||
go | ||
} |
Oops, something went wrong.