<?php
class Compra_model extends CI_Model {

	public function get_all($tipo_compra = 1, $periodo = '') {
		$this->db->select('*');
		$this->db->from('compras c');
		$this->db->where('c.deleted', 0);
		$this->db->where('c.id_tipo_compra', $tipo_compra);
		if(!empty($periodo)){
			$this->db->where('DATE_FORMAT(fecha_recepcion, "%Y%m") = ', $periodo);
		}
		$this->db->order_by('DATE_FORMAT(fecha_recepcion, \'%Y%m\') DESC');
		$this->db->order_by('c.fecha_recepcion', 'DESC');
		$this->db->order_by('c.folio', 'DESC');
		$query = $this->db->get();
		$result = $query->result_array();
		foreach ($result as &$compra) {
			$compra['mes'] = date('Ym', strtotime($compra['fecha_recepcion']));
		}

		return $result;
	}

	/**
	 * Retorna un arreglo con todos los meses en que se han realizado compras
	 * en formato YYYYMM
	 */
	public function get_meses_compras($current = true, $tipo_compra = 0){
		$this->db->select("DATE_FORMAT(fecha_recepcion,'%Y%m') as mes");
		$this->db->from('compras');
		$this->db->where('deleted', 0);
		if (!empty($tipo_compra)) {
			$this->db->where('id_tipo_compra', $tipo_compra);
		}
		$this->db->group_by('mes');
		$this->db->order_by('mes', 'DESC');
		$meses = $this->db->get()->result_array();

		if ($current) {
			$tmp_meses[0] = date('Ym');
			foreach ($meses as $k => $c) {
				if ($c['mes'] != $tmp_meses[0]) {
					$tmp_meses[] = $c['mes'];
				}
			}
		}
		else {
			$tmp_meses[0] = 0;
			foreach ($meses as $k => $c) {
				$tmp_meses[] = $c['mes'];
			}
		}

		return $tmp_meses;
	}

	/**
	 * Retorna un arreglo con todas las categorias de compras ordenadas por campo orden
	 */
	public function list_categorias_compras() {
		$this->db->select("id, nombre");
		$this->db->from('categorias_compras');
		$this->db->order_by('orden', 'ASC');
		$categorias = $this->db->get()->result_array();

		$return = [];
		foreach ($categorias as $c) {
			$return[$c['id']] = $c['nombre'];
		}
		return $return;
	}

	public function get($id) {
		$this->db->select('c.*,p.nombre');
		$this->db->from('compras c');
		$this->db->join('proveedores p','c.id_proveedor = p.id', 'left');
		$this->db->where('c.id', $id);
		$this->db->where('c.deleted', 0);
		$query = $this->db->get();
		$compra = $query->result_array();
		
		if (!empty($compra)) {
			$this->db->select('cp.*, p.ps_id');
			$this->db->from('compras_productos cp');
			$this->db->join('productos p','cp.id_producto = p.id', 'left');
			$this->db->where('cp.id_compra', $id);
			$this->db->where('cp.deleted', 0);
			$query = $this->db->get();
			$comprasProductos = $query->result_array();

			$CI =& get_instance();
			$CI->load->model('producto_model');
			foreach ($comprasProductos as &$cp) {
				$cp['id_image'] = $CI->producto_model->get_ps_image($cp['ps_id']);
			}

			$compra[0]['fecha'] = date('Y-m-d', strtotime($compra[0]['fecha']));
			$compra[0]['proveedor'] = $compra[0]['nombre'];
			$compra[0]['compras_productos'] = $comprasProductos;
			return $compra[0];
		}
		else{
			return [];
		}
	}

