Add improved production UI

This commit is contained in:
Urtzi Alfaro
2025-09-23 12:49:35 +02:00
parent 8d54202e91
commit 4ae8e14e55
35 changed files with 6848 additions and 415 deletions

View File

@@ -88,7 +88,9 @@ export const useActiveBatches = (
) => {
return useQuery<ProductionBatchListResponse, ApiError>({
queryKey: productionKeys.activeBatches(tenantId),
queryFn: () => productionService.getActiveBatches(tenantId),
queryFn: () => productionService.getBatches(tenantId, {
status: undefined // Get all active statuses
}),
enabled: !!tenantId,
staleTime: 30 * 1000, // 30 seconds
refetchInterval: 60 * 1000, // 1 minute
@@ -103,7 +105,7 @@ export const useBatchDetails = (
) => {
return useQuery<ProductionBatchResponse, ApiError>({
queryKey: productionKeys.batch(tenantId, batchId),
queryFn: () => productionService.getBatchDetails(tenantId, batchId),
queryFn: () => productionService.getBatch(tenantId, batchId),
enabled: !!tenantId && !!batchId,
staleTime: 30 * 1000, // 30 seconds
...options,
@@ -160,9 +162,9 @@ export const useCreateProductionBatch = (
options?: UseMutationOptions<ProductionBatchResponse, ApiError, { tenantId: string; batchData: ProductionBatchCreate }>
) => {
const queryClient = useQueryClient();
return useMutation<ProductionBatchResponse, ApiError, { tenantId: string; batchData: ProductionBatchCreate }>({
mutationFn: ({ tenantId, batchData }) => productionService.createProductionBatch(tenantId, batchData),
mutationFn: ({ tenantId, batchData }) => productionService.createBatch(tenantId, batchData),
onSuccess: (data, { tenantId }) => {
// Invalidate active batches to refresh the list
queryClient.invalidateQueries({ queryKey: productionKeys.activeBatches(tenantId) });
@@ -189,7 +191,7 @@ export const useUpdateBatchStatus = (
ApiError,
{ tenantId: string; batchId: string; statusUpdate: ProductionBatchStatusUpdate }
>({
mutationFn: ({ tenantId, batchId, statusUpdate }) =>
mutationFn: ({ tenantId, batchId, statusUpdate }) =>
productionService.updateBatchStatus(tenantId, batchId, statusUpdate),
onSuccess: (data, { tenantId, batchId }) => {
// Update the specific batch data

View File

@@ -1,79 +1,360 @@
import { apiClient } from '../client';
import type {
ProductionBatchCreate,
ProductionBatchStatusUpdate,
/**
* Production API Service - Handles all production-related API calls
*/
import { apiClient } from '../client/apiClient';
import {
// Types
ProductionBatchResponse,
ProductionBatchCreate,
ProductionBatchUpdate,
ProductionBatchStatusUpdate,
ProductionBatchListResponse,
ProductionBatchFilters,
ProductionScheduleResponse,
ProductionScheduleCreate,
ProductionScheduleUpdate,
ProductionScheduleFilters,
ProductionCapacityResponse,
ProductionCapacityFilters,
QualityCheckResponse,
QualityCheckCreate,
QualityCheckFilters,
ProductionPerformanceAnalytics,
YieldTrendsAnalytics,
TopDefectsAnalytics,
EquipmentEfficiencyAnalytics,
CapacityBottlenecks,
ProductionDashboardSummary,
DailyProductionRequirements,
ProductionScheduleData,
ProductionCapacityStatus,
ProductionRequirements,
ProductionYieldMetrics,
BatchStatistics,
} from '../types/production';
export class ProductionService {
private readonly baseUrl = '/production';
private baseUrl = '/production';
getDashboardSummary(tenantId: string): Promise<ProductionDashboardSummary> {
return apiClient.get(`/tenants/${tenantId}${this.baseUrl}/dashboard-summary`);
// ================================================================
// PRODUCTION BATCH ENDPOINTS
// ================================================================
async getBatches(
tenantId: string,
filters?: ProductionBatchFilters
): Promise<ProductionBatchListResponse> {
const params = new URLSearchParams();
if (filters?.status) params.append('status', filters.status);
if (filters?.product_id) params.append('product_id', filters.product_id);
if (filters?.order_id) params.append('order_id', filters.order_id);
if (filters?.start_date) params.append('start_date', filters.start_date);
if (filters?.end_date) params.append('end_date', filters.end_date);
if (filters?.page) params.append('page', filters.page.toString());
if (filters?.page_size) params.append('page_size', filters.page_size.toString());
const queryString = params.toString();
const url = `/tenants/${tenantId}${this.baseUrl}/batches${queryString ? `?${queryString}` : ''}`;
return apiClient.get<ProductionBatchListResponse>(url);
}
getDailyRequirements(tenantId: string, date?: string): Promise<DailyProductionRequirements> {
const params = date ? { date } : {};
return apiClient.get(`/tenants/${tenantId}${this.baseUrl}/daily-requirements`, { params });
async getBatch(tenantId: string, batchId: string): Promise<ProductionBatchResponse> {
return apiClient.get<ProductionBatchResponse>(`/tenants/${tenantId}${this.baseUrl}/batches/${batchId}`);
}
getProductionRequirements(tenantId: string, date?: string): Promise<ProductionRequirements> {
const params = date ? { date } : {};
return apiClient.get(`/tenants/${tenantId}${this.baseUrl}/requirements`, { params });
async createBatch(
tenantId: string,
batchData: ProductionBatchCreate
): Promise<ProductionBatchResponse> {
return apiClient.post<ProductionBatchResponse>(
`/tenants/${tenantId}${this.baseUrl}/batches`,
batchData
);
}
createProductionBatch(tenantId: string, batchData: ProductionBatchCreate): Promise<ProductionBatchResponse> {
return apiClient.post(`/tenants/${tenantId}${this.baseUrl}/batches`, batchData);
}
getActiveBatches(tenantId: string): Promise<ProductionBatchListResponse> {
return apiClient.get(`/tenants/${tenantId}${this.baseUrl}/batches/active`);
}
getBatchDetails(tenantId: string, batchId: string): Promise<ProductionBatchResponse> {
return apiClient.get(`/tenants/${tenantId}${this.baseUrl}/batches/${batchId}`);
}
updateBatchStatus(
async updateBatch(
tenantId: string,
batchId: string,
statusUpdate: ProductionBatchStatusUpdate
batchData: ProductionBatchUpdate
): Promise<ProductionBatchResponse> {
return apiClient.put(`/tenants/${tenantId}${this.baseUrl}/batches/${batchId}/status`, statusUpdate);
return apiClient.put<ProductionBatchResponse>(
`/tenants/${tenantId}${this.baseUrl}/batches/${batchId}`,
batchData
);
}
getProductionSchedule(
async deleteBatch(tenantId: string, batchId: string): Promise<void> {
return apiClient.delete<void>(`/tenants/${tenantId}${this.baseUrl}/batches/${batchId}`);
}
async updateBatchStatus(
tenantId: string,
batchId: string,
statusData: ProductionBatchStatusUpdate
): Promise<ProductionBatchResponse> {
return apiClient.patch<ProductionBatchResponse>(
`/tenants/${tenantId}${this.baseUrl}/batches/${batchId}/status`,
statusData
);
}
async startBatch(tenantId: string, batchId: string): Promise<ProductionBatchResponse> {
return apiClient.post<ProductionBatchResponse>(
`/tenants/${tenantId}${this.baseUrl}/batches/${batchId}/start`
);
}
async completeBatch(
tenantId: string,
batchId: string,
completionData?: { actual_quantity?: number; notes?: string }
): Promise<ProductionBatchResponse> {
return apiClient.post<ProductionBatchResponse>(
`/tenants/${tenantId}${this.baseUrl}/batches/${batchId}/complete`,
completionData || {}
);
}
async getBatchStatistics(
tenantId: string,
startDate?: string,
endDate?: string
): Promise<ProductionScheduleData> {
const params: Record<string, string> = {};
if (startDate) params.start_date = startDate;
if (endDate) params.end_date = endDate;
return apiClient.get(`/tenants/${tenantId}${this.baseUrl}/schedule`, { params });
): Promise<BatchStatistics> {
const params = new URLSearchParams();
if (startDate) params.append('start_date', startDate);
if (endDate) params.append('end_date', endDate);
const queryString = params.toString();
const url = `/tenants/${tenantId}${this.baseUrl}/batches/stats${queryString ? `?${queryString}` : ''}`;
return apiClient.get<BatchStatistics>(url);
}
getCapacityStatus(tenantId: string, date?: string): Promise<ProductionCapacityStatus> {
const params = date ? { date } : {};
return apiClient.get(`/tenants/${tenantId}${this.baseUrl}/capacity/status`, { params });
// ================================================================
// PRODUCTION SCHEDULE ENDPOINTS
// ================================================================
async getSchedules(
tenantId: string,
filters?: ProductionScheduleFilters
): Promise<{ schedules: ProductionScheduleResponse[]; total_count: number; page: number; page_size: number }> {
const params = new URLSearchParams();
if (filters?.start_date) params.append('start_date', filters.start_date);
if (filters?.end_date) params.append('end_date', filters.end_date);
if (filters?.is_finalized !== undefined) params.append('is_finalized', filters.is_finalized.toString());
if (filters?.page) params.append('page', filters.page.toString());
if (filters?.page_size) params.append('page_size', filters.page_size.toString());
const queryString = params.toString();
const url = `/tenants/${tenantId}${this.baseUrl}/schedules${queryString ? `?${queryString}` : ''}`;
return apiClient.get(url);
}
getYieldMetrics(
async getSchedule(tenantId: string, scheduleId: string): Promise<ProductionScheduleResponse> {
return apiClient.get<ProductionScheduleResponse>(`/tenants/${tenantId}${this.baseUrl}/schedules/${scheduleId}`);
}
async createSchedule(
tenantId: string,
scheduleData: ProductionScheduleCreate
): Promise<ProductionScheduleResponse> {
return apiClient.post<ProductionScheduleResponse>(
`/tenants/${tenantId}${this.baseUrl}/schedules`,
scheduleData
);
}
async updateSchedule(
tenantId: string,
scheduleId: string,
scheduleData: ProductionScheduleUpdate
): Promise<ProductionScheduleResponse> {
return apiClient.put<ProductionScheduleResponse>(
`/tenants/${tenantId}${this.baseUrl}/schedules/${scheduleId}`,
scheduleData
);
}
async deleteSchedule(tenantId: string, scheduleId: string): Promise<void> {
return apiClient.delete<void>(`/tenants/${tenantId}${this.baseUrl}/schedules/${scheduleId}`);
}
async finalizeSchedule(tenantId: string, scheduleId: string): Promise<ProductionScheduleResponse> {
return apiClient.post<ProductionScheduleResponse>(
`/tenants/${tenantId}${this.baseUrl}/schedules/${scheduleId}/finalize`
);
}
async getTodaysSchedule(tenantId: string): Promise<ProductionScheduleResponse | null> {
return apiClient.get<ProductionScheduleResponse | null>(`/tenants/${tenantId}${this.baseUrl}/schedules/today`);
}
// ================================================================
// PRODUCTION CAPACITY ENDPOINTS
// ================================================================
async getCapacity(
tenantId: string,
filters?: ProductionCapacityFilters
): Promise<{ capacity: ProductionCapacityResponse[]; total_count: number; page: number; page_size: number }> {
const params = new URLSearchParams();
if (filters?.resource_type) params.append('resource_type', filters.resource_type);
if (filters?.date) params.append('date', filters.date);
if (filters?.availability !== undefined) params.append('availability', filters.availability.toString());
if (filters?.page) params.append('page', filters.page.toString());
if (filters?.page_size) params.append('page_size', filters.page_size.toString());
const queryString = params.toString();
const url = `/tenants/${tenantId}${this.baseUrl}/capacity${queryString ? `?${queryString}` : ''}`;
return apiClient.get(url);
}
async getCapacityByDate(tenantId: string, date: string): Promise<ProductionCapacityResponse[]> {
return apiClient.get<ProductionCapacityResponse[]>(`/tenants/${tenantId}${this.baseUrl}/capacity/date/${date}`);
}
async getCapacityByResource(tenantId: string, resourceId: string): Promise<ProductionCapacityResponse[]> {
return apiClient.get<ProductionCapacityResponse[]>(`/tenants/${tenantId}${this.baseUrl}/capacity/resource/${resourceId}`);
}
// ================================================================
// QUALITY CHECK ENDPOINTS
// ================================================================
async getQualityChecks(
tenantId: string,
filters?: QualityCheckFilters
): Promise<{ quality_checks: QualityCheckResponse[]; total_count: number; page: number; page_size: number }> {
const params = new URLSearchParams();
if (filters?.batch_id) params.append('batch_id', filters.batch_id);
if (filters?.product_id) params.append('product_id', filters.product_id);
if (filters?.start_date) params.append('start_date', filters.start_date);
if (filters?.end_date) params.append('end_date', filters.end_date);
if (filters?.pass_fail !== undefined) params.append('pass_fail', filters.pass_fail.toString());
if (filters?.page) params.append('page', filters.page.toString());
if (filters?.page_size) params.append('page_size', filters.page_size.toString());
const queryString = params.toString();
const url = `/tenants/${tenantId}${this.baseUrl}/quality-checks${queryString ? `?${queryString}` : ''}`;
return apiClient.get(url);
}
async getQualityCheck(tenantId: string, checkId: string): Promise<QualityCheckResponse> {
return apiClient.get<QualityCheckResponse>(`/tenants/${tenantId}${this.baseUrl}/quality-checks/${checkId}`);
}
async createQualityCheck(
tenantId: string,
checkData: QualityCheckCreate
): Promise<QualityCheckResponse> {
return apiClient.post<QualityCheckResponse>(
`/tenants/${tenantId}${this.baseUrl}/quality-checks`,
checkData
);
}
async getQualityChecksByBatch(tenantId: string, batchId: string): Promise<QualityCheckResponse[]> {
return apiClient.get<QualityCheckResponse[]>(`/tenants/${tenantId}${this.baseUrl}/quality-checks/batch/${batchId}`);
}
// ================================================================
// ANALYTICS ENDPOINTS
// ================================================================
async getPerformanceAnalytics(
tenantId: string,
startDate: string,
endDate: string
): Promise<ProductionYieldMetrics> {
const params = { start_date: startDate, end_date: endDate };
return apiClient.get(`/tenants/${tenantId}${this.baseUrl}/metrics/yield`, { params });
): Promise<ProductionPerformanceAnalytics> {
return apiClient.get<ProductionPerformanceAnalytics>(
`/tenants/${tenantId}${this.baseUrl}/analytics/performance?start_date=${startDate}&end_date=${endDate}`
);
}
async getYieldTrends(
tenantId: string,
period: 'week' | 'month' = 'week'
): Promise<YieldTrendsAnalytics> {
return apiClient.get<YieldTrendsAnalytics>(
`/tenants/${tenantId}${this.baseUrl}/analytics/yield-trends?period=${period}`
);
}
async getTopDefects(
tenantId: string,
startDate?: string,
endDate?: string
): Promise<TopDefectsAnalytics> {
const params = new URLSearchParams();
if (startDate) params.append('start_date', startDate);
if (endDate) params.append('end_date', endDate);
const queryString = params.toString();
const url = `/tenants/${tenantId}${this.baseUrl}/analytics/defects${queryString ? `?${queryString}` : ''}`;
return apiClient.get<TopDefectsAnalytics>(url);
}
async getEquipmentEfficiency(
tenantId: string,
startDate?: string,
endDate?: string
): Promise<EquipmentEfficiencyAnalytics> {
const params = new URLSearchParams();
if (startDate) params.append('start_date', startDate);
if (endDate) params.append('end_date', endDate);
const queryString = params.toString();
const url = `/tenants/${tenantId}${this.baseUrl}/analytics/equipment-efficiency${queryString ? `?${queryString}` : ''}`;
return apiClient.get<EquipmentEfficiencyAnalytics>(url);
}
async getCapacityBottlenecks(
tenantId: string,
days: number = 7
): Promise<CapacityBottlenecks> {
return apiClient.get<CapacityBottlenecks>(
`/tenants/${tenantId}${this.baseUrl}/analytics/capacity-bottlenecks?days=${days}`
);
}
// ================================================================
// DASHBOARD ENDPOINTS
// ================================================================
async getDashboardSummary(tenantId: string): Promise<ProductionDashboardSummary> {
return apiClient.get<ProductionDashboardSummary>(`/tenants/${tenantId}${this.baseUrl}/dashboard/summary`);
}
async getDailyProductionPlan(tenantId: string, date?: string): Promise<any> {
const queryString = date ? `?date=${date}` : '';
return apiClient.get(`/tenants/${tenantId}${this.baseUrl}/dashboard/daily-plan${queryString}`);
}
async getProductionRequirements(tenantId: string, date: string): Promise<any> {
return apiClient.get(`/tenants/${tenantId}${this.baseUrl}/dashboard/requirements/${date}`);
}
async getCapacityOverview(tenantId: string, date?: string): Promise<any> {
const queryString = date ? `?date=${date}` : '';
return apiClient.get(`/tenants/${tenantId}${this.baseUrl}/dashboard/capacity-overview${queryString}`);
}
async getQualityOverview(
tenantId: string,
startDate?: string,
endDate?: string
): Promise<any> {
const params = new URLSearchParams();
if (startDate) params.append('start_date', startDate);
if (endDate) params.append('end_date', endDate);
const queryString = params.toString();
const url = `/tenants/${tenantId}${this.baseUrl}/dashboard/quality-overview${queryString ? `?${queryString}` : ''}`;
return apiClient.get(url);
}
}
export const productionService = new ProductionService();
export const productionService = new ProductionService();
export default productionService;

View File

@@ -1,77 +1,82 @@
export enum ProductionStatusEnum {
PENDING = "pending",
IN_PROGRESS = "in_progress",
COMPLETED = "completed",
CANCELLED = "cancelled",
ON_HOLD = "on_hold",
QUALITY_CHECK = "quality_check",
FAILED = "failed"
/**
* Production API Types - Mirror backend schemas
*/
// Enums
export enum ProductionStatus {
PENDING = "PENDING",
IN_PROGRESS = "IN_PROGRESS",
COMPLETED = "COMPLETED",
CANCELLED = "CANCELLED",
ON_HOLD = "ON_HOLD",
QUALITY_CHECK = "QUALITY_CHECK",
FAILED = "FAILED"
}
export enum ProductionPriorityEnum {
LOW = "low",
MEDIUM = "medium",
HIGH = "high",
URGENT = "urgent"
}
export enum ProductionBatchStatus {
PLANNED = "planned",
IN_PROGRESS = "in_progress",
COMPLETED = "completed",
CANCELLED = "cancelled",
ON_HOLD = "on_hold"
export enum ProductionPriority {
LOW = "LOW",
MEDIUM = "MEDIUM",
HIGH = "HIGH",
URGENT = "URGENT"
}
// Quality Check Status Enum
export enum QualityCheckStatus {
PENDING = "pending",
IN_PROGRESS = "in_progress",
PASSED = "passed",
FAILED = "failed",
REQUIRES_ATTENTION = "requires_attention"
PASSED = "PASSED",
FAILED = "FAILED",
PENDING = "PENDING",
IN_REVIEW = "IN_REVIEW"
}
// Alternative exports for compatibility
export const ProductionStatusEnum = ProductionStatus;
export const ProductionPriorityEnum = ProductionPriority;
export const ProductionBatchStatus = ProductionStatus;
export const ProductionBatchPriority = ProductionPriority;
export const QualityCheckStatusEnum = QualityCheckStatus;
// Production Batch Types
export interface ProductionBatchBase {
product_id: string;
product_name: string;
recipe_id?: string | null;
recipe_id?: string;
planned_start_time: string;
planned_end_time: string;
planned_quantity: number;
planned_duration_minutes: number;
priority: ProductionPriorityEnum;
priority: ProductionPriority;
is_rush_order: boolean;
is_special_recipe: boolean;
production_notes?: string | null;
production_notes?: string;
}
export interface ProductionBatchCreate extends ProductionBatchBase {
batch_number?: string | null;
order_id?: string | null;
forecast_id?: string | null;
equipment_used?: string[] | null;
staff_assigned?: string[] | null;
station_id?: string | null;
batch_number?: string;
order_id?: string;
forecast_id?: string;
equipment_used?: string[];
staff_assigned?: string[];
station_id?: string;
}
export interface ProductionBatchUpdate {
product_name?: string | null;
planned_start_time?: string | null;
planned_end_time?: string | null;
planned_quantity?: number | null;
planned_duration_minutes?: number | null;
actual_quantity?: number | null;
priority?: ProductionPriorityEnum | null;
equipment_used?: string[] | null;
staff_assigned?: string[] | null;
station_id?: string | null;
production_notes?: string | null;
product_name?: string;
planned_start_time?: string;
planned_end_time?: string;
planned_quantity?: number;
planned_duration_minutes?: number;
actual_quantity?: number;
priority?: ProductionPriority;
equipment_used?: string[];
staff_assigned?: string[];
station_id?: string;
production_notes?: string;
}
export interface ProductionBatchStatusUpdate {
status: ProductionStatusEnum;
actual_quantity?: number | null;
notes?: string | null;
status: ProductionStatus;
actual_quantity?: number;
notes?: string;
}
export interface ProductionBatchResponse {
@@ -80,37 +85,50 @@ export interface ProductionBatchResponse {
batch_number: string;
product_id: string;
product_name: string;
recipe_id?: string | null;
recipe_id?: string;
planned_start_time: string;
planned_end_time: string;
planned_quantity: number;
planned_duration_minutes: number;
actual_start_time?: string | null;
actual_end_time?: string | null;
actual_quantity?: number | null;
actual_duration_minutes?: number | null;
status: ProductionStatusEnum;
priority: ProductionPriorityEnum;
estimated_cost?: number | null;
actual_cost?: number | null;
yield_percentage?: number | null;
quality_score?: number | null;
equipment_used?: string[] | null;
staff_assigned?: string[] | null;
station_id?: string | null;
order_id?: string | null;
forecast_id?: string | null;
actual_start_time?: string;
actual_end_time?: string;
actual_quantity?: number;
actual_duration_minutes?: number;
status: ProductionStatus;
priority: ProductionPriority;
estimated_cost?: number;
actual_cost?: number;
labor_cost?: number;
material_cost?: number;
overhead_cost?: number;
yield_percentage?: number;
quality_score?: number;
waste_quantity?: number;
defect_quantity?: number;
equipment_used?: string[];
staff_assigned?: string[];
station_id?: string;
order_id?: string;
forecast_id?: string;
is_rush_order: boolean;
is_special_recipe: boolean;
production_notes?: string | null;
quality_notes?: string | null;
delay_reason?: string | null;
cancellation_reason?: string | null;
production_notes?: string;
quality_notes?: string;
delay_reason?: string;
cancellation_reason?: string;
created_at: string;
updated_at: string;
completed_at?: string | null;
completed_at?: string;
}
export interface ProductionBatchListResponse {
batches: ProductionBatchResponse[];
total_count: number;
page: number;
page_size: number;
}
// Production Schedule Types
export interface ProductionScheduleBase {
schedule_date: string;
shift_start: string;
@@ -118,23 +136,23 @@ export interface ProductionScheduleBase {
total_capacity_hours: number;
planned_capacity_hours: number;
staff_count: number;
equipment_capacity?: Record<string, any> | null;
station_assignments?: Record<string, any> | null;
schedule_notes?: string | null;
equipment_capacity?: Record<string, any>;
station_assignments?: Record<string, any>;
schedule_notes?: string;
}
export interface ProductionScheduleCreate extends ProductionScheduleBase {}
export interface ProductionScheduleUpdate {
shift_start?: string | null;
shift_end?: string | null;
total_capacity_hours?: number | null;
planned_capacity_hours?: number | null;
staff_count?: number | null;
overtime_hours?: number | null;
equipment_capacity?: Record<string, any> | null;
station_assignments?: Record<string, any> | null;
schedule_notes?: string | null;
shift_start?: string;
shift_end?: string;
total_capacity_hours?: number;
planned_capacity_hours?: number;
staff_count?: number;
overtime_hours?: number;
equipment_capacity?: Record<string, any>;
station_assignments?: Record<string, any>;
schedule_notes?: string;
}
export interface ProductionScheduleResponse {
@@ -145,27 +163,58 @@ export interface ProductionScheduleResponse {
shift_end: string;
total_capacity_hours: number;
planned_capacity_hours: number;
actual_capacity_hours?: number | null;
overtime_hours?: number | null;
actual_capacity_hours?: number;
overtime_hours?: number;
staff_count: number;
equipment_capacity?: Record<string, any> | null;
station_assignments?: Record<string, any> | null;
equipment_capacity?: Record<string, any>;
station_assignments?: Record<string, any>;
total_batches_planned: number;
total_batches_completed?: number | null;
total_batches_completed?: number;
total_quantity_planned: number;
total_quantity_produced?: number | null;
total_quantity_produced?: number;
is_finalized: boolean;
is_active: boolean;
efficiency_percentage?: number | null;
utilization_percentage?: number | null;
on_time_completion_rate?: number | null;
schedule_notes?: string | null;
schedule_adjustments?: Record<string, any> | null;
efficiency_percentage?: number;
utilization_percentage?: number;
on_time_completion_rate?: number;
schedule_notes?: string;
schedule_adjustments?: Record<string, any>;
created_at: string;
updated_at: string;
finalized_at?: string | null;
finalized_at?: string;
}
// Production Capacity Types
export interface ProductionCapacityResponse {
id: string;
tenant_id: string;
resource_type: string;
resource_id: string;
resource_name: string;
date: string;
start_time: string;
end_time: string;
total_capacity_units: number;
allocated_capacity_units: number;
remaining_capacity_units: number;
is_available: boolean;
is_maintenance: boolean;
is_reserved: boolean;
equipment_type?: string;
max_batch_size?: number;
min_batch_size?: number;
setup_time_minutes?: number;
cleanup_time_minutes?: number;
efficiency_rating?: number;
maintenance_status?: string;
last_maintenance_date?: string;
notes?: string;
restrictions?: Record<string, any>;
created_at: string;
updated_at: string;
}
// Quality Check Types
export interface QualityCheckBase {
batch_id: string;
check_type: string;
@@ -173,21 +222,21 @@ export interface QualityCheckBase {
quality_score: number;
pass_fail: boolean;
defect_count: number;
defect_types?: string[] | null;
check_notes?: string | null;
defect_types?: string[];
check_notes?: string;
}
export interface QualityCheckCreate extends QualityCheckBase {
checker_id?: string | null;
measured_weight?: number | null;
measured_temperature?: number | null;
measured_moisture?: number | null;
measured_dimensions?: Record<string, number> | null;
target_weight?: number | null;
target_temperature?: number | null;
target_moisture?: number | null;
tolerance_percentage?: number | null;
corrective_actions?: string[] | null;
checker_id?: string;
measured_weight?: number;
measured_temperature?: number;
measured_moisture?: number;
measured_dimensions?: Record<string, number>;
target_weight?: number;
target_temperature?: number;
target_moisture?: number;
tolerance_percentage?: number;
corrective_actions?: string[];
}
export interface QualityCheckResponse {
@@ -196,32 +245,128 @@ export interface QualityCheckResponse {
batch_id: string;
check_type: string;
check_time: string;
checker_id?: string | null;
checker_id?: string;
quality_score: number;
pass_fail: boolean;
defect_count: number;
defect_types?: string[] | null;
measured_weight?: number | null;
measured_temperature?: number | null;
measured_moisture?: number | null;
measured_dimensions?: Record<string, number> | null;
target_weight?: number | null;
target_temperature?: number | null;
target_moisture?: number | null;
tolerance_percentage?: number | null;
within_tolerance?: boolean | null;
defect_types?: string[];
measured_weight?: number;
measured_temperature?: number;
measured_moisture?: number;
measured_dimensions?: Record<string, number>;
target_weight?: number;
target_temperature?: number;
target_moisture?: number;
tolerance_percentage?: number;
within_tolerance?: boolean;
corrective_action_needed: boolean;
corrective_actions?: string[] | null;
check_notes?: string | null;
photos_urls?: string[] | null;
certificate_url?: string | null;
corrective_actions?: string[];
check_notes?: string;
photos_urls?: string[];
certificate_url?: string;
created_at: string;
updated_at: string;
}
// Filter Types
export interface ProductionBatchFilters {
status?: ProductionStatus;
product_id?: string;
order_id?: string;
start_date?: string;
end_date?: string;
page?: number;
page_size?: number;
}
export interface ProductionScheduleFilters {
start_date?: string;
end_date?: string;
is_finalized?: boolean;
page?: number;
page_size?: number;
}
export interface ProductionCapacityFilters {
resource_type?: string;
date?: string;
availability?: boolean;
page?: number;
page_size?: number;
}
export interface QualityCheckFilters {
batch_id?: string;
product_id?: string;
start_date?: string;
end_date?: string;
pass_fail?: boolean;
page?: number;
page_size?: number;
}
// Analytics Types
export interface ProductionPerformanceAnalytics {
completion_rate: number;
waste_percentage: number;
labor_cost_per_unit: number;
on_time_completion_rate: number;
average_yield_percentage: number;
total_output: number;
efficiency_percentage: number;
period_start: string;
period_end: string;
}
export interface YieldTrendsAnalytics {
trends: Array<{
date: string;
product_name: string;
yield_percentage: number;
quantity_produced: number;
}>;
period: 'week' | 'month';
}
export interface TopDefectsAnalytics {
defects: Array<{
defect_type: string;
count: number;
percentage: number;
}>;
}
export interface EquipmentEfficiencyAnalytics {
equipment: Array<{
resource_name: string;
efficiency_rating: number;
uptime_percentage: number;
downtime_hours: number;
total_batches: number;
}>;
}
export interface CapacityBottlenecks {
bottlenecks: Array<{
date: string;
time_slot: string;
resource_name: string;
predicted_utilization: number;
severity: 'low' | 'medium' | 'high';
suggestion: string;
}>;
}
// Dashboard Types
export interface ProductionDashboardSummary {
active_batches: number;
todays_production_plan: Record<string, any>[];
todays_production_plan: Array<{
batch_id: string;
product_name: string;
planned_quantity: number;
status: ProductionStatus;
priority: ProductionPriority;
}>;
capacity_utilization: number;
on_time_completion_rate: number;
average_quality_score: number;
@@ -229,73 +374,14 @@ export interface ProductionDashboardSummary {
efficiency_percentage: number;
}
export interface DailyProductionRequirements {
date: string;
production_plan: Record<string, any>[];
total_capacity_needed: number;
available_capacity: number;
capacity_gap: number;
urgent_items: number;
recommended_schedule?: Record<string, any> | null;
}
export interface ProductionMetrics {
period_start: string;
period_end: string;
export interface BatchStatistics {
total_batches: number;
completed_batches: number;
failed_batches: number;
cancelled_batches: number;
completion_rate: number;
average_yield_percentage: number;
on_time_completion_rate: number;
total_production_cost: number;
average_quality_score: number;
efficiency_trends: Record<string, any>[];
}
export interface ProductionBatchListResponse {
batches: ProductionBatchResponse[];
total_count: number;
page: number;
page_size: number;
}
export interface ProductionScheduleListResponse {
schedules: ProductionScheduleResponse[];
total_count: number;
page: number;
page_size: number;
}
export interface QualityCheckListResponse {
quality_checks: QualityCheckResponse[];
total_count: number;
page: number;
page_size: number;
}
export interface ProductionScheduleData {
start_date: string;
end_date: string;
schedules: {
id: string;
date: string;
shift_start: string;
shift_end: string;
capacity_utilization: number;
batches_planned: number;
is_finalized: boolean;
}[];
total_schedules: number;
}
export interface ProductionCapacityStatus {
[key: string]: any;
}
export interface ProductionRequirements {
[key: string]: any;
}
export interface ProductionYieldMetrics {
[key: string]: any;
average_yield: number;
on_time_rate: number;
period_start: string;
period_end: string;
}