show fees on lot occupancy search

deepsource-autofix-76c6eb20
Dan Gowans 2023-01-27 15:55:22 -05:00
parent f2db647d55
commit 50a881a009
14 changed files with 110 additions and 16 deletions

View File

@ -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,

View File

@ -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({

View File

@ -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,

View File

@ -22,7 +22,9 @@ export async function handler(
{
limit: -1,
offset: 0,
includeOccupants: true
includeOccupants: true,
includeFees: false,
includeTransactions: false
}
)

View File

@ -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,

View File

@ -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,

View File

@ -18,6 +18,8 @@ async function _getLot(sql, lotIdOrLotName) {
lotId: lot.lotId
}, {
includeOccupants: true,
includeFees: false,
includeTransactions: false,
limit: -1,
offset: 0
}, database);

View File

@ -32,6 +32,8 @@ async function _getLot(
},
{
includeOccupants: true,
includeFees: false,
includeTransactions: false,
limit: -1,
offset: 0
},

View File

@ -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;

View File

@ -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);
}

View File

@ -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!,

View File

@ -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 = `<div class="message is-info">
<p class="message-body">
@ -52,6 +52,23 @@ Object.defineProperty(exports, "__esModule", { value: true });
cityssm.escapeHTML((_c = occupant.occupantName) !== null && _c !== void 0 ? _c : '') +
'</span><br />';
}
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 = `<span class="icon"
data-tooltip="Total Fees: $${feeTotal}"
aria-label="Total Fees: $${feeTotal}">
<i class="fas fa-dollar-sign ${feeTotal === transactionTotal ? 'has-text-success' : 'has-text-danger'}" aria-hidden="true"></i>
</span>`;
}
resultsTbodyElement.insertAdjacentHTML('beforeend', '<tr>' +
('<td class="has-width-1">' + occupancyTimeHTML + '</td>') +
('<td>' +
@ -62,12 +79,12 @@ Object.defineProperty(exports, "__esModule", { value: true });
'</a>' +
'</td>') +
('<td>' +
(((_d = lotOccupancy.lotId) !== null && _d !== void 0 ? _d : -1) === -1
(((_h = lotOccupancy.lotId) !== null && _h !== void 0 ? _h : -1) === -1
? '<span class="has-text-grey">(No ' +
los.escapedAliases.Lot +
')</span>'
: '<a class="has-tooltip-right" data-tooltip="' +
cityssm.escapeHTML((_e = lotOccupancy.lotType) !== null && _e !== void 0 ? _e : '') +
cityssm.escapeHTML((_j = lotOccupancy.lotType) !== null && _j !== void 0 ? _j : '') +
'" href="' +
los.getLotURL(lotOccupancy.lotId) +
'">' +
@ -75,7 +92,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
'</a>') +
'<br />' +
('<span class="is-size-7">' +
cityssm.escapeHTML((_f = lotOccupancy.mapName) !== null && _f !== void 0 ? _f : '') +
cityssm.escapeHTML((_k = lotOccupancy.mapName) !== null && _k !== void 0 ? _k : '') +
'</span>') +
'</td>') +
('<td>' + lotOccupancy.occupancyStartDateString + '</td>') +
@ -85,6 +102,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
: '<span class="has-text-grey">(No End Date)</span>') +
'</td>') +
('<td>' + occupantsHTML + '</td>') +
('<td>' + feeIconHTML + '</td>') +
'<td>' +
(lotOccupancy.printEJS
? '<a class="button is-small" data-tooltip="Print" href="' +
@ -108,6 +126,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
<th>${los.escapedAliases.OccupancyStartDate}</th>
<th>End Date</th>
<th>${los.escapedAliases.Occupants}</th>
<th class="has-width-1"><span class="is-sr-only">Fees and Transactions</span></th>
<th class="has-width-1"><span class="is-sr-only">Print</span></th>
</tr></thead>
<table>`;
@ -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}...`);

View File

@ -84,6 +84,35 @@ declare const cityssm: cityssmGlobal
'</span><br />'
}
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 = `<span class="icon"
data-tooltip="Total Fees: $${feeTotal}"
aria-label="Total Fees: $${feeTotal}">
<i class="fas fa-dollar-sign ${
feeTotal === transactionTotal ? 'has-text-success' : 'has-text-danger'
}" aria-hidden="true"></i>
</span>`
}
resultsTbodyElement.insertAdjacentHTML(
'beforeend',
'<tr>' +
@ -112,13 +141,14 @@ declare const cityssm: cityssmGlobal
cityssm.escapeHTML(lotOccupancy.mapName ?? '') +
'</span>') +
'</td>') +
('<td>' + lotOccupancy.occupancyStartDateString + '</td>') +
('<td>' + lotOccupancy.occupancyStartDateString! + '</td>') +
('<td>' +
(lotOccupancy.occupancyEndDate
? lotOccupancy.occupancyEndDateString
: '<span class="has-text-grey">(No End Date)</span>') +
'</td>') +
('<td>' + occupantsHTML + '</td>') +
('<td>' + feeIconHTML + '</td>') +
'<td>' +
(lotOccupancy.printEJS
? '<a class="button is-small" data-tooltip="Print" href="' +
@ -144,6 +174,7 @@ declare const cityssm: cityssmGlobal
<th>${los.escapedAliases.OccupancyStartDate}</th>
<th>End Date</th>
<th>${los.escapedAliases.Occupants}</th>
<th class="has-width-1"><span class="is-sr-only">Fees and Transactions</span></th>
<th class="has-width-1"><span class="is-sr-only">Print</span></th>
</tr></thead>
<table>`

