<?php
namespace App\ExportData\ExportFile;

class ClientInvoiceCashing extends GeneralAbstract
{
	/**
	 * General description of the entity.
	 * @var String
	 */
	protected $entityType = 'cashing';

	/**
	 * The XML root tag name.
	 * @var String
	 */
	protected $rootTag = 'cashing';

	/**
	 * The document type of invoice cashing
	 * @var String
	 */
	protected $documentType = NULL;

	/**
	 * The allowed operation types - they are checked in the constructor.
	 * @var array
	 */
	protected $allowedOperationTypes = ['issue', 'void', 'confirm', 'unconfirm'];

	/**
	 * Checks the input for the current class.
	 * @param Int $idEntity
	 * @param String $operation
	 * @throws \Exception - if there's anything wrong with the input
	*/
	public function __construct($idEntity, $operation, $documentType=NULL)
	{
		parent::__construct($idEntity, $operation);

		if ($this->operation == 'issue' and !$documentType) {
			throw new \Exception("The document type `{$documentType}` is not valid for entity type `{$this->entityType}`, operation `{$this->operation}`.");
		}

		$this->documentType = $documentType;
	}

	/**
	 * {@inheritDoc}
	 * @see \App\ExportData\ExportFile\GeneralAbstract::checkIfInactiveEntity()
	 */
	protected function checkIfInactiveEntity()
	{
		$invoiceCashingEntity = \Entity\InvoiceCashing::select($this->idEntity);
		$cashingConfig = \App\Config\ExportData_ActiveEntities::getInstance()->get("cashing|".$invoiceCashingEntity->docTypeCode);

		$operation = "";

		if ($this->operation == "issue" or $this->operation == "void") {
			$operation = "issue";
		}
		elseif ($this->operation == "confirm" or $this->operation == "unconfirm") {
			$operation = "block";
		}

		return !$cashingConfig[$operation];
	}

