Renombrar la gestion de asignaciones por Listado SAI - Persona
This commit is contained in:
@@ -5,7 +5,7 @@ Android application developed in Kotlin using Jetpack Compose that scans barcode
|
|||||||
## 🚀 Features
|
## 🚀 Features
|
||||||
|
|
||||||
- **Instant Scan**: The camera opens when adding a new SAI.
|
- **Instant Scan**: The camera opens when adding a new SAI.
|
||||||
- **Multi-Entity Management**: Dedicated sections for SAIs, Batteries, and People.
|
- **Multi-Entity Management**: Dedicated sections for SAIs, Batteries, People, and SAI-Person Assignments.
|
||||||
- **CRUD Operations**: Add, View, and Delete records for all managed entities.
|
- **CRUD Operations**: Add, View, and Delete records for all managed entities.
|
||||||
- **Connection Status**: Real-time indicator on the home screen.
|
- **Connection Status**: Real-time indicator on the home screen.
|
||||||
- **Visual Overlay**: Centered scanning guide with a red line to help align barcodes.
|
- **Visual Overlay**: Centered scanning guide with a red line to help align barcodes.
|
||||||
@@ -58,13 +58,14 @@ CREATE TABLE Persona (
|
|||||||
nombre VARCHAR(255) NOT NULL
|
nombre VARCHAR(255) NOT NULL
|
||||||
);
|
);
|
||||||
|
|
||||||
-- Table for Assignments
|
-- Table for SAI - Person Assignments
|
||||||
CREATE TABLE Asignado (
|
CREATE TABLE Asignado (
|
||||||
id_asignacion INT AUTO_INCREMENT PRIMARY KEY,
|
id_asignacion INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
id_sai INT,
|
id_sai INT,
|
||||||
id_persona INT,
|
id_persona INT,
|
||||||
fecha_asignado DATE,
|
fecha_asignado DATE,
|
||||||
fecha_devolucion DATE,
|
fecha_devolucion DATE,
|
||||||
|
observaciones VARCHAR(255),
|
||||||
FOREIGN KEY (id_sai) REFERENCES SAIs(id_sai),
|
FOREIGN KEY (id_sai) REFERENCES SAIs(id_sai),
|
||||||
FOREIGN KEY (id_persona) REFERENCES Persona(id_persona)
|
FOREIGN KEY (id_persona) REFERENCES Persona(id_persona)
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ class AssignmentRepository {
|
|||||||
val connection = MariaDbConnection.getConnection() ?: return@withContext Result.failure(Exception("db_connection_error"))
|
val connection = MariaDbConnection.getConnection() ?: return@withContext Result.failure(Exception("db_connection_error"))
|
||||||
try {
|
try {
|
||||||
val sql = """
|
val sql = """
|
||||||
SELECT a.id_asignacion, a.id_sai, a.id_persona, a.fecha_asignado, a.fecha_devolucion,
|
SELECT a.id_asignacion, a.id_sai, a.id_persona, a.fecha_asignado, a.fecha_devolucion, a.observaciones,
|
||||||
s.ns as sai_ns, p.nombre as person_name
|
s.ns as sai_ns, p.nombre as person_name
|
||||||
FROM Asignado a
|
FROM Asignado a
|
||||||
LEFT JOIN SAIs s ON a.id_sai = s.id_sai
|
LEFT JOIN SAIs s ON a.id_sai = s.id_sai
|
||||||
@@ -27,6 +27,7 @@ class AssignmentRepository {
|
|||||||
idPersona = resultSet.getInt("id_persona"),
|
idPersona = resultSet.getInt("id_persona"),
|
||||||
assignedDate = resultSet.getString("fecha_asignado"),
|
assignedDate = resultSet.getString("fecha_asignado"),
|
||||||
returnDate = resultSet.getString("fecha_devolucion"),
|
returnDate = resultSet.getString("fecha_devolucion"),
|
||||||
|
observations = resultSet.getString("observaciones"),
|
||||||
saiNs = resultSet.getString("sai_ns"),
|
saiNs = resultSet.getString("sai_ns"),
|
||||||
personName = resultSet.getString("person_name")
|
personName = resultSet.getString("person_name")
|
||||||
))
|
))
|
||||||
@@ -42,7 +43,7 @@ class AssignmentRepository {
|
|||||||
suspend fun getById(id: Int): Result<Assignment> = withContext(Dispatchers.IO) {
|
suspend fun getById(id: Int): Result<Assignment> = withContext(Dispatchers.IO) {
|
||||||
val connection = MariaDbConnection.getConnection() ?: return@withContext Result.failure(Exception("db_connection_error"))
|
val connection = MariaDbConnection.getConnection() ?: return@withContext Result.failure(Exception("db_connection_error"))
|
||||||
try {
|
try {
|
||||||
val sql = "SELECT id_asignacion, id_sai, id_persona, fecha_asignado, fecha_devolucion FROM Asignado WHERE id_asignacion = ?"
|
val sql = "SELECT id_asignacion, id_sai, id_persona, fecha_asignado, fecha_devolucion, observaciones FROM Asignado WHERE id_asignacion = ?"
|
||||||
val statement = connection.prepareStatement(sql)
|
val statement = connection.prepareStatement(sql)
|
||||||
statement.setInt(1, id)
|
statement.setInt(1, id)
|
||||||
val resultSet = statement.executeQuery()
|
val resultSet = statement.executeQuery()
|
||||||
@@ -52,7 +53,8 @@ class AssignmentRepository {
|
|||||||
idSai = resultSet.getInt("id_sai"),
|
idSai = resultSet.getInt("id_sai"),
|
||||||
idPersona = resultSet.getInt("id_persona"),
|
idPersona = resultSet.getInt("id_persona"),
|
||||||
assignedDate = resultSet.getString("fecha_asignado"),
|
assignedDate = resultSet.getString("fecha_asignado"),
|
||||||
returnDate = resultSet.getString("fecha_devolucion")
|
returnDate = resultSet.getString("fecha_devolucion"),
|
||||||
|
observations = resultSet.getString("observaciones")
|
||||||
))
|
))
|
||||||
} else {
|
} else {
|
||||||
Result.failure(Exception("not_found"))
|
Result.failure(Exception("not_found"))
|
||||||
@@ -67,12 +69,13 @@ class AssignmentRepository {
|
|||||||
suspend fun insert(item: Assignment): Result<Unit> = withContext(Dispatchers.IO) {
|
suspend fun insert(item: Assignment): Result<Unit> = withContext(Dispatchers.IO) {
|
||||||
val connection = MariaDbConnection.getConnection() ?: return@withContext Result.failure(Exception("db_connection_error"))
|
val connection = MariaDbConnection.getConnection() ?: return@withContext Result.failure(Exception("db_connection_error"))
|
||||||
try {
|
try {
|
||||||
val sql = "INSERT INTO Asignado (id_sai, id_persona, fecha_asignado, fecha_devolucion) VALUES (?, ?, ?, ?)"
|
val sql = "INSERT INTO Asignado (id_sai, id_persona, fecha_asignado, fecha_devolucion, observaciones) VALUES (?, ?, ?, ?, ?)"
|
||||||
val statement = connection.prepareStatement(sql)
|
val statement = connection.prepareStatement(sql)
|
||||||
statement.setInt(1, item.idSai)
|
statement.setInt(1, item.idSai)
|
||||||
statement.setInt(2, item.idPersona)
|
statement.setInt(2, item.idPersona)
|
||||||
statement.setString(3, item.assignedDate)
|
statement.setString(3, item.assignedDate)
|
||||||
statement.setString(4, item.returnDate)
|
statement.setString(4, item.returnDate)
|
||||||
|
statement.setString(5, item.observations)
|
||||||
|
|
||||||
if (statement.executeUpdate() > 0) Result.success(Unit)
|
if (statement.executeUpdate() > 0) Result.success(Unit)
|
||||||
else Result.failure(Exception("no_rows_inserted"))
|
else Result.failure(Exception("no_rows_inserted"))
|
||||||
@@ -86,13 +89,14 @@ class AssignmentRepository {
|
|||||||
suspend fun update(item: Assignment): Result<Unit> = withContext(Dispatchers.IO) {
|
suspend fun update(item: Assignment): Result<Unit> = withContext(Dispatchers.IO) {
|
||||||
val connection = MariaDbConnection.getConnection() ?: return@withContext Result.failure(Exception("db_connection_error"))
|
val connection = MariaDbConnection.getConnection() ?: return@withContext Result.failure(Exception("db_connection_error"))
|
||||||
try {
|
try {
|
||||||
val sql = "UPDATE Asignado SET id_sai = ?, id_persona = ?, fecha_asignado = ?, fecha_devolucion = ? WHERE id_asignacion = ?"
|
val sql = "UPDATE Asignado SET id_sai = ?, id_persona = ?, fecha_asignado = ?, fecha_devolucion = ?, observaciones = ? WHERE id_asignacion = ?"
|
||||||
val statement = connection.prepareStatement(sql)
|
val statement = connection.prepareStatement(sql)
|
||||||
statement.setInt(1, item.idSai)
|
statement.setInt(1, item.idSai)
|
||||||
statement.setInt(2, item.idPersona)
|
statement.setInt(2, item.idPersona)
|
||||||
statement.setString(3, item.assignedDate)
|
statement.setString(3, item.assignedDate)
|
||||||
statement.setString(4, item.returnDate)
|
statement.setString(4, item.returnDate)
|
||||||
statement.setInt(5, item.id)
|
statement.setString(5, item.observations)
|
||||||
|
statement.setInt(6, item.id)
|
||||||
|
|
||||||
if (statement.executeUpdate() > 0) Result.success(Unit)
|
if (statement.executeUpdate() > 0) Result.success(Unit)
|
||||||
else Result.failure(Exception("update_failed"))
|
else Result.failure(Exception("update_failed"))
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ data class Assignment(
|
|||||||
val idPersona: Int,
|
val idPersona: Int,
|
||||||
val assignedDate: String? = null,
|
val assignedDate: String? = null,
|
||||||
val returnDate: String? = null,
|
val returnDate: String? = null,
|
||||||
|
val observations: String? = null,
|
||||||
// Optional display fields for joining data
|
// Optional display fields for joining data
|
||||||
val saiNs: String? = null,
|
val saiNs: String? = null,
|
||||||
val personName: String? = null
|
val personName: String? = null
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ fun AddAssignmentScreen(
|
|||||||
var assignedDateDb by remember { mutableStateOf("") }
|
var assignedDateDb by remember { mutableStateOf("") }
|
||||||
var returnDateDisplay by remember { mutableStateOf("") }
|
var returnDateDisplay by remember { mutableStateOf("") }
|
||||||
var returnDateDb by remember { mutableStateOf("") }
|
var returnDateDb by remember { mutableStateOf("") }
|
||||||
|
var observations by remember { mutableStateOf("") }
|
||||||
|
|
||||||
var sais by remember { mutableStateOf<List<Sai>>(emptyList()) }
|
var sais by remember { mutableStateOf<List<Sai>>(emptyList()) }
|
||||||
var people by remember { mutableStateOf<List<Person>>(emptyList()) }
|
var people by remember { mutableStateOf<List<Person>>(emptyList()) }
|
||||||
@@ -118,7 +119,7 @@ fun AddAssignmentScreen(
|
|||||||
Scaffold(
|
Scaffold(
|
||||||
topBar = {
|
topBar = {
|
||||||
TopAppBar(
|
TopAppBar(
|
||||||
title = { Text("Añadir Asignación") },
|
title = { Text("Añadir SAI - Persona") },
|
||||||
navigationIcon = {
|
navigationIcon = {
|
||||||
IconButton(onClick = onNavigateBack) {
|
IconButton(onClick = onNavigateBack) {
|
||||||
Icon(Icons.Default.ArrowBack, contentDescription = "Atrás")
|
Icon(Icons.Default.ArrowBack, contentDescription = "Atrás")
|
||||||
@@ -233,6 +234,16 @@ fun AddAssignmentScreen(
|
|||||||
modifier = Modifier.fillMaxWidth().clickable { showReturnDatePicker = true }
|
modifier = Modifier.fillMaxWidth().clickable { showReturnDatePicker = true }
|
||||||
)
|
)
|
||||||
|
|
||||||
|
Spacer(modifier = Modifier.height(16.dp))
|
||||||
|
|
||||||
|
OutlinedTextField(
|
||||||
|
value = observations,
|
||||||
|
onValueChange = { observations = it },
|
||||||
|
label = { Text(stringResource(R.string.label_observations)) },
|
||||||
|
modifier = Modifier.fillMaxWidth(),
|
||||||
|
minLines = 3
|
||||||
|
)
|
||||||
|
|
||||||
Spacer(modifier = Modifier.height(32.dp))
|
Spacer(modifier = Modifier.height(32.dp))
|
||||||
|
|
||||||
Button(
|
Button(
|
||||||
@@ -245,10 +256,11 @@ fun AddAssignmentScreen(
|
|||||||
idSai = selectedSaiId!!,
|
idSai = selectedSaiId!!,
|
||||||
idPersona = selectedPersonId!!,
|
idPersona = selectedPersonId!!,
|
||||||
assignedDate = assignedDateDb.takeIf { it.isNotBlank() },
|
assignedDate = assignedDateDb.takeIf { it.isNotBlank() },
|
||||||
returnDate = returnDateDb.takeIf { it.isNotBlank() }
|
returnDate = returnDateDb.takeIf { it.isNotBlank() },
|
||||||
|
observations = observations.takeIf { it.isNotBlank() }
|
||||||
)
|
)
|
||||||
).onSuccess {
|
).onSuccess {
|
||||||
Toast.makeText(context, "Asignación guardada", Toast.LENGTH_SHORT).show()
|
Toast.makeText(context, "Asignación SAI - Persona guardada", Toast.LENGTH_SHORT).show()
|
||||||
onNavigateBack()
|
onNavigateBack()
|
||||||
}.onFailure {
|
}.onFailure {
|
||||||
Toast.makeText(context, "Error: ${it.message}", Toast.LENGTH_SHORT).show()
|
Toast.makeText(context, "Error: ${it.message}", Toast.LENGTH_SHORT).show()
|
||||||
|
|||||||
@@ -55,7 +55,8 @@ fun AssignmentListScreen(
|
|||||||
val filteredItems = remember(items, searchQuery) {
|
val filteredItems = remember(items, searchQuery) {
|
||||||
items.filter {
|
items.filter {
|
||||||
it.personName?.contains(searchQuery, ignoreCase = true) ?: false ||
|
it.personName?.contains(searchQuery, ignoreCase = true) ?: false ||
|
||||||
it.saiNs?.contains(searchQuery, ignoreCase = true) ?: false
|
it.saiNs?.contains(searchQuery, ignoreCase = true) ?: false ||
|
||||||
|
it.observations?.contains(searchQuery, ignoreCase = true) ?: false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -74,7 +75,7 @@ fun AssignmentListScreen(
|
|||||||
Scaffold(
|
Scaffold(
|
||||||
topBar = {
|
topBar = {
|
||||||
TopAppBar(
|
TopAppBar(
|
||||||
title = { Text("Listado de Asignaciones") },
|
title = { Text("Listado SAI - Persona") },
|
||||||
navigationIcon = {
|
navigationIcon = {
|
||||||
IconButton(onClick = onNavigateBack) {
|
IconButton(onClick = onNavigateBack) {
|
||||||
Icon(Icons.Default.ArrowBack, contentDescription = "Atrás")
|
Icon(Icons.Default.ArrowBack, contentDescription = "Atrás")
|
||||||
@@ -84,7 +85,7 @@ fun AssignmentListScreen(
|
|||||||
},
|
},
|
||||||
floatingActionButton = {
|
floatingActionButton = {
|
||||||
FloatingActionButton(onClick = onNavigateToAdd) {
|
FloatingActionButton(onClick = onNavigateToAdd) {
|
||||||
Icon(Icons.Default.Add, contentDescription = "Añadir Asignación")
|
Icon(Icons.Default.Add, contentDescription = "Añadir SAI - Persona")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
) { padding ->
|
) { padding ->
|
||||||
@@ -122,6 +123,9 @@ fun AssignmentListScreen(
|
|||||||
if (item.returnDate != null) {
|
if (item.returnDate != null) {
|
||||||
Text("Devolución: ${formatDate(item.returnDate)}")
|
Text("Devolución: ${formatDate(item.returnDate)}")
|
||||||
}
|
}
|
||||||
|
if (!item.observations.isNullOrBlank()) {
|
||||||
|
Text("Obs: ${item.observations}", style = MaterialTheme.typography.bodySmall, color = MaterialTheme.colorScheme.secondary)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
trailingContent = {
|
trailingContent = {
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ fun EditAssignmentScreen(
|
|||||||
var assignedDateDb by remember { mutableStateOf("") }
|
var assignedDateDb by remember { mutableStateOf("") }
|
||||||
var returnDateDisplay by remember { mutableStateOf("") }
|
var returnDateDisplay by remember { mutableStateOf("") }
|
||||||
var returnDateDb by remember { mutableStateOf("") }
|
var returnDateDb by remember { mutableStateOf("") }
|
||||||
|
var observations by remember { mutableStateOf("") }
|
||||||
|
|
||||||
var sais by remember { mutableStateOf<List<Sai>>(emptyList()) }
|
var sais by remember { mutableStateOf<List<Sai>>(emptyList()) }
|
||||||
var people by remember { mutableStateOf<List<Person>>(emptyList()) }
|
var people by remember { mutableStateOf<List<Person>>(emptyList()) }
|
||||||
@@ -68,6 +69,7 @@ fun EditAssignmentScreen(
|
|||||||
val item = assignmentResult.getOrNull()!!
|
val item = assignmentResult.getOrNull()!!
|
||||||
selectedSaiId = item.idSai
|
selectedSaiId = item.idSai
|
||||||
selectedPersonId = item.idPersona
|
selectedPersonId = item.idPersona
|
||||||
|
observations = item.observations ?: ""
|
||||||
|
|
||||||
val dbFormat = SimpleDateFormat("yyyy-MM-dd", Locale.getDefault())
|
val dbFormat = SimpleDateFormat("yyyy-MM-dd", Locale.getDefault())
|
||||||
val displayFormat = SimpleDateFormat("dd-MM-yyyy", Locale.getDefault())
|
val displayFormat = SimpleDateFormat("dd-MM-yyyy", Locale.getDefault())
|
||||||
@@ -159,7 +161,7 @@ fun EditAssignmentScreen(
|
|||||||
Scaffold(
|
Scaffold(
|
||||||
topBar = {
|
topBar = {
|
||||||
TopAppBar(
|
TopAppBar(
|
||||||
title = { Text("Editar Asignación") },
|
title = { Text("Editar SAI - Persona") },
|
||||||
navigationIcon = {
|
navigationIcon = {
|
||||||
IconButton(onClick = onNavigateBack) {
|
IconButton(onClick = onNavigateBack) {
|
||||||
Icon(Icons.Default.ArrowBack, contentDescription = "Atrás")
|
Icon(Icons.Default.ArrowBack, contentDescription = "Atrás")
|
||||||
@@ -279,6 +281,16 @@ fun EditAssignmentScreen(
|
|||||||
modifier = Modifier.fillMaxWidth().clickable { showReturnDatePicker = true }
|
modifier = Modifier.fillMaxWidth().clickable { showReturnDatePicker = true }
|
||||||
)
|
)
|
||||||
|
|
||||||
|
Spacer(modifier = Modifier.height(16.dp))
|
||||||
|
|
||||||
|
OutlinedTextField(
|
||||||
|
value = observations,
|
||||||
|
onValueChange = { observations = it },
|
||||||
|
label = { Text(stringResource(R.string.label_observations)) },
|
||||||
|
modifier = Modifier.fillMaxWidth(),
|
||||||
|
minLines = 3
|
||||||
|
)
|
||||||
|
|
||||||
Spacer(modifier = Modifier.height(32.dp))
|
Spacer(modifier = Modifier.height(32.dp))
|
||||||
|
|
||||||
Button(
|
Button(
|
||||||
@@ -292,10 +304,11 @@ fun EditAssignmentScreen(
|
|||||||
idSai = selectedSaiId!!,
|
idSai = selectedSaiId!!,
|
||||||
idPersona = selectedPersonId!!,
|
idPersona = selectedPersonId!!,
|
||||||
assignedDate = assignedDateDb.takeIf { it.isNotBlank() },
|
assignedDate = assignedDateDb.takeIf { it.isNotBlank() },
|
||||||
returnDate = returnDateDb.takeIf { it.isNotBlank() }
|
returnDate = returnDateDb.takeIf { it.isNotBlank() },
|
||||||
|
observations = observations.takeIf { it.isNotBlank() }
|
||||||
)
|
)
|
||||||
).onSuccess {
|
).onSuccess {
|
||||||
Toast.makeText(context, "Asignación actualizada", Toast.LENGTH_SHORT).show()
|
Toast.makeText(context, "Asignación SAI - Persona actualizada", Toast.LENGTH_SHORT).show()
|
||||||
onNavigateBack()
|
onNavigateBack()
|
||||||
}.onFailure {
|
}.onFailure {
|
||||||
Toast.makeText(context, "Error: ${it.message}", Toast.LENGTH_SHORT).show()
|
Toast.makeText(context, "Error: ${it.message}", Toast.LENGTH_SHORT).show()
|
||||||
|
|||||||
@@ -26,10 +26,11 @@
|
|||||||
<string name="menu_sais">Gestión de SAIs</string>
|
<string name="menu_sais">Gestión de SAIs</string>
|
||||||
<string name="menu_batteries">Gestión de Baterías</string>
|
<string name="menu_batteries">Gestión de Baterías</string>
|
||||||
<string name="menu_people">Gestión de Personas</string>
|
<string name="menu_people">Gestión de Personas</string>
|
||||||
<string name="menu_assignments">Gestión de Asignaciones</string>
|
<string name="menu_assignments">Gestion SAI - Persona</string>
|
||||||
|
|
||||||
<string name="label_person">Persona</string>
|
<string name="label_person">Persona</string>
|
||||||
<string name="label_assigned_date">Fecha Asignación (DD-MM-AAAA)</string>
|
<string name="label_assigned_date">Fecha Asignación (DD-MM-AAAA)</string>
|
||||||
<string name="label_return_date">Fecha Devolución (DD-MM-AAAA)</string>
|
<string name="label_return_date">Fecha Devolución (DD-MM-AAAA)</string>
|
||||||
|
<string name="label_observations">Observaciones</string>
|
||||||
<string name="select_person">Seleccionar Persona</string>
|
<string name="select_person">Seleccionar Persona</string>
|
||||||
</resources>
|
</resources>
|
||||||
Reference in New Issue
Block a user