<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Auth;
use DB;
use App\Models\Venta;
use App\Models\Local;
use App\Models\Cliente;
use App\Models\Producto;
use App\Models\Usuario;
use App\Models\ProductoLocal;
use App\Models\DetalleVenta;
use App\Models\TipoComprobante;
use App\Models\TipoDocumento;
use App\Models\TipoPresentacion;
use App\Models\UnidadMedida;
use App\Models\Proforma;
use App\Models\Empresa;
use App\Models\DetalleProforma;
use App\Models\DetalleCredito;
use App\Models\Delivery;
use App\Models\DetalleDelivery;
use App\Http\Controllers\XmlController;
use App\Models\VentasCredito;
use App\Models\Nota;

class VentaController extends Controller
{
	public function __construct()
    {
        $this->middleware('auth:usuario');
    }
    
	public function listar()
    {
	 	$res = Venta::with(['local', 'cliente', 'tipo_comprobante'])->where('id_local', Auth::guard("usuario")->user()->id_local)->where('id_nota', null)->where('id_cliente', '<>', null)->where('estado', 1)->where('contingencia', 0)->orderBy('created_at', 'desc')->paginate(20);

        return view('venta.listar', [ 'data' => $res]); 
	}

    public function listar_anulados()
    {
        $res = Venta::with(['local', 'cliente', 'tipo_comprobante', 'nota'])->where('id_local', Auth::guard("usuario")->user()->id_local)->where('id_nota', '<>',null)->where('id_cliente', '<>', null)->where('estado', 1)->where('contingencia', 0)->orderBy('updated_at', 'desc')->paginate(20);

        return view('venta.listar_anulados', [ 'data' => $res]); 
    }

	public function nuevo()
    {
	 	$correl = $this->getCorrel(2, Auth::guard("usuario")->user()->id_local);
        $id_local = Auth::guard("usuario")->user()->id_local;
        $data = [
	 		'locales' => Local::where('estado', 1)->get(), 
            'empresa' => Empresa::where('estado', 1)->first(), 
	 		'clientes' => Cliente::where('estado', 1)->orderBy('nombre', 'ASC')->limit(20)->get(), 

            'productos' => ProductoLocal::with('producto')->where('id_local', $id_local)->where('estado', 1)->where('stock', '>', 0)->limit(20)->get(),

	 		'producto' => ProductoLocal::with('producto')->where('id_local', Auth::guard("usuario")->user()->id_local)->where('estado', 1)->where('stock', '>', 0)->limit(20)->get(),
	 		'tipo_documento' => TipoDocumento::all(), 
	 		'tipo_comprobante' => TipoComprobante::where('grupo', 1)->get(), 
	 		'tipo_presentacion' => TipoPresentacion::all(), 
	 		'unidad_medida' => UnidadMedida::all(), 
            'serie' => $correl['serie'],
            'numero' => $correl['numero']
	 	];
	 	return view('venta.nuevo', $data); 
	}

