From de02b0d4960218abe8d20843c987f377f865b58b Mon Sep 17 00:00:00 2001 From: Dan Gowans Date: Wed, 17 Aug 2022 16:26:12 -0400 Subject: [PATCH] development --- handlers/lotOccupancies-post/doGetFees.d.ts | 3 + handlers/lotOccupancies-post/doGetFees.js | 16 ++++++ handlers/lotOccupancies-post/doGetFees.ts | 33 +++++++++++ helpers/lotOccupancyDB/getLotOccupancy.js | 2 +- helpers/lotOccupancyDB/getLotOccupancy.ts | 2 +- public-typescript/lotOccupancyEdit.js | 44 +++++++++++++++ public-typescript/lotOccupancyEdit.ts | 61 +++++++++++++++++++++ public/html/lotOccupancy-addFee.html | 34 ++++++++++++ public/javascripts/lotOccupancyEdit.min.js | 2 +- routes/lotOccupancies.js | 2 + routes/lotOccupancies.ts | 8 +++ types/recordTypes.d.ts | 1 + types/recordTypes.ts | 1 + views/lotOccupancy-edit.ejs | 17 +++++- 14 files changed, 222 insertions(+), 4 deletions(-) create mode 100644 handlers/lotOccupancies-post/doGetFees.d.ts create mode 100644 handlers/lotOccupancies-post/doGetFees.js create mode 100644 handlers/lotOccupancies-post/doGetFees.ts create mode 100644 public/html/lotOccupancy-addFee.html diff --git a/handlers/lotOccupancies-post/doGetFees.d.ts b/handlers/lotOccupancies-post/doGetFees.d.ts new file mode 100644 index 00000000..9621c611 --- /dev/null +++ b/handlers/lotOccupancies-post/doGetFees.d.ts @@ -0,0 +1,3 @@ +import type { RequestHandler } from "express"; +export declare const handler: RequestHandler; +export default handler; diff --git a/handlers/lotOccupancies-post/doGetFees.js b/handlers/lotOccupancies-post/doGetFees.js new file mode 100644 index 00000000..a71f5b90 --- /dev/null +++ b/handlers/lotOccupancies-post/doGetFees.js @@ -0,0 +1,16 @@ +import { getLotOccupancy } from "../../helpers/lotOccupancyDB/getLotOccupancy.js"; +import { getFeeCategories } from "../../helpers/lotOccupancyDB/getFeeCategories.js"; +export const handler = (request, response) => { + const lotOccupancyId = request.body.lotOccupancyId; + const lotOccupancy = getLotOccupancy(lotOccupancyId); + const feeCategories = getFeeCategories({ + occupancyTypeId: lotOccupancy.occupancyTypeId, + lotTypeId: lotOccupancy.lotTypeId + }, { + includeFees: true + }); + response.json({ + feeCategories, + }); +}; +export default handler; diff --git a/handlers/lotOccupancies-post/doGetFees.ts b/handlers/lotOccupancies-post/doGetFees.ts new file mode 100644 index 00000000..1d5d866a --- /dev/null +++ b/handlers/lotOccupancies-post/doGetFees.ts @@ -0,0 +1,33 @@ +import type { + RequestHandler +} from "express"; + +import { + getLotOccupancy +} from "../../helpers/lotOccupancyDB/getLotOccupancy.js"; + +import { + getFeeCategories +} from "../../helpers/lotOccupancyDB/getFeeCategories.js"; + + +export const handler: RequestHandler = (request, response) => { + + const lotOccupancyId = request.body.lotOccupancyId; + + const lotOccupancy = getLotOccupancy(lotOccupancyId); + + const feeCategories = getFeeCategories({ + occupancyTypeId: lotOccupancy.occupancyTypeId, + lotTypeId: lotOccupancy.lotTypeId + }, { + includeFees: true + }); + + response.json({ + feeCategories, + }); +}; + + +export default handler; \ No newline at end of file diff --git a/helpers/lotOccupancyDB/getLotOccupancy.js b/helpers/lotOccupancyDB/getLotOccupancy.js index 7437aec3..1f02cfbb 100644 --- a/helpers/lotOccupancyDB/getLotOccupancy.js +++ b/helpers/lotOccupancyDB/getLotOccupancy.js @@ -14,7 +14,7 @@ export const getLotOccupancy = (lotOccupancyId) => { const lotOccupancy = database .prepare("select o.lotOccupancyId," + " o.occupancyTypeId, t.occupancyType," + - " o.lotId, l.lotName," + + " o.lotId, l.lotName, l.lotTypeId," + " l.mapId, m.mapName," + " o.occupancyStartDate, userFn_dateIntegerToString(o.occupancyStartDate) as occupancyStartDateString," + " o.occupancyEndDate, userFn_dateIntegerToString(o.occupancyEndDate) as occupancyEndDateString" + diff --git a/helpers/lotOccupancyDB/getLotOccupancy.ts b/helpers/lotOccupancyDB/getLotOccupancy.ts index b7a116e6..4920d573 100644 --- a/helpers/lotOccupancyDB/getLotOccupancy.ts +++ b/helpers/lotOccupancyDB/getLotOccupancy.ts @@ -42,7 +42,7 @@ export const getLotOccupancy = (lotOccupancyId: number | string): recordTypes.Lo const lotOccupancy: recordTypes.LotOccupancy = database .prepare("select o.lotOccupancyId," + " o.occupancyTypeId, t.occupancyType," + - " o.lotId, l.lotName," + + " o.lotId, l.lotName, l.lotTypeId," + " l.mapId, m.mapName," + " o.occupancyStartDate, userFn_dateIntegerToString(o.occupancyStartDate) as occupancyStartDateString," + " o.occupancyEndDate, userFn_dateIntegerToString(o.occupancyEndDate) as occupancyEndDateString" + diff --git a/public-typescript/lotOccupancyEdit.js b/public-typescript/lotOccupancyEdit.js index 1b2f8136..8f8660a4 100644 --- a/public-typescript/lotOccupancyEdit.js +++ b/public-typescript/lotOccupancyEdit.js @@ -553,4 +553,48 @@ Object.defineProperty(exports, "__esModule", { value: true }); }); renderLotOccupancyComments(); } + if (!isCreate) { + let lotOccupancyFees = exports.lotOccupancyFees; + const lotOccupancyFeesContainerElement = document.querySelector("#container--lotOccupancyFees"); + const renderLotOccupancyFees = () => { + }; + document.querySelector("#button--addFee").addEventListener("click", () => { + if (hasUnsavedChanges) { + bulmaJS.alert({ + message: "Please save all unsaved changes before adding fees.", + contextualColorName: "warning" + }); + return; + } + let feeCategories; + let feeFilterElement; + const filterFees = () => { + const filterStringPieces = feeFilterElement.value.trim().toLowerCase().split(" "); + }; + cityssm.openHtmlModal("lotOccupancy-addFee", { + onshow: (modalElement) => { + cityssm.postJSON(urlPrefix + "/lotOccupancies/doGetFees", { + lotOccupancyId + }, (responseJSON) => { + feeCategories = responseJSON.feeCategories; + feeFilterElement = modalElement.querySelector("#feeSelect--feeName"); + feeFilterElement.disabled = false; + feeFilterElement.addEventListener("keyup", filterFees); + feeFilterElement.focus(); + filterFees(); + }); + }, + onshown: () => { + bulmaJS.toggleHtmlClipped(); + }, + onhidden: () => { + renderLotOccupancyFees(); + }, + onremoved: () => { + bulmaJS.toggleHtmlClipped(); + } + }); + }); + renderLotOccupancyFees(); + } })(); diff --git a/public-typescript/lotOccupancyEdit.ts b/public-typescript/lotOccupancyEdit.ts index a4c080a1..e692778c 100644 --- a/public-typescript/lotOccupancyEdit.ts +++ b/public-typescript/lotOccupancyEdit.ts @@ -793,6 +793,67 @@ declare const bulmaJS: BulmaJS; * Fees */ + if (!isCreate) { + let lotOccupancyFees: recordTypes.LotOccupancyFee[] = exports.lotOccupancyFees; + const lotOccupancyFeesContainerElement = document.querySelector("#container--lotOccupancyFees") as HTMLElement; + + const renderLotOccupancyFees = () => { + + }; + + document.querySelector("#button--addFee").addEventListener("click", () => { + + if (hasUnsavedChanges) { + bulmaJS.alert({ + message: "Please save all unsaved changes before adding fees.", + contextualColorName: "warning" + }); + return; + } + + let feeCategories: recordTypes.FeeCategory[]; + + let feeFilterElement: HTMLInputElement; + + const filterFees = () => { + + const filterStringPieces = feeFilterElement.value.trim().toLowerCase().split(" "); + + + }; + + cityssm.openHtmlModal("lotOccupancy-addFee", { + onshow: (modalElement) => { + + cityssm.postJSON(urlPrefix + "/lotOccupancies/doGetFees", { + lotOccupancyId + }, + (responseJSON: { feeCategories: recordTypes.FeeCategory[]}) => { + feeCategories = responseJSON.feeCategories; + + feeFilterElement = modalElement.querySelector("#feeSelect--feeName"); + feeFilterElement.disabled = false; + feeFilterElement.addEventListener("keyup", filterFees); + feeFilterElement.focus(); + + filterFees(); + }); + }, + onshown: () => { + bulmaJS.toggleHtmlClipped(); + }, + onhidden: () => { + renderLotOccupancyFees(); + }, + onremoved: () => { + bulmaJS.toggleHtmlClipped(); + } + }); + }); + + renderLotOccupancyFees(); + } + /* * Transactions */ diff --git a/public/html/lotOccupancy-addFee.html b/public/html/lotOccupancy-addFee.html new file mode 100644 index 00000000..d1e41946 --- /dev/null +++ b/public/html/lotOccupancy-addFee.html @@ -0,0 +1,34 @@ + \ No newline at end of file diff --git a/public/javascripts/lotOccupancyEdit.min.js b/public/javascripts/lotOccupancyEdit.min.js index d842422b..934e4836 100644 --- a/public/javascripts/lotOccupancyEdit.min.js +++ b/public/javascripts/lotOccupancyEdit.min.js @@ -1 +1 @@ -"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),(()=>{const e=exports.los,t=document.querySelector("main").dataset.urlPrefix,c=document.querySelector("#lotOccupancy--lotOccupancyId").value,o=""===c;let a=!1,n=o;const s=()=>{a||(a=!0,cityssm.enableNavBlocker())},l=document.querySelector("#form--lotOccupancy");l.addEventListener("submit",e=>{e.preventDefault(),cityssm.postJSON(t+"/lotOccupancies/"+(o?"doCreateLotOccupancy":"doUpdateLotOccupancy"),l,e=>{e.success?(a=!1,cityssm.disableNavBlocker(),o||n?window.location.href=t+"/lotOccupancies/"+e.lotOccupancyId+"/edit?t="+Date.now():bulmaJS.alert({message:exports.aliases.occupancy+" Updated Successfully",contextualColorName:"success"})):bulmaJS.alert({title:"Error Saving "+exports.aliases.occupancy,message:e.errorMessage,contextualColorName:"danger"})})});const u=l.querySelectorAll("input, select");for(const e of u)e.addEventListener("change",s);const r=document.querySelector("#lotOccupancy--occupancyTypeId");if(o){const e=document.querySelector("#container--lotOccupancyFields");r.addEventListener("change",()=>{""!==r.value?cityssm.postJSON(t+"/lotOccupancies/doGetOccupancyTypeFields",{occupancyTypeId:r.value},t=>{if(0===t.occupancyTypeFields.length)return void(e.innerHTML='

