Skip to main content
The Bodycam Deliveries system allows you to track the assignment and return of body-worn cameras to police personnel, maintaining a complete audit trail of all bodycam movements.

Overview

Similar to equipment deliveries, the bodycam system manages the lifecycle of bodycam assignments including:
  • Checkout documentation with personnel details
  • Automatic status updates for bodycam inventory
  • Partial and full returns
  • Supporting documentation (images and files)
  • Official delivery document generation
Bodycams are tracked separately from radio equipment with their own inventory system including IMEI, serial numbers, and battery tracking.

Creating a Bodycam Delivery

1

Navigate to bodycam deliveries

Access the bodycam delivery section from the main menu
2

Complete delivery information

Enter the required details:
  • Delivery date and time
  • Department (dependencia) - Receiving police unit
  • Operational reason - Purpose of assignment
  • Personnel details - Names and badge numbers for both receiver and deliverer
3

Select available bodycams

Choose from bodycams with status “disponible” (available):
  • Code - Internal identifier
  • IMEI - Device unique identifier
  • Serial number
  • Battery number
4

Attach documentation

Upload up to 3 images and 1 additional file for record-keeping
5

Submit delivery

The system will:
  • Create the delivery record
  • Update bodycam status to “entregada” (delivered)
  • Generate the delivery document

Code Example: Bodycam Delivery Creation

// EntregasBodycamsController.php:67-139
$validated = $request->validate([
    'fecha_entrega' => 'required|date',
    'hora_entrega' => 'required',
    'dependencia' => 'required|string|max:255',
    'motivo_operativo' => 'required|string',
    'bodycams_seleccionadas' => 'required|array|min:1',
    'bodycams_seleccionadas.*' => 'exists:bodycams,id'
]);

DB::beginTransaction();

$entrega = EntregaBodycam::create([
    'fecha_entrega' => $request->fecha_entrega,
    'hora_entrega' => $request->hora_entrega,
    'dependencia' => $request->dependencia,
    'personal_receptor' => $request->personal_receptor ?? '',
    'motivo_operativo' => $request->motivo_operativo,
    'usuario_creador' => auth()->user()->name
]);

// Link bodycams and update status
foreach ($request->bodycams_seleccionadas as $bodycamId) {
    DetalleEntregaBodycam::create([
        'entrega_id' => $entrega->id,
        'bodycam_id' => $bodycamId
    ]);
    
    Bodycam::find($bodycamId)->update(['estado' => 'entregada']);
}

DB::commit();
All bodycam deliveries are wrapped in database transactions to ensure data consistency. If any step fails, the entire operation is rolled back.

Viewing Delivery Details

The delivery detail page shows:

Delivery Information

Date, time, department, operational reason

Personnel Records

Names and badge numbers of receiver and deliverer

Bodycam List

All assigned bodycams with IMEI and serial numbers

Return History

All partial and full returns linked to this delivery
// EntregasBodycamsController.php:142-151
$entrega = EntregaBodycam::with([
    'bodycams',
    'detalleEntregas.bodycam',
    'devoluciones'
])->findOrFail($id);

return view('entregas.entregas-bodycams.show', compact('entrega'));

Document Generation

The system generates standardized Word documents for bodycam deliveries using the template template_entrega_bodycams.docx.

Template Variables

The document includes:
  • Header - Date (day/month/year), time, department name
  • Quantity - Number of bodycams (numeric and written)
  • Device details - Brand, model
  • Equipment table - Code, IMEI, serial number, battery number for each bodycam
  • Personnel - Receiver and deliverer information
  • Operational reason - Purpose of assignment
// EntregasBodycamsController.php:275-356
$templateProcessor = new TemplateProcessor($templatePath);

// Replace header variables
$templateProcessor->setValue('DIA', $entrega->fecha_entrega->format('d'));
$templateProcessor->setValue('MES', $mesEspanol);
$templateProcessor->setValue('HORA', Carbon::parse($entrega->hora_entrega)->format('H:i'));

// Device information
$cantidadBodycams = $entrega->bodycams->count();
$templateProcessor->setValue('CANTIDAD_BODYCAMS', $cantidadBodycams);
$templateProcessor->setValue('CANTIDAD_BODYCAMS_LETRAS', 
    $this->numeroALetras($cantidadBodycams));

// Build bodycam table data
$bodycamsData = [];
$contador = 1;

foreach ($entrega->bodycams as $bodycam) {
    $bodycamsData[] = [
        'NUMERO' => $contador++,
        'CODIGO' => $bodycam->codigo ?? 'N/A',
        'IMEI' => $bodycam->imei ?? 'N/A',
        'SERIE' => $bodycam->numero_serie ?? 'N/A',
        'BATERIA' => $bodycam->numero_bateria ?? 'N/A'
    ];
}

$templateProcessor->cloneRowAndSetValues('NUMERO', $bodycamsData);
Documents are automatically saved to: \\193.169.1.247\Comp_Tecnica$\01-Técnica 911 Doc\01-Documentos\U.M. - Acontecimientos - Eventos\Entregas Bodycams CAR911

