File: /var/www/matriculas_api_dev/app/Http/Controllers/PeriodPricingController.php
<?php
namespace App\Http\Controllers;
use App\Models\PaymentConceptDetail;
use App\Services\PeriodPricingService;
use Illuminate\Http\Request;
use Exception;
class PeriodPricingController extends Controller
{
protected $periodPricingService;
public function __construct(PeriodPricingService $periodPricingService)
{
$this->periodPricingService = $periodPricingService;
}
/**
* Listar configuraciones de precios por periodo.
*/
public function list($periodId)
{
$configs = $this->periodPricingService->list($periodId);
return genericResponse(['data' => $configs, 'message' => 'ok', 'code' => 200], 200);
}
/**
* Crear configuración de precio.
*/
public function store(Request $request)
{
$request->validate([
'period_id' => 'required|integer',
'config_type' => 'required|string',
'concept_code' => 'required|string',
'currency_type' => 'required|string',
]);
try {
$config = $this->periodPricingService->store($request->all());
return genericResponse(['data' => $config, 'message' => 'Configuración creada', 'code' => 201], 201);
} catch (Exception $e) {
return genericResponse(['data' => null, 'message' => $e->getMessage(), 'code' => $e->getCode() ?: 500], $e->getCode() ?: 500);
}
}
/**
* Actualizar configuración de precio.
*/
public function update($id, Request $request)
{
$config = $this->periodPricingService->update($id, $request->all());
return genericResponse(['data' => $config, 'message' => 'Configuración actualizada', 'code' => 200], 200);
}
/**
* Eliminar configuración de precio.
*/
public function destroy($id)
{
$this->periodPricingService->destroy($id);
return genericResponse(['data' => null, 'message' => 'Configuración eliminada', 'code' => 200], 200);
}
/**
* Copiar configuraciones de un periodo a otro.
*/
public function copy(Request $request)
{
$request->validate([
'from_period_id' => 'required|integer',
'to_period_id' => 'required|integer',
]);
$result = $this->periodPricingService->copy($request->from_period_id, $request->to_period_id);
$message = "Copiados {$result['created']} conceptos" . ($result['skipped'] > 0 ? " ({$result['skipped']} ya existían)" : "");
return genericResponse(['data' => $result, 'message' => $message, 'code' => 200], 200);
}
/**
* Eliminar múltiples configuraciones.
*/
public function bulkDelete(Request $request)
{
$request->validate(['ids' => 'required|array']);
$this->periodPricingService->bulkDelete($request->ids);
return genericResponse(['data' => null, 'message' => 'Configuraciones eliminadas', 'code' => 200], 200);
}
/**
* Guardar configuraciones masivas.
*/
public function bulkSave(Request $request)
{
$request->validate([
'period_id' => 'required|integer',
'configs' => 'required|array',
]);
$result = $this->periodPricingService->bulkSave($request->period_id, $request->configs);
$message = count($result['skipped']) > 0
? 'Configuraciones guardadas. ' . count($result['skipped']) . ' duplicado(s) omitido(s).'
: 'Configuraciones guardadas';
return genericResponse(['data' => $result, 'message' => $message, 'code' => 200], 200);
}
/**
* Importar configuraciones de precios desde Excel.
*/
public function importExcel(Request $request)
{
$request->validate([
'period_id' => 'required|integer|exists:periods,id',
'file' => 'required|file|mimes:xlsx,xls|max:5120',
]);
try {
$result = $this->periodPricingService->importFromExcel(
$request->period_id,
$request->file('file')
);
$message = "Importación completada: {$result['created']} creados, {$result['updated']} actualizados";
if (count($result['errors']) > 0) {
$message .= ", " . count($result['errors']) . " errores";
}
return genericResponse([
'data' => $result,
'message' => $message,
'code' => 200,
], 200);
} catch (Exception $e) {
return genericResponse(['error' => $e->getMessage()], $e->getCode() ?: 500);
}
}
/**
* Listar códigos de conceptos de pago disponibles.
*/
public function conceptCodes()
{
$concepts = PaymentConceptDetail::where('status', 1)
->select('code', 'description')
->orderBy('description')
->get();
return genericResponse(['data' => $concepts, 'message' => 'ok', 'code' => 200], 200);
}
/**
* Exportar configuraciones de precios a Excel.
*/
public function exportExcel($periodId)
{
try {
$result = $this->periodPricingService->exportToExcel($periodId);
return response()->download($result['tempFile'], $result['fileName'], [
'Content-Type' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
])->deleteFileAfterSend(true);
} catch (Exception $e) {
return genericResponse(['error' => $e->getMessage()], $e->getCode() ?: 500);
}
}
}