Skip to content

Commit

Permalink
BillingTransaction to Transaction
Browse files Browse the repository at this point in the history
  • Loading branch information
Cruikshanks committed Sep 12, 2023
1 parent cf97417 commit ff405cf
Show file tree
Hide file tree
Showing 33 changed files with 297 additions and 296 deletions.
4 changes: 2 additions & 2 deletions app/models/water/bill-licence.model.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,9 @@ class BillLicenceModel extends WaterBaseModel {
to: 'billingInvoices.billingInvoiceId'
}
},
billingTransactions: {
transactions: {
relation: Model.HasManyRelation,
modelClass: 'billing-transaction.model',
modelClass: 'transaction.model',
join: {
from: 'billingInvoiceLicences.billingInvoiceLicenceId',
to: 'billingTransactions.billingInvoiceLicenceId'
Expand Down
4 changes: 2 additions & 2 deletions app/models/water/charge-element.model.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,9 @@ class ChargeElementModel extends WaterBaseModel {
to: 'chargePurposes.chargeElementId'
}
},
billingTransactions: {
transactions: {
relation: Model.HasManyRelation,
modelClass: 'billing-transaction.model',
modelClass: 'transaction.model',
join: {
from: 'chargeElements.chargeElementId',
to: 'billingTransactions.chargeElementId'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@

/**
* Model for billing_transactions
* @module BillingTransactionModel
* @module TransactionModel
*/

const { Model } = require('objection')

const WaterBaseModel = require('./water-base.model.js')

class BillingTransactionModel extends WaterBaseModel {
class TransactionModel extends WaterBaseModel {
static get tableName () {
return 'billingTransactions'
}
Expand Down Expand Up @@ -57,4 +57,4 @@ class BillingTransactionModel extends WaterBaseModel {
}
}

module.exports = BillingTransactionModel
module.exports = TransactionModel
10 changes: 4 additions & 6 deletions app/presenters/charging-module/create-transaction.presenter.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,14 @@
const { formatChargingModuleDate } = require('../base.presenter.js')

/**
* Formats a transaction object, generated by `FormatSrocTransactionLineService`, as a Charging Module API transaction
* request
* Formats a transaction as a Charging Module API transaction request
*
* @param {Object} transaction the object returned by `FormatSrocTransactionLineService` which represents a WRLS
* transaction ready to be saved to the DB
* @param {Object} billingPeriod an object representing the financial year the transaction is for
* @param {Object} transaction the transaction object
* @param {Object} billingPeriod The billing period of the transaction
* @param {string} invoiceAccountNumber known as the customer reference in the Charging Module API
* @param {module:LicenceModel} licence an instance of LicenceModel
*
* @returns {Object} an object that can be directly used as the body in a charging module POST transaction request
* @returns {Object} an object to be used as the body in a Charging Module POST transaction request
*/
function go (transaction, billingPeriod, invoiceAccountNumber, licence) {
const periodStart = formatChargingModuleDate(billingPeriod.startDate)
Expand Down
12 changes: 6 additions & 6 deletions app/presenters/data/mock-bill-run.presenter.js
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ function _formatBills (bills) {
function _formatBillLicences (billLicences) {
return billLicences.map((billLicence) => {
const {
billingTransactions,
transactions,
credit,
debit,
netTotal,
Expand All @@ -138,13 +138,13 @@ function _formatBillLicences (billLicences) {
credit: formatNumberAsMoney(convertPenceToPounds(credit)),
debit: formatNumberAsMoney(convertPenceToPounds(debit)),
netTotal: formatNumberAsMoney(convertPenceToPounds(netTotal)),
transactions: _formatBillingTransactions(billingTransactions)
transactions: _formatTransactions(transactions)
}
})
}

function _formatBillingTransactions (billingTransactions) {
return billingTransactions.map((billingTransaction) => {
function _formatTransactions (transactions) {
return transactions.map((transaction) => {
const {
authorisedDays,
billableDays,
Expand All @@ -159,7 +159,7 @@ function _formatBillingTransactions (billingTransactions) {
billableQuantity: chargeQuantity,
chargeCategoryDescription: chargeDescription,
description: lineDescription
} = billingTransaction
} = transaction

return {
type: chargeType === 'standard' ? 'Water abstraction charge' : 'Compensation charge',
Expand All @@ -172,7 +172,7 @@ function _formatBillingTransactions (billingTransactions) {
chargePeriod: `${formatLongDate(startDate)} to ${formatLongDate(endDate)}`,
chargeRefNumber: `${chargeCategoryCode} (${formatNumberAsMoney(grossValuesCalculated.baselineCharge, true)})`,
chargeDescription,
addCharges: _formatAdditionalCharges(billingTransaction),
addCharges: _formatAdditionalCharges(transaction),
adjustments: _formatAdjustments(chargeElement),
elements: _formatChargePurposes(chargeElement.chargePurposes)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
* This is to cover scenarios where a charge version with a start date in 2022-23 would have resulted in a debit in both
* 2022-23 and 2023-24. Then a new charge version is added that starts in 2022-23. The old one is still valid, but the
* 2023-24 debit for it needs to be credited. We only know to do that by fetching it when running the
* `ProcessBillingPeriodService` for 2023-24 so `ProcessBillingTransactionsService` will fetch the previous transactions
* `ProcessBillingPeriodService` for 2023-24 so `ProcessTransactionsService` will fetch the previous transactions
* for it.
*
* Add to that licences that end before the charge version or billing period and you get scenarios where the start and
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ async function go (regionId) {
.joinRelated('billRun')
.where('billRun.regionId', regionId)
.where('billRun.scheme', 'sroc')
.withGraphFetched('billLicences.billingTransactions')
.withGraphFetched('billLicences.transactions')
.modifyGraph('billLicences', (builder) => {
builder.select(
'licenceRef',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
/**
* Fetches the previously billed transactions that match the bill, licence and year provided, removing any debits
* which are cancelled out by previous credits.
* @module FetchPreviousBillingTransactionsService
* @module FetchPreviousTransactionsService
*/

const { db } = require('../../../../db/db.js')
Expand All @@ -18,28 +18,27 @@ const { db } = require('../../../../db/db.js')
* match against
* @param {Number} financialYearEnding The year the financial billing period ends that we need to match against
*
* @returns {Object} The resulting matched billing transactions
* @returns {Object} The resulting matched transactions
*/
async function go (bill, billLicence, financialYearEnding) {
const billingTransactions = await _fetch(
const transactions = await _fetch(
billLicence.licenceId,
bill.invoiceAccountId,
financialYearEnding
)

return _cleanse(billingTransactions)
return _cleanse(transactions)
}

/**
* Cleanse the billing transactions by cancelling out matching pairs of debits and credits, and return the remaining
* debits.
* Cleanse the transactions by cancelling out matching pairs of debits and credits, and return the remaining debits.
*
* If a credit matches to a debit then its something that was dealt with in a previous supplementary bill run. We need
* to know only about debits that have not been credited.
*/
function _cleanse (billingTransactions) {
const credits = billingTransactions.filter((transaction) => transaction.isCredit)
const debits = billingTransactions.filter((transaction) => !transaction.isCredit)
function _cleanse (transactions) {
const credits = transactions.filter((transaction) => transaction.isCredit)
const debits = transactions.filter((transaction) => !transaction.isCredit)

credits.forEach((credit) => {
const debitIndex = debits.findIndex((debit) => {
Expand Down Expand Up @@ -78,13 +77,15 @@ function _cleanse (billingTransactions) {
*/
function _matchTransactions (debit, credit) {
// TODO: This logic is a duplicate of what we are doing in
// app/services/supplementary-billing/process-billing-transactions.service.js. This also means we are running the
// app/services/supplementary-billing/process-transactions.service.js. This also means we are running the
// same kind of unit tests on 2 places. We need to refactor this duplication in the code and the tests out.

// When we put together this matching logic our instincts were to try and do something 'better' than this long,
// When we put together this matching logic our instincts was to try and do something 'better' than this long,
// chained && statement. But whatever we came up with was
//
// - more complex
// - less performant
//
// We found this easy to see what properties are being compared. Plus the moment something doesn't match we bail. So,
// much as it feels 'wrong', we are sticking with it!
return debit.chargeType === credit.chargeType &&
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
'use strict'

/**
* Generate billing transaction data from the the charge element and other information passed in
* @module GenerateBillingTransactionsService
* Generate transaction data from the the charge element and other information passed in
* @module GenerateTransactionsService
*/

const { generateUUID } = require('../../../lib/general.lib.js')
Expand Down Expand Up @@ -39,10 +39,10 @@ function go (chargeElement, billingPeriod, chargePeriod, isNewLicence, isWaterUn
chargeElement
)

const billingTransactions = []
const transactions = []

if (billableDays === 0) {
return billingTransactions
return transactions
}

const standardTransaction = _standardTransaction(
Expand All @@ -54,24 +54,24 @@ function go (chargeElement, billingPeriod, chargePeriod, isNewLicence, isWaterUn
isNewLicence,
isWaterUndertaker
)
billingTransactions.push(standardTransaction)
transactions.push(standardTransaction)

if (!isWaterUndertaker) {
const compensationTransaction = _compensationTransaction(generateUUID(), standardTransaction)
billingTransactions.push(compensationTransaction)
transactions.push(compensationTransaction)
}

return billingTransactions
return transactions
}

/**
* Generates a compensation transaction by taking a standard transaction and overwriting it with the supplied billing id
* and the correct charge type and description for a compensation charge.
*/
function _compensationTransaction (billingTransactionId, standardTransaction) {
function _compensationTransaction (transactionId, standardTransaction) {
return {
...standardTransaction,
billingTransactionId,
billingTransactionId: transactionId,
chargeType: 'compensation',
description: 'Compensation charge: calculated from the charge reference, activity description and regional environmental improvement charge; excludes any supported source additional charge and two-part tariff charge agreement'
}
Expand Down Expand Up @@ -101,7 +101,7 @@ function _generatePurposes (chargeElement) {
* Generates a standard transaction based on the supplied data, along with some default fields (eg. status)
*/
function _standardTransaction (
billingTransactionId,
transactionId,
authorisedDays,
billableDays,
chargeElement,
Expand All @@ -110,7 +110,7 @@ function _standardTransaction (
isWaterUndertaker
) {
return {
billingTransactionId,
billingTransactionId: transactionId,
authorisedDays,
billableDays,
isNewLicence,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@ const BillRunError = require('../../../errors/bill-run.error.js')
const BillRunModel = require('../../../models/water/bill-run.model.js')
const BillModel = require('../../../models/water/bill.model.js')
const BillLicenceModel = require('../../../models/water/bill-licence.model.js')
const BillingTransactionModel = require('../../../models/water/billing-transaction.model.js')
const DetermineChargePeriodService = require('./determine-charge-period.service.js')
const DetermineMinimumChargeService = require('./determine-minimum-charge.service.js')
const GenerateBillingTransactionsService = require('./generate-billing-transactions.service.js')
const GenerateTransactionsService = require('./generate-transactions.service.js')
const PreGenerateBillingDataService = require('./pre-generate-billing-data.service.js')
const ProcessBillingTransactionsService = require('./process-billing-transactions.service.js')
const SendBillingTransactionsService = require('./send-billing-transactions.service.js')
const ProcessTransactionsService = require('./process-transactions.service.js')
const SendTransactionsService = require('./send-transactions.service.js')
const TransactionModel = require('../../../models/water/transaction.model.js')

/**
* Creates the bills and transactions in both WRLS and the Charging Module API
Expand Down Expand Up @@ -61,7 +61,7 @@ async function _buildDataToPersist (billingData, billingPeriod, billRunExternalI
const cleansedTransactions = await _cleanseTransactions(currentBillingData, billingPeriod)

if (cleansedTransactions.length !== 0) {
const billingTransactions = await SendBillingTransactionsService.go(
const transactions = await SendTransactionsService.go(
currentBillingData.licence,
currentBillingData.bill,
currentBillingData.billLicence,
Expand All @@ -70,7 +70,7 @@ async function _buildDataToPersist (billingData, billingPeriod, billRunExternalI
billingPeriod
)

dataToPersist.transactions.push(...billingTransactions)
dataToPersist.transactions.push(...transactions)
// Note that sets use add rather than push
dataToPersist.bills.add(currentBillingData.bill)
dataToPersist.billLicences.push(currentBillingData.billLicence)
Expand Down Expand Up @@ -138,7 +138,7 @@ async function _persistData (dataToPersist) {
return false
}

await BillingTransactionModel.query().insert(dataToPersist.transactions)
await TransactionModel.query().insert(dataToPersist.transactions)
await BillModel.query().insert(dataToPersist.bills)
await BillLicenceModel.query().insert(dataToPersist.billLicences)

Expand Down Expand Up @@ -176,7 +176,7 @@ async function _cleanseTransactions (currentBillingData, billingPeriod) {
return []
}

const cleansedTransactions = await ProcessBillingTransactionsService.go(
const cleansedTransactions = await ProcessTransactionsService.go(
currentBillingData.calculatedTransactions,
currentBillingData.bill,
currentBillingData.billLicence,
Expand All @@ -197,9 +197,9 @@ function _generateCalculatedTransactions (billingPeriod, chargeVersion) {
const isNewLicence = DetermineMinimumChargeService.go(chargeVersion, chargePeriod)
const isWaterUndertaker = chargeVersion.licence.isWaterUndertaker

// We use flatMap as GenerateBillingTransactionsService returns an array of transactions
// We use flatMap as GenerateTransactionsService returns an array of transactions
const transactions = chargeVersion.chargeElements.flatMap((chargeElement) => {
return GenerateBillingTransactionsService.go(
return GenerateTransactionsService.go(
chargeElement,
billingPeriod,
chargePeriod,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
'use strict'

/**
* Fetches the matching debit billing transactions from a previous bill run and reverses them as credits; removes
* any which would be cancelled out by the supplied calculated debit transactions; combines the remaining transactions
* and returns them all
* @module ProcessBillingTransactionsService
* Fetches the matching debit transactions from a previous bill run and reverses them as credits; removes any which
* would be cancelled out by the supplied calculated debit transactions; combines the remaining transactions and returns
* them all
* @module ProcessTransactionsService
*/

const FetchPreviousBillingTransactionsService = require('./fetch-previous-billing-transactions.service.js')
const ReverseBillingTransactionsService = require('./reverse-billing-transactions.service.js')
const FetchPreviousTransactionsService = require('./fetch-previous-transactions.service.js')
const ReverseTransactionsService = require('./reverse-transactions.service.js')

/**
* Fetches debit-only billing transactions from the previous bill run for the invoice account and licence provided
* and reverses them as credits. These credits are compared with the supplied calculated debit transactions (ie. debit
* transactions which are to be sent to the Charging Module) and any matching pairs of transactions which would cancel
* each other out are removed. Any remaining reversed credits and calculated debits are returned.
* Fetches debit-only transactions from the previous bill run for the invoice account and licence provided and reverses
* them as credits.
*
* These credits are compared with the supplied calculated debit transactions (ie. debit transactions which are to be
* sent to the Charging Module) and any matching pairs of transactions which would cancel each other out are removed.
* Any remaining reversed credits and calculated debits are returned.
*
* @param {Object[]} calculatedTransactions The calculated transactions to be processed
* @param {Object} bill A generated bill that identifies the invoice account ID we need to match against
Expand All @@ -31,7 +33,7 @@ async function go (calculatedTransactions, bill, billLicence, billingPeriod) {
return calculatedTransactions
}

const reversedTransactions = ReverseBillingTransactionsService.go(previousTransactions, billLicence)
const reversedTransactions = ReverseTransactionsService.go(previousTransactions, billLicence)

return _cleanseTransactions(calculatedTransactions, reversedTransactions)
}
Expand Down Expand Up @@ -125,7 +127,7 @@ function _cleanseTransactions (calculatedTransactions, reverseTransactions) {
async function _fetchPreviousTransactions (bill, billLicence, billingPeriod) {
const financialYearEnding = billingPeriod.endDate.getFullYear()

const transactions = await FetchPreviousBillingTransactionsService.go(bill, billLicence, financialYearEnding)
const transactions = await FetchPreviousTransactionsService.go(bill, billLicence, financialYearEnding)

return transactions
}
Expand Down
Loading

0 comments on commit ff405cf

Please sign in to comment.