@TransactionDemarcate(joinToken = true)
  public ActionForward load(
      final ActionMapping mapping,
      final ActionForm form,
      final HttpServletRequest request,
      @SuppressWarnings("unused") final HttpServletResponse response)
      throws Exception {

    LoanDisbursementActionForm loanDisbursementActionForm = (LoanDisbursementActionForm) form;
    loanDisbursementActionForm.clear();
    loanDisbursementActionForm.setAmountCannotBeZero(false);

    Integer loanAccountId = Integer.valueOf(loanDisbursementActionForm.getAccountId());
    LoanDisbursalDto loanDisbursalDto =
        loanAccountServiceFacade.retrieveLoanDisbursalDetails(loanAccountId);

    UserContext uc = getUserContext(request);
    SessionUtils.setAttribute(
        LoanConstants.PROPOSED_DISBURSAL_DATE, loanDisbursalDto.getProposedDate(), request);
    loanDisbursementActionForm.setTransactionDate(
        getUserLocaleDate(uc.getPreferredLocale(), loanDisbursalDto.getProposedDate()));

    loanDisbursementActionForm.setAmount(loanDisbursalDto.getAmountPaidAtDisbursement());
    loanDisbursementActionForm.setLoanAmount(loanDisbursalDto.getLoanAmount());
    if (loanDisbursalDto.isMultiCurrencyEnabled()) {
      loanDisbursementActionForm.setCurrencyId(loanDisbursalDto.getCurrencyId());
    }

    Short repaymentIndependentOfMeetingScheduleValue =
        loanDisbursalDto.isRepaymentIndependentOfMeetingSchedule()
            ? Short.valueOf("1")
            : Short.valueOf("0");
    SessionUtils.setAttribute(
        LoanConstants.REPAYMENT_SCHEDULES_INDEPENDENT_OF_MEETING_IS_ENABLED,
        repaymentIndependentOfMeetingScheduleValue,
        request);
    SessionUtils.setAttribute(
        AccountingRulesConstants.BACKDATED_TRANSACTIONS_ALLOWED,
        loanDisbursalDto.isBackDatedTransactionsAllowed(),
        request);

    List<PaymentTypeEntity> disbursementTypes =
        legacyAcceptedPaymentTypeDao.getAcceptedPaymentTypesForATransaction(
            uc.getLocaleId(), TrxnTypes.loan_disbursement.getValue());
    SessionUtils.setCollectionAttribute(MasterConstants.PAYMENT_TYPE, disbursementTypes, request);

    List<PaymentTypeEntity> feesTypes =
        legacyAcceptedPaymentTypeDao.getAcceptedPaymentTypesForATransaction(
            uc.getLocaleId(), TrxnTypes.loan_repayment.getValue());
    SessionUtils.setCollectionAttribute(MasterConstants.FEE_PAYMENT_TYPE, feesTypes, request);

    return mapping.findForward(Constants.LOAD_SUCCESS);
  }
  @TransactionDemarcate(validateAndResetToken = true)
  @CloseSession
  public ActionForward update(
      final ActionMapping mapping,
      final ActionForm form,
      final HttpServletRequest request,
      @SuppressWarnings("unused") final HttpServletResponse response)
      throws Exception {

    LoanDisbursementActionForm actionForm = (LoanDisbursementActionForm) form;

    UserContext uc = getUserContext(request);
    Date trxnDate = getDateFromString(actionForm.getTransactionDate(), uc.getPreferredLocale());
    trxnDate = DateUtils.getDateWithoutTimeStamp(trxnDate.getTime());
    Date receiptDate = getDateFromString(actionForm.getReceiptDate(), uc.getPreferredLocale());

    Integer loanAccountId = Integer.valueOf(actionForm.getAccountId());
    AccountBO accountBO = new AccountBusinessService().getAccount(loanAccountId);

    createGroupQuestionnaire.saveResponses(request, actionForm, loanAccountId);

    try {
      String paymentTypeIdStringForDisbursement = actionForm.getPaymentTypeId();
      Short paymentTypeIdForDisbursement =
          StringUtils.isEmpty(paymentTypeIdStringForDisbursement)
              ? PaymentTypes.CASH.getValue()
              : Short.valueOf(paymentTypeIdStringForDisbursement);

      Short paymentTypeId = Short.valueOf(paymentTypeIdForDisbursement);
      final String comment = "";
      final BigDecimal disbursalAmount = new BigDecimal(actionForm.getLoanAmount());
      CustomerDto customerDto = null;

      PaymentTypeDto paymentType = null;
      AccountPaymentParametersDto loanDisbursement =
          new AccountPaymentParametersDto(
              new UserReferenceDto(uc.getId()),
              new AccountReferenceDto(loanAccountId),
              disbursalAmount,
              new LocalDate(trxnDate),
              paymentType,
              comment,
              new LocalDate(receiptDate),
              actionForm.getReceiptId(),
              customerDto);

      monthClosingServiceFacade.validateTransactionDate(trxnDate);

      // GLIM
      List<LoanBO> individualLoans = this.loanDao.findIndividualLoans(loanAccountId);
      for (LoanBO individual : individualLoans) {
        if (!loanAccountServiceFacade.isTrxnDateValid(
            Integer.valueOf(individual.getAccountId()), trxnDate)) {
          throw new BusinessRuleException("errors.invalidTxndateOfDisbursal");
        }
      }

      this.loanAccountServiceFacade.disburseLoan(loanDisbursement, paymentTypeId);

      for (LoanBO individual : individualLoans) {
        loanDisbursement =
            new AccountPaymentParametersDto(
                new UserReferenceDto(uc.getId()),
                new AccountReferenceDto(individual.getAccountId()),
                individual.getLoanAmount().getAmount(),
                new LocalDate(trxnDate),
                paymentType,
                comment,
                new LocalDate(receiptDate),
                actionForm.getReceiptId(),
                customerDto);

        this.loanAccountServiceFacade.disburseLoan(loanDisbursement, paymentTypeId);
      }
    } catch (BusinessRuleException e) {
      throw new AccountException(e.getMessage());
    } catch (MifosRuntimeException e) {
      if (e.getCause() != null && e.getCause() instanceof AccountException) {
        throw new AccountException(e.getCause().getMessage());
      }
      String msg = "errors.cannotDisburseLoan.because.disburseFailed";
      logger.error(msg, e);
      throw new AccountException(msg);
    } catch (Exception e) {
      String msg = "errors.cannotDisburseLoan.because.disburseFailed";
      logger.error(msg, e);
      throw new AccountException(msg);
    }

    return mapping.findForward(Constants.UPDATE_SUCCESS);
  }