219 lines
6.9 KiB
PHP
219 lines
6.9 KiB
PHP
<?php
|
|
|
|
namespace App\Helpers;
|
|
|
|
use App\GrupoDeCompra;
|
|
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();
|
|
self::exportarCSV(
|
|
$filePath,
|
|
$barrios,
|
|
self::generarContenidoCSV(
|
|
$barrios,
|
|
fn ($grupoId) =>
|
|
"subpedidos.grupo_de_compra_id = $grupoId
|
|
AND subpedidos.tipo_pedido_id = 2"
|
|
)
|
|
);
|
|
}
|
|
|
|
/**
|
|
* @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;
|
|
}
|
|
}
|