/**
   * Modify a transaction before it is used to complete the panel for auto fill. The supplied
   * transaction must be a new or cloned transaction. It can't be a transaction that lives in the
   * map. The returned transaction can be the supplied reference or may be a new instance
   *
   * @param t The transaction to modify
   * @return the modified transaction
   */
  private Transaction modifyTransactionForAutoComplete(final Transaction t) {

    // tweak the transaction
    t.setNumber(null);
    t.setReconciled(ReconciledState.NOT_RECONCILED); // clear both sides

    // set the last date as required
    if (!Options.rememberLastDateProperty().get()) {
      t.setDate(LocalDate.now());
    } else {
      t.setDate(datePicker.getValue());
    }

    // preserve any transaction entries that may have been entered first
    if (amountField.getLength() > 0) {
      Transaction newTrans = buildTransaction();
      t.clearTransactionEntries();
      t.addTransactionEntries(newTrans.getTransactionEntries());
    }

    // preserve any preexisting memo field info
    if (memoTextField.getLength() > 0) {
      t.setMemo(memoTextField.getText());
    }

    // Do not copy over attachments
    t.setAttachment(null);

    return t;
  }
  @Override
  public void clearForm() {

    modTrans = null;

    amountField.setDecimal(BigDecimal.ZERO);

    reconciledButton.setDisable(false);
    reconciledButton.setSelected(false);
    reconciledButton.setIndeterminate(false);

    if (payeeTextField != null) { // transfer slips do not use the payee field
      payeeTextField.setEditable(true);
      payeeTextField.clear();
    }

    datePicker.setEditable(true);
    if (!Options.rememberLastDateProperty().get()) {
      datePicker.setValue(LocalDate.now());
    }

    memoTextField.clear();

    numberComboBox.setValue(null);
    numberComboBox.setDisable(false);

    attachmentPane.clear();
  }
  @FXML
  public void initialize() {

    // Needed to support tri-state capability
    reconciledButton.setAllowIndeterminate(true);

    // Number combo needs to know the account in order to determine the next transaction number
    numberComboBox.accountProperty().bind(accountProperty());

    AutoCompleteFactory.setMemoModel(memoTextField);

    accountProperty.addListener(
        (observable, oldValue, newValue) -> {
          // Set the number of fixed decimal places for entry
          amountField.scaleProperty().set(newValue.getCurrencyNode().getScale());

          // Enabled auto completion for the payee field
          if (payeeTextField != null) { // transfer slips do not use the payee field
            AutoCompleteFactory.setPayeeModel(payeeTextField, newValue);
          }
        });

    // If focus is lost, check and load the form with an existing transaction
    if (payeeTextField != null) { // transfer slips do not use the payee field
      payeeTextField
          .focusedProperty()
          .addListener(
              (observable, oldValue, newValue) -> {
                if (!newValue) {
                  handlePayeeFocusChange();
                }
              });
    }

    // Install an event handler when the parent has been set via injection
    parentProperty.addListener(
        (observable, oldValue, newValue) -> {
          newValue.addEventHandler(
              KeyEvent.KEY_PRESSED,
              event -> {
                if (JavaFXUtils.ESCAPE_KEY.match(
                    event)) { // clear the form if an escape key is detected
                  clearForm();
                } else if (JavaFXUtils.ENTER_KEY.match(event)) { // handle an enter key if detected
                  if (validateForm()) {
                    Platform.runLater(AbstractSlipController.this::handleEnterAction);
                  } else {
                    Platform.runLater(
                        () -> {
                          if (event.getSource() instanceof Node) {
                            JavaFXUtils.focusNext((Node) event.getSource());
                          }
                        });
                  }
                }
              });
        });
  }
  @Override
  protected void updateDisplayNode() {
    final BigDecimal value = detailedDecimalTextField.getValue();

    if (initialDecimalFieldValue != null) {
      textField.setDecimal(initialDecimalFieldValue);
      initialDecimalFieldValue = null;
    } else {
      detailedDecimalTextField.setValue(value);
    }
  }
  private DecimalTextField getInputNode() {
    if (textField != null) return textField;

    textField = detailedDecimalTextField.getEditor();
    textField.setFocusTraversable(true);
    textField.promptTextProperty().bindBidirectional(detailedDecimalTextField.promptTextProperty());

    initialDecimalFieldValue = textField.getDecimal();

    focusChangeListener =
        (observable, oldValue, hasFocus) -> {
          // RT-21454 starts here
          if (!hasFocus) {
            setTextFromTextFieldIntoComboBoxValue();
            pseudoClassStateChanged(CONTAINS_FOCUS_PSEUDO_CLASS_STATE, false);
          } else {
            pseudoClassStateChanged(CONTAINS_FOCUS_PSEUDO_CLASS_STATE, true);
          }
        };

    textField.focusedProperty().addListener(new WeakChangeListener<>(focusChangeListener));

    return textField;
  }
  @Override
  public boolean validateForm() {
    if (payeeTextField != null) { // transfer slips do not use the payee field
      if (payeeTextField.getText() == null || payeeTextField.getText().isEmpty()) {
        ValidationFactory.showValidationWarning(
            payeeTextField, resources.getString("Message.Warn.EmptyPayee"));
      }
    }

    if (amountField.getDecimal().compareTo(BigDecimal.ZERO) == 0) {
      ValidationFactory.showValidationError(
          amountField, resources.getString("Message.Error.Value"));
      return false;
    }

    return true;
  }