diff --git a/.classpath b/.classpath
index ec96f8d09f7b3ccd3429d6e35b8e8203497c0728..d67069e9013636f5559574bddc8949f675e64448 100644
--- a/.classpath
+++ b/.classpath
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <classpath>
-	<classpathentry including="**/*.java" kind="src" output="target/classes" path="src">
+	<classpathentry kind="src" output="target/classes" path="src">
 		<attributes>
 			<attribute name="optional" value="true"/>
 			<attribute name="maven.pomderived" value="true"/>
diff --git a/.settings/org.eclipse.core.resources.prefs b/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..99f26c0203a7844de00dbfc56e6a35d8ed3c022c
--- /dev/null
+++ b/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+encoding/<project>=UTF-8
diff --git a/settings.properties b/settings.json
similarity index 67%
rename from settings.properties
rename to settings.json
index 04a92f8bcf3c4441dd3c421a8bfac89cce05c055..b60e9bf038beddea9fb9d43d3543ffa1c2f56898 100644
--- a/settings.properties
+++ b/settings.json
@@ -4,5 +4,7 @@
 	"databaseUsername": "root",
 	"databasePassword": "",
 	"serverPort": 9000,
-	"serverSecret": "geheim"
+	"serverSecret": "geheim",
+	"keystorePath": "",
+	"keystorePassword": "geheim"
 }
\ No newline at end of file
diff --git a/src/de/deadlocker8/budgetmaster/logic/Budget.java b/src/de/deadlocker8/budgetmaster/logic/Budget.java
new file mode 100644
index 0000000000000000000000000000000000000000..a7aef0079cc7ee5dae1229dd5ef62b7fb6efea5d
--- /dev/null
+++ b/src/de/deadlocker8/budgetmaster/logic/Budget.java
@@ -0,0 +1,46 @@
+package de.deadlocker8.budgetmaster.logic;
+
+import java.util.List;
+
+public class Budget
+{
+	private double incomeSum;
+	private double paymentSum;
+	
+	public Budget(List<Payment> payments)
+	{		
+		incomeSum = 0;
+		paymentSum = 0;
+		for(Payment currentPayment : payments)
+		{
+			double amount = currentPayment.getAmount();
+			if(amount > 0)
+			{
+				incomeSum += amount;
+			}
+			else
+			{
+				paymentSum += amount;
+			}
+		}
+		
+		incomeSum /= 100.0;
+		paymentSum /= 100.0;
+	}
+
+	public double getIncomeSum()
+	{
+		return incomeSum;
+	}
+
+	public double getPaymentSum()
+	{
+		return paymentSum;
+	}
+
+	@Override
+	public String toString()
+	{
+		return "Budget [incomeSum=" + incomeSum + ", paymentSum=" + paymentSum + "]";
+	}
+}
\ No newline at end of file
diff --git a/src/de/deadlocker8/budgetmaster/logic/Category.java b/src/de/deadlocker8/budgetmaster/logic/Category.java
index 1b523345a323e9476da6ff49393b13638ce27c92..29c523ae028ab6709db76c641e9a2b0022498f70 100644
--- a/src/de/deadlocker8/budgetmaster/logic/Category.java
+++ b/src/de/deadlocker8/budgetmaster/logic/Category.java
@@ -7,17 +7,17 @@ public class Category
 	private int ID;
 	private String name;
 	private Color color;
-	
+
 	public Category(String name, Color color)
 	{
 		this.name = name;
 		this.color = color;
 	}
-	
+
 	public Category(int ID, String name, Color color)
 	{
 		this.ID = ID;
-		this.name =name;
+		this.name = name;
 		this.color = color;
 	}
 
@@ -51,4 +51,19 @@ public class Category
 	{
 		return "Category [ID=" + ID + ", name=" + name + ", color=" + color + "]";
 	}
+	
+	@Override
+	public boolean equals(Object obj)
+	{
+		if(this == obj)
+			return true;
+		if(obj == null)
+			return false;
+		if(getClass() != obj.getClass())
+			return false;
+		Category other = (Category)obj;
+		if(ID != other.ID)
+			return false;
+		return true;
+	}
 }
\ No newline at end of file
diff --git a/src/de/deadlocker8/budgetmaster/logic/CategoryHandler.java b/src/de/deadlocker8/budgetmaster/logic/CategoryHandler.java
index f02b9553e4f4121225528c7e7d85b1062c20970c..f47381e8b532c95ef8ca079fe480bb610b095587 100644
--- a/src/de/deadlocker8/budgetmaster/logic/CategoryHandler.java
+++ b/src/de/deadlocker8/budgetmaster/logic/CategoryHandler.java
@@ -32,6 +32,6 @@ public class CategoryHandler
 			}
 		}
 		
-		return new Category(0, "NONE", Color.web("#FFFFFF"));
+		return new Category(1, "NONE", Color.web("#FFFFFF"));
 	}
 }
\ No newline at end of file
diff --git a/src/de/deadlocker8/budgetmaster/logic/Helpers.java b/src/de/deadlocker8/budgetmaster/logic/Helpers.java
index e3d1ae1010fd0d3a2b3261c8a3e3fcf95c026be1..a3761e796fd6ad0bd0a435ffe141d0d397e9fa34 100644
--- a/src/de/deadlocker8/budgetmaster/logic/Helpers.java
+++ b/src/de/deadlocker8/budgetmaster/logic/Helpers.java
@@ -2,9 +2,14 @@ package de.deadlocker8.budgetmaster.logic;
 
 import java.io.UnsupportedEncodingException;
 import java.net.URLEncoder;
+import java.text.DecimalFormat;
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
 
 public class Helpers
 {
+	public static final DecimalFormat NUMBER_FORMAT = new DecimalFormat("0.00");
+	
 	public static String getURLEncodedString(String input)
 	{
 		try
@@ -16,4 +21,14 @@ public class Helpers
 			return input;
 		}
 	}
+	
+	public static String getDateString(LocalDate date)
+	{
+		if(date == null)
+		{
+			return "";
+		}
+		DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
+		return date.format(formatter);
+	}
 }
\ No newline at end of file
diff --git a/src/de/deadlocker8/budgetmaster/logic/LatestRepeatingPayment.java b/src/de/deadlocker8/budgetmaster/logic/LatestRepeatingPayment.java
new file mode 100644
index 0000000000000000000000000000000000000000..4ac70eef388f1d35e06cf0e4509c26231af1ca66
--- /dev/null
+++ b/src/de/deadlocker8/budgetmaster/logic/LatestRepeatingPayment.java
@@ -0,0 +1,36 @@
+package de.deadlocker8.budgetmaster.logic;
+
+public class LatestRepeatingPayment
+{
+	private int ID;
+	private int repeatingPaymentID;				
+	private String lastDate;
+	
+	public LatestRepeatingPayment(int ID, int repeatingPaymentID, String lastDate)
+	{
+		this.ID = ID;
+		this.repeatingPaymentID = repeatingPaymentID;
+		this.lastDate = lastDate;
+	}
+	
+	public int getID()
+	{
+		return ID;
+	}
+	
+	public int getRepeatingPaymentID()
+	{
+		return repeatingPaymentID;
+	}
+	
+	public String getLastDate()
+	{
+		return lastDate;
+	}
+	
+	@Override
+	public String toString()
+	{
+		return "LatestRepeatingPayment [ID=" + ID + ", repeatingPaymentID=" + repeatingPaymentID + ", lastDate=" + lastDate + "]";
+	}
+}
\ No newline at end of file
diff --git a/src/de/deadlocker8/budgetmaster/logic/NormalPayment.java b/src/de/deadlocker8/budgetmaster/logic/NormalPayment.java
new file mode 100644
index 0000000000000000000000000000000000000000..7441eae7f2051e7c8a0d69ba17d6935b4e7fefa4
--- /dev/null
+++ b/src/de/deadlocker8/budgetmaster/logic/NormalPayment.java
@@ -0,0 +1,15 @@
+package de.deadlocker8.budgetmaster.logic;
+
+public class NormalPayment extends Payment
+{	
+	public NormalPayment(int ID, int amount, String date, int categoryID, String name)
+	{		
+		super(ID, amount, date, categoryID, name);
+	}
+	
+	@Override
+	public String toString()
+	{
+		return "Payment [ID=" + super.getID() + ", amount=" + super.getAmount() + ", date=" + super.getDate() + ", categoryID=" + super.getCategoryID() + ", name=" + super.getName() + "]";
+	}
+}
\ No newline at end of file
diff --git a/src/de/deadlocker8/budgetmaster/logic/Payment.java b/src/de/deadlocker8/budgetmaster/logic/Payment.java
index 21f3f14514c5640ced7ab52798b507496849f0d9..38e72ccab692209e7b26135dae8e7665f7bc98e4 100644
--- a/src/de/deadlocker8/budgetmaster/logic/Payment.java
+++ b/src/de/deadlocker8/budgetmaster/logic/Payment.java
@@ -1,38 +1,32 @@
 package de.deadlocker8.budgetmaster.logic;
 
-public class Payment
+public abstract class Payment
 {	
 	private int ID;
 	private int amount;
 	private String date;
 	private int categoryID;
-	private String name;	
-	private int repeatInterval;
-	private String repeatEndDate;
-	private int repeatMonthDay;
-
-	public Payment(int ID, int amount, String date, int categoryID, String name, int repeatInterval, String repeatEndDate, int repeatMonthDay)
+	private String name;
+	
+	public Payment(int ID, int amount, String date, int categoryID, String name)
 	{		
-		this.ID = ID;		
+		this.ID = ID;
 		this.amount = amount;
 		this.date = date;
 		this.categoryID = categoryID;
 		this.name = name;
-		this.repeatInterval = repeatInterval;
-		this.repeatEndDate = repeatEndDate;
-		this.repeatMonthDay = repeatMonthDay;
 	}
 
 	public int getID()
 	{
 		return ID;
 	}
-	
-	public boolean isIncome()
+
+	public void setID(int iD)
 	{
-		return amount > 0;
+		ID = iD;
 	}
-	
+
 	public int getAmount()
 	{
 		return amount;
@@ -72,55 +66,9 @@ public class Payment
 	{
 		this.name = name;
 	}
-
-	public int getRepeatInterval()
-	{
-		return repeatInterval;
-	}
-
-	public void setRepeatInterval(int repeatInterval)
-	{
-		this.repeatInterval = repeatInterval;
-	}
-
-	public String getRepeatEndDate()
-	{
-		return repeatEndDate;
-	}
-
-	public void setRepeatEndDate(String repeatEndDate)
-	{
-		this.repeatEndDate = repeatEndDate;
-	}
-
-	public int getRepeatMonthDay()
-	{
-		return repeatMonthDay;
-	}
-
-	public void setRepeatMonthDay(int repeatMonthDay)
-	{
-		this.repeatMonthDay = repeatMonthDay;
-	}
 	
-	public boolean isRepeating()
-	{
-		if(repeatInterval != 0)
-		{
-			return true;
-		}
-		 
-		if(repeatMonthDay != 0)
-		{
-			return true;
-		}
-		
-		return false;
-	}
-
-	@Override
-	public String toString()
+	public boolean isIncome()
 	{
-		return "Payment [ID=" + ID + ", amount=" + amount + ", date=" + date + ", categoryID=" + categoryID + ", name=" + name + ", repeatInterval=" + repeatInterval + ", repeatEndDate=" + repeatEndDate + ", repeatMonthDay=" + repeatMonthDay + "]";
+		return amount > 0;
 	}
 }
\ No newline at end of file
diff --git a/src/de/deadlocker8/budgetmaster/logic/RepeatingPayment.java b/src/de/deadlocker8/budgetmaster/logic/RepeatingPayment.java
new file mode 100644
index 0000000000000000000000000000000000000000..1bc6195f8692dcd027cbc2965e7262c5fd7815fc
--- /dev/null
+++ b/src/de/deadlocker8/budgetmaster/logic/RepeatingPayment.java
@@ -0,0 +1,66 @@
+package de.deadlocker8.budgetmaster.logic;
+
+public class RepeatingPayment extends Payment
+{	
+	private int repeatInterval;
+	private String repeatEndDate;
+	private int repeatMonthDay;
+
+	public RepeatingPayment(int ID, int amount, String date, int categoryID, String name, int repeatInterval, String repeatEndDate, int repeatMonthDay)
+	{
+		super(ID, amount, date, categoryID, name);
+		this.repeatInterval = repeatInterval;
+		this.repeatEndDate = repeatEndDate;
+		this.repeatMonthDay = repeatMonthDay;
+	}
+
+	public int getRepeatInterval()
+	{
+		return repeatInterval;
+	}
+
+	public void setRepeatInterval(int repeatInterval)
+	{
+		this.repeatInterval = repeatInterval;
+	}
+
+	public String getRepeatEndDate()
+	{
+		return repeatEndDate;
+	}
+
+	public void setRepeatEndDate(String repeatEndDate)
+	{
+		this.repeatEndDate = repeatEndDate;
+	}
+
+	public int getRepeatMonthDay()
+	{
+		return repeatMonthDay;
+	}
+
+	public void setRepeatMonthDay(int repeatMonthDay)
+	{
+		this.repeatMonthDay = repeatMonthDay;
+	}
+	
+	@Override
+	public String toString()
+	{
+		return "RepeatingPayment [ID=" + super.getID() + ", amount=" + super.getAmount() + ", date=" + super.getDate() + ", categoryID=" + super.getCategoryID() + ", name=" + super.getName() + ", repeatInterval=" + repeatInterval + ", repeatEndDate=" + repeatEndDate + ", repeatMonthDay=" + repeatMonthDay + "]";
+	}
+	
+	@Override
+	public boolean equals(Object obj)
+	{
+		if(obj instanceof LatestRepeatingPayment)
+		{
+			return super.getID() == ((LatestRepeatingPayment)obj).getRepeatingPaymentID();
+		}
+		else if(obj instanceof RepeatingPayment)
+		{
+			return super.getID() == ((RepeatingPayment)obj).getID();
+		}
+		return super.equals(obj);
+	}
+}
\ No newline at end of file
diff --git a/src/de/deadlocker8/budgetmaster/logic/RepeatingPaymentEntry.java b/src/de/deadlocker8/budgetmaster/logic/RepeatingPaymentEntry.java
new file mode 100644
index 0000000000000000000000000000000000000000..5527764bd283903271d28884dbde18365fd31e2d
--- /dev/null
+++ b/src/de/deadlocker8/budgetmaster/logic/RepeatingPaymentEntry.java
@@ -0,0 +1,45 @@
+package de.deadlocker8.budgetmaster.logic;
+
+public class RepeatingPaymentEntry extends Payment
+{		
+	private int repeatingPaymentID;		
+	private int repeatInterval;
+	private String repeatEndDate;
+	private int repeatMonthDay;
+	
+	public RepeatingPaymentEntry(int ID, int repeatingPaymentID, String date, int amount, int categoryID, String name, int repeatInterval, String repeatEndDate, int repeatMonthDay)
+	{
+		super(ID, amount, date, categoryID, name);		
+		this.repeatingPaymentID = repeatingPaymentID;	
+		this.repeatInterval = repeatInterval;
+		this.repeatEndDate = repeatEndDate;
+		this.repeatMonthDay = repeatMonthDay;
+	}
+	
+	public int getRepeatingPaymentID()
+	{
+		return repeatingPaymentID;
+	}
+
+	public int getRepeatInterval()
+	{
+		return repeatInterval;
+	}
+
+	public String getRepeatEndDate()
+	{
+		return repeatEndDate;
+	}
+
+	public int getRepeatMonthDay()
+	{
+		return repeatMonthDay;
+	}
+
+	@Override
+	public String toString()
+	{
+		return "RepeatingPaymentEntry [ID=" + super.getID() + ", repeatingPaymentID=" + repeatingPaymentID + ", date=" + super.getDate() + ", amount=" + super.getAmount() + ", categoryID=" + super.getCategoryID() + ", name=" + super.getName() + ", repeatInterval=" + repeatInterval + ", repeatEndDate=" + repeatEndDate + ", repeatMonthDay="
+				+ repeatMonthDay + "]";
+	}
+}
\ No newline at end of file
diff --git a/src/de/deadlocker8/budgetmaster/logic/ServerConnection.java b/src/de/deadlocker8/budgetmaster/logic/ServerConnection.java
index 71e3708921a240af443e6f191bc344b4dcbe0389..1792a896e1fe7e43e739e90eb4739fffa4744cc3 100644
--- a/src/de/deadlocker8/budgetmaster/logic/ServerConnection.java
+++ b/src/de/deadlocker8/budgetmaster/logic/ServerConnection.java
@@ -76,14 +76,10 @@ public class ServerConnection
 			return null;
 		}
 	}
-
-	/*
-	 * Category
-	 */
+	
 	public Category getCategory(int ID) throws Exception
 	{
 		URL url = new URL(settings.getUrl() + "/category/single?secret=" + Helpers.getURLEncodedString(settings.getSecret()) + "&id=" + ID);
-		System.out.println(url);
 		HttpsURLConnection httpsCon = (HttpsURLConnection)url.openConnection();
 		httpsCon.setDoOutput(true);
 		httpsCon.setRequestMethod("GET");
@@ -132,13 +128,13 @@ public class ServerConnection
 		BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
 		reader.close();
 	}
-
+	
 	/*
-	 * CategoryBudget
+	 * Payment
 	 */
-	public ArrayList<CategoryBudget> getCategoryBudgets(int year, int month) throws Exception
+	public ArrayList<NormalPayment> getPayments(int year, int month) throws Exception
 	{
-		URL url = new URL(settings.getUrl() + "/categorybudget?secret=" + Helpers.getURLEncodedString(settings.getSecret()) + "&year=" + year + "&month=" + month);
+		URL url = new URL(settings.getUrl() + "/payment?secret=" + Helpers.getURLEncodedString(settings.getSecret()) + "&year=" + year + "&month=" + month);
 		HttpsURLConnection httpsCon = (HttpsURLConnection)url.openConnection();
 		httpsCon.setDoOutput(true);
 		httpsCon.setRequestMethod("GET");
@@ -147,7 +143,7 @@ public class ServerConnection
 		{
 			String result = Read.getStringFromInputStream(httpsCon.getInputStream());
 			// required by GSON
-			Type listType = new TypeToken<ArrayList<CategoryBudget>>()
+			Type listType = new TypeToken<ArrayList<NormalPayment>>()
 			{
 			}.getType();
 			return gson.fromJson(result, listType);
@@ -158,12 +154,9 @@ public class ServerConnection
 		}
 	}
 
-	/*
-	 * Payment
-	 */
-	public ArrayList<Payment> getPayments(int year, int month) throws Exception
+	public ArrayList<RepeatingPaymentEntry> getRepeatingPayments(int year, int month) throws Exception
 	{
-		URL url = new URL(settings.getUrl() + "/payment?secret=" + Helpers.getURLEncodedString(settings.getSecret()) + "&year=" + year + "&month=" + month);
+		URL url = new URL(settings.getUrl() + "/repeatingpayment?secret=" + Helpers.getURLEncodedString(settings.getSecret()) + "&year=" + year + "&month=" + month);
 		HttpsURLConnection httpsCon = (HttpsURLConnection)url.openConnection();
 		httpsCon.setDoOutput(true);
 		httpsCon.setRequestMethod("GET");
@@ -172,7 +165,7 @@ public class ServerConnection
 		{
 			String result = Read.getStringFromInputStream(httpsCon.getInputStream());
 			// required by GSON
-			Type listType = new TypeToken<ArrayList<Payment>>()
+			Type listType = new TypeToken<ArrayList<RepeatingPaymentEntry>>()
 			{
 			}.getType();
 			return gson.fromJson(result, listType);
@@ -182,17 +175,57 @@ public class ServerConnection
 			return null;
 		}
 	}
