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 *
* 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; } }