<?php defined('BASEPATH') OR exit('No direct script access allowed');

require_once APPPATH . 'interfaces/Validator_interface.php';

class DateValidator implements Validator_interface
{
	private $params;

	public function __construct(&$params=null)
	{
        $this->params =& $params;
	}

	public function is_valid(&$data)
	{
		if (empty($data['tDate']))
		{
			$data['tDate'] = gmdate('Y-m-d');
		}

		$this->_check_freeze_date($data);

		$this->_check_block_before_date($data);

		$this->_check_gstr_freeze($data);

		$this->_check_before_opening_balance($data);

		return true;
	}

	private function _check_block_before_date(&$data)
	{
		$block_data_edit = get_rights("TBBDE");

		if(!empty($block_data_edit) && !empty($block_data_edit['actionRights']))
		{
			$ci =& get_instance();

			$ci->load->helper("date");

			if(empty($data['id']))
			{
				$checkDate = gmdate('Y-m-d');

				$config = get_company('config');

				$timezoneOffset = $config['timeZone'];

				$daylightsavetime = FALSE;

				if (empty($timezoneOffset))
				{
					$timezoneOffset = "UP55";
				}

				$data['tDate'] = gmdate('Y-m-d', gmt_to_local(strtotime($checkDate), $timezoneOffset, $daylightsavetime));
			}
			else
			{
				$tmp = $ci->db->select('tDate')->from('trans')->where(array(
					'cId'	=> $this->params->cId,
					'id'	=> $data['id'],
					'bId'	=> $this->params->bId
				))->get()->row_array();

				$checkDate = $tmp['tDate'];

				if(strtotime($data['tDate']) != strtotime($checkDate))
				{
					throw new Exception(lang('BLOCK_DATE_EDIT'));
					return false;
				}
			}
		}

		return true;
	}

	private function _check_freeze_date(&$data)
	{
/*
		if (empty($data['id']))
		{
			return true;
		}
*/

		$comp_conf = get_company('config');

		if (!empty($comp_conf['freezeDate']) && strtotime($data['tDate']) < strtotime($comp_conf['freezeDate']))
		{
			throw new Exception(sprintf(lang('FREEZE_TRANSACTION_DATE'), $comp_conf['freezeDate']));
			return false;
		}

		return true;
	}

	private function _check_gstr_freeze(&$data)
	{
		$comp_conf = get_company('config');

		// Payment/NonGST expense need not to be locked based on GSTR1/3B 

		if (in_array($data['tType'], array(SALINV,SALRETAIL,CRNOTE,DBNOTE)))
		{
			$data["isSales"] = true;
			if (!empty($comp_conf['g1Date']) && strtotime($data['tDate']) < strtotime($comp_conf['g1Date']))
			{
				throw new Exception(sprintf(lang('FREEZE_TRANSACTION_GSTR1_DATE'), $comp_conf['g1Date']));
				return false;
			}
		}
		else if (in_array($data['tType'], array(PURINV,PURRETAIL,EXPINV,EXPRETAIL,PURDBNOTE)) && $data['classCode'] != 'XPNG')
		{
			if (!empty($comp_conf['g3Date']) && strtotime($data['tDate']) < strtotime($comp_conf['g3Date']))
			{
				throw new Exception(sprintf(lang('FREEZE_TRANSACTION_GSTR3_DATE'), $comp_conf['g3Date']));
				return false;
			}
		}

/*
		if (!in_array($data['tType'], $this->NonAccTranTypes) && !in_array($data['tType'], array(JOURNAL_VOUCHER,JOURNAL_CONTRA,SALPMT,PURPMT)) && ($data['tType']!=EXPRETAIL || $data['classCode']!='XPNG')) {
			if (in_array($data['tType'], array(SALINV,SALRETAIL,CRNOTE,DBNOTE)))
			{
				$data["isSales"] = true;
				if (!empty($comp_conf['g1Date']) && strtotime($data['tDate']) < strtotime($comp_conf['g1Date']))
				{
					$this->error = sprintf(lang('FREEZE_TRANSACTION_GSTR1_DATE'), $comp_conf['g1Date']);
					return false;
				}
			}

			if (!empty($comp_conf['g3Date']) && strtotime($data['tDate']) < strtotime($comp_conf['g3Date'])) {
				$this->error = sprintf(lang('FREEZE_TRANSACTION_GSTR3_DATE'), $comp_conf['g3Date']);
				return false;
			}
		}
*/

		return true;
	}

	private function _check_before_opening_balance(&$data)
	{
		$ci =& get_instance();

		// check date below opening balance
		$ci->db->select('tDate')->from('trans')->where(array(
			'cId'	=> $this->params->cId,
			'tNo'	=> 1,
			'tType'	=> OPENING_BALANCE
		));

		if (sal_mod_active(BRANCH_MOD))
		{
			$ci->db->where('bId', $this->params->bId);
		}

		$ci->db->order_by("tDate", "asc");
		$ci->db->limit(1);
		$row = $ci->db->get()->row_array();

		if ($row && strtotime($data['tDate']) < strtotime($row['tDate']))
		{
			throw new Exception(sprintf(lang('DATE_ABOVE_OPEN_BALANCE'), $row['tDate']));
			return false;
		}

		return true;
	}
}