View File

@ -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=`<div class="message is-info">\n <p class="message-body">\n There are no ${t.escapedAliases.occupancy} records that meet the search criteria.\n </p>\n </div>`);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)?`<span class="has-tooltip-right" data-tooltip="Current ${t.escapedAliases.Occupancy}">\n <i class="fas fa-play" aria-label="Current ${t.escapedAliases.Occupancy}"></i>\n </span>`:a.occupancyStartDateString>f?`<span class="has-tooltip-right" data-tooltip="Future ${t.escapedAliases.Occupancy}">\n <i class="fas fa-fast-forward" aria-label="Future ${t.escapedAliases.Occupancy}"></i>\n </span>`:`<span class="has-tooltip-right" data-tooltip="Past ${t.escapedAliases.Occupancy}">\n <i class="fas fa-stop" aria-label="Past ${t.escapedAliases.Occupancy}"></i>\n </span>`;let s="";for(const t of a.lotOccupancyOccupants)s+='<span class="has-tooltip-left" data-tooltip="'+cityssm.escapeHTML(null!==(c=t.lotOccupantType)&&void 0!==c?c:"")+'"><i class="fas fa-fw fa-'+cityssm.escapeHTML(""===(null!==(n=t.fontAwesomeIconClass)&&void 0!==n?n:"")?"user":t.fontAwesomeIconClass)+'" aria-hidden="true"></i> '+cityssm.escapeHTML(null!==(i=t.occupantName)&&void 0!==i?i:"")+"</span><br />";y.insertAdjacentHTML("beforeend",'<tr><td class="has-width-1">'+e+'</td><td><a class="has-text-weight-bold" href="'+t.getLotOccupancyURL(a.lotOccupancyId)+'">'+cityssm.escapeHTML(a.occupancyType)+"</a></td><td>"+(-1===(null!==(l=a.lotId)&&void 0!==l?l:-1)?'<span class="has-text-grey">(No '+t.escapedAliases.Lot+")</span>":'<a class="has-tooltip-right" data-tooltip="'+cityssm.escapeHTML(null!==(p=a.lotType)&&void 0!==p?p:"")+'" href="'+t.getLotURL(a.lotId)+'">'+cityssm.escapeHTML(a.lotName)+"</a>")+'<br /><span class="is-size-7">'+cityssm.escapeHTML(null!==(d=a.mapName)&&void 0!==d?d:"")+"</span></td><td>"+a.occupancyStartDateString+"</td><td>"+(a.occupancyEndDate?a.occupancyEndDateString:'<span class="has-text-grey">(No End Date)</span>')+"</td><td>"+s+"</td><td>"+(a.printEJS?'<a class="button is-small" data-tooltip="Print" href="'+t.urlPrefix+"/print/"+a.printEJS+"/?lotOccupancyId="+a.lotOccupancyId+'" target="_blank"><i class="fas fa-print" aria-label="Print"></i></a>':"")+"</td></tr>")}a.innerHTML=`<table class="table is-fullwidth is-striped is-hoverable has-sticky-header">\n <thead><tr>\n <th class="has-width-1"></th>\n <th>${t.escapedAliases.Occupancy} Type</th>\n <th>${t.escapedAliases.Lot}</th>\n <th>${t.escapedAliases.OccupancyStartDate}</th>\n <th>End Date</th>\n <th>${t.escapedAliases.Occupants}</th>\n <th class="has-width-1"><span class="is-sr-only">Print</span></th>\n </tr></thead>\n <table>`,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()})();
"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=`<div class="message is-info">\n <p class="message-body">\n There are no ${t.escapedAliases.occupancy} records that meet the search criteria.\n </p>\n </div>`);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)?`<span class="has-tooltip-right" data-tooltip="Current ${t.escapedAliases.Occupancy}">\n <i class="fas fa-play" aria-label="Current ${t.escapedAliases.Occupancy}"></i>\n </span>`:e.occupancyStartDateString>L?`<span class="has-tooltip-right" data-tooltip="Future ${t.escapedAliases.Occupancy}">\n <i class="fas fa-fast-forward" aria-label="Future ${t.escapedAliases.Occupancy}"></i>\n </span>`:`<span class="has-tooltip-right" data-tooltip="Past ${t.escapedAliases.Occupancy}">\n <i class="fas fa-stop" aria-label="Past ${t.escapedAliases.Occupancy}"></i>\n </span>`;let s="";for(const t of e.lotOccupancyOccupants)s+='<span class="has-tooltip-left" data-tooltip="'+cityssm.escapeHTML(null!==(c=t.lotOccupantType)&&void 0!==c?c:"")+'"><i class="fas fa-fw fa-'+cityssm.escapeHTML(""===(null!==(n=t.fontAwesomeIconClass)&&void 0!==n?n:"")?"user":t.fontAwesomeIconClass)+'" aria-hidden="true"></i> '+cityssm.escapeHTML(null!==(l=t.occupantName)&&void 0!==l?l:"")+"</span><br />";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=`<span class="icon"\n data-tooltip="Total Fees: $${o}"\n aria-label="Total Fees: $${o}">\n <i class="fas fa-dollar-sign ${o===r?"has-text-success":"has-text-danger"}" aria-hidden="true"></i>\n </span>`),g.insertAdjacentHTML("beforeend",'<tr><td class="has-width-1">'+a+'</td><td><a class="has-text-weight-bold" href="'+t.getLotOccupancyURL(e.lotOccupancyId)+'">'+cityssm.escapeHTML(e.occupancyType)+"</a></td><td>"+(-1===(null!==(h=e.lotId)&&void 0!==h?h:-1)?'<span class="has-text-grey">(No '+t.escapedAliases.Lot+")</span>":'<a class="has-tooltip-right" data-tooltip="'+cityssm.escapeHTML(null!==(y=e.lotType)&&void 0!==y?y:"")+'" href="'+t.getLotURL(e.lotId)+'">'+cityssm.escapeHTML(e.lotName)+"</a>")+'<br /><span class="is-size-7">'+cityssm.escapeHTML(null!==(f=e.mapName)&&void 0!==f?f:"")+"</span></td><td>"+e.occupancyStartDateString+"</td><td>"+(e.occupancyEndDate?e.occupancyEndDateString:'<span class="has-text-grey">(No End Date)</span>')+"</td><td>"+s+"</td><td>"+v+"</td><td>"+(e.printEJS?'<a class="button is-small" data-tooltip="Print" href="'+t.urlPrefix+"/print/"+e.printEJS+"/?lotOccupancyId="+e.lotOccupancyId+'" target="_blank"><i class="fas fa-print" aria-label="Print"></i></a>':"")+"</td></tr>")}e.innerHTML=`<table class="table is-fullwidth is-striped is-hoverable has-sticky-header">\n <thead><tr>\n <th class="has-width-1"></th>\n <th>${t.escapedAliases.Occupancy} Type</th>\n <th>${t.escapedAliases.Lot}</th>\n <th>${t.escapedAliases.OccupancyStartDate}</th>\n <th>End Date</th>\n <th>${t.escapedAliases.Occupants}</th>\n <th class="has-width-1"><span class="is-sr-only">Fees and Transactions</span></th>\n <th class="has-width-1"><span class="is-sr-only">Print</span></th>\n </tr></thead>\n <table>`,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()})();