Software">
Nothing Special   »   [go: up one dir, main page]

Crud Laravel Vue 2.0

Descargar como docx, pdf o txt
Descargar como docx, pdf o txt
Está en la página 1de 59

Crear 

proyecto en Laravel:
composer create-project --prefer-dist laravel/laravel senasoft_beta "5.6."*

Ubicarse dentro del proyecto en la línea de comandos e iniciar el servidor:

php artisan serve

Abrir la url : 
localhost:8000
Y Verficiar el funcionamiento del aplicativo
Abrir el proyecto con Visual Studio Code

Pasos para instalar vue

Vue es una librería para desarrollar de lado del Frontend

En la terminal de comandos del proyecto:

Verificar si node y npm están instalados. Si no están instalados


instalarlos. Si se instala node automáticamente se instala npm
 node -v

 npm -v

Instalar Laravel mix para trabajar con package.json. Se instala en el direct
orio del proyecto de la siguiente manera:

npm install

Luego de instalar ejecutar en el directorio del proyecto:

npm run dev

El anterior comando permite compilar todos los archivos javascript y css.


Cuando se hagan cambios a componentes de vue debe ejecutarse el comando npm run dev

instalar sweetalert
npm install sweetalert --save-dev

Editar el archivo boostrap
resources\assets\js\bootstrap.js

Agregar el código:
require("sweetalert");

boostrap.js debe quedar como el siguiente código:

window._ = require('lodash');
window.Popper = require('popper.js').default;

/**
 * We'll load jQuery and the Bootstrap jQuery plugin which provides support
 * for JavaScript based Bootstrap features such as modals and tabs. This
 * code may be modified to fit the specific needs of your application.
 */

try {
    window.$ = window.jQuery = require('jquery');

    require('bootstrap');
    require("sweetalert");
} catch (e) {}

/**
 * We'll load the axios HTTP library which allows us to easily issue request
s
 * to our Laravel back-end. This library automatically handles sending the
 * CSRF token as a header based on the value of the "XSRF" token cookie.
 */

window.axios = require('axios');

window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';

/**
 * Next we will register the CSRF Token as a common header with Axios so tha
t
 * all outgoing HTTP requests automatically have it attached. This is just
 * a simple convenience so we don't have to attach every token manually.
 */

let token = document.head.querySelector('meta[name="csrf-token"]');

if (token) {
    window.axios.defaults.headers.common['X-CSRF-TOKEN'] = token.content;
} else {
    console.error('CSRF token not found: https://laravel.com/docs/csrf#csrf-
x-csrf-token');
}

/**
 * Echo exposes an expressive API for subscribing to channels and listening
 * for events that are broadcast by Laravel. Echo and event broadcasting
 * allows your team to easily build robust real-time web applications.
 */

// import Echo from 'laravel-echo'

// window.Pusher = require('pusher-js');

// window.Echo = new Echo({
//     broadcaster: 'pusher',
//     key: process.env.MIX_PUSHER_APP_KEY,
//     cluster: process.env.MIX_PUSHER_APP_CLUSTER,
//     encrypted: true
// });

  Ejecutar el comando
   npm run dev 
El anterior comando compila javascript y css
Debe aparecer luego de compilar:

CONFIGURAR BASE DE DATOS:

Crear la base de datos en phpmyadmin:
sensasoft_beta

Cambiar la cadena de conexión de la base de datos

Ubicarse en el archivo .env y cambiar la cadena de conexión: Para el ejemplo
será:

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=senasoft_beta
DB_USERNAME=root
DB_PASSWORD=
Luego limpiar la caché de laravel cuando no se apliquen cambios en el navega
dor
php artisan cache:clear
php artisan config:clear
php artisan config:cache

Reiniciar el servidor en la línea de comandos del CMD:


php artisan serve

Migraciones:

Crear migraciones de la tabla Categoria:

php artisan make:migration create_categorias_table

El archivo migraciones debe quedar como el siguiente:

<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateCategoriasTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('categorias', function (Blueprint $table) {
            $table->increments('id');
            $table->string('nombre',50);
            $table->string('descripcion',256)->nullable;
            $table->boolean('estado')->default(1);
            $table->timestamps();
        });
    }
    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('categorias');
    }
}

Migrar la tabla:
php artisan migrate

Para crear el modelo de categorias:

php artisan make:model Categoria

El modelo categorías debe quedar como el siguiente:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Categoria extends Model
{
    protected $fillable = ['nombre','descripcion','estado'];

Luego crear el controlador Categoria:

php artisan make:Controller CategoriaController
El controlador debe quedar con los siguientes métodos:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Categoria;

class CategoriaController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index(Request $request)
    {
        $buscar = $request->buscar;
        $criterio = $request->criterio;
        
        if ($buscar==''){
            $categorias = Categoria::orderBy('id', 'desc')->paginate(3);
        }
        else{
            $categorias = Categoria::where($criterio, 'like', '%'. $buscar . 
'%')->orderBy('id', 'desc')->paginate(3);
        }
        

        return [
            'pagination' => [
                'total'        => $categorias->total(),
                'current_page' => $categorias->currentPage(),
                'per_page'     => $categorias->perPage(),
                'last_page'    => $categorias->lastPage(),
                'from'         => $categorias->firstItem(),
                'to'           => $categorias->lastItem(),
            ],
            'categorias' => $categorias
        ];
    }

    public function listaCategoria(Request $request){
         $categorias = Categoria::where('estado','=','1')
        ->select('id','nombre')->orderBy('nombre', 'asc')->get();
        return ['categorias' => $categorias];
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
         $categoria = new Categoria();
        $categoria->nombre = $request->nombre;
        $categoria->descripcion = $request->descripcion;
        $categoria->estado = '1';
        $categoria->save();
    }
  

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request)
    {
        $categoria = Categoria::findOrFail($request->id);
        $categoria->nombre = $request->nombre;
        $categoria->descripcion = $request->descripcion;
        $categoria->estado = '1';
        $categoria->save();
    }

    public function desactivar(Request $request)
    {
        if (!$request->ajax()) return redirect('/');  //Comentar cuando no s
e requieran peticiones ajax
        $categoria = Categoria::findOrFail($request->id);
        $categoria->estado = '0';
        $categoria->save();
    }

    public function activar(Request $request)
    {
        $categoria = Categoria::findOrFail($request->id);
        $categoria->estado = '1';
        $categoria->save();
    }
}

Agregar al archivo web.php las siguientes rutas:

<?php

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/

Route::get('/', function () {
    return view('welcome');
});

Route::get('/categoria', 'CategoriaController@index');
Route::post('/categoria/registrar', 'CategoriaController@store');
Route::put('/categoria/actualizar', 'CategoriaController@update');
Route::put('/categoria/activar', 'CategoriaController@activar');
Route::put('/categoria/desactivar', 'CategoriaController@desactivar');
Route::get('/categoria/listaCategoria', 'CategoriaController@selectCategoria');

insertar desde el phpmyadmin en la tabla categoria 1 registro


insertar desde el phpmyadmin en la tabla users 1 registro

Testear en la url
localhost:8000/categoria

Debe aparecer los datos de la categoría en formato json


Creando el componente vue para el crud de las categorías.

Ubicarse en el directorio resources\assets\js\components y crear el archivo


