/**
   * Update Bank EFT Status.
   *
   * @param disbursements DisbursementDTO
   */
  public void updateBankEFTStatus(Collection<DisbursementDTO> disbursements) {
    for (DisbursementDTO disbursementDTOParam : disbursements) {
      DisbursementPartyDTO disbursementPartyDTO = disbursementDTOParam.getDisbursementParty();
      boolean preNoteInd = false;
      /*
       * Use MinimalPartyPojo to retrieve all other data. Note: context is
       * for getting address by context, we won't be using the address
       * data anyway
       */
      if (disbursementPartyDTO == null) {
        return;
      }
      // 12/17/2013 @GR - Performance Tuning - Fetch MinimalParty only for PreNotes
      /*MinimalPartyRequestDTO minimalPartyRequestDTO = new MinimalPartyRequestDTO();
      minimalPartyRequestDTO.setPartyId(disbursementPartyDTO
      		.getPartyIdPayeePrimary());
      /*
       * Need to set something, it's only used for fetching address, which
       * we don't care about
       *
      minimalPartyRequestDTO.setContextType("");
      MinimalPartyDTO minParty = MuleServiceFactory.getService(
      		PartyService.class).retrieveMinimalParty(
      		minimalPartyRequestDTO);
      minParty.setContext(getExportResourceManager().getContext());*/
      Collection<BankAccountDTO> bankAccounts =
          retrievePartyBankAccountInformation(disbursementPartyDTO.getPartyIdPayeePrimary());
      for (BankAccountDTO bankAccountDTO : bankAccounts) {

        // Trying to avoid multiple saves to the same Party since was producing Party Merge
        // Optimistic Locking Exception
        if (!DisbursementConstants.EFT_SENT_STAUTS.equals(bankAccountDTO.getEFTStatusCode())
            && bankAccountDTO.ispreNoteIndicator()) {
          preNoteInd = true;
          bankAccountDTO.setEFTStatusCode(DisbursementConstants.EFT_SENT_STAUTS);
          bankAccountDTO.setEFTStatusEffDate(DateUtility.getSystemDateTime());
        }
      }
      if (preNoteInd) {
        MinimalPartyRequestDTO minimalPartyRequestDTO = new MinimalPartyRequestDTO();
        minimalPartyRequestDTO.setPartyId(disbursementPartyDTO.getPartyIdPayeePrimary());
        /*
         * Need to set something, it's only used for fetching address, which
         * we don't care about
         */
        minimalPartyRequestDTO.setContextType("");
        MinimalPartyDTO minParty =
            MuleServiceFactory.getService(PartyService.class)
                .retrieveMinimalParty(minimalPartyRequestDTO);
        minParty.setBankInformations(bankAccounts);
        MuleServiceFactory.getService(PartyService.class).saveMinimalParty(minParty);
      }
    }
  }
  /**
   * Formats Claim Policy information to be in synch with Claim Import layout
   *
   * @param returnDetailsForImport
   * @param claimsPolicyCompositeHelper
   * @param clmDetailResponse
   */
  public void processClaimPolicy(
      boolean returnDetailsForImport,
      ClaimsPolicyCompositeHelper claimsPolicyCompositeHelper,
      ClaimDetailsResponseDTO clmDetailResponse) {
    ClaimPolicyDTO clmPolicyDTO = clmDetailResponse.getClaimDTO().getPolicy();

    getClaimPolicyUnitExternalSourceId().clear();

    // populate claim policy party info.
    claimsPolicyCompositeHelper.normalizePolicyDetails(clmPolicyDTO);

    // Claim Details returns a Collection of ClaimPolicyParticipationDTO
    // which contains ClaimPolicyFinancialInterestParticipationDTO,
    // ClaimPolicyDriverParticipationDTO,
    // ClaimPolicyAgencyParticipationDTO,
    // ClaimPolicyInsuredParticipationDTO.
    // For Claim Import we need the Participants as separate Collection.
    // So we loop thru' the Collection of ClaimPolicyParticipationDTO
    // add to the corresponding Collections.
    if (clmPolicyDTO != null && clmPolicyDTO.getParticipations() != null) {

      for (ClaimPolicyParticipationDTO participantDTO : clmPolicyDTO.getParticipations()) {
        if (participantDTO.getParticipationEffectiveDate() == null) {
          participantDTO.setParticipationEffectiveDate(DateUtility.getSystemDateTime());
        }
        participantDTO.setAlreadyUpdated(true);
        if (participantDTO instanceof ClaimPolicyFinancialInterestParticipationDTO) {
          clmPolicyDTO
              .getClmPolicyFinancialInterestParticipants()
              .add((ClaimPolicyFinancialInterestParticipationDTO) participantDTO);
        } else if (participantDTO instanceof ClaimPolicyDriverParticipationDTO) {
          clmPolicyDTO
              .getClmPolicyDriverParticipants()
              .add((ClaimPolicyDriverParticipationDTO) participantDTO);
        } else if (participantDTO instanceof ClaimPolicyAgencyParticipationDTO) {
          clmPolicyDTO
              .getClmPolicyAgencyParticipants()
              .add((ClaimPolicyAgencyParticipationDTO) participantDTO);
        } else if (participantDTO instanceof ClaimPolicyInsuredParticipationDTO) {
          clmPolicyDTO
              .getClmPolicyInsuredParticipants()
              .add((ClaimPolicyInsuredParticipationDTO) participantDTO);
        }
      }
      clmPolicyDTO.setParticipations(null);
    }
    // For Claim Import Claim Policy Units should be a Collection of
    // ClaimPolicyUnitVehicleDTO.
    // Claim Details returns the Collection with ClaimPolicyUnitDTO and
    // ClaimPolicyUnitVehicleDTO.
    if (clmPolicyDTO != null && clmPolicyDTO.getUnits() != null) {

      Collection<ClaimPolicyUnitDTO> claimPolicyUnits = new ArrayList<ClaimPolicyUnitDTO>();

      for (ClaimPolicyUnitDTO claimPolicyUnit : clmPolicyDTO.getUnits()) {
        if (returnDetailsForImport) {
          getClaimPolicyUnitExternalSourceId()
              .put(claimPolicyUnit.getRecordId(), claimPolicyUnit.getExternalSourceId());
        }
        if (claimPolicyUnit instanceof ClaimPolicyUnitDTO) {
          ClaimPolicyUnitVehicleDTO claimPolicyVehicleUnit = new ClaimPolicyUnitVehicleDTO();
          BeanUtils.copyProperties(claimPolicyUnit, claimPolicyVehicleUnit);
          claimPolicyUnits.add(claimPolicyVehicleUnit);
        } else {
          claimPolicyUnits.add((ClaimPolicyUnitVehicleDTO) claimPolicyUnit);
        }
      }
      clmPolicyDTO.setUnits(claimPolicyUnits);
      /*
       * for(ClaimPolicyUnitDTO claimPolicyVehicleUnit:
       * clmPolicyDTO.getUnits()) { if(claimPolicyVehicleUnit
       * instanceof ClaimPolicyUnitVehicleDTO) {
       * claimPolicyUnits.add(claimPolicyVehicleUnit); } }
       */
    }
  }
  /**
   * The method should be invoked before collection of disbursement DTO has been saved within
   * staging database.
   *
   * @param dtos Input collection of DisbursementDTO
   * @return collection of DisbursementDTO processed successfully.
   */
  public Collection<DisbursementDTO> preProcess(Collection<DisbursementDTO> dtos) {
    /*
     * Disbursement State of "Incomplete" and Disbursement
     * Status of "Incomplete Payment" that have not been sent to Payment
     * Processor for processing and a Disbursement Date less than or equal
     * to the Business Date is eligible for processing.
     */

    Collection<DisbursementDTO> validDisbursement = new ArrayList<DisbursementDTO>();
    if (dtos != null && dtos.size() > 0) {
      logger.debug(
          "Process Started. [ClientExportPaymentHelper] Validate disbursement to be exported.");
      Date businessDate =
          MuleServiceFactory.getService(DateService.class)
              .getBusinessDate(1L, BusinessDateType.BUSINESS);

      for (DisbursementDTO dto : dtos) {

        if (DisbursementConstants.DISB_STATE_TYPE_CODE_INCOMPLETE.equalsIgnoreCase(
                dto.getStateCode())
            && DisbursementConstants.DISB_STATUS_TYPE_CODE_INCOMPLETE_PAYMENT.equalsIgnoreCase(
                dto.getStatusCode())
            && (DateUtility.compareDate(dto.getEffectiveDate(), businessDate) <= 0)
            && (dto.getEndDate() == null
                || DateUtility.compareDate(dto.getEndDate(), businessDate) >= 0)) {
          validDisbursement.add(dto);

        } else if (DisbursementConstants.DISB_STATE_TYPE_CODE_OPEN.equalsIgnoreCase(
                dto.getStateCode())
            && DisbursementConstants.DISB_STATUS_TYPE_CODE_PAYMENT_STOPPED_NOT_REISSUED
                .equalsIgnoreCase(dto.getStatusCode())
            && (DateUtility.compareDate(dto.getEffectiveDate(), businessDate) <= 0)
            && (dto.getEndDate() == null
                || DateUtility.compareDate(dto.getEndDate(), businessDate) >= 0)) {
          validDisbursement.add(dto);
        } else if (DisbursementConstants.DISB_STATE_TYPE_CODE_OPEN.equalsIgnoreCase(
                dto.getStateCode())
            && DisbursementConstants.DISB_STATUS_TYPE_CODE_ISSUED_PAYMENT.equalsIgnoreCase(
                dto.getStatusCode())
            && (dto.getDisbursementStatuses().size() == 1)
            && (DateUtility.compareDate(dto.getEffectiveDate(), businessDate) <= 0)
            && (dto.getEndDate() == null
                || DateUtility.compareDate(dto.getEndDate(), businessDate) >= 0)) {
          validDisbursement.add(dto);
        } else if (DisbursementConstants.DISB_STATE_TYPE_CODE_COMPLETE.equalsIgnoreCase(
                dto.getStateCode())
            && DisbursementConstants.DISB_STATUS_TYPE_CODE_PAYMENT_VOIDED_NOT_REISSUED
                .equalsIgnoreCase(dto.getStatusCode())
            && (DateUtility.compareDate(dto.getEffectiveDate(), businessDate) <= 0)
            && (dto.getEndDate() == null
                || DateUtility.compareDate(dto.getEndDate(), businessDate) >= 0)) {
          validDisbursement.add(dto);
        } else {
          logger.debug(
              "[ClientExportPaymentHelper] Criteria Not Met for Disbursement ID = {} ",
              dto.getRecordId());
        }
      }
      // Flush all context to re initialize sequence generator.
      ExportPaymentSequenceGenHelper.flushAllContext();
    }
    return validDisbursement;
  }
  /**
   * Update Disbursement Status.
   *
   * @param disbursements DisbursementDTO collection
   */
  public void updateDisbursementStatus(Collection<DisbursementDTO> disbursements) {
    for (DisbursementDTO dto : disbursements) {
      Collection<DisbursementStatusDTO> statusColl = dto.getDisbursementStatuses();

      /* This logic is updating the existing man_pay record, This should be no different from regular status update, expire the existing record
       * and create a new record for DISB_STATUS_REASON_CODE_SENT_TO_PAYMENT_PROCESSOR
       * if (updateManualCheckDisbursementStatus(dto)) {
       continue;
      }*/
      DisbursementStatusDTO voidedDisbStatus = null;
      for (DisbursementStatusDTO disbursementStatusDTO : statusColl) {
        if (disbursementStatusDTO.getEndDateTime() == null) {
          disbursementStatusDTO.setEndDateTime(DateUtility.getSystemDateTime());
        }
        // Check for voids and stop pay no issue statuses
        if (disbursementStatusDTO
                .getDisbursementStatusType()
                .equals(DisbursementConstants.DISB_STATUS_TYPE_CODE_PAYMENT_VOIDED_NOT_REISSUED)
            || disbursementStatusDTO
                .getDisbursementStatusType()
                .equals(DisbursementConstants.DISB_STATUS_TYPE_CODE_PAYMENT_STOPPED_NOT_REISSUED)) {
          voidedDisbStatus = disbursementStatusDTO;
        }
      }

      DisbursementStatusDTO currentStatus = new DisbursementStatusDTO();

      if (voidedDisbStatus != null) {
        // If voided copy the current codes for the new status record.
        currentStatus.setDisbursementStatusType(voidedDisbStatus.getDisbursementStatusType());
        currentStatus.setDisbursementState(voidedDisbStatus.getDisbursementState());
      } else if ((dto.isManualCheckIndicator())
          || (dto.getFinancialAgreementTypeCode().equals("dsb")
              && dto.getDisbursementTypeCode().equals("prenote"))) {
        currentStatus.setDisbursementStatusType(
            DisbursementConstants.DISB_STATUS_TYPE_CODE_ISSUED_PAYMENT);
        currentStatus.setDisbursementState(DisbursementConstants.DISB_STATE_TYPE_CODE_OPEN);
      } else {
        currentStatus.setDisbursementStatusType(
            DisbursementConstants.DISB_STATUS_TYPE_CODE_AWAITING_PAYMENT);
        currentStatus.setDisbursementState(DisbursementConstants.DISB_STATE_TYPE_CODE_INCOMPLETE);
      }

      currentStatus.setDisbursementStatusReason(
          DisbursementConstants.DISB_STATUS_REASON_CODE_SENT_TO_PAYMENT_PROCESSOR);
      currentStatus.setEffectiveDateTime(DateUtility.getSystemDateTime());

      /**
       * AP Export Performance Fix - @GR - 03/30/2014 - Save just the Disbursement Status record.
       */
      // dto.getDisbursementStatuses().add(currentStatus);
      statusColl.add(currentStatus);
      // DTOUtils.saveEntityWithAssociations(lds, dto);
      /*
       * Save the DisbursementStatusBO along with all its
       * associations from the values in DTO
       */
      // fetch DisbursementBO
      DisbursementBO disbursement = getDisbursementDao().retrieveDisbursement(dto.getRecordId());
      /*
       * Instantiate the custom mapper for
       * DisbursementStatusBO
       */
      DisbursementStatusDTOMapper disbStatusDTOMapper =
          new DisbursementStatusDTOMapper(disbursement);

      for (DisbursementStatusDTO disbstatus : statusColl) {
        DTOUtils.saveEntityWithAssociations(
            lds, disbstatus, DisbursementStatusBO.class, disbStatusDTOMapper, true);
      }
    }
  }