Add frontend order API
This commit is contained in:
332
frontend/src/api/hooks/orders.ts
Normal file
332
frontend/src/api/hooks/orders.ts
Normal file
@@ -0,0 +1,332 @@
|
||||
/**
|
||||
* Orders React Query hooks
|
||||
*/
|
||||
import { useMutation, useQuery, useQueryClient, UseQueryOptions, UseMutationOptions } from '@tanstack/react-query';
|
||||
import { OrdersService } from '../services/orders';
|
||||
import {
|
||||
OrderResponse,
|
||||
OrderCreate,
|
||||
OrderUpdate,
|
||||
CustomerResponse,
|
||||
CustomerCreate,
|
||||
CustomerUpdate,
|
||||
OrdersDashboardSummary,
|
||||
DemandRequirements,
|
||||
BusinessModelDetection,
|
||||
ServiceStatus,
|
||||
GetOrdersParams,
|
||||
GetCustomersParams,
|
||||
UpdateOrderStatusParams,
|
||||
GetDemandRequirementsParams,
|
||||
} from '../types/orders';
|
||||
import { ApiError } from '../client/apiClient';
|
||||
|
||||
// Query Keys
|
||||
export const ordersKeys = {
|
||||
all: ['orders'] as const,
|
||||
|
||||
// Orders
|
||||
orders: () => [...ordersKeys.all, 'orders'] as const,
|
||||
ordersList: (params: GetOrdersParams) => [...ordersKeys.orders(), 'list', params] as const,
|
||||
order: (tenantId: string, orderId: string) => [...ordersKeys.orders(), 'detail', tenantId, orderId] as const,
|
||||
|
||||
// Customers
|
||||
customers: () => [...ordersKeys.all, 'customers'] as const,
|
||||
customersList: (params: GetCustomersParams) => [...ordersKeys.customers(), 'list', params] as const,
|
||||
customer: (tenantId: string, customerId: string) => [...ordersKeys.customers(), 'detail', tenantId, customerId] as const,
|
||||
|
||||
// Dashboard & Analytics
|
||||
dashboard: (tenantId: string) => [...ordersKeys.all, 'dashboard', tenantId] as const,
|
||||
demandRequirements: (params: GetDemandRequirementsParams) => [...ordersKeys.all, 'demand', params] as const,
|
||||
businessModel: (tenantId: string) => [...ordersKeys.all, 'business-model', tenantId] as const,
|
||||
|
||||
// Status
|
||||
status: (tenantId: string) => [...ordersKeys.all, 'status', tenantId] as const,
|
||||
} as const;
|
||||
|
||||
// ===== Order Queries =====
|
||||
|
||||
export const useOrders = (
|
||||
params: GetOrdersParams,
|
||||
options?: Omit<UseQueryOptions<OrderResponse[], ApiError>, 'queryKey' | 'queryFn'>
|
||||
) => {
|
||||
return useQuery<OrderResponse[], ApiError>({
|
||||
queryKey: ordersKeys.ordersList(params),
|
||||
queryFn: () => OrdersService.getOrders(params),
|
||||
staleTime: 2 * 60 * 1000, // 2 minutes
|
||||
...options,
|
||||
});
|
||||
};
|
||||
|
||||
export const useOrder = (
|
||||
tenantId: string,
|
||||
orderId: string,
|
||||
options?: Omit<UseQueryOptions<OrderResponse, ApiError>, 'queryKey' | 'queryFn'>
|
||||
) => {
|
||||
return useQuery<OrderResponse, ApiError>({
|
||||
queryKey: ordersKeys.order(tenantId, orderId),
|
||||
queryFn: () => OrdersService.getOrder(tenantId, orderId),
|
||||
staleTime: 1 * 60 * 1000, // 1 minute
|
||||
enabled: !!tenantId && !!orderId,
|
||||
...options,
|
||||
});
|
||||
};
|
||||
|
||||
// ===== Customer Queries =====
|
||||
|
||||
export const useCustomers = (
|
||||
params: GetCustomersParams,
|
||||
options?: Omit<UseQueryOptions<CustomerResponse[], ApiError>, 'queryKey' | 'queryFn'>
|
||||
) => {
|
||||
return useQuery<CustomerResponse[], ApiError>({
|
||||
queryKey: ordersKeys.customersList(params),
|
||||
queryFn: () => OrdersService.getCustomers(params),
|
||||
staleTime: 5 * 60 * 1000, // 5 minutes
|
||||
...options,
|
||||
});
|
||||
};
|
||||
|
||||
export const useCustomer = (
|
||||
tenantId: string,
|
||||
customerId: string,
|
||||
options?: Omit<UseQueryOptions<CustomerResponse, ApiError>, 'queryKey' | 'queryFn'>
|
||||
) => {
|
||||
return useQuery<CustomerResponse, ApiError>({
|
||||
queryKey: ordersKeys.customer(tenantId, customerId),
|
||||
queryFn: () => OrdersService.getCustomer(tenantId, customerId),
|
||||
staleTime: 5 * 60 * 1000, // 5 minutes
|
||||
enabled: !!tenantId && !!customerId,
|
||||
...options,
|
||||
});
|
||||
};
|
||||
|
||||
// ===== Dashboard & Analytics Queries =====
|
||||
|
||||
export const useOrdersDashboard = (
|
||||
tenantId: string,
|
||||
options?: Omit<UseQueryOptions<OrdersDashboardSummary, ApiError>, 'queryKey' | 'queryFn'>
|
||||
) => {
|
||||
return useQuery<OrdersDashboardSummary, ApiError>({
|
||||
queryKey: ordersKeys.dashboard(tenantId),
|
||||
queryFn: () => OrdersService.getDashboardSummary(tenantId),
|
||||
staleTime: 1 * 60 * 1000, // 1 minute
|
||||
enabled: !!tenantId,
|
||||
...options,
|
||||
});
|
||||
};
|
||||
|
||||
export const useDemandRequirements = (
|
||||
params: GetDemandRequirementsParams,
|
||||
options?: Omit<UseQueryOptions<DemandRequirements, ApiError>, 'queryKey' | 'queryFn'>
|
||||
) => {
|
||||
return useQuery<DemandRequirements, ApiError>({
|
||||
queryKey: ordersKeys.demandRequirements(params),
|
||||
queryFn: () => OrdersService.getDemandRequirements(params),
|
||||
staleTime: 30 * 60 * 1000, // 30 minutes
|
||||
enabled: !!params.tenant_id && !!params.target_date,
|
||||
...options,
|
||||
});
|
||||
};
|
||||
|
||||
export const useBusinessModelDetection = (
|
||||
tenantId: string,
|
||||
options?: Omit<UseQueryOptions<BusinessModelDetection, ApiError>, 'queryKey' | 'queryFn'>
|
||||
) => {
|
||||
return useQuery<BusinessModelDetection, ApiError>({
|
||||
queryKey: ordersKeys.businessModel(tenantId),
|
||||
queryFn: () => OrdersService.detectBusinessModel(tenantId),
|
||||
staleTime: 60 * 60 * 1000, // 1 hour
|
||||
enabled: !!tenantId,
|
||||
...options,
|
||||
});
|
||||
};
|
||||
|
||||
export const useOrdersServiceStatus = (
|
||||
tenantId: string,
|
||||
options?: Omit<UseQueryOptions<ServiceStatus, ApiError>, 'queryKey' | 'queryFn'>
|
||||
) => {
|
||||
return useQuery<ServiceStatus, ApiError>({
|
||||
queryKey: ordersKeys.status(tenantId),
|
||||
queryFn: () => OrdersService.getServiceStatus(tenantId),
|
||||
staleTime: 30 * 1000, // 30 seconds
|
||||
enabled: !!tenantId,
|
||||
...options,
|
||||
});
|
||||
};
|
||||
|
||||
// ===== Order Mutations =====
|
||||
|
||||
export const useCreateOrder = (
|
||||
options?: UseMutationOptions<OrderResponse, ApiError, OrderCreate>
|
||||
) => {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
return useMutation<OrderResponse, ApiError, OrderCreate>({
|
||||
mutationFn: (orderData: OrderCreate) => OrdersService.createOrder(orderData),
|
||||
onSuccess: (data, variables) => {
|
||||
// Invalidate orders list for this tenant
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: ordersKeys.orders(),
|
||||
predicate: (query) => {
|
||||
const queryKey = query.queryKey as string[];
|
||||
return queryKey.includes('list') &&
|
||||
JSON.stringify(queryKey).includes(variables.tenant_id);
|
||||
},
|
||||
});
|
||||
|
||||
// Invalidate dashboard
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: ordersKeys.dashboard(variables.tenant_id),
|
||||
});
|
||||
|
||||
// Add the new order to cache
|
||||
queryClient.setQueryData(
|
||||
ordersKeys.order(variables.tenant_id, data.id),
|
||||
data
|
||||
);
|
||||
},
|
||||
...options,
|
||||
});
|
||||
};
|
||||
|
||||
export const useUpdateOrderStatus = (
|
||||
options?: UseMutationOptions<OrderResponse, ApiError, UpdateOrderStatusParams>
|
||||
) => {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
return useMutation<OrderResponse, ApiError, UpdateOrderStatusParams>({
|
||||
mutationFn: (params: UpdateOrderStatusParams) => OrdersService.updateOrderStatus(params),
|
||||
onSuccess: (data, variables) => {
|
||||
// Update the specific order in cache
|
||||
queryClient.setQueryData(
|
||||
ordersKeys.order(variables.tenant_id, variables.order_id),
|
||||
data
|
||||
);
|
||||
|
||||
// Invalidate orders list for this tenant
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: ordersKeys.orders(),
|
||||
predicate: (query) => {
|
||||
const queryKey = query.queryKey as string[];
|
||||
return queryKey.includes('list') &&
|
||||
JSON.stringify(queryKey).includes(variables.tenant_id);
|
||||
},
|
||||
});
|
||||
|
||||
// Invalidate dashboard
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: ordersKeys.dashboard(variables.tenant_id),
|
||||
});
|
||||
},
|
||||
...options,
|
||||
});
|
||||
};
|
||||
|
||||
// ===== Customer Mutations =====
|
||||
|
||||
export const useCreateCustomer = (
|
||||
options?: UseMutationOptions<CustomerResponse, ApiError, CustomerCreate>
|
||||
) => {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
return useMutation<CustomerResponse, ApiError, CustomerCreate>({
|
||||
mutationFn: (customerData: CustomerCreate) => OrdersService.createCustomer(customerData),
|
||||
onSuccess: (data, variables) => {
|
||||
// Invalidate customers list for this tenant
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: ordersKeys.customers(),
|
||||
predicate: (query) => {
|
||||
const queryKey = query.queryKey as string[];
|
||||
return queryKey.includes('list') &&
|
||||
JSON.stringify(queryKey).includes(variables.tenant_id);
|
||||
},
|
||||
});
|
||||
|
||||
// Add the new customer to cache
|
||||
queryClient.setQueryData(
|
||||
ordersKeys.customer(variables.tenant_id, data.id),
|
||||
data
|
||||
);
|
||||
|
||||
// Invalidate dashboard (for customer metrics)
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: ordersKeys.dashboard(variables.tenant_id),
|
||||
});
|
||||
},
|
||||
...options,
|
||||
});
|
||||
};
|
||||
|
||||
export const useUpdateCustomer = (
|
||||
options?: UseMutationOptions<CustomerResponse, ApiError, { tenantId: string; customerId: string; data: CustomerUpdate }>
|
||||
) => {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
return useMutation<CustomerResponse, ApiError, { tenantId: string; customerId: string; data: CustomerUpdate }>({
|
||||
mutationFn: ({ tenantId, customerId, data }) => OrdersService.updateCustomer(tenantId, customerId, data),
|
||||
onSuccess: (data, variables) => {
|
||||
// Update the specific customer in cache
|
||||
queryClient.setQueryData(
|
||||
ordersKeys.customer(variables.tenantId, variables.customerId),
|
||||
data
|
||||
);
|
||||
|
||||
// Invalidate customers list for this tenant
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: ordersKeys.customers(),
|
||||
predicate: (query) => {
|
||||
const queryKey = query.queryKey as string[];
|
||||
return queryKey.includes('list') &&
|
||||
JSON.stringify(queryKey).includes(variables.tenantId);
|
||||
},
|
||||
});
|
||||
},
|
||||
...options,
|
||||
});
|
||||
};
|
||||
|
||||
// ===== Utility Functions =====
|
||||
|
||||
export const useInvalidateOrders = () => {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
return {
|
||||
invalidateAllOrders: (tenantId?: string) => {
|
||||
if (tenantId) {
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: ordersKeys.all,
|
||||
predicate: (query) => {
|
||||
return JSON.stringify(query.queryKey).includes(tenantId);
|
||||
},
|
||||
});
|
||||
} else {
|
||||
queryClient.invalidateQueries({ queryKey: ordersKeys.all });
|
||||
}
|
||||
},
|
||||
invalidateOrdersList: (tenantId: string) => {
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: ordersKeys.orders(),
|
||||
predicate: (query) => {
|
||||
const queryKey = query.queryKey as string[];
|
||||
return queryKey.includes('list') &&
|
||||
JSON.stringify(queryKey).includes(tenantId);
|
||||
},
|
||||
});
|
||||
},
|
||||
invalidateCustomersList: (tenantId: string) => {
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: ordersKeys.customers(),
|
||||
predicate: (query) => {
|
||||
const queryKey = query.queryKey as string[];
|
||||
return queryKey.includes('list') &&
|
||||
JSON.stringify(queryKey).includes(tenantId);
|
||||
},
|
||||
});
|
||||
},
|
||||
invalidateDashboard: (tenantId: string) => {
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: ordersKeys.dashboard(tenantId),
|
||||
});
|
||||
},
|
||||
};
|
||||
};
|
||||
@@ -24,6 +24,7 @@ export { foodSafetyService } from './services/foodSafety';
|
||||
export { trainingService } from './services/training';
|
||||
export { alertProcessorService } from './services/alert_processor';
|
||||
export { suppliersService } from './services/suppliers';
|
||||
export { OrdersService } from './services/orders';
|
||||
|
||||
// Types - Auth
|
||||
export type {
|
||||
@@ -234,6 +235,42 @@ export {
|
||||
PerformanceMetricType,
|
||||
} from './types/suppliers';
|
||||
|
||||
// Types - Orders
|
||||
export type {
|
||||
CustomerType,
|
||||
DeliveryMethod,
|
||||
PaymentTerms as OrdersPaymentTerms,
|
||||
PaymentMethod,
|
||||
PaymentStatus,
|
||||
CustomerSegment,
|
||||
PriorityLevel,
|
||||
OrderType,
|
||||
OrderStatus,
|
||||
OrderSource,
|
||||
SalesChannel,
|
||||
BusinessModel,
|
||||
CustomerBase,
|
||||
CustomerCreate,
|
||||
CustomerUpdate,
|
||||
CustomerResponse,
|
||||
OrderItemBase,
|
||||
OrderItemCreate,
|
||||
OrderItemUpdate,
|
||||
OrderItemResponse,
|
||||
OrderBase,
|
||||
OrderCreate,
|
||||
OrderUpdate,
|
||||
OrderResponse,
|
||||
OrdersDashboardSummary,
|
||||
DemandRequirements,
|
||||
BusinessModelDetection,
|
||||
ServiceStatus,
|
||||
GetOrdersParams,
|
||||
GetCustomersParams,
|
||||
UpdateOrderStatusParams,
|
||||
GetDemandRequirementsParams,
|
||||
} from './types/orders';
|
||||
|
||||
// Hooks - Auth
|
||||
export {
|
||||
useAuthProfile,
|
||||
@@ -460,6 +497,24 @@ export {
|
||||
suppliersKeys,
|
||||
} from './hooks/suppliers';
|
||||
|
||||
// Hooks - Orders
|
||||
export {
|
||||
useOrders,
|
||||
useOrder,
|
||||
useCustomers,
|
||||
useCustomer,
|
||||
useOrdersDashboard,
|
||||
useDemandRequirements,
|
||||
useBusinessModelDetection,
|
||||
useOrdersServiceStatus,
|
||||
useCreateOrder,
|
||||
useUpdateOrderStatus,
|
||||
useCreateCustomer,
|
||||
useUpdateCustomer,
|
||||
useInvalidateOrders,
|
||||
ordersKeys,
|
||||
} from './hooks/orders';
|
||||
|
||||
// Query Key Factories (for advanced usage)
|
||||
export {
|
||||
authKeys,
|
||||
@@ -474,5 +529,6 @@ export {
|
||||
trainingKeys,
|
||||
alertProcessorKeys,
|
||||
suppliersKeys,
|
||||
ordersKeys,
|
||||
dataImportKeys,
|
||||
};
|
||||
173
frontend/src/api/services/orders.ts
Normal file
173
frontend/src/api/services/orders.ts
Normal file
@@ -0,0 +1,173 @@
|
||||
/**
|
||||
* Orders Service - API endpoints for Orders Service
|
||||
*
|
||||
* This service mirrors the backend API endpoints defined in:
|
||||
* services/orders/app/api/orders.py
|
||||
*/
|
||||
|
||||
import { apiClient } from '../client/apiClient';
|
||||
import {
|
||||
OrderResponse,
|
||||
OrderCreate,
|
||||
OrderUpdate,
|
||||
CustomerResponse,
|
||||
CustomerCreate,
|
||||
CustomerUpdate,
|
||||
OrdersDashboardSummary,
|
||||
DemandRequirements,
|
||||
BusinessModelDetection,
|
||||
ServiceStatus,
|
||||
GetOrdersParams,
|
||||
GetCustomersParams,
|
||||
UpdateOrderStatusParams,
|
||||
GetDemandRequirementsParams,
|
||||
} from '../types/orders';
|
||||
|
||||
export class OrdersService {
|
||||
// ===== Dashboard and Analytics Endpoints =====
|
||||
|
||||
/**
|
||||
* Get comprehensive dashboard summary for orders
|
||||
* GET /tenants/{tenant_id}/orders/dashboard-summary
|
||||
*/
|
||||
static async getDashboardSummary(tenantId: string): Promise<OrdersDashboardSummary> {
|
||||
return apiClient.get<OrdersDashboardSummary>(`/tenants/${tenantId}/orders/dashboard-summary`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get demand requirements for production planning
|
||||
* GET /tenants/{tenant_id}/orders/demand-requirements
|
||||
*/
|
||||
static async getDemandRequirements(params: GetDemandRequirementsParams): Promise<DemandRequirements> {
|
||||
const { tenant_id, target_date } = params;
|
||||
return apiClient.get<DemandRequirements>(
|
||||
`/tenants/${tenant_id}/orders/demand-requirements?target_date=${target_date}`
|
||||
);
|
||||
}
|
||||
|
||||
// ===== Order Management Endpoints =====
|
||||
|
||||
/**
|
||||
* Create a new customer order
|
||||
* POST /tenants/{tenant_id}/orders
|
||||
*/
|
||||
static async createOrder(orderData: OrderCreate): Promise<OrderResponse> {
|
||||
const { tenant_id, ...data } = orderData;
|
||||
return apiClient.post<OrderResponse>(`/tenants/${tenant_id}/orders`, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get order details with items
|
||||
* GET /tenants/{tenant_id}/orders/{order_id}
|
||||
*/
|
||||
static async getOrder(tenantId: string, orderId: string): Promise<OrderResponse> {
|
||||
return apiClient.get<OrderResponse>(`/tenants/${tenantId}/orders/${orderId}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get orders with filtering and pagination
|
||||
* GET /tenants/{tenant_id}/orders
|
||||
*/
|
||||
static async getOrders(params: GetOrdersParams): Promise<OrderResponse[]> {
|
||||
const { tenant_id, status_filter, start_date, end_date, skip = 0, limit = 100 } = params;
|
||||
|
||||
const queryParams = new URLSearchParams({
|
||||
skip: skip.toString(),
|
||||
limit: limit.toString(),
|
||||
});
|
||||
|
||||
if (status_filter) {
|
||||
queryParams.append('status_filter', status_filter);
|
||||
}
|
||||
if (start_date) {
|
||||
queryParams.append('start_date', start_date);
|
||||
}
|
||||
if (end_date) {
|
||||
queryParams.append('end_date', end_date);
|
||||
}
|
||||
|
||||
return apiClient.get<OrderResponse[]>(`/tenants/${tenant_id}/orders?${queryParams.toString()}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update order status
|
||||
* PUT /tenants/{tenant_id}/orders/{order_id}/status
|
||||
*/
|
||||
static async updateOrderStatus(params: UpdateOrderStatusParams): Promise<OrderResponse> {
|
||||
const { tenant_id, order_id, new_status, reason } = params;
|
||||
|
||||
const queryParams = new URLSearchParams();
|
||||
if (reason) {
|
||||
queryParams.append('reason', reason);
|
||||
}
|
||||
|
||||
const url = `/tenants/${tenant_id}/orders/${order_id}/status${queryParams.toString() ? `?${queryParams.toString()}` : ''}`;
|
||||
|
||||
return apiClient.put<OrderResponse>(url, { status: new_status });
|
||||
}
|
||||
|
||||
// ===== Customer Management Endpoints =====
|
||||
|
||||
/**
|
||||
* Create a new customer
|
||||
* POST /tenants/{tenant_id}/customers
|
||||
*/
|
||||
static async createCustomer(customerData: CustomerCreate): Promise<CustomerResponse> {
|
||||
const { tenant_id, ...data } = customerData;
|
||||
return apiClient.post<CustomerResponse>(`/tenants/${tenant_id}/customers`, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get customers with filtering and pagination
|
||||
* GET /tenants/{tenant_id}/customers
|
||||
*/
|
||||
static async getCustomers(params: GetCustomersParams): Promise<CustomerResponse[]> {
|
||||
const { tenant_id, active_only = true, skip = 0, limit = 100 } = params;
|
||||
|
||||
const queryParams = new URLSearchParams({
|
||||
active_only: active_only.toString(),
|
||||
skip: skip.toString(),
|
||||
limit: limit.toString(),
|
||||
});
|
||||
|
||||
return apiClient.get<CustomerResponse[]>(`/tenants/${tenant_id}/customers?${queryParams.toString()}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get customer details
|
||||
* GET /tenants/{tenant_id}/customers/{customer_id}
|
||||
*/
|
||||
static async getCustomer(tenantId: string, customerId: string): Promise<CustomerResponse> {
|
||||
return apiClient.get<CustomerResponse>(`/tenants/${tenantId}/customers/${customerId}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update customer details
|
||||
* PUT /tenants/{tenant_id}/customers/{customer_id}
|
||||
*/
|
||||
static async updateCustomer(tenantId: string, customerId: string, customerData: CustomerUpdate): Promise<CustomerResponse> {
|
||||
return apiClient.put<CustomerResponse>(`/tenants/${tenantId}/customers/${customerId}`, customerData);
|
||||
}
|
||||
|
||||
// ===== Business Intelligence Endpoints =====
|
||||
|
||||
/**
|
||||
* Detect business model based on order patterns
|
||||
* GET /tenants/{tenant_id}/orders/business-model
|
||||
*/
|
||||
static async detectBusinessModel(tenantId: string): Promise<BusinessModelDetection> {
|
||||
return apiClient.get<BusinessModelDetection>(`/tenants/${tenantId}/orders/business-model`);
|
||||
}
|
||||
|
||||
// ===== Health and Status Endpoints =====
|
||||
|
||||
/**
|
||||
* Get orders service status
|
||||
* GET /tenants/{tenant_id}/orders/status
|
||||
*/
|
||||
static async getServiceStatus(tenantId: string): Promise<ServiceStatus> {
|
||||
return apiClient.get<ServiceStatus>(`/tenants/${tenantId}/orders/status`);
|
||||
}
|
||||
}
|
||||
|
||||
export default OrdersService;
|
||||
283
frontend/src/api/types/orders.ts
Normal file
283
frontend/src/api/types/orders.ts
Normal file
@@ -0,0 +1,283 @@
|
||||
/**
|
||||
* TypeScript types for Orders Service
|
||||
* Based on backend schemas in services/orders/app/schemas/order_schemas.py
|
||||
*/
|
||||
|
||||
export type CustomerType = 'individual' | 'business' | 'central_bakery';
|
||||
export type DeliveryMethod = 'delivery' | 'pickup';
|
||||
export type PaymentTerms = 'immediate' | 'net_30' | 'net_60';
|
||||
export type PaymentMethod = 'cash' | 'card' | 'bank_transfer' | 'account';
|
||||
export type PaymentStatus = 'pending' | 'partial' | 'paid' | 'failed' | 'refunded';
|
||||
export type CustomerSegment = 'vip' | 'regular' | 'wholesale';
|
||||
export type PriorityLevel = 'high' | 'normal' | 'low';
|
||||
export type OrderType = 'standard' | 'rush' | 'recurring' | 'special';
|
||||
export type OrderStatus = 'pending' | 'confirmed' | 'in_production' | 'ready' | 'out_for_delivery' | 'delivered' | 'cancelled' | 'failed';
|
||||
export type OrderSource = 'manual' | 'online' | 'phone' | 'app' | 'api';
|
||||
export type SalesChannel = 'direct' | 'wholesale' | 'retail';
|
||||
export type BusinessModel = 'individual_bakery' | 'central_bakery';
|
||||
|
||||
// ===== Customer Types =====
|
||||
|
||||
export interface CustomerBase {
|
||||
name: string;
|
||||
business_name?: string;
|
||||
customer_type: CustomerType;
|
||||
email?: string;
|
||||
phone?: string;
|
||||
address_line1?: string;
|
||||
address_line2?: string;
|
||||
city?: string;
|
||||
state?: string;
|
||||
postal_code?: string;
|
||||
country: string;
|
||||
is_active: boolean;
|
||||
preferred_delivery_method: DeliveryMethod;
|
||||
payment_terms: PaymentTerms;
|
||||
credit_limit?: number;
|
||||
discount_percentage: number;
|
||||
customer_segment: CustomerSegment;
|
||||
priority_level: PriorityLevel;
|
||||
special_instructions?: string;
|
||||
delivery_preferences?: Record<string, any>;
|
||||
product_preferences?: Record<string, any>;
|
||||
}
|
||||
|
||||
export interface CustomerCreate extends CustomerBase {
|
||||
customer_code: string;
|
||||
tenant_id: string;
|
||||
}
|
||||
|
||||
export interface CustomerUpdate extends Partial<Omit<CustomerBase, 'country' | 'is_active' | 'preferred_delivery_method' | 'payment_terms' | 'discount_percentage' | 'customer_segment' | 'priority_level'>> {
|
||||
country?: string;
|
||||
is_active?: boolean;
|
||||
preferred_delivery_method?: DeliveryMethod;
|
||||
payment_terms?: PaymentTerms;
|
||||
discount_percentage?: number;
|
||||
customer_segment?: CustomerSegment;
|
||||
priority_level?: PriorityLevel;
|
||||
}
|
||||
|
||||
export interface CustomerResponse extends CustomerBase {
|
||||
id: string;
|
||||
tenant_id: string;
|
||||
customer_code: string;
|
||||
total_orders: number;
|
||||
total_spent: number;
|
||||
average_order_value: number;
|
||||
last_order_date?: string;
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
}
|
||||
|
||||
// ===== Order Item Types =====
|
||||
|
||||
export interface OrderItemBase {
|
||||
product_id: string;
|
||||
product_name: string;
|
||||
product_sku?: string;
|
||||
product_category?: string;
|
||||
quantity: number;
|
||||
unit_of_measure: string;
|
||||
weight?: number;
|
||||
unit_price: number;
|
||||
line_discount: number;
|
||||
product_specifications?: Record<string, any>;
|
||||
customization_details?: string;
|
||||
special_instructions?: string;
|
||||
recipe_id?: string;
|
||||
}
|
||||
|
||||
export interface OrderItemCreate extends OrderItemBase {}
|
||||
|
||||
export interface OrderItemUpdate {
|
||||
quantity?: number;
|
||||
unit_price?: number;
|
||||
line_discount?: number;
|
||||
product_specifications?: Record<string, any>;
|
||||
customization_details?: string;
|
||||
special_instructions?: string;
|
||||
}
|
||||
|
||||
export interface OrderItemResponse extends OrderItemBase {
|
||||
id: string;
|
||||
order_id: string;
|
||||
line_total: number;
|
||||
status: string;
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
}
|
||||
|
||||
// ===== Order Types =====
|
||||
|
||||
export interface OrderBase {
|
||||
customer_id: string;
|
||||
order_type: OrderType;
|
||||
priority: PriorityLevel;
|
||||
requested_delivery_date: string;
|
||||
delivery_method: DeliveryMethod;
|
||||
delivery_address?: Record<string, any>;
|
||||
delivery_instructions?: string;
|
||||
delivery_window_start?: string;
|
||||
delivery_window_end?: string;
|
||||
discount_percentage: number;
|
||||
delivery_fee: number;
|
||||
payment_method?: PaymentMethod;
|
||||
payment_terms: PaymentTerms;
|
||||
special_instructions?: string;
|
||||
custom_requirements?: Record<string, any>;
|
||||
allergen_warnings?: Record<string, any>;
|
||||
order_source: OrderSource;
|
||||
sales_channel: SalesChannel;
|
||||
order_origin?: string;
|
||||
communication_preferences?: Record<string, any>;
|
||||
}
|
||||
|
||||
export interface OrderCreate extends OrderBase {
|
||||
tenant_id: string;
|
||||
items: OrderItemCreate[];
|
||||
}
|
||||
|
||||
export interface OrderUpdate {
|
||||
status?: OrderStatus;
|
||||
priority?: PriorityLevel;
|
||||
requested_delivery_date?: string;
|
||||
confirmed_delivery_date?: string;
|
||||
delivery_method?: DeliveryMethod;
|
||||
delivery_address?: Record<string, any>;
|
||||
delivery_instructions?: string;
|
||||
delivery_window_start?: string;
|
||||
delivery_window_end?: string;
|
||||
payment_method?: PaymentMethod;
|
||||
payment_status?: PaymentStatus;
|
||||
special_instructions?: string;
|
||||
custom_requirements?: Record<string, any>;
|
||||
allergen_warnings?: Record<string, any>;
|
||||
}
|
||||
|
||||
export interface OrderResponse extends OrderBase {
|
||||
id: string;
|
||||
tenant_id: string;
|
||||
order_number: string;
|
||||
status: OrderStatus;
|
||||
order_date: string;
|
||||
confirmed_delivery_date?: string;
|
||||
actual_delivery_date?: string;
|
||||
subtotal: number;
|
||||
discount_amount: number;
|
||||
tax_amount: number;
|
||||
total_amount: number;
|
||||
payment_status: PaymentStatus;
|
||||
business_model?: string;
|
||||
estimated_business_model?: string;
|
||||
production_batch_id?: string;
|
||||
quality_score?: number;
|
||||
customer_rating?: number;
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
items: OrderItemResponse[];
|
||||
}
|
||||
|
||||
// ===== Dashboard and Analytics Types =====
|
||||
|
||||
export interface OrdersDashboardSummary {
|
||||
// Current period metrics
|
||||
total_orders_today: number;
|
||||
total_orders_this_week: number;
|
||||
total_orders_this_month: number;
|
||||
|
||||
// Revenue metrics
|
||||
revenue_today: number;
|
||||
revenue_this_week: number;
|
||||
revenue_this_month: number;
|
||||
|
||||
// Order status breakdown
|
||||
pending_orders: number;
|
||||
confirmed_orders: number;
|
||||
in_production_orders: number;
|
||||
ready_orders: number;
|
||||
delivered_orders: number;
|
||||
|
||||
// Customer metrics
|
||||
total_customers: number;
|
||||
new_customers_this_month: number;
|
||||
repeat_customers_rate: number;
|
||||
|
||||
// Performance metrics
|
||||
average_order_value: number;
|
||||
order_fulfillment_rate: number;
|
||||
on_time_delivery_rate: number;
|
||||
|
||||
// Business model detection
|
||||
business_model?: string;
|
||||
business_model_confidence?: number;
|
||||
|
||||
// Recent activity
|
||||
recent_orders: OrderResponse[];
|
||||
high_priority_orders: OrderResponse[];
|
||||
}
|
||||
|
||||
export interface DemandRequirements {
|
||||
date: string;
|
||||
tenant_id: string;
|
||||
|
||||
// Product demand breakdown
|
||||
product_demands: Record<string, any>[];
|
||||
|
||||
// Aggregate metrics
|
||||
total_orders: number;
|
||||
total_quantity: number;
|
||||
total_value: number;
|
||||
|
||||
// Business context
|
||||
business_model?: string;
|
||||
rush_orders_count: number;
|
||||
special_requirements: string[];
|
||||
|
||||
// Timing requirements
|
||||
earliest_delivery: string;
|
||||
latest_delivery: string;
|
||||
average_lead_time_hours: number;
|
||||
}
|
||||
|
||||
export interface BusinessModelDetection {
|
||||
business_model: string;
|
||||
confidence: string;
|
||||
detected_at: string;
|
||||
}
|
||||
|
||||
export interface ServiceStatus {
|
||||
service: string;
|
||||
status: string;
|
||||
timestamp: string;
|
||||
tenant_id: string;
|
||||
}
|
||||
|
||||
// ===== Query Parameters Types =====
|
||||
|
||||
export interface GetOrdersParams {
|
||||
tenant_id: string;
|
||||
status_filter?: string;
|
||||
start_date?: string;
|
||||
end_date?: string;
|
||||
skip?: number;
|
||||
limit?: number;
|
||||
}
|
||||
|
||||
export interface GetCustomersParams {
|
||||
tenant_id: string;
|
||||
active_only?: boolean;
|
||||
skip?: number;
|
||||
limit?: number;
|
||||
}
|
||||
|
||||
export interface UpdateOrderStatusParams {
|
||||
tenant_id: string;
|
||||
order_id: string;
|
||||
new_status: OrderStatus;
|
||||
reason?: string;
|
||||
}
|
||||
|
||||
export interface GetDemandRequirementsParams {
|
||||
tenant_id: string;
|
||||
target_date: string;
|
||||
}
|
||||
Reference in New Issue
Block a user