There are no additional fields for this '+exports.aliases.occupancy.toLowerCase()+" type.

");e.innerHTML="";let c="";for(const o of t.occupancyTypeFields){c+=","+o.occupancyTypeFieldId;const t=document.createElement("div");t.className="field",t.innerHTML='
',t.querySelector("label").textContent=o.occupancyTypeField;const a=document.createElement("input");a.className="input",a.id="lotOccupancy--lotOccupancyFieldValue_"+o.occupancyTypeFieldId,a.name="lotOccupancyFieldValue_"+o.occupancyTypeFieldId,a.type="text",a.required=o.isRequired,a.minLength=o.minimumLength,a.maxLength=o.maximumLength,o.pattern&&""!==o.pattern&&(a.pattern=o.pattern),t.querySelector(".control").append(a),e.append(t)}e.insertAdjacentHTML("beforeend",'')}):e.innerHTML='

Select the '+exports.aliases.occupancy.toLowerCase()+" type to load the available fields.

"})}else{const e=r.value;r.addEventListener("change",()=>{r.value!==e&&bulmaJS.confirm({title:"Confirm Change",message:"Are you sure you want to change the "+exports.aliases.occupancy.toLowerCase()+" type?\nThis change affects the additional fields associated with this record, and may also affect the available fees.",contextualColorName:"warning",okButton:{text:"Yes, Keep the Change",callbackFunction:()=>{n=!0}},cancelButton:{text:"Revert the Change",callbackFunction:()=>{r.value=e}}})})}if(document.querySelector("#lotOccupancy--lotName").addEventListener("click",c=>{const o=c.currentTarget.value;let a,n,l;const u=e=>{e.preventDefault();const t=e.currentTarget;document.querySelector("#lotOccupancy--lotId").value=t.dataset.lotId,document.querySelector("#lotOccupancy--lotName").value=t.dataset.lotName,s(),a()},r=()=>{l.innerHTML='


