sunrise-cms/helpers/lotOccupancyDB/getLotOccupancies.ts

182 lines
5.8 KiB
TypeScript

import sqlite from "better-sqlite3";
import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js";
import {
dateIntegerToString,
dateStringToInteger,
dateToInteger
} from "@cityssm/expressjs-server-js/dateTimeFns.js";
import { getLotOccupancyOccupants } from "./getLotOccupancyOccupants.js";
import type * as recordTypes from "../../types/recordTypes";
interface GetLotOccupanciesFilters {
lotId?: number | string;
occupancyTime?: "" | "past" | "current" | "future";
occupancyStartDateString?: string;
occupantName?: string;
occupancyTypeId?: number | string;
mapId?: number | string;
lotName?: string;
lotTypeId?: number | string;
workOrderId?: number | string;
}
interface GetLotOccupanciesOptions {
limit: -1 | number;
offset: number;
includeOccupants: boolean;
}
export const getLotOccupancies = (
filters: GetLotOccupanciesFilters,
options: GetLotOccupanciesOptions,
connectedDatabase?: sqlite.Database
): {
count: number;
lotOccupancies: recordTypes.LotOccupancy[];
} => {
const database =
connectedDatabase ||
sqlite(databasePath, {
readonly: true
});
database.function("userFn_dateIntegerToString", dateIntegerToString);
let sqlWhereClause = " where o.recordDelete_timeMillis is null";
const sqlParameters = [];
if (filters.lotId) {
sqlWhereClause += " and o.lotId = ?";
sqlParameters.push(filters.lotId);
}
if (filters.lotName) {
const lotNamePieces = filters.lotName.toLowerCase().split(" ");
for (const lotNamePiece of lotNamePieces) {
sqlWhereClause += " and instr(lower(l.lotName), ?)";
sqlParameters.push(lotNamePiece);
}
}
if (filters.occupantName) {
const occupantNamePieces = filters.occupantName
.toLowerCase()
.split(" ");
for (const occupantNamePiece of occupantNamePieces) {
sqlWhereClause +=
" and o.lotOccupancyId in (select oo.lotOccupancyId from LotOccupancyOccupants oo where oo.recordDelete_timeMillis is null and instr(lower(oo.occupantName), ?))";
sqlParameters.push(occupantNamePiece);
}
}
if (filters.occupancyTypeId) {
sqlWhereClause += " and o.occupancyTypeId = ?";
sqlParameters.push(filters.occupancyTypeId);
}
if (filters.occupancyTime) {
const currentDateString = dateToInteger(new Date());
switch (filters.occupancyTime) {
case "current":
sqlWhereClause +=
" and o.occupancyStartDate <= ? and (o.occupancyEndDate is null or o.occupancyEndDate >= ?)";
sqlParameters.push(currentDateString, currentDateString);
break;
case "past":
sqlWhereClause += " and o.occupancyEndDate < ?";
sqlParameters.push(currentDateString);
break;
case "future":
sqlWhereClause += " and o.occupancyStartDate > ?";
sqlParameters.push(currentDateString);
break;
}
}
if (filters.occupancyStartDateString) {
sqlWhereClause += " and o.occupancyStartDate = ?";
sqlParameters.push(
dateStringToInteger(filters.occupancyStartDateString)
);
}
if (filters.mapId) {
sqlWhereClause += " and l.mapId = ?";
sqlParameters.push(filters.mapId);
}
if (filters.lotTypeId) {
sqlWhereClause += " and l.lotTypeId = ?";
sqlParameters.push(filters.lotTypeId);
}
if (filters.workOrderId) {
sqlWhereClause +=
" and o.lotOccupancyId in (select lotOccupancyId from WorkOrderLotOccupancies where recordDelete_timeMillis is null and workOrderId = ?)";
sqlParameters.push(filters.workOrderId);
}
const count: number = database
.prepare(
"select count(*) as recordCount" +
" from LotOccupancies o" +
" left join Lots l on o.lotId = l.lotId" +
sqlWhereClause
)
.get(sqlParameters).recordCount;
let lotOccupancies: recordTypes.LotOccupancy[] = [];
if (count > 0) {
lotOccupancies = database
.prepare(
"select o.lotOccupancyId," +
" o.occupancyTypeId, t.occupancyType," +
" o.lotId, l.lotName," +
" l.mapId, m.mapName," +
" o.occupancyStartDate, userFn_dateIntegerToString(o.occupancyStartDate) as occupancyStartDateString," +
" o.occupancyEndDate, userFn_dateIntegerToString(o.occupancyEndDate) as occupancyEndDateString" +
" from LotOccupancies o" +
" left join OccupancyTypes t on o.occupancyTypeId = t.occupancyTypeId" +
" left join Lots l on o.lotId = l.lotId" +
" left join Maps m on l.mapId = m.mapId" +
sqlWhereClause +
" order by o.occupancyStartDate desc, ifnull(o.occupancyEndDate, 99999999) desc, l.lotName, o.lotId" +
(options.limit !== -1
? " limit " +
options.limit +
" offset " +
options.offset
: "")
)
.all(sqlParameters);
if (options.includeOccupants) {
for (const lotOccupancy of lotOccupancies) {
lotOccupancy.lotOccupancyOccupants = getLotOccupancyOccupants(
lotOccupancy.lotOccupancyId,
database
);
}
}
}
if (!connectedDatabase) {
database.close();
}
return {
count,
lotOccupancies
};
};
export default getLotOccupancies;