Compare commits

..

No commits in common. "b0ae4abc4d26a07bad96f02960a717885c795912" and "70bbaad3c7fb6e5bc72288917bab830ab939dcf4" have entirely different histories.

33 changed files with 392 additions and 480 deletions

View file

@ -1,72 +0,0 @@
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
class AgregarEsBonoAPedidosAprobados extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'command:AgregarEsBonoAPedidosAprobados';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Agrega "producto_bono" a la view PedidosAprobados';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return int
*/
public function handle(): int
{
DB::statement("
ALTER VIEW pedidos_aprobados(
grupo_de_compra_id,
grupo_de_compra_nombre,
grupo_de_compra_region,
producto_id,
producto_nombre,
producto_precio,
cantidad_pedida,
total_por_producto,
producto_es_bono
) AS
SELECT
g.id as grupo_de_compra_id,
g.nombre as grupo_de_compra_nombre,
g.region as grupo_de_compra_region,
pr.id AS producto_id,
pr.nombre as producto_nombre,
pr.precio as producto_precio,
SUM(ps.cantidad) as cantidad_pedida,
pr.precio*SUM(ps.cantidad) as total_por_producto,
pr.bono
FROM grupos_de_compra g
JOIN subpedidos s ON (s.grupo_de_compra_id = g.id AND s.aprobado=1)
JOIN producto_subpedido ps ON (ps.subpedido_id = s.id)
JOIN productos pr ON (pr.id = ps.producto_id)
GROUP BY
g.id, g.nombre, pr.id, pr.nombre
;");
return 0;
}
}

View file

