From 89bc53b11c288fae62d80b231b675749b2b44a39 Mon Sep 17 00:00:00 2001
From: Robert Goldmann <deadlocker@gmx.de>
Date: Sun, 23 Jun 2019 14:54:39 +0200
Subject: [PATCH] #436 - functionality for adding new charts

---
 .../budgetmaster/charts/ChartController.java  | 37 +++++++++
 .../budgetmaster/charts/ChartValidator.java   | 22 ++++++
 .../budgetmaster/utils/Strings.java           |  2 +
 src/main/resources/languages/_de.properties   |  3 +
 src/main/resources/languages/_en.properties   |  3 +
 .../resources/templates/charts/chartList.ftl  | 14 ++--
 .../resources/templates/charts/newChart.ftl   | 77 +++++++++++++++++++
 7 files changed, 151 insertions(+), 7 deletions(-)
 create mode 100644 src/main/java/de/deadlocker8/budgetmaster/charts/ChartValidator.java
 create mode 100644 src/main/resources/templates/charts/newChart.ftl

diff --git a/src/main/java/de/deadlocker8/budgetmaster/charts/ChartController.java b/src/main/java/de/deadlocker8/budgetmaster/charts/ChartController.java
index 93855167e..da7897666 100644
--- a/src/main/java/de/deadlocker8/budgetmaster/charts/ChartController.java
+++ b/src/main/java/de/deadlocker8/budgetmaster/charts/ChartController.java
@@ -6,7 +6,10 @@ import de.deadlocker8.budgetmaster.settings.SettingsService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Controller;
 import org.springframework.ui.Model;
+import org.springframework.validation.BindingResult;
+import org.springframework.web.bind.annotation.ModelAttribute;
 import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
 
 @Controller
 public class ChartController extends BaseController
@@ -30,4 +33,38 @@ public class ChartController extends BaseController
 		model.addAttribute("settings", settingsService.getSettings());
 		return "charts/chartList";
 	}
+
+	@RequestMapping("/charts/newChart")
+	public String newChart(Model model)
+	{
+		Chart emptyChart = new Chart(null, null, ChartType.CUSTOM);
+		model.addAttribute("chart", emptyChart);
+		model.addAttribute("settings", settingsService.getSettings());
+		return "charts/newChart";
+	}
+
+	@RequestMapping(value = "/charts/newChart", method = RequestMethod.POST)
+	public String post(Model model, @ModelAttribute("NewChart") Chart chart, BindingResult bindingResult)
+	{
+		ChartValidator userValidator = new ChartValidator();
+		userValidator.validate(chart, bindingResult);
+
+		if(bindingResult.hasErrors())
+		{
+			model.addAttribute("error", bindingResult);
+			model.addAttribute("chart", chart);
+			model.addAttribute("settings", settingsService.getSettings());
+			return "charts/newChart";
+		}
+		else
+		{
+			if(chart.getType() == null)
+			{
+				chart.setType(ChartType.CUSTOM);
+			}
+			chartService.getRepository().save(chart);
+		}
+
+		return "redirect:/charts/chartList";
+	}
 }
