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

Reverse previous SROC billing batches in supplementary bill run process #186

Merged
merged 3 commits into from
Apr 11, 2023
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,7 +1,8 @@
'use strict'

/**
* Fetches the previously billed transactions that match the invoice, licence and year provided
* Fetches the previously billed transactions that match the invoice, licence and year provided, removing any debits
* which are cancelled out by previous credits.
* @module FetchPreviousBillingTransactionsService
*/

Expand All @@ -14,7 +15,29 @@ async function go (billingInvoice, billingInvoiceLicence, financialYearEnding) {
financialYearEnding
)

return billingTransactions
return _cleanse(billingTransactions)
}

/**
* Cleanse the billing transactions by cancelling out matching pairs of debits and credits, and return the remaining
* debits. We judge a pair of credits and debits to be matching if they have the same number of billable days and the
* same charge type.
*/
function _cleanse (billingTransactions) {
const credits = billingTransactions.filter((transaction) => transaction.isCredit)
const debits = billingTransactions.filter((transaction) => !transaction.isCredit)

for (const credit of credits) {
const debitIndex = debits.findIndex((debit) => {
return debit.billableDays === credit.billableDays && debit.chargeType === credit.chargeType
})

if (debitIndex > -1) {
debits.splice(debitIndex, 1)
}
}

return debits
}

async function _fetch (licenceId, invoiceAccountId, financialYearEnding) {
Expand Down Expand Up @@ -70,14 +93,9 @@ async function _fetch (licenceId, invoiceAccountId, financialYearEnding) {
'bb.status': 'sent',
'bb.scheme': 'sroc'
})
.orderBy('bb.dateCreated', 'desc')
.limit(1)
.as('validBillingInvoices'),
'bt.billingInvoiceLicenceId', 'validBillingInvoices.billingInvoiceLicenceId'
)
.where({
'bt.isCredit': false
})
}