+	
+	public RepeatingPayment getRepeatingPayment(int ID) throws Exception
+	{
+		URL url = new URL(settings.getUrl() + "/repeatingpayment/single?secret=" + Helpers.getURLEncodedString(settings.getSecret()) + "&id=" + ID);
+		HttpsURLConnection httpsCon = (HttpsURLConnection)url.openConnection();
+		httpsCon.setDoOutput(true);
+		httpsCon.setRequestMethod("GET");
 
-	public void addPayment(Payment payment) throws Exception
+		if(httpsCon.getResponseCode() == HttpsURLConnection.HTTP_OK)
+		{
+			String result = Read.getStringFromInputStream(httpsCon.getInputStream());		
+			return gson.fromJson(result, RepeatingPayment.class);
+		}
+		else
+		{
+			return null;
+		}
+	}
+
+	public void addNormalPayment(NormalPayment payment) throws Exception
+	{
+		URL url = new URL(settings.getUrl() + "/payment?secret=" + Helpers.getURLEncodedString(settings.getSecret()) + "&amount=" + payment.getAmount() + "&date=" + payment.getDate() + "&categoryID=" + payment.getCategoryID() + "&name=" + Helpers.getURLEncodedString(payment.getName()));
+		HttpsURLConnection httpsCon = (HttpsURLConnection)url.openConnection();
+		httpsCon.setRequestMethod("POST");
+		httpsCon.setDoInput(true);
+		InputStream stream = httpsCon.getInputStream();
+		BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
+		reader.close();
+	}
+
+	public void updateNormalPayment(NormalPayment payment) throws Exception
+	{
+		 URL url = new URL(settings.getUrl() + "/payment?secret=" + settings.getSecret() + "&id=" + payment.getID() + "&amount=" + payment.getAmount() + "&date=" + payment.getDate() + "&categoryID=" + payment.getCategoryID() + "&name=" + Helpers.getURLEncodedString(payment.getName()));
+		 HttpsURLConnection httpsCon = (HttpsURLConnection)url.openConnection();
+		 httpsCon.setRequestMethod("PUT");
+		 httpsCon.setDoInput(true);
+		 InputStream stream = httpsCon.getInputStream();
+		 BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
+		 reader.close();
+	}
+
+	public void addRepeatingPayment(RepeatingPayment payment) throws Exception
 	{
 		String repeatEndDate = payment.getRepeatEndDate();
 		if(repeatEndDate == null || repeatEndDate.equals(""))
 		{
-			//A is placeholder for empty repeatEndDate
+			// A is placeholder for empty repeatEndDate
 			repeatEndDate = "A";
 		}
 
-		URL url = new URL(settings.getUrl() + "/payment?secret=" + Helpers.getURLEncodedString(settings.getSecret()) + "&amount=" + payment.getAmount() + "&date=" + payment.getDate() + "&categoryID=" + payment.getCategoryID() + "&name=" + Helpers.getURLEncodedString(payment.getName())
+		URL url = new URL(settings.getUrl() + "/repeatingpayment?secret=" + Helpers.getURLEncodedString(settings.getSecret()) + "&amount=" + payment.getAmount() + "&date=" + payment.getDate() + "&categoryID=" + payment.getCategoryID() + "&name=" + Helpers.getURLEncodedString(payment.getName())
 				+ "&repeatInterval=" + payment.getRepeatInterval() + "&repeatEndDate=" + repeatEndDate + "&repeatMonthDay=" + payment.getRepeatMonthDay());
 		HttpsURLConnection httpsCon = (HttpsURLConnection)url.openConnection();
 		httpsCon.setRequestMethod("POST");
@@ -202,36 +235,71 @@ public class ServerConnection
 		reader.close();
 	}
 
-	public void updatePayment(Payment payment, Payment oldPayment) throws Exception
+	public void deleteNormalPayment(NormalPayment payment) throws Exception
+	{
+		URL url = new URL(settings.getUrl() + "/payment?secret=" + Helpers.getURLEncodedString(settings.getSecret()) + "&id=" + payment.getID());
+		HttpsURLConnection httpsCon = (HttpsURLConnection)url.openConnection();
+		httpsCon.setRequestMethod("DELETE");
+		httpsCon.setDoInput(true);
+		InputStream stream = httpsCon.getInputStream();
+		BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
+		reader.close();
+	}
+	
+	public void deleteRepeatingPayment(RepeatingPaymentEntry payment) throws Exception
 	{
-		// TODO update payment
-		// TODO handle changing of repeating type
-		// URL url = new URL(settings.getUrl() + "/payment?secret=" + settings.getSecret() + "&id=" + category.getID() + "&name=" + category.getName() + "&color=" + ConvertTo.toRGBHexWithoutOpacity(category.getColor()).replace("#", ""));
-		// HttpsURLConnection httpsCon = (HttpsURLConnection)url.openConnection();
-		// httpsCon.setRequestMethod("PUT");
-		// httpsCon.setDoInput(true);
-		// InputStream stream = httpsCon.getInputStream();
-		// BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
-		// reader.close();
+		URL url = new URL(settings.getUrl() + "/repeatingpayment?secret=" + Helpers.getURLEncodedString(settings.getSecret()) + "&id=" + payment.getRepeatingPaymentID());
+		HttpsURLConnection httpsCon = (HttpsURLConnection)url.openConnection();
+		httpsCon.setRequestMethod("DELETE");
+		httpsCon.setDoInput(true);
+		InputStream stream = httpsCon.getInputStream();
+		BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
+		reader.close();
 	}
-
-	public void deletePayment(Payment payment) throws Exception
+	
+	/*
+	 * CATEGORYBUDGET
+	 */
+	public ArrayList<CategoryBudget> getCategoryBudgets(int year, int month) throws Exception
 	{
-		// TODO handle repeating payments
+		URL url = new URL(settings.getUrl() + "/categorybudget?secret=" + Helpers.getURLEncodedString(settings.getSecret()) + "&year=" + year + "&month=" + month);
+		HttpsURLConnection httpsCon = (HttpsURLConnection)url.openConnection();
+		httpsCon.setDoOutput(true);
+		httpsCon.setRequestMethod("GET");
 
-		if(payment.isRepeating())
+		if(httpsCon.getResponseCode() == HttpsURLConnection.HTTP_OK)
 		{
+			String result = Read.getStringFromInputStream(httpsCon.getInputStream());
+			// required by GSON
+			Type listType = new TypeToken<ArrayList<CategoryBudget>>()
+			{
+			}.getType();
+			return gson.fromJson(result, listType);
+		}
+		else
+		{
+			return null;
+		}
+	}
+	
+	/*
+	 * REST
+	 */
+	public int getRestForAllPreviousMonths(int year, int month) throws Exception
+	{
+		URL url = new URL(settings.getUrl() + "/rest?secret=" + Helpers.getURLEncodedString(settings.getSecret()) + "&year=" + year + "&month=" + month);
+		HttpsURLConnection httpsCon = (HttpsURLConnection)url.openConnection();
+		httpsCon.setDoOutput(true);
+		httpsCon.setRequestMethod("GET");
 
+		if(httpsCon.getResponseCode() == HttpsURLConnection.HTTP_OK)
+		{
+			String result = Read.getStringFromInputStream(httpsCon.getInputStream());		
+			return gson.fromJson(result, Integer.class);
 		}
 		else
 		{
-			URL url = new URL(settings.getUrl() + "/payment?secret=" + Helpers.getURLEncodedString(settings.getSecret()) + "&id=" + payment.getID());
-			HttpsURLConnection httpsCon = (HttpsURLConnection)url.openConnection();
-			httpsCon.setRequestMethod("DELETE");
-			httpsCon.setDoInput(true);
-			InputStream stream = httpsCon.getInputStream();
-			BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
-			reader.close();
+			return 0;
 		}
 	}
 }
\ No newline at end of file
diff --git a/src/de/deadlocker8/budgetmaster/logic/Settings.java b/src/de/deadlocker8/budgetmaster/logic/Settings.java
index eccef861d3f45a70046c46e716b2cfecd2572663..84a6b6ff524b6d19e94dcaf081e953e7ff75ab4e 100644
--- a/src/de/deadlocker8/budgetmaster/logic/Settings.java
+++ b/src/de/deadlocker8/budgetmaster/logic/Settings.java
@@ -4,6 +4,8 @@ public class Settings
 {
 	private String url;
 	private String secret;
+	private String currency;
+	private boolean restActivated;
 	
 	public Settings()
 	{
@@ -29,4 +31,30 @@ public class Settings
 	{
 		this.secret = secret;
 	}
+
+	public String getCurrency()
+	{
+		return currency;
+	}
+
+	public void setCurrency(String currency)
+	{
+		this.currency = currency;
+	}
+
+	public boolean isRestActivated()
+	{
+		return restActivated;
+	}
+
+	public void setRestActivated(boolean restActivated)
+	{
+		this.restActivated = restActivated;
+	}
+
+	@Override
+	public String toString()
+	{
+		return "Settings [url=" + url + ", secret=" + secret + ", currency=" + currency + ", restActivated=" + restActivated + "]";
+	}
 }
\ No newline at end of file
diff --git a/src/de/deadlocker8/budgetmaster/logic/Utils.java b/src/de/deadlocker8/budgetmaster/logic/Utils.java
index 5b949e4a3f3329ab002e266b61921c6c76ddf7df..55789dca5c6081740ca9e6a6fb2d427eda140c45 100644
--- a/src/de/deadlocker8/budgetmaster/logic/Utils.java
+++ b/src/de/deadlocker8/budgetmaster/logic/Utils.java
@@ -2,6 +2,9 @@ package de.deadlocker8.budgetmaster.logic;
 
 import java.io.File;
 import java.io.IOException;
+import java.io.Reader;
+import java.io.Writer;
+import java.nio.charset.Charset;
 import java.nio.file.Files;
 import java.nio.file.Paths;
 import java.util.Locale;
@@ -17,14 +20,14 @@ public class Utils
 	
 	public static Settings loadSettings()
 	{
-		String settingsJSON;
 		Settings settings;
 		try
 		{
 			Gson gson = new Gson();
 			PathUtils.checkFolder(new File(PathUtils.getOSindependentPath() + bundle.getString("folder")));
-			settingsJSON = new String(Files.readAllBytes(Paths.get(PathUtils.getOSindependentPath() + bundle.getString("folder") + "/settings.json")));				
-			settings = gson.fromJson(settingsJSON, Settings.class);	
+			Reader reader = Files.newBufferedReader(Paths.get(PathUtils.getOSindependentPath() + bundle.getString("folder") + "/settings.json"), Charset.forName("UTF-8"));
+			settings = gson.fromJson(reader, Settings.class);	
+			reader.close();
 			return settings;
 		}
 		catch(IOException e)
@@ -33,19 +36,13 @@ public class Utils
 		}
 	}
 	
-	public static void saveSettings(Settings settings)
-	{
-		try
-		{
-			Gson gson = new Gson();
-			String jsonString = gson.toJson(settings);
-			
-			Files.write(Paths.get(PathUtils.getOSindependentPath() + bundle.getString("folder")  + "/settings.json"), jsonString.getBytes());				
-		}
-		catch(IOException e)
-		{
-			//ERRORHANDLING
-			e.printStackTrace();			
-		}
+	public static void saveSettings(Settings settings) throws IOException
+	{		
+		Gson gson = new Gson();
+		String jsonString = gson.toJson(settings);
+		
+		Writer writer = Files.newBufferedWriter(Paths.get(PathUtils.getOSindependentPath() + bundle.getString("folder")  + "/settings.json"), Charset.forName("UTF-8"));
+		writer.write(jsonString);
+		writer.close();
 	}
 }
\ No newline at end of file
diff --git a/src/de/deadlocker8/budgetmaster/main/Main.java b/src/de/deadlocker8/budgetmaster/main/Main.java
index 2c59fb7efc79105646a4401279ab53b193d16410..de459fc7283f353dffd55a22b23e6ef6b476d50c 100644
--- a/src/de/deadlocker8/budgetmaster/main/Main.java
+++ b/src/de/deadlocker8/budgetmaster/main/Main.java
@@ -1,5 +1,6 @@
 package de.deadlocker8.budgetmaster.main;
 
+import java.io.File;
 import java.util.Arrays;
 import java.util.Locale;
 import java.util.ResourceBundle;
@@ -13,6 +14,7 @@ import javafx.scene.image.Image;
 import javafx.stage.Stage;
 import logger.LogLevel;
 import logger.Logger;
+import tools.PathUtils;
 
 public class Main extends Application
 {
@@ -26,7 +28,7 @@ public class Main extends Application
 			FXMLLoader loader = new FXMLLoader(getClass().getClassLoader().getResource("de/deadlocker8/budgetmaster/ui/GUI.fxml"));
 			Parent root = (Parent)loader.load();
 
-			Scene scene = new Scene(root, 600, 600);			
+			Scene scene = new Scene(root, 600, 650);			
 
 			((Controller)loader.getController()).init(stage);
 
@@ -41,7 +43,7 @@ public class Main extends Application
 		}
 		catch(Exception e)
 		{
-			Logger.log(LogLevel.ERROR, Logger.exceptionToString(e));
+			Logger.error(e);
 		}
 	}
 
@@ -50,15 +52,20 @@ public class Main extends Application
 		if(Arrays.asList(args).contains("debug"))
 		{
 			Logger.setLevel(LogLevel.ALL);
-			Logger.log(LogLevel.INFO, "Running in Debug Mode");
+			Logger.info("Running in Debug Mode");
 		}
 		else
 		{
-			Logger.setLevel(LogLevel.ERROR);
+			Logger.setLevel(LogLevel.ERROR);			
 		}
+		
+		PathUtils.checkFolder(new File(PathUtils.getOSindependentPath() + bundle.getString("folder")));
+		File logFile = new File(PathUtils.getOSindependentPath() + bundle.getString("folder") + "/error.log");				
+		Logger.enableFileOutput(logFile);
 	
-		Logger.log(LogLevel.INFO, bundle.getString("app.name") + " - v" + bundle.getString("version.name") + " - (versioncode: " + bundle.getString("version.code") + ") from " + bundle.getString("version.date"));
-
+		Logger.appInfo(bundle.getString("app.name"), bundle.getString("version.name"), bundle.getString("version.code"), bundle.getString("version.date"));
+		
 		launch(args);
 	}
+	
 }
\ No newline at end of file
diff --git a/src/de/deadlocker8/budgetmaster/ui/CategoryController.java b/src/de/deadlocker8/budgetmaster/ui/CategoryController.java
index da47709aeb71cde5216a8c52ca0cfc037c7e7580..413622a226caa0e82bfd862e6686638741cf1b62 100644
--- a/src/de/deadlocker8/budgetmaster/ui/CategoryController.java
+++ b/src/de/deadlocker8/budgetmaster/ui/CategoryController.java
@@ -24,7 +24,6 @@ import javafx.scene.layout.AnchorPane;
 import javafx.stage.Modality;
 import javafx.stage.Stage;
 import javafx.util.Callback;
-import logger.LogLevel;
 import logger.Logger;
 
 public class CategoryController implements Refreshable
@@ -64,7 +63,7 @@ public class CategoryController implements Refreshable
 			}
 		});
 		
-		Label labelPlaceholder = new Label("Keine Kategorien verf�gbar");
+		Label labelPlaceholder = new Label("Keine Kategorien verfügbar");
 		labelPlaceholder.setStyle("-fx-font-size: 16");
 		listView.setPlaceholder(labelPlaceholder);
 
@@ -130,7 +129,7 @@ public class CategoryController implements Refreshable
 		}
 		catch(IOException e)
 		{
-			Logger.log(LogLevel.ERROR, Logger.exceptionToString(e));
+			Logger.error(e);
 		}
 	}
 	
diff --git a/src/de/deadlocker8/budgetmaster/ui/ColorView.java b/src/de/deadlocker8/budgetmaster/ui/ColorView.java
index 846235ada90bf4bc478890d10c7e4d01c5d4a26e..9abaf1f94b172651e662746390f93c0a160417cc 100644
--- a/src/de/deadlocker8/budgetmaster/ui/ColorView.java
+++ b/src/de/deadlocker8/budgetmaster/ui/ColorView.java
@@ -18,7 +18,6 @@ import javafx.scene.paint.Color;
 import javafx.scene.shape.Rectangle;
 import javafx.stage.Modality;
 import javafx.stage.Stage;
-import logger.LogLevel;
 import logger.Logger;
 import tools.ConvertTo;
 
@@ -101,7 +100,7 @@ public class ColorView extends GridPane
 							}
 							catch(Exception e)
 							{
-								Logger.log(LogLevel.ERROR, Logger.exceptionToString(e));
+								Logger.error(e);
 							}
 						});
 						
diff --git a/src/de/deadlocker8/budgetmaster/ui/Controller.java b/src/de/deadlocker8/budgetmaster/ui/Controller.java
index f6aee7e40bfff86ca68c48eb1495177cec41c089..72dd89028d9fb763269ae8ada420ba7ab6cbf6be 100644
--- a/src/de/deadlocker8/budgetmaster/ui/Controller.java
+++ b/src/de/deadlocker8/budgetmaster/ui/Controller.java
@@ -2,6 +2,8 @@ package de.deadlocker8.budgetmaster.ui;
 
 import java.io.IOException;
 import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
 import java.util.Locale;
 import java.util.ResourceBundle;
 
@@ -9,6 +11,7 @@ import org.joda.time.DateTime;
 
 import de.deadlocker8.budgetmaster.logic.CategoryBudget;
 import de.deadlocker8.budgetmaster.logic.CategoryHandler;
+import de.deadlocker8.budgetmaster.logic.NormalPayment;
 import de.deadlocker8.budgetmaster.logic.Payment;
 import de.deadlocker8.budgetmaster.logic.ServerConnection;
 import de.deadlocker8.budgetmaster.logic.Settings;
@@ -31,7 +34,6 @@ import javafx.scene.image.Image;
 import javafx.scene.layout.AnchorPane;
 import javafx.stage.Stage;
 import javafx.util.Duration;
-import logger.LogLevel;
 import logger.Logger;
 import tools.AlertGenerator;
 
@@ -74,14 +76,6 @@ public class Controller implements Refreshable
 
 		settings = Utils.loadSettings();
 
-		if(settings == null)
-		{			
-			Platform.runLater(() -> {
-				AlertGenerator.showAlert(AlertType.WARNING, "Warnung", "", "Bitte gibt zuerst deine Serverdaten ein!", icon, stage, null, false);
-				tabPane.getSelectionModel().select(tabSettings);
-			});
-		}
-		
 		try
 		{
 			FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/de/deadlocker8/budgetmaster/ui/HomeTab.fxml"));
@@ -107,6 +101,8 @@ public class Controller implements Refreshable
 			chartController = fxmlLoader.getController();
 			chartController.init(this);
 			tabCharts.setContent(nodeTabChart);
+			//TODO
+			tabCharts.setDisable(true);
 
 			fxmlLoader = new FXMLLoader(getClass().getResource("/de/deadlocker8/budgetmaster/ui/SettingsTab.fxml"));
 			Parent nodeTabSettings = (Parent)fxmlLoader.load();
@@ -116,8 +112,10 @@ public class Controller implements Refreshable
 		}
 		catch(IOException e)
 		{
-			// ERRORHANDLING
-			Logger.log(LogLevel.ERROR, Logger.exceptionToString(e));
+			Logger.error(e);
+			Platform.runLater(() -> {
+				AlertGenerator.showAlert(AlertType.ERROR, "Fehler", "", "Beim Erstellen der Benutzeroberfläche ist ein Fehler aufgetreten", icon, stage, null, false);
+			});			
 		}
 
 		FontIcon iconPrevious = new FontIcon(FontIconType.CHEVRON_LEFT);
@@ -134,7 +132,17 @@ public class Controller implements Refreshable
 		buttonLeft.setStyle("-fx-background-color: transparent;");
 		buttonRight.setStyle("-fx-background-color: transparent;");
 		
-		refresh();
+		if(settings == null)
+		{			
+			Platform.runLater(() -> {
+				AlertGenerator.showAlert(AlertType.WARNING, "Warnung", "", "Bitte gibt zuerst deine Serverdaten ein!", icon, stage, null, false);
+				tabPane.getSelectionModel().select(tabSettings);
+			});
+		}
+		else
+		{
+			refresh();
+		}
 	}
 
 	public Stage getStage()
@@ -213,7 +221,7 @@ public class Controller implements Refreshable
 				Alert alert = new Alert(AlertType.ERROR);
 				alert.setTitle("Fehler");
 				alert.setHeaderText("");
-				alert.setContentText("Beim Herstellen der Verbindung zum Server ist ein Fehler aufgetreten. Bitte �berpr�fe deine Einstellungen und ob der Server l�uft.");
+				alert.setContentText("Beim Herstellen der Verbindung zum Server ist ein Fehler aufgetreten. Bitte überprüfe deine Einstellungen und ob der Server läuft.");
 				Stage dialogStage = (Stage)alert.getDialogPane().getScene().getWindow();
 				dialogStage.getIcons().add(icon);
 				dialogStage.initOwner(stage);
@@ -252,23 +260,42 @@ public class Controller implements Refreshable
 	{
 		AlertGenerator.showAboutAlert(bundle.getString("app.name"), bundle.getString("version.name"), bundle.getString("version.code"), bundle.getString("version.date"), bundle.getString("author"), icon, stage, null, false);
 	}
-
+	
 	@Override
 	public void refresh()
 	{
 		try
 		{
-			ServerConnection connection = new ServerConnection(settings);
-			categoryBudgets = connection.getCategoryBudgets(currentDate.getYear(), currentDate.getMonthOfYear());
-			payments = connection.getPayments(currentDate.getYear(), currentDate.getMonthOfYear());
+			ServerConnection connection = new ServerConnection(settings);			
+			
+			payments = new ArrayList<>();
+			payments.addAll(connection.getPayments(currentDate.getYear(), currentDate.getMonthOfYear()));
+			payments.addAll(connection.getRepeatingPayments(currentDate.getYear(), currentDate.getMonthOfYear()));			
+			Collections.sort(payments, new Comparator<Payment>() {
+		        @Override
+		        public int compare(Payment payment1, Payment payment2)
+		        {
+		            return  payment2.getDate().compareTo(payment1.getDate());
+		        }
+		    });		
+			if(settings.isRestActivated())
+			{
+				int rest = connection.getRestForAllPreviousMonths(currentDate.getYear(), currentDate.getMonthOfYear());
+				//categoryID 2 = Rest
+				payments.add(new NormalPayment(-1, rest, currentDate.withDayOfMonth(1).toString("yyyy-MM-dd"), 2, "Übertrag"));				
+			}
+			
 			categoryHandler = new CategoryHandler(connection.getCategories());
+			
+			categoryBudgets = connection.getCategoryBudgets(currentDate.getYear(), currentDate.getMonthOfYear());		
 		}
 		catch(Exception e)
 		{
+			Logger.error(e);
 			categoryHandler = new CategoryHandler(null);			
 			showConnectionErrorAlert();
 		}
 
-		refreshAllTabs();
+		refreshAllTabs();		
 	}
 }
\ No newline at end of file
diff --git a/src/de/deadlocker8/budgetmaster/ui/HomeController.java b/src/de/deadlocker8/budgetmaster/ui/HomeController.java
index 46a5376b61724c6f3474cf71756911441ee43ac4..9ed68f956751faeea513ced57fdf8c939ba93cba 100644
--- a/src/de/deadlocker8/budgetmaster/ui/HomeController.java
+++ b/src/de/deadlocker8/budgetmaster/ui/HomeController.java
@@ -2,7 +2,11 @@ package de.deadlocker8.budgetmaster.ui;
 
 import java.util.ArrayList;
 
+import org.joda.time.DateTime;
+
+import de.deadlocker8.budgetmaster.logic.Budget;
 import de.deadlocker8.budgetmaster.logic.CategoryBudget;
+import de.deadlocker8.budgetmaster.logic.Helpers;
 import de.deadlocker8.budgetmaster.ui.cells.CategoryBudgetCell;
 import javafx.application.Platform;
 import javafx.beans.value.ChangeListener;
@@ -29,12 +33,13 @@ public class HomeController implements Refreshable
 	{
 		this.controller = controller;
 
+		HomeController thisController = this;
 		listView.setCellFactory(new Callback<ListView<CategoryBudget>, ListCell<CategoryBudget>>()
 		{
 			@Override
 			public ListCell<CategoryBudget> call(ListView<CategoryBudget> param)
 			{
-				return new CategoryBudgetCell();
+				return new CategoryBudgetCell(thisController);
 			}
 		});
 
@@ -54,11 +59,7 @@ public class HomeController implements Refreshable
 		});
 		anchorPaneMain.setStyle("-fx-background-color: #F4F4F4;");
 		
-		Label labelPlaceholder = new Label("Keine Daten verf�gbar");
-		labelPlaceholder.setStyle("-fx-font-size: 16");
-		listView.setPlaceholder(labelPlaceholder);
-		
-		refreshListView();
+		refresh();
 	}
 	
 	private void refreshListView()
@@ -71,10 +72,46 @@ public class HomeController implements Refreshable
 			listView.getItems().setAll(categoryBudgets);
 		}		
 	}
