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

Feature/readable ticket #53

Merged
merged 4 commits into from
Feb 22, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 4 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,17 @@
"generate-fake-data": "ts-node ./src/cli/generate-fake-data",
"send-test-email": "ts-node ./src/cli/send-test-email",
"send-test-sms": "ts-node ./src/cli/send-test-sms",
"send-test-dispatch": "ts-node ./src/cli/send-test-dispatch"
"send-test-dispatch": "ts-node ./src/cli/send-test-dispatch",
"ensure-public-ids": "ts-node ./src/cli/ensure-public-ids"
},
"bin": {
"govflow-start": "./cli/default-server.js",
"govflow-migrate": "./cli/migrate-database.js",
"govflow-generate-fake-data": "./cli/generate-fake-data.js",
"govflow-send-test-email": "./cli/send-test-email.js",
"govflow-send-test-sms": "./cli/send-test-sms.js",
"govflow-send-test-dispatch": "./cli/send-test-dispatch.js"
"govflow-send-test-dispatch": "./cli/send-test-dispatch.js",
"govflow-ensure-public-ids": "./cli/ensure-public-ids.js"
},
"license": "MIT",
"dependencies": {
Expand Down
12 changes: 12 additions & 0 deletions src/cli/ensure-public-ids.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#! /usr/bin/env node
import { createApp } from '..';

(async () => {
const app = await createApp();
const { database } = app;
const { ServiceRequest } = database.models;
const records = await ServiceRequest.findAll();
for (const record of records) {
await record.save()
}
})();
41 changes: 40 additions & 1 deletion src/core/service-requests/helpers.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { StaffUserAttributes } from "../../types";
import { Op } from "sequelize";
import { ServiceRequestInstance, ServiceRequestModel, StaffUserAttributes } from "../../types";

export function makeAuditMessage(user: StaffUserAttributes | undefined, fieldName: string, oldValue:string, newValue:string): string {
let displayName = 'System';
Expand All @@ -7,3 +8,41 @@ export function makeAuditMessage(user: StaffUserAttributes | undefined, fieldNam
}
return `${displayName} changed this request ${fieldName} from ${oldValue} to ${newValue}`;
}

export function makePublicIdString(year: number, month: number, counter: number): string {
const yearStr = year.toString(10).slice(-2);
const monthStr = String((month + 1).toString(10)).padStart(2, "0");
return `${yearStr}${monthStr}${counter}`;
}
export async function makePublicIdForRequest(instance: ServiceRequestInstance): Promise<void> {
if (instance.publicId) {
// do nothing if the instance already has a publicId
} else {
const year = instance.createdAt.getFullYear();
const month = instance.createdAt.getMonth();
const windowLower = new Date(year, month, 0);
const windowHigher = (month != 11) ? new Date(year, month + 1, 0) : new Date(year + 1, 0, 0);
const ServiceRequest = instance.constructor as ServiceRequestModel;
const lookup = await ServiceRequest.findAll(
{
where: {
jurisdictionId: instance.jurisdictionId,
createdAt: { [Op.gte]: windowLower, [Op.lt]: windowHigher }
}
}
) as ServiceRequestInstance[];
let lastIncrement = 0;
if (lookup.length > 0) {
const lastRecord = lookup.reduce(
(last: ServiceRequestInstance, curr: ServiceRequestInstance) =>
(last.idCounter > curr.idCounter) ? last : curr

);
lastIncrement = lastRecord.idCounter;
}
const idCounter = lastIncrement + 1;
const publicId = makePublicIdString(year, month, idCounter);
instance.idCounter = idCounter;
instance.publicId = publicId;
}
}
20 changes: 19 additions & 1 deletion src/core/service-requests/models.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { DataTypes } from 'sequelize';
import { ModelDefinition } from '../../types';
import { ModelDefinition, ServiceRequestInstance } from '../../types';
import { makePublicIdForRequest } from './helpers';

export const REQUEST_STATUSES = {
'inbox': 'Inbox',
Expand Down Expand Up @@ -39,6 +40,14 @@ export const ServiceRequestModel: ModelDefinition = {
allowNull: false,
primaryKey: true,
},
publicId: {
type: DataTypes.STRING,
allowNull: false,
},
idCounter: {
type: DataTypes.INTEGER,
allowNull: false,
},
inputChannel: {
allowNull: false,
type: DataTypes.ENUM(...INPUT_CHANNEL_KEYS),
Expand Down Expand Up @@ -172,6 +181,10 @@ export const ServiceRequestModel: ModelDefinition = {
unique: true,
fields: ['id', 'jurisdictionId']
},
{
unique: true,
fields: ['publicId', 'jurisdictionId']
},
{
unique: false,
fields: ['status']
Expand All @@ -195,6 +208,11 @@ export const ServiceRequestModel: ModelDefinition = {
throw new Error('A Service Request requires one of a lat/lon pair, address, or address_id.');
}
}
},
hooks: {
beforeValidate(instance: ServiceRequestInstance) {
return makePublicIdForRequest(instance);
}
}
}
}
Expand Down
4 changes: 0 additions & 4 deletions src/core/service-requests/repositories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,8 +138,6 @@ export class ServiceRequestRepository implements IServiceRequestRepository {
): Promise<ServiceRequestAttributes> {
const { ServiceRequest } = this.models;
let record = await ServiceRequest.findByPk(id) as ServiceRequestInstance;
console.error("ASSIGNED TO")
console.error(user);
const auditMessage = makeAuditMessage(user, '"assigned to"', record.assignedTo, assignedTo);
record.assignedTo = assignedTo;
record = await record.save();
Expand All @@ -152,8 +150,6 @@ export class ServiceRequestRepository implements IServiceRequestRepository {
): Promise<ServiceRequestAttributes> {
const { ServiceRequest } = this.models;
let record = await ServiceRequest.findByPk(id) as ServiceRequestInstance;
console.error("DEPARTMENT")
console.error(user);
const auditMessage = makeAuditMessage(user, '"department"', record.departmentId, department);
record.departmentId = department;
record = await record.save();
Expand Down
22 changes: 22 additions & 0 deletions src/migrations/11_public_id_for_request.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import type { QueryInterface } from 'sequelize';
import { DataTypes } from 'sequelize';

export async function up({ context: queryInterface }: Record<string, QueryInterface>): Promise<void> {
await queryInterface.addColumn(
'ServiceRequest',
'publicId',
{ type: DataTypes.STRING, allowNull: false }
);
await queryInterface.addColumn(
'ServiceRequest',
'idCounter',
{ type: DataTypes.INTEGER, allowNull: false }
);
await queryInterface.addIndex('ServiceRequest', ['jurisdictionId', 'publicId']);
}

export async function down({ context: queryInterface }: Record<string, QueryInterface>): Promise<void> {
await queryInterface.removeColumn('ServiceRequest', 'publicId');
await queryInterface.removeColumn('ServiceRequest', 'idCounter');
await queryInterface.removeIndex('ServiceRequest', ['jurisdictionId', 'publicId'])
}
2 changes: 2 additions & 0 deletions src/types/data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ export interface ServiceInstance

export interface ServiceRequestAttributes {
id: string;
publicId: string,
idCounter: number,
serviceId?: string;
jurisdictionId: string;
description: string;
Expand Down
4 changes: 3 additions & 1 deletion src/types/db.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,13 @@ export interface ServiceRequestFilterParams {
assignedTo?: string;
}

export type ServiceRequestModel = ModelCtor<Model<ServiceRequestAttributes, ServiceRequestCreateAttributes>>;

export interface Models {
Jurisdiction: ModelCtor<Model<JurisdictionAttributes, JurisdictionCreateAttributes>>,
StaffUser: ModelCtor<Model<StaffUserAttributes, StaffUserCreateAttributes>>,
Service: ModelCtor<Model<ServiceAttributes, ServiceCreateAttributes>>,
ServiceRequest: ModelCtor<Model<ServiceRequestAttributes, ServiceRequestCreateAttributes>>,
ServiceRequest: ServiceRequestModel,
ServiceRequestComment: ModelCtor<Model<ServiceRequestCommentAttributes, ServiceRequestCommentCreateAttributes>>,
Communication: ModelCtor<Model<CommunicationAttributes, CommunicationCreateAttributes>>,
Department: ModelCtor<Model<DepartmentAttributes, DepartmentCreateAttributes>>,
Expand Down
12 changes: 11 additions & 1 deletion test/test-models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import chai from 'chai';
import type { Application } from 'express';
import { createApp } from '../src/index';
import makeTestData from '../src/tools/fake-data-generator';
import { TestDataPayload } from '../src/types';
import { ServiceRequestInstance, TestDataPayload } from '../src/types';

describe('Verify Core Models.', function () {

Expand Down Expand Up @@ -60,6 +60,16 @@ describe('Verify Core Models.', function () {
}
});

it('should have generated public ids for service requests', async function () {
const { ServiceRequest } = app.database.models;
const records = await ServiceRequest.findAll() as ServiceRequestInstance[];

for (const record of records) {
chai.assert(record.publicId);
chai.assert(record.idCounter);
}
});

it('should write communications to database', async function () {
const { Communication } = app.database.models;
for (const communicationData of testData.communications) {
Expand Down