Vistas y controladores personalizados en Laravel Voyager

En esta ocasión veremos como trabajar con nuestras propias vistas y controladores en Voyager Laravel.

Tomaré como ejemplo la creación de una orden de servicio o de compra a la que se le vincularan artículos.

Desde el gestor de tablas creen una tabla llamada products.  Creen también su modelo.

Agreguen los campos que gusten.  Con los campos id, descripción y los timestamps será suficiente para este ejemplo.

Yo tengo más campos porque los usaré para otro post.

Creen el BREAD de esa tabla y cárguenle algo de info.

Vamos a crear la tabla de orden de servicio

Se llamará orders y contendrá los campos (recuerden crear también el modelo):

Id, number, date, notes, subtotal, total, iva.

Los tres últimos campos nos servirán para almacenar los costos del total de la orden.

También creen el BREAD para esta tabla.

Lo siguiente es crear la tabla puente entre productos y ordenes, por convención se llamará order_products y tendrá la siguiente estructura (a esta tabla no será necesario crearle un modelo):

Ahora ya tenemos todo listo para empezar.

Tenemos que decirle a Laravel como se relacionaran las tablas, orders, products y order_products (nuestra tabla pivote).

Abran el modelo de Order y agregaremos la siguiente función

class Order extends Model
{
    public function products()
    {
        return $this->belongsToMany('App\Product','order_products', 'order_id','product_id')->withPivot('id','quantity','cost_unity');
    }
}

De esta manera le decimos cual será la relación entre ordenes y productos y que de esa relación me interesa obtener también los campos cuantity y cost_unity.

Vistas personalizadas

Toca el turno de crear nuestras propias vistas, lo que haremos es tomar como base las vistas que Voyager usar por defecto y las copiaremos en una nueva carpeta.

Para el módulo de ordenes de servicio no necesitaremos modificar la vista Index ó, como le llaman aquí: Browse.  Nos centraremos en la vista de creación y edición que en Voyager es una sola vista.

Hay que dirigirse a la siguiente ubicación: vendor/tcg/resources/view/bread/

Aquí es donde están las vistas que se usan para todos los módulos, copiemos primero el archivo edit-add.blade.php y nos movemos a la siguiente dirección: /resources/views/vendor/voyager/ aquí vamos a crear la carpeta ordenes y dentro de esa carpeta pegamos la vista de tal forma que quede así: /resources/views/vendor/voyager/ordes/edit-add.blade.php

Nota:  “deben llamar a la carpeta con el nombre del slug que están usando para ese modelo o sección, en mi caso yo llamé a la tabla orders pero al CRUD le di el slug de ordenes  entonces yo debería llamar a mi carpeta ordenes y no orders, pero eso dependerá de cómo le llamaron ustedes.”

Mi url es esta:  /public/admin/ordenes/créate

Si nos dirigimos a la vista de creación de ordenes podemos ver que nada ha cambiado

Pero si vamos a nuestra nueva vista y modificamos la sección del ‘page_header’ de esta manera:

@section('page_header')
    <h1 class="page-title">
        <i class="{{ $dataType->icon }}"></i>
        {{ __('voyager::generic.'.($edit ? 'edit' : 'add')).' '.$dataType->getTranslatedAttribute('display_name_singular') }}
        Título de prueba
    </h1>
    @include('voyager::multilingual.language-selector')
@stop

Si guardamos y actualizamos la vista podemos ver el cambio

Ahora ya pueden controlar la vista a discreción tanto como la necesiten.

Ustedes pueden borrar todo el código y empezar a construir su vista desde cero, pero para este ejemplo solo agregaré las líneas necesarias para darle la funcionalidad que necesito.

Agregando un controlador

Ahora vamos a personalizar nuestro controlador.

Al igual que las vistas, Voyager también tiene controladores predeterminados. La ruta para encontrar el controlador es /vendor/tcg/Voyager/src/Http/Controllers/VoyagerBaseController.php

