<?php

namespace App\AutoProcessRules;

class ImportedServiceCancel_Definition extends DefinitionAbstract
{

	/**
	 * List with all available filters
	 * @var array
	 */
	protected $filtersConfig = [
		'corporates',
		'corporateGroups',
		'customers',
		'serviceCodes',
		'orderExternalSystems',
		'orderDate',
		'cancelDate',
		'serviceStatus',
	];

	/**
	 * List with filters for cache
	 * @var array
	 */
	protected $filtersCacheConfig = [
		'serviceCodes' =>				'serviceCode',
		'orderExternalSystems' =>		'orderExternalSystem',
		'corporates' =>					'corporate',
		'customers' =>					'customer',
	];

	/**
	 * List with all available fields
	 * @var array
	 */
	protected $fieldsConfig = [
		'serviceCancelReason', 'serviceCancelDetails',
		'dueDays', 'idInvoiceSeries', 'idInvoiceUser', 'temporaryInvoice',
		'formOfPayment', 'idAgencyBankAccount', 'invoiceRemarks'
	];

	/**
	 * List with fields for cached
	 * Value of array represents type of variable
	 * @var array
	 */
	protected $fieldsCacheConfig = [
		'serviceCancelReason' => 'serviceCancelReason',
	];

	/**
	 * (non-PHPdoc)
	 * @see \App\AutoProcessRules\DefinitionAbstract::checkFields()
	 */
	protected function checkFields(\App\MessagesCollector $msgs)
	{

		// load service cancel reasons
		\Entity\Service::loadCFG();
		$CFG = \Engine\Loader_Cfg::getInstance()->getGlobal();

		// check service cancel reason
		if (!$this->fields['serviceCancelReason']) {
			$msgs->addWarning('Service cancel reason not set.');
		} elseif ( !in_array($this->fields['serviceCancelReason'], $CFG['globalEntity']['::Service']['_special']['serviceCancelReasons']) ) {
			$msgs->addWarning('Invalid service cancel reason.');
		}

		// check the dueDays
		if (strlen($this->fields['dueDays']) and (!is_numeric($this->fields['dueDays']) or $this->fields['dueDays']<0)) {
			$msgs->addWarning('The due days is not valid - it should be a positive integer.');
		}

		// id invoice series
		if ($this->fields['idInvoiceSeries']) {
			$ser = \Entity\DocumentSeries::select($this->fields['idInvoiceSeries']);
			if (!$ser->recordExists() or $ser->deleted) {
				$msgs->addWarning('Invalid invoice series.');
			}
		}

		// id invoice user
		if (!$this->fields['idInvoiceUser']) {
			$msgs->addWarning('No invoice responsible user selected.');
		} else {
			$user = \Entity\User::select($this->fields['idInvoiceUser']);
			if (!$user->recordExists() or $user->deleted) {
				$msgs->addWarning('Invalid responsible user selected.');
			}
		}

		// check form of payment
		if ($this->fields['formOfPayment'] and !\App\Config\FormsOfPayment::getInstance()->check($this->fields['formOfPayment'])) {
			$msgs->addWarning('Invalid form of payment.');
		}

		// check agency bank account
		if ($this->fields['idAgencyBankAccount']) {
			$abaEnt = \Entity\AgencyBankAccount::select($this->fields['idAgencyBankAccount']);
			if (!$abaEnt->recordExists() or $abaEnt->deleted) {
				$msgs->addWarning('Invalid agency bank account.');
			}
		}

	}


	/**
	 * (non-PHPdoc)
	 * @see \App\AutoProcessRules\DefinitionAbstract::checkFilters()
	 */
	protected function checkFilters(\App\MessagesCollector $msgs)
	{

		// check service codes
		if ($this->filters['serviceCodes']) {
			if (!is_array($this->filters['serviceCodes']) ) {
				$msgs->addError('The service codes must be set as a list.');
			} else {
				foreach ($this->filters['serviceCodes'] as $sc) {
					if (!\App\Config\Services_Basic::getInstance()->checkService($sc)) {
						$msgs->addError(sprintf('Invalid service code - %s.', $sc));
					}
				}
			}
		}

		// check orderExternalSystems
		if (!$this->filters['orderExternalSystems']) {
			$msgs->addWarning("You must select at least one external system");
		}
		else {
			if (!is_array($this->filters['orderExternalSystems']) ) {
				$msgs->addError('The external systems must be set as a list.');
			}
			else {
				foreach ($this->filters['orderExternalSystems'] as $idSys) {
					if ($idSys) {
						$sysEnt = \Entity\ExtResSystem::select($idSys);
						if (!$sysEnt->recordExists() or $sysEnt->deleted) {
							$msgs->addError(sprintf('Invalid external system id - %s.', $idSys));
						}
					}
				}
			}
		}

		// check order date
		if ($this->filters['orderDate']) {
			if ( !($this->filters['orderDate'] instanceof \App\Utils\SmartDateInterval) ) {
				$msgs->addError('Invalid smart date interval for order date.');
			} else {
				$msgsTemp = new \App\MessagesCollector();
				$this->filters['orderDate']->check($msgsTemp);
				$msgs->appendMessages($msgsTemp, 'Order date problem: %s');
			}
		}

		// check cancel date
		if ($this->filters['cancelDate']) {
			if (!($this->filters['cancelDate'] instanceof  \App\Utils\SmartDateInterval)) {
				$msgs->addError('Invalid smart date interval for cancel date.');
			}
			else {
				$msgsTemp = new \App\MessagesCollector();
				$this->filters['cancelDate']->check($msgsTemp);
				$msgs->appendMessages($msgsTemp, 'Cancel date problem: %s');
			}
		}

		// check service status (blank means not-invoiced services
		if ($this->filters['serviceStatus'] and $this->filters['serviceStatus']!='invoiced') {
			$msgs->addError('The service status filter is not valid.');
		}

	}

