Componente aparte para seccion saldos

This commit is contained in:
Alejandro Tasistro 2025-06-18 19:56:05 -03:00
parent 5c3d68a4e9
commit ac559770c0
2 changed files with 151 additions and 127 deletions

View file

@ -16,73 +16,7 @@
<div class="block pb-6"
id="saldos-comisiones-seccion"
:class="seccionActiva === 'saldos-comisiones-seccion' ? 'is-active' : 'is-hidden'">
<div class="block" id="saldos-comisiones-seccion">
<div class="columns">
<div class="column">
<article class="message is-warning">
<div class="message-header">
<p>
<span class="icon is-small"
@click="toggleSaldosFileDialog">
<i :class="`fas ${!show_saldos_file_dialog ? 'fa-angle-down' : 'fa-angle-up'}`" aria-hidden="true"></i>
</span>
Cargar saldos
</p>
</div>
<div class="message-body" v-if="show_saldos_file_dialog">
<div class="content">
La planilla de saldos tiene que tener el siguiente formato para que la aplicación la lea correctamente:
<ul>
<li>Los valores deben usar punto y no coma decimal</li>
<li>El nombre de las columnas deben ser "Barrio" y "Saldo"</li>
<li>Las celdas deben separarse con '|'</li>
<li>No puede haber "enters" en ninguna celda</li>
<li>El nombre de los barrios debe estar exactamente igual que como est&aacute;n configurados en esta aplicacai&oacute;n</li>
</ul>
<article class="message is-danger mt-2">
<div class="message-body">
<div class="content">
Cargar un archivo de saldos s&oacute;lo reemplazar&aacute; los saldos de los barrios presentes en la tabla.
</div>
</div>
</article>
</div>
<input-file-button text="Subir archivo" @archivo-subido="saldosSubido" />
</div>
</article>
</div>
<div class="column">
<table class="table container">
<thead>
<tr>
<th>Barrio</th>
<th>Saldo</th>
</tr>
</thead>
<tbody>
<tr v-for="gdc in grupos_de_compra">
<th>{{ gdc.nombre }}</th>
<td>
<input id="cantidad"
v-model="gdc.saldo"
class="input is-small"
type="number"
style="text-align: center"
@input="saldoModificado(gdc.id)">
</td>
<td>
<button :disabled="!isSaldoModificado(gdc.id)" class="button is-small is-success ml-1" @click="confirmar_saldo(gdc.id)">
<span class="icon">
<i class="fas fa-check"></i>
</span>
</button>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<saldos-seccion/>
</div>
</div>
</template>
@ -91,12 +25,14 @@
import TabsSecciones from "../comunes/TabsSecciones.vue";
import DropdownDescargar from "./DropdownDescargar.vue";
import InputFileButton from "../comunes/InputFileButton.vue";
import { mapActions, mapState } from "vuex";
import CanastaSeccion from "./canasta/CanastaSeccion.vue";
import SaldosSeccion from "./saldos/SaldosSeccion.vue";
import { mapActions } from "vuex";
export default {
name: "ComisionesBody",
components: {
SaldosSeccion,
CanastaSeccion,
TabsSecciones,
DropdownDescargar,
@ -111,72 +47,14 @@ export default {
],
tabActiva: "pedidos-comisiones",
seccionActiva: "pedidos-comisiones-seccion",
archivo: undefined,
saldo_modificado: {},
show_saldos_file_dialog: true,
}
},
methods: {
...mapActions('comisiones', ['getGruposDeCompra']),
setSeccionActiva(tabId) {
this.tabActiva = tabId;
this.seccionActiva = tabId + "-seccion";
},
...mapActions('comisiones', ['getGruposDeCompra', 'setSaldo']),
...mapActions('ui',["toast"]),
async confirmar_saldo(gdc_id) {
var saldo = this.getSaldo(gdc_id);
await this.setSaldo({
gdc_id: gdc_id,
saldo: saldo,
});
this.saldo_modificado[gdc_id] = false;
await this.getGruposDeCompra();
},
saldoModificado(gdc_id) {
this.saldo_modificado[gdc_id] = true;
},
isSaldoModificado(gdc_id) {
return gdc_id in this.saldo_modificado && this.saldo_modificado[gdc_id];
},
getSaldo(gdc_id) {
for (var i = 0; i < this.grupos_de_compra.length; i++) {
if (this.grupos_de_compra[i].id == gdc_id) {
return this.grupos_de_compra[i].saldo;
}
}
return 0;
},
async saldosSubido(event) {
var archivo = event.archivo;
if (archivo.type === "text/csv") {
const formData = new FormData();
formData.append("data", archivo);
try {
const response = await axios.post("/comisiones/saldos", formData, {
headers: {
"Content-Type": "multipart/form-data",
},
});
this.getGruposDeCompra();
this.toast({ mensaje: (response.data.message || "Canasta cargada exitosamente") });
} catch (error) {
console.log(error);
this.toast({ mensaje: (error.response?.data?.message || "Hubo errores.") });
}
event.component.cargando = false;
} else {
this.toast("El archivo debe ser .CSV");
event.component.cargando = false;
}
},
toggleSaldosFileDialog() {
this.show_saldos_file_dialog = !this.show_saldos_file_dialog;
},
},
computed: {
...mapState('comisiones', [
'grupos_de_compra',
]),
},
async mounted() {
await this.getGruposDeCompra();

View file

@ -0,0 +1,146 @@
<script>
import InputFileButton from "../../comunes/InputFileButton.vue";
import { mapActions, mapState } from "vuex";
export default {
name: "SaldosSeccion",
components: { InputFileButton },
data() {
return {
archivo: undefined,
saldo_modificado: {},
show_saldos_file_dialog: true,
};
},
methods: {
...mapActions('ui',["toast"]),
...mapActions('comisiones', ['setSaldo']),
async confirmar_saldo(gdc_id) {
var saldo = this.getSaldo(gdc_id);
await this.setSaldo({
gdc_id: gdc_id,
saldo: saldo,
});
this.saldo_modificado[gdc_id] = false;
await this.getGruposDeCompra();
},
saldoModificado(gdc_id) {
this.saldo_modificado[gdc_id] = true;
},
isSaldoModificado(gdc_id) {
return gdc_id in this.saldo_modificado && this.saldo_modificado[gdc_id];
},
getSaldo(gdc_id) {
for (var i = 0; i < this.grupos_de_compra.length; i++) {
if (this.grupos_de_compra[i].id == gdc_id) {
return this.grupos_de_compra[i].saldo;
}
}
return 0;
},
async saldosSubido(event) {
var archivo = event.archivo;
if (archivo.type === "text/csv") {
const formData = new FormData();
formData.append("data", archivo);
try {
const response = await axios.post("/comisiones/saldos", formData, {
headers: {
"Content-Type": "multipart/form-data",
},
});
this.getGruposDeCompra();
this.toast({ mensaje: (response.data.message || "Canasta cargada exitosamente") });
} catch (error) {
console.log(error);
this.toast({ mensaje: (error.response?.data?.message || "Hubo errores.") });
}
event.component.cargando = false;
} else {
this.toast("El archivo debe ser .CSV");
event.component.cargando = false;
}
},
toggleSaldosFileDialog() {
this.show_saldos_file_dialog = !this.show_saldos_file_dialog;
},
},
computed: {
...mapState('comisiones', ['grupos_de_compra']),
},
}
</script>
<template>
<div>
<div class="columns">
<div class="column">
<article class="message is-warning">
<div class="message-header">
<p>
<span class="icon is-small"
@click="toggleSaldosFileDialog">
<i :class="`fas ${!show_saldos_file_dialog ? 'fa-angle-down' : 'fa-angle-up'}`" aria-hidden="true"></i>
</span>
Cargar saldos
</p>
</div>
<div class="message-body" v-if="show_saldos_file_dialog">
<div class="content">
La planilla de saldos tiene que tener el siguiente formato para que la aplicación la lea correctamente:
<ul>
<li>Los valores deben usar punto y no coma decimal</li>
<li>El nombre de las columnas deben ser "Barrio" y "Saldo"</li>
<li>Las celdas deben separarse con '|'</li>
<li>No puede haber "enters" en ninguna celda</li>
<li>El nombre de los barrios debe estar exactamente igual que como est&aacute;n configurados en esta aplicacai&oacute;n</li>
</ul>
<article class="message is-danger mt-2">
<div class="message-body">
<div class="content">
Cargar un archivo de saldos s&oacute;lo reemplazar&aacute; los saldos de los barrios presentes en la tabla.
</div>
</div>
</article>
</div>
<input-file-button text="Subir archivo" @archivo-subido="saldosSubido" />
</div>
</article>
</div>
<div class="column">
<table class="table container">
<thead>
<tr>
<th>Barrio</th>
<th>Saldo</th>
</tr>
</thead>
<tbody>
<tr v-for="gdc in grupos_de_compra">
<th>{{ gdc.nombre }}</th>
<td>
<input id="cantidad"
v-model="gdc.saldo"
class="input is-small"
type="number"
style="text-align: center"
@input="saldoModificado(gdc.id)">
</td>
<td>
<button :disabled="!isSaldoModificado(gdc.id)" class="button is-small is-success ml-1" @click="confirmar_saldo(gdc.id)">
<span class="icon">
<i class="fas fa-check"></i>
</span>
</button>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</template>
<style scoped>
</style>