module.exports = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,7 @@ describe('Fetch Previous Billing Transactions service', () => {
describe('when there is a bill run', () => {
describe('for the same licence and invoice account', () => {
beforeEach(async () => {
const { billingBatchId } = await BillingBatchHelper.add({ status: 'sent' })
const { billingInvoiceId } = await BillingInvoiceHelper.add({ invoiceAccountId }, { billingBatchId })
const { billingInvoiceLicenceId } = await BillingInvoiceLicenceHelper.add(
{},
{ licenceId },
{ billingInvoiceId }
)
const billingInvoiceLicenceId = await _createBillingBatchInvoiceAndLicence(invoiceAccountId, licenceId)
await BillingTransactionHelper.add({ billingInvoiceLicenceId })
})

Expand All @@ -63,14 +57,35 @@ describe('Fetch Previous Billing Transactions service', () => {

describe('followed by another run which credits the previous', () => {
beforeEach(async () => {
const { billingBatchId } = await BillingBatchHelper.add({ status: 'sent' })
const { billingInvoiceId } = await BillingInvoiceHelper.add({ invoiceAccountId }, { billingBatchId })
const { billingInvoiceLicenceId } = await BillingInvoiceLicenceHelper.add(
{},
const billingInvoiceLicenceId = await _createBillingBatchInvoiceAndLicence(invoiceAccountId, licenceId)
await BillingTransactionHelper.add({ billingInvoiceLicenceId, isCredit: true })
})

it('returns no results', async () => {
const result = await FetchPreviousBillingTransactionsService.go(
{ invoiceAccountId },
{ licenceId },
{ billingInvoiceId }
financialYearEnding
)
await BillingTransactionHelper.add({ billingInvoiceLicenceId, isCredit: true })

expect(result).to.be.empty()
})
})

describe('followed by more runs with equal credits and debits', () => {
beforeEach(async () => {
const creditsBillingInvoiceLicenceId = await _createBillingBatchInvoiceAndLicence(invoiceAccountId, licenceId)
await BillingTransactionHelper.add({
billingInvoiceLicenceId: creditsBillingInvoiceLicenceId,
isCredit: true
})
await BillingTransactionHelper.add({
billingInvoiceLicenceId: creditsBillingInvoiceLicenceId,
isCredit: true
})

const debitBillingInvoiceLicenceId = await _createBillingBatchInvoiceAndLicence(invoiceAccountId, licenceId)
await BillingTransactionHelper.add({ billingInvoiceLicenceId: debitBillingInvoiceLicenceId })
})

it('returns no results', async () => {
Expand All @@ -83,17 +98,42 @@ describe('Fetch Previous Billing Transactions service', () => {
expect(result).to.be.empty()
})
})

describe('followed by more runs with unequal credits and debits', () => {
beforeEach(async () => {
const unmatchedBillingInvoiceLicenceId = await _createBillingBatchInvoiceAndLicence(
invoiceAccountId,
licenceId
)
await BillingTransactionHelper.add({
billingInvoiceLicenceId: unmatchedBillingInvoiceLicenceId,
billableDays: 30,
isCredit: true
})

const matchedBillingInvoiceLicenceId = await _createBillingBatchInvoiceAndLicence(invoiceAccountId, licenceId)
await BillingTransactionHelper.add({
billingInvoiceLicenceId: matchedBillingInvoiceLicenceId,
isCredit: true
})
await BillingTransactionHelper.add({ billingInvoiceLicenceId: matchedBillingInvoiceLicenceId })
})

it('returns results', async () => {
const result = await FetchPreviousBillingTransactionsService.go(
{ invoiceAccountId },
{ licenceId },
financialYearEnding
)

expect(result).to.have.length(1)
})
})
})

describe('but for a different licence', () => {
beforeEach(async () => {
const { billingBatchId } = await BillingBatchHelper.add({ status: 'sent' })
const { billingInvoiceId } = await BillingInvoiceHelper.add({ invoiceAccountId }, { billingBatchId })
const { billingInvoiceLicenceId } = await BillingInvoiceLicenceHelper.add(
{},
{ licenceId: '66498337-e6a6-4a2a-9fb7-e39f43410f80' },
{ billingInvoiceId }
)
const billingInvoiceLicenceId = await _createBillingBatchInvoiceAndLicence(invoiceAccountId, '66498337-e6a6-4a2a-9fb7-e39f43410f80')
await BillingTransactionHelper.add({ billingInvoiceLicenceId })
})

Expand All @@ -110,15 +150,9 @@ describe('Fetch Previous Billing Transactions service', () => {

describe('but for a different invoice account', () => {
beforeEach(async () => {
const { billingBatchId } = await BillingBatchHelper.add({ status: 'sent' })
const { billingInvoiceId } = await BillingInvoiceHelper.add(
{ invoiceAccountId: 'b0b75e7a-e80a-4c28-9ac9-33b3a850722b' },
{ billingBatchId }
)
const { billingInvoiceLicenceId } = await BillingInvoiceLicenceHelper.add(
{},
{ licenceId },
{ billingInvoiceId }
const billingInvoiceLicenceId = await _createBillingBatchInvoiceAndLicence(
'b0b75e7a-e80a-4c28-9ac9-33b3a850722b',
licenceId
)
await BillingTransactionHelper.add({ billingInvoiceLicenceId })
})
Expand All @@ -135,3 +169,15 @@ describe('Fetch Previous Billing Transactions service', () => {
})
})
})

async function _createBillingBatchInvoiceAndLicence (invoiceAccountId, licenceId) {
const { billingBatchId } = await BillingBatchHelper.add({ status: 'sent' })
const { billingInvoiceId } = await BillingInvoiceHelper.add({ invoiceAccountId }, { billingBatchId })
const { billingInvoiceLicenceId } = await BillingInvoiceLicenceHelper.add(
{},
{ licenceId },
{ billingInvoiceId }
)

return billingInvoiceLicenceId
}