Fix Purchase Order modal and reorganize documentation
Frontend Changes: - Fix runtime error: Remove undefined handleModify reference from ActionQueueCard in DashboardPage - Migrate PurchaseOrderDetailsModal to use correct PurchaseOrderItem type from purchase_orders service - Fix item display: Parse unit_price as string (Decimal) instead of number - Use correct field names: item_notes instead of notes - Remove deprecated PurchaseOrder types from suppliers.ts to prevent type conflicts - Update CreatePurchaseOrderModal to use unified types - Clean up API exports: Remove old PO hooks re-exported from suppliers - Add comprehensive translations for PO modal (en, es, eu) Documentation Reorganization: - Move WhatsApp implementation docs to docs/03-features/notifications/whatsapp/ - Move forecast validation docs to docs/03-features/forecasting/ - Move specification docs to docs/03-features/specifications/ - Move deployment docs (Colima, K8s, VPS sizing) to docs/05-deployment/ - Archive completed implementation summaries to docs/archive/implementation-summaries/ - Delete obsolete FRONTEND_CHANGES_NEEDED.md - Standardize filenames to lowercase with hyphens 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -49,6 +49,8 @@ export interface ReasoningInputs {
|
||||
aiInsights: boolean;
|
||||
}
|
||||
|
||||
// Note: This is a different interface from PurchaseOrderSummary in purchase_orders.ts
|
||||
// This is specifically for OrchestrationSummary dashboard display
|
||||
export interface PurchaseOrderSummary {
|
||||
supplierName: string;
|
||||
itemCategories: string[];
|
||||
|
||||
@@ -10,6 +10,7 @@ import type {
|
||||
PurchaseOrderDetail,
|
||||
PurchaseOrderSearchParams,
|
||||
PurchaseOrderUpdateData,
|
||||
PurchaseOrderCreateData,
|
||||
PurchaseOrderStatus,
|
||||
CreateDeliveryInput,
|
||||
DeliveryResponse
|
||||
@@ -19,6 +20,7 @@ import {
|
||||
getPurchaseOrder,
|
||||
getPendingApprovalPurchaseOrders,
|
||||
getPurchaseOrdersByStatus,
|
||||
createPurchaseOrder,
|
||||
updatePurchaseOrder,
|
||||
approvePurchaseOrder,
|
||||
rejectPurchaseOrder,
|
||||
@@ -112,6 +114,37 @@ export const usePurchaseOrder = (
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Hook to create a new purchase order
|
||||
*/
|
||||
export const useCreatePurchaseOrder = (
|
||||
options?: UseMutationOptions<
|
||||
PurchaseOrderDetail,
|
||||
ApiError,
|
||||
{ tenantId: string; data: PurchaseOrderCreateData }
|
||||
>
|
||||
) => {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
return useMutation<
|
||||
PurchaseOrderDetail,
|
||||
ApiError,
|
||||
{ tenantId: string; data: PurchaseOrderCreateData }
|
||||
>({
|
||||
mutationFn: ({ tenantId, data }) => createPurchaseOrder(tenantId, data),
|
||||
onSuccess: (data, variables) => {
|
||||
// Invalidate all lists to refresh with new PO
|
||||
queryClient.invalidateQueries({ queryKey: purchaseOrderKeys.lists() });
|
||||
// Add to cache
|
||||
queryClient.setQueryData(
|
||||
purchaseOrderKeys.detail(variables.tenantId, data.id),
|
||||
data
|
||||
);
|
||||
},
|
||||
...options,
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Hook to update a purchase order
|
||||
*/
|
||||
|
||||
@@ -15,11 +15,6 @@ import type {
|
||||
SupplierSearchParams,
|
||||
SupplierStatistics,
|
||||
SupplierDeletionSummary,
|
||||
PurchaseOrderCreate,
|
||||
PurchaseOrderUpdate,
|
||||
PurchaseOrderResponse,
|
||||
PurchaseOrderApproval,
|
||||
PurchaseOrderSearchParams,
|
||||
DeliveryCreate,
|
||||
DeliveryUpdate,
|
||||
DeliveryResponse,
|
||||
@@ -49,15 +44,6 @@ export const suppliersKeys = {
|
||||
byType: (tenantId: string, supplierType: string) =>
|
||||
[...suppliersKeys.suppliers.all(), 'by-type', tenantId, supplierType] as const,
|
||||
},
|
||||
purchaseOrders: {
|
||||
all: () => [...suppliersKeys.all, 'purchase-orders'] as const,
|
||||
lists: () => [...suppliersKeys.purchaseOrders.all(), 'list'] as const,
|
||||
list: (params?: PurchaseOrderSearchParams) =>
|
||||
[...suppliersKeys.purchaseOrders.lists(), params] as const,
|
||||
details: () => [...suppliersKeys.purchaseOrders.all(), 'detail'] as const,
|
||||
detail: (orderId: string) =>
|
||||
[...suppliersKeys.purchaseOrders.details(), orderId] as const,
|
||||
},
|
||||
deliveries: {
|
||||
all: () => [...suppliersKeys.all, 'deliveries'] as const,
|
||||
lists: () => [...suppliersKeys.deliveries.all(), 'list'] as const,
|
||||
@@ -173,35 +159,6 @@ export const useSuppliersByType = (
|
||||
});
|
||||
};
|
||||
|
||||
// Purchase Order Queries
|
||||
export const usePurchaseOrders = (
|
||||
tenantId: string,
|
||||
queryParams?: PurchaseOrderSearchParams,
|
||||
options?: Omit<UseQueryOptions<PurchaseOrderResponse[], ApiError>, 'queryKey' | 'queryFn'>
|
||||
) => {
|
||||
return useQuery<PurchaseOrderResponse[], ApiError>({
|
||||
queryKey: suppliersKeys.purchaseOrders.list(queryParams),
|
||||
queryFn: () => suppliersService.getPurchaseOrders(tenantId, queryParams as any),
|
||||
enabled: !!tenantId,
|
||||
staleTime: 1 * 60 * 1000, // 1 minute
|
||||
...options,
|
||||
});
|
||||
};
|
||||
|
||||
export const usePurchaseOrder = (
|
||||
tenantId: string,
|
||||
orderId: string,
|
||||
options?: Omit<UseQueryOptions<PurchaseOrderResponse, ApiError>, 'queryKey' | 'queryFn'>
|
||||
) => {
|
||||
return useQuery<PurchaseOrderResponse, ApiError>({
|
||||
queryKey: suppliersKeys.purchaseOrders.detail(orderId),
|
||||
queryFn: () => suppliersService.getPurchaseOrder(tenantId, orderId),
|
||||
enabled: !!tenantId && !!orderId,
|
||||
staleTime: 2 * 60 * 1000, // 2 minutes
|
||||
...options,
|
||||
});
|
||||
};
|
||||
|
||||
// Delivery Queries
|
||||
export const useDeliveries = (
|
||||
tenantId: string,
|
||||
@@ -462,94 +419,6 @@ export const useHardDeleteSupplier = (
|
||||
});
|
||||
};
|
||||
|
||||
// Purchase Order Mutations
|
||||
export const useCreatePurchaseOrder = (
|
||||
options?: UseMutationOptions<PurchaseOrderResponse, ApiError, PurchaseOrderCreate>
|
||||
) => {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
return useMutation<PurchaseOrderResponse, ApiError, PurchaseOrderCreate>({
|
||||
mutationFn: (orderData) => suppliersService.createPurchaseOrder(orderData),
|
||||
onSuccess: (data) => {
|
||||
// Add to cache
|
||||
queryClient.setQueryData(
|
||||
suppliersKeys.purchaseOrders.detail(data.id),
|
||||
data
|
||||
);
|
||||
|
||||
// Invalidate lists
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: suppliersKeys.purchaseOrders.lists()
|
||||
});
|
||||
},
|
||||
...options,
|
||||
});
|
||||
};
|
||||
|
||||
export const useUpdatePurchaseOrder = (
|
||||
options?: UseMutationOptions<
|
||||
PurchaseOrderResponse,
|
||||
ApiError,
|
||||
{ orderId: string; updateData: PurchaseOrderUpdate }
|
||||
>
|
||||
) => {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
return useMutation<
|
||||
PurchaseOrderResponse,
|
||||
ApiError,
|
||||
{ orderId: string; updateData: PurchaseOrderUpdate }
|
||||
>({
|
||||
mutationFn: ({ orderId, updateData }) =>
|
||||
suppliersService.updatePurchaseOrder(orderId, updateData),
|
||||
onSuccess: (data, { orderId }) => {
|
||||
// Update cache
|
||||
queryClient.setQueryData(
|
||||
suppliersKeys.purchaseOrders.detail(orderId),
|
||||
data
|
||||
);
|
||||
|
||||
// Invalidate lists
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: suppliersKeys.purchaseOrders.lists()
|
||||
});
|
||||
},
|
||||
...options,
|
||||
});
|
||||
};
|
||||
|
||||
export const useApprovePurchaseOrder = (
|
||||
options?: UseMutationOptions<
|
||||
PurchaseOrderResponse,
|
||||
ApiError,
|
||||
{ orderId: string; approval: PurchaseOrderApproval }
|
||||
>
|
||||
) => {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
return useMutation<
|
||||
PurchaseOrderResponse,
|
||||
ApiError,
|
||||
{ orderId: string; approval: PurchaseOrderApproval }
|
||||
>({
|
||||
mutationFn: ({ orderId, approval }) =>
|
||||
suppliersService.approvePurchaseOrder(orderId, approval),
|
||||
onSuccess: (data, { orderId }) => {
|
||||
// Update cache
|
||||
queryClient.setQueryData(
|
||||
suppliersKeys.purchaseOrders.detail(orderId),
|
||||
data
|
||||
);
|
||||
|
||||
// Invalidate lists
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: suppliersKeys.purchaseOrders.lists()
|
||||
});
|
||||
},
|
||||
...options,
|
||||
});
|
||||
};
|
||||
|
||||
// Delivery Mutations
|
||||
export const useCreateDelivery = (
|
||||
options?: UseMutationOptions<DeliveryResponse, ApiError, DeliveryCreate>
|
||||
|
||||
Reference in New Issue
Block a user