untitled

Pasted Nov 9, 2026, 7:46 PM1 file150 lines

Scan to open on your phone

Point a camera at the QR code - it opens this exact paste, no app needed.

https://codepastes.com/zzgs8w0rmkmgxa75
untitled
@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,854 chars · codepastes.com