@ -36,7 +36,7 @@ class CrearPedidosAprobadosViewCommand extends Command
* *
* @return int * @return int
*/ */
public function handle(): int public function handle()
{ {
DB::statement(" DB::statement("
CREATE OR REPLACE VIEW pedidos_aprobados CREATE OR REPLACE VIEW pedidos_aprobados

View file

@ -5,15 +5,12 @@ namespace App\Filtros;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Builder;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Throwable;
use TypeError;
class Filtro extends Model class Filtro extends Model
{ {
protected Request $request; protected $request;
protected $builder; protected $builder;
protected array $MENSAJES_ERROR = [ protected $MENSAJES_ERROR = [
'ARGUMENTO' => 'Argumento inválido para el parámetro %s. Revise la documentación.' 'ARGUMENTO' => 'Argumento inválido para el parámetro %s. Revise la documentación.'
]; ];
@ -25,10 +22,10 @@ class Filtro extends Model
/** /**
* Apply all existing filters, if available. * Apply all existing filters, if available.
* *
* @param Builder $builder * @param \Illuminate\Database\Eloquent\Builder $builder
* @return Builder * @return \Illuminate\Database\Eloquent\Builder
*/ */
public function aplicar(Builder $builder): Builder public function aplicar(Builder $builder)
{ {
$this->builder = $builder; $this->builder = $builder;
@ -50,11 +47,11 @@ class Filtro extends Model
//Llamar métodos sin argumentos //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 //Llamar métodos con argumentos
try { try {
$this->$metodo($valor); $this->$metodo($valor);
} catch (Throwable $th) { } catch (\Throwable $th) {
if (is_a($th,'TypeError') ) { throw new HttpException(400, sprintf($this->MENSAJES_ERROR['ARGUMENTO'],$filtro)); } if (is_a($th,'TypeError') ) { throw new HttpException(400, sprintf($this->MENSAJES_ERROR['ARGUMENTO'],$filtro)); }
throw $th; throw $th;
} }
@ -66,7 +63,7 @@ class Filtro extends Model
//Buscar un término en el nombre //Buscar un término en el nombre
public function nombre(String $valor) 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') public function alfabetico(String $order = 'asc')

View file

@ -1,6 +1,7 @@
<?php <?php
namespace App\Filtros; namespace App\Filtros;
use Illuminate\Database\Eloquent\Builder;
class FiltroDeProducto extends Filtro { class FiltroDeProducto extends Filtro {
@ -9,4 +10,4 @@ class FiltroDeProducto extends Filtro {
$this->builder->where('categoria', $valor); $this->builder->where('categoria', $valor);
} }
} }

View file

@ -2,7 +2,7 @@
namespace App\Filtros; namespace App\Filtros;
use TypeError; use Illuminate\Database\Eloquent\Model;
class FiltroDeSubpedido extends Filtro class FiltroDeSubpedido extends Filtro
{ {

View file

@ -2,15 +2,13 @@
namespace App; namespace App;
use App\Helpers\CsvHelper;
use App\Helpers\PdfHelper;
use App\Helpers\TransporteHelper; use App\Helpers\TransporteHelper;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log; use League\Csv\CannotInsertRecord;
use League\Csv\Reader;
use League\Csv\Writer;
use Mpdf\Mpdf;
class GrupoDeCompra extends Model class GrupoDeCompra extends Model
{ {
@ -19,12 +17,12 @@ class GrupoDeCompra extends Model
protected $table = 'grupos_de_compra'; protected $table = 'grupos_de_compra';
protected $hidden = ['password']; protected $hidden = ['password'];
public function subpedidos(): HasMany public function subpedidos()
{ {
return $this->hasMany(Subpedido::class); return $this->hasMany('App\Subpedido');
} }
public function toggleDevoluciones(): bool public function toggleDevoluciones()
{ {
$this->devoluciones_habilitadas = !$this->devoluciones_habilitadas; $this->devoluciones_habilitadas = !$this->devoluciones_habilitadas;
$this->save(); $this->save();
@ -93,52 +91,25 @@ class GrupoDeCompra extends Model
return TransporteHelper::totalTransporte($this->totalCentralesQuePaganTransporte()); return TransporteHelper::totalTransporte($this->totalCentralesQuePaganTransporte());
} }
/** public function cantidadTransporte()
* @return int
* Calcula la cantidad de bonos de transporte del barrio
*/
public function cantidadTransporte(): int
{ {
return TransporteHelper::cantidadTransporte($this->totalCentralesQuePaganTransporte()); return TransporteHelper::cantidadTransporte($this->totalCentralesQuePaganTransporte());
} }
public function exportarPedidosAPdf() public function exportarPlanillasAPdf()
{ {
$subpedidos = $this->pedidosAprobados(); $subpedidos = $this->pedidosAprobados();
PdfHelper::exportarPedidos($this->nombre . '.pdf', $subpedidos); //generar pdf
} $mpdf = new Mpdf();
foreach ($subpedidos as $subpedido) {
function pedidoParaPdf(): array $tabla = $subpedido->generarHTML();
{ // agregar la tabla al pdf en una nueva página
$productos = $this->productosPedidos(true, true); $mpdf->WriteHTML($tabla);
$pedido = []; $mpdf->AddPage();
$pedido['productos'] = [];
$pedido['nombre'] = $this->nombre;
foreach ($productos as $producto) {
$productoParaPdf = [];
$productoParaPdf['pivot'] = [];
$productoParaPdf['nombre'] = $producto->producto_nombre;
$productoParaPdf['pivot']['cantidad'] = $producto->cantidad_pedida;
$productoParaPdf['pivot']['notas'] = false;
$productoParaPdf['bono'] = $producto->producto_es_bono;
$pedido['productos'][] = $productoParaPdf;
} }
$filename = $this->nombre . '.pdf';
return $pedido; // imprimir el pdf
} $mpdf->Output($filename, "D");
public function generarHTML()
{
$view = view("pdfgen.pedido_tabla", ["pedido" => $this->pedidoParaPdf()]);
return $view->render();
}
public static function exportarPedidosBarrialesAPdf()
{
$barrios = GrupoDeCompra::barriosMenosPrueba()->get();
PdfHelper::exportarPedidos('pedidos_por_barrio.pdf', $barrios);
} }
static function filaVacia(string $product, int $columns): array static function filaVacia(string $product, int $columns): array
@ -151,7 +122,7 @@ class GrupoDeCompra extends Model
} }
//Asume que los productos están gruadados en orden de fila //Asume que los productos están gruadados en orden de fila
public static function obtenerTemplateDeFilasVacias(int $columns): array public static function obtenerTemplateDeFilasVacias(int $columns)
{ {
$productosFilaID = Producto::productosFilaID(); $productosFilaID = Producto::productosFilaID();
$productosIDNombre = Producto::productosIDNombre(); $productosIDNombre = Producto::productosIDNombre();
@ -164,53 +135,104 @@ class GrupoDeCompra extends Model
$template[$fila] = GrupoDeCompra::filaVacia($productosIDNombre[$id], $columns); $template[$fila] = GrupoDeCompra::filaVacia($productosIDNombre[$id], $columns);
$num_fila = $fila + 1; $num_fila = $fila + 1;
} }
$template[TransporteHelper::filaTransporte()] = GrupoDeCompra::filaVacia("Bonos de transporte", $columns); $template[GrupoDeCompra::obtenerFilaDeBonoTransporte()] = GrupoDeCompra::filaVacia("Bonos de transporte", $columns);
return $template; return $template;
} }
private static function obtenerFilaDeBonoTransporte()
{
$csv = Reader::createFromPath(resource_path('csv/productos.csv'), 'r');
$csv->setDelimiter("|");
$csv->setEnclosure("'");
$registros = $csv->getRecords();
foreach ($registros as $key => $registro)
if ($registro[0] == 'T') return $key;
throw new Exception('No hay bono de transporte');
}
private function totalPedidosSinBonos()
{
$total = 0;
foreach ($this->pedidosAprobados() as $pedido) {
$total += ceil($pedido->totalSinBonos());
}
return $total;
}
public function calcularCantidadBDT()
{
$total = 0;
foreach ($this->pedidosAprobados() as $pedido) {
$total += $pedido->totalParaTransporte();
}
return ceil($total / 500);
}
public function totalBonosBarriales()
{
$total = 0;
$bonoBarrial = Producto::where('nombre', 'LIKE', '%barrial%')->first();
if ($bonoBarrial) {
$pedidos = $this->pedidosAprobados();
foreach ($pedidos as $pedido) {
$bonoPedido = $pedido->productos()->find($bonoBarrial["id"]);
if ($bonoPedido) {
$total += $bonoPedido["pivot"]["total"];
}
}
}
return $total;
}
public function exportarPedidoEnCSV() public function exportarPedidoEnCSV()
{ {
$records = $this->generarColumnaCantidades(); $records = $this->generarColumnaCantidades();
try {
CsvHelper::generarCsv('csv/exports/' . $this->nombre . '.csv', $records); $writer = Writer::createFromPath(resource_path('csv/exports/' . $this->nombre . '.csv'), 'w');
$writer->insertAll($records);
} catch (CannotInsertRecord $e) {
var_export($e->getRecords());
}
} }
public function generarColumnaCantidades(): array public function generarColumnaCantidades()
{ {
$productos_en_pedido = $this->productosPedidos(); $productos_en_pedido = DB::table('pedidos_aprobados')->where('grupo_de_compra_id', $this->id)->get()->keyBy('producto_id');
//si no hay pedidos aprobados, salir //si no hay pedidos aprobados, salir
if ($productos_en_pedido->count() == 0) { if ($productos_en_pedido->count() == 0) {
Log::debug("El grupo de compra " . $this->nombre . " no tiene pedidos aprobados."); \Log::debug("El grupo de compra " . $this->nombre . " no tiene pedidos aprobados.");
return []; return [];
} }
$records = $this->obtenerTemplateDeFilasVacias(1); $records = $this->obtenerTemplateDeFilasVacias(1);
$productos_id_fila = Producto::productosIDFila(); $productos_id_fila = Producto::productosIdFila();
foreach ($productos_en_pedido as $id => $producto_pedido) { foreach ($productos_en_pedido as $id => $producto_pedido) {
$fila = $productos_id_fila[$id]; $fila = $productos_id_fila[$id];
$records[$fila][1] = $producto_pedido->cantidad_pedida; $records[$fila][1] = $producto_pedido->cantidad_pedida;
} }
$records[TransporteHelper::filaTransporte()][1] = $this->cantidadTransporte(); $records[$this->obtenerFilaDeBonoTransporte()][1] = $this->calcularCantidadBDT();
return $records; return $records;
} }
public function exportarPedidoConNucleosEnCSV() public function exportarPedidoConNucleosEnCSV()
{ {
$productos_en_pedido = $this->productosPedidos(); $productos_en_pedido = DB::table('pedidos_aprobados')->where('grupo_de_compra_id', $this->id)->get()->keyBy('producto_id');
// si no hay pedidos aprobados, salir // si no hay pedidos aprobados, salir
if ($productos_en_pedido->count() == 0) { if ($productos_en_pedido->count() == 0) {
Log::debug("El grupo de compra " . $this->nombre . " no tiene pedidos aprobados."); \Log::debug("El grupo de compra " . $this->nombre . " no tiene pedidos aprobados.");
return; return;
} }
$pedidos = $this->pedidosAprobados(); $pedidos = $this->pedidosAprobados();
// Generar tabla vacía con una columna por núcleo // Generar tabla vacía con una columna por núcleo
$records = $this->obtenerTemplateDeFilasVacias($pedidos->count()); $records = $this->obtenerTemplateDeFilasVacias($pedidos->count());
$productos_id_fila = Producto::productosIDFila(); $productos_id_fila = Producto::productosIdFila();
foreach ($productos_en_pedido as $id => $producto_pedido) { foreach ($productos_en_pedido as $id => $producto_pedido) {
$fila = $productos_id_fila[$id]; $fila = $productos_id_fila[$id];
@ -229,7 +251,13 @@ class GrupoDeCompra extends Model
} }
array_splice($records, 0, 0, array($nucleos)); array_splice($records, 0, 0, array($nucleos));
CsvHelper::generarCsv('csv/exports/' . $this->nombre . '-completo.csv', $records); // Guardar en un archivo .csv
try {
$writer = Writer::createFromPath(resource_path('csv/exports/' . $this->nombre . '-completo.csv'), 'w');
$writer->insertAll($records);
} catch (CannotInsertRecord $e) {
var_export($e->getRecords());
}
} }
public function agregarCantidad($pedido, $id, array $records, $fila, int $i): array public function agregarCantidad($pedido, $id, array $records, $fila, int $i): array
@ -241,40 +269,52 @@ class GrupoDeCompra extends Model
return array($records, $i, $cantidad); return array($records, $i, $cantidad);
} }
public static function barriosMenosPrueba(): Builder static public function totalesParaTransportePorBarrio() {
{ return DB::table('grupos_de_compra')
return self::where('nombre', '<>', 'PRUEBA') ->leftJoin('subpedidos', 'grupos_de_compra.id', '=', 'subpedidos.grupo_de_compra_id')
->orderBy('region') ->leftJoin('producto_subpedido', 'subpedidos.id', '=', 'producto_subpedido.subpedido_id')
->orderBy('nombre'); ->leftJoin('productos', 'producto_subpedido.producto_id', '=', 'productos.id')
->where(function ($query) {
$query->whereNull('productos.categoria')
->orWhere('productos.categoria', 'not like', '%SUBSIDIADO%');
})
->where(function ($query) {
$query->whereNull('productos.bono')
->orWhere('productos.bono', 0);
})
->where(function ($query) {
$query->whereNull('subpedidos.aprobado')
->orWhere('subpedidos.aprobado', 1);
})
->select(
'grupos_de_compra.id as id',
'grupos_de_compra.nombre as barrio',
DB::raw('COALESCE(SUM(producto_subpedido.cantidad * productos.precio), 0) as total')
)
->groupBy('grupos_de_compra.id')
->get();
} }
public static function transportePorBarrio(): array
{
$result = [];
$barrios = GrupoDeCompra::barriosMenosPrueba()->get();
foreach ($barrios as $barrio) { static public function planillaTransporte() {
$result[] = $barrio->cantidadTransporte(); $totalesPorBarrio = self::totalesParaTransportePorBarrio();
$barrios = [];
$bonosDeTransporte = [];
foreach ($totalesPorBarrio as $totalBarrio) {
$barrios[] = $totalBarrio->barrio;
$bonosDeTransporte[] = ceil($totalBarrio->total / 500);
} }
return $result; $planilla = [];
} $planilla[] = array_merge(['Barrio'], $barrios);
$planilla[] = array_merge(['Cant. bonos de transporte'], $bonosDeTransporte);
/** try {
* @return Collection $writer = Writer::createFromPath(resource_path('csv/exports/transporte-por-barrio.csv'), 'w');
*/ $writer->insertAll($planilla);
public function productosPedidos($excluirBarriales = false, $excluirBonos = false): Collection } catch (CannotInsertRecord $e) {
{ var_export($e->getRecords());
$query = DB::table('pedidos_aprobados') }
->where('grupo_de_compra_id', $this->id);
if ($excluirBarriales)
$query = $query->where('producto_nombre','NOT LIKE','%barrial%');
if ($excluirBonos)
$query = $query->where('producto_es_bono',false);
return $query
->get()
->keyBy('producto_id');
} }
} }

View file

@ -9,15 +9,14 @@ use DatabaseSeeder;
use Illuminate\Support\Arr; use Illuminate\Support\Arr;
use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str; use Illuminate\Support\Str;
use League\Csv\Reader;
class CanastaHelper class CanastaHelper
{ {
const TIPO = "Tipo"; const FILA_HEADER = "Tipo";
const TOTAL = "TOTAL"; const ULTIMA_FILA = "TOTAL";
const ARCHIVO_SUBIDO = 'Archivo subido'; const ARCHIVO_SUBIDO = 'Archivo subido';
const CANASTA_CARGADA = 'Canasta cargada'; const CANASTA_CARGADA = 'Canasta cargada';
const TIPOS_BONO = ["B", "F", "BE"];
public static function guardarCanasta($data, $path): string { public static function guardarCanasta($data, $path): string {
$nombre = $data->getClientOriginalName(); $nombre = $data->getClientOriginalName();
@ -32,43 +31,53 @@ class CanastaHelper
public static function cargarCanasta($archivo) { public static function cargarCanasta($archivo) {
self::limpiarTablas(); self::limpiarTablas();
$registros = CsvHelper::getRecords($archivo); $csv = Reader::createFromPath(resource_path($archivo), 'r');
$csv->setDelimiter("|");
$iHeader = self::obtenerIndiceDeHeader($csv);
$csv->setHeaderOffset($iHeader);
$registros = $csv->getRecords();
$toInsert = []; $toInsert = [];
$categoria = ''; $categoria = '';
foreach($registros as $i => $registro){
//filas que están arriba del header
if ($i <= $iHeader){
continue;
}
foreach($registros as $i => $registro) { //finalizar
// finalizar if ($registro[self::FILA_HEADER] == self::ULTIMA_FILA) {
if ($registro[self::TIPO] == self::TOTAL)
break; break;
}
// saltear filas que no tienen tipo //filas que no tienen tipo
if (self::noTieneTipo($registro)) { if (!Arr::has($registro,self::FILA_HEADER)|| trim($registro[self::FILA_HEADER]) == ''){
var_dump("no hay tipo en la fila " . $i); var_dump("no hay tipo en la fila " . $i);
continue; continue;
} }
// saltear bono de transporte //saltear bono de transporte
if ($registro[self::TIPO] == "T"){ if ($registro[self::FILA_HEADER] == "T"){
continue; continue;
} }
// obtener categoria si no hay producto //obtener categoria
if ($registro['Producto'] == '') { if ($registro['Producto'] == '') {
// no es la pregunta de la copa? //es la pregunta de la copa?
if (!Str::contains($registro[self::TIPO],"¿")) if (Str::contains($registro[self::FILA_HEADER],"¿")) { continue; }
$categoria = $registro[self::TIPO]; $categoria = $registro[self::FILA_HEADER];
continue; continue;
} }
// completar producto //completar producto
$toInsert[] = [ $toInsert[] = [
'fila' => $i, 'fila' => $i,
'categoria' => $categoria, 'categoria' => $categoria,
'nombre' => trim(str_replace('*', '',$registro['Producto'])), 'nombre' => trim(str_replace('*', ' ',$registro['Producto'])),
'precio' => $registro['Precio'], 'precio' => $registro['Precio'],
'proveedor_id' => self::obtenerProveedor($registro['Producto']), 'proveedor_id' => self::obtenerProveedor($registro['Producto']),
'bono' => in_array($registro[self::TIPO], self::TIPOS_BONO), 'bono' => $registro[self::FILA_HEADER] == "B",
'requiere_notas'=> $registro[self::TIPO] =="PTC", 'requiere_notas'=> $registro[self::FILA_HEADER] =="PTC",
]; ];
} }
@ -81,6 +90,18 @@ class CanastaHelper
self::log($archivo, self::CANASTA_CARGADA); self::log($archivo, self::CANASTA_CARGADA);
} }
private static function obtenerIndiceDeHeader($csv){
$registros = $csv->getRecords();
$iheader = 0;
foreach ($registros as $i => $registro){
if (strtolower($registro[0]) == strtolower(self::FILA_HEADER)) {
$iheader = $i;
break;
}
}
return $iheader;
}
private static function obtenerProveedor($nombre) { private static function obtenerProveedor($nombre) {
$result = null; $result = null;
if (Str::contains($nombre,"*")){ if (Str::contains($nombre,"*")){
@ -116,14 +137,7 @@ class CanastaHelper
private static function agregarBonoBarrial() private static function agregarBonoBarrial()
{ {
$categoria = Producto::all() $categoria = Producto::all()->pluck('categoria')->unique()->flatten()->first(function ($c) { return Str::contains($c, 'BONO'); });
->pluck('categoria')
->unique()
->flatten()
->first(function ($c) {
return Str::contains($c, 'BONO');
});
DB::table('productos')->insert([ DB::table('productos')->insert([
'fila' => 420, 'fila' => 420,
'nombre' => "Bono barrial", 'nombre' => "Bono barrial",
@ -134,13 +148,4 @@ class CanastaHelper
'requiere_notas'=> false, 'requiere_notas'=> false,
]); ]);
} }
/**
* @param $registro
* @return bool
*/
public static function noTieneTipo($registro): bool
{
return !Arr::has($registro, self::TIPO) || trim($registro[self::TIPO]) == '';
}
} }

View file

@ -1,40 +0,0 @@
<?php
namespace App\Helpers;
use Illuminate\Support\Facades\Log;
use Iterator;
use League\Csv\CannotInsertRecord;
use League\Csv\Exception;
use League\Csv\InvalidArgument;
use League\Csv\Reader;
use League\Csv\Writer;
class CsvHelper
{
public static function getRecords($filePath): Iterator {
$csv = Reader::createFromPath(resource_path($filePath));
try {
$csv->setDelimiter("|");
$csv->setEnclosure("'");
$csv->setHeaderOffset(0);
return $csv->getRecords();
} catch (InvalidArgument|Exception $e) {
Log::error($e->getMessage());
return null;
}
}
public static function generarCsv($filePath, $contenido, $headers = null): void
{
try {
$writer = Writer::createFromPath(resource_path($filePath), 'w');
if ($headers) {
$writer->insertOne($headers);
}
$writer->insertAll($contenido);
} catch (CannotInsertRecord $e) {
Log::error($e->getMessage(), $e->getTrace());
}
}
}

View file

@ -1,29 +0,0 @@
<?php
namespace App\Helpers;
use Mpdf\Mpdf;
use Mpdf\MpdfException;
class PdfHelper
{
/**
* Requiere que el segundo argumento tenga definida la función generarHTML()
* para crear la tabla con los datos del pedido que se inserta en el pdf.
*
* @return void
* @throws MpdfException
*/
public static function exportarPedidos($filepath, $pedidos)
{
$mpdf = new Mpdf();
foreach ($pedidos as $pedido) {
$html = $pedido->generarHTML();
$mpdf->WriteHTML($html);
$mpdf->AddPage();
}
$mpdf->Output($filepath, 'D');
}
}

View file

@ -2,9 +2,6 @@
namespace App\Helpers; namespace App\Helpers;
use App\CanastaLog;
use Illuminate\Support\Facades\Log;
class TransporteHelper class TransporteHelper
{ {
const COSTO_TRANSPORTE = 15; const COSTO_TRANSPORTE = 15;
@ -19,20 +16,4 @@ class TransporteHelper
{ {
return self::cantidadTransporte($monto) * self::COSTO_TRANSPORTE; return self::cantidadTransporte($monto) * self::COSTO_TRANSPORTE;
} }
public static function filaTransporte()
{
$ultimaCanasta = CanastaLog::where('descripcion', CanastaHelper::CANASTA_CARGADA)
->orderBy('created_at', 'desc')
->pluck('path')
->first();
$registros = CsvHelper::getRecords($ultimaCanasta);
foreach ($registros as $key => $registro)
if ($registro[CanastaHelper::TIPO] == 'T') return $key;
Log::error('No hay fila de tipo T en la planilla: ' . $ultimaCanasta);
return null;
}
} }

View file

@ -3,7 +3,8 @@
namespace App\Http\Controllers; namespace App\Http\Controllers;
use App\GrupoDeCompra; use App\GrupoDeCompra;
use Symfony\Component\HttpFoundation\BinaryFileResponse; use Illuminate\Http\Request;
use Response;
class AdminController extends Controller class AdminController extends Controller
{ {
@ -16,19 +17,17 @@ class AdminController extends Controller
return view('auth/admin_subpedidos'); return view('auth/admin_subpedidos');
} }
public function exportarPedidosAPdf(GrupoDeCompra $gdc) { public function exportarPlanillasAPdf(GrupoDeCompra $gdc) {
$gdc->exportarPedidosAPdf(); return $gdc->exportarPlanillasAPdf();
} }
public function exportarPedidoACSV(GrupoDeCompra $gdc): BinaryFileResponse public function exportarPedidoACSV(GrupoDeCompra $gdc) {
{
$gdc->exportarPedidoEnCSV(); $gdc->exportarPedidoEnCSV();
$file = resource_path('csv/exports/'.$gdc->nombre.'.csv'); $file = resource_path('csv/exports/'.$gdc->nombre.'.csv');
return response()->download($file); return response()->download($file);
} }
public function exportarPedidoConNucleosACSV(GrupoDeCompra $gdc): BinaryFileResponse public function exportarPedidoConNucleosACSV(GrupoDeCompra $gdc) {
{
$gdc->exportarPedidoConNucleosEnCSV(); $gdc->exportarPedidoConNucleosEnCSV();
$file = resource_path('csv/exports/'.$gdc->nombre.'-completo.csv'); $file = resource_path('csv/exports/'.$gdc->nombre.'-completo.csv');
return response()->download($file); return response()->download($file);

View file

@ -10,11 +10,24 @@ use App\Producto;
class ProductoController extends Controller class ProductoController extends Controller
{ {
/**
* Mostrar una lista de productos.
*
* @param App\Filtros\FiltroDeProducto $filtros
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function index(FiltroDeProducto $filtros, Request $request) public function index(FiltroDeProducto $filtros, Request $request)
{ {
return ProductoResource::collection(Producto::filtrar($filtros)->paginate(Producto::getPaginar($request))); return ProductoResource::collection(Producto::filtrar($filtros)->paginate(Producto::getPaginar($request)));
} }
/**
* Display the specified resource.
*
* @param \App\Producto $producto
* @return \Illuminate\Http\Response
*/
public function show(Producto $producto) public function show(Producto $producto)
{ {
return new ProductoResource($producto); return new ProductoResource($producto);

View file

@ -15,6 +15,13 @@ use Symfony\Component\HttpKernel\Exception\HttpException;
class SubpedidoController extends Controller class SubpedidoController extends Controller
{ {
/**
* Mostrar una lista de productos.
*
* @param App\Filtros\FiltroDeSubpedido $filtros
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function index(FiltroDeSubpedido $filtros, Request $request) public function index(FiltroDeSubpedido $filtros, Request $request)
{ {
return Subpedido::filtrar($filtros)->get(); return Subpedido::filtrar($filtros)->get();
@ -25,6 +32,12 @@ class SubpedidoController extends Controller
return SubpedidoResource::collection(Subpedido::filtrar($filtros)->get()); return SubpedidoResource::collection(Subpedido::filtrar($filtros)->get());
} }
/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(Request $request) public function store(Request $request)
{ {
$validado = $this->validateSubpedido(); $validado = $this->validateSubpedido();
@ -38,8 +51,7 @@ class SubpedidoController extends Controller
return $s; return $s;
} }
protected function validateSubpedido(): array protected function validateSubpedido(){
{
return request()->validate([ return request()->validate([
'nombre' => 'required|max:255', 'nombre' => 'required|max:255',
'grupo_de_compra_id' => [ 'grupo_de_compra_id' => [
@ -49,6 +61,12 @@ class SubpedidoController extends Controller
]); ]);
} }
/**
* Display the specified resource.
*
* @param \App\Subpedido $subpedido
* @return \Illuminate\Http\Response
*/
public function show(Subpedido $subpedido) public function show(Subpedido $subpedido)
{ {
return new SubpedidoResource($subpedido); return new SubpedidoResource($subpedido);

View file

@ -5,9 +5,7 @@ namespace App\Http\Controllers;
use App\GrupoDeCompra; use App\GrupoDeCompra;
use App\Helpers\CanastaHelper; use App\Helpers\CanastaHelper;
use App\Producto; use App\Producto;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\BinaryFileResponse;
class ComprasController class ComprasController
{ {
@ -17,22 +15,22 @@ class ComprasController
return view('compras_pedidos'); return view('compras_pedidos');
} }
public function descargarPedidos(): BinaryFileResponse public function descargarPedidos() {
{
Producto::planillaTotales(); Producto::planillaTotales();
$file = resource_path('csv/exports/pedidos-por-barrio.csv'); $file = resource_path('csv/exports/pedidos-por-barrio.csv');
return response()->download($file); return response()->download($file);
} }
public function descargarNotas(): BinaryFileResponse public function descargarNotas() {
{
Producto::planillaNotas(); Producto::planillaNotas();
$file = resource_path('csv/exports/notas-por-barrio.csv'); $file = resource_path('csv/exports/notas-por-barrio.csv');
return response()->download($file); return response()->download($file);
} }
public function pdf() { public function descargarTransporte() {
GrupoDeCompra::exportarPedidosBarrialesAPdf(); GrupoDeCompra::planillaTransporte();
$file = resource_path('csv/exports/transporte-por-barrio.csv');
return response()->download($file);
} }
public function show() public function show()
@ -40,7 +38,7 @@ class ComprasController
return view('auth/compras_login'); return view('auth/compras_login');
} }
public function cargarCanasta(Request $request): JsonResponse public function cargarCanasta(Request $request)
{ {
$request->validate([ $request->validate([
'data' => 'required|file|mimes:csv,txt|max:2048', 'data' => 'required|file|mimes:csv,txt|max:2048',
@ -51,11 +49,10 @@ class ComprasController
return response()->json([ return response()->json([
'message' => 'Canasta cargada exitosamente', 'message' => 'Canasta cargada exitosamente',
]); ], 200);
} }
public function descargarCanastaEjemplo(): BinaryFileResponse public function descargarCanastaEjemplo() {
{
$file = resource_path('csv/productos.csv'); $file = resource_path('csv/productos.csv');
return response()->download($file); return response()->download($file);
} }

View file

@ -2,6 +2,8 @@
namespace App\Http\Controllers; namespace App\Http\Controllers;
use Illuminate\Http\Request;
class ProductoController extends Controller class ProductoController extends Controller
{ {
/** /**
@ -14,6 +16,11 @@ class ProductoController extends Controller
$this->middleware(['auth','subpedido']); $this->middleware(['auth','subpedido']);
} }
/**
* Show the application dashboard.
*
* @return \Illuminate\Contracts\Support\Renderable
*/
public function index() public function index()
{ {
return view('productos'); return view('productos');

View file

@ -3,12 +3,18 @@
namespace App\Http\Middleware; namespace App\Http\Middleware;
use Closure; use Closure;
use Illuminate\Support\Facades\Auth; use Auth;
use Illuminate\Http\Request;
class Admin class Admin
{ {
public function handle(Request $request, Closure $next) /**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{ {
$user = Auth::user(); $user = Auth::user();
if ($user->is_admin) { if ($user->is_admin) {

View file

@ -3,18 +3,17 @@
namespace App\Http\Middleware; namespace App\Http\Middleware;
use Closure; use Closure;
use Illuminate\Http\Request;
class Subpedido class Subpedido
{ {
/** /**
* Handle an incoming request. * Handle an incoming request.
* *
* @param Request $request * @param \Illuminate\Http\Request $request
* @param Closure $next * @param \Closure $next
* @return mixed * @return mixed
*/ */
public function handle(Request $request, Closure $next) public function handle($request, Closure $next)
{ {
if (!session('subpedido_nombre') || !session('subpedido_id')) { if (!session('subpedido_nombre') || !session('subpedido_id')) {
return redirect()->route('subpedidos.create'); return redirect()->route('subpedidos.create');

View file

@ -2,7 +2,6 @@
namespace App\Http\Resources; namespace App\Http\Resources;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource; use Illuminate\Http\Resources\Json\JsonResource;
class GrupoDeCompraResource extends JsonResource class GrupoDeCompraResource extends JsonResource
@ -10,10 +9,10 @@ class GrupoDeCompraResource extends JsonResource
/** /**
* Transform the resource into an array. * Transform the resource into an array.
* *
* @param Request $request * @param \Illuminate\Http\Request $request
* @return array * @return array
*/ */
public function toArray($request): array public function toArray($request)
{ {
return [ return [
'id' => $this->id, 'id' => $this->id,
@ -24,8 +23,8 @@ class GrupoDeCompraResource extends JsonResource
'total_barrial' => number_format($this->totalBarrial(),2), 'total_barrial' => number_format($this->totalBarrial(),2),
'total_devoluciones' => number_format($this->totalDevoluciones(),2), 'total_devoluciones' => number_format($this->totalDevoluciones(),2),
'total_a_transferir' => number_format($this->totalATransferir(),2), 'total_a_transferir' => number_format($this->totalATransferir(),2),
'total_transporte' => number_format($this->totalTransporte()), 'total_transporte' => number_format($this->totalTransporte(),0),
'cantidad_transporte' => number_format($this->cantidadTransporte()), 'cantidad_transporte' => number_format($this->cantidadTransporte(),0),
]; ];
} }
} }

View file

@ -2,7 +2,6 @@
namespace App\Http\Resources; namespace App\Http\Resources;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource; use Illuminate\Http\Resources\Json\JsonResource;
class ProductoResource extends JsonResource class ProductoResource extends JsonResource
@ -10,10 +9,10 @@ class ProductoResource extends JsonResource
/** /**
* Transform the resource into an array. * Transform the resource into an array.
* *
* @param Request $request * @param \Illuminate\Http\Request $request
* @return array * @return array
*/ */
public function toArray($request): array public function toArray($request)
{ {
return [ return [
'id' => $this->id, 'id' => $this->id,

View file

@ -2,7 +2,6 @@
namespace App\Http\Resources; namespace App\Http\Resources;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource; use Illuminate\Http\Resources\Json\JsonResource;
class SubpedidoResource extends JsonResource class SubpedidoResource extends JsonResource
@ -10,10 +9,10 @@ class SubpedidoResource extends JsonResource
/** /**
* Transform the resource into an array. * Transform the resource into an array.
* *
* @param Request $request * @param \Illuminate\Http\Request $request
* @return array * @return array
*/ */
public function toArray($request): array public function toArray($request)
{ {
return [ return [
'id' => $this->id, 'id' => $this->id,
@ -22,8 +21,8 @@ class SubpedidoResource extends JsonResource
'productos' => $this->productos, 'productos' => $this->productos,
'aprobado' => (bool) $this->aprobado, 'aprobado' => (bool) $this->aprobado,
'total' => number_format($this->total(),2), 'total' => number_format($this->total(),2),
'total_transporte' => number_format($this->totalTransporte()), 'total_transporte' => number_format($this->totalTransporte(),0),
'cantidad_transporte' => number_format($this->cantidadTransporte()), 'cantidad_transporte' => number_format($this->cantidadTransporte(),0),
'total_sin_devoluciones' => number_format($this->totalSinDevoluciones(),2), 'total_sin_devoluciones' => number_format($this->totalSinDevoluciones(),2),
'devoluciones_total' => number_format($this->devoluciones_total,2), 'devoluciones_total' => number_format($this->devoluciones_total,2),
'devoluciones_notas' => $this->devoluciones_notas 'devoluciones_notas' => $this->devoluciones_notas

View file

@ -3,61 +3,65 @@
namespace App; namespace App;
use App\Filtros\FiltroDeProducto; use App\Filtros\FiltroDeProducto;
use App\Helpers\CsvHelper;
use App\Helpers\TransporteHelper;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;
use League\Csv\CannotInsertRecord;
use League\Csv\Reader;
use League\Csv\Writer;
class Producto extends Model class Producto extends Model
{ {
public $timestamps = false; public $timestamps = false;
protected $fillable = ["nombre", "precio", "presentacion", "stock", "categoria"]; protected $fillable = ["nombre", "precio", "presentacion", "stock", "categoria"];
static int $paginarPorDefecto = 10; static $paginarPorDefecto = 10;
public function subpedidos(): BelongsToMany public function subpedidos()
{ {
return $this->belongsToMany('App\Subpedido', 'productos_subpedidos')->withPivot(["cantidad", "notas"]); return $this->belongsToMany('App\Subpedido', 'productos_subpedidos')->withPivot(["cantidad", "notas"]);
} }
public function proveedor(): BelongsTo public function proveedor()
{ {
return $this->belongsTo('App\Proveedor'); return $this->belongsTo('App\Proveedor');
} }
public function pagaTransporte()
{
return !($this->bono || Str::contains($this->categoria, 'SUBSIDIADO'));
}
//Este método permite que se apliquen los filtros al hacer una request (por ejemplo, de búsqueda) //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 public function scopeFiltrar($query, FiltroDeProducto $filtros)
{ {
return $filtros->aplicar($query); return $filtros->aplicar($query);
} }
public static function getPaginar(Request $request): int public static function getPaginar(Request $request)
{ {
return $request->has('paginar') && intval($request->input('paginar')) ? intval($request->input('paginar')) : self::$paginarPorDefecto; return $request->has('paginar') && intval($request->input('paginar')) ? intval($request->input('paginar')) : self::$paginarPorDefecto;
} }
public static function productosFilaID() public static function productosFilaID()
{ {
return Producto::pluck('id', 'fila')->all(); return Producto::pluck('id', 'fila',)->all();
} }
public static function productosIDFila() public static function productosIDFila()
{ {
return Producto::pluck('fila', 'id')->all(); return Producto::pluck('fila', 'id',)->all();
} }
public static function productosIDNombre() public static function productosIDNombre()
{ {
return Producto::pluck('nombre', 'id')->all(); return Producto::pluck('nombre', 'id',)->all();
} }
static public function cantidadesPorBarrio(): Collection static public function cantidadesPorBarrio()
{ {
$barrios = GrupoDeCompra::barriosMenosPrueba() $barrios = DB::table('grupos_de_compra')
->where('nombre', '<>', 'PRUEBA')
->pluck('id', 'nombre'); ->pluck('id', 'nombre');
$columnasBarrios = $barrios->map(function ($id, $nombre) { $columnasBarrios = $barrios->map(function ($id, $nombre) {
@ -78,28 +82,22 @@ class Producto extends Model
->get(); ->get();
} }
static public function planillaTotales() static public function planillaTotales() {
{
$headers = ['Producto']; $headers = ['Producto'];
$barrios = GrupoDeCompra::barriosMenosPrueba() $barrios = DB::table('grupos_de_compra')
->where('nombre', '<>', 'PRUEBA')
->pluck('nombre')->toArray(); ->pluck('nombre')->toArray();
$headers = array_merge($headers, $barrios); $headers = array_merge($headers, $barrios);
$cantidadesPorBarrio = self::cantidadesPorBarrio(); $cantidadesPorBarrio = self::cantidadesPorBarrio();
$transportePorBarrio = GrupoDeCompra::transportePorBarrio();
$planilla = []; $planilla = [];
$ultimaFila = 1; $ultimaFila = 1;
$filaTransporte = TransporteHelper::filaTransporte();
foreach ($cantidadesPorBarrio as $productoCantidades) { foreach ($cantidadesPorBarrio as $productoCantidades) {
$fila = $productoCantidades->fila; $fila = $productoCantidades->fila;
while ($fila - $ultimaFila > 1) { while ($fila - $ultimaFila > 1) {
$ultimaFila++; $ultimaFila++;
if ($ultimaFila == $filaTransporte) { $planilla[$ultimaFila] = ['---'];
$planilla[$ultimaFila] = ['Bono de transporte'];
} else {
$planilla[$ultimaFila] = ['---'];
}
} }
$planilla[$fila] = [$productoCantidades->producto]; $planilla[$fila] = [$productoCantidades->producto];
foreach ($barrios as $barrio) { foreach ($barrios as $barrio) {
@ -108,14 +106,16 @@ class Producto extends Model
$ultimaFila = $fila; $ultimaFila = $fila;
} }
foreach ($transportePorBarrio as $key => $cantidad) { try {
$planilla[$filaTransporte][] = $cantidad; $writer = Writer::createFromPath(resource_path('csv/exports/pedidos-por-barrio.csv'), 'w');
$writer->insertOne($headers);
$writer->insertAll($planilla);
} catch (CannotInsertRecord $e) {
var_export($e->getRecords());
} }
CsvHelper::generarCsv('csv/exports/pedidos-por-barrio.csv', $planilla, $headers);
} }
public static function notasPorBarrio(): Collection public static function notasPorBarrio(): \Illuminate\Support\Collection
{ {
return DB::table('productos') return DB::table('productos')
->join('producto_subpedido', 'productos.id', '=', 'producto_subpedido.producto_id') ->join('producto_subpedido', 'productos.id', '=', 'producto_subpedido.producto_id')
@ -133,7 +133,8 @@ class Producto extends Model
static public function planillaNotas() { static public function planillaNotas() {
$headers = ['Producto']; $headers = ['Producto'];
$barrios = GrupoDeCompra::barriosMenosPrueba() $barrios = DB::table('grupos_de_compra')
->where('nombre', '<>', 'PRUEBA')
->pluck('nombre')->toArray(); ->pluck('nombre')->toArray();
$headers = array_merge($headers, $barrios); $headers = array_merge($headers, $barrios);
@ -149,6 +150,12 @@ class Producto extends Model
$planilla[] = $fila; $planilla[] = $fila;
} }
CsvHelper::generarCsv('csv/exports/notas-por-barrio.csv', $planilla, $headers); try {
$writer = Writer::createFromPath(resource_path('csv/exports/notas-por-barrio.csv'), 'w');
$writer->insertOne($headers);
$writer->insertAll($planilla);
} catch (CannotInsertRecord $e) {
var_export($e->getRecords());
}
} }
} }

View file

@ -3,15 +3,14 @@
namespace App; namespace App;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
class Proveedor extends Model class Proveedor extends Model
{ {
public $timestamps = false; public $timestamps = false;
protected $fillable = [ "nombre","direccion","telefono","correo","comentario" ]; protected $fillable = [ "nombre","direccion","telefono","correo","comentario" ];
protected $table = 'proveedores'; protected $table = 'proveedores';
public function productos(): HasMany public function productos()
{ {
return $this->hasMany('App\Producto'); return $this->hasMany('App\Producto');
} }

View file

@ -3,33 +3,43 @@
namespace App; namespace App;
use App\Helpers\TransporteHelper; use App\Helpers\TransporteHelper;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\DB;
use Log;
use App\Filtros\FiltroDeSubpedido; use App\Filtros\FiltroDeSubpedido;
class Subpedido extends Model class Subpedido extends Model
{ {
const COSTO_TRANSPORTE = 15;
public $timestamps = false; public $timestamps = false;
protected $fillable = ['grupo_de_compra_id', 'aprobado', 'nombre', 'devoluciones_total', 'devoluciones_notas']; protected $fillable = ['grupo_de_compra_id', 'aprobado', 'nombre', 'devoluciones_total', 'devoluciones_notas'];
public function productos(): BelongsToMany public function productos()
{ {
return $this->belongsToMany('App\Producto')->withPivot(["cantidad", "total", "notas"]); return $this->belongsToMany('App\Producto')->withPivot(["cantidad","total", "notas"]);
} }
public function grupoDeCompra(): BelongsTo //Bonos del MPS, Sororo, etc. NO devuelve bonos de transporte
{ private function bonos()
return $this->belongsTo('App\GrupoDeCompra'); {
} return $this->productos()->where('bono',1);
}
// Permite que se apliquen los filtros al hacer una request (por ejemplo, de búsqueda) public function productosSinBonos()
public function scopeFiltrar($query, FiltroDeSubpedido $filtros): Builder {
{ return $this->productos()->where('bono',false);
return $filtros->aplicar($query); }
}
public function grupoDeCompra()
{
return $this->belongsTo('App\GrupoDeCompra');
}
//Permite que se apliquen los filtros al hacer una request (por ejemplo, de búsqueda)
public function scopeFiltrar($query, FiltroDeSubpedido $filtros)
{
return $filtros->aplicar($query);
}
public function total() public function total()
{ {
@ -92,40 +102,36 @@ class Subpedido extends Model
return TransporteHelper::cantidadTransporte($this->totalCentralesQuePaganTransporte()); return TransporteHelper::cantidadTransporte($this->totalCentralesQuePaganTransporte());
} }
//Actualiza el pedido, agregando o quitando del subpedido según sea necesario. Debe ser llamado desde el controlador de subpedidos, luego de validar que los parámetros $producto y $cantidad son correctos. También calcula el subtotal por producto. //Actualiza el pedido, agregando o quitando del subpedido según sea necesario. Debe ser llamado desde el controlador de subpedidos, luego de validar que los parámetros $producto y $cantidad son correctos. También calcula el subtotal por producto.
public function syncProducto(Producto $producto, int $cantidad, string $notas) public function syncProducto(Producto $producto, Int $cantidad, string $notas) {
{ if ($cantidad){
if ($cantidad) { //si la cantidad es 1 o más se agrega el producto o actualiza la cantidad
//si la cantidad es 1 o más se agrega el producto o actualiza la cantidad $this->productos()->syncWithoutDetaching([
$this->productos()->syncWithoutDetaching([ $producto->id => [
$producto->id => [ 'cantidad' => $cantidad,
'cantidad' => $cantidad, 'total' => $cantidad * $producto->precio,
'total' => $cantidad * $producto->precio, 'notas' => $notas,
'notas' => $notas, ]
] ]);
]);
} else { } else {
//si la cantidad es 0, se elimina el producto del subpedido //si la cantidad es 0, se elimina el producto del subpedido
$this->productos()->detach($producto->id); $this->productos()->detach($producto->id);
} }
} }
public function toggleAprobacion(bool $aprobacion) public function toggleAprobacion(bool $aprobacion) {
{ $this->aprobado = $aprobacion;
$this->aprobado = $aprobacion; $this->save();
$this->save(); }
}
public function generarHTML() public function generarHTML() {
{ $view = view("pdfgen.subpedido_tabla", ["subpedido" => $this]);
$view = view("pdfgen.pedido_tabla", ["pedido" => $this]); return $view->render();
return $view->render(); }
}
public function syncDevoluciones(float $total, string $notas) public function syncDevoluciones(float $total, string $notas) {
{ $this->devoluciones_total = $total;
$this->devoluciones_total = $total; $this->devoluciones_notas = $notas;
$this->devoluciones_notas = $notas; $this->save();
$this->save(); }
}
} }

View file

@ -2,7 +2,7 @@
namespace App; namespace App;
use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable; use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable; use Illuminate\Notifications\Notifiable;
@ -38,7 +38,7 @@ class User extends Authenticatable
]; ];
public function grupoDeCompra(): BelongsTo public function grupoDeCompra()
{ {
return $this->belongsTo('App\GrupoDeCompra'); return $this->belongsTo('App\GrupoDeCompra');
} }

View file

@ -1,10 +1,9 @@
<?php <?php
/** @var Factory $factory */ /** @var \Illuminate\Database\Eloquent\Factory $factory */
use App\User; use App\User;
use Faker\Generator as Faker; use Faker\Generator as Faker;
use Illuminate\Database\Eloquent\Factory;
use Illuminate\Support\Str; use Illuminate\Support\Str;
/* /*

View file

@ -1,6 +1,8 @@
<?php <?php
use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CallCrearPedidosAprobados extends Migration class CallCrearPedidosAprobados extends Migration
{ {

View file

@ -1,27 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Support\Facades\Artisan;
class CallAgregarEsBonoAPedidosAprobados extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Artisan::call("command:AgregarEsBonoAPedidosAprobados");
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
//
}
}

View file

@ -1,9 +1,9 @@
<?php <?php
use App\Helpers\CsvHelper as CsvHelperAlias;
use Illuminate\Database\Seeder; use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash; use Illuminate\Support\Facades\Hash;
use League\Csv\Reader;
class GrupoDeCompraSeeder extends Seeder class GrupoDeCompraSeeder extends Seeder
{ {
@ -14,7 +14,11 @@ class GrupoDeCompraSeeder extends Seeder
*/ */
public function run() public function run()
{ {
$registros = CsvHelperAlias::getRecords('csv/barrios.csv'); $csv = Reader::createFromPath(resource_path('csv/barrios.csv'), 'r');
$csv->setDelimiter("|");
$csv->setEnclosure("'");
$csv->setHeaderOffset(0);
$registros = $csv->getRecords();
$gdcToInsert = []; $gdcToInsert = [];
$usersToInsert = []; $usersToInsert = [];

View file

@ -20,9 +20,10 @@
La planilla de la canasta tiene que tener el siguiente formato para que la aplicación la lea correctamente: La planilla de la canasta tiene que tener el siguiente formato para que la aplicación la lea correctamente:
<ul> <ul>
<li> Los precios deben usar punto y no coma decimal </li> <li> Los precios deben usar punto y no coma decimal </li>
<li> El nombre de las columnas deben ser "Tipo", "Producto", y "Precio" respectivamente </li> <li> El nombre de la columna de precios debe ser "Precio" </li>
<li> Las celdas deben separarse con '|' </li> <li> Las celdas deben separarse con '|' </li>
<li> No puede haber "enters" en ninguna celda </li> <li> No puede haber "enters" en ninguna celda </li>
<li> Todos los bonos deben tener tipo 'B' para evitar que paguen transporte </li>
<li> El bono de transporte debe tener tipo 'T' </li> <li> El bono de transporte debe tener tipo 'T' </li>
</ul> </ul>
<a class="has-text-info" href="/compras/canasta/ejemplo">Planilla de ejemplo.</a> <a class="has-text-info" href="/compras/canasta/ejemplo">Planilla de ejemplo.</a>

View file

@ -20,8 +20,8 @@
<a href="/compras/pedidos/notas" class="dropdown-item"> <a href="/compras/pedidos/notas" class="dropdown-item">
Notas por barrio Notas por barrio
</a> </a>
<a href="/compras/pedidos/pdf" class="dropdown-item"> <a href="/compras/pedidos/transporte" class="dropdown-item">
Pedidos por barrio en pdf Transporte por barrio
</a> </a>
</div> </div>
</div> </div>

View file

@ -4,7 +4,7 @@
background: #CCC background: #CCC
} }
</style> </style>
<h3>{{$pedido['nombre']}}</h3> <h3>{{$subpedido->nombre}}</h3>
<table style="width: 100%"> <table style="width: 100%">
<tr> <tr>
@ -25,18 +25,18 @@
</th> </th>
</tr> </tr>
@foreach($pedido['productos'] as $producto) @foreach($subpedido->productos as $producto)
@if(!$producto['bono']) @if(!$producto->bono)
<tr> <tr>
<td> <td>
{{ $producto['nombre'] }} {{ $producto->nombre }}
@if($producto['pivot']['notas']) @if($producto->pivot->notas)
<br /><b>Talle/Color:</b> {{ $producto['pivot']['notas'] }} <br /><b>Talle/Color:</b> {{ $producto->pivot->notas }}
@endif @endif
</td> </td>
<td style="text-align: center"> <td style="text-align: center">
{{ $producto['pivot']['cantidad'] }} {{ $producto->pivot->cantidad }}
</td> </td>
</tr> </tr>
@endif @endif

View file

@ -1,5 +1,8 @@
<?php <?php
use App\Filtros\FiltroDeProducto;
use App\Filtros\FiltroDeSubpedido;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route; use Illuminate\Support\Facades\Route;
use App\GrupoDeCompra; use App\GrupoDeCompra;
use App\Producto; use App\Producto;

View file

@ -1,9 +1,6 @@
<?php <?php
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Route; use Illuminate\Support\Facades\Route;
use Illuminate\Support\Facades\URL;
use Symfony\Component\HttpKernel\Exception\HttpException; use Symfony\Component\HttpKernel\Exception\HttpException;
/* /*
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------
@ -29,15 +26,16 @@ Route::get('/productos', 'ProductoController@index')->name('productos.index');
Route::get('/admin', 'AdminController@show')->name('admin_login.show'); Route::get('/admin', 'AdminController@show')->name('admin_login.show');
Route::get('/admin/obtener_sesion', function() { Route::get('/admin/obtener_sesion', function() {
return [ $sesion = [
'gdc' => session("admin_gdc") 'gdc' => session("admin_gdc")
]; ];
return $sesion;
})->name('admin_obtener_sesion'); })->name('admin_obtener_sesion');
Route::middleware(['auth', 'admin'])->group( function () { Route::middleware(['auth', 'admin'])->group( function () {
Route::get('/admin/pedidos', 'AdminController@index')->name('admin_login.index'); Route::get('/admin/pedidos', 'AdminController@index')->name('admin_login.index');
Route::get('/admin/exportar-planillas-a-pdf/{gdc}', 'AdminController@exportarPedidosAPdf'); Route::get('/admin/exportar-planillas-a-pdf/{gdc}', 'AdminController@exportarPlanillasAPdf');
Route::get('/admin/exportar-pedido-a-csv/{gdc}', 'AdminController@exportarPedidoACSV'); Route::get('/admin/exportar-pedido-a-csv/{gdc}', 'AdminController@exportarPedidoACSV');
@ -66,13 +64,14 @@ Route::middleware('auth')->group( function() {
})->name('guardarSesion'); })->name('guardarSesion');
Route::get('obtener_sesion', function() { Route::get('obtener_sesion', function() {
return [ $sesion = [
'subpedido' => [ 'subpedido' => [
'nombre' => session("subpedido_nombre"), 'nombre' => session("subpedido_nombre"),
'id' => session("subpedido_id") 'id' => session("subpedido_id")
], ],
'gdc' => session("gdc") 'gdc' => session("gdc")
]; ];
return $sesion;
})->name('obtenerSesion'); })->name('obtenerSesion');
}); });
}); });
@ -83,7 +82,7 @@ Route::middleware(['compras'])->group( function() {
Route::get('/compras/pedidos', 'ComprasController@indexPedidos')->name('compras.pedidos'); Route::get('/compras/pedidos', 'ComprasController@indexPedidos')->name('compras.pedidos');
Route::get('/compras/pedidos/descargar', 'ComprasController@descargarPedidos')->name('compras.pedidos.descargar'); Route::get('/compras/pedidos/descargar', 'ComprasController@descargarPedidos')->name('compras.pedidos.descargar');
Route::get('/compras/pedidos/notas', 'ComprasController@descargarNotas')->name('compras.pedidos.descargar'); Route::get('/compras/pedidos/notas', 'ComprasController@descargarNotas')->name('compras.pedidos.descargar');
Route::get('/compras/pedidos/pdf', 'ComprasController@pdf')->name('compras.pedidos.pdf'); Route::get('/compras/pedidos/transporte', 'ComprasController@descargarTransporte')->name('compras.pedidos.descargar');
Route::post('/compras/canasta', 'ComprasController@cargarCanasta')->name('compras.canasta'); Route::post('/compras/canasta', 'ComprasController@cargarCanasta')->name('compras.canasta');
Route::get('/compras/canasta/ejemplo', 'ComprasController@descargarCanastaEjemplo')->name('compras.canasta.ejemplo'); Route::get('/compras/canasta/ejemplo', 'ComprasController@descargarCanastaEjemplo')->name('compras.canasta.ejemplo');
}); });