Skip to content

Commit

Permalink
Add LicenceDocumentRoleModel from document_roles (#630)
Browse files Browse the repository at this point in the history
https://eaflood.atlassian.net/browse/WATER-4292

> This is part of a series of changes to add the ability to identify the licence holder for a licence

This change adds the migration, model, test helper and unit tests for a new `LicenceDocumentRoleModel`.

We added [LicenceDocumentModel](#618). Though pointless, it's the only thing that points us to who the licence holder is. In the `crm_v2` schema it does this in `crm_v2.document_roles` which is the join table between `crm_v2.documents` and `crm_v2.roles`. `roles` is a lookup table of the 'role' a `crm_v2.contact` or `crm_c2.company` has, for example, licence holder! We added that as [LicenceRoleModel](#629).

We are now on the final step which is adding the model that allows us to identify and extract the `crm_v2.document_roles` record that identifies _who_ is the current licence holder for a licence.
  • Loading branch information
Cruikshanks authored Jan 3, 2024
1 parent 2e4755e commit f2c9e7c
Show file tree
Hide file tree
Showing 15 changed files with 660 additions and 4 deletions.
8 changes: 8 additions & 0 deletions app/models/address.model.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,14 @@ class AddressModel extends BaseModel {
from: 'addresses.id',
to: 'billingAccountAddresses.addressId'
}
},
licenceDocumentRoles: {
relation: Model.HasManyRelation,
modelClass: 'licence-document-role.model',
join: {
from: 'addresses.id',
to: 'licenceDocumentRoles.addressId'
}
}
}
}
Expand Down
8 changes: 8 additions & 0 deletions app/models/company.model.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,14 @@ class CompanyModel extends BaseModel {
from: 'companies.id',
to: 'billingAccounts.companyId'
}
},
licenceDocumentRoles: {
relation: Model.HasManyRelation,
modelClass: 'licence-document-role.model',
join: {
from: 'companies.id',
to: 'licenceDocumentRoles.companyId'
}
}
}
}
Expand Down
8 changes: 8 additions & 0 deletions app/models/contact.model.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,14 @@ class ContactModel extends BaseModel {
from: 'contacts.id',
to: 'billingAccountAddresses.contactId'
}
},
licenceDocumentRoles: {
relation: Model.HasManyRelation,
modelClass: 'licence-document-role.model',
join: {
from: 'contacts.id',
to: 'licenceDocumentRoles.contactId'
}
}
}
}
Expand Down
63 changes: 63 additions & 0 deletions app/models/licence-document-role.model.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
'use strict'

/**
* Model for licence_document_roles (crm_v2.document_roles)
* @module LicenceDocumentRoleModel
*/

const { Model } = require('objection')

const BaseModel = require('./base.model.js')

class LicenceDocumentRoleModel extends BaseModel {
static get tableName () {
return 'licenceDocumentRoles'
}

static get relationMappings () {
return {
address: {
relation: Model.BelongsToOneRelation,
modelClass: 'address.model',
join: {
from: 'licenceDocumentRoles.addressId',
to: 'addresses.id'
}
},
company: {
relation: Model.BelongsToOneRelation,
modelClass: 'company.model',
join: {
from: 'licenceDocumentRoles.companyId',
to: 'companies.id'
}
},
contact: {
relation: Model.BelongsToOneRelation,
modelClass: 'contact.model',
join: {
from: 'licenceDocumentRoles.contactId',
to: 'contacts.id'
}
},
licenceDocument: {
relation: Model.BelongsToOneRelation,
modelClass: 'licence-document.model',
join: {
from: 'licenceDocumentRoles.licenceDocumentId',
to: 'licenceDocuments.id'
}
},
licenceRole: {
relation: Model.BelongsToOneRelation,
modelClass: 'licence-role.model',
join: {
from: 'licenceDocumentRoles.licenceRoleId',
to: 'licenceRoles.id'
}
}
}
}
}

module.exports = LicenceDocumentRoleModel
15 changes: 15 additions & 0 deletions app/models/licence-document.model.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,27 @@
* @module LicenceDocumentModel
*/

const { Model } = require('objection')

const BaseModel = require('./base.model.js')

class LicenceDocumentModel extends BaseModel {
static get tableName () {
return 'licenceDocuments'
}

static get relationMappings () {
return {
licenceDocumentRoles: {
relation: Model.HasManyRelation,
modelClass: 'licence-document-role.model',
join: {
from: 'licenceDocuments.id',
to: 'licenceDocumentRoles.licenceDocumentId'
}
}
}
}
}

module.exports = LicenceDocumentModel
15 changes: 15 additions & 0 deletions app/models/licence-role.model.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,27 @@
* @module LicenceRoleModel
*/

const { Model } = require('objection')

const BaseModel = require('./base.model.js')

class LicenceRoleModel extends BaseModel {
static get tableName () {
return 'licenceRoles'
}

static get relationMappings () {
return {
licenceDocumentRoles: {
relation: Model.HasManyRelation,
modelClass: 'licence-document-role.model',
join: {
from: 'licenceRoles.id',
to: 'licenceDocumentRoles.licenceRoleId'
}
}
}
}
}

module.exports = LicenceRoleModel
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
'use strict'

const tableName = 'document_roles'