	/**
	 *
	 * {@inheritDoc}
	 * @see \App\AutoProcessRules\DefinitionAbstract::getDescriptionFilters()
	 */
	public function getDescriptionFilters()
	{

		$filters = $this->getFilters();
		$descrFilters = [];

		// FILTERS
		foreach ($this->filtersConfig as $filterName) {
			switch ($filterName) {
				case 'serviceCodes':
					$servCodeArray = [];
					if ($filters['serviceCodes']) {
						foreach ($filters['serviceCodes'] as $code) {
							$servCodeArray[] = \App\Config\Services_Basic::getInstance()->getServiceName($code);
						}
						$descrFilters[] = sprintf("service codes - %s", implode(', ', $servCodeArray));
					}
				break;

				case 'orderExternalSystems':
					if ($filters['orderExternalSystems']) {
						$extSystem = [];
						foreach ($filters['orderExternalSystems'] as $code) {
							if ($code) {
								$extSystem[] = \Entity\ExtResSystem::select($code)->name;
							}
							else {
								$extSystem[] = 'MANUAL';
							}
						}
						$descrFilters[] = sprintf("order external systems - %s", implode(', ', $extSystem));
					}
				break;

				case 'orderDate': case 'cancelDate':
					if ($filters[$filterName] ){
						if ($filters[$filterName]->getReadableDescription()) {
							$descrFilters[] = $filterName.' - '.$filters[$filterName]->getReadableDescription();
						}
					}
				break;

				case 'serviceStatus':
					if (!$filters['serviceStatus']) {
						$descrFilters[] = "service status - not invoiced";
					} elseif ($filters['serviceStatus']=='invoiced') {
						$descrFilters[] = "service status - invoiced";
					}
				break;

				default: {
					$this->populateDescriptionCommonFilters($descrFilters, $filterName);
				}

			}

		}

		return implode('; ',$descrFilters);

	}


	/**
	 *
	 * {@inheritDoc}
	 * @see \App\AutoProcessRules\DefinitionAbstract::getDescriptionFields()
	 */
	public function getDescriptionFields()
	{
		$_LANG = \App\Loader_Lang::getInstance()->getAll();

		$fields = $this->getFields();
		$descrFields = [];

		// FIELDS
		foreach ($this->fieldsConfig as $fieldName) {
			switch ($fieldName) {

				case 'serviceCancelReason':
					$descrFields[] = $fieldName.' - '.$_LANG['serviceCancelReason'][$fields[$fieldName]];
				break;

				case 'serviceCancelDetails': case 'dueDays': case 'invoiceRemarks':
					if ($fields[$fieldName]) {
						$descrFields[] = $fieldName.' - '.$fields[$fieldName];
					}
				break;

				case 'idInvoiceSeries':
					if ($fields['idInvoiceSeries']) {
						$descrFields[] = sprintf("invoice series - %s", \Entity\DocumentSeries::select($fields['idInvoiceSeries'])->code);
					}
				break;

				case 'idInvoiceUser':
					if ($fields['idInvoiceUser']) {
						$descrFields[] = sprintf("invoice user - %s", \Entity\User::select($fields['idInvoiceUser'])->name);
					}
				break;

				case 'formOfPayment':
					if ($fields['formOfPayment']) {
						$descrFields[] = sprintf("form of payment - %s", \App\Config\FormsOfPayment::getInstance()->get($fields['formOfPayment']));
					}
				break;

				case 'temporaryInvoice':
					if ($fields[$fieldName]) {
						$descrFields[] = $fieldName.' - '.$_LANG['yes'];
					}
				break;

				case 'idAgencyBankAccount':
					if ($fields['idAgencyBankAccount']) {
						$descrFields[] = sprintf("agency bank account - %s", \Entity\AgencyBankAccount::select($fields['idAgencyBankAccount'])->account);
					}
				break;

			}
		}

		return implode('; ',$descrFields);

	}

}
