Closes the user-reported symptom where washes spanning midnight fell outside the visible date window when navigating from an invoice-period flag. Changes: - Add FLAGGED_WASH_DATE_WINDOW_DAYS = 7 constant - Add shiftDateOnly() helper that pads an ISO-8601 date by ±N days (UTC math, no DST drift) - initialDateFrom/initialDateTo now compute [start - 7d, start + 7d] when a flagged wash is in the route - Add vitest source assertion to lock the new behavior Test result: 68/68 vitest passed (was 67, +1 new test) Refs TRU-10
103 lines
3.5 KiB
Vue
103 lines
3.5 KiB
Vue
<script setup lang="ts">
|
|
import XLVaskUsagePagination from "@/components/displays/pagination/models/DepartmentPos/XLVaskUsagePagination.vue";
|
|
import { dates } from "@/views/dashboards/superUserDashboard/InvoicingBillingPeriod/imports/InvoicingBillingPeriodImportDates.vue";
|
|
import { computed } from "vue";
|
|
import { useRoute } from "vue-router";
|
|
import i18n from "@/i18n";
|
|
|
|
/**
|
|
* Number of days to widen the date window on either side of a flagged
|
|
* wash's `start_time` when navigating to the Selvvask view from a
|
|
* flag-link in the invoice period review.
|
|
*
|
|
* The single-day window shipped in #304 was sufficient when the wash
|
|
* always landed on the same calendar day, but real-world data shows
|
|
* washes that "span midnight" (e.g. a wash at 23:50 visible at 00:10)
|
|
* would fall outside the visible range. Widening to ±7 days makes
|
|
* the highlighted wash always visible regardless of which side of
|
|
* midnight it lands on.
|
|
*/
|
|
const FLAGGED_WASH_DATE_WINDOW_DAYS = 7;
|
|
|
|
const DATE_ONLY_PATTERN = /^(\d{4})-(\d{2})-(\d{2})$/;
|
|
|
|
const parseRouteDateOnly = (value: any) => {
|
|
const rawValue = Array.isArray(value) ? String(value[0] ?? "") : String(value ?? "");
|
|
const match = DATE_ONLY_PATTERN.exec(rawValue.trim());
|
|
if (!match) {
|
|
return "";
|
|
}
|
|
return `${match[1]}-${match[2]}-${match[3]}`;
|
|
};
|
|
|
|
/**
|
|
* Pad an ISO-8601 date string (`YYYY-MM-DD`) by `±days` and return a
|
|
* new `YYYY-MM-DD` string. Invalid inputs return "".
|
|
*/
|
|
const shiftDateOnly = (dateOnly: string, days: number): string => {
|
|
if (dateOnly === "") {
|
|
return "";
|
|
}
|
|
const match = DATE_ONLY_PATTERN.exec(dateOnly);
|
|
if (!match) {
|
|
return "";
|
|
}
|
|
const utc = Date.UTC(
|
|
Number.parseInt(match[1], 10),
|
|
Number.parseInt(match[2], 10) - 1,
|
|
Number.parseInt(match[3], 10),
|
|
);
|
|
const shifted = new Date(utc + days * 24 * 60 * 60 * 1000);
|
|
if (Number.isNaN(shifted.getTime())) {
|
|
return "";
|
|
}
|
|
const yyyy = shifted.getUTCFullYear();
|
|
const mm = String(shifted.getUTCMonth() + 1).padStart(2, "0");
|
|
const dd = String(shifted.getUTCDate()).padStart(2, "0");
|
|
return `${yyyy}-${mm}-${dd}`;
|
|
};
|
|
|
|
const route = useRoute();
|
|
const highlightedUsageLogId = computed(() => {
|
|
const parsedId = Number.parseInt(String(route.query.xlvaskUsageLogId || ""), 10);
|
|
return Number.isInteger(parsedId) && parsedId > 0 ? parsedId : 0;
|
|
});
|
|
|
|
const flaggedWashStartDate = computed(() => parseRouteDateOnly(route.query.xlvaskUsageLogStartTime));
|
|
|
|
/**
|
|
* Date window for the Selvvask view:
|
|
* - If a flagged wash start time is in the route, open a ±7d window
|
|
* around it so the highlighted wash is always visible.
|
|
* - Otherwise fall back to the current period date range.
|
|
*/
|
|
const initialDateFrom = computed(() => {
|
|
if (flaggedWashStartDate.value) {
|
|
return shiftDateOnly(flaggedWashStartDate.value, -FLAGGED_WASH_DATE_WINDOW_DAYS);
|
|
}
|
|
return dates.computed.formattedStartDate.value;
|
|
});
|
|
|
|
const initialDateTo = computed(() => {
|
|
if (flaggedWashStartDate.value) {
|
|
return shiftDateOnly(flaggedWashStartDate.value, FLAGGED_WASH_DATE_WINDOW_DAYS);
|
|
}
|
|
return dates.computed.formattedEndDate.value;
|
|
});
|
|
|
|
const selfWashTitle = computed(() => i18n.global.t("nav.self_wash"));
|
|
</script>
|
|
|
|
<template>
|
|
<section data-testid="invoicing-period-self-wash-view">
|
|
<XLVaskUsagePagination
|
|
:title="selfWashTitle"
|
|
:initial-date-from="initialDateFrom"
|
|
:initial-date-to="initialDateTo"
|
|
:inherit-period-filters="true"
|
|
:load-all-at-once="false"
|
|
:highlight-usage-log-id="highlightedUsageLogId"
|
|
/>
|
|
</section>
|
|
</template>
|