/**
* Copyright [2015] [Christian Loehnert]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package de.ks.idnadrev.cost.bookingview;
import de.ks.BaseController;
import de.ks.executor.group.LastTextChange;
import de.ks.i18n.Localized;
import de.ks.idnadrev.cost.pattern.view.BookingPatternParser;
import de.ks.idnadrev.entity.cost.Account;
import de.ks.idnadrev.entity.cost.Booking;
import de.ks.javafx.event.ClearTextOnEscape;
import de.ks.persistence.PersistentWork;
import de.ks.validation.validators.DoubleValidator;
import de.ks.validation.validators.NotNullValidator;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.scene.control.*;
import javafx.stage.Modality;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.inject.Inject;
import java.net.URL;
import java.time.LocalDate;
import java.util.List;
import java.util.Optional;
import java.util.ResourceBundle;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;
public class BookingViewController extends BaseController<BookingViewModel> {
private static final Logger log = LoggerFactory.getLogger(BookingViewController.class);
@FXML
protected DatePicker startTime;
@FXML
protected DatePicker endTime;
@FXML
protected ComboBox<String> account;
@FXML
protected TextField amount;
@FXML
protected TextField description;
@FXML
protected TextField category;
@FXML
protected Button delete;
@FXML
protected Button applyPatterns;
@FXML
protected BookingViewTableController bookingTableController;
@Inject
BookingPatternParser patternParser;
@Override
public void initialize(URL location, ResourceBundle resources) {
startTime.setValue(LocalDate.now().minusMonths(3));
endTime.setValue(LocalDate.now().plusDays(1));
validationRegistry.registerValidator(startTime, new NotNullValidator());
validationRegistry.registerValidator(endTime, new NotNullValidator());
validationRegistry.registerValidator(amount, new DoubleValidator());
account.valueProperty().addListener((p, o, n) -> applyLoadingHintAndReload());
startTime.valueProperty().addListener((p, o, n) -> applyLoadingHintAndReload());
endTime.valueProperty().addListener((p, o, n) -> applyLoadingHintAndReload());
new LastTextChange(amount, 500, controller.getExecutorService()).registerHandler(t -> applyLoadingHintAndReload());
new LastTextChange(description, 500, controller.getExecutorService()).registerHandler(t -> applyLoadingHintAndReload());
new LastTextChange(category, 500, controller.getExecutorService()).registerHandler(t -> applyLoadingHintAndReload());
amount.setOnKeyReleased(new ClearTextOnEscape());
description.setOnKeyReleased(new ClearTextOnEscape());
category.setOnKeyReleased(new ClearTextOnEscape());
}
public void applyLoadingHintAndReload() {
applyLoadingHint();
store.reload();
}
protected void applyLoadingHint() {
BookingLoadingHint hint = new BookingLoadingHint(account.getValue());
hint.setStartDate(startTime.getValue());
hint.setEndDate(endTime.getValue());
String desc = description.textProperty().getValueSafe().trim();
if (!desc.isEmpty()) {
hint.setDescription(desc);
}
String amt = amount.textProperty().getValueSafe().trim();
if (!amt.isEmpty()) {
try {
hint.setAmount(Double.valueOf(amt));
} catch (NumberFormatException e) {
log.trace("Could not set new value", amt);
}
}
String cat = category.textProperty().getValueSafe().trim();
if (!cat.isEmpty()) {
hint.setCategory(cat);
}
store.getDatasource().setLoadingHint(hint);
}
@Override
public void onStart() {
onResume();
}
@Override
public void onResume() {
startTime.setValue(LocalDate.now().minusMonths(3));
endTime.setValue(LocalDate.now().plusDays(1));
CompletableFuture.supplyAsync(() -> PersistentWork.from(Account.class), controller.getExecutorService())//
.thenAcceptAsync(accounts -> {
List<String> accountNames = accounts.stream().map(a -> a.getName()).collect(Collectors.toList());
account.getItems().clear();
account.getItems().addAll(accountNames);
if (!accountNames.isEmpty()) {
account.getSelectionModel().select(0);
}
}, controller.getJavaFXExecutor());
}
@FXML
public void onDelete() {
boolean interactive = false;
onDelete(interactive);
}
protected void onDelete(boolean interactive) {
List<Booking> bookingsToDelete = bookingTableController.getMarked().entrySet().stream().filter(e -> e.getValue().get()).map(e -> e.getKey()).collect(Collectors.toList());
Optional optional;
if (interactive) {
Dialog dialog = new Dialog();
dialog.initModality(Modality.APPLICATION_MODAL);
dialog.setContentText(Localized.get("bookings.delete", bookingsToDelete.size()));
dialog.setTitle(Localized.get("delete"));
dialog.setOnCloseRequest(r -> dialog.close());
ButtonType yes = new ButtonType(Localized.get("yes"), ButtonBar.ButtonData.YES);
ButtonType no = new ButtonType(Localized.get("no"), ButtonBar.ButtonData.NO);
dialog.getDialogPane().getButtonTypes().addAll(yes, no);
optional = dialog.showAndWait().filter(response -> {
ButtonType type = (ButtonType) response;
return type.getButtonData() == ButtonBar.ButtonData.YES;
});
} else {
optional = Optional.of(true);
}
optional.ifPresent(o -> {
PersistentWork.run(em -> {
for (Booking booking : bookingsToDelete) {
Booking reload = PersistentWork.reload(booking);
em.remove(reload);
}
});
controller.reload();
});
}
@FXML
public void onApplyPatterns() {
ObservableList<Booking> items = bookingTableController.getBookingTable().getItems();
store.executeCustomRunnable(() -> {
items.forEach(i -> {
PersistentWork.wrap(() -> {
Booking reload = PersistentWork.reload(i);
String result = patternParser.parseLine(reload.getDescription());
if (result != null) {
reload.setCategory(result);
}
});
});
});
store.reload();
}
protected TableView<Booking> getBookingTable() {
return bookingTableController.bookingTable;
}
}