Skip to content

Commit

Permalink
Merge branch 'main' into add-base-point-model
Browse files Browse the repository at this point in the history
  • Loading branch information
Cruikshanks authored Aug 29, 2024
2 parents 6167fa4 + b8fc0aa commit 893b3c6
Show file tree
Hide file tree
Showing 10 changed files with 877 additions and 0 deletions.
12 changes: 12 additions & 0 deletions app/controllers/licences.controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const InitiateSessionService = require('../services/return-requirements/initiate
const ViewLicenceBillsService = require('../services/licences/view-licence-bills.service.js')
const ViewLicenceCommunicationsService = require('../services/licences/view-licence-communications.service.js')
const ViewLicenceContactDetailsService = require('../services/licences/view-licence-contact-details.service.js')
const ViewLicenceHistoryService = require('../services/licences/view-licence-history.service.js')
const ViewLicenceReturnsService = require('../services/licences/view-licence-returns.service.js')
const ViewLicenceSetUpService = require('../services/licences/view-licence-set-up.service.js')
const ViewLicenceSummaryService = require('../services/licences/view-licence-summary.service.js')
Expand Down Expand Up @@ -72,6 +73,16 @@ async function viewContacts (request, h) {
})
}

async function viewHistory (request, h) {
const { params: { id }, auth } = request

const data = await ViewLicenceHistoryService.go(id, auth)

return h.view('licences/history.njk', {
...data
})
}

