Skip to content

Commit

Permalink
Create crm_v2 schema models and helpers (#561)
Browse files Browse the repository at this point in the history
https://eaflood.atlassian.net/browse/WATER-4057

As part of the work we have been doing on two-part tariff we are going to be creating all our new tables in the default `public` schema.

We have also decided that when there is a legacy table that we are still going to need we will create a [View](https://www.postgresql.org/docs/current/sql-createview.html) of it in the `public` schema. This allows us to correct any issues with naming conventions, strip out unused fields, and join entities that are currently sat in different schemas. The first example of this approach was done in PR #531 .

This change adds the models and helpers for the views in the `crm_v2` schema that were created in PR #556

> The final step will then be to refactor the existing code to use the new models and delete the old legacy ones.
  • Loading branch information
Cruikshanks authored Dec 4, 2023
1 parent 1ca446d commit 174a8c3
Show file tree
Hide file tree
Showing 18 changed files with 1,341 additions and 3 deletions.
31 changes: 31 additions & 0 deletions app/models/address.model.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
'use strict'

/**
* Model for addresses (crm_v2.addresses)
* @module AddressModel
*/

const { Model } = require('objection')

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

class AddressModel extends BaseModel {
static get tableName () {
return 'addresses'
}

static get relationMappings () {
return {
billingAccountAddresses: {
relation: Model.HasManyRelation,
modelClass: 'billing-account-address.model',
join: {
from: 'addresses.id',
to: 'billingAccountAddresses.addressId'
}
}
}
}
}

module.exports = AddressModel
55 changes: 55 additions & 0 deletions app/models/billing-account-address.model.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
'use strict'

/**
* Model for billing_account_addresses (crm_v2.invoice_account_addresses)
* @module BillingAccountAddressModel
*/

const { Model } = require('objection')

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

class BillingAccountAddressModel extends BaseModel {
static get tableName () {
return 'billingAccountAddresses'
}

static get relationMappings () {
return {
address: {
relation: Model.BelongsToOneRelation,
modelClass: 'address.model',
join: {
from: 'billingAccountAddresses.addressId',
to: 'addresses.id'
}
},
billingAccount: {
relation: Model.BelongsToOneRelation,
modelClass: 'billing-account.model',
join: {
from: 'billingAccountAddresses.billingAccountId',
to: 'billingAccounts.id'
}
},
company: {
relation: Model.BelongsToOneRelation,
modelClass: 'company.model',
join: {
from: 'billingAccountAddresses.companyId',
to: 'companies.id'
}
},
contact: {
relation: Model.BelongsToOneRelation,
modelClass: 'contact.model',
join: {
from: 'billingAccountAddresses.contactId',
to: 'contacts.id'
}
}
}
}
}

module.exports = BillingAccountAddressModel
39 changes: 39 additions & 0 deletions app/models/billing-account.model.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
'use strict'

/**
* Model for billing_accounts (crm_v2.invoice_accounts)
* @module BillingAccountModel
*/

const { Model } = require('objection')

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

class BillingAccountModel extends BaseModel {
static get tableName () {
return 'billingAccounts'
}

static get relationMappings () {
return {
billingAccountAddresses: {
relation: Model.HasManyRelation,
modelClass: 'billing-account-address.model',
join: {
from: 'billingAccounts.id',
to: 'billingAccountAddresses.billingAccountId'
}
},
company: {
relation: Model.BelongsToOneRelation,
modelClass: 'company.model',
join: {
from: 'billingAccounts.companyId',
to: 'companies.id'
}
}
}
}
}

module.exports = BillingAccountModel
71 changes: 71 additions & 0 deletions app/models/company.model.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
'use strict'

/**
* Model for companies (crm_v2.companies)
* @module CompanyModel
*/

const { Model } = require('objection')

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

/**
* Objection model that represents a `company` in the `crm_v2.companies` table
*
* ### Notes
*
* There is no `dataSource` field in the table. But anything that has `externalId` populated can be assumed to have been
* imported from NALD and everything else directly entered into WRLS.
*
* For all records `name` and `type` are set
*
* When the source is 'nald'
*
* - `companyNumber` is always null
* - `organisationType` is always null
* - `lastHash` is always set
* - `currentHash` is always set
* - `externalId` is always set
*
* When the source is 'wrls'
*
* - `lastHash` is always null
* - `currentHash` is always null
* - `externalId` is always null
* - if `type` is 'organisation' then `companyNumber` is always set
* - if `type` is 'organisation' then `organisationType` can be null or set
* - if `type` is 'person' then `companyNumber` is always null
* - if `type` is 'person' then `organisationType` is always null
* - as of 2023-08-01 there were 28 companies with `type` set to 'organisation'
*
* We currently do not know how `organisationType` gets populated!
*
*/
class CompanyModel extends BaseModel {
static get tableName () {
return 'companies'
}

static get relationMappings () {
return {
billingAccountAddresses: {
relation: Model.HasManyRelation,
modelClass: 'billing-account-address.model',
join: {
from: 'companies.id',
to: 'billingAccountAddresses.companyId'
}
},
billingAccounts: {
relation: Model.HasManyRelation,
modelClass: 'billing-account.model',
join: {
from: 'companies.id',
to: 'billingAccounts.companyId'
}
}
}
}
}

module.exports = CompanyModel
102 changes: 102 additions & 0 deletions app/models/contact.model.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
'use strict'

/**
* Model for contacts (crm_v2.contacts)
* @module ContactModel
*/

const { Model } = require('objection')

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

/**
* Objection model that represents a `contact` in the `crm_v2.contacts` table
*
* ### Notes
*
* For all records `lastName` is always set
*
* When the `dataSource` is 'nald'
*
* - `contactType` is always null
* - `department` is always null
* - `middleInitials` is always null
* - `suffix` is always null
* - `externalId` is always set
*
* When the `dataSource` is 'wrls'
*
* - `contactType` is always set
* - `initials` is always null
* - `externalId` is always null
* - if `middleInitials` is set then `firstName` is always set
* - a 'person' always has `firstName` and `lastName` set
* - a 'person' can have `department` populated
* - a 'department' will only have `department` populated
* - as of 2023-08-01 there were 6 contacts with `suffix` populated out of 42,827 (1,621 WRLS)
*
*/
class ContactModel extends BaseModel {
static get tableName () {
return 'contacts'
}

static get relationMappings () {
return {
billingAccountAddresses: {
relation: Model.HasManyRelation,
modelClass: 'billing-account-address.model',
join: {
from: 'contacts.id',
to: 'billingAccountAddresses.contactId'
}
}
}
}

/**
* Returns the name for the contact derived from its various parts
*
* We have 2 sources for contact data; the import from NALD and those directly entered into the service. For reasons
* only the previous team will know we have not been consistent across them. What fields are populated depends on
* the data source. Added to that 'contacts' entered via the service are used to hold both departments and people.
*
* We have to send a derived name when sending customer changes to the Charging Module API as it accepts only a
* single `customerName` value. What we have implemented here replicates what the legacy code was doing to derive
* what that name should be.
*
* @returns {String} The name for the contact derived from its various parts
*/
$name () {
if (this.contactType === 'department') {
return this.department
}

const initials = this._determineInitials()

const allNameParts = [
this.salutation,
initials || this.firstName, // if we have initials use them else use firstName
this.lastName,
this.suffix
]

const onlyPopulatedNameParts = allNameParts.filter((item) => item)

return onlyPopulatedNameParts.join(' ')
}

_determineInitials () {
if (this.initials) {
return this.initials
}

if (this.middleInitials) {
return `${this.firstName.slice(0, 1)} ${this.middleInitials}`
}

return null
}
}

module.exports = ContactModel
2 changes: 1 addition & 1 deletion app/models/return-log.model.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
'use strict'

/**
* Model for return_logs
* Model for return_logs (returns.returns)
* @module ReturnLogModel
*/

Expand Down
2 changes: 1 addition & 1 deletion app/models/return-submission-line.model.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
'use strict'

/**
* Model for return_submission_lines
* Model for return_submission_lines (returns.lines)
* @module ReturnSubmissionLineModel
*/

Expand Down
2 changes: 1 addition & 1 deletion app/models/return-submission.model.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
'use strict'

/**
* Model for return_submissions
* Model for return_submissions (returns.versions)
* @module ReturnSubmissionModel
*/

Expand Down
Loading

0 comments on commit 174a8c3

Please sign in to comment.