feat(invoicing): filter rows to the logged-in rep's own orders
This commit is contained in:
parent
8faa4437b6
commit
29eb003cd6
1 changed files with 19 additions and 4 deletions
|
|
@ -12,6 +12,8 @@ import { Switch } from "@/components/ui/switch";
|
||||||
import { ModalShell } from "@/components/ui/modal-shell";
|
import { ModalShell } from "@/components/ui/modal-shell";
|
||||||
import { StockBookingSection, NEW_BOOKING_EVENT } from "@/components/invoicing/stock-booking-section";
|
import { StockBookingSection, NEW_BOOKING_EVENT } from "@/components/invoicing/stock-booking-section";
|
||||||
import { getPocketBase } from "@/lib/pocketbase";
|
import { getPocketBase } from "@/lib/pocketbase";
|
||||||
|
import { useAuth } from "@/components/auth-provider";
|
||||||
|
import { isRepUser } from "@/lib/rep-visibility";
|
||||||
import { cn } from "@/lib/utils";
|
import { cn } from "@/lib/utils";
|
||||||
import { useBooleanPreference } from "@/lib/use-boolean-preference";
|
import { useBooleanPreference } from "@/lib/use-boolean-preference";
|
||||||
import { colorForOrder } from "@/lib/order-color";
|
import { colorForOrder } from "@/lib/order-color";
|
||||||
|
|
@ -159,8 +161,14 @@ async function listAllInvoicingRows(
|
||||||
return [firstPage, ...rest].flatMap((page) => page.items);
|
return [firstPage, ...rest].flatMap((page) => page.items);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function loadInvoicingRows(pb: ReturnType<typeof getPocketBase>): Promise<RawInvoicingRow[]> {
|
async function loadInvoicingRows(
|
||||||
const seedRows = await listAllInvoicingRows(pb, INVOICING_STATUS_FILTER);
|
pb: ReturnType<typeof getPocketBase>,
|
||||||
|
repId: string | null,
|
||||||
|
): Promise<RawInvoicingRow[]> {
|
||||||
|
const repFilter = repId
|
||||||
|
? ` && order.customer.rep = "${escapeFilterValue(repId)}"`
|
||||||
|
: "";
|
||||||
|
const seedRows = await listAllInvoicingRows(pb, INVOICING_STATUS_FILTER + repFilter);
|
||||||
const readyOrderIds = Array.from(
|
const readyOrderIds = Array.from(
|
||||||
new Set(
|
new Set(
|
||||||
seedRows
|
seedRows
|
||||||
|
|
@ -174,6 +182,9 @@ async function loadInvoicingRows(pb: ReturnType<typeof getPocketBase>): Promise<
|
||||||
return seedRows;
|
return seedRows;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// No need to re-apply repFilter here — readyOrderIds is already
|
||||||
|
// derived from the rep-scoped seedRows above, so the sibling fetch
|
||||||
|
// (by explicit order id) is implicitly scoped too.
|
||||||
const siblingFilter = readyOrderIds
|
const siblingFilter = readyOrderIds
|
||||||
.map((orderId) => `order = "${escapeFilterValue(orderId)}"`)
|
.map((orderId) => `order = "${escapeFilterValue(orderId)}"`)
|
||||||
.join(" || ");
|
.join(" || ");
|
||||||
|
|
@ -1404,18 +1415,22 @@ export default function InvoicingPage() {
|
||||||
// card list can render without a second round-trip.
|
// card list can render without a second round-trip.
|
||||||
const [stockBookings, setStockBookings] = useState<StockBookingRow[] | null>(null);
|
const [stockBookings, setStockBookings] = useState<StockBookingRow[] | null>(null);
|
||||||
|
|
||||||
|
const { user } = useAuth();
|
||||||
|
|
||||||
const load = useCallback(async () => {
|
const load = useCallback(async () => {
|
||||||
setRows(null);
|
setRows(null);
|
||||||
try {
|
try {
|
||||||
const pb = getPocketBase();
|
const pb = getPocketBase();
|
||||||
const items = await loadInvoicingRows(pb);
|
const userType = (user as { user_type?: string[] } | null)?.user_type;
|
||||||
|
const repId = user && isRepUser(userType) ? user.id : null;
|
||||||
|
const items = await loadInvoicingRows(pb, repId);
|
||||||
setRows(items);
|
setRows(items);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
const message = err instanceof Error ? err.message : String(err);
|
const message = err instanceof Error ? err.message : String(err);
|
||||||
toast.error(message);
|
toast.error(message);
|
||||||
setRows([]);
|
setRows([]);
|
||||||
}
|
}
|
||||||
}, []);
|
}, [user]);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Lazy load of the booking list that surfaces on the Invoiced tab.
|
* Lazy load of the booking list that surfaces on the Invoiced tab.
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue