/**
  * Sets the cover levels
  *
  * @param float $sumInsured
  * @param bool $isNilExcess
  * @param string $referenceType
  * @param int $policyLength
  * @param bool $isPayMonthly
  * @param bool $isRentInAdvance
  * @return $this
  * @throws \RRP\Rate\Exception\BandAExceededException
  * @throws \RRP\Rate\Exception\BandBExceededException
  * @throws \RRP\Rate\Exception\UnhandledPolicyOptionsException
  * @throws \RRP\Rate\Exception\NilExcessNotAllowedException
  */
 public function setCoverAmounts($sumInsured, $isNilExcess, $referenceType, $policyLength, $isPayMonthly, $isRentInAdvance = false)
 {
     $this->isFullReference = ReferenceTypes::isFullReference($referenceType);
     if ($sumInsured > self::BAND_B_LIMIT) {
         throw new BandBExceededException();
     } else {
         if ($sumInsured > self::BAND_A_LIMIT) {
             if ($this->isFullReference) {
                 $this->band = self::BAND_B;
             } else {
                 throw new BandAExceededException();
             }
         } else {
             $this->band = self::BAND_A;
         }
     }
     if (!$this->isFullReference && $this->band != self::BAND_A) {
         throw new NilExcessNotAllowedException();
     } else {
         $this->isNilExcess = $isNilExcess;
     }
     if ($this->isFullReference) {
         if (!isset($this->fullReferenceRates[$policyLength][$isNilExcess][$this->band])) {
             $error = sprintf('PolicyLength:%d isNilExcess:%d Band:%d', $policyLength, $isNilExcess, $this->band);
             throw new UnhandledPolicyOptionsException($error);
         }
     } else {
         if (!isset($this->creditCheckRates[$policyLength])) {
             $error = sprintf('PolicyLength:%d', $policyLength);
             throw new UnhandledPolicyOptionsException($error);
         }
     }
     $this->policyLength = $policyLength;
     $this->isPayMonthly = $isPayMonthly;
     $this->isRentInAdvance = $isRentInAdvance;
     $this->calculatePremium();
     return $this;
 }
 /**
  * Sets the defaults for a new quote
  *
  * @param string $policyNumber
  * @param string $referenceType
  * @param bool $isContinuationOfExistingPolicy
  * @param string $propertyLetType
  * @param float $propertyDeposit
  * @param string $status
  * @return $this
  */
 public function setDefaults($policyNumber, $referenceType, $isContinuationOfExistingPolicy, $propertyLetType, $propertyDeposit, $status)
 {
     $this->setPolicyNumber($policyNumber)->getAppData()->setPolicyName('rentrecoveryp')->setIssueDate(date('d-m-Y'))->setCancelledDate('00-00-0000')->setPayStatus('')->setPayMethod('CreditAccount')->setPaidNet('no')->setPolicyType('A')->setStatus($status)->setDateOfLastPayment('')->setTimeCompleted('')->setWhiteLabelID('HL')->setOrigin(0)->setExcessID(0)->setStartTime('00:00:00');
     if (!ReferenceTypes::isProviderRequired($referenceType)) {
         $this->getRrpData()->setOtherProvider('');
     } else {
         $this->clearAllRrpTenantReferences();
     }
     if ($isContinuationOfExistingPolicy) {
         $this->getRrpData()->setIsExistingPolicyToBeCancelled(false);
     }
     if (!PropertyLetTypes::isLandlordPermissionRequired($propertyLetType)) {
         $this->getRrpData()->setHasLandlordPermission(false);
     }
     if ($propertyDeposit > 0.0) {
         $this->getRrpData()->setHasNilDepositInsurance(false);
     }
     return $this;
 }
 /**
  * Renew a policy from the 'temporary' insight_rrp_policy to the policy table
  *
  * @param string $rrpPolicyNumber
  * @param string $newPolicyNumber
  * @param string $termNumber
  * @return bool
  * @throws \RuntimeException
  */
 public function migratePolicy($rrpPolicyNumber, $newPolicyNumber, $termNumber)
 {
     if ($this->policyNumberManager->isRentRecoveryPlusInsightPolicy($rrpPolicyNumber)) {
         $this->setPolicyNumber($newPolicyNumber);
         $disbData = $this->disbursement->getDisbursement($this->appData->getWhiteLabelID(), $this->appData->getRateSetID());
         if (!$disbData) {
             $message = sprintf('Disbursement data not found (WhiteLabelId = %s, RateSetID = %d)', $this->appData->getWhiteLabelID(), $this->appData->getRateSetID());
             throw new \RuntimeException($message);
         }
         $getter = sprintf('getRrpi%s%dm', ReferenceTypes::isFullReference($this->rrpData->getReferenceType()) ? 'FullRef' : 'CreditCheck', $this->appData->getPolicyLength());
         if (PolicyOptionsManager::isOptionSet($this->appData->getPolicyOptions(), $this->container->get('rrp.legacy.const.policy_option_rrp-nilexcess'), $this->appData->getAmountsCovered())) {
             $getter .= '0xs';
         }
         if (!method_exists($disbData, $getter)) {
             $message = sprintf('Unknown disbursement type (%s)', $getter);
             throw new \RuntimeException($message);
         }
         $disbursement = $disbData->{$getter}();
         if (empty($disbursement)) {
             $message = sprintf('Disbursement data not set (WhiteLabelId = %s, RateSetID = %d, %s)', $this->appData->getWhiteLabelID(), $this->appData->getRateSetID(), $getter);
             throw new \RuntimeException($message);
         }
         $propertyRental = PolicyOptionsManager::getOption($this->appData->getPolicyOptions(), $this->getContainer()->get('rrp.legacy.const.policy_option_rrp'), $this->appData->getAmountsCovered());
         if ($propertyRental < RentRecoveryPlus::BAND_A_LIMIT) {
             $band = $disbData::BAND_A;
         } else {
             $band = $disbData::BAND_B;
         }
         $insuranceNetAmount = $disbData->extractBandDisbursement($disbursement, $band);
         // Policy Term
         $termId = $this->policyTerm->updatePolicyTerm($this->appData, $termNumber, array('netPremium' => $insuranceNetAmount, 'collectedPremium' => $this->appData->premium));
         if ($termId) {
             // Write the policy to the datasource
             $this->getAppData()->setStatus($this->container->get('rrp.legacy.const.status_policy'))->setTermId($termId);
             $legacyPolicy = $this->container->get('rrp.legacy.datasource.policy');
             $legacyPolicy->save($this->appData);
             // Delete the legacy insight record.
             $policyConstType = $this->container->get('rrp.legacy.const.quote_policy_number');
             $this->application->remove(array($policyConstType => $rrpPolicyNumber));
             $insightStatusIas = $this->container->get('rrp.legacy.const.insight_status_ias');
             // Now move the RRP / LL Interest parts
             if ($this->rrp->accept($rrpPolicyNumber, $newPolicyNumber, $insightStatusIas)) {
                 if ($this->llInterest->accept($rrpPolicyNumber, $newPolicyNumber)) {
                     /** @var RentRecoveryPlusAnswers $underwriting */
                     $underwriting = UnderwritingDecoratorFactory::getDecorator(UnderwritingDecoratorFactory::UNDERWRITING_RENT_RECOVERY_PLUS, $this->container->get('rrp.config.underwriting_question_set_id'), $this->appData->getIssueDate(), $rrpPolicyNumber);
                     $answers = $underwriting->getAllAnswers();
                     $answers[RentRecoveryPlusAnswers::QUESTION_ID_RENT_IN_ADVANCE] = true;
                     $answers[RentRecoveryPlusAnswers::QUESTION_ID_PRIOR_CLAIMS] = false;
                     $answers[RentRecoveryPlusAnswers::QUESTION_ID_DEPOSIT_SUFFICIENT] = true;
                     $underwriting->setAnswers($answers)->saveAnswers()->changeQuoteToPolicy($newPolicyNumber);
                     $coverOptions = array();
                     foreach ($this->appData->getValidPolicyOptionNames() as $optionName) {
                         if (PolicyOptionsManager::isOptionSet($this->appData->getPolicyOptions(), $optionName, $this->appData->getAmountsCovered())) {
                             $optionId = $this->policyOptions->fetchOptionsByName($optionName);
                             $sumInsured = PolicyOptionsManager::getOption($this->appData->getPolicyOptions(), $optionName, $this->appData->getAmountsCovered());
                             $premium = PolicyOptionsManager::getOption($this->appData->getPolicyOptions(), $optionName, $this->appData->getOptionPremiums());
                             $coverOptions[] = array('policyNumber' => $newPolicyNumber, 'policyOptionID' => $optionId, 'sumInsured' => $sumInsured, 'premium' => $premium);
                         }
                     }
                     $this->policyCover->setCover($newPolicyNumber, $coverOptions);
                     return $newPolicyNumber;
                 }
             }
         }
     }
     return false;
 }
 /**
  * Gets an array of referral reasons
  *
  * @return array
  */
 public function getReferralReason()
 {
     $reasons = array();
     if ($this->hasPossibleClaimCircumstances) {
         $reasons[] = 'There are circumstances that may give rise to a claim as follows:';
         $reasons[] = '  ' . $this->claimInfo;
     }
     if (!$this->hasPermittedOccupiersOnly) {
         $reasons[] = 'The property has does not have only permitted occupiers.';
     }
     if ($this->hasTenancyDisputes) {
         $reasons[] = 'There are tenancy disputes or late payment of rent issues.';
     }
     if ($this->hasPriorClaims) {
         $reasons[] = 'There have been claims logged during the existing tenancy.';
     }
     if (!$this->isDepositSufficient) {
         $reasons[] = 'A deposit with a sum equivalent to (or greater than) 1 months rent was not taken prior to the commencement of the tenancy.';
     }
     if ($this->propertyRental > RentRecoveryPlus::BAND_B_LIMIT) {
         $reasons .= 'There monthly rental exceeds the upper limit of £' . RentRecoveryPlus::BAND_B_LIMIT;
     }
     if ($this->propertyDeposit <= 0.0 && (self::SOURCE_APPLICATION == $this->source || self::SOURCE_RENT_RECOVERY_PLUS == $this->source)) {
         $reasons[] = 'No deposit has been paid.';
     }
     if (!$this->hasPaidRentInAdvance && (self::SOURCE_APPLICATION == $this->source || self::SOURCE_RENT_RECOVERY_PLUS == $this->source)) {
         $reasons[] = 'No rent has been paid in advance.';
     }
     if (!$this->isAssuredShortholdTenancy) {
         $reasons[] = 'There is not a Assured Shorthold Tenancy agreement.';
     }
     if (!$this->hasProviderBeenChecked && ReferenceTypes::isProviderRequired($this->referenceType) && (self::SOURCE_APPLICATION == $this->source || self::SOURCE_RENT_RECOVERY_PLUS == $this->source)) {
         if ($this->otherProvider == '') {
             $reasons[] = 'The reference was provided by another provider';
         } else {
             $reasons[] = 'The reference was provided by ' . $this->otherProvider;
         }
     }
     if ($this->isContinuationOfExistingPolicy && (self::SOURCE_APPLICATION == $this->source || self::SOURCE_RENT_RECOVERY_PLUS == $this->source)) {
         $reasons[] .= 'This is the continuation of existing policy ' . $this->existingPolicyRef . '. As such the no claims period is waived so we need to consider if it is acceptable' . ' and to ensure the relevant endorsement is applied if it is agreed.';
     }
     $now = new \DateTime();
     $now->setTime(0, 0, 0);
     if ($this->policyStartAt < $now) {
         $reasons[] .= 'The policy start date has already passed.';
     }
     if (count($reasons) == 0) {
         $reasons[] = 'The premium calculation failed';
     }
     return $reasons;
 }
 /**
  * @inheritdoc
  */
 public function accept($policyNumber, $mtaId)
 {
     /** @var \RRP\Application\Decorators\RentRecoveryPlusPolicy $policy */
     $policy = ApplicationDecoratorFactory::getDecorator('RentRecoveryPlusPolicy');
     $policy->populateByPolicyNumber($policyNumber);
     $this->legacyMtaData = $this->legacyMta->getByMtaID($mtaId);
     $this->rrpMtaData = $this->rrpMta->getRentRecoveryPlusMta($mtaId);
     $proRataPremium = $policy->getAppData()->getPremium() + $this->legacyMtaData->getPremium();
     $proRataQuote = $policy->getAppData()->getQuote() + $this->legacyMtaData->getQuote();
     $proRataIpt = $policy->getAppData()->getIpt() + $this->legacyMtaData->getIpt();
     $propertyRental = PolicyOptionsManager::getOption($this->legacyMtaData->getPolicyOptions(), $this->getContainer()->get('rrp.legacy.const.policy_option_rrp'), $this->legacyMtaData->getAmountscovered());
     $isNilExcess = PolicyOptionsManager::isOptionSet($this->legacyMtaData->getPolicyOptions(), $this->getContainer()->get('rrp.legacy.const.policy_option_rrp-nilexcess'), $this->legacyMtaData->getAmountscovered());
     $policyPremium = PolicyOptionsManager::getOption($policy->getAppData()->getPolicyOptions(), $this->getContainer()->get('rrp.legacy.const.policy_option_rrp'), $policy->getAppData()->getOptionPremiums());
     $mtaPremium = PolicyOptionsManager::getOption($this->legacyMtaData->getPolicyOptions(), $this->getContainer()->get('rrp.legacy.const.policy_option_rrp'), $this->legacyMtaData->getOptionPremiums());
     $optionPremiums = PolicyOptionsManager::addPolicyOption($policyPremium + $mtaPremium);
     if ($isNilExcess) {
         $policyNilExcessOption = PolicyOptionsManager::getOption($policy->getAppData()->getPolicyOptions(), $this->getContainer()->get('rrp.legacy.const.policy_option_rrp-nilexcess'), $policy->getAppData()->getOptionPremiums());
         $mtaNilExcessOption = PolicyOptionsManager::getOption($this->legacyMtaData->getPolicyOptions(), $this->getContainer()->get('rrp.legacy.const.policy_option_rrp-nilexcess'), $this->legacyMtaData->getOptionPremiums());
         $optionPremiums = PolicyOptionsManager::addPolicyOption($policyNilExcessOption + $mtaNilExcessOption, $optionPremiums);
     }
     $policy->getAppData()->setPolicyOptions($this->legacyMtaData->getPolicyOptions())->setAmountsCovered($this->legacyMtaData->getAmountscovered())->setOptionPremiums($optionPremiums)->setPremium($proRataPremium)->setQuote($proRataQuote)->setIpt($proRataIpt);
     $policy->getRrpData()->setClaimInfo($this->rrpMtaData->getClaimInfo());
     $disbData = $this->disbursement->getDisbursement($policy->getAppData()->getWhiteLabelID(), $policy->getAppData()->getRateSetID());
     if (!$disbData) {
         $message = sprintf('Disbursement data not found (WhiteLabelId = %s, RateSetID = %d)', $policy->getAppData()->getWhiteLabelID(), $policy->getAppData()->getRateSetID());
         throw new \RuntimeException($message);
     }
     $getter = sprintf('getRrpi%s%dm', ReferenceTypes::isFullReference($policy->getRrpData()->getReferenceType()) ? 'FullRef' : 'CreditCheck', $policy->getAppData()->getPolicyLength());
     if ($isNilExcess) {
         $getter .= '0xs';
     }
     if (!method_exists($disbData, $getter)) {
         $message = sprintf('Unknown disbursement type (%s)', $getter);
         throw new \RuntimeException($message);
     }
     $disbursement = $disbData->{$getter}();
     if (empty($disbursement)) {
         $message = sprintf('Disbursement data not set (WhiteLabelId = %s, RateSetID = %d, %s)', $policy->getAppData()->getWhiteLabelID(), $policy->getAppData()->getRateSetID(), $getter);
         throw new \RuntimeException($message);
     }
     $termData = $this->policyTerm->getPolicyTerm($policy->getAppData()->getPolicyNumber(), $policy->getAppData()->getStartDate());
     if (!$termData->id) {
         throw new \RuntimeException('Invalid Term Id');
     }
     if ($propertyRental < RentRecoveryPlus::BAND_A_LIMIT) {
         $band = $disbData::BAND_A;
         $transBand = RentRecoveryPlus::BAND_A;
     } else {
         $band = $disbData::BAND_B;
         $transBand = RentRecoveryPlus::BAND_B;
     }
     $insuranceNetAmount = $disbData->extractBandDisbursement($disbursement, $band);
     $proRataCalcs = new ProRataCalculations($policy->getAppData()->getStartDate(), $this->legacyMtaData->getDateOnRisk());
     $netPremium = $proRataCalcs->getProRata($policy->getAppData()->getPolicyLength(), $policy->getAppData()->getPolicyLength(), $insuranceNetAmount, $termData->netPremium);
     $this->policyTerm->updatePolicyTerm($policy->getAppData(), $termData->term, array('netPremium' => $netPremium));
     $this->policyNotes->addNote($policyNumber, $this->legacyMtaData->getDisplayNotes());
     if ($policy->save()) {
         if ($this->legacyMta->updateStatus($policyNumber, $mtaId, $this->mtaStatusLive)) {
             $coverOptions = array();
             foreach ($policy->getAppData()->getValidPolicyOptionNames() as $optionName) {
                 if (PolicyOptionsManager::isOptionSet($policy->getAppData()->getPolicyOptions(), $optionName, $policy->getAppData()->getAmountsCovered())) {
                     $optionId = $this->policyOptions->fetchOptionsByName($optionName);
                     $sumInsured = PolicyOptionsManager::getOption($policy->getAppData()->getPolicyOptions(), $optionName, $policy->getAppData()->getAmountsCovered());
                     $premium = PolicyOptionsManager::getOption($policy->getAppData()->getPolicyOptions(), $optionName, $policy->getAppData()->getOptionPremiums());
                     $coverOptions[] = array('policyNumber' => $policyNumber, 'policyOptionID' => $optionId, 'sumInsured' => $sumInsured, 'premium' => $premium);
                 }
             }
             $this->policyCover->setCover($policyNumber, $coverOptions);
             if ($this->legacyMtaData->getPremium() == 0) {
                 //If no premium change there's no need to store anything in the transaction
                 return true;
             }
             $transaction = TransactionDecoratorFactory::getDecorator(TransactionDecoratorFactory::TRANSACTION_UPDATE, $policy->getAppData()->getPremium(), $insuranceNetAmount, $termData->id, $mtaId, $transBand, $this->legacyMtaData->getDateOnRisk(), $policy->getAppData());
             $transaction->processAllTransactions();
             return true;
         }
     }
     return false;
 }
 /**
  * Validation function for optional constraints
  *
  * @param RentRecoveryPlusMta $mta
  * @param ExecutionContextInterface $context
  */
 public function checkRateBandLimits($mta, ExecutionContextInterface $context)
 {
     if (ReferenceTypes::isOnlyAllowBandA($mta->getReferenceType()) && $mta->getPropertyRental() > RentRecoveryPlus::BAND_A_LIMIT) {
         $context->addViolationAt('propertyRental', 'Monthly rental amount cannot be greater than £' . RentRecoveryPlus::BAND_A_LIMIT, array(), null);
     } else {
         if ($mta->getPropertyRental() > RentRecoveryPlus::BAND_B_LIMIT) {
             $context->addViolationAt('propertyRental', 'Monthly rental amount cannot be greater than £' . RentRecoveryPlus::BAND_B_LIMIT, array(), null);
         }
     }
 }
 /**
  * Accept the quote and change it to a policy
  *
  * @param string $quoteNumber
  * @return null|string
  * @throws \RuntimeException
  */
 public function acceptQuote($quoteNumber)
 {
     /** @var \Manager_Core_PolicyNumber $policyNumberManager */
     $policyNumberManager = $this->getContainer()->get('rrp.legacy.manager.policy_number');
     if ($policyNumberManager->isRentRecoveryPlusQuote($quoteNumber)) {
         $this->isNewApplication = false;
         $policyNumber = $policyNumberManager::convertQuoteToPolicyNumber($quoteNumber);
         if ($this->populateByPolicyNumber($quoteNumber)) {
             //Set the issueDate and timecompleted fields (which oddly record the same value but
             // in different formats).
             $timeCompleted = time();
             $issueDate = new \DateTime();
             $issueDate->setTimestamp($timeCompleted);
             $this->setPolicyNumber($policyNumber)->appData->setStatus($this->getContainer()->get('rrp.legacy.const.status_policy'))->setPayStatus($this->getContainer()->get('rrp.legacy.const.pay_status_up-to-date'))->setIssueDate($issueDate)->setTimeCompleted($timeCompleted);
             $disbData = $this->disbursement->getDisbursement($this->appData->getWhiteLabelID(), $this->appData->getRateSetID());
             if (!$disbData) {
                 $message = sprintf('Disbursement data not found (WhiteLabelId = %s, RateSetID = %d)', $this->appData->getWhiteLabelID(), $this->appData->getRateSetID());
                 throw new \RuntimeException($message);
             }
             $getter = sprintf('getRrpi%s%dm', ReferenceTypes::isFullReference($this->rrpData->getReferenceType()) ? 'FullRef' : 'CreditCheck', $this->appData->getPolicyLength());
             if (PolicyOptionsManager::isOptionSet($this->appData->getPolicyOptions(), $this->container->get('rrp.legacy.const.policy_option_rrp-nilexcess'), $this->appData->getAmountsCovered())) {
                 $getter .= '0xs';
             }
             if (!method_exists($disbData, $getter)) {
                 $message = sprintf('Unknown disbursement type (%s)', $getter);
                 throw new \RuntimeException($message);
             }
             $disbursement = $disbData->{$getter}();
             if (empty($disbursement)) {
                 $message = sprintf('Disbursement data not set (WhiteLabelId = %s, RateSetID = %d, %s)', $this->appData->getWhiteLabelID(), $this->appData->getRateSetID(), $getter);
                 throw new \RuntimeException($message);
             }
             $propertyRental = PolicyOptionsManager::getOption($this->appData->getPolicyOptions(), $this->getContainer()->get('rrp.legacy.const.policy_option_rrp'), $this->appData->getAmountscovered());
             if ($propertyRental < RentRecoveryPlus::BAND_A_LIMIT) {
                 $band = $disbData::BAND_A;
                 $transBand = RentRecoveryPlus::BAND_A;
             } else {
                 $band = $disbData::BAND_B;
                 $transBand = RentRecoveryPlus::BAND_B;
             }
             $insuranceNetAmount = $disbData->extractBandDisbursement($disbursement, $band);
             $termId = $this->policyTerm->insertPolicyTerm($this->appData, $insuranceNetAmount);
             if ($termId) {
                 $policy = $this->container->get('rrp.legacy.datasource.policy');
                 if ($policy->save($this->appData)) {
                     //Delete the legacy quote.
                     $policyConstType = $this->container->get('rrp.legacy.const.quote_policy_number');
                     $this->application->remove(array($policyConstType => $quoteNumber));
                     // Now move the RRP / LL Interest parts
                     if ($this->rrp->accept($quoteNumber, $policyNumber)) {
                         if ($this->rrpTenantReference->accept($quoteNumber, $policyNumber, $termId)) {
                             if ($this->llInterest->accept($quoteNumber, $policyNumber)) {
                                 $this->policyNotes->changeQuoteToPolicy($quoteNumber, $policyNumber);
                                 $transaction = TransactionDecoratorFactory::getDecorator(TransactionDecoratorFactory::TRANSACTION_ADD, $this->getAppData()->getPremium(), $insuranceNetAmount, $termId, 0, $transBand, $this->appData->getStartDate(), $this->appData);
                                 $transaction->processAllTransactions();
                                 $underwriting = UnderwritingDecoratorFactory::getDecorator(UnderwritingDecoratorFactory::UNDERWRITING_RENT_RECOVERY_PLUS, $this->container->get('rrp.config.underwriting_question_set_id'), $this->appData->getIssueDate(), $quoteNumber);
                                 $underwriting->changeQuoteToPolicy();
                                 /** @var \Datasource_Insurance_Policy_Cover $policyCover */
                                 $policyCover = $this->container->get('rrp.legacy.datasource.policy_cover');
                                 $policyCover->changeQuoteToPolicy($quoteNumber, $policyNumber);
                                 return $policyNumber;
                             }
                         }
                     }
                 }
             }
         }
     }
     return null;
 }