Spaces:
Sleeping
Sleeping
| /** | |
| * Test Data Mocking | |
| * Provides consistent mock data for frontend tests that matches backend API responses. | |
| */ | |
| import { NormEntry } from '../lib/norm-utils'; | |
| // Mock Sale Order Details Response | |
| export const mockSaleOrderResponse = { | |
| sale_order: "81S_81S-25000172", | |
| dna: { | |
| Article: "18006BA", | |
| "Grey Code": "18006BA", | |
| "Grey Code DB": "18006BA", | |
| Count: "80", | |
| Product: "Cotton Normal", | |
| Route: "Continouse", | |
| Finish: "Soft", | |
| "Shade Type": "Dyed", | |
| "Material Type": "Cotton", | |
| Customer: "N/A", | |
| Segment: "N/A", | |
| "Sub-Segment": "N/A", | |
| OCDKE1: "18006", | |
| OCDKE2: "BA", | |
| OCDKE3: "CT-SF", | |
| OCDKE4: "5000082944", | |
| "Dispo Date": "2025-01-10", | |
| "Pack Date": "2025-01-15", | |
| "PO Series": "F0U...", | |
| "Total POs": 1, | |
| "Input POs": 1, | |
| "Output POs": 1 | |
| }, | |
| metrics: { | |
| "Order Qty": 425, | |
| "PO Qty": 425, | |
| "Reserved Qty": 495, | |
| "Actual Issued": 545, | |
| "Total Packing": 508, | |
| "Pack Fresh": 510, | |
| "Shortfall": -85, | |
| "Status": "Fulfilled", | |
| "Fresh Yield %": 93.58, | |
| "Reprocess Count": 0, | |
| "Reprocess Qty": 0, | |
| "Rejection Rate %": 0, | |
| "Extra Gr Reserved %": 16.47, | |
| "Actual Gr Issue %": 28.24, | |
| "Shrinkage %": 6.79, | |
| "Fresh Pkg %": 100.39, | |
| "Fresh to Order %": 120.00 | |
| }, | |
| calculations: { | |
| extra_gr_reserved: { | |
| label: "Extra Gr %age Reserved", | |
| formula: "(Reserved - PO_Qty) / PO_Qty × 100", | |
| steps: [ | |
| "= (495 - 425) / 425 × 100", | |
| "= 70 / 425 × 100", | |
| "= 16.47%" | |
| ], | |
| value: 16.47, | |
| interpretation: "Greige reserved above PO demand" | |
| }, | |
| actual_gr_issue: { | |
| label: "Actual Gr Issue %age", | |
| formula: "(Issued - PO_Qty) / PO_Qty × 100", | |
| steps: [ | |
| "= (545 - 425) / 425 × 100", | |
| "= 28.24%" | |
| ], | |
| value: 28.24, | |
| interpretation: "Total greige issued above PO demand" | |
| }, | |
| shrinkage: { | |
| label: "Shrinkage %age (Process Loss)", | |
| formula: "(Issued - Total Packing) / Issued × 100", | |
| steps: [ | |
| "= (545 - 508) / 545 × 100", | |
| "= 6.79%" | |
| ], | |
| value: 6.79, | |
| interpretation: "Material lost during processing" | |
| }, | |
| fresh_pkg: { | |
| label: "Fresh Pkg %age", | |
| formula: "Pack Fresh / Total Packing × 100", | |
| steps: [ | |
| "= 510 / 508 × 100", | |
| "= 100.39%" | |
| ], | |
| value: 100.39, | |
| interpretation: "Proportion of packing that is fresh" | |
| }, | |
| fresh_yield: { | |
| label: "Fresh Process Yield", | |
| formula: "Pack Fresh / Fresh Issued × 100", | |
| steps: [ | |
| "= 510 / 545 × 100", | |
| "= 93.58%" | |
| ], | |
| value: 93.58, | |
| interpretation: "Efficiency of the first run" | |
| } | |
| }, | |
| intelligence: { | |
| waterfall: [ | |
| { label: "Demand", value: 425, type: "base" }, | |
| { label: "Policy Gap", value: 70, type: "variance", desc: "Norm Buffer" }, | |
| { label: "Execution Adj", value: 50, type: "variance", desc: "Planner Adj" }, | |
| { label: "Process Loss", value: -35, type: "variance", desc: "Net Loss" }, | |
| { label: "Delivered", value: 510, type: "final" } | |
| ], | |
| norm_adequacy: 120.0, | |
| intervention_roi: "High", | |
| break_even_tolerance: 22.0, | |
| yield_rate: 93.6, | |
| blame_breakdown: { | |
| policy_impact: 70, | |
| execution_impact: 50, | |
| process_impact: -35, | |
| policy_pct: 45.2, | |
| execution_pct: 32.3, | |
| process_pct: 22.5 | |
| }, | |
| elasticity: { | |
| classification: "HIGH", | |
| value: 0.89 | |
| }, | |
| false_yield_warning: false, | |
| safety_recommendation: { | |
| value: 5.5, | |
| confidence_low: 5.0, | |
| confidence_high: 6.0 | |
| }, | |
| po_imbalance: { | |
| detected: false, | |
| stddev: 0, | |
| details: [] | |
| }, | |
| min_charge_distortion: false, | |
| risk_fingerprint: { | |
| norm_reliability: 0.95, | |
| policy_sensitivity: "HIGH", | |
| reprocessing_dependence: 0, | |
| risk_level: "MEDIUM" | |
| } | |
| }, | |
| rows: [ | |
| { | |
| PO_NO: "F0U0000996", | |
| "PO Type": "Fresh Input", | |
| DORQT1: 425, | |
| RES_QTY: 495, | |
| ISS_QTY: 545, | |
| pack_fresh: 510, | |
| is_input: true, | |
| is_output: true | |
| } | |
| ], | |
| po_breakdown: [ | |
| { | |
| po_no: "F0U0000996", | |
| po_code: "F0U", | |
| type: "Fresh", | |
| issued_qty: 545, | |
| pack_fresh: 510, | |
| reserved_qty: 495, | |
| line_no: "1" | |
| } | |
| ] | |
| }; | |
| // Mock Global Analytics Response | |
| export const mockGlobalAnalyticsResponse = { | |
| kpis: { | |
| total_orders: 970, | |
| total_volume_m: 2500000, | |
| global_yield_pct: 94.5, | |
| shortfall_risk_pct: 15.2 | |
| }, | |
| distributions: { | |
| route: [ | |
| { Route: "Continouse", yield: 94.8, count: 4100 }, | |
| { Route: "Jigger", yield: 92.3, count: 306 }, | |
| { Route: "Jet", yield: 93.1, count: 189 } | |
| ], | |
| finish: [ | |
| { Finish: "Soft", yield: 94.2, count: 2500 }, | |
| { Finish: "Peach", yield: 93.8, count: 2100 } | |
| ], | |
| shade: [ | |
| { "Shade Type": "Dyed", yield: 94.1, count: 3725 }, | |
| { "Shade Type": "FB", yield: 95.2, count: 659 }, | |
| { "Shade Type": "RFD", yield: 94.5, count: 181 } | |
| ], | |
| segment: [], | |
| customer: [] | |
| }, | |
| trends: [ | |
| { month: "2024-10", yield: 93.5 }, | |
| { month: "2024-11", yield: 94.2 }, | |
| { month: "2024-12", yield: 94.8 } | |
| ], | |
| global_waterfall: [ | |
| { label: "Total Demand", value: 2500000, type: "base" }, | |
| { label: "Policy Gap", value: 175000, type: "variance", desc: "Norm vs Demand" }, | |
| { label: "Execution Adj", value: 50000, type: "variance", desc: "Issued vs Norm" }, | |
| { label: "Process Loss", value: -362500, type: "variance", desc: "Defects & Shrinkage" }, | |
| { label: "Delivered", value: 2362500, type: "final" } | |
| ], | |
| global_blame: { | |
| policy_pct: 46.7, | |
| execution_pct: 13.3, | |
| process_pct: 40.0 | |
| } | |
| }; | |
| // Mock Article Prediction Response | |
| export const mockArticlePredictionResponse = { | |
| article_id: "18006BA", | |
| details: { | |
| product: "Cotton Normal", | |
| count: "80", | |
| finish: "Soft", | |
| route: "Continouse" | |
| }, | |
| norm_params: { | |
| division_factor: "Dyed", | |
| sub_type: "Normal", | |
| composition: "Cotton", | |
| count_range: "40s and above" | |
| }, | |
| stats: { | |
| total_volume: 150000, | |
| avg_yield: 93.5, | |
| total_orders: 25, | |
| total_input: 165000, | |
| total_output: 154275 | |
| }, | |
| ai_prediction: { | |
| historical_orders: 25, | |
| yield_stats: { | |
| avg: 93.5, | |
| min: 88.2, | |
| max: 98.1, | |
| std_dev: 2.3 | |
| }, | |
| norm_analysis: { | |
| applicable_rule_upto_3000: "7% or 100m", | |
| applicable_rule_above_3000: "5% or 100m", | |
| base_norm_pct: 7.0, | |
| min_charge_m: 100 | |
| }, | |
| historical_analysis: { | |
| avg_actual_reservation_pct: 8.2, | |
| avg_fulfillment_pct: 102.8, | |
| success_rate_pct: 92.0, | |
| shortfall_rate_pct: 8.0, | |
| fulfilled_orders: 23, | |
| median_successful_reservation_pct: 7.5, | |
| performance_gap_pct: 1.2 | |
| }, | |
| recommendation: { | |
| suggested_reservation_pct: 8.0, | |
| ai_adjustment_pct: 1.0, | |
| explanation: "Norms appear adequate based on historical success" | |
| }, | |
| avg_process_loss_pct: 6.5, | |
| recommended_multiplier: 1.08, | |
| confidence: "high" | |
| }, | |
| orders: [ | |
| { | |
| id: "81S_81S-25000172", | |
| volume: 425, | |
| input: 545, | |
| output: 510, | |
| yield: 93.58, | |
| dates: { dispo: "2025-01-10" } | |
| } | |
| ] | |
| }; | |
| // Mock Full Data Response | |
| export const mockFullDataResponse = [ | |
| { | |
| PO_NO: "F0U0000866", | |
| Article: "18006BA", | |
| "Order Qty": 153, | |
| "Reserver Qty as per Std Norms": 223, | |
| "Actual Gr Opening": 278, | |
| Deviation: 55, | |
| Finish: "Soft", | |
| Route: "Continouse", | |
| Product: "Cotton Normal" | |
| }, | |
| { | |
| PO_NO: "FQT0001479", | |
| Article: "A240B236HMF", | |
| "Order Qty": 200, | |
| "Reserver Qty as per Std Norms": 300, | |
| "Actual Gr Opening": 313, | |
| Deviation: 13, | |
| Finish: "Peach", | |
| Route: "Continouse", | |
| Product: "Stretch Cotton" | |
| } | |
| ]; | |
| // Mock Trends Response | |
| export const mockTrendsResponse = { | |
| articles: [ | |
| { | |
| id: "18006BA", | |
| name: "18006BA", | |
| rank: 1, | |
| count: 25, | |
| volume: 150000, | |
| yield: 93.5, | |
| trend: "up", | |
| shortfall: -5000, | |
| shortfall_pct: -3.3, | |
| success_rate: 92.0, | |
| deviation: { avg: 5.2, std: 2.1, min: 1.5, max: 12.3 }, | |
| efficiency_score: 89.5, | |
| risk_level: "low", | |
| greige_issued: 165000, | |
| greige_reserved: 160500, | |
| norm_deviation: { absolute: 4500, percent: 2.8, over_allocated_pct: 65.0, under_allocated_pct: 35.0 }, | |
| waterfall: { demand: 150000, policy_gap: 10500, execution_adj: 4500, process_loss: -10650, delivered: 154350 }, | |
| blame: { policy_pct: 40.5, execution_pct: 17.3, process_pct: 42.2 }, | |
| compliance: { norm_compliance: 85.0, norm_reliability: 92.0 } | |
| } | |
| ], | |
| sale_orders: [], | |
| po_numbers: [], | |
| shades: [], | |
| routes: [], | |
| finishes: [], | |
| customers: [], | |
| segments: [], | |
| counts: [], | |
| products: [], | |
| summary: { | |
| total_articles: 496, | |
| total_sale_orders: 970, | |
| total_pos: 4613, | |
| avg_yield: 94.2 | |
| } | |
| }; | |
| // Mock Norm Entries | |
| export const mockNormEntries: NormEntry[] = [ | |
| { | |
| id: 1, | |
| division_factor: "Dyed", | |
| sub_type: "Peach", | |
| composition: "Cotton", | |
| count_range: "Below 40s", | |
| route: "Continouse", | |
| rules: { | |
| upto_3000m: "7% or 100m", | |
| above_3000m: "5% or 100m" | |
| }, | |
| tolerance_adjustments: { | |
| tolerance_3_percent: "1% Extra", | |
| tolerance_5_7_percent: "2% Extra", | |
| tolerance_10_percent: "5% Extra", | |
| tolerance_plus0_minus3_5: "-1% Less", | |
| tolerance_1_2_percent: "As per Std Norms" | |
| } | |
| }, | |
| { | |
| id: 2, | |
| division_factor: "Dyed", | |
| sub_type: "Normal", | |
| composition: "Cotton", | |
| count_range: "40s and above", | |
| route: "Continouse", | |
| rules: { | |
| upto_3000m: "5% or 100m", | |
| above_3000m: "4% or 100m" | |
| }, | |
| tolerance_adjustments: { | |
| tolerance_3_percent: "1% Extra", | |
| tolerance_5_7_percent: "2% Extra", | |
| tolerance_10_percent: "5% Extra", | |
| tolerance_plus0_minus3_5: "-1% Less", | |
| tolerance_1_2_percent: "As per Std Norms" | |
| } | |
| }, | |
| { | |
| id: 3, | |
| division_factor: "RFD", | |
| sub_type: "Peach/ Soft", | |
| composition: "Cotton", | |
| count_range: "Below 40s", | |
| route: "Continouse", | |
| rules: { | |
| upto_3000m: "5% or 100m", | |
| above_3000m: "3% or 100m" | |
| }, | |
| tolerance_adjustments: { | |
| tolerance_3_percent: "1% Extra", | |
| tolerance_5_7_percent: "2% Extra", | |
| tolerance_10_percent: "5% Extra", | |
| tolerance_plus0_minus3_5: "-1% Less", | |
| tolerance_1_2_percent: "As per Std Norms" | |
| } | |
| } | |
| ]; | |
| // Helper to create mock fetch response | |
| export function createMockFetchResponse(data: any, ok = true) { | |
| return { | |
| ok, | |
| json: async () => data, | |
| status: ok ? 200 : 404 | |
| }; | |
| } | |
| // Helper formulas matching backend | |
| export const ManualCalculator = { | |
| extra_gr_reserved_pct: (reserved: number, po_qty: number) => | |
| po_qty > 0 ? ((reserved - po_qty) / po_qty) * 100 : 0, | |
| actual_gr_issue_pct: (issued: number, po_qty: number) => | |
| po_qty > 0 ? ((issued - po_qty) / po_qty) * 100 : 0, | |
| shrinkage_pct: (issued: number, packing: number) => | |
| issued > 0 ? ((issued - packing) / issued) * 100 : 0, | |
| fresh_pkg_pct: (pack_fresh: number, total_packing: number) => | |
| total_packing > 0 ? (pack_fresh / total_packing) * 100 : 0, | |
| fresh_yield_pct: (pack_fresh: number, fresh_issued: number) => | |
| fresh_issued > 0 ? (pack_fresh / fresh_issued) * 100 : 0, | |
| shortfall: (order_qty: number, pack_fresh: number) => | |
| order_qty - pack_fresh, | |
| policy_impact: (reserved: number, demand: number) => | |
| reserved - demand, | |
| execution_impact: (issued: number, reserved: number) => | |
| issued - reserved, | |
| process_impact: (pack_fresh: number, issued: number) => | |
| pack_fresh - issued, | |
| yield_rate: (pack_fresh: number, issued: number) => | |
| issued > 0 ? (pack_fresh / issued) * 100 : 0, | |
| norm_score: (pack_fresh: number, demand: number) => | |
| demand > 0 ? (pack_fresh / demand) * 100 : 0 | |
| }; | |