	public function save($data) {
			//se guarda
			$compra = $data;
			unset($compra['proveedor'], $compra['id_producto'], $compra['nombre'], $compra['cantidad'], $compra['costo_neto'], $compra['costo_total']);

			if ($compra['fecha_recepcion'] != '') {
				$compra['fecha_recepcion'] = date("Y-m-d", strtotime( $compra['fecha_recepcion']));
			}
			else {
				$compra['fecha_recepcion'] = date("Y-m-d");
			}
			$compra['fecha'] = $compra['fecha_recepcion'];
			// Guarda fecha para ajustar Stock
			$data['fecha'] = $compra['fecha'];

			$idAlmacenAnterior = 0;

			if (empty($data['id'])) {
				if ($compra['contable']) {
					$this->ajusta_saldo($compra['total']);
				}

				$compra['created'] = date('Y-m-d H:i:s');
				$this->db->insert('compras', $compra);
				$idCompra = $this->db->insert_id();
			}
			else {
				$this->db->from('compras');
				$this->db->select('id_almacen');
				$this->db->where('id', $data['id']);
				$anterior = $this->db->get()->row_array();
				$idAlmacenAnterior = $anterior['id_almacen'];

				$this->ajusta_saldo($compra['total'], $data['id'], $compra['contable']);
				$this->db->where('id', $data['id']);
				$this->db->update('compras', $compra);
				$idCompra = $data['id'];
			}

			$this->ajusta_stock($data, $idCompra, $compra['id_almacen'], $idAlmacenAnterior);
			
			return $idCompra;
		/*
		}
		else {
			//no se guarda na
			pr('total Incorrecto');
			pr($data);
			pr($totalCompra);
			pr($data['total']);
		}
		*/
	}

	public function delete($id) {
		//Revisar si viene id y si viene se hace update
		if (!empty($id)) {

			$this->db->from('compras');
			$this->db->select('id_almacen');
			$this->db->where('id', $id);
			$anterior = $this->db->get()->row_array();
			$idAlmacenAnterior = $anterior['id_almacen'];

			$this->ajusta_saldo(0, $id);

			$this->db->set('deleted', 1, FALSE);
			$this->db->where('id', $id);
			$this->db->update('compras');
			$data['id'] = $id;
			$this->ajusta_stock($data, $id, 0, $idAlmacenAnterior);
		}
	}

	public function revisar($id, $revisado) {
		//Revisar si viene id y si viene se hace update
		if (!empty($id)) {
			$this->db->set('revisado', $revisado, FALSE);
			$this->db->where('id', $id);
			$this->db->update('compras');
			return true;
		}
	}

