Compare commits
9
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8e3af2ba32 | ||
|
|
b70a758099 | ||
|
|
3a69119eb7 | ||
|
|
165dc6d901 | ||
|
|
384dc2d853 | ||
|
|
2f69c48800 | ||
|
|
86a9eeaf2e | ||
|
|
9ba252b828 | ||
|
|
90d2de65de |
@@ -93,23 +93,27 @@ public class CropDetailController {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setPlantFromCrop(Crop crop) throws HardinessZoneNotSetException, IOException, PlantNotFoundException {
|
public void setPlantFromCrop(Crop crop) throws PlantNotFoundException {
|
||||||
this.crop = crop;
|
this.crop = crop;
|
||||||
Plant plant = plantList.getPlantById(Settings.getInstance().getCurrentHardinessZone(), crop.getPlantId())
|
try {
|
||||||
.orElseThrow(PlantNotFoundException::new);
|
Plant plant = plantList.getPlantById(Settings.getInstance().getCurrentHardinessZone(), crop.getPlantId())
|
||||||
|
.orElseThrow(PlantNotFoundException::new);
|
||||||
|
|
||||||
cropName_label.setText(plant.name());
|
cropName_label.setText(plant.name());
|
||||||
description_label.setText(plant.description());
|
description_label.setText(plant.description());
|
||||||
light_label.setText(String.valueOf(plant.light()));
|
light_label.setText(String.valueOf(plant.light()));
|
||||||
soil_label.setText(plant.soil());
|
soil_label.setText(plant.soil());
|
||||||
spacing_label.setText(plant.spacing());
|
spacing_label.setText(plant.spacing());
|
||||||
if (plant.image() != null) {
|
if (plant.image() != null) {
|
||||||
imageView.setImage(plant.image());
|
imageView.setImage(plant.image());
|
||||||
|
}
|
||||||
|
area_label.setText("");
|
||||||
|
location_label.setText("");
|
||||||
|
createTaskLists(crop);
|
||||||
|
createPestList(plant);
|
||||||
|
} catch (HardinessZoneNotSetException | IOException e) {
|
||||||
|
throw new PlantNotFoundException();
|
||||||
}
|
}
|
||||||
area_label.setText("");
|
|
||||||
location_label.setText("");
|
|
||||||
createTaskLists(crop);
|
|
||||||
createPestList(plant);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createTaskLists(Crop crop) {
|
private void createTaskLists(Crop crop) {
|
||||||
|
|||||||
@@ -90,10 +90,12 @@ public class MyGardenController {
|
|||||||
Label label = new Label(plant.name());
|
Label label = new Label(plant.name());
|
||||||
label.setMaxWidth(2000);
|
label.setMaxWidth(2000);
|
||||||
HBox.setHgrow(label, Priority.ALWAYS);
|
HBox.setHgrow(label, Priority.ALWAYS);
|
||||||
|
|
||||||
Button details = new Button("Details");
|
Button details = new Button("Details");
|
||||||
Button delete = new Button("delete");
|
Button delete = new Button("delete");
|
||||||
details.setOnAction(getGoToCropDetailEvent(crop));
|
details.setOnAction(getGoToCropDetailEvent(crop));
|
||||||
delete.setOnAction(getDeleteCropEvent(crop));
|
delete.setOnAction(getDeleteCropEvent(crop));
|
||||||
|
|
||||||
hBox.getChildren().addAll(imageView, label, details, delete);
|
hBox.getChildren().addAll(imageView, label, details, delete);
|
||||||
return hBox;
|
return hBox;
|
||||||
}
|
}
|
||||||
@@ -108,7 +110,7 @@ public class MyGardenController {
|
|||||||
stage.initModality(Modality.APPLICATION_MODAL);
|
stage.initModality(Modality.APPLICATION_MODAL);
|
||||||
stage.setResizable(true);
|
stage.setResizable(true);
|
||||||
stage.showAndWait();
|
stage.showAndWait();
|
||||||
} catch (IOException | HardinessZoneNotSetException | PlantNotFoundException e) {
|
} catch (IOException | PlantNotFoundException e) {
|
||||||
// TODO: show error alert
|
// TODO: show error alert
|
||||||
LOG.log(Level.SEVERE, "Could not load plant details.", e);
|
LOG.log(Level.SEVERE, "Could not load plant details.", e);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,9 +9,6 @@ import ch.zhaw.gartenverwaltung.models.GardenSchedule;
|
|||||||
import ch.zhaw.gartenverwaltung.types.Crop;
|
import ch.zhaw.gartenverwaltung.types.Crop;
|
||||||
import ch.zhaw.gartenverwaltung.types.Plant;
|
import ch.zhaw.gartenverwaltung.types.Plant;
|
||||||
import ch.zhaw.gartenverwaltung.types.Task;
|
import ch.zhaw.gartenverwaltung.types.Task;
|
||||||
import javafx.beans.property.ListProperty;
|
|
||||||
import javafx.beans.property.SimpleListProperty;
|
|
||||||
import javafx.collections.FXCollections;
|
|
||||||
import javafx.fxml.FXML;
|
import javafx.fxml.FXML;
|
||||||
import javafx.scene.control.Label;
|
import javafx.scene.control.Label;
|
||||||
import javafx.scene.control.ListCell;
|
import javafx.scene.control.ListCell;
|
||||||
@@ -37,8 +34,6 @@ public class MyScheduleController {
|
|||||||
@Inject
|
@Inject
|
||||||
private PlantList plantList;
|
private PlantList plantList;
|
||||||
|
|
||||||
private final ListProperty<Crop> cropListProperty = new SimpleListProperty<>(FXCollections.observableArrayList());
|
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private Label day1_label;
|
private Label day1_label;
|
||||||
|
|
||||||
@@ -90,15 +85,8 @@ public class MyScheduleController {
|
|||||||
@AfterInject
|
@AfterInject
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
public void init() {
|
public void init() {
|
||||||
List<Crop> cropList;
|
|
||||||
try {
|
|
||||||
cropList = garden.getCrops();
|
|
||||||
cropListProperty.addAll(cropList);
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
setCellFactoryListView();
|
setCellFactoryListView();
|
||||||
scheduledPlants_listview.itemsProperty().bind(cropListProperty);
|
scheduledPlants_listview.itemsProperty().bind(garden.getPlantedCrops());
|
||||||
lookForSelectedListEntries();
|
lookForSelectedListEntries();
|
||||||
setDayLabels();
|
setDayLabels();
|
||||||
information_label.setText("");
|
information_label.setText("");
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ import javafx.scene.image.Image;
|
|||||||
import javafx.scene.image.ImageView;
|
import javafx.scene.image.ImageView;
|
||||||
import javafx.scene.layout.AnchorPane;
|
import javafx.scene.layout.AnchorPane;
|
||||||
import javafx.scene.layout.VBox;
|
import javafx.scene.layout.VBox;
|
||||||
import javafx.stage.Stage;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
@@ -74,7 +73,6 @@ public class PlantsController {
|
|||||||
*/
|
*/
|
||||||
@FXML
|
@FXML
|
||||||
void selectSowDate() throws IOException {
|
void selectSowDate() throws IOException {
|
||||||
Stage stage = new Stage();
|
|
||||||
Dialog<LocalDate> dateSelection = new Dialog<>();
|
Dialog<LocalDate> dateSelection = new Dialog<>();
|
||||||
dateSelection.setTitle("Select Date");
|
dateSelection.setTitle("Select Date");
|
||||||
dateSelection.setHeaderText(String.format("Select Harvest/Sow Date for %s:", selectedPlant.name()));
|
dateSelection.setHeaderText(String.format("Select Harvest/Sow Date for %s:", selectedPlant.name()));
|
||||||
@@ -85,22 +83,21 @@ public class PlantsController {
|
|||||||
ButtonType sowButton = new ButtonType("Save", ButtonBar.ButtonData.OK_DONE);
|
ButtonType sowButton = new ButtonType("Save", ButtonBar.ButtonData.OK_DONE);
|
||||||
dialogPane.getButtonTypes().addAll(sowButton, ButtonType.CANCEL);
|
dialogPane.getButtonTypes().addAll(sowButton, ButtonType.CANCEL);
|
||||||
|
|
||||||
if (appLoader.loadSceneToStage("SelectSowDay.fxml", stage) instanceof SelectSowDayController controller) {
|
if (appLoader.loadPaneToDialog("SelectSowDay.fxml", dialogPane) instanceof SelectSowDayController controller) {
|
||||||
controller.initSaveButton((Button) dialogPane.lookupButton(sowButton));
|
controller.initSaveButton((Button) dialogPane.lookupButton(sowButton));
|
||||||
controller.setSelectedPlant(selectedPlant);
|
controller.setSelectedPlant(selectedPlant);
|
||||||
dateSelection.setResultConverter(button -> button.equals(sowButton) ? controller.retrieveResult() : null);
|
dateSelection.setResultConverter(button -> button.equals(sowButton) ? controller.retrieveResult() : null);
|
||||||
}
|
|
||||||
dialogPane.setContent(stage.getScene().getRoot());
|
|
||||||
|
|
||||||
dateSelection.showAndWait()
|
dateSelection.showAndWait()
|
||||||
.ifPresent(date -> {
|
.ifPresent(date -> {
|
||||||
try {
|
try {
|
||||||
garden.plantAsCrop(selectedPlant, date);
|
garden.plantAsCrop(selectedPlant, date);
|
||||||
} catch (IOException | HardinessZoneNotSetException | PlantNotFoundException e) {
|
} catch (IOException | HardinessZoneNotSetException | PlantNotFoundException e) {
|
||||||
LOG.log(Level.SEVERE, "Couldn't save Crop", e);
|
LOG.log(Level.SEVERE, "Couldn't save Crop", e);
|
||||||
}
|
}
|
||||||
plantsRoot.fireEvent(new ChangeViewEvent(ChangeViewEvent.CHANGE_MAIN_VIEW, "MyGarden.fxml"));
|
plantsRoot.fireEvent(new ChangeViewEvent(ChangeViewEvent.CHANGE_MAIN_VIEW, "MyGarden.fxml"));
|
||||||
});
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import javafx.scene.control.*;
|
|||||||
import javafx.util.Callback;
|
import javafx.util.Callback;
|
||||||
|
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class SelectSowDayController {
|
public class SelectSowDayController {
|
||||||
private Plant selectedPlant;
|
private Plant selectedPlant;
|
||||||
@@ -17,12 +16,15 @@ public class SelectSowDayController {
|
|||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private RadioButton harvest_radio;
|
private RadioButton harvest_radio;
|
||||||
|
@FXML
|
||||||
|
private RadioButton sow_radio;
|
||||||
|
@FXML
|
||||||
|
public ToggleGroup phase_group;
|
||||||
|
|
||||||
public LocalDate retrieveResult() {
|
public LocalDate retrieveResult() {
|
||||||
LocalDate sowDate = datepicker.getValue();
|
LocalDate sowDate = datepicker.getValue();
|
||||||
if (harvest_radio.isSelected()) {
|
if (harvest_radio.isSelected()) {
|
||||||
//ToDo method to get current lifecycle group in plant
|
sowDate = selectedPlant.sowDateFromHarvestDate(sowDate);
|
||||||
sowDate = selectedPlant.sowDateFromHarvestDate(datepicker.getValue(), 0);
|
|
||||||
}
|
}
|
||||||
return sowDate;
|
return sowDate;
|
||||||
}
|
}
|
||||||
@@ -46,6 +48,9 @@ public class SelectSowDayController {
|
|||||||
Callback<DatePicker, DateCell> dayCellFactory = getDayCellFactory();
|
Callback<DatePicker, DateCell> dayCellFactory = getDayCellFactory();
|
||||||
datepicker.setDayCellFactory(dayCellFactory);
|
datepicker.setDayCellFactory(dayCellFactory);
|
||||||
datepicker.setEditable(false);
|
datepicker.setEditable(false);
|
||||||
|
|
||||||
|
sow_radio.setUserData(GrowthPhaseType.SOW);
|
||||||
|
harvest_radio.setUserData(GrowthPhaseType.HARVEST);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void initSaveButton(Button saveButton) {
|
public void initSaveButton(Button saveButton) {
|
||||||
@@ -61,35 +66,28 @@ public class SelectSowDayController {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* date picker disable/enable dates according to selected plant: sow or harvest day
|
* date picker disable/enable dates according to selected plant: sow or harvest day
|
||||||
|
*
|
||||||
* @return cellFactory of datePicker
|
* @return cellFactory of datePicker
|
||||||
*/
|
*/
|
||||||
private Callback<DatePicker, DateCell> getDayCellFactory() {
|
private Callback<DatePicker, DateCell> getDayCellFactory() {
|
||||||
|
|
||||||
return (datePicker) -> new DateCell() {
|
return (datePicker) -> new DateCell() {
|
||||||
|
private final LocalDate today = LocalDate.now();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateItem(LocalDate item, boolean empty) {
|
public void updateItem(LocalDate item, boolean empty) {
|
||||||
super.updateItem(item, empty);
|
super.updateItem(item, empty);
|
||||||
setDisable(true);
|
setDisable(true);
|
||||||
setStyle("-fx-background-color: #ffc0cb;");
|
setStyle("-fx-background-color: #ffc0cb;");
|
||||||
List<LocalDate> dates;
|
|
||||||
LocalDate today = LocalDate.now();
|
if (item.compareTo(today) > 0 && (!harvest_radio.isSelected() || selectedPlant.sowDateFromHarvestDate(item).compareTo(today) >= 0)) {
|
||||||
if (harvest_radio.isSelected()) {
|
GrowthPhaseType selectedPhase = (GrowthPhaseType) phase_group.getSelectedToggle().getUserData();
|
||||||
dates = selectedPlant.getDateListOfGrowthPhase(GrowthPhaseType.HARVEST);
|
|
||||||
} else {
|
if (selectedPlant.isDateInPhase(item, selectedPhase)) {
|
||||||
dates = selectedPlant.getDateListOfGrowthPhase(GrowthPhaseType.SOW);
|
|
||||||
}
|
|
||||||
for (LocalDate date : dates) {
|
|
||||||
if (item.getMonth() == date.getMonth()
|
|
||||||
&& item.getDayOfMonth() == date.getDayOfMonth()
|
|
||||||
&& item.compareTo(today) > 0) {
|
|
||||||
setDisable(false);
|
setDisable(false);
|
||||||
setStyle("-fx-background-color: #32CD32;");
|
setStyle("-fx-background-color: #32CD32;");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((harvest_radio.isSelected() && selectedPlant.sowDateFromHarvestDate(item, 0).compareTo(today) < 0)) {
|
|
||||||
setDisable(true);
|
|
||||||
setStyle("-fx-background-color: #ffc0cb;");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import ch.zhaw.gartenverwaltung.models.GardenSchedule;
|
|||||||
import ch.zhaw.gartenverwaltung.models.PlantListModel;
|
import ch.zhaw.gartenverwaltung.models.PlantListModel;
|
||||||
import javafx.fxml.FXMLLoader;
|
import javafx.fxml.FXMLLoader;
|
||||||
import javafx.scene.Scene;
|
import javafx.scene.Scene;
|
||||||
|
import javafx.scene.control.DialogPane;
|
||||||
import javafx.scene.layout.Pane;
|
import javafx.scene.layout.Pane;
|
||||||
import javafx.stage.Stage;
|
import javafx.stage.Stage;
|
||||||
|
|
||||||
@@ -78,6 +79,24 @@ public class AppLoader {
|
|||||||
return controller;
|
return controller;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads the given fxml-file from resources (no caching) and appendeds it's
|
||||||
|
* contents to the given {@link DialogPane}.
|
||||||
|
* Performs dependency-injection.
|
||||||
|
*
|
||||||
|
* @param fxmlFile The file name to be loaded
|
||||||
|
* @param appendee The {@link DialogPane} to which the FXML contents are to be appended.
|
||||||
|
* @return The controller of the loaded scene.
|
||||||
|
* @throws IOException if the file could not be loaded
|
||||||
|
*/
|
||||||
|
public Object loadPaneToDialog(String fxmlFile, DialogPane appendee) throws IOException {
|
||||||
|
FXMLLoader loader = new FXMLLoader(Objects.requireNonNull(HelloApplication.class.getResource(fxmlFile)));
|
||||||
|
appendee.setContent(loader.load());
|
||||||
|
Object controller = loader.getController();
|
||||||
|
annotationInject(controller);
|
||||||
|
return controller;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads the given fxml-file from resources and caches the pane.
|
* Loads the given fxml-file from resources and caches the pane.
|
||||||
* Performs dependency-injection.
|
* Performs dependency-injection.
|
||||||
|
|||||||
@@ -46,7 +46,8 @@ public class GardenSchedule {
|
|||||||
*/
|
*/
|
||||||
public void planTasksForCrop(Crop crop) throws PlantNotFoundException, HardinessZoneNotSetException, IOException {
|
public void planTasksForCrop(Crop crop) throws PlantNotFoundException, HardinessZoneNotSetException, IOException {
|
||||||
Plant plant = plantList.getPlantById(Settings.getInstance().getCurrentHardinessZone(), crop.getPlantId()).orElseThrow(PlantNotFoundException::new);
|
Plant plant = plantList.getPlantById(Settings.getInstance().getCurrentHardinessZone(), crop.getPlantId()).orElseThrow(PlantNotFoundException::new);
|
||||||
for (GrowthPhase growthPhase : plant.lifecycle()) {
|
int growPhaseGroup = plant.getGrowphaseGroupForDate(crop.getStartDate());
|
||||||
|
for (GrowthPhase growthPhase : plant.lifecycleForGroup(growPhaseGroup)) {
|
||||||
for (TaskTemplate taskTemplate : growthPhase.taskTemplates()) {
|
for (TaskTemplate taskTemplate : growthPhase.taskTemplates()) {
|
||||||
addTask(taskTemplate.generateTask(crop.getStartDate(), crop.getCropId().orElse(0L)));
|
addTask(taskTemplate.generateTask(crop.getStartDate(), crop.getCropId().orElse(0L)));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ package ch.zhaw.gartenverwaltung.types;
|
|||||||
import javafx.scene.image.Image;
|
import javafx.scene.image.Image;
|
||||||
|
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.util.LinkedList;
|
import java.time.MonthDay;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@@ -39,14 +39,23 @@ public record Plant(
|
|||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getGrowphaseGroupForDate(LocalDate date) {
|
||||||
|
for(GrowthPhase growthPhase : lifecycle){
|
||||||
|
MonthDay plantingDate = MonthDay.of(date.getMonth().getValue(), date.getDayOfMonth());
|
||||||
|
if(plantingDate.isAfter(growthPhase.startDate()) && plantingDate.isBefore(growthPhase.endDate())){
|
||||||
|
return growthPhase.group();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0; // TODO implement
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get sow date from given harvest day from lifecycle group
|
* get sow date from given harvest day from lifecycle group
|
||||||
* @param harvestDate date of the harvest
|
* @param harvestDate date of the harvest
|
||||||
* @param group lifecycle group
|
|
||||||
* @return LocaleDate of sow date
|
* @return LocaleDate of sow date
|
||||||
*/
|
*/
|
||||||
public LocalDate sowDateFromHarvestDate(LocalDate harvestDate, int group) {
|
public LocalDate sowDateFromHarvestDate(LocalDate harvestDate) {
|
||||||
return harvestDate.minusDays(timeToHarvest(group));
|
return harvestDate.minusDays(timeToHarvest(lifecycleGroupFromHarvestDate(harvestDate)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -69,37 +78,43 @@ public record Plant(
|
|||||||
return (int) DAYS.between(harvest.startDate().atYear(currentYear), sow.startDate().atYear(currentYear));
|
return (int) DAYS.between(harvest.startDate().atYear(currentYear), sow.startDate().atYear(currentYear));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public int lifecycleGroupFromHarvestDate(LocalDate harvestDate) {
|
||||||
* filter out the given growthPhase out of the lifecycle
|
return lifecycle.stream()
|
||||||
* create list of dates for this growthPhase and return it
|
.filter(growthPhase -> growthPhase.type().equals(GrowthPhaseType.HARVEST) &&
|
||||||
* @param growthPhase the wanted growthPhase
|
dateInRange(harvestDate, growthPhase.startDate(), growthPhase.endDate()))
|
||||||
* @return a list of dates of the current year
|
.map(GrowthPhase::group)
|
||||||
*/
|
.findFirst()
|
||||||
public List<LocalDate> getDateListOfGrowthPhase(GrowthPhaseType growthPhase) {
|
.orElse(0);
|
||||||
List<LocalDate> dates = new LinkedList<>();
|
|
||||||
for (GrowthPhase growth : lifecycle) {
|
|
||||||
if (growth.type().equals(growthPhase)) {
|
|
||||||
dates = addDatesFromMonthDay(growth);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return dates;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* transform monthDay value of the given growthPhase to localDate
|
* Checks if the given {@link LocalDate} is within a {@link GrowthPhase} of the given {@link GrowthPhaseType}
|
||||||
* return a list of dates from start to end of growth phase
|
*
|
||||||
* @param growthPhase the current growthPhase
|
* @param date The date to check.
|
||||||
* @return a list of dates of the current year
|
* @param phase The {@link GrowthPhaseType} to match against
|
||||||
|
* @return Whether the date is within the given {@link GrowthPhaseType}
|
||||||
*/
|
*/
|
||||||
private List<LocalDate> addDatesFromMonthDay(GrowthPhase growthPhase) {
|
public boolean isDateInPhase(LocalDate date, GrowthPhaseType phase) {
|
||||||
List<LocalDate> dates = new LinkedList<>();
|
return lifecycle.stream()
|
||||||
LocalDate today = LocalDate.now();
|
.filter(growthPhase -> growthPhase.type().equals(phase))
|
||||||
LocalDate start = growthPhase.startDate().atYear(today.getYear());
|
.anyMatch(growthPhase -> dateInRange(date, growthPhase.startDate(), growthPhase.endDate()));
|
||||||
LocalDate end = growthPhase.endDate().atYear(today.getYear());
|
}
|
||||||
while (!start.isAfter(end)) {
|
|
||||||
dates.add(start);
|
/**
|
||||||
start = start.plusDays(1);
|
* Checks if the given {@link LocalDate} is within the given {@link MonthDay} range.
|
||||||
}
|
* (regardless of year)
|
||||||
return dates;
|
*
|
||||||
|
* @param subject The date to check
|
||||||
|
* @param min The start of the date-range
|
||||||
|
* @param max The end of the date-range
|
||||||
|
* @return Whether the subject is within the range.
|
||||||
|
*/
|
||||||
|
private boolean dateInRange(LocalDate subject, MonthDay min, MonthDay max) {
|
||||||
|
return subject.getMonth().compareTo(min.getMonth()) >= 0 &&
|
||||||
|
subject.getMonth().compareTo(max.getMonth()) <= 0 &&
|
||||||
|
// if the day is less than the minimum day, the minimum month must not be equal
|
||||||
|
(subject.getDayOfMonth() >= min.getDayOfMonth() || !subject.getMonth().equals(min.getMonth())) &&
|
||||||
|
// if the day is greater than the maximum day, the maximum month must not be equal
|
||||||
|
(subject.getDayOfMonth() <= max.getDayOfMonth() || !subject.getMonth().equals(max.getMonth()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,15 +18,15 @@
|
|||||||
<children>
|
<children>
|
||||||
<VBox alignment="CENTER_LEFT" prefHeight="88.0" prefWidth="155.0">
|
<VBox alignment="CENTER_LEFT" prefHeight="88.0" prefWidth="155.0">
|
||||||
<children>
|
<children>
|
||||||
<RadioButton fx:id="sow_radio" mnemonicParsing="false" selected="true" text="Sow" toggleGroup="$group">
|
<RadioButton fx:id="sow_radio" mnemonicParsing="false" selected="true" text="Sow" toggleGroup="$phase_group">
|
||||||
<VBox.margin>
|
<VBox.margin>
|
||||||
<Insets bottom="10.0" />
|
<Insets bottom="10.0" />
|
||||||
</VBox.margin>
|
</VBox.margin>
|
||||||
<toggleGroup>
|
<toggleGroup>
|
||||||
<ToggleGroup fx:id="group" />
|
<ToggleGroup fx:id="phase_group" />
|
||||||
</toggleGroup>
|
</toggleGroup>
|
||||||
</RadioButton>
|
</RadioButton>
|
||||||
<RadioButton fx:id="harvest_radio" mnemonicParsing="false" text="Harvest" toggleGroup="$group" />
|
<RadioButton fx:id="harvest_radio" mnemonicParsing="false" text="Harvest" toggleGroup="$phase_group" />
|
||||||
</children>
|
</children>
|
||||||
<HBox.margin>
|
<HBox.margin>
|
||||||
<Insets top="10.0" />
|
<Insets top="10.0" />
|
||||||
|
|||||||
+62
-24
@@ -1,35 +1,45 @@
|
|||||||
package ch.zhaw.gartenverwaltung.taskList;
|
package ch.zhaw.gartenverwaltung.models;
|
||||||
|
|
||||||
import ch.zhaw.gartenverwaltung.io.*;
|
import ch.zhaw.gartenverwaltung.io.*;
|
||||||
import ch.zhaw.gartenverwaltung.models.GardenSchedule;
|
import ch.zhaw.gartenverwaltung.models.GardenSchedule;
|
||||||
import ch.zhaw.gartenverwaltung.types.HardinessZone;
|
import ch.zhaw.gartenverwaltung.types.*;
|
||||||
import ch.zhaw.gartenverwaltung.types.Plant;
|
|
||||||
import ch.zhaw.gartenverwaltung.types.Task;
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
|
import java.time.MonthDay;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.*;
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
import static org.mockito.Mockito.*;
|
import static org.mockito.Mockito.*;
|
||||||
|
|
||||||
class GardenScheduleTest {
|
class GardenScheduleTest {
|
||||||
|
LocalDate exampleStartDate = LocalDate.of(2020, 02, 02);
|
||||||
TaskList taskList;
|
TaskList taskList;
|
||||||
PlantList plantList;
|
PlantList plantList;
|
||||||
|
List<Plant> examplePlantList;
|
||||||
List<Task> exampleTaskList;
|
List<Task> exampleTaskList;
|
||||||
Map<Long, Plant> examplePlantMap;
|
List<TaskTemplate> exampleTaskTemplateList;
|
||||||
GardenSchedule model;
|
GardenSchedule model;
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
void setUp() throws IOException {
|
void setUp() throws IOException, HardinessZoneNotSetException {
|
||||||
createExampleTaskList();
|
createExampleTaskList();
|
||||||
|
createExampleTaskTemplateList();
|
||||||
|
createExamplePlantList();
|
||||||
taskList = mockTaskDatabase(exampleTaskList);
|
taskList = mockTaskDatabase(exampleTaskList);
|
||||||
plantList = mockPlantDatabase(examplePlantMap);
|
plantList = mockPlantDatabase(examplePlantList);
|
||||||
model = new GardenSchedule(taskList, plantList);
|
model = new GardenSchedule(taskList, plantList);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PlantList mockPlantDatabase(List<Plant> plantList) throws HardinessZoneNotSetException, IOException {
|
||||||
|
PlantList plantDatabase = mock(JsonPlantList.class);
|
||||||
|
when(plantDatabase.getPlantList(HardinessZone.ZONE_8A)).thenReturn(plantList);
|
||||||
|
when(plantDatabase.getPlantById(HardinessZone.ZONE_8A,20)).thenReturn(Optional.of(examplePlantList.get(0)));
|
||||||
|
return plantDatabase;
|
||||||
|
}
|
||||||
|
|
||||||
private TaskList mockTaskDatabase(List<Task> exampleTaskList) throws IOException {
|
private TaskList mockTaskDatabase(List<Task> exampleTaskList) throws IOException {
|
||||||
TaskList taskList = mock(JsonTaskList.class);
|
TaskList taskList = mock(JsonTaskList.class);
|
||||||
when(taskList.getTaskList(LocalDate.MIN, LocalDate.MAX)).thenReturn(exampleTaskList);
|
when(taskList.getTaskList(LocalDate.MIN, LocalDate.MAX)).thenReturn(exampleTaskList);
|
||||||
@@ -54,18 +64,39 @@ class GardenScheduleTest {
|
|||||||
return taskList;
|
return taskList;
|
||||||
}
|
}
|
||||||
|
|
||||||
private PlantList mockPlantDatabase(Map<Long, Plant> examplePlantMap) {
|
void createExampleTaskTemplateList(){
|
||||||
return new PlantList() {
|
exampleTaskTemplateList = new ArrayList<>();
|
||||||
@Override
|
exampleTaskTemplateList.add(mock(TaskTemplate.class));
|
||||||
public List<Plant> getPlantList(HardinessZone zone) {
|
exampleTaskTemplateList.add(mock(TaskTemplate.class));
|
||||||
return null;
|
exampleTaskTemplateList.add(mock(TaskTemplate.class));
|
||||||
}
|
exampleTaskTemplateList.add(mock(TaskTemplate.class));
|
||||||
|
when(exampleTaskTemplateList.get(0).generateTask(exampleStartDate, 30)).thenReturn(exampleTaskList.get(0));
|
||||||
|
when(exampleTaskTemplateList.get(1).generateTask(exampleStartDate, 30)).thenReturn(exampleTaskList.get(1));
|
||||||
|
when(exampleTaskTemplateList.get(2).generateTask(exampleStartDate, 30)).thenReturn(exampleTaskList.get(2));
|
||||||
|
when(exampleTaskTemplateList.get(3).generateTask(exampleStartDate, 30)).thenReturn(exampleTaskList.get(3));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
void createExamplePlantList(){
|
||||||
public Optional<Plant> getPlantById(HardinessZone zone, long id) {
|
examplePlantList = new ArrayList<>();
|
||||||
return Optional.ofNullable(examplePlantMap.get(id));
|
examplePlantList.add(new Plant(
|
||||||
}
|
20,
|
||||||
};
|
"summertime onion",
|
||||||
|
"Onion, (Allium cepa), herbaceous biennial plant in the amaryllis family (Amaryllidaceae) grown for its edible bulb. The onion is likely native to southwestern Asia but is now grown throughout the world, chiefly in the temperate zones. Onions are low in nutrients but are valued for their flavour and are used widely in cooking. They add flavour to such dishes as stews, roasts, soups, and salads and are also served as a cooked vegetable.",
|
||||||
|
null,
|
||||||
|
"15,30,2",
|
||||||
|
0,
|
||||||
|
"sandy to loamy, loose soil, free of stones",
|
||||||
|
new ArrayList<>(),
|
||||||
|
List.of(
|
||||||
|
new GrowthPhase(MonthDay.of(6, 4), MonthDay.of(12, 4), 0, new WateringCycle(0, 0, null), GrowthPhaseType.HARVEST, HardinessZone.ZONE_8A, List.of(
|
||||||
|
exampleTaskTemplateList.get(0),
|
||||||
|
exampleTaskTemplateList.get(1)
|
||||||
|
)),
|
||||||
|
new GrowthPhase(MonthDay.of(4, 3), MonthDay.of(12, 4), 0, new WateringCycle(0, 0, null), GrowthPhaseType.PLANT, HardinessZone.ZONE_8A, List.of(
|
||||||
|
exampleTaskTemplateList.get(2),
|
||||||
|
exampleTaskTemplateList.get(3)
|
||||||
|
))
|
||||||
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void createExampleTaskList() {
|
void createExampleTaskList() {
|
||||||
@@ -77,12 +108,6 @@ class GardenScheduleTest {
|
|||||||
exampleTaskList.add(new Task("name", "description", LocalDate.of(2019, 5, 5), 2L));
|
exampleTaskList.add(new Task("name", "description", LocalDate.of(2019, 5, 5), 2L));
|
||||||
}
|
}
|
||||||
|
|
||||||
void createExamplePlantMap() {
|
|
||||||
examplePlantMap = new HashMap<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void addTask() throws IOException {
|
void addTask() throws IOException {
|
||||||
Task taskToAdd = new Task("name", "description", LocalDate.now(), 1L);
|
Task taskToAdd = new Task("name", "description", LocalDate.now(), 1L);
|
||||||
@@ -156,4 +181,17 @@ class GardenScheduleTest {
|
|||||||
model.removeTasksForCrop(1L);
|
model.removeTasksForCrop(1L);
|
||||||
verify(taskList, times(1)).removeTasksForCrop(1L);
|
verify(taskList, times(1)).removeTasksForCrop(1L);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void planTasksForCrop() throws HardinessZoneNotSetException, PlantNotFoundException, IOException {
|
||||||
|
model.planTasksForCrop(new Crop(20, exampleStartDate).withId(30));
|
||||||
|
verify(exampleTaskTemplateList.get(0), times(1)).generateTask(exampleStartDate, 30);
|
||||||
|
verify(exampleTaskTemplateList.get(1), times(1)).generateTask(exampleStartDate, 30);
|
||||||
|
verify(exampleTaskTemplateList.get(2), times(1)).generateTask(exampleStartDate, 30);
|
||||||
|
verify(exampleTaskTemplateList.get(3), times(1)).generateTask(exampleStartDate, 30);
|
||||||
|
verify(taskList, times(1)).saveTask(exampleTaskList.get(0));
|
||||||
|
verify(taskList, times(1)).saveTask(exampleTaskList.get(1));
|
||||||
|
verify(taskList, times(1)).saveTask(exampleTaskList.get(2));
|
||||||
|
verify(taskList, times(1)).saveTask(exampleTaskList.get(3));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user