<?php

namespace Modules\Orders\ServicesList;

class Controller extends \App\Mvc\Controller\Window\PaginatedListing\ListingAbstract
{
	/**
	 * The list of columns which support ordering.
	 * @var array
	 */
	protected $listOrderingColumns = ['id', 'orderId'];

	/**
	 * (non-PHPdoc)
	 * @see \App\Mvc\Controller\Window\PaginatedListing\ListingAbstract::alterListParams()
	 */
	protected function index_alterListParams($R)
	{
		$filters = [];

		if ($R['filters']['idBalance']) {

			// get services list from balance entity
			$servicesListAdv = \Entity\Balance::select($R['filters']['idBalance'])->orderServicesListAdv;

			// populate ordersList
			$ordersList = $servicesList = [];
			foreach ($servicesListAdv as $servDet) {
				$ordersList[] = \Entity\Service::select($servDet['id'])->idOrder;
				$servicesList[] = $servDet['id'];
			}

			// get the date filters from the orders
			$dateYM = null;
			$arr = [];
			foreach ($ordersList as $id) {
				$dateYM = \App\Utils\Db\TablesUtils::getInstance()->getYmFromId($id);
				$arr[] = $dateYM;
			}

			$arr = array_unique($arr);
			sort($arr);
			$endDate =  \Engine\DateTime::createFromIsoDate(sprintf('%s-%s-01', substr(end($arr), 0, 4), substr(end($arr), -2)));
			$startDate =  \Engine\DateTime::createFromIsoDate(sprintf('%s-%s-01', substr(reset($arr), 0, 4), substr(reset($arr), -2)));

			$filters['orderId'] = implode(',', array_unique($servicesList));
			$filters['idOrdersTypes'] = "idService";
			$filters['responsibleUserOffice']['id'] = '0|0';
			$filters['orderDate'] = [
				'start' 	=> $startDate->format('Y-m-d'),
				'end' 		=> $endDate->format('Y-m-t')
			];
		}

		// if the filter idInvoice is set, populate the services id filter
		if ($R['filters']['idInvoice']) {
			$invoiceEnt = \Entity\Invoice::select($R['filters']['idInvoice']);
			$ordersList = $invoiceEnt->idReservationsList;

			// get the date interval for this filter
			$arr = [];
			foreach ($ordersList as $id) {
				$arr[] = \App\Utils\Db\TablesUtilsCached::getInstance()->getYmFromId($id);
			}
			$arr = array_unique($arr);

			// new filters
			$filters['orderDate'] = [
				'start' 	=> \Engine\DateTime::createFromIsoDate(sprintf('%s-%s-01', substr(min($arr), 0, 4), substr(min($arr), -2)))->format('Y-m-d'),
				'end' 		=> \Engine\DateTime::createFromIsoDate(sprintf('%s-%s-01', substr(max($arr), 0, 4), substr(max($arr), -2)))->format('Y-m-t')
			];

			$filters['responsibleUserOffice']['id'] = '0|0';
		}

		// overwrite the responsible user and date interval
		if ($R['filters']['orderId']) {
			$filters['responsibleUserOffice']['id'] = '0|0';

            $idReservation = \App\Utils\Db\TablesUtilsCached::getInstance()->switchIdReservationConversion($R['filters']['orderId'], 'normal');
            if ($idReservation) {
                $dateYM = \App\Utils\Db\TablesUtils::getInstance()->getYmFromId($idReservation);
                $date = \Engine\DateTime::createFromIsoDate(sprintf('%s-%s-01', substr($dateYM, 0, 4), substr($dateYM, -2)));
                $filters['orderDate'] = [
                    'start' => $date->format('Y-m-d'),
                    'end' => $date->format('Y-m-t')
                ];
            }
		}

		if ($filters) {
			$this->listingParams->mergeFilters($filters);
			$this->listingParams->save();
		}
	}

	/**
	 * (non-PHPdoc)
	 * @see \App\Mvc\Controller\Window\PaginatedListing\ListingAbstract::actionList_getModelOutput()
	 */
	protected function actionList_getModelOutput($R)
	{
		$filters = $this->getListingParams()->getFilters();

		if (!\Engine\DateTime::createFromIsoDate($filters['orderDate']['start'])->isValid() || !\Engine\DateTime::createFromIsoDate($filters['orderDate']['end'])->isValid()) {
			throw new \Engine\Mvc\ControllerException($this->lang['index']['messages']['orderDate_mandatory']);
		}

		if (\Engine\DateTime::createFromIsoDate($filters['orderDate']['start'])->add(\Engine\DateInterval::createFromIntervalSpec("P{$this->cfg['listingParams']['filters']['orderDate']['maxDifference']}D"))->formatDateIso() < \Engine\DateTime::createFromIsoDate($filters['orderDate']['end'])->formatDateIso()) {
			throw new \Engine\Mvc\ControllerException($this->lang['index']['messages']['orderDate_invalidInterval']);
		}

		return parent::actionList_getModelOutput($R);
	}

