<?php

namespace Modules\RemoteData\EntityManagementWs\Model\Entity\ClientInvoice;

class Insert extends \Modules\RemoteData\EntityManagementWs\Model\Entity\InsertAbstract
{

	protected $forcedRequestAttributes = ['idCorporate', 'idCustomer', 'serviceInvoiceOptions', 'currency', 'invoiceDate', 'dueDate'];


	/**
	 * {@inheritDoc}
	 * @see \Modules\RemoteData\EntityManagementWs\Model\Entity\GeneralAbstract::checkRequestData()
	 */
	protected function checkRequestData() :void
	{

		// high-level client setting
		if (!$this->request->idCorporate and !$this->request->idCustomer) {
			throw new \Modules\RemoteData\EntityManagementWs\Model\RuntimeException( 'You did not set the invoice client - either set `idCorporate`+`idCorporateOffice` or `idCustomer`.', 'InvoiceClientNotSet' );
		}
		if ($this->request->idCorporate and $this->request->idCustomer) {
			throw new \Modules\RemoteData\EntityManagementWs\Model\RuntimeException( 'You cannot set both client types `idCorporate` and `idCustomer`.', 'InvoiceClientBothSet' );
		}

		// serviceInvoiceOptions - is mandatory
		if (!$this->request->serviceInvoiceOptions) {
			throw new \Modules\RemoteData\EntityManagementWs\Model\RuntimeException( 'The `serviceInvoiceOptions` field is not set.', 'ServiceInvoiceOptionsMissing' );
		}

		// check currency
		if ($this->request->currency!='default' and $this->request->currency!='profile') {
			if (!$this->request->currency) {
				throw new \Modules\RemoteData\EntityManagementWs\Model\RuntimeException( 'The invoice currency is not set.', 'InvoiceCurrencyMissing' );
			} elseif (!\App\Config\Currencies::getInstance()->check($this->request->currency)) {
				throw new \Modules\RemoteData\EntityManagementWs\Model\RuntimeException( 'The invoice currency is not valid.', 'InvoiceCurrencyInvalid' );
			}
		}

		// check roundTotal
		if (!isset($this->request->roundTotal)) {
			throw new \Modules\RemoteData\EntityManagementWs\Model\RuntimeException( 'The invoice round total flag is not set.', 'InvoiceRoundTotalMissing' );
		}

	}


	/**
	 * {@inheritDoc}
	 * @see \Modules\RemoteData\EntityManagementWs\Model\Entity\InsertAbstract::initEntityObject()
	 */
	protected function initEntityObject() :\App\Entity\GeneralAbstract
	{
		return \Entity\Invoice::insert();
	}