Searching...

',cityssm.postJSON(t+"/lots/doSearchLots",n,e=>{if(0===e.count)return void(l.innerHTML='

No results.

');const t=document.createElement("div");t.className="panel";for(const c of e.lots){const e=document.createElement("a");e.className="panel-block is-block",e.href="#",e.dataset.lotId=c.lotId.toString(),e.dataset.lotName=c.lotName,e.innerHTML='
'+cityssm.escapeHTML(c.lotName)+'
'+cityssm.escapeHTML(c.mapName)+'
'+cityssm.escapeHTML(c.lotStatus)+'
'+(c.lotOccupancyCount>0?"Currently Occupied":"")+"
",e.addEventListener("click",u),t.append(e)}l.innerHTML="",l.append(t)})};cityssm.openHtmlModal("lotOccupancy-selectLot",{onshow:t=>{e.populateAliases(t)},onshown:(e,t)=>{bulmaJS.toggleHtmlClipped(),a=t;const c=e.querySelector("#lotSelect--lotName");c.value=o,c.focus(),c.addEventListener("change",r),e.querySelector("#lotSelect--occupancyStatus").addEventListener("change",r),n=e.querySelector("#form--lotSelect"),l=e.querySelector("#resultsContainer--lotSelect"),n.addEventListener("submit",e=>{e.preventDefault()}),r()},onremoved:()=>{bulmaJS.toggleHtmlClipped()}})}),document.querySelector("#lotOccupancy--occupancyStartDateString").addEventListener("change",()=>{document.querySelector("#lotOccupancy--occupancyEndDateString").min=document.querySelector("#lotOccupancy--occupancyStartDateString").value}),e.initializeUnlockFieldButtons(l),!o){let o=exports.lotOccupancyOccupants;const a=a=>{const n=Number.parseInt(a.currentTarget.closest("tr").dataset.lotOccupantIndex,10),l=o.find(e=>e.lotOccupantIndex===n);let u,r;const p=e=>{e.preventDefault(),cityssm.postJSON(t+"/lotOccupancies/doUpdateLotOccupancyOccupant",u,e=>{e.success?(o=e.lotOccupancyOccupants,r(),s()):bulmaJS.alert({title:"Error Updating "+exports.aliases.occupant,message:e.errorMessage,contextualColorName:"danger"})})};cityssm.openHtmlModal("lotOccupancy-editOccupant",{onshow:t=>{e.populateAliases(t),t.querySelector("#lotOccupancyOccupantEdit--lotOccupancyId").value=c,t.querySelector("#lotOccupancyOccupantEdit--lotOccupantIndex").value=n.toString();const o=t.querySelector("#lotOccupancyOccupantEdit--lotOccupantTypeId");let a=!1;for(const e of exports.lotOccupantTypes){const t=document.createElement("option");t.value=e.lotOccupantTypeId.toString(),t.textContent=e.lotOccupantType,e.lotOccupantTypeId===l.lotOccupantTypeId&&(t.selected=!0,a=!0),o.append(t)}if(!a){const e=document.createElement("option");e.value=l.lotOccupantTypeId.toString(),e.textContent=l.lotOccupantType,e.selected=!0,o.append(e)}t.querySelector("#lotOccupancyOccupantEdit--occupantName").value=l.occupantName,t.querySelector("#lotOccupancyOccupantEdit--occupantAddress1").value=l.occupantAddress1,t.querySelector("#lotOccupancyOccupantEdit--occupantAddress2").value=l.occupantAddress2,t.querySelector("#lotOccupancyOccupantEdit--occupantCity").value=l.occupantCity,t.querySelector("#lotOccupancyOccupantEdit--occupantProvince").value=l.occupantProvince,t.querySelector("#lotOccupancyOccupantEdit--occupantPostalCode").value=l.occupantPostalCode,t.querySelector("#lotOccupancyOccupantEdit--occupantPhoneNumber").value=l.occupantPhoneNumber},onshown:(e,t)=>{bulmaJS.toggleHtmlClipped(),(u=e.querySelector("form")).addEventListener("submit",p),r=t},onremoved:()=>{bulmaJS.toggleHtmlClipped()}})},n=e=>{const a=e.currentTarget.closest("tr").dataset.lotOccupantIndex;bulmaJS.confirm({title:"Remove "+exports.aliases.occupant+"?",message:"Are you sure you want to remove this "+exports.aliases.occupant.toLowerCase()+"?",okButton:{text:"Yes, Remove "+exports.aliases.occupant,callbackFunction:()=>{cityssm.postJSON(t+"/lotOccupancies/doDeleteLotOccupancyOccupant",{lotOccupancyId:c,lotOccupantIndex:a},e=>{e.success?(o=e.lotOccupancyOccupants,s()):bulmaJS.alert({title:"Error Removing "+exports.aliases.occupant,message:e.errorMessage,contextualColorName:"danger"})})}},contextualColorName:"warning"})},s=()=>{const e=document.querySelector("#container--lotOccupancyOccupants");if(cityssm.clearElement(e),0===o.length)return void(e.innerHTML='

