/**
  * {@inheritdoc}
  */
 public function buildForm(FormBuilderInterface $builder, array $options)
 {
     // Minimum tenancy start date for back-end validation
     $minTenancyStartDate = new \DateTime();
     $minTenancyStartDate->sub(new \DateInterval('P1D'));
     // Maximum tenancy start date for back-end validation
     // todo: Properly parameterise how far ahead tenancy start dates can be.
     $maxTenancyStartDays = 200;
     $maxTenancyStartDate = new \DateTime();
     $maxTenancyStartDate->add(new \DateInterval('P' . $maxTenancyStartDays . 'D'));
     // Minimum and maximum tenancy start years for front end
     $minTenancyStartDateYear = $minTenancyStartDate->format('Y');
     $maxTenancyStartDateYear = $maxTenancyStartDate->format('Y');
     $tenancyStartYears = array();
     // Add earliest year
     $tenancyStartYears[$minTenancyStartDateYear] = $minTenancyStartDateYear;
     // If latest year is different to earliest, add it too
     if ($minTenancyStartDateYear != $maxTenancyStartDateYear) {
         $tenancyStartYears[$maxTenancyStartDateYear] = $maxTenancyStartDateYear;
     }
     $builder->add('address', new AddressType())->add('totalRent', new MoneyWithoutStringTransformerType(), array('currency' => 'GBP', 'constraints' => array(new Assert\GreaterThan(array('value' => 0)), new Assert\NotBlank(), new Assert\Regex(array('pattern' => '/^([0-9]+\\.[0-9]{0,2}|[0-9]+)$/', 'message' => 'Amount must either have 2 decimal places or a whole number, e.g. "15000.00" or "15000"'))), 'label' => 'Total Rent (£ Per Calendar Month)'))->add('rentGuaranteeOfferingType', 'choice', array('choices' => Lookup::getInstance()->getCategoryAsChoices(LookupCategoryOptions::RENT_GUARANTEE_OFFERING_TYPE), 'empty_value' => '- Please Select -', 'constraints' => array(new Assert\NotBlank()), 'label' => 'How is Rent Guarantee offered to your landlord?'))->add('propertyLetType', 'choice', array('choices' => Lookup::getInstance()->getCategoryAsChoices(LookupCategoryOptions::PROPERTY_LET_TYPE), 'empty_value' => '- Please Select -', 'constraints' => array(new Assert\NotBlank()), 'label' => 'Property Let Type'))->add('numberOfBedrooms', 'integer', array('constraints' => array(new Assert\GreaterThanOrEqual(array('value' => 0))), 'label' => 'How many bedrooms does the property have?', 'attr' => array('min' => 0), 'empty_data' => '0'))->add('propertyType', 'choice', array('choices' => Lookup::getInstance()->getCategoryAsChoices(LookupCategoryOptions::PROPERTY_TYPE), 'empty_value' => '- Please Select -', 'label' => 'Property Type', 'empty_data' => '6'))->add('propertyBuiltInRangeType', 'choice', array('choices' => Lookup::getInstance()->getCategoryAsChoices(LookupCategoryOptions::PROPERTY_BUILT_IN_RANGE_TYPE), 'empty_value' => '- Please Select -', 'label' => 'When was the property built?', 'empty_data' => '10'))->add('tenancyTermInMonths', 'choice', array('choices' => array('6' => '6', '12' => '12', '18' => '18', '24' => '24'), 'empty_value' => '- Please Select -', 'constraints' => array(new Assert\NotBlank()), 'label' => 'Tenancy Term in Months'))->add('numberOfTenants', 'choice', array('choices' => array('1' => '1', '2' => '2', '3' => '3', '4' => '4', '5' => '5', '6' => '6', '7' => '7', '8' => '8', '9' => '9', '10' => '10'), 'empty_value' => '- Please Select -', 'constraints' => array(new Assert\NotBlank()), 'label' => 'Number of Tenants'))->add('tenancyStartDate', 'date', array('constraints' => array(new Assert\NotBlank(), new Assert\GreaterThanOrEqual(array('value' => $minTenancyStartDate, 'message' => 'The tenancy start date cannot be in the past.')), new Assert\LessThanOrEqual(array('value' => $maxTenancyStartDate, 'message' => sprintf('The tenancy start date cannot be more than %d days in the future.', $maxTenancyStartDays)))), 'label' => 'Tenancy Start Date (dd/mm/yyyy)', 'widget' => 'single_text', 'format' => 'dd/MM/yyyy', 'attr' => array('data-provide' => 'datepicker')));
     // As this is the first step, remove the back button.
     $builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) {
         $event->getForm()->getParent()->remove('back');
     });
 }
 /**
  * {@inheritdoc}
  */
 public function buildForm(FormBuilderInterface $builder, array $options)
 {
     $userLabel = 'Tenant';
     if (isset($options['userLabel']) && is_string($options['userLabel'])) {
         $userLabel = $options['userLabel'];
     }
     /** @var \Barbondev\IRISSDK\IndividualApplication\ReferencingCase\Model\ReferencingCase $case */
     $case = $this->progressiveStore->getPrototypeByClass('Barbondev\\IRISSDK\\IndividualApplication\\ReferencingCase\\Model\\ReferencingCase');
     $builder->add('signaturePreference', 'hidden', array('data' => SignaturePreferenceOptions::SCANNED_DECLARATION))->add('productId', 'choice', array('label' => 'Product', 'choices' => $this->getProductChoices(), 'empty_value' => '- Please Select -', 'constraints' => array(new Assert\NotBlank(array('message' => 'Please select a product')))))->add('update', 'submit', array('attr' => array('value' => '1')))->add('title', 'choice', array('choices' => Titles::getTitles(), 'empty_value' => '- Please Select -', 'constraints' => array(new Assert\NotBlank(array('message' => 'Please select a title', 'groups' => array('fullValidation'))))))->add('firstName', 'text', array('label' => $userLabel . ' First Name', 'constraints' => array(new Assert\NotBlank(array('groups' => array('fullValidation'), 'message' => 'Please enter a first name')), new Assert\Regex(array('pattern' => '/^[-a-zA-Z0-9\\w]+$/', 'message' => 'Please enter alphanumeric characters and spaces only')))))->add('middleName', 'text', array('label' => $userLabel . ' Middle Name', 'required' => false, 'constraints' => array(new Assert\Regex(array('pattern' => '/^[ -a-zA-Z0-9\\w]*$/', 'message' => 'Please enter alphanumeric characters and spaces only')))))->add('lastName', 'text', array('label' => $userLabel . ' Last Name', 'constraints' => array(new Assert\NotBlank(array('groups' => array('fullValidation'), 'message' => 'Please enter a last name')), new Assert\Regex(array('pattern' => '/^[ -a-zA-Z0-9\\w]+$/', 'message' => 'Please enter alphanumeric characters and spaces only')))))->add('email', 'repeated', array('type' => 'email', 'options' => array('required' => true, 'constraints' => array(new Assert\NotBlank(array('groups' => array('fullValidation'), 'message' => 'Please enter an email address')), new Assert\Email(array('groups' => array('fullValidation'), 'message' => 'Please enter a valid email address')))), 'first_options' => array('label' => $userLabel . ' Email'), 'second_options' => array('label' => 'Confirm Email')))->add('rentShare', new MoneyWithoutStringTransformerType(), array('label' => 'Share of Rent', 'currency' => 'GBP', 'constraints' => array(new Assert\GreaterThanOrEqual(array('value' => 0, 'groups' => array('fullValidation'), 'message' => 'Please enter a positive numeric value for share of rent')), new Assert\NotBlank(array('groups' => array('fullValidation'), 'message' => 'Please enter a share of rent')), new Assert\Regex(array('pattern' => '/^([0-9]+\\.[0-9]{0,2}|[0-9]+)$/', 'message' => 'Amount must either have 2 decimal places or a whole number, e.g. "15000.00" or "15000"')), new Assert\LessThanOrEqual(array('value' => $case->getTotalRent(), 'groups' => array('fullValidation'), 'message' => 'This amount must be less than the total rent')))))->add('completionMethod', 'choice', array('choices' => Lookup::getInstance()->getCategoryAsChoices(LookupCategoryOptions::COMPLETION_METHODS), 'empty_value' => '- Please Select -', 'constraints' => array(new Assert\NotBlank(array('groups' => array('fullValidation'), 'message' => 'Please select a completion method')))));
     $self = $this;
     /**
      * Form modifier callback - adds policyLength field if rent guarantee product and adds helper notes depending on
      * the product.
      *
      * @param FormInterface $form
      * @param \Barbondev\IRISSDK\IndividualApplication\Product\Model\Product $product
      * @return void
      */
     $policyLengthFormModifier = function (FormInterface $form, Product $product = null) {
         if (null !== $product) {
             // Check if this is a rent guarantee product
             if ($product->getHasRentGuarantee()) {
                 // Check for international products by product code
                 $form->add('policyLength', 'choice', array('choices' => array(6 => '6 Months', 12 => '12 Months'), 'expanded' => true, 'constraints' => array(new Assert\NotBlank(array('message' => 'Please enter a policy length for rent guarantee')), new Assert\Choice(array('choices' => array(6, 12))))));
             } else {
                 // Not a rent guarantee product
             }
         } elseif (null !== $product && !$product->getHasRentGuarantee()) {
             if ($form->has('policyLength')) {
                 $form->remove('policyLength');
             }
         }
     };
     if (!$this->progressiveStore instanceof AgentGuarantorProgressiveStore) {
         $builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) use($self, $policyLengthFormModifier) {
             /** @var \Barbondev\IRISSDK\IndividualApplication\ReferencingApplication\Model\ReferencingApplication $application */
             $application = $event->getData();
             if ($application->getProductId()) {
                 // Get the current product and if has rent guarantee, add a policy length field
                 $product = $self->getProductById($application->getProductId());
                 $policyLengthFormModifier($event->getForm(), $product);
             }
         });
         $builder->addEventListener(FormEvents::SUBMIT, function (FormEvent $event) use($self, $policyLengthFormModifier) {
             /** @var \Barbondev\IRISSDK\IndividualApplication\ReferencingApplication\Model\ReferencingApplication $application */
             $application = $event->getData();
             // Get the current product and if has rent guarantee, add a policy length field
             $product = $self->getProductById($application->getProductId());
             $policyLengthFormModifier($event->getForm(), $product);
         });
         $builder->get('productId')->addEventListener(FormEvents::POST_SUBMIT, function (FormEvent $event) use($self, $policyLengthFormModifier) {
             $productId = $event->getForm()->getData();
             // Get the current product and if has rent guarantee, add a policy length field
             $product = $self->getProductById($productId);
             $policyLengthFormModifier($event->getForm()->getParent(), $product);
         });
     }
 }
 /**
  * {@inheritdoc}
  */
 public function buildForm(FormBuilderInterface $builder, array $options)
 {
     // Get the current application
     $currentApplication = \Zend_Registry::get('iris_container')->get('iris.referencing.application.current_form_flow_records')->getApplication();
     // Get the financial referee type choices
     $financialRefereeTypeChoices = Lookup::getInstance()->getCategoryAsChoices(LookupCategoryOptions::FINANCIAL_REFEREE_TYPE);
     // If this is the current employer, limit choices depending on employment status
     if (isset($options['refereeStatus']) && 1 == $options['refereeStatus']) {
         $financialRefereeTypeChoices = $this->truncateFinancialRefereeChoicesByEmploymentStatus($financialRefereeTypeChoices, $currentApplication->getEmploymentStatus());
     }
     // At first we display only a type selection, as the rest of the form makes no sense until it's been selected.
     // On the front end, selecting the type automatically POSTs the form and serverside when this happens the
     //   validation of the remaining fields must be suppressed.
     $builder->add('financialRefereeType', 'choice', array('choices' => $financialRefereeTypeChoices, 'empty_value' => '- Please Select -', 'required' => false, 'constraints' => array(new Assert\NotBlank(array('message' => ' This should not be blank')))))->add('update', 'submit', array('attr' => array('value' => '1')))->add('companyName', 'text', array('constraints' => array(new Assert\NotNull(array('groups' => 'referee_details', 'message' => self::COMPANY_NAME_BLANK_MESSAGE)), new Assert\Length(array('min' => 2, 'minMessage' => self::COMPANY_NAME_LESS_THAN_MIN_CHARS_MESSAGE, 'groups' => 'referee_details')))))->add('address', new AddressType(), array('has_foreign_type' => true))->add('contactName', 'text', array('constraints' => array(new Assert\NotNull(array('groups' => 'referee_details', 'message' => self::CONTACT_NAME_BLANK_MESSAGE)), new Assert\Length(array('min' => 2, 'groups' => 'referee_details', 'minMessage' => self::CONTACT_NAME_LESS_THAN_MIN_CHARS_MESSAGE)))))->add('contactPosition', 'text', array('constraints' => array(new Assert\NotNull(array('groups' => 'referee_details', 'message' => self::CONTACT_POSITION_BLANK_MESSAGE)), new Assert\Length(array('min' => 2, 'groups' => 'referee_details', 'minMessage' => self::CONTACT_POSITION_LESS_THAN_MIN_CHARS_MESSAGE)))))->add('phone', 'text', array('label' => 'Telephone (day)', 'constraints' => array(new Assert\NotNull(array('groups' => 'referee_details', 'message' => self::PHONE_BLANK_MESSAGE)), new Assert\Length(array('min' => 9, 'groups' => 'contact_details', 'minMessage' => self::PHONE_LESS_THAN_MIN_CHARS_MESSAGE)), new Assert\NotEqualTo(array('value' => $currentApplication->getPhone() ?: 'nophone', 'message' => 'Telephone number must not be the same as tenant contact details')), new Assert\Regex(array('pattern' => '/^[0-9+\\(\\)#\\.\\s\\/ext-]{1,20}+$/', 'message' => 'Phone number is invalid')))))->add('fax', 'text', array('constraints' => array(new Assert\Length(array('min' => 9, 'groups' => 'contact_details', 'minMessage' => self::FAX_LESS_THAN_MIN_CHARS_MESSAGE)), new Assert\Regex(array('pattern' => '/^[0-9+\\(\\)#\\.\\s\\/ext-]{1,20}+$/', 'message' => 'Fax number is invalid'))), 'required' => false))->add('email', 'email', array('required' => false, 'constraints' => array(new Assert\Email(array('groups' => 'contact_details', 'message' => self::EMAIL_NOT_VALID_MESSAGE)), new Assert\NotEqualTo(array('value' => $currentApplication->getEmail() ?: 'noemail', 'message' => 'Email must not be the same as tenant contact details')))))->add('applicantPositionHeld', 'text', array('label' => 'Position Held by Applicant', 'constraints' => array(new Assert\NotNull(array('groups' => 'referee_details', 'message' => self::APPLICANT_POSITION_HELD_BLANK_MESSAGE)), new Assert\Length(array('min' => 2, 'max' => 45, 'groups' => 'applicant_details', 'minMessage' => self::APPLICANT_POSITION_HELD_LESS_THAN_MIN_CHARS_MESSAGE, 'maxMessage' => self::APPLICANT_POSITION_HELD_LESS_THAN_MAX_CHARS_MESSAGE)))))->add('isPermanent', new BooleanExpandedType(), array('label' => 'Is the position permanent?', 'required' => false, 'constraints' => array(new Assert\NotNull(array('groups' => 'applicant_details', 'message' => self::IS_PERMANENT_BLANK_MESSAGE)))))->add('payrollNumber', 'text', array('label' => 'Payroll/Service/Pension/National Insurance Number'))->add('applicantAnnualIncome', new MoneyWithoutStringTransformerType(), array('label' => 'Gross Annual Salary', 'currency' => 'GBP', 'constraints' => array(new Assert\NotNull(array('groups' => 'income', 'message' => self::APPLICANT_ANNUAL_INCOME_BLANK_MESSAGE)), new Assert\Regex(array('groups' => 'income', 'pattern' => '/^([0-9]+\\.[0-9]{0,2}|[0-9]+)$/', 'message' => 'Amount must either have 2 decimal places or a whole number, e.g. "15000.00" or "15000"')))))->add('employmentStartDate', 'date', array('label' => 'Start Date', 'years' => self::getEmploymentStartDateYears(), 'constraints' => array(new Assert\Date(array('groups' => 'applicant_position_commencement', 'message' => self::FINANCIAL_REFEREE_START_DATE_INVALID)))))->add('employmentChangeDuringTenancy', new BooleanExpandedType(), array('label' => 'Will this employment change before or during the tenancy?', 'required' => false))->add('multipleJobOrPension', new BooleanExpandedType(), array('label' => 'Select if you have more than one job or are in receipt of a pension', 'required' => false));
     // Correct initialise the status Id depending on options passed
     $financialRefereeStatusOptions = array();
     if (null !== $options['refereeStatus']) {
         $financialRefereeStatusOptions['empty_data'] = $options['refereeStatus'];
         $financialRefereeStatusOptions['data'] = $options['refereeStatus'];
     }
     $builder->add('financialRefereeStatus', 'hidden', $financialRefereeStatusOptions);
     // Listener to control inclusion of fields
     $builder->addEventSubscriber(new FinancialRefereeDegradationListener());
 }
 /**
  * {@inheritdoc}
  */
 public function buildForm(FormBuilderInterface $builder, array $options)
 {
     $builder->add('title', 'choice', array('choices' => Titles::getTitles(), 'empty_value' => '- Please Select -', 'constraints' => array(new Assert\NotBlank())))->add('firstName', 'text', array('constraints' => array(new Assert\Length(array('min' => 1)), new Assert\NotBlank())))->add('middleName', 'text', array('required' => false))->add('lastName', 'text', array('constraints' => array(new Assert\Length(array('min' => 1)), new Assert\NotBlank())))->add('otherName', 'text', array('required' => false))->add('birthDate', 'birthday')->add('employmentStatus', 'choice', array('label' => 'Current Employment Status', 'choices' => Lookup::getInstance()->getCategoryAsChoices(LookupCategoryOptions::EMPLOYMENT_STATUS), 'empty_value' => '- Please Select -'))->add('grossIncome', new MoneyWithoutStringTransformerType(), array('label' => 'Total Gross Annual Income', 'currency' => 'GBP', 'constraints' => array(new Assert\GreaterThanOrEqual(array('value' => 0)), new Assert\NotNull(array('message' => 'Please confirm the gross annual income')), new Assert\Regex(array('pattern' => '/^([0-9]+\\.[0-9]{0,2}|[0-9]+)$/', 'message' => 'Amount must either have 2 decimal places or a whole number, e.g. "15000.00" or "15000"')))))->add('bankAccount', new BankAccountType(), array())->add('phone', 'text', array('label' => 'Telephone Number', 'required' => false, 'constraints' => array(new Assert\Length(array('groups' => 'phone', 'min' => 9)), new Assert\NotBlank(array('groups' => 'phone')), new Assert\Regex(array('pattern' => '/^[0-9+\\(\\)#\\.\\s\\/ext-]{1,20}+$/', 'message' => 'Phone number is invalid')))))->add('mobile', 'text', array('label' => 'Mobile Number', 'required' => false, 'constraints' => array(new Assert\Length(array('groups' => 'mobile', 'min' => 11)), new Assert\NotBlank(array('groups' => 'mobile')), new Assert\Regex(array('pattern' => '/^[0-9+\\(\\)#\\.\\s\\/ext-]{1,20}+$/', 'message' => 'Phone number is invalid')))))->add('email', 'email', array('label' => 'Email Address', 'required' => false, 'constraints' => array(new Assert\Email(), new Assert\NotBlank())))->add('hasCCJ', 'checkbox', array('label' => 'Any CCJs or adverse credit history?', 'required' => false));
 }
 /**
  * {@inheritdoc}
  */
 public function buildForm(FormBuilderInterface $builder, array $options)
 {
     // Get the current application
     $currentApplication = \Zend_Registry::get('iris_container')->get('iris.referencing.application.current_form_flow_records')->getApplication();
     $builder->add('type', 'choice', array('choices' => Lookup::getInstance()->getCategoryAsChoices(LookupCategoryOptions::LETTING_REFEREE_TYPE), 'empty_value' => '- Please Select -', 'constraints' => array(new Assert\NotBlank())))->add('name', 'text', array('constraints' => array(new Assert\NotBlank(), new Assert\Length(array('min' => 2)))))->add('address', new AddressType(), array('has_foreign_type' => true))->add('dayPhone', 'text', array('required' => false, 'constraints' => array(new Assert\NotBlank(array('groups' => 'dayphone', 'message' => self::PHONE_BLANK_MESSAGE)), new Assert\Length(array('groups' => 'dayphone', 'min' => 9)), new Assert\NotEqualTo(array('value' => $currentApplication->getPhone() ?: 'nophone', 'message' => 'Telephone number must not be the same as tenant contact details')), new Assert\Regex(array('pattern' => '/^[0-9+\\(\\)#\\.\\s\\/ext-]{1,20}+$/', 'message' => 'Phone number is invalid'))), 'label' => 'Telephone (day)'))->add('eveningPhone', 'text', array('required' => false, 'constraints' => array(new Assert\NotBlank(array('groups' => 'eveningphone', 'message' => self::PHONE_BLANK_MESSAGE)), new Assert\Length(array('groups' => 'eveningphone', 'min' => 9)), new Assert\NotEqualTo(array('value' => $currentApplication->getPhone() ?: 'nophone', 'message' => 'Telephone number must not be the same as tenant contact details')), new Assert\Regex(array('pattern' => '/^[0-9+\\(\\)#\\.\\s\\/ext-]{1,20}+$/', 'message' => 'Phone number is invalid'))), 'label' => 'Telephone (evening)'))->add('fax', 'text', array('required' => false, 'constraints' => array(new Assert\Length(array('min' => 9)), new Assert\Regex(array('pattern' => '/^[0-9+\\(\\)#\\.\\s\\/ext-]{1,20}+$/', 'message' => 'Fax number is invalid')))))->add('email', 'email', array('required' => false, 'constraints' => array(new Assert\NotBlank(array('groups' => 'email')), new Assert\NotEqualTo(array('value' => $currentApplication->getEmail() ?: 'noemail', 'message' => 'Email must not be the same as tenant contact details')))));
 }
 /**
  * Get employment status choices
  *
  * @return array
  */
 public static function getEmploymentStatusChoices()
 {
     return Lookup::getInstance()->getCategoryAsChoices(LookupCategoryOptions::EMPLOYMENT_STATUS);
 }
 /**
  * Get lookup item name by id and category name
  *
  * @param int $id
  * @param string $categoryName
  * @return string
  */
 public function lookupNameFilter($id, $categoryName)
 {
     return Lookup::getInstance()->findById($categoryName, $id)->getName();
 }