	/**
	 *
	 * {@inheritDoc}
	 * @see \App\ExportData\ExportFile\GeneralAbstract::populateXml()
	 */
	protected function populateXml(\SimpleXMLElement $xml, \App\MessagesCollector $msgs)
	{
		global $CFG;

		// GET CASHING DETAILS --------------------------------------------------------------------
		$cashingDetails = \Entity\InvoiceCashing::select($this->idEntity);
		if (!$cashingDetails->recordExists()) {
			$msgs->addError("The invoice cashing id `{$this->idEntity}` is not valid.");
		}

		// set file name
		$this->fileName = 'cashing_'.$cashingDetails->docTypeCode;

		// GET INVOICE DETAILS --------------------------------------------------------------------
		$invoiceDetails = $cashingDetails->invoice;

		// GET IMPORTED DOCUMENT DETAILS //////////////////////////////////////////////////////////
		if ($cashingDetails->idImportedDoc) {
			$importedDocument = $cashingDetails->importedDocument;
			$importingSystem = 	\Entity\ImportedDocumentsSystem::select($importedDocument->idExternalSystem);
		}

		// INVOICE CLIENT DETAILS /////////////////////////////////////////////////////////////////

		// GET CORPORATE DETAILS ------------------------------------------------------------------
		if ($invoiceDetails->idCorporate) {
			$invDetIdClient = 		$invoiceDetails->idCorporate;
			$invDetClientType= 		"legalEntity";
			// corporate details
			$corporateDetails = 	$invoiceDetails->corporate;
			// corporate main office
			$corporateIdMainOffice = 	$corporateDetails->idMainOffice;
			$corporateMainOffice = 		\Entity\CorporateOffice::select($corporateIdMainOffice);
			// corporate selected office
			$corporateSelectedOffice = \Entity\CorporateOffice::select($invoiceDetails->idCorporateOffice);
		}
		// GET INDIVIDUAL DETAILS -----------------------------------------------------------------
		else {
			$invDetIdClient = 		$invoiceDetails->idCustomer;
			$invDetClientType =		"individual";
			// customer details
			$customerDetails =		$invoiceDetails->customer;
		}

		// DETERMINING THE ID OFFICE (for export configs) /////////////////////////////////////////
		$thisIdOffice = 0;
		if ($this->operation == "issue" or $this->operation == "void") {
			$thisIdOffice = $cashingDetails->issueUser->idOffice;
		}
		if ($this->operation == "confirm" or $this->operation == "unconfirm") {
			$thisIdOffice = $cashingDetails->blockUser->idOffice;
		}
		if (!$thisIdOffice) {
			$thisIdOffice = CURRENT_ID_OFFICE;
		}

		// EXPORT CONFIGS /////////////////////////////////////////////////////////////////////////
		$docComponents = [
			'docType' => $cashingDetails->docTypeCode,
			'idOffice'=>$thisIdOffice, // TODO: not ok - should be responsible office
			'idBankAccount'=>$cashingDetails->idBankAccount,
			'clientType'=>$invDetClientType,
			'currency'=>$cashingDetails->currency
		];
		$exportConfigs = \App\Config\ExportData_Fields_Cashing::getInstance()->getActiveFieldsValues($docComponents);

		// add main attributes
		$xml['operation'] = 	$this->operation;

		if ($this->operation == 'issue') {
			$xml['issueDocType'] = $this->documentType;
		}

		$xml['id'] = 			$this->idEntity;
		$xml['exportTime'] = 	date("Y-m-d\TH:i:s");

		// IMPORTED DOCUMENT DETAILS //////////////////////////////////////////////////////////////
		if ($cashingDetails->idImportedDoc) {
			$xml->imported = '';
			$xml->imported['idDocTina'] = 	$cashingDetails->idImportedDoc;
			$xml->imported['idDocSystem'] =	htmlUnclean($importedDocument->idSystem);
			$xml->imported->system =		'';
			$xml->imported->system['id'] =	$importedDocument->idExternalSystem;
			if ($importingSystem->code) {
				$xml->imported->system['code'] = htmlUnclean($importingSystem->code);
			}
			if ($importingSystem->name) {
				$xml->imported->system['name'] = htmlUnclean($importingSystem->name);
			}
		}

		// CASHING DETAILS ////////////////////////////////////////////////////////////////////////
		$xml->docNumber =	 htmlUnclean($cashingDetails->docNumber);
		$xml->docDate = 	$cashingDetails->docDate;
		if ($cashingDetails->idCashingSeries) {
			$xml->cashingSeries = 		htmlUnclean($cashingDetails->cashingSeries->code);
			$xml->cashingSeries['id'] =	$cashingDetails->idCashingSeries;
		}

		$xml->docType =			$cashingDetails->docTypeCode;
		$xml->value = 			$cashingDetails->value;
		$xml->currency =		htmlUnclean($cashingDetails->currency);
		$xml->currency['exchangeRate'] = \App\CurrencyExchange\Rates::getInstance($cashingDetails->docDate)->convert(1, $cashingDetails->currency, $CFG['currencies']['defaultCurrency'], null);
		$xml->invoiceCashedValue = $cashingDetails->invoiceCashedValue;
		if ($cashingDetails->explanations) {
			$xml->explanations = htmlUnclean($cashingDetails->explanations);
		}
		if ($cashingDetails->comments) {
			$xml->comments = htmlUnclean($cashingDetails->comments);
		}
		if ($cashingDetails->remarks) {
			$xmlRemarks = $xml->addChild('remarks');
			$this->attachXmlRemarks($xmlRemarks, $cashingDetails->remarks, $cashingDetails->processedRemarks);
		}

		// bank account details
		if ($cashingDetails->idBankAccount) {
			$bankAccountDetails = 		$cashingDetails->bankAccount;
			$xml->bankAccount['id'] =	htmlUnclean($cashingDetails->idBankAccount);
			if ($bankAccountDetails->account)
				$xml->bankAccount->account = htmlUnclean($bankAccountDetails->account);
			if ($bankAccountDetails->idBank) {
				$xml->bankAccount->bankName = 		htmlUnclean($bankAccountDetails->bank->name);
				$xml->bankAccount->bankName['id'] =	$bankAccountDetails->idBank;
			}
			if ($bankAccountDetails->idBankOffice) {
				$xml->bankAccount->bankOfficeName = 		htmlUnclean($bankAccountDetails->bankOffice->name);
				$xml->bankAccount->bankOfficeName['id'] =	$bankAccountDetails->idBankOffice;
			}
		}

		// ADD USER ///////////////////////////////////////////////////////////////////////////////
		$xml->addUser='';
		$xml->addUser['id'] = 				$cashingDetails->idAddUser;
		$xml->addUser->lastName = 			htmlUnclean($cashingDetails->addUser->lastName);
		$xml->addUser->firstName = 			htmlUnclean($cashingDetails->addUser->firstName);
		$xml->addUser->office = 			htmlUnclean($cashingDetails->addUser->office->name);
		$xml->addUser->office['id'] = 		$cashingDetails->addUser->idOffice;
		$xml->addUser->department = 		htmlUnclean($cashingDetails->addUser->department->name);
		$xml->addUser->department['id'] = 	$cashingDetails->addUser->idDepartment;
		$xml->addTime = 					\Engine\DateTime::createFromTimestamp($cashingDetails->addTime)->format("Y-m-d\TH:i:s");

		// ISSUE USER /////////////////////////////////////////////////////////////////////////////
		if ($cashingDetails->idIssueUser) {
			$xml->issueUser = 		'';
			$xml->issueUser['id'] =				$cashingDetails->idIssueUser;
			$xml->issueUser->lastName =			htmlUnclean($cashingDetails->issueUser->lastName);
			$xml->issueUser->firstName =		htmlUnclean($cashingDetails->issueUser->firstName);
			$xml->issueUser->office = 			htmlUnclean($cashingDetails->issueUser->office->name);
			$xml->issueUser->office['id'] = 	$cashingDetails->issueUser->idOffice;
			$xml->issueUser->department = 		htmlUnclean($cashingDetails->issueUser->department->name);
			$xml->issueUser->department['id'] = $cashingDetails->issueUser->idDepartment;
		}
		if ($cashingDetails->issueTime) {
			$xml->issueTime = \Engine\DateTime::createFromTimestamp($cashingDetails->issueTime)->format("Y-m-d\TH:i:s");
		}

		// BLOCK USER /////////////////////////////////////////////////////////////////////////////
		if ($cashingDetails->idBlockUser) {
			$xml->blockUser='';
			$xml->blockUser['id'] = 			$cashingDetails->idBlockUser;
			$xml->blockUser->lastName = 		htmlUnclean($cashingDetails->blockUser->lastName);
			$xml->blockUser->firstName = 		htmlUnclean($cashingDetails->blockUser->firstName);
			$xml->blockUser->office = 			htmlUnclean($cashingDetails->blockUser->office->name);
			$xml->blockUser->office['id'] = 	$cashingDetails->blockUser->idOffice;
			$xml->blockUser->department = 		htmlUnclean($cashingDetails->blockUser->department->name);
			$xml->blockUser->department['id'] = $cashingDetails->blockUser->idDepartment;
		}
		if ($cashingDetails->blockTime) {
			$xml->blockTime = \Engine\DateTime::createFromTimestamp($cashingDetails->blockTime)->format("Y-m-d\TH:i:s");
		}

		// VOID USER //////////////////////////////////////////////////////////////////////////////
		if ($cashingDetails->idVoidUser) {
			$xml->voidUser='';
			$xml->voidUser['id'] = 				$cashingDetails->idVoidUser;
			$xml->voidUser->lastName = 			htmlUnclean($cashingDetails->voidUser->lastName);
			$xml->voidUser->firstName = 		htmlUnclean($cashingDetails->voidUser->firstName);
			$xml->voidUser->office = 			htmlUnclean($cashingDetails->voidUser->office->name);
			$xml->voidUser->office['id'] = 		$cashingDetails->voidUser->idOffice;
			$xml->voidUser->department = 		htmlUnclean($cashingDetails->voidUser->department->name);
			$xml->voidUser->department['id'] =	$cashingDetails->voidUser->idDepartment;
		}
		if ($cashingDetails->voidTime) {
			$xml->voidTime = \Engine\DateTime::createFromTimestamp($cashingDetails->voidTime)->format("Y-m-d\TH:i:s");
		}
		if ($cashingDetails->voidReason) {
			$xml->voidReason = $cashingDetails->voidReason;
		}

		// RESPONSIBLE USER ///////////////////////////////////////////////////////////////////////
		$xml->responsibleUser='';
		$xml->responsibleUser['id'] = 				$cashingDetails->idUser;
		$xml->responsibleUser->lastName = 			htmlUnclean($cashingDetails->user->lastName);
		$xml->responsibleUser->firstName =			htmlUnclean($cashingDetails->user->firstName);
		$xml->responsibleUser->office = 			htmlUnclean($cashingDetails->office->name);
		$xml->responsibleUser->office['id'] = 		$cashingDetails->idOffice;
		$xml->responsibleUser->department = 		htmlUnclean($cashingDetails->user->department->name);
		$xml->responsibleUser->department['id'] = 	$cashingDetails->user->idDepartment;
		$xml->responsibleUser->department['code'] = htmlUnclean($cashingDetails->user->department->code);


		// INVOICE DETAILS ////////////////////////////////////////////////////////////////////////
		$xml->invoiceDetails='';
		$xml->invoiceDetails['id'] = 				$cashingDetails->idInvoice;
		$xml->invoiceDetails->invoiceNumber = 		$invoiceDetails->invoiceNumber;
		$xml->invoiceDetails->invoiceDate = 		$invoiceDetails->invoiceDate;
		$xml->invoiceDetails->invoiceTotalValue = 	$invoiceDetails->printTotal;
		$xml->invoiceDetails->invoiceCurrency = 	htmlUnclean($invoiceDetails->currency);

		// CLIENT DETAILS /////////////////////////////////////////////////////////////////////////
		$xml->invoiceDetails->client['type'] = 	$invDetClientType;
		$xml->invoiceDetails->client['id'] = 	$invDetIdClient;

		// CORPORATE CLIENT ///////////////////////////////////////////////////////////////////////
		if ($invoiceDetails->idCorporate) {

			$xml->invoiceDetails->client->corporateDetails = '';
			$xmlCorp = $xml->invoiceDetails->client->corporateDetails;

			// CORPORATE DETAILS --------------------------------------------------------------

			// id real corporate
			if ($corporateDetails->idRealCorporate) {
				$xml->invoiceDetails->client['idRealClient'] = $corporateDetails->idRealCorporate;
			}

			// company type
			if ($corporateDetails->type) {
				$xmlCorp->type = $corporateDetails->type;
			}
			// alias
			if ($corporateDetails->alias) {
				$xmlCorp->alias = htmlUnclean($corporateDetails->alias);
			}
			// company
			$xmlCorp->company = htmlUnclean($corporateDetails->company);
			if ($corporateDetails->companyPrefix) {
				$xmlCorp->company['prefix'] = htmlUnclean($corporateDetails->companyPrefix);
			}
			if ($corporateDetails->companySuffix) {
				$xmlCorp->company['suffix'] = htmlUnclean($corporateDetails->companySuffix);
			}
			// trust
			if ($corporateDetails->idTrust) {
				$xmlCorp->trust = 			htmlUnclean($corporateDetails->trust->name);
				$xmlCorp->trust['id'] = 	$corporateDetails->idTrust;
			}
			// fiscalCode
			if ($corporateDetails->fiscalCode) {
				$xmlCorp->fiscalCode = htmlUnclean($corporateDetails->fiscalCode);
			}

			// vatCertificateNumber
			if ($corporateDetails->vatCertificateNumber) {
				$xmlCorp->vatCertificateNumber = htmlUnclean($corporateDetails->vatCertificateNumber);
			}
			// regNo
			if ($corporateDetails->regNo) {
				$xmlCorp->regNo = htmlUnclean($corporateDetails->regNo);
			}


			// CORPORATE MAIN OFFICE --------------------------------------------------------------

			// corporate offices
			$xmlCorp->offices->office[0] = '';
			$xmlCorpOff = $xmlCorp->offices->office[0];

			$xmlCorpOff['id'] = 	$corporateMainOffice->getId();
			$xmlCorpOff['type'] = 	"central";
			$xmlCorpOff->name = 	htmlUnclean($corporateMainOffice->name);
			if ($corporateMainOffice->countryCode) {
				$xmlCorpOff->country = 			htmlUnclean($corporateMainOffice->country->name);
				$xmlCorpOff->country['code'] = 	trim($corporateMainOffice->countryCode);
			}
			if ($corporateMainOffice->cityId) {
				$xmlCorpOff->city = 			htmlUnclean($corporateMainOffice->city->name);
				$xmlCorpOff->city['id'] = 		$corporateMainOffice->cityId;
				$xmlCorpOff->city['district'] = htmlUnclean($corporateMainOffice->city->district);
			}
			if ($corporateMainOffice->address) {
				$xmlCorpOff->address = 	htmlUnclean($corporateMainOffice->address);
			}
			if ($corporateMainOffice->zipCode) {
				$xmlCorpOff->zipCode = htmlUnclean($corporateMainOffice->zipCode);
			}

			// bank details
			$idBankAccountOptium = \Entity\CorporateOffice::select($corporateMainOffice->getId())->getOptimumBankAccountByCurrency($cashingDetails->currency);
			$corporateOfficeBankAccount = $corporateMainOffice->bankAccounts[$idBankAccountOptium];

			// bank name
			if ($corporateOfficeBankAccount['idBank']) {
				$xmlCorpOff->bankName = 		htmlUnclean(\Entity\Bank::select($corporateOfficeBankAccount['idBank'])->name);
				$xmlCorpOff->bankName['id'] = 	$corporateOfficeBankAccount['idBank'];
			}

			// bank office
			if ($corporateOfficeBankAccount['idBankOffice']) {
				$xmlCorpOff->bankOfficeName = 		htmlUnclean(\Entity\BankOffice::select($corporateOfficeBankAccount['idBankOffice'])->name);
				$xmlCorpOff->bankOfficeName['id'] = $corporateOfficeBankAccount['idBankOffice'];
			}

			// bank account
			if ($corporateOfficeBankAccount['account']) {
				$xmlCorpOff->bankAccount = 		htmlUnclean($corporateOfficeBankAccount['account']);
				if ($corporateOfficeBankAccount['currency']) {
					$xmlCorpOff->bankAccount['currency'] = htmlUnclean($corporateOfficeBankAccount['currency']);
				}
			}


			// CORPORATE SELECTED OFFICE ----------------------------------------------------------
			$xmlCorp->offices->office[1]='';
			$xmlCorpOff=$xmlCorp->offices->office[1];

			$xmlCorpOff['id'] = 	$corporateSelectedOffice->getId();
			$xmlCorpOff['type'] = 	"selected";
			$xmlCorpOff->name = 	htmlUnclean($corporateSelectedOffice->name);
			if ($corporateSelectedOffice->countryCode) {
				$xmlCorpOff->country = 			htmlUnclean($corporateSelectedOffice->country->name);
				$xmlCorpOff->country['code'] = 	trim($corporateSelectedOffice->countryCode);
			}
			if ($corporateSelectedOffice->cityId) {
				$xmlCorpOff->city = 			htmlUnclean($corporateMainOffice->city->name);
				$xmlCorpOff->city['id'] = 		$corporateMainOffice->cityId;
				$xmlCorpOff->city['district'] = htmlUnclean($corporateMainOffice->city->district);
			}
			if ($corporateSelectedOffice->address) {
				$xmlCorpOff->address = htmlUnclean($corporateSelectedOffice->address);
			}
			if ($corporateSelectedOffice->zipCode) {
				$xmlCorpOff->zipCode = htmlUnclean($corporateSelectedOffice->zipCode);
			}

			// bank details
			$idBankAccountOptium = \Entity\CorporateOffice::select($corporateSelectedOffice->getId())->getOptimumBankAccountByCurrency($cashingDetails->currency);
			$corporateOfficeBankAccount = $corporateSelectedOffice->bankAccounts[$idBankAccountOptium];

			// bank name
			if ($corporateOfficeBankAccount['idBank']) {
				$xmlCorpOff->bankName = 		htmlUnclean(\Entity\Bank::select($corporateOfficeBankAccount['idBank'])->name);
				$xmlCorpOff->bankName['id'] = 	$corporateOfficeBankAccount['idBank'];
			}

			// bank office
			if ($corporateOfficeBankAccount['idBankOffice']) {
				$xmlCorpOff->bankOfficeName = 		htmlUnclean(\Entity\BankOffice::select($corporateOfficeBankAccount['idBankOffice'])->name);
				$xmlCorpOff->bankOfficeName['id'] = $corporateOfficeBankAccount['idBankOffice'];
			}

			// bank account
			if ($corporateOfficeBankAccount['account']) {
				$xmlCorpOff->bankAccount = 		htmlUnclean($corporateOfficeBankAccount['account']);
				if ($corporateOfficeBankAccount['currency']) {
					$xmlCorpOff->bankAccount['currency'] = htmlUnclean($corporateOfficeBankAccount['currency']);
				}
			}
		}
		// INDIVIDUAL CLIENT //////////////////////////////////////////////////////////////////////

		else {

			$xml->invoiceDetails->client->individualDetails='';
			$xmlCust=$xml->invoiceDetails->client->individualDetails;
			// general customer details
			if ($customerDetails->idRealCustomer) {
				$xml->invoiceDetails->client['idRealClient'] = $customerDetails->idRealCustomer;
			}
			$xmlCust->firstName = 	htmlUnclean($customerDetails->firstName);
			$xmlCust->lastName = 	htmlUnclean($customerDetails->lastName);
			if ($customerDetails->PNC) {
				$xmlCust->PNC = htmlUnclean($customerDetails->PNC);
			}
			if ($customerDetails->address) {
				$xmlCust->address = htmlUnclean($customerDetails->address);
			}
			if ($customerDetails->zipCode) {
				$xmlCust->zipCode = htmlUnclean($customerDetails->zipCode);
			}
			if ($customerDetails->countryCode) {
				$xmlCust->country = 		htmlUnclean($customerDetails->country->name);
				$xmlCust->country['code'] = htmlUnclean($customerDetails->countryCode);
			}
			if ($customerDetails->cityId) {
				$xmlCust->city = 				htmlUnclean($customerDetails->city->name);
				$xmlCust->city['id'] = 			$customerDetails->cityId;
				$xmlCust->city['district'] = 	htmlUnclean($customerDetails->city->district);
			}
			if ($customerDetails->idBank) {
				$xmlCust->bankName = 		htmlUnclean($customerDetails->bank->name);
				$xmlCust->bankName['id'] = 	$customerDetails->idBank;
			}
			if ($customerDetails->idBankOffice) {
				$xmlCust->bankOfficeName = 			htmlUnclean($customerDetails->bankOffice->name);
				$xmlCust->bankOfficeName['id'] = 	$customerDetails->idBankOffice;
			}
			if ($customerDetails->bankAccount) {
				$xmlCust->bankAccount = htmlUnclean($customerDetails->bankAccount);
			}
		}

		// invoice responsible
		$xml->invoiceDetails->responsibleUser='';
		$xml->invoiceDetails->responsibleUser['id'] = 				$invoiceDetails->idUser;
		$xml->invoiceDetails->responsibleUser->lastName = 			htmlUnclean($invoiceDetails->user->lastName);
		$xml->invoiceDetails->responsibleUser->firstName = 			htmlUnclean($invoiceDetails->user->firstName);
		$xml->invoiceDetails->responsibleUser->office = 			htmlUnclean($invoiceDetails->office->name);
		$xml->invoiceDetails->responsibleUser->office['id'] =		$invoiceDetails->idOffice;
		$xml->invoiceDetails->responsibleUser->department = 		htmlUnclean($invoiceDetails->user->department->name);
		$xml->invoiceDetails->responsibleUser->department['id'] = 	$invoiceDetails->user->idDepartment;

		// generated documents
		if ($cashingDetails->documentsList) {
			$documentsListXml = $xml->addChild('generatedDocuments');
			$this->attachXmlGeneratedDocs($documentsListXml, $cashingDetails->documentsList);
		}

		// export configs
		if (is_array($exportConfigs)) {
			$xml->exportConfigs = '';
			foreach($exportConfigs as $expCfgName=>$expCfgVal) {
				if (!$expCfgName) {
					$expCfgName = "_DEFAULT_";
				}
				$xml->exportConfigs->$expCfgName = htmlUnclean($expCfgVal);
			}
		}

	}

}
