From b90d3766393142b532297ce2f0ec037ebd975627 Mon Sep 17 00:00:00 2001
From: Robert Goldmann <deadlocker@gmx.de>
Date: Mon, 19 Mar 2018 20:53:32 +0100
Subject: [PATCH] #267 - added switch for income/payment; added date picker;
 #286 - localized datePicker; #286 - initial language is obtained from
 settings

---
 .../de/deadlocker8/budgetmaster/Main.java     |  5 +-
 .../controller/PaymentController.java         |  4 --
 .../budgetmaster/services/HelpersService.java | 13 ++++
 .../services/SettingsService.java             |  6 ++
 .../budgetmaster/utils/LanguageType.java      |  2 +-
 .../budgetmaster/utils/Strings.java           | 61 +++++++++++--------
 src/main/resources/languages/_de.properties   | 11 ++++
 src/main/resources/languages/_en.properties   | 11 ++++
 src/main/resources/static/css/style.css       |  9 +++
 src/main/resources/static/js/payments.js      | 28 +++++++++
 src/main/resources/templates/datePicker.ftl   | 33 +++++++++-
 .../templates/payments/newPayment.ftl         | 21 +++++++
 12 files changed, 169 insertions(+), 35 deletions(-)

diff --git a/src/main/java/de/deadlocker8/budgetmaster/Main.java b/src/main/java/de/deadlocker8/budgetmaster/Main.java
index c95564617..ab9a53841 100644
--- a/src/main/java/de/deadlocker8/budgetmaster/Main.java
+++ b/src/main/java/de/deadlocker8/budgetmaster/Main.java
@@ -1,8 +1,10 @@
 package de.deadlocker8.budgetmaster;
 
+import de.deadlocker8.budgetmaster.repositories.SettingsRepository;
 import de.deadlocker8.budgetmaster.utils.Strings;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.ApplicationArguments;
 import org.springframework.boot.ApplicationRunner;
 import org.springframework.boot.SpringApplication;
@@ -25,9 +27,6 @@ public class Main implements ApplicationRunner
 	@Override
 	public void run(ApplicationArguments args) throws Exception
 	{
-		Localization.init("languages/");
-		Localization.loadLanguage(Locale.ENGLISH);
-
 		//TODO set loglevel
 //		String logLevelParam = args.getOptionValues("loglevel").get(0);
 
diff --git a/src/main/java/de/deadlocker8/budgetmaster/controller/PaymentController.java b/src/main/java/de/deadlocker8/budgetmaster/controller/PaymentController.java
index 90d82fe8a..306b1cc26 100644
--- a/src/main/java/de/deadlocker8/budgetmaster/controller/PaymentController.java
+++ b/src/main/java/de/deadlocker8/budgetmaster/controller/PaymentController.java
@@ -1,6 +1,5 @@
 package de.deadlocker8.budgetmaster.controller;
 
-import de.deadlocker8.budgetmaster.entities.Category;
 import de.deadlocker8.budgetmaster.entities.CategoryType;
 import de.deadlocker8.budgetmaster.entities.Payment;
 import de.deadlocker8.budgetmaster.entities.Settings;
@@ -8,8 +7,6 @@ import de.deadlocker8.budgetmaster.repositories.CategoryRepository;
 import de.deadlocker8.budgetmaster.repositories.PaymentRepository;
 import de.deadlocker8.budgetmaster.repositories.SettingsRepository;
 import de.deadlocker8.budgetmaster.services.HelpersService;
-import de.deadlocker8.budgetmaster.utils.Colors;
-import de.deadlocker8.budgetmaster.validators.CategoryValidator;
 import de.deadlocker8.budgetmaster.validators.PaymentValidator;
 import org.joda.time.DateTime;
 import org.joda.time.format.DateTimeFormat;
@@ -18,7 +15,6 @@ import org.springframework.stereotype.Controller;
 import org.springframework.ui.Model;
 import org.springframework.validation.BindingResult;
 import org.springframework.web.bind.annotation.*;
-import tools.ConvertTo;
 
 import java.util.List;
 
diff --git a/src/main/java/de/deadlocker8/budgetmaster/services/HelpersService.java b/src/main/java/de/deadlocker8/budgetmaster/services/HelpersService.java
index 1b8569b02..568ca1cb1 100644
--- a/src/main/java/de/deadlocker8/budgetmaster/services/HelpersService.java
+++ b/src/main/java/de/deadlocker8/budgetmaster/services/HelpersService.java
@@ -54,6 +54,19 @@ public class HelpersService
 		return date.toString(DateTimeFormat.forPattern("MMMM yyyy").withLocale(settingsRepository.findOne(0).getLanguage().getLocale()));
 	}
 
