feat(issued-orders): counterparty is now a supplier (dodavatel), not a customer
Issued orders are purchase orders WE send - they must pick from suppliers (sklad_suppliers), not from customers. Per user decision customer_id was REPLACED (not kept alongside): migration drops issued_orders.customer_id and adds supplier_id FK -> sklad_suppliers (existing rows lose their counterparty - the feature is days old; re-point them in the UI). - service: input/filters/search (suppliers.name + ico)/enrichment/detail all supplier-based; create validates the supplier inside the transaction and update before write -> Czech 400 'Dodavatel nenalezen' instead of P2003 500; detail returns a minimal supplier field set (no internal notes leak) - routes: supplier_id on list + stats; new GET /issued-orders/suppliers lookup (orders.view/create/edit guard - orders users lack warehouse.manage which guards the warehouse suppliers CRUD), active suppliers only, name+id ordering - PDF: Dodavatel block now renders the supplier (name, newline-split address, IC/DIC), layout and both language label sets unchanged - frontend: new SupplierPicker kit component (CustomerPicker untouched), IssuedOrderDetail/IssuedOrders switched to supplier_id/supplier_name; the picker keeps a fallback option for orders whose supplier was later deactivated; WarehouseSuppliers CRUD now also invalidates issued-orders so the picker can't go stale - tests: issued-orders suite switched to supplier fixtures + new coverage (lookup shape + 403, nonexistent supplier 400, PDF supplier block) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -4,8 +4,8 @@ import { jsonQuery, paginatedJsonQuery } from "../apiAdapter";
|
||||
export interface IssuedOrder {
|
||||
id: number;
|
||||
po_number: string | null;
|
||||
customer_id: number | null;
|
||||
customer_name: string | null;
|
||||
supplier_id: number | null;
|
||||
supplier_name: string | null;
|
||||
status: string;
|
||||
currency: string | null;
|
||||
order_date: string | null;
|
||||
@@ -14,6 +14,17 @@ export interface IssuedOrder {
|
||||
total: number;
|
||||
}
|
||||
|
||||
/** Active supplier row from the lightweight PO-picker lookup endpoint. */
|
||||
export interface Supplier {
|
||||
id: number;
|
||||
name: string;
|
||||
ico: string | null;
|
||||
dic: string | null;
|
||||
address: string | null;
|
||||
email: string | null;
|
||||
phone: string | null;
|
||||
}
|
||||
|
||||
export interface IssuedOrderItem {
|
||||
id?: number;
|
||||
description: string | null;
|
||||
@@ -37,10 +48,19 @@ export interface IssuedOrderDetail extends IssuedOrder {
|
||||
notes: string | null;
|
||||
internal_notes: string | null;
|
||||
items: IssuedOrderItem[];
|
||||
customer: Record<string, unknown> | null;
|
||||
supplier: Record<string, unknown> | null;
|
||||
valid_transitions: string[];
|
||||
}
|
||||
|
||||
// Suppliers lookup for the PO supplier picker — hits the issued-orders-scoped
|
||||
// endpoint (orders permissions), NOT the warehouse.manage-guarded CRUD list.
|
||||
export const issuedOrderSuppliersOptions = () =>
|
||||
queryOptions({
|
||||
queryKey: ["issued-orders", "suppliers"],
|
||||
queryFn: () => jsonQuery<Supplier[]>("/api/admin/issued-orders/suppliers"),
|
||||
staleTime: 2 * 60_000,
|
||||
});
|
||||
|
||||
export const issuedOrderListOptions = (filters: {
|
||||
search?: string;
|
||||
sort?: string;
|
||||
|
||||
Reference in New Issue
Block a user