forked from nathalie/pedi2
Merge pull request 'Saldos' (#46) from funcion/saldos into funcion/refactor-general
Reviewed-on: nathalie/pedi2#46
This commit is contained in:
commit
1115764d81
30 changed files with 592 additions and 71 deletions
|
@ -11,10 +11,11 @@ use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
use Illuminate\Support\Facades\Log;
|
use Illuminate\Support\Facades\Log;
|
||||||
|
use League\Csv\Exception;
|
||||||
|
|
||||||
class GrupoDeCompra extends Model
|
class GrupoDeCompra extends Model
|
||||||
{
|
{
|
||||||
protected $fillable = ["nombre", "region", "devoluciones_habilitadas"];
|
protected $fillable = ["nombre", "region", "devoluciones_habilitadas", "saldo"];
|
||||||
protected $table = 'grupos_de_compra';
|
protected $table = 'grupos_de_compra';
|
||||||
|
|
||||||
public function subpedidos(): HasMany
|
public function subpedidos(): HasMany
|
||||||
|
@ -69,11 +70,17 @@ class GrupoDeCompra extends Model
|
||||||
return $total;
|
return $total;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function totalATransferir()
|
public function totalDePedido()
|
||||||
{
|
{
|
||||||
return $this->totalCentralesQueNoPaganTransporte()
|
return $this->totalCentralesQueNoPaganTransporte()
|
||||||
+ $this->totalCentralesQuePaganTransporte()
|
+ $this->totalCentralesQuePaganTransporte()
|
||||||
+ $this->totalTransporte();
|
+ $this->totalTransporte()
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function totalATransferir()
|
||||||
|
{
|
||||||
|
return $this->totalDePedido() - $this->saldo;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function totalCentralesQueNoPaganTransporte()
|
public function totalCentralesQueNoPaganTransporte()
|
||||||
|
@ -159,6 +166,10 @@ class GrupoDeCompra extends Model
|
||||||
}
|
}
|
||||||
|
|
||||||
//Asume que los productos están gruadados en orden de fila
|
//Asume que los productos están gruadados en orden de fila
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
public static function obtenerTemplateDeFilasVacias(int $columns): array
|
public static function obtenerTemplateDeFilasVacias(int $columns): array
|
||||||
{
|
{
|
||||||
$productosFilaID = Producto::productosFilaID();
|
$productosFilaID = Producto::productosFilaID();
|
||||||
|
@ -176,6 +187,9 @@ class GrupoDeCompra extends Model
|
||||||
return $template;
|
return $template;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
public function exportarPedidoEnCSV()
|
public function exportarPedidoEnCSV()
|
||||||
{
|
{
|
||||||
$records = $this->generarColumnaCantidades();
|
$records = $this->generarColumnaCantidades();
|
||||||
|
@ -184,6 +198,9 @@ class GrupoDeCompra extends Model
|
||||||
CsvHelper::generarCsv('csv/exports/' . $this->nombre . '-' . $fecha . '.csv', $records);
|
CsvHelper::generarCsv('csv/exports/' . $this->nombre . '-' . $fecha . '.csv', $records);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
public function generarColumnaCantidades(): array
|
public function generarColumnaCantidades(): array
|
||||||
{
|
{
|
||||||
$productos_en_pedido = $this->productosPedidos();
|
$productos_en_pedido = $this->productosPedidos();
|
||||||
|
@ -206,6 +223,9 @@ class GrupoDeCompra extends Model
|
||||||
return $records;
|
return $records;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
public function exportarPedidoConNucleosEnCSV()
|
public function exportarPedidoConNucleosEnCSV()
|
||||||
{
|
{
|
||||||
$productos_en_pedido = $this->productosPedidos();
|
$productos_en_pedido = $this->productosPedidos();
|
||||||
|
@ -284,4 +304,9 @@ class GrupoDeCompra extends Model
|
||||||
->get()
|
->get()
|
||||||
->keyBy('producto_id');
|
->keyBy('producto_id');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function setSaldo(float $saldo) {
|
||||||
|
$this->saldo = $saldo;
|
||||||
|
$this->save();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@ use Illuminate\Support\Arr;
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
use Illuminate\Support\Facades\File;
|
use Illuminate\Support\Facades\File;
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
|
use League\Csv\Exception;
|
||||||
|
|
||||||
class CanastaHelper
|
class CanastaHelper
|
||||||
{
|
{
|
||||||
|
@ -25,7 +26,8 @@ class CanastaHelper
|
||||||
$log = CanastaLog::where('descripcion', self::CANASTA_CARGADA)
|
$log = CanastaLog::where('descripcion', self::CANASTA_CARGADA)
|
||||||
->orderBy('created_at', 'desc')
|
->orderBy('created_at', 'desc')
|
||||||
->first();
|
->first();
|
||||||
$nombre = str_replace("csv/canastas/", "", $log->path);
|
$nombre = str_replace(storage_path(), "", $log->path);
|
||||||
|
$nombre = str_replace("/csv/canastas/", "", $nombre);
|
||||||
$result["nombre"] = str_replace(".csv", "", $nombre);
|
$result["nombre"] = str_replace(".csv", "", $nombre);
|
||||||
$result["fecha"] = $log->created_at;
|
$result["fecha"] = $log->created_at;
|
||||||
return $result;
|
return $result;
|
||||||
|
@ -38,17 +40,22 @@ class CanastaHelper
|
||||||
|
|
||||||
$nombre = $data->getClientOriginalName();
|
$nombre = $data->getClientOriginalName();
|
||||||
|
|
||||||
$data->move(storage_path($path), $nombre);
|
$storage_path = storage_path($path);
|
||||||
|
$data->move($storage_path, $nombre);
|
||||||
|
|
||||||
self::log($path . $nombre, self::ARCHIVO_SUBIDO);
|
self::log($storage_path . $nombre, self::ARCHIVO_SUBIDO);
|
||||||
|
|
||||||
return $nombre;
|
return $nombre;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
public static function cargarCanasta($archivo) {
|
public static function cargarCanasta($archivo) {
|
||||||
self::limpiarTablas();
|
self::limpiarTablas();
|
||||||
|
|
||||||
$registros = CsvHelper::getRecords($archivo);
|
$registros = CsvHelper::getRecords($archivo, "No se pudo leer el archivo.");
|
||||||
|
|
||||||
$toInsert = [];
|
$toInsert = [];
|
||||||
$categoria = '';
|
$categoria = '';
|
||||||
|
|
||||||
|
|
|
@ -13,8 +13,11 @@ use League\Csv\Writer;
|
||||||
|
|
||||||
class CsvHelper
|
class CsvHelper
|
||||||
{
|
{
|
||||||
public static function getRecords($filePath): Iterator {
|
/**
|
||||||
$csv = Reader::createFromPath(storage_path($filePath));
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public static function getRecords($filePath, $message): Iterator {
|
||||||
|
$csv = Reader::createFromPath($filePath);
|
||||||
try {
|
try {
|
||||||
$csv->setDelimiter("|");
|
$csv->setDelimiter("|");
|
||||||
$csv->setEnclosure("'");
|
$csv->setEnclosure("'");
|
||||||
|
@ -22,7 +25,7 @@ class CsvHelper
|
||||||
return $csv->getRecords();
|
return $csv->getRecords();
|
||||||
} catch (InvalidArgument|Exception $e) {
|
} catch (InvalidArgument|Exception $e) {
|
||||||
Log::error($e->getMessage());
|
Log::error($e->getMessage());
|
||||||
return null;
|
throw new Exception($message, $e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ namespace App\Helpers;
|
||||||
|
|
||||||
use App\CanastaLog;
|
use App\CanastaLog;
|
||||||
use Illuminate\Support\Facades\Log;
|
use Illuminate\Support\Facades\Log;
|
||||||
|
use League\Csv\Exception;
|
||||||
|
|
||||||
class TransporteHelper
|
class TransporteHelper
|
||||||
{
|
{
|
||||||
|
@ -20,6 +21,9 @@ class TransporteHelper
|
||||||
return self::cantidadTransporte($monto) * self::COSTO_TRANSPORTE;
|
return self::cantidadTransporte($monto) * self::COSTO_TRANSPORTE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
public static function filaTransporte()
|
public static function filaTransporte()
|
||||||
{
|
{
|
||||||
$ultimaCanasta = CanastaLog::where('descripcion', CanastaHelper::CANASTA_CARGADA)
|
$ultimaCanasta = CanastaLog::where('descripcion', CanastaHelper::CANASTA_CARGADA)
|
||||||
|
@ -27,12 +31,14 @@ class TransporteHelper
|
||||||
->pluck('path')
|
->pluck('path')
|
||||||
->first();
|
->first();
|
||||||
|
|
||||||
$registros = CsvHelper::getRecords($ultimaCanasta);
|
$registros = CsvHelper::getRecords($ultimaCanasta, "No se encontró la ultima canasta.");
|
||||||
|
$error = 'No hay fila de tipo T en la planilla: ' . $ultimaCanasta;
|
||||||
|
|
||||||
foreach ($registros as $key => $registro)
|
foreach ($registros as $key => $registro)
|
||||||
if ($registro[CanastaHelper::TIPO] == 'T') return $key;
|
if ($registro[CanastaHelper::TIPO] == 'T')
|
||||||
|
return $key;
|
||||||
|
|
||||||
Log::error('No hay fila de tipo T en la planilla: ' . $ultimaCanasta);
|
Log::error($error);
|
||||||
return null;
|
throw new Exception($error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
namespace App\Http\Controllers;
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
use App\GrupoDeCompra;
|
use App\GrupoDeCompra;
|
||||||
use Symfony\Component\HttpFoundation\BinaryFileResponse;
|
use League\Csv\Exception;
|
||||||
|
|
||||||
class AdminController extends Controller
|
class AdminController extends Controller
|
||||||
{
|
{
|
||||||
|
@ -20,9 +20,13 @@ class AdminController extends Controller
|
||||||
$gdc->exportarPedidosAPdf();
|
$gdc->exportarPedidosAPdf();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function exportarPedidoACSV(GrupoDeCompra $gdc): BinaryFileResponse
|
public function exportarPedidoACSV(GrupoDeCompra $gdc)
|
||||||
{
|
{
|
||||||
$gdc->exportarPedidoEnCSV();
|
try {
|
||||||
|
$gdc->exportarPedidoEnCSV();
|
||||||
|
} catch (Exception $e) {
|
||||||
|
return response()->json(['message' => $e->getMessage()]);
|
||||||
|
}
|
||||||
$pattern = storage_path('csv/exports/'. $gdc->nombre . '-*.csv');
|
$pattern = storage_path('csv/exports/'. $gdc->nombre . '-*.csv');
|
||||||
$files = glob($pattern);
|
$files = glob($pattern);
|
||||||
|
|
||||||
|
@ -33,9 +37,13 @@ class AdminController extends Controller
|
||||||
return response()->download($files[0]);
|
return response()->download($files[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function exportarPedidoConNucleosACSV(GrupoDeCompra $gdc): BinaryFileResponse
|
public function exportarPedidoConNucleosACSV(GrupoDeCompra $gdc)
|
||||||
{
|
{
|
||||||
$gdc->exportarPedidoConNucleosEnCSV();
|
try {
|
||||||
|
$gdc->exportarPedidoConNucleosEnCSV();
|
||||||
|
} catch (Exception $e) {
|
||||||
|
return response()->json(['message' => $e->getMessage()]);
|
||||||
|
}
|
||||||
$pattern = storage_path('csv/exports/'.$gdc->nombre.'-completo-*.csv');
|
$pattern = storage_path('csv/exports/'.$gdc->nombre.'-completo-*.csv');
|
||||||
$files = glob($pattern);
|
$files = glob($pattern);
|
||||||
|
|
||||||
|
|
|
@ -4,9 +4,8 @@ namespace App\Http\Controllers\Api;
|
||||||
|
|
||||||
use App\GrupoDeCompra;
|
use App\GrupoDeCompra;
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use App\Http\Resources\GrupoDeCompraReducido;
|
use App\Http\Resources\GrupoDeCompraComisionesResource;
|
||||||
use App\Http\Resources\GrupoDeCompraResource;
|
use App\Http\Resources\GrupoDeCompraResource;
|
||||||
use http\Env\Request;
|
|
||||||
|
|
||||||
class GrupoDeCompraController extends Controller
|
class GrupoDeCompraController extends Controller
|
||||||
{
|
{
|
||||||
|
@ -32,4 +31,18 @@ class GrupoDeCompraController extends Controller
|
||||||
GrupoDeCompra::find($gdc)->toggleDevoluciones();
|
GrupoDeCompra::find($gdc)->toggleDevoluciones();
|
||||||
return response()->noContent();
|
return response()->noContent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function setSaldo(int $gdc) {
|
||||||
|
$valid = request()->validate([
|
||||||
|
'saldo' => ['required', 'min:0'],
|
||||||
|
]);
|
||||||
|
$grupoDeCompra = GrupoDeCompra::find($gdc);
|
||||||
|
$grupoDeCompra->setSaldo($valid['saldo']);
|
||||||
|
return response()->noContent();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function saldos()
|
||||||
|
{
|
||||||
|
return GrupoDeCompraComisionesResource::collection(GrupoDeCompra::all());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,23 +4,32 @@ namespace App\Http\Controllers;
|
||||||
|
|
||||||
use App\GrupoDeCompra;
|
use App\GrupoDeCompra;
|
||||||
use App\Helpers\CanastaHelper;
|
use App\Helpers\CanastaHelper;
|
||||||
|
use App\Helpers\CsvHelper;
|
||||||
|
use App\Http\Resources\GrupoDeCompraResource;
|
||||||
use App\Producto;
|
use App\Producto;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
use League\Csv\Exception;
|
||||||
use Symfony\Component\HttpFoundation\BinaryFileResponse;
|
use Symfony\Component\HttpFoundation\BinaryFileResponse;
|
||||||
|
|
||||||
class ComisionesController
|
class ComisionesController
|
||||||
{
|
{
|
||||||
const CANASTAS_PATH = 'csv/canastas/';
|
const CANASTAS_PATH = 'csv/canastas/';
|
||||||
|
const BARRIO = "Barrio";
|
||||||
|
const SALDO = "Saldo";
|
||||||
|
|
||||||
public function show()
|
public function show()
|
||||||
{
|
{
|
||||||
return view('auth/login');
|
return view('auth/login');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function descargarPedidos(): BinaryFileResponse
|
public function descargarPedidos()
|
||||||
{
|
{
|
||||||
Producto::planillaTotales();
|
try {
|
||||||
|
Producto::planillaTotales();
|
||||||
|
} catch (Exception $e) {
|
||||||
|
return response()->json(['message' => $e->getMessage()], 500);
|
||||||
|
}
|
||||||
$pattern = storage_path('csv/exports/pedidos-por-barrio-*.csv');
|
$pattern = storage_path('csv/exports/pedidos-por-barrio-*.csv');
|
||||||
$files = glob($pattern);
|
$files = glob($pattern);
|
||||||
|
|
||||||
|
@ -55,7 +64,11 @@ class ComisionesController
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$nombre = CanastaHelper::guardarCanasta($request->file('data'), self::CANASTAS_PATH);
|
$nombre = CanastaHelper::guardarCanasta($request->file('data'), self::CANASTAS_PATH);
|
||||||
CanastaHelper::cargarCanasta(self::CANASTAS_PATH . $nombre);
|
try {
|
||||||
|
CanastaHelper::cargarCanasta(storage_path(self::CANASTAS_PATH . $nombre));
|
||||||
|
} catch (Exception $e) {
|
||||||
|
return response()->json(['message' => $e->getMessage()], 500);
|
||||||
|
}
|
||||||
|
|
||||||
return response()->json([
|
return response()->json([
|
||||||
'message' => 'Canasta cargada exitosamente',
|
'message' => 'Canasta cargada exitosamente',
|
||||||
|
@ -64,7 +77,31 @@ class ComisionesController
|
||||||
|
|
||||||
public function descargarCanastaEjemplo(): BinaryFileResponse
|
public function descargarCanastaEjemplo(): BinaryFileResponse
|
||||||
{
|
{
|
||||||
$file = storage_path('csv/productos.csv');
|
$file = resource_path('csv/productos.csv');
|
||||||
return response()->download($file);
|
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();
|
||||||
|
|
||||||
|
try {
|
||||||
|
$records = CsvHelper::getRecords($file, "No se pudo leer el archivo.");
|
||||||
|
} catch (Exception $e) {
|
||||||
|
return response()->json(['message' => $e->getMessage()], 500);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($records as $record) {
|
||||||
|
$barrio = $record[self::BARRIO];
|
||||||
|
$saldo = $record[self::SALDO];
|
||||||
|
GrupoDeCompra::where('nombre', $barrio)
|
||||||
|
->update(['saldo' => $saldo]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return response()->json(GrupoDeCompraResource::collection(GrupoDeCompra::all()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
namespace App\Http\Controllers;
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
use App\GrupoDeCompra;
|
use App\GrupoDeCompra;
|
||||||
use App\Http\Resources\GrupoDeCompraReducido;
|
use App\Http\Resources\GrupoDeCompraPedidoResource;
|
||||||
use App\Http\Resources\GrupoDeCompraResource;
|
use App\Http\Resources\GrupoDeCompraResource;
|
||||||
use App\UserRole;
|
use App\UserRole;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
@ -22,7 +22,7 @@ class UserController extends Controller
|
||||||
$grupo_de_compra = GrupoDeCompra::find($user->grupo_de_compra_id);
|
$grupo_de_compra = GrupoDeCompra::find($user->grupo_de_compra_id);
|
||||||
switch (UserRole::findOrFail($user->role_id)->nombre) {
|
switch (UserRole::findOrFail($user->role_id)->nombre) {
|
||||||
case 'barrio':
|
case 'barrio':
|
||||||
$result['grupo_de_compra'] = new GrupoDeCompraReducido($grupo_de_compra);
|
$result['grupo_de_compra'] = new GrupoDeCompraPedidoResource($grupo_de_compra);
|
||||||
break;
|
break;
|
||||||
case 'admin_barrio':
|
case 'admin_barrio':
|
||||||
$result['grupo_de_compra'] = new GrupoDeCompraResource($grupo_de_compra);
|
$result['grupo_de_compra'] = new GrupoDeCompraResource($grupo_de_compra);
|
||||||
|
|
22
app/Http/Resources/GrupoDeCompraComisionesResource.php
Normal file
22
app/Http/Resources/GrupoDeCompraComisionesResource.php
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Resources;
|
||||||
|
|
||||||
|
use Illuminate\Http\Resources\Json\JsonResource;
|
||||||
|
|
||||||
|
class GrupoDeCompraComisionesResource extends JsonResource
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Transform the resource into an array.
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Http\Request $request
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function toArray($request): array {
|
||||||
|
return [
|
||||||
|
'id' => $this->id,
|
||||||
|
'nombre' => $this->nombre,
|
||||||
|
'saldo' => $this->saldo,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,7 +4,7 @@ namespace App\Http\Resources;
|
||||||
|
|
||||||
use Illuminate\Http\Resources\Json\JsonResource;
|
use Illuminate\Http\Resources\Json\JsonResource;
|
||||||
|
|
||||||
class GrupoDeCompraReducido extends JsonResource
|
class GrupoDeCompraPedidoResource extends JsonResource
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Transform the resource into an array.
|
* Transform the resource into an array.
|
|
@ -21,9 +21,11 @@ class GrupoDeCompraResource extends JsonResource
|
||||||
'devoluciones_habilitadas' => $this->devoluciones_habilitadas,
|
'devoluciones_habilitadas' => $this->devoluciones_habilitadas,
|
||||||
'pedidos' => SubpedidoResource::collection($this->subpedidos),
|
'pedidos' => SubpedidoResource::collection($this->subpedidos),
|
||||||
'total_a_recaudar' => number_format($this->totalARecaudar(),2),
|
'total_a_recaudar' => number_format($this->totalARecaudar(),2),
|
||||||
|
'saldo' => number_format($this->saldo, 2, ".", ""),
|
||||||
'total_sin_devoluciones' => number_format($this->totalSinDevoluciones(),2),
|
'total_sin_devoluciones' => number_format($this->totalSinDevoluciones(),2),
|
||||||
'total_barrial' => number_format($this->totalBarrial(),2),
|
'total_barrial' => number_format($this->totalBarrial(),2),
|
||||||
'total_devoluciones' => number_format($this->totalDevoluciones(),2),
|
'total_devoluciones' => number_format($this->totalDevoluciones(),2),
|
||||||
|
'total_de_pedido' => number_format($this->totalDePedido(),2),
|
||||||
'total_a_transferir' => number_format($this->totalATransferir(),2),
|
'total_a_transferir' => number_format($this->totalATransferir(),2),
|
||||||
'total_transporte' => number_format($this->totalTransporte()),
|
'total_transporte' => number_format($this->totalTransporte()),
|
||||||
'cantidad_transporte' => number_format($this->cantidadTransporte()),
|
'cantidad_transporte' => number_format($this->cantidadTransporte()),
|
||||||
|
|
|
@ -11,6 +11,7 @@ use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use League\Csv\Exception;
|
||||||
|
|
||||||
class Producto extends Model
|
class Producto extends Model
|
||||||
{
|
{
|
||||||
|
@ -75,6 +76,9 @@ class Producto extends Model
|
||||||
->get();
|
->get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
static public function planillaTotales()
|
static public function planillaTotales()
|
||||||
{
|
{
|
||||||
$headers = ['Producto'];
|
$headers = ['Producto'];
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
class AgregarSaldosABarrios extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
// Agregar columna 'saldo' a la tabla 'grupos_de_compra'
|
||||||
|
Schema::table('grupos_de_compra', function (Blueprint $table) {
|
||||||
|
$table->double('saldo', 10, 2)->default(0);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
// Remover columna 'saldo' de la tabla 'grupos_de_compra'
|
||||||
|
Schema::table('grupos_de_compra', function (Blueprint $table) {
|
||||||
|
$table->dropColumn('saldo');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -11,9 +11,10 @@ class CanastaSeeder extends Seeder
|
||||||
* Run the database seeds.
|
* Run the database seeds.
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
|
* @throws \League\Csv\Exception
|
||||||
*/
|
*/
|
||||||
public function run()
|
public function run()
|
||||||
{
|
{
|
||||||
CanastaHelper::cargarCanasta(self::ARCHIVO_DEFAULT);
|
CanastaHelper::cargarCanasta(resource_path(self::ARCHIVO_DEFAULT));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,10 +13,11 @@ class GrupoDeCompraSeeder extends Seeder
|
||||||
* Run the database seeds.
|
* Run the database seeds.
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
|
* @throws \League\Csv\Exception
|
||||||
*/
|
*/
|
||||||
public function run()
|
public function run()
|
||||||
{
|
{
|
||||||
$registros = CsvHelper::getRecords('csv/barrios.csv');
|
$registros = CsvHelper::getRecords(resource_path('csv/barrios.csv'), 'No se pudo leer la planilla de barrios.');
|
||||||
$gdcToInsert = [];
|
$gdcToInsert = [];
|
||||||
$usersToInsert = [];
|
$usersToInsert = [];
|
||||||
$roles = UserRole::where('nombre', 'barrio')->orWhere('nombre', 'admin_barrio')->get();
|
$roles = UserRole::where('nombre', 'barrio')->orWhere('nombre', 'admin_barrio')->get();
|
||||||
|
|
|
@ -43,7 +43,15 @@
|
||||||
<td class="has-text-right">$ {{ total_transporte }}</td>
|
<td class="has-text-right">$ {{ total_transporte }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Total a depositar:</th>
|
<th>Total de pedido:</th>
|
||||||
|
<td class="has-text-right">$ {{ total_de_pedido }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>Saldo a favor:</th>
|
||||||
|
<td class="has-text-right">- $ {{ saldo }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>Total a transferir:</th>
|
||||||
<td class="has-text-right">$ {{ total_a_transferir }}</td>
|
<td class="has-text-right">$ {{ total_a_transferir }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
@ -67,7 +75,9 @@ export default {
|
||||||
"total_devoluciones",
|
"total_devoluciones",
|
||||||
"cantidad_transporte",
|
"cantidad_transporte",
|
||||||
"total_transporte",
|
"total_transporte",
|
||||||
|
"total_de_pedido",
|
||||||
"total_a_transferir",
|
"total_a_transferir",
|
||||||
|
"saldo",
|
||||||
]),
|
]),
|
||||||
...mapGetters('admin', ['pedidosAprobados']),
|
...mapGetters('admin', ['pedidosAprobados']),
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,44 +1,22 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="block ml-3 mr-3 is-max-widescreen is-max-desktop">
|
<div class="block ml-3 mr-3 is-max-widescreen is-max-desktop">
|
||||||
<comunes-tabs-secciones :tabs="tabs" :tabInicial="tabActiva"></comunes-tabs-secciones>
|
<tabs-secciones :tabs="tabs" :tabInicial="tabActiva"/>
|
||||||
<div class="block pb-6" id="pedidos-comisiones-seccion"
|
<div class="block pb-6"
|
||||||
|
id="pedidos-comisiones-seccion"
|
||||||
:class="seccionActiva === 'pedidos-comisiones-seccion' ? 'is-active' : 'is-hidden'">
|
:class="seccionActiva === 'pedidos-comisiones-seccion' ? 'is-active' : 'is-hidden'">
|
||||||
<div class="block" id="pedidos-comisiones-tabla-y-dropdown">
|
<div class="block" id="pedidos-comisiones-tabla-y-dropdown">
|
||||||
<dropdown-descargar/>
|
<dropdown-descargar/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="block pb-6" id="canasta-comisiones-seccion"
|
<div class="block pb-6"
|
||||||
|
id="canasta-comisiones-seccion"
|
||||||
:class="seccionActiva === 'canasta-comisiones-seccion' ? 'is-active' : 'is-hidden'">
|
:class="seccionActiva === 'canasta-comisiones-seccion' ? 'is-active' : 'is-hidden'">
|
||||||
<div class="block" id="canasta-comisiones-seccion">
|
<canasta-seccion/>
|
||||||
<article class="message is-warning">
|
</div>
|
||||||
<div class="message-header">
|
<div class="block pb-6"
|
||||||
<p>Formato de la canasta</p>
|
id="saldos-comisiones-seccion"
|
||||||
</div>
|
:class="seccionActiva === 'saldos-comisiones-seccion' ? 'is-active' : 'is-hidden'">
|
||||||
<div class="message-body">
|
<saldos-seccion/>
|
||||||
<div class="content">
|
|
||||||
La planilla de la canasta tiene que tener el siguiente formato para que la aplicación la lea correctamente:
|
|
||||||
<ul>
|
|
||||||
<li> Los precios deben usar punto y no coma decimal </li>
|
|
||||||
<li> El nombre de las columnas deben ser "Tipo", "Producto", y "Precio" respectivamente </li>
|
|
||||||
<li> Las celdas deben separarse con '|' </li>
|
|
||||||
<li> No puede haber "enters" en ninguna celda </li>
|
|
||||||
<li> El bono de transporte debe tener tipo 'T' </li>
|
|
||||||
</ul>
|
|
||||||
<a class="has-text-info" href="/comisiones/canasta/ejemplo">Planilla de ejemplo.</a>
|
|
||||||
<article class="message is-danger mt-2">
|
|
||||||
<div class="message-body">
|
|
||||||
<div class="content">
|
|
||||||
Cuidado! Cargar una nueva canasta elimina todos los pedidos de la aplicación.
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</article>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</article>
|
|
||||||
<div class="buttons is-right">
|
|
||||||
<canasta-input/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -46,22 +24,29 @@
|
||||||
<script>
|
<script>
|
||||||
import TabsSecciones from "../comunes/TabsSecciones.vue";
|
import TabsSecciones from "../comunes/TabsSecciones.vue";
|
||||||
import DropdownDescargar from "./DropdownDescargar.vue";
|
import DropdownDescargar from "./DropdownDescargar.vue";
|
||||||
import CanastaInput from "./CanastaInput.vue";
|
import InputFileButton from "../comunes/InputFileButton.vue";
|
||||||
|
import CanastaSeccion from "./canasta/CanastaSeccion.vue";
|
||||||
|
import SaldosSeccion from "./saldos/SaldosSeccion.vue";
|
||||||
|
import { mapActions } from "vuex";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "ComisionesBody",
|
name: "ComisionesBody",
|
||||||
components: {
|
components: {
|
||||||
|
SaldosSeccion,
|
||||||
|
CanastaSeccion,
|
||||||
TabsSecciones,
|
TabsSecciones,
|
||||||
DropdownDescargar,
|
DropdownDescargar,
|
||||||
CanastaInput,
|
InputFileButton,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
tabs: [{ id: "pedidos-comisiones", nombre: "Pedidos" },
|
tabs: [
|
||||||
{ id: "canasta-comisiones", nombre: "Canasta" }],
|
{ id: "pedidos-comisiones", nombre: "Pedidos" },
|
||||||
|
{ id: "canasta-comisiones", nombre: "Canasta" },
|
||||||
|
{ id: "saldos-comisiones", nombre: "Saldos" },
|
||||||
|
],
|
||||||
tabActiva: "pedidos-comisiones",
|
tabActiva: "pedidos-comisiones",
|
||||||
seccionActiva: "pedidos-comisiones-seccion",
|
seccionActiva: "pedidos-comisiones-seccion",
|
||||||
archivo: undefined,
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
@ -69,6 +54,6 @@ export default {
|
||||||
this.tabActiva = tabId;
|
this.tabActiva = tabId;
|
||||||
this.seccionActiva = tabId + "-seccion";
|
this.seccionActiva = tabId + "-seccion";
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
<script>
|
||||||
|
import { defineComponent } from "vue";
|
||||||
|
import CanastaInput from "./CanastaInput.vue";
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
components: { CanastaInput },
|
||||||
|
name: "CanastaSeccion",
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<article class="message is-warning">
|
||||||
|
<div class="message-header">
|
||||||
|
<p>Formato de la canasta</p>
|
||||||
|
</div>
|
||||||
|
<div class="message-body">
|
||||||
|
<div class="content">
|
||||||
|
La planilla de la canasta tiene que tener el siguiente formato para que la aplicación la lea correctamente:
|
||||||
|
<ul>
|
||||||
|
<li> Los precios deben usar punto y no coma decimal </li>
|
||||||
|
<li> El nombre de las columnas deben ser "Tipo", "Producto", y "Precio" respectivamente </li>
|
||||||
|
<li> Las celdas deben separarse con '|' </li>
|
||||||
|
<li> No puede haber "enters" en ninguna celda </li>
|
||||||
|
<li> El bono de transporte debe tener tipo 'T' </li>
|
||||||
|
</ul>
|
||||||
|
<a class="has-text-info" href="/comisiones/canasta/ejemplo">Planilla de ejemplo.</a>
|
||||||
|
<article class="message is-danger mt-2">
|
||||||
|
<div class="message-body">
|
||||||
|
<div class="content">
|
||||||
|
Cuidado! Cargar una nueva canasta elimina todos los pedidos de la aplicación.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
<div class="buttons">
|
||||||
|
<canasta-input/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
71
resources/js/components/comisiones/saldos/SaldoRow.vue
Normal file
71
resources/js/components/comisiones/saldos/SaldoRow.vue
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
<script>
|
||||||
|
import { mapActions, mapGetters, mapState } from "vuex";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "SaldoRow",
|
||||||
|
props: {
|
||||||
|
grupo_de_compra: {
|
||||||
|
type: Object,
|
||||||
|
required: true,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
saldoControl: 0,
|
||||||
|
inputSaldoInteractuado: false,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.saldoControl = this.grupo_de_compra.saldo;
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
lastFetch() {
|
||||||
|
this.saldoControl = this.grupo_de_compra.saldo;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
...mapActions("comisiones", ["setSaldo"]),
|
||||||
|
async confirmarSaldo() {
|
||||||
|
await this.setSaldo({
|
||||||
|
gdc_id: this.grupo_de_compra.id,
|
||||||
|
saldo: this.saldoControl,
|
||||||
|
});
|
||||||
|
this.inputSaldoInteractuado = false;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...mapState("comisiones", ["lastFetch"]),
|
||||||
|
...mapGetters("comisiones", ["saldo"]),
|
||||||
|
saldoModificado() {
|
||||||
|
return Number.parseFloat(this.saldo(this.grupo_de_compra.id)) !== Number.parseFloat(this.saldoControl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<tr>
|
||||||
|
<th>{{ grupo_de_compra.nombre }}</th>
|
||||||
|
<td>
|
||||||
|
<input :id="`saldo-input-${grupo_de_compra.id}`"
|
||||||
|
v-model="saldoControl"
|
||||||
|
class="input is-small"
|
||||||
|
type="number"
|
||||||
|
style="text-align: center"
|
||||||
|
@input="inputSaldoInteractuado = true">
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<button :disabled="!(inputSaldoInteractuado && saldoModificado)"
|
||||||
|
class="button is-small is-success ml-1"
|
||||||
|
@click="confirmarSaldo">
|
||||||
|
<span class="icon">
|
||||||
|
<i class="fas fa-check"/>
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
76
resources/js/components/comisiones/saldos/SaldosSeccion.vue
Normal file
76
resources/js/components/comisiones/saldos/SaldosSeccion.vue
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
<script>
|
||||||
|
import InputFileButton from "../../comunes/InputFileButton.vue";
|
||||||
|
import { mapActions } from "vuex";
|
||||||
|
import TablaSaldos from "./TablaSaldos.vue";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "SaldosSeccion",
|
||||||
|
components: { TablaSaldos, InputFileButton },
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
archivo: undefined,
|
||||||
|
show_saldos_file_dialog: true,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
...mapActions('ui',["toast"]),
|
||||||
|
...mapActions('comisiones', ['cargarSaldos']),
|
||||||
|
async archivoSubido(event) {
|
||||||
|
event.component.cargando = true;
|
||||||
|
const formData = new FormData();
|
||||||
|
formData.append('data',event.archivo);
|
||||||
|
await this.cargarSaldos(formData);
|
||||||
|
event.component.cargando = false;
|
||||||
|
},
|
||||||
|
toggleSaldosFileDialog() {
|
||||||
|
this.show_saldos_file_dialog = !this.show_saldos_file_dialog;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</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án configurados en esta aplicacaión</li>
|
||||||
|
</ul>
|
||||||
|
<article class="message is-danger mt-2">
|
||||||
|
<div class="message-body">
|
||||||
|
<div class="content">
|
||||||
|
Al cargar un archivo, se reemplazaran los saldos de los barrios que éste contenga, el resto quedará sin cambiar.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
</div>
|
||||||
|
<input-file-button text="Subir archivo" @archivo-subido="archivoSubido" />
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
</div>
|
||||||
|
<div class="column">
|
||||||
|
<tabla-saldos/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
</style>
|
38
resources/js/components/comisiones/saldos/TablaSaldos.vue
Normal file
38
resources/js/components/comisiones/saldos/TablaSaldos.vue
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
<script>
|
||||||
|
import { mapActions, mapState } from "vuex";
|
||||||
|
import SaldoRow from "./SaldoRow.vue";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "TablaSaldos",
|
||||||
|
components: { SaldoRow },
|
||||||
|
async mounted() {
|
||||||
|
await this.getGruposDeCompra();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
...mapActions("comisiones", ["getGruposDeCompra"]),
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...mapState("comisiones", ["grupos_de_compra"]),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<table class="table container">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Barrio</th>
|
||||||
|
<th>Saldo</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<saldo-row v-for="(gdc,index) in grupos_de_compra"
|
||||||
|
:grupo_de_compra="gdc"
|
||||||
|
:key="index"/>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
56
resources/js/components/comunes/InputFileButton.vue
Normal file
56
resources/js/components/comunes/InputFileButton.vue
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
<template>
|
||||||
|
<div class="file has-name">
|
||||||
|
<label class="file-label">
|
||||||
|
<input
|
||||||
|
class="file-input"
|
||||||
|
type="file"
|
||||||
|
name="canasta"
|
||||||
|
@change="archivoSubido"
|
||||||
|
/>
|
||||||
|
<span class="file-cta">
|
||||||
|
<span class="file-icon">
|
||||||
|
<i class="fas fa-cloud-upload-alt"></i>
|
||||||
|
</span>
|
||||||
|
<span class="file-label">{{ text }}</span>
|
||||||
|
</span>
|
||||||
|
<span class="file-name" v-if="cargando">
|
||||||
|
{{ 'Cargando ' + archivo.nombre }}
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "InputFileButton",
|
||||||
|
props: {
|
||||||
|
text: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
archivo: null,
|
||||||
|
cargando: false,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
archivoSubido(event) {
|
||||||
|
const archivo = event.target.files[0];
|
||||||
|
if (archivo) {
|
||||||
|
this.archivo = { data: archivo, nombre: archivo.name };
|
||||||
|
this.$emit("archivo-subido", {
|
||||||
|
component: this,
|
||||||
|
archivo: archivo
|
||||||
|
});
|
||||||
|
this.cargando = true;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<div id="pedidos-body">
|
<div id="pedidos-body" class="pb-6 mb-6">
|
||||||
<pedido-select v-if="!pedidoDefinido"/>
|
<pedido-select v-if="!pedidoDefinido"/>
|
||||||
<div v-else>
|
<div v-else>
|
||||||
<nav-migas/>
|
<nav-migas/>
|
||||||
|
|
2
resources/js/store/index.js
vendored
2
resources/js/store/index.js
vendored
|
@ -1,6 +1,7 @@
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
import Vuex from 'vuex';
|
import Vuex from 'vuex';
|
||||||
import admin from "./modules/admin";
|
import admin from "./modules/admin";
|
||||||
|
import comisiones from "./modules/comisiones";
|
||||||
import login from "./modules/login";
|
import login from "./modules/login";
|
||||||
import pedido from "./modules/pedido";
|
import pedido from "./modules/pedido";
|
||||||
import productos from "./modules/productos";
|
import productos from "./modules/productos";
|
||||||
|
@ -11,6 +12,7 @@ Vue.use(Vuex);
|
||||||
export default new Vuex.Store({
|
export default new Vuex.Store({
|
||||||
modules: {
|
modules: {
|
||||||
admin,
|
admin,
|
||||||
|
comisiones,
|
||||||
login,
|
login,
|
||||||
pedido,
|
pedido,
|
||||||
productos,
|
productos,
|
||||||
|
|
4
resources/js/store/modules/admin.js
vendored
4
resources/js/store/modules/admin.js
vendored
|
@ -10,9 +10,11 @@ const state = {
|
||||||
total_sin_devoluciones: null,
|
total_sin_devoluciones: null,
|
||||||
total_barrial: null,
|
total_barrial: null,
|
||||||
total_devoluciones: null,
|
total_devoluciones: null,
|
||||||
|
total_de_pedido: null,
|
||||||
total_a_transferir: null,
|
total_a_transferir: null,
|
||||||
total_transporte: null,
|
total_transporte: null,
|
||||||
cantidad_transporte: null,
|
cantidad_transporte: null,
|
||||||
|
saldo: null,
|
||||||
};
|
};
|
||||||
|
|
||||||
const mutations = {
|
const mutations = {
|
||||||
|
@ -26,9 +28,11 @@ const mutations = {
|
||||||
state.total_sin_devoluciones = grupo_de_compra.total_sin_devoluciones;
|
state.total_sin_devoluciones = grupo_de_compra.total_sin_devoluciones;
|
||||||
state.total_barrial = grupo_de_compra.total_barrial;
|
state.total_barrial = grupo_de_compra.total_barrial;
|
||||||
state.total_devoluciones = grupo_de_compra.total_devoluciones;
|
state.total_devoluciones = grupo_de_compra.total_devoluciones;
|
||||||
|
state.total_de_pedido = grupo_de_compra.total_de_pedido;
|
||||||
state.total_a_transferir = grupo_de_compra.total_a_transferir;
|
state.total_a_transferir = grupo_de_compra.total_a_transferir;
|
||||||
state.total_transporte = grupo_de_compra.total_transporte;
|
state.total_transporte = grupo_de_compra.total_transporte;
|
||||||
state.cantidad_transporte = grupo_de_compra.cantidad_transporte;
|
state.cantidad_transporte = grupo_de_compra.cantidad_transporte;
|
||||||
|
state.saldo = grupo_de_compra.saldo;
|
||||||
},
|
},
|
||||||
toggleCaracteristica(state, { caracteristica_id }) {
|
toggleCaracteristica(state, { caracteristica_id }) {
|
||||||
state[`${caracteristica_id}_habilitadas`] = !state[`${caracteristica_id}_habilitadas`];
|
state[`${caracteristica_id}_habilitadas`] = !state[`${caracteristica_id}_habilitadas`];
|
||||||
|
|
65
resources/js/store/modules/comisiones.js
vendored
Normal file
65
resources/js/store/modules/comisiones.js
vendored
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
import axios from "axios";
|
||||||
|
|
||||||
|
const state = {
|
||||||
|
lastFetch: undefined,
|
||||||
|
grupos_de_compra: [],
|
||||||
|
};
|
||||||
|
|
||||||
|
const mutations = {
|
||||||
|
setGruposDeCompra(state, { data }) {
|
||||||
|
state.grupos_de_compra = data;
|
||||||
|
state.lastFetch = new Date();
|
||||||
|
},
|
||||||
|
setSaldo(state, { gdc_id, saldo }) {
|
||||||
|
const barrio = state.grupos_de_compra.find(gdc => gdc.id === gdc_id);
|
||||||
|
const i = state.grupos_de_compra.indexOf(barrio);
|
||||||
|
state.grupos_de_compra[i].saldo = saldo;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const actions = {
|
||||||
|
async getGruposDeCompra({ commit }) {
|
||||||
|
const response = await axios.get('/api/grupos-de-compra/saldos');
|
||||||
|
commit('setGruposDeCompra', response.data);
|
||||||
|
},
|
||||||
|
async setSaldo({ commit, dispatch }, { gdc_id, saldo }) {
|
||||||
|
try {
|
||||||
|
await axios.post(
|
||||||
|
"api/grupos-de-compra/" + gdc_id + "/saldo",
|
||||||
|
{ saldo: saldo }
|
||||||
|
);
|
||||||
|
commit('setSaldo', { gdc_id: gdc_id, saldo: saldo });
|
||||||
|
dispatch("ui/toast", { mensaje: 'Saldo modificado con éxito' }, { root: true });
|
||||||
|
} catch (error) {
|
||||||
|
dispatch("ui/error", { error: error }, { root: true });
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async cargarSaldos({ commit, dispatch }, formData) {
|
||||||
|
try {
|
||||||
|
const response = await axios.post("/comisiones/saldos", formData, {
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "multipart/form-data",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
commit('setGruposDeCompra', response);
|
||||||
|
dispatch("ui/toast", { mensaje: 'Saldos cargados con éxito' }, { root: true });
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
dispatch("ui/error", { error: error }, { root: true });
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const getters = {
|
||||||
|
saldo() {
|
||||||
|
return (gdc_id) => state.grupos_de_compra.find(gdc => gdc.id === gdc_id)?.saldo ?? 0;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default {
|
||||||
|
namespaced: true,
|
||||||
|
state,
|
||||||
|
mutations,
|
||||||
|
actions,
|
||||||
|
getters,
|
||||||
|
};
|
|
@ -20,8 +20,11 @@ Route::middleware('api')->group(function() {
|
||||||
Route::get('/canasta-actual', 'Api\CanastaController@canastaActual');
|
Route::get('/canasta-actual', 'Api\CanastaController@canastaActual');
|
||||||
|
|
||||||
Route::prefix('grupos-de-compra')->group(function() {
|
Route::prefix('grupos-de-compra')->group(function() {
|
||||||
|
Route::get('/', 'Api\GrupoDeCompraController@index');
|
||||||
|
Route::get('/saldos','Api\GrupoDeCompraController@saldos');
|
||||||
Route::get('/{grupoDeCompra}', 'Api\GrupoDeCompraController@show');
|
Route::get('/{grupoDeCompra}', 'Api\GrupoDeCompraController@show');
|
||||||
Route::post('/{gdc}/devoluciones', 'Api\GrupoDeCompraController@toggleDevoluciones');
|
Route::post('/{gdc}/devoluciones', 'Api\GrupoDeCompraController@toggleDevoluciones');
|
||||||
|
Route::post('/{gdc}/saldo', 'Api\GrupoDeCompraController@setSaldo');
|
||||||
});
|
});
|
||||||
|
|
||||||
Route::prefix('subpedidos')->group(function () {
|
Route::prefix('subpedidos')->group(function () {
|
||||||
|
|
|
@ -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/pedidos/pdf', 'ComisionesController@pdf')->name('comisiones.pedidos.pdf');
|
||||||
Route::get('/comisiones/canasta/ejemplo', 'ComisionesController@descargarCanastaEjemplo')->name('comisiones.canasta.ejemplo');
|
Route::get('/comisiones/canasta/ejemplo', 'ComisionesController@descargarCanastaEjemplo')->name('comisiones.canasta.ejemplo');
|
||||||
Route::post('/comisiones/canasta', 'ComisionesController@cargarCanasta')->name('comisiones.canasta');
|
Route::post('/comisiones/canasta', 'ComisionesController@cargarCanasta')->name('comisiones.canasta');
|
||||||
|
Route::post('/comisiones/saldos', 'ComisionesController@cargarSaldos')->name('comisiones.saldos');
|
||||||
});
|
});
|
||||||
|
|
1
run_watch.sh
Executable file
1
run_watch.sh
Executable file
|
@ -0,0 +1 @@
|
||||||
|
sudo docker compose exec app npm run watch
|
Loading…
Add table
Reference in a new issue