Skip to content

Commit

Permalink
Create endpoint to generate mock data (#347)
Browse files Browse the repository at this point in the history
https://eaflood.atlassian.net/browse/WATER-4070
https://eaflood.atlassian.net/browse/WATER-4073

We are looking to re-design the bill runs page in the internal service due to repeated issues with the existing one timing out. It is simply trying to return too much data when displaying annual bill runs.

To properly test the new design our UAT team hit a blocker; how do we demonstrate a large bill run in the prototype? They were able to manually create a bill run or 2. But to properly test this they needed 100's of licences represented and thousands of bills. They also had to be 'realistic' because previous testing had highlighted users got distracted by inaccuracies in the test data.

So, we have created a new feature in the app which allows the delivery team to 'mock' existing records. Currently, it only supports mocking bill runs but this change is done in a way it should be easy to add additional entity types if needed.

To mock a bill run, a team member would first identify one in the environment they are connected to that they would like to mock (the endpoint is only available in non-prod environments). They then extract the ID from the URL and make a request in their browser to

- `https://[non-prod-environment-domain]/system/data/mock/bill-run/96187453-7243-4f45-a6a7-d0c5f530cbac`

> When called in our local development environment drop `/system` from the URL

The system will then use the existing bill run as a template, mock things like invoice and licence holder details and obfuscate other data before returning the mocked bill run as JSON. The format returned is based on what the prototype is already using so it can be copied and pasted right in.

---

Co-authored-by: Alan Cruikshanks <alan.cruikshanks@gmail.com>
  • Loading branch information
StuAA78 and Cruikshanks authored Aug 15, 2023
1 parent 831c4c1 commit 20d1e8b
Show file tree
Hide file tree
Showing 12 changed files with 1,031 additions and 2 deletions.
9 changes: 9 additions & 0 deletions app/controllers/data/data.controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
*/

const ExportService = require('../../services/data/export/export.service.js')
const MockService = require('../../services/data/mock/mock.service.js')
const SeedService = require('../../services/data/seed/seed.service.js')
const TearDownService = require('../../services/data/tear-down/tear-down.service.js')

Expand All @@ -20,6 +21,13 @@ async function exportDb (_request, h) {
return h.response().code(204)
}

async function mock (request, h) {
const { type, id } = request.params
const mockData = await MockService.go(type, id)

return h.response(mockData)
}

async function seed (_request, h) {
await SeedService.go()

Expand All @@ -34,6 +42,7 @@ async function tearDown (_request, h) {

module.exports = {
exportDb,
mockData: mock,
seed,
tearDown
}
205 changes: 205 additions & 0 deletions app/presenters/data/mock-bill-run.presenter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,205 @@
'use strict'

/**
* Formats the response for the GET `/data/mock/{bill-run}` endpoint
* @module MockBillRunPresenter
*/

const { convertPenceToPounds, formatAbstractionPeriod, formatLongDate, formatNumberAsMoney } = require('../base.presenter.js')

function go (billingBatch) {
const {
billingInvoices,
billRunNumber,
createdAt,
fromFinancialYearEnding,
netTotal,
region,
status,
scheme,
toFinancialYearEnding,
batchType: type,
transactionFileReference: transactionFile
} = billingBatch

return {
dateCreated: formatLongDate(createdAt),
status,
region: region.name,
type,
chargeScheme: scheme === 'sroc' ? 'Current' : 'Old',
transactionFile,
billRunNumber,
financialYear: `${fromFinancialYearEnding} to ${toFinancialYearEnding}`,
debit: formatNumberAsMoney(convertPenceToPounds(netTotal)),
bills: _formatBillingInvoices(billingInvoices)
}
}

function _formatAdditionalCharges (transaction) {
const formattedData = []

const { grossValuesCalculated, isWaterCompanyCharge, supportedSourceName } = transaction

if (supportedSourceName) {
const formattedSupportedSourceCharge = formatNumberAsMoney(grossValuesCalculated.supportedSourceCharge, true)
formattedData.push(`Supported source ${supportedSourceName} (${formattedSupportedSourceCharge})`)
}

if (isWaterCompanyCharge) {
formattedData.push('Public Water Supply')
}

return formattedData
}

function _formatAdjustments (chargeElement) {
const formattedData = []

if (!chargeElement.adjustments) {
return formattedData
}

const { aggregate, charge, s126, s127, s130, winter } = chargeElement.adjustments

if (aggregate) {
formattedData.push(`Aggregate factor (${aggregate})`)
}

if (charge) {
formattedData.push(`Adjustment factor (${charge})`)
}

if (s126) {
formattedData.push(`Abatement factor (${s126})`)
}

if (s127) {
formattedData.push('Two-part tariff (0.5)')
}

if (s130) {
formattedData.push('Canal and River Trust (0.5)')
}

if (winter) {
formattedData.push('Winter discount (0.5)')
}

return formattedData
}

function _formatBillingInvoices (billingInvoices) {
return billingInvoices.map((billingInvoice) => {
const {
accountAddress,
billingInvoiceLicences,
contact,
creditNoteValue,
invoiceValue,
netAmount,
billingInvoiceId: id,
invoiceAccountNumber: account,
invoiceNumber: number
} = billingInvoice

return {
id,
account,
number,
accountAddress,
contact,
isWaterCompany: billingInvoiceLicences[0].licence.isWaterUndertaker,
credit: formatNumberAsMoney(convertPenceToPounds(creditNoteValue)),
debit: formatNumberAsMoney(convertPenceToPounds(invoiceValue)),
netTotal: formatNumberAsMoney(convertPenceToPounds(netAmount)),
licences: _formatBillingInvoiceLicences(billingInvoiceLicences)
}
})
}

function _formatBillingInvoiceLicences (billingInvoiceLicences) {
return billingInvoiceLicences.map((billingInvoiceLicence) => {
const {
billingTransactions,
credit,
debit,
netTotal,
licenceHolder,
billingInvoiceLicenceId: id,
licenceRef: licence
} = billingInvoiceLicence

return {
id,
licence,
licenceStartDate: billingInvoiceLicence.licence.startDate,
licenceHolder,
credit: formatNumberAsMoney(convertPenceToPounds(credit)),
debit: formatNumberAsMoney(convertPenceToPounds(debit)),
netTotal: formatNumberAsMoney(convertPenceToPounds(netTotal)),
transactions: _formatBillingTransactions(billingTransactions)
}
})
}

function _formatBillingTransactions (billingTransactions) {
return billingTransactions.map((billingTransaction) => {
const {
authorisedDays,
billableDays,
chargeCategoryCode,
chargeElement,
chargeType,
endDate,
grossValuesCalculated,
isCredit,
netAmount,
startDate,
billableQuantity: chargeQuantity,
chargeCategoryDescription: chargeDescription,
description: lineDescription
} = billingTransaction

return {
type: chargeType === 'standard' ? 'Water abstraction charge' : 'Compensation charge',
lineDescription,
billableDays,
authorisedDays,
chargeQuantity,
credit: isCredit ? formatNumberAsMoney(convertPenceToPounds(netAmount)) : '0.00',
debit: isCredit ? '0.00' : formatNumberAsMoney(convertPenceToPounds(netAmount)),
chargePeriod: `${formatLongDate(startDate)} to ${formatLongDate(endDate)}`,
chargeRefNumber: `${chargeCategoryCode} (${formatNumberAsMoney(grossValuesCalculated.baselineCharge, true)})`,
chargeDescription,
addCharges: _formatAdditionalCharges(billingTransaction),
adjustments: _formatAdjustments(chargeElement),
elements: _formatChargePurposes(chargeElement.chargePurposes)
}
})
}

function _formatChargePurposes (chargePurposes) {
return chargePurposes.map((chargePurpose) => {
const {
purposesUse,
abstractionPeriodStartDay: startDay,
abstractionPeriodStartMonth: startMonth,
abstractionPeriodEndDay: endDay,
abstractionPeriodEndMonth: endMonth,
authorisedAnnualQuantity: authorisedQuantity,
chargePurposeId: id
} = chargePurpose

return {
id,
purpose: purposesUse.description,
abstractionPeriod: formatAbstractionPeriod(startDay, startMonth, endDay, endMonth),
authorisedQuantity
}
})
}

module.exports = {
go
}
9 changes: 9 additions & 0 deletions app/routes/data.routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,15 @@ const routes = [
}
}
},
{
method: 'GET',
path: '/data/mock/{type}/{id}',
handler: DataController.mockData,
options: {
description: 'Used to generate mock data',
app: { excludeFromProd: true }
}
},
{
method: 'POST',
path: '/data/seed',
Expand Down
Loading

0 comments on commit 20d1e8b

Please sign in to comment.