+	
+	private void refreshCounter()
+	{
+		if(controller.getPayments() != null)
+		{
+			Budget budget = new Budget(controller.getPayments());	
+			double remaining = budget.getIncomeSum() + budget.getPaymentSum();
+			labelBudget.setText(String.valueOf(Helpers.NUMBER_FORMAT.format(remaining).replace(".", ",")) + " " + controller.getSettings().getCurrency());
+			labelStartBudget.setText("von " + String.valueOf(Helpers.NUMBER_FORMAT.format(budget.getIncomeSum()).replace(".", ",")) + " " + controller.getSettings().getCurrency() + " verbleibend");
+			
+			double factor = remaining / budget.getIncomeSum();
+			if(factor < 0)
+			{
+				factor = 0;
+			}
+			progressBar.setProgress(factor);
+		}
+	}
+	
+	public Controller getController()
+	{
+		return controller;
+	}
 
 	@Override
 	public void refresh()
 	{
-		refreshListView();		
+		refreshListView();	
+		refreshCounter();
+		
+		Label labelPlaceholder;
+		if(controller.getCurrentDate().isAfter(DateTime.now()))
+		{
+			labelPlaceholder = new Label("Datum liegt in der Zukunft");			
+		}
+		else
+		{
+			labelPlaceholder = new Label("Keine Daten verfügbar");			
+		}
+		labelPlaceholder.setStyle("-fx-font-size: 16");
+		listView.setPlaceholder(labelPlaceholder);
 	}
 }
\ No newline at end of file
diff --git a/src/de/deadlocker8/budgetmaster/ui/HomeTab.fxml b/src/de/deadlocker8/budgetmaster/ui/HomeTab.fxml
index a94b2d9e2c45187b1919e5e712b11287fabe42fe..0144989045ba447bb06c251528de84497b54b7b2 100644
--- a/src/de/deadlocker8/budgetmaster/ui/HomeTab.fxml
+++ b/src/de/deadlocker8/budgetmaster/ui/HomeTab.fxml
@@ -12,21 +12,29 @@
    <children>
       <VBox alignment="TOP_CENTER" layoutY="24.0" prefHeight="562.0" prefWidth="772.0" spacing="15.0" AnchorPane.bottomAnchor="14.0" AnchorPane.leftAnchor="14.0" AnchorPane.rightAnchor="14.0" AnchorPane.topAnchor="14.0">
          <children>
-            <Label fx:id="labelBudget" text="372,56 €">
+            <Label fx:id="labelBudget" text="0,00 €">
                <font>
                   <Font name="System Bold" size="55.0" />
                </font>
             </Label>
-            <Label fx:id="labelStartBudget" text="von 560,00 € verbleibend">
+            <Label fx:id="labelStartBudget" text="von 0,00 € verbleibend">
                <font>
                   <Font name="System Bold" size="18.0" />
                </font>
             </Label>
             <ProgressBar fx:id="progressBar" prefHeight="18.0" prefWidth="380.0" progress="0.68" />
-            <ListView fx:id="listView" prefHeight="200.0" prefWidth="200.0" VBox.vgrow="ALWAYS">
+            <Label text="Verbrauch nach Kategorien">
+               <font>
+                  <Font name="System Bold" size="16.0" />
+               </font>
                <VBox.margin>
                   <Insets top="25.0" />
                </VBox.margin>
+            </Label>
+            <ListView fx:id="listView" prefHeight="200.0" prefWidth="200.0" VBox.vgrow="ALWAYS">
+               <VBox.margin>
+                  <Insets />
+               </VBox.margin>
             </ListView>
          </children>
       </VBox>
diff --git a/src/de/deadlocker8/budgetmaster/ui/NewCategoryController.java b/src/de/deadlocker8/budgetmaster/ui/NewCategoryController.java
index 8b1c3db60b77557f5fcb408338707bef94cba856..5f34e6cd4186045210fec19f36c31e13bd5d799c 100644
--- a/src/de/deadlocker8/budgetmaster/ui/NewCategoryController.java
+++ b/src/de/deadlocker8/budgetmaster/ui/NewCategoryController.java
@@ -131,7 +131,7 @@ public class NewCategoryController
 		String name = textFieldName.getText();
 		if(name == null || name.equals(""))
 		{
-			AlertGenerator.showAlert(AlertType.WARNING, "Warnung", "", "Das Feld f�r den Namen darf nicht leer sein.", controller.getIcon(), controller.getStage(), null, false);
+			AlertGenerator.showAlert(AlertType.WARNING, "Warnung", "", "Das Feld für den Namen darf nicht leer sein.", controller.getIcon(), controller.getStage(), null, false);
 			return;
 		}
 		
diff --git a/src/de/deadlocker8/budgetmaster/ui/NewPaymentController.java b/src/de/deadlocker8/budgetmaster/ui/NewPaymentController.java
index 81bf6a9762a662b7c30736df67831bdaeecaa6f9..86b7357c0e8e11b66a04c1bb902d2e5abaae5a4f 100644
--- a/src/de/deadlocker8/budgetmaster/ui/NewPaymentController.java
+++ b/src/de/deadlocker8/budgetmaster/ui/NewPaymentController.java
@@ -1,11 +1,14 @@
 package de.deadlocker8.budgetmaster.ui;
 
 import java.time.LocalDate;
-import java.time.format.DateTimeFormatter;
 import java.util.ArrayList;
 
 import de.deadlocker8.budgetmaster.logic.Category;
+import de.deadlocker8.budgetmaster.logic.Helpers;
+import de.deadlocker8.budgetmaster.logic.NormalPayment;
 import de.deadlocker8.budgetmaster.logic.Payment;
+import de.deadlocker8.budgetmaster.logic.RepeatingPayment;
+import de.deadlocker8.budgetmaster.logic.RepeatingPaymentEntry;
 import de.deadlocker8.budgetmaster.logic.ServerConnection;
 import de.deadlocker8.budgetmaster.ui.cells.ButtonCategoryCell;
 import de.deadlocker8.budgetmaster.ui.cells.RepeatingDayCell;
@@ -27,6 +30,7 @@ import javafx.scene.control.TextField;
 import javafx.scene.control.ToggleGroup;
 import javafx.scene.paint.Color;
 import javafx.stage.Stage;
+import logger.Logger;
 import tools.AlertGenerator;
 import tools.ConvertTo;
 
@@ -52,6 +56,7 @@ public class NewPaymentController
 	private boolean isPayment;
 	private boolean edit;
 	private Payment payment;
