import { computed } from 'vue' import type { ComputedRef } from 'vue' export interface IngresoRecord { estado: 'pagado' | 'pendiente' tipo: 'uva' | 'oreado' | 'mojado' | 'verde' peso_seco: number peso_neto: number precio: number } export interface IngresosMetrics { // Totales de ingreso y compra totalQqSecoIngresado: ComputedRef totalQqSecoComprado: ComputedRef precioPromedioUvaPorQqLb: ComputedRef precioPromedioOreadoPorQq: ComputedRef precioPromedioMojadoPorQq: ComputedRef // Inversión inversionUva: ComputedRef inversionOreado: ComputedRef inversionMojado: ComputedRef totalInvertido: ComputedRef // Inventarios en depósito totalQqSecoDeposito: ComputedRef totalQqMojadoDeposito: ComputedRef totalQqOreadoDeposito: ComputedRef totalLbUvaDeposito: ComputedRef // Inversión restante inversionRestanteOreado: ComputedRef inversionRestanteMojado: ComputedRef inversionRestanteUva: ComputedRef inversionRestanteEsperada: ComputedRef // Totales netos de verde totalLbNetoVerde: ComputedRef precioPromedioVerdePagado: ComputedRef totalLbNetoVerdeDeposito: ComputedRef inversionVerdeHastaFecha: ComputedRef inversionRestanteVerde: ComputedRef totalLbNetoCompradoVerde: ComputedRef // Secos vendidos y pérdidas (placeholder) totalQqSecoPorVender: ComputedRef precioVentaPromedioPorQq: ComputedRef precioCompraPromedioPorQq: ComputedRef margenGananciaPorQq: ComputedRef } export function useIngresosMetrics(ingresos: ComputedRef) { // Función auxiliar para calcular total a pagar const calcularTotalAPagar = (ingreso: IngresoRecord): number => { if (ingreso.tipo === 'verde' || ingreso.tipo === 'uva') { return ingreso.precio * ingreso.peso_neto } if (ingreso.tipo === 'oreado' || ingreso.tipo === 'mojado') { return (ingreso.precio / 2) * ingreso.peso_seco } return 0 } // TOTALES DE INGRESO Y COMPRA const totalQqSecoIngresado = computed(() => { return ingresos.value .filter(i => i.estado === 'pagado' || i.estado === 'pendiente') .reduce((sum, i) => sum + (i.peso_seco || 0), 0) }) const totalQqSecoComprado = computed(() => { return ingresos.value .filter(i => i.estado === 'pagado') .reduce((sum, i) => sum + (i.peso_seco || 0), 0) }) const precioPromedioUvaPorQqLb = computed(() => { const uvasPagadas = ingresos.value.filter(i => i.tipo === 'uva' && i.estado === 'pagado') const sumaPesoNeto = uvasPagadas.reduce((sum, i) => sum + (i.peso_neto || 0), 0) if (sumaPesoNeto === 0) return 0 const sumaProducto = uvasPagadas.reduce((sum, i) => sum + (i.peso_neto || 0) * (i.precio || 0), 0 ) return sumaProducto / sumaPesoNeto }) const precioPromedioOreadoPorQq = computed(() => { const oreadosPagados = ingresos.value.filter(i => i.tipo === 'oreado' && i.estado === 'pagado') const sumaPesoSeco = oreadosPagados.reduce((sum, i) => sum + (i.peso_seco || 0), 0) if (sumaPesoSeco === 0) return 0 const sumaProducto = oreadosPagados.reduce((sum, i) => sum + (i.peso_seco || 0) * (i.precio || 0), 0 ) return (sumaProducto / sumaPesoSeco) / 2 }) const precioPromedioMojadoPorQq = computed(() => { const mojadosPagados = ingresos.value.filter(i => i.tipo === 'mojado' && i.estado === 'pagado') const sumaPesoSeco = mojadosPagados.reduce((sum, i) => sum + (i.peso_seco || 0), 0) if (sumaPesoSeco === 0) return 0 const sumaProducto = mojadosPagados.reduce((sum, i) => sum + (i.peso_seco || 0) * (i.precio || 0), 0 ) return (sumaProducto / sumaPesoSeco) / 2 }) // INVERSIÓN const inversionUva = computed(() => { return ingresos.value .filter(i => i.tipo === 'uva' && i.estado === 'pagado') .reduce((sum, i) => sum + calcularTotalAPagar(i), 0) }) const inversionOreado = computed(() => { return ingresos.value .filter(i => i.tipo === 'oreado' && i.estado === 'pagado') .reduce((sum, i) => sum + calcularTotalAPagar(i), 0) }) const inversionMojado = computed(() => { return ingresos.value .filter(i => i.tipo === 'mojado' && i.estado === 'pagado') .reduce((sum, i) => sum + calcularTotalAPagar(i), 0) }) const totalInvertido = computed(() => { return inversionUva.value + inversionOreado.value + inversionMojado.value }) // INVENTARIOS EN DEPÓSITO const totalQqSecoDeposito = computed(() => { return ingresos.value .filter(i => i.estado === 'pendiente') .reduce((sum, i) => sum + (i.peso_seco || 0), 0) }) const totalQqMojadoDeposito = computed(() => { return ingresos.value .filter(i => i.tipo === 'mojado' && i.estado === 'pendiente') .reduce((sum, i) => sum + (i.peso_seco || 0), 0) }) const totalQqOreadoDeposito = computed(() => { return ingresos.value .filter(i => i.tipo === 'oreado' && i.estado === 'pendiente') .reduce((sum, i) => sum + (i.peso_seco || 0), 0) }) const totalLbUvaDeposito = computed(() => { return ingresos.value .filter(i => i.tipo === 'uva' && i.estado === 'pendiente') .reduce((sum, i) => sum + (i.peso_neto || 0), 0) }) // INVERSIÓN RESTANTE const inversionRestanteOreado = computed(() => { return precioPromedioOreadoPorQq.value * totalQqOreadoDeposito.value }) const inversionRestanteMojado = computed(() => { return precioPromedioMojadoPorQq.value * totalQqMojadoDeposito.value }) const inversionRestanteUva = computed(() => { return precioPromedioUvaPorQqLb.value * totalLbUvaDeposito.value }) const inversionRestanteEsperada = computed(() => { return inversionRestanteOreado.value + inversionRestanteMojado.value + inversionRestanteUva.value }) // TOTALES NETOS DE VERDE const totalLbNetoVerde = computed(() => { return ingresos.value .filter(i => i.tipo === 'verde') .reduce((sum, i) => sum + (i.peso_neto || 0), 0) }) const precioPromedioVerdePagado = computed(() => { const verdesPagados = ingresos.value.filter(i => i.tipo === 'verde' && i.estado === 'pagado') const sumaPesoNeto = verdesPagados.reduce((sum, i) => sum + (i.peso_neto || 0), 0) if (sumaPesoNeto === 0) return 0 const sumaProducto = verdesPagados.reduce((sum, i) => sum + (i.peso_neto || 0) * (i.precio || 0), 0 ) return sumaProducto / sumaPesoNeto }) const totalLbNetoVerdeDeposito = computed(() => { return ingresos.value .filter(i => i.tipo === 'verde' && i.estado === 'pendiente') .reduce((sum, i) => sum + (i.peso_neto || 0), 0) }) const inversionVerdeHastaFecha = computed(() => { return ingresos.value .filter(i => i.tipo === 'verde' && i.estado === 'pagado') .reduce((sum, i) => sum + calcularTotalAPagar(i), 0) }) const inversionRestanteVerde = computed(() => { return precioPromedioVerdePagado.value * totalLbNetoVerdeDeposito.value }) const totalLbNetoCompradoVerde = computed(() => { return ingresos.value .filter(i => i.tipo === 'verde' && i.estado === 'pagado') .reduce((sum, i) => sum + (i.peso_neto || 0), 0) }) // SECOS VENDIDOS Y PÉRDIDAS (placeholder - necesitan datos de ventas) const totalQqSecoPorVender = computed(() => totalQqSecoDeposito.value) const precioVentaPromedioPorQq = computed(() => 0) // Necesita datos de ventas const precioCompraPromedioPorQq = computed(() => { const totalPagado = ingresos.value.filter(i => i.estado === 'pagado') const sumaPesoSeco = totalPagado.reduce((sum, i) => sum + (i.peso_seco || 0), 0) if (sumaPesoSeco === 0) return 0 const sumaTotal = totalPagado.reduce((sum, i) => sum + calcularTotalAPagar(i), 0) return sumaTotal / sumaPesoSeco }) const margenGananciaPorQq = computed(() => precioVentaPromedioPorQq.value - precioCompraPromedioPorQq.value ) return { // Totales de ingreso y compra totalQqSecoIngresado, totalQqSecoComprado, precioPromedioUvaPorQqLb, precioPromedioOreadoPorQq, precioPromedioMojadoPorQq, // Inversión inversionUva, inversionOreado, inversionMojado, totalInvertido, // Inventarios en depósito totalQqSecoDeposito, totalQqMojadoDeposito, totalQqOreadoDeposito, totalLbUvaDeposito, // Inversión restante inversionRestanteOreado, inversionRestanteMojado, inversionRestanteUva, inversionRestanteEsperada, // Totales netos de verde totalLbNetoVerde, precioPromedioVerdePagado, totalLbNetoVerdeDeposito, inversionVerdeHastaFecha, inversionRestanteVerde, totalLbNetoCompradoVerde, // Secos vendidos y pérdidas totalQqSecoPorVender, precioVentaPromedioPorQq, precioCompraPromedioPorQq, margenGananciaPorQq } }