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

View Licence set up page #1034

Merged
merged 37 commits into from
May 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
b933b0a
View Licence set up page
jonathangoulding May 20, 2024
d5e85e0
feat: initial charge version spike
jonathangoulding May 20, 2024
17dba2b
feat: add charge versions
jonathangoulding May 20, 2024
7f6f9e9
test: add fetch charge version test
jonathangoulding May 20, 2024
e975e6b
test: add fetch charge version test
jonathangoulding May 20, 2024
8e41e00
Merge branch 'main' into feature-view-licence-charge-information-tab
jonathangoulding May 20, 2024
587767b
feat: use licence id for charge version query
jonathangoulding May 21, 2024
ba5dca6
feat: add workflows fetch and basic view
jonathangoulding May 21, 2024
5eedf3a
feat: add authorised user workflow
jonathangoulding May 21, 2024
c92d054
feat: add status tags for workflows
jonathangoulding May 21, 2024
8bc07b6
chore: fix sonar cloud
jonathangoulding May 21, 2024
5c38105
Merge branch 'main' into feature-view-licence-charge-information-tab
jonathangoulding May 21, 2024
7aaf57f
feat: add billing role to links for editing licence
jonathangoulding May 21, 2024
e3cfe78
chore: fix indent
jonathangoulding May 21, 2024
c4e4e4e
feat: add licence show button less than 6 years old
jonathangoulding May 21, 2024
8d7ef05
chore: pre pr issues
jonathangoulding May 21, 2024
764add9
test:stub all time for presenter test
jonathangoulding May 22, 2024
4cd94d2
test: add mock for fetch licence service
jonathangoulding May 22, 2024
065c3f8
fix: sonar issues
jonathangoulding May 22, 2024
74b1ce3
fix: pr issues
jonathangoulding May 22, 2024
059f41d
refactor: licence-set-up to set-up
jonathangoulding May 22, 2024
3ed812f
Update app/services/licences/fetch-charge-versions.service.js
jonathangoulding May 22, 2024
71f5222
refactor: guard clauses
jonathangoulding May 22, 2024
3779af7
refactor: use button macro instead of html
jonathangoulding May 22, 2024
4bca313
Update app/services/licences/fetch-charge-versions.service.js
jonathangoulding May 22, 2024
52501bd
refactor: presenter 6 year old logic
jonathangoulding May 23, 2024
3f216f8
fix: pr issues
jonathangoulding May 23, 2024
748b6f5
Merge branch 'main' into feature-view-licence-charge-information-tab
jonathangoulding May 23, 2024
3404562
Update set-up.presenter.js
jonathangoulding May 23, 2024
a1db930
Update set-up.presenter.js
jonathangoulding May 23, 2024
078f1e8
Update set-up.presenter.js
jonathangoulding May 23, 2024
77b2cf3
Update set-up.presenter.js
jonathangoulding May 23, 2024
d5e4cf3
Update set-up.presenter.js
jonathangoulding May 23, 2024
cfde86e
Update fetch-workflows.service.js
jonathangoulding May 23, 2024
4a62a4f
Update view-licence-set-up.service.test.js
jonathangoulding May 23, 2024
ce25218
Update view-licence-set-up.service.test.js
jonathangoulding May 23, 2024
1d32ba7
fix: failing test data
jonathangoulding May 23, 2024
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
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 ViewLicenceBillsService = require('../services/licences/view-licence-bills
const ViewLicenceCommunicationsService = require('../services/licences/view-licence-communications.service.js')
const ViewLicenceContactDetailsService = require('../services/licences/view-licence-contact-details.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')

const ViewLicencePage = 'licences/view.njk'
Expand Down Expand Up @@ -40,6 +41,16 @@ async function viewBills (request, h) {
})
}

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

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

return h.view(ViewLicencePage, {
...data
})
}