CategoriaComponent.vue

El archivo debe contener el siguiente código. El código permite realizar todo el CRUD a través de
VUE. Todo componente en vue se ubica dentro las etiquetas <template></template>

<template>
            <main class="main">
            <div class="container-fluid">
                <!-- Listado -->
                <div class="card">
                    <div class="card-header">
                        <i class="fa fa-align-justify"></i> Categorías
                        <button type="button" @click="abrirModal('categoria'
,'registrar')" class="btn btn-secondary">
                            <i class="icon-plus"></i>&nbsp;Nuevo
                        </button>
                    </div>
                    <div class="card-body">
                        <div class="form-group row">
                            <div class="col-md-6">
                                <div class="input-group">
                                    <select class="form-control col-md-3" v-
model="criterio">
                                      <option value="nombre">Nombre</option>
                                      <option value="descripcion">Descripció
n</option>
                                    </select>
                                    <input type="text" v-model="buscar" 
@keyup.enter="listarCategoria(1,buscar,criterio)" class="form-control" place
holder="Texto a buscar">
                                    <button type="submit" @click="listarCate
goria(1,buscar,criterio)" class="btn btn-primary"><i class="fa fa-
search"></i> Buscar</button>
                                </div>
                            </div>
                        </div>
                        
                        <table class="table table-bordered table-striped tab
le-sm" id="table">
                            <thead>
                                <tr>
                                    <th>Nombre</th>
                                    <th>Descripción</th>
                                    <th>Estado</th>
                                    <th>Acciones</th>
                                </tr>
                            </thead>
                            <tbody>
                                <tr v-for="categoria in arrayCategoria" 
:key="categoria.id">
                                    <td v-text="categoria.nombre"></td>
                                    <td v-text="categoria.descripcion"></td>
                                    <td>
                                        <div v-if="categoria.estado">
                                            <button class="badge badge-
success">Activo</button>
                                        </div>
                                        <div v-else>
                                             <button class="badge badge-
success">Inactivo</button>
                                        </div>
                                        
                                    </td>
                                    <td>
                                        <button type="button" @click="abrirM
odal('categoria','actualizar',categoria)" class="btn btn-warning btn-sm">
                                          <i class="icon-pencil">Editar</i>
                                        </button> &nbsp;
                                        <template v-if="categoria.estado">
                                            <button type="button" class="btn 
btn-danger" @click="desactivarCategoria(categoria.id)">
                                                <i class="icon-
trash">Inactivar</i>
                                            </button>
                                        </template>
                                        <template v-else>
                                            <button type="button" class="btn 
btn-info" @click="activarCategoria(categoria.id)">
                                                <i class="icon-
check">Activar</i>
                                            </button>
                                        </template>
                                    </td>
                                </tr>                                
                            </tbody>
                        </table>
                        <nav>
                            <ul class="pagination">
                                <li class="page-item" v-
if="pagination.current_page > 1">
                                    <a class="page-link" href="#" 
@click.prevent="cambiarPagina(pagination.current_page - 1,buscar,criterio)">
Ant</a>
                                </li>
                                <li class="page-item" v-for="page in pagesNu
mber" :key="page" :class="[page == isActived ? 'active' : '']">
                                    <a class="page-link" href="#" 
@click.prevent="cambiarPagina(page,buscar,criterio)" v-text="page"></a>
                                </li>
                                <li class="page-item" v-
if="pagination.current_page < pagination.last_page">
                                    <a class="page-link" href="#" 
@click.prevent="cambiarPagina(pagination.current_page + 1,buscar,criterio)">
Sig</a>
                                </li>
                            </ul>
                        </nav>
                    </div>
                </div>
                <!-- Fin Listado Tabla -->
            </div>
            <!--Inicio del modal agregar/actualizar-->
            <div class="modal fade" tabindex="-1" :class="{'mostrar' : moda
l}" role="dialog" aria-labelledby="myModalLabel" style="display: none;" aria
-hidden="true">
                <div class="modal-dialog modal-primary modal-lg" rol
e="document">
                    <div class="modal-content">
                        <div class="modal-header">
                            <h4 class="modal-title" v-
text="tituloModal"></h4>
                            <button type="button" class="close" @click="cerr
arModal()" aria-label="Close">
                              <span aria-hidden="true">×</span>
                            </button>
                        </div>
                        <div class="modal-body">
                            <form action="" method="post" enctype="multipart
/form-data" class="form-horizontal">
                                <div class="form-group row">
                                    <label class="col-md-3 form-control-
label" for="text-input">Nombre</label>
                                    <div class="col-md-9">
                                        <input type="text" v-model="nombre" 
class="form-control" placeholder="Nombre de categoría">
                                        
                                    </div>
                                </div>
                                <div class="form-group row">
                                    <label class="col-md-3 form-control-
label" for="email-input">Descripción</label>
                                    <div class="col-md-9">
                                        <input type="email" v-
model="descripcion" class="form-control" placeholder="Ingrese descripción">
                                    </div>
                                </div>
                                <div v-show="errorCategoria" class="form-
group row div-error">
                                    <div class="text-center text-error">
                                        <div v-for="error in errorMostrarMsj
Categoria" :key="error" v-text="error">

                                        </div>
                                    </div>
                                </div>

                            </form>
                        </div>
                        <div class="modal-footer">
                            <button type="button" class="btn btn-secondary" 
@click="cerrarModal()">Cerrar</button>
                            <button type="button" v-if="tipoAccion==1" clas
s="btn btn-primary" @click="registrarCategoria()">Guardar</button>
                            <button type="button" v-if="tipoAccion==2" clas
s="btn btn-primary" @click="actualizarCategoria()">Actualizar</button>
                        </div>
                    </div>
                    <!-- /.modal-content -->
                </div>
                <!-- /.modal-dialog -->
            </div>
            <!--Fin del modal-->
        </main>
</template>