There are no '+exports.aliases.occupants.toLowerCase()+" associated with this record.

");const t=document.createElement("table");t.className="table is-fullwidth is-striped is-hoverable",t.innerHTML=""+exports.aliases.occupant+" Type"+exports.aliases.occupant+"AddressPhone Number";for(const e of o){const c=document.createElement("tr");c.dataset.lotOccupantIndex=e.lotOccupantIndex.toString(),c.innerHTML=""+cityssm.escapeHTML(e.lotOccupantType)+""+cityssm.escapeHTML(e.occupantName)+""+cityssm.escapeHTML(e.occupantAddress1)+"
"+(e.occupantAddress2?cityssm.escapeHTML(e.occupantAddress2)+"
":"")+cityssm.escapeHTML(e.occupantCity)+", "+cityssm.escapeHTML(e.occupantProvince)+"
"+cityssm.escapeHTML(e.occupantPostalCode)+""+cityssm.escapeHTML(e.occupantPhoneNumber)+'
',c.querySelector(".button--edit").addEventListener("click",a),c.querySelector(".button--delete").addEventListener("click",n),t.querySelector("tbody").append(c)}e.append(t)};document.querySelector("#button--addOccupant").addEventListener("click",()=>{let a,n;const l=e=>{e.preventDefault(),cityssm.postJSON(t+"/lotOccupancies/doAddLotOccupancyOccupant",a,e=>{e.success?(o=e.lotOccupancyOccupants,n(),s()):bulmaJS.alert({title:"Error Adding "+exports.aliases.occupant,message:e.errorMessage,contextualColorName:"danger"})})};cityssm.openHtmlModal("lotOccupancy-addOccupant",{onshow:t=>{e.populateAliases(t),t.querySelector("#lotOccupancyOccupantAdd--lotOccupancyId").value=c;const o=t.querySelector("#lotOccupancyOccupantAdd--lotOccupantTypeId");for(const e of exports.lotOccupantTypes){const t=document.createElement("option");t.value=e.lotOccupantTypeId.toString(),t.textContent=e.lotOccupantType,o.append(t)}t.querySelector("#lotOccupancyOccupantAdd--occupantCity").value=exports.occupantCityDefault,t.querySelector("#lotOccupancyOccupantAdd--occupantProvince").value=exports.occupantProvinceDefault},onshown:(e,t)=>{bulmaJS.toggleHtmlClipped(),(a=e.querySelector("form")).addEventListener("submit",l),n=t},onremoved:()=>{bulmaJS.toggleHtmlClipped()}})}),s()}if(!o){let o=exports.lotOccupancyComments;const a=a=>{const n=Number.parseInt(a.currentTarget.closest("tr").dataset.lotOccupancyCommentId,10),l=o.find(e=>e.lotOccupancyCommentId===n);let u,r;const p=e=>{e.preventDefault(),cityssm.postJSON(t+"/lotOccupancies/doUpdateLotOccupancyComment",u,e=>{e.success?(o=e.lotOccupancyComments,r(),s()):bulmaJS.alert({title:"Error Updating Comment",message:e.errorMessage,contextualColorName:"danger"})})};cityssm.openHtmlModal("lotOccupancy-editComment",{onshow:t=>{e.populateAliases(t),t.querySelector("#lotOccupancyCommentEdit--lotOccupancyId").value=c,t.querySelector("#lotOccupancyCommentEdit--lotOccupancyCommentId").value=n.toString(),t.querySelector("#lotOccupancyCommentEdit--lotOccupancyComment").value=l.lotOccupancyComment,t.querySelector("#lotOccupancyCommentEdit--lotOccupancyCommentDateString").value=l.lotOccupancyCommentDateString,t.querySelector("#lotOccupancyCommentEdit--lotOccupancyCommentTimeString").value=l.lotOccupancyCommentTimeString},onshown:(e,t)=>{bulmaJS.toggleHtmlClipped(),(u=e.querySelector("form")).addEventListener("submit",p),r=t},onremoved:()=>{bulmaJS.toggleHtmlClipped()}})},n=e=>{const a=Number.parseInt(e.currentTarget.closest("tr").dataset.lotOccupancyCommentId,10);bulmaJS.confirm({title:"Remove Comment?",message:"Are you sure you want to remove this comment?",okButton:{text:"Yes, Remove Comment",callbackFunction:()=>{cityssm.postJSON(t+"/lotOccupancies/doDeleteLotOccupancyComment",{lotOccupancyId:c,lotOccupancyCommentId:a},e=>{e.success?(o=e.lotOccupancyComments,s()):bulmaJS.alert({title:"Error Removing Comment",message:e.errorMessage,contextualColorName:"danger"})})}},contextualColorName:"warning"})},s=()=>{const e=document.querySelector("#container--lotOccupancyComments");if(0===o.length)return void(e.innerHTML='

