<?php
namespace Modules\Orders\OrdersList;

class Controller extends \App\Mvc\Controller\Window\PaginatedListing\PaginatedEntityListing
{

	/**
	 * Indicates if the entity execution should use or not a transaction.
	 * @var Boolean
	 */
	protected $useSqlTransaction=true;

	/**
	 * (non-PHPdoc)
	 * @see \App\Mvc\Controller\Window\PaginatedListing\ListingAbstract::alterListParams()
	 */
	protected function index_alterListParams($R)
	{
		$filters = [];
		if ($R['filters']['idBalance']) {
			$balanceEnt = \Entity\Balance::select($R['filters']['idBalance']);
			$servicesList = array_map(function($srv) {	// filter only service id's
				return $srv['id'];
			}, $balanceEnt->orderServicesListAdv);

			// populate orders list
			$ordersList = [];
			foreach ($servicesList as $servId) {
				$ordersList[] = \Entity\Service::select($servId)->idOrder;
			}

			// new filters
			if ($ordersList) {

				$ordersList = array_unique($ordersList);	// deduplicate oreder id's, because we might have multiple services on the same order

				// get orders YMs
				sort($ordersList);
				$arr = [];
				foreach ($ordersList as $id) {
					$arr[] = \App\Utils\Db\TablesUtilsCached::getInstance()->getYmFromId($id);
				}
				$arr = array_unique($arr);

				// apply the filter
				$filters['date'] = [
					'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['idReservation'] = implode(',', $ordersList);
				$filters['idReservationType'] = "id";
				$filters['idOffice']['id'] = '';
			}
		}

		// if the filter idInvoice is set, populate the order 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);

			// apply the filter
			$filters['date'] = [
				'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['idReservation'] = implode(',', $ordersList);
			$filters['idReservationType'] = "id";
			$filters['idOffice']['id'] = '';
		}

		// overwrite the responsible user and date interval
		if ($R['filters']['idReservation']??null) {
			$filters['idOffice']['id'] = '0|0';

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

		if ($R['filters']['idCustomer']['id']??null) {
			$filters['idOffice']['id'] = '0|0';
		}

		if ($R['filters']['idSupplierInvoice']??null) {
			$filters['idOffice']['id'] = '0|0';

			$supplierInvoice = \Entity\SupplierInvoice::select($R['filters']['idSupplierInvoice']);
			$rows = $supplierInvoice->rowsList;

			$dateArr = [];
			foreach ($rows as $row) {
				if ($row['reservationId']) {
					$dateArr[] = \App\Utils\Db\TablesUtilsCached::getInstance()->getYmFromId($row['reservationId']);
				}
			}

			if ($dateArr) {
				sort($dateArr);
				$date = \Engine\DateTime::createFromIsoDate(sprintf('%s-%s-01', substr($dateArr[0], 0, 4), substr($dateArr[0], -2)));
				$filters['date'] = [
					'start' 	=> $date->format('Y-m-d'),
					'end' 		=> $date->format('Y-m-t')
				];
			}
			// min si  max

			//\App\Utils\Db\TablesUtilsCached::getInstance()->getYmFromId()
		}


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

	/**
	 * (non-PHPdoc)
	 * @see \App\Mvc\Controller\Window\PaginatedListing\PaginatedListing::initialize()
	 */
	protected function initialize()
	{
		parent::initialize();

		$this->actionsCfg['cancelOrder'] =   	['checkSection' => false,  'checkOption' => 'Modules/Orders/Cancel-cancelOrder',];
		$this->actionsCfg['bulkUpdate'] =    ['checkSection' => false, 'checkOption' => false,];
	}

	/**
	 * The list of columns which support ordering.
	 * @var array
	 */
	protected $listOrderingColumns = ['addTime'];

	/**
	 * (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['date']['start'])->isValid() || !\Engine\DateTime::createFromIsoDate($filters['date']['end'])->isValid()) {
			throw new \Engine\Mvc\ControllerException($this->lang['index']['messages']['date_mandatory']);
		}

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

		return parent::actionList_getModelOutput($R);
	}

	/**
	 * This action is used for updating the responsible user for all orders.
	 */
	public function actionBulkUpdate($R)
	{

		$msgs = \App\MessagesCollector::create();

		$closePopup = false;

		// get the entities ids from selection
		$ids = $this->getListingSelection()->getList();

		if ($R[$this->formSubmitButtonName]) {

			// at least one action selected
			if (empty($R['respUserAction']) and empty($R['miceProjectAction']) and
				empty($R['orderTypeAction']) and empty($R['serviceTypeAction']) and empty($R['flagAction'])
			) {
				$msgs->addWarning($this->lang['bulkUpdate']['msgs']['warning']['noActionSelected']);
			}
			// for updating the resp user, you must select the user
			if ($R['respUserAction'] == 'update' and empty($R['idUser']['id'])) {
				$msgs->addWarning($this->lang['bulkUpdate']['msgs']['warning']['noRespUserSelected']);
			}
			// for updating MICE you must select a MICE project
			if ($R['miceProjectAction'] == 'update' && empty($R['idMiceProject']['id'])) {
				$msgs->addWarning($this->lang['bulkUpdate']['msgs']['warning']['noMiceProjectSelected']);
			}
			// for updating order type you must select an order type
			if ($R['orderTypeAction'] == 'update' && empty($R['orderType'])) {
				$msgs->addWarning($this->lang['bulkUpdate']['msgs']['warning']['noOrderTypeSelected']);
			}
			// for updating service type you must select a service type
			if ($R['serviceTypeAction'] == 'update' && empty($R['serviceType'])) {
				$msgs->addWarning($this->lang['bulkUpdate']['msgs']['warning']['noServiceTypeSelected']);
			}
			// for updating flag you must select a flag
			if ($R['flagAction'] == 'update' && empty($R['flag'])) {
				$msgs->addWarning($this->lang['bulkUpdate']['msgs']['warning']['noFlagSelected']);
			}
		}

		// if the submit button is pressed and there are no errors
		if ($R[$this->formSubmitButtonName] and !$msgs->hasErrorOrWarning() ) {
			foreach ($ids as $id) {

				try {

					// start transaction
					\DB::startTransaction();

					$order = \Entity\Order::update($id);

					if ($R['respUserAction'] == 'update') {
						$order->idUser = $R['idUser']['id'];
						$order->idOffice = \Entity\User::select($R['idUser']['id'])->idOffice;
					}

					if ($R['miceProjectAction'] == 'update') {
						$order->idMiceProject = $R['idMiceProject']['id'];
					}
					elseif ($R['miceProjectAction'] == 'delete') {
						$order->idMiceProject = 0;
					}

					if ($R['orderTypeAction'] == 'update') {
						$order->resType = $R['orderType'];
					}
					elseif ($R['orderTypeAction'] == 'delete') {
						$order->resType = '';
					}

					if ($R['serviceTypeAction'] == 'update') {
						$order->servicesType = $R['serviceType'];
					}
					elseif ($R['serviceTypeAction'] == 'delete') {
						$order->servicesType = '';
					}

					if ($R['flagAction'] == 'update') {
						$order->flag = $R['flag'];
					}
					elseif ($R['flagAction'] == 'delete') {
						$order->flag = '';
					}

					// save the entity
					$order->save();

					// commit transaction
					\DB::commitTransaction();

					// action was successful
					$msgs->addSuccess($order->getMessages());

					// delete the entity id from selection
					$this->getListingSelection()->delete([$id]);
				}
				catch (\App\Entity\Exception $e) {
					\DB::rollbackTransaction();
					$msgs->appendMessages($e->getMessagesCollector());
					break;
				}
			}

			if (!$msgs->hasErrorOrWarning()) {
				$closePopup = true;
			}
		}

		// messages
		$successTexts = 0;
		foreach($msgs->getMessages() as $msg) {
			if ($msg->getType()=='success') {
				$successTexts++;
			}
		}
		if ($successTexts>1) {
			$msgs->removeSuccess();
			$msgs->addSuccess(sprintf($this->lang['bulkUpdate']['msgs']['success']['updateSuccessful'], $successTexts));
		}

		// create the view
		$view = new View_BulkUpdate($this);

		// append messages
		$view->getMessagesCollector()->appendMessages($msgs);

		// add form data
		$view->addInput('formData', $R);

		// close the popup
		if ($closePopup) {
			$view->setClosePopup(true);
		}

		$view->addInput('formSubmitButtonName', $this->formSubmitButtonName);

		// render the view
		return new \Engine\Mvc\Response\Html($view->render());
	}

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

			case 'addService':
				$option->determineOperationAvailability(\Entity\Service::insert());
			break;

			case 'importServices':
				if (!\App\UserAccess\CurrentUserAccessFast::getInstance()->getAccessOptionValue('reservationProcessFromImportedRes')) {
					$option->setDisabled();
					$option->addMessage('warning', $this->globalLang['noAccessToOption']);
				} else {
					$option->determineOperationAvailability(\Entity\Service::insert());
				}
			break;

            case 'orderCompanies':
                if (!\App\UserAccess\CurrentUserAccessFast::getInstance()->getAccessOptionValue('Modules/Orders-canAddCorporateOnOrder')) {
                    $option->setDisabled();
                    $option->addMessage('warning', $this->globalLang['noAccessToOption']);
                }
            break;

            case 'orderPassengers':
                if (!\App\UserAccess\CurrentUserAccessFast::getInstance()->getAccessOptionValue('Modules/Orders-canAddCustomerOnOrder')) {
                    $option->setDisabled();
                    $option->addMessage('warning', $this->globalLang['noAccessToOption']);
                }
            break;

            case 'passengersServicesAssociations':
                if (!\App\UserAccess\CurrentUserAccessFast::getInstance()->getAccessOptionValue('reservationCustomersServAssocUpdate')) {   // TODO RENAME
                    $option->setDisabled();
                    $option->addMessage('warning', $this->globalLang['noAccessToOption']);
                }
            break;

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

				if (!\App\Config\IssueDocuments::getInstance()->getOrderDocsList()) {
					$option->setDisabled();
					$option->addMessage('warning', $this->lang['index']['options']['reasons']['manageDocuments']['noDocuments']);
				}

				foreach ($selection as $selectedItem) {
					// determine option icon
					$option->determineIconGeneratedDocuments($selectedItem);
				}

			break;

			case 'orderInvoices': case 'orderInvoicesBulk':
				if ( !\App\UserAccess\CurrentUserAccessFast::getInstance()->hasAccessToSection('Modules/Invoices/InvoicesList') ) {
					$option->setDisabled();
					$option->addMessage('warning', $this->globalLang['noAccessToSection']);
				}
			break;

			case 'orderSupplierInvoices': case 'addSupplierInvoice':
				if ( !\App\UserAccess\CurrentUserAccessFast::getInstance()->hasAccessToSection('Modules/Invoices/SupplierInvoices') ) {
					$option->setDisabled();
					$option->addMessage('warning', $this->globalLang['noAccessToSection']);
				}
			break;

			case 'orderBalances':
				if ( !\App\UserAccess\CurrentUserAccessFast::getInstance()->hasAccessToSection('balanceInvoices') ) {
					$option->setDisabled();
					$option->addMessage('warning', $this->globalLang['noAccessToSection']);
				}
			break;

			case 'tasksOnOrder':
				if ( !\App\UserAccess\CurrentUserAccessFast::getInstance()->hasAccessToSection('Modules/TaskManagement/Tasks') ) {
					$option->setDisabled();
					$option->addMessage('warning', $this->globalLang['noAccessToSection']);
				}
			break;

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

			case 'redirectToServicesList':
				if ( !\App\UserAccess\CurrentUserAccessFast::getInstance()->hasAccessToSection('Modules/Orders/ServicesList') ) {
					$option->setDisabled();
					$option->addMessage('warning', $this->globalLang['noAccessToOption']);
				}
			break;

			case 'details': case 'quickNav': case 'remoteLoad': case 'sortServices': case 'documentsBulkDownload': case 'orderDetails' : case 'bulkUpdate':
			break;

			case 'dashboard':
				if (!\App\UserAccess\CurrentUserAccessFast::getInstance()->hasAccessToSection("Modules/Orders/Dashboard")) {
					$option->setDisabled();
				}

			break;

			case 'notesCompleted': {
				foreach ($selection as $selectedItem) {
					if (!\Entity\Order::select($selectedItem)->notes or !\App\UserAccess\CurrentUserAccessFast::getInstance()->hasAccessToOption("Modules/Orders/Details/OrderNotes")) {
						$option->setDisabled();
					}
				}
				break;
			}

			case 'notesEmpty': {
				foreach ($selection as $selectedItem) {
					if (\Entity\Order::select($selectedItem)->notes or !\App\UserAccess\CurrentUserAccessFast::getInstance()->hasAccessToOption("Modules/Orders/Details/OrderNotes")) {
						$option->setDisabled();
					}
				}
				break;
			}

			case 'addImpDocOnOrder':
				foreach ($selection as $selectedItem) {
					if (\Entity\Order::select($selectedItem)->statusOp == "XX" or !\App\UserAccess\CurrentUserAccessFast::getInstance()->hasAccessToSection("Modules/Documents/ImportedDocuments")) {
						$option->setDisabled();
					}
				}
				break;

			default:
				return false;
		}

		return true;
	}

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

	/**
	 * (non-PHPdoc)
	 * @see \App\Mvc\Controller\Window\PaginatedListing\PaginatedListing::insert_getDefaultFormData()
	 */
	protected function insert_getDefaultFormData($R)
	{
		return [];
	}

	/**
	 * (non-PHPdoc)
	 * @see \App\Mvc\Controller\Window\PaginatedListing\PaginatedEntityListing::insert_createEntityObject()
	 */
	protected function insert_createEntityObject($formData)
	{}

	/**
	 * (non-PHPdoc)
	 * @see \App\Mvc\Controller\Window\PaginatedListing\PaginatedListing::update_getDefaultFormData()
	 */
	protected function update_getDefaultFormData($idEntity)
	{
		return [];
	}

	/**
	 * (non-PHPdoc)
	 * @see \App\Mvc\Controller\Window\PaginatedListing\PaginatedEntityListing::update_createEntityObject()
	 */
	protected function update_createEntityObject($formData)
	{}

	/**
	 * (non-PHPdoc)
	 * @see \App\Mvc\Controller\Window\PaginatedListing\PaginatedEntityListing::delete_createEntityObject()
	 */
	protected function delete_createEntityObject($idRecord)
	{}

}