	/**
	 *
	 * @param \App\Entity\GeneralAbstract $entityObj
	 */
	protected function populateEntityFields(\App\Entity\GeneralAbstract $entityObj)
	{

		if ($this->request->idCorporate) {
			$entityObj->idCorporate = $this->request->idCorporate;
			$entityObj->idCorporateOffice = $this->request->idCorporateOffice;
		} elseif ($this->request->idCustomer) {
			$entityObj->idCustomer = $this->request->idCustomer;
		}

		// service invoice options
		$sios = [];
		$idOrder = 0;
		foreach ($this->request->serviceInvoiceOptions as $sioRq) {

			$sio = [
				'invoiceContent'			=> $sioRq->invoiceContent,
				'idReservationService'		=> $sioRq->idService,
			];
			if ($sioRq->value??null or $sioRq->currency??null) {
				$sio['value']				= $sioRq->value;
				$sio['currency']			= $sioRq->currency;
			}
			if ($sioRq->quantityType??null) {
				$sio['quantityType']		= $sioRq->quantityType;
			}
			if ($sioRq->finalizeAdvanceMode??null) {
				$sio['finalizeAdvanceMode']	= $sioRq->finalizeAdvanceMode;
			}

			// add refund details
			$rfndDet = $sioRq->refundDetails??null;
			if ($rfndDet) {
				$sio['refundDetails'] = [];
				$sio['refundDetails']['supplierTotal']				= $rfndDet->supplierTotal		?? null;
				$sio['refundDetails']['supplierVat']				= $rfndDet->supplierVat			?? null;
				$sio['refundDetails']['supplierCurrency']			= $rfndDet->supplierCurrency	?? null;
				$sio['refundDetails']['commissionTotal']			= $rfndDet->commissionTotal		?? null;
				$sio['refundDetails']['commissionCurrency']			= $rfndDet->commissionCurrency	?? null;
				$sio['refundDetails']['serviceFeeTotal']			= $rfndDet->serviceFeeTotal		?? null;
				$sio['refundDetails']['serviceFeeCurrency']			= $rfndDet->serviceFeeCurrency	?? null;
				$sio['refundDetails']['taxTotal']					= $rfndDet->taxTotal			?? null;
				$sio['refundDetails']['taxVat']						= $rfndDet->taxVat				?? null;
				$sio['refundDetails']['taxCurrency']				= $rfndDet->taxCurrency			?? null;
				$sio['refundDetails']['penaltyTotal']				= $rfndDet->penaltyTotal		?? null;
				$sio['refundDetails']['penaltyCurrency']			= $rfndDet->penaltyCurrency		?? null;
				$sio['refundDetails']['returnServiceFee ']			= $rfndDet->returnServiceFee	?? null;
			}

			$sios[] = $sio;

			if (!$idOrder) {
				$idOrder = \Entity\Service::selectForUpdate($sioRq->idService)->idOrder;
			}

		}
		$entityObj->servicesInvoiceOptions	= $sios;
		$entityObj->idReservation			= $idOrder;

		$entityObj->invoiceDate				= $this->request->invoiceDate;

		// set the currency (from profile/default)
		if ($this->request->currency=='profile' or $this->request->currency=='default') {
			$currencyFromProfile = null;
			if ($this->request->currency=='profile' and $this->request->idCorporate) {
				$currencyFromProfile = \App\EntityPreference\Corporate::getInstance($this->request->idCorporate)->invoiceCurrency;
			}
			if ($currencyFromProfile) {
				$entityObj->currency			= $currencyFromProfile;
			}
			// no profile - get from default
			else {
				$entityObj->currency			= \App\Config\InvoiceCurrency::getInstance()->get('defaultCurrency');
			}
		}
		// manually set the currency
		else {
			$entityObj->currency				= $this->request->currency;
		}


		if ($this->request->dueDate=='default') {
			$entityObj->dueDate				= $entityObj->get_defaultDueDate();
		} elseif ($this->request->dueDate) {
			$entityObj->dueDate				= $this->request->dueDate;
		}

		if ($this->request->fulfillmentDate??null) {
			if ($this->request->fulfillmentDate=='default') {
				$entityObj->fulfillmentDate		= $entityObj->get_defaultFulfillmentDate();
			} elseif ($this->request->fulfillmentDate) {
				$entityObj->fulfillmentDate		= $this->request->fulfillmentDate;
			}
		}

		// bank account
		if ($this->request->bankAccount??null) {
			if ($this->request->bankAccount=='default' or $this->request->bankAccount=='profile') {
				$baFromProfile = null;
				if ($this->request->bankAccount=='profile' and $this->request->idCorporate) {
					$baFromProfile = \App\EntityPreference\Corporate::getInstance($this->request->idCorporate)->agencyBankAccount;
				}
				if ($baFromProfile) {
					$entityObj->idBankAccount	= $baFromProfile;
				}
				// no profile - get from default
				else {
					$entityObj->idBankAccount	= \Entity\AgencyBankAccount::getDefaultId();
				}
			}
			else {
				$entityObj->idBankAccount		= (Int)$this->request->bankAccount;
			}
		}

		// invoice total rounding
		if (\App\Config\InvoiceRounding::getInstance()->isEnabled()) {
			if ($this->request->roundTotal==='default' or $this->request->roundTotal==='profile') { // correctly compare against bool values
				$roundFromProfile = null;
				if ($this->request->roundTotal=='profile' and $this->request->idCorporate) {
					$roundFromProfile = \App\EntityPreference\Corporate::getInstance($this->request->idCorporate)->roundInvoice;
				}
				if (!is_null($roundFromProfile)) {
					$entityObj->roundTotal	= $roundFromProfile;
				}
				// no profile - get from app default
				else {
					$entityObj->roundTotal	= (bool)\App\Config\InvoiceRounding::getInstance()->defaultByCurrency( $entityObj->getField('currency') );
				}
			}
			else {
				$entityObj->roundTotal		= (bool)$this->request->roundTotal;
			}
		}

		$entityObj->temporary				= $this->request->temporary??false;

		// add remarks copied from services and the manually set remarks
		$entityObj->remarks					= trim($this->request->remarks??'' . "\n" . $entityObj->get_invoiceRemarksFromServices());

		if ($this->request->comments??null) {
			$entityObj->comments				= $this->request->comments;
		}

		// apply a forced rows description scheme
		if ($this->request->rowDescriptionScheme??null) {
			$entityObj->rowDescriptionScheme	= $this->request->rowDescriptionScheme;
		}
		// check if the corporate has something in its profile and apply it
		else {
			if ($this->request->idCorporate) {
				$corpProfileScheme = \App\EntityPreference\Corporate::getInstance($this->request->idCorporate)->invoiceRowsScheme;
				if ($corpProfileScheme) {
					$entityObj->rowDescriptionScheme	= $corpProfileScheme;
				}
			}
		}

		$entityObj->idInvoiceSeries			= (int)($this->request->idSeries??0);
		$entityObj->formOfPayment			= $this->request->formOfPayment??'';

		$entityObj->idUser					= $this->request->idUser??0;
		$entityObj->idOffice					= \Entity\User::select($this->request->idUser??0)->idOffice;

	}

}