There are no comments associated with this record.

');const t=document.createElement("table");t.className="table is-fullwidth is-striped is-hoverable",t.innerHTML='CommentorComment DateCommentOptions';for(const e of o){const c=document.createElement("tr");c.dataset.lotOccupancyCommentId=e.lotOccupancyCommentId.toString(),c.innerHTML=""+cityssm.escapeHTML(e.recordCreate_userName)+""+e.lotOccupancyCommentDateString+(0===e.lotOccupancyCommentTime?"":" "+e.lotOccupancyCommentTimeString)+""+cityssm.escapeHTML(e.lotOccupancyComment)+'
',c.querySelector(".button--edit").addEventListener("click",a),c.querySelector(".button--delete").addEventListener("click",n),t.querySelector("tbody").append(c)}e.innerHTML="",e.append(t)};document.querySelector("#button--addComment").addEventListener("click",()=>{let a,n;const l=e=>{e.preventDefault(),cityssm.postJSON(t+"/lotOccupancies/doAddLotOccupancyComment",a,e=>{e.success?(o=e.lotOccupancyComments,n(),s()):bulmaJS.alert({title:"Error Adding Comment",message:e.errorMessage,contextualColorName:"danger"})})};cityssm.openHtmlModal("lotOccupancy-addComment",{onshow:t=>{e.populateAliases(t),t.querySelector("#lotOccupancyCommentAdd--lotOccupancyId").value=c},onshown:(e,t)=>{bulmaJS.toggleHtmlClipped(),(a=e.querySelector("form")).addEventListener("submit",l),n=t},onremoved:()=>{bulmaJS.toggleHtmlClipped()}})}),s()}})(); \ No newline at end of file +"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),(()=>{const e=exports.los,t=document.querySelector("main").dataset.urlPrefix,c=document.querySelector("#lotOccupancy--lotOccupancyId").value,o=""===c;let a=!1,n=o;const s=()=>{a||(a=!0,cityssm.enableNavBlocker())},l=document.querySelector("#form--lotOccupancy");l.addEventListener("submit",e=>{e.preventDefault(),cityssm.postJSON(t+"/lotOccupancies/"+(o?"doCreateLotOccupancy":"doUpdateLotOccupancy"),l,e=>{e.success?(a=!1,cityssm.disableNavBlocker(),o||n?window.location.href=t+"/lotOccupancies/"+e.lotOccupancyId+"/edit?t="+Date.now():bulmaJS.alert({message:exports.aliases.occupancy+" Updated Successfully",contextualColorName:"success"})):bulmaJS.alert({title:"Error Saving "+exports.aliases.occupancy,message:e.errorMessage,contextualColorName:"danger"})})});const u=l.querySelectorAll("input, select");for(const e of u)e.addEventListener("change",s);const r=document.querySelector("#lotOccupancy--occupancyTypeId");if(o){const e=document.querySelector("#container--lotOccupancyFields");r.addEventListener("change",()=>{""!==r.value?cityssm.postJSON(t+"/lotOccupancies/doGetOccupancyTypeFields",{occupancyTypeId:r.value},t=>{if(0===t.occupancyTypeFields.length)return void(e.innerHTML='

There are no additional fields for this '+exports.aliases.occupancy.toLowerCase()+" type.

");e.innerHTML="";let c="";for(const o of t.occupancyTypeFields){c+=","+o.occupancyTypeFieldId;const t=document.createElement("div");t.className="field",t.innerHTML='
',t.querySelector("label").textContent=o.occupancyTypeField;const a=document.createElement("input");a.className="input",a.id="lotOccupancy--lotOccupancyFieldValue_"+o.occupancyTypeFieldId,a.name="lotOccupancyFieldValue_"+o.occupancyTypeFieldId,a.type="text",a.required=o.isRequired,a.minLength=o.minimumLength,a.maxLength=o.maximumLength,o.pattern&&""!==o.pattern&&(a.pattern=o.pattern),t.querySelector(".control").append(a),e.append(t)}e.insertAdjacentHTML("beforeend",'')}):e.innerHTML='

Select the '+exports.aliases.occupancy.toLowerCase()+" type to load the available fields.