exports.up = function (knex) {
return knex
.schema
.withSchema('crm_v2')
.createTable(tableName, (table) => {
// Primary Key
table.uuid('document_role_id').primary().defaultTo(knex.raw('gen_random_uuid()'))

// Data
table.uuid('document_id').notNullable()
table.uuid('company_id')
table.uuid('contact_id')
table.uuid('address_id')
table.uuid('role_id').notNullable()
table.date('start_date').notNullable()
table.date('end_date')
table.uuid('invoice_account_id')
table.boolean('is_test').notNullable().defaultTo(false)

// Legacy timestamps
table.timestamp('date_created').notNullable().defaultTo(knex.fn.now())
table.timestamp('date_updated').notNullable().defaultTo(knex.fn.now())

// Constraints
table.unique(['document_id', 'role_id', 'start_date'], { useConstraint: true })
})
// If it was a simple check constraint we could have used https://knexjs.org/guide/schema-builder.html#checks
// But because of the complexity of the constraint we have had to drop to using raw() to add the constraint after
// Knex has created the table.
.raw(`
ALTER TABLE crm_v2.document_roles
ADD CONSTRAINT company_or_invoice_account
CHECK (
((company_id IS NOT NULL AND address_id IS NOT NULL) OR invoice_account_id IS NOT NULL)
);
`)
}

exports.down = function (knex) {
return knex
.schema
.withSchema('crm_v2')
.dropTableIfExists(tableName)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
'use strict'

const viewName = 'licence_document_roles'

exports.up = function (knex) {
return knex
.schema
.createView(viewName, (view) => {
// NOTE: We have commented out unused columns from the source table
view.as(knex('document_roles').withSchema('crm_v2').select([
'document_role_id AS id',
'document_id AS licence_document_id',
'company_id',
'contact_id',
'address_id',
'role_id AS licence_role_id',
// 'invoice_account_id',
'start_date',
'end_date',
// 'is_test',
'date_created AS created_at',
'date_updated AS updated_at'
]))
})
}

exports.down = function (knex) {
return knex
.schema
.dropViewIfExists(viewName)
}
39 changes: 39 additions & 0 deletions test/models/address.model.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ const AddressHelper = require('../support/helpers/address.helper.js')
const BillingAccountAddressHelper = require('../support/helpers/billing-account-address.helper.js')
const BillingAccountAddressModel = require('../../app/models/billing-account-address.model.js')
const DatabaseHelper = require('../support/helpers/database.helper.js')
const LicenceDocumentRoleHelper = require('../support/helpers/licence-document-role.helper.js')
const LicenceDocumentRoleModel = require('../../app/models/licence-document-role.model.js')

// Thing under test
const AddressModel = require('../../app/models/address.model.js')
Expand Down Expand Up @@ -75,5 +77,42 @@ describe('Address model', () => {
expect(result.billingAccountAddresses).to.include(testBillingAccountAddresses[1])
})
})

describe('when linking to licence document roles', () => {
let testLicenceDocumentRoles

beforeEach(async () => {
testRecord = await AddressHelper.add()

const { id: addressId } = testRecord

testLicenceDocumentRoles = []
for (let i = 0; i < 2; i++) {
const licenceDocumentRole = await LicenceDocumentRoleHelper.add({ addressId })
testLicenceDocumentRoles.push(licenceDocumentRole)
}
})

it('can successfully run a related query', async () => {
const query = await AddressModel.query()
.innerJoinRelated('licenceDocumentRoles')

expect(query).to.exist()
})

it('can eager load the licence document roles', async () => {
const result = await AddressModel.query()
.findById(testRecord.id)
.withGraphFetched('licenceDocumentRoles')

expect(result).to.be.instanceOf(AddressModel)
expect(result.id).to.equal(testRecord.id)

expect(result.licenceDocumentRoles).to.be.an.array()
expect(result.licenceDocumentRoles[0]).to.be.an.instanceOf(LicenceDocumentRoleModel)
expect(result.licenceDocumentRoles).to.include(testLicenceDocumentRoles[0])
expect(result.licenceDocumentRoles).to.include(testLicenceDocumentRoles[1])
})
})
})
})
39 changes: 39 additions & 0 deletions test/models/company.model.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ const BillingAccountHelper = require('../support/helpers/billing-account.helper.
const BillingAccountModel = require('../../app/models/billing-account.model.js')
const CompanyHelper = require('../support/helpers/company.helper.js')
const DatabaseHelper = require('../support/helpers/database.helper.js')
const LicenceDocumentRoleHelper = require('../support/helpers/licence-document-role.helper.js')
const LicenceDocumentRoleModel = require('../../app/models/licence-document-role.model.js')

// Thing under test
const CompanyModel = require('../../app/models/company.model.js')
Expand Down Expand Up @@ -113,5 +115,42 @@ describe('Company model', () => {
expect(result.billingAccounts).to.include(testBillingAccounts[1])
})
})

describe('when linking to licence document roles', () => {
let testLicenceDocumentRoles

beforeEach(async () => {
testRecord = await CompanyHelper.add()

const { id: companyId } = testRecord

testLicenceDocumentRoles = []
for (let i = 0; i < 2; i++) {
const licenceDocumentRole = await LicenceDocumentRoleHelper.add({ companyId })
testLicenceDocumentRoles.push(licenceDocumentRole)
}
})

it('can successfully run a related query', async () => {
const query = await CompanyModel.query()
.innerJoinRelated('licenceDocumentRoles')

expect(query).to.exist()
})

it('can eager load the licence document roles', async () => {
const result = await CompanyModel.query()
.findById(testRecord.id)
.withGraphFetched('licenceDocumentRoles')

expect(result).to.be.instanceOf(CompanyModel)
expect(result.id).to.equal(testRecord.id)

expect(result.licenceDocumentRoles).to.be.an.array()
expect(result.licenceDocumentRoles[0]).to.be.an.instanceOf(LicenceDocumentRoleModel)
expect(result.licenceDocumentRoles).to.include(testLicenceDocumentRoles[0])
expect(result.licenceDocumentRoles).to.include(testLicenceDocumentRoles[1])
})
})
})
})
Loading

0 comments on commit f2c9e7c

Please sign in to comment.