paginate(20); return view('model-pricing.index', compact('modelPricing')); } /** * Show the form for creating a new model pricing */ public function create() { return view('model-pricing.create'); } /** * Store a newly created model pricing */ public function store(Request $request) { $validated = $request->validate([ 'model_key' => 'required|string|max:255|unique:model_pricing,model_key', 'input_price_per_million' => 'required|numeric|min:0', 'output_price_per_million' => 'required|numeric|min:0', ]); ModelPricing::create($validated); return redirect() ->route('model-pricing.index') ->with('success', 'Model pricing created successfully!'); } /** * Display the specified model pricing */ public function show(string $modelKey) { $model = ModelPricing::findOrFail($modelKey); return view('model-pricing.show', compact('model')); } /** * Show the form for editing the specified model pricing */ public function edit(string $modelKey) { $model = ModelPricing::findOrFail($modelKey); return view('model-pricing.edit', compact('model')); } /** * Update the specified model pricing */ public function update(Request $request, string $modelKey) { $model = ModelPricing::findOrFail($modelKey); $validated = $request->validate([ 'input_price_per_million' => 'required|numeric|min:0', 'output_price_per_million' => 'required|numeric|min:0', ]); $model->update($validated); return redirect() ->route('model-pricing.index') ->with('success', 'Model pricing updated successfully!'); } /** * Remove the specified model pricing */ public function destroy(string $modelKey) { $model = ModelPricing::findOrFail($modelKey); $model->delete(); return redirect() ->route('model-pricing.index') ->with('success', 'Model pricing deleted successfully!'); } /** * Show the cost calculator */ public function calculator() { $models = ModelPricing::orderBy('model_key')->get(); return view('model-pricing.calculator', compact('models')); } /** * Calculate cost based on input */ public function calculate(Request $request) { $validated = $request->validate([ 'model_key' => 'required|exists:model_pricing,model_key', 'input_tokens' => 'required|integer|min:0', 'output_tokens' => 'required|integer|min:0', ]); $model = ModelPricing::findOrFail($validated['model_key']); $cost = $model->calculateCost( $validated['input_tokens'], $validated['output_tokens'] ); return response()->json([ 'model' => $model->model_key, 'input_tokens' => $validated['input_tokens'], 'output_tokens' => $validated['output_tokens'], 'total_tokens' => $validated['input_tokens'] + $validated['output_tokens'], 'cost' => $cost, 'cost_formatted' => '$' . number_format($cost, 6), ]); } /** * Show CSV import form */ public function importForm() { return view('model-pricing.import'); } /** * Import model pricing from CSV */ public function import(Request $request) { $request->validate([ 'csv_file' => 'required|file|mimes:csv,txt|max:2048', ]); $file = $request->file('csv_file'); $handle = fopen($file->getRealPath(), 'r'); $imported = 0; $updated = 0; $errors = []; // Skip header row fgetcsv($handle); while (($row = fgetcsv($handle)) !== false) { if (count($row) < 3) { continue; // Skip invalid rows } $modelKey = trim($row[0]); $inputPrice = floatval($row[1]); $outputPrice = floatval($row[2]); if (empty($modelKey) || $inputPrice < 0 || $outputPrice < 0) { $errors[] = "Invalid data for model: {$modelKey}"; continue; } $existing = ModelPricing::find($modelKey); if ($existing) { $existing->update([ 'input_price_per_million' => $inputPrice, 'output_price_per_million' => $outputPrice, ]); $updated++; } else { ModelPricing::create([ 'model_key' => $modelKey, 'input_price_per_million' => $inputPrice, 'output_price_per_million' => $outputPrice, ]); $imported++; } } fclose($handle); $message = "Import completed! Created: {$imported}, Updated: {$updated}"; if (count($errors) > 0) { $message .= '. Errors: ' . implode(', ', array_slice($errors, 0, 5)); } return redirect() ->route('model-pricing.index') ->with('success', $message); } }