"})}else{const e=r.value;r.addEventListener("change",()=>{r.value!==e&&bulmaJS.confirm({title:"Confirm Change",message:"Are you sure you want to change the "+exports.aliases.occupancy.toLowerCase()+" type?\nThis change affects the additional fields associated with this record, and may also affect the available fees.",contextualColorName:"warning",okButton:{text:"Yes, Keep the Change",callbackFunction:()=>{n=!0}},cancelButton:{text:"Revert the Change",callbackFunction:()=>{r.value=e}}})})}if(document.querySelector("#lotOccupancy--lotName").addEventListener("click",c=>{const o=c.currentTarget.value;let a,n,l;const u=e=>{e.preventDefault();const t=e.currentTarget;document.querySelector("#lotOccupancy--lotId").value=t.dataset.lotId,document.querySelector("#lotOccupancy--lotName").value=t.dataset.lotName,s(),a()},r=()=>{l.innerHTML='


Searching...

',cityssm.postJSON(t+"/lots/doSearchLots",n,e=>{if(0===e.count)return void(l.innerHTML='

No results.

');const t=document.createElement("div");t.className="panel";for(const c of e.lots){const e=document.createElement("a");e.className="panel-block is-block",e.href="#",e.dataset.lotId=c.lotId.toString(),e.dataset.lotName=c.lotName,e.innerHTML='
'+cityssm.escapeHTML(c.lotName)+'
'+cityssm.escapeHTML(c.mapName)+'
'+cityssm.escapeHTML(c.lotStatus)+'
'+(c.lotOccupancyCount>0?"Currently Occupied":"")+"
",e.addEventListener("click",u),t.append(e)}l.innerHTML="",l.append(t)})};cityssm.openHtmlModal("lotOccupancy-selectLot",{onshow:t=>{e.populateAliases(t)},onshown:(e,t)=>{bulmaJS.toggleHtmlClipped(),a=t;const c=e.querySelector("#lotSelect--lotName");c.value=o,c.focus(),c.addEventListener("change",r),e.querySelector("#lotSelect--occupancyStatus").addEventListener("change",r),n=e.querySelector("#form--lotSelect"),l=e.querySelector("#resultsContainer--lotSelect"),n.addEventListener("submit",e=>{e.preventDefault()}),r()},onremoved:()=>{bulmaJS.toggleHtmlClipped()}})}),document.querySelector("#lotOccupancy--occupancyStartDateString").addEventListener("change",()=>{document.querySelector("#lotOccupancy--occupancyEndDateString").min=document.querySelector("#lotOccupancy--occupancyStartDateString").value}),e.initializeUnlockFieldButtons(l),!o){let o=exports.lotOccupancyOccupants;const a=a=>{const n=Number.parseInt(a.currentTarget.closest("tr").dataset.lotOccupantIndex,10),l=o.find(e=>e.lotOccupantIndex===n);let u,r;const p=e=>{e.preventDefault(),cityssm.postJSON(t+"/lotOccupancies/doUpdateLotOccupancyOccupant",u,e=>{e.success?(o=e.lotOccupancyOccupants,r(),s()):bulmaJS.alert({title:"Error Updating "+exports.aliases.occupant,message:e.errorMessage,contextualColorName:"danger"})})};cityssm.openHtmlModal("lotOccupancy-editOccupant",{onshow:t=>{e.populateAliases(t),t.querySelector("#lotOccupancyOccupantEdit--lotOccupancyId").value=c,t.querySelector("#lotOccupancyOccupantEdit--lotOccupantIndex").value=n.toString();const o=t.querySelector("#lotOccupancyOccupantEdit--lotOccupantTypeId");let a=!1;for(const e of exports.lotOccupantTypes){const t=document.createElement("option");t.value=e.lotOccupantTypeId.toString(),t.textContent=e.lotOccupantType,e.lotOccupantTypeId===l.lotOccupantTypeId&&(t.selected=!0,a=!0),o.append(t)}if(!a){const e=document.createElement("option");e.value=l.lotOccupantTypeId.toString(),e.textContent=l.lotOccupantType,e.selected=!0,o.append(e)}t.querySelector("#lotOccupancyOccupantEdit--occupantName").value=l.occupantName,t.querySelector("#lotOccupancyOccupantEdit--occupantAddress1").value=l.occupantAddress1,t.querySelector("#lotOccupancyOccupantEdit--occupantAddress2").value=l.occupantAddress2,t.querySelector("#lotOccupancyOccupantEdit--occupantCity").value=l.occupantCity,t.querySelector("#lotOccupancyOccupantEdit--occupantProvince").value=l.occupantProvince,t.querySelector("#lotOccupancyOccupantEdit--occupantPostalCode").value=l.occupantPostalCode,t.querySelector("#lotOccupancyOccupantEdit--occupantPhoneNumber").value=l.occupantPhoneNumber},onshown:(e,t)=>{bulmaJS.toggleHtmlClipped(),(u=e.querySelector("form")).addEventListener("submit",p),r=t},onremoved:()=>{bulmaJS.toggleHtmlClipped()}})},n=e=>{const a=e.currentTarget.closest("tr").dataset.lotOccupantIndex;bulmaJS.confirm({title:"Remove "+exports.aliases.occupant+"?",message:"Are you sure you want to remove this "+exports.aliases.occupant.toLowerCase()+"?",okButton:{text:"Yes, Remove "+exports.aliases.occupant,callbackFunction:()=>{cityssm.postJSON(t+"/lotOccupancies/doDeleteLotOccupancyOccupant",{lotOccupancyId:c,lotOccupantIndex:a},e=>{e.success?(o=e.lotOccupancyOccupants,s()):bulmaJS.alert({title:"Error Removing "+exports.aliases.occupant,message:e.errorMessage,contextualColorName:"danger"})})}},contextualColorName:"warning"})},s=()=>{const e=document.querySelector("#container--lotOccupancyOccupants");if(cityssm.clearElement(e),0===o.length)return void(e.innerHTML='

