copy lot occupancy as new

deepsource-autofix-76c6eb20
Dan Gowans 2022-11-08 12:12:02 -05:00
parent 055aa8db59
commit 4888bd2294
21 changed files with 324 additions and 51 deletions

View File

@ -0,0 +1,3 @@
import type { RequestHandler } from "express";
export declare const handler: RequestHandler;
export default handler;

View File

@ -0,0 +1,9 @@
import { copyLotOccupancy } from "../../helpers/lotOccupancyDB/copyLotOccupancy.js";
export const handler = async (request, response) => {
const lotOccupancyId = copyLotOccupancy(request.body.lotOccupancyId, request.session);
response.json({
success: true,
lotOccupancyId
});
};
export default handler;

View File

@ -0,0 +1,14 @@
import type { RequestHandler } from "express";
import { copyLotOccupancy } from "../../helpers/lotOccupancyDB/copyLotOccupancy.js";
export const handler: RequestHandler = async (request, response) => {
const lotOccupancyId = copyLotOccupancy(request.body.lotOccupancyId, request.session);
response.json({
success: true,
lotOccupancyId
});
};
export default handler;

View File

@ -1,3 +1,4 @@
import sqlite from "better-sqlite3";
import type * as recordTypes from "../../types/recordTypes";
interface AddLotOccupancyForm {
occupancyTypeId: string | number;
@ -7,5 +8,5 @@ interface AddLotOccupancyForm {
occupancyTypeFieldIds?: string;
[lotOccupancyFieldValue_occupancyTypeFieldId: string]: unknown;
}
export declare const addLotOccupancy: (lotOccupancyForm: AddLotOccupancyForm, requestSession: recordTypes.PartialSession) => number;
export declare const addLotOccupancy: (lotOccupancyForm: AddLotOccupancyForm, requestSession: recordTypes.PartialSession, connectedDatabase?: sqlite.Database) => number;
export default addLotOccupancy;

View File

@ -2,8 +2,8 @@ import sqlite from "better-sqlite3";
import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js";
import * as dateTimeFunctions from "@cityssm/expressjs-server-js/dateTimeFns.js";
import { addOrUpdateLotOccupancyField } from "./addOrUpdateLotOccupancyField.js";
export const addLotOccupancy = (lotOccupancyForm, requestSession) => {
const database = sqlite(databasePath);
export const addLotOccupancy = (lotOccupancyForm, requestSession, connectedDatabase) => {
const database = connectedDatabase || sqlite(databasePath);
const rightNowMillis = Date.now();
const occupancyStartDate = dateTimeFunctions.dateStringToInteger(lotOccupancyForm.occupancyStartDateString);
if (occupancyStartDate <= 0) {
@ -31,7 +31,9 @@ export const addLotOccupancy = (lotOccupancyForm, requestSession) => {
}, requestSession, database);
}
}
if (!connectedDatabase) {
database.close();
}
return lotOccupancyId;
};
export default addLotOccupancy;

View File

