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

Implement permit fields in the survey metadata form #405

Merged
merged 20 commits into from
Jul 13, 2021
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
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
4 changes: 4 additions & 0 deletions api/src/models/survey-create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ export class PostSurveyObject {
survey_data_proprietary: boolean;
survey_purpose: string;
geometry: Feature[];
permit_number: string;
permit_type: string;
survey_proprietor?: PostSurveyProprietorData;

constructor(obj?: any) {
Expand All @@ -35,6 +37,8 @@ export class PostSurveyObject {
this.ancillary_species = (obj?.ancillary_species?.length && obj.ancillary_species) || [];
this.start_date = obj?.start_date || null;
this.survey_area_name = obj?.survey_area_name || null;
this.permit_number = obj?.permit_number || null;
this.permit_type = obj?.permit_type || null;
this.survey_data_proprietary = obj?.survey_data_proprietary === 'true' || false;
this.survey_name = obj?.survey_name || null;
this.survey_purpose = obj?.survey_purpose || null;
Expand Down
4 changes: 4 additions & 0 deletions api/src/models/survey-update.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ export class PutSurveyDetailsData {
lead_last_name: string;
location_name: string;
geometry: Feature[];
permit_number: string;
permit_type: string;
revision_count: number;

constructor(obj?: any) {
Expand All @@ -36,6 +38,8 @@ export class PutSurveyDetailsData {
this.lead_last_name = obj?.survey_details?.biologist_last_name || null;
this.location_name = obj?.survey_details?.survey_area_name || null;
this.geometry = obj?.survey_details?.geometry || null;
this.permit_number = obj?.survey_details.permit_number || null;
this.permit_type = obj?.survey_details.permit_type || null;
this.revision_count = obj?.survey_details?.revision_count ?? null;
}
}
Expand Down
4 changes: 4 additions & 0 deletions api/src/models/survey-view-update.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ export class GetSurveyDetailsData {
survey_area_name: string;
geometry: Feature[];
revision_count: number;
permit_number: string;
permit_type: string;
completion_status: string;
publish_date: string;

Expand Down Expand Up @@ -57,6 +59,8 @@ export class GetSurveyDetailsData {
this.biologist_last_name = surveyDataItem?.lead_last_name || '';
this.survey_area_name = surveyDataItem?.location_name || '';
this.geometry = (surveyDataItem?.geometry?.length && [JSON.parse(surveyDataItem.geometry)]) || [];
this.permit_number = surveyDataItem?.number || '';
this.permit_type = surveyDataItem?.type || '';
this.revision_count = surveyDataItem?.revision_count ?? null;
this.completion_status =
(surveyDataItem &&
Expand Down
6 changes: 6 additions & 0 deletions api/src/paths/project/{projectId}/survey/create.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@ describe('createSurvey', () => {

sinon.stub(survey_create_queries, 'postSurveySQL').returns(SQL`something`);
sinon.stub(survey_create_queries, 'postSurveyProprietorSQL').returns(null);
sinon.stub(create, 'insertSurveyPermit').resolves(true);

try {
const result = create.createSurvey();
Expand All @@ -226,6 +227,7 @@ describe('createSurvey', () => {
});

sinon.stub(survey_create_queries, 'postSurveySQL').returns(SQL`something`);
sinon.stub(create, 'insertSurveyPermit').resolves(true);

const result = create.createSurvey();

Expand Down Expand Up @@ -256,6 +258,7 @@ describe('createSurvey', () => {
sinon.stub(survey_create_queries, 'postSurveySQL').returns(SQL`something`);
sinon.stub(create, 'insertFocalSpecies').resolves(1);
sinon.stub(create, 'insertAncillarySpecies').resolves(1);
sinon.stub(create, 'insertSurveyPermit').resolves(true);

const result = create.createSurvey();

Expand Down Expand Up @@ -297,6 +300,7 @@ describe('createSurvey', () => {

sinon.stub(survey_create_queries, 'postSurveySQL').returns(SQL`something`);
sinon.stub(survey_create_queries, 'postSurveyProprietorSQL').returns(SQL`something else`);
sinon.stub(create, 'insertSurveyPermit').resolves(true);

const result = create.createSurvey();

Expand Down Expand Up @@ -326,6 +330,7 @@ describe('createSurvey', () => {

sinon.stub(survey_create_queries, 'postSurveySQL').returns(SQL`some query`);
sinon.stub(survey_create_queries, 'postSurveyProprietorSQL').returns(SQL`something else`);
sinon.stub(create, 'insertSurveyPermit').resolves(true);

try {
const result = create.createSurvey();
Expand Down Expand Up @@ -357,6 +362,7 @@ describe('createSurvey', () => {

sinon.stub(survey_create_queries, 'postSurveySQL').returns(SQL`some query`);
sinon.stub(survey_create_queries, 'postSurveyProprietorSQL').returns(SQL`something else`);
sinon.stub(create, 'insertSurveyPermit').resolves(true);

try {
const result = create.createSurvey();
Expand Down
44 changes: 43 additions & 1 deletion api/src/paths/project/{projectId}/survey/create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@ import { surveyCreatePostRequestObject, surveyIdResponseObject } from '../../../
import {
postAncillarySpeciesSQL,
postFocalSpeciesSQL,
postNewSurveyPermitSQL,
postSurveyProprietorSQL,
postSurveySQL
} from '../../../../queries/survey/survey-create-queries';
import { putNewSurveyPermitNumberSQL } from '../../../../queries/survey/survey-update-queries';
import { getLogger } from '../../../../utils/logger';
import { logRequest } from '../../../../utils/path-utils';

Expand Down Expand Up @@ -83,6 +85,7 @@ export function createSurvey(): RequestHandler {
throw new HTTP400('Missing required path param `projectId`');
}

const projectId = Number(req.params.projectId);
const connection = getDBConnection(req['keycloak_token']);
const sanitizedPostSurveyData = (req.body && new PostSurveyObject(req.body)) || null;

Expand All @@ -91,7 +94,7 @@ export function createSurvey(): RequestHandler {
}

try {
const postSurveySQLStatement = postSurveySQL(Number(req.params.projectId), sanitizedPostSurveyData);
const postSurveySQLStatement = postSurveySQL(projectId, sanitizedPostSurveyData);

if (!postSurveySQLStatement) {
throw new HTTP400('Failed to build survey SQL insert statement');
Expand Down Expand Up @@ -134,6 +137,17 @@ export function createSurvey(): RequestHandler {
)
);

// Handle inserting any permit associated to this survey
promises.push(
insertSurveyPermit(
sanitizedPostSurveyData.permit_number,
sanitizedPostSurveyData.permit_type,
projectId,
surveyId,
connection
)
);

// Handle survey proprietor data
sanitizedPostSurveyData.survey_proprietor &&
promises.push(insertSurveyProprietor(sanitizedPostSurveyData.survey_proprietor, surveyId, connection));
Expand Down Expand Up @@ -218,3 +232,31 @@ export const insertSurveyProprietor = async (

return result.id;
};

export const insertSurveyPermit = async (
permit_number: string,
permit_type: string | null,
project_id: number,
survey_id: number,
connection: IDBConnection
): Promise<boolean> => {
let sqlStatement;

if (!permit_type) {
sqlStatement = putNewSurveyPermitNumberSQL(survey_id, permit_number);
} else {
sqlStatement = postNewSurveyPermitSQL(project_id, survey_id, permit_number, permit_type);
}

if (!sqlStatement) {
throw new HTTP400('Failed to build SQL statement for insertSurveyPermit');
}

const response = await connection.query(sqlStatement.text, sqlStatement.values);

if (!response) {
throw new HTTP400('Failed to insert survey permit number data');
}

return true;
};
93 changes: 93 additions & 0 deletions api/src/paths/project/{projectId}/survey/permits/list.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
'use strict';

import { RequestHandler } from 'express';
import { Operation } from 'express-openapi';
import { SYSTEM_ROLE } from '../../../../../constants/roles';
import { getDBConnection } from '../../../../../database/db';
import { HTTP400 } from '../../../../../errors/CustomError';
import { getSurveyPermitNumbersSQL } from '../../../../../queries/survey/survey-view-queries';
import { getLogger } from '../../../../../utils/logger';

const defaultLog = getLogger('/api/project/{projectId}/survey/permits/list');

export const GET: Operation = [getPermitNumbers()];

GET.apiDoc = {
description: 'Fetches a list of permit numbers for a survey based on a project.',
tags: ['permit_numbers'],
security: [
{
Bearer: [SYSTEM_ROLE.SYSTEM_ADMIN, SYSTEM_ROLE.PROJECT_ADMIN]
}
],
parameters: [
{
in: 'path',
name: 'projectId',
schema: {
type: 'number'
},
required: true
}
],
responses: {
200: {
description: 'Permit numbers get response string array.',
content: {
'application/json': {
schema: {
type: 'array',
items: {
type: 'string'
},
description: 'Permit numbers applicable for the survey'
}
}
}
},
401: {
$ref: '#/components/responses/401'
},
default: {
$ref: '#/components/responses/default'
}
}
};

export function getPermitNumbers(): RequestHandler {
return async (req, res) => {
defaultLog.debug({ label: 'Get permit numbers list', message: 'params', req_params: req.params });

if (!req.params.projectId) {
throw new HTTP400('Missing required path param `projectId`');
}

const connection = getDBConnection(req['keycloak_token']);

try {
const getSurveyPermitNumbersSQLStatement = getSurveyPermitNumbersSQL(Number(req.params.projectId));

if (!getSurveyPermitNumbersSQLStatement) {
throw new HTTP400('Failed to build SQL get statement');
}

await connection.open();

const permitNumbersData = await connection.query(
getSurveyPermitNumbersSQLStatement.text,
getSurveyPermitNumbersSQLStatement.values
);

await connection.commit();

const getPermitNumbersData = (permitNumbersData && permitNumbersData.rows) || null;

return res.status(200).json(getPermitNumbersData);
} catch (error) {
defaultLog.debug({ label: 'getPermitNumbers', message: 'error', error });
throw error;
} finally {
connection.release();
}
};
}
13 changes: 10 additions & 3 deletions api/src/paths/project/{projectId}/survey/{surveyId}/update.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,9 @@ describe('getSurveyForUpdate', () => {
location_name: 'location',
revision_count: 1,
geometry: [],
publish_timestamp: null
publish_timestamp: null,
number: '123',
type: 'scientific'
};

const mockQuery = sinon.stub();
Expand Down Expand Up @@ -158,6 +160,8 @@ describe('getSurveyForUpdate', () => {
survey_area_name: survey_details.location_name,
revision_count: survey_details.revision_count,
geometry: survey_details.geometry,
permit_number: survey_details.number,
permit_type: survey_details.type,
completion_status: 'Completed',
publish_date: ''
},
Expand Down Expand Up @@ -291,6 +295,8 @@ describe('getSurveyForUpdate', () => {
survey_area_name: survey_details.location_name,
revision_count: survey_details.revision_count,
geometry: survey_details.geometry,
permit_number: '',
permit_type: '',
completion_status: 'Completed',
publish_date: ''
},
Expand Down Expand Up @@ -881,7 +887,7 @@ describe('updateSurveyDetailsData', () => {
}
});

it('should return true on success with focal and ancillary species', async () => {
it('should return resolved promises on success with focal and ancillary species', async () => {
const mockQuery = sinon.stub();

mockQuery.onFirstCall().resolves({ rowCount: 1 }).onSecondCall().resolves(true).onThirdCall().resolves(true);
Expand All @@ -892,13 +898,14 @@ describe('updateSurveyDetailsData', () => {

sinon.stub(create, 'insertFocalSpecies').resolves(1);
sinon.stub(create, 'insertAncillarySpecies').resolves(2);
sinon.stub(update, 'updateSurveyPermitNumber').resolves(true);

const result = await update.updateSurveyDetailsData(projectId, surveyId, data, {
...dbConnectionObj,
query: mockQuery
});

expect(result).to.eql([1, 2]);
expect(result).to.eql([1, 2, true]);
});
});

Expand Down
Loading