*/ protected $fillable = [ 'nombre', ]; /** * La región a la que pertenece el barrio. */ public function region(): BelongsTo { return $this->belongsTo(Region::class); } /** * Los pedidos que pertenecen al barrio. */ public function pedidos(): HasMany { return $this->hasMany(Pedido::class); } public function crearPedido(string $nombre) : Pedido { return $this->pedidos()->create(['nombre' => $nombre]); } /** * Devuelve una query, para obtener el resultado agregarle ->get(). * La query devuelve objetos con todos los atributos de un producto, seguidos * de la cantidad de ese producto pedida entre todos los pedidos del barrio y * el costo total de dicha cantidad. */ public function productosPedidos() { return DB::table('productos') ->join('pedido_producto', 'productos.id', '=', 'pedido_producto.producto_id') ->join('pedidos', 'pedidos.id', '=', 'pedido_producto.pedido_id') ->where(['pedidos.barrio_id' => $this->id, 'pedidos.pagado' => true]) ->select('productos.*', DB::raw('SUM(pedido_producto.cantidad) as cantidad'), DB::raw('SUM(pedido_producto.cantidad * productos.precio) as total')) ->groupBy('productos.id'); } public function totalARecaudar() : float { return $this->pedidos()->where(['pagado' => true])->get()->sum( fn($p) => $p->totalATransferir() ); } public function totalATransferir() : float { return $this->totalProductosConTransporte() + $this->totalBonosDeTransporte(); } public function totalBonosDeTransporte() : int { return TransporteUtils::calcularTotal($this->totalProductosConTransporte()); } public function totalProductosConTransporte(): float { return $this->totalProductosIf(fn($p) => $p->pagaTransporte()); } private function totalProductosIf($predicado) : float { return $this->productosPedidos()->where($predicado)->get()->sum( fn($producto) => $producto->total ); } /** * Los productos que pertenecen al barrio. */ public function productos(): HasMany { return $this->hasMany(Producto::class); } public function exportarPedidoACsv() { if ($this->productosPedidos()->get()->isNotEmpty()) { $columnaProductos = $this->armarColumnaTotales(); try { $writer = Writer::createFromPath(resource_path('csv/exports/'.$this->nombre.'.csv'), 'w'); $writer->setDelimiter("|"); $writer->setEnclosure("'"); $writer->insertAll($columnaProductos); return true; } catch (CannotInsertRecord $e) { var_export($e->getRecords()); return false; } } return false; } private function armarColumnaTotales() : array { $columnaProductos = []; $filasVaciasAgregadas = false; $productos = $this->productosPedidos()->where(['barrial' => false])->get(); foreach (Categoria::orderBy('id')->get() as $categoria) { if ($categoria->productos()->where(['barrial' => false])->count() == 0) continue; $columnaProductos[] = ['nombre' => $categoria->nombre, 'cantidad' => null]; if ($categoria->nombre == 'TRANSPORTE, BONOS Y FINANCIAMIENTO SORORO') $columnaProductos[] = ['nombre' => 'Bono de Transporte', 'cantidad' => TransporteUtils::cantidad($this->totalProductosConTransporte())]; if ($categoria->nombre == 'PRODUCTOS DE GESTIÓN MENSTRUAL') $columnaProductos[] = ['nombre' => '¿Cuántas copas quieren y pueden comprar en el grupo?', 'cantidad' => null]; foreach ($categoria->productos()->orderBy('id')->get() as $producto) { if ($producto->precio == 0 && !$filasVaciasAgregadas) { $columnaProductos[] = ['nombre' => '¿Cuántas copas quieren adquirir a través del financiamiento sororo?', 'cantidad' => null]; $filasVaciasAgregadas = true; } $columnaProductos[] = ['nombre' => $producto->nombre, 'cantidad' => $this->cantidadPedida($producto->id, $productos)]; } } return $columnaProductos; } private function cantidadPedida($productoId, $productos) { return $productos->find($productoId)->cantidad ?? 0; } }