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
Navigate to bodycam deliveries
Access the bodycam delivery section from the main menu
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
Select available bodycams
Choose from bodycams with status “disponible” (available):
Code - Internal identifier
IMEI - Device unique identifier
Serial number
Battery number
Attach documentation
Upload up to 3 images and 1 additional file for record-keeping
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
Access return form
From the delivery detail page, click “Return Bodycams”
Select bodycams to return
The system shows only bodycams that are still pending return
Enter return details
Provide:
Return date and time
Person returning (name and badge)
Observations
Supporting images or documents
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:
Filter Description Código Search by bodycam code Número de Serie Find by serial number Fecha Filter by delivery date Dependencia Filter 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:
Route Method Purpose /entrega-bodycamsGET List all bodycam deliveries /entrega-bodycams/createGET Show delivery creation form /entrega-bodycamsPOST Store new delivery /entrega-bodycams/{id}GET View delivery details /entrega-bodycams/{id}/editGET Edit delivery /entrega-bodycams/{id}PUT/PATCH Update delivery /entrega-bodycams/{id}DELETE Delete delivery /entrega-bodycams/{id}/documentoGET Generate delivery document /entrega-bodycams/{id}/devolverGET Show return form /entrega-bodycams/{id}/procesar-devolucionPOST Process 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
Verify IMEI numbers - Confirm device identifiers before delivery
Check battery condition - Note battery serial numbers and condition
Use clear operational reasons - Document why bodycams are being assigned
Process returns immediately - Update system as soon as devices come back
Attach photos - Document device condition at both delivery and return
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