async function viewCommunications (request, h) {
const { params: { id }, auth, query: { page = 1 } } = request

Expand Down Expand Up @@ -87,5 +98,6 @@ module.exports = {
viewCommunications,
viewContacts,
viewReturns,
viewSetUp,
viewSummary
}
152 changes: 152 additions & 0 deletions app/presenters/licences/set-up.presenter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
'use strict'

/**
* Formats data for the `/licences/{id}/set-up` view licence set up page
* @module SetUpPresenter
*/

const { formatLongDate } = require('../base.presenter.js')

const roles = {
billing: 'billing',
workflowEditor: 'charge_version_workflow_editor',
workflowReviewer: 'charge_version_workflow_reviewer'
}

/**
* Formats data for the `/licences/{id}/set-up` view licence set up page
*
* @param {module:ChargeVersionModel[]} chargeVersions - All charge versions records for the licence
* @param {module:WorkflowModel[]} workflows - All in-progress workflow records for the licence
* @param {Object} auth - The auth object taken from `request.auth` containing user details
* @param {Object} commonData - Licence data already formatted for the view's shared elements
*
* @returns {Object} The data formatted for the view template
*/
function go (chargeVersions, workflows, auth, commonData) {
return {
..._authorisedLinks(auth, commonData),
chargeInformation: _chargeInformation(chargeVersions, workflows, auth)
}
}

function _authorisedLinks (auth, commonData) {
if (auth.credentials.scope.includes(roles.workflowEditor) && !_endsSixYearsAgo(commonData.ends)) {
return {
setupNewCharge: `/licences/${commonData.licenceId}/charge-information/create`,
makeLicenceNonChargeable: `/licences/${commonData.licenceId}/charge-information/non-chargeable-reason?start=1`
}
}

return {}
}

function _chargeInformation (chargeVersions, workflows, auth) {
return [
..._workflows(workflows, auth),
..._chargeVersions(chargeVersions)
]
}

function _chargeVersions (chargeVersions) {
return chargeVersions.map((chargeVersion) => {
return {
id: chargeVersion.id,
startDate: formatLongDate(chargeVersion.startDate),
endDate: chargeVersion.endDate ? formatLongDate(chargeVersion.endDate) : '-',
status: _status(chargeVersion.status),
reason: chargeVersion.changeReason?.description,
action: [
{
text: 'View',
link: `/licences/${chargeVersion.licenceId}/charge-information/${chargeVersion.id}/view`
}
]
}
})
}

function _endsSixYearsAgo (endDate) {
if (!endDate) {
return null
}

const sixYears = 6
const timeStamp = { hour: 23, minutes: 59, seconds: 59, ms: 999 }

const yesterday = new Date()
yesterday.setDate(yesterday.getDate() - 1)
yesterday.setHours(timeStamp.hour, timeStamp.minutes, timeStamp.seconds, timeStamp.ms)

const sixYearsFromYesterday = new Date(yesterday.getTime())
sixYearsFromYesterday.setFullYear(yesterday.getFullYear() - sixYears)

return endDate < sixYearsFromYesterday
}

function _status (status) {
const statuses = {
current: 'approved',
draft: 'draft',
approved: 'approved',
replaced: 'replaced',
superseded: 'replaced',
invalid: 'invalid',
review: 'review',
changes_requested: 'change request',
to_setup: 'to set up'
}

return statuses[status]
}

function _workflows (workflows, auth) {
return workflows.map((workflow) => {
return {
action: _workflowAction(workflow, auth),
endDate: '-',
id: workflow.id,
reason: workflow.data.chargeVersion?.changeReason?.description,
startDate: workflow.createdAt ? formatLongDate(workflow.createdAt) : '-',
status: _status(workflow.status)
}
})
}

function _workflowAction (workflow, auth) {
if (workflow.status === 'to_setup' && auth.credentials.scope.includes(roles.workflowEditor)) {
return _workflowActionEditor(workflow)
}

if (auth.credentials.scope.includes(roles.workflowReviewer)) {
return _workflowActionReviewer(workflow)
}

return []
}

function _workflowActionEditor (workflow) {
return [
{
text: 'Set up',
link: `/licences/${workflow.licenceId}/charge-information/create?chargeVersionWorkflowId=${workflow.id}`
},
{
text: 'Remove',
link: `/charge-information-workflow/${workflow.id}/remove`
}
]
}

function _workflowActionReviewer (workflow) {
return [
{
text: 'Review',
link: `/licences/${workflow.licenceId}/charge-information/${workflow.id}/review`
}
]
}

module.exports = {
go
}
3 changes: 2 additions & 1 deletion app/presenters/licences/view-licence.presenter.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ function go (licence, auth) {
roles: _authRoles(auth),
warning: _generateWarningMessage(ends),
activeNavBar: 'search',
documentId: licenceDocumentHeader.id
documentId: licenceDocumentHeader.id,
ends
}
}