Processing Returns

Bodycams can be returned individually or in groups while maintaining the connection to the original delivery.

Return Workflow

1

Access return form

From the delivery detail page, click “Return Bodycams”
2

Select bodycams to return

The system shows only bodycams that are still pending return
3

Enter return details

Provide:
  • Return date and time
  • Person returning (name and badge)
  • Observations
  • Supporting images or documents
4

Confirm return

The system processes the return and updates all statuses
// EntregasBodycamsController.php:422-498
$devolucion = DevolucionBodycam::create([
    'entrega_id' => $entrega->id,
    'fecha_devolucion' => $request->fecha_devolucion,
    'hora_devolucion' => $request->hora_devolucion,
    'personal_devuelve' => $request->personal_devuelve,
    'observaciones' => $request->observaciones,
    'usuario_creador' => auth()->user()->name
]);

// Create return details and update bodycam status
foreach ($request->bodycams_devolver as $bodycamId) {
    DetalleDevolucionBodycam::create([
        'devolucion_id' => $devolucion->id,
        'bodycam_id' => $bodycamId
    ]);
    
    // Return bodycam to available status
    Bodycam::find($bodycamId)->update(['estado' => 'disponible']);
}

// Update delivery state (active/partial/complete)
$entrega->actualizarEstado();

Searching Deliveries

Filter bodycam deliveries using multiple criteria:
FilterDescription
CódigoSearch by bodycam code
Número de SerieFind by serial number
FechaFilter by delivery date
DependenciaFilter by department
// EntregasBodycamsController.php:28-51
$query = EntregaBodycam::with(['bodycams', 'detalleEntregas']);

if ($request->filled('codigo')) {
    $query->buscarPorCodigo($request->codigo);
}

if ($request->filled('numero_serie')) {
    $query->buscarPorSerie($request->numero_serie);
}

if ($request->filled('fecha')) {
    $query->buscarPorFecha($request->fecha);
}

if ($request->filled('dependencia')) {
    $query->buscarPorDependencia($request->dependencia);
}

$entregas = $query->orderBy('created_at', 'desc')->paginate(15);

Editing Deliveries

You can modify delivery details before or after bodycams are returned:
When editing bodycam selections, previously assigned bodycams that are removed will be returned to “disponible” status.
// EntregasBodycamsController.php:240-258
// Release previous bodycams
$bodycamsAnteriores = $entrega->bodycams->pluck('id')->toArray();
foreach ($bodycamsAnteriores as $bodycamId) {
    if (!in_array($bodycamId, $request->bodycams_seleccionadas)) {
        Bodycam::find($bodycamId)->update(['estado' => 'disponible']);
    }
}

// Delete old details and create new ones
$entrega->detalleEntregas()->delete();

foreach ($request->bodycams_seleccionadas as $bodycamId) {
    DetalleEntregaBodycam::create([
        'entrega_id' => $entrega->id,
        'bodycam_id' => $bodycamId
    ]);
    
    Bodycam::find($bodycamId)->update(['estado' => 'entregada']);
}

Routes

The bodycam delivery system uses these routes:
RouteMethodPurpose
/entrega-bodycamsGETList all bodycam deliveries
/entrega-bodycams/createGETShow delivery creation form
/entrega-bodycamsPOSTStore new delivery
/entrega-bodycams/{id}GETView delivery details
/entrega-bodycams/{id}/editGETEdit delivery
/entrega-bodycams/{id}PUT/PATCHUpdate delivery
/entrega-bodycams/{id}DELETEDelete delivery
/entrega-bodycams/{id}/documentoGETGenerate delivery document
/entrega-bodycams/{id}/devolverGETShow return form
/entrega-bodycams/{id}/procesar-devolucionPOSTProcess bodycam return
Routes require permissions: crear-entrega-bodycams, ver-menu-entregas-bodycams, ver-reportes-entregas-bodycams

Deleting Deliveries

When deleting a delivery, the system automatically releases all bodycams back to available status:
// EntregasBodycamsController.php:501-525
try {
    $entrega = EntregaBodycam::findOrFail($id);
    
    DB::beginTransaction();
    
    // Release bodycams before deleting
    foreach ($entrega->bodycams as $bodycam) {
        $bodycam->update(['estado' => 'disponible']);
    }
    
    $entrega->delete();
    
    DB::commit();
    
    return redirect()->route('entrega-bodycams.index')
        ->with('success', 'Acta de entrega eliminada exitosamente');
}

Best Practices

  1. Verify IMEI numbers - Confirm device identifiers before delivery
  2. Check battery condition - Note battery serial numbers and condition
  3. Use clear operational reasons - Document why bodycams are being assigned
  4. Process returns immediately - Update system as soon as devices come back
  5. Attach photos - Document device condition at both delivery and return
  6. Review pending returns - Regularly audit deliveries with unreturned bodycams

Equipment Deliveries

Similar system for managing radio equipment loans

Bodycam Management

Main bodycam inventory and tracking system

Build docs developers (and LLMs) love