Skip to content

Commit

Permalink
New charge category model for SROC supplementary bill run (#57)
Browse files Browse the repository at this point in the history
https://eaflood.atlassian.net/browse/WATER-3861

Behind the scenes, the charge references are held in the billing_charge_categories table. It is a lookup table as the references are static. They are linked to a charge version via the charge_elements table.
  • Loading branch information
Jozzey authored Dec 16, 2022
1 parent 11cf126 commit 540a998
Show file tree
Hide file tree
Showing 6 changed files with 190 additions and 0 deletions.
31 changes: 31 additions & 0 deletions app/models/billing-charge-category.model.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
'use strict'

/**
* Model for water.billing_charge_categories
* @module BillingChargeCategoryModel
*/

const { Model } = require('objection')

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

class BillingChargeCategoryModel extends BaseModel {
static get tableName () {
return 'water.billing_charge_categories'
}

static get relationMappings () {
return {
chargeElement: {
relation: Model.HasManyRelation,
modelClass: 'charge-element.model',
join: {
from: 'water.billing_charge_categories.billing_charge_category_id',
to: 'water.charge_elements.billing_charge_category_id'
}
}
}
}
}

module.exports = BillingChargeCategoryModel
8 changes: 8 additions & 0 deletions app/models/charge-element.model.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,14 @@ class ChargeElementModel extends BaseModel {
from: 'water.charge_elements.charge_version_id',
to: 'water.charge_versions.charge_version_id'
}
},
billingChargeCategory: {
relation: Model.BelongsToOneRelation,
modelClass: 'billing-charge-category.model',
join: {
from: 'water.charge_elements.billing_charge_category_id',
to: 'water.billing_charge_categories.billing_charge_category_id'
}
}
}
}
Expand Down
43 changes: 43 additions & 0 deletions db/migrations/20221216112650_create_billing_charge_categories.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
'use strict'

const tableName = 'billing_charge_categories'

exports.up = async function (knex) {
await knex
.schema
.withSchema('water')
.createTable(tableName, table => {
// Primary Key
table.uuid('billing_charge_category_id').primary().defaultTo(knex.raw('gen_random_uuid()'))

// Data
table.string('reference')
table.integer('subsistence_charge')
table.string('description')
table.string('short_description')
table.boolean('is_tidal')
table.string('loss_factor')
table.string('model_tier')
table.boolean('is_restricted_source')
table.bigInteger('min_volume')
table.bigInteger('max_volume')

// Automatic timestamps
table.timestamps(false, true)
})

await knex.raw(`
CREATE TRIGGER update_timestamp
BEFORE UPDATE
ON water.${tableName}
FOR EACH ROW
EXECUTE PROCEDURE update_timestamp();
`)
}

exports.down = function (knex) {
return knex
.schema
.withSchema('water')
.dropTableIfExists(tableName)
}
30 changes: 30 additions & 0 deletions test/models/billing-charge-category.model.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
'use strict'

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

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

// Thing under test
const BillingChargeCategory = require('../../app/models/billing-charge-category.model.js')

describe('Billing Charge Category model', () => {
it('can successfully run a query', async () => {
const query = await BillingChargeCategory.query()

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

describe('Relationships', () => {
describe('when linking to charge element', () => {
it('can successfully run a query', async () => {
const query = await BillingChargeCategory.query()
.innerJoinRelated('chargeElement')

expect(query).to.exist()
})
})
})
})
9 changes: 9 additions & 0 deletions test/models/charge-element.model.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,14 @@ describe('Charge Element model', () => {
expect(query).to.exist()
})
})

describe('when linking to billing charge category', () => {
it('can successfully run a query', async () => {
const query = await ChargeElement.query()
.innerJoinRelated('billingChargeCategory')

expect(query).to.exist()
})
})
})
})
69 changes: 69 additions & 0 deletions test/support/helpers/billing-charge-category.helper.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
'use strict'

/**
* @module BillingChargeCategoryHelper
*/

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

/**
* Add a new billing charge category
*
* If no `data` is provided, default values will be used. These are
*
* - `reference` - 4.4.5
* - `subsistence_charge` - 12000
* - `description` - Low loss non-tidal abstraction of restricted water up to and including 5,000 megalitres a year, where a Tier 1 model applies.
* - `short_description` - Low loss, non-tidal, restricted water, up to and including 5,000 ML/yr, Tier 1 model
* - `is_tidal` - false
* - `loss_factor` - low
* - `model_tier` - tier 1
* - `is_restricted_source` - true
* - `min_volume` - 0
* - `max_volume` - 5000
*
* @param {Object} [data] Any data you want to use instead of the defaults used here or in the database
*
* @returns {string} The ID of the newly created record
*/
async function add (data = {}) {
const insertData = defaults(data)

const result = await db.table('water.billing_charge_categories')
.insert(insertData)
.returning('billing_charge_category_id')

return result
}

/**
* Returns the defaults used when creating a new billing charge category
*
* It will override or append to them any data provided. Mainly used by the `add()` method, we make it available
* for use in tests to avoid having to duplicate values.
*
* @param {Object} [data] Any data you want to use instead of the defaults used here or in the database
*/
function defaults (data = {}) {
const defaults = {
reference: '4.4.5',
subsistence_charge: 12000,
description: 'Low loss non-tidal abstraction of restricted water up to and including 5,000 megalitres a year, where a Tier 1 model applies.',
short_description: 'Low loss, non-tidal, restricted water, up to and including 5,000 ML/yr, Tier 1 model',
is_tidal: false,
loss_factor: 'low',
model_tier: 'tier 1',
is_restricted_source: true,
min_volume: 0,
max_volume: 5000
}

return {
...defaults,
...data
}
}

module.exports = {
add
}

0 comments on commit 540a998

Please sign in to comment.