Expand Down
13 changes: 13 additions & 0 deletions app/routes/licence.routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,19 @@ const routes = [
description: 'View a licence contacts page'
}
},
{
method: 'GET',
path: '/licences/{id}/set-up',
handler: LicencesController.viewSetUp,
options: {
auth: {
access: {
scope: ['billing']
}
},
description: 'View a licence set up page'
}
},
{
method: 'GET',
path: '/licences/{id}/summary',
Expand Down
44 changes: 44 additions & 0 deletions app/services/licences/fetch-charge-versions.service.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
'use strict'

/**
* Fetches charge version data needed for the view '/licences/{id}/set-up` page
* @module FetchChargeVersionsService
*/

const ChargeVersionModel = require('../../models/charge-version.model.js')

/**
* Fetches charge version data needed for the view '/licences/{id}/set-up` page
*
* @param {string} licenceId - The UUID for the licence to fetch charge versions for
*
* @returns {Promise<Object>} the data needed to populate the view licence page's set up tab
*/
async function go (licenceId) {
return _fetch(licenceId)
}

async function _fetch (licenceId) {
return ChargeVersionModel.query()
.where('licenceId', licenceId)
.select([
'id',
'startDate',
'endDate',
'status',
'licenceId'
])
.withGraphFetched('changeReason')
.modifyGraph('changeReason', (builder) => {
builder.select([
'description'
])
})
.orderBy([
{ column: 'startDate', order: 'desc' }
])
}

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

/**
* Fetches workflow data needed for the view '/licences/{id}/set-up` page
* @module FetchWorkflowsService
*/

const WorkflowModel = require('../../models/workflow.model.js')

/**
* Fetches workflow data needed for the view '/licences/{id}/set-up` page
*
* @param {string} licenceId - The UUID for the licence to fetch workflow data for
*
* @returns {Promise<Object>} the data needed to populate the view licence page's set up tab
*/
async function go (licenceId) {
return _fetch(licenceId)
}

async function _fetch (licenceId) {
return WorkflowModel.query()
.where('licenceId', licenceId)
.andWhere('deletedAt', null)
.select([
'id',
'createdAt',
'status',
'licenceId',
'data'
])
.orderBy([
{ column: 'createdAt', order: 'desc' }
])
}

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

/**
* Orchestrates fetching and presenting the data needed for the view licence set up tab
* @module ViewLicenceSetUpService
*/

const FetchChargeVersionsService = require('./fetch-charge-versions.service.js')
const FetchWorkflowsService = require('./fetch-workflows.service.js')
const SetUpPresenter = require('../../presenters/licences/set-up.presenter.js')
const ViewLicenceService = require('./view-licence.service.js')

/**
* Orchestrates fetching and presenting the data needed for the licence set up page
*
* @param {string} licenceId - The UUID of the licence
* @param {Object} auth - The auth object taken from `request.auth` containing user details
*
* @returns {Promise<Object>} an object representing the `pageData` needed by the licence set up template.
*/
async function go (licenceId, auth) {
const commonData = await ViewLicenceService.go(licenceId, auth)

const chargeVersions = await FetchChargeVersionsService.go(licenceId)
const workflows = await FetchWorkflowsService.go(licenceId)

const licenceSetUpData = SetUpPresenter.go(chargeVersions, workflows, auth, commonData)

return {
activeTab: 'set-up',
...commonData,
...licenceSetUpData
}
}

module.exports = {
go
}
1 change: 0 additions & 1 deletion app/services/licences/view-licence.service.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ const ViewLicencePresenter = require('../../presenters/licences/view-licence.pre
* @returns {Promise<Object>} an object representing the `pageData` needed by the licence summary template.
*/
async function go (licenceId, auth) {
// fox this fetch
const licenceData = await FetchLicenceService.go(licenceId)

const pageData = ViewLicencePresenter.go(licenceData, auth)
Expand Down
Loading
Loading