There are no '+exports.aliases.occupants.toLowerCase()+" associated with this record.

");const t=document.createElement("table");t.className="table is-fullwidth is-striped is-hoverable",t.innerHTML=""+exports.aliases.occupant+" Type"+exports.aliases.occupant+"AddressPhone Number";for(const e of o){const c=document.createElement("tr");c.dataset.lotOccupantIndex=e.lotOccupantIndex.toString(),c.innerHTML=""+cityssm.escapeHTML(e.lotOccupantType)+""+cityssm.escapeHTML(e.occupantName)+""+cityssm.escapeHTML(e.occupantAddress1)+"
"+(e.occupantAddress2?cityssm.escapeHTML(e.occupantAddress2)+"
":"")+cityssm.escapeHTML(e.occupantCity)+", "+cityssm.escapeHTML(e.occupantProvince)+"
"+cityssm.escapeHTML(e.occupantPostalCode)+""+cityssm.escapeHTML(e.occupantPhoneNumber)+'
',c.querySelector(".button--edit").addEventListener("click",a),c.querySelector(".button--delete").addEventListener("click",n),t.querySelector("tbody").append(c)}e.append(t)};document.querySelector("#button--addOccupant").addEventListener("click",()=>{let a,n;const l=e=>{e.preventDefault(),cityssm.postJSON(t+"/lotOccupancies/doAddLotOccupancyOccupant",a,e=>{e.success?(o=e.lotOccupancyOccupants,n(),s()):bulmaJS.alert({title:"Error Adding "+exports.aliases.occupant,message:e.errorMessage,contextualColorName:"danger"})})};cityssm.openHtmlModal("lotOccupancy-addOccupant",{onshow:t=>{e.populateAliases(t),t.querySelector("#lotOccupancyOccupantAdd--lotOccupancyId").value=c;const o=t.querySelector("#lotOccupancyOccupantAdd--lotOccupantTypeId");for(const e of exports.lotOccupantTypes){const t=document.createElement("option");t.value=e.lotOccupantTypeId.toString(),t.textContent=e.lotOccupantType,o.append(t)}t.querySelector("#lotOccupancyOccupantAdd--occupantCity").value=exports.occupantCityDefault,t.querySelector("#lotOccupancyOccupantAdd--occupantProvince").value=exports.occupantProvinceDefault},onshown:(e,t)=>{bulmaJS.toggleHtmlClipped(),(a=e.querySelector("form")).addEventListener("submit",l),n=t},onremoved:()=>{bulmaJS.toggleHtmlClipped()}})}),s()}if(!o){let o=exports.lotOccupancyComments;const a=a=>{const n=Number.parseInt(a.currentTarget.closest("tr").dataset.lotOccupancyCommentId,10),l=o.find(e=>e.lotOccupancyCommentId===n);let u,r;const p=e=>{e.preventDefault(),cityssm.postJSON(t+"/lotOccupancies/doUpdateLotOccupancyComment",u,e=>{e.success?(o=e.lotOccupancyComments,r(),s()):bulmaJS.alert({title:"Error Updating Comment",message:e.errorMessage,contextualColorName:"danger"})})};cityssm.openHtmlModal("lotOccupancy-editComment",{onshow:t=>{e.populateAliases(t),t.querySelector("#lotOccupancyCommentEdit--lotOccupancyId").value=c,t.querySelector("#lotOccupancyCommentEdit--lotOccupancyCommentId").value=n.toString(),t.querySelector("#lotOccupancyCommentEdit--lotOccupancyComment").value=l.lotOccupancyComment,t.querySelector("#lotOccupancyCommentEdit--lotOccupancyCommentDateString").value=l.lotOccupancyCommentDateString,t.querySelector("#lotOccupancyCommentEdit--lotOccupancyCommentTimeString").value=l.lotOccupancyCommentTimeString},onshown:(e,t)=>{bulmaJS.toggleHtmlClipped(),(u=e.querySelector("form")).addEventListener("submit",p),r=t},onremoved:()=>{bulmaJS.toggleHtmlClipped()}})},n=e=>{const a=Number.parseInt(e.currentTarget.closest("tr").dataset.lotOccupancyCommentId,10);bulmaJS.confirm({title:"Remove Comment?",message:"Are you sure you want to remove this comment?",okButton:{text:"Yes, Remove Comment",callbackFunction:()=>{cityssm.postJSON(t+"/lotOccupancies/doDeleteLotOccupancyComment",{lotOccupancyId:c,lotOccupancyCommentId:a},e=>{e.success?(o=e.lotOccupancyComments,s()):bulmaJS.alert({title:"Error Removing Comment",message:e.errorMessage,contextualColorName:"danger"})})}},contextualColorName:"warning"})},s=()=>{const e=document.querySelector("#container--lotOccupancyComments");if(0===o.length)return void(e.innerHTML='

There are no comments associated with this record.

