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

Import licence document for a licence #1392

Merged
merged 20 commits into from
Oct 16, 2024
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
04dcc2e
Import licence document for a licence
jonathangoulding Oct 8, 2024
8ce8260
chore: fix sql linting
jonathangoulding Oct 8, 2024
f5cfb11
feat: add required default to persist the licence document into WRLS
jonathangoulding Oct 9, 2024
d50252c
Merge branch 'main' into import-licence-document
jonathangoulding Oct 9, 2024
ae22278
feat: ignore licence versions in draft
jonathangoulding Oct 9, 2024
0d58e39
Merge branch 'main' into import-licence-document
jonathangoulding Oct 10, 2024
eff0baa
Merge branch 'main' into import-licence-document
jonathangoulding Oct 11, 2024
c9cfd86
Merge branch 'main' into import-licence-document
jonathangoulding Oct 11, 2024
c681963
Merge remote-tracking branch 'refs/remotes/origin/main' into import-l…
jonathangoulding Oct 11, 2024
607bc39
feat persist licence document - WIP
jonathangoulding Oct 11, 2024
cc88c81
test: persist licence
jonathangoulding Oct 15, 2024
1c5ce01
Merge branch 'main' into import-licence-document
jonathangoulding Oct 15, 2024
2f48dbb
fix: old confused logic for crm persist not wrls
jonathangoulding Oct 15, 2024
3ed6264
fix: old confused logic for crm persist not wrls
jonathangoulding Oct 15, 2024
6a216ab
fix: transform test
jonathangoulding Oct 15, 2024
baa6666
chore: pre pr checks
jonathangoulding Oct 15, 2024
4efce16
Update persist-licence-document.service.test.js
jonathangoulding Oct 16, 2024
81fe53a
Update persist-licence-document.service.test.js
jonathangoulding Oct 16, 2024
114d39b
Update transform-licence-document.service.test.js
jonathangoulding Oct 16, 2024
d1dee3c
fix: remove deleted at logic
jonathangoulding Oct 16, 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
27 changes: 27 additions & 0 deletions app/presenters/import/legacy/licence-document.presenter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
'use strict'

/**
* Maps legacy NALD licence data to the WRLS licence document format
* @module LicenceDocumentPresenter
*/

/**
* Maps legacy NALD licence data to the WRLS licence document format
*
* @param {ImportLegacyLicenceDocumentType} licenceDocument - the legacy NALD licence
*
* @returns {object} the NALD licence data transformed into the WRLS licence document format
* ready for validation and persisting
*/
function go (licenceDocument) {
return {
deletedAt: null,
licenceRef: licenceDocument.licence_ref,
endDate: licenceDocument.end_date,
startDate: licenceDocument.start_date
}
}

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

/**
* Fetches the licence document data from the import.NALD_ABS_LICENCES table for the licence being imported
* @module FetchLicenceDocumentService
*/

const { db } = require('../../../../db/db.js')

/**
* Fetches the licence document data from the import.NALD_ABS_LICENCES table for the licence being imported
*
* @param {string} regionCode - The NALD region code
* @param {string} licenceId - The NALD licence ID
*
* @returns {Promise<ImportLegacyLicenceDocumentType>}
*/
async function go (regionCode, licenceId) {
const query = _query()

const { rows: [row] } = await db.raw(query, [regionCode, licenceId])

return row
}

function _query () {
return `
SELECT
CASE
WHEN
NULLIF(nal."ORIG_EFF_DATE", 'null') IS NULL
THEN MIN(TO_DATE(nalv."EFF_ST_DATE", 'DD/MM/YYYY' ))
ELSE TO_DATE(nal."ORIG_EFF_DATE", 'DD/MM/YYYY')
END
as start_date,
LEAST(
TO_DATE(NULLIF(nal."LAPSED_DATE", 'null'), 'DD/MM/YYYY'),
TO_DATE(NULLIF(nal."REV_DATE", 'null'), 'DD/MM/YYYY'),
TO_DATE(NULLIF(nal."EXPIRY_DATE", 'null'), 'DD/MM/YYYY')
) as end_date,
nal."LIC_NO" as licence_ref
FROM import."NALD_ABS_LICENCES" nal
INNER JOIN import."NALD_ABS_LIC_VERSIONS" nalv
ON nalv."FGAC_REGION_CODE" = nal."FGAC_REGION_CODE"
AND nalv."AABL_ID" = nal."ID"
AND NOT nalv."STATUS" = 'DRAFT'
WHERE nalv."FGAC_REGION_CODE" = ? AND nalv."AABL_ID" = ?
GROUP BY nal."FGAC_REGION_CODE", nal."ID", nal."LIC_NO", nal."ORIG_EFF_DATE", nal."EXPIRY_DATE", nal."REV_DATE", nal."LAPSED_DATE";
`
}

