<?php
namespace App\Config;

/**
 * Field validator for the payment export configs
 * @author FlorinRusu
 *
 */
class ExportData_Fields_Payment extends ExportData_Fields_GeneralAbstract
{
	/**
	 * lastUpdateTime column preset
	 * @var string
	 */
	protected $dbTableLastUpdateTimeCol = 'lastUpdateTime';

	/**
	 * The primary key (the list of columns) for this table - in the correct order.
	 * @var array
	 */
	protected $entityCriteriaList = [
		'docType',
		'idOffice',
		'idBankAccount',
		'currency',
	];


	/**
	 *
	 * {@inheritDoc}
	 * @see \App\Config\DbMultiAssocVarsAbstract::getDbTableName()
	 */
	protected function getDbTableName()
	{
		global $DBTExportData_payments;
		return $DBTExportData_payments;
	}

	/**
	 * Gets the values of all fields for a criteria list (each field is given as a parameter)
	 * @param String $field
	 * @param String $serviceCode
	 * @param String $location
	 * @param String $calculationType
	 * @param String $rowType
	 * @param String $currency
	 * @return Array
	 */
	public function getFieldValue($field, $docType, $idOffice, $idBankAccount, $currency)
	{
		// compose criteria list
		$criteriaList = [
			'docType'		=>	$docType,
			'idOffice'		=>	$idOffice,
			'idBankAccount'	=>	$idBankAccount,
			'currency'		=>	$currency,
		];

		return $this->getFieldValueByCriteriaList($field, $criteriaList);

	}

	/**
	 * Get all active fields values for a criteria list
	 * @param array $criteriaList =  [docType, idOffice, idBankAccount, currency]
	 * @return Array
	 */
	public function getActiveFieldsValues(Array $criteriaList) {
		$activeFields = \App\Config\ExportData_Fields::getInstance()->getFieldsActive('payments');
		$return = [];
		foreach ($activeFields as $fieldCode => $fieldName) {
			$return[$fieldCode] = $this->getFieldValue($fieldCode, $criteriaList['docType'], $criteriaList['idOffice'], $criteriaList['idBankAccount'], $criteriaList['currency']);
		}

		return $return;
	}

	/**
	 * Get all the rules defined for the criteria (serviceCode, location, calculationType) and for the fieldCodes selected
	 * @param String $serviceCode
	 * @param String $location
	 * @param String $calculationType
	 * @param array $fieldCodes
	 */
	public function getRules($docType, Array $fieldCodes)
	{
		if (!$fieldCodes) {
			throw new \App\Config\MessageException('No export field selected.');
		}

		$paymentsListObj = new \App\EntityList\ExportDataPayments();
		$paymentsListObj->setColumns(['docType', 'idOffice', 'idBankAccount', 'currency', 'field', 'value']);

		if ($docType !== null) {
			$paymentsListObj->setFilter('docType', 'LIKE', $docType);
		}

		$paymentsListObj->setFilter('field', 'IN', $fieldCodes);
		$records = $paymentsListObj->exportRecords();

		if (!$records) {
			throw new \App\Config\MessageException('No rule was defined.');
		}

		return $records;
	}

	/**
	 * Sets a value for certain criteria list.
	 * @param String $field
	 * @param String $bankAccount
	 * @param String $currency
	 */
	public function setValue($field, $docType, $idOffice, $idBankAccount, $currency, $value)
	{
		$pkFields = [
			'field'			=>  $field,
			'docType'		=>	$docType,
			'idOffice'		=>	$idOffice,
			'idBankAccount'	=>	$idBankAccount,
			'currency'		=>	$currency,
		];

		$this->set($pkFields, $value);

	}

	/**
	 *
	 * {@inheritDoc}
	 * @see \App\Config\DbMultiAssocVarsAbstract::save_check()
	 */
	protected function save_check()
	{
		if (!\DB::isInsideTransaction()) {
			throw new \Exception("This operation must be performed inside a transaction.");
		}

		parent::save_check();
		if ($this->itemsList) {
			foreach($this->itemsList as $fields) {
				$this->checkFields($fields['pkFields']['field'], $fields['pkFields']['docType'], $fields['pkFields']['idOffice'], $fields['pkFields']['idBankAccount'], $fields['pkFields']['currency']);
			}
		}
	}

	/**
	 * Check if the criterions and the field are valid
	 * @param String $field
	 * @param String $bankAccount
	 * @param String $currency
	 * @throws \Exception
	 */
	private function checkFields($field, $docType, $idOffice, $idBankAccount, $currency)
	{
		// check if fieldCode exists
		if (!in_array($field, array_keys(\App\Config\ExportData_Fields::getInstance()->getFieldsAll('payments')))) {
			throw new \App\Config\MessageException(sprintf('The field code (%s) is not valid', $field));
		}

		// check docType defined or *
		if (!$docType) {
			throw new \App\Config\MessageException('The cashing document type is mandatory.');
		}
		if (!\App\Config\PaymentDocuments::getInstance()->exists($docType) and $docType != '*') {
			throw new \App\Config\MessageException(sprintf('The document type (%s) is incorrect or not defined', $docType));
		}

		// id office
		if (!$idOffice) {
			throw new \App\Config\MessageException('The office is mandatory.');
		}

		if ($idOffice != "*" && !\Entity\Office::select($idOffice)->recordExists()) {
			throw new \App\Config\MessageException(sprintf('The office id (%s) is incorrect or not defined', $idOffice));
		}

		// check bankAccount defined or *
		if (!$idBankAccount) {
			throw new \App\Config\MessageException('The cashing bank account is mandatory.');
		}

		if ($idBankAccount != '*' && !\Entity\AgencyBankAccount::select($idBankAccount)->recordExists()) {
			throw new \App\Config\MessageException(sprintf('The bank account id (%s) is incorrect or not defined', $idBankAccount));
		}

		// check currency defined or *
		if (!$currency) {
			throw new \App\Config\MessageException('The cashing currency is mandatory.');
		}
		if (!\App\Config\Currencies::getInstance()->check($currency) and $currency != '*') {
			throw new \App\Config\MessageException(sprintf('The currency (%s) is incorrect or not defined', $currency));
		}

	}

}