	public function get_totales() {
		//SELECT SUM(total) AS total, COUNT(DISTINCT(boleta)) AS boletas, DATE_FORMAT(fecha,'%Y%m') AS mes FROM ventas GROUP BY DATE_FORMAT(fecha,'%Y%m')
		$this->db->select('SUM(total) AS total, COUNT(DISTINCT(id)) AS cantidad, DATE_FORMAT(fecha,"%Y%m") AS mes');
		$this->db->from('compras c');
		$this->db->where('c.deleted', 0);
		$this->db->where('c.contable', 1);
		$this->db->where('c.id_tipo_compra', 1);
		$this->db->group_by('DATE_FORMAT(fecha,"%Y%m")');
		$meses = $this->db->get()->result_array();
		$total = 0;
		foreach($meses as $mes) {
			$totales[$mes['mes']][1]['cantidad'] = $mes['cantidad'];
			$totales[$mes['mes']][1]['total'] = $mes['total'];
			$total += $mes['total'];
		}
		$totales['total'][1] = $total;

		//SELECT SUM(total) AS total, COUNT(DISTINCT(boleta)) AS boletas, DATE_FORMAT(fecha,'%Y%m') AS mes FROM ventas GROUP BY DATE_FORMAT(fecha,'%Y%m')
		$this->db->select('SUM(total) AS total, COUNT(DISTINCT(id)) AS cantidad, DATE_FORMAT(fecha,"%Y%m") AS mes');
		$this->db->from('compras c');
		$this->db->where('c.deleted', 0);
		$this->db->where('c.contable', 1);
		$this->db->where('c.id_tipo_compra', 2);
		$this->db->group_by('DATE_FORMAT(fecha,"%Y%m")');
		$meses = $this->db->get()->result_array();
		$total = 0;
		foreach($meses as $mes) {
			$totales[$mes['mes']][2]['cantidad'] = $mes['cantidad'];
			$totales[$mes['mes']][2]['total'] = $mes['total'];
			$total += $mes['total'];
		}
		$totales['total'][2] = $total;

		//SELECT SUM(total) AS total, COUNT(DISTINCT(boleta)) AS boletas, DATE_FORMAT(fecha,'%Y%m') AS mes FROM ventas GROUP BY DATE_FORMAT(fecha,'%Y%m')
		$this->db->select('SUM(total) AS total, COUNT(DISTINCT(id)) AS cantidad, DATE_FORMAT(fecha,"%Y%m") AS mes');
		$this->db->from('compras c');
		$this->db->where('c.deleted', 0);
		$this->db->where('c.id_tipo_compra', 3);
		$this->db->group_by('DATE_FORMAT(fecha,"%Y%m")');
		$meses = $this->db->get()->result_array();
		$total = 0;
		foreach($meses as $mes) {
			$totales[$mes['mes']][3]['cantidad'] = $mes['cantidad'];
			$totales[$mes['mes']][3]['total'] = $mes['total'];
			$total += $mes['total'];
		}
		$totales['total'][3] = $total;

		$this->db->select('SUM(total) AS total, COUNT(DISTINCT(id)) AS cantidad, DATE_FORMAT(fecha,"%Y%m") AS mes');
		$this->db->from('compras c');
		$this->db->where('c.deleted', 0);
		$this->db->where('c.contable', 1);
		$this->db->where('c.id_tipo_compra', 4);
		$this->db->group_by('DATE_FORMAT(fecha,"%Y%m")');
		$meses = $this->db->get()->result_array();
		$total = 0;
		foreach($meses as $mes) {
			$totales[$mes['mes']][4]['cantidad'] = $mes['cantidad'];
			$totales[$mes['mes']][4]['total'] = $mes['total'];
			$total += $mes['total'];
		}
		$totales['total'][4] = $total;


		$this->db->select('SUM(total) AS total, COUNT(DISTINCT(id)) AS cantidad, DATE_FORMAT(fecha,"%Y%m") AS mes');
		$this->db->from('compras c');
		$this->db->where('c.deleted', 0);
		$this->db->where('c.contable', 1);
		$this->db->where('c.id_tipo_compra', 5);
		$this->db->group_by('DATE_FORMAT(fecha,"%Y%m")');
		$meses = $this->db->get()->result_array();
		$total = 0;
		foreach($meses as $mes) {
			$totales[$mes['mes']][5]['cantidad'] = $mes['cantidad'];
			$totales[$mes['mes']][5]['total'] = $mes['total'];
			$total += $mes['total'];
		}
		$totales['total'][5] = $total;

		$this->db->select('SUM(total) AS total, COUNT(DISTINCT(id)) AS cantidad, DATE_FORMAT(fecha,"%Y%m") AS mes');
		$this->db->from('compras c');
		$this->db->where('c.deleted', 0);
		$this->db->where('c.contable', 1);
		$this->db->where('c.id_tipo_compra', 6);
		$this->db->group_by('DATE_FORMAT(fecha,"%Y%m")');
		$meses = $this->db->get()->result_array();
		$total = 0;
		foreach($meses as $mes) {
			$totales[$mes['mes']][6]['cantidad'] = $mes['cantidad'];
			$totales[$mes['mes']][6]['total'] = $mes['total'];
			$total += $mes['total'];
		}
		$totales['total'][6] = $total;

		return $totales;
	}

