Files
ToldoConjunto/apps/toldo-app/src/views/Jornada.vue

107 lines
4.7 KiB
Vue

<template>
<div>
<h1 class="text-h4 mb-4">Jornada del Toldo (Apertura/Cierre)</h1>
<v-alert v-if="jornadaAbierta" type="success" class="mb-4">
Jornada ABIERTA desde {{ formatFecha(jornadaAbierta.fechaApertura) }} | Responsables: {{ (jornadaAbierta.responsables||[]).join(', ') }} | Base inicial: ${{ jornadaAbierta.baseInicial }}
</v-alert>
<v-alert v-else type="info" class="mb-4">No hay jornada abierta</v-alert>
<v-row>
<v-col cols="12" md="6">
<v-card>
<v-card-title>Apertura de Jornada</v-card-title>
<v-card-text>
<v-text-field v-model="responsablesStr" label="Responsables (separados por coma)" placeholder="Ana, Luis"></v-text-field>
<v-text-field v-model.number="baseInicial" type="number" label="Base inicial (efectivo)" class="mt-2"></v-text-field>
<v-btn @click="abrir" color="primary" block class="mt-2" :disabled="!!jornadaAbierta">Abrir Jornada</v-btn>
</v-card-text>
</v-card>
</v-col>
<v-col cols="12" md="6">
<v-card>
<v-card-title>Cierre de Jornada</v-card-title>
<v-card-text>
<div v-if="resumen">
<div class="mb-2">Ventas: ${{ resumen.totalVentas }}</div>
<div class="mb-2">Gastos: ${{ resumen.totalGastos }}</div>
<div class="mb-2 font-weight-bold">Saldo esperado en efectivo: ${{ saldoEsperadoEfectivo.toLocaleString() }}</div>
</div>
<v-text-field v-model.number="saldoRealEfectivo" type="number" label="Efectivo contado (obligatorio)" prefix="$" class="mt-4" />
<v-text-field v-model.number="totalQRBanco" type="number" label="Dinero en banco por QR (opcional)" prefix="$" />
<v-alert v-if="saldoRealEfectivo !== null && resumen" :type="diferenciaEfectivo === 0 ? 'success' : 'warning'" variant="tonal" class="mb-2">Diferencia de efectivo: ${{ diferenciaEfectivo.toLocaleString() }}</v-alert>
<v-alert v-if="cierreError" :type="cierreCompletado ? 'success' : 'error'" variant="tonal" class="mb-2">{{ cierreError }}</v-alert>
<v-btn @click="cerrar" color="error" block class="mt-2" :disabled="!jornadaAbierta || saldoRealEfectivo < 0" prepend-icon="mdi-lock-check">Cerrar caja y jornada</v-btn>
</v-card-text>
</v-card>
</v-col>
</v-row>
</div>
</template>
<script setup lang="ts">
import { ref, computed, onMounted } from 'vue';
import { JornadaService, CuadreService } from '@toldo/services';
const service = new JornadaService();
const cuadreService = new CuadreService();
const jornadaAbierta = ref<any>(null);
const responsablesStr = ref('');
const baseInicial = ref(0);
const resumen = ref<any>(null);
const saldoRealEfectivo = ref<number | null>(null);
const totalQRBanco = ref<number | null>(null);
const cierreError = ref('');
const cierreCompletado = ref(false);
const saldoEsperadoEfectivo = ref(0);
const diferenciaEfectivo = computed(() => saldoRealEfectivo.value === null ? 0 : saldoRealEfectivo.value - saldoEsperadoEfectivo.value);
function formatFecha(d: any) {
try { return new Date(d).toLocaleString(); } catch { return d; }
}
async function cargar() {
jornadaAbierta.value = await service.getJornadaAbierta();
if (jornadaAbierta.value) {
resumen.value = await service.getResumenJornada(jornadaAbierta.value.id);
const cuadre = await cuadreService.calcularCuadreDelDia(jornadaAbierta.value.fecha, jornadaAbierta.value.baseInicial);
saldoEsperadoEfectivo.value = cuadre.saldoEsperadoEfectivo ?? 0;
} else {
resumen.value = null;
saldoEsperadoEfectivo.value = 0;
}
}
async function abrir() {
if (!responsablesStr.value.trim()) return alert('Ingrese responsables');
const responsables = responsablesStr.value.split(',').map(r => r.trim()).filter(r => r);
try {
await service.abrirJornada(responsables, Number(baseInicial.value) || 0);
responsablesStr.value = '';
baseInicial.value = 0;
await cargar();
alert('Jornada abierta');
} catch (e: any) {
alert(e.message);
}
}
async function cerrar() {
if (!jornadaAbierta.value) return;
cierreError.value = '';
cierreCompletado.value = false;
if (saldoRealEfectivo.value === null || saldoRealEfectivo.value === undefined || saldoRealEfectivo.value < 0) { cierreError.value = 'El efectivo contado es obligatorio.'; return; }
try {
const cid = await service.cerrarJornada(jornadaAbierta.value.id, Number(saldoRealEfectivo.value), totalQRBanco.value === null ? undefined : Number(totalQRBanco.value));
await cargar();
cierreCompletado.value = true;
cierreError.value = `Cierre de caja y jornada completado: ${cid}`;
} catch (e: any) {
alert(e.message);
}
}
onMounted(cargar);
</script>