Add more services
This commit is contained in:
@@ -15,6 +15,9 @@ import { NotificationService } from './notification.service';
|
||||
import { OnboardingService } from './onboarding.service';
|
||||
import { InventoryService } from './inventory.service';
|
||||
import { RecipesService } from './recipes.service';
|
||||
import { ProductionService } from './production.service';
|
||||
import { OrdersService } from './orders.service';
|
||||
import { SuppliersService } from './suppliers.service';
|
||||
|
||||
// Create service instances
|
||||
export const authService = new AuthService();
|
||||
@@ -27,6 +30,9 @@ export const notificationService = new NotificationService();
|
||||
export const onboardingService = new OnboardingService();
|
||||
export const inventoryService = new InventoryService();
|
||||
export const recipesService = new RecipesService();
|
||||
export const productionService = new ProductionService();
|
||||
export const ordersService = new OrdersService();
|
||||
export const suppliersService = new SuppliersService();
|
||||
|
||||
// Export the classes as well
|
||||
export {
|
||||
@@ -39,7 +45,10 @@ export {
|
||||
NotificationService,
|
||||
OnboardingService,
|
||||
InventoryService,
|
||||
RecipesService
|
||||
RecipesService,
|
||||
ProductionService,
|
||||
OrdersService,
|
||||
SuppliersService
|
||||
};
|
||||
|
||||
// Import base client
|
||||
@@ -61,6 +70,9 @@ export const api = {
|
||||
onboarding: onboardingService,
|
||||
inventory: inventoryService,
|
||||
recipes: recipesService,
|
||||
production: productionService,
|
||||
orders: ordersService,
|
||||
suppliers: suppliersService,
|
||||
} as const;
|
||||
|
||||
// Service status checking
|
||||
@@ -81,6 +93,9 @@ export class HealthService {
|
||||
{ name: 'External', endpoint: '/external/health' },
|
||||
{ name: 'Training', endpoint: '/training/health' },
|
||||
{ name: 'Inventory', endpoint: '/inventory/health' },
|
||||
{ name: 'Production', endpoint: '/production/health' },
|
||||
{ name: 'Orders', endpoint: '/orders/health' },
|
||||
{ name: 'Suppliers', endpoint: '/suppliers/health' },
|
||||
{ name: 'Forecasting', endpoint: '/forecasting/health' },
|
||||
{ name: 'Notification', endpoint: '/notifications/health' },
|
||||
];
|
||||
|
||||
@@ -433,22 +433,6 @@ export class InventoryService {
|
||||
|
||||
// ========== DASHBOARD & ANALYTICS ==========
|
||||
|
||||
/**
|
||||
* Get inventory dashboard data
|
||||
*/
|
||||
async getDashboardData(tenantId: string): Promise<InventoryDashboardData> {
|
||||
// TODO: Map to correct endpoint when available
|
||||
return {
|
||||
total_items: 0,
|
||||
low_stock_items: 0,
|
||||
out_of_stock_items: 0,
|
||||
total_value: 0,
|
||||
recent_movements: [],
|
||||
top_products: [],
|
||||
stock_alerts: []
|
||||
};
|
||||
// return apiClient.get(`/tenants/${tenantId}/inventory/dashboard`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get inventory value report
|
||||
@@ -696,6 +680,129 @@ export class InventoryService {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// ========== ENHANCED DASHBOARD FEATURES ==========
|
||||
|
||||
/**
|
||||
* Get inventory dashboard data with analytics
|
||||
*/
|
||||
async getDashboardData(tenantId: string, params?: {
|
||||
date_from?: string;
|
||||
date_to?: string;
|
||||
location?: string;
|
||||
}): Promise<{
|
||||
summary: {
|
||||
total_items: number;
|
||||
low_stock_count: number;
|
||||
out_of_stock_items: number;
|
||||
expiring_soon: number;
|
||||
total_value: number;
|
||||
};
|
||||
recent_movements: any[];
|
||||
active_alerts: any[];
|
||||
stock_trends: {
|
||||
dates: string[];
|
||||
stock_levels: number[];
|
||||
movements_in: number[];
|
||||
movements_out: number[];
|
||||
};
|
||||
}> {
|
||||
try {
|
||||
return await apiClient.get(`/tenants/${tenantId}/inventory/dashboard`, { params });
|
||||
} catch (error) {
|
||||
console.error('❌ Error fetching inventory dashboard:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get food safety compliance data
|
||||
*/
|
||||
async getFoodSafetyCompliance(tenantId: string): Promise<{
|
||||
compliant_items: number;
|
||||
non_compliant_items: number;
|
||||
expiring_items: any[];
|
||||
temperature_violations: any[];
|
||||
compliance_score: number;
|
||||
}> {
|
||||
try {
|
||||
return await apiClient.get(`/tenants/${tenantId}/inventory/food-safety/compliance`);
|
||||
} catch (error) {
|
||||
console.error('❌ Error fetching food safety compliance:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get temperature monitoring data
|
||||
*/
|
||||
async getTemperatureMonitoring(tenantId: string, params?: {
|
||||
item_id?: string;
|
||||
location?: string;
|
||||
date_from?: string;
|
||||
date_to?: string;
|
||||
}): Promise<{
|
||||
readings: any[];
|
||||
violations: any[];
|
||||
}> {
|
||||
try {
|
||||
return await apiClient.get(`/tenants/${tenantId}/inventory/food-safety/temperature-monitoring`, { params });
|
||||
} catch (error) {
|
||||
console.error('❌ Error fetching temperature monitoring:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Record temperature reading
|
||||
*/
|
||||
async recordTemperatureReading(tenantId: string, params: {
|
||||
item_id: string;
|
||||
temperature: number;
|
||||
humidity?: number;
|
||||
location: string;
|
||||
notes?: string;
|
||||
}): Promise<void> {
|
||||
try {
|
||||
return await apiClient.post(`/tenants/${tenantId}/inventory/food-safety/temperature-reading`, params);
|
||||
} catch (error) {
|
||||
console.error('❌ Error recording temperature reading:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get inventory alerts
|
||||
*/
|
||||
async getInventoryAlerts(tenantId: string, params?: {
|
||||
alert_type?: string;
|
||||
severity?: string;
|
||||
status?: string;
|
||||
item_id?: string;
|
||||
limit?: number;
|
||||
}): Promise<any[]> {
|
||||
try {
|
||||
return await apiClient.get(`/tenants/${tenantId}/inventory/alerts`, { params });
|
||||
} catch (error) {
|
||||
console.error('❌ Error fetching inventory alerts:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get restock recommendations
|
||||
*/
|
||||
async getRestockRecommendations(tenantId: string): Promise<{
|
||||
urgent_restocks: any[];
|
||||
optimal_orders: any[];
|
||||
}> {
|
||||
try {
|
||||
return await apiClient.get(`/tenants/${tenantId}/inventory/forecasting/restock-recommendations`);
|
||||
} catch (error) {
|
||||
console.error('❌ Error fetching restock recommendations:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const inventoryService = new InventoryService();
|
||||
363
frontend/src/api/services/orders.service.ts
Normal file
363
frontend/src/api/services/orders.service.ts
Normal file
@@ -0,0 +1,363 @@
|
||||
// ================================================================
|
||||
// frontend/src/api/services/orders.service.ts
|
||||
// ================================================================
|
||||
/**
|
||||
* Orders Service - API client for Orders Service endpoints
|
||||
*/
|
||||
|
||||
import { apiClient } from '../client';
|
||||
|
||||
// Order Types
|
||||
export interface Order {
|
||||
id: string;
|
||||
tenant_id: string;
|
||||
customer_id?: string;
|
||||
customer_name?: string;
|
||||
customer_email?: string;
|
||||
customer_phone?: string;
|
||||
order_number: string;
|
||||
status: 'pending' | 'confirmed' | 'in_production' | 'ready' | 'delivered' | 'cancelled';
|
||||
order_type: 'walk_in' | 'online' | 'phone' | 'catering';
|
||||
business_model: 'individual_bakery' | 'central_bakery';
|
||||
items: OrderItem[];
|
||||
subtotal: number;
|
||||
tax_amount: number;
|
||||
discount_amount: number;
|
||||
total_amount: number;
|
||||
delivery_date?: string;
|
||||
delivery_address?: string;
|
||||
notes?: string;
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
}
|
||||
|
||||
export interface OrderItem {
|
||||
id: string;
|
||||
recipe_id: string;
|
||||
recipe_name: string;
|
||||
quantity: number;
|
||||
unit_price: number;
|
||||
total_price: number;
|
||||
customizations?: Record<string, any>;
|
||||
production_notes?: string;
|
||||
}
|
||||
|
||||
export interface Customer {
|
||||
id: string;
|
||||
name: string;
|
||||
email?: string;
|
||||
phone?: string;
|
||||
address?: string;
|
||||
customer_type: 'individual' | 'business' | 'catering';
|
||||
preferences?: string[];
|
||||
loyalty_points?: number;
|
||||
total_orders: number;
|
||||
total_spent: number;
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
}
|
||||
|
||||
export interface OrderDashboardData {
|
||||
summary: {
|
||||
total_orders_today: number;
|
||||
pending_orders: number;
|
||||
orders_in_production: number;
|
||||
completed_orders: number;
|
||||
revenue_today: number;
|
||||
average_order_value: number;
|
||||
};
|
||||
recent_orders: Order[];
|
||||
peak_hours: { hour: number; orders: number }[];
|
||||
popular_items: { recipe_name: string; quantity: number }[];
|
||||
business_model_distribution: { model: string; count: number; revenue: number }[];
|
||||
}
|
||||
|
||||
export interface ProcurementPlan {
|
||||
id: string;
|
||||
date: string;
|
||||
status: 'draft' | 'approved' | 'ordered' | 'completed';
|
||||
total_cost: number;
|
||||
items: ProcurementItem[];
|
||||
supplier_orders: SupplierOrder[];
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
}
|
||||
|
||||
export interface ProcurementItem {
|
||||
ingredient_id: string;
|
||||
ingredient_name: string;
|
||||
required_quantity: number;
|
||||
current_stock: number;
|
||||
quantity_to_order: number;
|
||||
unit: string;
|
||||
estimated_cost: number;
|
||||
priority: 'low' | 'medium' | 'high' | 'critical';
|
||||
supplier_id?: string;
|
||||
supplier_name?: string;
|
||||
}
|
||||
|
||||
export interface SupplierOrder {
|
||||
supplier_id: string;
|
||||
supplier_name: string;
|
||||
items: ProcurementItem[];
|
||||
total_cost: number;
|
||||
delivery_date?: string;
|
||||
notes?: string;
|
||||
}
|
||||
|
||||
export interface OrderCreateRequest {
|
||||
customer_id?: string;
|
||||
customer_name?: string;
|
||||
customer_email?: string;
|
||||
customer_phone?: string;
|
||||
order_type: 'walk_in' | 'online' | 'phone' | 'catering';
|
||||
business_model: 'individual_bakery' | 'central_bakery';
|
||||
items: {
|
||||
recipe_id: string;
|
||||
quantity: number;
|
||||
customizations?: Record<string, any>;
|
||||
}[];
|
||||
delivery_date?: string;
|
||||
delivery_address?: string;
|
||||
notes?: string;
|
||||
}
|
||||
|
||||
export interface OrderUpdateRequest {
|
||||
status?: 'pending' | 'confirmed' | 'in_production' | 'ready' | 'delivered' | 'cancelled';
|
||||
items?: {
|
||||
recipe_id: string;
|
||||
quantity: number;
|
||||
customizations?: Record<string, any>;
|
||||
}[];
|
||||
delivery_date?: string;
|
||||
delivery_address?: string;
|
||||
notes?: string;
|
||||
}
|
||||
|
||||
export class OrdersService {
|
||||
private readonly basePath = '/orders';
|
||||
|
||||
// Dashboard
|
||||
async getDashboardData(params?: {
|
||||
date_from?: string;
|
||||
date_to?: string;
|
||||
}): Promise<OrderDashboardData> {
|
||||
return apiClient.get(`${this.basePath}/dashboard`, { params });
|
||||
}
|
||||
|
||||
async getDashboardMetrics(params?: {
|
||||
date_from?: string;
|
||||
date_to?: string;
|
||||
granularity?: 'hour' | 'day' | 'week' | 'month';
|
||||
}): Promise<{
|
||||
dates: string[];
|
||||
order_counts: number[];
|
||||
revenue: number[];
|
||||
average_order_values: number[];
|
||||
business_model_breakdown: { model: string; orders: number[]; revenue: number[] }[];
|
||||
}> {
|
||||
return apiClient.get(`${this.basePath}/dashboard/metrics`, { params });
|
||||
}
|
||||
|
||||
// Orders
|
||||
async getOrders(params?: {
|
||||
status?: string;
|
||||
order_type?: string;
|
||||
business_model?: string;
|
||||
customer_id?: string;
|
||||
date_from?: string;
|
||||
date_to?: string;
|
||||
limit?: number;
|
||||
offset?: number;
|
||||
}): Promise<Order[]> {
|
||||
return apiClient.get(`${this.basePath}`, { params });
|
||||
}
|
||||
|
||||
async getOrder(orderId: string): Promise<Order> {
|
||||
return apiClient.get(`${this.basePath}/${orderId}`);
|
||||
}
|
||||
|
||||
async createOrder(order: OrderCreateRequest): Promise<Order> {
|
||||
return apiClient.post(`${this.basePath}`, order);
|
||||
}
|
||||
|
||||
async updateOrder(orderId: string, updates: OrderUpdateRequest): Promise<Order> {
|
||||
return apiClient.put(`${this.basePath}/${orderId}`, updates);
|
||||
}
|
||||
|
||||
async deleteOrder(orderId: string): Promise<void> {
|
||||
return apiClient.delete(`${this.basePath}/${orderId}`);
|
||||
}
|
||||
|
||||
async updateOrderStatus(orderId: string, status: Order['status']): Promise<Order> {
|
||||
return apiClient.patch(`${this.basePath}/${orderId}/status`, { status });
|
||||
}
|
||||
|
||||
async getOrderHistory(orderId: string): Promise<{
|
||||
order: Order;
|
||||
status_changes: {
|
||||
status: string;
|
||||
timestamp: string;
|
||||
user: string;
|
||||
notes?: string
|
||||
}[];
|
||||
}> {
|
||||
return apiClient.get(`${this.basePath}/${orderId}/history`);
|
||||
}
|
||||
|
||||
// Customers
|
||||
async getCustomers(params?: {
|
||||
search?: string;
|
||||
customer_type?: string;
|
||||
limit?: number;
|
||||
offset?: number;
|
||||
}): Promise<Customer[]> {
|
||||
return apiClient.get(`${this.basePath}/customers`, { params });
|
||||
}
|
||||
|
||||
async getCustomer(customerId: string): Promise<Customer> {
|
||||
return apiClient.get(`${this.basePath}/customers/${customerId}`);
|
||||
}
|
||||
|
||||
async createCustomer(customer: {
|
||||
name: string;
|
||||
email?: string;
|
||||
phone?: string;
|
||||
address?: string;
|
||||
customer_type: 'individual' | 'business' | 'catering';
|
||||
preferences?: string[];
|
||||
}): Promise<Customer> {
|
||||
return apiClient.post(`${this.basePath}/customers`, customer);
|
||||
}
|
||||
|
||||
async updateCustomer(customerId: string, updates: {
|
||||
name?: string;
|
||||
email?: string;
|
||||
phone?: string;
|
||||
address?: string;
|
||||
customer_type?: 'individual' | 'business' | 'catering';
|
||||
preferences?: string[];
|
||||
}): Promise<Customer> {
|
||||
return apiClient.put(`${this.basePath}/customers/${customerId}`, updates);
|
||||
}
|
||||
|
||||
async getCustomerOrders(customerId: string, params?: {
|
||||
limit?: number;
|
||||
offset?: number;
|
||||
}): Promise<Order[]> {
|
||||
return apiClient.get(`${this.basePath}/customers/${customerId}/orders`, { params });
|
||||
}
|
||||
|
||||
// Procurement Planning
|
||||
async getProcurementPlans(params?: {
|
||||
status?: string;
|
||||
date_from?: string;
|
||||
date_to?: string;
|
||||
limit?: number;
|
||||
offset?: number;
|
||||
}): Promise<ProcurementPlan[]> {
|
||||
return apiClient.get(`${this.basePath}/procurement/plans`, { params });
|
||||
}
|
||||
|
||||
async getProcurementPlan(planId: string): Promise<ProcurementPlan> {
|
||||
return apiClient.get(`${this.basePath}/procurement/plans/${planId}`);
|
||||
}
|
||||
|
||||
async createProcurementPlan(params: {
|
||||
date: string;
|
||||
orders?: string[];
|
||||
forecast_days?: number;
|
||||
}): Promise<ProcurementPlan> {
|
||||
return apiClient.post(`${this.basePath}/procurement/plans`, params);
|
||||
}
|
||||
|
||||
async updateProcurementPlan(planId: string, updates: {
|
||||
items?: ProcurementItem[];
|
||||
notes?: string;
|
||||
}): Promise<ProcurementPlan> {
|
||||
return apiClient.put(`${this.basePath}/procurement/plans/${planId}`, updates);
|
||||
}
|
||||
|
||||
async approveProcurementPlan(planId: string): Promise<ProcurementPlan> {
|
||||
return apiClient.post(`${this.basePath}/procurement/plans/${planId}/approve`);
|
||||
}
|
||||
|
||||
async generateSupplierOrders(planId: string): Promise<SupplierOrder[]> {
|
||||
return apiClient.post(`${this.basePath}/procurement/plans/${planId}/generate-orders`);
|
||||
}
|
||||
|
||||
// Business Model Detection
|
||||
async detectBusinessModel(): Promise<{
|
||||
detected_model: 'individual_bakery' | 'central_bakery';
|
||||
confidence: number;
|
||||
factors: {
|
||||
daily_order_volume: number;
|
||||
delivery_ratio: number;
|
||||
catering_ratio: number;
|
||||
average_order_size: number;
|
||||
};
|
||||
recommendations: string[];
|
||||
}> {
|
||||
return apiClient.post(`${this.basePath}/business-model/detect`);
|
||||
}
|
||||
|
||||
async updateBusinessModel(model: 'individual_bakery' | 'central_bakery'): Promise<void> {
|
||||
return apiClient.put(`${this.basePath}/business-model`, { business_model: model });
|
||||
}
|
||||
|
||||
// Analytics
|
||||
async getOrderTrends(params?: {
|
||||
date_from?: string;
|
||||
date_to?: string;
|
||||
granularity?: 'hour' | 'day' | 'week' | 'month';
|
||||
}): Promise<{
|
||||
dates: string[];
|
||||
order_counts: number[];
|
||||
revenue: number[];
|
||||
popular_items: { recipe_name: string; count: number }[];
|
||||
}> {
|
||||
return apiClient.get(`${this.basePath}/analytics/trends`, { params });
|
||||
}
|
||||
|
||||
async getCustomerAnalytics(params?: {
|
||||
date_from?: string;
|
||||
date_to?: string;
|
||||
}): Promise<{
|
||||
new_customers: number;
|
||||
returning_customers: number;
|
||||
customer_retention_rate: number;
|
||||
average_lifetime_value: number;
|
||||
top_customers: Customer[];
|
||||
}> {
|
||||
return apiClient.get(`${this.basePath}/analytics/customers`, { params });
|
||||
}
|
||||
|
||||
async getSeasonalAnalysis(params?: {
|
||||
date_from?: string;
|
||||
date_to?: string;
|
||||
}): Promise<{
|
||||
seasonal_patterns: { month: string; order_count: number; revenue: number }[];
|
||||
weekly_patterns: { day: string; order_count: number }[];
|
||||
hourly_patterns: { hour: number; order_count: number }[];
|
||||
trending_products: { recipe_name: string; growth_rate: number }[];
|
||||
}> {
|
||||
return apiClient.get(`${this.basePath}/analytics/seasonal`, { params });
|
||||
}
|
||||
|
||||
// Alerts
|
||||
async getOrderAlerts(params?: {
|
||||
severity?: string;
|
||||
status?: string;
|
||||
limit?: number;
|
||||
}): Promise<any[]> {
|
||||
return apiClient.get(`${this.basePath}/alerts`, { params });
|
||||
}
|
||||
|
||||
async acknowledgeAlert(alertId: string): Promise<void> {
|
||||
return apiClient.post(`${this.basePath}/alerts/${alertId}/acknowledge`);
|
||||
}
|
||||
|
||||
async resolveAlert(alertId: string, resolution?: string): Promise<void> {
|
||||
return apiClient.post(`${this.basePath}/alerts/${alertId}/resolve`, { resolution });
|
||||
}
|
||||
}
|
||||
314
frontend/src/api/services/production.service.ts
Normal file
314
frontend/src/api/services/production.service.ts
Normal file
@@ -0,0 +1,314 @@
|
||||
// ================================================================
|
||||
// frontend/src/api/services/production.service.ts
|
||||
// ================================================================
|
||||
/**
|
||||
* Production Service - API client for Production Service endpoints
|
||||
*/
|
||||
|
||||
import { apiClient } from '../client';
|
||||
|
||||
// Production Types
|
||||
export interface ProductionBatch {
|
||||
id: string;
|
||||
recipe_id: string;
|
||||
recipe_name: string;
|
||||
quantity: number;
|
||||
unit: string;
|
||||
status: 'scheduled' | 'in_progress' | 'completed' | 'delayed' | 'failed';
|
||||
scheduled_start: string;
|
||||
actual_start?: string;
|
||||
expected_end: string;
|
||||
actual_end?: string;
|
||||
equipment_id: string;
|
||||
equipment_name: string;
|
||||
operator_id: string;
|
||||
operator_name: string;
|
||||
temperature?: number;
|
||||
humidity?: number;
|
||||
quality_score?: number;
|
||||
notes?: string;
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
}
|
||||
|
||||
export interface ProductionPlan {
|
||||
id: string;
|
||||
date: string;
|
||||
total_capacity: number;
|
||||
allocated_capacity: number;
|
||||
efficiency_target: number;
|
||||
quality_target: number;
|
||||
batches: ProductionBatch[];
|
||||
status: 'draft' | 'approved' | 'in_progress' | 'completed';
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
}
|
||||
|
||||
export interface Equipment {
|
||||
id: string;
|
||||
name: string;
|
||||
type: string;
|
||||
status: 'active' | 'idle' | 'maintenance' | 'error';
|
||||
location: string;
|
||||
capacity: number;
|
||||
current_batch_id?: string;
|
||||
temperature?: number;
|
||||
utilization: number;
|
||||
last_maintenance: string;
|
||||
next_maintenance: string;
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
}
|
||||
|
||||
export interface ProductionDashboardData {
|
||||
summary: {
|
||||
active_batches: number;
|
||||
equipment_in_use: number;
|
||||
current_efficiency: number;
|
||||
todays_production: number;
|
||||
alerts_count: number;
|
||||
};
|
||||
efficiency_trend: { date: string; efficiency: number }[];
|
||||
quality_trend: { date: string; quality: number }[];
|
||||
equipment_status: Equipment[];
|
||||
active_batches: ProductionBatch[];
|
||||
alerts: any[];
|
||||
}
|
||||
|
||||
export interface BatchCreateRequest {
|
||||
recipe_id: string;
|
||||
quantity: number;
|
||||
scheduled_start: string;
|
||||
expected_end: string;
|
||||
equipment_id: string;
|
||||
operator_id: string;
|
||||
notes?: string;
|
||||
priority?: number;
|
||||
}
|
||||
|
||||
export interface BatchUpdateRequest {
|
||||
status?: 'scheduled' | 'in_progress' | 'completed' | 'delayed' | 'failed';
|
||||
actual_start?: string;
|
||||
actual_end?: string;
|
||||
temperature?: number;
|
||||
humidity?: number;
|
||||
quality_score?: number;
|
||||
notes?: string;
|
||||
}
|
||||
|
||||
export interface PlanCreateRequest {
|
||||
date: string;
|
||||
batches: BatchCreateRequest[];
|
||||
efficiency_target?: number;
|
||||
quality_target?: number;
|
||||
}
|
||||
|
||||
export class ProductionService {
|
||||
private readonly basePath = '/production';
|
||||
|
||||
// Dashboard
|
||||
async getDashboardData(params?: {
|
||||
date_from?: string;
|
||||
date_to?: string;
|
||||
}): Promise<ProductionDashboardData> {
|
||||
return apiClient.get(`${this.basePath}/dashboard`, { params });
|
||||
}
|
||||
|
||||
async getDashboardMetrics(params?: {
|
||||
date_from?: string;
|
||||
date_to?: string;
|
||||
granularity?: 'hour' | 'day' | 'week' | 'month';
|
||||
}): Promise<{
|
||||
dates: string[];
|
||||
efficiency: number[];
|
||||
quality: number[];
|
||||
production_volume: number[];
|
||||
equipment_utilization: number[];
|
||||
}> {
|
||||
return apiClient.get(`${this.basePath}/dashboard/metrics`, { params });
|
||||
}
|
||||
|
||||
// Batches
|
||||
async getBatches(params?: {
|
||||
status?: string;
|
||||
equipment_id?: string;
|
||||
date_from?: string;
|
||||
date_to?: string;
|
||||
limit?: number;
|
||||
offset?: number;
|
||||
}): Promise<ProductionBatch[]> {
|
||||
return apiClient.get(`${this.basePath}/batches`, { params });
|
||||
}
|
||||
|
||||
async getBatch(batchId: string): Promise<ProductionBatch> {
|
||||
return apiClient.get(`${this.basePath}/batches/${batchId}`);
|
||||
}
|
||||
|
||||
async createBatch(batch: BatchCreateRequest): Promise<ProductionBatch> {
|
||||
return apiClient.post(`${this.basePath}/batches`, batch);
|
||||
}
|
||||
|
||||
async updateBatch(batchId: string, updates: BatchUpdateRequest): Promise<ProductionBatch> {
|
||||
return apiClient.put(`${this.basePath}/batches/${batchId}`, updates);
|
||||
}
|
||||
|
||||
async deleteBatch(batchId: string): Promise<void> {
|
||||
return apiClient.delete(`${this.basePath}/batches/${batchId}`);
|
||||
}
|
||||
|
||||
async startBatch(batchId: string): Promise<ProductionBatch> {
|
||||
return apiClient.post(`${this.basePath}/batches/${batchId}/start`);
|
||||
}
|
||||
|
||||
async completeBatch(batchId: string, qualityScore?: number, notes?: string): Promise<ProductionBatch> {
|
||||
return apiClient.post(`${this.basePath}/batches/${batchId}/complete`, {
|
||||
quality_score: qualityScore,
|
||||
notes
|
||||
});
|
||||
}
|
||||
|
||||
async getBatchStatus(batchId: string): Promise<{
|
||||
status: string;
|
||||
progress: number;
|
||||
current_phase: string;
|
||||
temperature: number;
|
||||
humidity: number;
|
||||
estimated_completion: string;
|
||||
alerts: any[];
|
||||
}> {
|
||||
return apiClient.get(`${this.basePath}/batches/${batchId}/status`);
|
||||
}
|
||||
|
||||
// Production Plans
|
||||
async getPlans(params?: {
|
||||
date_from?: string;
|
||||
date_to?: string;
|
||||
status?: string;
|
||||
limit?: number;
|
||||
offset?: number;
|
||||
}): Promise<ProductionPlan[]> {
|
||||
return apiClient.get(`${this.basePath}/plans`, { params });
|
||||
}
|
||||
|
||||
async getPlan(planId: string): Promise<ProductionPlan> {
|
||||
return apiClient.get(`${this.basePath}/plans/${planId}`);
|
||||
}
|
||||
|
||||
async createPlan(plan: PlanCreateRequest): Promise<ProductionPlan> {
|
||||
return apiClient.post(`${this.basePath}/plans`, plan);
|
||||
}
|
||||
|
||||
async updatePlan(planId: string, updates: Partial<PlanCreateRequest>): Promise<ProductionPlan> {
|
||||
return apiClient.put(`${this.basePath}/plans/${planId}`, updates);
|
||||
}
|
||||
|
||||
async deletePlan(planId: string): Promise<void> {
|
||||
return apiClient.delete(`${this.basePath}/plans/${planId}`);
|
||||
}
|
||||
|
||||
async approvePlan(planId: string): Promise<ProductionPlan> {
|
||||
return apiClient.post(`${this.basePath}/plans/${planId}/approve`);
|
||||
}
|
||||
|
||||
async optimizePlan(planId: string): Promise<ProductionPlan> {
|
||||
return apiClient.post(`${this.basePath}/plans/${planId}/optimize`);
|
||||
}
|
||||
|
||||
// Equipment
|
||||
async getEquipment(params?: {
|
||||
status?: string;
|
||||
type?: string;
|
||||
location?: string;
|
||||
limit?: number;
|
||||
offset?: number;
|
||||
}): Promise<Equipment[]> {
|
||||
return apiClient.get(`${this.basePath}/equipment`, { params });
|
||||
}
|
||||
|
||||
async getEquipmentById(equipmentId: string): Promise<Equipment> {
|
||||
return apiClient.get(`${this.basePath}/equipment/${equipmentId}`);
|
||||
}
|
||||
|
||||
async updateEquipment(equipmentId: string, updates: {
|
||||
status?: 'active' | 'idle' | 'maintenance' | 'error';
|
||||
temperature?: number;
|
||||
notes?: string;
|
||||
}): Promise<Equipment> {
|
||||
return apiClient.put(`${this.basePath}/equipment/${equipmentId}`, updates);
|
||||
}
|
||||
|
||||
async getEquipmentMetrics(equipmentId: string, params?: {
|
||||
date_from?: string;
|
||||
date_to?: string;
|
||||
}): Promise<{
|
||||
utilization: number[];
|
||||
temperature: number[];
|
||||
maintenance_events: any[];
|
||||
performance_score: number;
|
||||
}> {
|
||||
return apiClient.get(`${this.basePath}/equipment/${equipmentId}/metrics`, { params });
|
||||
}
|
||||
|
||||
async scheduleMaintenanceForEquipment(equipmentId: string, scheduledDate: string, notes?: string): Promise<void> {
|
||||
return apiClient.post(`${this.basePath}/equipment/${equipmentId}/maintenance`, {
|
||||
scheduled_date: scheduledDate,
|
||||
notes
|
||||
});
|
||||
}
|
||||
|
||||
// Analytics
|
||||
async getEfficiencyTrends(params?: {
|
||||
date_from?: string;
|
||||
date_to?: string;
|
||||
equipment_id?: string;
|
||||
}): Promise<{
|
||||
dates: string[];
|
||||
efficiency: number[];
|
||||
quality: number[];
|
||||
volume: number[];
|
||||
}> {
|
||||
return apiClient.get(`${this.basePath}/analytics/efficiency`, { params });
|
||||
}
|
||||
|
||||
async getProductionForecast(params?: {
|
||||
days?: number;
|
||||
include_weather?: boolean;
|
||||
}): Promise<{
|
||||
dates: string[];
|
||||
predicted_volume: number[];
|
||||
confidence_intervals: number[][];
|
||||
factors: string[];
|
||||
}> {
|
||||
return apiClient.get(`${this.basePath}/analytics/forecast`, { params });
|
||||
}
|
||||
|
||||
async getQualityAnalysis(params?: {
|
||||
date_from?: string;
|
||||
date_to?: string;
|
||||
recipe_id?: string;
|
||||
}): Promise<{
|
||||
average_quality: number;
|
||||
quality_trend: number[];
|
||||
quality_factors: { factor: string; impact: number }[];
|
||||
recommendations: string[];
|
||||
}> {
|
||||
return apiClient.get(`${this.basePath}/analytics/quality`, { params });
|
||||
}
|
||||
|
||||
// Alerts
|
||||
async getProductionAlerts(params?: {
|
||||
severity?: string;
|
||||
status?: string;
|
||||
limit?: number;
|
||||
}): Promise<any[]> {
|
||||
return apiClient.get(`${this.basePath}/alerts`, { params });
|
||||
}
|
||||
|
||||
async acknowledgeAlert(alertId: string): Promise<void> {
|
||||
return apiClient.post(`${this.basePath}/alerts/${alertId}/acknowledge`);
|
||||
}
|
||||
|
||||
async resolveAlert(alertId: string, resolution?: string): Promise<void> {
|
||||
return apiClient.post(`${this.basePath}/alerts/${alertId}/resolve`, { resolution });
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user