diff --git a/handlers/admin-post/doMoveFeeCategoryDown.js b/handlers/admin-post/doMoveFeeCategoryDown.js index c671280a..44474bd2 100644 --- a/handlers/admin-post/doMoveFeeCategoryDown.js +++ b/handlers/admin-post/doMoveFeeCategoryDown.js @@ -1,7 +1,9 @@ -import { moveFeeCategoryDown } from "../../helpers/lotOccupancyDB/moveFeeCategoryDown.js"; +import { moveFeeCategoryDown, moveFeeCategoryDownToBottom } from "../../helpers/lotOccupancyDB/moveFeeCategoryDown.js"; import { getFeeCategories } from "../../helpers/lotOccupancyDB/getFeeCategories.js"; export const handler = async (request, response) => { - const success = moveFeeCategoryDown(request.body.feeCategoryId); + const success = request.body.moveToBottom === "1" + ? moveFeeCategoryDownToBottom(request.body.feeCategoryId) + : moveFeeCategoryDown(request.body.feeCategoryId); const feeCategories = getFeeCategories({}, { includeFees: true }); diff --git a/handlers/admin-post/doMoveFeeCategoryDown.ts b/handlers/admin-post/doMoveFeeCategoryDown.ts index 36d885ff..5b0e9ffa 100644 --- a/handlers/admin-post/doMoveFeeCategoryDown.ts +++ b/handlers/admin-post/doMoveFeeCategoryDown.ts @@ -1,11 +1,17 @@ import type { RequestHandler } from "express"; -import { moveFeeCategoryDown } from "../../helpers/lotOccupancyDB/moveFeeCategoryDown.js"; +import { + moveFeeCategoryDown, + moveFeeCategoryDownToBottom +} from "../../helpers/lotOccupancyDB/moveFeeCategoryDown.js"; import { getFeeCategories } from "../../helpers/lotOccupancyDB/getFeeCategories.js"; export const handler: RequestHandler = async (request, response) => { - const success = moveFeeCategoryDown(request.body.feeCategoryId); + const success = + request.body.moveToBottom === "1" + ? moveFeeCategoryDownToBottom(request.body.feeCategoryId) + : moveFeeCategoryDown(request.body.feeCategoryId); const feeCategories = getFeeCategories( {}, diff --git a/handlers/admin-post/doMoveFeeCategoryUp.js b/handlers/admin-post/doMoveFeeCategoryUp.js index 4a8844b4..0c1b3675 100644 --- a/handlers/admin-post/doMoveFeeCategoryUp.js +++ b/handlers/admin-post/doMoveFeeCategoryUp.js @@ -1,7 +1,9 @@ -import { moveFeeCategoryUp } from "../../helpers/lotOccupancyDB/moveFeeCategoryUp.js"; +import { moveFeeCategoryUp, moveFeeCategoryUpToTop } from "../../helpers/lotOccupancyDB/moveFeeCategoryUp.js"; import { getFeeCategories } from "../../helpers/lotOccupancyDB/getFeeCategories.js"; export const handler = async (request, response) => { - const success = moveFeeCategoryUp(request.body.feeCategoryId); + const success = request.body.moveToTop === "1" + ? moveFeeCategoryUpToTop(request.body.feeCategoryId) + : moveFeeCategoryUp(request.body.feeCategoryId); const feeCategories = getFeeCategories({}, { includeFees: true }); diff --git a/handlers/admin-post/doMoveFeeCategoryUp.ts b/handlers/admin-post/doMoveFeeCategoryUp.ts index ab5c485e..256337f2 100644 --- a/handlers/admin-post/doMoveFeeCategoryUp.ts +++ b/handlers/admin-post/doMoveFeeCategoryUp.ts @@ -1,11 +1,17 @@ import type { RequestHandler } from "express"; -import { moveFeeCategoryUp } from "../../helpers/lotOccupancyDB/moveFeeCategoryUp.js"; +import { + moveFeeCategoryUp, + moveFeeCategoryUpToTop +} from "../../helpers/lotOccupancyDB/moveFeeCategoryUp.js"; import { getFeeCategories } from "../../helpers/lotOccupancyDB/getFeeCategories.js"; export const handler: RequestHandler = async (request, response) => { - const success = moveFeeCategoryUp(request.body.feeCategoryId); + const success = + request.body.moveToTop === "1" + ? moveFeeCategoryUpToTop(request.body.feeCategoryId) + : moveFeeCategoryUp(request.body.feeCategoryId); const feeCategories = getFeeCategories( {}, diff --git a/handlers/admin-post/doMoveFeeDown.js b/handlers/admin-post/doMoveFeeDown.js index 43eb9839..0308accd 100644 --- a/handlers/admin-post/doMoveFeeDown.js +++ b/handlers/admin-post/doMoveFeeDown.js @@ -1,7 +1,9 @@ -import { moveFeeDown } from "../../helpers/lotOccupancyDB/moveFeeDown.js"; +import { moveFeeDown, moveFeeDownToBottom } from "../../helpers/lotOccupancyDB/moveFeeDown.js"; import { getFeeCategories } from "../../helpers/lotOccupancyDB/getFeeCategories.js"; export const handler = async (request, response) => { - const success = moveFeeDown(request.body.feeId); + const success = request.body.moveToBottom === "1" + ? moveFeeDownToBottom(request.body.feeId) + : moveFeeDown(request.body.feeId); const feeCategories = getFeeCategories({}, { includeFees: true }); diff --git a/handlers/admin-post/doMoveFeeDown.ts b/handlers/admin-post/doMoveFeeDown.ts index d1dcb369..5434e859 100644 --- a/handlers/admin-post/doMoveFeeDown.ts +++ b/handlers/admin-post/doMoveFeeDown.ts @@ -1,11 +1,14 @@ import type { RequestHandler } from "express"; -import { moveFeeDown } from "../../helpers/lotOccupancyDB/moveFeeDown.js"; +import { moveFeeDown, moveFeeDownToBottom } from "../../helpers/lotOccupancyDB/moveFeeDown.js"; import { getFeeCategories } from "../../helpers/lotOccupancyDB/getFeeCategories.js"; export const handler: RequestHandler = async (request, response) => { - const success = moveFeeDown(request.body.feeId); + const success = + request.body.moveToBottom === "1" + ? moveFeeDownToBottom(request.body.feeId) + : moveFeeDown(request.body.feeId); const feeCategories = getFeeCategories( {}, diff --git a/handlers/admin-post/doMoveFeeUp.js b/handlers/admin-post/doMoveFeeUp.js index d20042bc..b98ffc48 100644 --- a/handlers/admin-post/doMoveFeeUp.js +++ b/handlers/admin-post/doMoveFeeUp.js @@ -1,7 +1,9 @@ -import { moveFeeUp } from "../../helpers/lotOccupancyDB/moveFeeUp.js"; +import { moveFeeUp, moveFeeUpToTop } from "../../helpers/lotOccupancyDB/moveFeeUp.js"; import { getFeeCategories } from "../../helpers/lotOccupancyDB/getFeeCategories.js"; export const handler = async (request, response) => { - const success = moveFeeUp(request.body.feeId); + const success = request.body.moveToTop === "1" + ? moveFeeUpToTop(request.body.feeId) + : moveFeeUp(request.body.feeId); const feeCategories = getFeeCategories({}, { includeFees: true }); diff --git a/handlers/admin-post/doMoveFeeUp.ts b/handlers/admin-post/doMoveFeeUp.ts index 4e882ec8..8bf92f8b 100644 --- a/handlers/admin-post/doMoveFeeUp.ts +++ b/handlers/admin-post/doMoveFeeUp.ts @@ -1,11 +1,14 @@ import type { RequestHandler } from "express"; -import { moveFeeUp } from "../../helpers/lotOccupancyDB/moveFeeUp.js"; +import { moveFeeUp, moveFeeUpToTop } from "../../helpers/lotOccupancyDB/moveFeeUp.js"; import { getFeeCategories } from "../../helpers/lotOccupancyDB/getFeeCategories.js"; export const handler: RequestHandler = async (request, response) => { - const success = moveFeeUp(request.body.feeId); + const success = + request.body.moveToTop === "1" + ? moveFeeUpToTop(request.body.feeId) + : moveFeeUp(request.body.feeId); const feeCategories = getFeeCategories( {}, diff --git a/helpers/lotOccupancyDB/addFee.js b/helpers/lotOccupancyDB/addFee.js index 687dd3eb..09b6507a 100644 --- a/helpers/lotOccupancyDB/addFee.js +++ b/helpers/lotOccupancyDB/addFee.js @@ -14,7 +14,7 @@ export const addFee = (feeForm, requestSession) => { " recordCreate_userName, recordCreate_timeMillis," + " recordUpdate_userName, recordUpdate_timeMillis)" + " values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)") - .run(feeForm.feeCategoryId, feeForm.feeName, feeForm.feeDescription, feeForm.occupancyTypeId || undefined, feeForm.lotTypeId || undefined, feeForm.feeAmount || undefined, feeForm.feeFunction || undefined, feeForm.taxAmount || undefined, feeForm.taxPercentage || undefined, feeForm.includeQuantity ? 1 : 0, feeForm.quantityUnit, feeForm.isRequired ? 1 : 0, feeForm.orderNumber || 0, requestSession.user.userName, rightNowMillis, requestSession.user.userName, rightNowMillis); + .run(feeForm.feeCategoryId, feeForm.feeName, feeForm.feeDescription, feeForm.occupancyTypeId || undefined, feeForm.lotTypeId || undefined, feeForm.feeAmount || undefined, feeForm.feeFunction || undefined, feeForm.taxAmount || undefined, feeForm.taxPercentage || undefined, feeForm.includeQuantity ? 1 : 0, feeForm.quantityUnit, feeForm.isRequired ? 1 : 0, feeForm.orderNumber || -1, requestSession.user.userName, rightNowMillis, requestSession.user.userName, rightNowMillis); database.close(); return result.lastInsertRowid; }; diff --git a/helpers/lotOccupancyDB/addFee.ts b/helpers/lotOccupancyDB/addFee.ts index 5f3d91a2..345da39b 100644 --- a/helpers/lotOccupancyDB/addFee.ts +++ b/helpers/lotOccupancyDB/addFee.ts @@ -53,7 +53,7 @@ export const addFee = ( feeForm.includeQuantity ? 1 : 0, feeForm.quantityUnit, feeForm.isRequired ? 1 : 0, - feeForm.orderNumber || 0, + feeForm.orderNumber || -1, requestSession.user.userName, rightNowMillis, requestSession.user.userName, diff --git a/helpers/lotOccupancyDB/addFeeCategory.js b/helpers/lotOccupancyDB/addFeeCategory.js index 829ef786..7d2bd35e 100644 --- a/helpers/lotOccupancyDB/addFeeCategory.js +++ b/helpers/lotOccupancyDB/addFeeCategory.js @@ -9,7 +9,7 @@ export const addFeeCategory = (feeCategoryForm, requestSession) => { " recordCreate_userName, recordCreate_timeMillis," + " recordUpdate_userName, recordUpdate_timeMillis)" + " values (?, ?, ?, ?, ?, ?)") - .run(feeCategoryForm.feeCategory, feeCategoryForm.orderNumber || 0, requestSession.user.userName, rightNowMillis, requestSession.user.userName, rightNowMillis); + .run(feeCategoryForm.feeCategory, feeCategoryForm.orderNumber || -1, requestSession.user.userName, rightNowMillis, requestSession.user.userName, rightNowMillis); database.close(); return result.lastInsertRowid; }; diff --git a/helpers/lotOccupancyDB/addFeeCategory.ts b/helpers/lotOccupancyDB/addFeeCategory.ts index c19a9f17..1503e17e 100644 --- a/helpers/lotOccupancyDB/addFeeCategory.ts +++ b/helpers/lotOccupancyDB/addFeeCategory.ts @@ -26,7 +26,7 @@ export const addFeeCategory = ( ) .run( feeCategoryForm.feeCategory, - feeCategoryForm.orderNumber || 0, + feeCategoryForm.orderNumber || -1, requestSession.user.userName, rightNowMillis, requestSession.user.userName, diff --git a/helpers/lotOccupancyDB/getFee.d.ts b/helpers/lotOccupancyDB/getFee.d.ts index 51bff88e..066f6937 100644 --- a/helpers/lotOccupancyDB/getFee.d.ts +++ b/helpers/lotOccupancyDB/getFee.d.ts @@ -1,3 +1,4 @@ +import sqlite from "better-sqlite3"; import type * as recordTypes from "../../types/recordTypes"; -export declare const getFee: (feeId: number | string) => recordTypes.Fee; +export declare const getFee: (feeId: number | string, connectedDatabase?: sqlite.Database) => recordTypes.Fee; export default getFee; diff --git a/helpers/lotOccupancyDB/getFee.js b/helpers/lotOccupancyDB/getFee.js index d9e50047..032e9e3e 100644 --- a/helpers/lotOccupancyDB/getFee.js +++ b/helpers/lotOccupancyDB/getFee.js @@ -1,9 +1,10 @@ import sqlite from "better-sqlite3"; import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js"; -export const getFee = (feeId) => { - const database = sqlite(databasePath, { - readonly: true - }); +export const getFee = (feeId, connectedDatabase) => { + const database = connectedDatabase || + sqlite(databasePath, { + readonly: true + }); const fee = database .prepare("select f.feeId," + " f.feeCategoryId, c.feeCategory," + @@ -13,7 +14,7 @@ export const getFee = (feeId) => { " ifnull(f.feeAmount, 0) as feeAmount, f.feeFunction," + " f.taxAmount, f.taxPercentage," + " f.includeQuantity, f.quantityUnit," + - " f.isRequired" + + " f.isRequired, f.orderNumber" + " from Fees f" + " left join FeeCategories c on f.feeCategoryId = c.feeCategoryId" + " left join OccupancyTypes o on f.occupancyTypeId = o.occupancyTypeId" + @@ -21,7 +22,9 @@ export const getFee = (feeId) => { " where f.recordDelete_timeMillis is null" + " and f.feeId = ?") .get(feeId); - database.close(); + if (!connectedDatabase) { + database.close(); + } return fee; }; export default getFee; diff --git a/helpers/lotOccupancyDB/getFee.ts b/helpers/lotOccupancyDB/getFee.ts index 2de99911..402bc5c9 100644 --- a/helpers/lotOccupancyDB/getFee.ts +++ b/helpers/lotOccupancyDB/getFee.ts @@ -4,10 +4,15 @@ import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js"; import type * as recordTypes from "../../types/recordTypes"; -export const getFee = (feeId: number | string): recordTypes.Fee => { - const database = sqlite(databasePath, { - readonly: true - }); +export const getFee = ( + feeId: number | string, + connectedDatabase?: sqlite.Database +): recordTypes.Fee => { + const database = + connectedDatabase || + sqlite(databasePath, { + readonly: true + }); const fee = database .prepare( @@ -19,7 +24,7 @@ export const getFee = (feeId: number | string): recordTypes.Fee => { " ifnull(f.feeAmount, 0) as feeAmount, f.feeFunction," + " f.taxAmount, f.taxPercentage," + " f.includeQuantity, f.quantityUnit," + - " f.isRequired" + + " f.isRequired, f.orderNumber" + " from Fees f" + " left join FeeCategories c on f.feeCategoryId = c.feeCategoryId" + " left join OccupancyTypes o on f.occupancyTypeId = o.occupancyTypeId" + @@ -29,7 +34,9 @@ export const getFee = (feeId: number | string): recordTypes.Fee => { ) .get(feeId); - database.close(); + if (!connectedDatabase) { + database.close(); + } return fee; }; diff --git a/helpers/lotOccupancyDB/moveFeeCategoryDown.d.ts b/helpers/lotOccupancyDB/moveFeeCategoryDown.d.ts index e032c071..ad106d73 100644 --- a/helpers/lotOccupancyDB/moveFeeCategoryDown.d.ts +++ b/helpers/lotOccupancyDB/moveFeeCategoryDown.d.ts @@ -1,2 +1,3 @@ export declare const moveFeeCategoryDown: (feeCategoryId: number | string) => boolean; +export declare const moveFeeCategoryDownToBottom: (feeCategoryId: number | string) => boolean; export default moveFeeCategoryDown; diff --git a/helpers/lotOccupancyDB/moveFeeCategoryDown.js b/helpers/lotOccupancyDB/moveFeeCategoryDown.js index 86d24b51..a8cdd809 100644 --- a/helpers/lotOccupancyDB/moveFeeCategoryDown.js +++ b/helpers/lotOccupancyDB/moveFeeCategoryDown.js @@ -3,9 +3,7 @@ import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js"; export const moveFeeCategoryDown = (feeCategoryId) => { const database = sqlite(databasePath); const currentOrderNumber = database - .prepare("select orderNumber" + - " from FeeCategories" + - " where feeCategoryId = ?") + .prepare("select orderNumber from FeeCategories where feeCategoryId = ?") .get(feeCategoryId).orderNumber; database .prepare("update FeeCategories" + @@ -14,11 +12,33 @@ export const moveFeeCategoryDown = (feeCategoryId) => { " and orderNumber = ? + 1") .run(currentOrderNumber); const result = database - .prepare("update FeeCategories" + - " set orderNumber = ? + 1" + - " where feeCategoryId = ?") + .prepare("update FeeCategories set orderNumber = ? + 1 where feeCategoryId = ?") .run(currentOrderNumber, feeCategoryId); database.close(); return result.changes > 0; }; +export const moveFeeCategoryDownToBottom = (feeCategoryId) => { + const database = sqlite(databasePath); + const currentOrderNumber = database + .prepare("select orderNumber from FeeCategories where feeCategoryId = ?") + .get(feeCategoryId).orderNumber; + const maxOrderNumber = database + .prepare("select max(orderNumber) as maxOrderNumber" + + " from FeeCategories" + + " where recordDelete_timeMillis is null") + .get().maxOrderNumber; + if (currentOrderNumber !== maxOrderNumber) { + database + .prepare("update FeeCategories set orderNumber = ? + 1 where feeCategoryId = ?") + .run(maxOrderNumber, feeCategoryId); + database + .prepare("update FeeCategories" + + " set orderNumber = orderNumber - 1" + + " where recordDelete_timeMillis is null" + + " and orderNumber > ?") + .run(currentOrderNumber); + } + database.close(); + return true; +}; export default moveFeeCategoryDown; diff --git a/helpers/lotOccupancyDB/moveFeeCategoryDown.ts b/helpers/lotOccupancyDB/moveFeeCategoryDown.ts index 6c83b998..d1a1548f 100644 --- a/helpers/lotOccupancyDB/moveFeeCategoryDown.ts +++ b/helpers/lotOccupancyDB/moveFeeCategoryDown.ts @@ -2,17 +2,11 @@ import sqlite from "better-sqlite3"; import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js"; -export const moveFeeCategoryDown = ( - feeCategoryId: number | string -): boolean => { +export const moveFeeCategoryDown = (feeCategoryId: number | string): boolean => { const database = sqlite(databasePath); const currentOrderNumber: number = database - .prepare( - "select orderNumber" + - " from FeeCategories" + - " where feeCategoryId = ?" - ) + .prepare("select orderNumber from FeeCategories where feeCategoryId = ?") .get(feeCategoryId).orderNumber; database @@ -25,11 +19,7 @@ export const moveFeeCategoryDown = ( .run(currentOrderNumber); const result = database - .prepare( - "update FeeCategories" + - " set orderNumber = ? + 1" + - " where feeCategoryId = ?" - ) + .prepare("update FeeCategories set orderNumber = ? + 1 where feeCategoryId = ?") .run(currentOrderNumber, feeCategoryId); database.close(); @@ -37,4 +27,39 @@ export const moveFeeCategoryDown = ( return result.changes > 0; }; +export const moveFeeCategoryDownToBottom = (feeCategoryId: number | string): boolean => { + const database = sqlite(databasePath); + + const currentOrderNumber: number = database + .prepare("select orderNumber from FeeCategories where feeCategoryId = ?") + .get(feeCategoryId).orderNumber; + + const maxOrderNumber: number = database + .prepare( + "select max(orderNumber) as maxOrderNumber" + + " from FeeCategories" + + " where recordDelete_timeMillis is null" + ) + .get().maxOrderNumber; + + if (currentOrderNumber !== maxOrderNumber) { + database + .prepare("update FeeCategories set orderNumber = ? + 1 where feeCategoryId = ?") + .run(maxOrderNumber, feeCategoryId); + + database + .prepare( + "update FeeCategories" + + " set orderNumber = orderNumber - 1" + + " where recordDelete_timeMillis is null" + + " and orderNumber > ?" + ) + .run(currentOrderNumber); + } + + database.close(); + + return true; +}; + export default moveFeeCategoryDown; diff --git a/helpers/lotOccupancyDB/moveFeeCategoryUp.d.ts b/helpers/lotOccupancyDB/moveFeeCategoryUp.d.ts index 87edbda2..d1389eca 100644 --- a/helpers/lotOccupancyDB/moveFeeCategoryUp.d.ts +++ b/helpers/lotOccupancyDB/moveFeeCategoryUp.d.ts @@ -1,2 +1,3 @@ export declare const moveFeeCategoryUp: (feeCategoryId: number | string) => boolean; +export declare const moveFeeCategoryUpToTop: (feeCategoryId: number | string) => boolean; export default moveFeeCategoryUp; diff --git a/helpers/lotOccupancyDB/moveFeeCategoryUp.js b/helpers/lotOccupancyDB/moveFeeCategoryUp.js index a3fb7bc1..9012f7b0 100644 --- a/helpers/lotOccupancyDB/moveFeeCategoryUp.js +++ b/helpers/lotOccupancyDB/moveFeeCategoryUp.js @@ -3,9 +3,7 @@ import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js"; export const moveFeeCategoryUp = (feeCategoryId) => { const database = sqlite(databasePath); const currentOrderNumber = database - .prepare("select orderNumber" + - " from FeeCategories" + - " where feeCategoryId = ?") + .prepare("select orderNumber from FeeCategories where feeCategoryId = ?") .get(feeCategoryId).orderNumber; if (currentOrderNumber <= 0) { database.close(); @@ -18,11 +16,28 @@ export const moveFeeCategoryUp = (feeCategoryId) => { " and orderNumber = ? - 1") .run(currentOrderNumber); const result = database - .prepare("update FeeCategories" + - " set orderNumber = ? - 1" + - " where feeCategoryId = ?") + .prepare("update FeeCategories set orderNumber = ? - 1 where feeCategoryId = ?") .run(currentOrderNumber, feeCategoryId); database.close(); return result.changes > 0; }; +export const moveFeeCategoryUpToTop = (feeCategoryId) => { + const database = sqlite(databasePath); + const currentOrderNumber = database + .prepare("select orderNumber from FeeCategories where feeCategoryId = ?") + .get(feeCategoryId).orderNumber; + if (currentOrderNumber > 0) { + database + .prepare("update FeeCategories set orderNumber = -1 where feeCategoryId = ?") + .run(feeCategoryId); + database + .prepare("update FeeCategories" + + " set orderNumber = orderNumber + 1" + + " where recordDelete_timeMillis is null" + + " and orderNumber < ?") + .run(currentOrderNumber); + } + database.close(); + return true; +}; export default moveFeeCategoryUp; diff --git a/helpers/lotOccupancyDB/moveFeeCategoryUp.ts b/helpers/lotOccupancyDB/moveFeeCategoryUp.ts index fbdfff6f..1ca0df6d 100644 --- a/helpers/lotOccupancyDB/moveFeeCategoryUp.ts +++ b/helpers/lotOccupancyDB/moveFeeCategoryUp.ts @@ -6,11 +6,7 @@ export const moveFeeCategoryUp = (feeCategoryId: number | string): boolean => { const database = sqlite(databasePath); const currentOrderNumber: number = database - .prepare( - "select orderNumber" + - " from FeeCategories" + - " where feeCategoryId = ?" - ) + .prepare("select orderNumber from FeeCategories where feeCategoryId = ?") .get(feeCategoryId).orderNumber; if (currentOrderNumber <= 0) { @@ -28,11 +24,7 @@ export const moveFeeCategoryUp = (feeCategoryId: number | string): boolean => { .run(currentOrderNumber); const result = database - .prepare( - "update FeeCategories" + - " set orderNumber = ? - 1" + - " where feeCategoryId = ?" - ) + .prepare("update FeeCategories set orderNumber = ? - 1 where feeCategoryId = ?") .run(currentOrderNumber, feeCategoryId); database.close(); @@ -40,4 +32,31 @@ export const moveFeeCategoryUp = (feeCategoryId: number | string): boolean => { return result.changes > 0; }; +export const moveFeeCategoryUpToTop = (feeCategoryId: number | string): boolean => { + const database = sqlite(databasePath); + + const currentOrderNumber: number = database + .prepare("select orderNumber from FeeCategories where feeCategoryId = ?") + .get(feeCategoryId).orderNumber; + + if (currentOrderNumber > 0) { + database + .prepare("update FeeCategories set orderNumber = -1 where feeCategoryId = ?") + .run(feeCategoryId); + + database + .prepare( + "update FeeCategories" + + " set orderNumber = orderNumber + 1" + + " where recordDelete_timeMillis is null" + + " and orderNumber < ?" + ) + .run(currentOrderNumber); + } + + database.close(); + + return true; +}; + export default moveFeeCategoryUp; diff --git a/helpers/lotOccupancyDB/moveFeeDown.d.ts b/helpers/lotOccupancyDB/moveFeeDown.d.ts index 26c37023..8743aed8 100644 --- a/helpers/lotOccupancyDB/moveFeeDown.d.ts +++ b/helpers/lotOccupancyDB/moveFeeDown.d.ts @@ -1,2 +1,3 @@ export declare const moveFeeDown: (feeId: number | string) => boolean; +export declare const moveFeeDownToBottom: (feeId: number | string) => boolean; export default moveFeeDown; diff --git a/helpers/lotOccupancyDB/moveFeeDown.js b/helpers/lotOccupancyDB/moveFeeDown.js index 38b3769d..ff09a095 100644 --- a/helpers/lotOccupancyDB/moveFeeDown.js +++ b/helpers/lotOccupancyDB/moveFeeDown.js @@ -1,20 +1,44 @@ import sqlite from "better-sqlite3"; import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js"; +import { getFee } from "./getFee.js"; export const moveFeeDown = (feeId) => { const database = sqlite(databasePath); - const currentOrderNumber = database - .prepare("select orderNumber" + " from Fees" + " where feeId = ?") - .get(feeId).orderNumber; + const currentFee = getFee(feeId, database); database .prepare("update Fees" + " set orderNumber = orderNumber - 1" + " where recordDelete_timeMillis is null" + + " and feeCategoryId = ?" + " and orderNumber = ? + 1") - .run(currentOrderNumber); + .run(currentFee.feeCategoryId, currentFee.orderNumber); const result = database - .prepare("update Fees" + " set orderNumber = ? + 1" + " where feeId = ?") - .run(currentOrderNumber, feeId); + .prepare("update Fees set orderNumber = ? + 1 where feeId = ?") + .run(currentFee.orderNumber, feeId); database.close(); return result.changes > 0; }; +export const moveFeeDownToBottom = (feeId) => { + const database = sqlite(databasePath); + const currentFee = getFee(feeId, database); + const maxOrderNumber = database + .prepare("select max(orderNumber) as maxOrderNumber" + + " from Fees" + + " where recordDelete_timeMillis is null" + + " and feeCategoryId = ?") + .get(currentFee.feeCategoryId).maxOrderNumber; + if (currentFee.orderNumber !== maxOrderNumber) { + database + .prepare("update Fees set orderNumber = ? + 1 where feeId = ?") + .run(maxOrderNumber, feeId); + database + .prepare("update Fees" + + " set orderNumber = orderNumber - 1" + + " where recordDelete_timeMillis is null" + + " and feeCategoryId = ?" + + " and orderNumber > ?") + .run(currentFee.feeCategoryId, currentFee.orderNumber); + } + database.close(); + return true; +}; export default moveFeeDown; diff --git a/helpers/lotOccupancyDB/moveFeeDown.ts b/helpers/lotOccupancyDB/moveFeeDown.ts index 3ddbd53b..19544477 100644 --- a/helpers/lotOccupancyDB/moveFeeDown.ts +++ b/helpers/lotOccupancyDB/moveFeeDown.ts @@ -2,31 +2,65 @@ import sqlite from "better-sqlite3"; import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js"; +import { getFee } from "./getFee.js"; + export const moveFeeDown = (feeId: number | string): boolean => { const database = sqlite(databasePath); - const currentOrderNumber: number = database - .prepare("select orderNumber" + " from Fees" + " where feeId = ?") - .get(feeId).orderNumber; + const currentFee = getFee(feeId, database); database .prepare( "update Fees" + " set orderNumber = orderNumber - 1" + " where recordDelete_timeMillis is null" + + " and feeCategoryId = ?" + " and orderNumber = ? + 1" ) - .run(currentOrderNumber); + .run(currentFee.feeCategoryId, currentFee.orderNumber); const result = database - .prepare( - "update Fees" + " set orderNumber = ? + 1" + " where feeId = ?" - ) - .run(currentOrderNumber, feeId); + .prepare("update Fees set orderNumber = ? + 1 where feeId = ?") + .run(currentFee.orderNumber, feeId); database.close(); return result.changes > 0; }; +export const moveFeeDownToBottom = (feeId: number | string): boolean => { + const database = sqlite(databasePath); + + const currentFee = getFee(feeId, database); + + const maxOrderNumber: number = database + .prepare( + "select max(orderNumber) as maxOrderNumber" + + " from Fees" + + " where recordDelete_timeMillis is null" + + " and feeCategoryId = ?" + ) + .get(currentFee.feeCategoryId).maxOrderNumber; + + if (currentFee.orderNumber !== maxOrderNumber) { + database + .prepare("update Fees set orderNumber = ? + 1 where feeId = ?") + .run(maxOrderNumber, feeId); + + database + .prepare( + "update Fees" + + " set orderNumber = orderNumber - 1" + + " where recordDelete_timeMillis is null" + + " and feeCategoryId = ?" + + " and orderNumber > ?" + ) + .run(currentFee.feeCategoryId, currentFee.orderNumber); + } + + database.close(); + + return true; +}; + export default moveFeeDown; diff --git a/helpers/lotOccupancyDB/moveFeeUp.d.ts b/helpers/lotOccupancyDB/moveFeeUp.d.ts index 1e7c0999..9d14c129 100644 --- a/helpers/lotOccupancyDB/moveFeeUp.d.ts +++ b/helpers/lotOccupancyDB/moveFeeUp.d.ts @@ -1,2 +1,3 @@ export declare const moveFeeUp: (feeId: number | string) => boolean; +export declare const moveFeeUpToTop: (feeId: number | string) => boolean; export default moveFeeUp; diff --git a/helpers/lotOccupancyDB/moveFeeUp.js b/helpers/lotOccupancyDB/moveFeeUp.js index 47ead832..fe11c013 100644 --- a/helpers/lotOccupancyDB/moveFeeUp.js +++ b/helpers/lotOccupancyDB/moveFeeUp.js @@ -1,11 +1,10 @@ import sqlite from "better-sqlite3"; import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js"; +import { getFee } from "./getFee.js"; export const moveFeeUp = (feeId) => { const database = sqlite(databasePath); - const currentOrderNumber = database - .prepare("select orderNumber" + " from Fees" + " where feeId = ?") - .get(feeId).orderNumber; - if (currentOrderNumber <= 0) { + const currentFee = getFee(feeId, database); + if (currentFee.orderNumber <= 0) { database.close(); return true; } @@ -13,12 +12,29 @@ export const moveFeeUp = (feeId) => { .prepare("update Fees" + " set orderNumber = orderNumber + 1" + " where recordDelete_timeMillis is null" + + " and feeCategoryId = ?" + " and orderNumber = ? - 1") - .run(currentOrderNumber); + .run(currentFee.feeCategoryId, currentFee.orderNumber); const result = database - .prepare("update Fees" + " set orderNumber = ? - 1" + " where feeId = ?") - .run(currentOrderNumber, feeId); + .prepare("update Fees set orderNumber = ? - 1 where feeId = ?") + .run(currentFee.orderNumber, feeId); database.close(); return result.changes > 0; }; +export const moveFeeUpToTop = (feeId) => { + const database = sqlite(databasePath); + const currentFee = getFee(feeId, database); + if (currentFee.orderNumber > 0) { + database.prepare("update Fees set orderNumber = -1 where feeId = ?").run(feeId); + database + .prepare("update Fees" + + " set orderNumber = orderNumber + 1" + + " where recordDelete_timeMillis is null" + + " and feeCategoryId = ?" + + " and orderNumber < ?") + .run(currentFee.feeCategoryId, currentFee.orderNumber); + } + database.close(); + return true; +}; export default moveFeeUp; diff --git a/helpers/lotOccupancyDB/moveFeeUp.ts b/helpers/lotOccupancyDB/moveFeeUp.ts index 02849bba..19229d7b 100644 --- a/helpers/lotOccupancyDB/moveFeeUp.ts +++ b/helpers/lotOccupancyDB/moveFeeUp.ts @@ -2,14 +2,14 @@ import sqlite from "better-sqlite3"; import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js"; +import { getFee } from "./getFee.js"; + export const moveFeeUp = (feeId: number | string): boolean => { const database = sqlite(databasePath); - const currentOrderNumber: number = database - .prepare("select orderNumber" + " from Fees" + " where feeId = ?") - .get(feeId).orderNumber; + const currentFee = getFee(feeId, database); - if (currentOrderNumber <= 0) { + if (currentFee.orderNumber <= 0) { database.close(); return true; } @@ -19,19 +19,42 @@ export const moveFeeUp = (feeId: number | string): boolean => { "update Fees" + " set orderNumber = orderNumber + 1" + " where recordDelete_timeMillis is null" + + " and feeCategoryId = ?" + " and orderNumber = ? - 1" ) - .run(currentOrderNumber); + .run(currentFee.feeCategoryId, currentFee.orderNumber); const result = database - .prepare( - "update Fees" + " set orderNumber = ? - 1" + " where feeId = ?" - ) - .run(currentOrderNumber, feeId); + .prepare("update Fees set orderNumber = ? - 1 where feeId = ?") + .run(currentFee.orderNumber, feeId); database.close(); return result.changes > 0; }; +export const moveFeeUpToTop = (feeId: number | string): boolean => { + const database = sqlite(databasePath); + + const currentFee = getFee(feeId, database); + + if (currentFee.orderNumber > 0) { + database.prepare("update Fees set orderNumber = -1 where feeId = ?").run(feeId); + + database + .prepare( + "update Fees" + + " set orderNumber = orderNumber + 1" + + " where recordDelete_timeMillis is null" + + " and feeCategoryId = ?" + + " and orderNumber < ?" + ) + .run(currentFee.feeCategoryId, currentFee.orderNumber); + } + + database.close(); + + return true; +}; + export default moveFeeUp; diff --git a/helpers/lotOccupancyDB/moveLotTypeFieldUp.js b/helpers/lotOccupancyDB/moveLotTypeFieldUp.js index b9f61628..0878c04a 100644 --- a/helpers/lotOccupancyDB/moveLotTypeFieldUp.js +++ b/helpers/lotOccupancyDB/moveLotTypeFieldUp.js @@ -4,7 +4,7 @@ import { clearLotTypesCache } from "../functions.cache.js"; export const moveLotTypeFieldUp = (lotTypeFieldId) => { const database = sqlite(databasePath); const currentField = database - .prepare("select lotTypeId, orderNumber" + " from LotTypeFields" + " where lotTypeFieldId = ?") + .prepare("select lotTypeId, orderNumber from LotTypeFields where lotTypeFieldId = ?") .get(lotTypeFieldId); if (currentField.orderNumber <= 0) { database.close(); @@ -18,7 +18,7 @@ export const moveLotTypeFieldUp = (lotTypeFieldId) => { " and orderNumber = ? - 1") .run(currentField.lotTypeId, currentField.orderNumber); const result = database - .prepare("update LotTypeFields" + " set orderNumber = ? - 1" + " where lotTypeFieldId = ?") + .prepare("update LotTypeFields set orderNumber = ? - 1 where lotTypeFieldId = ?") .run(currentField.orderNumber, lotTypeFieldId); database.close(); clearLotTypesCache(); diff --git a/helpers/lotOccupancyDB/moveLotTypeFieldUp.ts b/helpers/lotOccupancyDB/moveLotTypeFieldUp.ts index 402945d7..a35c7a12 100644 --- a/helpers/lotOccupancyDB/moveLotTypeFieldUp.ts +++ b/helpers/lotOccupancyDB/moveLotTypeFieldUp.ts @@ -8,9 +8,7 @@ export const moveLotTypeFieldUp = (lotTypeFieldId: number | string): boolean => const database = sqlite(databasePath); const currentField: { lotTypeId: number; orderNumber: number } = database - .prepare( - "select lotTypeId, orderNumber" + " from LotTypeFields" + " where lotTypeFieldId = ?" - ) + .prepare("select lotTypeId, orderNumber from LotTypeFields where lotTypeFieldId = ?") .get(lotTypeFieldId); if (currentField.orderNumber <= 0) { @@ -29,7 +27,7 @@ export const moveLotTypeFieldUp = (lotTypeFieldId: number | string): boolean => .run(currentField.lotTypeId, currentField.orderNumber); const result = database - .prepare("update LotTypeFields" + " set orderNumber = ? - 1" + " where lotTypeFieldId = ?") + .prepare("update LotTypeFields set orderNumber = ? - 1 where lotTypeFieldId = ?") .run(currentField.orderNumber, lotTypeFieldId); database.close(); diff --git a/public-typescript/adminFees.js b/public-typescript/adminFees.js index 34f1aba7..cf817456 100644 --- a/public-typescript/adminFees.js +++ b/public-typescript/adminFees.js @@ -17,42 +17,40 @@ Object.defineProperty(exports, "__esModule", { value: true }); feeCategoriesContainerElement.innerHTML = ""; for (const feeCategory of feeCategories) { const feeCategoryContainerElement = document.createElement("section"); - feeCategoryContainerElement.className = - "panel container--feeCategory"; + feeCategoryContainerElement.className = "panel container--feeCategory"; feeCategoryContainerElement.dataset.feeCategoryId = feeCategory.feeCategoryId.toString(); feeCategoryContainerElement.innerHTML = '
' + - '
' + - ('
' + - '
' + + '
' + + ('
' + '

' + cityssm.escapeHTML(feeCategory.feeCategory) + "

" + - "
" + "
") + - ('
' + + ('
' + + '
' + (feeCategory.fees.length === 0 - ? '
' + + ? '
' + '" + "
" : "") + - ('
' + + ('
' + '" + "
") + - ('
' + + ('
' + '" + "
") + - ('
' + + ('
' + '
' + '
' + '
" + "
") + "
"; - panelBlockElement - .querySelector("a") - .addEventListener("click", openEditFee); + panelBlockElement.querySelector("a").addEventListener("click", openEditFee); panelBlockElement .querySelector(".button--moveFeeUp") .addEventListener("click", moveFeeUp); @@ -187,9 +182,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); feeCategoriesContainerElement.append(feeCategoryContainerElement); } }; - document - .querySelector("#button--addFeeCategory") - .addEventListener("click", () => { + document.querySelector("#button--addFeeCategory").addEventListener("click", () => { let addCloseModalFunction; const doAddFeeCategory = (submitEvent) => { submitEvent.preventDefault(); @@ -213,9 +206,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); bulmaJS.toggleHtmlClipped(); modalElement.querySelector("#feeCategoryAdd--feeCategory").focus(); addCloseModalFunction = closeModalFunction; - modalElement - .querySelector("form") - .addEventListener("submit", doAddFeeCategory); + modalElement.querySelector("form").addEventListener("submit", doAddFeeCategory); }, onremoved: () => { bulmaJS.toggleHtmlClipped(); @@ -253,9 +244,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); onshown: (modalElement, closeModalFunction) => { bulmaJS.toggleHtmlClipped(); editCloseModalFunction = closeModalFunction; - modalElement - .querySelector("form") - .addEventListener("submit", doUpdateFeeCategory); + modalElement.querySelector("form").addEventListener("submit", doUpdateFeeCategory); modalElement.querySelector("#feeCategoryEdit--feeCategory").focus(); }, onremoved: () => { @@ -295,7 +284,8 @@ Object.defineProperty(exports, "__esModule", { value: true }); const moveFeeCategoryUp = (clickEvent) => { const feeCategoryId = Number.parseInt(clickEvent.currentTarget.closest(".container--feeCategory").dataset.feeCategoryId, 10); cityssm.postJSON(urlPrefix + "/admin/doMoveFeeCategoryUp", { - feeCategoryId + feeCategoryId, + moveToTop: clickEvent.shiftKey ? "1" : "0" }, (responseJSON) => { if (responseJSON.success) { feeCategories = responseJSON.feeCategories; @@ -313,7 +303,8 @@ Object.defineProperty(exports, "__esModule", { value: true }); const moveFeeCategoryDown = (clickEvent) => { const feeCategoryId = Number.parseInt(clickEvent.currentTarget.closest(".container--feeCategory").dataset.feeCategoryId, 10); cityssm.postJSON(urlPrefix + "/admin/doMoveFeeCategoryDown", { - feeCategoryId + feeCategoryId, + moveToBottom: clickEvent.shiftKey ? "1" : "0" }, (responseJSON) => { if (responseJSON.success) { feeCategories = responseJSON.feeCategories; @@ -363,8 +354,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); const occupancyTypeElement = modalElement.querySelector("#feeAdd--occupancyTypeId"); for (const occupancyType of exports.occupancyTypes) { const optionElement = document.createElement("option"); - optionElement.value = - occupancyType.occupancyTypeId.toString(); + optionElement.value = occupancyType.occupancyTypeId.toString(); optionElement.textContent = occupancyType.occupancyType; occupancyTypeElement.append(optionElement); } @@ -381,9 +371,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); onshown: (modalElement, closeModalFunction) => { bulmaJS.toggleHtmlClipped(); addCloseModalFunction = closeModalFunction; - modalElement - .querySelector("form") - .addEventListener("submit", doAddFee); + modalElement.querySelector("form").addEventListener("submit", doAddFee); modalElement.querySelector("#feeAdd--feeName").focus(); modalElement .querySelector("#feeAdd--feeFunction") @@ -391,16 +379,12 @@ Object.defineProperty(exports, "__esModule", { value: true }); const feeAmountElement = modalElement.querySelector("#feeAdd--feeAmount"); const feeFunctionElement = modalElement.querySelector("#feeAdd--feeFunction"); if (feeFunctionElement.value === "") { - feeFunctionElement - .closest(".select") - .classList.remove("is-success"); + feeFunctionElement.closest(".select").classList.remove("is-success"); feeAmountElement.classList.add("is-success"); feeAmountElement.disabled = false; } else { - feeFunctionElement - .closest(".select") - .classList.add("is-success"); + feeFunctionElement.closest(".select").classList.add("is-success"); feeAmountElement.classList.remove("is-success"); feeAmountElement.disabled = true; } @@ -437,7 +421,8 @@ Object.defineProperty(exports, "__esModule", { value: true }); clickEvent.preventDefault(); const feeContainerElement = clickEvent.currentTarget.closest(".container--fee"); const feeId = Number.parseInt(feeContainerElement.dataset.feeId, 10); - const feeCategoryId = Number.parseInt(feeContainerElement.closest(".container--feeCategory").dataset.feeCategoryId); + const feeCategoryId = Number.parseInt(feeContainerElement.closest(".container--feeCategory").dataset + .feeCategoryId); const feeCategory = feeCategories.find((currentFeeCategory) => { return currentFeeCategory.feeCategoryId === feeCategoryId; }); @@ -497,16 +482,12 @@ Object.defineProperty(exports, "__esModule", { value: true }); const feeAmountElement = editModalElement.querySelector("#feeEdit--feeAmount"); const feeFunctionElement = editModalElement.querySelector("#feeEdit--feeFunction"); if (feeFunctionElement.value === "") { - feeFunctionElement - .closest(".select") - .classList.remove("is-success"); + feeFunctionElement.closest(".select").classList.remove("is-success"); feeAmountElement.classList.add("is-success"); feeAmountElement.disabled = false; } else { - feeFunctionElement - .closest(".select") - .classList.add("is-success"); + feeFunctionElement.closest(".select").classList.add("is-success"); feeAmountElement.classList.remove("is-success"); feeAmountElement.disabled = true; } @@ -527,12 +508,14 @@ Object.defineProperty(exports, "__esModule", { value: true }); }; const toggleQuantityFields = () => { editModalElement.querySelector("#feeEdit--quantityUnit").disabled = - editModalElement.querySelector("#feeEdit--includeQuantity").value === ""; + editModalElement.querySelector("#feeEdit--includeQuantity") + .value === ""; }; cityssm.openHtmlModal("adminFees-editFee", { onshow: (modalElement) => { editModalElement = modalElement; - modalElement.querySelector("#feeEdit--feeId").value = fee.feeId.toString(); + modalElement.querySelector("#feeEdit--feeId").value = + fee.feeId.toString(); const feeCategoryElement = modalElement.querySelector("#feeEdit--feeCategoryId"); for (const feeCategory of feeCategories) { const optionElement = document.createElement("option"); @@ -543,13 +526,13 @@ Object.defineProperty(exports, "__esModule", { value: true }); } feeCategoryElement.append(optionElement); } - modalElement.querySelector("#feeEdit--feeName").value = fee.feeName; + modalElement.querySelector("#feeEdit--feeName").value = + fee.feeName; modalElement.querySelector("#feeEdit--feeDescription").value = fee.feeDescription; const occupancyTypeElement = modalElement.querySelector("#feeEdit--occupancyTypeId"); for (const occupancyType of exports.occupancyTypes) { const optionElement = document.createElement("option"); - optionElement.value = - occupancyType.occupancyTypeId.toString(); + optionElement.value = occupancyType.occupancyTypeId.toString(); optionElement.textContent = occupancyType.occupancyType; if (occupancyType.occupancyTypeId === fee.occupancyTypeId) { optionElement.selected = true; @@ -566,16 +549,16 @@ Object.defineProperty(exports, "__esModule", { value: true }); } lotTypeElement.append(optionElement); } - modalElement.querySelector("#feeEdit--feeAmount").value = fee.feeAmount ? fee.feeAmount.toFixed(2) : ""; + modalElement.querySelector("#feeEdit--feeAmount").value = + fee.feeAmount ? fee.feeAmount.toFixed(2) : ""; modalElement .querySelector("#feeEdit--feeFunction") .addEventListener("change", toggleFeeFields); toggleFeeFields(); - modalElement.querySelector("#feeEdit--taxAmount").value = fee.taxAmount ? fee.taxAmount.toFixed(2) : ""; + modalElement.querySelector("#feeEdit--taxAmount").value = + fee.taxAmount ? fee.taxAmount.toFixed(2) : ""; const taxPercentageElement = modalElement.querySelector("#feeEdit--taxPercentage"); - taxPercentageElement.value = fee.taxPercentage - ? fee.taxPercentage.toString() - : ""; + taxPercentageElement.value = fee.taxPercentage ? fee.taxPercentage.toString() : ""; taxPercentageElement.addEventListener("keyup", toggleTaxFields); toggleTaxFields(); const includeQuantityElement = modalElement.querySelector("#feeEdit--includeQuantity"); @@ -583,7 +566,8 @@ Object.defineProperty(exports, "__esModule", { value: true }); includeQuantityElement.value = "1"; } includeQuantityElement.addEventListener("change", toggleQuantityFields); - modalElement.querySelector("#feeEdit--quantityUnit").value = fee.quantityUnit || ""; + modalElement.querySelector("#feeEdit--quantityUnit").value = + fee.quantityUnit || ""; toggleQuantityFields(); if (fee.isRequired) { modalElement.querySelector("#feeEdit--isRequired").value = "1"; @@ -593,9 +577,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); onshown: (modalElement, closeModalFunction) => { bulmaJS.toggleHtmlClipped(); editCloseModalFunction = closeModalFunction; - modalElement - .querySelector("form") - .addEventListener("submit", doUpdateFee); + modalElement.querySelector("form").addEventListener("submit", doUpdateFee); bulmaJS.init(modalElement); modalElement .querySelector(".button--deleteFee") @@ -610,7 +592,8 @@ Object.defineProperty(exports, "__esModule", { value: true }); const feeContainerElement = clickEvent.currentTarget.closest(".container--fee"); const feeId = Number.parseInt(feeContainerElement.dataset.feeId, 10); cityssm.postJSON(urlPrefix + "/admin/doMoveFeeUp", { - feeId + feeId, + moveToTop: clickEvent.shiftKey ? "1" : "0" }, (responseJSON) => { if (responseJSON.success) { feeCategories = responseJSON.feeCategories; @@ -629,7 +612,8 @@ Object.defineProperty(exports, "__esModule", { value: true }); const feeContainerElement = clickEvent.currentTarget.closest(".container--fee"); const feeId = Number.parseInt(feeContainerElement.dataset.feeId, 10); cityssm.postJSON(urlPrefix + "/admin/doMoveFeeDown", { - feeId + feeId, + moveToBottom: clickEvent.shiftKey ? "1" : "0" }, (responseJSON) => { if (responseJSON.success) { feeCategories = responseJSON.feeCategories; diff --git a/public-typescript/adminFees.ts b/public-typescript/adminFees.ts index 1ead6696..ec552028 100644 --- a/public-typescript/adminFees.ts +++ b/public-typescript/adminFees.ts @@ -35,47 +35,44 @@ declare const bulmaJS: BulmaJS; feeCategoriesContainerElement.innerHTML = ""; for (const feeCategory of feeCategories) { - const feeCategoryContainerElement = - document.createElement("section"); + const feeCategoryContainerElement = document.createElement("section"); - feeCategoryContainerElement.className = - "panel container--feeCategory"; + feeCategoryContainerElement.className = "panel container--feeCategory"; feeCategoryContainerElement.dataset.feeCategoryId = feeCategory.feeCategoryId.toString(); feeCategoryContainerElement.innerHTML = '
' + - '
' + - ('
' + - '
' + + '
' + + ('
' + '

' + cityssm.escapeHTML(feeCategory.feeCategory) + "

" + - "
" + "
") + - ('
' + + ('
' + + '
' + (feeCategory.fees.length === 0 - ? '
' + + ? '
' + '" + "
" : "") + - ('
' + + ('
' + '" + "
") + - ('
' + + ('
' + '" + "
") + - ('
' + + ('
' + '
' + '
' + '
") + - ('
' + - (fee.feeFunction - ? cityssm.escapeHTML(fee.feeFunction) + - "
" + - "Fee Function" - : "$" + - fee.feeAmount.toFixed(2) + - "
" + - "Fee") + - "
") + - ('
' + - (fee.taxPercentage - ? fee.taxPercentage + "%" - : "$" + fee.taxAmount.toFixed(2)) + - "
Tax" + - "
") + - ('
' + - (fee.includeQuantity - ? cityssm.escapeHTML(fee.quantityUnit) + - "
" + - "Quantity" - : "") + + ('
' + + '
' + + ('
' + + (fee.feeFunction + ? cityssm.escapeHTML(fee.feeFunction) + + "
" + + "Fee Function" + : "$" + + fee.feeAmount.toFixed(2) + + "
" + + "Fee") + + "
") + + ('
' + + (fee.taxPercentage + ? fee.taxPercentage + "%" + : "$" + fee.taxAmount.toFixed(2)) + + "
Tax" + + "
") + + ('
' + + (fee.includeQuantity + ? cityssm.escapeHTML(fee.quantityUnit) + + "
" + + "Quantity" + : "") + + "
") + + "
" + "
") + ('
' + - '
' + + '
' + '
' + '
") + "
"; - panelBlockElement - .querySelector("a") - .addEventListener("click", openEditFee); + panelBlockElement.querySelector("a").addEventListener("click", openEditFee); panelBlockElement .querySelector(".button--moveFeeUp") @@ -230,56 +222,50 @@ declare const bulmaJS: BulmaJS; * Fee Categories */ - document - .querySelector("#button--addFeeCategory") - .addEventListener("click", () => { - let addCloseModalFunction: () => void; + document.querySelector("#button--addFeeCategory").addEventListener("click", () => { + let addCloseModalFunction: () => void; - const doAddFeeCategory = (submitEvent: SubmitEvent) => { - submitEvent.preventDefault(); + const doAddFeeCategory = (submitEvent: SubmitEvent) => { + submitEvent.preventDefault(); - cityssm.postJSON( - urlPrefix + "/admin/doAddFeeCategory", - submitEvent.currentTarget, - (responseJSON: { - success: boolean; - errorMessage?: string; - feeCategories: recordTypes.FeeCategory[]; - }) => { - if (responseJSON.success) { - feeCategories = responseJSON.feeCategories; - addCloseModalFunction(); - renderFeeCategories(); - } else { - bulmaJS.alert({ - title: "Error Creating Fee Category", - message: responseJSON.errorMessage, - contextualColorName: "danger" - }); - } + cityssm.postJSON( + urlPrefix + "/admin/doAddFeeCategory", + submitEvent.currentTarget, + (responseJSON: { + success: boolean; + errorMessage?: string; + feeCategories: recordTypes.FeeCategory[]; + }) => { + if (responseJSON.success) { + feeCategories = responseJSON.feeCategories; + addCloseModalFunction(); + renderFeeCategories(); + } else { + bulmaJS.alert({ + title: "Error Creating Fee Category", + message: responseJSON.errorMessage, + contextualColorName: "danger" + }); } - ); - }; - - cityssm.openHtmlModal("adminFees-addFeeCategory", { - onshown: (modalElement, closeModalFunction) => { - bulmaJS.toggleHtmlClipped(); - ( - modalElement.querySelector( - "#feeCategoryAdd--feeCategory" - ) as HTMLInputElement - ).focus(); - - addCloseModalFunction = closeModalFunction; - modalElement - .querySelector("form") - .addEventListener("submit", doAddFeeCategory); - }, - onremoved: () => { - bulmaJS.toggleHtmlClipped(); } - }); + ); + }; + + cityssm.openHtmlModal("adminFees-addFeeCategory", { + onshown: (modalElement, closeModalFunction) => { + bulmaJS.toggleHtmlClipped(); + ( + modalElement.querySelector("#feeCategoryAdd--feeCategory") as HTMLInputElement + ).focus(); + + addCloseModalFunction = closeModalFunction; + modalElement.querySelector("form").addEventListener("submit", doAddFeeCategory); + }, + onremoved: () => { + bulmaJS.toggleHtmlClipped(); + } }); + }); const openEditFeeCategory = (clickEvent: Event) => { const feeCategoryId = Number.parseInt( @@ -331,9 +317,7 @@ declare const bulmaJS: BulmaJS; ) as HTMLInputElement ).value = feeCategory.feeCategoryId.toString(); ( - modalElement.querySelector( - "#feeCategoryEdit--feeCategory" - ) as HTMLInputElement + modalElement.querySelector("#feeCategoryEdit--feeCategory") as HTMLInputElement ).value = feeCategory.feeCategory; }, onshown: (modalElement, closeModalFunction) => { @@ -341,14 +325,10 @@ declare const bulmaJS: BulmaJS; editCloseModalFunction = closeModalFunction; - modalElement - .querySelector("form") - .addEventListener("submit", doUpdateFeeCategory); + modalElement.querySelector("form").addEventListener("submit", doUpdateFeeCategory); ( - modalElement.querySelector( - "#feeCategoryEdit--feeCategory" - ) as HTMLInputElement + modalElement.querySelector("#feeCategoryEdit--feeCategory") as HTMLInputElement ).focus(); }, onremoved: () => { @@ -403,7 +383,7 @@ declare const bulmaJS: BulmaJS; }); }; - const moveFeeCategoryUp = (clickEvent: Event) => { + const moveFeeCategoryUp = (clickEvent: MouseEvent) => { const feeCategoryId = Number.parseInt( ( (clickEvent.currentTarget as HTMLElement).closest( @@ -416,7 +396,8 @@ declare const bulmaJS: BulmaJS; cityssm.postJSON( urlPrefix + "/admin/doMoveFeeCategoryUp", { - feeCategoryId + feeCategoryId, + moveToTop: clickEvent.shiftKey ? "1" : "0" }, (responseJSON: { success: boolean; @@ -437,7 +418,7 @@ declare const bulmaJS: BulmaJS; ); }; - const moveFeeCategoryDown = (clickEvent: Event) => { + const moveFeeCategoryDown = (clickEvent: MouseEvent) => { const feeCategoryId = Number.parseInt( ( (clickEvent.currentTarget as HTMLElement).closest( @@ -450,7 +431,8 @@ declare const bulmaJS: BulmaJS; cityssm.postJSON( urlPrefix + "/admin/doMoveFeeCategoryDown", { - feeCategoryId + feeCategoryId, + moveToBottom: clickEvent.shiftKey ? "1" : "0" }, (responseJSON: { success: boolean; @@ -537,8 +519,7 @@ declare const bulmaJS: BulmaJS; for (const occupancyType of exports.occupancyTypes as recordTypes.OccupancyType[]) { const optionElement = document.createElement("option"); - optionElement.value = - occupancyType.occupancyTypeId.toString(); + optionElement.value = occupancyType.occupancyTypeId.toString(); optionElement.textContent = occupancyType.occupancyType; occupancyTypeElement.append(optionElement); } @@ -554,11 +535,9 @@ declare const bulmaJS: BulmaJS; lotTypeElement.append(optionElement); } - ( - modalElement.querySelector( - "#feeAdd--taxPercentage" - ) as HTMLInputElement - ).value = (exports.taxPercentageDefault as number).toString(); + (modalElement.querySelector("#feeAdd--taxPercentage") as HTMLInputElement).value = ( + exports.taxPercentageDefault as number + ).toString(); los.populateAliases(modalElement); }, @@ -567,15 +546,9 @@ declare const bulmaJS: BulmaJS; addCloseModalFunction = closeModalFunction; - modalElement - .querySelector("form") - .addEventListener("submit", doAddFee); + modalElement.querySelector("form").addEventListener("submit", doAddFee); - ( - modalElement.querySelector( - "#feeAdd--feeName" - ) as HTMLInputElement - ).focus(); + (modalElement.querySelector("#feeAdd--feeName") as HTMLInputElement).focus(); modalElement .querySelector("#feeAdd--feeFunction") @@ -588,16 +561,12 @@ declare const bulmaJS: BulmaJS; ) as HTMLSelectElement; if (feeFunctionElement.value === "") { - feeFunctionElement - .closest(".select") - .classList.remove("is-success"); + feeFunctionElement.closest(".select").classList.remove("is-success"); feeAmountElement.classList.add("is-success"); feeAmountElement.disabled = false; } else { - feeFunctionElement - .closest(".select") - .classList.add("is-success"); + feeFunctionElement.closest(".select").classList.add("is-success"); feeAmountElement.classList.remove("is-success"); feeAmountElement.disabled = true; @@ -631,9 +600,7 @@ declare const bulmaJS: BulmaJS; .querySelector("#feeAdd--includeQuantity") .addEventListener("change", () => { ( - modalElement.querySelector( - "#feeAdd--quantityUnit" - ) as HTMLInputElement + modalElement.querySelector("#feeAdd--quantityUnit") as HTMLInputElement ).disabled = ( modalElement.querySelector( @@ -651,17 +618,14 @@ declare const bulmaJS: BulmaJS; const openEditFee = (clickEvent: Event) => { clickEvent.preventDefault(); - const feeContainerElement = ( - clickEvent.currentTarget as HTMLElement - ).closest(".container--fee") as HTMLElement; + const feeContainerElement = (clickEvent.currentTarget as HTMLElement).closest( + ".container--fee" + ) as HTMLElement; const feeId = Number.parseInt(feeContainerElement.dataset.feeId, 10); const feeCategoryId = Number.parseInt( - ( - feeContainerElement.closest( - ".container--feeCategory" - ) as HTMLElement - ).dataset.feeCategoryId + (feeContainerElement.closest(".container--feeCategory") as HTMLElement).dataset + .feeCategoryId ); const feeCategory = feeCategories.find((currentFeeCategory) => { @@ -750,16 +714,12 @@ declare const bulmaJS: BulmaJS; ) as HTMLSelectElement; if (feeFunctionElement.value === "") { - feeFunctionElement - .closest(".select") - .classList.remove("is-success"); + feeFunctionElement.closest(".select").classList.remove("is-success"); feeAmountElement.classList.add("is-success"); feeAmountElement.disabled = false; } else { - feeFunctionElement - .closest(".select") - .classList.add("is-success"); + feeFunctionElement.closest(".select").classList.add("is-success"); feeAmountElement.classList.remove("is-success"); feeAmountElement.disabled = true; @@ -789,26 +749,18 @@ declare const bulmaJS: BulmaJS; const toggleQuantityFields = () => { ( - editModalElement.querySelector( - "#feeEdit--quantityUnit" - ) as HTMLInputElement + editModalElement.querySelector("#feeEdit--quantityUnit") as HTMLInputElement ).disabled = - ( - editModalElement.querySelector( - "#feeEdit--includeQuantity" - ) as HTMLSelectElement - ).value === ""; + (editModalElement.querySelector("#feeEdit--includeQuantity") as HTMLSelectElement) + .value === ""; }; cityssm.openHtmlModal("adminFees-editFee", { onshow: (modalElement) => { editModalElement = modalElement; - ( - modalElement.querySelector( - "#feeEdit--feeId" - ) as HTMLInputElement - ).value = fee.feeId.toString(); + (modalElement.querySelector("#feeEdit--feeId") as HTMLInputElement).value = + fee.feeId.toString(); const feeCategoryElement = modalElement.querySelector( "#feeEdit--feeCategoryId" @@ -826,15 +778,10 @@ declare const bulmaJS: BulmaJS; feeCategoryElement.append(optionElement); } + (modalElement.querySelector("#feeEdit--feeName") as HTMLInputElement).value = + fee.feeName; ( - modalElement.querySelector( - "#feeEdit--feeName" - ) as HTMLInputElement - ).value = fee.feeName; - ( - modalElement.querySelector( - "#feeEdit--feeDescription" - ) as HTMLTextAreaElement + modalElement.querySelector("#feeEdit--feeDescription") as HTMLTextAreaElement ).value = fee.feeDescription; const occupancyTypeElement = modalElement.querySelector( @@ -843,8 +790,7 @@ declare const bulmaJS: BulmaJS; for (const occupancyType of exports.occupancyTypes as recordTypes.OccupancyType[]) { const optionElement = document.createElement("option"); - optionElement.value = - occupancyType.occupancyTypeId.toString(); + optionElement.value = occupancyType.occupancyTypeId.toString(); optionElement.textContent = occupancyType.occupancyType; if (occupancyType.occupancyTypeId === fee.occupancyTypeId) { @@ -870,29 +816,21 @@ declare const bulmaJS: BulmaJS; lotTypeElement.append(optionElement); } - ( - modalElement.querySelector( - "#feeEdit--feeAmount" - ) as HTMLInputElement - ).value = fee.feeAmount ? fee.feeAmount.toFixed(2) : ""; + (modalElement.querySelector("#feeEdit--feeAmount") as HTMLInputElement).value = + fee.feeAmount ? fee.feeAmount.toFixed(2) : ""; modalElement .querySelector("#feeEdit--feeFunction") .addEventListener("change", toggleFeeFields); toggleFeeFields(); - ( - modalElement.querySelector( - "#feeEdit--taxAmount" - ) as HTMLInputElement - ).value = fee.taxAmount ? fee.taxAmount.toFixed(2) : ""; + (modalElement.querySelector("#feeEdit--taxAmount") as HTMLInputElement).value = + fee.taxAmount ? fee.taxAmount.toFixed(2) : ""; const taxPercentageElement = modalElement.querySelector( "#feeEdit--taxPercentage" ) as HTMLInputElement; - taxPercentageElement.value = fee.taxPercentage - ? fee.taxPercentage.toString() - : ""; + taxPercentageElement.value = fee.taxPercentage ? fee.taxPercentage.toString() : ""; taxPercentageElement.addEventListener("keyup", toggleTaxFields); toggleTaxFields(); @@ -905,24 +843,16 @@ declare const bulmaJS: BulmaJS; includeQuantityElement.value = "1"; } - includeQuantityElement.addEventListener( - "change", - toggleQuantityFields - ); + includeQuantityElement.addEventListener("change", toggleQuantityFields); - ( - modalElement.querySelector( - "#feeEdit--quantityUnit" - ) as HTMLInputElement - ).value = fee.quantityUnit || ""; + (modalElement.querySelector("#feeEdit--quantityUnit") as HTMLInputElement).value = + fee.quantityUnit || ""; toggleQuantityFields(); if (fee.isRequired) { ( - modalElement.querySelector( - "#feeEdit--isRequired" - ) as HTMLSelectElement + modalElement.querySelector("#feeEdit--isRequired") as HTMLSelectElement ).value = "1"; } @@ -933,9 +863,7 @@ declare const bulmaJS: BulmaJS; editCloseModalFunction = closeModalFunction; - modalElement - .querySelector("form") - .addEventListener("submit", doUpdateFee); + modalElement.querySelector("form").addEventListener("submit", doUpdateFee); bulmaJS.init(modalElement); @@ -949,17 +877,18 @@ declare const bulmaJS: BulmaJS; }); }; - const moveFeeUp = (clickEvent: Event) => { - const feeContainerElement = ( - clickEvent.currentTarget as HTMLElement - ).closest(".container--fee") as HTMLElement; + const moveFeeUp = (clickEvent: MouseEvent) => { + const feeContainerElement = (clickEvent.currentTarget as HTMLElement).closest( + ".container--fee" + ) as HTMLElement; const feeId = Number.parseInt(feeContainerElement.dataset.feeId, 10); cityssm.postJSON( urlPrefix + "/admin/doMoveFeeUp", { - feeId + feeId, + moveToTop: clickEvent.shiftKey ? "1" : "0" }, (responseJSON: { success: boolean; @@ -980,17 +909,18 @@ declare const bulmaJS: BulmaJS; ); }; - const moveFeeDown = (clickEvent: Event) => { - const feeContainerElement = ( - clickEvent.currentTarget as HTMLElement - ).closest(".container--fee") as HTMLElement; + const moveFeeDown = (clickEvent: MouseEvent) => { + const feeContainerElement = (clickEvent.currentTarget as HTMLElement).closest( + ".container--fee" + ) as HTMLElement; const feeId = Number.parseInt(feeContainerElement.dataset.feeId, 10); cityssm.postJSON( urlPrefix + "/admin/doMoveFeeDown", { - feeId + feeId, + moveToBottom: clickEvent.shiftKey ? "1" : "0" }, (responseJSON: { success: boolean; diff --git a/public/javascripts/adminFees.min.js b/public/javascripts/adminFees.min.js index cd090e7d..432b0a8e 100644 --- a/public/javascripts/adminFees.min.js +++ b/public/javascripts/adminFees.min.js @@ -1 +1 @@ -"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),(()=>{const e=exports.los,t=document.querySelector("main").dataset.urlPrefix,s=document.querySelector("#container--feeCategories");let a=exports.feeCategories;delete exports.feeCategories;const o=()=>{if(0!==a.length){s.innerHTML="";for(const e of a){const t=document.createElement("section");if(t.className="panel container--feeCategory",t.dataset.feeCategoryId=e.feeCategoryId.toString(),t.innerHTML='

'+cityssm.escapeHTML(e.feeCategory)+'

'+(0===e.fees.length?'
':"")+'
',0===e.fees.length)t.insertAdjacentHTML("beforeend",'

There are no fees in the "'+cityssm.escapeHTML(e.feeCategory)+'" category.

');else for(const s of e.fees){const e=document.createElement("div");e.className="panel-block is-block container--fee",e.dataset.feeId=s.feeId.toString(),e.innerHTML='

'+cityssm.escapeHTML(s.feeName)+"
"+cityssm.escapeHTML(s.feeDescription).replace(/\n/g,"
")+'

'+(s.isRequired?'Required':"")+(s.occupancyTypeId?' '+cityssm.escapeHTML(s.occupancyType)+"":"")+(s.lotTypeId?' '+cityssm.escapeHTML(s.lotType)+"":"")+'

'+(s.feeFunction?cityssm.escapeHTML(s.feeFunction)+"
Fee Function":"$"+s.feeAmount.toFixed(2)+"
Fee")+'
'+(s.taxPercentage?s.taxPercentage+"%":"$"+s.taxAmount.toFixed(2))+'
Tax
'+(s.includeQuantity?cityssm.escapeHTML(s.quantityUnit)+"
Quantity":"")+'
',e.querySelector("a").addEventListener("click",d),e.querySelector(".button--moveFeeUp").addEventListener("click",u),e.querySelector(".button--moveFeeDown").addEventListener("click",y),t.append(e)}0===e.fees.length&&t.querySelector(".button--deleteFeeCategory").addEventListener("click",n),t.querySelector(".button--editFeeCategory").addEventListener("click",r),t.querySelector(".button--addFee").addEventListener("click",i),t.querySelector(".button--moveFeeCategoryUp").addEventListener("click",l),t.querySelector(".button--moveFeeCategoryDown").addEventListener("click",c),s.append(t)}}else s.innerHTML='

There are no available fees.

'};document.querySelector("#button--addFeeCategory").addEventListener("click",()=>{let e;const s=s=>{s.preventDefault(),cityssm.postJSON(t+"/admin/doAddFeeCategory",s.currentTarget,t=>{t.success?(a=t.feeCategories,e(),o()):bulmaJS.alert({title:"Error Creating Fee Category",message:t.errorMessage,contextualColorName:"danger"})})};cityssm.openHtmlModal("adminFees-addFeeCategory",{onshown:(t,a)=>{bulmaJS.toggleHtmlClipped(),t.querySelector("#feeCategoryAdd--feeCategory").focus(),e=a,t.querySelector("form").addEventListener("submit",s)},onremoved:()=>{bulmaJS.toggleHtmlClipped()}})});const r=e=>{const s=Number.parseInt(e.currentTarget.closest(".container--feeCategory").dataset.feeCategoryId,10),r=a.find(e=>e.feeCategoryId===s);let n;const l=e=>{e.preventDefault(),cityssm.postJSON(t+"/admin/doUpdateFeeCategory",e.currentTarget,e=>{e.success?(a=e.feeCategories,n(),o()):bulmaJS.alert({title:"Error Updating Fee Category",message:e.errorMessage,contextualColorName:"danger"})})};cityssm.openHtmlModal("adminFees-editFeeCategory",{onshow:e=>{e.querySelector("#feeCategoryEdit--feeCategoryId").value=r.feeCategoryId.toString(),e.querySelector("#feeCategoryEdit--feeCategory").value=r.feeCategory},onshown:(e,t)=>{bulmaJS.toggleHtmlClipped(),n=t,e.querySelector("form").addEventListener("submit",l),e.querySelector("#feeCategoryEdit--feeCategory").focus()},onremoved:()=>{bulmaJS.toggleHtmlClipped()}})},n=e=>{const s=Number.parseInt(e.currentTarget.closest(".container--feeCategory").dataset.feeCategoryId,10);bulmaJS.confirm({title:"Delete Fee Category?",message:"Are you sure you want to delete this fee category?",contextualColorName:"warning",okButton:{text:"Yes, Delete the Fee Category",callbackFunction:()=>{cityssm.postJSON(t+"/admin/doDeleteFeeCategory",{feeCategoryId:s},e=>{e.success?(a=e.feeCategories,o()):bulmaJS.alert({title:"Error Updating Fee Category",message:e.errorMessage,contextualColorName:"danger"})})}}})},l=e=>{const s=Number.parseInt(e.currentTarget.closest(".container--feeCategory").dataset.feeCategoryId,10);cityssm.postJSON(t+"/admin/doMoveFeeCategoryUp",{feeCategoryId:s},e=>{e.success?(a=e.feeCategories,o()):bulmaJS.alert({title:"Error Moving Fee Category",message:e.errorMessage,contextualColorName:"danger"})})},c=e=>{const s=Number.parseInt(e.currentTarget.closest(".container--feeCategory").dataset.feeCategoryId,10);cityssm.postJSON(t+"/admin/doMoveFeeCategoryDown",{feeCategoryId:s},e=>{e.success?(a=e.feeCategories,o()):bulmaJS.alert({title:"Error Moving Fee Category",message:e.errorMessage,contextualColorName:"danger"})})},i=s=>{const r=Number.parseInt(s.currentTarget.closest(".container--feeCategory").dataset.feeCategoryId,10);let n;const l=e=>{e.preventDefault(),cityssm.postJSON(t+"/admin/doAddFee",e.currentTarget,e=>{e.success?(a=e.feeCategories,n(),o()):bulmaJS.alert({title:"Error Adding Fee",message:e.errorMessage,contextualColorName:"danger"})})};cityssm.openHtmlModal("adminFees-addFee",{onshow:t=>{const s=t.querySelector("#feeAdd--feeCategoryId");for(const e of a){const t=document.createElement("option");t.value=e.feeCategoryId.toString(),t.textContent=e.feeCategory,e.feeCategoryId===r&&(t.selected=!0),s.append(t)}const o=t.querySelector("#feeAdd--occupancyTypeId");for(const e of exports.occupancyTypes){const t=document.createElement("option");t.value=e.occupancyTypeId.toString(),t.textContent=e.occupancyType,o.append(t)}const n=t.querySelector("#feeAdd--lotTypeId");for(const e of exports.lotTypes){const t=document.createElement("option");t.value=e.lotTypeId.toString(),t.textContent=e.lotType,n.append(t)}t.querySelector("#feeAdd--taxPercentage").value=exports.taxPercentageDefault.toString(),e.populateAliases(t)},onshown:(e,t)=>{bulmaJS.toggleHtmlClipped(),n=t,e.querySelector("form").addEventListener("submit",l),e.querySelector("#feeAdd--feeName").focus(),e.querySelector("#feeAdd--feeFunction").addEventListener("change",()=>{const t=e.querySelector("#feeAdd--feeAmount"),s=e.querySelector("#feeAdd--feeFunction");""===s.value?(s.closest(".select").classList.remove("is-success"),t.classList.add("is-success"),t.disabled=!1):(s.closest(".select").classList.add("is-success"),t.classList.remove("is-success"),t.disabled=!0)}),e.querySelector("#feeAdd--taxPercentage").addEventListener("keyup",()=>{const t=e.querySelector("#feeAdd--taxAmount"),s=e.querySelector("#feeAdd--taxPercentage");""===s.value?(s.classList.remove("is-success"),t.classList.add("is-success"),t.disabled=!1):(s.classList.add("is-success"),t.classList.remove("is-success"),t.disabled=!0)}),e.querySelector("#feeAdd--includeQuantity").addEventListener("change",()=>{e.querySelector("#feeAdd--quantityUnit").disabled=""===e.querySelector("#feeAdd--includeQuantity").value})},onremoved:()=>{bulmaJS.toggleHtmlClipped()}})},d=s=>{s.preventDefault();const r=s.currentTarget.closest(".container--fee"),n=Number.parseInt(r.dataset.feeId,10),l=Number.parseInt(r.closest(".container--feeCategory").dataset.feeCategoryId),c=a.find(e=>e.feeCategoryId===l).fees.find(e=>e.feeId===n);let i,d;const u=e=>{e.preventDefault(),cityssm.postJSON(t+"/admin/doUpdateFee",e.currentTarget,e=>{e.success?(a=e.feeCategories,i(),o()):bulmaJS.alert({title:"Error Updating Fee",message:e.errorMessage,contextualColorName:"danger"})})},y=e=>{e.preventDefault();bulmaJS.confirm({title:"Delete Fee?",message:"Are you sure you want to delete this fee?",contextualColorName:"warning",okButton:{text:"Yes, Delete the Fee",callbackFunction:()=>{cityssm.postJSON(t+"/admin/doDeleteFee",{feeId:n},e=>{e.success?(a=e.feeCategories,i(),o()):bulmaJS.alert({title:"Error Deleting Fee",message:e.errorMessage,contextualColorName:"danger"})})}}})},m=()=>{const e=d.querySelector("#feeEdit--feeAmount"),t=d.querySelector("#feeEdit--feeFunction");""===t.value?(t.closest(".select").classList.remove("is-success"),e.classList.add("is-success"),e.disabled=!1):(t.closest(".select").classList.add("is-success"),e.classList.remove("is-success"),e.disabled=!0)},p=()=>{const e=d.querySelector("#feeEdit--taxAmount"),t=d.querySelector("#feeEdit--taxPercentage");""===t.value?(t.classList.remove("is-success"),e.classList.add("is-success"),e.disabled=!1):(t.classList.add("is-success"),e.classList.remove("is-success"),e.disabled=!0)},g=()=>{d.querySelector("#feeEdit--quantityUnit").disabled=""===d.querySelector("#feeEdit--includeQuantity").value};cityssm.openHtmlModal("adminFees-editFee",{onshow:t=>{d=t,t.querySelector("#feeEdit--feeId").value=c.feeId.toString();const s=t.querySelector("#feeEdit--feeCategoryId");for(const e of a){const t=document.createElement("option");t.value=e.feeCategoryId.toString(),t.textContent=e.feeCategory,e.feeCategoryId===l&&(t.selected=!0),s.append(t)}t.querySelector("#feeEdit--feeName").value=c.feeName,t.querySelector("#feeEdit--feeDescription").value=c.feeDescription;const o=t.querySelector("#feeEdit--occupancyTypeId");for(const e of exports.occupancyTypes){const t=document.createElement("option");t.value=e.occupancyTypeId.toString(),t.textContent=e.occupancyType,e.occupancyTypeId===c.occupancyTypeId&&(t.selected=!0),o.append(t)}const r=t.querySelector("#feeEdit--lotTypeId");for(const e of exports.lotTypes){const t=document.createElement("option");t.value=e.lotTypeId.toString(),t.textContent=e.lotType,e.lotTypeId===c.lotTypeId&&(t.selected=!0),r.append(t)}t.querySelector("#feeEdit--feeAmount").value=c.feeAmount?c.feeAmount.toFixed(2):"",t.querySelector("#feeEdit--feeFunction").addEventListener("change",m),m(),t.querySelector("#feeEdit--taxAmount").value=c.taxAmount?c.taxAmount.toFixed(2):"";const n=t.querySelector("#feeEdit--taxPercentage");n.value=c.taxPercentage?c.taxPercentage.toString():"",n.addEventListener("keyup",p),p();const i=t.querySelector("#feeEdit--includeQuantity");c.includeQuantity&&(i.value="1"),i.addEventListener("change",g),t.querySelector("#feeEdit--quantityUnit").value=c.quantityUnit||"",g(),c.isRequired&&(t.querySelector("#feeEdit--isRequired").value="1"),e.populateAliases(t)},onshown:(e,t)=>{bulmaJS.toggleHtmlClipped(),i=t,e.querySelector("form").addEventListener("submit",u),bulmaJS.init(e),e.querySelector(".button--deleteFee").addEventListener("click",y)},onremoved:()=>{bulmaJS.toggleHtmlClipped()}})},u=e=>{const s=e.currentTarget.closest(".container--fee"),r=Number.parseInt(s.dataset.feeId,10);cityssm.postJSON(t+"/admin/doMoveFeeUp",{feeId:r},e=>{e.success?(a=e.feeCategories,o()):bulmaJS.alert({title:"Error Moving Fee",message:e.errorMessage,contextualColorName:"danger"})})},y=e=>{const s=e.currentTarget.closest(".container--fee"),r=Number.parseInt(s.dataset.feeId,10);cityssm.postJSON(t+"/admin/doMoveFeeDown",{feeId:r},e=>{e.success?(a=e.feeCategories,o()):bulmaJS.alert({title:"Error Moving Fee",message:e.errorMessage,contextualColorName:"danger"})})};o()})(); \ No newline at end of file +"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),(()=>{const e=exports.los,t=document.querySelector("main").dataset.urlPrefix,s=document.querySelector("#container--feeCategories");let o=exports.feeCategories;delete exports.feeCategories;const a=()=>{if(0!==o.length){s.innerHTML="";for(const e of o){const t=document.createElement("section");if(t.className="panel container--feeCategory",t.dataset.feeCategoryId=e.feeCategoryId.toString(),t.innerHTML='

'+cityssm.escapeHTML(e.feeCategory)+'

'+(0===e.fees.length?'
':"")+'
',0===e.fees.length)t.insertAdjacentHTML("beforeend",'

There are no fees in the "'+cityssm.escapeHTML(e.feeCategory)+'" category.

');else for(const s of e.fees){const e=document.createElement("div");e.className="panel-block is-block container--fee",e.dataset.feeId=s.feeId.toString(),e.innerHTML='

'+cityssm.escapeHTML(s.feeName)+"
"+cityssm.escapeHTML(s.feeDescription).replace(/\n/g,"
")+'

'+(s.isRequired?'Required':"")+(s.occupancyTypeId?' '+cityssm.escapeHTML(s.occupancyType)+"":"")+(s.lotTypeId?' '+cityssm.escapeHTML(s.lotType)+"":"")+'

'+(s.feeFunction?cityssm.escapeHTML(s.feeFunction)+"
Fee Function":"$"+s.feeAmount.toFixed(2)+"
Fee")+'
'+(s.taxPercentage?s.taxPercentage+"%":"$"+s.taxAmount.toFixed(2))+'
Tax
'+(s.includeQuantity?cityssm.escapeHTML(s.quantityUnit)+"
Quantity":"")+'
',e.querySelector("a").addEventListener("click",d),e.querySelector(".button--moveFeeUp").addEventListener("click",u),e.querySelector(".button--moveFeeDown").addEventListener("click",y),t.append(e)}0===e.fees.length&&t.querySelector(".button--deleteFeeCategory").addEventListener("click",n),t.querySelector(".button--editFeeCategory").addEventListener("click",r),t.querySelector(".button--addFee").addEventListener("click",i),t.querySelector(".button--moveFeeCategoryUp").addEventListener("click",c),t.querySelector(".button--moveFeeCategoryDown").addEventListener("click",l),s.append(t)}}else s.innerHTML='

There are no available fees.

'};document.querySelector("#button--addFeeCategory").addEventListener("click",()=>{let e;const s=s=>{s.preventDefault(),cityssm.postJSON(t+"/admin/doAddFeeCategory",s.currentTarget,t=>{t.success?(o=t.feeCategories,e(),a()):bulmaJS.alert({title:"Error Creating Fee Category",message:t.errorMessage,contextualColorName:"danger"})})};cityssm.openHtmlModal("adminFees-addFeeCategory",{onshown:(t,o)=>{bulmaJS.toggleHtmlClipped(),t.querySelector("#feeCategoryAdd--feeCategory").focus(),e=o,t.querySelector("form").addEventListener("submit",s)},onremoved:()=>{bulmaJS.toggleHtmlClipped()}})});const r=e=>{const s=Number.parseInt(e.currentTarget.closest(".container--feeCategory").dataset.feeCategoryId,10),r=o.find(e=>e.feeCategoryId===s);let n;const c=e=>{e.preventDefault(),cityssm.postJSON(t+"/admin/doUpdateFeeCategory",e.currentTarget,e=>{e.success?(o=e.feeCategories,n(),a()):bulmaJS.alert({title:"Error Updating Fee Category",message:e.errorMessage,contextualColorName:"danger"})})};cityssm.openHtmlModal("adminFees-editFeeCategory",{onshow:e=>{e.querySelector("#feeCategoryEdit--feeCategoryId").value=r.feeCategoryId.toString(),e.querySelector("#feeCategoryEdit--feeCategory").value=r.feeCategory},onshown:(e,t)=>{bulmaJS.toggleHtmlClipped(),n=t,e.querySelector("form").addEventListener("submit",c),e.querySelector("#feeCategoryEdit--feeCategory").focus()},onremoved:()=>{bulmaJS.toggleHtmlClipped()}})},n=e=>{const s=Number.parseInt(e.currentTarget.closest(".container--feeCategory").dataset.feeCategoryId,10);bulmaJS.confirm({title:"Delete Fee Category?",message:"Are you sure you want to delete this fee category?",contextualColorName:"warning",okButton:{text:"Yes, Delete the Fee Category",callbackFunction:()=>{cityssm.postJSON(t+"/admin/doDeleteFeeCategory",{feeCategoryId:s},e=>{e.success?(o=e.feeCategories,a()):bulmaJS.alert({title:"Error Updating Fee Category",message:e.errorMessage,contextualColorName:"danger"})})}}})},c=e=>{const s=Number.parseInt(e.currentTarget.closest(".container--feeCategory").dataset.feeCategoryId,10);cityssm.postJSON(t+"/admin/doMoveFeeCategoryUp",{feeCategoryId:s,moveToTop:e.shiftKey?"1":"0"},e=>{e.success?(o=e.feeCategories,a()):bulmaJS.alert({title:"Error Moving Fee Category",message:e.errorMessage,contextualColorName:"danger"})})},l=e=>{const s=Number.parseInt(e.currentTarget.closest(".container--feeCategory").dataset.feeCategoryId,10);cityssm.postJSON(t+"/admin/doMoveFeeCategoryDown",{feeCategoryId:s,moveToBottom:e.shiftKey?"1":"0"},e=>{e.success?(o=e.feeCategories,a()):bulmaJS.alert({title:"Error Moving Fee Category",message:e.errorMessage,contextualColorName:"danger"})})},i=s=>{const r=Number.parseInt(s.currentTarget.closest(".container--feeCategory").dataset.feeCategoryId,10);let n;const c=e=>{e.preventDefault(),cityssm.postJSON(t+"/admin/doAddFee",e.currentTarget,e=>{e.success?(o=e.feeCategories,n(),a()):bulmaJS.alert({title:"Error Adding Fee",message:e.errorMessage,contextualColorName:"danger"})})};cityssm.openHtmlModal("adminFees-addFee",{onshow:t=>{const s=t.querySelector("#feeAdd--feeCategoryId");for(const e of o){const t=document.createElement("option");t.value=e.feeCategoryId.toString(),t.textContent=e.feeCategory,e.feeCategoryId===r&&(t.selected=!0),s.append(t)}const a=t.querySelector("#feeAdd--occupancyTypeId");for(const e of exports.occupancyTypes){const t=document.createElement("option");t.value=e.occupancyTypeId.toString(),t.textContent=e.occupancyType,a.append(t)}const n=t.querySelector("#feeAdd--lotTypeId");for(const e of exports.lotTypes){const t=document.createElement("option");t.value=e.lotTypeId.toString(),t.textContent=e.lotType,n.append(t)}t.querySelector("#feeAdd--taxPercentage").value=exports.taxPercentageDefault.toString(),e.populateAliases(t)},onshown:(e,t)=>{bulmaJS.toggleHtmlClipped(),n=t,e.querySelector("form").addEventListener("submit",c),e.querySelector("#feeAdd--feeName").focus(),e.querySelector("#feeAdd--feeFunction").addEventListener("change",()=>{const t=e.querySelector("#feeAdd--feeAmount"),s=e.querySelector("#feeAdd--feeFunction");""===s.value?(s.closest(".select").classList.remove("is-success"),t.classList.add("is-success"),t.disabled=!1):(s.closest(".select").classList.add("is-success"),t.classList.remove("is-success"),t.disabled=!0)}),e.querySelector("#feeAdd--taxPercentage").addEventListener("keyup",()=>{const t=e.querySelector("#feeAdd--taxAmount"),s=e.querySelector("#feeAdd--taxPercentage");""===s.value?(s.classList.remove("is-success"),t.classList.add("is-success"),t.disabled=!1):(s.classList.add("is-success"),t.classList.remove("is-success"),t.disabled=!0)}),e.querySelector("#feeAdd--includeQuantity").addEventListener("change",()=>{e.querySelector("#feeAdd--quantityUnit").disabled=""===e.querySelector("#feeAdd--includeQuantity").value})},onremoved:()=>{bulmaJS.toggleHtmlClipped()}})},d=s=>{s.preventDefault();const r=s.currentTarget.closest(".container--fee"),n=Number.parseInt(r.dataset.feeId,10),c=Number.parseInt(r.closest(".container--feeCategory").dataset.feeCategoryId),l=o.find(e=>e.feeCategoryId===c).fees.find(e=>e.feeId===n);let i,d;const u=e=>{e.preventDefault(),cityssm.postJSON(t+"/admin/doUpdateFee",e.currentTarget,e=>{e.success?(o=e.feeCategories,i(),a()):bulmaJS.alert({title:"Error Updating Fee",message:e.errorMessage,contextualColorName:"danger"})})},y=e=>{e.preventDefault();bulmaJS.confirm({title:"Delete Fee?",message:"Are you sure you want to delete this fee?",contextualColorName:"warning",okButton:{text:"Yes, Delete the Fee",callbackFunction:()=>{cityssm.postJSON(t+"/admin/doDeleteFee",{feeId:n},e=>{e.success?(o=e.feeCategories,i(),a()):bulmaJS.alert({title:"Error Deleting Fee",message:e.errorMessage,contextualColorName:"danger"})})}}})},m=()=>{const e=d.querySelector("#feeEdit--feeAmount"),t=d.querySelector("#feeEdit--feeFunction");""===t.value?(t.closest(".select").classList.remove("is-success"),e.classList.add("is-success"),e.disabled=!1):(t.closest(".select").classList.add("is-success"),e.classList.remove("is-success"),e.disabled=!0)},p=()=>{const e=d.querySelector("#feeEdit--taxAmount"),t=d.querySelector("#feeEdit--taxPercentage");""===t.value?(t.classList.remove("is-success"),e.classList.add("is-success"),e.disabled=!1):(t.classList.add("is-success"),e.classList.remove("is-success"),e.disabled=!0)},g=()=>{d.querySelector("#feeEdit--quantityUnit").disabled=""===d.querySelector("#feeEdit--includeQuantity").value};cityssm.openHtmlModal("adminFees-editFee",{onshow:t=>{d=t,t.querySelector("#feeEdit--feeId").value=l.feeId.toString();const s=t.querySelector("#feeEdit--feeCategoryId");for(const e of o){const t=document.createElement("option");t.value=e.feeCategoryId.toString(),t.textContent=e.feeCategory,e.feeCategoryId===c&&(t.selected=!0),s.append(t)}t.querySelector("#feeEdit--feeName").value=l.feeName,t.querySelector("#feeEdit--feeDescription").value=l.feeDescription;const a=t.querySelector("#feeEdit--occupancyTypeId");for(const e of exports.occupancyTypes){const t=document.createElement("option");t.value=e.occupancyTypeId.toString(),t.textContent=e.occupancyType,e.occupancyTypeId===l.occupancyTypeId&&(t.selected=!0),a.append(t)}const r=t.querySelector("#feeEdit--lotTypeId");for(const e of exports.lotTypes){const t=document.createElement("option");t.value=e.lotTypeId.toString(),t.textContent=e.lotType,e.lotTypeId===l.lotTypeId&&(t.selected=!0),r.append(t)}t.querySelector("#feeEdit--feeAmount").value=l.feeAmount?l.feeAmount.toFixed(2):"",t.querySelector("#feeEdit--feeFunction").addEventListener("change",m),m(),t.querySelector("#feeEdit--taxAmount").value=l.taxAmount?l.taxAmount.toFixed(2):"";const n=t.querySelector("#feeEdit--taxPercentage");n.value=l.taxPercentage?l.taxPercentage.toString():"",n.addEventListener("keyup",p),p();const i=t.querySelector("#feeEdit--includeQuantity");l.includeQuantity&&(i.value="1"),i.addEventListener("change",g),t.querySelector("#feeEdit--quantityUnit").value=l.quantityUnit||"",g(),l.isRequired&&(t.querySelector("#feeEdit--isRequired").value="1"),e.populateAliases(t)},onshown:(e,t)=>{bulmaJS.toggleHtmlClipped(),i=t,e.querySelector("form").addEventListener("submit",u),bulmaJS.init(e),e.querySelector(".button--deleteFee").addEventListener("click",y)},onremoved:()=>{bulmaJS.toggleHtmlClipped()}})},u=e=>{const s=e.currentTarget.closest(".container--fee"),r=Number.parseInt(s.dataset.feeId,10);cityssm.postJSON(t+"/admin/doMoveFeeUp",{feeId:r,moveToTop:e.shiftKey?"1":"0"},e=>{e.success?(o=e.feeCategories,a()):bulmaJS.alert({title:"Error Moving Fee",message:e.errorMessage,contextualColorName:"danger"})})},y=e=>{const s=e.currentTarget.closest(".container--fee"),r=Number.parseInt(s.dataset.feeId,10);cityssm.postJSON(t+"/admin/doMoveFeeDown",{feeId:r,moveToBottom:e.shiftKey?"1":"0"},e=>{e.success?(o=e.feeCategories,a()):bulmaJS.alert({title:"Error Moving Fee",message:e.errorMessage,contextualColorName:"danger"})})};a()})(); \ No newline at end of file diff --git a/views/admin-fees.ejs b/views/admin-fees.ejs index 0a893d1c..a1b7ec6b 100644 --- a/views/admin-fees.ejs +++ b/views/admin-fees.ejs @@ -23,16 +23,16 @@ -
+
-
+

Fee Management

-
+