	public function registrar(Request $request)
    {
        if ($request->ajax())
        {    
            //PARA SEGUIMIENTO DE PROFORMA
            if ($request->id_proforma) {
                $prof = Proforma::find($request->id_proforma);
                $prof->genera_venta = 1;
                $prof->save(); 
            }

            $empresa = Empresa::where(['id_empresa' => 1 , 'estado' => 1])->first();
            if(!is_null($request->numero_documento) && !is_null($request->nombre)){

                $buscar = Cliente::where('numero_documento', $request->numero_documento)->first();

                if ($buscar) {

                    $request->request->add(['id_cliente' => $buscar->id_cliente]);
                    // Si el cliente ya esta registrado, se actualiza sus datos
                    if ($buscar->id_cliente != 1) { // no se actualiza si es CLIENTES VARIOS
                        $cli = Cliente::find($buscar->id_cliente);
                        $cli->nombre = $request->nombre;
                        $cli->direccion = $request->direccion;
                        $cli->save();  
                    }
                      
                }
                else{ // Si el cliente no esta registrado, se crea
                    $data = [
                        'nombre' => $request->nombre,
                        'numero_documento' => $request->numero_documento,
                        'id_tipo_documento' => $request->id_tipo_documento,
                        'direccion' => $request->direccion
                    ];
                    $cli = Cliente::create($data); 
                    $request->request->add(['id_cliente' => $cli->id_cliente]);
                }
                
            } else { // le pone direccion a clientes varios
                $request->request->add(['id_cliente' => 1]);
                $cli2 = Cliente::find(1);
                if ($request->direccion != null) {
                    $cli2->direccion = $request->direccion;
                }else{
                    $cli2->direccion = '';
                }
                $cli2->save(); 
            }



            $id_local = Auth::guard("usuario")->user()->id_local;
            $correl = $this->getCorrel($request->id_tipo_comprobante, $id_local);
            $request->request->add(['id_usuario' => Auth::guard("usuario")->user()->id_usuario]); 
            $request->request->add(['id_local' => $id_local]);
            $request->request->add(['serie_comprobante' => $correl['serie']]);
            $request->request->add(['numero_comprobante' => $correl['numero']]);
            $request->request->add(['nombre_comprobante' => $correl['nombre']]);
            $request->request->add(['fecha_venta' => date('Y-m-d')]);
            $request->request->add(['estado_envio' => 'REGISTRADO']);
            $request->request->add(['mensaje_envio' => 'El comprobante se encuentra pendiente de envio a la SUNAT']);

 			$res = Venta::create($request->all());
            
            if ($res) 
            {
                $total = 0;
                $suma_igv = 0;
                $suma_gravado = 0;
                $suma_icbper = 0;
                $suma_total = 0;
                $suma_exonerado = 0;
                $suma_inafecto = 0;

                for( $i = 0; $i < count($request->id_producto); $i++)
	            {
	                $prod_venta = Producto::find($request->id_producto[$i]);

                    $total = $total + $request->subtotal[$i]; //total sin icbper

                    if ($prod_venta->situacion_impuesto == "AFECTO") {
                        $suma_total = $suma_total + number_format($request->subtotal[$i], 2, '.', '');
                        $suma_gravado = $suma_gravado + number_format($request->subtotal[$i]-$request->impuesto[$i], 2, '.', '');
                        $suma_igv = $suma_igv + number_format($request->impuesto[$i], 2, '.', '');
                    } 
                    if ($prod_venta->situacion_impuesto == "EXONERADO") {
                        $suma_exonerado = $suma_exonerado + number_format($request->subtotal[$i], 2, '.', '');
                    } 
                    if ($prod_venta->situacion_impuesto == "INAFECTO") {
                        $suma_inafecto = $suma_inafecto + number_format($request->subtotal[$i], 2, '.', '');
                    } 
                    if ($prod_venta->icbper == 1) {
                        $suma_icbper =  $suma_icbper + $empresa->valor_icbper*$request->cantidad[$i];
                    }

                  /*  if ($request->impuesto[$i] > 0) {
                        $suma_total = $suma_total + number_format($request->subtotal[$i], 2, '.', '');
                        $suma_gravado = $suma_gravado + number_format($request->subtotal[$i]-$request->impuesto[$i], 2, '.', '');
                        $suma_igv = $suma_igv + number_format($request->impuesto[$i], 2, '.', '');
                    } */
                    
                    $detalle_venta= [
	                	'id_venta' => $res->id_venta, 
	                	'id_producto' => $request->id_producto[$i], 
			        	'cantidad' => $request->cantidad[$i], 
			        	'precio_venta' => $request->precio_venta[$i], 
			        	'impuesto' => $request->impuesto[$i], 
			        	'precio_venta_neto' => number_format($request->subtotal[$i]-$request->impuesto[$i], 6, '.', ''), 
			        	'descuento' => $request->descuento[$i], 
			        	'precio_venta_total' => $request->subtotal[$i], 
	                ];

	                $res1 = DetalleVenta::create($detalle_venta);

	                if ($res1) // si el registro de detalle venta esta ok, se actualizan stock y otros datos
	                {
	                	if ($request->tipo_pago !== 'LIQUIDACION') {
                            $producto_local = ProductoLocal::where(['id_producto' => $request->id_producto[$i] , 'id_local' => $id_local, 'estado' => 1])->get();
                            $prod = ProductoLocal::find($producto_local[0]->id_producto_local);
                            $prod->stock = ($producto_local[0]->stock - $request->cantidad[$i]) < 1000000 ? 1000000 : ($producto_local[0]->stock - $request->cantidad[$i]);
                            $prod->save();
                        }

                        //modulo puntos
                        if ($request->id_cliente !== 1 && $empresa->modulo_puntos != 0) {
                            if($request->total_venta >= 10){
                                $puntos = intdiv($request->total_venta, 10);

                                $cli3 = Cliente::find($request->id_cliente);
                                $cli3->puntos = $cli3->puntos + $puntos;
                                $cli3->save(); 
                            }  
                        }

                        $produ = Producto::find($request->id_producto[$i]);
                        if (is_null($produ->precio_compra)) {
                            $produ->precio_compra = 0;
                        }
                        //$produ->precio = $request->precio_venta[$i];
                        $produ->utilidad= (($request->precio_venta[$i] - $produ->precio_compra) < 0 ) ? 0 : ($request->precio_venta[$i] - $produ->precio_compra);
                        $produ->save();
	                }
		        }

                if ( $request->numero_cuotas > 0 ) { // PARA LAS CUOTAS AL CREDITO
                    if ($suma_igv > 0) {
                        $total_v = $request->total_venta;
                    } else { $total_v = $total; }
                    for( $i = 0; $i < count($request->numero_cuota); $i++)
                    {
                        if (is_null($request->fecha_pago_cuota[$i])) {
                            $fecha_pago_cuota = date('Y-m-d');
                        } else{
                            $fecha_pago_cuota =  $request->fecha_pago_cuota[$i];
                        }
                        $detalle_venta_credito= [
                            'id_venta' => $res->id_venta, 
                            'nombre_cuota' => 'Cuota00'.$request->numero_cuota[$i], 
                            'numero_cuota' => $request->numero_cuota[$i], 
                            'monto_cuota' => number_format($total_v/count($request->numero_cuota), 2, '.', ''), 
                            'fecha_pago_cuota' =>  $fecha_pago_cuota 
                            
                        ];
                        $res_cuota = VentasCredito::create($detalle_venta_credito);
                    }
                }

                if ($request->numero_cuotas == 0 && !is_null($request->fecha_pago) ) { //no hay cuotas pero si hay fecha de pago
                    $detalle_venta_credito= [
                        'id_venta' => $res->id_venta, 
                        'nombre_cuota' => 'Cuota001', 
                        'numero_cuota' => 1, 
                        'monto_cuota' => number_format($request->total_venta, 2, '.', ''), 
                        'fecha_pago_cuota' =>  $request->fecha_pago 
                    ];
                    $res_cuota = VentasCredito::create($detalle_venta_credito);
                    $cuo = Venta::find($res->id_venta);
                    $cuo->numero_cuotas = 1;
                    $cuo->save();
                }
                
                //Corregimos el descuento solo para operaciones gravadas
                if ($suma_total > 0 && $suma_igv > 0) { //significa que hay gravados
                    $impu = Venta::find($res->id_venta);
                    $factor = $request->descuento_global/$suma_total;
                    $impu->gravado_total = ($suma_gravado - $suma_gravado*$factor);
                    $impu->igv_total = ($suma_igv - $suma_igv*$factor);
                    $impu->save();
                } else {
                    $impu = Venta::find($res->id_venta);
                    $impu->total_venta = $total;
                    $impu->descuento_global = 0;
                    $impu->save();
                }
                
                //Sumamos el ICBPER al total
                $venta = Venta::find($res->id_venta);
                //$venta->total_venta = $venta->total_venta + $suma_icbper; 
                $venta->total_venta = $total + $suma_icbper;

                $venta->exonerado_total = $suma_exonerado;
                $venta->inafecto_total = $suma_inafecto;
                $venta->icbper_total = $suma_icbper;

                $venta->save();

                //Creamos documentos XML
                $xml = new XmlController();
                $xml->crearComprobante($res->id_venta);    
	        }
	        
            $res ? $res['message'] = 'success' : $res['message'] = 'error';

            return response()->json($res); 
        }
	}

    public function getCorrel($tipo, $id_local)
    {
        $num = Venta::where(['id_tipo_comprobante' => $tipo, 'id_local' => $id_local, 'estado' => 1, 'contingencia' => 0])->max('numero_comprobante');
        if ($tipo == 1) {
            $res = Local::where(['id_local' => $id_local , 'estado' => 1])->first();
            $serie = $res->serie_factura;
        }
        if ($tipo == 2) {
            $res = Local::where(['id_local' => $id_local , 'estado' => 1])->first();
            $serie = $res->serie_boleta;
        }

        return ['numero' => $num + 1, 'serie' => $serie, 'nombre' => $serie.'-'.($num+1)];
    }

    public function getCorrelativo(Request $request)
    {
        if ($request->ajax())
        {
            $num = Venta::where(['id_tipo_comprobante' => $request->id_tipo_comprobante, 'id_local' => $request->id_local, 'estado' => 1, 'contingencia' => 0])->max('numero_comprobante');

            if ($request->id_tipo_comprobante == 1) {
                $res = Local::where(['id_local' => $request->id_local , 'estado' => 1])->first();
                $serie = $res->serie_factura;
            }
            if ($request->id_tipo_comprobante == 2) {
                $res = Local::where(['id_local' => $request->id_local , 'estado' => 1])->first();
                $serie = $res->serie_boleta;
            }

            return response()->json(['numero' => $num + 1, 'serie' => $serie]); 
        }    
    }

	public function detalles($id)
    {
        return view('venta.detalles', [
            'data' => Venta::with(['local', 'cliente', 'usuario', 'tipo_comprobante'])->where(['id_venta' => $id])->first(),
            'empresa' => Empresa::where('estado', 1)->first(), 
            'detalle_venta' => DetalleVenta::with(['producto'])->where(['id_venta' => $id])->get(),
            'nota' => Nota::with(['tipo_comprobante'])->where(['id_venta' => $id , 'estado' => 1])->first()
        ]); 
    }

    public function buscar(Request $request)
    {
        if ($request)
        {
            $id1 = Cliente::where('nombre', 'LIKE', '%'.$request->search.'%')->orWhere('numero_documento', $request->search)->first();
            $id2 = Local::where('nombre', 'LIKE', '%'.$request->search.'%')->first();
            $id3 = TipoComprobante::where('nombre', 'LIKE', '%'.$request->search.'%')->first();

	 		$res =  Venta::with(['local', 'cliente'])->where(function ($query) {
                    $query->where('id_local', Auth::guard("usuario")->user()->id_local)->where('estado', 1)->where('contingencia', 0)->where('id_cliente','<>', null);
                })->where(function ($query)  use ($request, $id1 ,$id2 ,$id3) {
                    $query->where('total_venta', 'LIKE',  '%'.$request->search.'%')
                          ->orWhere('tipo_pago', 'LIKE',  '%'.$request->search.'%')
                          ->orWhere('fecha_venta', 'LIKE', '%'.$request->search.'%')
                          ->orWhere('serie_comprobante', 'LIKE', '%'.$request->search.'%')
                          ->orWhere('numero_comprobante', 'LIKE', '%'.$request->search.'%')
                          ->orWhere('nombre_comprobante', 'LIKE', '%'.$request->search.'%')
                          ->orWhere('estado_envio', 'LIKE', '%'.$request->search.'%')
                          ->orWhere('id_cliente', '=', $id1 ? $id1->id_cliente : '')
                          ->orWhere('id_local', '=', $id2 ? $id2->id_local : '')
                          ->orWhere('id_tipo_comprobante', '=', $id3 ? $id3->id_tipo_comprobante : '');
                })->paginate(10);
		 	
            
            $res->appends(['search' => $request->search]); 
	        return view('venta.listar', [ 'data' => $res]); 

        }
    }

    public function listar_deuda()
    {
        $res = [
            'data' => Venta::with(['local', 'cliente', 'tipo_comprobante'])->where('id_local', Auth::guard("usuario")->user()->id_local)->where('fecha_pago', '<>', null)->where(['estado' => 1, 'id_nota' => null])->where('tipo_pago', 'CREDITO')->orderBy('created_at', 'desc')->paginate(20)
        ];

        return view('venta.listar_deuda', $res); 
    }

    public function detalles_deuda($id)
    {
        return view('venta.detalles_deuda', [
            'data' => Venta::with(['local', 'cliente', 'usuario', 'tipo_comprobante'])->where(['id_venta' => $id, 'estado' => 1, 'id_nota' => null])->first(),
            'pagado' => DB::table('detalle_credito')->where(['id_venta' => $id, 'estado' => 1])->sum('monto'),
            'detalle_credito' => DetalleCredito::with(['usuario'])->where(['id_venta' => $id, 'estado' => 1])->orderBy('created_at', 'desc')->get(),
        ]); 
    }

    public function anular_deuda(Request $request)
    {
        if ($request->ajax())
        {
            $data1 = Venta::where(['id_venta' => $request->id_venta])->first();
            $data2 = DB::table('detalle_credito')->where(['id_venta' => $request->id_venta, 'estado' => 1])->sum('monto');
            $saldo = $data1->total_venta - $data2;

            $datos = [
                'id_usuario' => Auth::guard("usuario")->user()->id_usuario,
                'id_venta' => $request->id_venta,
                'fecha_pago' => date('Y-m-d'),
                'monto' => $saldo,
                'observacion' => "LIQUIDACION TOTAL DE LA DEUDA",
            ];

            $data = Venta::find($request->id_venta);
            $data->fecha_pago = null;
            $data->save();


            $res = DetalleCredito::create($datos);

            return response()->json($res ? ['message' => 'success'] : ['message' => 'error']);  
        }
    }

    public function registrar_letra(Request $request)
    {
        if ($request->ajax())
        {
            $request->request->add(['id_usuario' => Auth::guard("usuario")->user()->id_usuario]);
            $request->request->add(['fecha_pago' => date('Y-m-d')]);

            $res = DetalleCredito::create($request->all());

            $res ? $res['message'] = 'success' : $res['message'] = 'error';

            return response()->json($res); 
        }
    }

    public function eliminar_letra(Request $request)
    {
        if ($request->ajax())
        {
            $data = DetalleCredito::find($request->id_detalle_credito);
            $data->estado = 0;
            $res  = $data->save();
        
            return response()->json($res ? ['message' => 'success'] : ['message' => 'error']);  
        }
    }

    public function proforma_venta($id)
    {
        $correl = $this->getCorrel(2, Auth::guard("usuario")->user()->id_local);
        $data = [
            'proforma' => Proforma::with(['local', 'usuario'])->where(['id_proforma' => $id])->first(),
            'empresa' => Empresa::where('estado', 1)->first(), 
            'detalle_proforma' => DetalleProforma::with(['producto'])->where(['id_proforma' => $id, 'estado' => 1])->orderBy('id_detalle_proforma', 'ASC')->get(),
            'locales' => Local::where('estado', 1)->get(), 
            'clientes' => Cliente::where('estado', 1)->orderBy('nombre', 'ASC')->limit(20)->get(), 
            'productos' => ProductoLocal::with('producto')->where('id_local', Auth::guard("usuario")->user()->id_local)->where('estado', 1)->where('stock', '>', 0)->limit(50)->get(),
            'producto' => ProductoLocal::with('producto')->where('id_local', Auth::guard("usuario")->user()->id_local)->where('estado', 1)->where('stock', '>', 0)->limit(50)->get(),
            'tipo_documento' => TipoDocumento::all(), 
            'tipo_comprobante' => TipoComprobante::where('grupo', 1)->get(), 
            'tipo_presentacion' => TipoPresentacion::all(), 
            'unidad_medida' => UnidadMedida::all(), 
            'serie' => $correl['serie'],
            'numero' => $correl['numero']
        ];
        return view('proforma.venta', $data); 
    } 

    public function delivery_venta($id)
    {
        $correl = $this->getCorrel(2, Auth::guard("usuario")->user()->id_local);
        $data = [
            'proforma' => Delivery::where(['id_delivery' => $id])->first(),
            'empresa' => Empresa::where('estado', 1)->first(), 
            'detalle_proforma' => DetalleDelivery::with(['producto'])->where(['id_delivery' => $id, 'estado' => 1])->orderBy('id_detalle_delivery', 'ASC')->get(),
            'locales' => Local::where('estado', 1)->get(), 
            'clientes' => Cliente::where('estado', 1)->orderBy('nombre', 'ASC')->limit(20)->get(), 
            'productos' => ProductoLocal::with('producto')->where('id_local', Auth::guard("usuario")->user()->id_local)->where('estado', 1)->where('stock', '>', 0)->get(),
            'producto' => ProductoLocal::with('producto')->where('id_local', Auth::guard("usuario")->user()->id_local)->where('estado', 1)->where('stock', '>', 0)->limit(50)->get(),
            'tipo_documento' => TipoDocumento::all(), 
            'tipo_comprobante' => TipoComprobante::where('grupo', 1)->get(), 
            'tipo_presentacion' => TipoPresentacion::all(), 
            'unidad_medida' => UnidadMedida::all(), 
            'serie' => $correl['serie'],
            'numero' => $correl['numero']
        ];
        return view('delivery.venta', $data); 
    } 


    public function buscar_deuda(Request $request)
    {
        if ($request)
        {
            $id1 = Cliente::where('nombre', 'LIKE', '%'.$request->search.'%')->orWhere('numero_documento', $request->search)->first();

            $res =  Venta::with(['local', 'cliente', 'tipo_comprobante'])->where(function ($query) {
                        $query->where('id_local', Auth::guard("usuario")->user()->id_local)->where('fecha_pago', '<>', null)->where(['estado' => 1, 'id_nota' => null])->where('tipo_pago', 'CREDITO');
                    })->where(function ($query)  use ($request, $id1) {
                        $query->where('nombre_comprobante', 'LIKE',  '%'.$request->search.'%')
                              ->orWhere('serie_comprobante', 'LIKE',  '%'.$request->search.'%')
                              ->orWhere('numero_comprobante', 'LIKE',  '%'.$request->search.'%')
                              ->orWhere('fecha_venta', 'LIKE', '%'.$request->search.'%')
                              ->orWhere('id_cliente', '=', $id1 ? $id1->id_cliente : '');
                    })->paginate(10);

            $res->appends(['search' => $request->search]); 
            return view('venta.listar_deuda', ['data' => $res]); 
        }
    }


    
    
}