<script>
    export default {
        data (){
            return {
                //Variables a usar de javascript
                categoria_id: 0,
                nombre : '',
                descripcion : '',
                arrayCategoria : [], //array para almacenar las categorias
                modal : 0,
                tituloModal : '',
                tipoAccion : 0,
                errorCategoria : 0,
                errorMostrarMsjCategoria : [],
                pagination : {
                    'total' : 0,
                    'current_page' : 0,
                    'per_page' : 0,
                    'last_page' : 0,
                    'from' : 0,
                    'to' : 0,
                },
                offset : 3,
                criterio : 'nombre',
                buscar : ''
            }
        },
        computed:{
            isActived: function(){
                return this.pagination.current_page; //Retornar la página ac
tiva
            },
            //Calcular los elementos de la paginación
            pagesNumber: function() {
                if(!this.pagination.to) {
                    return [];
                }
                
                var from = this.pagination.current_page - this.offset; 
                if(from < 1) {
                    from = 1;
                }

                var to = from + (this.offset * 2); 
                if(to >= this.pagination.last_page){
                    to = this.pagination.last_page;
                }  

                var pagesArray = [];
                while(from <= to) {
                    pagesArray.push(from);
                    from++;
                }
                return pagesArray;             

            }
        },
        methods : {
            //Mètodos involucrados en el CRUD
            listarCategoria (page,buscar,criterio){ //Listar las categorías.
                let me=this;
                var url= '/categoria?page=' + page + '&buscar='+ buscar + '&
criterio='+ criterio;
                axios.get(url).then(function (response) {
                    var respuesta= response.data;
                    me.arrayCategoria = respuesta.categorias.data;
                    me.pagination= respuesta.pagination;
                })
                .catch(function (error) {
                    console.log(error);
                });
            },
            cambiarPagina(page,buscar,criterio){ //Método para cambiar de pá
gina en la paginación
                let me = this;
                //Actualiza la página actual
                me.pagination.current_page = page;
                //Envia la petición para visualizar la data de esa página
                me.listarCategoria(page,buscar,criterio);
            },
            registrarCategoria(){ //Método para Registrar la Categoría
                if (this.validarCategoria()){
                    return;
                }
                
                let me = this;

                axios.post('/categoria/registrar',{
                    'nombre': this.nombre,
                    'descripcion': this.descripcion
                }).then(function (response) {
                    me.cerrarModal();
                    me.listarCategoria(1,'','nombre');
                }).catch(function (error) {
                    console.log(error);
                });
            },
            actualizarCategoria(){ //Método para actualizar la categoría
               if (this.validarCategoria()){
                    return;
                }
                
                let me = this;

                axios.put('/categoria/actualizar',{
                    'nombre': this.nombre,
                    'descripcion': this.descripcion,
                    'id': this.categoria_id
                }).then(function (response) {
                    me.cerrarModal();
                    me.listarCategoria(1,'','nombre');
                }).catch(function (error) {
                    console.log(error);
                }); 
            },
            desactivarCategoria(id){ //Método para desactivar la categoría
                let me = this;
                 axios.put('/categoria/desactivar',{
                        'id': id
                    }).then(function (response) {
                        
                        me.listarCategoria(1,'','nombre');
                        swal(
                        'Desactivado!',
                        'El registro ha sido desactivado con éxito.',
                        'success'
                        )
                        
                       console.log(response);
                    }).catch(function (error) {
                        console.log(error);
                    });
            },
            activarCategoria(id){ //Método para activar la categoría
                                let me = this;

                    axios.put('/categoria/activar',{
                        'id': id
                    }).then(function (response) {
                        console.log(response);
                        me.listarCategoria(1,'','nombre');
                        swal(
                        'Activado!',
                        'El registro ha sido activado con éxito.',
                        'success'
                        )
                    }).catch(function (error) {
                        console.log(error);
                    });
            },
            validarCategoria(){ //Método para Validar la Categoría
                this.errorCategoria=0;
                this.errorMostrarMsjCategoria =[];

                if (!this.nombre) this.errorMostrarMsjCategoria.push("El nom
bre de la categoría no puede estar vacío.");

                if (this.errorMostrarMsjCategoria.length) this.errorCategori
a = 1;

                return this.errorCategoria;
            },
            cerrarModal(){ //Método para cerrar la modal
                this.modal=0;
                this.tituloModal='';
                this.nombre='';
                this.descripcion='';
            },
            abrirModal(modelo, accion, data = []){ //Método para abrir la mo
dal
                switch(modelo){
                    case "categoria":
                    {
                        switch(accion){
                            case 'registrar':
                            {
                                this.modal = 1;
                                this.tituloModal = 'Registrar Categoría';
                                this.nombre= '';
                                this.descripcion = '';
                                this.tipoAccion = 1;
                                break;
                            }
                            case 'actualizar':
                            {
                                this.modal=1;
                                this.tituloModal='Actualizar categoría';
                                this.tipoAccion=2;
                                this.categoria_id=data['id'];
                                this.nombre = data['nombre'];
                                this.descripcion= data['descripcion'];
                                break;
                            }
                        }
                    }
                }
            }
        },
        mounted() { //Método que se cargaal acceder al componente.
            this.listarCategoria(1,this.buscar,this.criterio);
        }
    }
</script>

<style>    
    .modal-content{
        width: 100% !important;
        position: absolute !important;
    }
    .mostrar{
        display: list-item !important;
        opacity: 1 !important;
        position: absolute !important;
        background-color: #3c29297a !important;
    }
    .text-error{
        color: red !important;
        font-weight: bold;
    }
    .div-error{
        display: flex;
        justify-content: center;
    }
</style>

Luego de crear un componente vue, para incluir los cambios en la aplicación ejecutar el
comando npm run dev para compilar el componente.

Abrir el archivo app.js

Debe quedar como sigue:

/**
 * First we will load all of this project's JavaScript dependencies which
 * includes Vue and other libraries. It is a great starting point when
 * building robust, powerful web applications using Vue and Laravel.
 */

require('./bootstrap');

window.Vue = require('vue');

/**
 * Next, we will create a fresh Vue application instance and attach it to
 * the page. Then, you may begin adding components to this application
 * or customize the JavaScript scaffolding to fit your unique needs.
 */

//Se deben ubicar los componentes
//Vue.component('example-component', require('./components/ExampleComponent.
vue'));
Vue.component('categoria-component', requir
e('./components/CategoriaComponent.vue'));

const app = new Vue({
    el: '#app', // Este es el id de la línea 12 ubicado en principal.blade.p
hp
    data :{
        menu :0  //Se indica la opción de menú 0
    }
});
Ejecutar el comando npm run dev para incluir los cambios efectuados en app.js

Configurando menú con Vue:

En el directorio resources\views crear el archivo menu.blade.php con el siguiente código:

<div class="sidebar">
    <nav class="sidebar-nav">
        <ul class="nav">
            <li class="nav-item nav-dropdown">
                <a class="nav-link nav-dropdown-toggle" href="#"><i clas
s="icon-bag"></i> Almacén</a>
                <ul class="nav-dropdown-items">
                    <li @click="menu=1" class="nav-item">
                        <a class="nav-link" href="#"><i class="icon-
bag"></i> Categorías</a>
                    </li>
                    <li @click="menu=2" class="nav-item">
                        <a class="nav-link" href="#"><i class="icon-
bag"></i> Productos</a>
                    </li>
                    <li @click="menu=3" class="nav-item">
                        <a class="nav-link" href="#"><i class="icon-
bag"></i> Ventas</a>
                    </li>
                </ul>
            </li>
        </ul>
    </nav>
</div>

El @click="menu=1” indica que cuando se le dé clic a esa opción llama el


menu1 el cual corresponde a las categorías.

El @click="menu=2” indica que cuando se le dé clic a esa opción llama el


menu1 el cual corresponde a los productos.

El @click="menu=13indica que cuando se le dé clic a esa opción llama el menu3


el cual corresponde a las ventas.

En el directorio resources\views crear el archivo contenido.blade.php

El archivo debe contener el siguiente código:


@extends('principal')
@section('contenido')

   <template v-if="menu==1">
   <!-- v-if es el if en vue -->
     <!--redireccionar al componente categoria-component -->
      <categoria-component></categoria-component>
   </template>

   <template v-if="menu==2">
       <h1>Contenido del menú 2</h1>
   </template>

   <template v-if="menu==3">
    <!--redireccionar al componente venta-component -->
   <venta-component></venta-component>
   </template>

@endsection

En el directorio resources\views crear el archivo principal.blade.php

El archivo debe contener el siguiente código:

<!doctype html>
<html lang="{{ app()->getLocale() }}">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Prueba</title>
        <link href="{{asset('css/app.css')}}" rel="stylesheet"> <!--Añadimos 
el css-->
        <meta name="csrf-token" content="{{ csrf_token() }}">
    </head>
    <body>
            <div id="app" class="content"><!--La equita id debe ser app, com
o hemos visto en app.js-->
            @include('menu')
            @yield('contenido')
            </div>
        <script src="{{asset('js/app.js')}}"></script> <!--Añadimos el js, d
onde se encuentra el componente vuejs-->
    </body>
</html>

principal.blade.php es el archivo que se cargará por defecto.

Para cargarlo por defecto ir al archivo web.php y cambiar

Route::get('/', function () {
    return view('welcome');
});

Por:

Route::get('/', function () {
    return view('contenido');
});

Al ir al navegador debe aparecer una ventana como la siguiente:

Al dar clic en categorías deberá aparecer:


CRUD MAESTRO DETALLE.

Para realizar el CRUD maestro detalle requerimos de las siguientes entidades:

Categoria que ya está creada.

Cliente

Producto

Crear la migracion de productos

php artisan make:migration create_productos_table

El archivo migraciones de producto debe quedar como el siguiente:

<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateProductosTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up() //Crear la migración de productos
    {
        Schema::create('productos', function (Blueprint $table) {
                $table->increments('id');
                $table->integer('idcategoria')->unsigned();
                $table->string('codigo', 30)->nullable();
                $table->string('nombre', 60)->unique();
                $table->string('descripcion', 256)->nullable();
                $table->decimal('precio', 12, 2);
                $table->integer('stock');
                $table->boolean('estado')->default(1);
                $table->timestamps();
                $table->foreign('idcategoria')->references('id')-
>on('categorias');
          });
     }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('productos');
    }
}

