Fix ? / 0.00h display for in-progress shifts
Frontend: pivotWfShifts now skips entries where times='?' and hours=0 — immediately removes the visual glitch from any stale DB rows. Backend: when today's timesheet pull finds no completed shifts, write a source='workforce' row instead of skipping, so the stale timesheet entry is overwritten and rota sync can restore schedule data for today. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
e3c8f143ef
commit
b194cf1278
5 changed files with 30 additions and 28 deletions
|
|
@ -106,13 +106,13 @@ export async function runTimesheetSync(from, to) {
|
|||
while (day <= toDate) {
|
||||
const d = fmtDate(day)
|
||||
const staffForDate = byDate[d] || []
|
||||
// For today: only write a timesheet row if at least one shift has clocked out.
|
||||
// An empty row would overwrite rota data with nothing while staff are still working.
|
||||
if (d === today && staffForDate.length === 0) {
|
||||
day.setDate(day.getDate() + 1)
|
||||
continue
|
||||
// Nobody has clocked out yet — write a workforce-sourced row so this clears any
|
||||
// stale timesheet entry and rota sync can overwrite with schedule data again
|
||||
dailyRows.push({ date: d, staff: [], source: 'workforce' })
|
||||
} else {
|
||||
dailyRows.push({ date: d, staff: staffForDate, source: 'timesheet' })
|
||||
}
|
||||
dailyRows.push({ date: d, staff: staffForDate, source: 'timesheet' })
|
||||
day.setDate(day.getDate() + 1)
|
||||
}
|
||||
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
2
frontend/dist/index.html
vendored
2
frontend/dist/index.html
vendored
|
|
@ -5,7 +5,7 @@
|
|||
<meta name="viewport" content="width=1280" />
|
||||
<meta name="theme-color" content="#2d6a4f" />
|
||||
<title>HK Planner</title>
|
||||
<script type="module" crossorigin src="/hk-planner/assets/index-CY2exSVU.js"></script>
|
||||
<script type="module" crossorigin src="/hk-planner/assets/index-ag4V1yp1.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="/hk-planner/assets/index-B7_UXJgZ.css">
|
||||
<link rel="manifest" href="/hk-planner/manifest.webmanifest"><script id="vite-plugin-pwa:register-sw" src="/hk-planner/registerSW.js"></script></head>
|
||||
<body>
|
||||
|
|
|
|||
2
frontend/dist/sw.js
vendored
2
frontend/dist/sw.js
vendored
|
|
@ -1 +1 @@
|
|||
if(!self.define){let e,i={};const n=(n,s)=>(n=new URL(n+".js",s).href,i[n]||new Promise(i=>{if("document"in self){const e=document.createElement("script");e.src=n,e.onload=i,document.head.appendChild(e)}else e=n,importScripts(n),i()}).then(()=>{let e=i[n];if(!e)throw new Error(`Module ${n} didn’t register its module`);return e}));self.define=(s,r)=>{const o=e||("document"in self?document.currentScript.src:"")||location.href;if(i[o])return;let t={};const d=e=>n(e,o),c={module:{uri:o},exports:t,require:d};i[o]=Promise.all(s.map(e=>c[e]||d(e))).then(e=>(r(...e),t))}}define(["./workbox-9c191d2f"],function(e){"use strict";self.skipWaiting(),e.clientsClaim(),e.precacheAndRoute([{url:"registerSW.js",revision:"a2c395d8c225f1b3ea12388f15189bce"},{url:"index.html",revision:"57d49ab8e52eda5d76e17210e69e20a4"},{url:"icons/icon-512.png",revision:"c32202b9deed67ef38331f63dec9d1c8"},{url:"icons/icon-192.png",revision:"46ece317d50d10b8f5e225e073b3221d"},{url:"assets/index-CY2exSVU.js",revision:null},{url:"assets/index-B7_UXJgZ.css",revision:null},{url:"manifest.webmanifest",revision:"c2510de876adb84db0c4b300b71216fa"}],{}),e.cleanupOutdatedCaches(),e.registerRoute(new e.NavigationRoute(e.createHandlerBoundToURL("/hk-planner/index.html"),{denylist:[/\/api\//]}))});
|
||||
if(!self.define){let e,i={};const n=(n,s)=>(n=new URL(n+".js",s).href,i[n]||new Promise(i=>{if("document"in self){const e=document.createElement("script");e.src=n,e.onload=i,document.head.appendChild(e)}else e=n,importScripts(n),i()}).then(()=>{let e=i[n];if(!e)throw new Error(`Module ${n} didn’t register its module`);return e}));self.define=(s,r)=>{const o=e||("document"in self?document.currentScript.src:"")||location.href;if(i[o])return;let t={};const d=e=>n(e,o),c={module:{uri:o},exports:t,require:d};i[o]=Promise.all(s.map(e=>c[e]||d(e))).then(e=>(r(...e),t))}}define(["./workbox-9c191d2f"],function(e){"use strict";self.skipWaiting(),e.clientsClaim(),e.precacheAndRoute([{url:"registerSW.js",revision:"a2c395d8c225f1b3ea12388f15189bce"},{url:"index.html",revision:"de42cfe99caaa236e4dd89d982fdd24a"},{url:"icons/icon-512.png",revision:"c32202b9deed67ef38331f63dec9d1c8"},{url:"icons/icon-192.png",revision:"46ece317d50d10b8f5e225e073b3221d"},{url:"assets/index-ag4V1yp1.js",revision:null},{url:"assets/index-B7_UXJgZ.css",revision:null},{url:"manifest.webmanifest",revision:"c2510de876adb84db0c4b300b71216fa"}],{}),e.cleanupOutdatedCaches(),e.registerRoute(new e.NavigationRoute(e.createHandlerBoundToURL("/hk-planner/index.html"),{denylist:[/\/api\//]}))});
|
||||
|
|
|
|||
|
|
@ -836,6 +836,8 @@ function pivotWfShifts(wfShifts: Record<string, WfDayData>, dates: string[]): Wf
|
|||
const day = wfShifts[date]
|
||||
if (!day) continue
|
||||
for (const s of day.staff) {
|
||||
// Skip in-progress timesheet entries — clocked in but no clock-out time yet
|
||||
if (s.times === '?' && s.hours === 0) continue
|
||||
if (!members[s.id]) members[s.id] = { id: s.id, name: s.name, days: {} }
|
||||
members[s.id].days[date] = { hours: s.hours, times: s.times, status: s.status }
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue