Merge pull request 'funcion/pedido-ollas' (#47) from funcion/pedido-ollas into master
Reviewed-on: #47 Reviewed-by: Rodrigo <rodrigopdm@protonmail.com>
This commit is contained in:
commit
45a7688fbd
60 changed files with 1652 additions and 465 deletions
|
@ -46,17 +46,24 @@ class Filtro extends Model
|
|||
//Obtener nombre del método (snake_case a camelCase)
|
||||
$metodo = str_replace('_', '', lcfirst(ucwords($filtro, '_')));
|
||||
|
||||
if(!method_exists($this, $metodo)) { continue; }
|
||||
if (!method_exists($this, $metodo))
|
||||
continue;
|
||||
|
||||
//Llamar métodos sin argumentos
|
||||
if ($valor === null|| (is_a($valor,'String') && trim($valor)=='')){ $this->$metodo(); continue; }
|
||||
if ($valor === null || (is_a($valor,'String') && trim($valor)=='')) {
|
||||
$this->$metodo();
|
||||
continue;
|
||||
}
|
||||
|
||||
//Llamar métodos con argumentos
|
||||
try {
|
||||
$this->$metodo($valor);
|
||||
} catch (Throwable $th) {
|
||||
if (is_a($th,'TypeError') ) { throw new HttpException(400, sprintf($this->MENSAJES_ERROR['ARGUMENTO'],$filtro)); }
|
||||
throw $th;
|
||||
} catch (Throwable $error) {
|
||||
if (is_a($error,'TypeError')) {
|
||||
$mensaje = sprintf($this->MENSAJES_ERROR['ARGUMENTO'], $filtro);
|
||||
throw new HttpException(400, $mensaje);
|
||||
}
|
||||
throw $error;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -66,12 +73,16 @@ class Filtro extends Model
|
|||
//Buscar un término en el nombre
|
||||
public function nombre(String $valor)
|
||||
{
|
||||
$this->builder->where('nombre', "LIKE", "%" . $valor . "%")->orderByRaw("IF(nombre = '$valor',2,IF(nombre LIKE '$valor%',1,0)) DESC");
|
||||
$this->builder
|
||||
->where('nombre', "LIKE", "%" . $valor . "%")
|
||||
->orderByRaw("IF(nombre = '$valor',2,IF(nombre LIKE '$valor%',1,0)) DESC");
|
||||
}
|
||||
|
||||
public function alfabetico(String $order = 'asc')
|
||||
{
|
||||
if(!in_array($order,['asc','desc'])) { throw new TypeError(); }
|
||||
if (!in_array($order,['asc','desc']))
|
||||
throw new TypeError();
|
||||
|
||||
$this->builder->orderBy('nombre', $order);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,17 @@ class FiltroDeSubpedido extends Filtro
|
|||
{
|
||||
public function grupoDeCompra(String $valor)
|
||||
{
|
||||
if (!is_numeric($valor)) { throw new TypeError();}
|
||||
if (!is_numeric($valor))
|
||||
throw new TypeError();
|
||||
|
||||
$this->builder->where('grupo_de_compra_id', intval($valor));
|
||||
}
|
||||
|
||||
public function tipoPedido(String $valor)
|
||||
{
|
||||
if (!is_numeric($valor))
|
||||
throw new TypeError();
|
||||
|
||||
$this->builder->where('tipo_pedido_id', intval($valor));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ use Illuminate\Support\Collection;
|
|||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use League\Csv\Exception;
|
||||
use Mpdf\MpdfException;
|
||||
|
||||
class GrupoDeCompra extends Model
|
||||
{
|
||||
|
@ -23,6 +24,11 @@ class GrupoDeCompra extends Model
|
|||
return $this->hasMany(Subpedido::class);
|
||||
}
|
||||
|
||||
public function users(): HasMany
|
||||
{
|
||||
return $this->hasMany(User::class);
|
||||
}
|
||||
|
||||
public function toggleDevoluciones(): bool
|
||||
{
|
||||
$this->devoluciones_habilitadas = !$this->devoluciones_habilitadas;
|
||||
|
@ -32,7 +38,14 @@ class GrupoDeCompra extends Model
|
|||
|
||||
public function pedidosAprobados()
|
||||
{
|
||||
return $this->subpedidos->where('aprobado', 1);
|
||||
return $this->pedidosHogares()
|
||||
->where('aprobado', 1);
|
||||
}
|
||||
|
||||
public function pedidosHogares()
|
||||
{
|
||||
return $this->subpedidos
|
||||
->where('tipo_pedido_id', '=', 1);
|
||||
}
|
||||
|
||||
public function totalARecaudar()
|
||||
|
@ -115,11 +128,15 @@ class GrupoDeCompra extends Model
|
|||
return TransporteHelper::cantidadTransporte($this->totalCentralesQuePaganTransporte());
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws MpdfException
|
||||
*/
|
||||
public function exportarPedidosAPdf()
|
||||
{
|
||||
$subpedidos = $this->pedidosAprobados();
|
||||
$fecha = now()->format('Y-m-d');
|
||||
PdfHelper::exportarPedidos($this->nombre . '-' . $fecha . '.pdf', $subpedidos);
|
||||
$filepath = $this->nombre . '-' . $fecha . '.pdf';
|
||||
PdfHelper::exportarPedidos($filepath, $subpedidos);
|
||||
}
|
||||
|
||||
function pedidoParaPdf(): array
|
||||
|
@ -149,126 +166,15 @@ class GrupoDeCompra extends Model
|
|||
return $view->render();
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws MpdfException
|
||||
*/
|
||||
public static function exportarPedidosBarrialesAPdf()
|
||||
{
|
||||
$barrios = GrupoDeCompra::barriosMenosPrueba()->get();
|
||||
$fecha = now()->format('Y-m-d');
|
||||
PdfHelper::exportarPedidos('pedidos_por_barrio-' . $fecha . '.pdf', $barrios);
|
||||
}
|
||||
|
||||
static function filaVacia(string $product, int $columns): array
|
||||
{
|
||||
$fila = [$product];
|
||||
for ($i = 1; $i <= $columns; $i++) {
|
||||
$fila[$i] = "0";
|
||||
}
|
||||
return $fila;
|
||||
}
|
||||
|
||||
//Asume que los productos están gruadados en orden de fila
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function obtenerTemplateDeFilasVacias(int $columns): array
|
||||
{
|
||||
$productosFilaID = Producto::productosFilaID();
|
||||
$productosIDNombre = Producto::productosIDNombre();
|
||||
$num_fila = 1;
|
||||
$template = [];
|
||||
foreach ($productosFilaID as $fila => $id) {
|
||||
for ($i = $num_fila; $i < $fila; $i++) {
|
||||
$template[$i] = GrupoDeCompra::filaVacia("", $columns);
|
||||
}
|
||||
$template[$fila] = GrupoDeCompra::filaVacia($productosIDNombre[$id], $columns);
|
||||
$num_fila = $fila + 1;
|
||||
}
|
||||
$template[TransporteHelper::filaTransporte()] = GrupoDeCompra::filaVacia("Bonos de transporte", $columns);
|
||||
return $template;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function exportarPedidoEnCSV()
|
||||
{
|
||||
$records = $this->generarColumnaCantidades();
|
||||
|
||||
$fecha = now()->format('Y-m-d');
|
||||
CsvHelper::generarCsv('csv/exports/' . $this->nombre . '-' . $fecha . '.csv', $records);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function generarColumnaCantidades(): array
|
||||
{
|
||||
$productos_en_pedido = $this->productosPedidos();
|
||||
|
||||
//si no hay pedidos aprobados, salir
|
||||
if ($productos_en_pedido->count() == 0) {
|
||||
Log::debug("El grupo de compra " . $this->nombre . " no tiene pedidos aprobados.");
|
||||
return [];
|
||||
}
|
||||
|
||||
$records = $this->obtenerTemplateDeFilasVacias(1);
|
||||
$productos_id_fila = Producto::productosIDFila();
|
||||
foreach ($productos_en_pedido as $id => $producto_pedido) {
|
||||
$fila = $productos_id_fila[$id];
|
||||
$records[$fila][1] = $producto_pedido->cantidad_pedida;
|
||||
}
|
||||
|
||||
$records[TransporteHelper::filaTransporte()][1] = $this->cantidadTransporte();
|
||||
|
||||
return $records;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function exportarPedidoConNucleosEnCSV()
|
||||
{
|
||||
$productos_en_pedido = $this->productosPedidos();
|
||||
|
||||
// si no hay pedidos aprobados, salir
|
||||
if ($productos_en_pedido->count() == 0) {
|
||||
Log::debug("El grupo de compra " . $this->nombre . " no tiene pedidos aprobados.");
|
||||
return;
|
||||
}
|
||||
|
||||
$pedidos = $this->pedidosAprobados();
|
||||
// Generar tabla vacía con una columna por núcleo
|
||||
$records = $this->obtenerTemplateDeFilasVacias($pedidos->count());
|
||||
$productos_id_fila = Producto::productosIDFila();
|
||||
|
||||
foreach ($productos_en_pedido as $id => $producto_pedido) {
|
||||
$fila = $productos_id_fila[$id];
|
||||
$i = 1;
|
||||
// Poner cantidad de cada producto para cada núcleo
|
||||
foreach ($pedidos as $pedido) {
|
||||
list($records, $i, $_) = $this->agregarCantidad($pedido, $id, $records, $fila, $i);
|
||||
}
|
||||
}
|
||||
// Insertar lista de núcleos en la primera fila
|
||||
$nucleos = [""];
|
||||
$i = 1;
|
||||
foreach ($pedidos as $pedido) {
|
||||
$nucleos[$i] = $pedido->nombre;
|
||||
$i++;
|
||||
}
|
||||
array_splice($records, 0, 0, array($nucleos));
|
||||
|
||||
$fecha = now()->format('Y-m-d');
|
||||
CsvHelper::generarCsv('csv/exports/' . $this->nombre . '-completo-' . $fecha . '.csv', $records);
|
||||
}
|
||||
|
||||
public function agregarCantidad($pedido, $id, array $records, $fila, int $i): array
|
||||
{
|
||||
$producto = $pedido->productos()->find($id);
|
||||
$cantidad = $producto == NULL ? 0 : $producto->pivot->cantidad;
|
||||
$records[$fila][$i] = $cantidad;
|
||||
$i++;
|
||||
return array($records, $i, $cantidad);
|
||||
$filepath = 'pedidos_por_barrio-' . $fecha . '.pdf';
|
||||
PdfHelper::exportarPedidos($filepath, $barrios);
|
||||
}
|
||||
|
||||
public static function barriosMenosPrueba(): Builder
|
||||
|
@ -278,18 +184,6 @@ class GrupoDeCompra extends Model
|
|||
->orderBy('nombre');
|
||||
}
|
||||
|
||||
public static function transportePorBarrio(): array
|
||||
{
|
||||
$result = [];
|
||||
$barrios = GrupoDeCompra::barriosMenosPrueba()->get();
|
||||
|
||||
foreach ($barrios as $barrio) {
|
||||
$result[] = $barrio->cantidadTransporte();
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function productosPedidos($excluirBonos = false, $orderBy = 'producto_nombre'): Collection
|
||||
{
|
||||
$query = DB::table('pedidos_aprobados')
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace App\Helpers;
|
||||
|
||||
use App\Http\Controllers\ComisionesController;
|
||||
use Illuminate\Support\Facades\File;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Iterator;
|
||||
|
@ -13,15 +14,13 @@ use League\Csv\Writer;
|
|||
|
||||
class CsvHelper
|
||||
{
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function getRecords($filePath, $message): Iterator {
|
||||
$csv = Reader::createFromPath($filePath);
|
||||
try {
|
||||
$csv->setDelimiter("|");
|
||||
$csv->setEnclosure("'");
|
||||
$csv->setHeaderOffset(0);
|
||||
$csv = self::getReader($filePath);
|
||||
return $csv->getRecords();
|
||||
} catch (InvalidArgument|Exception $e) {
|
||||
Log::error($e->getMessage());
|
||||
|
@ -29,20 +28,74 @@ class CsvHelper
|
|||
}
|
||||
}
|
||||
|
||||
public static function generarCsv($filePath, $contenido, $headers = null): void
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function cambiarParametro(string $id, string $valor): void
|
||||
{
|
||||
if (!File::exists(storage_path('csv/exports'))) {
|
||||
File::makeDirectory(storage_path('csv/exports'), 0755, true);
|
||||
}
|
||||
|
||||
try {
|
||||
$writer = Writer::createFromPath(storage_path($filePath), 'w');
|
||||
if ($headers) {
|
||||
$writer->insertOne($headers);
|
||||
$updated = false;
|
||||
$filePath = resource_path(ComisionesController::PARAMETROS_PATH);
|
||||
$csv = self::getReader($filePath);
|
||||
$headers = $csv->getHeader();
|
||||
$records = array_map(fn($r) => (array) $r, iterator_to_array($csv->getRecords()));
|
||||
|
||||
foreach ($records as &$record) {
|
||||
if ($record['id'] === $id) {
|
||||
$record['valor'] = $valor;
|
||||
$updated = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
$writer->insertAll($contenido);
|
||||
} catch (CannotInsertRecord $e) {
|
||||
Log::error($e->getMessage(), $e->getTrace());
|
||||
unset($record);
|
||||
|
||||
if (!$updated)
|
||||
throw new Exception("Parametro '{$id}' no encontrado.");
|
||||
|
||||
self::generarCsv($filePath, $records, $headers, "|", "'", false);
|
||||
} catch (CannotInsertRecord | InvalidArgument $e) {
|
||||
Log::error("Error al actualizar csv: " . $e->getMessage());
|
||||
throw new Exception("Error al actualizar csv", $e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws InvalidArgument
|
||||
* @throws CannotInsertRecord
|
||||
*/
|
||||
public static function generarCsv($filePath, $contenido, $headers = null, $delimiter = null, $enclosure = null, $export = true): void
|
||||
{
|
||||
$path = $filePath;
|
||||
|
||||
if ($export) {
|
||||
if (!File::exists(storage_path('csv/exports')))
|
||||
File::makeDirectory(storage_path('csv/exports'), 0755, true);
|
||||
$path = storage_path($filePath);
|
||||
}
|
||||
|
||||
$writer = Writer::createFromPath($path, 'w');
|
||||
if ($delimiter)
|
||||
$writer->setDelimiter($delimiter);
|
||||
if ($enclosure)
|
||||
$writer->setEnclosure($enclosure);
|
||||
if ($headers)
|
||||
$writer->insertOne($headers);
|
||||
|
||||
$writer->insertAll($contenido);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $filePath
|
||||
* @return Reader
|
||||
* @throws InvalidArgument
|
||||
* @throws Exception
|
||||
*/
|
||||
private static function getReader(string $filePath): Reader
|
||||
{
|
||||
$csv = Reader::createFromPath($filePath);
|
||||
$csv->setDelimiter("|");
|
||||
$csv->setEnclosure("'");
|
||||
$csv->setHeaderOffset(0);
|
||||
return $csv;
|
||||
}
|
||||
}
|
||||
|
|
244
app/Helpers/PedidosExportHelper.php
Normal file
244
app/Helpers/PedidosExportHelper.php
Normal file
|
@ -0,0 +1,244 @@
|
|||
<?php
|
||||
|
||||
namespace App\Helpers;
|
||||
|
||||
use App\GrupoDeCompra;
|
||||
use App\TipoPedido;
|
||||
use Closure;
|
||||
use Illuminate\Database\Query\Expression;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use League\Csv\CannotInsertRecord;
|
||||
use League\Csv\Exception;
|
||||
use League\Csv\InvalidArgument;
|
||||
|
||||
class PedidosExportHelper
|
||||
{
|
||||
/**
|
||||
* @throws InvalidArgument
|
||||
* @throws CannotInsertRecord
|
||||
* @throws Exception
|
||||
*/
|
||||
static public function pedidosBarriales()
|
||||
{
|
||||
$filePath = "csv/exports/pedidos-por-barrio-" . now()->format('Y-m-d') . ".csv";
|
||||
$barrios = GrupoDeCompra::barriosMenosPrueba()->get();
|
||||
self::exportarCSV(
|
||||
$filePath,
|
||||
$barrios,
|
||||
self::generarContenidoCSV(
|
||||
$barrios,
|
||||
fn ($grupoId) =>
|
||||
"subpedidos.grupo_de_compra_id = $grupoId
|
||||
AND subpedidos.aprobado = 1
|
||||
AND subpedidos.tipo_pedido_id = 1"
|
||||
)
|
||||
);
|
||||
}
|
||||
/**
|
||||
* @throws InvalidArgument
|
||||
* @throws CannotInsertRecord
|
||||
* @throws Exception
|
||||
*/
|
||||
static public function pedidosDeOllas()
|
||||
{
|
||||
$filePath = "csv/exports/pedidos-de-ollas-" . now()->format('Y-m-d') . ".csv";
|
||||
$barrios = GrupoDeCompra::barriosMenosPrueba()->get();
|
||||
|
||||
$contenido = self::generarContenidoCSV($barrios,
|
||||
fn($grupoId) => "subpedidos.grupo_de_compra_id = $grupoId
|
||||
AND subpedidos.tipo_pedido_id = 2");
|
||||
$ollas = self::cantidadDeOllasParaCSV($barrios, $contenido);
|
||||
|
||||
self::exportarCSV(
|
||||
$filePath,
|
||||
$barrios,
|
||||
$contenido->concat([$ollas])
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function cantidadDeOllasParaCSV(Collection $barrios, Collection $contenido)
|
||||
{
|
||||
$tipo_olla = TipoPedido::where('nombre', 'olla')->first()->id;
|
||||
|
||||
$parametros = collect(CsvHelper::getRecords(resource_path("csv/parametros.csv"), "No se pudo leer el archivo."));
|
||||
$fila = [
|
||||
"producto" => "Cantidad de ollas",
|
||||
"precio" => $parametros->where('id','monto-olla')->pluck('valor')->first(),
|
||||
"paga_transporte" => false,
|
||||
"fila" => $contenido->last()->fila + 1,
|
||||
];
|
||||
|
||||
foreach ($barrios as $barrio) {
|
||||
$pedido = $barrio->subpedidos()->where('tipo_pedido_id', $tipo_olla)->first();
|
||||
$fila[$barrio->nombre] = $pedido->cantidad_ollas;
|
||||
}
|
||||
|
||||
return (object) $fila;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws InvalidArgument
|
||||
* @throws CannotInsertRecord
|
||||
* @throws Exception
|
||||
*/
|
||||
static public function pedidoTotalDeBarrio(GrupoDeCompra $grupo)
|
||||
{
|
||||
$filePath = "csv/exports/" . $grupo->nombre . "-" . now()->format('Y-m-d') . ".csv";
|
||||
|
||||
$falsoBarrio = new GrupoDeCompra(['nombre' => 'Total']);
|
||||
$falsoBarrio->id = $grupo->id;
|
||||
$header = collect([$falsoBarrio]);
|
||||
|
||||
self::exportarCSV(
|
||||
$filePath,
|
||||
$header,
|
||||
self::generarContenidoCSV(
|
||||
$header,
|
||||
fn($grupoId) => "subpedidos.grupo_de_compra_id = $grupoId
|
||||
AND subpedidos.aprobado = 1"
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws InvalidArgument
|
||||
* @throws CannotInsertRecord
|
||||
* @throws Exception
|
||||
*/
|
||||
static public function pedidosDeBarrio(GrupoDeCompra $grupo)
|
||||
{
|
||||
$filePath = "csv/exports/" . $grupo->nombre . "-completo-" . now()->format('Y-m-d') . ".csv";
|
||||
$subpedidos = $grupo->subpedidos()->where('aprobado', true)->get();
|
||||
self::exportarCSV(
|
||||
$filePath,
|
||||
$subpedidos,
|
||||
self::generarContenidoCSV(
|
||||
$subpedidos,
|
||||
fn ($subpedidoId) => "subpedidos.id = $subpedidoId",
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws InvalidArgument
|
||||
* @throws CannotInsertRecord
|
||||
* @throws Exception
|
||||
*/
|
||||
private static function exportarCSV(
|
||||
string $filename,
|
||||
Collection $headers,
|
||||
Collection $contenido
|
||||
): void {
|
||||
$nombresColumnas = $headers->pluck('nombre')->toArray();
|
||||
$columnas = array_merge(['Producto'], $nombresColumnas);
|
||||
$filaTransporte = TransporteHelper::filaTransporte();
|
||||
$planilla = [];
|
||||
$ultimaFila = 1;
|
||||
|
||||
foreach ($contenido as $fila) {
|
||||
$filaActual = $fila->fila;
|
||||
while ($filaActual - $ultimaFila > 1) {
|
||||
$ultimaFila++;
|
||||
$planilla[$ultimaFila] = [$ultimaFila === $filaTransporte ? 'Bono de transporte' : '---'];
|
||||
}
|
||||
$planilla[$filaActual] = [$fila->producto];
|
||||
foreach ($nombresColumnas as $nombre)
|
||||
$planilla[$filaActual][] = $fila->$nombre ?? 0;
|
||||
|
||||
$ultimaFila = $filaActual;
|
||||
}
|
||||
|
||||
$planilla[$filaTransporte] = array_merge(['Bono de transporte'], self::cantidadesTransporte($nombresColumnas, $contenido));
|
||||
|
||||
ksort($planilla);
|
||||
CsvHelper::generarCsv($filename, $planilla, $columnas);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Collection $headers
|
||||
* @param Closure $filtroCallback
|
||||
* <br>
|
||||
* Ejemplo de uso:
|
||||
* ``
|
||||
* PedidosExportHelper::generarContenidoCSV(GrupoDeCompra::barriosMenosPrueba(),
|
||||
* fn($gdc_id) => "subpedidos.grupo_de_compra_id = $gdc_id");
|
||||
* ``
|
||||
* @return Collection
|
||||
* Los elementos son de la forma
|
||||
* {
|
||||
* fila: int (fila del producto),
|
||||
* producto: string (nombre del producto),
|
||||
* precio: float (precio del producto),
|
||||
* paga_transporte: bool (1 o 0, calculado a partir de bono y categoria),
|
||||
* barrio_1: string (cantidad pedida por barrio_1),
|
||||
* ...
|
||||
* barrio_n: string (cantidad pedida por barrio_n)
|
||||
* }
|
||||
*/
|
||||
public static function generarContenidoCSV(
|
||||
Collection $headers,
|
||||
Closure $filtroCallback
|
||||
): Collection {
|
||||
$expresionesColumnas = $headers->map(function ($header) use ($filtroCallback) {
|
||||
$id = $header['id'];
|
||||
$nombre = $header['nombre'];
|
||||
$filtro = $filtroCallback($id);
|
||||
return DB::raw("
|
||||
SUM(CASE WHEN $filtro THEN producto_subpedido.cantidad ELSE 0 END) as `$nombre`
|
||||
");
|
||||
})->toArray();
|
||||
|
||||
$query = DB::table('productos')
|
||||
->where('productos.nombre', 'not like', '%barrial%')
|
||||
->leftJoin('producto_subpedido', 'productos.id', '=', 'producto_subpedido.producto_id')
|
||||
->leftJoin('subpedidos', 'subpedidos.id', '=', 'producto_subpedido.subpedido_id');
|
||||
|
||||
$columnasProducto = [
|
||||
'productos.fila as fila',
|
||||
'productos.nombre as producto',
|
||||
'productos.precio as precio',
|
||||
self::pagaTransporte(),
|
||||
];
|
||||
|
||||
return $query->select(array_merge(
|
||||
$columnasProducto,
|
||||
$expresionesColumnas
|
||||
))->groupBy('productos.fila', 'productos.id', 'productos.nombre')
|
||||
->orderBy('productos.fila')
|
||||
->get();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Expression
|
||||
*/
|
||||
public static function pagaTransporte(): Expression
|
||||
{
|
||||
return DB::raw('CASE WHEN productos.bono OR productos.categoria LIKE "%SUBSIDIADO%" THEN 0 ELSE 1 END as paga_transporte');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $nombresColumnas
|
||||
* @param Collection $contenido
|
||||
* @return array
|
||||
*/
|
||||
public static function cantidadesTransporte(array $nombresColumnas, Collection $contenido): array
|
||||
{
|
||||
$transporte = [];
|
||||
foreach ($nombresColumnas as $nombre) {
|
||||
$suma = 0;
|
||||
foreach ($contenido as $fila) {
|
||||
if ($fila->paga_transporte) {
|
||||
$cantidad = $fila->$nombre ?? 0;
|
||||
$precio = $fila->precio ?? 0;
|
||||
$suma += $cantidad * $precio;
|
||||
}
|
||||
}
|
||||
$transporte[] = TransporteHelper::cantidadTransporte($suma);
|
||||
}
|
||||
return $transporte;
|
||||
}
|
||||
}
|
|
@ -4,21 +4,29 @@ namespace App\Helpers;
|
|||
|
||||
use App\CanastaLog;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use InvalidArgumentException;
|
||||
use League\Csv\Exception;
|
||||
|
||||
class TransporteHelper
|
||||
{
|
||||
const COSTO_TRANSPORTE = 15;
|
||||
const MONTO_TRANSPORTE = 500;
|
||||
private const COSTO_TRANSPORTE = "bono-transporte";
|
||||
private const MONTO_TRANSPORTE = "monto-transporte";
|
||||
private static ?array $parametros = null;
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function cantidadTransporte($monto)
|
||||
{
|
||||
return ceil($monto / self::MONTO_TRANSPORTE);
|
||||
return ceil($monto / self::getParametro(self::MONTO_TRANSPORTE));
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function totalTransporte($monto)
|
||||
{
|
||||
return self::cantidadTransporte($monto) * self::COSTO_TRANSPORTE;
|
||||
return self::cantidadTransporte($monto) * self::getParametro(self::COSTO_TRANSPORTE);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -41,4 +49,28 @@ class TransporteHelper
|
|||
Log::error($error);
|
||||
throw new Exception($error);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function getParametro(string $id): int
|
||||
{
|
||||
if (self::$parametros === null) {
|
||||
$records = CsvHelper::getRecords(resource_path('csv/parametros.csv'), "No se pudo leer el archivo.");
|
||||
self::$parametros = [];
|
||||
foreach ($records as $row) {
|
||||
self::$parametros[$row['id']] = $row;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isset(self::$parametros[$id])) {
|
||||
throw new InvalidArgumentException("Parámetro '$id' no encontrado.");
|
||||
}
|
||||
|
||||
return (int) self::$parametros[$id]['valor'];
|
||||
}
|
||||
|
||||
public static function resetParametros(): void {
|
||||
self::$parametros = null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,9 @@
|
|||
namespace App\Http\Controllers;
|
||||
|
||||
use App\GrupoDeCompra;
|
||||
use App\Helpers\PedidosExportHelper;
|
||||
use League\Csv\Exception;
|
||||
use Mpdf\MpdfException;
|
||||
|
||||
class AdminController extends Controller
|
||||
{
|
||||
|
@ -17,13 +19,18 @@ class AdminController extends Controller
|
|||
}
|
||||
|
||||
public function exportarPedidosAPdf(GrupoDeCompra $gdc) {
|
||||
$gdc->exportarPedidosAPdf();
|
||||
try {
|
||||
$gdc->exportarPedidosAPdf();
|
||||
return response();
|
||||
} catch (MpdfException $e) {
|
||||
return response()->json(['message' => $e->getMessage()], 500);
|
||||
}
|
||||
}
|
||||
|
||||
public function exportarPedidoACSV(GrupoDeCompra $gdc)
|
||||
{
|
||||
try {
|
||||
$gdc->exportarPedidoEnCSV();
|
||||
PedidosExportHelper::pedidoTotalDeBarrio($gdc);
|
||||
} catch (Exception $e) {
|
||||
return response()->json(['message' => $e->getMessage()]);
|
||||
}
|
||||
|
@ -40,7 +47,7 @@ class AdminController extends Controller
|
|||
public function exportarPedidoConNucleosACSV(GrupoDeCompra $gdc)
|
||||
{
|
||||
try {
|
||||
$gdc->exportarPedidoConNucleosEnCSV();
|
||||
PedidosExportHelper::pedidosDeBarrio($gdc);
|
||||
} catch (Exception $e) {
|
||||
return response()->json(['message' => $e->getMessage()]);
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ namespace App\Http\Controllers\Api;
|
|||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Producto;
|
||||
use App\TipoPedido;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Filtros\FiltroDeSubpedido;
|
||||
use App\Subpedido;
|
||||
|
@ -12,7 +13,6 @@ use App\Http\Resources\SubpedidoResource;
|
|||
use Illuminate\Validation\Rule;
|
||||
use Symfony\Component\HttpKernel\Exception\HttpException;
|
||||
|
||||
|
||||
class SubpedidoController extends Controller
|
||||
{
|
||||
public function index(FiltroDeSubpedido $filtros, Request $request)
|
||||
|
@ -25,17 +25,25 @@ class SubpedidoController extends Controller
|
|||
return SubpedidoResource::collection(Subpedido::filtrar($filtros)->get());
|
||||
}
|
||||
|
||||
public function store(Request $request)
|
||||
public function store(Request $request)
|
||||
{
|
||||
$validado = $this->validateSubpedido();
|
||||
if (Subpedido::where("nombre",$validado["nombre"])->where("grupo_de_compra_id",$validado["grupo_de_compra_id"])->get()->count()) {
|
||||
throw new HttpException(400, "Ya existe un subpedido con este nombre");
|
||||
}
|
||||
$s = new Subpedido();
|
||||
$s->nombre = $validado["nombre"];
|
||||
$s->grupo_de_compra_id = $validado["grupo_de_compra_id"];
|
||||
$s->save();
|
||||
return $this->show($s);
|
||||
|
||||
if (Subpedido::where([
|
||||
"nombre" => $validado["nombre"],
|
||||
"tipo_pedido_id" => $validado["tipo_id"],
|
||||
"grupo_de_compra_id" => $validado["grupo_de_compra_id"]])
|
||||
->get()
|
||||
->count())
|
||||
throw new HttpException(400, "Ya existe un pedido con este nombre");
|
||||
|
||||
$pedido = new Subpedido();
|
||||
$pedido->nombre = $validado["nombre"];
|
||||
$pedido->grupo_de_compra_id = $validado["grupo_de_compra_id"];
|
||||
$pedido->tipo_pedido_id = $validado["tipo_id"];
|
||||
$pedido->save();
|
||||
|
||||
return $this->show($pedido);
|
||||
}
|
||||
|
||||
protected function validateSubpedido(): array
|
||||
|
@ -45,7 +53,11 @@ class SubpedidoController extends Controller
|
|||
'grupo_de_compra_id' => [
|
||||
'required',
|
||||
Rule::in(GrupoDeCompra::all()->pluck('id')),
|
||||
]
|
||||
],
|
||||
'tipo_id' => [
|
||||
'required',
|
||||
Rule::in(TipoPedido::all()->pluck('id')),
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
|
|
|
@ -5,15 +5,19 @@ namespace App\Http\Controllers;
|
|||
use App\GrupoDeCompra;
|
||||
use App\Helpers\CanastaHelper;
|
||||
use App\Helpers\CsvHelper;
|
||||
use App\Helpers\PedidosExportHelper;
|
||||
use App\Helpers\TransporteHelper;
|
||||
use App\Http\Resources\GrupoDeCompraResource;
|
||||
use App\Producto;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use League\Csv\Exception;
|
||||
use Mpdf\MpdfException;
|
||||
use Symfony\Component\HttpFoundation\BinaryFileResponse;
|
||||
|
||||
class ComisionesController
|
||||
{
|
||||
const PARAMETROS_PATH = 'csv/parametros.csv';
|
||||
const CANASTAS_PATH = 'csv/canastas/';
|
||||
const BARRIO = "Barrio";
|
||||
const SALDO = "Saldo";
|
||||
|
@ -26,7 +30,7 @@ class ComisionesController
|
|||
public function descargarPedidos()
|
||||
{
|
||||
try {
|
||||
Producto::planillaTotales();
|
||||
PedidosExportHelper::pedidosBarriales();
|
||||
} catch (Exception $e) {
|
||||
return response()->json(['message' => $e->getMessage()], 500);
|
||||
}
|
||||
|
@ -40,6 +44,23 @@ class ComisionesController
|
|||
return response()->download($files[0]);
|
||||
}
|
||||
|
||||
public function descargarPedidosDeOllas()
|
||||
{
|
||||
try {
|
||||
PedidosExportHelper::pedidosDeOllas();
|
||||
} catch (Exception $e) {
|
||||
return response()->json(['message' => $e->getMessage()], 500);
|
||||
}
|
||||
$pattern = storage_path('csv/exports/pedidos-de-ollas-*.csv');
|
||||
$files = glob($pattern);
|
||||
|
||||
usort($files, function ($a, $b) {
|
||||
return filemtime($b) <=> filemtime($a);
|
||||
});
|
||||
|
||||
return response()->download($files[0]);
|
||||
}
|
||||
|
||||
public function descargarNotas(): BinaryFileResponse
|
||||
{
|
||||
Producto::planillaNotas();
|
||||
|
@ -54,7 +75,12 @@ class ComisionesController
|
|||
}
|
||||
|
||||
public function pdf() {
|
||||
GrupoDeCompra::exportarPedidosBarrialesAPdf();
|
||||
try {
|
||||
GrupoDeCompra::exportarPedidosBarrialesAPdf();
|
||||
return response();
|
||||
} catch (MpdfException $e) {
|
||||
return response()->json(['message' => $e->getMessage()], 500);
|
||||
}
|
||||
}
|
||||
|
||||
public function cargarCanasta(Request $request): JsonResponse
|
||||
|
@ -104,4 +130,43 @@ class ComisionesController
|
|||
|
||||
return response()->json(GrupoDeCompraResource::collection(GrupoDeCompra::all()));
|
||||
}
|
||||
|
||||
public function obtenerParametros(): JsonResponse
|
||||
{
|
||||
try {
|
||||
$records = self::parametrosRecords();
|
||||
$result = [];
|
||||
foreach ($records as $record)
|
||||
$result[] = $record;
|
||||
return response()->json($result);
|
||||
} catch (Exception $e) {
|
||||
return response()->json(['message' => $e->getMessage()], 500);
|
||||
}
|
||||
}
|
||||
|
||||
public function modificarParametros(string $parametro_id, Request $request) {
|
||||
try {
|
||||
if (collect(self::parametrosRecords())
|
||||
->contains('id', $parametro_id)) {
|
||||
$valid = $request->validate([
|
||||
'valor' => ['required', 'numeric', 'gte:0'],
|
||||
]);
|
||||
CsvHelper::cambiarParametro($parametro_id, $valid['valor']);
|
||||
TransporteHelper::resetParametros();
|
||||
return response()->noContent();
|
||||
}
|
||||
return response()->json(['message' => 'Parametro no encontrado.'], 404);
|
||||
} catch (Exception $e) {
|
||||
return response()->json(['message' => $e->getMessage()], 500);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
private static function parametrosRecords(): array
|
||||
{
|
||||
$records = CsvHelper::getRecords(resource_path(self::PARAMETROS_PATH), "No se pudo leer el archivo.");
|
||||
return iterator_to_array($records);
|
||||
}
|
||||
}
|
||||
|
|
40
app/Http/Controllers/OllasController.php
Normal file
40
app/Http/Controllers/OllasController.php
Normal file
|
@ -0,0 +1,40 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\GrupoDeCompra;
|
||||
use App\Http\Resources\PedidoOllasResource;
|
||||
use App\TipoPedido;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class OllasController extends Controller
|
||||
{
|
||||
public function show()
|
||||
{
|
||||
return view('auth/login');
|
||||
}
|
||||
|
||||
public function pedido(GrupoDeCompra $gdc)
|
||||
{
|
||||
$tipoOlla = TipoPedido::firstOrCreate(['nombre' => 'olla']);
|
||||
$pedido = $gdc->subpedidos()->firstOrCreate([
|
||||
'nombre' => 'Pedido de Ollas de ' . $gdc->nombre,
|
||||
'tipo_pedido_id' => $tipoOlla->id,
|
||||
'cantidad_ollas' => 0,
|
||||
]);
|
||||
return response()->json(new PedidoOllasResource($pedido));
|
||||
}
|
||||
|
||||
public function actualizarCantidadOllas(GrupoDeCompra $gdc, Request $request)
|
||||
{
|
||||
$valid = $request->validate([
|
||||
'cantidad' => 'required|numeric|min:0',
|
||||
]);
|
||||
$pedido = $gdc->subpedidos()->where([
|
||||
'nombre' => 'Pedido de Ollas de ' . $gdc->nombre
|
||||
])->first();
|
||||
$pedido->cantidad_ollas = $valid['cantidad'];
|
||||
$pedido->save();
|
||||
return response()->noContent();
|
||||
}
|
||||
}
|
|
@ -15,6 +15,7 @@ class RouteController extends Controller
|
|||
$barrio = UserRole::where('nombre', 'barrio')->first();
|
||||
$admin = UserRole::where('nombre', 'admin_barrio')->first();
|
||||
$comision = UserRole::where('nombre', 'comision')->first();
|
||||
$ollas = UserRole::where('nombre', 'ollas')->first();
|
||||
|
||||
switch ($request->user()->role_id) {
|
||||
case $barrio->id:
|
||||
|
@ -23,6 +24,8 @@ class RouteController extends Controller
|
|||
return redirect('/admin');
|
||||
case $comision->id:
|
||||
return redirect('/comisiones');
|
||||
case $ollas->id:
|
||||
return redirect('/ollas');
|
||||
default:
|
||||
abort(400, 'Rol de usuario invalido');
|
||||
}
|
||||
|
|
|
@ -11,6 +11,11 @@ use Illuminate\Support\Facades\Auth;
|
|||
|
||||
class UserController extends Controller
|
||||
{
|
||||
public function user(Request $request)
|
||||
{
|
||||
return ['user' => $request->user()->name];
|
||||
}
|
||||
|
||||
public function rol(Request $request) {
|
||||
return ["rol" => UserRole::find($request->user()->role_id)->nombre];
|
||||
}
|
||||
|
@ -21,6 +26,7 @@ class UserController extends Controller
|
|||
$result = [ 'grupo_de_compra' => null, ];
|
||||
$grupo_de_compra = GrupoDeCompra::find($user->grupo_de_compra_id);
|
||||
switch (UserRole::findOrFail($user->role_id)->nombre) {
|
||||
case 'ollas':
|
||||
case 'barrio':
|
||||
$result['grupo_de_compra'] = new GrupoDeCompraPedidoResource($grupo_de_compra);
|
||||
break;
|
||||
|
|
|
@ -3,16 +3,17 @@
|
|||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Auth\Middleware\Authenticate as Middleware;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class Authenticate extends Middleware
|
||||
{
|
||||
/**
|
||||
* Get the path the user should be redirected to when they are not authenticated.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param Request $request
|
||||
* @return string|null
|
||||
*/
|
||||
protected function redirectTo($request)
|
||||
protected function redirectTo($request): string
|
||||
{
|
||||
if (!$request->expectsJson()) {
|
||||
$path = $request->path();
|
||||
|
@ -20,7 +21,10 @@ class Authenticate extends Middleware
|
|||
return route('admin.login');
|
||||
if (preg_match('~^comisiones.*~i', $path))
|
||||
return route('comisiones.login');
|
||||
if (preg_match('~^ollas.*~i', $path))
|
||||
return route('ollas.login');
|
||||
return route('login');
|
||||
}
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace App\Http\Resources;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
class GrupoDeCompraPedidoResource extends JsonResource
|
||||
|
@ -9,7 +10,7 @@ class GrupoDeCompraPedidoResource extends JsonResource
|
|||
/**
|
||||
* Transform the resource into an array.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param Request $request
|
||||
* @return array
|
||||
*/
|
||||
public function toArray($request): array {
|
||||
|
|
|
@ -19,7 +19,7 @@ class GrupoDeCompraResource extends JsonResource
|
|||
'id' => $this->id,
|
||||
'nombre' => $this->nombre,
|
||||
'devoluciones_habilitadas' => $this->devoluciones_habilitadas,
|
||||
'pedidos' => SubpedidoResource::collection($this->subpedidos),
|
||||
'pedidos' => SubpedidoResource::collection($this->pedidosHogares()),
|
||||
'total_a_recaudar' => number_format($this->totalARecaudar(),2),
|
||||
'saldo' => number_format($this->saldo, 2, ".", ""),
|
||||
'total_sin_devoluciones' => number_format($this->totalSinDevoluciones(),2),
|
||||
|
|
30
app/Http/Resources/PedidoOllasResource.php
Normal file
30
app/Http/Resources/PedidoOllasResource.php
Normal file
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Resources;
|
||||
|
||||
use App\TipoPedido;
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
class PedidoOllasResource extends JsonResource
|
||||
{
|
||||
/**
|
||||
* Transform the resource into an array.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return array
|
||||
*/
|
||||
public function toArray($request): array
|
||||
{
|
||||
$productos = $this->productos;
|
||||
foreach ($productos as $producto) {
|
||||
$producto['pivot']['total'] = number_format($producto->pivot->cantidad * $producto->precio, 2);
|
||||
}
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'nombre' => $this->nombre,
|
||||
'productos' => $productos,
|
||||
'total' => number_format($this->totalCentralesSinTransporte(),2),
|
||||
'cantidad_de_ollas' => $this->cantidad_ollas,
|
||||
];
|
||||
}
|
||||
}
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace App\Http\Resources;
|
||||
|
||||
use App\TipoPedido;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
|
@ -29,7 +30,11 @@ class SubpedidoResource extends JsonResource
|
|||
'cantidad_transporte' => number_format($this->cantidadTransporte()),
|
||||
'total_sin_devoluciones' => number_format($this->totalSinDevoluciones(),2),
|
||||
'devoluciones_total' => number_format($this->devoluciones_total,2),
|
||||
'devoluciones_notas' => $this->devoluciones_notas
|
||||
'devoluciones_notas' => $this->devoluciones_notas,
|
||||
'tipo' => [
|
||||
'id' => $this->tipo_pedido_id,
|
||||
'nombre' => TipoPedido::find($this->tipo_pedido_id)->nombre
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,7 +11,9 @@ use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
|||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use League\Csv\CannotInsertRecord;
|
||||
use League\Csv\Exception;
|
||||
use League\Csv\InvalidArgument;
|
||||
|
||||
class Producto extends Model
|
||||
{
|
||||
|
@ -19,15 +21,10 @@ class Producto extends Model
|
|||
|
||||
public function subpedidos(): BelongsToMany
|
||||
{
|
||||
return $this->belongsToMany(Subpedido::class, 'productos_subpedidos')->withPivot(["cantidad", "notas"]);
|
||||
return $this->belongsToMany(Subpedido::class, 'productos_subpedidos')
|
||||
->withPivot(["cantidad", "notas"]);
|
||||
}
|
||||
|
||||
public static function noBarriales()
|
||||
{
|
||||
return self::where('nombre', 'not like', '%barrial%');
|
||||
}
|
||||
|
||||
// Este método permite que se apliquen los filtros al hacer una request (por ejemplo, de búsqueda)
|
||||
public function scopeFiltrar($query, FiltroDeProducto $filtros): Builder
|
||||
{
|
||||
return $filtros->aplicar($query);
|
||||
|
@ -35,7 +32,9 @@ class Producto extends Model
|
|||
|
||||
public static function getPaginar(Request $request): int
|
||||
{
|
||||
return $request->has('paginar') && intval($request->input('paginar')) ? intval($request->input('paginar')) : self::all()->count();
|
||||
return $request->has('paginar') && intval($request->input('paginar')) ?
|
||||
intval($request->input('paginar')) :
|
||||
self::all()->count();
|
||||
}
|
||||
|
||||
public static function productosFilaID()
|
||||
|
@ -53,77 +52,20 @@ class Producto extends Model
|
|||
return self::noBarriales()->pluck('nombre', 'id')->all();
|
||||
}
|
||||
|
||||
static public function cantidadesPorBarrio(): Collection
|
||||
public static function noBarriales()
|
||||
{
|
||||
$barrios = GrupoDeCompra::barriosMenosPrueba()
|
||||
->pluck('id', 'nombre');
|
||||
|
||||
$columnasBarrios = $barrios->map(function ($id, $nombre) {
|
||||
return DB::raw("SUM(CASE WHEN subpedidos.grupo_de_compra_id = $id AND subpedidos.aprobado = 1 THEN producto_subpedido.cantidad ELSE 0 END) as `$nombre`");
|
||||
})->toArray();
|
||||
|
||||
return DB::table('productos')
|
||||
->where('productos.nombre', 'not like', '%barrial%')
|
||||
->leftJoin('producto_subpedido', 'productos.id', '=', 'producto_subpedido.producto_id')
|
||||
->leftJoin('subpedidos', 'subpedidos.id', '=', 'producto_subpedido.subpedido_id')
|
||||
->select(array_merge(
|
||||
['productos.fila as fila'],
|
||||
['productos.nombre as producto'],
|
||||
$columnasBarrios
|
||||
))
|
||||
->groupBy('productos.fila', 'productos.id', 'productos.nombre')
|
||||
->orderBy('productos.fila')
|
||||
->get();
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
static public function planillaTotales()
|
||||
{
|
||||
$headers = ['Producto'];
|
||||
$barrios = GrupoDeCompra::barriosMenosPrueba()
|
||||
->pluck('nombre')->toArray();
|
||||
$headers = array_merge($headers, $barrios);
|
||||
|
||||
$cantidadesPorBarrio = self::cantidadesPorBarrio();
|
||||
$transportePorBarrio = GrupoDeCompra::transportePorBarrio();
|
||||
$planilla = [];
|
||||
$ultimaFila = 1;
|
||||
$filaTransporte = TransporteHelper::filaTransporte();
|
||||
|
||||
foreach ($cantidadesPorBarrio as $productoCantidades) {
|
||||
$fila = $productoCantidades->fila;
|
||||
while ($fila - $ultimaFila > 1) {
|
||||
$ultimaFila++;
|
||||
if ($ultimaFila == $filaTransporte) {
|
||||
$planilla[$ultimaFila] = ['Bono de transporte'];
|
||||
} else {
|
||||
$planilla[$ultimaFila] = ['---'];
|
||||
}
|
||||
}
|
||||
$planilla[$fila] = [$productoCantidades->producto];
|
||||
foreach ($barrios as $barrio) {
|
||||
$planilla[$fila][] = $productoCantidades->$barrio ?? 0;
|
||||
}
|
||||
$ultimaFila = $fila;
|
||||
}
|
||||
|
||||
foreach ($transportePorBarrio as $key => $cantidad) {
|
||||
$planilla[$filaTransporte][] = $cantidad;
|
||||
}
|
||||
|
||||
$fecha = now()->format('Y-m-d');
|
||||
CsvHelper::generarCsv('csv/exports/pedidos-por-barrio- ' . $fecha . '.csv', $planilla, $headers);
|
||||
return self::where('nombre', 'not like', '%barrial%');
|
||||
}
|
||||
|
||||
public static function notasPorBarrio(): Collection
|
||||
{
|
||||
return DB::table('productos')
|
||||
->where('productos.nombre', 'not like', '%barrial%')
|
||||
->join('producto_subpedido', 'productos.id', '=', 'producto_subpedido.producto_id')
|
||||
->join('subpedidos', 'producto_subpedido.subpedido_id', '=', 'subpedidos.id')
|
||||
->join('grupos_de_compra', 'subpedidos.grupo_de_compra_id', '=', 'grupos_de_compra.id')
|
||||
->where('productos.requiere_notas', 1)
|
||||
->where('subpedidos.tipo_pedido_id', '=', 1)
|
||||
->select(
|
||||
'productos.nombre as producto',
|
||||
'grupos_de_compra.nombre as barrio',
|
||||
|
@ -133,6 +75,10 @@ class Producto extends Model
|
|||
->groupBy('producto');
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws InvalidArgument
|
||||
* @throws CannotInsertRecord
|
||||
*/
|
||||
static public function planillaNotas() {
|
||||
$headers = ['Producto'];
|
||||
$barrios = GrupoDeCompra::barriosMenosPrueba()
|
||||
|
@ -145,13 +91,16 @@ class Producto extends Model
|
|||
foreach ($notasPorBarrio as $producto => $notasGrupo) {
|
||||
$fila = [$producto];
|
||||
foreach ($barrios as $barrio) {
|
||||
$notas = $notasGrupo->where('barrio', $barrio)->pluck('notas')->implode('; ');
|
||||
$notas = $notasGrupo->where('barrio', $barrio)
|
||||
->pluck('notas')
|
||||
->implode('; ');
|
||||
$fila[] = $notas ?: '';
|
||||
}
|
||||
$planilla[] = $fila;
|
||||
}
|
||||
|
||||
$fecha = now()->format('Y-m-d');
|
||||
CsvHelper::generarCsv('csv/exports/notas-por-barrio-' . $fecha . '.csv', $planilla, $headers);
|
||||
$filePath = 'csv/exports/notas-por-barrio-' . $fecha . '.csv';
|
||||
CsvHelper::generarCsv($filePath, $planilla, $headers);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,15 @@ use App\Filtros\FiltroDeSubpedido;
|
|||
|
||||
class Subpedido extends Model
|
||||
{
|
||||
protected $fillable = ['grupo_de_compra_id', 'aprobado', 'nombre', 'devoluciones_total', 'devoluciones_notas'];
|
||||
protected $fillable = [
|
||||
'grupo_de_compra_id',
|
||||
'aprobado',
|
||||
'nombre',
|
||||
'devoluciones_total',
|
||||
'devoluciones_notas',
|
||||
'tipo_pedido_id',
|
||||
'cantidad_ollas'
|
||||
];
|
||||
|
||||
public function productos(): BelongsToMany
|
||||
{
|
||||
|
@ -24,6 +32,11 @@ class Subpedido extends Model
|
|||
return $this->belongsTo(GrupoDeCompra::class);
|
||||
}
|
||||
|
||||
public function tipoPedido(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(TipoPedido::class);
|
||||
}
|
||||
|
||||
// Permite que se apliquen los filtros al hacer una request (por ejemplo, de búsqueda)
|
||||
public function scopeFiltrar($query, FiltroDeSubpedido $filtros): Builder
|
||||
{
|
||||
|
@ -52,7 +65,11 @@ class Subpedido extends Model
|
|||
|
||||
public function totalCentral()
|
||||
{
|
||||
return $this->totalCentralesQueNoPaganTransporte() + $this->totalCentralesQuePaganTransporte() + $this->totalTransporte();
|
||||
return $this->totalCentralesSinTransporte() + $this->totalTransporte();
|
||||
}
|
||||
|
||||
public function totalCentralesSinTransporte() {
|
||||
return $this->totalCentralesQueNoPaganTransporte() + $this->totalCentralesQuePaganTransporte();
|
||||
}
|
||||
|
||||
public function totalCentralesQueNoPaganTransporte()
|
||||
|
|
10
app/TipoPedido.php
Normal file
10
app/TipoPedido.php
Normal file
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
|
||||
namespace App;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class TipoPedido extends Model
|
||||
{
|
||||
protected $fillable = ["nombre"];
|
||||
}
|
|
@ -67,7 +67,7 @@ return [
|
|||
|
|
||||
*/
|
||||
|
||||
'timezone' => 'UTC',
|
||||
'timezone' => 'America/Montevideo',
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
<?php
|
||||
|
||||
use App\TipoPedido;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class CreateTipoPedidosTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('tipo_pedidos', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string("nombre");
|
||||
$table->timestamps();
|
||||
});
|
||||
|
||||
$hogar = TipoPedido::firstOrCreate(['nombre' => 'hogar']);
|
||||
TipoPedido::firstOrCreate(['nombre' => 'olla']);
|
||||
|
||||
Schema::table('subpedidos', function (Blueprint $table) use ($hogar) {
|
||||
$table->foreignId('tipo_pedido_id')->default($hogar->id);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('tipo_pedidos');
|
||||
Schema::table('subpedidos', function (Blueprint $table) {
|
||||
$table->dropColumn('tipo_pedido_id');
|
||||
});
|
||||
}
|
||||
}
|
40
database/migrations/2025_06_20_040800_user_role_ollas.php
Normal file
40
database/migrations/2025_06_20_040800_user_role_ollas.php
Normal file
|
@ -0,0 +1,40 @@
|
|||
<?php
|
||||
|
||||
use App\GrupoDeCompra;
|
||||
use App\User;
|
||||
use App\UserRole;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
|
||||
class UserRoleOllas extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
$ollasRol = UserRole::firstOrCreate(['nombre' => 'ollas']);
|
||||
$barrios = GrupoDeCompra::all();
|
||||
foreach ($barrios as $barrio) {
|
||||
$barrio->users()->firstOrCreate([
|
||||
'name' => $barrio->nombre . '_ollas',
|
||||
'password' => Hash::make('123'),
|
||||
'role_id' => $ollasRol->id
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
$ollasRol = UserRole::where('nombre', 'ollas')->firstOrFail();
|
||||
User::where('role_id', $ollasRol->id)->delete();
|
||||
$ollasRol->delete();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class CantidadOllasPedidos extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('subpedidos', function (Blueprint $table) {
|
||||
$table->integer('cantidad_ollas')->nullable();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('subpedidos', function (Blueprint $table) {
|
||||
$table->dropColumn('cantidad_ollas');
|
||||
});
|
||||
}
|
||||
}
|
|
@ -24,5 +24,6 @@ class DatabaseSeeder extends Seeder
|
|||
$this->call(CanastaSeeder::class);
|
||||
$this->call(GrupoDeCompraSeeder::class);
|
||||
$this->call(UserSeeder::class);
|
||||
$this->call(UsuarioOllasSeeder::class);
|
||||
}
|
||||
}
|
||||
|
|
34
database/seeds/UsuarioOllasSeeder.php
Normal file
34
database/seeds/UsuarioOllasSeeder.php
Normal file
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
|
||||
use App\GrupoDeCompra;
|
||||
use App\User;
|
||||
use App\UserRole;
|
||||
use Illuminate\Database\Seeder;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
|
||||
class UsuarioOllasSeeder extends Seeder
|
||||
{
|
||||
/**
|
||||
* Run the database seeds.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
$barrios = GrupoDeCompra::all();
|
||||
$usersToInsert = [];
|
||||
$ollas_id = UserRole::where('nombre', 'ollas')->first()->id;
|
||||
|
||||
foreach ($barrios as $barrio) {
|
||||
$usersToInsert[] = DatabaseSeeder::addTimestamps([
|
||||
'name' => $barrio->nombre . '_ollas',
|
||||
'password' => Hash::make('123'),
|
||||
'role_id' => $ollas_id,
|
||||
'grupo_de_compra_id' => $barrio->id,
|
||||
]);
|
||||
}
|
||||
|
||||
foreach (array_chunk($usersToInsert,DatabaseSeeder::CHUNK_SIZE) as $chunk)
|
||||
User::insert($chunk);
|
||||
}
|
||||
}
|
25
package-lock.json
generated
25
package-lock.json
generated
|
@ -1648,19 +1648,6 @@
|
|||
"hasInstallScript": true,
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"@parcel/watcher-android-arm64": "2.5.1",
|
||||
"@parcel/watcher-darwin-arm64": "2.5.1",
|
||||
"@parcel/watcher-darwin-x64": "2.5.1",
|
||||
"@parcel/watcher-freebsd-x64": "2.5.1",
|
||||
"@parcel/watcher-linux-arm-glibc": "2.5.1",
|
||||
"@parcel/watcher-linux-arm-musl": "2.5.1",
|
||||
"@parcel/watcher-linux-arm64-glibc": "2.5.1",
|
||||
"@parcel/watcher-linux-arm64-musl": "2.5.1",
|
||||
"@parcel/watcher-linux-x64-glibc": "2.5.1",
|
||||
"@parcel/watcher-linux-x64-musl": "2.5.1",
|
||||
"@parcel/watcher-win32-arm64": "2.5.1",
|
||||
"@parcel/watcher-win32-ia32": "2.5.1",
|
||||
"@parcel/watcher-win32-x64": "2.5.1",
|
||||
"detect-libc": "^1.0.3",
|
||||
"is-glob": "^4.0.3",
|
||||
"micromatch": "^4.0.5",
|
||||
|
@ -2056,7 +2043,6 @@
|
|||
"dependencies": {
|
||||
"@babel/parser": "^7.23.5",
|
||||
"postcss": "^8.4.14",
|
||||
"prettier": "^1.18.2 || ^2.0.0",
|
||||
"source-map": "^0.6.1"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
|
@ -2102,7 +2088,6 @@
|
|||
"merge-source-map": "^1.1.0",
|
||||
"postcss": "^7.0.36",
|
||||
"postcss-selector-parser": "^6.0.2",
|
||||
"prettier": "^1.18.2 || ^2.0.0",
|
||||
"source-map": "~0.6.1",
|
||||
"vue-template-es2015-compiler": "^1.9.0"
|
||||
},
|
||||
|
@ -3555,7 +3540,6 @@
|
|||
"anymatch": "^2.0.0",
|
||||
"async-each": "^1.0.1",
|
||||
"braces": "^2.3.2",
|
||||
"fsevents": "^1.2.7",
|
||||
"glob-parent": "^3.1.0",
|
||||
"inherits": "^2.0.3",
|
||||
"is-binary-path": "^1.0.0",
|
||||
|
@ -7975,9 +7959,6 @@
|
|||
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
|
||||
"integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"graceful-fs": "^4.1.6"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"graceful-fs": "^4.1.6"
|
||||
}
|
||||
|
@ -11334,7 +11315,6 @@
|
|||
"integrity": "sha512-d0NoFH4v6SjEK7BoX810Jsrhj7IQSYHAHLi/iSpgqKc7LaIDshFRlSg5LOymf9FqQhxEHs2W5ZQXlvy0KD45Uw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@parcel/watcher": "^2.4.1",
|
||||
"chokidar": "^4.0.0",
|
||||
"immutable": "^5.0.2",
|
||||
"source-map-js": ">=0.6.2 <2.0.0"
|
||||
|
@ -13424,10 +13404,8 @@
|
|||
"integrity": "sha512-9P3MWk6SrKjHsGkLT2KHXdQ/9SNkyoJbabxnKOoJepsvJjJG8uYTR3yTPxPQvNDI3w4Nz1xnE0TLHK4RIVe/MQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"chokidar": "^3.4.1",
|
||||
"graceful-fs": "^4.1.2",
|
||||
"neo-async": "^2.5.0",
|
||||
"watchpack-chokidar2": "^2.0.1"
|
||||
"neo-async": "^2.5.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"chokidar": "^3.4.1",
|
||||
|
@ -13493,7 +13471,6 @@
|
|||
"dependencies": {
|
||||
"anymatch": "~3.1.2",
|
||||
"braces": "~3.0.2",
|
||||
"fsevents": "~2.3.2",
|
||||
"glob-parent": "~5.1.2",
|
||||
"is-binary-path": "~2.1.0",
|
||||
"is-glob": "~4.0.1",
|
||||
|
|
0
resources/csv/exports/.gitignore
vendored
0
resources/csv/exports/.gitignore
vendored
4
resources/csv/parametros.csv
Normal file
4
resources/csv/parametros.csv
Normal file
|
@ -0,0 +1,4 @@
|
|||
id|nombre|valor
|
||||
bono-transporte|'Bono de transporte'|15
|
||||
monto-transporte|'Monto para bono de transporte'|500
|
||||
monto-olla|'Monto por olla'|1200
|
|
|
@ -5,9 +5,10 @@ import ComisionesBody from "./comisiones/Body.vue";
|
|||
import AdminBody from "./admin/Body.vue";
|
||||
import PedidosBody from "./pedidos/Body.vue";
|
||||
import InfoTags from "./comunes/InfoTags.vue";
|
||||
import OllasBody from "./ollas/OllasBody.vue";
|
||||
export default {
|
||||
name: 'Main',
|
||||
components: { InfoTags, ComisionesBody, AdminBody, PedidosBody, NavBar },
|
||||
components: { OllasBody, InfoTags, ComisionesBody, AdminBody, PedidosBody, NavBar },
|
||||
computed: {
|
||||
...mapState("login", ["rol"]),
|
||||
},
|
||||
|
@ -26,6 +27,7 @@ export default {
|
|||
<pedidos-body v-if="rol === 'barrio'"/>
|
||||
<admin-body v-else-if="rol === 'admin_barrio'"/>
|
||||
<comisiones-body v-else-if="rol === 'comision'"/>
|
||||
<ollas-body v-else-if="rol === 'ollas'"/>
|
||||
<info-tags/>
|
||||
</div>
|
||||
</template>
|
||||
|
|
25
resources/js/components/admin/AdminNavBarBrand.vue
Normal file
25
resources/js/components/admin/AdminNavBarBrand.vue
Normal file
|
@ -0,0 +1,25 @@
|
|||
<script>
|
||||
import { mapGetters, mapMutations, mapState } from "vuex";
|
||||
|
||||
export default {
|
||||
name: "AdminNavBarBrand",
|
||||
computed: {
|
||||
...mapState('ui', ["burger_activa"]),
|
||||
...mapGetters('admin', ["barrio"])
|
||||
},
|
||||
methods: {
|
||||
...mapMutations('ui', ["toggleBurger"]),
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="navbar-item hide-below-1024">
|
||||
<p>
|
||||
{{`Barrio: ${barrio}`}}
|
||||
</p>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
</style>
|
|
@ -18,6 +18,11 @@
|
|||
:class="seccionActiva === 'saldos-comisiones-seccion' ? 'is-active' : 'is-hidden'">
|
||||
<saldos-seccion/>
|
||||
</div>
|
||||
<div class="block pb-6"
|
||||
id="parametros-comisiones-seccion"
|
||||
:class="seccionActiva === 'parametros-comisiones-seccion' ? 'is-active' : 'is-hidden'">
|
||||
<parametros-seccion/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -27,11 +32,12 @@ import DropdownDescargar from "./DropdownDescargar.vue";
|
|||
import InputFileButton from "../comunes/InputFileButton.vue";
|
||||
import CanastaSeccion from "./canasta/CanastaSeccion.vue";
|
||||
import SaldosSeccion from "./saldos/SaldosSeccion.vue";
|
||||
import { mapActions } from "vuex";
|
||||
import ParametrosSeccion from "./parametros/ParametrosSeccion.vue";
|
||||
|
||||
export default {
|
||||
name: "ComisionesBody",
|
||||
components: {
|
||||
ParametrosSeccion,
|
||||
SaldosSeccion,
|
||||
CanastaSeccion,
|
||||
TabsSecciones,
|
||||
|
@ -44,6 +50,7 @@ export default {
|
|||
{ id: "pedidos-comisiones", nombre: "Pedidos" },
|
||||
{ id: "canasta-comisiones", nombre: "Canasta" },
|
||||
{ id: "saldos-comisiones", nombre: "Saldos" },
|
||||
{ id: "parametros-comisiones", nombre: "Parámetros" },
|
||||
],
|
||||
tabActiva: "pedidos-comisiones",
|
||||
seccionActiva: "pedidos-comisiones-seccion",
|
||||
|
|
31
resources/js/components/comisiones/ComisionesNavBarBrand.vue
Normal file
31
resources/js/components/comisiones/ComisionesNavBarBrand.vue
Normal file
|
@ -0,0 +1,31 @@
|
|||
<script>
|
||||
import { mapMutations, mapState } from "vuex";
|
||||
|
||||
export default {
|
||||
name: "ComisionesNavBarBrand",
|
||||
computed: {
|
||||
...mapState('ui', ["burger_activa"])
|
||||
},
|
||||
methods: {
|
||||
...mapMutations('ui', ["toggleBurger"]),
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
nombre: '',
|
||||
}
|
||||
},
|
||||
async mounted() {
|
||||
const response = await axios.get('/user');
|
||||
this.nombre = response.data.user;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="navbar-item hide-below-1024">
|
||||
<p>{{ nombre }}</p>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
</style>
|
|
@ -15,14 +15,17 @@
|
|||
<div class="dropdown-menu" id="dropdown-menu" role="menu">
|
||||
<div class="dropdown-content">
|
||||
<a href="/comisiones/pedidos/descargar" class="dropdown-item">
|
||||
Pedidos por barrio
|
||||
Pedidos por barrio en csv
|
||||
</a>
|
||||
<a href="/comisiones/pedidos/notas" class="dropdown-item">
|
||||
Notas por barrio
|
||||
Notas por barrio en csv
|
||||
</a>
|
||||
<a href="/comisiones/pedidos/pdf" class="dropdown-item">
|
||||
Pedidos por barrio en pdf
|
||||
</a>
|
||||
<a href="/comisiones/pedidos/ollas" class="dropdown-item">
|
||||
Pedidos de ollas en csv
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
<script>
|
||||
import {mapActions, mapGetters} from "vuex";
|
||||
|
||||
export default {
|
||||
props: {
|
||||
parametro: {
|
||||
type: Object,
|
||||
required: true,
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
control: this.parametro.valor,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
hayCambios() {
|
||||
return this.control !== this.parametro.valor;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
...mapActions("comisiones", ["cambiarParametro"]),
|
||||
modificar() {
|
||||
this.cambiarParametro({
|
||||
parametro_id: this.parametro.id,
|
||||
valor: this.control,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<tr>
|
||||
<td>{{ parametro.nombre }}</td>
|
||||
<td>
|
||||
<div class="field">
|
||||
<input :type="parametro.tipo"
|
||||
:id="'input-' + parametro.id"
|
||||
v-model="control"
|
||||
class="has-text-right">
|
||||
</div>
|
||||
</td>
|
||||
<td class="has-text-centered">
|
||||
<div class="control">
|
||||
<button class="button is-small is-success"
|
||||
@click="modificar"
|
||||
:disabled="!hayCambios">
|
||||
<span class="icon">
|
||||
<i class="fas fa-check"></i>
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
<td class="has-text-centered">
|
||||
<div class="control">
|
||||
<button class="button is-small is-danger"
|
||||
@click="control = parametro.valor"
|
||||
:disabled="!hayCambios">
|
||||
<span class="icon">
|
||||
<i class="fa fa-undo" aria-hidden="true"></i>
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
|
@ -0,0 +1,41 @@
|
|||
<script>
|
||||
import FilaCaracteristica from "../../admin/FilaCaracteristica.vue";
|
||||
import FilaParametro from "./FilaParametro.vue";
|
||||
import { mapActions, mapState } from "vuex";
|
||||
|
||||
export default {
|
||||
name:"ParametrosSeccion",
|
||||
components: { FilaParametro, FilaCaracteristica },
|
||||
methods: {
|
||||
...mapActions("comisiones", ["getParametros"]),
|
||||
},
|
||||
computed: {
|
||||
...mapState("comisiones", ["parametros"]),
|
||||
},
|
||||
async mounted() {
|
||||
await this.getParametros();
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<table class="table is-striped is-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th> Parámetro </th>
|
||||
<th> Valor $ </th>
|
||||
<th> Cambiar </th>
|
||||
<th> Deshacer </th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<fila-parametro v-for="(p,i) in parametros"
|
||||
:key="i"
|
||||
:parametro="p"/>
|
||||
</tbody>
|
||||
</table>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
30
resources/js/components/comunes/Burger.vue
Normal file
30
resources/js/components/comunes/Burger.vue
Normal file
|
@ -0,0 +1,30 @@
|
|||
<script>
|
||||
import { mapMutations, mapState } from "vuex";
|
||||
|
||||
export default {
|
||||
name: "Burger",
|
||||
computed: {
|
||||
...mapState('ui', ["burger_activa"])
|
||||
},
|
||||
methods: {
|
||||
...mapMutations('ui', ["toggleBurger"]),
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<a role="button"
|
||||
class="navbar-burger"
|
||||
:class="{'is-active': burger_activa}"
|
||||
aria-label="menu"
|
||||
aria-expanded="false"
|
||||
data-target="nav-bar"
|
||||
@click="toggleBurger">
|
||||
<span aria-hidden="true"></span>
|
||||
<span aria-hidden="true"></span>
|
||||
<span aria-hidden="true"></span>
|
||||
</a>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
</style>
|
|
@ -1,43 +1,33 @@
|
|||
<template>
|
||||
<nav id="nav-bar" class="navbar is-danger is-fixed-top" role="navigation" aria-label="main navigation">
|
||||
<nav id="nav-bar"
|
||||
class="navbar is-danger is-fixed-top"
|
||||
role="navigation"
|
||||
aria-label="main navigation">
|
||||
<div class="navbar-brand">
|
||||
<a class="navbar-item" href="https://mps.org.uy">
|
||||
<img src="/assets/logoMPS.png" height="28">
|
||||
</a>
|
||||
<div class="navbar-item hide-below-1024" v-if="pedidoDefinido">
|
||||
<p>{{ `Barrio: ${grupo_de_compra.nombre} - Núcleo: ${nombre}` }}</p>
|
||||
</div>
|
||||
<chismosa-dropdown
|
||||
v-if="pedidoDefinido"
|
||||
class="hide-above-1023"
|
||||
ariaControls="mobile"
|
||||
/>
|
||||
<a role="button" class="navbar-burger" :class="{'is-active':burgerActiva}" aria-label="menu"
|
||||
aria-expanded="false" data-target="nav-bar" @click="toggleBurger">
|
||||
<span aria-hidden="true"></span>
|
||||
<span aria-hidden="true"></span>
|
||||
<span aria-hidden="true"></span>
|
||||
<img src="/assets/logoMPS.png" height="28" alt="Logo del MPS">
|
||||
</a>
|
||||
<pedidos-nav-bar-brand v-if="rol === 'barrio'"/>
|
||||
<ollas-nav-bar-brand v-else-if="rol === 'ollas'"/>
|
||||
<admin-nav-bar-brand v-else-if="rol === 'admin_barrio'"/>
|
||||
<comisiones-nav-bar-brand v-else/>
|
||||
<burger/>
|
||||
</div>
|
||||
<div class="navbar-menu" :class="{'is-active':burgerActiva}">
|
||||
<div class="navbar-end">
|
||||
<div v-if="pedidoDefinido" class="navbar-item field has-addons mt-1 mr-3 mb-1">
|
||||
<a class="button is-small has-text-dark-grey" @click.capture="buscar">
|
||||
<span class="icon">
|
||||
<i class="fas fa-search"></i>
|
||||
</span>
|
||||
</a>
|
||||
<input class="input is-small" type="text" placeholder="Harina" v-model="searchString"
|
||||
@keyup.enter="buscar">
|
||||
<div class="navbar-menu" :class="{'is-active': burger_activa}">
|
||||
<div class="navbar-start is-flex is-justify-content-center is-flex-grow-1">
|
||||
<div v-if="mostrarAviso" class="is-absolute-center is-flex is-align-items-center navbar-item">
|
||||
<span class="tag is-warning is-size-6">
|
||||
Monto superado
|
||||
</span>
|
||||
</div>
|
||||
<chismosa-dropdown
|
||||
v-if="pedidoDefinido"
|
||||
class="hide-below-1024"
|
||||
ariaControls="wide">
|
||||
</chismosa-dropdown>
|
||||
</div>
|
||||
<div class="navbar-end">
|
||||
<buscador v-if="pedidoDefinido"/>
|
||||
<chismosa-dropdown v-if="pedidoDefinido"
|
||||
class="hide-below-1024"
|
||||
ariaControls="wide"/>
|
||||
<div class="block navbar-item">
|
||||
<a onclick="event.preventDefault(); document.getElementById('logout-form').submit();"
|
||||
class="text-a">
|
||||
<a @click="logOut" class="text-a">
|
||||
Cerrar sesión
|
||||
</a>
|
||||
</div>
|
||||
|
@ -48,63 +38,38 @@
|
|||
|
||||
<script>
|
||||
import ChismosaDropdown from '../pedidos/ChismosaDropdown.vue';
|
||||
import { mapActions, mapGetters, mapMutations, mapState } from "vuex";
|
||||
import { mapGetters, mapState } from "vuex";
|
||||
import PedidosNavBarBrand from "../pedidos/PedidosNavBarBrand.vue";
|
||||
import ComisionesNavBarBrand from "../comisiones/ComisionesNavBarBrand.vue";
|
||||
import AdminNavBarBrand from "../admin/AdminNavBarBrand.vue";
|
||||
import OllasNavBarBrand from "../ollas/OllasNavBarBrand.vue";
|
||||
import Buscador from "../pedidos/Buscador.vue";
|
||||
import Burger from "./Burger.vue";
|
||||
|
||||
export default {
|
||||
components: { ChismosaDropdown },
|
||||
data() {
|
||||
return {
|
||||
burgerActiva: false,
|
||||
searchString: "",
|
||||
nombreCanasta: "",
|
||||
fechaCanasta: "",
|
||||
}
|
||||
},
|
||||
components: { Burger, Buscador, OllasNavBarBrand, AdminNavBarBrand, ComisionesNavBarBrand, PedidosNavBarBrand, ChismosaDropdown },
|
||||
computed: {
|
||||
...mapGetters('pedido', ["pedidoDefinido"]),
|
||||
...mapState('pedido', ["nombre"]),
|
||||
...mapState('pedido', ["grupo_de_compra"]),
|
||||
},
|
||||
methods: {
|
||||
...mapActions('productos', ["filtrarProductos"]),
|
||||
...mapMutations('ui', ["addMiga", "popUltimaBusqueda"]),
|
||||
toggleBurger() {
|
||||
this.burgerActiva = !this.burgerActiva
|
||||
},
|
||||
buscar() {
|
||||
if (this.burgerActiva)
|
||||
this.toggleBurger();
|
||||
this.filtrarProductos({ filtro: "nombre", valor: this.searchString });
|
||||
this.popUltimaBusqueda();
|
||||
this.addMiga({ nombre: this.searchString });
|
||||
...mapGetters('ollas', ["montoSuperado"]),
|
||||
...mapState('login', ["rol"]),
|
||||
...mapState('ui', ["burger_activa"]),
|
||||
mostrarAviso() {
|
||||
return this.pedidoDefinido && this.rol === 'ollas' && this.montoSuperado;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
logOut() {
|
||||
event.preventDefault();
|
||||
document.getElementById('logout-form').submit();
|
||||
},
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
p.navbar-item:empty {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#nav-bar {
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.text-a {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
@media (max-width: 1023px) {
|
||||
.hide-below-1024 {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1024px) {
|
||||
.hide-above-1023 {
|
||||
display: none !important;
|
||||
}
|
||||
.is-absolute-center {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,12 +1,17 @@
|
|||
<script>
|
||||
import { mapGetters } from "vuex";
|
||||
|
||||
export default {
|
||||
name: "UserInput",
|
||||
computed: {
|
||||
...mapGetters("login", ["estilos"]),
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="field">
|
||||
<label class="label">Usuario</label>
|
||||
<label class="label" :class="estilos.texto">Usuario</label>
|
||||
<div class="field has-addons">
|
||||
<div class="control">
|
||||
<input required class="input" type="text" name="name" placeholder="Usuario">
|
||||
|
|
138
resources/js/components/ollas/CantidadOllas.vue
Normal file
138
resources/js/components/ollas/CantidadOllas.vue
Normal file
|
@ -0,0 +1,138 @@
|
|||
<template>
|
||||
<div class="ollas-box mt-0 py-0">
|
||||
<div class="header-row">
|
||||
<span v-if="visible" class="label">Cantidad de ollas:</span>
|
||||
<span v-else class="label">Cantidad de ollas: {{ control }}</span>
|
||||
</div>
|
||||
<transition name="slide-fade">
|
||||
<div v-if="visible" class="field my-1 has-addons is-justify-content-center">
|
||||
<div class="control">
|
||||
<button class="button is-small" :disabled="control < 1" @click="decrementar">
|
||||
<i class="fas fa-minus" />
|
||||
</button>
|
||||
</div>
|
||||
<div class="control">
|
||||
<input
|
||||
type="number"
|
||||
min="0"
|
||||
v-model.number="control"
|
||||
@input="actualizarDebounced"
|
||||
class="input is-small input-centered"
|
||||
/>
|
||||
</div>
|
||||
<div class="control">
|
||||
<button class="button is-small" @click="incrementar">
|
||||
<i class="fas fa-plus" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</transition>
|
||||
<span class="icon-toggle mt-2 mb-0 pb-0" @click="visible = !visible">
|
||||
<i :class="iconoToggle"/>
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapActions, mapMutations, mapState } from "vuex";
|
||||
|
||||
export default {
|
||||
name: "CantidadOllas",
|
||||
data() {
|
||||
return {
|
||||
control: 0,
|
||||
visible: true,
|
||||
debounceTimer: null,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapState("pedido", ["cantidad_de_ollas"]),
|
||||
iconoToggle() {
|
||||
return this.visible? 'fas fa-angle-up' : 'fas fa-angle-down'
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
cantidad_de_ollas(newVal) {
|
||||
this.control = newVal;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
...mapActions("ollas", ["actualizarCantidadOllas"]),
|
||||
...mapMutations("pedido", ["setCantidadOllas"]),
|
||||
incrementar() {
|
||||
this.control++;
|
||||
this.actualizarDebounced();
|
||||
},
|
||||
decrementar() {
|
||||
if (this.control > 0) {
|
||||
this.control--;
|
||||
this.actualizarDebounced();
|
||||
}
|
||||
},
|
||||
actualizarDebounced() {
|
||||
clearTimeout(this.debounceTimer);
|
||||
const params = { cantidad: this.control };
|
||||
this.debounceTimer = setTimeout(() => {
|
||||
this.setCantidadOllas(params);
|
||||
this.actualizarCantidadOllas(params);
|
||||
}, 500);
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.control = this.cantidad_de_ollas;
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.ollas-box {
|
||||
position: relative;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: -1.5rem;
|
||||
z-index: 2;
|
||||
padding: 1rem 1.5rem;
|
||||
background: white;
|
||||
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
|
||||
border-radius: 10px;
|
||||
width: fit-content;
|
||||
margin: 1rem auto;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.header-row {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.label {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.input-centered {
|
||||
width: 60px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.icon-toggle {
|
||||
cursor: pointer;
|
||||
color: #888;
|
||||
transition: color 0.2s;
|
||||
}
|
||||
.icon-toggle:hover {
|
||||
color: #000;
|
||||
}
|
||||
|
||||
/* Animation */
|
||||
.slide-fade-enter-active,
|
||||
.slide-fade-leave-active {}
|
||||
.slide-fade-enter-from,
|
||||
.slide-fade-leave-to {
|
||||
opacity: 0;
|
||||
transform: translateY(-10px);
|
||||
max-height: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
27
resources/js/components/ollas/OllasBody.vue
Normal file
27
resources/js/components/ollas/OllasBody.vue
Normal file
|
@ -0,0 +1,27 @@
|
|||
<script>
|
||||
import PedidosMain from "../pedidos/PedidosMain.vue";
|
||||
import { mapActions, mapMutations } from "vuex";
|
||||
|
||||
export default {
|
||||
name: "OllasBody",
|
||||
components: { PedidosMain },
|
||||
methods: {
|
||||
...mapActions('pedido', ["getPedidoDeOllas", "getGrupoDeCompra"]),
|
||||
...mapMutations('ui', ["migasOllas"])
|
||||
},
|
||||
async mounted() {
|
||||
await this.getGrupoDeCompra();
|
||||
await this.getPedidoDeOllas();
|
||||
this.migasOllas();
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div id="ollas-body" class="mt-0 mb-6 pb-0 pb-6">
|
||||
<pedidos-main/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
</style>
|
35
resources/js/components/ollas/OllasNavBarBrand.vue
Normal file
35
resources/js/components/ollas/OllasNavBarBrand.vue
Normal file
|
@ -0,0 +1,35 @@
|
|||
<script>
|
||||
import { mapActions, mapGetters, mapMutations, mapState } from "vuex";
|
||||
import ChismosaDropdown from "../pedidos/ChismosaDropdown.vue";
|
||||
|
||||
export default {
|
||||
name: "OllasNavBarBrand",
|
||||
components: { ChismosaDropdown },
|
||||
computed: {
|
||||
...mapGetters('pedido', ["pedidoDefinido"]),
|
||||
...mapGetters('ollas', ["montoTotal"]),
|
||||
...mapState('ui', ["burger_activa"]),
|
||||
...mapState('pedido', ["nombre"]),
|
||||
},
|
||||
methods: {
|
||||
...mapActions('ollas', ["getMontoPorOlla"]),
|
||||
...mapMutations('ui', ["toggleBurger"]),
|
||||
},
|
||||
async mounted() {
|
||||
await this.getMontoPorOlla();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="navbar-item hide-below-1024">
|
||||
<p v-if="pedidoDefinido">{{ `${nombre}` }}</p>
|
||||
<chismosa-dropdown
|
||||
v-if="pedidoDefinido"
|
||||
class="hide-above-1023"
|
||||
ariaControls="mobile"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
</style>
|
|
@ -1,41 +1,25 @@
|
|||
<template>
|
||||
<div id="pedidos-body" class="pb-6 mb-6">
|
||||
<pedido-select v-if="!pedidoDefinido"/>
|
||||
<div v-else>
|
||||
<nav-migas/>
|
||||
<div class="columns">
|
||||
<div class="column" :class="{ 'is-two-thirds-desktop is-hidden-touch': show_chismosa }">
|
||||
<cartel-pedido-aprobado/>
|
||||
<canasta/>
|
||||
</div>
|
||||
<div class="column is-full-touch" v-if="show_chismosa">
|
||||
<chismosa/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<pedidos-main v-else>
|
||||
<template v-slot:cartel>
|
||||
<cartel-pedido-aprobado/>
|
||||
</template>
|
||||
</pedidos-main>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapActions, mapGetters, mapState } from "vuex";
|
||||
import CartelPedidoAprobado from "./CartelPedidoAprobado.vue";
|
||||
import { mapGetters } from "vuex";
|
||||
import PedidoSelect from "./PedidoSelect.vue";
|
||||
import Canasta from "./Canasta.vue";
|
||||
import NavMigas from "./NavMigas.vue";
|
||||
import Chismosa from "./Chismosa.vue";
|
||||
import PedidosMain from "./PedidosMain.vue";
|
||||
import CartelPedidoAprobado from "./CartelPedidoAprobado.vue";
|
||||
|
||||
export default {
|
||||
name: "PedidosBody",
|
||||
components: { Chismosa, NavMigas, CartelPedidoAprobado, PedidoSelect, Canasta },
|
||||
components: { CartelPedidoAprobado, PedidosMain, PedidoSelect },
|
||||
computed: {
|
||||
...mapGetters('pedido', ["pedidoDefinido"]),
|
||||
...mapState('ui', ["show_chismosa"]),
|
||||
},
|
||||
methods: {
|
||||
...mapActions('productos', ["init"]),
|
||||
},
|
||||
async mounted() {
|
||||
await this.init();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
42
resources/js/components/pedidos/Buscador.vue
Normal file
42
resources/js/components/pedidos/Buscador.vue
Normal file
|
@ -0,0 +1,42 @@
|
|||
<script>
|
||||
import { mapActions, mapMutations } from "vuex";
|
||||
|
||||
export default {
|
||||
name: "Buscador",
|
||||
methods: {
|
||||
...mapActions('productos', ["filtrarProductos"]),
|
||||
...mapMutations('ui', ["addMiga", "popUltimaBusqueda", "toggleBurger"]),
|
||||
buscar() {
|
||||
if (this.burger_activa)
|
||||
this.toggleBurger();
|
||||
this.filtrarProductos({ filtro: "nombre", valor: this.searchString });
|
||||
this.popUltimaBusqueda();
|
||||
this.addMiga({ nombre: this.searchString });
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
searchString: "",
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="navbar-item field has-addons mt-1 mr-3 mb-1">
|
||||
<a class="button is-small has-text-dark-grey" @click.capture="buscar">
|
||||
<span class="icon">
|
||||
<i class="fas fa-search"></i>
|
||||
</span>
|
||||
</a>
|
||||
<input class="input is-small"
|
||||
type="text"
|
||||
placeholder="Harina"
|
||||
v-model="searchString"
|
||||
@keyup.enter="buscar">
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
|
@ -2,10 +2,10 @@
|
|||
<div class="dropdown is-right navbar-item" :class="{'is-active': show_chismosa}">
|
||||
<div class="dropdown-trigger">
|
||||
<a class="text-a" aria-haspopup="true" :aria-controls="ariaControls" @click.capture="toggleChismosa">
|
||||
<span class="icon is-small mr-1">
|
||||
<img src="/assets/chismosa.png">
|
||||
</span>
|
||||
<span v-text="'$' + total"></span>
|
||||
<span class="icon is-small mr-1">
|
||||
<img src="/assets/chismosa.png">
|
||||
</span>
|
||||
<span v-text="textoChismosa"/>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -13,7 +13,7 @@
|
|||
|
||||
<script>
|
||||
import Chismosa from './Chismosa.vue'
|
||||
import { mapMutations, mapState } from "vuex";
|
||||
import { mapGetters, mapMutations, mapState } from "vuex";
|
||||
export default {
|
||||
components: {
|
||||
Chismosa
|
||||
|
@ -27,6 +27,13 @@ export default {
|
|||
computed: {
|
||||
...mapState('pedido',["total"]),
|
||||
...mapState('ui',["show_chismosa"]),
|
||||
...mapState('login', ["rol"]),
|
||||
...mapGetters('ollas', ["montoTotal"]),
|
||||
textoChismosa() {
|
||||
if (this.rol === 'ollas')
|
||||
return `$${this.total} / $${this.montoTotal}`;
|
||||
return `$${this.total}`;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
...mapMutations('ui',["toggleChismosa"]),
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<nav class="breadcrumb is-centered has-background-danger-light is-fixed-top"
|
||||
aria-label="breadcrumbs" v-show="visible">
|
||||
<nav class="breadcrumb is-centered has-background-danger-light is-fixed-top mb-0"
|
||||
aria-label="breadcrumbs">
|
||||
<ul class="mt-4">
|
||||
<li v-for="(miga, i) in migas" :key="i" :class="{'is-active': i === migaActiva}">
|
||||
<a @click="clickMiga({ miga: miga })"
|
||||
|
@ -17,15 +17,11 @@ import { mapActions, mapMutations, mapState } from "vuex";
|
|||
|
||||
export default {
|
||||
methods: {
|
||||
...mapActions('productos', ["getProductos"]),
|
||||
...mapActions('ui', ["clickMiga"]),
|
||||
...mapMutations('ui', ["addMiga"]),
|
||||
},
|
||||
computed: {
|
||||
...mapState('ui', ["migas"]),
|
||||
visible() {
|
||||
return this.migas.length > 0;
|
||||
},
|
||||
migaActiva() {
|
||||
return this.migas.length - 1;
|
||||
},
|
||||
|
|
|
@ -88,7 +88,8 @@ export default {
|
|||
const response = await axios.get('/api/subpedidos/',{
|
||||
params: {
|
||||
nombre: nombre,
|
||||
grupo_de_compra: this.grupo_de_compra.id
|
||||
grupo_de_compra: this.grupo_de_compra.id,
|
||||
tipo_pedido: 1,
|
||||
}
|
||||
});
|
||||
this.pedidos = response.data;
|
||||
|
@ -105,7 +106,8 @@ export default {
|
|||
else
|
||||
await this.crearPedido({
|
||||
nombre: this.searchString,
|
||||
grupo_de_compra_id: this.grupo_de_compra.id
|
||||
grupo_de_compra_id: this.grupo_de_compra.id,
|
||||
tipo_id: 1,
|
||||
});
|
||||
},
|
||||
}
|
||||
|
|
43
resources/js/components/pedidos/PedidosMain.vue
Normal file
43
resources/js/components/pedidos/PedidosMain.vue
Normal file
|
@ -0,0 +1,43 @@
|
|||
<script>
|
||||
import { defineComponent } from "vue";
|
||||
import Canasta from "./Canasta.vue";
|
||||
import Chismosa from "./Chismosa.vue";
|
||||
import NavMigas from "./NavMigas.vue";
|
||||
import { mapActions, mapState } from "vuex";
|
||||
import CantidadOllas from "../ollas/CantidadOllas.vue";
|
||||
|
||||
export default defineComponent({
|
||||
name: "PedidosMain",
|
||||
components: { CantidadOllas, NavMigas, Chismosa, Canasta },
|
||||
computed: {
|
||||
...mapState('ui', ["show_chismosa"]),
|
||||
...mapState('login', ["rol"])
|
||||
},
|
||||
methods: {
|
||||
...mapActions('productos', ["init"]),
|
||||
},
|
||||
async mounted() {
|
||||
await this.init();
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<nav-migas/>
|
||||
<cantidad-ollas v-if="rol === 'ollas'"/>
|
||||
<div class="columns">
|
||||
<div class="column" :class="{ 'is-two-thirds-desktop is-hidden-touch': show_chismosa }">
|
||||
<slot name="cartel"></slot>
|
||||
<canasta/>
|
||||
</div>
|
||||
<div class="column is-full-touch" v-if="show_chismosa">
|
||||
<chismosa/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
32
resources/js/components/pedidos/PedidosNavBarBrand.vue
Normal file
32
resources/js/components/pedidos/PedidosNavBarBrand.vue
Normal file
|
@ -0,0 +1,32 @@
|
|||
<script>
|
||||
import { mapGetters, mapMutations, mapState } from "vuex";
|
||||
import ChismosaDropdown from "./ChismosaDropdown.vue";
|
||||
|
||||
export default {
|
||||
name: "PedidosNavBarBrand",
|
||||
components: { ChismosaDropdown },
|
||||
computed: {
|
||||
...mapGetters('pedido', ["pedidoDefinido"]),
|
||||
...mapState('pedido', ["nombre", "grupo_de_compra"]),
|
||||
...mapState('ui', ["burger_activa"])
|
||||
},
|
||||
methods: {
|
||||
...mapMutations('ui', ["toggleBurger"]),
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="navbar-item hide-below-1024">
|
||||
<p v-if="pedidoDefinido">
|
||||
{{ `Barrio: ${grupo_de_compra.nombre} - Núcleo: ${nombre}` }}
|
||||
</p>
|
||||
<chismosa-dropdown
|
||||
v-if="pedidoDefinido"
|
||||
class="hide-above-1023"
|
||||
ariaControls="mobile"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
</style>
|
|
@ -117,6 +117,7 @@ export default {
|
|||
this.notas_warning_visible = true;
|
||||
return;
|
||||
}
|
||||
this.notas_warning_visible = false;
|
||||
await this.modificarChismosa({
|
||||
producto_id: this.producto_id,
|
||||
cantidad: this.cantidadControl,
|
||||
|
|
2
resources/js/store/index.js
vendored
2
resources/js/store/index.js
vendored
|
@ -6,6 +6,7 @@ import login from "./modules/login";
|
|||
import pedido from "./modules/pedido";
|
||||
import productos from "./modules/productos";
|
||||
import ui from "./modules/ui";
|
||||
import ollas from "./modules/ollas";
|
||||
|
||||
Vue.use(Vuex);
|
||||
|
||||
|
@ -17,5 +18,6 @@ export default new Vuex.Store({
|
|||
pedido,
|
||||
productos,
|
||||
ui,
|
||||
ollas,
|
||||
},
|
||||
});
|
||||
|
|
3
resources/js/store/modules/admin.js
vendored
3
resources/js/store/modules/admin.js
vendored
|
@ -61,6 +61,9 @@ const getters = {
|
|||
grupoDeCompraDefinido() {
|
||||
return state.lastFetch !== null;
|
||||
},
|
||||
barrio() {
|
||||
return state.nombre?.replace('_admin','') ?? '';
|
||||
},
|
||||
hayPedidos() {
|
||||
return state.pedidos?.length > 0;
|
||||
},
|
||||
|
|
26
resources/js/store/modules/comisiones.js
vendored
26
resources/js/store/modules/comisiones.js
vendored
|
@ -3,6 +3,7 @@ import axios from "axios";
|
|||
const state = {
|
||||
lastFetch: undefined,
|
||||
grupos_de_compra: [],
|
||||
parametros: [],
|
||||
};
|
||||
|
||||
const mutations = {
|
||||
|
@ -10,6 +11,15 @@ const mutations = {
|
|||
state.grupos_de_compra = data;
|
||||
state.lastFetch = new Date();
|
||||
},
|
||||
setParametros(state, parametros) {
|
||||
state.parametros = parametros;
|
||||
state.parametros.forEach(
|
||||
p => p.valor = Number.parseInt(p.valor)
|
||||
);
|
||||
},
|
||||
actualizarParametro(state, { parametro_id, valor }) {
|
||||
state.parametros.find(p => p.id === parametro_id).valor = valor;
|
||||
},
|
||||
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);
|
||||
|
@ -22,6 +32,22 @@ const actions = {
|
|||
const response = await axios.get('/api/grupos-de-compra/saldos');
|
||||
commit('setGruposDeCompra', response.data);
|
||||
},
|
||||
async getParametros({ commit }) {
|
||||
const response = await axios.get('/api/parametros');
|
||||
commit('setParametros', response.data);
|
||||
},
|
||||
async cambiarParametro({ commit, dispatch }, { parametro_id, valor }) {
|
||||
try {
|
||||
await axios.put(
|
||||
`/comisiones/parametros/${parametro_id}`,
|
||||
{ valor: valor }
|
||||
);
|
||||
commit('actualizarParametro', { parametro_id, valor });
|
||||
dispatch("ui/toast", { mensaje: 'Parámetro modificado con éxito' }, { root: true });
|
||||
} catch (error) {
|
||||
dispatch("ui/error", { error: error }, { root: true });
|
||||
}
|
||||
},
|
||||
async setSaldo({ commit, dispatch }, { gdc_id, saldo }) {
|
||||
try {
|
||||
await axios.post(
|
||||
|
|
83
resources/js/store/modules/login.js
vendored
83
resources/js/store/modules/login.js
vendored
|
@ -50,6 +50,14 @@ const getters = {
|
|||
textos() {
|
||||
let rol = getters.urlRol();
|
||||
switch (rol) {
|
||||
case 'pedido':
|
||||
return {
|
||||
titulo: "Pedidos MPS",
|
||||
subtitlo: "aplicación de pedidos",
|
||||
password: "Contraseña",
|
||||
ayuda: "Si no la sabés, consultá a la comisión informática",
|
||||
label: "Seleccioná tu región"
|
||||
};
|
||||
case 'admin':
|
||||
return {
|
||||
titulo: "Administración de Pedidos MPS",
|
||||
|
@ -66,11 +74,11 @@ const getters = {
|
|||
ayuda: "Si no la sabés, consultá a la comisión informática",
|
||||
label: "Usuario"
|
||||
};
|
||||
case 'pedido':
|
||||
case 'ollas':
|
||||
return {
|
||||
titulo: "Pedidos MPS",
|
||||
subtitlo: "aplicación de pedidos",
|
||||
password: "Contraseña",
|
||||
titulo: "Ollas MPS",
|
||||
subtitlo: "aplicación de pedidos de ollas",
|
||||
password: "Contraseña de ollas del barrio",
|
||||
ayuda: "Si no la sabés, consultá a la comisión informática",
|
||||
label: "Seleccioná tu región"
|
||||
};
|
||||
|
@ -81,23 +89,29 @@ const getters = {
|
|||
estilos() {
|
||||
let rol = getters.urlRol();
|
||||
switch (rol) {
|
||||
case 'admin':
|
||||
return {
|
||||
fondo: "has-background-danger",
|
||||
texto: "has-text-white",
|
||||
botones: "is-warning",
|
||||
};
|
||||
case 'comisiones':
|
||||
return {
|
||||
fondo: "has-background-warning",
|
||||
texto: "",
|
||||
botones: "is-dark"
|
||||
};
|
||||
case 'pedido':
|
||||
return {
|
||||
fondo: "",
|
||||
texto: "",
|
||||
botones: "is-danger"
|
||||
botones: "danger-dark-button"
|
||||
};
|
||||
case 'admin':
|
||||
return {
|
||||
fondo: "has-background-danger-dark",
|
||||
texto: "has-text-white",
|
||||
botones: "is-dark",
|
||||
};
|
||||
case 'comisiones':
|
||||
return {
|
||||
fondo: "has-background-grey",
|
||||
texto: "has-text-white",
|
||||
botones: "danger-dark-button",
|
||||
};
|
||||
case 'ollas':
|
||||
return {
|
||||
fondo: "has-background-dark",
|
||||
texto: "has-text-white",
|
||||
botones: "danger-dark-button",
|
||||
};
|
||||
default:
|
||||
throw new Error("Url inválida");
|
||||
|
@ -106,27 +120,48 @@ const getters = {
|
|||
opcionesLogin() {
|
||||
let rol = getters.urlRol();
|
||||
switch (rol) {
|
||||
case 'pedido':
|
||||
return [
|
||||
{ nombre: "Administración", href: "/admin" },
|
||||
{ nombre: "Ollas", href: "/ollas" },
|
||||
{ nombre: "Comisiones", href: "/comisiones" },
|
||||
];
|
||||
case 'admin':
|
||||
return [
|
||||
{ nombre: "Pedidos", href: "/" },
|
||||
{ nombre: "Comisiones", href: "/comisiones" }
|
||||
{ nombre: "Ollas", href: "/ollas" },
|
||||
{ nombre: "Comisiones", href: "/comisiones" },
|
||||
];
|
||||
case 'comisiones':
|
||||
return [
|
||||
{ nombre: "Pedidos", href: "/" },
|
||||
{ nombre: "Administración", href: "/admin" }
|
||||
];
|
||||
case 'pedido':
|
||||
return [
|
||||
{ nombre: "Ollas", href: "/ollas" },
|
||||
{ nombre: "Administración", href: "/admin" },
|
||||
{ nombre: "Comisiones", href: "/comisiones" }
|
||||
];
|
||||
case 'ollas':
|
||||
return [
|
||||
{ nombre: "Pedidos", href: "/" },
|
||||
{ nombre: "Administración", href: "/admin" },
|
||||
{ nombre: "Comisiones", href: "/comisiones" },
|
||||
];
|
||||
default:
|
||||
throw new Error("Url inválida");
|
||||
}
|
||||
},
|
||||
nombre() {
|
||||
return `${state.grupo_de_compra_elegido}${ getters.urlRol() === 'admin' ? '_admin' : ''}`;
|
||||
let rol = getters.urlRol();
|
||||
switch (rol) {
|
||||
case 'pedido':
|
||||
return state.grupo_de_compra_elegido;
|
||||
case 'admin':
|
||||
return `${state.grupo_de_compra_elegido}_admin`;
|
||||
case 'ollas':
|
||||
return `${state.grupo_de_compra_elegido}_ollas`;
|
||||
case 'comisiones':
|
||||
return "";
|
||||
default:
|
||||
throw new Error("Url inválida");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
|
45
resources/js/store/modules/ollas.js
vendored
Normal file
45
resources/js/store/modules/ollas.js
vendored
Normal file
|
@ -0,0 +1,45 @@
|
|||
import axios from "axios";
|
||||
|
||||
const state = {
|
||||
monto_por_olla: undefined,
|
||||
};
|
||||
|
||||
const mutations = {
|
||||
setMontoPorOlla(state, parametros) {
|
||||
state.monto_por_olla = Number.parseInt(parametros.find(p => p.id === 'monto-olla').valor);
|
||||
},
|
||||
};
|
||||
|
||||
const actions = {
|
||||
async getMontoPorOlla({ commit }) {
|
||||
const response = await axios.get('/api/parametros');
|
||||
commit('setMontoPorOlla', response.data);
|
||||
},
|
||||
async actualizarCantidadOllas({ rootState, dispatch }, { cantidad: cantidad}) {
|
||||
try {
|
||||
const barrio = rootState.pedido.grupo_de_compra.id;
|
||||
const params = { cantidad : cantidad };
|
||||
await axios.put(`/ollas/${barrio}/cantidad`, params);
|
||||
dispatch("ui/toast", { mensaje: 'Cantidad modificada con éxito' }, { root: true });
|
||||
} catch (error) {
|
||||
dispatch("ui/error", { error: { message: "Cantidad inválida" } }, { root: true });
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const getters = {
|
||||
montoTotal(state, _, rootState) {
|
||||
return state.monto_por_olla * rootState.pedido.cantidad_de_ollas;
|
||||
},
|
||||
montoSuperado: (_, getters, rootState) => {
|
||||
return rootState.pedido.total > getters.montoTotal;
|
||||
}
|
||||
};
|
||||
|
||||
export default {
|
||||
namespaced: true,
|
||||
state,
|
||||
mutations,
|
||||
actions,
|
||||
getters,
|
||||
};
|
80
resources/js/store/modules/pedido.js
vendored
80
resources/js/store/modules/pedido.js
vendored
|
@ -3,16 +3,17 @@ import axios from "axios";
|
|||
const state = {
|
||||
lastFetch: null,
|
||||
grupo_de_compra: null,
|
||||
pedido_id: null,
|
||||
nombre: null,
|
||||
productos: null,
|
||||
aprobado: null,
|
||||
total: null,
|
||||
total_transporte: null,
|
||||
cantidad_transporte: null,
|
||||
total_sin_devoluciones: null,
|
||||
devoluciones_total: null,
|
||||
devoluciones_notas: null,
|
||||
pedido_id: 0,
|
||||
nombre: "",
|
||||
productos: [],
|
||||
aprobado: false,
|
||||
total: 0,
|
||||
total_transporte: 0,
|
||||
cantidad_transporte: 0,
|
||||
total_sin_devoluciones: 0,
|
||||
devoluciones_total: 0,
|
||||
devoluciones_notas: "",
|
||||
cantidad_de_ollas: 0,
|
||||
};
|
||||
|
||||
const mutations = {
|
||||
|
@ -25,13 +26,27 @@ const mutations = {
|
|||
state.nombre = pedido.nombre;
|
||||
state.productos = pedido.productos;
|
||||
state.aprobado = pedido.aprobado;
|
||||
state.total = pedido.total;
|
||||
state.total_transporte = pedido.total_transporte;
|
||||
state.cantidad_transporte = pedido.cantidad_transporte;
|
||||
state.total_sin_devoluciones = pedido.total_sin_devoluciones;
|
||||
state.devoluciones_total = pedido.devoluciones_total;
|
||||
state.total = Number.parseFloat(pedido.total.replace(',',''));
|
||||
state.total_transporte = Number.parseInt(pedido.total_transporte?.replace(',',''));
|
||||
state.cantidad_transporte = Number.parseInt(pedido.cantidad_transporte?.replace(',',''));
|
||||
state.total_sin_devoluciones = Number.parseFloat(pedido.total_sin_devoluciones?.replace(',',''));
|
||||
state.devoluciones_total = Number.parseFloat(pedido.devoluciones_total?.replace(',',''));
|
||||
state.devoluciones_notas = pedido.devoluciones_notas;
|
||||
},
|
||||
setPedidoDeOllas(state, pedido) {
|
||||
state.lastFetch = new Date();
|
||||
state.pedido_id = pedido.id;
|
||||
state.nombre = pedido.nombre;
|
||||
state.productos = pedido.productos;
|
||||
state.total = Number.parseFloat(pedido.total.replace(',',''));
|
||||
state.cantidad_de_ollas = Number.parseInt(pedido.cantidad_de_ollas);
|
||||
delete state.aprobado;
|
||||
delete state.total_transporte;
|
||||
delete state.cantidad_transporte;
|
||||
delete state.total_sin_devoluciones;
|
||||
delete state.devoluciones_total;
|
||||
delete state.devoluciones_notas;
|
||||
},
|
||||
reset(state) {
|
||||
state.lastFetch = null;
|
||||
state.pedido_id = null;
|
||||
|
@ -44,6 +59,10 @@ const mutations = {
|
|||
state.total_sin_devoluciones = null;
|
||||
state.devoluciones_total = null;
|
||||
state.devoluciones_notas = null;
|
||||
},
|
||||
setCantidadOllas(state, { cantidad }) {
|
||||
if (cantidad >= 0)
|
||||
state.cantidad_de_ollas = cantidad;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -53,28 +72,25 @@ const actions = {
|
|||
commit('setGrupoDeCompra', response.data.grupo_de_compra);
|
||||
},
|
||||
async guardarSesion(_, { pedido_id }) {
|
||||
await axios.post("/pedido/sesion", { id: pedido_id });
|
||||
const body = { id: pedido_id };
|
||||
await axios.post("/pedido/sesion", body);
|
||||
},
|
||||
async crearPedido({ commit, dispatch }, { nombre, grupo_de_compra_id }) {
|
||||
const response = await axios.post("/api/subpedidos", {
|
||||
nombre: nombre,
|
||||
grupo_de_compra_id: grupo_de_compra_id
|
||||
});
|
||||
async crearPedido({ commit, dispatch }, { nombre, grupo_de_compra_id, tipo_id }) {
|
||||
const body = { nombre, grupo_de_compra_id, tipo_id };
|
||||
const response = await axios.post("/api/subpedidos", body);
|
||||
dispatch("guardarSesion", { pedido_id: response.data.data.id});
|
||||
commit('setPedido', response.data.data);
|
||||
},
|
||||
async elegirPedido({ commit, dispatch }, { pedido_id }) {
|
||||
const response = await axios.get(`/api/subpedidos/${pedido_id}`);
|
||||
dispatch("guardarSesion", { pedido_id: pedido_id})
|
||||
const body = { pedido_id: pedido_id};
|
||||
dispatch("guardarSesion", body)
|
||||
commit('setPedido', response.data.data);
|
||||
},
|
||||
async modificarChismosa({ commit, dispatch }, { producto_id, cantidad, notas }) {
|
||||
const body = { cantidad: cantidad, producto_id: producto_id, notas: notas };
|
||||
try {
|
||||
const response = await axios.post("/api/subpedidos/" + state.pedido_id + "/sync", {
|
||||
cantidad: cantidad,
|
||||
producto_id: producto_id,
|
||||
notas: notas,
|
||||
});
|
||||
const response = await axios.post("/api/subpedidos/" + state.pedido_id + "/sync", body);
|
||||
commit('setPedido', response.data.data);
|
||||
dispatch("ui/toast", { mensaje: 'Pedido modificado con éxito' }, { root: true });
|
||||
} catch (error) {
|
||||
|
@ -82,11 +98,9 @@ const actions = {
|
|||
}
|
||||
},
|
||||
async modificarDevoluciones({ commit, dispatch }, { monto, notas }) {
|
||||
const body = { total: monto, notas: notas };
|
||||
try {
|
||||
const response = await axios.post("api/subpedidos/" + state.pedido_id + "/sync_devoluciones", {
|
||||
total: monto,
|
||||
notas: notas,
|
||||
});
|
||||
const response = await axios.post("api/subpedidos/" + state.pedido_id + "/sync_devoluciones", body);
|
||||
commit('setPedido', response.data.data);
|
||||
dispatch("ui/toast", { mensaje: 'Devoluciones modificadas con éxito' }, { root: true });
|
||||
} catch (error) {
|
||||
|
@ -99,6 +113,10 @@ const actions = {
|
|||
dispatch("ui/resetear", null, { root: true });
|
||||
commit('reset');
|
||||
},
|
||||
async getPedidoDeOllas({ commit }) {
|
||||
const response = await axios.get(`/ollas/${state.grupo_de_compra.id}`);
|
||||
commit('setPedidoDeOllas', response.data);
|
||||
},
|
||||
};
|
||||
|
||||
const getters = {
|
||||
|
|
17
resources/js/store/modules/ui.js
vendored
17
resources/js/store/modules/ui.js
vendored
|
@ -2,6 +2,7 @@ const state = {
|
|||
show_chismosa: false,
|
||||
show_devoluciones: false,
|
||||
show_tags: true,
|
||||
burger_activa: false,
|
||||
tags_interactuada: false,
|
||||
migas: [{ nombre: 'Pedidos', action: 'pedido/resetear' }],
|
||||
canasta_actual: null,
|
||||
|
@ -18,10 +19,12 @@ const mutations = {
|
|||
state.show_devoluciones = !state.show_devoluciones;
|
||||
},
|
||||
toggleTags(state, manual) {
|
||||
if (manual)
|
||||
state.tags_interactuada = true;
|
||||
state.tags_interactuada = manual;
|
||||
state.show_tags = !state.show_tags;
|
||||
},
|
||||
toggleBurger(state) {
|
||||
state.burger_activa = !state.burger_activa;
|
||||
},
|
||||
addMiga(state, miga) {
|
||||
state.migas.push(miga);
|
||||
},
|
||||
|
@ -32,7 +35,10 @@ const mutations = {
|
|||
reset(state) {
|
||||
state.show_chismosa = false;
|
||||
state.show_devoluciones = false;
|
||||
}
|
||||
},
|
||||
migasOllas(state) {
|
||||
state.migas.reverse().pop();
|
||||
},
|
||||
};
|
||||
|
||||
const actions = {
|
||||
|
@ -50,7 +56,7 @@ const actions = {
|
|||
}
|
||||
|
||||
dispatch(miga.action, miga.arguments ?? null, { root: true });
|
||||
state.migas = dropWhile(state.migas.reverse(),(m => m.nombre !== miga.nombre)).reverse();
|
||||
state.migas = dropWhile(state.migas.reverse(), (m => m.nombre !== miga.nombre)).reverse();
|
||||
},
|
||||
toast(_, { mensaje }) {
|
||||
return window.bulmaToast.toast({
|
||||
|
@ -69,6 +75,9 @@ const actions = {
|
|||
resetear({ commit }) {
|
||||
commit("reset");
|
||||
},
|
||||
migasOllas({ commit }) {
|
||||
commit("migasOllas");
|
||||
},
|
||||
};
|
||||
|
||||
export default {
|
||||
|
|
37
resources/sass/app.scss
vendored
37
resources/sass/app.scss
vendored
|
@ -13,12 +13,12 @@ html, body {
|
|||
height: 100%;
|
||||
}
|
||||
|
||||
form, #root, #login-form {
|
||||
form, #root, #login-form, #main {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
main.has-top-padding {
|
||||
padding-top: 4.5rem !important;
|
||||
padding-top: 4rem !important;
|
||||
}
|
||||
|
||||
table.table td {
|
||||
|
@ -35,14 +35,39 @@ table.table td {
|
|||
z-index: 30;
|
||||
}
|
||||
|
||||
#main {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.container {
|
||||
max-height: 100% !important;
|
||||
}
|
||||
|
||||
.danger-dark-button {
|
||||
background-color: $danger-dark;
|
||||
border-color: transparent;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
p.navbar-item:empty {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#nav-bar {
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.text-a {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
@media (max-width: 1023px) {
|
||||
.hide-below-1024 {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1024px) {
|
||||
.hide-above-1023 {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
/*
|
||||
Author: Aseem Lalfakawma <alalfakawma.github.io>
|
||||
This SCSS mixin will allow sizing of table columns in Bulma CSS Framework.
|
||||
|
|
|
@ -48,4 +48,6 @@ Route::middleware('api')->group(function() {
|
|||
Route::prefix('productos')->group(function () {
|
||||
Route::get('/','Api\ProductoController@index');
|
||||
});
|
||||
|
||||
Route::get('/parametros', 'ComisionesController@obtenerParametros');
|
||||
});
|
||||
|
|
|
@ -24,6 +24,7 @@ Auth::routes(['register' => false]);
|
|||
Route::get('/', 'RouteController@home')->name('home');
|
||||
|
||||
Route::middleware(['auth'])->group(function () {
|
||||
Route::get('/user', 'UserController@user')->name('user');
|
||||
Route::get('/user/rol', 'UserController@rol')->name('user.rol');
|
||||
Route::get('/user/grupo_de_compra', 'UserController@grupoDeCompra');
|
||||
});
|
||||
|
@ -52,7 +53,17 @@ Route::middleware(['auth', 'role:comision'])->group( function() {
|
|||
Route::get('/comisiones/pedidos/descargar', 'ComisionesController@descargarPedidos')->name('comisiones.pedidos.descargar');
|
||||
Route::get('/comisiones/pedidos/notas', 'ComisionesController@descargarNotas')->name('comisiones.pedidos.descargar');
|
||||
Route::get('/comisiones/pedidos/pdf', 'ComisionesController@pdf')->name('comisiones.pedidos.pdf');
|
||||
Route::get('/comisiones/pedidos/ollas', 'ComisionesController@descargarPedidosDeOllas')->name('comisiones.pedidos.ollas');
|
||||
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.saldos');
|
||||
Route::put('/comisiones/parametros/{parametro_id}', 'ComisionesController@modificarParametros');
|
||||
});
|
||||
|
||||
Route::get('/ollas/login', 'OllasController@show')->name('ollas.login');
|
||||
|
||||
Route::middleware(['auth', 'role:ollas'])->prefix('ollas')->group( function() {
|
||||
Route::get('/', 'RouteController@main')->name('ollas');
|
||||
Route::get('/{gdc}','OllasController@pedido');
|
||||
Route::put('/{gdc}/cantidad','OllasController@actualizarCantidadOllas');
|
||||
});
|
||||
|
|
Loading…
Add table
Reference in a new issue