Realizar la migración de producto

php artisan migrate
Crear el modelo de productos:

php artisan make:model Producto

El modelo de productos debe quedar como el siguiente:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Producto extends Model
{
    protected $fillable =[
        'idcategoria','codigo','nombre', 'descripcion','precio','stock','est
ado'
    ];
    public function categoria(){
        return $this->belongsTo('App\Categoria');
    }
}

Crear el controlador:

php artisan make:Controller ProductoController

El controlador debe quedar de la siguiente manera:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Producto;
class ProductoController extends Controller
{
    public function index(Request $request)
    {
        $buscar = $request->buscar;
        $criterio = $request->criterio;
        
        if ($buscar==''){
            $productos = Producto::join('categorias','productos.idcategoria'
,'=','categorias.id')
            -
>select('productos.id','productos.idcategoria','productos.codigo','productos
.nombre','productos.descripcion','categorias.nombre as nombre_categoria','pr
oductos.precio','productos.stock','productos.estado')
            ->orderBy('productos.id', 'desc')->paginate(3);
        }
        else{
            $productos = Producto::join('categorias','productos.idcategoria'
,'=','categorias.id')
            -
>select('productos.id','productos.idcategoria','productos.codigo','productos
.nombre','categorias.nombre as nombre_categoria','productos.descripcion','pr
oductos.precio','productos.stock','productos.estado')
            ->where('productos.'.$criterio, 'like', '%'. $buscar . '%')
            ->orderBy('productos.id', 'desc')->paginate(3);
        }
        

        return [
            'pagination' => [
                'total'        => $productos->total(),
                'current_page' => $productos->currentPage(),
                'per_page'     => $productos->perPage(),
                'last_page'    => $productos->lastPage(),
                'from'         => $productos->firstItem(),
                'to'           => $productos->lastItem(),
            ],
            'productos' => $productos
        ];
    }
    
    public function store(Request $request)
    {
        $producto = new Producto();
        $producto->idcategoria = $request->idcategoria;
        $producto->codigo = $request->codigo;
        $producto->nombre = $request->nombre;
        $producto->descripcion = $request->descripcion;
        $producto->precio = $request->precio;
        $producto->stock = $request->stock;
        $producto->estado = '1';
        $producto->save();
    }
    public function update(Request $request)
    {
        $producto = Producto::findOrFail($request->id);
        $producto->idcategoria = $request->idcategoria;
        $producto->codigo = $request->codigo;
        $producto->nombre = $request->nombre;
        $producto->descripcion = $request->descripcion;
        $producto->precio = $request->precio;
        $producto->stock = $request->stock;
        $producto->estado = '1';
        $producto->save();
    }

    public function activar(Request $request)
    {
        $producto = Producto::findOrFail($request->id);
        $producto->estado = '1';
        $producto->save();
    }

    public function desactivar(Request $request)
    {
        $producto = Producto::findOrFail($request->id);
        $producto->estado = '0';
        $producto->save();
    }

    public function listarProductoVenta(Request $request)
    {
        $buscar = $request->buscar;
        $criterio = $request->criterio;
        
        if ($buscar==''){
            $productos = Producto::join('categorias','productos.idcategoria'
,'=','categorias.id')
            -
>select('productos.id','productos.idcategoria','productos.codigo','productos
.nombre','categorias.nombre as nombre_categoria','productos.precio','product
os.stock','productos.descripcion','productos.estado')
            ->where('productos.stock','>','0')
            ->orderBy('productos.id', 'desc')->paginate(10);
        }
        else{
            $productos = Producto::join('categorias','productos.idcategoria'
,'=','categorias.id')
            -
>select('productos.id','productos.idcategoria','productos.codigo','productos
.nombre','categorias.nombre as nombre_categoria','productos.precio','product
os.stock','productos.descripcion','productos.estado')
            ->where('productos.'.$criterio, 'like', '%'. $buscar . '%')
            ->where('productos.stock','>','0')
            ->orderBy('productos.id', 'desc')->paginate(10);
        }
        

        return ['productos' => $productos];
    }

    public function buscarProductoVenta(Request $request){

        $filtro = $request->filtro;
        $productos = Producto::where('codigo','=', $filtro)
        ->select('id','nombre','stock','precio')
        ->where('stock','>','0')
        ->orderBy('nombre', 'asc')
        ->take(1)->get();

        return ['productos' => $productos];
    }

Agregar las siguientes rutas a web.php

Route::get('/producto', 'ProductoController@index');
Route::post('/producto/registrar', 'ProductoController@store');
Route::put('/producto/actualizar', 'ProductoController@update');
Route::put('/producto/activar', 'ProductoController@activar');
Route::put('/producto/desactivar', 'ProductoController@desactivar');
Route::get('/producto/buscarProducto', 'ProductoController@buscarProducto');
Route::get('/producto/listarProducto', 'ProductoController@listarProducto');
Route::get('/producto/buscarProductoVenta', 'ProductoController@buscarProduc
toVenta');
Route::get('/producto/listarProductoVenta', 'ProductoController@listarProduc
toVenta');

Insertar un registro en la tabla productos empleando phpmyadmin

Ir a la Url y probar localhost:8000/producto

Debe aparecer en formato json el producto ingresado,

////////////////////////////////////////FIN PRODUCTOS////////////////////////////////////////

////////////////////////////////////////INICIO CLIENTES////////////////////////////////////////

Crear la migracion de clientes

php artisan make:migration create_clientes_table

El archivo migraciones de cliente debe quedar como el siguiente:

<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateClientesTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('clientes', function (Blueprint $table) {
            $table->increments('id');
            $table->string('nombre', 100)->unique();
            $table->string('tipo_documento', 20)->nullable();
            $table->string('numero_documento', 20)->nullable();
            $table->string('direccion', 70)->nullable();
            $table->string('telefono', 20)->nullable();
            $table->string('email', 50)->nullable();
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('clientes');
    }
}
Realizar la migración de cliente

php artisan migrate

Crear el modelo de clientes:

php artisan make:model Cliente

El modelo de clientes debe quedar como el siguiente:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Cliente extends Model
{
    protected $fillable = ['nombre','tipo_documento','numero_documento','dir
eccion','telefono','email'];

    public function user()
    {
        return $this->hasOne('App\User');
    }
}

Crear el controlador:

php artisan make:Controller ClienteController

El controlador debe quedar de la siguiente manera:

<?php

namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Cliente;

class ClienteController extends Controller
{
    public function index(Request $request)
    {
        $buscar = $request->buscar;
        $criterio = $request->criterio;
        
        if ($buscar==''){
            $clientes = Cliente::orderBy('id', 'desc')->paginate(3);
        }
        else{
            $clientes = Cliente::where($criterio, 'like', '%'. $buscar . '%'
)->orderBy('id', 'desc')->paginate(3);
        }    

        return [
            'pagination' => [
                'total'        => $clientes->total(),
                'current_page' => $clientes->currentPage(),
                'per_page'     => $clientes->perPage(),
                'last_page'    => $clientes->lastPage(),
                'from'         => $clientes->firstItem(),
                'to'           => $clientes->lastItem(),
            ],
            'clientes' => $clientes
        ];
    }

    public function listaCliente(Request $request){
        $filtro = $request->filtro;
        $clientes = Cliente::where('nombre', 'like', '%'. $filtro . '%')
        ->orWhere('numero_documento', 'like', '%'. $filtro . '%')
        ->select('id','nombre','numero_documento')
        ->orderBy('nombre', 'asc')->get();

        return ['clientes' => $clientes];
    }

    public function store(Request $request)
    {
        $cliente = new Cliente();
        $cliente->nombre = $request->nombre;
        $cliente->tipo_documento = $request->tipo_documento;
        $cliente->numero_documento = $request->numero_documento;
        $cliente->direccion = $request->direccion;
        $cliente->telefono = $request->telefono;
        $cliente->email = $request->email;

        $cliente->save();
    }

    public function update(Request $request)
    {
        $cliente = Cliente::findOrFail($request->id);
        $cliente->nombre = $request->nombre;
        $cliente->tipo_documento = $request->tipo_documento;
        $cliente->numero_documento = $request->numero_documento;
        $cliente->direccion = $request->direccion;
        $cliente->telefono = $request->telefono;
        $cliente->email = $request->email;
        $cliente->save();
    }
}

Agregar las siguientes rutas a web.php

Route::get('/cliente', 'ClienteController@index');
Route::post('/cliente/registrar', 'ClienteController@store');
Route::put('/cliente/actualizar', 'ClienteController@update');
Route::get('/cliente/listaCliente', 'ClienteController@listaCliente');

Insertar un registro en la tabla cliente empleando phpmyadmin

Ir a la Url y probar localhost:8000/cliente

Debe aparecer en formato json el cliente ingresado,


////////////////////////////////////////FIN CLIENTES////////////////////////////////////////

////////////////////////////////////////INICIO VENTA-DETALLE////////////////////////////

CREAR LA MIGRACIÓN DE LA TABLA ventas

php artisan make:migration create_ventas_table

CREAR LA MIGRACIÓN DE LA TABLA detalle_ventas

php artisan make:migration create_detalle_ventas_table

La migración de ventas debe quedar como:

<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateVentasTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('ventas', function (Blueprint $table) {
            $table->increments('id');
            $table->integer('idcliente')->unsigned();
            $table->foreign('idcliente')->references('id')->on('clientes');
            $table->integer('idusuario')->unsigned();
            $table->foreign('idusuario')->references('id')->on('users');
            $table->dateTime('fecha_hora');
            $table->decimal('total', 12, 2);
            $table->string('estado', 20);
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('ventas');
    }
}

La migración de detalle_ventas debe quedar como:

<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateDetalleVentasTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('detalle_ventas', function (Blueprint $table) {
            $table->increments('id');
            $table->integer('idventa')->unsigned();
            $table->foreign('idventa')->references('id')->on('ventas')-
>onDelete('cascade');
            $table->integer('idproducto')->unsigned();
            $table->foreign('idproducto')->references('id')-
>on('productos');
            $table->integer('cantidad');
            $table->decimal('precio', 12, 2);
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('detalle_ventas');
    }
}

Migrar las tablas venta y detalle_venta:

php artisan migrate

Para crear el modelo de ventas:

php artisan make:model Venta

El modelo ventas debe quedar como:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Venta extends Model
{
    
    protected $fillable =[
        'idcliente', 
        'idusuario',
        'fecha_hora',
        'total',
        'estado'
    ];
}

Luego crear el controlador:

php artisan make:Controller VentaController

El controlador venta debe quedar como el siguiente:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Carbon\Carbon;
use App\Venta;
use App\DetalleVenta;

class VentaController extends Controller
{
    public function index(Request $request)
    {
        $buscar = $request->buscar;
        $criterio = $request->criterio;
        
        if ($buscar==''){
            $ventas = Venta::join('clientes','ventas.idcliente','=','cliente
s.id')
            ->join('users','ventas.idusuario','=','users.id')
            ->select('ventas.id','ventas.fecha_hora','ventas.total',
            'ventas.estado','clientes.nombre','users.name')
            ->orderBy('ventas.id', 'desc')->paginate(3);
        }
        else{
            $ventas = Venta::join('clientes','ventas.idcliente','=','cliente
s.id')
            ->join('users','ventas.idusuario','=','users.id')
            ->select('ventas.id','ventas.fecha_hora','ventas.total',
            'ventas.estado','clientes.nombre','users.name')
            ->where('ventas.'.$criterio, 'like', '%'. $buscar . '%')
            ->orderBy('ventas.id', 'desc')->paginate(3);
        }
        
        return [
            'pagination' => [
                'total'        => $ventas->total(),
                'current_page' => $ventas->currentPage(),
                'per_page'     => $ventas->perPage(),
                'last_page'    => $ventas->lastPage(),
                'from'         => $ventas->firstItem(),
                'to'           => $ventas->lastItem(),
            ],
            'ventas' => $ventas
        ];
    }

    public function desactivar(Request $request)
    {
        $venta = Venta::findOrFail($request->id);
        $venta->estado = 'Anulado';
        $venta->save();
    }

    public function obtenerEncabezado(Request $request){

        $id = $request->id;
        $venta = Venta::join('clientes','ventas.idcliente','=','clientes.id'
)
        ->join('users','ventas.idusuario','=','users.id')
        ->select('ventas.id','ventas.fecha_hora','ventas.total',
        'ventas.estado','clientes.nombre','users.name')
        ->where('ventas.id','=',$id)
        ->orderBy('ventas.id', 'desc')->take(1)->get();
        
        return ['venta' => $venta];
    }
    
    public function obtenerDetalles(Request $request){

        $id = $request->id;
        $detalles = DetalleVenta::join('productos','detalle_ventas.idproduct
o','=','productos.id')
        ->select('detalle_ventas.cantidad','detalle_ventas.precio',
        'productos.nombre as producto')
        ->where('detalle_ventas.idventa','=',$id)
        ->orderBy('detalle_ventas.id', 'desc')->get();
        
        return ['detalles' => $detalles];
    }

    public function store(Request $request)
    {
        $venta = new Venta();
        $venta->idcliente = $request->idcliente;
        //$venta->idusuario = \Auth::user()->id;
        $venta->idusuario = 1; //Si no hay login colocar un id de los usuari
os registrados
        $venta->fecha_hora = Carbon::now('America/Lima');
        $venta->total = $request->idcliente;
        $venta->estado = 'Registrado';
        $venta->save();

        $detalles = $request->data;//Array de detalles
        //Recorro los elementos del array
        
        foreach($detalles as $ep=>$det)
        {
            $detalle = new DetalleVenta();
            $detalle->idventa = $venta->id;
            $detalle->idproducto = $det['idproducto'];
            $detalle->cantidad = $det['cantidad'];
            $detalle->precio = $det['precio'];      
            $detalle->save();
        }  
        return response()->json($venta->id);       
    }
}

Crear el modelo detalle-ventas

Para crear el modelo  de ventas:

php artisan make:model DetalleVenta
El modelo detalle ventas debe quedar como:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class DetalleVenta extends Model
{
    protected $table = 'detalle_ventas';
    protected $fillable = [
        'idventa', 
        'idproducto',
        'cantidad',
        'precio'
    ];
    public $timestamps = false;
}

Ahora se debe crear el componente VentaComponent.vue en el directorio:


resources\assets\js\components que contendrá todas las operaciones del crud de ventas

El archivo deberá contener el siguiente código con las operaciones del crud a través de VUE.

<template>
<div class="card-body">

    <div class="card-header">
        <i class="fa fa-align-justify"></i> Ventas
        <button type="button" @click="mostrarDetalle()" class="btn btn-
secondary">
        <i class="icon-plus"></i>&nbsp;Nueva Venta
        </button>
    </div>
     <!-- Listado-->
     <template v-if="listado==1">
        <div class="table-responsive">
        <table class="table table-bordered table-striped table-sm">
            <thead>
                <tr>
                    <th>Usuario</th>
                    <th>Cliente</th>
                    <th>Fecha Hora</th>
                    <th>Total</th>
                    <th>Estado</th>
                    <th>Acciones</th>
                </tr>
            </thead>
            <tbody>
                <tr v-for="venta in arrayVenta" :key="venta.id">
                    <td v-text="venta.name"></td>
                    <td v-text="venta.nombre"></td>
                    <td v-text="venta.fecha_hora"></td>
                    <td v-text="venta.total"></td>
                    <td v-text="venta.estado"></td>
                    <td>
                        <button type="button" @click="verVenta(venta.id)" cl
ass="btn btn-success btn-sm">
                        Detallar Venta
                        </button> &nbsp;
                        <template v-if="venta.estado=='Registrado'">
                            <button type="button" class="btn btn-danger btn-
sm" @click="desactivarVenta(venta.id)">
                                Desactivar
                            </button>
                        </template>
                    </td>
                </tr>                                
            </tbody>
        </table>
          <nav>
            <ul class="pagination">
                <li class="page-item" v-if="pagination.current_page > 1">
                    <a class="page-link" href="#" 
@click.prevent="cambiarPagina(pagination.current_page - 1,buscar,criterio)">
Ant</a>
                </li>
                <li class="page-item" v-for="page in pagesNumber" 
:key="page" :class="[page == isActived ? 'active' : '']">
                    <a class="page-link" href="#" 
@click.prevent="cambiarPagina(page,buscar,criterio)" v-text="page"></a>
                </li>
                <li class="page-item" v-if="pagination.current_page < pagina
tion.last_page">
                    <a class="page-link" href="#" 
@click.prevent="cambiarPagina(pagination.current_page + 1,buscar,criterio)">
Sig</a>
                </li>
            </ul>
        </nav>
    </div>
     </template>

        <!-- Ver ingreso -->
                    <template v-if="listado==2">
                    <div class="card-body">
                        <div class="form-group row border">
                            <div class="col-md-9">
                                <div class="form-group">
                                    <label for="">Cliente</label>
                                    <p v-text="nombreCliente"></p>
                                </div>
                            </div>
                            <div class="col-md-3">
                                <label for="">Id</label>
                                <p v-text="idVenta"></p>
                            </div>
                        </div>
                        <div class="form-group row border">
                            <div class="table-responsive col-md-12">
                                <table class="table table-bordered table-
striped table-sm">
                                    <thead>
                                        <tr>
                                            <th>Prducto</th>
                                            <th>Precio</th>
                                            <th>Cantidad</th>
                                            <th>Subtotal</th>
                                        </tr>
                                    </thead>
                                    <tbody v-if="arrayDetalle.length">
                                        <tr v-for="detalle in arrayDetalle" 
:key="detalle.id">
                                            <td v-text="detalle.producto">
                                            </td>
                                            <td v-text="detalle.precio">
                                            </td>
                                            <td v-text="detalle.cantidad">
                                            </td>
                                            <td>
                                                {{detalle.precio*detalle.can
tidad}}
                                            </td>
                                        </tr>
                                        <!--<tr style="background-color: #CE
ECF5;">
                                            <td colspan="4" align="right"><s
trong>Total Parcial:</strong></td>
                                            <td>$ {{totalParcial=(total-
totalImpuesto).toFixed(2)}}</td>
                                        </tr>
                                        <tr style="background-color: #CEECF5
;">
                                            <td colspan="4" align="right"><s
trong>Total Impuesto:</strong></td>
                                            <td>$ {{totalImpuesto=((total*im
puesto)).toFixed(2)}}</td>
                                        </tr>
                                        <tr style="background-color: #CEECF5
;">
                                            <td colspan="4" align="right"><s
trong>Total Neto:</strong></td>
                                            <td>$ {{total}}</td>
                                        </tr>
                                        -->
                                    </tbody>
                                    <tbody v-else>
                                        <tr>
                                            <td colspan="5">
                                                NO hay artículos agregados
                                            </td>
                                        </tr>
                                    </tbody>                                 
   
                                </table>
                            </div>
                        </div>
                        <div class="form-group row">
                            <div class="col-md-12">
                                <button type="button" @click="ocultarDetalle
()" class="btn btn-secondary">Cerrar</button>
                                
                            </div>
                        </div>
                    </div>
                    </template>
                    <!-- fin ver ingreso -->

    <template v-else-if="listado==0">
    <div class="card-body">
        <div class="form-group row border">
            <div class="col-md-9">
                <div class="form-group">
                    <label for="">Cliente(*)</label>
                    <select class="form-control" v-model="idcliente">
                        <option value="0" disabled>Seleccione</option>
                        <option v-for="cliente in arrayCliente" 
:key="cliente.id" :value="cliente.id" v-text="cliente.nombre"></option>
                    </select>                                        
                </div> 
            </div>

            <div class="col-md-12">
                <div v-show="errorVenta" class="form-group row div-error">
                    <div class="text-center text-error">
                        <div v-for="error in errorMostrarMsjVenta" 
:key="error" v-text="error">

                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>

    <div class="form-group row border">
        <div class="col-md-4">
            <div class="form-group">
                <label>Producto <span style="color:red;" v-
show="idproducto==0">(*Seleccione)</span></label>
                <div class="form-inline">
                    <input type="text" class="form-control" v-model="codigo" 
@keyup.enter="buscarArticulo()" placeholder="Ingrese producto">
                    <input type="text" readonly class="form-control" v-
model="producto">
                </div>                                    
            </div>
        </div>

        <div class="col-md-4">
            <div class="form-group">
                <label>Cantidad <span style="color:red;" v-
show="cantidad==0">(*Ingrese)</span></label>
                <input type="number" value="0" class="form-control" v-
model="cantidad">                  
            </div> 
        </div>

          <div class="col-md-2">
            <div class="form-group">
                <button @click="agregarDetalle()" class="btn btn-success for
m-control btnagregar">Agregar</button>
            </div>
         </div>

        <div class="form-group row">
            <div class="col-md-12">
                    <button type="button" class="btn btn-primary" 
@click="registrarVenta()">Registrar Venta</button>
            </div>
        </div>
        
        <div class="form-group row border">
            <div class="table-responsive col-md-12">
                <table class="table table-bordered table-striped table-sm">
                    <thead>
                        <tr>
                            <th>Opciones</th>
                            <th>Producto</th>
                            <th>Precio</th>
                            <th>Cantidad</th>
                            <th>Subtotal</th>
                        </tr>
                    </thead>
                    <tbody v-if="arrayDetalle.length">
                        <tr v-for="(detalle,index) in arrayDetalle" 
:key="detalle.id">
                            <td>
                                <button @click="eliminarDetalle(index)" type
="button" class="btn btn-danger btn-sm">
                                    <i class="icon-close"></i>
                                </button>
                            </td>
                            <td v-text="detalle.producto">
                            </td>
                            <td>
                                <input v-model="detalle.precio" typ
e="number" class="form-control">
                            </td>
                            <td>
                                <span style="color:red;" v-
show="detalle.cantidad>detalle.stock">Stock: {{detalle.stock}}</span>
                                <input v-model="detalle.cantidad" typ
e="number" class="form-control">
                            </td>
                            <td>
                                {{detalle.precio*detalle.cantidad}}
                            </td>
                        </tr>
                        <!--
                        <tr style="background-color: #CEECF5;">
                            <td colspan="5" align="right"><strong>Total Parc
ial:</strong></td>
                            <td>$ {{totalParcial=(total-
totalImpuesto).toFixed(2)}}</td>
                        </tr>
                        <tr style="background-color: #CEECF5;">
                            <td colspan="5" align="right"><strong>Total Impu
esto:</strong></td>
                            <td>$ {{totalImpuesto=((total*impuesto)/
(1+impuesto)).toFixed(2)}}</td>
                        </tr>
                        <tr style="background-color: #CEECF5;">
                            <td colspan="5" align="right"><strong>Total Neto
:</strong></td>
                            <td>$ {{total=calcularTotal}}</td>
                        </tr>
                        -->
                    </tbody>
                    <tbody v-else>
                        <tr>
                            <td colspan="6">
                                NO hay artículos agregados
                            </td>
                        </tr>
                    </tbody>                                    
                </table>
            </div>
        </div>
        
       
    </div>
    </template>
    
</div>

</template>

<script>
    export default {
        data (){
            return {
                arrayVenta : [],
                criterio : 'id',
                buscar : '',
                listado:1,
                nombreCliente:'',
                idVenta: 0,
                idcliente:0,
                codigo:0,
                arrayCliente: [],
                arrayProducto: [],
                arrayDetalle : [],
                idproducto: 0,
                producto: '',
                precio: 0,
                cantidad: 0,
                stock: 0,
                total:0,
                errorVenta:0,
                errorMostrarMsjVenta : [],
                pagination : {
                    'total' : 0,
                    'current_page' : 0,
                    'per_page' : 0,
                    'last_page' : 0,
                    'from' : 0,
                    'to' : 0,
                },
                offset : 3
            }
        },
        computed:{
            isActived: function(){
                return this.pagination.current_page;
            },
            //Calcula los elementos de la paginación
            pagesNumber: function() {
                if(!this.pagination.to) {
                    return [];
                }
                
                var from = this.pagination.current_page - this.offset; 
                if(from < 1) {
                    from = 1;
                }

                var to = from + (this.offset * 2); 
                if(to >= this.pagination.last_page){
                    to = this.pagination.last_page;
                }  

                var pagesArray = [];
                while(from <= to) {
                    pagesArray.push(from);
                    from++;
                }
                return pagesArray;
            },
            calcularTotal: function(){
                var resultado=0.0;
                for(var i=0;i<this.arrayDetalle.length;i++){
                    resultado=resultado+
(this.arrayDetalle[i].precio*this.arrayDetalle[i].cantidad-
this.arrayDetalle[i].descuento)
                }
                return resultado;
            }
        },
        methods : {
            listarVenta (page,buscar,criterio){
                let me=this;
                var url= '/venta?page=' + page + '&buscar='+ buscar + '&crit
erio='+ criterio;
                axios.get(url).then(function (response) {
                    var respuesta= response.data;
                    me.arrayVenta = respuesta.ventas.data;
                    me.pagination= respuesta.pagination;
                })
                .catch(function (error) {
                    console.log(error);
                });
            },
           cambiarPagina(page,buscar,criterio){
                let me = this;
                //Actualizar la página actual
                me.pagination.current_page = page;
                //Enviar la petición para visualizar la data de esa página
                me.listarVenta(page,buscar,criterio);
            },
             selectCliente(){
                let me=this;
                  var url= '/cliente/listaCliente';
                axios.get(url).then(function (response) {
                    //console.log(response);
                    var respuesta= response.data;
                    me.arrayCliente = respuesta.clientes;
                })
                .catch(function (error) {
                    console.log(error);
                });
            },
            buscarArticulo(){
                let me=this;
                var url= '/producto/buscarProductoVenta?filtro=' + m
e.codigo;

                axios.get(url).then(function (response) {
                    var respuesta= response.data;
                    me.arrayProducto = respuesta.productos;

                    if (me.arrayProducto.length>0){
                        me.producto=me.arrayProducto[0]['nombre'];
                        me.idproducto=me.arrayProducto[0]['id'];
                        me.precio=me.arrayProducto[0]['precio'];
                        me.stock=me.arrayProducto[0]['stock'];
                    }
                    else{
                        me.producto='No existe producto';
                        me.idproducto=0;
                    }
                })
                .catch(function (error) {
                    console.log(error);
                });
            },
            agregarDetalle(){
                let me=this;
                if(me.idproducto==0 || me.cantidad==0 || me.precio==0){
                }
                else{
                    if(me.encuentra(me.idproducto)){
                        swal({
                            type: 'error',
                            title: 'Error...',
                            text: 'Ese artículo ya se encuentra agregado!',
                            })
                    }
                    else{
                       if(me.cantidad>me.stock){
                           swal({
                            type: 'error',
                            title: 'Error...',
                            text: 'NO hay stock disponible!',
                            })
                       } 
                       else{
                           me.arrayDetalle.push({
                                idproducto: me.idproducto,
                                producto: me.producto,
                                cantidad: me.cantidad,
                                precio: me.precio,
                                stock: me.stock
                            });
                            me.codigo="";
                            me.idproducto=0;
                            me.producto="";
                            me.cantidad=0;
                            me.precio=0;
                            me.stock=0
                       }
                    }
                    
                }
            },
            encuentra(id){
                var sw=0;
                for(var i=0;i<this.arrayDetalle.length;i++){
                    if(this.arrayDetalle[i].idarticulo==id){
                        sw=true;
                    }
                }
                return sw;
            },
            registrarVenta(){
                if (this.validarVenta()){
                    return;
                }
                
                let me = this;
                axios.post('/venta/registrar',{
                    'idcliente': this.idcliente,
                    'idproducto': this.idproducto,
                    'total' : this.total,
                    'data': this.arrayDetalle
                }).then(function (response) {
                    me.listado=1;
                    me.listarVenta(1,'','id');
                    me.idcliente=0;
                    me.total=0.0;
                    me.idproducto=0;
                    me.prodcto='';
                    me.cantidad=0;
                    me.precio=0;
                    me.stock=0;
                    me.codigo='';
                    me.arrayDetalle=[];
                    console.log(response);
                }).catch(function (error) {
                    console.log(error);
                });           
            },
            verVenta(id){
                let me=this;
                me.listado=2;
                
                //Obtener los datos del ingreso
                var arrayVentaT=[];
                var url= '/venta/obtenerEncabezado?id=' + id;
                
                axios.get(url).then(function (response) {
                    var respuesta= response.data;
                    arrayVentaT = respuesta.venta;

                    me.idVenta = arrayVentaT[0]['id'];
                    me.nombreCliente = arrayVentaT[0]['nombre'];
                    me.total=arrayVentaT[0]['total'];
                })
                .catch(function (error) {
                    console.log(error);
                });

                //Obtener los datos de los detalles 
               var urld= '/venta/obtenerDetalles?id=' + id;
                
                axios.get(urld).then(function (response) {
                    console.log(response);
                    var respuesta= response.data;
                    me.arrayDetalle = respuesta.detalles;
                })
                .catch(function (error) {
                    console.log(error);
                }); 
                   
              
            },
            ocultarDetalle(){
                this.listado=1;
            },
            mostrarDetalle(){
                let me=this;
                me.listado=0;
                me.idproducto=0;
                me.producto='';
                me.cantidad=0;
                me.precio=0;
                me.impuesto=0.20;
                me.total=0.0;
                me.arrayDetalle=[];
            },
            ocultarDetalle(){
                this.listado=1;
            },
            validarVenta(){
                let me=this;
                me.errorVenta=0;
                me.errorMostrarMsjVenta =[];
                var art;
                
                me.arrayDetalle.map(function(x){
                    if (x.cantidad>x.stock){
                        art=x.articulo + " con stock insuficiente";
                        me.errorMostrarMsjVenta.push(art);
                    }
                });

                if (me.idcliente==0) me.errorMostrarMsjVenta.push("Seleccion
e un Cliente");
                 if (me.arrayDetalle.length<=0) me.errorMostrarMsjVenta.push
("Ingrese detalles");

                if (me.errorMostrarMsjVenta.length) me.errorVenta = 1;

                return me.errorVenta;
            },
        },
           mounted() {
            this.listarVenta(1,this.buscar,this.criterio);
            this.selectCliente();
        }
    }
    </script>

Editar el archivo web.php para agregar las rutas:

Route::get('/venta', 'VentaController@index');
Route::post('/venta/registrar', 'VentaController@store');
Route::put('/venta/desactivar', 'VentaController@desactivar');
Route::get('/venta/obtenerEncabezado', 'VentaController@obtenerEncabezado');
Route::get('/venta/obtenerDetalles', 'VentaController@obtenerDetalles');

Editar el archivo: resources\assets\js\app.js

Se debe agregar el componente ventas.

Vue.component('venta-component', requir
e('./components/VentaComponent.vue'));

El archivo queda como el siguiente:


/**
 * First we will load all of this project's JavaScript dependencies which
 * includes Vue and other libraries. It is a great starting point when
 * building robust, powerful web applications using Vue and Laravel.
 */

require('./bootstrap');

window.Vue = require('vue');

/**
 * Next, we will create a fresh Vue application instance and attach it to
 * the page. Then, you may begin adding components to this application
 * or customize the JavaScript scaffolding to fit your unique needs.
 */

//Vue.component('example-component', require('./components/ExampleComponent.
vue'));
Vue.component('categoria-component', requir
e('./components/CategoriaComponent.vue'));
Vue.component('venta-component', requir
e('./components/VentaComponent.vue'));

const app = new Vue({
    el: '#app',
    data :{
        menu :0
    }
});

Ejecutar el comando:

npm run dev


El anterior comando compila todos los cambios en los componentes y en el javascript, sino se
compila por más mínimo que sea el cambio no se efectuará en el aplicativo.

Cada vez que se efectúe un cambio en los componentes o en el javascript ejecutar el comando
npm run dev
Al finalizar la compilación debe aparecer un mensaje en el terminal de comandos como el
siguiente:
Luego en las vistas verificar en menu.blade.php si ventas está incluido en las opciones de menú:

Para el caso Ventas corresponde al menú 3.

   <li @click="menu=3" class="nav-item">
                        <a class="nav-link" href="#"><i class="icon-
bag"></i> Ventas</a>
                    </li>

El archivo completo es:

<div class="sidebar">
    <nav class="sidebar-nav">
        <ul class="nav">
            <li class="nav-item nav-dropdown">
                <a class="nav-link nav-dropdown-toggle" href="#"><i clas
s="icon-bag"></i> Almacén</a>
                <ul class="nav-dropdown-items">
                    <li @click="menu=1" class="nav-item">
                        <a class="nav-link" href="#"><i class="icon-
bag"></i> Categorías</a>
                    </li>
                    <li @click="menu=2" class="nav-item">
                        <a class="nav-link" href="#"><i class="icon-
bag"></i> Productos</a>
                    </li>
                    <li @click="menu=3" class="nav-item">
                        <a class="nav-link" href="#"><i class="icon-
bag"></i> Ventas</a>
                    </li>
                </ul>
            </li>
        </ul>
    </nav>
</div>

Luego en contenido.blade.php verificar si la opción de menú 3 está incluída.

El archivo debe quedar como sigue:

@extends('principal')
@section('contenido')

   <template v-if="menu==1">
   <!-- v-if es el if en vue -->
     <!--redireccionar al componente categoria-component -->
      <categoria-component></categoria-component>
   </template>

   <template v-if="menu==2">
       <h1>Contenido del menú 2</h1>
   </template>

   <template v-if="menu==3">
    <!--redireccionar al componente venta-component -->
   <venta-component></venta-component>
   </template>

@endsection

Ejecutar npm run dev para compilar los cambios.

Ir al navegador y digitar la url: http://localhost:8000/

Debe aparecer una ventana como:


Dar clic en ventas:

Debe quedar la vista del siguiente modo:


////////////////////////////////////////FIN VENTA-DETALLE////////////////////////////////

También podría gustarte