@Transactional
  @Override
  public EntityIdentifier addLoanCharge(final LoanChargeCommand command) {
    this.context.authenticatedUser();

    LoanChargeCommandValidator validator = new LoanChargeCommandValidator(command);
    validator.validateForCreate();

    final Loan loan = this.loanRepository.findOne(command.getLoanId());
    if (loan == null) {
      throw new LoanNotFoundException(command.getLoanId());
    }

    final Charge chargeDefinition = this.chargeRepository.findOne(command.getChargeId());
    if (chargeDefinition == null || chargeDefinition.isDeleted()) {
      throw new ChargeNotFoundException(command.getChargeId());
    }

    if (!chargeDefinition.isActive()) {
      throw new ChargeIsNotActiveException(chargeDefinition.getId(), chargeDefinition.getName());
    }

    final LoanCharge loanCharge = LoanCharge.createNew(loan, chargeDefinition, command);

    if (!loan.hasCurrencyCodeOf(chargeDefinition.getCurrencyCode())) {
      String errorMessage = "Charge and Loan must have the same currency.";
      throw new InvalidCurrencyException("charge", "attach.to.loan", errorMessage);
    }

    loan.addLoanCharge(loanCharge);
    this.loanRepository.saveAndFlush(loan);

    return new EntityIdentifier(loanCharge.getId());
  }
  @Transactional
  @Override
  public EntityIdentifier updateLoanCharge(final LoanChargeCommand command) {

    this.context.authenticatedUser();

    LoanChargeCommandValidator validator = new LoanChargeCommandValidator(command);
    validator.validateForUpdate();

    final Long loanId = command.getLoanId();
    final Loan loan = retrieveLoanBy(loanId);

    final Long loanChargeId = command.getId();
    final LoanCharge loanCharge = retrieveLoanChargeBy(loanId, loanChargeId);

    loan.updateLoanCharge(loanCharge, command);

    this.loanRepository.save(loan);

    return new EntityIdentifier(loanCharge.getId());
  }