diff --git a/src/main/java/de/deadlocker8/budgetmaster/charts/ChartValidator.java b/src/main/java/de/deadlocker8/budgetmaster/charts/ChartValidator.java
new file mode 100644
index 000000000..23b90aa90
--- /dev/null
+++ b/src/main/java/de/deadlocker8/budgetmaster/charts/ChartValidator.java
@@ -0,0 +1,22 @@
+package de.deadlocker8.budgetmaster.charts;
+
+import de.deadlocker8.budgetmaster.categories.Category;
+import de.deadlocker8.budgetmaster.utils.Strings;
+import org.springframework.validation.Errors;
+import org.springframework.validation.ValidationUtils;
+import org.springframework.validation.Validator;
+
+
+public class ChartValidator implements Validator
+{
+	public boolean supports(Class clazz)
+	{
+		return Category.class.equals(clazz);
+	}
+
+	public void validate(Object obj, Errors errors)
+	{
+		ValidationUtils.rejectIfEmptyOrWhitespace(errors, "name", Strings.WARNING_EMPTY_CHART_NAME);
+		ValidationUtils.rejectIfEmptyOrWhitespace(errors, "script", Strings.WARNING_EMPTY_CHART_SCRIPT);
+	}
+}
\ No newline at end of file
diff --git a/src/main/java/de/deadlocker8/budgetmaster/utils/Strings.java b/src/main/java/de/deadlocker8/budgetmaster/utils/Strings.java
index 0b7736c9b..4dea4a643 100644
--- a/src/main/java/de/deadlocker8/budgetmaster/utils/Strings.java
+++ b/src/main/java/de/deadlocker8/budgetmaster/utils/Strings.java
@@ -38,6 +38,8 @@ public class Strings
     public static final String WARNING_SETTINGS_PASSWORD_LENGTH = "warning.settings.password.length";
     public static final String WARNING_SETTINGS_PASSWORD_CONFIRMATION_EMPTY = "warning.settings.password.confirmation.empty";
     public static final String WARNING_SETTINGS_PASSWORD_CONFIRMATION_WRONG = "warning.settings.password.confirmation.wrong";
+    public static final String WARNING_EMPTY_CHART_NAME = "warning.empty.chart.name";
+    public static final String WARNING_EMPTY_CHART_SCRIPT = "warning.empty.chart.script";
 
     //REPORT
     public static final String REPORT_FOOTER_LEFT = "report.footer.left";
diff --git a/src/main/resources/languages/_de.properties b/src/main/resources/languages/_de.properties
index fa769b660..80bd5ba2b 100644
--- a/src/main/resources/languages/_de.properties
+++ b/src/main/resources/languages/_de.properties
@@ -123,6 +123,8 @@ warning.settings.password.empty=Bitte gib ein Passwort ein.
 warning.settings.password.length=Das Passwort muss mindestens drei Zeichen lang sein.
 warning.settings.password.confirmation.empty=Bitte gib dein Passwort zur Best�tigung erneut ein.
 warning.settings.password.confirmation.wrong=Passwort und Passwort Wiederholung stimmen nicht �berein.
+warning.empty.chart.name=Bitte gib einen Namen ein.
+warning.empty.chart.script=Bitte gib ein Script ein.
 
 # UI
 menu.home=Startseite
@@ -325,5 +327,6 @@ charts.default.month=Eingaben/Ausgaben pro Monat
 charts.default.categoryBudget=Verbrauch nach Kategorien
 
 chart.new.label.name=Name
+chart.new.label.script=Script
 chart.type=Typ
 chart.actions=Aktionen
\ No newline at end of file
diff --git a/src/main/resources/languages/_en.properties b/src/main/resources/languages/_en.properties
index f8289593c..61f06b1a5 100644
--- a/src/main/resources/languages/_en.properties
+++ b/src/main/resources/languages/_en.properties
@@ -123,6 +123,8 @@ warning.settings.password.empty=Please enter a password.
 warning.settings.password.length=The password must be at least three characters long.
 warning.settings.password.confirmation.empty=Please enter your password again for confirmation.
 warning.settings.password.confirmation.wrong=Password and password confirmation do not match.
+warning.empty.chart.name=Please insert a name.
+warning.empty.chart.script=Please insert a script.
 
 # UI
 menu.home=Home
@@ -325,5 +327,6 @@ charts.default.month=Income/Payments per Month
 charts.default.categoryBudget=Consumption by categories
 
 chart.new.label.name=Name
+chart.new.label.script=Script
 chart.type=Type
 chart.actions=Actions
\ No newline at end of file
diff --git a/src/main/resources/templates/charts/chartList.ftl b/src/main/resources/templates/charts/chartList.ftl
index 6bd402dbd..95bd0bc3a 100644
--- a/src/main/resources/templates/charts/chartList.ftl
+++ b/src/main/resources/templates/charts/chartList.ftl
@@ -22,15 +22,15 @@
                 <br>
                 <div class="container">
                     <table class="bordered">
+                        <thead>
+                            <tr>
+                                <th>${locale.getString("chart.new.label.name")}</th>
+                                <th>${locale.getString("chart.type")}</th>
+                                <th>${locale.getString("chart.actions")}</th>
+                            </tr>
+                        </thead>
                         <#list charts as chart>
                             <#assign chartName=chartFunctions.getChartName(chart)>
