@Transactional
  @Override
  public EntityIdentifier approveLoanApplication(final Long loanId, final JsonCommand command) {

    AppUser currentUser = context.authenticatedUser();

    final LoanStateTransitionCommand approveLoanApplication =
        this.loanStateTransitionCommandFromApiJsonDeserializer.commandFromApiJson(command.json());
    approveLoanApplication.validate();

    final Loan loan = retrieveLoanBy(loanId);

    final LocalDate approvedOnLocalDate = approveLoanApplication.getApprovedOnDate();
    if (this.isBeforeToday(approvedOnLocalDate) && currentUser.canNotApproveLoanInPast()) {
      throw new NoAuthorizationException(
          "User has no authority to approve loan with a date in the past.");
    }

    final Map<String, Object> changes =
        loan.loanApplicationApproval(command, defaultLoanLifecycleStateMachine());
    this.loanRepository.save(loan);

    final String noteText = command.stringValueOfParameterNamed("note");
    if (StringUtils.isNotBlank(noteText)) {
      Note note = Note.loanNote(loan, noteText);
      changes.put("note", noteText);
      this.noteRepository.save(note);
    }

    return EntityIdentifier.resourceResult(loanId, command.commandId(), changes);
  }