process-aware-ai / frontend /__tests__ /test-data-mocking.ts
borndeveloper's picture
Deploy Process Aware AI Dashboard without binaries
b4a2e7f
Raw
History Blame Contribute Delete
13.7 kB
/**
* 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
};