feat: branch betos — propiedades, oferta de proveedores, chat en contratos y flujo de postulacion renovado
- Sistema de propiedades: tabla, modelo, CRUD API para que el cliente guarde direcciones nombradas - Postulacion renovada: cliente elige propiedad sin precio ni fecha, sube fotos a GCS/S3 - Proveedores ofertan date_1, date_2 y amount al postularse via pivot; sort por fecha/monto/membresia - Contratacion: selected_date recibe date_1 o date_2, amount desde pivot (depreca minimun_fee) - Cancelacion/repostulacion: archive con status=perdido, related_postulation_id para vincular - Chat en contratos activos: tabla contract_comments, controller, rutas web+API, vista panel, notificaciones bilingues - PaymentIntent calcula amount desde pivot en vez de recibirlo del front - getpendingcontracts: sin filtro de tiempo, filtra por status=active, agrega time_created - Expiracion de postulaciones reducida a 1000 min Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
132
app/Http/Controllers/ContractCommentController.php
Normal file
132
app/Http/Controllers/ContractCommentController.php
Normal file
@@ -0,0 +1,132 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use OneSignal;
|
||||
use App\Models\Suppliers;
|
||||
use App\Models\ContractComment;
|
||||
use App\Models\CurrentContracts;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
|
||||
class ContractCommentController extends Controller
|
||||
{
|
||||
public function index(Request $request, $id)
|
||||
{
|
||||
$contract = CurrentContracts::with(['user', 'suppliers.user', 'categories', 'status'])->find($id);
|
||||
|
||||
if (!$contract) {
|
||||
abort(404);
|
||||
}
|
||||
|
||||
$comments = ContractComment::with('user')
|
||||
->where('contract_id', $id)
|
||||
->orderBy('created_at', 'asc')
|
||||
->paginate(50);
|
||||
|
||||
return view('currentcontracts.comments', compact('comments', 'contract'));
|
||||
}
|
||||
|
||||
public function store(Request $request, $id)
|
||||
{
|
||||
$validator = Validator::make($request->all(), [
|
||||
'comment' => 'required|string',
|
||||
]);
|
||||
|
||||
if ($validator->fails()) {
|
||||
if ($request->expectsJson()) {
|
||||
return response()->json($validator->errors(), 422);
|
||||
}
|
||||
return redirect()->back()->withErrors($validator);
|
||||
}
|
||||
|
||||
$contract = CurrentContracts::find($id);
|
||||
|
||||
if (!$contract) {
|
||||
if ($request->expectsJson()) {
|
||||
return response()->json(['message' => 'Contrato no encontrado'], 404);
|
||||
}
|
||||
abort(404);
|
||||
}
|
||||
|
||||
$comment = new ContractComment();
|
||||
$comment->contract_id = $id;
|
||||
$comment->user_id = Auth::id();
|
||||
$comment->comment = strip_tags($request->comment);
|
||||
$comment->save();
|
||||
|
||||
$supplier = Suppliers::find($contract->supplier_id);
|
||||
$isClient = Auth::id() === $contract->user_id;
|
||||
$recipientId = $isClient ? ($supplier->user_id ?? null) : $contract->user_id;
|
||||
|
||||
if ($recipientId) {
|
||||
try {
|
||||
OneSignal::sendNotificationCustom([
|
||||
'include_external_user_ids' => [(string) $recipientId],
|
||||
'contents' => [
|
||||
'es' => Auth::user()->name . ': ' . $comment->comment,
|
||||
'en' => Auth::user()->name . ': ' . $comment->comment,
|
||||
],
|
||||
'headings' => [
|
||||
'es' => 'Nuevo mensaje en tu contrato',
|
||||
'en' => 'New message on your contract',
|
||||
],
|
||||
]);
|
||||
} catch (\Exception $e) {}
|
||||
}
|
||||
|
||||
if ($request->expectsJson()) {
|
||||
return response()->json([
|
||||
'id' => $comment->id,
|
||||
'sender_id' => Auth::id(),
|
||||
'sender_name'=> Auth::user()->name,
|
||||
'comment' => $comment->comment,
|
||||
'created_at' => $comment->created_at,
|
||||
], 201);
|
||||
}
|
||||
|
||||
return redirect()->back();
|
||||
}
|
||||
|
||||
public function apiIndex(Request $request, $id)
|
||||
{
|
||||
$user = Auth::user();
|
||||
$contract = CurrentContracts::with('suppliers')->find($id);
|
||||
|
||||
if (!$contract) {
|
||||
return response()->json(['message' => 'Contrato no encontrado'], 404);
|
||||
}
|
||||
|
||||
$supplier = Suppliers::find($contract->supplier_id);
|
||||
$supplierUserId = $supplier->user_id ?? null;
|
||||
|
||||
if ($user->id !== $contract->user_id && $user->id !== $supplierUserId) {
|
||||
return response()->json(['message' => 'No autorizado'], 403);
|
||||
}
|
||||
|
||||
$comments = ContractComment::with('user')
|
||||
->where('contract_id', $id)
|
||||
->orderBy('created_at', 'asc')
|
||||
->get()
|
||||
->map(function ($c) use ($contract, $supplierUserId) {
|
||||
$isSupplier = $c->user_id === $supplierUserId;
|
||||
return [
|
||||
'id' => $c->id,
|
||||
'sender_id' => $c->user_id,
|
||||
'sender_name' => $c->user->name ?? null,
|
||||
'role_id' => $c->user->role_id ?? null,
|
||||
'comment' => $c->comment,
|
||||
'created_at' => $c->created_at,
|
||||
];
|
||||
});
|
||||
|
||||
return response()->json($comments);
|
||||
}
|
||||
|
||||
public function destroy($id, $comment_id)
|
||||
{
|
||||
ContractComment::destroy($comment_id);
|
||||
return redirect('currentcontracts/' . $id . '/comments');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user