<?php

///////////////////////////////////////////////////////////////////////////////////////////////////
// ADD OFFER //////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////

if ( $R['addOffer'] ) {

	$OK=1;


	DB::startTransaction();

	// TEST REQUEST VARS //////////////////////////////////////////////////////////////////////////

	$idSupplier=$R['idSupplier'];

	// test supplier id
	if ( !is_numeric($R['idSupplier']) or $R['idSupplier']<=0) {
		$showMessage['warning'] = $_LANG['reservations']['serviceOffers']['phpMessages']['offerAddNoSupplier'];
		$OK=0;
		writeLog('Possible problem. Offer adding with not enough data (no supplier)', 'events', 4);
	}

	$offerType=$R['offerType'];

	// test offer type
	if ( !$offerType or !$CFG['offers']['listAllOfferTypes'][$offerType] ) {
		$showMessage['warning'] = $_LANG['reservations']['serviceOffers']['phpMessages']['offerAddNoOfferType'];
		$OK=0;
		writeLog('Possible problem. Offer adding with not enough data (no offerType)', 'events', 6);
	}

	// get location and calculation type
	$calculationArr=explode('|', $R['calculationType']);

	$location=$calculationArr[0];
	$calculationType=$calculationArr[1];

	// test location and calculation type
	if ( !$location or !is_numeric($calculationType) or $calculationType<0 ) {
		$showMessage['warning'] = $_LANG['reservations']['serviceOffers']['phpMessages']['offerAddNoCalculationType'];
		$OK=0;
		writeLog('Possible problem. Offer adding with not enough data (no location or calculationType)', 'events', 7);
	}

	// currency last update
	$currencyDate=\App\CurrencyExchange\Date::getInstance()->getLastDefinedDate();
	if (!$currencyDate) {
		$showMessage['warning'] = $_LANG['reservations']['serviceOffers']['phpMessages']['offerAddNoCurrencyExchangeRates'];
		$OK=0;
	}

	// test that offers count does not exceed the max limit ///////////////////////////////////////
	if ($CFG['reservations']['offers']['maxOffersPerService']) {
		// check the limit of offers
		if ($currentOfferCount>=$CFG['reservations']['offers']['maxOffersPerService']) {
			$showMessage['warning'] = $_LANG['reservations']['serviceOffers']['phpMessages']['offerAddNoOtherOffersAllowed'];
			$OK=0;
		}
	}

	// test if service is not cancelled
	if ($serviceStatusOp=="XX") {
		$showMessage['warning'] = $_LANG['reservations']['serviceOffers']['phpMessages']['cantAddOfferOnCancelledServ'];
		$OK=0;
	}

	// test that user has access
	if (!$S['auth']['userOptionsAccess']['reservationServiceOfferAdd']) {
		$showMessage['warning'] = $_LANG['noAccessToOption'];
		$OK=0;
	}

	// test that supplier is not locked / and rewrite id if supplier is duplicated
	if ($OK) {

		$getSupplierDetSQL="SELECT id, alias, locked, idRealSupplier, countryCode FROM `$DBTSuppliers` WHERE id='".$idSupplier."' AND deleted='0'";
		$getSupplierDetArr=$db->GetRow($getSupplierDetSQL);

		// check sql
		if (!is_array($getSupplierDetArr)) {
			writeLog("Could not get supplier lock status. SQL: ".$getSupplierDetSQL, 'events', 10);
			$showMessage['error'] = $_LANG['reservations']['serviceOffers']['phpMessages']['couldNotCheckSuppLock'];
			$OK=0;
		} else {
			// check if supplier is locked
			if ($getSupplierDetArr['locked']) {
				$showMessage['warning'] = $_LANG['reservations']['serviceOffers']['phpMessages']['suppIsLocked'];
				$OK=0;
			}
			// check if the id of the supplier is ok
			if (!$getSupplierDetArr['id']) {
				$showMessage['warning'] = $_LANG['reservations']['serviceOffers']['phpMessages']['suppIdIsBad'];
				$OK=0;
			}
			// rewrite with id real supplier
			if ($getSupplierDetArr['idRealSupplier']) {
				$idSupplier=$getSupplierDetArr['idRealSupplier'];
			}
		}
	}

	// test if service is parent and offer mode is reference
	if ($serviceDetails['packageOfferMode']=="reference") {
		$showMessage['warning'] = $_LANG['reservations']['serviceOffers']['phpMessages']['serviceHasReferenceOffer'];
		$OK=0;
	}

	// CHECK IF THE SUPPLIER CAN BE ADDED ON THIS SERVICE TYPE ////////////////////////////////////
	if ($OK) {
		$suppServListBulk=\App\EntityPreference\Supplier::getInstance($idSupplier)->availableServicesList;
		if ($suppServListBulk) {
			$suppServList=unserialize($suppServListBulk);
			if ($suppServList and !in_array($serviceCode, $suppServList)) {
				$showMessage['warning'] = sprintf($_LANG['reservations']['serviceOffers']['phpMessages']['supplierServiceCodeNotAvailable'], $getSupplierDetArr['alias']);
				$OK=0;
			}
		}
	}

	// CHECK TABLES AUTOINCREMENT /////////////////////////////////////////////////////////////////
	if ($OK) {
		\App\Utils\Db\TablesUtils::getInstance()->checkMonthTableAutoincrement($DBTReservationServiceOffers, $tableTime);
		\App\Utils\Db\TablesUtils::getInstance()->checkMonthTableAutoincrement($DBTReservationServiceOfferItems, $tableTime);
	}

	// plugin trigger
	if ($OK) {
		\Engine\Plugins\Manager::getInstance()->executeEvent("serviceOffers-offersAdd-validate");
	}

	// rollback if anything is wrong
	if (!$OK) {
		DB::rollbackTransaction();
	}

	///////////////////////////////////////////////////////////////////////////////////////////////
	// ADD OFFER INTO DATABASE ////////////////////////////////////////////////////////////////////
	// VARS: $idSupplier, $location, $calculationType /////////////////////////////////////////////
	///////////////////////////////////////////////////////////////////////////////////////////////
	if ($OK) {

		// ASSOCIATE idSupplierProduct ////////////////////////////////////////////////////////////
		if ($R['idSupplierProduct']) {
			$idSupplierProduct=$R['idSupplierProduct'];
		} else {
			$idSupplierProduct=0;
		}

		// ASSOCIATE SUPPLIER SERVICE TO THE SUPPLIER /////////////////////////////////////////////
		if ($R['associateServiceToSupplier']) {
			$updateSupplierProdSQL="
				REPLACE `$DBTSuppliersProductsAssoc`  (idSupplier, idSupplierProduct)
				VALUES ('".$idSupplier."', '".$idSupplierProduct."')
			";
			$updateSupplierProdEx=$db->Execute($updateSupplierProdSQL);
			if (!$updateSupplierProdEx)
				writeLog("Could not associate supplier with supplier service.", 'events', 10);
		}

		///////////////////////////////////////////////////////////////////////////////////////////
		// BLOCK THE DELETION OF THIS SUPPLIER (canDelete=0) //////////////////////////////////////
		///////////////////////////////////////////////////////////////////////////////////////////
		$updateSupplierSQL="UPDATE `$DBTSuppliers` SET canDelete=0 WHERE id='".$idSupplier."'";
		$updateSupplierEx=$db->Execute($updateSupplierSQL);
		// if sql failed
		if (!$updateSupplierEx)
			writeLog("Could not update this supplier. SQL: ".$updateSupplierSQL, 'events', 9);


		///////////////////////////////////////////////////////////////////////////////////////////
		// COLLECT ALL NECESSARY DATA TO ADD THIS OFFER ///////////////////////////////////////////
		///////////////////////////////////////////////////////////////////////////////////////////

		// calculations details (configs) - offerDefaultCurrency, serviceFeeDefaultCurrency, totalDefaultCurrency
		$cfgObj = \App\Config\Services_Calculations_OfferDefaults::getInstance();
		$offerCalculationsCfgDetails = $cfgObj->getCalculationDetails($serviceCode, $location, $calculationType);

		$totalDefaultCurrency=$offerCalculationsCfgDetails['totalCurrency'];
		$currencyType=$offerCalculationsCfgDetails['currencyType'];
		$ignoreSupplierOnDocuments = ( \App\Config\Services_OfferDetails::getInstance()->getIgnoreSupplierOnDocuments($serviceCode) == 'defaultSelected' );

		// offer calculation VATs (configs) - supplierVatIncluded, commissionVatIncluded, discountVatIncluded, serviceFeeVatIncluded, taxVatIncluded
		$offerCfgVats=\App\Config\Services_Calculations_OfferVat::getInstance()->getCalculationDetails($serviceCode, $location, $calculationType);
		$offerExpirationDate=OfferDetails::determineOfferExpirationDate($serviceCode, TODAY_ISO, $serviceStartDate);
		if ($offerExpirationDate) {
			$offerExpirationDate = "'{$offerExpirationDate}'";
		} else {
			$offerExpirationDate = "NULL";
		}



		// GET PROFILE DETAILS ////////////////////////////////////////////////////////////////////
		$servEnt = \Entity\Service::select($idService);
		$profileFields = new \App\OfferProfileRules\Fields();

		$profileFields->operation = 'issue';
		$profileFields->serviceCode = $serviceCode;
		$profileFields->offerLocation = $location;
		$profileFields->offerStartDate = $servEnt->startDate;
		$profileFields->populateFromServiceEntitySelect($servEnt);
		$profileFields->idSupplier = $idSupplier;
		$profileFields->supplierCategory = \Entity\Supplier::select($idSupplier)->category;
		$profileFields->offerIdSupplierProduct = $idSupplierProduct;
		$profileFields->offerDepartureCountryCode = $servEnt->departureCountryCode;
		$profileFields->offerDepartureCityId = $servEnt->departureCityId;
		$profileFields->offerDepartureStationCode = $servEnt->departureStationCode;
		$profileFields->offerDestinationCountryCode = $servEnt->destinationCountryCode;
		$profileFields->offerDestinationCityId = $servEnt->destinationCityId;
		$profileFields->offerDestinationStationCode = $servEnt->destinationStationCode;

		$getProfile = new \App\OfferProfileRules\GetProfile($profileFields);
		$getProfile->search();

		$appliedOfferProfileRules = [
			'commission' => null,
			'discount' => null,
			'serviceFee' => null,
		];

		// STORE THE COMMISSION DETAILS -----------------------------------------------------------
		$commissionData = [];
		if ($getProfile->getCommissionDetails()) {
			$commissionData = [
				'commissionable' => (String)$getProfile->getCommissionDetails()->included,
				'percent' =>		$getProfile->getCommissionDetails()->percent,
				'value' =>			$getProfile->getCommissionDetails()->value,
				'currency' =>		$getProfile->getCommissionDetails()->currency,
			];
			// rewrite the currency with the default offer currency
			if ($commissionData['percent'] or !$commissionData['currency']) {
				$commissionData['currency'] = $offerCalculationsCfgDetails['offerCurrency'];
			}
			$appliedOfferProfileRules['commission'] = (Int)$getProfile->getIdMatchedRule_commission();
		} else {
			$commissionData['currency'] = $offerCalculationsCfgDetails['offerCurrency'];
		}
		if (!isset($commissionData['commissionable'])) {
			$commissionData['commissionable'] = true;
		}

		// STORE THE SERVICE FEE DETAILS ----------------------------------------------------------
		$serviceFeeData = [];
		if ($getProfile->getServiceFeeDetails()) {
			$serviceFeeData['currency'] = $getProfile->getServiceFeeDetails()->currency;
			$serviceFeeData['mode'] = $getProfile->getServiceFeeDetails()->mode;
			$serviceFeeData['percentSource'] = $getProfile->getServiceFeeDetails()->percentSource;
			$serviceFeeData['percent'] = $getProfile->getServiceFeeDetails()->percent;
			$serviceFeeData['value'] = $getProfile->getServiceFeeDetails()->value;
			$appliedOfferProfileRules['serviceFee'] = (Int)$getProfile->getIdMatchedRule_serviceFee();
		}
		if (!$serviceFeeData['currency']) {
			$serviceFeeData['currency'] = $offerCalculationsCfgDetails['serviceFeeCurrency'];
		}
		if (!$serviceFeeData['mode']) {
			$serviceFeeData['mode'] = $CFG['reservations']['offers']['serviceFeeMode'];
		}
		if (!$serviceFeeData['percentSource']) {
			$serviceFeeData['percentSource'] = $CFG['reservations']['offers']['serviceFeePercentSource'];
		}

		// STORE THE DISCOUNT DETAILS -------------------------------------------------------------
		$discountData = [];
		if ($getProfile->getDiscountDetails()) {
			$discountData['percentSource'] = $getProfile->getDiscountDetails()->percentSource;
			$discountData['percent'] = $getProfile->getDiscountDetails()->percent;
			$discountData['value'] = $getProfile->getDiscountDetails()->value;
			$discountData['currency'] = $getProfile->getDiscountDetails()->currency;

			// rewrite the currency with the default offer currency
			if ($discountData['percent'] or !$discountData['currency']) {
				$discountData['currency'] = $offerCalculationsCfgDetails['offerCurrency'];
			}
			$appliedOfferProfileRules['discount'] = (Int)$getProfile->getIdMatchedRule_discount();
		} else {
			$discountData['supplierCurrency'] = $offerCalculationsCfgDetails['offerCurrency'];
			$discountData['commissionCurrency'] = $offerCalculationsCfgDetails['offerCurrency'];
			$discountData['serviceFeeCurrency'] = $offerCalculationsCfgDetails['offerCurrency'];
			$discountData['currency'] = $offerCalculationsCfgDetails['offerCurrency'];
		}

		// force percentSource
		if (!$discountData['percentSource']) {
			$discountData['percentSource']=$CFG['reservations']['offers']['discountPercentSource'];
		}

		$extraInfo = ['appliedOfferProfileRules'=>$appliedOfferProfileRules];
		$extraInfoStr = serialize($extraInfo);


		///////////////////////////////////////////////////////////////////////////////////////////
		// ADD OFFER INTO DATABASE ////////////////////////////////////////////////////////////////
		///////////////////////////////////////////////////////////////////////////////////////////

		$insertOfferSQL="
			INSERT INTO `$DBTReservationServiceOffers$tableTime`
			(
				`deleted` , `calculated` , `idReservationService` ,
				`idSupplierProduct` , `idSupplier` , `productName` ,
				`offerType` , `serviceCode` , `location` , `calculationType` ,
				`commissionable` , `discountPercentSource`, `serviceFeeMode`, `serviceFeePercentSource`, `currencyType` , `currencyDate` ,
				`offerCurrency` , `serviceFeeCurrency` , `totalCurrency` , `ignoreSupplierOnDocuments`,
				`supplierVatIncluded`, `commissionVatIncluded`, `discountVatIncluded`, `serviceFeeVatIncluded`, `taxVatIncluded`,
				`startDatetime`, `endDatetime`, `duration`,
				`departureCountryCode`, `departureCityId`, `departureStationCode`,
				`destinationCountryCode`, `destinationCityId`, `destinationStationCode`,
				`extraInfo`, `expirationDate`, `idAddUser` , `addTime`
			) VALUES (
				'0', '0', '".$idService."',
				'".$idSupplierProduct."', '".$idSupplier."', '".$serviceDetails['productName']."',
				'".$offerType."', '".$serviceCode."', '".$location."', '".$calculationType."',
				'".$commissionData['commissionable']."', '".$discountData['percentSource']."', '".$serviceFeeData['mode']."', '".$serviceFeeData['percentSource']."', '".$currencyType."', '".$currencyDate."',
				'".$offerCalculationsCfgDetails['offerCurrency']."', '".$offerCalculationsCfgDetails['serviceFeeCurrency']."', '".$totalDefaultCurrency."', '".$ignoreSupplierOnDocuments."',
				'".$offerCfgVats['supplier']['included']."', '".$offerCfgVats['commission']['included']."', '".$offerCfgVats['discount']['included']."', '".$offerCfgVats['serviceFee']['included']."', '".$offerCfgVats['tax']['included']."',
				'{$serviceDetails['startDate']} {$serviceDetails['startTime']}', '{$serviceDetails['endDate']} {$serviceDetails['endTime']}', '{$serviceDetails['duration']}',
				'{$serviceDetails['departureCountryCode']}', '{$serviceDetails['departureCityId']}', '{$serviceDetails['departureStationCode']}',
				'{$serviceDetails['destinationCountryCode']}', '{$serviceDetails['destinationCityId']}', '{$serviceDetails['destinationStationCode']}',
				'{$extraInfoStr}', {$offerExpirationDate}, '".CURRENT_ID_USER."', '".TIMESTAMP."'
			)


		";
		$insertOfferEx=$db->Execute($insertOfferSQL);

		// if SQL failed
		if (!$insertOfferEx) {
			writeLog("Offer could not be added. SQL:".$insertOfferSQL, 'events', 10);
			$OK=0;
			$showMessage['error'] = $_LANG['reservations']['serviceOffers']['phpMessages']['offerAddOfferPivotAddFailed'];
		}
		// this newly added
		$idOffer=$db->Insert_ID();
		// test id offer
		if (!$idOffer) {
			writeLog("Added offer id could not be obtained.", 'events', 10);
			$OK=0;
			$showMessage['error'] = $_LANG['reservations']['serviceOffers']['phpMessages']['offerAddIdFailed'];
		}

		// ADD OFFER DETAILS //////////////////////////////////////////////////////////////////////
		if ($OK) {

			// increase the current number of offers
			$currentOfferCount++;

			// add offer items
			include("offers_add_offerItems.php");

		}

		// TEST IF OFFER ADDING WAS OK AND DISPLAY MESSAGE ////////////////////////////////////////
		if ($OK) {
			$showMessage['success'] = $_LANG['reservations']['serviceOffers']['phpMessages']['offerAddOk'];

			DB::commitTransaction();

			// store some data regarding the newly added offer
			$addOfferId=$idOffer;
			$addOfferCurrencyType=$currencyType;
			$addOfferCurrencyDate=$currencyDate;

			// trace visit
			$userTrailItem->updateActionOld('reservationServiceOfferAdd');
			$userTrailItem->updateEntityOld('serviceOffer', $idOffer);

		} else {
			if (!$showMessage) {
				$showMessage['error'] = $_LANG['reservations']['serviceOffers']['phpMessages']['offerAddBad'];
			}
			DB::rollbackTransaction();
		}

	}

}

?>