<?php

namespace Modules\Partners\Corporates;

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;

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


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

		$this->actionsCfg['insert'] =         	[ 'checkSection' => false, 'checkOption' => true ];
		$this->actionsCfg['update'] =         	[ 'checkSection' => false, 'checkOption' => true ];
		$this->actionsCfg['delete'] =         	[ 'checkSection' => false, 'checkOption' => true ];
		$this->actionsCfg['profile'] =        	[ 'checkSection' => false, 'checkOption' => true ];
		$this->actionsCfg['lock'] =           	[ 'checkSection' => false, 'checkOption' => true ];
		$this->actionsCfg['unlock'] =           [ 'checkSection' => false, 'checkOption' => 'Modules/Partners/Corporates-lock' ];
		$this->actionsCfg['markDuplicate'] =  	[ 'checkSection' => false,];
		$this->actionsCfg['unmarkDuplicate'] = 	[ 'checkSection' => false ];
		$this->actionsCfg['bulkUpdate'] = 		[ 'checkSection' => false, 'checkOption' => 'Modules/Partners/Corporates-update' ];
		$this->actionsCfg['collectionProfile']=	[ 'checkSection' => false, 'checkOption' => false ];
		$this->actionsCfg['sendAlert'] =		[ 'checkSection' => false, 'checkOption' => false ];
	}

	/**
	 * (non-PHPdoc)
	 * @see \App\Mvc\Controller\Window\PaginatedListing\ListingAbstract::optionDefineParams()
	 */
	protected function optionDefineParams(\App\Mvc\View\Utils\RowOptions\Option\Option $option, $selection)
	{
		$_LANG = \App\Loader_Lang::getInstance()->getGlobal();

		switch ($option->getId()) {

			// simple options - no checks needed
			case 'listCustomers': case 'contactPersons': case 'contracts': case 'contacts': case 'listOffices':
			break;

			case 'dueDatesManagement':
				if (!\App\UserAccess\CurrentUserAccessFast::getInstance()->hasAccessToOption('Modules/Partners/Corporates-profile')) {
					$option->setDisabled();
				}
			break;

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

			case 'insert':
				if (!\App\UserAccess\CurrentUserAccessFast::getInstance()->hasAccessToOption("Modules/Partners/Corporates-insert")) {
					$option->setDisabled();
				}
			break;

			case 'addCustomer':
				if (!\App\UserAccess\CurrentUserAccessFast::getInstance()->hasAccessToOption("Modules/Partners/ContactPersons-insert")) {
					$option->setDisabled();
					$option->addMessage('warning', $_LANG['noAccessToOption']);
				}
			break;

			case 'supplierInsert':
				if (!\App\UserAccess\CurrentUserAccessFast::getInstance()->hasAccessToOption('Modules/Partners/Suppliers-insert')) {
					$option->setDisabled();
				}
				break;

			case 'profile':
				if (!\App\UserAccess\CurrentUserAccessFast::getInstance()->hasAccessToOption("Modules/Partners/Corporates-profile")) {
					$option->setDisabled();
					$option->addMessage('warning', $_LANG['noAccessToOption']);
				}
			break;

			case 'gdsProfile':
				if (!\App\UserAccess\CurrentUserAccessFast::getInstance()->hasAccessToOption("Modules/Partners/Corporates-gdsProfile")) {
					$option->setDisabled();
					$option->addMessage('warning', $_LANG['noAccessToOption']);
				}
			break;

			case 'corporateCreditCards':
				if (!\App\UserAccess\CurrentUserAccessFast::getInstance()->hasAccessToSection("Modules/Partners/Corporates/CreditCards")) {
					$option->setDisabled();
				}
			break;

			case 'lock':
				if (!\App\UserAccess\CurrentUserAccessFast::getInstance()->hasAccessToOption("Modules/Partners/Corporates-lock") or \Entity\Corporate::select($selection[0])->locked) {
					$option->setDisabled();
				}
			break;

			case 'unlock':
				if (!\App\UserAccess\CurrentUserAccessFast::getInstance()->hasAccessToOption("Modules/Partners/Corporates-lock") or !\Entity\Corporate::select($selection[0])->locked) {
					$option->setDisabled();
				}
			break;

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

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

			case 'markDuplicate':  case 'collectionProfile': case 'autoCompensate':
			break;

			case 'sendAlert': {
				foreach ($selection as $selectedItem) {
					$corporateCollection = \Entity\CorporateCollection::select($selectedItem);
					if ($corporateCollection->recordExists() and !$corporateCollection->active) {
						$option->setDisabled();
						$option->addMessage('warning', $this->lang['index']['messages']['sendEmailOption']['profileInactive']);
					}
				}
				break;
			}

			case 'unmarkDuplicate':
				foreach ($selection as $selectedItem) {
					if (!$option->determineOperationAvailability(\Entity\Corporate::unmarkDuplicate($selectedItem))) {
						break; // if operation is unavailable, break
					}
				}
			break;

			default:
				return false;

		}
		return true;

	}

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

	/**
	 * (non-PHPdoc)
	 * @see \App\Mvc\Controller\Window\PaginatedListing\PaginatedListing::insert_getDefaultFormData()
	 */
	protected function insert_getDefaultFormData($R)
	{
		$formData = $R;

		if ($R['inheritFromIdSupplier']) {
			// get supplier details
			$supplier = \Entity\Supplier::select($R['inheritFromIdSupplier']);

			$formData['alias'] = 	$supplier->alias;
			$formData['company']['standard']= [
				'prefix' => 	$supplier->companyPrefix,
				'company' => 	$supplier->company,
				'suffix' =>		$supplier->companySuffix,
			];

			// fiscal details
			$formData['fiscalCode'] = 		$supplier->fiscalCode;
			$formData['regNo'] = 			$supplier->regNo;
			$formData['vatRegistered'] =	$supplier->vatRegistered;
			$formData['vatCertificateNumber']=$supplier->vatCertificateNumber;

			// contact details
			$formData['telephone'] = 	$supplier->telephone;
			$formData['fax'] = 			$supplier->fax;
			$formData['email'] = 		$supplier->email;
			$formData['website'] = 		$supplier->website;

			// office details
			$formData['office']['address'] = 								$supplier->address;
			$formData['office']['addressMainDetails']['streetPrefix'] = 	$supplier->address_main_streetPrefix;
			$formData['office']['addressMainDetails']['streetName'] = 		$supplier->address_main_streetName;
			$formData['office']['addressMainDetails']['streetNumber'] = 	$supplier->address_main_streetNumber;
			$formData['office']['addressMainDetails']['district'] = 		$supplier->address_main_district;
			$formData['office']['addressMainDetails']['buildingNumber'] = 	$supplier->address_main_buildingNumber;
			$formData['office']['addressMainDetails']['buildingEntrance'] = $supplier->address_main_buildingEntrance;
			$formData['office']['addressMainDetails']['floor'] = 			$supplier->address_main_floor;
			$formData['office']['addressMainDetails']['apartment'] = 		$supplier->address_main_apartment;
			$formData['office']['addressMainDetails']['zipCode'] = 			$supplier->address_main_zipCode;
			$formData['office']['addressMainDetails']['countryCity'] = 		sprintf("%s|%s", $supplier->address_main_countryCode, $supplier->address_main_cityId);

			$formData['office']['deliveryAddress'] = 						$supplier->deliveryAddress;
			$formData['office']['addressDeliveryDetails']['streetPrefix'] = $supplier->address_delivery_streetPrefix;
			$formData['office']['addressDeliveryDetails']['streetName'] = 	$supplier->address_delivery_streetName;
			$formData['office']['addressDeliveryDetails']['streetNumber'] = $supplier->address_delivery_streetNumber;
			$formData['office']['addressDeliveryDetails']['district'] = 	$supplier->address_delivery_district;
			$formData['office']['addressDeliveryDetails']['buildingNumber']=$supplier->address_delivery_buildingNumber;
			$formData['office']['addressDeliveryDetails']['buildingEntrance']=$supplier->address_delivery_buildingEntrance;
			$formData['office']['addressDeliveryDetails']['floor'] = 		$supplier->address_delivery_floor;
			$formData['office']['addressDeliveryDetails']['apartment'] = 	$supplier->address_delivery_apartment;
			$formData['office']['addressDeliveryDetails']['zipCode'] = 		$supplier->address_delivery_zipCode;
			$formData['office']['addressMainDetails']['countryCity'] = 		sprintf("%s|%s", $supplier->address_main_countryCode, $supplier->address_main_cityId);

			$formData['office']['zipCode'] = 			$supplier->zipCode;
			$formData['office']['idLocation'] = 		sprintf("%s|%s", $supplier->countryCode, $supplier->cityId);

			// corporate office bank accounts
			$formData['office']['bankAccounts']=[];
			$idx=0;
			foreach($supplier->bankAccounts as $ba) {
				$formData['office']['bankAccounts'][++$idx]= [
					'id' =>			0, // forces "insert"
					'bank' => 		['id'=>$ba['idBank'].'|'.$ba['idBankOffice']],
					'account' =>	$ba['account'],
					'currency' =>	$ba['currency'],
					'default' =>	$ba['defaultAccount'],
				];
			}
		}

		$formData['type']   = 				$formData['type']?:$this->cfg['addEdit']['defaultClientType'];
		$formData['office']['copyAddress'] = 1;
		$formData['remarks'] = 				($formData['remarks']?:\App\EntityPreference\User::getInstance()->corporate_defaultRemarks)?:$this->cfg['addEdit']['defaultRemarks'];
		$formData['status'] =				$formData['status']?:$this->cfg['addEdit']['defaultStatus']; // CLIENT

		return $formData;
	}

	/**
	 * (non-PHPdoc)
	 * @see \App\Mvc\Controller\Window\PaginatedListing\PaginatedEntityListing::insert_createEntityObject()
	 */
	protected function insert_createEntityObject($formData)
	{
		$corp = \Entity\Corporate::insert();
		$corp->_exportToGds = true;

		$this->populateEntityObject($corp, $formData);

		return $corp;
	}

	/**
	 * (non-PHPdoc)
	 * @see \App\Mvc\Controller\Window\PaginatedListing\PaginatedListing::update_getDefaultFormData()
	 */
	protected function update_getDefaultFormData($idEntity)
	{
		$CFG   = \Engine\Loader_Cfg::getInstance()->getGlobal();

		$corp = \Entity\Corporate::select($idEntity);
		if (!$corp->recordExists()) {
			return null;
		}

		$formData = [];

		$formData['type'] = 		$corp->type;
		$formData['alias'] = 		$corp->alias;

		if ($CFG['useAlternativeNames']['corporates']) {
			$formData['company'] = [
				'standard' => 	[
					'prefix' => 	$corp->companyPrefixStandard,
					'company' => 	$corp->companyStandard,
					'suffix' => 	$corp->companySuffixStandard,
				],
				'local' => 	[
					'prefix' => 	$corp->companyPrefixLocal,
					'company' => 	$corp->companyLocal,
					'suffix' => 	$corp->companySuffixLocal,
				],
			];
		} else {
			$formData['company'] = [
				'standard'=> [
					'prefix' => 	$corp->companyPrefixStandard,
					'company' =>	$corp->companyStandard,
					'suffix' => 	$corp->companySuffixStandard,
				]
			];
		}

		$formData['idSegment'] = 		$corp->idSegment;
		$formData['idGdsProfileTemplate'] = $corp->idGdsProfileTemplate;
		$formData['idTrust']['id'] = 	$corp->idTrust;
		$formData['fiscalCode'] = 		$corp->fiscalCode;
		$formData['status'] = 			$corp->status;
		$formData['statusComments'] = 	$corp->statusComments;
		$formData['accountingNumber'] = $corp->accountingNumber;

		$formData['regNo'] = 				$corp->regNo;
		$formData['euid'] = 				$corp->euid;
		$formData['registryAddress'] =		$corp->registryAddress;
		$formData['vatRegistered'] = 		$corp->vatRegistered;
		$formData['vatCertificateNumber']=	$corp->vatCertificateNumber;

		$formData['telephone'] = 			$corp->telephone;
		$formData['fax'] = 					$corp->fax;
		$formData['email'] =				$corp->email;
		$formData['website'] = 				$corp->website;
		$formData['comments'] = 			$corp->comments;
		$formData['remarks'] = 				$corp->remarks;
		$formData['incomeTaxPayer'] = 		$corp->incomeTaxPayer;
		$formData['liablePerson'] = 		$corp->liablePerson;

		$formData['activityCategoryDomain']['id'] = sprintf("%s|%s", $corp->idDomainCategory, $corp->idDomain);
		$formData['accountManager']['id'] = $corp->idAccountManager;
		$formData['collectionResponsible']['id'] = $corp->idCollectionResponsible;

		return $formData;
	}

	/**
	 * (non-PHPdoc)
	 * @see \App\Mvc\Controller\Window\PaginatedListing\PaginatedEntityListing::update_createEntityObject()
	 */
	protected function update_createEntityObject($formData)
	{
		$corp = \Entity\Corporate::update($formData['id']);
		$corp->_exportToGds = true;

		$this->populateEntityObject($corp, $formData);

		return $corp;
	}

	/**
	 * Populates the insert/update entity with fields from form.
	 * @param \App\Entity\GeneralAbstract $entity
	 * @param Array $formData
	 */
	private function populateEntityObject(\Entity\Corporate $corp, Array $formData)
	{
		$CFG   = \Engine\Loader_Cfg::getInstance()->getGlobal();
		$corp->type 	= $formData['type'];
		$corp->alias 	= $formData['alias'];
		$corp->companyPrefixStandard = 	$formData['company']['standard']['prefix'];
		$corp->companyStandard = 		$formData['company']['standard']['company'];
		$corp->companySuffixStandard = 	$formData['company']['standard']['suffix'];

		if($CFG['useAlternativeNames']['corporates']) {
			$corp->companyLocal = 		$formData['company']['local']['company'];
			$corp->companyPrefixLocal = $formData['company']['local']['prefix'];
			$corp->companySuffixLocal = $formData['company']['local']['suffix'];
		}

		$corp->idTrust = 		(Int)$formData['idTrust']['id'];
		$corp->fiscalCode = 	$formData['fiscalCode'];
		$corp->regNo = 			$formData['regNo'];
		$corp->euid = 			$formData['euid'];
		$corp->registryAddress = $formData['registryAddress'];
		$corp->vatRegistered = 	 $formData['vatRegistered'];
		$corp->vatCertificateNumber = $formData['vatCertificateNumber'];
		$corp->telephone = 		$formData['telephone'];
		$corp->fax = 			$formData['fax'];
		$corp->email = 			$formData['email'];
		$corp->website = 		$formData['website'];
		$corp->comments = 		$formData['comments'];
		$corp->remarks = 		$formData['remarks'];
		$corp->incomeTaxPayer = $formData['incomeTaxPayer'];
		$corp->liablePerson = 	$formData['liablePerson'];
		$corp->accountingNumber = 	$formData['accountingNumber'];

		if (isset($formData['status'])) {
			$corp->status 				= $formData['status'];
			$corp->statusComments 	= (String)$formData['statusComments'];
		} elseif ($corp->getOperation()=='insert') {
			$corp->status				= $this->cfg['addEdit']['defaultStatus'];
		}

		/*if($formData['idAccountManager']=='current'){	// there is no way to know the current user id from JS, so i used this alias for the current user TODO when?
			$corp->idAccountManager = CURRENT_ID_USER;
		}*/

		$corp->idAccountManager = $formData['accountManager']['id'];
		$corp->idCollectionResponsible = $formData['collectionResponsible']['id'];

		if (isset($formData['activityCategoryDomain'])) {
			list($idDomainCategory, $idDomain)= explode("|", $formData['activityCategoryDomain']['id']);

			$corp->idDomainCategory = ($idDomainCategory ? $idDomainCategory : null);
			$corp->idDomain 		= ($idDomain ? $idDomain : null);
		}

		if ($this->action=='insert') {
			//CALL OFFICES CONTROLLER
			$controller = new \Modules\Partners\Corporates\Offices\Controller('Partners/Corporates/Offices');
			$corp->office = $controller->insert_createEntityObject($formData);
		}

		$corp->idSegment = 		(Int)$formData['idSegment'];
		$corp->idGdsProfileTemplate = (int)$formData['idGdsProfileTemplate'];

		return $corp;
	}


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

	/**
	 * Lock corporate
	 * @return \Engine\Mvc\Response\Html
	 */
	public function actionLock($R)
	{
		$msgs = \App\MessagesCollector::create();
		$formData = $R;

		// execute the model (and collect the output)
		$closePopup = false;
		if ($R[$this->formSubmitButtonName]) {
			\DB::startTransaction();
			try {
				$corp = \Entity\Corporate::update($R['id']);
				$corp->locked = 1;
				$corp->lockedComments = $formData['lockedComments'];
				$corp->save();

				\DB::commitTransaction();

				// action was successful
				$corp->assignMessages();
				$closePopup = true;
			} catch (\App\Entity\Exception $e) {
				\DB::rollbackTransaction();
				$msgs->appendMessages($e->getMessagesCollector());
			}
		}

		// instantiate the view
		$view = new View_Lock($this);

		// send data to the view
		$view->addInput('formData', $formData);
		if ($closePopup) {
			$view->setClosePopup(true);
		}
		$view->getMessagesCollector()->appendMessages($msgs);
		$view->addInput('formSubmitButtonName', $this->formSubmitButtonName);

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

	public function actionUnlock($R)
	{
		$msgs = \App\MessagesCollector::create();
		$this->setListingSelection($R['listing']['selection']);

		$selIds = $this->getListingSelection()->getList();

		foreach ($selIds as $id) {

			\DB::startTransaction();
			try {
				$corp = \Entity\Corporate::update($id);
				$corp->locked = 0;
				$corp->save();

				// remove this record from the internal list
				$this->getListingSelection()->delete([$id]);

				\DB::commitTransaction();

				// action was successful
				foreach ($corp->getMessages()->getMessages() as $msg) {
					$msgs->addMessage($msg);
				}

			} catch (\App\Entity\Exception $ex) {
				\DB::rollbackTransaction();
				$msgs->addMessage(new \App\Message('warning', $ex->getMessage()));
			}
		}

		return $this->executeListRecords($R, $msgs);
	}

	/**
	 * Mark Corporate as Duplicated
	 * @param array $R
	 */
	public function actionMarkDuplicate($R)
	{
		$msgs = \App\MessagesCollector::create();

		$formData = [];
		foreach($this->getListingSelection()->getList() as $idCorporate) {
			$formData['corporateList'][$idCorporate] = $idCorporate;
		}

		if ($R[$this->formSubmitButtonName] ) {
			$formData['idCorporate'] = $R['idCorporate'];
		}

		$closePopup = false;

		if ($R[$this->formSubmitButtonName] && $R['idCorporate'] ) {
			$duplicatedCorporateList = array_diff($formData['corporateList'], [$R['idCorporate']]);

			\DB::startTransaction();
			try {
				$corporate = \Entity\Corporate::markDuplicate($R['idCorporate']);
				$corporate->duplicatedCorporateList = $duplicatedCorporateList;

				$corporate->save();

				\DB::commitTransaction();

				// action was successful
				$corporate->assignMessages();
				$closePopup = true;
			} catch (\App\Entity\Exception $e) {
				\DB::rollbackTransaction();
				$msgs->appendMessages($e->getMessagesCollector());
			}
		}
		elseif ($R[$this->formSubmitButtonName] && !$R['idCorporate']) {
			$msgs->addMessage(new \App\Message('warning', $this->lang['markDuplicate']['error']));
		}
		$view = new View_MarkDuplicate($this);

		// send data to the view
		$view->addInput('formData', $formData);
		if ($closePopup) {
			$view->setClosePopup(true);
		}

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

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

	/**
	 * Unmark duplicate
	 * @param array $R
	 */
	public function actionUnmarkDuplicate($R)
	{
		$msgs = \App\MessagesCollector::create();
		$this->setListingSelection($R['listing']['selection']);

		$ids = $this->getListingSelection()->getList();

		foreach ($ids as $id){
			try {
				\DB::startTransaction();

				$corporate = \Entity\Corporate::unmarkDuplicate($id);
				$corporate->save();

				// remove this record from the internal list
				$this->getListingSelection()->delete([$id]);

				// commit the current transaction
				\DB::commitTransaction();
				foreach($corporate->getMessages()->getMessages() as $msg) {
					$msgs->addMessage($msg);
				}
			}
			catch(\App\Entity\Exception $ex) {
				\DB::rollbackTransaction();
				$msgs->addMessage(new \App\Message('warning', sprintf($this->lang['unmarkDuplicate']['error'], \Entity\Corporate::select($id)->alias)));
			}
		}

		return $this->executeListRecords($R, $msgs);

	}

	/**
	 * Bulk update
	 * You can update the KAM or the segments for many corporation at the same time
	 * @param array $R
	 */
	public function actionBulkUpdate($R)
	{


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

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

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

			$groups = \App\Config\CorporateGroups::getInstance()->getAll();

			// check if some groups actions was set (at least one group)
			if ($groups) {
				$groupActionSelected = false;
				foreach ($groups as $idGroup => $groupDetails) {
					if ($R['groupAction'][$idGroup]) {
						$groupActionSelected = true;
					}
				}
			}

			// at least one action selected
			if (
				!$R['kamAction'] and !$R['collectionResponsibleAction'] and !$R['segmentAction'] and !$R['activityCategoryDomainAction']
				and !$R['gdsProfileTemplateAction'] and !$R['collectionProfileAction'] and !$R['autoCompensationAction'] and !$groupActionSelected
			) {
				$msgs->addWarning($this->lang['bulkUpdate']['msgs']['warning']['noActionSelected']);
			}
			// for updating the kam, you must select the user
			if ($R['kamAction'] == 'update' and empty($R['idUser']['id'])) {
				$msgs->addWarning($this->lang['bulkUpdate']['msgs']['warning']['noKamSelected']);
			}
			// for updating the collection responsible, you must select the user
			if ($R['collectionResponsibleAction'] == 'update' and empty($R['idCollectionResponsible']['id'])) {
				$msgs->addWarning($this->lang['bulkUpdate']['msgs']['warning']['noCollectionResponsibleSelected']);
			}
			// for updating the segments, you must select the segment
			if ($R['segmentAction'] == 'update' and empty($R['idSegment'])) {
				$msgs->addWarning($this->lang['bulkUpdate']['msgs']['warning']['noSegmentSelected']);
			}
			// for updating the activityDomain, you must select the activityCategoryDomain
			if ($R['activityCategoryDomainAction'] == 'update' and empty($R['activityCategoryDomain']['id'])) {
				$msgs->addWarning($this->lang['bulkUpdate']['msgs']['warning']['noActivityDomainSelected']);
			}
			// for updating the GDS profile temp, you must select the template
			if ($R['gdsProfileTemplateAction'] == 'update' and empty($R['idGdsProfileTemplate'])) {
				$msgs->addWarning($this->lang['bulkUpdate']['msgs']['warning']['nogdsTemplateSelected']);
			}
			// for updating the collection profile, you must select the profile code
			if ($R['collectionProfileAction'] == 'update' and empty($R['collectionProfileCode'])) {
				$msgs->addWarning($this->lang['bulkUpdate']['msgs']['warning']['noCollProfSelected']);
			}
			// for updating the compensation profile, you must select the type
			if ($R['autoCompensationAction'] == 'update' and !in_array($R['autoCompensationType'], ['onlyExactCreditNotes', 'bulk'])) {
				$msgs->addWarning($this->lang['bulkUpdate']['msgs']['warning']['noCompProfSelected']);
			}

			if ($groups) {
				foreach ($groups as $idGroup=>$groupDetails) {
					if ($R['groupAction'][$idGroup] == 'update' and empty($R['idGroupElements'][$idGroup])) {
						$msgs->addWarning($this->lang['bulkUpdate']['msgs']['warning']['noGroupElementsSelected']);
					}
				}
			}

		}

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

				try {

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

					// UPDATE CORPOERATE MAIN DETAILS ---------------------------------------------

					$corporate = \Entity\Corporate::update($id);

					// kam action
					if ($R['kamAction'] == 'delete') {
						$corporate->idAccountManager = 0;
					} elseif ($R['kamAction'] == 'update') {
						$corporate->idAccountManager = $R['idUser']['id'];
					}

					// COLLECTION RESPONSIBLE ACTION ..............................................
					if ($R['collectionResponsibleAction'] == 'delete') {
						$corporate->idCollectionResponsible = 0;
					} elseif ($R['collectionResponsibleAction'] == 'update') {
						$corporate->idCollectionResponsible = $R['idCollectionResponsible']['id'];
					}

					// SEGMENTS ACTION ............................................................
					if ($R['segmentAction'] == 'delete') {
						$corporate->idSegment = 0;
					} elseif ($R['segmentAction'] == 'update') {
						$corporate->idSegment = $R['idSegment'];
					}

					// ACTIVITY DOMAIN ACTION .....................................................
					if ($R['activityCategoryDomainAction'] == 'delete') {

						$corporate->idDomain = 0;
						$corporate->idDomainCategory = 0;

					} elseif ($R['activityCategoryDomainAction'] == 'update') {

						$actCatDomArr = explode('|',  $R['activityCategoryDomain']['id']);
						$corporate->idDomain =  $actCatDomArr[1];
						$corporate->idDomainCategory =  $actCatDomArr[0];
					}

					// GDS PROFILE TEMPLATE ACTION ................................................
					if ($R['gdsProfileTemplateAction'] == 'delete') {
						$corporate->idGdsProfileTemplate = 0;
					} elseif ($R['gdsProfileTemplateAction'] == 'update') {
						$corporate->idGdsProfileTemplate = $R['idGdsProfileTemplate'];
					}

					// COMPANY GROUPS .............................................................
					if ($groupActionSelected) {
						$corporateGroupElements = [];
						if ($groups) {
							foreach ($groups as $idGroup => $groupDetails) {
								if ($R['groupAction'][$idGroup] == 'update') {
									$corporateGroupElements[$idGroup] = $R['idGroupElements'][$idGroup];
								} elseif ($R['groupAction'][$idGroup] == 'delete') {
									$corporateGroupElements[$idGroup] = '';
								}
							}
							$existingCorporateGroups = \Entity\Corporate::selectForUpdate($id)->idGroupElements;
							$corporate->idGroupElements = array_merge((Array)$existingCorporateGroups, $corporateGroupElements);
						}
					}

					// save the entity - if something was set; maybe only collection profiles were saved (step2)
					if ($corporate->getFields()) {
						$corporate->save();
					}

					// UPDATE COLLECTION PROFILE AS WELL ------------------------------------------
					if ($R['collectionProfileAction']=='update') {
						if (\Entity\CorporateCollection::selectForUpdate($id)->recordExists()) {
							$corporateCollectionEnt = \Entity\CorporateCollection::update($id);
							$corporateCollectionEnt->active = true;
							$corporateCollectionEnt->profileCode = $R['collectionProfileCode'];
							$corporateCollectionEnt->save();
						} else {
							$corporateCollectionEnt = \Entity\CorporateCollection::insert();
							$corporateCollectionEnt->idCorporate = $id;
							$corporateCollectionEnt->active = true;
							$corporateCollectionEnt->profileCode = $R['collectionProfileCode'];
							$corporateCollectionEnt->save();
						}
					} elseif ($R['collectionProfileAction']=='delete') {
						if (\Entity\CorporateCollection::selectForUpdate($id)->recordExists()) {
							$corporateCollectionEnt = \Entity\CorporateCollection::delete($id);
							$corporateCollectionEnt->save();
						}
					}

					// UPDATE CORPORATE PREFERECENS (eg. compensation)-----------------------------
					if ($R['autoCompensationAction']=='delete') {
						\App\EntityPreference\Corporate::getInstance($id)->autoCompensateType = null;
					} elseif ($R['autoCompensationAction']=='update') {
						\App\EntityPreference\Corporate::getInstance($id)->autoCompensateType = $R['autoCompensationType'];
					}

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

					// action was successful
					$msgs->addSuccess($corporate->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());
	}

	/**
	 * Analyze the corporate profile and send if it is neccesary a collection reminder
	 * @param array $R
	 */
	public function actionSendAlert($R)
	{
		$msgs = \App\MessagesCollector::create();
		$this->setListingSelection($R['listing']['selection']);

		$ids = $this->getListingSelection()->getList();

		foreach ($ids as $id){

			$corporateEnt = \Entity\Corporate::select($id);
			$analyzer = new \App\ClientCollection\Corporate\Analyzer($id);
			$analyzer->analyze();

			$overdueInvoicesList = $analyzer->getOverdueInvoices();
			$dueInDaysInvoicesList = $analyzer->getDueInDaysInvoices();

			if (!$overdueInvoicesList and !$dueInDaysInvoicesList) {
				$msgs->addInfo(sprintf($this->lang['sendAlert']['messages']['sendAlert_noInvoices'], $corporateEnt->alias));
				continue;
			}

			if ($analyzer->getOverdueTotalDefCurr() + $analyzer->getDueInDaysTotalDefCurr() <= 0 ) {
				$msgs->addInfo(sprintf($this->lang['sendAlert']['messages']['sendAlert_invoicesNoTotal'], $corporateEnt->alias));
				continue;
			}

			$emailDataObj = new \App\ClientCollection\Corporate\EmailData($id);

			try {
				\DB::startTransaction();
				$corporateCollection = \Entity\CorporateCollection::sendEmail($id);
				$corporateCollection->executionType = 'manual';
				$corporateCollection->analyzer = $analyzer;
				$corporateCollection->emailData = $emailDataObj;

				$corporateCollection->save();
				\DB::commitTransaction();
				$msgs->addSuccess(sprintf($this->lang['sendAlert']['messages']['sendAlert_sendSuccess'], $corporateEnt->alias));
			}
			catch (\App\Entity\Exception|\App\MessagesException $e) {
				\DB::rollbackTransaction();
				$msgs->appendMessages($e->getMessagesCollector());
			}
		}

		return $this->executeListRecords($R, $msgs);

	}
}
