From 50a881a0090d0dad558b03eb84f573ee78359074 Mon Sep 17 00:00:00 2001 From: Dan Gowans Date: Fri, 27 Jan 2023 15:55:22 -0500 Subject: [PATCH] show fees on lot occupancy search --- .../doSearchLotOccupancies.js | 4 ++- .../doSearchLotOccupancies.ts | 4 ++- .../doAddWorkOrderLotOccupancy.js | 4 ++- .../doAddWorkOrderLotOccupancy.ts | 4 ++- helpers/lotOccupancyDB/getFees.js | 3 +- helpers/lotOccupancyDB/getFees.ts | 3 +- helpers/lotOccupancyDB/getLot.js | 2 ++ helpers/lotOccupancyDB/getLot.ts | 2 ++ helpers/lotOccupancyDB/getLotOccupancies.d.ts | 2 ++ helpers/lotOccupancyDB/getLotOccupancies.js | 9 +++++ helpers/lotOccupancyDB/getLotOccupancies.ts | 19 ++++++++++ public-typescript/lotOccupancySearch.js | 35 ++++++++++++++----- public-typescript/lotOccupancySearch.ts | 33 ++++++++++++++++- public/javascripts/lotOccupancySearch.min.js | 2 +- 14 files changed, 110 insertions(+), 16 deletions(-) diff --git a/handlers/lotOccupancies-post/doSearchLotOccupancies.js b/handlers/lotOccupancies-post/doSearchLotOccupancies.js index a990ea1e..ced835e7 100644 --- a/handlers/lotOccupancies-post/doSearchLotOccupancies.js +++ b/handlers/lotOccupancies-post/doSearchLotOccupancies.js @@ -3,7 +3,9 @@ export async function handler(request, response) { const result = await getLotOccupancies(request.body, { limit: request.body.limit, offset: request.body.offset, - includeOccupants: true + includeOccupants: true, + includeFees: true, + includeTransactions: true }); response.json({ count: result.count, diff --git a/handlers/lotOccupancies-post/doSearchLotOccupancies.ts b/handlers/lotOccupancies-post/doSearchLotOccupancies.ts index 15494c17..06c903c9 100644 --- a/handlers/lotOccupancies-post/doSearchLotOccupancies.ts +++ b/handlers/lotOccupancies-post/doSearchLotOccupancies.ts @@ -9,7 +9,9 @@ export async function handler( const result = await getLotOccupancies(request.body, { limit: request.body.limit, offset: request.body.offset, - includeOccupants: true + includeOccupants: true, + includeFees: true, + includeTransactions: true }) response.json({ diff --git a/handlers/workOrders-post/doAddWorkOrderLotOccupancy.js b/handlers/workOrders-post/doAddWorkOrderLotOccupancy.js index 8384cd73..00fd4596 100644 --- a/handlers/workOrders-post/doAddWorkOrderLotOccupancy.js +++ b/handlers/workOrders-post/doAddWorkOrderLotOccupancy.js @@ -10,7 +10,9 @@ export async function handler(request, response) { }, { limit: -1, offset: 0, - includeOccupants: true + includeOccupants: true, + includeFees: false, + includeTransactions: false }); response.json({ success, diff --git a/handlers/workOrders-post/doAddWorkOrderLotOccupancy.ts b/handlers/workOrders-post/doAddWorkOrderLotOccupancy.ts index fce33b81..f11c1525 100644 --- a/handlers/workOrders-post/doAddWorkOrderLotOccupancy.ts +++ b/handlers/workOrders-post/doAddWorkOrderLotOccupancy.ts @@ -22,7 +22,9 @@ export async function handler( { limit: -1, offset: 0, - includeOccupants: true + includeOccupants: true, + includeFees: false, + includeTransactions: false } ) diff --git a/helpers/lotOccupancyDB/getFees.js b/helpers/lotOccupancyDB/getFees.js index 3883caaa..bc40a867 100644 --- a/helpers/lotOccupancyDB/getFees.js +++ b/helpers/lotOccupancyDB/getFees.js @@ -18,7 +18,8 @@ export async function getFees(feeCategoryId, additionalFilters, connectedDatabas .prepare(`select f.feeId, f.feeName, f.feeDescription, f.occupancyTypeId, o.occupancyType, f.lotTypeId, l.lotType, - ifnull(f.feeAmount, 0) as feeAmount, f.feeFunction, + ifnull(f.feeAmount, 0) as feeAmount, + f.feeFunction, f.taxAmount, f.taxPercentage, f.includeQuantity, f.quantityUnit, f.isRequired, f.orderNumber, diff --git a/helpers/lotOccupancyDB/getFees.ts b/helpers/lotOccupancyDB/getFees.ts index de67997f..7e0680b8 100644 --- a/helpers/lotOccupancyDB/getFees.ts +++ b/helpers/lotOccupancyDB/getFees.ts @@ -44,7 +44,8 @@ export async function getFees( `select f.feeId, f.feeName, f.feeDescription, f.occupancyTypeId, o.occupancyType, f.lotTypeId, l.lotType, - ifnull(f.feeAmount, 0) as feeAmount, f.feeFunction, + ifnull(f.feeAmount, 0) as feeAmount, + f.feeFunction, f.taxAmount, f.taxPercentage, f.includeQuantity, f.quantityUnit, f.isRequired, f.orderNumber, diff --git a/helpers/lotOccupancyDB/getLot.js b/helpers/lotOccupancyDB/getLot.js index 2a36fc37..c7b6efdc 100644 --- a/helpers/lotOccupancyDB/getLot.js +++ b/helpers/lotOccupancyDB/getLot.js @@ -18,6 +18,8 @@ async function _getLot(sql, lotIdOrLotName) { lotId: lot.lotId }, { includeOccupants: true, + includeFees: false, + includeTransactions: false, limit: -1, offset: 0 }, database); diff --git a/helpers/lotOccupancyDB/getLot.ts b/helpers/lotOccupancyDB/getLot.ts index 2ea4023a..d2a031d4 100644 --- a/helpers/lotOccupancyDB/getLot.ts +++ b/helpers/lotOccupancyDB/getLot.ts @@ -32,6 +32,8 @@ async function _getLot( }, { includeOccupants: true, + includeFees: false, + includeTransactions: false, limit: -1, offset: 0 }, diff --git a/helpers/lotOccupancyDB/getLotOccupancies.d.ts b/helpers/lotOccupancyDB/getLotOccupancies.d.ts index 43660d41..bf117c42 100644 --- a/helpers/lotOccupancyDB/getLotOccupancies.d.ts +++ b/helpers/lotOccupancyDB/getLotOccupancies.d.ts @@ -18,6 +18,8 @@ interface GetLotOccupanciesOptions { limit: -1 | number; offset: number; includeOccupants: boolean; + includeFees: boolean; + includeTransactions: boolean; } export declare function getLotOccupancies(filters: GetLotOccupanciesFilters, options: GetLotOccupanciesOptions, connectedDatabase?: PoolConnection): Promise<{ count: number; diff --git a/helpers/lotOccupancyDB/getLotOccupancies.js b/helpers/lotOccupancyDB/getLotOccupancies.js index f45c3c29..a53b89ba 100644 --- a/helpers/lotOccupancyDB/getLotOccupancies.js +++ b/helpers/lotOccupancyDB/getLotOccupancies.js @@ -4,6 +4,8 @@ import * as configFunctions from '../functions.config.js'; import { getOccupancyTypeById } from '../functions.cache.js'; import { getLotOccupancyOccupants } from './getLotOccupancyOccupants.js'; import { getLotNameWhereClause, getOccupancyTimeWhereClause, getOccupantNameWhereClause } from '../functions.sqlFilters.js'; +import getLotOccupancyFees from './getLotOccupancyFees.js'; +import getLotOccupancyTransactions from './getLotOccupancyTransactions.js'; function buildWhereClause(filters) { let sqlWhereClause = ' where o.recordDelete_timeMillis is null'; const sqlParameters = []; @@ -103,6 +105,13 @@ export async function getLotOccupancies(filters, options, connectedDatabase) { ? configFunctions.getProperty('settings.lotOccupancy.prints')[0] : occupancyType.occupancyTypePrints[0]; } + if (options.includeFees) { + lotOccupancy.lotOccupancyFees = await getLotOccupancyFees(lotOccupancy.lotOccupancyId, database); + } + if (options.includeTransactions) { + lotOccupancy.lotOccupancyTransactions = + await getLotOccupancyTransactions(lotOccupancy.lotOccupancyId, database); + } if (options.includeOccupants) { lotOccupancy.lotOccupancyOccupants = await getLotOccupancyOccupants(lotOccupancy.lotOccupancyId, database); } diff --git a/helpers/lotOccupancyDB/getLotOccupancies.ts b/helpers/lotOccupancyDB/getLotOccupancies.ts index ed789cbe..a7b7a35a 100644 --- a/helpers/lotOccupancyDB/getLotOccupancies.ts +++ b/helpers/lotOccupancyDB/getLotOccupancies.ts @@ -19,6 +19,8 @@ import { getOccupancyTimeWhereClause, getOccupantNameWhereClause } from '../functions.sqlFilters.js' +import getLotOccupancyFees from './getLotOccupancyFees.js' +import getLotOccupancyTransactions from './getLotOccupancyTransactions.js' interface GetLotOccupanciesFilters { lotId?: number | string @@ -39,6 +41,8 @@ interface GetLotOccupanciesOptions { limit: -1 | number offset: number includeOccupants: boolean + includeFees: boolean + includeTransactions: boolean } function buildWhereClause(filters: GetLotOccupanciesFilters): { @@ -192,6 +196,21 @@ export async function getLotOccupancies( : occupancyType.occupancyTypePrints![0] } + if (options.includeFees) { + lotOccupancy.lotOccupancyFees = await getLotOccupancyFees( + lotOccupancy.lotOccupancyId!, + database + ) + } + + if (options.includeTransactions) { + lotOccupancy.lotOccupancyTransactions = + await getLotOccupancyTransactions( + lotOccupancy.lotOccupancyId!, + database + ) + } + if (options.includeOccupants) { lotOccupancy.lotOccupancyOccupants = await getLotOccupancyOccupants( lotOccupancy.lotOccupancyId!, diff --git a/public-typescript/lotOccupancySearch.js b/public-typescript/lotOccupancySearch.js index 2d140ec3..054ed93c 100644 --- a/public-typescript/lotOccupancySearch.js +++ b/public-typescript/lotOccupancySearch.js @@ -8,7 +8,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); const limit = Number.parseInt(document.querySelector('#searchFilter--limit').value, 10); const offsetElement = document.querySelector('#searchFilter--offset'); function renderLotOccupancies(responseJSON) { - var _a, _b, _c, _d, _e, _f, _g, _h; + var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m; if (responseJSON.lotOccupancies.length === 0) { searchResultsContainerElement.innerHTML = `

@@ -52,6 +52,23 @@ Object.defineProperty(exports, "__esModule", { value: true }); cityssm.escapeHTML((_c = occupant.occupantName) !== null && _c !== void 0 ? _c : '') + '
'; } + const feeTotal = ((_e = (_d = lotOccupancy.lotOccupancyFees) === null || _d === void 0 ? void 0 : _d.reduce((soFar, currentFee) => { + var _a, _b, _c; + return (soFar + + (((_a = currentFee.feeAmount) !== null && _a !== void 0 ? _a : 0) + ((_b = currentFee.taxAmount) !== null && _b !== void 0 ? _b : 0)) * + ((_c = currentFee.quantity) !== null && _c !== void 0 ? _c : 0)); + }, 0)) !== null && _e !== void 0 ? _e : 0).toFixed(2); + const transactionTotal = ((_g = (_f = lotOccupancy.lotOccupancyTransactions) === null || _f === void 0 ? void 0 : _f.reduce((soFar, currentTransaction) => { + return soFar + currentTransaction.transactionAmount; + }, 0)) !== null && _g !== void 0 ? _g : 0).toFixed(2); + let feeIconHTML = ''; + if (feeTotal !== '0.00' || transactionTotal !== '0.00') { + feeIconHTML = ` + + `; + } resultsTbodyElement.insertAdjacentHTML('beforeend', '' + ('' + occupancyTimeHTML + '') + ('' + @@ -62,12 +79,12 @@ Object.defineProperty(exports, "__esModule", { value: true }); '' + '') + ('' + - (((_d = lotOccupancy.lotId) !== null && _d !== void 0 ? _d : -1) === -1 + (((_h = lotOccupancy.lotId) !== null && _h !== void 0 ? _h : -1) === -1 ? '(No ' + los.escapedAliases.Lot + ')' : '' + @@ -75,7 +92,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); '') + '
' + ('' + - cityssm.escapeHTML((_f = lotOccupancy.mapName) !== null && _f !== void 0 ? _f : '') + + cityssm.escapeHTML((_k = lotOccupancy.mapName) !== null && _k !== void 0 ? _k : '') + '') + '') + ('' + lotOccupancy.occupancyStartDateString + '') + @@ -85,6 +102,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); : '(No End Date)') + '') + ('' + occupantsHTML + '') + + ('' + feeIconHTML + '') + '' + (lotOccupancy.printEJS ? '${los.escapedAliases.OccupancyStartDate} End Date ${los.escapedAliases.Occupants} + Fees and Transactions Print `; @@ -115,10 +134,10 @@ Object.defineProperty(exports, "__esModule", { value: true }); .querySelector('table') .append(resultsTbodyElement); searchResultsContainerElement.insertAdjacentHTML('beforeend', los.getSearchResultsPagerHTML(limit, responseJSON.offset, responseJSON.count)); - (_g = searchResultsContainerElement - .querySelector("button[data-page='previous']")) === null || _g === void 0 ? void 0 : _g.addEventListener('click', previousAndGetLotOccupancies); - (_h = searchResultsContainerElement - .querySelector("button[data-page='next']")) === null || _h === void 0 ? void 0 : _h.addEventListener('click', nextAndGetLotOccupancies); + (_l = searchResultsContainerElement + .querySelector("button[data-page='previous']")) === null || _l === void 0 ? void 0 : _l.addEventListener('click', previousAndGetLotOccupancies); + (_m = searchResultsContainerElement + .querySelector("button[data-page='next']")) === null || _m === void 0 ? void 0 : _m.addEventListener('click', nextAndGetLotOccupancies); } function getLotOccupancies() { searchResultsContainerElement.innerHTML = los.getLoadingParagraphHTML(`Loading ${los.escapedAliases.Occupancies}...`); diff --git a/public-typescript/lotOccupancySearch.ts b/public-typescript/lotOccupancySearch.ts index 4536654a..3fcb221c 100644 --- a/public-typescript/lotOccupancySearch.ts +++ b/public-typescript/lotOccupancySearch.ts @@ -84,6 +84,35 @@ declare const cityssm: cityssmGlobal '
' } + const feeTotal = + (lotOccupancy.lotOccupancyFees?.reduce((soFar, currentFee): number => { + return ( + soFar + + ((currentFee.feeAmount ?? 0) + (currentFee.taxAmount ?? 0)) * + (currentFee.quantity ?? 0) + ) + }, 0) ?? 0).toFixed(2) + + const transactionTotal = + (lotOccupancy.lotOccupancyTransactions?.reduce( + (soFar, currentTransaction): number => { + return soFar + currentTransaction.transactionAmount + }, + 0 + ) ?? 0).toFixed(2) + + let feeIconHTML = '' + + if (feeTotal !== '0.00' || transactionTotal !== '0.00') { + feeIconHTML = ` + + ` + } + resultsTbodyElement.insertAdjacentHTML( 'beforeend', '' + @@ -112,13 +141,14 @@ declare const cityssm: cityssmGlobal cityssm.escapeHTML(lotOccupancy.mapName ?? '') + '') + '') + - ('') + + ('') + ('') + ('') + + ('') + '
' + lotOccupancy.occupancyStartDateString + '' + lotOccupancy.occupancyStartDateString! + '' + (lotOccupancy.occupancyEndDate ? lotOccupancy.occupancyEndDateString : '(No End Date)') + '' + occupantsHTML + '' + feeIconHTML + '' + (lotOccupancy.printEJS ? 'Fees and Transactions Print
` diff --git a/public/javascripts/lotOccupancySearch.min.js b/public/javascripts/lotOccupancySearch.min.js index 5c59a2ff..98ddaef8 100644 --- a/public/javascripts/lotOccupancySearch.min.js +++ b/public/javascripts/lotOccupancySearch.min.js @@ -1 +1 @@ -"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),(()=>{const t=exports.los,e=document.querySelector("#form--searchFilters"),a=document.querySelector("#container--searchResults"),s=Number.parseInt(document.querySelector("#searchFilter--limit").value,10),c=document.querySelector("#searchFilter--offset");function n(e){var c,n,i,l,p,d,u,h;if(0===e.lotOccupancies.length)return void(a.innerHTML=`
\n

\n There are no ${t.escapedAliases.occupancy} records that meet the search criteria.\n

\n
`);const y=document.createElement("tbody"),f=cityssm.dateToString(new Date);for(const a of e.lotOccupancies){let e="";e=a.occupancyStartDateString<=f&&(""===a.occupancyEndDateString||a.occupancyEndDateString>=f)?`\n \n `:a.occupancyStartDateString>f?`\n \n `:`\n \n `;let s="";for(const t of a.lotOccupancyOccupants)s+=' '+cityssm.escapeHTML(null!==(i=t.occupantName)&&void 0!==i?i:"")+"
";y.insertAdjacentHTML("beforeend",'")}a.innerHTML=`
'+e+''+cityssm.escapeHTML(a.occupancyType)+""+(-1===(null!==(l=a.lotId)&&void 0!==l?l:-1)?'(No '+t.escapedAliases.Lot+")":''+cityssm.escapeHTML(a.lotName)+"")+'
'+cityssm.escapeHTML(null!==(d=a.mapName)&&void 0!==d?d:"")+"
"+a.occupancyStartDateString+""+(a.occupancyEndDate?a.occupancyEndDateString:'(No End Date)')+""+s+""+(a.printEJS?'':"")+"
\n \n \n \n \n \n \n \n \n \n
${t.escapedAliases.Occupancy} Type${t.escapedAliases.Lot}${t.escapedAliases.OccupancyStartDate}End Date${t.escapedAliases.Occupants}Print
`,a.querySelector("table").append(y),a.insertAdjacentHTML("beforeend",t.getSearchResultsPagerHTML(s,e.offset,e.count)),null===(u=a.querySelector("button[data-page='previous']"))||void 0===u||u.addEventListener("click",o),null===(h=a.querySelector("button[data-page='next']"))||void 0===h||h.addEventListener("click",r)}function i(){a.innerHTML=t.getLoadingParagraphHTML(`Loading ${t.escapedAliases.Occupancies}...`),cityssm.postJSON(t.urlPrefix+"/lotOccupancies/doSearchLotOccupancies",e,n)}function l(){c.value="0",i()}function o(){c.value=Math.max(Number.parseInt(c.value,10)-s,0).toString(),i()}function r(){c.value=(Number.parseInt(c.value,10)+s).toString(),i()}const p=e.querySelectorAll("input, select");for(const t of p)t.addEventListener("change",l);e.addEventListener("submit",t=>{t.preventDefault()}),i()})(); \ No newline at end of file +"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),(()=>{const t=exports.los,a=document.querySelector("#form--searchFilters"),e=document.querySelector("#container--searchResults"),s=Number.parseInt(document.querySelector("#searchFilter--limit").value,10),c=document.querySelector("#searchFilter--offset");function n(a){var c,n,l,i,d,p,u,h,y,f,v,m;if(0===a.lotOccupancies.length)return void(e.innerHTML=`
\n

\n There are no ${t.escapedAliases.occupancy} records that meet the search criteria.\n

\n
`);const g=document.createElement("tbody"),L=cityssm.dateToString(new Date);for(const e of a.lotOccupancies){let a="";a=e.occupancyStartDateString<=L&&(""===e.occupancyEndDateString||e.occupancyEndDateString>=L)?`\n \n `:e.occupancyStartDateString>L?`\n \n `:`\n \n `;let s="";for(const t of e.lotOccupancyOccupants)s+=' '+cityssm.escapeHTML(null!==(l=t.occupantName)&&void 0!==l?l:"")+"
";const o=(null!==(d=null===(i=e.lotOccupancyFees)||void 0===i?void 0:i.reduce((t,a)=>{var e,s,c;return t+((null!==(e=a.feeAmount)&&void 0!==e?e:0)+(null!==(s=a.taxAmount)&&void 0!==s?s:0))*(null!==(c=a.quantity)&&void 0!==c?c:0)},0))&&void 0!==d?d:0).toFixed(2),r=(null!==(u=null===(p=e.lotOccupancyTransactions)||void 0===p?void 0:p.reduce((t,a)=>t+a.transactionAmount,0))&&void 0!==u?u:0).toFixed(2);let v="";"0.00"===o&&"0.00"===r||(v=`\n \n `),g.insertAdjacentHTML("beforeend",'")}e.innerHTML=`
'+a+''+cityssm.escapeHTML(e.occupancyType)+""+(-1===(null!==(h=e.lotId)&&void 0!==h?h:-1)?'(No '+t.escapedAliases.Lot+")":''+cityssm.escapeHTML(e.lotName)+"")+'
'+cityssm.escapeHTML(null!==(f=e.mapName)&&void 0!==f?f:"")+"
"+e.occupancyStartDateString+""+(e.occupancyEndDate?e.occupancyEndDateString:'(No End Date)')+""+s+""+v+""+(e.printEJS?'':"")+"
\n \n \n \n \n \n \n \n \n \n \n
${t.escapedAliases.Occupancy} Type${t.escapedAliases.Lot}${t.escapedAliases.OccupancyStartDate}End Date${t.escapedAliases.Occupants}Fees and TransactionsPrint
`,e.querySelector("table").append(g),e.insertAdjacentHTML("beforeend",t.getSearchResultsPagerHTML(s,a.offset,a.count)),null===(v=e.querySelector("button[data-page='previous']"))||void 0===v||v.addEventListener("click",o),null===(m=e.querySelector("button[data-page='next']"))||void 0===m||m.addEventListener("click",r)}function l(){e.innerHTML=t.getLoadingParagraphHTML(`Loading ${t.escapedAliases.Occupancies}...`),cityssm.postJSON(t.urlPrefix+"/lotOccupancies/doSearchLotOccupancies",a,n)}function i(){c.value="0",l()}function o(){c.value=Math.max(Number.parseInt(c.value,10)-s,0).toString(),l()}function r(){c.value=(Number.parseInt(c.value,10)+s).toString(),l()}const d=a.querySelectorAll("input, select");for(const t of d)t.addEventListener("change",i);a.addEventListener("submit",t=>{t.preventDefault()}),l()})(); \ No newline at end of file