244 lines
7.2 KiB
TypeScript
244 lines
7.2 KiB
TypeScript
import {
|
|
dateIntegerToString,
|
|
dateStringToInteger
|
|
} from '@cityssm/utils-datetime'
|
|
import type { PoolConnection } from 'better-sqlite-pool'
|
|
|
|
import { getOccupancyTypeById } from '../helpers/functions.cache.js'
|
|
import * as configFunctions from '../helpers/functions.config.js'
|
|
import {
|
|
getLotNameWhereClause,
|
|
getOccupancyTimeWhereClause,
|
|
getOccupantNameWhereClause
|
|
} from '../helpers/functions.sqlFilters.js'
|
|
import type { LotOccupancy } from '../types/recordTypes.js'
|
|
|
|
import { getLotOccupancyFees } from './getLotOccupancyFees.js'
|
|
import { getLotOccupancyOccupants } from './getLotOccupancyOccupants.js'
|
|
import { getLotOccupancyTransactions } from './getLotOccupancyTransactions.js'
|
|
import { acquireConnection } from './pool.js'
|
|
|
|
interface GetLotOccupanciesFilters {
|
|
lotId?: number | string
|
|
occupancyTime?: '' | 'past' | 'current' | 'future'
|
|
occupancyStartDateString?: string
|
|
occupancyEffectiveDateString?: string
|
|
occupantName?: string
|
|
occupancyTypeId?: number | string
|
|
mapId?: number | string
|
|
lotNameSearchType?: '' | 'startsWith' | 'endsWith'
|
|
lotName?: string
|
|
lotTypeId?: number | string
|
|
workOrderId?: number | string
|
|
notWorkOrderId?: number | string
|
|
}
|
|
|
|
interface GetLotOccupanciesOptions {
|
|
limit: -1 | number
|
|
offset: number
|
|
includeOccupants: boolean
|
|
includeFees: boolean
|
|
includeTransactions: boolean
|
|
}
|
|
|
|
function buildWhereClause(filters: GetLotOccupanciesFilters): {
|
|
sqlWhereClause: string
|
|
sqlParameters: unknown[]
|
|
} {
|
|
let sqlWhereClause = ' where o.recordDelete_timeMillis is null'
|
|
const sqlParameters: unknown[] = []
|
|
|
|
if ((filters.lotId ?? '') !== '') {
|
|
sqlWhereClause += ' and o.lotId = ?'
|
|
sqlParameters.push(filters.lotId)
|
|
}
|
|
|
|
const lotNameFilters = getLotNameWhereClause(
|
|
filters.lotName,
|
|
filters.lotNameSearchType ?? '',
|
|
'l'
|
|
)
|
|
sqlWhereClause += lotNameFilters.sqlWhereClause
|
|
sqlParameters.push(...lotNameFilters.sqlParameters)
|
|
|
|
const occupantNameFilters = getOccupantNameWhereClause(
|
|
filters.occupantName,
|
|
'o'
|
|
)
|
|
if (occupantNameFilters.sqlParameters.length > 0) {
|
|
sqlWhereClause +=
|
|
' and o.lotOccupancyId in (select lotOccupancyId from LotOccupancyOccupants o where recordDelete_timeMillis is null' +
|
|
occupantNameFilters.sqlWhereClause +
|
|
')'
|
|
sqlParameters.push(...occupantNameFilters.sqlParameters)
|
|
}
|
|
|
|
if ((filters.occupancyTypeId ?? '') !== '') {
|
|
sqlWhereClause += ' and o.occupancyTypeId = ?'
|
|
sqlParameters.push(filters.occupancyTypeId)
|
|
}
|
|
|
|
const occupancyTimeFilters = getOccupancyTimeWhereClause(
|
|
filters.occupancyTime ?? '',
|
|
'o'
|
|
)
|
|
sqlWhereClause += occupancyTimeFilters.sqlWhereClause
|
|
sqlParameters.push(...occupancyTimeFilters.sqlParameters)
|
|
|
|
if ((filters.occupancyStartDateString ?? '') !== '') {
|
|
sqlWhereClause += ' and o.occupancyStartDate = ?'
|
|
sqlParameters.push(dateStringToInteger(filters.occupancyStartDateString!))
|
|
}
|
|
|
|
if ((filters.occupancyEffectiveDateString ?? '') !== '') {
|
|
sqlWhereClause += ` and (
|
|
o.occupancyEndDate is null
|
|
or (o.occupancyStartDate <= ? and o.occupancyEndDate >= ?)
|
|
)`
|
|
sqlParameters.push(
|
|
dateStringToInteger(filters.occupancyEffectiveDateString!),
|
|
dateStringToInteger(filters.occupancyEffectiveDateString!)
|
|
)
|
|
}
|
|
|
|
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)
|
|
}
|
|
|
|
if ((filters.notWorkOrderId ?? '') !== '') {
|
|
sqlWhereClause +=
|
|
' and o.lotOccupancyId not in (select lotOccupancyId from WorkOrderLotOccupancies where recordDelete_timeMillis is null and workOrderId = ?)'
|
|
sqlParameters.push(filters.notWorkOrderId)
|
|
}
|
|
|
|
return {
|
|
sqlWhereClause,
|
|
sqlParameters
|
|
}
|
|
}
|
|
|
|
async function addInclusions(
|
|
lotOccupancy: LotOccupancy,
|
|
options: GetLotOccupanciesOptions,
|
|
database: PoolConnection
|
|
): Promise<LotOccupancy> {
|
|
if (options.includeFees) {
|
|
lotOccupancy.lotOccupancyFees = await getLotOccupancyFees(
|
|
lotOccupancy.lotOccupancyId,
|
|
database
|
|
)
|
|
}
|
|
|
|
if (options.includeTransactions) {
|
|
lotOccupancy.lotOccupancyTransactions = await getLotOccupancyTransactions(
|
|
lotOccupancy.lotOccupancyId,
|
|
{ includeIntegrations: false },
|
|
database
|
|
)
|
|
}
|
|
|
|
if (options.includeOccupants) {
|
|
lotOccupancy.lotOccupancyOccupants = await getLotOccupancyOccupants(
|
|
lotOccupancy.lotOccupancyId,
|
|
database
|
|
)
|
|
}
|
|
|
|
return lotOccupancy
|
|
}
|
|
|
|
export async function getLotOccupancies(
|
|
filters: GetLotOccupanciesFilters,
|
|
options: GetLotOccupanciesOptions,
|
|
connectedDatabase?: PoolConnection
|
|
): Promise<{ count: number; lotOccupancies: LotOccupancy[] }> {
|
|
const database = connectedDatabase ?? (await acquireConnection())
|
|
|
|
database.function('userFn_dateIntegerToString', dateIntegerToString)
|
|
|
|
const { sqlWhereClause, sqlParameters } = buildWhereClause(filters)
|
|
|
|
let count = options.limit
|
|
|
|
const isLimited = options.limit !== -1
|
|
|
|
if (isLimited) {
|
|
count = (
|
|
database
|
|
.prepare(
|
|
`select count(*) as recordCount
|
|
from LotOccupancies o
|
|
left join Lots l on o.lotId = l.lotId
|
|
${sqlWhereClause}`
|
|
)
|
|
.get(sqlParameters) as { recordCount: number }
|
|
).recordCount
|
|
}
|
|
|
|
let lotOccupancies: LotOccupancy[] = []
|
|
|
|
if (count !== 0) {
|
|
lotOccupancies = database
|
|
.prepare(
|
|
`select o.lotOccupancyId,
|
|
o.occupancyTypeId, t.occupancyType,
|
|
o.lotId, lt.lotType, 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 LotTypes lt on l.lotTypeId = lt.lotTypeId
|
|
left join Maps m on l.mapId = m.mapId
|
|
${sqlWhereClause}
|
|
order by o.occupancyStartDate desc, ifnull(o.occupancyEndDate, 99999999) desc, l.lotName, o.lotId, o.lotOccupancyId desc` +
|
|
(isLimited ? ` limit ${options.limit} offset ${options.offset}` : '')
|
|
)
|
|
.all(sqlParameters) as LotOccupancy[]
|
|
|
|
if (!isLimited) {
|
|
count = lotOccupancies.length
|
|
}
|
|
|
|
for (const lotOccupancy of lotOccupancies) {
|
|
const occupancyType = await getOccupancyTypeById(
|
|
lotOccupancy.occupancyTypeId!
|
|
)
|
|
|
|
if (occupancyType !== undefined) {
|
|
lotOccupancy.printEJS = (
|
|
occupancyType.occupancyTypePrints ?? []
|
|
).includes('*')
|
|
? configFunctions.getConfigProperty('settings.lotOccupancy.prints')[0]
|
|
: occupancyType.occupancyTypePrints![0]
|
|
}
|
|
|
|
await addInclusions(lotOccupancy, options, database)
|
|
}
|
|
}
|
|
|
|
if (connectedDatabase === undefined) {
|
|
database.release()
|
|
}
|
|
|
|
return {
|
|
count,
|
|
lotOccupancies
|
|
}
|
|
}
|
|
|
|
export default getLotOccupancies
|