feat: API de reportes, fix distancia espacial y protección OneSignal

- GET/POST /api/contracts/reports y /api/postulations/reports
- GET/POST /api/contracts/reports/{id}/comments con verificación de autoría
- Fix distancia withinDistanceTo: 0.5 grados → 5000 metros (SRID 4326)
- Fix FK Report::finishedcontracts() → contract_id
- Wrap todas las llamadas OneSignal en try/catch para evitar crashes
- Chat UI de comentarios: burbujas por rol, botón veredicto fijo, estilos
- Botón veredicto movido de reports/index a reports/comments
- Ruta POST veredict y restructura reports/{id}/comments en web

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-18 21:04:14 -06:00
parent 185da1edbb
commit 38da1b56ce
12 changed files with 521 additions and 359 deletions

View File

@@ -109,7 +109,7 @@ class PostulationController extends Controller
$geometry = new Point($request->lat, $request->lng);
$category = Categories::where('name', strip_tags($request->category))->orwhere('en_name', strip_tags($request->category))->first();
$distance = 0.5;
$distance = 5000; // metros (5 km)
$suppliers = Suppliers::withinDistanceTo('location', $geometry, $distance)->get();
if ($suppliers != '[]') {
@@ -129,21 +129,25 @@ class PostulationController extends Controller
$postulation->details = preg_replace('/\d+/', '', strip_tags($request->details));
$postulation->save();
OneSignal::sendNotificationToExternalUser(
"Coméntele al Ing. que hay una postulación",
"128",
null, null, null, null,
"Admin: hay nueva postulación"
);
try {
OneSignal::sendNotificationToExternalUser(
"Coméntele al Ing. que hay una postulación",
"128",
null, null, null, null,
"Admin: hay nueva postulación"
);
} catch (\Exception $e) {}
foreach ($suppliers as $supplier) {
if (in_array($category->id, $supplier->categories->pluck('id')->toArray())) {
OneSignal::sendNotificationToExternalUser(
"Dirígete a la sección de postulaciones en la app para ver más detalles",
(string) $supplier->user_id,
null, null, null, null,
"Proveedor: hay nueva postulación"
);
try {
OneSignal::sendNotificationToExternalUser(
"Dirígete a la sección de postulaciones en la app para ver más detalles",
(string) $supplier->user_id,
null, null, null, null,
"Proveedor: hay nueva postulación"
);
} catch (\Exception $e) {}
// TODO: Configurar WhatsApp cuando esté disponible
// Whatsapp::send($supplier->user->phone, Messages\TemplateMessage::create()
@@ -171,13 +175,15 @@ class PostulationController extends Controller
$delay_UTC = Carbon::now()->addMinutes(15)->toString();
OneSignal::sendNotificationToExternalUser(
"Dirígete a la sección de contratos en la app para ver más detalles",
(string) $user->id,
null, null, null,
$delay_UTC,
"Búsqueda Finalizada"
);
try {
OneSignal::sendNotificationToExternalUser(
"Dirígete a la sección de contratos en la app para ver más detalles",
(string) $user->id,
null, null, null,
$delay_UTC,
"Búsqueda Finalizada"
);
} catch (\Exception $e) {}
return response()->json([
'message' => 'Servicio solicitado, espere a que un proveedor se postule'
@@ -217,12 +223,14 @@ class PostulationController extends Controller
if ($time_limit > 0) {
if (in_array($postulation->category_id, $supplier->categories->pluck('id')->toArray())) {
if($supplier->membership == 1) {
OneSignal::sendNotificationToExternalUser(
"Dirígete a la sección de contratos en la app para ver más detalles",
(string) $postulation->user_id,
null, null, null, null,
"Un proveedor certificado se ha postulado"
);
try {
OneSignal::sendNotificationToExternalUser(
"Dirígete a la sección de contratos en la app para ver más detalles",
(string) $postulation->user_id,
null, null, null, null,
"Un proveedor certificado se ha postulado"
);
} catch (\Exception $e) {}
}
// TODO: Configurar WhatsApp cuando esté disponible
// Whatsapp::send($postulation->user->phone, Messages\TemplateMessage::create()