lot summaries
parent
89a559d2b5
commit
c1707043e6
|
|
@ -1,14 +1,23 @@
|
||||||
import * as configFunctions from "../../helpers/functions.config.js";
|
import * as configFunctions from "../../helpers/functions.config.js";
|
||||||
import { getMap } from "../../helpers/lotOccupancyDB/getMap.js";
|
import { getMap } from "../../helpers/lotOccupancyDB/getMap.js";
|
||||||
|
import { getLotStatusSummary } from "../../helpers/lotOccupancyDB/getLotStatusSummary.js";
|
||||||
|
import { getLotTypeSummary } from "../../helpers/lotOccupancyDB/getLotTypeSummary.js";
|
||||||
export const handler = (request, response) => {
|
export const handler = (request, response) => {
|
||||||
const map = getMap(request.params.mapId);
|
const map = getMap(request.params.mapId);
|
||||||
if (!map) {
|
if (!map) {
|
||||||
return response.redirect(configFunctions.getProperty("reverseProxy.urlPrefix") +
|
return response.redirect(configFunctions.getProperty("reverseProxy.urlPrefix") + "/maps/?error=mapIdNotFound");
|
||||||
"/maps/?error=mapIdNotFound");
|
|
||||||
}
|
}
|
||||||
|
const lotTypeSummary = getLotTypeSummary({
|
||||||
|
mapId: map.mapId
|
||||||
|
});
|
||||||
|
const lotStatusSummary = getLotStatusSummary({
|
||||||
|
mapId: map.mapId
|
||||||
|
});
|
||||||
response.render("map-view", {
|
response.render("map-view", {
|
||||||
headTitle: map.mapName,
|
headTitle: map.mapName,
|
||||||
map
|
map,
|
||||||
|
lotTypeSummary,
|
||||||
|
lotStatusSummary
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
export default handler;
|
export default handler;
|
||||||
|
|
|
||||||
|
|
@ -3,20 +3,31 @@ import type { RequestHandler } from "express";
|
||||||
import * as configFunctions from "../../helpers/functions.config.js";
|
import * as configFunctions from "../../helpers/functions.config.js";
|
||||||
|
|
||||||
import { getMap } from "../../helpers/lotOccupancyDB/getMap.js";
|
import { getMap } from "../../helpers/lotOccupancyDB/getMap.js";
|
||||||
|
import { getLotStatusSummary } from "../../helpers/lotOccupancyDB/getLotStatusSummary.js";
|
||||||
|
import { getLotTypeSummary } from "../../helpers/lotOccupancyDB/getLotTypeSummary.js";
|
||||||
|
|
||||||
export const handler: RequestHandler = (request, response) => {
|
export const handler: RequestHandler = (request, response) => {
|
||||||
const map = getMap(request.params.mapId);
|
const map = getMap(request.params.mapId);
|
||||||
|
|
||||||
if (!map) {
|
if (!map) {
|
||||||
return response.redirect(
|
return response.redirect(
|
||||||
configFunctions.getProperty("reverseProxy.urlPrefix") +
|
configFunctions.getProperty("reverseProxy.urlPrefix") + "/maps/?error=mapIdNotFound"
|
||||||
"/maps/?error=mapIdNotFound"
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const lotTypeSummary = getLotTypeSummary({
|
||||||
|
mapId: map.mapId
|
||||||
|
});
|
||||||
|
|
||||||
|
const lotStatusSummary = getLotStatusSummary({
|
||||||
|
mapId: map.mapId
|
||||||
|
});
|
||||||
|
|
||||||
response.render("map-view", {
|
response.render("map-view", {
|
||||||
headTitle: map.mapName,
|
headTitle: map.mapName,
|
||||||
map
|
map,
|
||||||
|
lotTypeSummary,
|
||||||
|
lotStatusSummary
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
import type * as recordTypes from "../../types/recordTypes";
|
||||||
|
interface GetFilters {
|
||||||
|
mapId?: number | string;
|
||||||
|
}
|
||||||
|
interface LotStatusSummary extends recordTypes.LotStatus {
|
||||||
|
lotCount: number;
|
||||||
|
}
|
||||||
|
export declare const getLotStatusSummary: (filters?: GetFilters) => LotStatusSummary[];
|
||||||
|
export default getLotStatusSummary;
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
import sqlite from "better-sqlite3";
|
||||||
|
import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js";
|
||||||
|
export const getLotStatusSummary = (filters) => {
|
||||||
|
const database = sqlite(databasePath, {
|
||||||
|
readonly: true
|
||||||
|
});
|
||||||
|
let sqlWhereClause = " where l.recordDelete_timeMillis is null";
|
||||||
|
const sqlParameters = [];
|
||||||
|
if (filters && filters.mapId) {
|
||||||
|
sqlWhereClause += " and l.mapId = ?";
|
||||||
|
sqlParameters.push(filters.mapId);
|
||||||
|
}
|
||||||
|
const lotStatuses = database
|
||||||
|
.prepare("select s.lotStatusId, s.lotStatus, count(l.lotId) as lotCount" +
|
||||||
|
" from Lots l" +
|
||||||
|
" left join LotStatuses s on l.lotStatusId = s.lotStatusId" +
|
||||||
|
sqlWhereClause +
|
||||||
|
" group by s.lotStatusId, s.lotStatus, s.orderNumber" +
|
||||||
|
" order by s.orderNumber")
|
||||||
|
.all(sqlParameters);
|
||||||
|
database.close();
|
||||||
|
return lotStatuses;
|
||||||
|
};
|
||||||
|
export default getLotStatusSummary;
|
||||||
|
|
@ -0,0 +1,44 @@
|
||||||
|
import sqlite from "better-sqlite3";
|
||||||
|
|
||||||
|
import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js";
|
||||||
|
|
||||||
|
import type * as recordTypes from "../../types/recordTypes";
|
||||||
|
|
||||||
|
interface GetFilters {
|
||||||
|
mapId?: number | string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface LotStatusSummary extends recordTypes.LotStatus {
|
||||||
|
lotCount: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getLotStatusSummary = (filters?: GetFilters): LotStatusSummary[] => {
|
||||||
|
const database = sqlite(databasePath, {
|
||||||
|
readonly: true
|
||||||
|
});
|
||||||
|
|
||||||
|
let sqlWhereClause = " where l.recordDelete_timeMillis is null";
|
||||||
|
const sqlParameters = [];
|
||||||
|
|
||||||
|
if (filters && filters.mapId) {
|
||||||
|
sqlWhereClause += " and l.mapId = ?";
|
||||||
|
sqlParameters.push(filters.mapId);
|
||||||
|
}
|
||||||
|
|
||||||
|
const lotStatuses: LotStatusSummary[] = database
|
||||||
|
.prepare(
|
||||||
|
"select s.lotStatusId, s.lotStatus, count(l.lotId) as lotCount" +
|
||||||
|
" from Lots l" +
|
||||||
|
" left join LotStatuses s on l.lotStatusId = s.lotStatusId" +
|
||||||
|
sqlWhereClause +
|
||||||
|
" group by s.lotStatusId, s.lotStatus, s.orderNumber" +
|
||||||
|
" order by s.orderNumber"
|
||||||
|
)
|
||||||
|
.all(sqlParameters);
|
||||||
|
|
||||||
|
database.close();
|
||||||
|
|
||||||
|
return lotStatuses;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default getLotStatusSummary;
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
import type * as recordTypes from "../../types/recordTypes";
|
||||||
|
interface GetFilters {
|
||||||
|
mapId?: number | string;
|
||||||
|
}
|
||||||
|
interface LotTypeSummary extends recordTypes.LotType {
|
||||||
|
lotCount: number;
|
||||||
|
}
|
||||||
|
export declare const getLotTypeSummary: (filters?: GetFilters) => LotTypeSummary[];
|
||||||
|
export default getLotTypeSummary;
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
import sqlite from "better-sqlite3";
|
||||||
|
import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js";
|
||||||
|
export const getLotTypeSummary = (filters) => {
|
||||||
|
const database = sqlite(databasePath, {
|
||||||
|
readonly: true
|
||||||
|
});
|
||||||
|
let sqlWhereClause = " where l.recordDelete_timeMillis is null";
|
||||||
|
const sqlParameters = [];
|
||||||
|
if (filters && filters.mapId) {
|
||||||
|
sqlWhereClause += " and l.mapId = ?";
|
||||||
|
sqlParameters.push(filters.mapId);
|
||||||
|
}
|
||||||
|
const lotTypes = database
|
||||||
|
.prepare("select t.lotTypeId, t.lotType, count(l.lotId) as lotCount" +
|
||||||
|
" from Lots l" +
|
||||||
|
" left join LotTypes t on l.lotTypeId = t.lotTypeId" +
|
||||||
|
sqlWhereClause +
|
||||||
|
" group by t.lotTypeId, t.lotType, t.orderNumber" +
|
||||||
|
" order by t.orderNumber")
|
||||||
|
.all(sqlParameters);
|
||||||
|
database.close();
|
||||||
|
return lotTypes;
|
||||||
|
};
|
||||||
|
export default getLotTypeSummary;
|
||||||
|
|
@ -0,0 +1,44 @@
|
||||||
|
import sqlite from "better-sqlite3";
|
||||||
|
|
||||||
|
import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js";
|
||||||
|
|
||||||
|
import type * as recordTypes from "../../types/recordTypes";
|
||||||
|
|
||||||
|
interface GetFilters {
|
||||||
|
mapId?: number | string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface LotTypeSummary extends recordTypes.LotType {
|
||||||
|
lotCount: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getLotTypeSummary = (filters?: GetFilters): LotTypeSummary[] => {
|
||||||
|
const database = sqlite(databasePath, {
|
||||||
|
readonly: true
|
||||||
|
});
|
||||||
|
|
||||||
|
let sqlWhereClause = " where l.recordDelete_timeMillis is null";
|
||||||
|
const sqlParameters = [];
|
||||||
|
|
||||||
|
if (filters && filters.mapId) {
|
||||||
|
sqlWhereClause += " and l.mapId = ?";
|
||||||
|
sqlParameters.push(filters.mapId);
|
||||||
|
}
|
||||||
|
|
||||||
|
const lotTypes: LotTypeSummary[] = database
|
||||||
|
.prepare(
|
||||||
|
"select t.lotTypeId, t.lotType, count(l.lotId) as lotCount" +
|
||||||
|
" from Lots l" +
|
||||||
|
" left join LotTypes t on l.lotTypeId = t.lotTypeId" +
|
||||||
|
sqlWhereClause +
|
||||||
|
" group by t.lotTypeId, t.lotType, t.orderNumber" +
|
||||||
|
" order by t.orderNumber"
|
||||||
|
)
|
||||||
|
.all(sqlParameters);
|
||||||
|
|
||||||
|
database.close();
|
||||||
|
|
||||||
|
return lotTypes;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default getLotTypeSummary;
|
||||||
|
|
@ -94,16 +94,94 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<% const lotSearchUrl = urlPrefix + "/lots?mapId=" + map.mapId; %>
|
||||||
<div class="panel">
|
<div class="panel">
|
||||||
<h2 class="panel-heading">
|
<div class="panel-heading">
|
||||||
Related Searches
|
<div class="level is-mobile">
|
||||||
</h2>
|
<div class="level-left">
|
||||||
<div class="panel-block">
|
<div class="level-item">
|
||||||
<a class="button is-link" href="<%= urlPrefix %>/lots?mapId=<%= map.mapId %>">
|
<h2 class="title is-5 has-text-weight-bold">
|
||||||
<span class="icon is-small"><i class="fas fa-vector-square" aria-hidden="true"></i></span>
|
<%= configFunctions.getProperty("aliases.lot") %> Summaries
|
||||||
<span class="mr-2"><%= configFunctions.getProperty("aliases.lots") %></span>
|
<a class="tag is-link ml-2" href="<%= lotSearchUrl %>">
|
||||||
<span class="tag"><%= map.lotCount %></span>
|
<%= map.lotCount %>
|
||||||
</a>
|
</a>
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="level-right">
|
||||||
|
<div class="level-item">
|
||||||
|
<a class="button is-small is-link has-text-weight-normal" href="<%=urlPrefix %>/reports/lots-byMapId?mapId=<%= map.mapId %>" download>
|
||||||
|
<span class="icon"><i class="fas fa-download" aria-hidden="true"></i></span>
|
||||||
|
<span>Export All</span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="panel-block is-block">
|
||||||
|
<% if (map.lotCount === 0) { %>
|
||||||
|
<div class="message is-info">
|
||||||
|
<p class="message-body">
|
||||||
|
There are no <%= configFunctions.getProperty("aliases.lots").toLowerCase() %>
|
||||||
|
associated with this <%= configFunctions.getProperty("aliases.map").toLowerCase() %>.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<% } else { %>
|
||||||
|
<div class="columns">
|
||||||
|
<div class="column">
|
||||||
|
<table class="table is-fullwidth is-striped is-hoverable">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Type</th>
|
||||||
|
<th class="has-text-right">
|
||||||
|
<%= configFunctions.getProperty("aliases.lot") %> Count
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<% for (const lotType of lotTypeSummary) { %>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<a class="has-text-weight-bold" href="<%= lotSearchUrl %>&lotTypeId=<%= lotType.lotTypeId %>">
|
||||||
|
<%= lotType.lotType %>
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
<td class="has-text-right">
|
||||||
|
<%= lotType.lotCount %>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<% } %>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div class="column">
|
||||||
|
<table class="table is-fullwidth is-striped is-hoverable">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Status</th>
|
||||||
|
<th class="has-text-right">
|
||||||
|
<%= configFunctions.getProperty("aliases.lot") %> Count
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<% for (const lotStatus of lotStatusSummary) { %>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<a class="has-text-weight-bold" href="<%= lotSearchUrl %>&lotStatusId=<%= lotStatus.lotStatusId %>">
|
||||||
|
<%= lotStatus.lotStatus %>
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
<td class="has-text-right">
|
||||||
|
<%= lotStatus.lotCount %>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<% } %>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<% } %>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue