Scan to open on your phone
Point a camera at the QR code - it opens this exact paste, no app needed.
https://codepastes.com/zzgs8kczptyp6np6untitledPlain Text
@Transaction
suspend fun registrarLoteCompleto(
lote: LoteProduccionEntity,
detalles: List<LoteDetalleEntity>,
gastos: List<LoteGastoEntity>,
inventariosLote: List<LoteInventarioEntity>
) {
check(detalles.isNotEmpty()) {
"El lote debe tener al menos una presentación."
}
check(inventariosLote.isNotEmpty()) {
"Debes distribuir las unidades entre las ciudades."
}
check(detalles.all {
it.loteId == lote.id && it.cantidadFabricada > 0
}) {
"Hay cantidades de producción incorrectas."
}
check(detalles.map { it.presentacionId }.distinct().size == detalles.size) {
"No puedes repetir una presentación dentro del mismo lote."
}
check(gastos.all {
it.loteId == lote.id && it.monto >= 0
}) {
"Hay gastos incorrectos o asociados a otro lote."
}
check(inventariosLote.all {
it.loteId == lote.id &&
it.cantidadDisponible > 0 &&
it.cantidadReservada == 0 &&
it.sede.isNotBlank()
}) {
"Hay una distribución incorrecta."
}
val clavesDistribucion = inventariosLote.map {
"${it.presentacionId}|${it.sede}"
}
check(clavesDistribucion.distinct().size == clavesDistribucion.size) {
"Hay distribuciones duplicadas para una misma ciudad y presentación."
}
val presentacionesFabricadas =
detalles.map { it.presentacionId }.toSet()
val presentacionesDistribuidas =
inventariosLote.map { it.presentacionId }.toSet()
check(presentacionesFabricadas == presentacionesDistribuidas) {
"Las presentaciones fabricadas no coinciden con las distribuidas."
}
for (detalle in detalles) {
val cantidadDistribuida = inventariosLote
.filter { it.presentacionId == detalle.presentacionId }
.sumOf { it.cantidadDisponible }
check(cantidadDistribuida == detalle.cantidadFabricada) {
"La distribución no coincide con la cantidad fabricada de una presentación."
}
}
val fecha = lote.fechaCreacion
// Generar el siguiente número de lote
val ultimoNumero = obtenerUltimoNumeroLote() ?: 0
val siguienteNumero = ultimoNumero + 1
val contadorActualizado = actualizarUltimoNumeroLote(siguienteNumero)
check(contadorActualizado == 1) {
"No se pudo generar el número del lote."
}
val loteConNumero = lote.copy(
numeroLote = "LOTE-${siguienteNumero.toString().padStart(4, '0')}"
)
// Guardar información del lote
guardarLote(loteConNumero)
guardarDetallesLote(detalles)
if (gastos.isNotEmpty()) {
guardarGastosLote(gastos)
}
// Guardar existencias identificadas por lote
guardarInventariosLote(inventariosLote)
val movimientos = mutableListOf<MovimientoInventarioEntity>()
// Actualizar también el inventario general
for (entrada in inventariosLote) {
val inventarioActual = buscarInventario(
presentacionId = entrada.presentacionId,
sede = entrada.sede
)
if (inventarioActual == null) {
guardarInventario(
InventarioEntity(
id = UUID.randomUUID().toString(),
presentacionId = entrada.presentacionId,
sede = entrada.sede,
cantidadDisponible = entrada.cantidadDisponible,
cantidadReservada = 0,
fechaActualizacion = fecha
)
)
} else {
val actualizado = aumentarInventarioExistente(
inventarioId = inventarioActual.id,
cantidad = entrada.cantidadDisponible,
fecha = fecha
)
check(actualizado == 1) {
"No se pudo actualizar el inventario general."
}
}
movimientos.add(
MovimientoInventarioEntity(
id = UUID.randomUUID().toString(),
presentacionId = entrada.presentacionId,
sede = entrada.sede,
tipoMovimiento = "PRODUCCION",
cantidad = entrada.cantidadDisponible,
referenciaId = lote.id,
observacion = "Entrada por lote de producción"
)
)
}
guardarMovimientos(movimientos)
}
4,855 chars · codepastes.com