+	public ArrayList<String> getWeekDays()
+	{
+		ArrayList<String> weekDays = new ArrayList<>();
+		weekDays.add(Localization.getString(Strings.SUNDAY));
+		weekDays.add(Localization.getString(Strings.MONDAY));
+		weekDays.add(Localization.getString(Strings.TUESDAY));
+		weekDays.add(Localization.getString(Strings.WEDNESDAY));
+		weekDays.add(Localization.getString(Strings.THURSDAY));
+		weekDays.add(Localization.getString(Strings.FRIDAY));
+		weekDays.add(Localization.getString(Strings.SATURDAY));
+		return weekDays;
+	}
+
 	public ArrayList<String> getMonthList()
 	{
 		ArrayList<String> monthNames = new ArrayList<>();
diff --git a/src/main/java/de/deadlocker8/budgetmaster/services/SettingsService.java b/src/main/java/de/deadlocker8/budgetmaster/services/SettingsService.java
index fc1ff63f3..56fc1710b 100644
--- a/src/main/java/de/deadlocker8/budgetmaster/services/SettingsService.java
+++ b/src/main/java/de/deadlocker8/budgetmaster/services/SettingsService.java
@@ -6,6 +6,9 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
+import tools.Localization;
+
+import java.util.Locale;
 
 @Service
 public class SettingsService
@@ -20,5 +23,8 @@ public class SettingsService
 			settingsRepository.save(Settings.getDefault());
 			LOGGER.debug("Created default settings");
 		}
+
+		Localization.init("languages/");
+		Localization.loadLanguage(settingsRepository.findOne(0).getLanguage().getLocale());
 	}
 }
\ No newline at end of file
diff --git a/src/main/java/de/deadlocker8/budgetmaster/utils/LanguageType.java b/src/main/java/de/deadlocker8/budgetmaster/utils/LanguageType.java
index 0234ca4d1..5ec11ab94 100644
--- a/src/main/java/de/deadlocker8/budgetmaster/utils/LanguageType.java
+++ b/src/main/java/de/deadlocker8/budgetmaster/utils/LanguageType.java
@@ -11,7 +11,7 @@ public enum LanguageType
 	private Locale locale;
 	private String iconName;
 	