module.exports = {
go
}

/**
* Representation of a licence document fetched from the NALD data
* @typedef {object} ImportLegacyLicenceDocumentType
*
* @property {Date} start_date - The effective start date of the license.
* @property {Date | null} end_date - The earliest of the lapsed, revision, or expiry dates.
* @property {string} external_id - A combination of the region code and licence ID.
* @property {string} licence_ref - The licence number.
*/
4 changes: 4 additions & 0 deletions app/services/import/legacy/process-licence.service.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const LicenceStructureValidator = require('../../../validators/import/licence-st
const PersistImportService = require('../persist-import.service.js')
const ProcessLicenceReturnLogsService = require('../../jobs/return-logs/process-licence-return-logs.service.js')
const TransformAddressesService = require('./transform-addresses.service.js')
const TransformLicenceDocumentService = require('./transform-licence-document.service.js')
const TransformCompaniesService = require('./transform-companies.service.js')
const TransformCompanyAddressesService = require('./transform-company-addresses.service.js')
const TransformContactsService = require('./transform-contacts.service.js')
Expand Down Expand Up @@ -38,6 +39,9 @@ async function go (licenceRef) {
await TransformLicenceVersionPurposesService.go(regionCode, naldLicenceId, transformedLicence)
await TransformLicenceVersionPurposeConditionsService.go(regionCode, naldLicenceId, transformedLicence)

// Document
await TransformLicenceDocumentService.go(regionCode, naldLicenceId, transformedLicence)

// Transform the company data
const { transformedCompanies } = await TransformCompaniesService.go(regionCode, naldLicenceId)

Expand Down
35 changes: 35 additions & 0 deletions app/services/import/legacy/transform-licence-document.service.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
'use strict'

/**
* Transforms all NALD licence document data into an object that matches the WRLS structure
* @module ImportLegacyTransformLicenceDocumentService
*/

const FetchLicenceDocumentService = require('./fetch-licence-document.service.js')
const LicenceDocumentPresenter = require('../../../presenters/import/legacy/licence-document.presenter.js')
const LicenceDocumentValidator = require('../../../validators/import/licence-document.validator.js')

/**
* Transforms all NALD licence document data into an object that matches the WRLS structure
*
* NALD does not have a concept of a document it is a legacy WRLS construct
*
* After transforming and validating the NALD licence version data, it attaches it to the licence we're importing.
*
* @param {string} regionCode - The NALD region code for the licence being imported
* @param {string} naldLicenceId - The NALD ID for the licence being imported
* @param {object} transformedLicence - An object representing a valid WRLS licence
*/
async function go (regionCode, naldLicenceId, transformedLicence) {
const naldLicenceDocument = await FetchLicenceDocumentService.go(regionCode, naldLicenceId)

const transformedLicenceDocument = LicenceDocumentPresenter.go(naldLicenceDocument)

LicenceDocumentValidator.go(transformedLicenceDocument)

transformedLicence.licenceDocument = transformedLicenceDocument
}

module.exports = {
go
}
3 changes: 3 additions & 0 deletions app/services/import/persist-import.service.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
const PersistLicenceService = require('./persist/persist-licence.service.js')
const PersistLicenceVersionsService = require('./persist/persist-licence-versions.service.js')
const PersistCompanyService = require('./persist/persist-company.service.js')
const PersistLicenceDocumentService = require('./persist/persist-licence-document.service.js')
const LicenceModel = require('../../models/licence.model.js')
const { timestampForPostgres } = require('../../lib/general.lib.js')

Expand All @@ -27,6 +28,8 @@ async function go (transformedLicence, transformedCompanies) {

await PersistLicenceVersionsService.go(trx, updatedAt, transformedLicence, id)

await PersistLicenceDocumentService.go(trx, updatedAt, transformedLicence)

await PersistCompanyService.go(trx, updatedAt, transformedCompanies)

return id
Expand Down
37 changes: 37 additions & 0 deletions app/services/import/persist/persist-licence-document.service.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
'use strict'

/**
* Creates or updates a licence document
* @module PersistLicenceDocumentService
*/

const LicenceDocumentModel = require('../../../models/licence-document.model.js')

/**
* Creates or updates a licence document
*
* @param {object} trx - An Objection.js transaction object for PostgreSQL.
* @param {string} updatedAt - The timestamp indicating when the entity was last updated.
* @param {object} transformedLicence - An object representing a valid WRLS licence.
*
* @returns {Promise<string>} - The licence ID from WRLS.
*/
async function go (trx, updatedAt, transformedLicence) {
await _persistLicenceDocument(trx, updatedAt, transformedLicence.licenceDocument)
}

async function _persistLicenceDocument (trx, updatedAt, licenceDocument) {
return LicenceDocumentModel.query(trx)
.insert({ ...licenceDocument, updatedAt })
.onConflict('licenceRef')
.merge([
'endDate',
'startDate',
'updatedAt',
'deletedAt'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd have to dig into how deletedAt is determined (because I think that is set during the import as well).

But we shouldn't be overwriting this if it is already set.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The import sets this to null on the insert in the original query.

I took this as something has changed in NALD and now the data is no longer 'deleted' ?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see what you mean now.

Copy link
Collaborator Author

@jonathangoulding jonathangoulding Oct 16, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

-- auto-generated definition
create table documents
(
    document_id   uuid      default gen_random_uuid()                        not null
        primary key,
    regime        varchar   default 'water'::character varying               not null,
    document_type varchar   default 'abstraction_licence'::character varying not null,
    document_ref  varchar                                                    not null,
    start_date    date                                                       not null,
    end_date      date,
    external_id   varchar,
    date_created  timestamp default now()                                    not null,
    date_updated  timestamp default now()                                    not null,
    is_test       boolean   default false                                    not null,
    date_deleted  timestamp
);

I can remove 'deletedAt' from the upsert.

It will default to null if not set and not overide the existing logic.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change made and pushed to remove the deletedAt logic

])
}

module.exports = {
go
}
33 changes: 33 additions & 0 deletions app/validators/import/licence-document.validator.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
'use strict'

/**
* @module ImportLicenceDocumentValidator
*/

const Joi = require('joi')

/**
* Checks that imported licence data that has been transformed is valid for persisting to WRLS as a licence document
*
* @param {object} licenceDocument - The transformed licence data into a licence document
*
* @throws {Joi.ValidationError} - throws a Joi validation error if the validation fails
*/
function go (licenceDocument) {
const schema = Joi.object({
deletedAt: Joi.valid(null),
licenceRef: Joi.string().required(),
endDate: Joi.date().required().allow(null),
startDate: Joi.date().required()
})

const result = schema.validate(licenceDocument, { convert: false })

if (result.error) {
throw result.error
}
}

module.exports = {
go
}
2 changes: 1 addition & 1 deletion db/migrations/legacy/20221108003004_crm-v2-documents.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ exports.up = function (knex) {
table.timestamp('date_updated').notNullable().defaultTo(knex.fn.now())

// Constraints
table.unique(['regime', 'document_type', 'document_ref'])
table.unique(['document_ref'])
})
}

Expand Down
50 changes: 50 additions & 0 deletions test/presenters/import/legacy/licence-document.presenter.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
'use strict'

// Test framework dependencies
const Lab = require('@hapi/lab')
const Code = require('@hapi/code')

const { describe, it, beforeEach } = exports.lab = Lab.script()
const { expect } = Code

// Test helpers
const { generateLicenceRef } = require('../../../support/helpers/licence.helper.js')

// Thing under test
const LicenceDocumentPresenter = require('../../../../app/presenters/import/legacy/licence-document.presenter.js')

describe('Import Legacy Licence Document presenter', () => {
let legacyLicenceDocument
let licenceRef

beforeEach(() => {
licenceRef = generateLicenceRef()

legacyLicenceDocument = _legacyLicenceDocument(licenceRef)
})

it('correctly transforms the data', () => {
const result = LicenceDocumentPresenter.go(legacyLicenceDocument)

expect(result).to.equal({
deletedAt: null,
licenceRef,
endDate: null,
startDate: new Date('1999-01-01')
})
})

it('correctly sets the default data', () => {
const result = LicenceDocumentPresenter.go(legacyLicenceDocument)

expect(result.deletedAt).to.be.null()
})
})

function _legacyLicenceDocument (licenceRef) {
return {
end_date: null,
start_date: new Date('1999-01-01'),
licence_ref: licenceRef
}
}
2 changes: 2 additions & 0 deletions test/services/import/legacy/process-licence.service.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ const TransformAddressesService = require('../../../../app/services/import/legac
const TransformCompaniesService = require('../../../../app/services/import/legacy/transform-companies.service.js')
const TransformCompanyAddressesService = require('../../../../app/services/import/legacy/transform-company-addresses.service.js')
const TransformContactsService = require('../../../../app/services/import/legacy/transform-contacts.service.js')
const TransformLicenceDocumentService = require('../../../../app/services/import/legacy/transform-licence-document.service.js')
const TransformLicenceService = require('../../../../app/services/import/legacy/transform-licence.service.js')
const TransformLicenceVersionPurposeConditionsService = require('../../../../app/services/import/legacy/transform-licence-version-purpose-conditions.service.js')
const TransformLicenceVersionPurposesService = require('../../../../app/services/import/legacy/transform-licence-version-purposes.service.js')
Expand Down Expand Up @@ -49,6 +50,7 @@ describe('Import Legacy Process Licence service', () => {
Sinon.stub(TransformLicenceVersionsService, 'go').resolves()
Sinon.stub(TransformLicenceVersionPurposesService, 'go').resolves(transformedLicence)
Sinon.stub(TransformLicenceVersionPurposeConditionsService, 'go').resolves(transformedLicence)
Sinon.stub(TransformLicenceDocumentService, 'go').resolves()
Sinon.stub(TransformCompaniesService, 'go').resolves({ company: [], transformedCompany: [] })
Sinon.stub(TransformContactsService, 'go').resolves()
Sinon.stub(TransformAddressesService, 'go').resolves()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
'use strict'

// Test framework dependencies
const Lab = require('@hapi/lab')
const Code = require('@hapi/code')
const Sinon = require('sinon')

const { describe, it, beforeEach, afterEach } = exports.lab = Lab.script()
const { expect } = Code

// Test helpers
const { generateLicenceRef } = require('../../../support/helpers/licence.helper.js')

// Things to stub
const FetchLicenceDocumentService = require('../../../../app/services/import/legacy/fetch-licence-document.service.js')

// Thing under test
const TransformLicenceDocumentService =
require('../../../../app/services/import/legacy/transform-licence-document.service.js')

describe('Import Legacy Transform Licence Document service', () => {
// NOTE: Clearly this is an incomplete representation of the licence returned from TransformedLicenceService. But for
// the purposes of this service it is all that is needed
const transformedLicence = { licenceVersions: [] }

const naldLicenceId = '2113'
const regionCode = '6'

let legacyLicenceDocument
let licenceRef

beforeEach(() => {
licenceRef = generateLicenceRef()

legacyLicenceDocument = _legacyLicenceDocument(licenceRef)
})

afterEach(() => {
Sinon.restore()
})

describe('when a matching valid legacy licence is found', () => {
beforeEach(() => {
Sinon.stub(FetchLicenceDocumentService, 'go').resolves(legacyLicenceDocument)
})

it('attaches the record transformed and validated for WRLS to the transformed licence', async () => {
await TransformLicenceDocumentService.go(regionCode, naldLicenceId, transformedLicence)

expect(transformedLicence.licenceDocument).to.equal({
deletedAt: null,
licenceRef,
endDate: null,
startDate: new Date('1999-01-01')
})
})
})

describe('when no matching legacy licence version is found', () => {
jonathangoulding marked this conversation as resolved.
Show resolved Hide resolved
beforeEach(() => {
Sinon.stub(FetchLicenceDocumentService, 'go').resolves(null)
})

it('throws an error', async () => {
await expect(TransformLicenceDocumentService.go(regionCode, naldLicenceId, transformedLicence)).to.reject()
})
})
})

function _legacyLicenceDocument (licenceRef) {
return {
end_date: null,
start_date: new Date('1999-01-01'),
licence_ref: licenceRef
}
}
Loading
Loading