<?php

namespace App\ReportsData\Populate\Entity;

class ClientInvoice extends \App\ReportsData\Populate\GeneralAbstract
{

	/**
	 * The client invoice rows table.
	 * @var string
	 */
	private $dbTableName_clientInvoiceRows;

	/**
	 * Returns the table name that will store the current entity queue.
	 * @return string
	 */
	protected function getDbTableName()
	{
		global $DBTRd_clientInvoices, $DBTRd_clientInvoiceRows;
		$this->dbTableName_clientInvoiceRows = $DBTRd_clientInvoiceRows;
		return $DBTRd_clientInvoices;
	}


	/**
	 * {@inheritDoc}
	 * @see \App\ReportsData\Populate\GeneralAbstract::getEntityFields()
	 */
	protected function getEntityFields()
	{

		// get current entity details
		$entity = \Entity\Invoice::select($this->id);

		// for non existing rows - return null
		if (!$entity->recordExists()) {
			return null;
		}
		// if the invoice is cumulated, skip this step - but delete it afterwards
		if ($entity->cumulatedOnInvoiceId) {
			return null;
		}

		// get default currency rate
		$defaultCurrency = \App\CurrencyExchange\Date::getInstance($entity->invoiceDate)->getMarketCurrency();
		$workCurrency = \App\Config\Currencies::getInstance()->getWorkCurrency();
		$currencyRate = \App\CurrencyExchange\Rates::getInstance($entity->invoiceDate)->convert(1, $entity->currency, $defaultCurrency, null);
		$workCurrencyRate = \App\CurrencyExchange\Rates::getInstance($entity->invoiceDate)->convert(1, $workCurrency, $defaultCurrency, null);

		// populate the entity details
		$return = [
 			'id'					=> $this->id,
			'idOrders'				=> json_encode($entity->idReservationsList),
			'idAutoProcessRule'		=> $entity->idAutoProcessRule,
			'idInvoiceSeries'		=> $entity->idInvoiceSeries,
			'invoiceNumber'			=> $entity->invoiceNumber,
			'invoiceDate'			=> $entity->invoiceDate,
			'idCorporate'			=> $entity->idCorporate,
			'idCorporateOffice'		=> $entity->idCorporateOffice,
			'idCustomer'			=> $entity->idCustomer,
			'invoiceValue'			=> $entity->printValue,
			'invoiceVat'			=> $entity->printVat,
			'invoiceTotal'			=> $entity->printTotal,
			'currency'				=> $entity->currency,
			'currencyRate'			=> $currencyRate,
			'workCurrencyRate'		=> $workCurrencyRate,
			'cashedTotal'			=> $entity->cashedTotal,
			'cashedStatus'			=> $entity->cashedStatus,
			'lastCashingDate'		=> $entity->lastCashingDocumentDate?:null,
			'dueDate'				=> $entity->dueDate,
			'fulfillmentDate'		=> $entity->fulfillmentDate,
			'comments'				=> $entity->comments,
			'formOfPayment'			=> $entity->formOfPayment,
			'idBankAccount'			=> $entity->idBankAccount,
			'temporary'				=> $entity->temporary,
			'cumulativeInvoice'		=> $entity->cumulativeInvoice,
			'roundTotal'			=> $entity->roundTotal,
 			'remarks'				=> $entity->remarks,
 			'processedRemarks'		=> ($entity->processedRemarks ? json_encode($entity->processedRemarks) : ''),
			'extraInfo'				=> ($entity->extraInfo ? json_encode($entity->extraInfo) : ''),
			'genDocsAssoc'			=> ($entity->generatedDocumentsAssoc ? json_encode($entity->generatedDocumentsAssoc) : ''),
			'documentsList'			=> ($entity->documentsList ? json_encode($entity->documentsList) : ''),
			'idUser'				=> $entity->idUser,
			'idOffice'				=> $entity->idOffice,
			'idIssueUser'			=> $entity->idIssueUser,
			'issueTime'				=> ( $entity->issueTime ? \Engine\DateTime::createFromTimestamp($entity->issueTime)->formatDatetimeIso() : null ),
			'voidReason'			=> $entity->voidReason,
			'idVoidUser'			=> $entity->idVoidUser,
			'voidTime'				=> ( $entity->voidTime ? \Engine\DateTime::createFromTimestamp($entity->voidTime)->formatDatetimeIso() : null ),
			'addTime'				=> \Engine\DateTime::createFromTimestamp($entity->addTime)->formatDatetimeIso(),
			'idAddUser'				=> $entity->idAddUser,
			'lastUpdateTime'		=> ( $entity->lastUpdateTime ? \Engine\DateTime::createFromTimestamp($entity->lastUpdateTime)->formatDatetimeIso() : null ),
			'idUpdateUser'			=> $entity->idUpdateUser,
			'updatesCount'			=> $entity->updatesCount,
		];

		// ADD POPULATING REFERENCES --------------------------------------------------------------
		foreach($entity->cumulatedInvoicesIdsList as $idInvoice) {
			$this->addPopulatingReference('ClientInvoice', $idInvoice);
		}

		return $return;
	}


