From 616405e4ca15345d35ce6b0a61a496ffc3691009 Mon Sep 17 00:00:00 2001 From: Brijesh Date: Thu, 28 Sep 2023 15:14:32 -0700 Subject: [PATCH] Cdog Integration PDF changes/improvement --- .gitignore | 1 + planTemplate.docx | Bin 0 -> 84489 bytes src/libs/cdogs.js | 86 +++++ src/libs/mailer.js | 2 +- src/libs/template.js | 327 -------------------- src/router/controllers_v1/PDFGeneratoin.js | 146 +++++++++ src/router/controllers_v1/PlanController.js | 25 +- src/router/helpers/PDFHelper.js | 77 +++++ src/router/index.js | 4 +- src/router/routes_v1/plan.js | 3 + src/router/routes_v1/report.js | 144 --------- 11 files changed, 330 insertions(+), 485 deletions(-) create mode 100644 planTemplate.docx create mode 100644 src/libs/cdogs.js delete mode 100644 src/libs/template.js create mode 100644 src/router/controllers_v1/PDFGeneratoin.js create mode 100644 src/router/helpers/PDFHelper.js delete mode 100644 src/router/routes_v1/report.js diff --git a/.gitignore b/.gitignore index cde51608..8c47bd0e 100644 --- a/.gitignore +++ b/.gitignore @@ -18,6 +18,7 @@ schemaspy import public/doc sonar-runner/build +sonar-runner/.gradle # Autogenerated document location. See npm scripts. apidoc diff --git a/planTemplate.docx b/planTemplate.docx new file mode 100644 index 0000000000000000000000000000000000000000..38a2d3ae5c5f49ec089ec1e135b5287f4391ddad GIT binary patch literal 84489 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 literal 0 HcmV?d00001 diff --git a/src/libs/cdogs.js b/src/libs/cdogs.js new file mode 100644 index 00000000..b0530e25 --- /dev/null +++ b/src/libs/cdogs.js @@ -0,0 +1,86 @@ +import { errorWithCode, logger } from '@bcgov/nodejs-common-utils'; +import axios from "axios"; +import fs from 'fs'; + +export class Cdogs { + + constructor(authenticaitonURL = process.env.CDOGS_AUTHENTICATION_URL, + serviceURL = process.env.CDOGS_SERVICE_URL, + clientId = process.env.CDOGS_CLIENT_ID, + clientSecret = process.env.CDOGS_CLIENT_SECRET, + enabled = process.env.CDOGS_ENABLED) { + this.authenticationURL = authenticaitonURL; + this.serviceURL = serviceURL; + this.clientId = clientId; + this.clientSecret = clientSecret; + this.enabled = enabled; + } + + async init() { + this.template = { + encodingType: 'base64', + fileType: 'docx', + content: await this.readTemplate() + } + this.options = { + cacheReport: false, + convertTo: "pdf", + overwrite: true, + } + } + + async getBearerToken() { + const tokenEndpoint = `${this.authenticationURL}/auth/realms/comsvcauth/protocol/openid-connect/token` + const credentials = Buffer.from(`${this.clientId}:${this.clientSecret}`).toString('base64') + try { + const response = await axios.post(tokenEndpoint, 'grant_type=client_credentials', { + headers: { + 'Authorization': `Basic ${credentials}`, + 'Content-Type': 'application/x-www-form-urlencoded', + } + }); + logger.debug("Bearer token retrieved") + return response.data.access_token + } + catch (error) { + logger.error(`Failed to retrieve bearer token: ${JSON.stringify(error)}`) + throw errorWithCode('Failed to retrieve bearer token' + JSON.stringify(error), 500) + } + } + + async generatePDF(planData) { + if (!eval(this.enabled)) + return; + const serviceURL = `${this.serviceURL}/api/v2/template/render` + try { + const token = await this.getBearerToken() + const payload = { + data: planData, + options: { ...this.options, 'reportName': planData.agreementId + '.pdf' }, + template: this.template + } + const response = await axios.post(serviceURL, JSON.stringify(payload), { + timeout: 20000, + responseType: 'arraybuffer', + headers: { + Authorization: `Bearer ${token}`, + 'Content-Type': 'application/json', + }, + }); + return response.data + } catch (error) { + logger.error(`Error generating PDF file: ${JSON.stringify(error)}`) + throw errorWithCode(`Error generating PDF file: ${JSON.stringify(error)} ${JSON.stringify(error)}`, 500) + } + } + + async readTemplate(template = './planTemplate.docx') { + try { + const data = fs.readFileSync(template); + return Buffer.from(data).toString('base64'); + } catch (error) { + logger.error(`Error reading template file ${template}: ${JSON.stringify(error)}`) + throw errorWithCode(`Error reading template file ${template}: ${JSON.stringify(error)}`, 500) + } + } +} \ No newline at end of file diff --git a/src/libs/mailer.js b/src/libs/mailer.js index da591282..172c7d04 100644 --- a/src/libs/mailer.js +++ b/src/libs/mailer.js @@ -37,7 +37,7 @@ export class Mailer { try { const token = await this.getBearerToken() const emailPayload = { to, from, subject, body, bodyType, } - logger.debug("email payload: " + JSON.stringify(emailPayload)) + logger.debug("email payload: " + JSON.stringify(emailPayload)) await axios.post(emailEndpoint, JSON.stringify(emailPayload), { headers: { 'Content-Type': 'application/json', diff --git a/src/libs/template.js b/src/libs/template.js deleted file mode 100644 index ab4d7369..00000000 --- a/src/libs/template.js +++ /dev/null @@ -1,327 +0,0 @@ -// -// SecureImage -// -// Copyright © 2018 Province of British Columbia -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// Created by Jason Leach on 2018-01-18. -// - -/* eslint-env es6 */ - -'use strict'; - -import fs from 'fs'; -import handlebars from 'handlebars'; -import moment from 'moment'; -import path from 'path'; -import wkhtmltopdf from 'wkhtmltopdf'; -import { logger } from '@bcgov/nodejs-common-utils'; -import { AGREEMENT_HOLDER_ROLE, NOT_PROVIDED, DAYS_ON_THE_AVERAGE, DATE_FORMAT } from '../constants'; - -if (process.platform === 'linux') { - // On Linux (OpenShift) we need to run our own copy of the binary with any related - // libs. - const lpath = path.join(__dirname, '../', 'wkhtmltopdf-amd64-0.12.4', 'lib'); - const bpath = path.join(__dirname, '../', 'wkhtmltopdf-amd64-0.12.4', 'bin', 'wkhtmltopdf'); - wkhtmltopdf.command = `LD_LIBRARY_PATH=${process.env.LD_LIBRARY_PATH}:${lpath} ${bpath}`; -} - -// -// Format Helpers -// - -/** - * Convert a boolean value to its human readable equivolent - * - * @param {Boolean} boolValue The value to be operated on - * @returns A string with the reformated date - */ -// eslint-disable-next-line no-confusing-arrow -const asYesOrNoValue = boolValue => boolValue ? 'YES' : 'NO'; - -/** - * Present the date time in a more readable way - * - * @param {string | Date} isoFormatDate The stringified date time - * @param {boolean} isYearIncluded The boolean to specify whether the year is needed - * @returns {string} a formatted string or 'Not provided' - */ -const formatDateFromServer = (isoFormatDate, isYearIncluded = true, notProvided = NOT_PROVIDED) => { - if (isoFormatDate) { - const m = moment(isoFormatDate, DATE_FORMAT.SERVER_SIDE); - - if (isYearIncluded) { - return m.format(DATE_FORMAT.CLIENT_SIDE); - } - return m.format(DATE_FORMAT.CLIENT_SIDE_WITHOUT_YEAR); - } - return notProvided; -}; - -/** - * Convert the contact type / role to its string equivolent - * - * @param {Contact} contact The contact to be operated on - * @returns The `String` representing the contacts role - */ -const contactRole = (contact) => { - if (!contact) { - return NOT_PROVIDED; - } - if (contact.clientTypeCode === AGREEMENT_HOLDER_ROLE.PRIMARY) { - return 'Primary'; - } - - return 'Secondary'; -}; - -const handleNullValue = (value, notProvided) => { - if (!value) { - return typeof notProvided === 'string' ? notProvided : NOT_PROVIDED; - } - return value; -}; - -/** - * Convert the zone code / descriiption to its string equivolent - * - * @param {Zone} zone The zone to be operated on - * @returns The `String` representing the district - */ -const getDistrict = (zone) => { - if (!zone) { - return NOT_PROVIDED; - } - if (zone.district && zone.district.description) { - return `${zone.district.code} - ${zone.district.description}`; - } - return zone.district.code; -}; - -/** - * Convert the agreement type code / descriiption to its string equivolent - * - * @param {AgreementType} agreementType The zone to be operated on - * @returns The `String` representing the agreement type - */ -const getAgreementType = (agreementType) => { - if (!agreementType) { - return NOT_PROVIDED; - } - if (agreementType.description) { - return `${agreementType.code} - ${agreementType.description}`; - } - return agreementType.code; -}; - -/** - * Capitalize the first letter for a string - * - * @param {String} string The string to be operated on - * @returns A string with the first letter capitalized - */ -export const capitalizeFirstLetter = (string) => { - if (!string) { - return ''; - } - return string.charAt(0).toUpperCase() + string.slice(1); -}; - -/** - * Reformat the contact name - * - * @param {Contact} contact The contact to be operated on - * @returns A `String` represeting the contact name in the format `First Last` - */ -const contactFullName = (contact) => { - const [lastName, firstName] = contact.name - .split(',') - .map(string => string.toLowerCase()) - .map(string => string.trim()); - return `${capitalizeFirstLetter(firstName)} ${capitalizeFirstLetter(lastName)}`; -}; - -/** - * Handlebars helper to build the full name of the primary agreement holder - * - * @param {[Contact]} contacts The `Agreement` contacts - * @returns A string representing the full name of the promary contact - */ -export const primaryContactFullName = (contacts) => { - const [pcontact] = contacts - .filter(contact => contact.clientTypeCode === AGREEMENT_HOLDER_ROLE.PRIMARY); - - return contactFullName(pcontact); -}; - -const getYesOrNo = boolean => ( - boolean ? 'Yes' : 'No' -); - - -const shift = (number, precision) => { - const numArray = (`${number}`).split('e'); - return +(`${numArray[0]}e${(numArray[1] ? (+numArray[1] + precision) : precision)}`); -}; - -const round = (number, precision) => ( - shift(Math.round(shift(number, +precision)), -precision) -); - -/** - * Round the float to 1 decimal - * - * @param {float} number - * @returns the rounded float number - */ -export const roundToSingleDecimalPlace = number => ( - round(number, 1) -); - -/** - * - * @param {number} numberOfAnimals - * @param {number} totalDays - * @param {number} auFactor parameter provided from the livestock type - * @returns {float} the total AUMs - */ -export const calcTotalAUMs = (numberOfAnimals = 0, totalDays, auFactor = 0) => ( - ((numberOfAnimals * totalDays * auFactor) / DAYS_ON_THE_AVERAGE) -); - -/** - * Present user friendly string when getting null or undefined value - * - * @param {string | Date} first the string in the class Date form - * @param {string | Date} second the string in the class Date form - * @param {bool} isUserFriendly - * @returns {number | string} the number of days or 'N/P' - */ -export const calcDateDiff = (first, second, isUserFriendly) => { - if (first && second) { - return moment(first).diff(moment(second), 'days'); - } - return isUserFriendly ? 'N/P' : 0; -}; - -/** - * Calculate Private Land Deduction Animal Unit Month - * - * @param {number} totalAUMs - * @param {float} pasturePldPercent - * @returns {float} the pld AUMs - */ -export const calcPldAUMs = (totalAUMs, pasturePldPercent = 0) => ( - totalAUMs * pasturePldPercent -); - -/** - * Calculate Crown Animal Unit Month - * - * @param {number} totalAUMs - * @param {number} pldAUMs - * @returns {float} the crown AUMs - */ -export const calcCrownAUMs = (totalAUMs, pldAUMs) => ( - (totalAUMs - pldAUMs) -); - -/** - * Calculate the total Crown Animal Unit Month - * - * @param {Array} entries grazing schedule entries - * @returns {float} the total crown AUMs - */ -export const calcCrownTotalAUMs = (entries = []) => { - const reducer = (accumulator, currentValue) => accumulator + currentValue; - if (entries.length === 0) { - return 0; - } - return entries - .map(entry => entry.crownAUMs) - .reduce(reducer); -}; - -export const getPastureNames = (pastureIds = [], pastures = {}) => { - const pastureNames = pastureIds.map((pId) => { - const pasture = pastures.find(p => p.id === pId); - return pasture && pasture.name; - }); - const { length } = pastureNames; - switch (length) { - case 0: - return NOT_PROVIDED; - case 1: - case 2: - return pastureNames.join(' and '); - default: - return `${pastureNames.slice(0, length - 1).join(', ')}, and ${pastureNames[length - 1]}`; - } -}; - -// -// Document Rendering -// - -/** - * Compile the handelbars template and run it with the given context - * to produce html. - * - * @param {ReadStream} source A stream asociated to the handelbars markup template - * @param {JSON} context The object with appropriate data for the template - * @returns A resolved `Promise` with the HTML data. - */ -export const compile = (source, context) => { - handlebars.registerHelper('getContactRole', contactRole); - handlebars.registerHelper('getDistrict', getDistrict); - handlebars.registerHelper('getContactFullName', contactFullName); - handlebars.registerHelper('getPrimaryContactName', primaryContactFullName); - handlebars.registerHelper('getStandardDateFormat', formatDateFromServer); - handlebars.registerHelper('getBoolAsYesNoValue', asYesOrNoValue); - handlebars.registerHelper('handleNullValue', handleNullValue); - handlebars.registerHelper('getAgreementType', getAgreementType); - handlebars.registerHelper('getYesOrNo', getYesOrNo); - - const html = handlebars.compile(source.toString('utf-8'))(context); - return Promise.resolve(html); -}; - -/** - * Load the html template from the local file system and return it as a Buffer. - * - * @param {String} fileName The path and name of the file to be loaded - * @returns A resolved `Promise` with a stream of the loaded file; rejected otherwise. - */ -export const loadTemplate = (fileName) => { - const docpath = path.join(__dirname, '../../', 'templates', fileName); - - return new Promise((resolve, reject) => { - fs.access(docpath, fs.constants.R_OK, (accessErr) => { - if (accessErr) { - logger.warn('Unable to find templates'); - reject(accessErr); - } - - fs.readFile(docpath, (readFileErr, data) => { - if (readFileErr) { - logger.warn('Unable to load template'); - reject(readFileErr); - } - - resolve(data); - }); - }); - }); -}; diff --git a/src/router/controllers_v1/PDFGeneratoin.js b/src/router/controllers_v1/PDFGeneratoin.js new file mode 100644 index 00000000..260a396a --- /dev/null +++ b/src/router/controllers_v1/PDFGeneratoin.js @@ -0,0 +1,146 @@ +import moment from 'moment'; +import { Cdogs } from '../../libs/cdogs' +import PlanController from '../controllers_v1/PlanController' +import { calcCrownAUMs, calcDateDiff, calcPldAUMs, calcTotalAUMs, roundToSingleDecimalPlace } from '../helpers/PDFHelper'; +import { NOT_PROVIDED } from '../../constants'; + +export default class PDFGeneration { + static async generatePDF(req, res) { + const { + user, + params, + } = req; + const { planId } = params; + const dogs = new Cdogs(); + dogs.init() + const plan = await PlanController.fetchPlan(planId, user) + const adg = new AdditionalDetailsGenerator() + adg.setClientConfirmationStatus(plan) + adg.setInvasivePlantCheckListIsEmpty(plan) + adg.setPlantCommunityDetails(plan) + adg.setIndicatorPlantDetails(plan) + adg.setScheduleDetails(plan) + plan.currentDate = moment() + const response = await dogs.generatePDF(plan) + res.json(response).end() + } +} + +class AdditionalDetailsGenerator { + setClientConfirmationStatus(plan) { + for (const client of plan.agreement.clients) { + const confirmation = plan.confirmations.find((item) => { + return item.clientId === client.id + }) + client.confirmationStatus = 'Not Confirmed' + if (confirmation && confirmation.confirmed === true) { + client.confirmationStatus = 'Confirmed' + } + } + } + + setPlantCommunityDetails(plan) { + for (const pasture of plan.pastures) { + if (pasture) { + for (const pasture of plan.pastures) { + if (isNaN(pasture.pldPercentage)) { + pasture.pldPercentage = 0 + } + } + if (!pasture.allowableAum) + pasture.allowableAum = NOT_PROVIDED + if (!pasture.pldPercent) + pasture.pldPercent = NOT_PROVIDED + if (!pasture.notes) + pasture.notes = NOT_PROVIDED + for (const plantCommunity of pasture.plantCommunities) { + if (plantCommunity) { + if (!plantCommunity.rangeReadinessMonth && plantCommunity.rangeReadinessDay) { + plantCommunity.rangeReadinessDate = moment() + .set('month', plantCommunity.rangeReadinessMonth - 1) + .set('date', plantCommunity.rangeReadinessDay) + .format('MMMM D') + } + if (plantCommunity.plantCommunityActions) { + for (const action of plantCommunity.plantCommunityActions) { + if (action) { + action.name = action.actionType.name === 'Other' + ? `${action.name} (Other)` + : action.actionType.name + if (action.actionType.name === 'Timing') { + action.NoGrazeStartDate = action.noGrazeStartMonth && action.noGrazeStartDay + ? moment() + .set('month', action.noGrazeStartMonth - 1) + .set('date', action.noGrazeStartDay) + .format('MMMM Do') + : 'Not Provided' + action.NoGrazeEndDate = action.noGrazeEndMonth && action.noGrazeEndDay + ? moment() + .set('month', action.noGrazeEndMonth - 1) + .set('date', action.noGrazeEndDay) + .format('MMMM Do') + : 'Not Provided' + } + } + } + } + } + } + } + } + } + + setIndicatorPlantDetails(plan) { + for (const pasture of plan.pastures) { + if (pasture) { + for (const plantCommunity of pasture.plantCommunities) { + if (plantCommunity) { + for (const indicatorPlant of plantCommunity.indicatorPlants) { + indicatorPlant.name = indicatorPlant.plantSpecies.name === 'Other' + ? `${indicatorPlant.name} (Other)` + : indicatorPlant.plantSpecies.name + } + } + } + } + } + } + + setScheduleDetails(plan) { + for (const schedule of plan.grazingSchedules) { + if (schedule) { + schedule.crownTotalAUM = 0 + for (const entry of schedule.grazingScheduleEntries) { + if (entry) { + const pasture = plan.pastures.find((item) => { + return item.id === entry.pastureId + }) + entry.pasture = 'N/A' + if (pasture) { + entry.pasture = pasture.name + entry.graceDays = entry.graceDays || pasture.graceDays + } + entry.days = calcDateDiff(entry.dateOut, entry.dateIn, false) + entry.auFactor = entry.livestockType?.auFactor + entry.totalAUM = calcTotalAUMs(entry.livestockCount, entry.days, entry.auFactor) + entry.pldAUM = roundToSingleDecimalPlace(calcPldAUMs(entry.totalAUM, pasture.pldPercentage)) + entry.crownAUM = roundToSingleDecimalPlace(calcCrownAUMs(entry.totalAUM, entry.pldAUM)) + schedule.crownTotalAUM = schedule.crownTotalAUM + entry.crownAUM + } + } + if (plan.agreement.usage) { + const usage = plan.agreement.usage.find(usage => { return usage.year === schedule.year }) + schedule.authorizedAUM = usage.authorizedAum + schedule.percentUse = ((schedule.crownTotalAUM / schedule.authorizedAUM) * 100).toFixed(2) + } + } + } + } + + setInvasivePlantCheckListIsEmpty(plan) { + plan.invasivePlantChecklist.isEmpty = !(plan.invasivePlantChecklist.beginInUninfestedArea || + plan.invasivePlantChecklist.equipmentAndVehiclesParking || + plan.invasivePlantChecklist.revegetate || + plan.invasivePlantChecklist.undercarrigesInspected) + } +} \ No newline at end of file diff --git a/src/router/controllers_v1/PlanController.js b/src/router/controllers_v1/PlanController.js index e1a1ed83..4a632d22 100644 --- a/src/router/controllers_v1/PlanController.js +++ b/src/router/controllers_v1/PlanController.js @@ -48,7 +48,13 @@ export default class PlanController { checkRequiredFields( ['planId'], 'params', req, ); + const response = await PlanController.fetchPlan(planId, user) + return res.status(200) + .json(response) + .end(); + } + static async fetchPlan(planId, user,) { try { const [plan] = await Plan.findWithStatusExtension(db, { 'plan.id': planId }, ['id', 'desc']); if (!plan) { @@ -95,14 +101,11 @@ export default class PlanController { }; }), ); - - return res.status(200) - .json({ - ...plan, - grazingSchedules: mappedGrazingSchedules, - files: filteredFiles, - }) - .end(); + return { + ...plan, + grazingSchedules: mappedGrazingSchedules, + files: filteredFiles, + } } logger.info('loading last version'); @@ -122,8 +125,8 @@ export default class PlanController { logger.error(`Unable to fetch plan, error: ${error.message}`); throw errorWithCode(`There was a problem fetching the record. Error: ${error.message}`, error.code || 500); } - } + } /** * Create Plan * @param {*} req : express req object @@ -487,4 +490,6 @@ export default class PlanController { res.status(204) .end(); } -} + + +} \ No newline at end of file diff --git a/src/router/helpers/PDFHelper.js b/src/router/helpers/PDFHelper.js new file mode 100644 index 00000000..2cd934e1 --- /dev/null +++ b/src/router/helpers/PDFHelper.js @@ -0,0 +1,77 @@ + +import moment from 'moment' +import { DAYS_ON_THE_AVERAGE } from '../../constants' + +const shift = (number, precision) => { + const numArray = `${number}`.split('e') + return +`${numArray[0]}e${numArray[1] ? +numArray[1] + precision : precision}` +} + +const round = (number, precision) => + shift(Math.round(shift(number, +precision)), -precision) + +/** + * Round the float to 1 decimal + * + * @param {float} number + * @returns the rounded float number + */ +export const roundToSingleDecimalPlace = number => round(number, 1) + +/** + * + * @param {number} numberOfAnimals + * @param {number} totalDays + * @param {number} auFactor parameter provided from the livestock type + * @returns {float} the total AUMs + */ +export const calcTotalAUMs = (numberOfAnimals = 0, totalDays, auFactor = 0) => + (numberOfAnimals * totalDays * auFactor) / DAYS_ON_THE_AVERAGE + +/** + * Present user friendly string when getting null or undefined value + * + * @param {string | Date} first the string in the class Date form + * @param {string | Date} second the string in the class Date form + * @param {bool} isUserFriendly + * @returns {number | string} the number of days or 'N/P' + */ +export const calcDateDiff = (first, second, isUserFriendly) => { + if (first && second) { + return moment(first).diff(moment(second), 'days') + 1 + } + return isUserFriendly ? 'N/P' : 0 +} + +/** + * Calculate Private Land Deduction Animal Unit Month + * + * @param {number} totalAUMs + * @param {float} pasturePldPercent + * @returns {float} the pld AUMs + */ +export const calcPldAUMs = (totalAUMs, pasturePldPercent = 0) => + totalAUMs * pasturePldPercent + +/** + * Calculate Crown Animal Unit Month + * + * @param {number} totalAUMs + * @param {number} pldAUMs + * @returns {float} the crown AUMs + */ +export const calcCrownAUMs = (totalAUMs, pldAUMs) => totalAUMs - pldAUMs + +/** + * Calculate the total Crown Animal Unit Month + * + * @param {Array} entries grazing schedule entries + * @returns {float} the total crown AUMs + */ +export const calcCrownTotalAUMs = (entries = []) => { + const reducer = (accumulator, currentValue) => accumulator + currentValue + if (entries.length === 0) { + return 0 + } + return entries.map(entry => entry.crownAUMs).reduce(reducer) +} diff --git a/src/router/index.js b/src/router/index.js index 59ae6c65..5ddd6f78 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -35,7 +35,6 @@ import feedback from './routes_v1/feedback'; import files from './routes_v1/files'; import plan from './routes_v1/plan'; import reference from './routes_v1/reference'; -import report from './routes_v1/report'; import user from './routes_v1/user'; import version from './routes_v1/version'; import zone from './routes_v1/zone'; @@ -59,9 +58,8 @@ module.exports = (app) => { app.use('/api/v1/plan', plan); app.use('/api/v1/reference', reference); app.use('/api/v1/zone', zone); - app.use('/api/v1/report', report); app.use('/api/v1/user', user); app.use('/api/v1/feedback', feedback); app.use('/api/v1/files', files); app.use('/api/v1/emailTemplate', emailTemplate) -}; +}; \ No newline at end of file diff --git a/src/router/routes_v1/plan.js b/src/router/routes_v1/plan.js index d6eee117..2d154ac4 100644 --- a/src/router/routes_v1/plan.js +++ b/src/router/routes_v1/plan.js @@ -29,6 +29,7 @@ import { Router } from 'express'; * Controller for individual routes related to plan. */ import PlanController from '../controllers_v1/PlanController'; +import PDFGeneration from '../controllers_v1/PDFGeneratoin.js'; import PlanVersionController from '../controllers_v1/PlanVersionController'; import PlanStatusController from '../controllers_v1/PlanStatusController'; import PlanPastureController from '../controllers_v1/PlanPastureController'; @@ -213,4 +214,6 @@ router.put('/:planId?/management-consideration/:considerationId?', asyncMiddlewa // Delete a management consideration router.delete('/:planId?/management-consideration/:considerationId?', asyncMiddleware(PlanManagementConsiderationController.destroy)); +// Create a management consideration +router.get('/:planId?/PDF', asyncMiddleware(PDFGeneration.generatePDF)); module.exports = router; \ No newline at end of file diff --git a/src/router/routes_v1/report.js b/src/router/routes_v1/report.js deleted file mode 100644 index 7b6bbf02..00000000 --- a/src/router/routes_v1/report.js +++ /dev/null @@ -1,144 +0,0 @@ -// -// SecureImage -// -// Copyright © 2018 Province of British Columbia -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// Created by Jason Leach on 2018-01-18. -// - -/* eslint-env es6 */ - -'use strict'; - -import { asyncMiddleware, errorWithCode } from '@bcgov/nodejs-common-utils'; -import { Router } from 'express'; -import wkhtmltopdf from 'wkhtmltopdf'; -import config from '../../config'; -import { TEMPLATES } from '../../constants'; -import DataManager from '../../libs/db2'; -import { compile, loadTemplate, calcDateDiff, calcTotalAUMs, calcPldAUMs, calcCrownAUMs, roundToSingleDecimalPlace, calcCrownTotalAUMs, getPastureNames } from '../../libs/template'; - -const router = new Router(); -const dm2 = new DataManager(config); -const { - db, - Agreement, - Plan, -} = dm2; - -const userCanAccessAgreement = async (user, agreementId) => { - const [agreement] = await Agreement.find(db, { forest_file_id: agreementId }); - if (!agreement) { - throw errorWithCode('Unable to find the related agreement', 500); - } - - const can = await user.canAccessAgreement(db, agreement); - if (!can) { - throw errorWithCode('You do not access to this agreement', 403); - } -}; - -// -// PDF -// - -router.get('/:planId/', asyncMiddleware(async (req, res) => { - const { user, params } = req; - const { planId } = params; - - try { - const agreementId = await Plan.agreementForPlanId(db, planId); - if (!userCanAccessAgreement(user, agreementId)) { - throw errorWithCode('You do not access to this agreement', 403); - } - - const [agreement] = await Agreement.findWithAllRelations(db, { forest_file_id: agreementId }); - agreement.transformToV1(); - - const [plan] = await Plan.findWithStatusExtension(db, { 'plan.id': planId }, ['id', 'desc']); - await plan.eagerloadAllOneToMany(); - - const { pastures, grazingSchedules: gss, ministerIssues: mis } = plan || []; - const { zone } = agreement || {}; - const { user: staff } = zone || {}; - const { givenName, familyName } = staff; - user.name = givenName && familyName && `${givenName} ${familyName}`; - - const grazingSchedules = gss.map((schedule) => { - const { grazingScheduleEntries: gse, year } = schedule; - const grazingScheduleEntries = gse && gse.map((entry) => { - const { - pastureId, - livestockType, - livestockCount, - dateIn, - dateOut, - } = entry; - const days = calcDateDiff(dateOut, dateIn, false); - const pasture = pastures.find(p => p.id === pastureId); - const graceDays = pasture && pasture.graceDays; - const pldPercent = pasture && pasture.pldPercent; - const auFactor = livestockType && livestockType.auFactor; - - const totalAUMs = calcTotalAUMs(livestockCount, days, auFactor); - const pldAUMs = roundToSingleDecimalPlace(calcPldAUMs(totalAUMs, pldPercent)); - const crownAUMs = roundToSingleDecimalPlace(calcCrownAUMs(totalAUMs, pldAUMs)); - return { - ...entry, - pasture, - graceDays, - days, - pldAUMs, - crownAUMs, - }; - }); - const crownTotalAUMs = roundToSingleDecimalPlace(calcCrownTotalAUMs(grazingScheduleEntries)); - const yearUsage = agreement.usage.find(u => u.year === year); - const authorizedAUMs = yearUsage && yearUsage.authorizedAum; - return { - ...schedule, - grazingScheduleEntries, - crownTotalAUMs, - authorizedAUMs, - }; - }); - - const ministerIssues = mis.map((mi) => { - const ministerIssue = { ...mi }; - ministerIssue.pastureNames = getPastureNames(ministerIssue.pastures, pastures); - ministerIssue.actionsExist = ministerIssue.ministerIssueActions - && (ministerIssue.ministerIssueActions.length > 0); - - return ministerIssue; - }); - - const template = await loadTemplate(TEMPLATES.RANGE_USE_PLAN); - const html = await compile(template, { - user, - agreement, - plan, - zone, - pastures, - grazingSchedules, - ministerIssues, - }); - - return wkhtmltopdf(html).pipe(res); - } catch (err) { - throw err; - } -})); - -module.exports = router; \ No newline at end of file