+	private ButtonCategoryCell buttonCategoryCell;
 
 	public void init(Stage stage, Controller controller, PaymentController paymentController, boolean isPayment, boolean edit, Payment payment)
 	{
@@ -76,6 +81,13 @@ public class NewPaymentController
 
 		SpinnerValueFactory<Integer> valueFactory = new SpinnerValueFactory.IntegerSpinnerValueFactory(0, 1000, 0);
 		spinnerRepeatingPeriod.setValueFactory(valueFactory);
+		spinnerRepeatingPeriod.setEditable(true);
+		spinnerRepeatingPeriod.focusedProperty().addListener((observable, oldValue, newValue) -> {
+			if(!newValue)
+			{
+				spinnerRepeatingPeriod.increment(0); // won't change value, but will commit editor
+			}
+		});
 
 		comboBoxRepeatingDay.setCellFactory((view) -> {
 			return new RepeatingDayCell();
@@ -86,15 +98,16 @@ public class NewPaymentController
 			days.add(i);
 		}
 		comboBoxRepeatingDay.getItems().addAll(days);
-
+		
 		comboBoxCategory.setCellFactory((view) -> {
 			return new SmallCategoryCell();
 		});
-		comboBoxCategory.setButtonCell(new ButtonCategoryCell(Color.WHITE));
+		buttonCategoryCell = new ButtonCategoryCell(Color.WHITE);
+		comboBoxCategory.setButtonCell(buttonCategoryCell);
 		comboBoxCategory.setStyle("-fx-border-color: #000000; -fx-border-width: 2; -fx-border-radius: 5; -fx-background-radius: 5;");
-		comboBoxCategory.valueProperty().addListener((listener, oldValue, newValue) -> {
+		comboBoxCategory.valueProperty().addListener((listener, oldValue, newValue) -> {		
 			comboBoxCategory.setStyle("-fx-background-color: " + ConvertTo.toRGBHex(newValue.getColor()) + "; -fx-border-color: #000000; -fx-border-width: 2; -fx-border-radius: 5; -fx-background-radius: 5;");
-			comboBoxCategory.setButtonCell(new ButtonCategoryCell(newValue.getColor()));
+			buttonCategoryCell.setColor(newValue.getColor());
 		});
 
 		checkBoxRepeat.selectedProperty().addListener((listener, oldValue, newValue) -> {
@@ -142,7 +155,42 @@ public class NewPaymentController
 
 		if(edit)
 		{
-			// TODO prefill
+			//prefill
+			textFieldName.setText(payment.getName());
+			textFieldAmount.setText(Helpers.NUMBER_FORMAT.format(Math.abs(payment.getAmount()/100.0)).replace(".", ","));		
+			comboBoxCategory.setValue(controller.getCategoryHandler().getCategory(payment.getCategoryID()));
+			datePicker.setValue(LocalDate.parse(payment.getDate()));
+			
+			if(payment instanceof RepeatingPaymentEntry)
+			{
+				RepeatingPaymentEntry currentPayment = (RepeatingPaymentEntry)payment;
+				//repeates every x days
+				if(currentPayment.getRepeatInterval() != 0)
+				{					
+					checkBoxRepeat.setSelected(true);
+					radioButtonPeriod.setSelected(true);
+					toggleRepeatingArea(true);
+					spinnerRepeatingPeriod.setValueFactory(new SpinnerValueFactory.IntegerSpinnerValueFactory(0, 1000, currentPayment.getRepeatInterval()));
+				}
+				//repeat every month on day x
+				else
+				{
+					checkBoxRepeat.setSelected(true);
+					radioButtonDay.setSelected(true);
+					toggleRepeatingArea(true);
+					comboBoxRepeatingDay.getSelectionModel().select(currentPayment.getRepeatMonthDay());
+				}
+				if(currentPayment.getRepeatEndDate() != null)
+				{
+					datePickerEnddate.setValue(LocalDate.parse(currentPayment.getRepeatEndDate()));
+				}
+			}	
+			else
+			{				
+				checkBoxRepeat.setSelected(false);
+				radioButtonPeriod.setSelected(true);
+				toggleRepeatingArea(false);
+			}
 		}
 		else
 		{
@@ -158,21 +206,21 @@ public class NewPaymentController
 		String name = textFieldName.getText();
 		if(name == null || name.equals(""))
 		{
-			AlertGenerator.showAlert(AlertType.WARNING, "Warnung", "", "Das Feld f�r den Namen darf nicht leer sein.", controller.getIcon(), controller.getStage(), null, false);
+			AlertGenerator.showAlert(AlertType.WARNING, "Warnung", "", "Das Feld für den Namen darf nicht leer sein.", controller.getIcon(), controller.getStage(), null, false);
 			return;
 		}
 
 		String amountText = textFieldAmount.getText();
 		if(!amountText.matches("^-?\\d+(,\\d+)*(\\.\\d+(e\\d+)?)?$"))
 		{
-			AlertGenerator.showAlert(AlertType.WARNING, "Warnung", "", "Gib eine g�ltige Zahl f�r den Betrag ein.", controller.getIcon(), controller.getStage(), null, false);
+			AlertGenerator.showAlert(AlertType.WARNING, "Warnung", "", "Gib eine gültige Zahl für den Betrag ein.", controller.getIcon(), controller.getStage(), null, false);
 			return;
 		}
 
 		LocalDate date = datePicker.getValue();
 		if(date == null)
 		{
-			AlertGenerator.showAlert(AlertType.WARNING, "Warnung", "", "Bitte w�hle ein Datum aus.", controller.getIcon(), controller.getStage(), null, false);
+			AlertGenerator.showAlert(AlertType.WARNING, "Warnung", "", "Bitte wähle ein Datum aus.", controller.getIcon(), controller.getStage(), null, false);
 			return;
 		}
 
@@ -196,39 +244,94 @@ public class NewPaymentController
 				repeatingDay = comboBoxRepeatingDay.getValue();
 			}
 
+			if(repeatingInterval == 0 && repeatingDay == 0)
+			{
+				AlertGenerator.showAlert(AlertType.WARNING, "Warnung", "", "Wenn Wiederholung aktiviert ist dürfen nicht beide Eingabefelder 0 sein.\n(Zur Deaktivierung der Wiederholung einfach die Checkbox enthaken)", controller.getIcon(), controller.getStage(), null, false);
+				return;
+			}
+
 			if(datePickerEnddate.getValue() != null && datePickerEnddate.getValue().isBefore(date))
 			{
 				AlertGenerator.showAlert(AlertType.WARNING, "Warnung", "", "Das Enddatum darf zeitlich nicht vor dem Datum der Zahlung liegen.", controller.getIcon(), controller.getStage(), null, false);
 				return;
 			}
-		}
 
-		if(edit)
-		{
-			Payment newPayment = new Payment(payment.getID(), amount, getDateString(date), comboBoxCategory.getValue().getID(), name, repeatingInterval, getDateString(datePickerEnddate.getValue()), repeatingDay);
-
-			try
-			{
-				ServerConnection connection = new ServerConnection(controller.getSettings());
-				connection.updatePayment(newPayment, payment);
+			if(edit)
+			{				
+				try
+				{		
+					RepeatingPayment newPayment = new RepeatingPayment(-1, amount, Helpers.getDateString(date), comboBoxCategory.getValue().getID(), name, repeatingInterval, Helpers.getDateString(datePickerEnddate.getValue()), repeatingDay);
+							
+					ServerConnection connection = new ServerConnection(controller.getSettings());
+					if(payment instanceof NormalPayment)
+					{
+						connection.deleteNormalPayment((NormalPayment)payment);
+					}
+					else
+					{	
+						connection.deleteRepeatingPayment((RepeatingPaymentEntry)payment);						
+					}	
+					connection.addRepeatingPayment(newPayment);
+				}
+				catch(Exception e)
+				{
+					Logger.error(e);
+					controller.showConnectionErrorAlert();
+				}
 			}
-			catch(Exception e)
+			else
 			{
-				controller.showConnectionErrorAlert();
+				RepeatingPayment newPayment = new RepeatingPayment(-1, amount, Helpers.getDateString(date), comboBoxCategory.getValue().getID(), name, repeatingInterval,Helpers.getDateString(datePickerEnddate.getValue()), repeatingDay);
+				try
+				{
+					ServerConnection connection = new ServerConnection(controller.getSettings());
+					connection.addRepeatingPayment(newPayment);
+				}
+				catch(Exception e)
+				{
+					Logger.error(e);
+					controller.showConnectionErrorAlert();
+				}
 			}
 		}
 		else
 		{
-			Payment newPayment = new Payment(-1, amount, getDateString(date), comboBoxCategory.getValue().getID(), name, repeatingInterval, getDateString(datePickerEnddate.getValue()), repeatingDay);
-			try
+			if(edit)
 			{
-				ServerConnection connection = new ServerConnection(controller.getSettings());
-				connection.addPayment(newPayment);
+				NormalPayment newPayment = new NormalPayment(payment.getID(), amount, Helpers.getDateString(date), comboBoxCategory.getValue().getID(), name);
+				try
+				{
+					ServerConnection connection = new ServerConnection(controller.getSettings());
+					if(payment instanceof RepeatingPaymentEntry)
+					{
+						//if old one was repeating it should be deleted
+						connection.deleteRepeatingPayment((RepeatingPaymentEntry)payment);
+						connection.addNormalPayment(newPayment);
+					}
+					else
+					{
+						connection.updateNormalPayment(newPayment);
+					}					
+				}
+				catch(Exception e)
+				{
+					Logger.error(e);
+					controller.showConnectionErrorAlert();
+				}
 			}
-			catch(Exception e)
+			else
 			{
-				e.printStackTrace();
-				controller.showConnectionErrorAlert();
+				NormalPayment newPayment = new NormalPayment(-1, amount, Helpers.getDateString(date), comboBoxCategory.getValue().getID(), name);
+				try
+				{
+					ServerConnection connection = new ServerConnection(controller.getSettings());
+					connection.addNormalPayment(newPayment);
+				}
+				catch(Exception e)
+				{
+					Logger.error(e);
+					controller.showConnectionErrorAlert();
+				}
 			}
 		}
 
@@ -278,13 +381,5 @@ public class NewPaymentController
 		labelText3.setDisable(selected);
 	}
 
-	private String getDateString(LocalDate date)
-	{
-		if(date == null)
-		{
-			return "";
-		}
-		DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
-		return date.format(formatter);
-	}
+	
 }
\ No newline at end of file
diff --git a/src/de/deadlocker8/budgetmaster/ui/PaymentController.java b/src/de/deadlocker8/budgetmaster/ui/PaymentController.java
index 38b42740a34cad4dd1eef84679a34f1dd9a301a6..bb8e83b04bffff61ed232dd6dc0fb2b67a26d6c3 100644
--- a/src/de/deadlocker8/budgetmaster/ui/PaymentController.java
+++ b/src/de/deadlocker8/budgetmaster/ui/PaymentController.java
@@ -1,10 +1,16 @@
 package de.deadlocker8.budgetmaster.ui;
 
 import java.io.IOException;
-import java.text.DecimalFormat;
 import java.util.ArrayList;
 
+import org.joda.time.DateTime;
+
+import de.deadlocker8.budgetmaster.logic.Budget;
+import de.deadlocker8.budgetmaster.logic.Helpers;
+import de.deadlocker8.budgetmaster.logic.NormalPayment;
 import de.deadlocker8.budgetmaster.logic.Payment;
+import de.deadlocker8.budgetmaster.logic.RepeatingPayment;
+import de.deadlocker8.budgetmaster.logic.RepeatingPaymentEntry;
 import de.deadlocker8.budgetmaster.logic.ServerConnection;
 import de.deadlocker8.budgetmaster.ui.cells.PaymentCell;
 import fontAwesome.FontIcon;
@@ -26,7 +32,6 @@ import javafx.scene.layout.AnchorPane;
 import javafx.stage.Modality;
 import javafx.stage.Stage;
 import javafx.util.Callback;
-import logger.LogLevel;
 import logger.Logger;
 
 public class PaymentController implements Refreshable
@@ -41,7 +46,6 @@ public class PaymentController implements Refreshable
 	@FXML private Button buttonNewPayment;
 
 	private Controller controller;
-	private final DecimalFormat numberFormat = new DecimalFormat("0.00");
 
 	public void init(Controller controller)
 	{
@@ -60,9 +64,13 @@ public class PaymentController implements Refreshable
 					public void handle(MouseEvent event)
 					{
 						if(event.getClickCount() == 2)
-						{							
-							PaymentCell c = (PaymentCell)event.getSource();						
-							payment(!c.getItem().isIncome(), true, c.getItem());								
+						{
+							PaymentCell c = (PaymentCell)event.getSource();
+							// don't allow editing of payment "rest"
+							if(c.getItem().getCategoryID() != 2)
+							{
+								payment(!c.getItem().isIncome(), true, c.getItem());
+							}
 						}
 					}
 				});
@@ -105,7 +113,7 @@ public class PaymentController implements Refreshable
 
 		refresh();
 	}
-	
+
 	public void newIncome()
 	{
 		payment(false, false, null);
@@ -124,11 +132,11 @@ public class PaymentController implements Refreshable
 			Parent root = (Parent)fxmlLoader.load();
 			Stage newStage = new Stage();
 			newStage.initOwner(controller.getStage());
-			newStage.initModality(Modality.APPLICATION_MODAL);			
-			String titlePart;		
-			
-			titlePart = isPayment ? "Ausgabe" : "Einnahme";			
-			
+			newStage.initModality(Modality.APPLICATION_MODAL);
+			String titlePart;
+
+			titlePart = isPayment ? "Ausgabe" : "Einnahme";
+
 			if(edit)
 			{
 				newStage.setTitle(titlePart + " bearbeiten");
@@ -137,7 +145,7 @@ public class PaymentController implements Refreshable
 			{
 				newStage.setTitle("Neue " + titlePart);
 			}
-			
+
 			newStage.setScene(new Scene(root));
 			newStage.getIcons().add(controller.getIcon());
 			newStage.setResizable(false);
@@ -147,49 +155,73 @@ public class PaymentController implements Refreshable
 		}
 		catch(IOException e)
 		{
-			Logger.log(LogLevel.ERROR, Logger.exceptionToString(e));
+			Logger.error(e);
 		}
 	}
-	
+
 	private void refreshListView()
-	{		
+	{
 		listView.getItems().clear();
-		
+
 		ArrayList<Payment> payments = controller.getPayments();
 		if(payments != null)
-		{				
+		{
 			listView.getItems().setAll(payments);
-		}		
+		}
 	}
-	
+
 	private void refreshCounter()
 	{
-		ArrayList<Payment> payments = new ArrayList<>(listView.getItems());
-		double counterIncome = 0;
-		double counterPayment = 0;
-		for(Payment currentPayment : payments)
+		Budget budget = new Budget(listView.getItems());
+		String currency = "€";
+		if(controller.getSettings() != null)
 		{
-			double amount = currentPayment.getAmount();
-			if(amount > 0)
-			{
-				counterIncome += amount;
-			}
-			else
-			{
-				counterPayment += amount;
-			}
+			currency = controller.getSettings().getCurrency();
+		}
+		labelIncomes.setText(String.valueOf(Helpers.NUMBER_FORMAT.format(budget.getIncomeSum()).replace(".", ",")) + " " + currency);
+		labelPayments.setText(String.valueOf(Helpers.NUMBER_FORMAT.format(budget.getPaymentSum()).replace(".", ",")) + " " + currency);
+	}
+
+	public void deleteNormalPayment(NormalPayment payment)
+	{
+		try
+		{
+			ServerConnection connection = new ServerConnection(controller.getSettings());
+			connection.deleteNormalPayment(payment);
+			controller.refresh();
+		}
+		catch(Exception e)
+		{
+			e.printStackTrace();
+			controller.showConnectionErrorAlert();
 		}
-		
-		labelIncomes.setText(String.valueOf(numberFormat.format(counterIncome/100.0).replace(".", ",")) + " �");
-		labelPayments.setText(String.valueOf(numberFormat.format(counterPayment/100.0).replace(".", ",")) + " �");
 	}
-	
-	public void deletePayment(Payment payment)
-	{		
+
+	public void deleteRepeatingPayment(RepeatingPaymentEntry payment)
+	{
 		try
 		{
 			ServerConnection connection = new ServerConnection(controller.getSettings());
-			connection.deletePayment(payment);
+			connection.deleteRepeatingPayment(payment);
+			controller.refresh();
+		}
+		catch(Exception e)
+		{
+			e.printStackTrace();
+			controller.showConnectionErrorAlert();
+		}
+	}
+
+	public void deleteFuturePayments(RepeatingPaymentEntry payment)
+	{
+		try
+		{
+			ServerConnection connection = new ServerConnection(controller.getSettings());
+			RepeatingPayment oldRepeatingPayment = connection.getRepeatingPayment(payment.getRepeatingPaymentID());
+			RepeatingPayment newRepeatingPayment = new RepeatingPayment(payment.getID(), payment.getAmount(), oldRepeatingPayment.getDate(), payment.getCategoryID(), payment.getName(), payment.getRepeatInterval(), payment.getDate(), payment.getRepeatMonthDay());
+			connection.deleteRepeatingPayment(payment);
+			connection.addRepeatingPayment(newRepeatingPayment);
+
 			controller.refresh();
 		}
 		catch(Exception e)
@@ -207,7 +239,19 @@ public class PaymentController implements Refreshable
 	@Override
 	public void refresh()
 	{
-		refreshListView();	
+		refreshListView();
 		refreshCounter();
+
+		Label labelPlaceholder;
+		if(controller.getCurrentDate().isAfter(DateTime.now()))
+		{
+			labelPlaceholder = new Label("Datum liegt in der Zukunft");
+		}
+		else
+		{
+			labelPlaceholder = new Label("Keine Daten verfügbar");
+		}
+		labelPlaceholder.setStyle("-fx-font-size: 16");
+		listView.setPlaceholder(labelPlaceholder);
 	}
 }
\ No newline at end of file
diff --git a/src/de/deadlocker8/budgetmaster/ui/SettingsController.java b/src/de/deadlocker8/budgetmaster/ui/SettingsController.java
index bcd143e91cd5d059f44f831318821b1a9d0444dd..d82df810dbb1aaf7349dd76e6e6c2cce5bd943ec 100644
--- a/src/de/deadlocker8/budgetmaster/ui/SettingsController.java
+++ b/src/de/deadlocker8/budgetmaster/ui/SettingsController.java
@@ -1,13 +1,18 @@
 package de.deadlocker8.budgetmaster.ui;
 
+import java.io.IOException;
+
 import de.deadlocker8.budgetmaster.logic.Settings;
 import de.deadlocker8.budgetmaster.logic.Utils;
 import javafx.fxml.FXML;
 import javafx.scene.control.Alert.AlertType;
 import javafx.scene.control.Button;
 import javafx.scene.control.Label;
+import javafx.scene.control.RadioButton;
 import javafx.scene.control.TextField;
+import javafx.scene.control.ToggleGroup;
 import javafx.scene.layout.AnchorPane;
+import logger.Logger;
 import tools.AlertGenerator;
 
 public class SettingsController
@@ -17,7 +22,11 @@ public class SettingsController
 	@FXML private Label labelURL;
 	@FXML private TextField textFieldSecret;
 	@FXML private Label labelSecret;
+	@FXML private TextField textFieldCurrency;
+	@FXML private Label labelCurrency;
 	@FXML private Button buttonSave;
+	@FXML private RadioButton radioButtonRestActivated;
+	@FXML private RadioButton radioButtonRestDeactivated;
 
 	private Controller controller;
 
@@ -28,46 +37,83 @@ public class SettingsController
 		{
 			textFieldURL.setText(controller.getSettings().getUrl());
 			textFieldSecret.setText(controller.getSettings().getSecret());
+			textFieldCurrency.setText(controller.getSettings().getCurrency());
+			if(controller.getSettings().isRestActivated())
+			{
+				radioButtonRestActivated.setSelected(true);
+			}
+			else
+			{
+				radioButtonRestDeactivated.setSelected(true);
+			}
 		}
 		
 		anchorPaneMain.setStyle("-fx-background-color: #F4F4F4;");
 		labelSecret.setStyle("-fx-text-fill: " + controller.getBundle().getString("color.text"));
 		labelURL.setStyle("-fx-text-fill: " + controller.getBundle().getString("color.text"));
+		labelCurrency.setStyle("-fx-text-fill: " + controller.getBundle().getString("color.text"));
 		buttonSave.setStyle("-fx-background-color: #2E79B9; -fx-text-fill: white; -fx-font-weight: bold; -fx-font-size: 16;");	
 		textFieldURL.setPromptText("z.B. https://yourdomain.de");
+		textFieldCurrency.setPromptText("z.B. €, CHF, $");
+		
+		ToggleGroup toggleGroup = new ToggleGroup();
+		radioButtonRestActivated.setToggleGroup(toggleGroup);
+		radioButtonRestDeactivated.setToggleGroup(toggleGroup);
 	}
 	
 	public void save()
 	{
 		String url = textFieldURL.getText().trim();
 		String secret = textFieldSecret.getText().trim();
+		String currency = textFieldCurrency.getText().trim();
 		if(url != null && !url.equals(""))
 		{
 			if(secret != null && !secret.equals(""))
 			{
-				if(controller.getSettings() != null)
+				if(currency != null && !currency.equals(""))
 				{
-					controller.getSettings().setUrl(url);
-					controller.getSettings().setSecret(secret);				
+					if(controller.getSettings() != null)
+					{
+						controller.getSettings().setUrl(url);
+						controller.getSettings().setSecret(secret);	
+						controller.getSettings().setCurrency(currency);
+						controller.getSettings().setRestActivated(radioButtonRestActivated.isSelected());
+					}
+					else
+					{
+						Settings settings = new Settings();
+						settings.setUrl(url);
+						settings.setSecret(secret);
+						settings.setCurrency(currency);
+						settings.setRestActivated(radioButtonRestActivated.isSelected());
+						controller.setSettings(settings);
+					}
+					
+					try
+					{
+						Utils.saveSettings(controller.getSettings());
+					}
+					catch(IOException e)
+					{
+						Logger.error(e);
+						AlertGenerator.showAlert(AlertType.ERROR, "Fehler", "", "Beim Speichern der Einstellungen ist ein Fehler aufgetreten", controller.getIcon(), controller.getStage(), null, false);
+					}	
+					controller.refresh();
+					controller.showNotification("Erfolgreich gespeichert");
 				}
 				else
 				{
-					Settings settings = new Settings();
-					settings.setUrl(url);
-					settings.setSecret(secret);
-					controller.setSettings(settings);
+					AlertGenerator.showAlert(AlertType.WARNING, "Warnung", "", "Bitte gib deine gewünschte Währung ein!", controller.getIcon(), controller.getStage(), null, false);
 				}
-				Utils.saveSettings(controller.getSettings());	
-				controller.showNotification("Erfolgreich gespeichert");
 			}
 			else
 			{
-				AlertGenerator.showAlert(AlertType.WARNING, "Warnung", "", "Das Server Passwortfel darf nicht leer sein!", controller.getIcon(), controller.getStage(), null, false);
+				AlertGenerator.showAlert(AlertType.WARNING, "Warnung", "", "Das Server Passwortfeld darf nicht leer sein!", controller.getIcon(), controller.getStage(), null, false);
 			}
 		}
 		else
 		{
-			AlertGenerator.showAlert(AlertType.WARNING, "Warnung", "", "Das Feld f�r die Server URL darf nicht leer sein!", controller.getIcon(), controller.getStage(), null, false);
+			AlertGenerator.showAlert(AlertType.WARNING, "Warnung", "", "Das Feld für die Server URL darf nicht leer sein!", controller.getIcon(), controller.getStage(), null, false);
 		}
 	}
 }
\ No newline at end of file
diff --git a/src/de/deadlocker8/budgetmaster/ui/SettingsTab.fxml b/src/de/deadlocker8/budgetmaster/ui/SettingsTab.fxml
index baaca0685a533add8fa9041073df83ffddfa51d9..0fc94536e52887e64a3a83aaab44298d89253d10 100644
--- a/src/de/deadlocker8/budgetmaster/ui/SettingsTab.fxml
+++ b/src/de/deadlocker8/budgetmaster/ui/SettingsTab.fxml
@@ -3,6 +3,7 @@
 <?import javafx.geometry.Insets?>
 <?import javafx.scene.control.Button?>
 <?import javafx.scene.control.Label?>
+<?import javafx.scene.control.RadioButton?>
 <?import javafx.scene.control.TextField?>
 <?import javafx.scene.layout.AnchorPane?>
 <?import javafx.scene.layout.HBox?>
@@ -30,6 +31,16 @@
                               <Font name="System Bold" size="16.0" />
                            </font>
                         </Label>
+                        <Label fx:id="labelCurrency" prefHeight="25.0" text="Währung:">
+                           <font>
+                              <Font name="System Bold" size="16.0" />
+                           </font>
+                        </Label>
+                        <Label fx:id="labelSecret11" prefHeight="25.0" text="Übertrag:">
+                           <font>
+                              <Font name="System Bold" size="16.0" />
+                           </font>
+                        </Label>
                      </children>
                      <HBox.margin>
                         <Insets right="25.0" />
@@ -39,6 +50,24 @@
                      <children>
                         <TextField fx:id="textFieldURL" />
                         <TextField fx:id="textFieldSecret" />
+                        <TextField fx:id="textFieldCurrency" />
+                        <HBox alignment="CENTER" prefHeight="100.0" prefWidth="200.0">
+                           <children>
+                              <RadioButton fx:id="radioButtonRestActivated" maxWidth="1.7976931348623157E308" mnemonicParsing="false" text="aktiviert">
+                                 <font>
+                                    <Font size="14.0" />
+                                 </font>
+                                 <HBox.margin>
+                                    <Insets right="30.0" />
+                                 </HBox.margin>
+                              </RadioButton>
+                              <RadioButton fx:id="radioButtonRestDeactivated" maxWidth="1.7976931348623157E308" mnemonicParsing="false" text="deaktiviert" HBox.hgrow="ALWAYS">
+                                 <font>
+                                    <Font size="14.0" />
+                                 </font>
+                              </RadioButton>
+                           </children>
+                        </HBox>
                      </children>
                   </VBox>
                </children>
diff --git a/src/de/deadlocker8/budgetmaster/ui/cells/ButtonCategoryCell.java b/src/de/deadlocker8/budgetmaster/ui/cells/ButtonCategoryCell.java
index 809def1312a2f73b7bd655bbe5d7a38153ed564c..233398f6aba6a04a8cb2b52a050ce440c49bfa4c 100644
--- a/src/de/deadlocker8/budgetmaster/ui/cells/ButtonCategoryCell.java
+++ b/src/de/deadlocker8/budgetmaster/ui/cells/ButtonCategoryCell.java
@@ -17,12 +17,17 @@ public class ButtonCategoryCell extends ListCell<Category>
 	{
 		super();
 		this.color = color;
-	}	
+	}
 	
+	public void setColor(Color color)
+	{
+		this.color = color;
+	}
+
 	@Override
 	protected void updateItem(Category item, boolean empty)
 	{
-		super.updateItem(item, empty);
+		super.updateItem(item, empty);		
 
 		if(!empty)
 		{		
@@ -31,21 +36,21 @@ public class ButtonCategoryCell extends ListCell<Category>
 			if(item.getID() == 1)
 			{
 				item.setName("Keine Kategorie");
-			}
-			
+			}			
+		
 			Label labelName = new Label(item.getName());
 			labelName.setStyle("-fx-font-weight: bold; -fx-font-size: 14; -fx-text-fill: " + ConvertTo.toRGBHex(ConvertTo.getAppropriateTextColor(color)));
-			labelName.setAlignment(Pos.CENTER);
-			labelName.getStyleClass().add("greylabel");
+			labelName.setAlignment(Pos.CENTER);			
 			hbox.getChildren().add(labelName);
 				
 			hbox.setPadding(new Insets(0));
 			setStyle("-fx-background: transparent;");
 			setGraphic(hbox);	
+			setText(null);
 			setAlignment(Pos.CENTER);
 		}
 		else
-		{
+		{		
 			setStyle("-fx-background: transparent");
 			setText(null);
 			setGraphic(null);
diff --git a/src/de/deadlocker8/budgetmaster/ui/cells/CategoryBudgetCell.java b/src/de/deadlocker8/budgetmaster/ui/cells/CategoryBudgetCell.java
index db56197583f9096bbb84a8715d23852a163e25e9..ff09b4a5e7224bc504fba1904b9d0a1a083afb83 100644
--- a/src/de/deadlocker8/budgetmaster/ui/cells/CategoryBudgetCell.java
+++ b/src/de/deadlocker8/budgetmaster/ui/cells/CategoryBudgetCell.java
@@ -1,8 +1,8 @@
 package de.deadlocker8.budgetmaster.ui.cells;
 
-import java.text.DecimalFormat;
-
 import de.deadlocker8.budgetmaster.logic.CategoryBudget;
+import de.deadlocker8.budgetmaster.logic.Helpers;
+import de.deadlocker8.budgetmaster.ui.HomeController;
 import javafx.geometry.Insets;
 import javafx.geometry.Pos;
 import javafx.scene.control.Label;
@@ -14,8 +14,14 @@ import tools.ConvertTo;
 
 public class CategoryBudgetCell extends ListCell<CategoryBudget>
 {
-	private final double HEIGHT = 40.0;
-	private final DecimalFormat format = new DecimalFormat("0.00");
+	private final double HEIGHT = 40.0;	
+	private HomeController homeController;
+	
+	public CategoryBudgetCell(HomeController homeController)
+	{
+		super();
+		this.homeController = homeController;
+	}		
 
 	@Override
 	protected void updateItem(CategoryBudget item, boolean empty)
@@ -53,7 +59,7 @@ public class CategoryBudgetCell extends ListCell<CategoryBudget>
 			hbox.getChildren().add(r);
 			HBox.setHgrow(r, Priority.ALWAYS);
 
-			Label labelBudget = new Label(String.valueOf(format.format(item.getBudget() / 100.0)).replace(".", ",") + " �");
+			Label labelBudget = new Label(String.valueOf(Helpers.NUMBER_FORMAT.format(item.getBudget() / 100.0)).replace(".", ",") + " " + homeController.getController().getSettings().getCurrency());
 			labelBudget.setPrefHeight(HEIGHT);
 			labelBudget.setStyle("-fx-font-weight: bold; -fx-font-size: 16; -fx-text-fill: #212121;");
 			labelBudget.setAlignment(Pos.CENTER);
diff --git a/src/de/deadlocker8/budgetmaster/ui/cells/CategoryCell.java b/src/de/deadlocker8/budgetmaster/ui/cells/CategoryCell.java
index 7baf412c392f3e6ca4b93ed19a671d21b1135564..c81345ed20c85813d0377eec1a6dd407cb1a8c64 100644
--- a/src/de/deadlocker8/budgetmaster/ui/cells/CategoryCell.java
+++ b/src/de/deadlocker8/budgetmaster/ui/cells/CategoryCell.java
@@ -82,9 +82,9 @@ public class CategoryCell extends ListCell<Category>
 			buttonDelete.setStyle("-fx-background-color: transparent");
 			buttonDelete.setOnAction((event)->{
 				 Alert alert = new Alert(Alert.AlertType.CONFIRMATION);
-                 alert.setTitle("Kategorie l�schen");
+                 alert.setTitle("Kategorie löschen");
                  alert.setHeaderText("");
-                 alert.setContentText("M�chtest du diese Kategorie wirklich unwiderruflich l�schen?");
+                 alert.setContentText("Möchtest du diese Kategorie wirklich unwiderruflich löschen?");
                  Stage dialogStage = (Stage) alert.getDialogPane().getScene().getWindow();
                  dialogStage.getIcons().add(categoryController.getController().getIcon());
                  dialogStage.centerOnScreen();
@@ -95,7 +95,7 @@ public class CategoryCell extends ListCell<Category>
                 	 categoryController.deleteCategory(item.getID());
                  }				
 			});
-			//don't allow category "�bertrag" to be deleted
+			//don't allow category "Übertrag" to be deleted
 			if(item.getID() != 2)
 			{
 				hbox.getChildren().add(buttonDelete);
diff --git a/src/de/deadlocker8/budgetmaster/ui/cells/PaymentCell.java b/src/de/deadlocker8/budgetmaster/ui/cells/PaymentCell.java
index 5f13c18a34def69d235397270044d21e0523e597..8a6b957911d7bf78d4bb359eb197b4e8c737f39b 100644
--- a/src/de/deadlocker8/budgetmaster/ui/cells/PaymentCell.java
+++ b/src/de/deadlocker8/budgetmaster/ui/cells/PaymentCell.java
@@ -1,14 +1,16 @@
 package de.deadlocker8.budgetmaster.ui.cells;
 
 import java.text.DateFormat;
-import java.text.DecimalFormat;
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
 import java.util.Date;
 import java.util.Optional;
 
 import de.deadlocker8.budgetmaster.logic.Category;
+import de.deadlocker8.budgetmaster.logic.Helpers;
+import de.deadlocker8.budgetmaster.logic.NormalPayment;
 import de.deadlocker8.budgetmaster.logic.Payment;
+import de.deadlocker8.budgetmaster.logic.RepeatingPaymentEntry;
 import de.deadlocker8.budgetmaster.ui.PaymentController;
 import fontAwesome.FontIcon;
 import fontAwesome.FontIconType;
@@ -16,9 +18,11 @@ import javafx.geometry.Insets;
 import javafx.geometry.Pos;
 import javafx.scene.control.Alert;
 import javafx.scene.control.Button;
+import javafx.scene.control.ButtonBar.ButtonData;
 import javafx.scene.control.ButtonType;
 import javafx.scene.control.Label;
 import javafx.scene.control.ListCell;
+import javafx.scene.control.Tooltip;
 import javafx.scene.layout.HBox;
 import javafx.scene.layout.Priority;
 import javafx.scene.layout.Region;
@@ -29,12 +33,11 @@ import tools.ConvertTo;
 public class PaymentCell extends ListCell<Payment>
 {
 	private final double HEIGHT = 40.0;
-	private final DecimalFormat numberFormat = new DecimalFormat("0.00");
 	private PaymentController paymentController;
 
 	public PaymentCell(PaymentController paymentController)
 	{
-		super();		
+		super();
 		this.paymentController = paymentController;
 	}
 
@@ -70,7 +73,7 @@ public class PaymentCell extends ListCell<Payment>
 
 			FontIcon iconRepeating = new FontIcon(FontIconType.CALENDAR);
 			iconRepeating.setSize(20);
-			if(item.isRepeating())
+			if(item instanceof RepeatingPaymentEntry)
 			{
 				iconRepeating.setColor(Color.web("#212121"));
 			}
@@ -87,12 +90,12 @@ public class PaymentCell extends ListCell<Payment>
 			hbox.getChildren().add(labelRepeating);
 			HBox.setMargin(labelRepeating, new Insets(0, 30, 0, 15));
 
-			String categoryName = category.getName();			
+			String categoryName = category.getName();
 			if(categoryName.equals("NONE"))
 			{
 				categoryName = "Keine Kategorie";
 			}
-			
+
 			Label labelCircle = new Label(categoryName.substring(0, 1).toUpperCase());
 			labelCircle.setPrefWidth(HEIGHT);
 			labelCircle.setPrefHeight(HEIGHT);
@@ -100,7 +103,11 @@ public class PaymentCell extends ListCell<Payment>
 			labelCircle.getStyleClass().add("greylabel");
 			String textColor = ConvertTo.toRGBHex(ConvertTo.getAppropriateTextColor(category.getColor()));
 			labelCircle.setStyle("-fx-background-color: " + ConvertTo.toRGBHex(category.getColor()) + "; -fx-background-radius: 50%; -fx-text-fill: " + textColor + "; -fx-font-weight: bold; -fx-font-size: 20;");
+			Tooltip tooltip = new Tooltip(categoryName);
+			tooltip.setStyle("-fx-font-size: 14");
+			labelCircle.setTooltip(tooltip);
 			hbox.getChildren().add(labelCircle);
+			
 
 			Label labelName = new Label(item.getName());
 			labelName.setPrefHeight(HEIGHT);
@@ -114,7 +121,7 @@ public class PaymentCell extends ListCell<Payment>
 			hbox.getChildren().add(r);
 			HBox.setHgrow(r, Priority.ALWAYS);
 
-			Label labelBudget = new Label(String.valueOf(numberFormat.format(item.getAmount() / 100.0)).replace(".", ",") + " �");
+			Label labelBudget = new Label(String.valueOf(Helpers.NUMBER_FORMAT.format(item.getAmount() / 100.0)).replace(".", ",") + " " + paymentController.getController().getSettings().getCurrency());
 			labelBudget.setPrefHeight(HEIGHT);
 			labelBudget.setStyle("-fx-font-weight: bold; -fx-font-size: 16; -fx-text-fill: #247A2D");
 			labelBudget.setAlignment(Pos.CENTER);
@@ -138,36 +145,57 @@ public class PaymentCell extends ListCell<Payment>
 			buttonDelete.setGraphic(iconDelete);
 			buttonDelete.setPrefHeight(HEIGHT);
 			buttonDelete.getStyleClass().add("greylabel");
-			buttonDelete.setStyle("-fx-background-color: transparent");
-			//TODO advanced deleting alert for repeating payments
+			buttonDelete.setStyle("-fx-background-color: transparent");			
 			buttonDelete.setOnAction((event) -> {
 				Alert alert = new Alert(Alert.AlertType.CONFIRMATION);
-				alert.setTitle("Zahlung l�schen");
+				alert.setTitle("Zahlung löschen");
 				alert.setHeaderText("");
-				alert.setContentText("M�chtest du diesen Eintrag wirklich unwiderruflich l�schen?");
+				alert.setContentText("Diese Zahlung wirklich unwiederruflich löschen?");
 				Stage dialogStage = (Stage)alert.getDialogPane().getScene().getWindow();
 				dialogStage.getIcons().add(paymentController.getController().getIcon());
 				dialogStage.centerOnScreen();
 
-				Optional<ButtonType> result = alert.showAndWait();
-				if(result.get() == ButtonType.OK)
+				if(item instanceof RepeatingPaymentEntry)
 				{
-					paymentController.deletePayment(item);
+					alert.setContentText("Es handelt sich um eine wiederkehrende Zahlung. Wie soll gelöscht werden?");
+					
+					ButtonType buttonTypeOne = new ButtonType("Komplett löschen");
+					ButtonType buttonTypeTwo = new ButtonType("Alle zukünftigen Löschen");				
+					ButtonType buttonTypeCancel = new ButtonType("Abbrechen", ButtonData.CANCEL_CLOSE);
+
+					alert.getButtonTypes().setAll(buttonTypeOne, buttonTypeTwo, buttonTypeCancel);
+
+					Optional<ButtonType> result = alert.showAndWait();
+					if(result.get() == buttonTypeOne)
+					{
+						paymentController.deleteRepeatingPayment((RepeatingPaymentEntry)item);
+					}
+					else if(result.get() == buttonTypeTwo)
+					{
+						paymentController.deleteFuturePayments((RepeatingPaymentEntry)item);
+					}
+				}
+				else
+				{
+					Optional<ButtonType> result = alert.showAndWait();
+					if(result.get() == ButtonType.OK)
+					{
+						paymentController.deleteNormalPayment((NormalPayment)item);
+					}
 				}
 			});
 			hbox.getChildren().add(buttonDelete);
 			HBox.setMargin(buttonDelete, new Insets(0, 0, 0, 25));
-			//don't allow "�bertrag" to be deleted			
+			// don't allow "Übertrag" to be deleted
 			if(item.getID() == -1)
 			{
 				buttonDelete.setVisible(false);
-			}			
+			}
 
 			hbox.setPadding(new Insets(10));
 			setStyle("-fx-background: transparent; -fx-border-color: #545454; -fx-border-width: 0 0 1 0");
 			setGraphic(hbox);
 			setAlignment(Pos.CENTER);
-
 		}
 		else
 		{
diff --git a/src/de/deadlocker8/budgetmasterserver/main/DatabaseCreator.java b/src/de/deadlocker8/budgetmasterserver/main/DatabaseCreator.java
new file mode 100644
index 0000000000000000000000000000000000000000..18f8cb2ad37ab1c6db132b0c8dfca68a1e1a4db9
--- /dev/null
+++ b/src/de/deadlocker8/budgetmasterserver/main/DatabaseCreator.java
@@ -0,0 +1,229 @@
+package de.deadlocker8.budgetmasterserver.main;
+
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.ArrayList;
+
+import logger.Logger;
+
+public class DatabaseCreator
+{
+	private Connection connection;
+	private Settings settings;
+
+	public DatabaseCreator(Connection connection, Settings settings)
+	{
+		this.connection = connection;
+		this.settings = settings;
+		Logger.info("Checking tables...");
+		createTables(getExistingTables());	
+		Logger.info("Checking tables [DONE]");
+	}
+
+	private ArrayList<String> getExistingTables()
+	{
+		ArrayList<String> tables = new ArrayList<>();
+		try
+		{
+			DatabaseMetaData meta = connection.getMetaData();
+			ResultSet res = meta.getTables(settings.getDatabaseName(), null, "", new String[] { "TABLE" });
+			while(res.next())
+			{
+				tables.add(res.getString("TABLE_NAME"));
+			}			
+		}
+		catch(Exception e)
+		{
+			Logger.error(e);
+		}
+		return tables;
+	}
+	
+	private void createTables(ArrayList<String> existingTables)
+	{
+		if(!existingTables.contains("category"))
+		{
+			createTableCategory();
+		}
+		
+		if(!existingTables.contains("payment"))
+		{
+			createTablePayment();
+		}
+		
+		if(!existingTables.contains("repeating_payment"))
+		{
+			createTableRepeatingPayment();
+		}
+		
+		if(!existingTables.contains("repeating_entry"))
+		{
+			createTableRepeatingEntry();
+		}
+	}
+	
+	private void createTableCategory()
+	{
+		Statement stmt = null;
+		String query = "CREATE TABLE `category` (`ID` int(11) NOT NULL COMMENT 'ID'," +
+				 " `Name` varchar(45) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT 'category name'," +
+				  "`Color` text COLLATE utf8_unicode_ci NOT NULL COMMENT 'color hexcode'" +
+				") ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;";		
+		String query2 = "INSERT INTO `category` (`ID`, `Name`, `Color`) VALUES(1, 'NONE', '#FFFFFF'),(2, 'Übertrag', '#FFFF00');";		
+		String query3 = "ALTER TABLE `category` ADD PRIMARY KEY (`ID`);";		
+		String query4 = "ALTER TABLE `category` MODIFY `ID` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID', AUTO_INCREMENT=3;";	
+		
+		try
+		{
+			stmt = connection.createStatement();
+			stmt.execute(query);
+			stmt.execute(query2);
+			stmt.execute(query3);
+			stmt.execute(query4);
+			Logger.info("Successfully created table category");
+		}
+		catch(SQLException e)
+		{
+			Logger.error(e);
+		}
+		finally
+		{
+			if(stmt != null)
+			{
+				try
+				{
+					stmt.close();
+				}
+				catch(SQLException e)
+				{
+				}
+			}
+		}
+	}
+	
+	private void createTablePayment()
+	{
+		Statement stmt = null;
+		String query = "CREATE TABLE `payment` (" +
+					 "`ID` int(11) NOT NULL COMMENT 'ID'," +
+					 "`Name` varchar(45) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT 'payment name (description)'," +
+					 "`CategoryID` int(11) DEFAULT NULL COMMENT 'category ID'," +
+					 "`Amount` int(11) DEFAULT NULL COMMENT 'amount in cents'," +
+					 "`Date` date DEFAULT NULL COMMENT 'payment date'" +
+					 ") ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;";			
+		String query2 = "ALTER TABLE `payment` ADD PRIMARY KEY (`ID`);";		
+		String query3 = "ALTER TABLE `payment` MODIFY `ID` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID';";	
+		
+		try
+		{
+			stmt = connection.createStatement();
+			stmt.execute(query);
+			stmt.execute(query2);
+			stmt.execute(query3);
+			Logger.info("Successfully created table payment");
+		}
+		catch(SQLException e)
+		{
+			Logger.error(e);
+		}
+		finally
+		{
+			if(stmt != null)
+			{
+				try
+				{
+					stmt.close();
+				}
+				catch(SQLException e)
+				{
+				}
+			}
+		}
+	}
+	
+	private void createTableRepeatingEntry()
+	{
+		Statement stmt = null;
+		String query = "CREATE TABLE `repeating_entry` (" +
+					  "`ID` int(11) NOT NULL," +
+					  "`RepeatingPaymentID` int(11) NOT NULL," +
+					  "`Date` date NOT NULL" +
+					") ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;";			
+		String query2 = "ALTER TABLE `repeating_entry` ADD PRIMARY KEY (`ID`), ADD KEY `RepeatingPaymentID` (`RepeatingPaymentID`);";		
+		String query3 = "ALTER TABLE `repeating_entry` MODIFY `ID` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID';";	
+		String query4 = "ALTER TABLE `repeating_entry` ADD CONSTRAINT `constraint_1` FOREIGN KEY (`RepeatingPaymentID`) REFERENCES `repeating_payment` (`ID`) ON DELETE CASCADE ON UPDATE CASCADE;";
+		
+		try
+		{
+			stmt = connection.createStatement();
+			stmt.execute(query);
+			stmt.execute(query2);
+			stmt.execute(query3);
+			stmt.execute(query4);
+			Logger.info("Successfully created table repeating_entry");
+		}
+		catch(SQLException e)
+		{
+			Logger.error(e);
+		}
+		finally
+		{
+			if(stmt != null)
+			{
+				try
+				{
+					stmt.close();
+				}
+				catch(SQLException e)
+				{
+				}
+			}
+		}
+	}
+	
+	private void createTableRepeatingPayment()
+	{
+		Statement stmt = null;
+		String query = "CREATE TABLE `repeating_payment` (" +
+					  "`ID` int(11) NOT NULL COMMENT 'ID'," +
+					  "`Name` varchar(45) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT 'payment name (description)'," +
+					  "`CategoryID` int(11) DEFAULT NULL COMMENT 'category ID'," +
+					  "`Amount` int(11) DEFAULT NULL COMMENT 'amount in cents'," +
+					  "`Date` date DEFAULT NULL COMMENT 'payment date'," +
+					  "`RepeatInterval` int(11) DEFAULT NULL COMMENT 'repeat interval in days'," +
+					  "`RepeatEndDate` date DEFAULT NULL COMMENT 'repeat end date'," +
+					  "`RepeatMonthDay` int(11) DEFAULT NULL COMMENT 'day in month on which payment repeats'" +
+					") ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;";			
+		String query2 = "ALTER TABLE `repeating_payment` ADD PRIMARY KEY (`ID`);";		
+		String query3 = "ALTER TABLE `repeating_payment` MODIFY `ID` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID';";	
+		
+		try
+		{
+			stmt = connection.createStatement();
+			stmt.execute(query);
+			stmt.execute(query2);
+			stmt.execute(query3);
+			Logger.info("Successfully created table repeating_payment");
+		}
+		catch(SQLException e)
+		{
+			Logger.error(e);
+		}
+		finally
+		{
+			if(stmt != null)
+			{
+				try
+				{
+					stmt.close();
+				}
+				catch(SQLException e)
+				{
+				}
+			}
+		}
+	}
+}
\ No newline at end of file
diff --git a/src/de/deadlocker8/budgetmasterserver/main/DatabaseHandler.java b/src/de/deadlocker8/budgetmasterserver/main/DatabaseHandler.java
index 036cb0de1dd3c5dc172efada43c86740ba681329..266ad33db08358eaa25ce89cc61f74eb9f3bc7ab 100644
--- a/src/de/deadlocker8/budgetmasterserver/main/DatabaseHandler.java
+++ b/src/de/deadlocker8/budgetmasterserver/main/DatabaseHandler.java
@@ -1,7 +1,6 @@
 package de.deadlocker8.budgetmasterserver.main;
 
 import java.sql.Connection;
-import java.sql.DatabaseMetaData;
 import java.sql.DriverManager;
 import java.sql.ResultSet;
 import java.sql.SQLException;
@@ -13,10 +12,12 @@ import org.joda.time.format.DateTimeFormat;
 import org.joda.time.format.DateTimeFormatter;
 
 import de.deadlocker8.budgetmaster.logic.Category;
-import de.deadlocker8.budgetmaster.logic.CategoryBudget;
+import de.deadlocker8.budgetmaster.logic.LatestRepeatingPayment;
+import de.deadlocker8.budgetmaster.logic.NormalPayment;
 import de.deadlocker8.budgetmaster.logic.Payment;
+import de.deadlocker8.budgetmaster.logic.RepeatingPayment;
+import de.deadlocker8.budgetmaster.logic.RepeatingPaymentEntry;
 import javafx.scene.paint.Color;
-import logger.LogLevel;
 import logger.Logger;
 import tools.ConvertTo;
 
@@ -30,40 +31,59 @@ public class DatabaseHandler
 		try
 		{
 			this.connection = DriverManager.getConnection(settings.getDatabaseUrl() + settings.getDatabaseName() + "?useLegacyDatetimeCode=false&serverTimezone=Europe/Berlin", settings.getDatabaseUsername(), settings.getDatabasePassword());
+			new DatabaseCreator(connection, settings);
+			Logger.info("Successfully initialized database (" + settings.getDatabaseUrl() + settings.getDatabaseName() + ")");
 		}
 		catch(Exception e)
 		{
-			Logger.log(LogLevel.ERROR, Logger.exceptionToString(e));
+			Logger.error(e);
 			throw new IllegalStateException("Cannot connect the database!", e);
 		}
 	}
 
-	// DEBUG
-	public void listTables()
+	/*
+	 * GET
+	 */
+	public DateTime getFirstNormalPaymentDate()
 	{
+		Statement stmt = null;
+		String query = "SELECT MIN(Date) as \"min\" FROM payment";
+		DateTime dateTime = null;
 		try
 		{
-			DatabaseMetaData md = connection.getMetaData();
-			ResultSet rs = md.getTables(null, null, "%", null);
+			stmt = connection.createStatement();
+			ResultSet rs = stmt.executeQuery(query);
+
 			while(rs.next())
 			{
-				System.out.println(rs.getString(3));
+				dateTime = formatter.parseDateTime(rs.getString("min"));
 			}
 		}
 		catch(SQLException e)
 		{
-			throw new IllegalStateException("Cannot connect the database!", e);
+			Logger.error(e);
+		}
+		finally
+		{
+			if(stmt != null)
+			{
+				try
+				{
+					stmt.close();
+				}
+				catch(SQLException e)
+				{
+				}
+			}
 		}
-	}
-
-	/*
-	 * GET
-	 */
 
-	public DateTime getFirstPaymentDate()
+		return dateTime;
+	}
+	
+	public DateTime getFirstRepeatingPaymentDate()
 	{
 		Statement stmt = null;
-		String query = "SELECT MIN(Date) as \"min\" FROM Payment";
+		String query = "SELECT MIN(Date) as \"min\" FROM repeating_payment";
 		DateTime dateTime = null;
 		try
 		{
@@ -77,7 +97,7 @@ public class DatabaseHandler
 		}
 		catch(SQLException e)
 		{
-			Logger.log(LogLevel.ERROR, Logger.exceptionToString(e));
+			Logger.error(e);
 		}
 		finally
 		{
@@ -97,16 +117,32 @@ public class DatabaseHandler
 	}
 
 	public int getRestForAllPreviousMonths(int year, int month)
-	{
-		DateTime firstDate = getFirstPaymentDate();
+	{		
+		DateTime firstNormalPaymentDate = getFirstNormalPaymentDate();
+		DateTime firstRepeatingPaymentDate = getFirstRepeatingPaymentDate();
+		
+		DateTime firstDate = firstNormalPaymentDate;
+		if(firstRepeatingPaymentDate.isBefore(firstNormalPaymentDate))
+		{
+			firstDate = firstRepeatingPaymentDate;
+		}
+		
+		DateTimeFormatter formatter = DateTimeFormat.forPattern("MM.yyyy");
+		String dateString = String.valueOf(month) + "." + year;
+		DateTime currentDate = formatter.parseDateTime(dateString);//	
+	
+		if(firstDate.isAfter(currentDate))
+		{
+			return 0;
+		}
 
 		int startYear = firstDate.getYear();
 		int startMonth = firstDate.getMonthOfYear();
 		int totalRest = 0;
-
+		
 		while(startYear < year || startMonth < month)
 		{
-			totalRest += getRest(startYear, startMonth);
+			totalRest += getRest(startYear, startMonth);			
 
 			startMonth++;
 			if(startMonth > 12)
@@ -120,24 +156,40 @@ public class DatabaseHandler
 
 	public int getRest(int year, int month)
 	{
-		Statement stmt = null;
-		String query = "SELECT SUM(q.amount) as \"rest\" FROM(SELECT Payment.amount as \"amount\" FROM Payment WHERE (YEAR(Date) = " + year + " AND MONTH(Date) = " + month
-				+ " OR RepeatMonthDay != 0 OR RepeatInterval != 0 AND DATEDIFF(NOW(), Date ) % RepeatInterval = 0 AND RepeatEndDate IS NULL OR RepeatInterval != 0 AND DATEDIFF(NOW(), Date ) % RepeatInterval = 0 AND RepeatEndDate IS NOT NULL AND DATEDIFF(RepeatEndDate, NOW()) > 0) GROUP BY Payment.ID ORDER BY Payment.Date) q";
+		ArrayList<Payment> payments = new ArrayList<>();
+		payments.addAll(getPayments(year, month));
+		payments.addAll(getRepeatingPayments(year, month));
+		
+		int rest = 0;
+		for(Payment currentPayment : payments)
+		{
+			rest += currentPayment.getAmount();
+		}
+		
+		return rest;
+	}
 
-		int result = 0;
+	public ArrayList<Category> getCategories()
+	{
+		Statement stmt = null;
+		String query = "SELECT * FROM category ORDER BY category.ID";
+		ArrayList<Category> results = new ArrayList<>();
 		try
 		{
 			stmt = connection.createStatement();
 			ResultSet rs = stmt.executeQuery(query);
-
 			while(rs.next())
 			{
-				result = rs.getInt("rest");
+				int id = rs.getInt("ID");
+				String name = rs.getString("Name");
+				String color = rs.getString("Color");
+
+				results.add(new Category(id, name, Color.web(color)));
 			}
 		}
 		catch(SQLException e)
 		{
-			Logger.log(LogLevel.ERROR, Logger.exceptionToString(e));
+			Logger.error(e);
 		}
 		finally
 		{
@@ -153,30 +205,30 @@ public class DatabaseHandler
 			}
 		}
 
-		return result;
+		return results;
 	}
-
-	public ArrayList<Category> getCategories()
+	
+	public Category getCategory(int ID)
 	{
 		Statement stmt = null;
-		String query = "SELECT * FROM Category ORDER BY Category.ID";
-		ArrayList<Category> results = new ArrayList<>();
+		String query = "SELECT * FROM category WHERE category.ID = " + ID;	
+		Category result = null;
 		try
 		{
 			stmt = connection.createStatement();
-			ResultSet rs = stmt.executeQuery(query);
+			ResultSet rs = stmt.executeQuery(query);			
 			while(rs.next())
 			{
 				int id = rs.getInt("ID");
 				String name = rs.getString("Name");
 				String color = rs.getString("Color");
 
-				results.add(new Category(id, name, Color.web(color)));
+				result = new Category(id, name, Color.web(color));
 			}
 		}
 		catch(SQLException e)
 		{
-			Logger.log(LogLevel.ERROR, Logger.exceptionToString(e));
+			Logger.error(e);
 		}
 		finally
 		{
@@ -192,30 +244,32 @@ public class DatabaseHandler
 			}
 		}
 
-		return results;
+		return result;
 	}
 	
-	public Category getCategory(int ID)
+	public NormalPayment getPayment(int ID)
 	{
 		Statement stmt = null;
-		String query = "SELECT * FROM Category WHERE Category.ID = " + ID;	
-		Category result = null;
+		String query = "SELECT * FROM payment WHERE payment.ID= " + ID;
 		try
 		{
 			stmt = connection.createStatement();
-			ResultSet rs = stmt.executeQuery(query);			
+			ResultSet rs = stmt.executeQuery(query);
+
 			while(rs.next())
 			{
-				int id = rs.getInt("ID");
+				int resultID = rs.getInt("ID");
 				String name = rs.getString("Name");
-				String color = rs.getString("Color");
+				int amount = rs.getInt("amount");
+				String date = rs.getString("Date");
+				int categoryID = rs.getInt("CategoryID");
 
-				result = new Category(id, name, Color.web(color));
+				return new NormalPayment(resultID, amount, date, categoryID, name);
 			}
 		}
 		catch(SQLException e)
 		{
-			Logger.log(LogLevel.ERROR, Logger.exceptionToString(e));
+			Logger.error(e);
 		}
 		finally
 		{
@@ -231,17 +285,15 @@ public class DatabaseHandler
 			}
 		}
 
-		return result;
+		return null;
 	}
 
-	public ArrayList<CategoryBudget> getCategoryBudget(int year, int month)
+	public ArrayList<NormalPayment> getPayments(int year, int month)
 	{
-		String date = String.valueOf(year) + "-" + String.format("%02d", month) + "-";
 		Statement stmt = null;
-		String query = "SELECT q.cat_name AS \"Name\", q.cat_col AS \"Color\", SUM(q.amoun) AS \"Amount\" FROM (SELECT Payment.CategoryID as \"cat_ID\", Category.Name as \"cat_name\", Category.Color as \"cat_col\", Payment.Amount AS \"amoun\" FROM Payment, Category WHERE Payment.CategoryID = Category.ID AND (YEAR(Date) = "
-				+ year + " AND  MONTH(Date) = " + month + " AND RepeatMonthDay = 0 OR RepeatMonthDay != 0 AND CONCAT('" + date + "', RepeatMonthDay) >= Date AND RepeatEndDate IS NULL OR RepeatMonthDay != 0 AND CONCAT('" + date + "', RepeatMonthDay) >= Date AND CONCAT('" + date
-				+ "', RepeatMonthDay) <= RepeatEndDate OR RepeatInterval != 0 AND DATEDIFF(NOW(), Date ) % RepeatInterval = 0 AND RepeatEndDate IS NULL OR RepeatInterval != 0 AND DATEDIFF(NOW(), Date ) % RepeatInterval = 0 AND RepeatEndDate IS NOT NULL AND DATEDIFF(RepeatEndDate, NOW()) > 0)GROUP BY Payment.ID) as q GROUP BY q.cat_ID ORDER BY SUM(q.amoun) DESC";
-		ArrayList<CategoryBudget> results = new ArrayList<>();
+		String query = "SELECT * FROM payment WHERE YEAR(Date) = " + year + " AND  MONTH(Date) = " + month;
+
+		ArrayList<NormalPayment> results = new ArrayList<>();
 		try
 		{
 			stmt = connection.createStatement();
@@ -249,16 +301,18 @@ public class DatabaseHandler
 
 			while(rs.next())
 			{
+				int resultID = rs.getInt("ID");				
 				String name = rs.getString("Name");
-				String color = rs.getString("Color");
-				int amount = rs.getInt("Amount");
-
-				results.add(new CategoryBudget(name, Color.web(color), amount));
+				int amount = rs.getInt("amount");
+				String date = rs.getString("Date");				
+				int categoryID = rs.getInt("CategoryID");
+			
+				results.add(new NormalPayment(resultID, amount, date, categoryID, name));
 			}
 		}
 		catch(SQLException e)
 		{
-			Logger.log(LogLevel.ERROR, Logger.exceptionToString(e));
+			Logger.error(e);
 		}
 		finally
 		{
@@ -277,10 +331,12 @@ public class DatabaseHandler
 		return results;
 	}
 
-	public Payment getPayment(int ID, int year, int month)
+	public ArrayList<RepeatingPaymentEntry> getRepeatingPayments(int year, int month)
 	{
 		Statement stmt = null;
-		String query = "SELECT * FROM Payment WHERE Payment.ID= " + ID;
+		String query = "SELECT repeating_entry.ID, repeating_entry.RepeatingPaymentID, repeating_entry.Date, repeating_payment.Name, repeating_payment.CategoryID, repeating_payment.Amount, repeating_payment.RepeatInterval, repeating_payment.RepeatEndDate, repeating_payment.RepeatMonthDay FROM repeating_entry, repeating_payment WHERE repeating_entry.RepeatingPaymentID = repeating_payment.ID AND YEAR(repeating_entry.Date) = " + year + " AND MONTH(repeating_entry.Date) = " + month;
+
+		ArrayList<RepeatingPaymentEntry> results = new ArrayList<>();
 		try
 		{
 			stmt = connection.createStatement();
@@ -289,28 +345,67 @@ public class DatabaseHandler
 			while(rs.next())
 			{
 				int resultID = rs.getInt("ID");
+				int repeatingPaymentID = rs.getInt("repeatingPaymentID");				
 				String name = rs.getString("Name");
 				int amount = rs.getInt("amount");
-				String date = rs.getString("Date");
+				String date = rs.getString("Date");				
 				int categoryID = rs.getInt("CategoryID");
-
 				int repeatInterval = rs.getInt("RepeatInterval");
 				String repeatEndDate = rs.getString("RepeatEndDate");
-				int repeatMonthDay = rs.getInt("RepeatMonthDay");
-				if(repeatInterval != 0 || repeatMonthDay != 0)
+				int repeatMonthDay = rs.getInt("RepeatMonthDay");		
+			
+				results.add(new RepeatingPaymentEntry(resultID, repeatingPaymentID, date, amount, categoryID, name, repeatInterval, repeatEndDate, repeatMonthDay));
+			}
+		}
+		catch(SQLException e)
+		{
+			Logger.error(e);
+		}
+		finally
+		{
+			if(stmt != null)
+			{
+				try
+				{
+					stmt.close();
+				}
+				catch(SQLException e)
 				{
-					DateTime dateTime = formatter.parseDateTime(date);
-					dateTime = dateTime.year().setCopy(year);
-					dateTime = dateTime.monthOfYear().setCopy(month);
-					date = dateTime.toString(formatter);
 				}
+			}
+		}
+
+		return results;
+	}
+	
+	public ArrayList<RepeatingPayment> getAllRepeatingPayments()
+	{		
+		Statement stmt = null;
+		String query = "SELECT * FROM repeating_payment;";
 
-				return new Payment(resultID, amount, date, categoryID, name, repeatInterval, repeatEndDate, repeatMonthDay);
+		ArrayList<RepeatingPayment> results = new ArrayList<>();
+		try
+		{
+			stmt = connection.createStatement();
+			ResultSet rs = stmt.executeQuery(query);
+
+			while(rs.next())
+			{
+				int resultID = rs.getInt("ID");				
+				String name = rs.getString("Name");
+				int amount = rs.getInt("amount");
+				String date = rs.getString("Date");				
+				int categoryID = rs.getInt("CategoryID");
+				int repeatInterval = rs.getInt("RepeatInterval");
+				String repeatEndDate = rs.getString("RepeatEndDate");
+				int repeatMonthDay = rs.getInt("RepeatMonthDay");			
+
+				results.add(new RepeatingPayment(resultID, amount, date, categoryID, name, repeatInterval, repeatEndDate, repeatMonthDay));
 			}
 		}
 		catch(SQLException e)
 		{
-			Logger.log(LogLevel.ERROR, Logger.exceptionToString(e));
+			Logger.error(e);
 		}
 		finally
 		{
@@ -326,18 +421,15 @@ public class DatabaseHandler
 			}
 		}
 
-		return null;
+		return results;
 	}
-
-	public ArrayList<Integer> getPaymentIDs(int year, int month)
+	
+	public ArrayList<LatestRepeatingPayment> getLatestRepeatingPaymentEntries()
 	{
-		String date = String.valueOf(year) + "-" + String.format("%02d", month) + "-";
 		Statement stmt = null;
-		String query = "SELECT Payment.ID as ID FROM Payment WHERE (YEAR(Date) = " + year + " AND  MONTH(Date) = " + month + " AND RepeatMonthDay = 0 OR RepeatMonthDay != 0 AND CONCAT('" + date + "', RepeatMonthDay) >= Date AND RepeatEndDate IS NULL OR RepeatMonthDay != 0 AND CONCAT('" + date
-				+ "', RepeatMonthDay) >= Date AND CONCAT('" + date
-				+ "', RepeatMonthDay) <= RepeatEndDate OR RepeatInterval != 0 AND DATEDIFF(NOW(), Date ) % RepeatInterval = 0 AND RepeatEndDate IS NULL OR RepeatInterval != 0 AND DATEDIFF(NOW(), Date ) % RepeatInterval = 0 AND RepeatEndDate IS NOT NULL AND DATEDIFF(RepeatEndDate, NOW()) > 0) GROUP BY Payment.ID ORDER BY Payment.Date DESC";
+		String query = "SELECT ID, RepeatingPaymentID, MAX(Date) as 'LastDate' FROM repeating_entry GROUP BY RepeatingPaymentID";
 
-		ArrayList<Integer> results = new ArrayList<>();
+		ArrayList<LatestRepeatingPayment> results = new ArrayList<>();
 		try
 		{
 			stmt = connection.createStatement();
@@ -345,13 +437,16 @@ public class DatabaseHandler
 
 			while(rs.next())
 			{
-				int ID = rs.getInt("ID");
-				results.add(ID);
+				int resultID = rs.getInt("ID");
+				int repeatingPaymentID = rs.getInt("repeatingPaymentID");				
+				String date = rs.getString("LastDate");
+			
+				results.add(new LatestRepeatingPayment(resultID, repeatingPaymentID, date));
 			}
 		}
 		catch(SQLException e)
 		{
-			Logger.log(LogLevel.ERROR, Logger.exceptionToString(e));
+			Logger.error(e);
 		}
 		finally
 		{
@@ -369,37 +464,58 @@ public class DatabaseHandler
 
 		return results;
 	}
-
-	public ArrayList<Payment> getPayments(int year, int month)
+	
+	public RepeatingPayment getRepeatingPayment(int ID)
 	{
-		ArrayList<Payment> payments = new ArrayList<>();
-
-		// add rest from previous months
-		int restAmount = getRest(year, month);
-		Payment paymentRest = new Payment(-1, restAmount, year + "-" + month + "-01", 1, "�bertrag", 0, null, 0);
-		payments.add(paymentRest);
+		Statement stmt = null;
+		String query = "SELECT * FROM repeating_payment WHERE ID = " + ID;	
+		RepeatingPayment result = null;
+		try
+		{
+			stmt = connection.createStatement();
+			ResultSet rs = stmt.executeQuery(query);			
+			while(rs.next())
+			{
+				int id = rs.getInt("ID");				
+				int amount = rs.getInt("amount");
+				String date = rs.getString("Date");
+				int categoryID = rs.getInt("CategoryID");
+				String name = rs.getString("Name");
+				int repeatInterval = rs.getInt("repeatInterval");
+				String repeatEndDate = rs.getString("repeatEndDate");
+				int repeatMonthDay = rs.getInt("repeatMonthDay");
 
-		ArrayList<Integer> IDs = getPaymentIDs(year, month);
-		for(int currentID : IDs)
+				result = new RepeatingPayment(id, amount, date, categoryID, name, repeatInterval, repeatEndDate, repeatMonthDay);
+			}
+		}
+		catch(SQLException e)
 		{
-			Payment currentPayment = getPayment(currentID, year, month);
-			if(currentPayment != null)
+			Logger.error(e);
+		}
+		finally
+		{
+			if(stmt != null)
 			{
-				payments.add(currentPayment);
+				try
+				{
+					stmt.close();
+				}
+				catch(SQLException e)
+				{
+				}
 			}
 		}
 
-		return payments;
+		return result;
 	}
 
 	/*
 	 * DELETE
 	 */
-
 	public void deleteCategory(int ID)
 	{
 		Statement stmt = null;
-		String query = "DELETE FROM Category WHERE Category.ID = " + ID;
+		String query = "DELETE FROM category WHERE category.ID = " + ID;
 		try
 		{
 			stmt = connection.createStatement();
@@ -407,7 +523,7 @@ public class DatabaseHandler
 		}
 		catch(SQLException e)
 		{
-			Logger.log(LogLevel.ERROR, Logger.exceptionToString(e));
+			Logger.error(e);
 		}
 		finally
 		{
@@ -427,7 +543,7 @@ public class DatabaseHandler
 	public void deletePayment(int ID)
 	{
 		Statement stmt = null;
-		String query = "DELETE FROM Payment WHERE Payment.ID = " + ID;
+		String query = "DELETE FROM payment WHERE payment.ID = " + ID;
 		try
 		{
 			stmt = connection.createStatement();
@@ -435,7 +551,35 @@ public class DatabaseHandler
 		}
 		catch(SQLException e)
 		{
-			Logger.log(LogLevel.ERROR, Logger.exceptionToString(e));
+			Logger.error(e);
+		}
+		finally
+		{
+			if(stmt != null)
+			{
+				try
+				{
+					stmt.close();
+				}
+				catch(SQLException e)
+				{
+				}
+			}
+		}
+	}
+	
+	public void deleteRepeatingPayment(int ID)
+	{
+		Statement stmt = null;
+		String query = "DELETE FROM repeating_payment WHERE repeating_payment.ID = " + ID;
+		try
+		{
+			stmt = connection.createStatement();
+			stmt.execute(query);
+		}
+		catch(SQLException e)
+		{
+			Logger.error(e);
 		}
 		finally
 		{
@@ -458,7 +602,7 @@ public class DatabaseHandler
 	public void addCategory(String name, Color color)
 	{
 		Statement stmt = null;
-		String query = "INSERT INTO Category (Name, Color) VALUES('" + name + "' , '" + ConvertTo.toRGBHexWithoutOpacity(color) + "');";
+		String query = "INSERT INTO category (Name, Color) VALUES('" + name + "' , '" + ConvertTo.toRGBHexWithoutOpacity(color) + "');";
 		try
 		{
 			stmt = connection.createStatement();
@@ -466,7 +610,7 @@ public class DatabaseHandler
 		}
 		catch(SQLException e)
 		{
-			Logger.log(LogLevel.ERROR, Logger.exceptionToString(e));
+			Logger.error(e);
 		}
 		finally
 		{
@@ -483,7 +627,35 @@ public class DatabaseHandler
 		}
 	}
 
-	public void addPayment(int amount, String date, int categoryID, String name, int repeatInterval, String repeatEndDate, int repeatMonthDay)
+	public void addNormalPayment(int amount, String date, int categoryID, String name)
+	{
+		Statement stmt = null;
+		String query = "INSERT INTO payment (Amount, Date, CategoryID, Name) VALUES('" + amount + "' , '" + date + "' , '" + categoryID + "' , '" + name + "');";
+		try
+		{
+			stmt = connection.createStatement();
+			stmt.execute(query);
+		}
+		catch(SQLException e)
+		{
+			Logger.error(e);
+		}
+		finally
+		{
+			if(stmt != null)
+			{
+				try
+				{
+					stmt.close();
+				}
+				catch(SQLException e)
+				{
+				}
+			}
+		}
+	}
+	
+	public void addRepeatingPayment(int amount, String date, int categoryID, String name, int repeatInterval, String repeatEndDate, int repeatMonthDay)
 	{
 		Statement stmt = null;
 		String query;		
@@ -491,11 +663,11 @@ public class DatabaseHandler
 		if(repeatEndDate.equals("A") || repeatEndDate == null)
 		{
 			
-			query = "INSERT INTO Payment (Amount, Date, CategoryID, Name, RepeatInterval, RepeatEndDate, RepeatMonthDay) VALUES('" + amount + "' , '" + date + "' , '" + categoryID + "' , '" + name + "' , '" + repeatInterval + "' , NULL , '" + repeatMonthDay + "');";
+			query = "INSERT INTO repeating_payment (Amount, Date, CategoryID, Name, RepeatInterval, RepeatEndDate, RepeatMonthDay) VALUES('" + amount + "' , '" + date + "' , '" + categoryID + "' , '" + name + "' , '" + repeatInterval + "' , NULL , '" + repeatMonthDay + "');";
 		}
 		else
 		{
-			query = "INSERT INTO Payment (Amount, Date, CategoryID, Name, RepeatInterval, RepeatEndDate, RepeatMonthDay) VALUES('" + amount + "' , '" + date + "' , '" + categoryID + "' , '" + name + "' , '" + repeatInterval + "' , '" + repeatEndDate + "' , '" + repeatMonthDay + "');";
+			query = "INSERT INTO repeating_payment (Amount, Date, CategoryID, Name, RepeatInterval, RepeatEndDate, RepeatMonthDay) VALUES('" + amount + "' , '" + date + "' , '" + categoryID + "' , '" + name + "' , '" + repeatInterval + "' , '" + repeatEndDate + "' , '" + repeatMonthDay + "');";
 		}
 		
 		try
@@ -505,7 +677,36 @@ public class DatabaseHandler
 		}
 		catch(SQLException e)
 		{
-			Logger.log(LogLevel.ERROR, Logger.exceptionToString(e));
+			Logger.error(e);
+		}
+		finally
+		{
+			if(stmt != null)
+			{
+				try
+				{
+					stmt.close();
+				}
+				catch(SQLException e)
+				{
+				}
+			}
+		}
+	}
+	
+	public void addRepeatingPaymentEntry(int repeatingPaymentID, String date)
+	{
+		Statement stmt = null;
+		String query;		
+		query = "INSERT INTO repeating_entry (RepeatingPaymentID, Date) VALUES('" +  repeatingPaymentID + "' , '" + date + "');";
+		try
+		{
+			stmt = connection.createStatement();
+			stmt.execute(query);
+		}
+		catch(SQLException e)
+		{
+			Logger.error(e);
 		}
 		finally
 		{
@@ -528,7 +729,35 @@ public class DatabaseHandler
 	public void updateCategory(int ID, String name, Color color)
 	{
 		Statement stmt = null;
-		String query = "UPDATE Category SET name='" + name + "' , color='" + ConvertTo.toRGBHexWithoutOpacity(color) + "' WHERE ID = " + ID + ";";
+		String query = "UPDATE category SET name='" + name + "' , color='" + ConvertTo.toRGBHexWithoutOpacity(color) + "' WHERE ID = " + ID + ";";
+		try
+		{
+			stmt = connection.createStatement();
+			stmt.execute(query);
+		}
+		catch(SQLException e)
+		{
+			Logger.error(e);
+		}
+		finally
+		{
+			if(stmt != null)
+			{
+				try
+				{
+					stmt.close();
+				}
+				catch(SQLException e)
+				{
+				}
+			}
+		}
+	}	
+	
+	public void updateNormalPayment(int ID, int amount, String date, int categoryID, String name)
+	{
+		Statement stmt = null;
+		String query = "UPDATE payment SET amount = '" + amount + "', date='" + date + "', categoryID='" + categoryID + "', name='" + name + "' WHERE ID = " + ID + ";";
 		try
 		{
 			stmt = connection.createStatement();
@@ -536,7 +765,7 @@ public class DatabaseHandler
 		}
 		catch(SQLException e)
 		{
-			Logger.log(LogLevel.ERROR, Logger.exceptionToString(e));
+			Logger.error(e);
 		}
 		finally
 		{
diff --git a/src/de/deadlocker8/budgetmasterserver/main/Main.java b/src/de/deadlocker8/budgetmasterserver/main/Main.java
index 7d7412cc8c0eec5a2b59551d64431dcd6a225bc5..32f139cf59e6b614065fa5362b03372fca257be0 100644
--- a/src/de/deadlocker8/budgetmasterserver/main/Main.java
+++ b/src/de/deadlocker8/budgetmasterserver/main/Main.java
@@ -1,13 +1,51 @@
 package de.deadlocker8.budgetmasterserver.main;
 
+import java.io.File;
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+
+import de.deadlocker8.budgetmasterserver.server.SparkServer;
+import logger.LogLevel;
+import logger.Logger;
+
 public class Main
 {
 	public static void main(String[] args)
 	{
-		Settings settings = Utils.loadSettings();
-		DatabaseHandler handler = new DatabaseHandler(settings);
-		//handler.listTables();
-//		System.out.println(handler.getCategoryBudget(2017, 1));
-		System.out.println(handler.getRestForAllPreviousMonths(2017,10));
+		Logger.setLevel(LogLevel.ALL);		
+		try
+		{
+			File logFile = new File(Paths.get(SparkServer.class.getProtectionDomain().getCodeSource().getLocation().toURI()).getParent().toFile() + "/error.log");
+			Logger.enableFileOutput(logFile);
+		}
+		catch(URISyntaxException e1)
+		{
+			Logger.error(e1);
+		}		
+		
+		if(!Files.exists(Paths.get("settings.json")))
+		{
+			try
+			{
+				Files.copy(SparkServer.class.getClassLoader().getResourceAsStream("de/deadlocker8/budgetmasterserver/resources/settings.json"), Paths.get("settings.json"));
+			}
+			catch(IOException e)
+			{
+				Logger.error(e);
+			}
+		}
+
+		Settings settings;
+		try
+		{
+			settings = Utils.loadSettings();
+			new SparkServer(settings);
+		}
+		catch(IOException e)
+		{
+			Logger.error(e);
+		}
 	}
-}
\ No newline at end of file
+}
diff --git a/src/de/deadlocker8/budgetmasterserver/main/Settings.java b/src/de/deadlocker8/budgetmasterserver/main/Settings.java
index 3eb8f7216055391d51377be2de5fdc7380002cfc..1dbc26be8a1cacc8e1ecedba6a2216ec604b3d8b 100644
--- a/src/de/deadlocker8/budgetmasterserver/main/Settings.java
+++ b/src/de/deadlocker8/budgetmasterserver/main/Settings.java
@@ -2,12 +2,14 @@ package de.deadlocker8.budgetmasterserver.main;
 
 public class Settings
 {
-	private String databaseUrl = "jdbc:mysql://localhost:3306/";
-	private String databaseName = "budgetmaster";
-	private String databaseUsername = "root";
-	private String databasePassword = "";
+	private String databaseUrl;
+	private String databaseName;
+	private String databaseUsername;
+	private String databasePassword;
 	private int serverPort;	
 	private String serverSecret;
+	private String keystorePath;
+	private String keystorePassword;
 	
 	public Settings()
 	{
@@ -43,4 +45,21 @@ public class Settings
 	{
 		return serverSecret;
 	}
+
+	public String getKeystorePath()
+	{
+		return keystorePath;
+	}
+
+	public String getKeystorePassword()
+	{
+		return keystorePassword;
+	}
+
+	@Override
+	public String toString()
+	{
+		return "Settings [databaseUrl=" + databaseUrl + ", databaseName=" + databaseName + ", databaseUsername=" + databaseUsername + ", databasePassword=" + databasePassword + ", serverPort=" + serverPort + ", serverSecret=" + serverSecret + ", keystorePath=" + keystorePath + ", keystorePassword="
+				+ keystorePassword + "]";
+	}
 }
\ No newline at end of file
diff --git a/src/de/deadlocker8/budgetmasterserver/main/Utils.java b/src/de/deadlocker8/budgetmasterserver/main/Utils.java
index a79d9ec196cb728c9a86f0dc421fc2a1d7731276..417375ffc23b3164fd3e54bbb54fc37c73534438 100644
--- a/src/de/deadlocker8/budgetmasterserver/main/Utils.java
+++ b/src/de/deadlocker8/budgetmasterserver/main/Utils.java
@@ -8,22 +8,14 @@ import com.google.gson.Gson;
 
 public class Utils
 {
-	public static Settings loadSettings()
+	public static Settings loadSettings() throws IOException
 	{
 		String settingsJSON;
 		Settings settings;
-		try
-		{
-			Gson gson = new Gson();
-			settingsJSON = new String(Files.readAllBytes(Paths.get("settings.properties")));				
-			settings = gson.fromJson(settingsJSON, Settings.class);	
-			return settings;
-		}
-		catch(IOException e)
-		{
-			//ERRORHANDLING
-			e.printStackTrace();
-			return null;
-		}
+		
+		Gson gson = new Gson();
+		settingsJSON = new String(Files.readAllBytes(Paths.get("settings.json")));		
+		settings = gson.fromJson(settingsJSON, Settings.class);	
+		return settings;		
 	}
 }
\ No newline at end of file
diff --git a/src/de/deadlocker8/budgetmasterserver/resources/settings.json b/src/de/deadlocker8/budgetmasterserver/resources/settings.json
new file mode 100644
index 0000000000000000000000000000000000000000..a6d06ac193b1392dfc26688d3bbca53dc18710b5
--- /dev/null
+++ b/src/de/deadlocker8/budgetmasterserver/resources/settings.json
@@ -0,0 +1,10 @@
+{
+	"databaseUrl": "jdbc:mysql://localhost:3306/",
+	"databaseName": "budgetmastersave",
+	"databaseUsername": "root",
+	"databasePassword": "",
+	"serverPort": 9000,
+	"serverSecret": "geheim",
+	"keystorePath": "",
+	"keystorePassword": ""
+}
\ No newline at end of file
diff --git a/src/de/deadlocker8/budgetmasterserver/resources/settings.properties b/src/de/deadlocker8/budgetmasterserver/resources/settings.properties
deleted file mode 100644
index fd8e172c8710b9616b81c9f5d04150461ade7da7..0000000000000000000000000000000000000000
--- a/src/de/deadlocker8/budgetmasterserver/resources/settings.properties
+++ /dev/null
@@ -1,4 +0,0 @@
-{
-	"port": 9000,
-	"secret": "geheim"
-}
\ No newline at end of file
diff --git a/src/de/deadlocker8/budgetmasterserver/server/SparkServer.java b/src/de/deadlocker8/budgetmasterserver/server/SparkServer.java
index 5aa0663bd40a4194c859edb37f5a54a7dc130673..1d645f716c574109e752e3c2b2abeeeee8981d1a 100644
--- a/src/de/deadlocker8/budgetmasterserver/server/SparkServer.java
+++ b/src/de/deadlocker8/budgetmasterserver/server/SparkServer.java
@@ -1,380 +1,116 @@
 package de.deadlocker8.budgetmasterserver.server;
 
-import static spark.Spark.*;
+import static spark.Spark.after;
+import static spark.Spark.before;
+import static spark.Spark.delete;
+import static spark.Spark.get;
+import static spark.Spark.halt;
+import static spark.Spark.port;
+import static spark.Spark.post;
+import static spark.Spark.put;
+import static spark.Spark.secure;
 
-import java.io.IOException;
-import java.net.URISyntaxException;
-import java.nio.file.Files;
-import java.nio.file.Paths;
-import java.util.ArrayList;
+import java.io.File;
 
 import com.google.gson.Gson;
 import com.google.gson.GsonBuilder;
 
-import de.deadlocker8.budgetmaster.logic.*;
 import de.deadlocker8.budgetmasterserver.main.DatabaseHandler;
 import de.deadlocker8.budgetmasterserver.main.Settings;
-import de.deadlocker8.budgetmasterserver.main.Utils;
-import javafx.scene.paint.Color;
-import logger.LogLevel;
+import de.deadlocker8.budgetmasterserver.server.category.CategoryAdd;
+import de.deadlocker8.budgetmasterserver.server.category.CategoryDelete;
+import de.deadlocker8.budgetmasterserver.server.category.CategoryGet;
+import de.deadlocker8.budgetmasterserver.server.category.CategoryGetAll;
+import de.deadlocker8.budgetmasterserver.server.category.CategoryUpdate;
+import de.deadlocker8.budgetmasterserver.server.categorybudget.CategoryBudgetGet;
+import de.deadlocker8.budgetmasterserver.server.payment.normal.PaymentAdd;
+import de.deadlocker8.budgetmasterserver.server.payment.normal.PaymentDelete;
+import de.deadlocker8.budgetmasterserver.server.payment.normal.PaymentGet;
+import de.deadlocker8.budgetmasterserver.server.payment.normal.PaymentUpdate;
+import de.deadlocker8.budgetmasterserver.server.payment.repeating.RepeatingPaymentAdd;
+import de.deadlocker8.budgetmasterserver.server.payment.repeating.RepeatingPaymentDelete;
+import de.deadlocker8.budgetmasterserver.server.payment.repeating.RepeatingPaymentGet;
+import de.deadlocker8.budgetmasterserver.server.payment.repeating.RepeatingPaymentGetAll;
+import de.deadlocker8.budgetmasterserver.server.rest.RestGet;
+import de.deadlocker8.budgetmasterserver.server.updater.RepeatingPaymentUpdater;
 import logger.Logger;
+import spark.Spark;
 import spark.route.RouteOverview;
 
 public class SparkServer
-{
-	private static Gson gson;
+{	
+	private Gson gson;
+	private DatabaseHandler handler;
+	
+	public SparkServer(Settings settings)
+	{				
+		Logger.info("Initialized SparkServer");
 
-	public static void main(String[] args) throws URISyntaxException
-	{		
-		//DEBUG
-		Logger.setLevel(LogLevel.ALL);
-		
 		gson = new GsonBuilder().setPrettyPrinting().create();
 		
-		if (!Files.exists(Paths.get("settings.properties")))
+		port(settings.getServerPort());
+		
+		try
 		{
-			try
-			{
-				Files.copy(SparkServer.class.getClassLoader().getResourceAsStream("de/deadlocker8/budgetmasterserver/resources/settings.properties"), Paths.get("settings.properties"));
-			}
-			catch(IOException e)
-			{
-				//ERRORHANDLING
-				e.printStackTrace();
-			}		
+			File keystoreFile = new File(settings.getKeystorePath());		
+			secure(keystoreFile.getAbsolutePath(), settings.getKeystorePassword(), null, null);						
 		}
+		catch(Exception e)
+		{
+			Logger.error(e);
+			Logger.info("CANCELED server initialization");
+			return;
+		}		
 		
-		Settings settings = Utils.loadSettings();
-		
-		port(settings.getServerPort());	
-		//DEBUG
-		secure("certs/keystore.jks", "geheim", null, null);	
 		RouteOverview.enableRouteOverview();
 		
+		handler = new DatabaseHandler(settings);
+
 		before((request, response) -> {
-			
+
 			String clientSecret = request.queryMap("secret").value();
-		
-			if(clientSecret == null || !clientSecret.equals(settings.getServerSecret()))			
+
+			if(clientSecret == null || !clientSecret.equals(settings.getServerSecret()))
 			{
 				halt(401, "Unauthorized");
 			}
-		});
-
-		/*
-		 * Category
-		 */
-		get("/category", (req, res) -> {
-			try
-			{
-				DatabaseHandler handler = new DatabaseHandler(settings);			
-				ArrayList<Category> categories = handler.getCategories();			
 
-				return gson.toJson(categories);
-			}
-			catch(IllegalStateException e)
-			{
-				halt(500, "Internal Server Error");
-			}	
-			return null;
-		});
-		
-		get("/category/single", (req, res) -> {			
-			if(!req.queryParams().contains("id"))
-			{				
-				halt(400, "Bad Request");
-			}	
-			
-			int id = -1;		
-			
-			try
-			{				
-				id = Integer.parseInt(req.queryMap("id").value());
-				
-				if(id < 0)
-				{					
-					halt(400, "Bad Request");
-				}
-			
-				try
-				{
-					DatabaseHandler handler = new DatabaseHandler(settings);			
-					Category categeory = handler.getCategory(id);				
-	
-					return gson.toJson(categeory);
-				}
-				catch(IllegalStateException e)
-				{
-					e.printStackTrace();
-					halt(500, "Internal Server Error");
-				}	
-			}
-			catch(Exception e)
-			{				
-				halt(400, "Bad Request");
-			}
-			return null;
+			new RepeatingPaymentUpdater(handler).updateRepeatingPayments();
 		});
-		
-		post("/category", (req, res) -> {			
-			if(!req.queryParams().contains("name") || !req.queryParams().contains("color"))
-			{
-				halt(400, "Bad Request");
-			}	
-							
-			try
-			{
-				DatabaseHandler handler = new DatabaseHandler(settings);
-				handler.addCategory(req.queryMap("name").value(), Color.web("#" + req.queryMap("color").value()));			
 
-				return "";
-			}
-			catch(IllegalStateException ex)
-			{				
-				halt(500, "Internal Server Error");
-			}
-			catch(Exception e)
-			{				
-				halt(400, "Bad Request");
-			}
-			
-			return "";
-		});
-		
-		put("/category", (req, res) -> {			
-			if(!req.queryParams().contains("id") ||!req.queryParams().contains("name") || !req.queryParams().contains("color"))
-			{
-				halt(400, "Bad Request");
-			}	
-			
-			int id = -1;		
-			
-			try
-			{				
-				id = Integer.parseInt(req.queryMap("id").value());
-				
-				if(id < 0)
-				{
-					halt(400, "Bad Request");
-				}
-				
-				try
-				{
-					DatabaseHandler handler = new DatabaseHandler(settings);
-					handler.updateCategory(id, req.queryMap("name").value(), Color.web("#" + req.queryMap("color").value()));			
+		// Category
+		get("/category", new CategoryGetAll(handler, gson));
+		get("/category/single", new CategoryGet(handler, gson));
+		post("/category", new CategoryAdd(handler));
+		put("/category", new CategoryUpdate(handler));
+		delete("/category", new CategoryDelete(handler));
 
-					return "";
-				}
-				catch(IllegalStateException ex)
-				{				
-					halt(500, "Internal Server Error");
-				}
-			}		
-			catch(Exception e)
-			{
-				halt(400, "Bad Request");
-			}
-			
-			return "";
-		});
-				
-		delete("/category", (req, res) -> {			
-			if(!req.queryParams().contains("id"))
-			{
-				halt(400, "Bad Request");
-			}			
-			
-			int id = -1;		
-			
-			try
-			{				
-				id = Integer.parseInt(req.queryMap("id").value());
-				
-				if(id < 0)
-				{
-					halt(400, "Bad Request");
-				}
-				
-				try
-				{
-					DatabaseHandler handler = new DatabaseHandler(settings);			
-					handler.deleteCategory(id);			
+		// Payment
+		// Normal
+		get("/payment", new PaymentGet(handler, gson));
+		post("/payment", new PaymentAdd(handler));
+		put("/payment", new PaymentUpdate(handler));
+		delete("/payment", new PaymentDelete(handler));
 
-					return "";
-				}
-				catch(IllegalStateException ex)
-				{
-					halt(500, "Internal Server Error");
-				}
-			}
-			catch(Exception e)
-			{
-				halt(400, "Bad Request");
-			}
-			
-			return "";
-		});
+		// Repeating
+		get("/repeatingpayment/single", new RepeatingPaymentGet(handler, gson));
+		get("/repeatingpayment", new RepeatingPaymentGetAll(handler, gson));
+		post("/repeatingpayment", new RepeatingPaymentAdd(handler));
+		delete("/repeatingpayment", new RepeatingPaymentDelete(handler));
 		
-		/*
-		 * CategoryBudget
-		 */
-		get("/categorybudget", (req, res) -> {
-			
-			if(!req.queryParams().contains("year") || !req.queryParams().contains("month"))
-			{
-				halt(400, "Bad Request");
-			}
-			
-			int year = 0;
-			int month = 0;
-			
-			try
-			{				
-				year = Integer.parseInt(req.queryMap("year").value());
-				month = Integer.parseInt(req.queryMap("month").value());
-				
-				if(year < 0 || month < 1 || month > 12)
-				{
-					halt(400, "Bad Request");
-				}
-				
-				try
-				{
-					DatabaseHandler handler = new DatabaseHandler(settings);			
-					ArrayList<CategoryBudget> categories = handler.getCategoryBudget(year, month);			
-
-					return gson.toJson(categories);
-				}
-				catch(IllegalStateException ex)
-				{
-					halt(500, "Internal Server Error");
-				}
-			}
-			catch(Exception e)
-			{
-				halt(400, "Bad Request");
-			}
-			
-			return null;
-		});
+		// CategoryBudget
+		get("/categorybudget", new CategoryBudgetGet(handler, gson));
 		
-		/*
-		 * Payment
-		 */
-		get("/payment", (req, res) -> {
-			
-			if(!req.queryParams().contains("year") || !req.queryParams().contains("month"))
-			{
-				halt(400, "Bad Request");
-			}
-			
-			int year = 0;
-			int month = 0;
-			
-			try
-			{				
-				year = Integer.parseInt(req.queryMap("year").value());
-				month = Integer.parseInt(req.queryMap("month").value());
-				
-				if(year < 0 || month < 1 || month > 12)
-				{
-					halt(400, "Bad Request");
-				}
-				
-				try
-				{
-					DatabaseHandler handler = new DatabaseHandler(settings);			
-					ArrayList<Payment> payments = handler.getPayments(year, month);			
+		// Rest
+		get("/rest", new RestGet(handler, gson));
 
-					return gson.toJson(payments);
-				}
-				catch(IllegalStateException ex)
-				{
-					halt(500, "Internal Server Error");
-				}
-			}
-			catch(Exception e)
-			{
-				halt(400, "Bad Request");
-			}
-			
-			return null;
+		after((request, response) -> {
+			new RepeatingPaymentUpdater(handler).updateRepeatingPayments();
 		});
 		
-		post("/payment", (req, res) -> {			
-			if(!req.queryParams().contains("amount") || !req.queryParams().contains("date") || !req.queryParams().contains("categoryID") || !req.queryParams().contains("name") || !req.queryParams().contains("repeatInterval") || !req.queryParams().contains("repeatEndDate") || !req.queryParams().contains("repeatMonthDay"))
-			{				
-				halt(400, "Bad Request");
-			}	
-				
-			int amount = 0;
-			int categoryID = 0;
-			int repeatInterval = 0;
-			int repeatMonthDay = 0;
-			
-			try
-			{				
-				amount = Integer.parseInt(req.queryMap("amount").value());
-				categoryID = Integer.parseInt(req.queryMap("categoryID").value());
-				repeatInterval = Integer.parseInt(req.queryMap("repeatInterval").value());
-				repeatMonthDay = Integer.parseInt(req.queryMap("repeatMonthDay").value());
-				
-				try
-				{
-					DatabaseHandler handler = new DatabaseHandler(settings);
-					handler.addPayment(amount, req.queryMap("date").value(), categoryID, req.queryMap("name").value(), repeatInterval, req.queryMap("repeatEndDate").value(), repeatMonthDay);			
-	
-					return "";
-				}
-				catch(IllegalStateException ex)
-				{				
-					halt(500, "Internal Server Error");
-				}
-			}
-			catch(Exception e)
-			{			
-				e.printStackTrace();
-				halt(400, "Bad Request");
-			}
-			
-			return "";
-		});
-		
-		delete("/payment", (req, res) -> {			
-			if(!req.queryParams().contains("id"))
-			{
-				halt(400, "Bad Request");
-			}			
-			
-			int id = -1;		
-			
-			try
-			{				
-				id = Integer.parseInt(req.queryMap("id").value());
-				
-				if(id < 0)
-				{
-					halt(400, "Bad Request");
-				}
-				
-				try
-				{
-					DatabaseHandler handler = new DatabaseHandler(settings);			
-					handler.deletePayment(id);			
-
-					return "";
-				}
-				catch(IllegalStateException ex)
-				{
-					halt(500, "Internal Server Error");
-				}
-			}
-			catch(Exception e)
-			{
-				halt(400, "Bad Request");
-			}
-			
-			return "";
+		Spark.exception(Exception.class, (exception, request, response) -> {
+			Logger.error(exception);
+			exception.printStackTrace();
 		});
 	}
 }
\ No newline at end of file
diff --git a/src/de/deadlocker8/budgetmasterserver/server/category/CategoryAdd.java b/src/de/deadlocker8/budgetmasterserver/server/category/CategoryAdd.java
new file mode 100644
index 0000000000000000000000000000000000000000..c20739e619a6090aacd41e94d79ef9178600cbca
--- /dev/null
+++ b/src/de/deadlocker8/budgetmasterserver/server/category/CategoryAdd.java
@@ -0,0 +1,45 @@
+package de.deadlocker8.budgetmasterserver.server.category;
+
+import static spark.Spark.halt;
+
+import de.deadlocker8.budgetmasterserver.main.DatabaseHandler;
+import javafx.scene.paint.Color;
+import spark.Request;
+import spark.Response;
+import spark.Route;
+
+public class CategoryAdd implements Route
+{
+	private DatabaseHandler handler;
+	
+	public CategoryAdd( DatabaseHandler handler)
+	{	
+		this.handler = handler;
+	}
+
+	@Override
+	public Object handle(Request req, Response res) throws Exception
+	{
+		if(!req.queryParams().contains("name") || !req.queryParams().contains("color"))
+		{
+			halt(400, "Bad Request");
+		}	
+						
+		try
+		{			
+			handler.addCategory(req.queryMap("name").value(), Color.web("#" + req.queryMap("color").value()));			
+
+			return "";
+		}
+		catch(IllegalStateException ex)
+		{				
+			halt(500, "Internal Server Error");
+		}
+		catch(Exception e)
+		{				
+			halt(400, "Bad Request");
+		}
+		
+		return "";
+	}
+}
\ No newline at end of file
diff --git a/src/de/deadlocker8/budgetmasterserver/server/category/CategoryDelete.java b/src/de/deadlocker8/budgetmasterserver/server/category/CategoryDelete.java
new file mode 100644
index 0000000000000000000000000000000000000000..3a0088e2a9205c1d5b786d0b6e9782b3a3d1edca
--- /dev/null
+++ b/src/de/deadlocker8/budgetmasterserver/server/category/CategoryDelete.java
@@ -0,0 +1,56 @@
+package de.deadlocker8.budgetmasterserver.server.category;
+
+import static spark.Spark.halt;
+
+import de.deadlocker8.budgetmasterserver.main.DatabaseHandler;
+import spark.Request;
+import spark.Response;
+import spark.Route;
+
+public class CategoryDelete implements Route
+{
+	private DatabaseHandler handler;
+	
+	public CategoryDelete(DatabaseHandler handler)
+	{	
+		this.handler = handler;
+	}
+
+	@Override
+	public Object handle(Request req, Response res) throws Exception
+	{
+		if(!req.queryParams().contains("id"))
+		{
+			halt(400, "Bad Request");
+		}			
+		
+		int id = -1;		
+		
+		try
+		{				
+			id = Integer.parseInt(req.queryMap("id").value());
+			
+			if(id < 0)
+			{
+				halt(400, "Bad Request");
+			}
+			
+			try
+			{							
+				handler.deleteCategory(id);			
+
+				return "";
+			}
+			catch(IllegalStateException ex)
+			{
+				halt(500, "Internal Server Error");
+			}
+		}
+		catch(Exception e)
+		{
+			halt(400, "Bad Request");
+		}
+		
+		return "";
+	}
+}
\ No newline at end of file
diff --git a/src/de/deadlocker8/budgetmasterserver/server/category/CategoryGet.java b/src/de/deadlocker8/budgetmasterserver/server/category/CategoryGet.java
new file mode 100644
index 0000000000000000000000000000000000000000..55953ad73dd19db8f21cc266fc44908d3b4d6041
--- /dev/null
+++ b/src/de/deadlocker8/budgetmasterserver/server/category/CategoryGet.java
@@ -0,0 +1,61 @@
+package de.deadlocker8.budgetmasterserver.server.category;
+
+import static spark.Spark.halt;
+
+import com.google.gson.Gson;
+
+import de.deadlocker8.budgetmaster.logic.Category;
+import de.deadlocker8.budgetmasterserver.main.DatabaseHandler;
+import spark.Request;
+import spark.Response;
+import spark.Route;
+
+public class CategoryGet implements Route
+{
+	private DatabaseHandler handler;
+	private Gson gson;
+
+	public CategoryGet(DatabaseHandler handler, Gson gson)
+	{
+		this.handler = handler;
+		this.gson = gson;
+	}
+
+	@Override
+	public Object handle(Request req, Response res) throws Exception
+	{
+		if(!req.queryParams().contains("id"))
+		{
+			halt(400, "Bad Request");
+		}
+
+		int id = -1;
+
+		try
+		{
+			id = Integer.parseInt(req.queryMap("id").value());
+
+			if(id < 0)
+			{
+				halt(400, "Bad Request");
+			}
+
+			try
+			{
+				Category categeory = handler.getCategory(id);
+
+				return gson.toJson(categeory);
+			}
+			catch(IllegalStateException e)
+			{
+				e.printStackTrace();
+				halt(500, "Internal Server Error");
+			}
+		}
+		catch(Exception e)
+		{
+			halt(400, "Bad Request");
+		}
+		return null;
+	}
+}
\ No newline at end of file
diff --git a/src/de/deadlocker8/budgetmasterserver/server/category/CategoryGetAll.java b/src/de/deadlocker8/budgetmasterserver/server/category/CategoryGetAll.java
new file mode 100644
index 0000000000000000000000000000000000000000..75a921947320ca5ff99c070aeabaf8441a89cd08
--- /dev/null
+++ b/src/de/deadlocker8/budgetmasterserver/server/category/CategoryGetAll.java
@@ -0,0 +1,41 @@
+package de.deadlocker8.budgetmasterserver.server.category;
+
+import static spark.Spark.halt;
+
+import java.util.ArrayList;
+
+import com.google.gson.Gson;
+
+import de.deadlocker8.budgetmaster.logic.Category;
+import de.deadlocker8.budgetmasterserver.main.DatabaseHandler;
+import spark.Request;
+import spark.Response;
+import spark.Route;
+
+public class CategoryGetAll implements Route
+{
+	private DatabaseHandler handler;
+	private Gson gson;
+
+	public CategoryGetAll(DatabaseHandler handler, Gson gson)
+	{
+		this.handler = handler;
+		this.gson = gson;
+	}
+
+	@Override
+	public Object handle(Request req, Response res) throws Exception
+	{
+		try
+		{	
+			ArrayList<Category> categories = handler.getCategories();			
+
+			return gson.toJson(categories);
+		}
+		catch(IllegalStateException e)
+		{
+			halt(500, "Internal Server Error");
+		}	
+		return null;
+	}
+}
\ No newline at end of file
diff --git a/src/de/deadlocker8/budgetmasterserver/server/category/CategoryUpdate.java b/src/de/deadlocker8/budgetmasterserver/server/category/CategoryUpdate.java
new file mode 100644
index 0000000000000000000000000000000000000000..315199436e410d4d7c8bfd114fa030ae6d033e33
--- /dev/null
+++ b/src/de/deadlocker8/budgetmasterserver/server/category/CategoryUpdate.java
@@ -0,0 +1,57 @@
+package de.deadlocker8.budgetmasterserver.server.category;
+
+import static spark.Spark.halt;
+
+import de.deadlocker8.budgetmasterserver.main.DatabaseHandler;
+import javafx.scene.paint.Color;
+import spark.Request;
+import spark.Response;
+import spark.Route;
+
+public class CategoryUpdate implements Route
+{
+	private DatabaseHandler handler;
+
+	public CategoryUpdate(DatabaseHandler handler)
+	{		
+		this.handler = handler;
+	}
+
+	@Override
+	public Object handle(Request req, Response res) throws Exception
+	{
+		if(!req.queryParams().contains("id") ||!req.queryParams().contains("name") || !req.queryParams().contains("color"))
+		{
+			halt(400, "Bad Request");
+		}	
+		
+		int id = -1;		
+		
+		try
+		{				
+			id = Integer.parseInt(req.queryMap("id").value());
+			
+			if(id < 0)
+			{
+				halt(400, "Bad Request");
+			}
+			
+			try
+			{				
+				handler.updateCategory(id, req.queryMap("name").value(), Color.web("#" + req.queryMap("color").value()));			
+
+				return "";
+			}
+			catch(IllegalStateException ex)
+			{				
+				halt(500, "Internal Server Error");
+			}
+		}		
+		catch(Exception e)
+		{
+			halt(400, "Bad Request");
+		}
+		
+		return "";
+	}
+}
\ No newline at end of file
diff --git a/src/de/deadlocker8/budgetmasterserver/server/categorybudget/CategoryBudgetGet.java b/src/de/deadlocker8/budgetmasterserver/server/categorybudget/CategoryBudgetGet.java
new file mode 100644
index 0000000000000000000000000000000000000000..0b0859c69771c6405bf01921b09e09928f6ea535
--- /dev/null
+++ b/src/de/deadlocker8/budgetmasterserver/server/categorybudget/CategoryBudgetGet.java
@@ -0,0 +1,112 @@
+package de.deadlocker8.budgetmasterserver.server.categorybudget;
+
+import static spark.Spark.halt;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Iterator;
+
+import com.google.gson.Gson;
+
+import de.deadlocker8.budgetmaster.logic.Category;
+import de.deadlocker8.budgetmaster.logic.CategoryBudget;
+import de.deadlocker8.budgetmaster.logic.Payment;
+import de.deadlocker8.budgetmasterserver.main.DatabaseHandler;
+import spark.Request;
+import spark.Response;
+import spark.Route;
+
+public class CategoryBudgetGet implements Route
+{
+	private DatabaseHandler handler;
+	private Gson gson;
+
+	public CategoryBudgetGet(DatabaseHandler handler, Gson gson)
+	{
+		this.handler = handler;
+		this.gson = gson;
+	}
+
+	@Override
+	public Object handle(Request req, Response res) throws Exception
+	{
+		if(!req.queryParams().contains("year") || !req.queryParams().contains("month"))
+		{
+			halt(400, "Bad Request");
+		}
+		
+		int year = 0;
+		int month = 0;
+		
+		try
+		{				
+			year = Integer.parseInt(req.queryMap("year").value());
+			month = Integer.parseInt(req.queryMap("month").value());
+			
+			if(year < 0 || month < 1 || month > 12)
+			{
+				halt(400, "Bad Request");
+			}
+			
+			try
+			{	
+				ArrayList<Payment> payments = new ArrayList<>();
+				payments.addAll(handler.getPayments(year, month));
+				payments.addAll(handler.getRepeatingPayments(year, month));			
+				Collections.sort(payments, new Comparator<Payment>() {
+			        @Override
+			        public int compare(Payment payment1, Payment payment2)
+			        {
+			            return  payment2.getDate().compareTo(payment1.getDate());
+			        }
+			    });	
+				
+				ArrayList<CategoryBudget> budgets = new ArrayList<>();
+				
+				for(Category currentCategory : handler.getCategories())
+				{
+					budgets.add(new CategoryBudget(currentCategory.getName(), currentCategory.getColor(), 0));
+					CategoryBudget currentBudget = budgets.get(budgets.size() - 1);
+					for(Payment currentPayment : payments)
+					{					
+						if(currentCategory.getID() == currentPayment.getCategoryID())
+						{
+							currentBudget.setBudget(currentBudget.getBudget() + currentPayment.getAmount());
+						}						
+					}
+				}
+				
+				//filter empty categories
+				Iterator<CategoryBudget> iterator = budgets.iterator();
+				while(iterator.hasNext())
+				{		
+					if(iterator.next().getBudget() == 0)
+					{
+						iterator.remove();
+					}
+				}
+				
+				Collections.sort(budgets, new Comparator<CategoryBudget>() {
+			        @Override
+			        public int compare(CategoryBudget budget1, CategoryBudget budget2)
+			        {
+			            return  Double.compare(budget1.getBudget(), budget2.getBudget());
+			        }
+			    });		
+				
+				return gson.toJson(budgets);
+			}
+			catch(IllegalStateException ex)
+			{
+				halt(500, "Internal Server Error");
+			}
+		}
+		catch(Exception e)
+		{
+			halt(400, "Bad Request");
+		}
+		
+		return null;
+	}
+}
\ No newline at end of file
diff --git a/src/de/deadlocker8/budgetmasterserver/server/payment/normal/PaymentAdd.java b/src/de/deadlocker8/budgetmasterserver/server/payment/normal/PaymentAdd.java
new file mode 100644
index 0000000000000000000000000000000000000000..07fdabe48fea944786f0033cbbacbd7f29f2baa6
--- /dev/null
+++ b/src/de/deadlocker8/budgetmasterserver/server/payment/normal/PaymentAdd.java
@@ -0,0 +1,54 @@
+package de.deadlocker8.budgetmasterserver.server.payment.normal;
+
+import static spark.Spark.halt;
+
+import de.deadlocker8.budgetmasterserver.main.DatabaseHandler;
+import spark.Request;
+import spark.Response;
+import spark.Route;
+
+public class PaymentAdd implements Route
+{
+	private DatabaseHandler handler;
+	
+	public PaymentAdd(DatabaseHandler handler)
+	{	
+		this.handler = handler;
+	}
+
+	@Override
+	public Object handle(Request req, Response res) throws Exception
+	{
+		if(!req.queryParams().contains("amount") || !req.queryParams().contains("date") || !req.queryParams().contains("categoryID") || !req.queryParams().contains("name"))
+		{				
+			halt(400, "Bad Request");
+		}	
+			
+		int amount = 0;
+		int categoryID = 0;			
+		
+		try
+		{				
+			amount = Integer.parseInt(req.queryMap("amount").value());
+			categoryID = Integer.parseInt(req.queryMap("categoryID").value());				
+			
+			try
+			{			
+				handler.addNormalPayment(amount, req.queryMap("date").value(), categoryID, req.queryMap("name").value());			
+
+				return "";
+			}
+			catch(IllegalStateException ex)
+			{				
+				halt(500, "Internal Server Error");
+			}
+		}
+		catch(Exception e)
+		{			
+			e.printStackTrace();
+			halt(400, "Bad Request");
+		}
+		
+		return "";
+	}
+}
\ No newline at end of file
diff --git a/src/de/deadlocker8/budgetmasterserver/server/payment/normal/PaymentDelete.java b/src/de/deadlocker8/budgetmasterserver/server/payment/normal/PaymentDelete.java
new file mode 100644
index 0000000000000000000000000000000000000000..0933a3ba5a32f45ea6f1edc0cbaf577efe2f9083
--- /dev/null
+++ b/src/de/deadlocker8/budgetmasterserver/server/payment/normal/PaymentDelete.java
@@ -0,0 +1,56 @@
+package de.deadlocker8.budgetmasterserver.server.payment.normal;
+
+import static spark.Spark.halt;
+
+import de.deadlocker8.budgetmasterserver.main.DatabaseHandler;
+import spark.Request;
+import spark.Response;
+import spark.Route;
+
+public class PaymentDelete implements Route
+{
+	private DatabaseHandler handler;
+	
+	public PaymentDelete(DatabaseHandler handler)
+	{		
+		this.handler = handler;
+	}
+
+	@Override
+	public Object handle(Request req, Response res) throws Exception
+	{
+		if(!req.queryParams().contains("id"))
+		{
+			halt(400, "Bad Request");
+		}			
+		
+		int id = -1;		
+		
+		try
+		{				
+			id = Integer.parseInt(req.queryMap("id").value());
+			
+			if(id < 0)
+			{
+				halt(400, "Bad Request");
+			}
+			
+			try
+			{						
+				handler.deletePayment(id);			
+
+				return "";
+			}
+			catch(IllegalStateException ex)
+			{
+				halt(500, "Internal Server Error");
+			}
+		}
+		catch(Exception e)
+		{
+			halt(400, "Bad Request");
+		}
+		
+		return "";
+	}
+}
\ No newline at end of file
diff --git a/src/de/deadlocker8/budgetmasterserver/server/payment/normal/PaymentGet.java b/src/de/deadlocker8/budgetmasterserver/server/payment/normal/PaymentGet.java
new file mode 100644
index 0000000000000000000000000000000000000000..dcaab7e845fcd85d0aa9238e29367689d047df24
--- /dev/null
+++ b/src/de/deadlocker8/budgetmasterserver/server/payment/normal/PaymentGet.java
@@ -0,0 +1,66 @@
+package de.deadlocker8.budgetmasterserver.server.payment.normal;
+
+import static spark.Spark.halt;
+
+import java.util.ArrayList;
+
+import com.google.gson.Gson;
+
+import de.deadlocker8.budgetmaster.logic.NormalPayment;
+import de.deadlocker8.budgetmasterserver.main.DatabaseHandler;
+import spark.Request;
+import spark.Response;
+import spark.Route;
+
+public class PaymentGet implements Route
+{
+	private DatabaseHandler handler;
+	private Gson gson;
+
+	public PaymentGet(DatabaseHandler handler, Gson gson)
+	{
+		this.handler = handler;
+		this.gson = gson;
+	}
+
+	@Override
+	public Object handle(Request req, Response res) throws Exception
+	{
+		if(!req.queryParams().contains("year") || !req.queryParams().contains("month"))
+		{
+			halt(400, "Bad Request");
+		}
+		
+		int year = 0;
+		int month = 0;
+		
+		try
+		{				
+			year = Integer.parseInt(req.queryMap("year").value());
+			month = Integer.parseInt(req.queryMap("month").value());
+			
+			if(year < 0 || month < 1 || month > 12)
+			{
+				halt(400, "Bad Request");
+			}
+			
+			try
+			{				
+				ArrayList<NormalPayment> payments = new ArrayList<>();				
+				payments.addAll(handler.getPayments(year, month));	
+				
+				return gson.toJson(payments);
+			}
+			catch(IllegalStateException ex)
+			{
+				halt(500, "Internal Server Error");
+			}
+		}
+		catch(Exception e)
+		{
+			halt(400, "Bad Request");
+		}
+		
+		return null;
+	}
+}
\ No newline at end of file
diff --git a/src/de/deadlocker8/budgetmasterserver/server/payment/normal/PaymentUpdate.java b/src/de/deadlocker8/budgetmasterserver/server/payment/normal/PaymentUpdate.java
new file mode 100644
index 0000000000000000000000000000000000000000..36e8368dd55fd1c5bd9a6661bb685981157d1b2c
--- /dev/null
+++ b/src/de/deadlocker8/budgetmasterserver/server/payment/normal/PaymentUpdate.java
@@ -0,0 +1,60 @@
+package de.deadlocker8.budgetmasterserver.server.payment.normal;
+
+import static spark.Spark.halt;
+
+import de.deadlocker8.budgetmasterserver.main.DatabaseHandler;
+import spark.Request;
+import spark.Response;
+import spark.Route;
+
+public class PaymentUpdate implements Route
+{
+	private DatabaseHandler handler;
+	
+	public PaymentUpdate(DatabaseHandler handler)
+	{		
+		this.handler = handler;
+	}
+
+	@Override
+	public Object handle(Request req, Response res) throws Exception
+	{
+		if(!req.queryParams().contains("id") ||!req.queryParams().contains("amount") || !req.queryParams().contains("date") || !req.queryParams().contains("categoryID") || !req.queryParams().contains("name"))
+		{
+			halt(400, "Bad Request");
+		}	
+		
+		int id = -1;
+		int amount = 0;
+		int categoryID = -1;
+		
+		try
+		{				
+			id = Integer.parseInt(req.queryMap("id").value());
+			amount = Integer.parseInt(req.queryMap("amount").value());
+			categoryID = Integer.parseInt(req.queryMap("categoryID").value());
+			
+			if(id < 0)
+			{
+				halt(400, "Bad Request");
+			}
+			
+			try
+			{				
+				handler.updateNormalPayment(id, amount, req.queryMap("date").value(), categoryID, req.queryMap("name").value());			
+
+				return "";
+			}
+			catch(IllegalStateException ex)
+			{				
+				halt(500, "Internal Server Error");
+			}
+		}		
+		catch(Exception e)
+		{
+			halt(400, "Bad Request");
+		}
+		
+		return "";
+	}
+}
\ No newline at end of file
diff --git a/src/de/deadlocker8/budgetmasterserver/server/payment/repeating/RepeatingPaymentAdd.java b/src/de/deadlocker8/budgetmasterserver/server/payment/repeating/RepeatingPaymentAdd.java
new file mode 100644
index 0000000000000000000000000000000000000000..9480cb85c99e48bcee789d5c160c99d8f0ecd49b
--- /dev/null
+++ b/src/de/deadlocker8/budgetmasterserver/server/payment/repeating/RepeatingPaymentAdd.java
@@ -0,0 +1,58 @@
+package de.deadlocker8.budgetmasterserver.server.payment.repeating;
+
+import static spark.Spark.halt;
+
+import de.deadlocker8.budgetmasterserver.main.DatabaseHandler;
+import spark.Request;
+import spark.Response;
+import spark.Route;
+
+public class RepeatingPaymentAdd implements Route
+{
+	private DatabaseHandler handler;
+	
+	public RepeatingPaymentAdd(DatabaseHandler handler)
+	{		
+		this.handler = handler;
+	}
+
+	@Override
+	public Object handle(Request req, Response res) throws Exception
+	{
+		if(!req.queryParams().contains("amount") || !req.queryParams().contains("date") || !req.queryParams().contains("categoryID") || !req.queryParams().contains("name") || !req.queryParams().contains("repeatInterval") || !req.queryParams().contains("repeatEndDate") || !req.queryParams().contains("repeatMonthDay"))
+		{				
+			halt(400, "Bad Request");
+		}	
+			
+		int amount = 0;
+		int categoryID = 0;
+		int repeatInterval = 0;
+		int repeatMonthDay = 0;
+		
+		try
+		{				
+			amount = Integer.parseInt(req.queryMap("amount").value());
+			categoryID = Integer.parseInt(req.queryMap("categoryID").value());
+			repeatInterval = Integer.parseInt(req.queryMap("repeatInterval").value());
+			repeatMonthDay = Integer.parseInt(req.queryMap("repeatMonthDay").value());
+			
+			try
+			{				
+				handler.addRepeatingPayment(amount, req.queryMap("date").value(), categoryID, req.queryMap("name").value(), repeatInterval, req.queryMap("repeatEndDate").value(), repeatMonthDay);			
+
+				return "";
+			}
+			catch(IllegalStateException ex)
+			{				
+				halt(500, "Internal Server Error");
+			}
+		}
+		catch(Exception e)
+		{			
+			e.printStackTrace();
+			halt(400, "Bad Request");
+		}
+		
+		return "";
+	}
+}
\ No newline at end of file
diff --git a/src/de/deadlocker8/budgetmasterserver/server/payment/repeating/RepeatingPaymentDelete.java b/src/de/deadlocker8/budgetmasterserver/server/payment/repeating/RepeatingPaymentDelete.java
new file mode 100644
index 0000000000000000000000000000000000000000..b2b480c5d81f263a27b4340cf4f1616449d72df0
--- /dev/null
+++ b/src/de/deadlocker8/budgetmasterserver/server/payment/repeating/RepeatingPaymentDelete.java
@@ -0,0 +1,56 @@
+package de.deadlocker8.budgetmasterserver.server.payment.repeating;
+
+import static spark.Spark.halt;
+
+import de.deadlocker8.budgetmasterserver.main.DatabaseHandler;
+import spark.Request;
+import spark.Response;
+import spark.Route;
+
+public class RepeatingPaymentDelete implements Route
+{
+	private DatabaseHandler handler;
+	
+	public RepeatingPaymentDelete(DatabaseHandler handler)
+	{
+		this.handler = handler;
+	}
+
+	@Override
+	public Object handle(Request req, Response res) throws Exception
+	{
+		if(!req.queryParams().contains("id"))
+		{
+			halt(400, "Bad Request");
+		}			
+		
+		int id = -1;		
+		
+		try
+		{				
+			id = Integer.parseInt(req.queryMap("id").value());
+			
+			if(id < 0)
+			{
+				halt(400, "Bad Request");
+			}
+			
+			try
+			{					
+				handler.deleteRepeatingPayment(id);			
+
+				return "";
+			}
+			catch(IllegalStateException ex)
+			{
+				halt(500, "Internal Server Error");
+			}
+		}
+		catch(Exception e)
+		{
+			halt(400, "Bad Request");
+		}
+		
+		return "";
+	}
+}
\ No newline at end of file
diff --git a/src/de/deadlocker8/budgetmasterserver/server/payment/repeating/RepeatingPaymentGet.java b/src/de/deadlocker8/budgetmasterserver/server/payment/repeating/RepeatingPaymentGet.java
new file mode 100644
index 0000000000000000000000000000000000000000..fc6e13d84f23a612fbf0cc3c05fd9d66add7c6b4
--- /dev/null
+++ b/src/de/deadlocker8/budgetmasterserver/server/payment/repeating/RepeatingPaymentGet.java
@@ -0,0 +1,61 @@
+package de.deadlocker8.budgetmasterserver.server.payment.repeating;
+
+import static spark.Spark.halt;
+
+import com.google.gson.Gson;
+
+import de.deadlocker8.budgetmaster.logic.RepeatingPayment;
+import de.deadlocker8.budgetmasterserver.main.DatabaseHandler;
+import spark.Request;
+import spark.Response;
+import spark.Route;
+
+public class RepeatingPaymentGet implements Route
+{
+	private DatabaseHandler handler;
+	private Gson gson;
+	
+	public RepeatingPaymentGet(DatabaseHandler handler, Gson gson)
+	{
+		this.handler = handler;
+		this.gson = gson;
+	}
+	
+	@Override
+	public Object handle(Request req, Response res) throws Exception
+	{
+		if(!req.queryParams().contains("id"))
+		{
+			halt(400, "Bad Request");
+		}			
+		
+		int id = -1;		
+		
+		try
+		{				
+			id = Integer.parseInt(req.queryMap("id").value());
+			
+			if(id < 0)
+			{
+				halt(400, "Bad Request");
+			}
+			
+			try
+			{					
+				RepeatingPayment payment = handler.getRepeatingPayment(id);			
+
+				return gson.toJson(payment);
+			}
+			catch(IllegalStateException ex)
+			{
+				halt(500, "Internal Server Error");
+			}
+		}
+		catch(Exception e)
+		{
+			halt(400, "Bad Request");
+		}
+		
+		return "";
+	}
+}
\ No newline at end of file
diff --git a/src/de/deadlocker8/budgetmasterserver/server/payment/repeating/RepeatingPaymentGetAll.java b/src/de/deadlocker8/budgetmasterserver/server/payment/repeating/RepeatingPaymentGetAll.java
new file mode 100644
index 0000000000000000000000000000000000000000..0d1551c5b864179033bfc4a23245dfad80a77448
--- /dev/null
+++ b/src/de/deadlocker8/budgetmasterserver/server/payment/repeating/RepeatingPaymentGetAll.java
@@ -0,0 +1,66 @@
+package de.deadlocker8.budgetmasterserver.server.payment.repeating;
+
+import static spark.Spark.halt;
+
+import java.util.ArrayList;
+
+import com.google.gson.Gson;
+
+import de.deadlocker8.budgetmaster.logic.RepeatingPaymentEntry;
+import de.deadlocker8.budgetmasterserver.main.DatabaseHandler;
+import spark.Request;
+import spark.Response;
+import spark.Route;
+
+public class RepeatingPaymentGetAll implements Route
+{
+	private DatabaseHandler handler;
+	private Gson gson;
+
+	public RepeatingPaymentGetAll(DatabaseHandler handler, Gson gson)
+	{		
+		this.handler = handler;
+		this.gson = gson;
+	}
+	
+	@Override
+	public Object handle(Request req, Response res) throws Exception
+	{
+		if(!req.queryParams().contains("year") || !req.queryParams().contains("month"))
+		{
+			halt(400, "Bad Request");
+		}
+		
+		int year = 0;
+		int month = 0;
+		
+		try
+		{				
+			year = Integer.parseInt(req.queryMap("year").value());
+			month = Integer.parseInt(req.queryMap("month").value());
+			
+			if(year < 0 || month < 1 || month > 12)
+			{
+				halt(400, "Bad Request");
+			}
+			
+			try
+			{					
+				ArrayList<RepeatingPaymentEntry> payments = new ArrayList<>();				
+				payments.addAll(handler.getRepeatingPayments(year, month));	
+				
+				return gson.toJson(payments);
+			}
+			catch(IllegalStateException ex)
+			{
+				halt(500, "Internal Server Error");
+			}
+		}
+		catch(Exception e)
+		{
+			halt(400, "Bad Request");
+		}
+		
+		return null;
+	}
+}
\ No newline at end of file
diff --git a/src/de/deadlocker8/budgetmasterserver/server/rest/RestGet.java b/src/de/deadlocker8/budgetmasterserver/server/rest/RestGet.java
new file mode 100644
index 0000000000000000000000000000000000000000..0962749b594c2111f93c633685446494585704b7
--- /dev/null
+++ b/src/de/deadlocker8/budgetmasterserver/server/rest/RestGet.java
@@ -0,0 +1,62 @@
+package de.deadlocker8.budgetmasterserver.server.rest;
+
+import static spark.Spark.halt;
+
+import com.google.gson.Gson;
+
+import de.deadlocker8.budgetmasterserver.main.DatabaseHandler;
+import spark.Request;
+import spark.Response;
+import spark.Route;
+
+public class RestGet implements Route
+{
+	private DatabaseHandler handler;
+	private Gson gson;
+
+	public RestGet(DatabaseHandler handler, Gson gson)
+	{
+		this.handler = handler;
+		this.gson = gson;
+	}
+
+	@Override
+	public Object handle(Request req, Response res) throws Exception
+	{
+		if(!req.queryParams().contains("year") || !req.queryParams().contains("month"))
+		{
+			halt(400, "Bad Request");
+		}
+		
+		int year = 0;
+		int month = 0;
+		
+		try
+		{				
+			year = Integer.parseInt(req.queryMap("year").value());
+			month = Integer.parseInt(req.queryMap("month").value());
+			
+			if(year < 0 || month < 1 || month > 12)
+			{
+				halt(400, "Bad Request");
+			}
+			
+			try
+			{			
+				int rest = handler.getRestForAllPreviousMonths(year, month);	
+				
+				return gson.toJson(rest);
+			}
+			catch(IllegalStateException ex)
+			{
+				halt(500, "Internal Server Error");
+			}
+		}
+		catch(Exception e)
+		{
+			halt(400, "Bad Request");
+		}
+		
+		return null;
+	}
+}
\ No newline at end of file
diff --git a/src/de/deadlocker8/budgetmasterserver/server/updater/RepeatingPaymentUpdater.java b/src/de/deadlocker8/budgetmasterserver/server/updater/RepeatingPaymentUpdater.java
new file mode 100644
index 0000000000000000000000000000000000000000..facd9aaf152d1e6a7b1dba4af98737cd8f5201b6
--- /dev/null
+++ b/src/de/deadlocker8/budgetmasterserver/server/updater/RepeatingPaymentUpdater.java
@@ -0,0 +1,101 @@
+package de.deadlocker8.budgetmasterserver.server.updater;
+
+import java.util.ArrayList;
+
+import org.joda.time.DateTime;
+import org.joda.time.Days;
+import org.joda.time.Months;
+
+import de.deadlocker8.budgetmaster.logic.LatestRepeatingPayment;
+import de.deadlocker8.budgetmaster.logic.RepeatingPayment;
+import de.deadlocker8.budgetmasterserver.main.DatabaseHandler;
+import logger.Logger;
+
+public class RepeatingPaymentUpdater
+{
+	private DatabaseHandler handler;
+	
+	public RepeatingPaymentUpdater(DatabaseHandler handler)
+	{
+		this.handler = handler;
+	}
+
+	public void updateRepeatingPayments()
+	{
+		try
+		{						
+			ArrayList<RepeatingPayment> repeatingPayments = handler.getAllRepeatingPayments();				
+			ArrayList<LatestRepeatingPayment> latest = handler.getLatestRepeatingPaymentEntries();;
+			
+			for(RepeatingPayment currentPayment : repeatingPayments)
+			{
+				int index = latest.indexOf(currentPayment);	
+				DateTime now = DateTime.now();			
+				if(currentPayment.getRepeatEndDate() != null)
+				{
+					DateTime endDate = DateTime.parse(currentPayment.getRepeatEndDate());
+					if(endDate.isBefore(now))
+					{
+						now = endDate;
+					}
+				}
+				ArrayList<DateTime> correctDates = getCorrectRepeatingDates(currentPayment, now);				
+				if(index != -1)
+				{
+					LatestRepeatingPayment currentLatest = latest.get(index);					
+					DateTime latestDate = DateTime.parse(currentLatest.getLastDate());	
+					
+					for(int i = correctDates.size()-1; i > 0; i--)
+					{
+						DateTime currentDate = correctDates.get(i);
+						if(currentDate.isBefore(latestDate) || currentDate.isEqual(latestDate))
+						{
+							break;
+						}
+						
+						handler.addRepeatingPaymentEntry(currentLatest.getRepeatingPaymentID(), currentDate.toString("yyyy-MM-dd"));
+					}
+				}
+				else
+				{
+					for(DateTime currentDate : correctDates)
+					{
+						handler.addRepeatingPaymentEntry(currentPayment.getID(), currentDate.toString("yyyy-MM-dd"));
+					}
+				}
+			}
+		}
+		catch(IllegalStateException ex)
+		{
+			Logger.error(ex);
+		}
+	}
+	
+	private ArrayList<DateTime> getCorrectRepeatingDates(RepeatingPayment payment, DateTime now)
+	{
+		ArrayList<DateTime> dates = new ArrayList<>();
+		DateTime startDate = DateTime.parse(payment.getDate());
+		
+		//repeat every x days
+		if(payment.getRepeatInterval() != 0)
+		{			
+			int numberOfDays = Days.daysBetween(startDate, now).getDays();
+			int occurrences = numberOfDays % payment.getRepeatInterval();
+			for(int i = 0; i <= occurrences + 1; i++)
+			{
+				dates.add(startDate.plusDays(i * payment.getRepeatInterval()));
+			}
+		}
+		//repeat every month on day x
+		else
+		{
+			int numberOfMonths = Months.monthsBetween(startDate.withDayOfMonth(payment.getRepeatMonthDay()), now).getMonths();
+			for(int i = 0; i <= numberOfMonths; i++)
+			{
+				dates.add(startDate.plusMonths(i));
+			}				
+		}
+		
+		return dates;
+	}
+}
\ No newline at end of file