	/**
	 * Add invoice rows as well.
	 * {@inheritDoc}
	 * @see \App\ReportsData\Populate\GeneralAbstract::populate()
	 */
	public function populate() :void
	{

		// insert the invoice
		parent::populate();

		$entity = \Entity\Invoice::select($this->id);

		if (!$entity->recordExists()) {
			return ;
		}

		// if the invoice is cumulated - delete the whole invoice and rows
		if ($entity->cumulatedOnInvoiceId) {
			$this->dbExecuteDelete($this->dbTableName_clientInvoiceRows, 'idInvoice', $this->id);
			$this->dbExecuteDelete($this->dbTableName, 'id', $this->id);
			return ;
		}

		// GET INVOICE ROWS DETAILS ///////////////////////////////////////////////////////////////
		$invoiceRows = $entity->rowsList;


		// DELETE PREVIOUS INVOICE ROWS ///////////////////////////////////////////////////////////
		$this->dbExecuteDelete($this->dbTableName_clientInvoiceRows, 'idInvoice', $this->id);


		// ADD NEW INVOICE ROWS ///////////////////////////////////////////////////////////////////
		$servicesList = [];
		if ($invoiceRows) {
			foreach($invoiceRows as $idRow=>$invoiceRow) {

				$invoiceRowEnt = \Entity\InvoiceRow::select($idRow);
				$cumulatesInvoiceRowEnt = \Entity\InvoiceRow::select($invoiceRowEnt->cumulatesInvoiceRowId);

				if ($invoiceRowEnt->serviceCode) {
					$vatsCfg = \App\Config\Services_Calculations_InvoiceVat::getInstance()->getCalculationDetails($invoiceRowEnt->serviceCode, $invoiceRowEnt->location, $invoiceRowEnt->calculationType);
				} else {
					$vatsCfg = []; // skip global penalty (if there are any)
				}

				$servicesList[$invoiceRowEnt->idReservationService] = true;

				$fields = [
					'id'					=> $idRow,
					'idInvoice'				=> $this->id,
					'hiddenOnRowId'			=> $invoiceRowEnt->hiddenOnRowId,
					'idService'				=> $invoiceRowEnt->idReservationService,
					'serviceCode'			=> $invoiceRowEnt->serviceCode,
					'location'				=> $invoiceRowEnt->location,
					'calculationType'		=> $invoiceRowEnt->calculationType,
					'rowType'				=> $invoiceRowEnt->rowType,
					'rowIndex'				=> $invoiceRowEnt->rowIndex,
					'reversedRow'			=> $invoiceRowEnt->reversedRow,
					'reversesInvoiceRowId'	=> $invoiceRowEnt->reversesInvoiceRowId,
					'cumulatesIdInvoiceRow' => (Int)$invoiceRowEnt->cumulatesInvoiceRowId,
					'cumulatesIdInvoice'	=> (Int)$cumulatesInvoiceRowEnt->idInvoice,
					'refund'				=> $invoiceRowEnt->refund?1:0,
					'finalizeAdvanceMode'	=> $invoiceRowEnt->finalizeAdvanceMode,
					'description'			=> $invoiceRowEnt->description,
					'measureUnit'			=> $invoiceRowEnt->measureUnit,
					'quantity'				=> $invoiceRowEnt->quantity,
					'rowUnitValue'			=> $invoiceRowEnt->unitPricePrintValue,
					'rowValue'				=> $invoiceRowEnt->pricePrintValue,
					'rowVat'				=> $invoiceRowEnt->vatPrintValue,
					'rowOfferEstProfit'		=> $invoiceRowEnt->estProfitTotal,
					'vatPercent'			=> $invoiceRowEnt->vatPercent,
					'vatText'				=> $invoiceRowEnt->vatText,
					'vatRemarks'			=> (String)$vatsCfg[$invoiceRowEnt->rowType]['vatRemark'],
					'currencyType'			=> $invoiceRowEnt->currencyType,
					'currencyDate'			=> $invoiceRowEnt->currencyDate,
					'extraInfo'				=> ($invoiceRowEnt->extraInfo ? json_encode($invoiceRowEnt->extraInfo) : ''),
				];

				$this->dbExecuteInsert($this->dbTableName_clientInvoiceRows, $fields);

			}
		}

		// ADD POPULATING REFERENCES --------------------------------------------------------------
		foreach($servicesList as $idService=>$nada) {
			$this->addPopulatingReference('Service', $idService);
		}

	}

}