async function viewSummary (request, h) {
const { params: { id }, auth } = request

Expand Down Expand Up @@ -105,6 +116,7 @@ module.exports = {
viewBills,
viewCommunications,
viewContacts,
viewHistory,
viewReturns,
viewSetUp,
viewSummary
Expand Down
133 changes: 133 additions & 0 deletions app/presenters/licences/view-licence-history.presenter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
'use strict'

/**
* Formats data for the `/licences/{id}/history` view licence history page
* @module ViewLicenceHistoryPresenter
*/

const { formatLongDate } = require('../base.presenter.js')
const { returnRequirementReasons } = require('../../lib/static-lookups.lib.js')

/**
* Formats data for the `/licences/{id}/history` view licence history page
*
* @param {module:LicenceModel} licence - The licence and related charge, licence and return versions
*
* @returns The data formatted and sorted for the view template
*/
function go (licence) {
const { id: licenceId, licenceRef } = licence

const chargeVersionEntries = _chargeVersionEntries(licence)
const licenceVersionEntries = _licenceVersionEntries(licence)
const returnVersionEntries = _returnVersionEntries(licence)

const sortedEntries = _sortEntries(chargeVersionEntries, licenceVersionEntries, returnVersionEntries)

return {
entries: sortedEntries,
licenceId,
licenceRef,
pageTitle: `History for ${licenceRef}`
}
}

function _chargeVersionEntries (licence) {
const { chargeVersions, id } = licence

return chargeVersions.map((chargeVersion) => {
const createdAt = chargeVersion.$createdAt()
const notes = chargeVersion.$notes()

return {
createdAt,
createdBy: _createdBy(chargeVersion),
dateCreated: formatLongDate(createdAt),
displayNote: notes.length > 0,
notes,
link: `/licences/${id}/charge-information/${chargeVersion.id}/view`,
reason: chargeVersion.$reason(),
type: { index: 1, name: 'Charge version' }
}
})
}

function _createdBy (entry) {
const createdBy = entry.$createdBy()

if (createdBy) {
return createdBy
}

return 'Migrated from NALD'
}

function _licenceVersionEntries (licence) {
const { licenceVersions } = licence

return licenceVersions.map((licenceVersion) => {
const createdAt = licenceVersion.$createdAt()
const notes = licenceVersion.$notes()

return {
createdAt,
createdBy: _createdBy(licenceVersion),
dateCreated: formatLongDate(createdAt),
displayNote: notes.length > 0,
notes,
link: null,
reason: licenceVersion.$reason(),
type: { index: 0, name: 'Licence version' }
}
})
}

function _returnVersionEntries (licence) {
const { returnVersions } = licence

return returnVersions.map((returnVersion) => {
const createdAt = returnVersion.$createdAt()
const notes = returnVersion.$notes()
const reason = returnVersion.$reason()
const mappedReason = returnRequirementReasons[reason]

return {
createdAt,
createdBy: _createdBy(returnVersion),
dateCreated: formatLongDate(createdAt),
displayNote: notes.length > 0,
notes,
link: `/system/return-requirements/${returnVersion.id}/view`,
reason: mappedReason ?? reason,
type: { index: 2, name: 'Return version' }
}
})
}

function _sortEntries (chargeVersionEntries, licenceVersionEntries, returnVersionEntries) {
const joinedEntries = [...chargeVersionEntries, ...licenceVersionEntries, ...returnVersionEntries]

return joinedEntries.sort((entryA, entryB) => {
if (entryA.createdAt > entryB.createdAt) {
return -1
}

if (entryA.createdAt < entryB.createdAt) {
return 1
}

if (entryA.type.index > entryB.type.index) {
return -1
}

if (entryA.type.index < entryB.type.index) {
return 1
}

return 0
})
}

module.exports = {
go
}
12 changes: 12 additions & 0 deletions app/routes/licence.routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,18 @@ const routes = [
path: '/licences/{id}/contact-details',
handler: LicencesController.viewContacts
},
{
method: 'GET',
path: '/licences/{id}/history',
options: {
handler: LicencesController.viewHistory,
auth: {
access: {
scope: ['billing']
}
}
}
},
{
method: 'GET',
path: '/licences/{id}/set-up',
Expand Down
50 changes: 50 additions & 0 deletions app/services/licences/fetch-licence-history.service.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
'use strict'

/**
* Fetches data needed for the view '/licences/{id}/history` page
* @module FetchLicenceHistoryService
*/

const LicenceModel = require('../../models/licence.model.js')

/**
* Fetches data needed for the view '/licences/{id}/history` page
*
* @param {string} licenceId - The UUID for the licence to fetch
*
* @returns {Promise<module:LicenceModel>} the licence and related charge, licence and return versions
*/
async function go (licenceId) {
return _fetch(licenceId)
}

async function _fetch (licenceId) {
return LicenceModel.query()
.findById(licenceId)
.select(['id', 'licenceRef'])
.withGraphFetched('chargeVersions')
.modifyGraph('chargeVersions', (builder) => {
builder.select(
'id'
)
.modify('history')
})
.withGraphFetched('licenceVersions')
.modifyGraph('licenceVersions', (builder) => {
builder.select(
'id'
)
.modify('history')
})
.withGraphFetched('returnVersions')
.modifyGraph('returnVersions', (builder) => {
builder.select(
'id'
)
.modify('history')
})
}

module.exports = {
go
}
31 changes: 31 additions & 0 deletions app/services/licences/view-licence-history.service.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
'use strict'

/**
* Orchestrates fetching and presenting the data needed for the licence history page
* @module ViewLicenceHistoryService
*/

const FetchLicenceHistoryService = require('./fetch-licence-history.service.js')
const ViewLicenceHistoryPresenter = require('../../presenters/licences/view-licence-history.presenter.js')

/**
* Orchestrates fetching and presenting the data needed for the licence history page
*
* @param {string} licenceId - The UUID of the licence
*
* @returns {Promise<object>} an object representing the `pageData` needed by the licence history template.
*/
async function go (licenceId) {
const licence = await FetchLicenceHistoryService.go(licenceId)

const pageData = ViewLicenceHistoryPresenter.go(licence)

return {
activeNavBar: 'search',
...pageData
}
}

module.exports = {
go
}
105 changes: 105 additions & 0 deletions app/views/licences/history.njk
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
{% extends 'layout.njk' %}
{% from "govuk/components/back-link/macro.njk" import govukBackLink %}
{% from "govuk/components/details/macro.njk" import govukDetails %}
{% from "govuk/components/table/macro.njk" import govukTable %}

{% macro dateAndTypeColumn(entry) %}
{% if entry.link %}
<a href="{{ entry.link }}" class="govuk-link">{{ entry.dateCreated }}</a>
{% else %}
<div>{{ entry.dateCreated }}</div>
{% endif %}
<p class="govuk-body-s govuk-!-margin-bottom-0">{{ entry.type.name }}</p>
{% endmacro %}

{% macro formatNote(notes) %}
{% for note in notes %}
<p class="govuk-!-margin-bottom-0"> {{ note }}</p>
{% endfor %}
{% endmacro %}

{% block breadcrumbs %}
{{ govukBackLink({
text: 'Go back to licence ' + licenceRef,
href: "/system/licences/" + licenceId + "/summary"
}) }}
{% endblock %}

{% block content %}
{# Main heading #}
<div>
<span class="govuk-caption-l"> Licence {{ licenceRef }} </span>
<h1 class="govuk-heading-xl govuk-!-margin-bottom-3">History</h1>
</div>

{% if entries.length == 0 %}
<p>No history for this licence.</p>
{% else %}
{% set tableRows = [] %}
{% for entry in entries %}
{# Set an easier to use index. Also means we can refer to it inside our elementDetail loop #}
{% set rowIndex = loop.index0 %}

{% if entry.displayNote %}
{% set classes = 'table__cell--include govuk-!-margin-bottom-0 govuk-!-padding-bottom-0' %}
{% else %}
{% set classes = '' %}
{% endif %}

{# Set data row #}
{% set dataRow = [
{
html: dateAndTypeColumn(entry),
attributes: { 'data-test': 'entry-date-type-' + rowIndex },
classes: classes
},
{
text: entry.reason,
attributes: { 'data-test': 'entry-reason-' + rowIndex },
classes: classes
},
{
text: entry.createdBy,
attributes: { 'data-test': 'entry-created-by-' + rowIndex },
classes: classes
}
] %}

{% set tableRows = (tableRows.push(dataRow), tableRows) %}

{# Set note row #}
{% if entry.displayNote %}
{% set noteCell %}
{{
govukDetails({
classes: 'govuk-!-margin-bottom-0',
summaryText: 'Note',
html: formatNote(entry.notes)
})
}}
{% endset %}

{% set noteRow = [
{
html: noteCell,
attributes: { 'data-test': 'entry-note-' + rowIndex },
colspan: 3
}
] %}

{% set tableRows = (tableRows.push(noteRow), tableRows) %}
{% endif %}
{% endfor %}

{{ govukTable({
attributes: { 'data-test': 'bills-table' },
firstCellIsHeader: false,
head: [
{ text: 'Date and type', classes: 'govuk-!-width-one-quarter' },
{ text: 'Reason' },
{ text: 'Created by', classes: 'govuk-!-width-one-third' }
],
rows: tableRows
}) }}
{% endif %}
{% endblock %}
5 changes: 5 additions & 0 deletions client/sass/application.scss
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,11 @@ $govuk-global-styles: true;
}
}

// Used in tables where we want to include 2 rows as one, it removes the separator from the first row when applied
.table__cell--include {
border-bottom: none !important;
}

// ========== ========== ========== ========== ==========
// Widths
// ========== ========== ========== ========== ==========
Expand Down
Loading

0 comments on commit 893b3c6

Please sign in to comment.