From b6629d0455ccb41fc5666aa7c543ce24f43da4ff Mon Sep 17 00:00:00 2001 From: manglemix Date: Tue, 14 Jan 2025 23:35:05 -0700 Subject: [PATCH] team totals --- Makefile.toml | 7 -- .../src/routes/(apps)/manifest/+page.svelte | 102 +++++++++++------- 2 files changed, 63 insertions(+), 46 deletions(-) diff --git a/Makefile.toml b/Makefile.toml index 50d0556..b4db7c5 100644 --- a/Makefile.toml +++ b/Makefile.toml @@ -1,10 +1,3 @@ -[tasks.web] -workspace = false -cwd = "usr-web" -script_runner = "@shell" -script = ''' -npm run dev -- -- --host -''' [tasks.backend] workspace = false diff --git a/usr-web/src/routes/(apps)/manifest/+page.svelte b/usr-web/src/routes/(apps)/manifest/+page.svelte index c21eb61..bda0c6b 100644 --- a/usr-web/src/routes/(apps)/manifest/+page.svelte +++ b/usr-web/src/routes/(apps)/manifest/+page.svelte @@ -32,7 +32,7 @@ interface OrderStatus { order_id: number; instance_id: number; - date: string; + date: string | Date; status: 'New' | 'Submitted' | 'Shipped' | 'Delivered' | 'InStorage' | 'In Storage'; } let statuses: OrderStatus[] = $state([]); @@ -49,12 +49,7 @@ }); statuses = body.statuses; statuses = statuses.map((status) => { - status.date = new Date(status.date).toLocaleString('en-US', { - weekday: 'short', - year: 'numeric', - month: 'long', - day: 'numeric' - }); + status.date = new Date(status.date); if (status.status === 'InStorage') { status.status = 'In Storage'; } @@ -110,6 +105,45 @@ out.sort((a, b) => (a.instance_id < b.instance_id ? -1 : 1)); return out; } + + function exportCSV() { + const header = ['Name', 'Vendor', 'Link', 'Count', 'Unit Cost', 'Store In', 'Team', 'Reason', 'Subtotal', 'Status']; + const lines = [header.join(',')]; + + for (const o of orders) { + const st = statuses + .filter(s => s.order_id === o.id) + .map(s => { + const date = s.date as Date; + const day = String(date.getDate()).padStart(2, '0'); + const month = String(date.getMonth() + 1).padStart(2, '0'); + const year = String(date.getFullYear()).slice(-2); + return `${s.status}: ${day}/${month}/${year}`; + }) + .join(','); + const sub = (o.count * (o.unit_cost as number)).toFixed(2); + lines.push([ + o.name, + o.vendor, + o.link, + o.count, + o.unit_cost, + o.store_in, + o.team, + o.reason, + sub, + st, + ].map(String).join(',')); + } + + const csv = new Blob([lines.join('\n')], { type: 'text/csv' }); + const url = URL.createObjectURL(csv); + const link = document.createElement('a'); + link.href = url; + link.download = 'manifest.csv'; + link.click(); + URL.revokeObjectURL(url); + } @@ -123,11 +157,14 @@ Hide "In Storage" - {#if fetching} - - {:else} - - {/if} +
+ {#if fetching} + + {:else} + + {/if} + +
@@ -160,7 +197,12 @@ @@ -459,32 +501,14 @@ {orderOperationOutput} {/if} {:else if tabIndex === 4} - {#if selectedOrderId === null} - {@render selectAnOrder()} - {:else} - - {orderOperationOutput} - {/if} + {#snippet cost(team: string)} +

{team} Total: {orders + .filter(o => o.team === team) + .reduce((acc, cur) => acc + cur.count * (cur.unit_cost as number), 0).toLocaleString('en-US', { style: 'currency', currency: 'USD' })}

+ {/snippet} + {@render cost("Software")} + {@render cost("Mechanical")} + {@render cost("Electrical")} {/if}
{order.name} {#each statusesOf(order.id) as status} -

{status.status}: {status.date}

+

{status.status}: {status.date.toLocaleString('en-US', { + weekday: 'short', + year: 'numeric', + month: 'long', + day: 'numeric' + })}

{/each}
{order.vendor}