');const t=document.createElement("table");t.className="table is-fullwidth is-striped is-hoverable",t.innerHTML='CommentorComment DateCommentOptions';for(const e of o){const c=document.createElement("tr");c.dataset.lotOccupancyCommentId=e.lotOccupancyCommentId.toString(),c.innerHTML=""+cityssm.escapeHTML(e.recordCreate_userName)+""+e.lotOccupancyCommentDateString+(0===e.lotOccupancyCommentTime?"":" "+e.lotOccupancyCommentTimeString)+""+cityssm.escapeHTML(e.lotOccupancyComment)+'
',c.querySelector(".button--edit").addEventListener("click",a),c.querySelector(".button--delete").addEventListener("click",n),t.querySelector("tbody").append(c)}e.innerHTML="",e.append(t)};document.querySelector("#button--addComment").addEventListener("click",()=>{let a,n;const l=e=>{e.preventDefault(),cityssm.postJSON(t+"/lotOccupancies/doAddLotOccupancyComment",a,e=>{e.success?(o=e.lotOccupancyComments,n(),s()):bulmaJS.alert({title:"Error Adding Comment",message:e.errorMessage,contextualColorName:"danger"})})};cityssm.openHtmlModal("lotOccupancy-addComment",{onshow:t=>{e.populateAliases(t),t.querySelector("#lotOccupancyCommentAdd--lotOccupancyId").value=c},onshown:(e,t)=>{bulmaJS.toggleHtmlClipped(),(a=e.querySelector("form")).addEventListener("submit",l),n=t},onremoved:()=>{bulmaJS.toggleHtmlClipped()}})}),s()}if(!o){exports.lotOccupancyFees;document.querySelector("#container--lotOccupancyFees");const e=()=>{};document.querySelector("#button--addFee").addEventListener("click",()=>{if(a)return void bulmaJS.alert({message:"Please save all unsaved changes before adding fees.",contextualColorName:"warning"});let o,n;const s=()=>{n.value.trim().toLowerCase().split(" ")};cityssm.openHtmlModal("lotOccupancy-addFee",{onshow:e=>{cityssm.postJSON(t+"/lotOccupancies/doGetFees",{lotOccupancyId:c},t=>{o=t.feeCategories,(n=e.querySelector("#feeSelect--feeName")).disabled=!1,n.addEventListener("keyup",s),n.focus(),s()})},onshown:()=>{bulmaJS.toggleHtmlClipped()},onhidden:()=>{e()},onremoved:()=>{bulmaJS.toggleHtmlClipped()}})}),e()}})(); \ No newline at end of file diff --git a/routes/lotOccupancies.js b/routes/lotOccupancies.js index 1ef4f3e9..a95fb810 100644 --- a/routes/lotOccupancies.js +++ b/routes/lotOccupancies.js @@ -13,6 +13,7 @@ import handler_doDeleteLotOccupancyOccupant from "../handlers/lotOccupancies-pos import handler_doAddLotOccupancyComment from "../handlers/lotOccupancies-post/doAddLotOccupancyComment.js"; import handler_doUpdateLotOccupancyComment from "../handlers/lotOccupancies-post/doUpdateLotOccupancyComment.js"; import handler_doDeleteLotOccupancyComment from "../handlers/lotOccupancies-post/doDeleteLotOccupancyComment.js"; +import handler_doGetFees from "../handlers/lotOccupancies-post/doGetFees.js"; import * as permissionHandlers from "../handlers/permissions.js"; export const router = Router(); router.get("/", handler_search); @@ -29,4 +30,5 @@ router.post("/doDeleteLotOccupancyOccupant", permissionHandlers.updatePostHandle router.post("/doAddLotOccupancyComment", permissionHandlers.updatePostHandler, handler_doAddLotOccupancyComment); router.post("/doUpdateLotOccupancyComment", permissionHandlers.updatePostHandler, handler_doUpdateLotOccupancyComment); router.post("/doDeleteLotOccupancyComment", permissionHandlers.updatePostHandler, handler_doDeleteLotOccupancyComment); +router.post("/doGetFees", permissionHandlers.updatePostHandler, handler_doGetFees); export default router; diff --git a/routes/lotOccupancies.ts b/routes/lotOccupancies.ts index c12be9d3..83fd2681 100644 --- a/routes/lotOccupancies.ts +++ b/routes/lotOccupancies.ts @@ -22,6 +22,8 @@ import handler_doAddLotOccupancyComment from "../handlers/lotOccupancies-post/do import handler_doUpdateLotOccupancyComment from "../handlers/lotOccupancies-post/doUpdateLotOccupancyComment.js"; import handler_doDeleteLotOccupancyComment from "../handlers/lotOccupancies-post/doDeleteLotOccupancyComment.js"; +import handler_doGetFees from "../handlers/lotOccupancies-post/doGetFees.js"; + import * as permissionHandlers from "../handlers/permissions.js"; @@ -92,5 +94,11 @@ router.post("/doDeleteLotOccupancyComment", permissionHandlers.updatePostHandler, handler_doDeleteLotOccupancyComment); +// Fees + +router.post("/doGetFees", + permissionHandlers.updatePostHandler, + handler_doGetFees); + export default router; \ No newline at end of file diff --git a/types/recordTypes.d.ts b/types/recordTypes.d.ts index 6290d728..03db39e7 100644 --- a/types/recordTypes.d.ts +++ b/types/recordTypes.d.ts @@ -171,6 +171,7 @@ export interface LotOccupancy extends Record { occupancyTypeId?: number; occupancyType?: string; lotId?: number; + lotTypeId?: number; lotName?: string; mapId?: number; mapName?: string; diff --git a/types/recordTypes.ts b/types/recordTypes.ts index 4f7cfd09..c773d68d 100644 --- a/types/recordTypes.ts +++ b/types/recordTypes.ts @@ -244,6 +244,7 @@ export interface LotOccupancy extends Record { occupancyType ? : string; lotId ? : number; + lotTypeId ? : number; lotName ? : string; mapId ? : number; diff --git a/views/lotOccupancy-edit.ejs b/views/lotOccupancy-edit.ejs index 3e7d836b..b08485dd 100644 --- a/views/lotOccupancy-edit.ejs +++ b/views/lotOccupancy-edit.ejs @@ -224,7 +224,22 @@
-

Fees

+
+
+
+

Fees

+
+
+
+
+ +
+
+
+

Transactions