Compare commits

..

No commits in common. "8a2119028ca206d06909fea1d6635bf8b06d06e2" and "56020a7529a5064010cdac6224bdc96fedb2cf03" have entirely different histories.

13 changed files with 76 additions and 286 deletions

View File

@ -3,15 +3,15 @@ package ch.zhaw.gartenverwaltung;
import ch.zhaw.gartenverwaltung.bootstrap.AfterInject; import ch.zhaw.gartenverwaltung.bootstrap.AfterInject;
import ch.zhaw.gartenverwaltung.bootstrap.Inject; import ch.zhaw.gartenverwaltung.bootstrap.Inject;
import ch.zhaw.gartenverwaltung.io.PlantList; import ch.zhaw.gartenverwaltung.io.PlantList;
import ch.zhaw.gartenverwaltung.io.TaskList;
import ch.zhaw.gartenverwaltung.models.Garden; import ch.zhaw.gartenverwaltung.models.Garden;
import ch.zhaw.gartenverwaltung.io.HardinessZoneNotSetException; import ch.zhaw.gartenverwaltung.io.HardinessZoneNotSetException;
import ch.zhaw.gartenverwaltung.models.GardenSchedule; 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.application.Platform;
import javafx.beans.property.ListProperty; import javafx.beans.property.ListProperty;
import javafx.beans.property.SimpleListProperty;
import javafx.collections.FXCollections;
import javafx.event.ActionEvent; import javafx.event.ActionEvent;
import javafx.event.EventHandler; import javafx.event.EventHandler;
import javafx.fxml.FXML; import javafx.fxml.FXML;
@ -51,15 +51,9 @@ public class MyScheduleController {
@FXML @FXML
private ListView<Crop> scheduledPlants_listview; private ListView<Crop> scheduledPlants_listview;
@FXML
private void showAllTasks(ActionEvent actionEvent) throws IOException {
gardenSchedule.getTasksUpcomingWeek();
scheduledPlants_listview.getSelectionModel().clearSelection();
}
@AfterInject @AfterInject
@SuppressWarnings("unused") @SuppressWarnings("unused")
public void init() throws IOException { public void init() {
setCellFactoryCropListView(); setCellFactoryCropListView();
setCellFactoryTaskListView(); setCellFactoryTaskListView();
scheduledPlants_listview.itemsProperty().bind(garden.getPlantedCrops()); scheduledPlants_listview.itemsProperty().bind(garden.getPlantedCrops());
@ -67,19 +61,6 @@ public class MyScheduleController {
week_listView.itemsProperty().bind(taskListProperty); week_listView.itemsProperty().bind(taskListProperty);
lookForSelectedListEntries(); lookForSelectedListEntries();
information_label.setText(""); information_label.setText("");
gardenSchedule.getTasksUpcomingWeek();
TaskList.TaskListObserver taskListObserver = newTaskList -> {
Platform.runLater(() -> {
try {
gardenSchedule.getTasksUpcomingWeek();
scheduledPlants_listview.getSelectionModel().clearSelection();
} catch (IOException e) {
throw new RuntimeException(e);
}
});
};
gardenSchedule.setTaskListObserver(taskListObserver);
} }
/** /**
@ -100,8 +81,6 @@ public class MyScheduleController {
* set cellFactory for the crops. * set cellFactory for the crops.
*/ */
private void setCellFactoryCropListView() { private void setCellFactoryCropListView() {
MultipleSelectionModel<Crop> selectionModel = scheduledPlants_listview.getSelectionModel();
selectionModel.setSelectionMode(SelectionMode.MULTIPLE);
scheduledPlants_listview.setCellFactory(param -> new ListCell<>() { scheduledPlants_listview.setCellFactory(param -> new ListCell<>() {
@Override @Override
protected void updateItem(Crop crop, boolean empty) { protected void updateItem(Crop crop, boolean empty) {
@ -154,6 +133,8 @@ public class MyScheduleController {
} else { } else {
gardenSchedule.getTasksUpcomingWeek(); gardenSchedule.getTasksUpcomingWeek();
} }
//taskListProperty.clear();
//taskListProperty.addAll(taskLists);
} }
/** /**
@ -221,4 +202,5 @@ public class MyScheduleController {
}); });
} }
} }

View File

@ -22,8 +22,6 @@ public class TutorialController {
public ImageView imgAddNewPlant; public ImageView imgAddNewPlant;
public ImageView imgTaskList; public ImageView imgTaskList;
public ImageView imgSelectDate; public ImageView imgSelectDate;
public ImageView imgAddTaskButton;
public ImageView imgDetailDeleteButtons;
private int page = 0; private int page = 0;
@ -32,17 +30,10 @@ public class TutorialController {
switchViews(); switchViews();
setButtonAbilities(); setButtonAbilities();
Image addNewPlantImage = new Image(String.valueOf(PlantsController.class.getResource("add-new-plant.png"))); Image placeholder = new Image(String.valueOf(PlantsController.class.getResource("placeholder.png")));
Image selectSowHarvestImage = new Image(String.valueOf(PlantsController.class.getResource("select-sow-harvest.png"))); imgAddNewPlant.setImage(placeholder);
Image scheduleImage = new Image(String.valueOf(PlantsController.class.getResource("schedule.png"))); imgSelectDate.setImage(placeholder);
Image detailDeleteButtonsImage = new Image(String.valueOf(PlantsController.class.getResource("details-delete.png"))); imgTaskList.setImage(placeholder);
Image addTaskImage = new Image(String.valueOf(PlantsController.class.getResource("add-task.png")));
imgAddNewPlant.setImage(addNewPlantImage);
imgSelectDate.setImage(selectSowHarvestImage);
imgDetailDeleteButtons.setImage(detailDeleteButtonsImage);
imgAddTaskButton.setImage(addTaskImage);
imgTaskList.setImage(scheduleImage);
} }
public void viewNextPage() { public void viewNextPage() {

View File

@ -25,12 +25,11 @@ public class BackgroundTasks extends TimerTask {
private void movePastTasks() throws IOException { private void movePastTasks() throws IOException {
List<Task> taskList = this.taskList.getTaskList(LocalDate.MIN, LocalDate.now().minusDays(1)); List<Task> taskList = this.taskList.getTaskList(LocalDate.MIN, LocalDate.now().minusDays(1));
for (Task task : taskList) { taskList.forEach(task -> {
if (!task.isDone()) { if (!task.isDone()) {
task.setNextExecution(LocalDate.now()); task.setNextExecution(LocalDate.now());
this.taskList.saveTask(task);
}
} }
});
} }
public BackgroundTasks(TaskList taskList, CropList cropList, PlantList plantList) { public BackgroundTasks(TaskList taskList, CropList cropList, PlantList plantList) {

View File

@ -9,12 +9,8 @@ import ch.zhaw.gartenverwaltung.types.*;
import java.io.IOException; import java.io.IOException;
import java.time.LocalDate; import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List; import java.util.List;
import static java.util.stream.Collectors.toList;
/** /**
* The WeatherGardenTaskPlanner creates Tasks based on weather events and the rain amount from the last days * The WeatherGardenTaskPlanner creates Tasks based on weather events and the rain amount from the last days
* *
@ -47,7 +43,8 @@ public class WeatherGradenTaskPlanner {
private void getSevereWeatherEvents() throws IOException { private void getSevereWeatherEvents() throws IOException {
SevereWeather actualWeather = weatherService.causeSevereWeather(1); SevereWeather actualWeather = weatherService.causeSevereWeather(1);
if (SevereWeather.HAIL.equals(actualWeather)) { if (SevereWeather.HAIL.equals(actualWeather)) {
createPreHailTask(); //ToDo creates hail task all 3 seconds, pls fix
//createPreHailTask();
} else if (SevereWeather.FROST.equals(actualWeather)) { } else if (SevereWeather.FROST.equals(actualWeather)) {
createPreFrostTask(); createPreFrostTask();
} else if (SevereWeather.SNOW.equals(actualWeather)) { } else if (SevereWeather.SNOW.equals(actualWeather)) {
@ -66,27 +63,11 @@ public class WeatherGradenTaskPlanner {
*/ */
private void createPreHailTask() throws IOException { private void createPreHailTask() throws IOException {
List<Crop> actualCrops = cropList.getCrops();
for (Crop crop : actualCrops) {
Task preHailTask = new Task("Hail", Task preHailTask = new Task("Hail",
"During a summer Thunderstorm it could hail heavily. THe Hail could damage the crops. To prevent damage cover the plants with a strong tarpaulin", "During a summer Thunderstorm it could hail heavily. THe Hail could damage the crops. To prevent damage cover the plants with a strong tarpaulin",
dateSevereWeather,dateSevereWeather.plusDays(1L),crop.getCropId().orElse(-1L)); dateSevereWeather.minusDays(1L),dateSevereWeather.plusDays(1L),1L);
List<Task> actualCropTaskList = taskList.getTaskForCrop(crop.getCropId().orElse(-1L));
List<Task> hailTasklist = actualCropTaskList.stream().filter(task -> task.getName().equals("Hail")).toList();
List<Task> hailTaskListAtDate = new ArrayList<>();
for (Task task : hailTasklist) {
if (task.getStartDate() == (preHailTask.getStartDate())) {
hailTaskListAtDate.add(task);
}
}
if(hailTaskListAtDate.isEmpty() && hailTasklist.isEmpty()){
taskList.saveTask(preHailTask); taskList.saveTask(preHailTask);
}
}
} }
/** /**
@ -94,56 +75,23 @@ public class WeatherGradenTaskPlanner {
* @throws IOException If the database cannot be accessed * @throws IOException If the database cannot be accessed
*/ */
private void createPreFrostTask() throws IOException { private void createPreFrostTask() throws IOException {
List<Crop> actualCrops = cropList.getCrops();
for (Crop crop : actualCrops) {
Task preFrostTask = new Task("Frost", Task preFrostTask = new Task("Frost",
"The temperatur falls below zero degrees, cover especially the root with wool", "The temperatur falls below zero degrees, cover especially the root with wool",
dateSevereWeather,dateSevereWeather.plusDays(1L),crop.getCropId().orElse(-1L)); dateSevereWeather.minusDays(1L),dateSevereWeather.plusDays(1L),1L);
List<Task> actualCropTaskList = taskList.getTaskForCrop(crop.getCropId().orElse(-1L));
List<Task> frostTasklist = actualCropTaskList.stream().filter(task -> task.getName().equals("Frost")).toList();
List<Task> frostTaskListAtDate = new ArrayList<>();
for (Task task : frostTasklist) {
if (task.getStartDate() == preFrostTask.getStartDate()) {
frostTaskListAtDate.add(task);
}
}
if(frostTaskListAtDate.isEmpty() && frostTasklist.isEmpty()){
taskList.saveTask(preFrostTask); taskList.saveTask(preFrostTask);
} }
}
}
/** /**
* Method to create a PreSnowTask * Method to create a PreSnowTask
* @throws IOException If the database cannot be accessed * @throws IOException If the database cannot be accessed
*/ */
private void createPreSnowTask() throws IOException { private void createPreSnowTask() throws IOException {
List<Crop> actualCrops = cropList.getCrops();
for (Crop crop : actualCrops) {
Task preSnowTask = new Task("Snow", Task preSnowTask = new Task("Snow",
"The weather brings little snowfall. Cover your crops", "The weather brings little snowfall. Cover your crops",
dateSevereWeather, dateSevereWeather.plusDays(1L), crop.getCropId().orElse(-1L)); dateSevereWeather.minusDays(1L),dateSevereWeather.plusDays(1L),1L);
List<Task> actualCropTaskList = taskList.getTaskForCrop(crop.getCropId().orElse(-1L));
List<Task> snowTasklist = actualCropTaskList.stream().filter(task -> task.getName().equals("Snow")).toList();
List<Task> snowTaskListAtDate = new ArrayList<>();
for (Task task : snowTasklist) {
if (task.getStartDate() == preSnowTask.getStartDate()) {
snowTaskListAtDate.add(task);
}
}
if(snowTaskListAtDate .isEmpty() && snowTasklist.isEmpty()){
taskList.saveTask(preSnowTask); taskList.saveTask(preSnowTask);
} }
}
}
/** /**
* Method to adjust the water plant tasks * Method to adjust the water plant tasks
* @param rainAmount Amount of rain from the last 7 days * @param rainAmount Amount of rain from the last 7 days

View File

@ -32,6 +32,16 @@ public class GardenSchedule {
public GardenSchedule(TaskList taskList, PlantList plantList) throws IOException { public GardenSchedule(TaskList taskList, PlantList plantList) throws IOException {
this.taskList = taskList; this.taskList = taskList;
this.plantList = plantList; this.plantList = plantList;
TaskList.TaskListObserver taskListObserver = newTaskList -> {
Platform.runLater(() -> {
try {
getTasksUpcomingWeek();
} catch (IOException e) {
throw new RuntimeException(e);
}
});
};
setTaskListObserver(taskListObserver);
} }
public ListProperty<List<Task>> getWeeklyTaskListProperty() { public ListProperty<List<Task>> getWeeklyTaskListProperty() {
@ -166,12 +176,14 @@ public class GardenSchedule {
dayTaskList.add(new ArrayList<>()); dayTaskList.add(new ArrayList<>());
final int finalI = i; final int finalI = i;
weekTasks.forEach(task -> { weekTasks.forEach(task -> {
if(task.getNextExecution() != null) { if (task.getNextExecution() == null) {
task.isDone();
} else {
LocalDate checkDate = task.getNextExecution(); LocalDate checkDate = task.getNextExecution();
do { do {
if (date.equals(task.getNextExecution()) || (date.equals(checkDate) && !date.isAfter(task.getEndDate().orElse(LocalDate.MIN)))) { if (date.equals(checkDate) && !date.isAfter(task.getEndDate().orElse(LocalDate.MIN))) {
dayTaskList.get(finalI).add(task); dayTaskList.get(finalI).add(task);
break;
} }
checkDate = checkDate.plusDays(task.getInterval().orElse(0)); checkDate = checkDate.plusDays(task.getInterval().orElse(0));
} while (!(task.getInterval().orElse(0) == 0) && checkDate.isBefore(LocalDate.now().plusDays(listLength))); } while (!(task.getInterval().orElse(0) == 0) && checkDate.isBefore(LocalDate.now().plusDays(listLength)));

View File

@ -63,7 +63,6 @@ public class Task {
this.startDate = startDate; this.startDate = startDate;
nextExecution = startDate; nextExecution = startDate;
this.endDate = endDate; this.endDate = endDate;
this.cropId = cropId;
} }
/** /**
@ -108,7 +107,7 @@ public class Task {
* @return Whether the Task is within the given range * @return Whether the Task is within the given range
*/ */
public boolean isInTimePeriod(LocalDate searchStartDate, LocalDate searchEndDate) { public boolean isInTimePeriod(LocalDate searchStartDate, LocalDate searchEndDate) {
return (endDate.isAfter(searchStartDate) && startDate.isBefore(searchEndDate)) || ((nextExecution != null && nextExecution.isBefore(searchEndDate.plusDays(1)) && nextExecution.isAfter(searchStartDate.minusDays(1)))); return endDate.isAfter(searchStartDate) && startDate.isBefore(searchEndDate) || (nextExecution != null && nextExecution.isBefore(searchEndDate) && nextExecution.isAfter(searchStartDate));
} }
/** /**

View File

@ -89,7 +89,7 @@
<Insets bottom="10.0" /> <Insets bottom="10.0" />
</VBox.margin> </VBox.margin>
</ListView> </ListView>
<Button styleClass="button-class" fx:id="addTask_button" mnemonicParsing="false" onAction="#addTask" prefHeight="25.0" prefWidth="120.0" VBox.vgrow="NEVER" text="Add Task"> <Button styleClass="button-class" fx:id="addTask_button" mnemonicParsing="false" onAction="#addTask" prefHeight="25.0" prefWidth="45.0" VBox.vgrow="NEVER">
<VBox.margin> <VBox.margin>
<Insets /> <Insets />
</VBox.margin> </VBox.margin>

View File

@ -1,7 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?> <?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?> <?import javafx.scene.control.Label?>
<?import javafx.scene.control.ListView?> <?import javafx.scene.control.ListView?>
<?import javafx.scene.layout.AnchorPane?> <?import javafx.scene.layout.AnchorPane?>
@ -20,12 +19,11 @@
</Label> </Label>
<HBox maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="541.0" prefWidth="867.0" spacing="10.0" VBox.vgrow="ALWAYS"> <HBox maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="541.0" prefWidth="867.0" spacing="10.0" VBox.vgrow="ALWAYS">
<children> <children>
<VBox prefHeight="497.0" prefWidth="237.0" spacing="10.0" HBox.hgrow="NEVER"> <ListView fx:id="scheduledPlants_listview" maxWidth="1.7976931348623157E308" prefHeight="522.0" prefWidth="271.0" HBox.hgrow="NEVER">
<children> <HBox.margin>
<ListView fx:id="scheduledPlants_listview" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="522.0" prefWidth="271.0" VBox.vgrow="ALWAYS" /> <Insets />
<Button maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#showAllTasks" styleClass="button-class" text="Show All Tasks" VBox.vgrow="NEVER" /> </HBox.margin>
</children> </ListView>
</VBox>
<VBox maxWidth="1.7976931348623157E308" prefHeight="537.0" prefWidth="650.0" spacing="10.0" HBox.hgrow="ALWAYS"> <VBox maxWidth="1.7976931348623157E308" prefHeight="537.0" prefWidth="650.0" spacing="10.0" HBox.hgrow="ALWAYS">
<children> <children>
<ListView fx:id="week_listView" maxWidth="1.7976931348623157E308" prefHeight="200.0" prefWidth="200.0" VBox.vgrow="ALWAYS"> <ListView fx:id="week_listView" maxWidth="1.7976931348623157E308" prefHeight="200.0" prefWidth="200.0" VBox.vgrow="ALWAYS">

View File

@ -14,7 +14,7 @@
<?import javafx.scene.text.Text?> <?import javafx.scene.text.Text?>
<?import javafx.scene.text.TextFlow?> <?import javafx.scene.text.TextFlow?>
<BorderPane maxHeight="470.0" maxWidth="724.0" minHeight="470.0" minWidth="724.0" prefHeight="470.0" prefWidth="724.0" xmlns="http://javafx.com/javafx/19" xmlns:fx="http://javafx.com/fxml/1" fx:controller="ch.zhaw.gartenverwaltung.TutorialController"> <BorderPane maxHeight="470.0" maxWidth="724.0" minHeight="470.0" minWidth="724.0" prefHeight="470.0" prefWidth="724.0" xmlns="http://javafx.com/javafx/17" xmlns:fx="http://javafx.com/fxml/1" fx:controller="ch.zhaw.gartenverwaltung.TutorialController">
<bottom> <bottom>
<HBox alignment="CENTER" prefHeight="0.0" prefWidth="724.0" BorderPane.alignment="CENTER"> <HBox alignment="CENTER" prefHeight="0.0" prefWidth="724.0" BorderPane.alignment="CENTER">
<children> <children>
@ -22,9 +22,9 @@
<Separator prefWidth="50.0" visible="false" HBox.hgrow="ALWAYS" /> <Separator prefWidth="50.0" visible="false" HBox.hgrow="ALWAYS" />
<ButtonBar prefHeight="40.0" prefWidth="200.0"> <ButtonBar prefHeight="40.0" prefWidth="200.0">
<buttons> <buttons>
<Button cancelButton="true" contentDisplay="CENTER" graphicTextGap="5.0" mnemonicParsing="false" onAction="#closeTutorial" styleClass="button-class" text="Close" /> <Button styleClass="button-class" cancelButton="true" contentDisplay="CENTER" graphicTextGap="5.0" mnemonicParsing="false" text="Close" onAction="#closeTutorial"/>
<Button fx:id="previousPageButton" mnemonicParsing="false" onAction="#viewPreviousPage" styleClass="button-class" text="Previous" /> <Button styleClass="button-class" fx:id="previousPageButton" mnemonicParsing="false" text="Previous" onAction="#viewPreviousPage"/>
<Button fx:id="nextPageButton" defaultButton="true" mnemonicParsing="false" onAction="#viewNextPage" styleClass="button-class" text="Next" /> <Button styleClass="button-class" fx:id="nextPageButton" defaultButton="true" mnemonicParsing="false" text="Next" onAction="#viewNextPage" />
</buttons> </buttons>
</ButtonBar> </ButtonBar>
</children> </children>
@ -38,7 +38,7 @@
<children> <children>
<VBox layoutX="30.0" layoutY="26.0" opacity="0.0" prefHeight="200.0" prefWidth="100.0"> <VBox layoutX="30.0" layoutY="26.0" opacity="0.0" prefHeight="200.0" prefWidth="100.0">
<children> <children>
<Text strokeType="OUTSIDE" strokeWidth="0.0" text="Adding Crops"> <Text strokeType="OUTSIDE" strokeWidth="0.0" text="Managing Your Crops">
<font> <font>
<Font size="24.0" /> <Font size="24.0" />
</font> </font>
@ -75,7 +75,7 @@
</children> </children>
</TextFlow> </TextFlow>
<Separator prefWidth="200.0" visible="false" HBox.hgrow="ALWAYS" /> <Separator prefWidth="200.0" visible="false" HBox.hgrow="ALWAYS" />
<ImageView fx:id="imgSelectDate" fitHeight="150.0" fitWidth="400.0" pickOnBounds="true" preserveRatio="true" /> <ImageView fx:id="imgSelectDate" fitHeight="150.0" fitWidth="200.0" pickOnBounds="true" preserveRatio="true" />
</children> </children>
</HBox> </HBox>
</children> </children>
@ -83,50 +83,7 @@
<Insets /> <Insets />
</opaqueInsets> </opaqueInsets>
</VBox> </VBox>
<VBox layoutX="30.0" layoutY="30.0" prefHeight="200.0" prefWidth="100.0"> <VBox prefHeight="200.0" prefWidth="100.0">
<children>
<Text strokeType="OUTSIDE" strokeWidth="0.0" text="Managing Your Crops">
<font>
<Font size="24.0" />
</font>
</Text>
<Separator prefWidth="200.0">
<VBox.margin>
<Insets bottom="15.0" top="10.0" />
</VBox.margin>
</Separator>
<Text strokeType="OUTSIDE" strokeWidth="0.0" text="Once you've added a crop to your garden, it will be displayed in the &quot;My Garden&quot; tab.">
<VBox.margin>
<Insets bottom="20.0" />
</VBox.margin>
</Text>
<HBox prefHeight="100.0" prefWidth="200.0">
<children>
<TextFlow lineSpacing="4.0" prefHeight="200.0" prefWidth="500.0">
<children>
<Text strokeType="OUTSIDE" strokeWidth="0.0" text="On the right hand side of the listing, you'll see two buttons.&#10;&#10;Button with the &quot;trash can&quot; icon lets you remove a crop from your garden plan. This will also delete all associated tasks.&#10;&#10;The button on the left will display the details of the crop in a new window." />
</children>
</TextFlow>
<Separator prefWidth="200.0" visible="false" HBox.hgrow="ALWAYS" />
<ImageView fitHeight="70.0" fitWidth="100.0" pickOnBounds="true" preserveRatio="true" fx:id="imgDetailDeleteButtons"/>
</children></HBox>
<HBox layoutX="10.0" layoutY="105.0" prefHeight="100.0" prefWidth="200.0">
<children>
<TextFlow lineSpacing="4.0" prefHeight="200.0" prefWidth="500.0">
<children>
<Text strokeType="OUTSIDE" strokeWidth="0.0" text="Here, you can also add your own custom tasks, by clicking the &quot;Add Task&quot; button.&#10;In the subsequently shown dialog, you can enter the corresponding details.&#10;&#10;Note: If you want to make a task recurring, you need to set both an interval (in days) AND an end date, so the task won't repeat for all eternity." />
</children>
</TextFlow>
<Separator prefWidth="200.0" visible="false" HBox.hgrow="ALWAYS" />
<ImageView fitHeight="150.0" fitWidth="400.0" pickOnBounds="true" preserveRatio="true" fx:id="imgAddTaskButton"/>
</children>
</HBox>
</children>
<opaqueInsets>
<Insets />
</opaqueInsets>
</VBox>
<VBox opacity="0.0" prefHeight="200.0" prefWidth="100.0">
<children> <children>
<Text strokeType="OUTSIDE" strokeWidth="0.0" text="Managing Your Tasks"> <Text strokeType="OUTSIDE" strokeWidth="0.0" text="Managing Your Tasks">
<font> <font>
@ -154,9 +111,19 @@
</HBox.margin> </HBox.margin>
</TextFlow> </TextFlow>
<Separator prefWidth="200.0" visible="false" HBox.hgrow="ALWAYS" /> <Separator prefWidth="200.0" visible="false" HBox.hgrow="ALWAYS" />
<ImageView fx:id="imgTaskList" fitHeight="200.0" fitWidth="400.0" pickOnBounds="true" preserveRatio="true" /> <ImageView fx:id="imgTaskList" fitHeight="98.0" fitWidth="200.0" pickOnBounds="true" preserveRatio="true" />
</children> </children>
</HBox> </HBox>
<HBox prefHeight="100.0" prefWidth="200.0">
<children>
<TextFlow lineSpacing="4.0" prefHeight="200.0" prefWidth="500.0">
<children>
<Text strokeType="OUTSIDE" strokeWidth="0.0" text="You can also add your own custom tasks, by clicking the &quot;Add Task&quot; button.&#10;In the subsequently shown dialog, you can enter the corresponding details.&#10;&#10;Note: If you want to make a task recurring, you need to set both an interval (in days) AND an end date, so the task won't repeat for all eternity." />
</children>
</TextFlow>
<Separator prefWidth="200.0" visible="false" HBox.hgrow="ALWAYS" />
<ImageView fitHeight="150.0" fitWidth="200.0" pickOnBounds="true" preserveRatio="true" />
</children></HBox>
</children> </children>
<opaqueInsets> <opaqueInsets>
<Insets /> <Insets />

View File

@ -52,7 +52,7 @@ public class WeatherGardenTaskPlannerTest {
exampleTask.setNextExecution(LocalDate.now().plusDays(1L)); exampleTask.setNextExecution(LocalDate.now().plusDays(1L));
exampleWeatherTask = new Task("Hail", exampleWeatherTask = new Task("Hail",
"During a summer Thunderstorm it could hail heavily. THe Hail could damage the crops. To prevent damage cover the plants with a strong tarpaulin", "During a summer Thunderstorm it could hail heavily. THe Hail could damage the crops. To prevent damage cover the plants with a strong tarpaulin",
LocalDate.now(),LocalDate.now().plusDays(1L),3L); LocalDate.now().minusDays(1L),LocalDate.now().plusDays(1L),3L);
taskList = new JsonTaskList(testFile); taskList = new JsonTaskList(testFile);

View File

@ -1,12 +1,7 @@
package ch.zhaw.gartenverwaltung.io; package ch.zhaw.gartenverwaltung.io;
import ch.zhaw.gartenverwaltung.models.GardenSchedule;
import ch.zhaw.gartenverwaltung.models.PlantNotFoundException;
import ch.zhaw.gartenverwaltung.types.Crop;
import ch.zhaw.gartenverwaltung.types.Task; import ch.zhaw.gartenverwaltung.types.Task;
import javafx.application.Platform;
import org.junit.jupiter.api.*; import org.junit.jupiter.api.*;
import org.mockito.ArgumentCaptor;
import org.mockito.ArgumentMatchers; import org.mockito.ArgumentMatchers;
import org.mockito.Mockito; import org.mockito.Mockito;
@ -18,7 +13,6 @@ import java.nio.file.Path;
import java.nio.file.StandardCopyOption; import java.nio.file.StandardCopyOption;
import java.time.LocalDate; import java.time.LocalDate;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.List; import java.util.List;
import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNotNull;
@ -33,22 +27,6 @@ public class JsonTaskListTest {
private final URL dbDataSource = this.getClass().getResource("test-taskdb.json"); private final URL dbDataSource = this.getClass().getResource("test-taskdb.json");
private final URL testFile = this.getClass().getResource("template-taskdb.json"); private final URL testFile = this.getClass().getResource("template-taskdb.json");
@BeforeAll
static void setUpAll() {
try{
Platform.startup(()->{});
}catch (IllegalStateException ise){
//ignore double launches
}
}
@AfterAll
static void tearDownAll() {
//Dont do: Platform.exit();
}
@BeforeEach @BeforeEach
void connectToDb() throws URISyntaxException, IOException { void connectToDb() throws URISyntaxException, IOException {
assertNotNull(testFile); assertNotNull(testFile);
@ -57,10 +35,6 @@ public class JsonTaskListTest {
testDatabase = new JsonTaskList(dbDataSource); testDatabase = new JsonTaskList(dbDataSource);
} }
private void reloadDb() {
testDatabase = new JsonTaskList(dbDataSource);
}
@Test @Test
@DisplayName("Check if results are retrieved completely") @DisplayName("Check if results are retrieved completely")
void getTasks() { void getTasks() {
@ -73,8 +47,7 @@ public class JsonTaskListTest {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
List<Long> ids = taskList.stream().map(t -> t.getId().orElse(0L)).toList(); Assertions.assertEquals(3, taskList.size());
Assertions.assertEquals(Arrays.asList(1L, 2L, 5L), ids);
} }
@ -92,8 +65,7 @@ public class JsonTaskListTest {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
List<Long> ids = taskList.stream().map(t -> t.getId().orElse(0L)).toList(); Assertions.assertEquals(4, taskList.size());
Assertions.assertEquals(Arrays.asList(1L, 2L, 5L, 9L), ids);
} catch (IOException e) { } catch (IOException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
@ -111,8 +83,7 @@ public class JsonTaskListTest {
taskList = testDatabase.getTaskList(LocalDate.parse("2022-04-30", formatter), taskList = testDatabase.getTaskList(LocalDate.parse("2022-04-30", formatter),
LocalDate.parse("2022-05-31", formatter)); LocalDate.parse("2022-05-31", formatter));
List<Long> ids = taskList.stream().map(t -> t.getId().orElse(0L)).toList(); Assertions.assertEquals(2, taskList.size());
Assertions.assertEquals(Arrays.asList(1L, 5L), ids);
} catch (IOException e) { } catch (IOException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
@ -129,8 +100,8 @@ public class JsonTaskListTest {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
List<Long> ids = taskList.stream().map(t -> t.getId().orElse(0L)).toList(); Assertions.assertEquals(6, taskList.size());
Assertions.assertEquals(Arrays.asList(1L, 2L, 3L, 4L, 5L, 6L), ids);
} }
@ -145,16 +116,6 @@ public class JsonTaskListTest {
} }
Assertions.assertEquals(0, taskList.size()); Assertions.assertEquals(0, taskList.size());
try {
taskList = testDatabase.getTaskForCrop(1);
} catch (IOException e) {
throw new RuntimeException(e);
}
List<Long> ids = (taskList.stream().map( task -> task.getId().orElse(0L)).toList());
Assertions.assertEquals(Arrays.asList(7L, 8L), ids);
} }
@Test @Test
@ -177,43 +138,6 @@ public class JsonTaskListTest {
} catch (IOException e) { } catch (IOException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
verify(mockObs, times(1)).onChange(ArgumentMatchers.anyList());
ArgumentCaptor<List<Task>> captor = ArgumentCaptor.forClass(List.class);
verify(mockObs, times(1)).onChange(captor.capture());
List<Long> ids = captor.getValue().stream().map(t -> t.getId().orElse(0L)).toList();
Assertions.assertEquals(Arrays.asList(7L, 8L), ids);
}
@Test
@Tag("IntegrationTest")
void testComplete() {
JsonPlantList plantList = new JsonPlantList();
try {
testDatabase.removeTasksForCrop(0);
testDatabase.removeTasksForCrop(1);
} catch (IOException e) {
throw new RuntimeException(e);
}
GardenSchedule gardenSchedule = null;
try {
gardenSchedule = new GardenSchedule(testDatabase, plantList);
} catch (IOException e) {
throw new RuntimeException(e);
}
Crop crop = new Crop(3L, LocalDate.parse("2022-12-01", formatter));
try {
gardenSchedule.planTasksForCrop(crop);
reloadDb();
List<Task> tasks = gardenSchedule.getTaskList();
List<String> tasknames = (tasks.stream().map( task -> task.getName().substring(0,3).toLowerCase()).toList());
Assertions.assertEquals(Arrays.asList("ger","wat","hil","har"), tasknames);
} catch (IOException | PlantNotFoundException | HardinessZoneNotSetException e) {
throw new RuntimeException(e);
}
} }
} }

View File

@ -34,17 +34,12 @@ class GardenScheduleTest {
@BeforeAll @BeforeAll
static void setUpAll() { static void setUpAll() {
try{
Platform.startup(()->{}); Platform.startup(()->{});
}catch (IllegalStateException ise){
//ignore double launches
}
} }
@AfterAll @AfterAll
static void tearDownAll() { static void tearDownAll() {
//Dont do: Platform.exit(); Platform.exit();
} }
@BeforeEach @BeforeEach
@ -239,8 +234,5 @@ class GardenScheduleTest {
testTaskList.getTaskList(LocalDate.MIN,LocalDate.MAX).get(0); testTaskList.getTaskList(LocalDate.MIN,LocalDate.MAX).get(0);
} }
@Test
void testPlantNotFoundException() throws HardinessZoneNotSetException, IOException {
assertThrowsExactly(PlantNotFoundException.class, () -> { model.planTasksForCrop(new Crop(0, exampleStartDate)); });
}
} }

View File

@ -64,27 +64,5 @@
"endDate" : "2022-09-01", "endDate" : "2022-09-01",
"interval" : 0, "interval" : 0,
"cropId" : 0 "cropId" : 0
},
{
"id" : 7,
"name" : "sow plant",
"description": "Plant the seeds, crops in de bed.",
"startDate" : "2022-11-01",
"nextExecution": "2022-11-01",
"nextNotification": "2022-11-01",
"endDate" : "2022-11-01",
"interval" : 0,
"cropId" : 1
},
{
"id" : 8,
"name" : "harvest plant",
"description": "Pull the ripe vegetables out from the soil. Clean them with clear, fresh water. ",
"startDate" : "2022-12-01",
"nextExecution": "2022-12-01",
"nextNotification": "2022-12-01",
"endDate" : "2022-12-01",
"interval" : 0,
"cropId" : 1
} }
] ]