-                            <thead>
-                                <tr>
-                                    <th>${locale.getString("chart.new.label.name")}</th>
-                                    <th>${locale.getString("chart.type")}</th>
-                                    <th>${locale.getString("chart.actions")}</th>
-                                </tr>
-                            </thead>
                             <tr>
                                 <td>${chartName}</td>
                                 <td>
diff --git a/src/main/resources/templates/charts/newChart.ftl b/src/main/resources/templates/charts/newChart.ftl
new file mode 100644
index 000000000..34a93aa35
--- /dev/null
+++ b/src/main/resources/templates/charts/newChart.ftl
@@ -0,0 +1,77 @@
+<html>
+    <head>
+        <#import "../helpers/header.ftl" as header>
+        <@header.header "BudgetMaster"/>
+        <#import "/spring.ftl" as s>
+    </head>
+    <body class="budgetmaster-blue-light">
+        <#import "../helpers/navbar.ftl" as navbar>
+        <@navbar.navbar "charts" settings/>
+
+        <main>
+            <div class="card main-card background-color">
+                <div class="container">
+                    <div class="section center-align">
+                        <div class="headline"><#if chart.getID()??>${locale.getString("title.chart.edit")}<#else>${locale.getString("title.chart.new")}</#if></div>
+                    </div>
+                </div>
+                <div class="container">
+                    <#import "../helpers/validation.ftl" as validation>
+                    <form name="NewChart" action="<@s.url '/charts/newChart'/>" method="post">
+                        <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>
+                        <input type="hidden" name="ID" value="<#if chart.getID()??>${chart.getID()?c}</#if>">
+
+                        <#-- name -->
+                        <div class="row">
+                            <div class="input-field col s12 m12 l8 offset-l2">
+                                <input id="chart-name" type="text" name="name" <@validation.validation "name"/> value="<#if chart.getName()??>${chart.getName()}</#if>">
+                                <label for="chart-name">${locale.getString("chart.new.label.name")}</label>
+                            </div>
+                        </div>
+
+                        <#-- script -->
+                        <div class="row">
+                            <div class="input-field col s12 m12 l8 offset-l2">
+                                <textarea id="chart-script" name="script" <@validation.validation "script" "materialize-textarea"/>><#if chart.getScript()??>${chart.getScript()}</#if></textarea>
+                                <label for="chart-script">${locale.getString("chart.new.label.script")}</label>
+                            </div>
+                        </div>
+
+                        <br>
+
+                        <#-- buttons -->
+                        <div class="row hide-on-small-only">
+                            <div class="col s6 right-align">
+                                <a href="<@s.url '/charts/chartList'/>" class="waves-effect waves-light btn budgetmaster-blue"><i class="material-icons left">clear</i>${locale.getString("cancel")}</a>
+                            </div>
+
+                            <div class="col s6 left-align">
+                                <button class="btn waves-effect waves-light budgetmaster-blue" type="submit" name="action">
+                                    <i class="material-icons left">save</i>${locale.getString("save")}
+                                </button>
+                            </div>
+                        </div>
+                        <div class="hide-on-med-and-up">
+                            <div class="row center-align">
+                                <div class="col s12">
+                                    <a href="<@s.url '/charts/chartList'/>" class="waves-effect waves-light btn budgetmaster-blue"><i class="material-icons left">clear</i>${locale.getString("cancel")}</a>
+                                </div>
+                            </div>
+                            <div class="row center-align">
+                                <div class="col s12">
+                                    <button class="btn waves-effect waves-light budgetmaster-blue" type="submit" name="buttonSave">
+                                        <i class="material-icons left">save</i>${locale.getString("save")}
+                                    </button>
+                                </div>
+                            </div>
+                        </div>
+                    </form>
+                </div>
+            </div>
+        </main>
+
+        <!-- Scripts-->
+        <#import "../helpers/scripts.ftl" as scripts>
+        <@scripts.scripts/>
+    </body>
+</html>
\ No newline at end of file
-- 
GitLab