diff --git a/app/Http/Controllers/ComisionesController.php b/app/Http/Controllers/ComisionesController.php index 9ffd3f1..1532ec5 100644 --- a/app/Http/Controllers/ComisionesController.php +++ b/app/Http/Controllers/ComisionesController.php @@ -8,10 +8,14 @@ use App\Producto; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; use Symfony\Component\HttpFoundation\BinaryFileResponse; +use League\Csv\Reader; +use DatabaseSeeder; class ComisionesController { const CANASTAS_PATH = 'csv/canastas/'; + const BARRIO = "Barrio"; + const SALDO = "Saldo"; public function show() { @@ -67,4 +71,36 @@ class ComisionesController $file = storage_path('csv/productos.csv'); return response()->download($file); } + + public function cargarSaldos(Request $request): JsonResponse + { + $request->validate([ + 'data' => 'required|file|mimes:csv,txt|max:2048', + ]); + + $file = $request->file('data')->getPathname(); + $csv = Reader::createFromPath($file, 'r'); + try { + $csv->setDelimiter("|"); + $csv->setEnclosure("'"); + $csv->setHeaderOffset(0); + $records = $csv->getRecords(); + } catch (InvalidArgument|Exception $e) { + Log::error($e->getMessage()); + return response()->json([ + 'message' => 'No se pudo leer el csv', + ]); + } + + foreach ($records as $record) { + $barrio = $record[self::BARRIO]; + $saldo = $record[self::SALDO]; + GrupoDeCompra::where('nombre', $barrio) + ->update(['saldo' => $saldo]); + } + + return response()->json([ + 'message' => 'Saldos cargados exitosamente', + ]); + } } diff --git a/resources/js/components/comisiones/Body.vue b/resources/js/components/comisiones/Body.vue index 990ed72..eef8c6b 100644 --- a/resources/js/components/comisiones/Body.vue +++ b/resources/js/components/comisiones/Body.vue @@ -46,7 +46,38 @@ :class="seccionActiva === 'saldos-comisiones-seccion' ? 'is-active' : 'is-hidden'" >
- +
+
+

+ + Cargar saldos +

+
+
+
+ La planilla de saldos tiene que tener el siguiente formato para que la aplicación la lea correctamente: +
    +
  • Los valores deben usar punto y no coma decimal
  • +
  • El nombre de las columnas deben ser "Barrio" y "Saldo"
  • +
  • Las celdas deben separarse con '|'
  • +
  • No puede haber "enters" en ninguna celda
  • +
  • El nombre de los barrios debe estar exactamente igual que como están configurados en esta aplicacaión
  • +
+
+
+
+ Cargar un archivo de saldos sólo reemplazará los saldos de los barrios presentes en la tabla. +
+
+
+
+ +
+
+ +
@@ -83,6 +114,7 @@ import TabsSecciones from "../comunes/TabsSecciones.vue"; import DropdownDescargar from "./DropdownDescargar.vue"; import CanastaInput from "./CanastaInput.vue"; +import InputFileButton from "../comunes/InputFileButton.vue"; import { mapActions, mapState } from "vuex"; export default { @@ -104,6 +136,7 @@ export default { seccionActiva: "pedidos-comisiones-seccion", archivo: undefined, saldo_modificado: {}, + show_saldos_file_dialog: false, } }, methods: { @@ -112,6 +145,7 @@ export default { 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({ @@ -135,6 +169,32 @@ export default { } 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', [ diff --git a/resources/js/components/comunes/InputFileButton.vue b/resources/js/components/comunes/InputFileButton.vue new file mode 100644 index 0000000..a9f70a4 --- /dev/null +++ b/resources/js/components/comunes/InputFileButton.vue @@ -0,0 +1,56 @@ + + + + + diff --git a/routes/web.php b/routes/web.php index 56ac0be..73d3165 100644 --- a/routes/web.php +++ b/routes/web.php @@ -54,4 +54,5 @@ Route::middleware(['auth', 'role:comision'])->group( function() { Route::get('/comisiones/pedidos/pdf', 'ComisionesController@pdf')->name('comisiones.pedidos.pdf'); Route::get('/comisiones/canasta/ejemplo', 'ComisionesController@descargarCanastaEjemplo')->name('comisiones.canasta.ejemplo'); Route::post('/comisiones/canasta', 'ComisionesController@cargarCanasta')->name('comisiones.canasta'); + Route::post('/comisiones/saldos', 'ComisionesController@cargarSaldos')->name('comisiones.canasta'); });
Barrio