lot summaries
parent
89a559d2b5
commit
c1707043e6
|
|
@ -1,14 +1,23 @@
|
|||
import * as configFunctions from "../../helpers/functions.config.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) => {
|
||||
const map = getMap(request.params.mapId);
|
||||
if (!map) {
|
||||
return response.redirect(configFunctions.getProperty("reverseProxy.urlPrefix") +
|
||||
"/maps/?error=mapIdNotFound");
|
||||
return response.redirect(configFunctions.getProperty("reverseProxy.urlPrefix") + "/maps/?error=mapIdNotFound");
|
||||
}
|
||||
const lotTypeSummary = getLotTypeSummary({
|
||||
mapId: map.mapId
|
||||
});
|
||||
const lotStatusSummary = getLotStatusSummary({
|
||||
mapId: map.mapId
|
||||
});
|
||||
response.render("map-view", {
|
||||
headTitle: map.mapName,
|
||||
map
|
||||
map,
|
||||
lotTypeSummary,
|
||||
lotStatusSummary
|
||||
});
|
||||
};
|
||||
export default handler;
|
||||
|
|
|
|||
|
|
@ -3,20 +3,31 @@ import type { RequestHandler } from "express";
|
|||
import * as configFunctions from "../../helpers/functions.config.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) => {
|
||||
const map = getMap(request.params.mapId);
|
||||
|
||||
if (!map) {
|
||||
return response.redirect(
|
||||
configFunctions.getProperty("reverseProxy.urlPrefix") +
|
||||
"/maps/?error=mapIdNotFound"
|
||||
configFunctions.getProperty("reverseProxy.urlPrefix") + "/maps/?error=mapIdNotFound"
|
||||
);
|
||||
}
|
||||
|
||||
const lotTypeSummary = getLotTypeSummary({
|
||||
mapId: map.mapId
|
||||
});
|
||||
|
||||
const lotStatusSummary = getLotStatusSummary({
|
||||
mapId: map.mapId
|
||||
});
|
||||
|
||||
response.render("map-view", {
|
||||
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>
|
||||
|
||||
<% const lotSearchUrl = urlPrefix + "/lots?mapId=" + map.mapId; %>
|
||||
<div class="panel">
|
||||
<h2 class="panel-heading">
|
||||
Related Searches
|
||||
</h2>
|
||||
<div class="panel-block">
|
||||
<a class="button is-link" href="<%= urlPrefix %>/lots?mapId=<%= map.mapId %>">
|
||||
<span class="icon is-small"><i class="fas fa-vector-square" aria-hidden="true"></i></span>
|
||||
<span class="mr-2"><%= configFunctions.getProperty("aliases.lots") %></span>
|
||||
<span class="tag"><%= map.lotCount %></span>
|
||||
</a>
|
||||
<div class="panel-heading">
|
||||
<div class="level is-mobile">
|
||||
<div class="level-left">
|
||||
<div class="level-item">
|
||||
<h2 class="title is-5 has-text-weight-bold">
|
||||
<%= configFunctions.getProperty("aliases.lot") %> Summaries
|
||||
<a class="tag is-link ml-2" href="<%= lotSearchUrl %>">
|
||||
<%= map.lotCount %>
|
||||
</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>
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue