<?php

use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Validator;

class FormulasController extends \BaseController {

	public static $jqgrid_colmodel = [
		[
			'label' => 'Id',
			'name' => 'ID',
			'hidden' => true
		],
		[
			'label' => 'Num registro',
			'name' => 'NREGUIST',
		],
		[
			'label' => 'Código',
			'name' => 'CODIGO',
			'hidden' => true
		],
		[
			'label' => 'Nombre',
			'name' => 'NOMBRE',
		],
		[
			'label' => 'Observación',
			'name' => 'OBSERVACION',
		],
		[
			'label' => 'Densidad Total',
			'name' => 'DEN_TOTAL',
		],
		[
			'label' => 'Peso Total (Kg)',
			'name' => 'PESO_TOTAL',
		],
		[
			'label' => 'Volumen Total (Lts)',
			'name' => 'VOL_TOTAL',
		],
		[
			'label' => 'Costo Total',
			'name' => 'COSTO_TOTAL',
		],
		[
			'label' => 'Volumen Formulación (Lts)',
			'name' => 'VOLUMEN',
		],
		[
			'label' => 'Vida útil',
			'name' => 'VIDA_UTIL',
		],
		[
			'label' => 'Tipo articulo',
			'name' => 'TIPO_ARTICULO',
			'hidden' => true,
		],
		[
			'label' => 'Fecha Creación',
			'name' => 'FECHA_CRE',
			'searchoptions' => [
				'sopt' => ['custom']
			]
		],
		[
			'label' => 'Fecha Modificación',
			'name' => 'FECHA_MOD',
			'searchoptions' => [
				'sopt' => ['custom']
			]
		],
		[
			'label' => 'Usuario',
			'name' => 'USUARIO',
		],

	];

	public static $jqgrid_detalles_colmodel = [
		[
			'label' => 'Id',
			'name' => 'ID',
			'hidden' => true
		],
		[
			'label' => 'Orden',
			'name' => 'ORDEN',
		],
		[
			'label' => 'Materia Prima',
			'name' => 'NOMBRE',
		],
		[
			'label' => 'Densidad',
			'name' => 'DENSIDAD',
		],
		[
			'label' => 'Peso',
			'name' => 'PESO',
		],
		[
			'label' => 'Volumen',
			'name' => 'VOLUMEN',
		],
		[
			'label' => 'Costo',
			'name' => 'COSTO',
		],
	];

	/**
	 * Muestra grilla de fórmulas
	 *
	 * @return Response
	 */
	public function index($id = false)
	{
		$rowid = $id;
		$title = 'Fórmulas';
		Breadcrumb::append_crumb($title);
		Jqgrid::add_js_colmodel('formulas', self::$jqgrid_colmodel);
		Jqgrid::add_js_colmodel('detalles_formula', self::$jqgrid_detalles_colmodel);
		return View::make('formulas.index', compact('title', 'rowid'));
	}

	/**
	 * Genera el json para cargar los datos en jqgrid
	 * @return string
	 */
	public function datagrid() {
		Jqgrid::init('vFormulas', self::$jqgrid_colmodel, self::jqgrid_format(), self::jqgrid_filter_format());
		return Jqgrid::datagrid();
	}

	/**
	 * Genera el json para cargar los datos en jqgrid
	 * @return string
	 */
	public function detalles_datagrid() {
		Jqgrid::init('vDetallesFormula', self::$jqgrid_detalles_colmodel,  self::jqgrid_format());
		Jqgrid::get_query()->where('NREGUIST', Input::get('NREGUIST'));
		return Jqgrid::datagrid();
	}

	/**
	 * Retorna funcion anonima que define los formatos para los valores de las distintas columnas de la grilla
	 * @return function
	 */
	private static function jqgrid_format() {
		return function ($column, $value) {
			$result = $value;
			if (in_array($column, ['VOLUMEN', 'PESO', 'DENSIDAD', 'VOL_TOTAL', 'PESO_TOTAL', 'DEN_TOTAL'])) {
				$result = number_format($value, 3, ',', '.');
			} else if(in_array($column, ['FECHA_CRE', 'FECHA_MOD'])) {
				$result = date('d-m-Y H:i:s', strtotime($value));
			} else if(in_array($column, ['COSTO', 'COSTO_TOTAL'])) {
				$result = moneda($value);
			}
			return $result;
		};
	}

	/**
	 * Retorna funcion anonima que define los formatos de búsqueda para los valores de las distintas columnas de la grilla
	 * @return function
	 */
	private static function jqgrid_filter_format() {
		return function ($field, $data) {
			$result = $data;
			if (in_array($field, ['FECHA_CRE', 'FECHA_MOD'])) {
				$values = explode(' | ', $data);
				$v1 = date('d-m-Y', strtotime($values[0]));
				$v2 = date('d-m-Y', strtotime($values[1]));
				$aux = "$field BETWEEN '$v1 00:00:00' AND '$v2 23:59:59'";
				$result = $aux;
			}
			return $result;
		};
	}

	/**
	 * Muestra Vista de agregar fórmula
	 *
	 * @return \Illuminate\Http\Response
	 */
	public function vista_agregar() {
		$title = 'Agregar';
		Breadcrumb::append_crumb('Fórmulas');
		Breadcrumb::append_crumb($title);
		$agua = DB::table('vProductos')
			->where('NREGUIST', Config::get('settings.agua_id'))
			->first();
		return View::make('formulas.agregar', compact('title', 'agua'));
	}

	/**
	 * Muestra Vista de editar fórmula
	 *
	 * @return \Illuminate\Http\Response
	 */
	public function vista_editar($id) {
		$title = 'Editar';
		Breadcrumb::append_crumb('Fórmulas');
		Breadcrumb::append_crumb($title);
		$formula = DB::table('vFormulas')->where('ID', '=',$id)->first();
		if(empty($formula)) {
			App::abort(404);
		}
		$detalles_formula  = DB::table('vDetallesFormula')->where('NREGUIST', '=', $formula->NREGUIST)->get();
		$preguntas = DB::table('PRODUCCION_PREGUNTAS_FORMULA')->where('IDFORMULA', '=', $id)->get();
		$agua = DB::table('vProductos')
			->where('NREGUIST', Config::get('settings.agua_id'))
			->first();
		return View::make('formulas.editar', compact('id', 'title', 'formula', 'detalles_formula', 'preguntas', 'agua'));
	}

	/**
	 * Guarda fórmula en base de datos
	 *
	 * @return \Illuminate\Http\Response
	 */
	public function agregar_formula() {
		$data = json_decode(Input::get('data'), true);
		//Validacion
		$vdata = [
			'NREGUIST_PROD_TERMINADO' => isset($data['nreguist'])?$data['nreguist']:'',
			'VOLUMEN' => isset($data['volumen'])?$data['volumen']:'',
			'VIDA_UTIL' => isset($data['vida_util'])?$data['vida_util']:'',
			'OBSERVACION' => isset($data['observacion'])?$data['observacion']:'',
		];
		$vrules = [
			'NREGUIST_PROD_TERMINADO' => 'required|unique:PRODUCCION_CABECERA_FORMULAS',
			'VOLUMEN' => 'required|numeric',
			'VIDA_UTIL' => 'required|numeric',
		];
		$vmessages = [
			'NREGUIST_PROD_TERMINADO.required' => 'El campo Nombre del Producto es obligatorio.',
			'NREGUIST_PROD_TERMINADO.unique' => 'El Producto seleccionado ya poseé una fórmula.',
			'VOLUMEN.required' => 'El campo Volumen es obligatorio.',
			'VOLUMEN.numeric' => 'El campo Volumen debe ser numérico.',
			'VIDA_UTIL.required' => 'El campo Vida útil es obligatorio.',
			'VIDA_UTIL.numeric' => 'El campo Vida útil debe ser numérico.',
		];
		if(isset($data['materias_primas'])) {
			foreach($data['materias_primas'] as $mp) {
				$nreguists = implode(',', array_column(array_filter($data['materias_primas'], function($v) use ($mp) {return $v['id'] != $mp['id'];}), 'nreguist'));
				$vdata["MATERIA_PRIMA.{$mp['id']}.NREGUIST_MATERIA_PRIMA"] = isset($mp['nreguist'])?$mp['nreguist']:'';
				$vdata["MATERIA_PRIMA.{$mp['id']}.PESO"] = isset($mp['peso'])?$mp['peso']:'';

				$vrules["MATERIA_PRIMA.{$mp['id']}.NREGUIST_MATERIA_PRIMA"] = "required|not_in:$nreguists";
				$vrules["MATERIA_PRIMA.{$mp['id']}.PESO"] = 'required';

				$vmessages["MATERIA_PRIMA.{$mp['id']}.NREGUIST_MATERIA_PRIMA.required"] = 'El campo Materia Prima es obligatorio.';
				$vmessages["MATERIA_PRIMA.{$mp['id']}.NREGUIST_MATERIA_PRIMA.not_in"] = 'La Materia Prima no puede estar repetida.';
				$vmessages["MATERIA_PRIMA.{$mp['id']}.PESO.required"] = 'El campo Peso es obligatorio.';
			}
		}
		if(isset($data['preguntas_calidad'])) {
			foreach($data['preguntas_calidad'] as $pc) {
				$vdata["PREGUNTA.{$pc['id']}"] = isset($pc['pregunta'])?$pc['pregunta']:'';

				$vrules["PREGUNTA.{$pc['id']}"] = "required";

				$vmessages["PREGUNTA.{$pc['id']}.required"] = 'El campo Pregunta es obligatorio.';
			}
		}

		$validador = Validator::make($vdata, $vrules, $vmessages);

		if($validador->fails()) {
			$response = $validador->messages();
			return Response::json($response, 422);
		} else if(!isset($data['materias_primas'])) {
			$message = ['content' => 'Debe agregar Materias Primas.', 'type' => 'error'];
			$response = ['status' => 409, 'message' => $message];
		} else {
			//fin validacion
			$result = DB::transaction(function() use ($data, $vdata) {
				$id_insert = DB::table('PRODUCCION_CABECERA_FORMULAS')->insertGetId([
					'NREGUIST_PROD_TERMINADO' => $vdata['NREGUIST_PROD_TERMINADO'],
					'OBSERVACION' => $vdata['OBSERVACION'],
					'VOLUMEN' => $vdata['VOLUMEN'],
					'VIDA_UTIL' => $vdata['VIDA_UTIL'],
					'FECHA_CRE' => date('Ymd H:i:s'),
					'FECHA_MOD' => date('Ymd H:i:s'),
					'USUMOD' => Auth::id()
				]);

				foreach($data['materias_primas'] as $mp) {
					DB::table('PRODUCCION_DETALLE_FORMULAS')->insert([
						'ID_CABECERA' => $id_insert,
						'NREGUIST_PROD_TERMINADO' => $vdata['NREGUIST_PROD_TERMINADO'],
						'NREGUIST_MATERIA_PRIMA' => $vdata["MATERIA_PRIMA.{$mp['id']}.NREGUIST_MATERIA_PRIMA"],
						'PESO' => $vdata["MATERIA_PRIMA.{$mp['id']}.PESO"],
						'ORDEN' => $mp['orden']
					]);
				}

				if(isset($data['preguntas_calidad'])) {
					foreach($data['preguntas_calidad'] as $pc) {
						DB::table('PRODUCCION_PREGUNTAS_FORMULA')->insert([
							'IDFORMULA' => $id_insert,
							'ORDEN' => $pc['orden'],
							'PREGUNTA' => $vdata["PREGUNTA.{$pc['id']}"],
						]);
					}
				}

				return ['success' => true, 'id' => $id_insert];
			});

			if(isset($result['success'])) {
				$message = ['content' => 'La fórmula fue agregada.', 'type' => 'success', 'id' => $result['id']];
				$response = ['status' => 200, 'message' => $message];
			} else {
				$message = ['content' => 'La fórmula no pudo ser agregada.', 'type' => 'error'];
				$response = ['status' => 409, 'message' => $message];
			}
		}
		return Response::json($response, $response['status']);
	}

	/**
	 * Guarda fórmula en base de datos
	 *
	 * @return \Illuminate\Http\Response
	 */
	public function editar_formula($id) {
		$data = json_decode(Input::get('data'), true);
		//Validacion
		$vdata = [
			'NREGUIST_PROD_TERMINADO' => isset($data['nreguist'])?$data['nreguist']:'',
			'VOLUMEN' => isset($data['volumen'])?$data['volumen']:'',
			'VIDA_UTIL' => isset($data['vida_util'])?$data['vida_util']:'',
			'OBSERVACION' => isset($data['observacion'])?$data['observacion']:'',
		];
		$vrules = [
			'NREGUIST_PROD_TERMINADO' => "required|unique:PRODUCCION_CABECERA_FORMULAS,NREGUIST_PROD_TERMINADO,$id,ID",
			'VOLUMEN' => 'required|numeric',
			'VIDA_UTIL' => 'required|numeric',
		];
		$vmessages = [
			'NREGUIST_PROD_TERMINADO.required' => 'El campo Nombre del Producto es obligatorio.',
			'NREGUIST_PROD_TERMINADO.unique' => 'El Producto seleccionado ya poseé una fórmula.',
			'VOLUMEN.required' => 'El campo Volumen es obligatorio.',
			'VOLUMEN.numeric' => 'El campo Volumen debe ser numérico.',
			'VIDA_UTIL.required' => 'El campo Vida útil es obligatorio.',
			'VIDA_UTIL.numeric' => 'El campo Vida útil debe ser numérico.',
		];
		if(isset($data['materias_primas'])) {
			foreach($data['materias_primas'] as $mp) {
				$nreguists = implode(',', array_column(array_filter($data['materias_primas'], function($v) use ($mp) {return $v['id'] != $mp['id'];}), 'nreguist'));
				$vdata["MATERIA_PRIMA.{$mp['id']}.NREGUIST_MATERIA_PRIMA"] = isset($mp['nreguist'])?$mp['nreguist']:'';
				$vdata["MATERIA_PRIMA.{$mp['id']}.PESO"] = isset($mp['peso'])?$mp['peso']:'';

				$vrules["MATERIA_PRIMA.{$mp['id']}.NREGUIST_MATERIA_PRIMA"] = "required|not_in:$nreguists";
				$vrules["MATERIA_PRIMA.{$mp['id']}.PESO"] = 'required';

				$vmessages["MATERIA_PRIMA.{$mp['id']}.NREGUIST_MATERIA_PRIMA.required"] = 'El campo Materia Prima es obligatorio.';
				$vmessages["MATERIA_PRIMA.{$mp['id']}.NREGUIST_MATERIA_PRIMA.not_in"] = 'La Materia Prima no puede estar repetida.';
				$vmessages["MATERIA_PRIMA.{$mp['id']}.PESO.required"] = 'El campo Peso es obligatorio.';
			}
		}
		if(isset($data['preguntas_calidad'])) {
			foreach($data['preguntas_calidad'] as $pc) {
				$vdata["PREGUNTA.{$pc['id']}"] = isset($pc['pregunta'])?$pc['pregunta']:'';

				$vrules["PREGUNTA.{$pc['id']}"] = "required";

				$vmessages["PREGUNTA.{$pc['id']}.required"] = 'El campo Pregunta es obligatorio.';
			}
		}
		$validador = Validator::make($vdata, $vrules, $vmessages);
		if($validador->fails()) {
			$response = $validador->messages();
			return Response::json($response, 422);
		} elseif(!isset($data['materias_primas'])) {
			$message = ['content' => 'Debe agregar Materias Primas.', 'type' => 'error'];
			$response = ['status' => 409, 'message' => $message];
		} else {
			//fin validacion

			$result = DB::transaction(function() use ($data, $vdata, $id) {
				$id_insert = DB::table('PRODUCCION_CABECERA_FORMULAS')
					->where('ID', $id)
					->update([
					'NREGUIST_PROD_TERMINADO' => $vdata['NREGUIST_PROD_TERMINADO'],
					'OBSERVACION' => $vdata['OBSERVACION'],
					'VOLUMEN' => $vdata['VOLUMEN'],
					'VIDA_UTIL' => $vdata['VIDA_UTIL'],
					'FECHA_MOD' => date('Ymd H:i:s'),
					'USUMOD' => Auth::id()
				]);

				DB::table('PRODUCCION_DETALLE_FORMULAS')->where('ID_CABECERA', $id)->delete();

				foreach($data['materias_primas'] as $mp) {
					DB::table('PRODUCCION_DETALLE_FORMULAS')->insert([
						'ID_CABECERA' => $id,
						'NREGUIST_PROD_TERMINADO' => $vdata['NREGUIST_PROD_TERMINADO'],
						'NREGUIST_MATERIA_PRIMA' => $vdata["MATERIA_PRIMA.{$mp['id']}.NREGUIST_MATERIA_PRIMA"],
						'PESO' => $vdata["MATERIA_PRIMA.{$mp['id']}.PESO"],
						'ORDEN' => $mp['orden']
					]);
				}

				DB::table('PRODUCCION_PREGUNTAS_FORMULA')->where('IDFORMULA', $id)->delete();
				if(isset($data['preguntas_calidad'])) {
					foreach($data['preguntas_calidad'] as $pc) {
						DB::table('PRODUCCION_PREGUNTAS_FORMULA')->insert([
							'IDFORMULA' => $id,
							'PREGUNTA' => $vdata["PREGUNTA.{$pc['id']}"],
							'ORDEN' => $pc['orden']
						]);
					}
				}
				return ['success' => true, 'id' => $id_insert];
			});

			if(isset($result['success'])) {
				$message = ['content' => 'La fórmula fue editada.', 'type' => 'success', 'id' => $result['id']];
				$response = ['status' => 200, 'message' => $message];
			} else {
				$message = ['content' => 'La fórmula no pudo ser editada.', 'type' => 'error'];
				$response = ['status' => 409, 'message' => $message];
			}
		}
		return Response::json($response, $response['status']);
	}

	/**
	 * Elimina fórmula de base de datos
	 * @return mixed
	 */
	public function eliminar() {
		$id = Input::get('id');
		$result = DB::transaction(function() use ($id) {
			DB::table('PRODUCCION_DETALLE_FORMULAS')
				->where('ID_CABECERA', $id)
				->delete();
			DB::table('PRODUCCION_CABECERA_FORMULAS')
				->where('ID', $id)
				->delete();
			return true;
		});

		if($result) {
			$message = ['content' => 'La fórmula fue eliminada.', 'type' => 'success'];
			$response = ['status' => 200, 'message' => $message];
		} else {
			$message = ['content' => 'La fórmula no pudo ser eliminada.', 'type' => 'error'];
			$response = ['status' => 409, 'message' => $message];
		}

		return Response::json($response, $response['status']);
	}

	/**
	 * Obtiene listado de materias primas
	 * @return mixed
	 */
	public function select_materias_primas() {
		$query = Input::get('q', '');
		$materias_primas = DB::table('vListaProductos')
			->where('TIPO_ARTICULO', 'MATERIA PRIMA')
			->where('NOMBRE', 'LIKE', "%$query%")
			->select(DB::raw('NREGUIST as id, NOMBRE as text, VALPROM as costo, DENSIDAD as densidad'))
			->paginate(10);
		return $materias_primas;
	}

	/**
	 * Obtiene listado de productos terminados
	 * @return mixed
	 */
	public function select_productos() {
		$query = Input::get('q', '');
		$productos = DB::table('vListaProductos')
			->where('TIPO_ARTICULO', 'PRODUCTO GRANEL')
			->where('NOMBRE', 'LIKE', "%$query%")
			->whereRaw('NREGUIST NOT IN (SELECT NREGUIST FROM vFormulas)')
			->select(DB::raw('NREGUIST as id, NOMBRE as text, PRECVTA as precio_venta'))
			->paginate(10);
		return $productos;
	}
}
