Merge pull request 'Se ajusta validaciones de formulario y advierte al usuario cuando abandona la página por iteraciones en el navegador.' (#73) from warn_before_leave_purchase_#67 into main

Reviewed-on: OneTeam/don_confiao#73
This commit is contained in:
mono 2024-11-11 23:08:53 -05:00
commit b2756ac7ce

View File

@ -1,6 +1,6 @@
<template> <template>
<v-container> <v-container>
<v-form ref="form" v-model="valid"> <v-form ref="purchase" v-model="valid" @change="onFormChange">
<v-row> <v-row>
<v-col> <v-col>
<v-autocomplete <v-autocomplete
@ -10,6 +10,7 @@
no-data-text="No se hallaron clientes" no-data-text="No se hallaron clientes"
item-title="name" item-title="name"
item-value="id" item-value="id"
@update:model-value="onFormChange"
label="Cliente" label="Cliente"
:rules="[rules.required]" :rules="[rules.required]"
required required
@ -104,8 +105,11 @@
<v-col> <v-col>
<v-btn @click="removeLine(index)" color="red">Eliminar</v-btn> <v-btn @click="removeLine(index)" color="red">Eliminar</v-btn>
</v-col> </v-col>
</v-row> </v-row>
</v-container> <v-alert type="warning" :duration="2000" closable v-model="show_alert_lines">
No se puede eliminar la única línea.
</v-alert>
</v-container>
<v-btn @click="addLine" color="blue">Agregar</v-btn> <v-btn @click="addLine" color="blue">Agregar</v-btn>
</v-container> </v-container>
<v-divider></v-divider> <v-divider></v-divider>
@ -123,11 +127,16 @@
item-title="text" item-title="text"
item-value="value" item-value="value"
label="Pago en" label="Pago en"
:rules="[rules.required]"
required
></v-select> ></v-select>
<v-btn @click="openCasherModal" v-if="purchase.payment_method === 'CASH'">Calcular Devuelta</v-btn> <v-btn @click="openCasherModal" v-if="purchase.payment_method === 'CASH'">Calcular Devuelta</v-btn>
<CasherModal :total_purchase="calculateTotal" ref="casherModal"</CasherModal> <CasherModal :total_purchase="calculateTotal" ref="casherModal"</CasherModal>
</v-container> </v-container>
<v-btn @click="submit" color="green">Comprar</v-btn> <v-btn @click="submit" color="green">Comprar</v-btn>
<v-alert type="error" :duration="2000" closable v-model="show_alert_purchase">
Verifique los campos obligatorios.
</v-alert>
</v-form> </v-form>
</v-container> </v-container>
</template> </template>
@ -148,6 +157,9 @@
data() { data() {
return { return {
valid: false, valid: false,
form_changed: false,
show_alert_lines: false,
show_alert_purchase: false,
client_search: '', client_search: '',
product_search: '', product_search: '',
payment_methods: null, payment_methods: null,
@ -179,6 +191,12 @@
this.drawer = false this.drawer = false
}, },
}, },
beforeMount() {
window.addEventListener('beforeunload', this.confirmLeave);
},
beforeDestroy() {
window.removeEventListener('beforeunload', this.confirmLeave);
},
computed: { computed: {
calculateTotal() { calculateTotal() {
return this.purchase.saleline_set.reduce((total, saleline) => { return this.purchase.saleline_set.reduce((total, saleline) => {
@ -208,9 +226,20 @@
openModal() { openModal() {
this.$refs.customerModal.openModal(); this.$refs.customerModal.openModal();
}, },
onFormChange() {
this.form_changed = true;
},
openCasherModal() { openCasherModal() {
this.$refs.casherModal.dialog = true this.$refs.casherModal.dialog = true
}, },
confirmLeave(event) {
if (this.form_changed) {
const message = '¿seguro que quieres salir? Perderas la información diligenciada';
event.preventDefault();
event.returnValue = message;
return message;
}
},
getCurrentDate() { getCurrentDate() {
const today = new Date(); const today = new Date();
const yyyy = today.getFullYear(); const yyyy = today.getFullYear();
@ -223,7 +252,6 @@
const selectedProductId = this.purchase.saleline_set[index].product; const selectedProductId = this.purchase.saleline_set[index].product;
const selectedProduct = this.products.find(p => p.id == selectedProductId); const selectedProduct = this.products.find(p => p.id == selectedProductId);
this.purchase.saleline_set[index].unit_price = selectedProduct.price; this.purchase.saleline_set[index].unit_price = selectedProduct.price;
console.log(selectedProduct.measuring_unit);
this.purchase.saleline_set[index].measuring_unit = selectedProduct.measuring_unit; this.purchase.saleline_set[index].measuring_unit = selectedProduct.measuring_unit;
}, },
fetchClients() { fetchClients() {
@ -264,29 +292,21 @@
this.purchase.saleline_set.push({ product: '', unit_price: 0, quantity:0, measuring_unit: ''}); this.purchase.saleline_set.push({ product: '', unit_price: 0, quantity:0, measuring_unit: ''});
}, },
removeLine(index) { removeLine(index) {
// Solo elimina si hay más de una línea
if (this.purchase.saleline_set.length > 1) { if (this.purchase.saleline_set.length > 1) {
this.purchase.saleline_set.splice(index, 1); this.purchase.saleline_set.splice(index, 1);
} else { } else {
// Opcional: puedes mostrar un mensaje o alerta si lo deseas this.show_alert_lines = true;
console.log("No se puede eliminar la única línea."); setTimeout(() => {
this.show_alert_lines = false;
}, 2000);
} }
}, },
calculateSubtotal(line) { calculateSubtotal(line) {
return line.unit_price * line.quantity; return line.unit_price * line.quantity;
}, },
async submit() { async submit() {
if (this.$refs.form.validate()) { this.$refs.purchase.validate();
const hasInvalidQuantity = this.purchase.saleline_set.some(line => line.quantity <= 0); if (this.valid) {
if (hasInvalidQuantity) {
this.errorMessage = 'La cantidad de cada línea de compra debe ser mayor que cero.';
console.log(this.errorMessage);
return; // Detener el submit si hay cantidades inválidas
}
this.errorMessage = ''; // Limpiar el mensaje de error
try { try {
const response = await fetch('/don_confiao/api/sales/', { const response = await fetch('/don_confiao/api/sales/', {
method: 'POST', method: 'POST',
@ -308,6 +328,11 @@
} catch (error) { } catch (error) {
console.error('Error de red:', error); console.error('Error de red:', error);
} }
} else {
this.show_alert_purchase = true;
setTimeout(() => {
this.show_alert_purchase = false;
}, 4000);
} }
}, },
navigate(route) { navigate(route) {