-	private LanguageType(String name, Locale locale, String iconName)
+	LanguageType(String name, Locale locale, String iconName)
 	{
 		this.name = name;
 		this.locale = locale;
diff --git a/src/main/java/de/deadlocker8/budgetmaster/utils/Strings.java b/src/main/java/de/deadlocker8/budgetmaster/utils/Strings.java
index bdad0b0a0..9e3dea2fc 100644
--- a/src/main/java/de/deadlocker8/budgetmaster/utils/Strings.java
+++ b/src/main/java/de/deadlocker8/budgetmaster/utils/Strings.java
@@ -12,7 +12,7 @@ public class Strings
     public static final String FOLDER = "folder";
     public static final String ROADMAP_URL = "roadmap.url";
     public static final String GITHUB_URL = "github.url";
-    
+
     //TITLE
     public static final String TITLE_INCOMES = "title.incomes";
     public static final String TITLE_INCOME = "title.income";
@@ -25,8 +25,8 @@ public class Strings
     public static final String TITLE_INFO = "title.info";
     public static final String TITLE_WARNING = "title.warning";
     public static final String TITLE_ERROR = "title.error";
-    public static final String TITLE_CATEGORY_NEW = "title.category.new";  
-    public static final String TITLE_CATEGORY_EDIT = "title.category.edit";  
+    public static final String TITLE_CATEGORY_NEW = "title.category.new";
+    public static final String TITLE_CATEGORY_EDIT = "title.category.edit";
     public static final String TITLE_CHART_EXPORT = "title.chart.export";
     public static final String TITLE_MODAL = "title.modal";
     public static final String TITLE_PAYMENT_EDIT = "title.payment.edit";
@@ -38,7 +38,7 @@ public class Strings
     public static final String TITLE_DATABASE_IMPORT = "title.database.import";
     public static final String TITLE_DATEPICKER = "title.datepicker";
     public static final String TITLE_TAGS = "title.tags";
-    
+
     //LOAD
     public static final String LOAD_CHARTS = "load.charts";
     public static final String LOAD_DATA = "load.data";
@@ -53,8 +53,8 @@ public class Strings
     public static final String LOAD_DOWNLOAD_LOCAL_SERVER = "load.download.local.server";
     public static final String LOAD_LOCAL_SERVER_CONNECT = "load.local.server.connect";
     public static final String LOAD_LOCAL_SERVER_RETRY = "load.local.server.retry";
-    
-    
+
+
     //MISC
     public static final String CATEGORY_NONE = "category.none";
     public static final String CATEGORY_REST = "category.rest";
@@ -82,7 +82,7 @@ public class Strings
     public static final String LOCAL_SERVER_ACTION_NOT_PRESENT = "local.server.action.not.present";
     public static final String LOCAL_SERVER_STATUS_INCOMPATIBLE = "local.server.status.incompatible";
     public static final String LOCAL_SERVER_ACTION_INCOMPATIBLE = "local.server.action.incompatible";
-    
+
     //REPORT
     public static final String REPORT_POSITION = "report.position";
     public static final String REPORT_DATE = "report.date";
@@ -101,32 +101,41 @@ public class Strings
     public static final String REPORT_FOOTER_CENTER = "report.footer.center";
     public static final String REPORT_REPEATING_YES ="report.repeating.yes";
     public static final String REPORT_REPEATING_NO ="report.repeating.no";
-    public static final String REPORT_INITIAL_FILENAME ="report.initial.filename"; 
+    public static final String REPORT_INITIAL_FILENAME ="report.initial.filename";
     public static final String REPORT_BUDGET = "report.budget";
     public static final String REPORT_INCOMES = "report.incomes";
     public static final String REPORT_PAYMENTS = "report.payments";
     public static final String REPORT_BUDGET_REST = "report.budget.rest";
-    
+
+    //WEEK_DAYS
+    public static final String MONDAY ="monday";
+    public static final String TUESDAY ="tuesday";
+    public static final String WEDNESDAY ="wednesday";
+    public static final String THURSDAY ="thursday";
+    public static final String FRIDAY ="friday";
+    public static final String SATURDAY ="saturday";
+    public static final String SUNDAY ="sunday";
+
     //MONTH_NAMES
-    public static final String MONTH_JANUARY ="month.january"; 
-    public static final String MONTH_FEBRUARY ="month.february"; 
-    public static final String MONTH_MARCH ="month.march"; 
-    public static final String MONTH_APRIL ="month.april"; 
-    public static final String MONTH_MAY ="month.may"; 
-    public static final String MONTH_JUNE ="month.june"; 
-    public static final String MONTH_JULY ="month.july"; 
-    public static final String MONTH_AUGUST ="month.august"; 
-    public static final String MONTH_SEPTEMBER ="month.september"; 
-    public static final String MONTH_OCTOBER ="month.october"; 
-    public static final String MONTH_NOVEMBER ="month.november"; 
+    public static final String MONTH_JANUARY ="month.january";
+    public static final String MONTH_FEBRUARY ="month.february";
+    public static final String MONTH_MARCH ="month.march";
+    public static final String MONTH_APRIL ="month.april";
+    public static final String MONTH_MAY ="month.may";
+    public static final String MONTH_JUNE ="month.june";
+    public static final String MONTH_JULY ="month.july";
+    public static final String MONTH_AUGUST ="month.august";
+    public static final String MONTH_SEPTEMBER ="month.september";
+    public static final String MONTH_OCTOBER ="month.october";
+    public static final String MONTH_NOVEMBER ="month.november";
     public static final String MONTH_DECEMBER ="month.december";
-    
+
     //NOTIFICATION
     public static final String NOTIFICATION_CHART_EXPORT = "notification.chart.export";
     public static final String NOTIFICATION_REPORT_SAVE = "notification.report.save";
     public static final String NOTIFICATION_SETTINGS_SAVE = "notification.settings.save";
     public static final String NOTIFICATION_NO_UPDATE_AVAILABLE = "notification.no.update.available";
-    
+
     //INFO
     public static final String INFO_TITLE_CATEGORY_DELETE = "info.title.category.delete";
     public static final String INFO_TEXT_CATEGORY_DELETE = "info.text.category.delete";
@@ -174,7 +183,7 @@ public class Strings
     public static final String INFO_TAGS = "info.tags";
     public static final String INFO_TITLE_SHUTDOWN = "info.title.shutdown";
     public static final String INFO_TEXT_SHUTDOWN = "info.text.shutdown";
-        
+
     //WARNING
     public static final String WARNING_ENDDATE_BEFORE_STARTDATE = "warning.enddate.before.startdate";
     public static final String WARNING_EMPTY_WIDTH_IN_PIXELS = "warning.empty.width.in.pixels";
@@ -191,7 +200,7 @@ public class Strings
     public static final String WARNING_TAG_CHARACTER_LIMIT_REACHED_45 = "warning.tag.character.limit.reached.45";
     public static final String WARNING_PAYMENT_AMOUNT = "warning.payment.amount";
     public static final String WARNING_EMPTY_PAYMENT_DATE = "warning.empty.payment.date";
-    public static final String WARNING_PAYMENT_REPEATING = "warning.payment.repeating";    
+    public static final String WARNING_PAYMENT_REPEATING = "warning.payment.repeating";
     public static final String WARNING_EMPTY_SECRET_CLIENT = "warning.empty.secret.client";
     public static final String WARNING_EMPTY_URL = "warning.empty.url";
     public static final String WARNING_EMPTY_SECRET_SERVER = "warning.empty.secret.server";
@@ -202,7 +211,7 @@ public class Strings
     public static final String WARNING_SERVER_VERSION = "warning.server.version";
     public static final String WARNING_EMPTY_YEAR = "warning.empty.year";
     public static final String WARNING_WRONG_YEAR = "warning.wrong.year";
-    
+
     //ERROR
     public static final String ERROR_UNKNOWN_HOST = "error.unknown.host";
     public static final String ERROR_UNKNOWN_ERROR = "error.unknown.error";
@@ -228,7 +237,7 @@ public class Strings
     public static final String ERROR_OPEN_BROWSER = "error.open.browser";
     public static final String ERROR_LOCAL_SERVER_START = "error.local.server.start";
     public static final String ERROR_LOCAL_SERVER_DOWNLOAD = "error.local.server.download";
-    
+
     //ABOUT
     public static final String ABOUT = "about";
     public static final String ABOUT_ROADMAP_LINK = "about.roadmap.link";
diff --git a/src/main/resources/languages/_de.properties b/src/main/resources/languages/_de.properties
index e75205f18..c1eeb55bc 100644
--- a/src/main/resources/languages/_de.properties
+++ b/src/main/resources/languages/_de.properties
@@ -70,6 +70,8 @@ ok=OK
 cancel=Abbrechen
 save=Speichern
 delete=L�schen
+today=Heute
+clear=Zur�cksetzen
 home.placeholder=Keine Daten verf�gbar
 home.budget=von {0} verbleibend
 payments.placeholder=Keine Daten verf�gbar
@@ -111,6 +113,15 @@ report.incomes=Einnahmen:
 report.payments=Ausgaben: 
 report.budget.rest=Restbudget: 
 
+# WEEK DAYS
+monday=Montag
+tuesday=Dienstag
+wednesday=Mittwoch
+thursday=Donnerstag
+friday=Freitag
+saturday=Samstag
+sunday=Sonntag
+
 # MONTH
 month.january=Januar
 month.february=Februar
diff --git a/src/main/resources/languages/_en.properties b/src/main/resources/languages/_en.properties
index 10f50b7de..187c23f0e 100644
--- a/src/main/resources/languages/_en.properties
+++ b/src/main/resources/languages/_en.properties
@@ -70,6 +70,8 @@ ok=OK
 cancel=Cancel
 save=Save
 delete=Delete
+today=Today
+clear=Clear
 home.placeholder=No data available
 home.budget=of {0} remaining
 payments.placeholder=No data available
@@ -111,6 +113,15 @@ report.incomes=Incomes:
 report.payments=Payments: 
 report.budget.rest=Remaining Budget: 
 
+# WEEK DAYS
+monday=Monday
+tuesday=Tuesday
+wednesday=Wednesday
+thursday=Thursday
+friday=Friday
+saturday=Saturday
+sunday=Sunday
+
 # MONTH
 month.january=January
 month.february=February
diff --git a/src/main/resources/static/css/style.css b/src/main/resources/static/css/style.css
index c116eed68..f2dffbc9b 100644
--- a/src/main/resources/static/css/style.css
+++ b/src/main/resources/static/css/style.css
@@ -257,6 +257,15 @@ ul.dropdown-content.select-dropdown li.selected {
     background-color: rgba(0, 0, 0, 0.15);
 }
 
+/* switch color */
+.switch label input[type="checkbox"]:checked + .lever {
+    background-color: rgba(46, 121, 185, 0.6);
+}
+
+.switch label input[type="checkbox"]:checked + .lever::after {
+    background-color: #2E79B9;
+}
+
 .hidden {
     display: none;
 }
diff --git a/src/main/resources/static/js/payments.js b/src/main/resources/static/js/payments.js
index 967ade614..3423fbd5c 100644
--- a/src/main/resources/static/js/payments.js
+++ b/src/main/resources/static/js/payments.js
@@ -2,4 +2,32 @@ $( document ).ready(function() {
     $('#modalConfirmDelete').modal('open');
 
     $('select').material_select();
+
+    $('.datepicker').pickadate({
+        selectMonths: true,
+        selectYears: 100,
+        firstDay: 1,
+
+        // Strings and translations
+        monthsFull: monthNames,
+        monthsShort: monthNamesShort,
+        weekdaysFull: weekDays,
+        weekdaysShort: weekDaysShort,
+        weekdaysLetter: weekDaysLetters,
+
+        // Buttons
+        today: buttonToday,
+        clear: buttonClear,
+        close: buttonClose,
+
+        // Accessibility labels
+        labelMonthNext: '',
+        labelMonthPrev: '',
+        labelMonthSelect: '',
+        labelYearSelect: '',
+
+        // Formats
+        format: 'dd.mm.yyyy',
+        formatSubmit: 'dd.mm.yyyy'
+    });
 });
\ No newline at end of file
diff --git a/src/main/resources/templates/datePicker.ftl b/src/main/resources/templates/datePicker.ftl
index a7cd98eef..440e631e9 100644
--- a/src/main/resources/templates/datePicker.ftl
+++ b/src/main/resources/templates/datePicker.ftl
@@ -9,7 +9,7 @@
          </div>
      </div>
     <!-- modal to select specific month and year -->
-    <div id="modalDate" class="modal">
+    <div id="modalDate" class="modal modal-fixed-footer">
         <div class="modal-content">
             <h4>${locale.getString("title.datepicker")}</h4>
             <div class="input-field col s12">
@@ -34,4 +34,35 @@
             <a href="/setDate?target=${target}" id="buttonChooseDate" class="modal-action modal-close waves-effect waves-green btn-flat">${locale.getString("ok")}</a>
         </div>
     </div>
+</#macro>
+
+<#macro datePickerLocalization>
+    <#assign locale = static["tools.Localization"]>
+    <#-- localization for scripts -->
+    <script>
+        <#assign monthNames = "">
+        <#assign monthNamesShort = "">
+        <#list helpers.getMonthList() as monthName>
+            <#assign monthNames += "'" + monthName + "', ">
+            <#assign monthNamesShort += "'" + monthName[0..2] + "', ">
+        </#list>
+
+        <#assign weekDays = "">
+        <#assign weekDaysShort = "">
+        <#assign weekDaysLetters = "">
+        <#list helpers.getWeekDays() as weekDay>
+            <#assign weekDays += "'" + weekDay + "', ">
+            <#assign weekDaysShort += "'" + weekDay[0..1] + "', ">
+            <#assign weekDaysLetters += "'" + weekDay[0] + "', ">
+        </#list>
+
+        monthNames = [${monthNames}];
+        monthNamesShort = [${monthNamesShort}];
+        weekDays = [${weekDays}];
+        weekDaysShort = [${weekDaysShort}];
+        weekDaysLetters = [${weekDaysLetters}];
+        buttonToday = '${locale.getString("today")}';
+        buttonClear = '${locale.getString("clear")}';
+        buttonClose = '${locale.getString("ok")}';
+    </script>
 </#macro>
\ No newline at end of file
diff --git a/src/main/resources/templates/payments/newPayment.ftl b/src/main/resources/templates/payments/newPayment.ftl
index a9f10fcc1..2d5516333 100644
--- a/src/main/resources/templates/payments/newPayment.ftl
+++ b/src/main/resources/templates/payments/newPayment.ftl
@@ -19,6 +19,18 @@
                     <#import "../validation.ftl" as validation>
                     <form name="NewPayment" action="/payments/newPayment" method="post">
                         <input type="hidden" name="ID" value="<#if payment.getID()??>${payment.getID()}</#if>">
+                        <div class="row">
+                            <div class="s12 m12 l8 offset-l2 center-align">
+                                <div class="switch">
+                                    <label>
+                                        ${locale.getString("title.income")}
+                                        <input type="checkbox" <#if payment.getAmount()?? && payment.getAmount() < 0>checked</#if>>
+                                        <span class="lever"></span>
+                                        ${locale.getString("title.payment")}
+                                    </label>
+                                </div>
+                            </div>
+                        </div>
                         <div class="row">
                             <div class="input-field col s12 m12 l8 offset-l2">
                                 <input id="payment-name" type="text" name="name" <@validation.validation "name"/> value="<#if payment.getName()??>${payment.getName()}</#if>">
@@ -49,6 +61,12 @@
                                 <label for="payment-amount">${locale.getString("payment.new.label.category")}</label>
                             </div>
                         </div>
+                        <div class="row">
+                            <div class="input-field col s12 m12 l8 offset-l2">
+                                <input id="payment-datepicker" type="text" class="datepicker">
+                                <label for="payment-datepicker">${locale.getString("payment.new.label.date")}</label>
+                            </div>
+                        </div>
                         <div class="row">
                             <div class="input-field col s12 m12 l8 offset-l2">
                                 <textarea id="payment-description" class="materialize-textarea" name="description" <@validation.validation "description"/>><#if payment.getDescription()??>${payment.getDescription()}</#if></textarea>
@@ -86,6 +104,9 @@
             </div>
         </main>
 
+        <#import "../datePicker.ftl" as datePicker>
+        <@datePicker.datePickerLocalization/>
+
         <!-- Scripts-->
         <script src="https://code.jquery.com/jquery-2.1.1.min.js"></script>
         <script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.100.2/js/materialize.min.js"></script>
-- 
GitLab