Copien ese archivo.

Y lo vamos a pegar en la siguiente ruta

/app/Http/Controllers/Voyager/OrdersController.php

Abran el archive OrdersController.php y modifiquemos las siguientes líneas

El namespace debe quedar así: 

namespace App\Http\Controllers\Voyager;

Sustituimos la línea del nombre de la clase por esto:

class OrdersController extends \TCG\Voyager\Http\Controllers\VoyagerBaseController 

El último paso para vincular ese controlador con nuestra vista es ir a la configuración del BREAD y decirle cuál es su controlador. En el nombre del controlado colocamos este:

\App\Http\Controllers\Voyager\OrdersController

Guarden.

En este punto nuestras vistas de ordenes ya están trabajando con su propio controlador.

Hagamos una prueba.  En el archivo OrdersController.php vamos a la función index y quitemos todo el código y solo escriban un mensaje, por ejemplo:

public function index(Request $request)
    {
        return "Hola!";
    }

Guarden y vayan al módulo de ordenes

Listo, esto es todo lo que necesitamos saber para controlar totalmente nuestras vistas.

Para el resto del articulo no entraré en detalles del código porque si no, esto se alargará mucho, solo resumiré lo que estoy haciendo para mostrarle al final el resultado.

Lo que haré es crear una nueva orden pero le pasaré los artículos para que el usuario pueda ir agregándolos a la orden.

En OrdersController.php debemos agregar el modelo de los productos

use App\Product;

Después nos dirigimos a la función create y antes de que termine, agregamos la siguientes líneas:

$products =Product::where('status','=',1)
        ->orderBy('description','ASC')
        ->get();
        return Voyager::view($view, compact('dataType', 'dataTypeContent', 'isModelTranslatable','products'));

De esta forma la vista créate tendrá ya los datos de los productos.

Ahora hay que ir a la vista edit-add.blade.php y mostrar los artículos, lo que haré es hacer un ciclo para meter los artículos en un select y colocar otros campos como la cantidad o el precio unitario.

Esa sección lo colocaré justo después del botón guardar.

Después de esos cambios nuestro form se verá así:

Lo que sigue es hacer (mediante javascript) que los artículos se vayan agregando al form y se ejecuten las operaciones para obtener el impuesto y el total.

En el mismo edit-add.blade.php hay una sección al final donde podemos agregar los archivos javascript que necesiten usar:

@section('javascript')
    <script type="text/javascript" src="{{ URL::asset('js/orders.js') }}"></script>
    <script src="{{ asset(js/select2/dist/js/select2.full.min.js') }}"></script>
    <script type="text/javascript" src="{{ URL::asset('js/alertifyjs/alertify.js') }}"></script>
@stop

Yo estoy usando una librería para integrarle un buscador a los select y a parte hago referencia a al código js que usará y que he organizado en el archivo orders.js

La carpeta donde los guardo es public/js.

Después de hacer un poquito de magia, el form se ve así:

A medida que vamos ingresando los artículos y colocándole la cantidad y el precio unitario el form hará los cálculos.  Si se elimina alguna partida, el form realizará los cálculos nuevamente.

Ahora queda guardar toda la info en las tablas, pero eso lo realizaré en otro articulo o bien, lo pueden hacer de tarea. Con lo visto hasta este momento ustedes pueden trabajar con Voyager como si estuvieran trabajando cualquier proyecto en Laravel.

Related Posts Plugin for WordPress, Blogger...

publicidad

3 Comments

  1. Hola Alberto,

    Muy buen artículo! Serías tan amable de colgar el código de ejemplo para hacernos una idea de los cambios en la vista o en el controlador?

    Y otra cosa, en la linea return Voyager::view($view, compact(‘dataType’, ‘dataTypeContent’, ‘isModelTranslatable’,’sproducts’)); no sería más bien ‘products’?

    Gracias de antemano!

Deja una respuesta

Tu dirección de correo electrónico no será publicada.