	/**
	 * (non-PHPdoc)
	 * @see \App\Mvc\Controller\Window\PaginatedListing\ListingAbstract::optionDefineParams()
	 */
	protected function optionDefineParams(\App\Mvc\View\Utils\RowOptions\Option\Option $option, $selection)
	{
		switch($option->getId()) {

			case 'remoteLoad': case 'serviceOffer': case 'tasksOnService': case 'redirectToInvoicesList': case 'redirectToOrdersList': case 'documentsBulkDownload': case 'offerHistory':
			break;

			case 'simulateFeeRule':
			break;

			case 'itinerary': {
				foreach ($selection as $selectedItem) {
					$servEnt = \Entity\Service::select($selectedItem);
					if (in_array($servEnt->statusOp, ['XX', 'NP', 'PE'])) {
						$option->setDisabled();
						$option->addMessage('warning', $this->lang['index']['options']['reasons']['itinerary']['serviceBlocked']);
					}

				}
			}

			case 'invoiceAdd':
			if (!\App\UserAccess\CurrentUserAccessFast::getInstance()->hasAccessToOption('Modules/Invoices/InvoiceInsert') ) {
					$option->setDisabled();
					$option->addMessage('warning', $this->globalLang['noAccessToOption']);
				}
			break;

			case 'adminDocuments':
				if ( !\App\UserAccess\CurrentUserAccessFast::getInstance()->hasAccessToOption('serviceDocumentsManagement') ) {
					$option->setDisabled();
					$option->addMessage('warning', $this->globalLang['noAccessToOption']);
				}

				foreach ($selection as $selectedItem) {
					// determine option icon
					$option->determineIconGeneratedDocuments($selectedItem);
					$serviceEnt = \Entity\Service::select($selectedItem);
					if ($serviceEnt->chosenOfferId) {
						$serviceCode = $serviceEnt->chosenOffer->serviceCode;
					}
					else {
						$serviceCode = $serviceEnt->serviceCode;
					}
					if (!\App\Config\IssueDocuments::getInstance()->getServiceDocsList($serviceCode)) {
						$option->setDisabled();
						$option->addMessage('warning', $this->lang['index']['options']['reasons']['manageDocuments']['noDocuments']);
					}
				}
			break;

			case 'update':
				foreach ($selection as $selectedItem) {
					if (!$option->determineOperationAvailability(\Entity\Service::update($selectedItem))) {
						break;
					}
				}
			break;

			case 'addNewService':
				$filters = $this->getListingParams()->getFilters();
				if (!$filters['orderId'] || $filters['idOrdersTypes']!='id') {
					$option->setDisabled()->addMessage('warning', $this->lang['index']['options']['reasons']['addService']['orderIdNotSet']);
				} else {
					$option->determineOperationAvailability(\Entity\Service::insert());
				}
			break;

			case 'importServices':
				$filters = $this->getListingParams()->getFilters();
				if (!$filters['orderId'] || $filters['idOrdersTypes']!='id') {
					$option->setDisabled()->addMessage('warning', $this->lang['index']['options']['reasons']['addService']['orderIdNotSet']);
				}
				elseif (!\App\UserAccess\CurrentUserAccessFast::getInstance()->getAccessOptionValue('reservationProcessFromImportedRes')) {
					$option->setDisabled();
					$option->addMessage('warning', $this->globalLang['noAccessToOption']);
				}
				else {
					$option->determineOperationAvailability(\Entity\Service::insert());
				}
			break;

			case 'addService':
				foreach ($selection as $selectedItem) {
					if (!$option->determineOperationAvailability(\Entity\Service::insert())) {
						break;
					}
					if (\Entity\Service::select($selectedItem)->linkedToIdService) {
						$option->setDisabled();
						$option->addMessage('warning', $this->lang['index']['options']['reasons']['addService']['serviceLinkedToAnother']);
					}
					if (\Entity\Service::select($selectedItem)->statusOp == 'XX') {
						$option->setDisabled();
						$option->addMessage('warning', $this->lang['index']['options']['reasons']['addService']['serviceCanceled']);
					}
				}
			break;

			case 'tickets':
				foreach ($selection as $selectedItem) {
					$serviceCode = \Entity\Service::select($selectedItem)->serviceCode;
					if (!\App\Config\Services_OfferFields::getInstance()->manageTicketDetails($serviceCode) || !\App\UserAccess\CurrentUserAccessFast::getInstance()->hasAccessToOption('Modules/Orders/Services/ImportedServicesRefs-update')) {
						$option->setDisabled();
						$option->addMessage('warning', $this->lang['index']['options']['reasons']['tickets']['noManageTickets']);
					}
				}
			break;

			case 'cancel':
				foreach ($selection as $selectedItem) {
					if (!$option->determineOperationAvailability(\Entity\Service::cancel($selectedItem))) {
						break;
					}
				}
			break;

			case 'breakService':
				foreach ($selection as $selectedItem) {
					$serv = \Entity\Service::select($selectedItem);
					if ($serv->statusOp == 'XX') {
						$option->setDisabled()->addMessage('warning', $this->lang['index']['options']['reasons']['breakService']['serviceCanceled']);
						break;
					}
					if ($serv->statusFin=="TI") {
						$option->setDisabled()->addMessage('warning', $this->lang['index']['options']['reasons']['breakService']['invoicedService']);
						break;
					}
					if ($serv->packageOfferMode) {
						$option->setDisabled()->addMessage('warning', $this->lang['index']['options']['reasons']['breakService']['serviceIsPackage']);
						break;
					}
					if ($serv->idPackageService) {
						$option->setDisabled()->addMessage('warning', $this->lang['index']['options']['reasons']['breakService']['serviceIsSubserv']);
						break;
					}
					if ($serv->balance->id or $serv->balanceRefund->id) {
						$option->setDisabled()->addMessage('warning', $this->lang['index']['options']['reasons']['breakService']['serviceIsBalanced']);
						break;
					}
				}
			break;

			case 'clone':
				foreach ($selection as $selectedItem) {
					$service = \Entity\Service::select($selectedItem);
					if ($service->statusOp=="XX") {
						$option->addMessage('warning', $this->lang['index']['options']['reasons']['servIsCanceled']);
						$option->setDisabled();
						break;
					}
					if ($service->packageOfferMode) {
						$option->addMessage('warning', $this->lang['index']['options']['reasons']['packageCannotBeCloned']);
						$option->setDisabled();
						break;
					}
				}
			break;

			case 'serviceLink':
				foreach ($selection as $selectedItem) {
					if (\Entity\Service::select($selectedItem)->statusOp == 'XX') {
						$option->setDisabled();
						$option->addMessage('warning', $this->lang['index']['options']['reasons']['serviceReference']['serviceCanceled']);
						break;
					}
				}
			break;

			case 'addRemarksBulk':
				foreach ($selection as $selectedItem) {
					if (!$option->determineOperationAvailability(\Entity\Service::update($selectedItem))) {
						break;
					}
				}
			break;

			case 'createServicePackage':

				if (!\App\UserAccess\CurrentUserAccessFast::getInstance()->hasAccessToOption('reservationServiceCreatePackage')) {
					$option->setDisabled();
					$option->addMessage('warning', $this->globalLang['noAccessToOption']);
				}
				else {
					$idOrders = [];
					foreach ($selection as $idService) {
						$serviceEnt = \Entity\Service::select($idService);
						$idOrders[$serviceEnt->idOrder] = true;
						if (count($idOrders)>1) {
							$option->setDisabled();
							$option->addMessage('warning', $this->lang['index']['options']['reasons']['manualPackage']['notSameOrder']);
							break;
						}
						if ($serviceEnt->packageOfferMode) {
							$option->setDisabled();
							$option->addMessage('warning', $this->lang['index']['options']['reasons']['manualPackage']['noPackages']);
							break;
						}
						if ($serviceEnt->idPackageService) {
							$option->setDisabled();
							$option->addMessage('warning', $this->lang['index']['options']['reasons']['manualPackage']['noSubservices']);
							break;
						}
						if ($serviceEnt->statusOp=='XX' or $serviceEnt->statusFin!='NI') {
							$option->setDisabled();
							$option->addMessage('warning', $this->lang['index']['options']['reasons']['manualPackage']['servStsInvalid']);
							break;
						}
						if ($serviceEnt->idBalance or $serviceEnt->idBalanceRefund) {
							$option->setDisabled();
							$option->addMessage('warning', $this->lang['index']['options']['reasons']['manualPackage']['balancedServ']);
							break;
						}
					}

				}

			break;

			case 'serviceCashBulk': case 'assocImportDoc':
				try {
					$distributeImpDocsBulk = new \Modules\Documents\ImportedDocuments\BulkDistributeImportedDocs\ServiceModel($selection);
					$distributeImpDocsBulk->isAvailable(false);
				} catch (\App\MessagesException $e) {
					$option->setDisabled();
					$option->setDescription($e->getMessagesCollector()->getMessageBulk());
				}
			break;

			default:
				return false;

		}

		return true;

	}


	/**
	 * (non-PHPdoc)
	 * @see \App\Mvc\Controller\Window\PaginatedListing\ListingAbstract::optionGetEntityName()
	 */
	protected function optionGetEntityName($id)
	{
		return \Entity\Service::select($id)->getId();
	}
}