	/*
	 * Actualiza saldo de la tienda
	 * $total : nuevo monto de compra
	 * $id : $id de compra en edición
	 */
	public function ajusta_saldo($total = 0, $id = 0, $contable = 1) {
		$dinero = [];
		//Ajusta saldo segun el total de la compra
		$this->db->select('id, monto');
		$this->db->from('dineros d');
		$this->db->where('d.id_tipo_dinero', 0);
		$this->db->where('d.deleted', 0);
		$saldo = $this->db->get()->row_array();
		$dinero['monto'] = $saldo['monto'];

		if (!empty($id)) {
			$this->db->select('id, total, contable');
			$this->db->from('compras');
			$this->db->where('id', $id);
			$this->db->where('deleted', 0);
			$previo = $this->db->get()->row_array();
			//si antes fue contable se repone el dinero de la compra anterior
			if ($previo['contable']) {
				$dinero['monto'] += $previo['total'];
			}
		}

		//Si ahora es contable se resta el dinero de la compra actual
		if ($contable) {
			$dinero['monto'] -= $total;
		}

		$this->db->where('id', $saldo['id']);
		$this->db->update('dineros', $dinero);
		return true;
	}

	/*
	 * Actualiza Stock de productos de compra y de almacen por defecto
	 * $data: datos de los productos e id de compra
	 * $id : $id de compra en edición
	 */
	public function ajusta_stock($data = [], $idCompra = 0, $idAlmacenDefecto = 1, $idAlmacenAnterior = 1) {

		$productosAfectados = [];

		// Si está editando o eliminando se descuenta el stock anterior y se eliminan compras_productos
		if (!empty($data['id'])) { 

			$this->db->select('*');
			$this->db->from('compras_productos cp');
			$this->db->join('productos p','cp.id_producto = p.id');
			$this->db->where('cp.id_compra', $idCompra);
			$this->db->where('cp.deleted', 0);
			$this->db->where('p.deleted', 0);
			$query = $this->db->get();
			$comprasProductos = $query->result_array();

			foreach ($comprasProductos as $compraProducto) {

				if (!empty($compraProducto['id_producto'])) {

					$this->db->select('id, stock, disponibles, reservados');
					$this->db->from('almacenes_productos');
					$this->db->where('id_producto', $compraProducto['id_producto']);
					$this->db->where('id_almacen', $idAlmacenAnterior);
					$this->db->where('deleted', 0);
					$almacenProducto = $this->db->get()->row_array();

					$ap = [];

					if (empty($almacenProducto)) {
						$almacenProducto = [
							'id' => null,
							'stock' => 0,
							'disponibles' => 0,
							'reservados' => 0
						];
					}

					$producto['stock'] = $compraProducto['stock'] - $compraProducto['cantidad'];
					$ap['stock'] = $almacenProducto['stock'] - $compraProducto['cantidad'];

					$producto['disponibles'] = $compraProducto['disponibles'] - $compraProducto['cantidad'];
					$ap['disponibles'] = $almacenProducto['disponibles'] - $compraProducto['cantidad'];

					$producto['comprados'] = $compraProducto['comprados'] - $compraProducto['cantidad'];

					$this->db->where('id', $compraProducto['id_producto']);
					$this->db->update('productos', $producto);

					if (!empty($almacenProducto['id'])) {
						$this->db->where('id', $almacenProducto['id']);
						$this->db->update('almacenes_productos', $ap);
					}

					$productosAfectados[$compraProducto['id_producto']][$idAlmacenAnterior] = true;
				}
			}

			$compraProducto = [];
			$compraProducto['deleted'] = 1;
			$this->db->where('id_compra', $idCompra);
			$this->db->update('compras_productos', $compraProducto);
		}

		if (!empty($data['id_producto'])) {

			foreach ($data['id_producto'] as $key => $idProducto) {

				if (!empty($data['cantidad'][$key])) {

					$compraProducto = [];
					$compraProducto['id_compra'] = $idCompra;
					$compraProducto['id_producto'] = $idProducto;
					$compraProducto['nombre'] = $data['nombre'][$key];
					$compraProducto['cantidad'] = $data['cantidad'][$key];
					$compraProducto['costo_neto'] = $data['costo_neto'][$key];
					$compraProducto['costo_total'] = $data['costo_total'][$key];
					$compraProducto['created'] = date('Y-m-d H:i:s');

					$this->db->insert('compras_productos', $compraProducto);

					$this->db->select('id, stock, disponibles, reservados');
					$this->db->from('almacenes_productos');
					$this->db->where('id_producto', $idProducto);
					$this->db->where('id_almacen', $idAlmacenDefecto);
					$this->db->where('deleted', 0);
					$almacenProducto = $this->db->get()->row_array();

					$ap = [];

					if (empty($almacenProducto)) {
						$almacenProducto = [
							'id' => null,
							'stock' => 0,
							'disponibles' => 0,
							'reservados' => 0
						];

						$ap['id_producto'] = $compraProducto['id_producto'];
						$ap['id_almacen'] = $idAlmacenDefecto;
					}

					if (!empty($idProducto)) {

						$this->db->select('*');
						$this->db->from('productos p');
						$this->db->where('p.id', $idProducto);
						$this->db->where('p.deleted', 0);
						$producto = $this->db->get()->row_array();

						if (!empty($producto)) {

							$producto['stock'] = $producto['stock'] + $compraProducto['cantidad'];
							$ap['stock'] = $almacenProducto['stock'] + $compraProducto['cantidad'];

							$producto['disponibles'] = $producto['disponibles'] + $compraProducto['cantidad'];
							$ap['disponibles'] = $almacenProducto['disponibles'] + $compraProducto['cantidad'];

							$producto['comprados'] = $producto['comprados'] + $compraProducto['cantidad'];

							$producto['costo_neto'] = $compraProducto['costo_neto'];

							if (!empty($data['fecha'])) {
								$producto['ultima_compra'] = $data['fecha'];
							}

							$this->db->where('id', $idProducto);
							$this->db->update('productos', $producto);

							if (empty($almacenProducto['id'])) {
								$this->db->insert('almacenes_productos', $ap);
							}
							else {
								$this->db->where('id', $almacenProducto['id']);
								$this->db->update('almacenes_productos', $ap);
							}

							$productosAfectados[$idProducto][$idAlmacenDefecto] = true;
						}
					}
				}
			}
		}

		if (!empty($productosAfectados)) {

			if (!isset($this->Quiebre)) {
				$this->load->model('Quiebre_model', 'Quiebre');
			}

			foreach ($productosAfectados as $idProducto => $almacenes) {

				foreach ($almacenes as $idAlmacen => $v) {
					$this->Quiebre->evaluar_quiebre($idProducto, $idAlmacen, 1);
				}

				$this->Quiebre->evaluar_quiebre_interno($idProducto, 1);
			}
		}

		return true;
	}


	public function list_tipos() {
		$tipos = [
			1 => 'Factura',
			4 => 'Factura No Afecta',
			2 => 'Din',
			3 => 'Factura Internacional',
			5 => 'Nota de Débito',
			6 => 'Nota de Crédito',
		];

		return $tipos;
	}



	/**
	 * Retorna los datos necesarios para crear y editar compras: Proveedores, Tipos de compras, categorías de compras, almnacenes de recepción
	 * 
	 */
	public function datos_editar($data) {
		// Obtiene los proveedores y sus nombres
		$this->db->from('proveedores');
		$this->db->where('deleted', 0);
		$result = $this->db->get()->result_array();

		foreach ($result as $p) {
			$data['proveedoresNombres'][$p['nombre']] = $p['id'];
		}

		// Obtiene los tipos de compra
		$data['tipos_compras'] = $this->list_tipos();

		// Obtiene las categorias de compra
		$data['categorias_compras'] = $this->list_categorias_compras();

		$CI =& get_instance();

		// Obtiene los almacenes de recpeción
		$CI->load->model('almacen_model', 'Almacen');
		$data['almacenes'] = $this->Almacen->lista(false);


		//prx($data);
		return $data;
	}
}