This guide walks you through performing your first inventory scan operation using the EnvaSistema mobile application. You’ll learn how to navigate the interface and complete a production intake scan.
Prerequisites
Before you begin, ensure you have:- The EnvaSistema mobile app installed on your handheld device
- An active user account with proper credentials
- Terminal configured and connected (device should show “ONLINE” status)
- Access to the production floor or warehouse area with scannable QR codes
Understanding the Home Screen
When you launch the app, you’ll see the main HomeScreen with four primary operation categories:HomeScreen.kt
- Device status (e.g., “C66 · ONLINE”)
- Current user (e.g., “J. PÉREZ”)
- Date and shift information (e.g., “Lun, 9 de Marzo 2026” / “Turno Mañana”)
The app uses a navigation-based architecture. Each screen in the workflow is defined in
AppNavigation.kt and follows a consistent pattern for user interaction.Select Producción Nueva to begin scanning newly produced items. The app will navigate to the scanning interface:
composable(Screen.ProduccionNueva.route) {
ProduccionNuevaScreen(onBackClick = { navController.popBackStack() })
}
// Info Alert Card
Surface(
modifier = Modifier.fillMaxWidth(),
color = Color(0xFFE1F5FE),
shape = RoundedCornerShape(12.dp)
) {
Row(
modifier = Modifier.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically
) {
Box(modifier = Modifier.width(6.dp).height(60.dp).background(Color(0xFF0061A6)))
Icon(
imageVector = Icons.Default.RadioButtonChecked,
contentDescription = null,
tint = Color(0xFF0061A6),
modifier = Modifier.padding(horizontal = 12.dp).size(24.dp)
)
Text(
text = "Presione botón lateral para escanear código QR de la pieza / manga",
color = Color(0xFF0061A6),
fontSize = 14.sp,
fontWeight = FontWeight.Medium
)
}
}
Use the physical side button on your handheld terminal to trigger the scanner. Do not attempt to use the device camera or touchscreen for scanning.
// Scan Area Implementation
Box(
modifier = Modifier
.fillMaxWidth()
.height(200.dp)
.border(1.dp, Color(0xFFBDBDBD), RoundedCornerShape(16.dp))
.clip(RoundedCornerShape(16.dp))
.clickable { scannCount++ },
contentAlignment = Alignment.Center
) {
Column(horizontalAlignment = Alignment.CenterHorizontally) {
Surface(
color = Color(0xFFEEEEEE),
shape = CircleShape,
modifier = Modifier.size(80.dp)
) {
Icon(
imageVector = Icons.Default.QrCodeScanner,
contentDescription = null,
tint = Color(0xFF9E9E9E),
modifier = Modifier.padding(20.dp)
)
}
Spacer(modifier = Modifier.height(16.dp))
Text(
text = "Presione el botón lateral del terminal para escanear",
color = Color(0xFF607D8B),
fontSize = 14.sp,
textAlign = TextAlign.Center
)
}
}
The ScanningLayout component is reusable across different operation types and provides consistent scanning behavior throughout the app.
// Scanned Codes Counter
Row(
modifier = Modifier.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically
) {
Surface(
color = Color(0xFF0061A6),
shape = CircleShape,
modifier = Modifier.size(32.dp)
) {
Box(contentAlignment = Alignment.Center) {
Text(text = scannCount.toString(), color = Color.White, fontWeight = FontWeight.Bold)
}
}
Spacer(modifier = Modifier.width(12.dp))
Text(
text = "Códigos escaneados",
color = Color(0xFF455A64),
fontSize = 16.sp,
fontWeight = FontWeight.Bold
)
}
Button(
onClick = { /* TODO */ },
modifier = Modifier
.fillMaxWidth()
.height(56.dp),
shape = RoundedCornerShape(16.dp),
colors = ButtonDefaults.buttonColors(
containerColor = if (scannCount > 0) Color(0xFF0061A6) else Color(0xFFB0BEC5),
contentColor = Color.White
)
) {
Icon(imageVector = Icons.Default.Save, contentDescription = null)
Spacer(modifier = Modifier.width(8.dp))
Text(text = "Guardar Ingreso", fontSize = 18.sp, fontWeight = FontWeight.Bold)
}
Understanding the ScanningLayout Component
The app uses a reusable ScanningLayout component that powers all scanning operations. This component handles:- State management - Tracks scan count with
mutableIntStateOf - Dynamic styling - Adapts colors based on operation type
- Validation - Controls button enablement via
isSaveButtonEnabledlambda - Extensibility - Supports extra content through composable slots
ScanningLayout.kt
- ProduccionNuevaScreen - New production intake
- IngresoArmadoScreen - Assembly intake
- VentaPTScreen - Finished product sales
- TransferenciaInventarioScreen - Inventory transfers
Navigation Flow
The app follows a hierarchical navigation structure:AppNavigation.kt
onBackClick callback, which calls navController.popBackStack().
Common Patterns
Color Coding by Operation Type
Different operations use distinct color schemes:- Ingresos (Inbound) - Blue (
0xFF0061A6) - Salidas (Outbound) - Varies by sub-operation
- Movimientos (Transfers) - Gray (
0xFF455A64) - Transformaciones (Transformations) - Red (
0xFFB71C1C)
Consistent UI Structure
All scanning screens follow this structure:- SecondaryHeader - Title, subtitle, back button
- Info card - Operation-specific instructions
- Scan area - Large tap target with QR icon
- Counter row - Badge + label
- Empty state - “No hay códigos escaneados”
- Action button - Context-specific save/submit
Tips for Efficient Scanning
Best Practices
- Hold the terminal steady at optimal distance (4-6 inches)
- Ensure adequate lighting for QR code visibility
- Wait for the beep before moving to the next item
- Verify the counter increments after each scan
- Review total count before saving
Troubleshooting
- If scan fails, clean the scanner lens
- Check that device shows “ONLINE” status
- Ensure QR codes are not damaged or obscured
- Restart the app if counter doesn’t update
Next Steps
Now that you’ve completed your first inventory operation, explore these topics:System Architecture
Learn about the app’s technical structure and component organization
UI Components
Deep dive into reusable components like ScanningLayout and MenuCard
Inbound Operations
Explore all types of inbound operations and their specific workflows
Development Setup
Set up your development environment to customize the app