@ -21,9 +21,10 @@ interface AddLotOccupancyForm {
export const addLotOccupancy = (
lotOccupancyForm: AddLotOccupancyForm,
requestSession: recordTypes.PartialSession
requestSession: recordTypes.PartialSession,
connectedDatabase?: sqlite.Database
): number => {
const database = sqlite(databasePath);
const database = connectedDatabase || sqlite(databasePath);
const rightNowMillis = Date.now();
@ -50,9 +51,7 @@ export const addLotOccupancy = (
occupancyStartDate,
lotOccupancyForm.occupancyEndDateString === ""
? undefined
: dateTimeFunctions.dateStringToInteger(
lotOccupancyForm.occupancyEndDateString
),
: dateTimeFunctions.dateStringToInteger(lotOccupancyForm.occupancyEndDateString),
requestSession.user.userName,
rightNowMillis,
requestSession.user.userName,
@ -61,9 +60,7 @@ export const addLotOccupancy = (
const lotOccupancyId = result.lastInsertRowid as number;
const occupancyTypeFieldIds = (
lotOccupancyForm.occupancyTypeFieldIds || ""
).split(",");
const occupancyTypeFieldIds = (lotOccupancyForm.occupancyTypeFieldIds || "").split(",");
for (const occupancyTypeFieldId of occupancyTypeFieldIds) {
const lotOccupancyFieldValue = lotOccupancyForm[
@ -83,7 +80,9 @@ export const addLotOccupancy = (
}
}
if (!connectedDatabase) {
database.close();
}
return lotOccupancyId;
};

View File

@ -1,3 +1,4 @@
import sqlite from "better-sqlite3";
import type * as recordTypes from "../../types/recordTypes";
interface AddLotOccupancyOccupantForm {
lotOccupancyId: string | number;
@ -11,5 +12,5 @@ interface AddLotOccupancyOccupantForm {
occupantPhoneNumber: string;
occupantEmailAddress: string;
}
export declare const addLotOccupancyOccupant: (lotOccupancyOccupantForm: AddLotOccupancyOccupantForm, requestSession: recordTypes.PartialSession) => number;
export declare const addLotOccupancyOccupant: (lotOccupancyOccupantForm: AddLotOccupancyOccupantForm, requestSession: recordTypes.PartialSession, connectedDatabase?: sqlite.Database) => number;
export default addLotOccupancyOccupant;

View File

@ -1,7 +1,7 @@
import sqlite from "better-sqlite3";
import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js";
export const addLotOccupancyOccupant = (lotOccupancyOccupantForm, requestSession) => {
const database = sqlite(databasePath);
export const addLotOccupancyOccupant = (lotOccupancyOccupantForm, requestSession, connectedDatabase) => {
const database = connectedDatabase || sqlite(databasePath);
let lotOccupantIndex = 0;
const maxIndexResult = database
.prepare("select lotOccupantIndex" +
@ -26,7 +26,9 @@ export const addLotOccupancyOccupant = (lotOccupancyOccupantForm, requestSession
" recordUpdate_userName, recordUpdate_timeMillis)" +
" values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)")
.run(lotOccupancyOccupantForm.lotOccupancyId, lotOccupantIndex, lotOccupancyOccupantForm.occupantName, lotOccupancyOccupantForm.occupantAddress1, lotOccupancyOccupantForm.occupantAddress2, lotOccupancyOccupantForm.occupantCity, lotOccupancyOccupantForm.occupantProvince, lotOccupancyOccupantForm.occupantPostalCode, lotOccupancyOccupantForm.occupantPhoneNumber, lotOccupancyOccupantForm.occupantEmailAddress, lotOccupancyOccupantForm.lotOccupantTypeId, requestSession.user.userName, rightNowMillis, requestSession.user.userName, rightNowMillis);
if (!connectedDatabase) {
database.close();
}
return lotOccupantIndex;
};
export default addLotOccupancyOccupant;

View File

@ -19,9 +19,10 @@ interface AddLotOccupancyOccupantForm {
export const addLotOccupancyOccupant = (
lotOccupancyOccupantForm: AddLotOccupancyOccupantForm,
requestSession: recordTypes.PartialSession
requestSession: recordTypes.PartialSession,
connectedDatabase?: sqlite.Database
): number => {
const database = sqlite(databasePath);
const database = connectedDatabase || sqlite(databasePath);
let lotOccupantIndex = 0;
@ -72,7 +73,9 @@ export const addLotOccupancyOccupant = (
rightNowMillis
);
if (!connectedDatabase) {
database.close();
}
return lotOccupantIndex;
};

View File

@ -0,0 +1,3 @@
import type * as recordTypes from "../../types/recordTypes";
export declare const copyLotOccupancy: (oldLotOccupancyId: number | string, requestSession: recordTypes.PartialSession) => number;
export default copyLotOccupancy;

View File

@ -0,0 +1,42 @@
import sqlite from "better-sqlite3";
import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js";
import { getLotOccupancy } from "./getLotOccupancy.js";
import { addLotOccupancy } from "./addLotOccupancy.js";
import { addLotOccupancyOccupant } from "./addLotOccupancyOccupant.js";
import { dateToString } from "@cityssm/expressjs-server-js/dateTimeFns.js";
export const copyLotOccupancy = (oldLotOccupancyId, requestSession) => {
const database = sqlite(databasePath);
const oldLotOccupancy = getLotOccupancy(oldLotOccupancyId, database);
const newLotOccupancyId = addLotOccupancy({
lotId: oldLotOccupancy.lotId || "",
occupancyTypeId: oldLotOccupancy.occupancyTypeId,
occupancyStartDateString: dateToString(new Date()),
occupancyEndDateString: ""
}, requestSession, database);
const rightNowMillis = Date.now();
for (const occupancyField of oldLotOccupancy.lotOccupancyFields) {
database
.prepare("insert into LotOccupancyFields" +
" (lotOccupancyId, occupancyTypeFieldId, lotOccupancyFieldValue," +
" recordCreate_userName, recordCreate_timeMillis, recordUpdate_userName, recordUpdate_timeMillis)" +
" values (?, ?, ?, ?, ?, ?, ?)")
.run(newLotOccupancyId, occupancyField.occupancyTypeFieldId, occupancyField.lotOccupancyFieldValue, requestSession.user.userName, rightNowMillis, requestSession.user.userName, rightNowMillis);
}
for (const occupant of oldLotOccupancy.lotOccupancyOccupants) {
addLotOccupancyOccupant({
lotOccupancyId: newLotOccupancyId,
lotOccupantTypeId: occupant.lotOccupantTypeId,
occupantName: occupant.occupantName,
occupantAddress1: occupant.occupantAddress1,
occupantAddress2: occupant.occupantAddress2,
occupantCity: occupant.occupantCity,
occupantProvince: occupant.occupantProvince,
occupantPostalCode: occupant.occupantPostalCode,
occupantPhoneNumber: occupant.occupantPhoneNumber,
occupantEmailAddress: occupant.occupantEmailAddress
}, requestSession, database);
}
database.close();
return newLotOccupancyId;
};
export default copyLotOccupancy;

View File

@ -0,0 +1,81 @@
import sqlite from "better-sqlite3";
import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js";
import { getLotOccupancy } from "./getLotOccupancy.js";
import { addLotOccupancy } from "./addLotOccupancy.js";
import { addLotOccupancyOccupant } from "./addLotOccupancyOccupant.js";
import { dateToString } from "@cityssm/expressjs-server-js/dateTimeFns.js";
import type * as recordTypes from "../../types/recordTypes";
export const copyLotOccupancy = (
oldLotOccupancyId: number | string,
requestSession: recordTypes.PartialSession
): number => {
const database = sqlite(databasePath);
const oldLotOccupancy = getLotOccupancy(oldLotOccupancyId, database);
const newLotOccupancyId = addLotOccupancy(
{
lotId: oldLotOccupancy.lotId || "",
occupancyTypeId: oldLotOccupancy.occupancyTypeId,
occupancyStartDateString: dateToString(new Date()),
occupancyEndDateString: ""
},
requestSession,
database
);
// Copy Fields
const rightNowMillis = Date.now();
for (const occupancyField of oldLotOccupancy.lotOccupancyFields) {
database
.prepare(
"insert into LotOccupancyFields" +
" (lotOccupancyId, occupancyTypeFieldId, lotOccupancyFieldValue," +
" recordCreate_userName, recordCreate_timeMillis, recordUpdate_userName, recordUpdate_timeMillis)" +
" values (?, ?, ?, ?, ?, ?, ?)"
)
.run(
newLotOccupancyId,
occupancyField.occupancyTypeFieldId,
occupancyField.lotOccupancyFieldValue,
requestSession.user.userName,
rightNowMillis,
requestSession.user.userName,
rightNowMillis
);
}
// Copy Occupants
for (const occupant of oldLotOccupancy.lotOccupancyOccupants) {
addLotOccupancyOccupant(
{
lotOccupancyId: newLotOccupancyId,
lotOccupantTypeId: occupant.lotOccupantTypeId,
occupantName: occupant.occupantName,
occupantAddress1: occupant.occupantAddress1,
occupantAddress2: occupant.occupantAddress2,
occupantCity: occupant.occupantCity,
occupantProvince: occupant.occupantProvince,
occupantPostalCode: occupant.occupantPostalCode,
occupantPhoneNumber: occupant.occupantPhoneNumber,
occupantEmailAddress: occupant.occupantEmailAddress
},
requestSession,
database
);
}
database.close();
return newLotOccupancyId;
};
export default copyLotOccupancy;

View File

@ -1,3 +1,4 @@
import sqlite from "better-sqlite3";
import type * as recordTypes from "../../types/recordTypes";
export declare const getLotOccupancy: (lotOccupancyId: number | string) => recordTypes.LotOccupancy;
export declare const getLotOccupancy: (lotOccupancyId: number | string, connectedDatabase?: sqlite.Database) => recordTypes.LotOccupancy;
export default getLotOccupancy;

View File

@ -6,8 +6,9 @@ import { getLotOccupancyComments } from "./getLotOccupancyComments.js";
import { getLotOccupancyFields } from "./getLotOccupancyFields.js";
import { getLotOccupancyFees } from "./getLotOccupancyFees.js";
import { getLotOccupancyTransactions } from "./getLotOccupancyTransactions.js";
export const getLotOccupancy = (lotOccupancyId) => {
const database = sqlite(databasePath, {
export const getLotOccupancy = (lotOccupancyId, connectedDatabase) => {
const database = connectedDatabase ||
sqlite(databasePath, {
readonly: true
});
database.function("userFn_dateIntegerToString", dateIntegerToString);
@ -33,7 +34,9 @@ export const getLotOccupancy = (lotOccupancyId) => {
lotOccupancy.lotOccupancyFees = getLotOccupancyFees(lotOccupancyId, database);
lotOccupancy.lotOccupancyTransactions = getLotOccupancyTransactions(lotOccupancyId, database);
}
if (!connectedDatabase) {
database.close();
}
return lotOccupancy;
};
export default getLotOccupancy;

View File

@ -17,9 +17,12 @@ import { getLotOccupancyTransactions } from "./getLotOccupancyTransactions.js";
import type * as recordTypes from "../../types/recordTypes";
export const getLotOccupancy = (
lotOccupancyId: number | string
lotOccupancyId: number | string,
connectedDatabase?: sqlite.Database
): recordTypes.LotOccupancy => {
const database = sqlite(databasePath, {
const database =
connectedDatabase ||
sqlite(databasePath, {
readonly: true
});
@ -44,29 +47,19 @@ export const getLotOccupancy = (
.get(lotOccupancyId);
if (lotOccupancy) {
lotOccupancy.lotOccupancyFields = getLotOccupancyFields(
lotOccupancyId,
database
);
lotOccupancy.lotOccupancyOccupants = getLotOccupancyOccupants(
lotOccupancyId,
database
);
lotOccupancy.lotOccupancyComments = getLotOccupancyComments(
lotOccupancyId,
database
);
lotOccupancy.lotOccupancyFees = getLotOccupancyFees(
lotOccupancyId,
database
);
lotOccupancy.lotOccupancyFields = getLotOccupancyFields(lotOccupancyId, database);
lotOccupancy.lotOccupancyOccupants = getLotOccupancyOccupants(lotOccupancyId, database);
lotOccupancy.lotOccupancyComments = getLotOccupancyComments(lotOccupancyId, database);
lotOccupancy.lotOccupancyFees = getLotOccupancyFees(lotOccupancyId, database);
lotOccupancy.lotOccupancyTransactions = getLotOccupancyTransactions(
lotOccupancyId,
database
);
}
if (!connectedDatabase) {
database.close();
}
return lotOccupancy;
};

View File

@ -53,6 +53,49 @@ Object.defineProperty(exports, "__esModule", { value: true });
formInputElement.addEventListener("change", setUnsavedChanges);
}
if (!isCreate) {
const doCopy = () => {
cityssm.postJSON(los.urlPrefix + "/lotOccupancies/doCopyLotOccupancy", {
lotOccupancyId
}, (responseJSON) => {
var _a;
if (responseJSON.success) {
cityssm.disableNavBlocker();
window.location.href =
los.urlPrefix +
"/lotOccupancies/" +
((_a = responseJSON.lotOccupancyId) === null || _a === void 0 ? void 0 : _a.toString()) +
"/edit";
}
else {
bulmaJS.alert({
title: "Error Copying Record",
message: responseJSON.errorMessage || "",
contextualColorName: "danger"
});
}
});
};
document.querySelector("#button--copyLotOccupancy").addEventListener("click", (clickEvent) => {
clickEvent.preventDefault();
if (hasUnsavedChanges) {
bulmaJS.alert({
title: "Unsaved Changes",
message: "Please save all unsaved changes before continuing.",
contextualColorName: "warning"
});
}
else {
bulmaJS.confirm({
title: "Copy " + exports.aliases.occupancy + " Record as New",
message: "Are you sure you want to copy this record to a new record?",
contextualColorName: "info",
okButton: {
text: "Yes, Copy",
callbackFunction: doCopy
}
});
}
});
document.querySelector("#button--deleteLotOccupancy").addEventListener("click", (clickEvent) => {
clickEvent.preventDefault();
const doDelete = () => {
@ -1104,7 +1147,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
cityssm.escapeHTML(fee.feeName || "") +
"</strong><br />" +
"<small>" +
cityssm.escapeHTML(fee.feeDescription || "").replace(/\n/g, "<br />") +
cityssm
.escapeHTML(fee.feeDescription || "")
.replace(/\n/g, "<br />") +
"</small>";
panelBlockElement.addEventListener("click", tryAddFee);
categoryContainerElement.querySelector(".panel").append(panelBlockElement);

View File

@ -86,8 +86,64 @@ declare const bulmaJS: BulmaJS;
}
if (!isCreate) {
const doCopy = () => {
cityssm.postJSON(
los.urlPrefix + "/lotOccupancies/doCopyLotOccupancy",
{
lotOccupancyId
},
(responseJSON: {
success: boolean;
errorMessage?: string;
lotOccupancyId?: number;
}) => {
if (responseJSON.success) {
cityssm.disableNavBlocker();
window.location.href =
los.urlPrefix +
"/lotOccupancies/" +
responseJSON.lotOccupancyId?.toString() +
"/edit";
} else {
bulmaJS.alert({
title: "Error Copying Record",
message: responseJSON.errorMessage || "",
contextualColorName: "danger"
});
}
}
);
};
(document.querySelector("#button--copyLotOccupancy") as HTMLAnchorElement).addEventListener(
"click",
(clickEvent) => {
clickEvent.preventDefault();
if (hasUnsavedChanges) {
bulmaJS.alert({
title: "Unsaved Changes",
message: "Please save all unsaved changes before continuing.",
contextualColorName: "warning"
});
} else {
bulmaJS.confirm({
title: "Copy " + exports.aliases.occupancy + " Record as New",
message: "Are you sure you want to copy this record to a new record?",
contextualColorName: "info",
okButton: {
text: "Yes, Copy",
callbackFunction: doCopy
}
});
}
}
);
(
document.querySelector("#button--deleteLotOccupancy") as HTMLButtonElement
document.querySelector("#button--deleteLotOccupancy") as HTMLAnchorElement
).addEventListener("click", (clickEvent) => {
clickEvent.preventDefault();
@ -1717,7 +1773,9 @@ declare const bulmaJS: BulmaJS;
cityssm.escapeHTML(fee.feeName || "") +
"</strong><br />" +
"<small>" +
cityssm.escapeHTML(fee.feeDescription || "").replace(/\n/g, "<br />") +
cityssm
.escapeHTML(fee.feeDescription || "")
.replace(/\n/g, "<br />") +
"</small>";
panelBlockElement.addEventListener("click", tryAddFee);

File diff suppressed because one or more lines are too long

View File

@ -7,6 +7,7 @@ import handler_doGetOccupancyTypeFields from "../handlers/lotOccupancies-post/do
import handler_doCreateLotOccupancy from "../handlers/lotOccupancies-post/doCreateLotOccupancy.js";
import handler_edit from "../handlers/lotOccupancies-get/edit.js";
import handler_doUpdateLotOccupancy from "../handlers/lotOccupancies-post/doUpdateLotOccupancy.js";
import handler_doCopyLotOccupancy from "../handlers/lotOccupancies-post/doCopyLotOccupancy.js";
import handler_doDeleteLotOccupancy from "../handlers/lotOccupancies-post/doDeleteLotOccupancy.js";
import handler_doSearchPastOccupants from "../handlers/lotOccupancies-post/doSearchPastOccupants.js";
import handler_doAddLotOccupancyOccupant from "../handlers/lotOccupancies-post/doAddLotOccupancyOccupant.js";
@ -30,6 +31,7 @@ router.post("/doCreateLotOccupancy", permissionHandlers.updatePostHandler, handl
router.get("/:lotOccupancyId", handler_view);
router.get("/:lotOccupancyId/edit", permissionHandlers.updateGetHandler, handler_edit);
router.post("/doUpdateLotOccupancy", permissionHandlers.updatePostHandler, handler_doUpdateLotOccupancy);
router.post("/doCopyLotOccupancy", permissionHandlers.updatePostHandler, handler_doCopyLotOccupancy);
router.post("/doDeleteLotOccupancy", permissionHandlers.updatePostHandler, handler_doDeleteLotOccupancy);
router.post("/doSearchPastOccupants", permissionHandlers.updatePostHandler, handler_doSearchPastOccupants);
router.post("/doAddLotOccupancyOccupant", permissionHandlers.updatePostHandler, handler_doAddLotOccupancyOccupant);

View File

@ -11,6 +11,7 @@ import handler_doCreateLotOccupancy from "../handlers/lotOccupancies-post/doCrea
import handler_edit from "../handlers/lotOccupancies-get/edit.js";
import handler_doUpdateLotOccupancy from "../handlers/lotOccupancies-post/doUpdateLotOccupancy.js";
import handler_doCopyLotOccupancy from "../handlers/lotOccupancies-post/doCopyLotOccupancy.js";
import handler_doDeleteLotOccupancy from "../handlers/lotOccupancies-post/doDeleteLotOccupancy.js";
import handler_doSearchPastOccupants from "../handlers/lotOccupancies-post/doSearchPastOccupants.js";
@ -73,6 +74,12 @@ router.post(
handler_doUpdateLotOccupancy
);
router.post(
"/doCopyLotOccupancy",
permissionHandlers.updatePostHandler,
handler_doCopyLotOccupancy
);
router.post(
"/doDeleteLotOccupancy",
permissionHandlers.updatePostHandler,

View File

@ -282,6 +282,10 @@
</div>
<div class="dropdown-menu">
<div class="dropdown-content">
<a class="dropdown-item" id="button--copyLotOccupancy" href="#">
<span class="icon is-small"><i class="far fa-copy" aria-hidden="true"></i></span>
<span>Copy <%= configFunctions.getProperty("aliases.occupancy") %> Record as New</span>
</a>
<a class="dropdown-item" id="button--deleteLotOccupancy" href="#">
<span class="icon is-small"><i class="fas fa-trash has-text-danger" aria-hidden="true"></i></span>
<span>Delete <%= configFunctions.getProperty("aliases.occupancy") %> Record</span>