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

Cruikshanks latest changes to the view return log #1621

Merged
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
2 changes: 1 addition & 1 deletion app/controllers/return-logs.controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ async function view(request, h) {

const pageData = await ViewReturnLogService.go(query.id, version, auth)

return h.view('return-logs/view.njk', { activeNavBar: 'search', ...pageData })
return h.view('return-logs/view.njk', pageData)
}

module.exports = {
Expand Down
10 changes: 5 additions & 5 deletions app/presenters/bill-runs/review/base-review.presenter.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,12 @@ function calculateTotalBillableReturns(reviewChargeElements) {
function determineReturnLink(reviewReturn) {
const { returnId, returnStatus } = reviewReturn

if (FeatureFlagsConfig.enableSystemReturnsView) {
return `/system/return-logs?id=${returnId}`
}

if (['due', 'received'].includes(returnStatus)) {
if (FeatureFlagsConfig.enableSystemReturnsView) {
return `/system/return-logs/setup?returnLogId=${returnId}`
} else {
return `/return/internal?returnId=${returnId}`
}
return `/return/internal?returnId=${returnId}`
}

return `/returns/return?id=${returnId}`
Expand Down
10 changes: 5 additions & 5 deletions app/presenters/licences/view-licence-returns.presenter.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,16 @@ function go(returnLogs, hasRequirements, auth) {
}

function _link(status, returnLogId, canManageReturns) {
if (FeatureFlagsConfig.enableSystemReturnsView) {
return `/system/return-logs?id=${returnLogId}`
}

if (['completed', 'void'].includes(status)) {
return `/returns/return?id=${returnLogId}`
}

if (canManageReturns) {
if (FeatureFlagsConfig.enableSystemReturnsView) {
return `/system/return-logs/setup?returnLogId=${returnLogId}`
} else {
return `/return/internal?returnId=${returnLogId}`
}
return `/return/internal?returnId=${returnLogId}`
}

return null
Expand Down
58 changes: 47 additions & 11 deletions app/presenters/return-logs/base-return-logs.presenter.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,27 @@
const { formatNumber, sentenceCase } = require('../base.presenter.js')
const { returnRequirementFrequencies, returnUnits, unitNames } = require('../../lib/static-lookups.lib.js')

/**
* Formats the details of a return submission meter
*
* @param {object} meter - the meter to be formatted
*
* @returns {object|null} The formatted meter or null if the meter is null or undefined
*/
function formatMeterDetails(meter) {
if (!meter || !meter?.manufacturer) {
return null
}

const { manufacturer: make, multiplier, serialNumber } = meter

return {
make,
serialNumber,
xDisplay: multiplier === 1 ? 'No' : 'Yes'
}
}

/**
* Converts a quantity from a given unit to cubic meters and formats it
*
Expand All @@ -22,24 +43,37 @@ function formatQuantity(units, quantity) {
}

/**
* Formats the details of a return submission meter
* Formats the status for a return log, adjusting for specific conditions.
*
* @param {object} meter - the meter to be formatted
* If the return log's status is 'completed', it will be displayed as 'complete'. If the status is 'due' and the due
* date has passed, it will be displayed as 'overdue'. For all other cases, it will return the status as is.
*
* @returns {object|null} The formatted meter or null if the meter is null or undefined
* @param {module:ReturnLogModel} returnLog - The return log containing status and due date information
*
* @returns {string} The formatted status for display.
*/
function formatMeterDetails(meter) {
if (!meter || !meter?.manufacturer) {
return null
function formatStatus(returnLog) {
const { status, dueDate } = returnLog

// If the return is completed we are required to display it as 'complete'. This also takes priority over the other
// statues
if (status === 'completed') {
return 'complete'
}

const { manufacturer: make, multiplier, serialNumber } = meter
// Work out if the return is overdue (status is still 'due' and it is past the due date)
const today = new Date()

return {
make,
serialNumber,
xDisplay: multiplier === 1 ? 'No' : 'Yes'
// The due date held in the record is date-only. If we compared it against 'today' without this step any return due
// 'today' would be flagged as overdue when it is still due (just!)
today.setHours(0, 0, 0, 0)

if (status === 'due' && dueDate < today) {
return 'overdue'
}

// For all other cases we can just return the status and the return-status-tag macro will know how to display it
return status
}

/**
Expand Down Expand Up @@ -195,6 +229,8 @@ function _linkDetails(id, method, frequency, endDate, rootPath) {

module.exports = {
formatMeterDetails,
formatQuantity,
formatStatus,
generateSummaryTableHeaders,
generateSummaryTableRows
}
137 changes: 100 additions & 37 deletions app/presenters/return-logs/view-return-log.presenter.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
const { formatAbstractionPeriod, formatLongDate, formatNumber } = require('../base.presenter.js')
const {
formatMeterDetails,
formatStatus,
generateSummaryTableHeaders,
generateSummaryTableRows
} = require('./base-return-logs.presenter.js')
Expand All @@ -31,6 +32,7 @@ function go(returnLog, auth) {
periodStartDay,
periodStartMonth,
purposes,
receivedDate,
returnReference,
returnsFrequency,
returnSubmissions,
Expand All @@ -41,52 +43,76 @@ function go(returnLog, auth) {
versions
} = returnLog

const selectedReturnSubmission = returnSubmissions[0]
const selectedReturnSubmission = _selectedReturnSubmission(returnSubmissions)
const latest = _latest(versions, selectedReturnSubmission)
const editReturn = _editReturn(latest, auth, status)

const method = selectedReturnSubmission.$method()
const units = selectedReturnSubmission.$units()
const summaryTableHeaders = generateSummaryTableHeaders(method, returnsFrequency, units)
const summaryTableRows = generateSummaryTableRows(
method,
returnsFrequency,
selectedReturnSubmission.returnSubmissionLines,
selectedReturnSubmission.id
)
const method = selectedReturnSubmission?.$method()
const units = selectedReturnSubmission?.$units()

return {
abstractionPeriod: formatAbstractionPeriod(periodStartDay, periodStartMonth, periodEndDay, periodEndMonth),
actionButton: _actionButton(latest, auth, returnLog.id, status),
backLink: _backLink(returnLog.id, licence.id, latest),
displayReadings: method !== 'abstractionVolumes',
displayTable: _displayTable(selectedReturnSubmission),
displayTotal: !!selectedReturnSubmission,
displayUnits: units !== unitNames.CUBIC_METRES,
editReturn,
editReturnLink: editReturn ? `/return/internal?returnId=${returnLog.id}` : null,
latest,
licenceRef: licence.licenceRef,
meterDetails: formatMeterDetails(selectedReturnSubmission.$meter()),
meterDetails: formatMeterDetails(selectedReturnSubmission?.$meter()),
method,
nilReturn: selectedReturnSubmission.nilReturn,
nilReturn: selectedReturnSubmission ? selectedReturnSubmission.nilReturn : false,
pageTitle: 'Abstraction return',
purpose: _purpose(purposes),
receivedDate: receivedDate ? formatLongDate(receivedDate) : null,
returnReference,
returnPeriod: `${formatLongDate(startDate)} to ${formatLongDate(endDate)}`,
siteDescription,
startReading: selectedReturnSubmission.$meter()?.startReading,
status,
summaryTableHeaders,
summaryTableRows,
startReading: _startReading(selectedReturnSubmission),
status: formatStatus(returnLog),
summaryTableData: _summaryTableData(selectedReturnSubmission, returnsFrequency),
tableTitle: _tableTitle(returnsFrequency, method),
tariff: twoPartTariff ? 'Two-part' : 'Standard',
total: _total(selectedReturnSubmission),
versions: _versions(selectedReturnSubmission.id, versions, id)
versions: _versions(selectedReturnSubmission, versions, id)
}
}

function _actionButton(latest, auth, returnLogId, status) {
// You cannot edit a previous version
if (!latest) {
return null
}

// You cannot edit a void return
if (status === 'void') {
return null
}

// You cannot submit or edit if you do not have permission to
if (!auth.credentials.scope.includes('returns')) {
return null
}

// You can only edit a completed return
if (status === 'completed') {
return {
href: `/return/internal?returnId=${returnLogId}`,
text: 'Edit return'
}
}

// Else you have a due or received return so can only submit the first return submission
return {
href: `/system/return-logs/setup?returnLogId=${returnLogId}`,
text: 'Submit return'
}
}

function _backLink(returnId, licenceId, latest) {
if (latest) {
return {
href: `/system/licences/${licenceId}/summary`,
href: `/system/licences/${licenceId}/returns`,
text: 'Go back to summary'
}
}
Expand All @@ -97,23 +123,23 @@ function _backLink(returnId, licenceId, latest) {
}
}

function _latest(versions, selectedReturnSubmission) {
return versions[0].id === selectedReturnSubmission.id
}

function _editReturn(latest, auth, status) {
// You cannot edit a previous version
if (!latest) {
function _displayTable(selectedReturnSubmission) {
// We are dealing with a due or received return log so there are no submissions.
if (!selectedReturnSubmission) {
return false
}

// You cannot edit if you do not have permission to
if (!auth.credentials.scope.includes('returns')) {
return false
return !selectedReturnSubmission.nilReturn
}

function _latest(versions, selectedReturnSubmission) {
// We are dealing with a due or received return log so there are no submissions. We treat this as 'latest' to avoid
// displaying the warning message
if (!selectedReturnSubmission) {
return true
}

// You can only edit (add a new submission) to a completed or received return
return ['completed', 'received'].includes(status)
return versions[0].id === selectedReturnSubmission.id
}

function _purpose(purposes) {
Expand All @@ -122,6 +148,37 @@ function _purpose(purposes) {
return firstPurpose.alias ? firstPurpose.alias : firstPurpose.tertiary.description
}

function _selectedReturnSubmission(returnSubmissions) {
if (!returnSubmissions) {
return null
}

return returnSubmissions[0]
}

function _startReading(selectedReturnSubmission) {
if (!selectedReturnSubmission) {
return null
}

return selectedReturnSubmission.$meter()?.startReading
}

function _summaryTableData(selectedReturnSubmission, returnsFrequency) {
if (!selectedReturnSubmission) {
return null
}

const { id: returnSubmissionId, returnSubmissionLines } = selectedReturnSubmission
const method = selectedReturnSubmission.$method()
const units = selectedReturnSubmission.$units()

return {
headers: generateSummaryTableHeaders(method, returnsFrequency, units),
rows: generateSummaryTableRows(method, returnsFrequency, returnSubmissionLines, returnSubmissionId)
}
}

function _tableTitle(returnsFrequency, method) {
const frequency = returnRequirementFrequencies[returnsFrequency]
const postfix = method === 'abstractionVolumes' ? 'abstraction volumes' : 'meter readings'
Expand All @@ -130,7 +187,7 @@ function _tableTitle(returnsFrequency, method) {
}

function _total(selectedReturnSubmission) {
if (selectedReturnSubmission.nilReturn) {
if (!selectedReturnSubmission || selectedReturnSubmission.nilReturn) {
return 0
}

Expand All @@ -143,14 +200,20 @@ function _total(selectedReturnSubmission) {
return formatNumber(total)
}

function _versions(selectedReturnSubmissionId, versions, returnLogId) {
function _versions(selectedReturnSubmission, versions, returnLogId) {
// We are dealing with a due or received return log so there are no submissions, which means no versions to display
if (!selectedReturnSubmission) {
return null
}

return versions.map((version) => {
const { createdAt, id, userId: user, version: number } = version

return {
createdAt: `${formatLongDate(createdAt)} v${number}`,
createdAt: `${formatLongDate(createdAt)}`,
link: `/system/return-logs?id=${returnLogId}&version=${number}`,
selected: id === selectedReturnSubmissionId,
selected: id === selectedReturnSubmission.id,
version: number,
user
}
})
Expand Down
Loading
Loading