Migrate inventory and reports to the SPA
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
26 files changed
+1090
-18
No files matched your search
@@ -0,0 +1,138 @@
|
||||
import { useQuery } from "@apollo/client";
|
||||
import { format, subDays } from "date-fns";
|
||||
import React, { useState } from "react";
|
||||
|
||||
import { GQLError } from "../../components/GQLError";
|
||||
import { InventoryReportDocument } from "../../types";
|
||||
import { formatCurrency } from "../../utils/currency";
|
||||
import styles from "./Inventory.module.css";
|
||||
|
||||
const today = () => format(new Date(), "yyyy-MM-dd");
|
||||
const monthAgo = () => format(subDays(new Date(), 30), "yyyy-MM-dd");
|
||||
const timestampAt = (date: string, endOfDay = false) => `${date}T${endOfDay ? "23:59:59.999999" : "00:00:00"}`;
|
||||
|
||||
const InventoryReport = () => {
|
||||
const [startDate, setStartDate] = useState(monthAgo);
|
||||
const [endDate, setEndDate] = useState(today);
|
||||
const [appliedRange, setAppliedRange] = useState({ startDate: monthAgo(), endDate: today() });
|
||||
const invalidRange = startDate > endDate;
|
||||
const { data, loading, error } = useQuery(InventoryReportDocument, {
|
||||
variables: {
|
||||
startTime: timestampAt(appliedRange.startDate),
|
||||
endTime: timestampAt(appliedRange.endDate, true),
|
||||
},
|
||||
});
|
||||
|
||||
const onSubmit = (event: React.FormEvent<HTMLFormElement>) => {
|
||||
event.preventDefault();
|
||||
if (!invalidRange) setAppliedRange({ startDate, endDate });
|
||||
};
|
||||
|
||||
if (error) return <GQLError error={error} />;
|
||||
|
||||
const report = data?.inventoryReport;
|
||||
const balanceChange = report ? Number(report.balanceAtEnd) - Number(report.balanceAtStart) : 0;
|
||||
const inventoryChange = report ? Number(report.inventoryPurchases) - Number(report.productSales) : 0;
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h2>Varerapport</h2>
|
||||
<form className={styles.summary} onSubmit={onSubmit}>
|
||||
<label>
|
||||
Fra
|
||||
<input type="date" required value={startDate} onChange={(event) => setStartDate(event.target.value)} />
|
||||
</label>
|
||||
<label>
|
||||
Til
|
||||
<input type="date" required value={endDate} onChange={(event) => setEndDate(event.target.value)} />
|
||||
</label>
|
||||
<button type="submit" disabled={invalidRange}>
|
||||
Oppdater
|
||||
</button>
|
||||
</form>
|
||||
{invalidRange && <p className={styles.error}>Startdato må være før eller lik sluttdato.</p>}
|
||||
{loading && <div>Loading...</div>}
|
||||
{report && (
|
||||
<>
|
||||
<section className={styles.report}>
|
||||
<h3>Beholdningsendring</h3>
|
||||
<div className={styles.tableWrap}>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Vare</th>
|
||||
<th scope="col">Innkjøp</th>
|
||||
<th scope="col">Salg</th>
|
||||
<th scope="col">Endring verdi</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{report.products.map((product) => (
|
||||
<tr key={product.productId}>
|
||||
<td>{product.productName}</td>
|
||||
<td>
|
||||
{formatCurrency(Number(product.purchaseValue))} kr ({product.purchaseUnits} stk)
|
||||
</td>
|
||||
<td>
|
||||
{formatCurrency(Number(product.salesValue))} kr ({product.salesUnits} stk)
|
||||
</td>
|
||||
<td>{formatCurrency(Number(product.purchaseValue) - Number(product.salesValue))} kr</td>
|
||||
</tr>
|
||||
))}
|
||||
{!report.products.length && (
|
||||
<tr>
|
||||
<td colSpan={4}>Ingen varetransaksjoner i perioden.</td>
|
||||
</tr>
|
||||
)}
|
||||
<tr>
|
||||
<th scope="row">Totalt</th>
|
||||
<td>{formatCurrency(Number(report.inventoryPurchases))} kr</td>
|
||||
<td>{formatCurrency(Number(report.productSales))} kr</td>
|
||||
<td>{formatCurrency(inventoryChange)} kr</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</section>
|
||||
<section className={styles.report}>
|
||||
<h3>Innskudd og kjøp</h3>
|
||||
<div className={styles.tableWrap}>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Post</th>
|
||||
<th scope="col">Saldo</th>
|
||||
<th scope="col">Innskudd</th>
|
||||
<th scope="col">Kjøp</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th scope="row">Saldo ved periodestart</th>
|
||||
<td>{formatCurrency(Number(report.balanceAtStart))} kr</td>
|
||||
<td />
|
||||
<td />
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">Endring i perioden</th>
|
||||
<td>{formatCurrency(balanceChange)} kr</td>
|
||||
<td>{formatCurrency(Number(report.deposits))} kr</td>
|
||||
<td>{formatCurrency(Number(report.orderPurchases))} kr</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">Saldo ved periodeslutt</th>
|
||||
<td>{formatCurrency(Number(report.balanceAtEnd))} kr</td>
|
||||
<td />
|
||||
<td />
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</section>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default InventoryReport;
|
||||
Reference in new issue
Block a user