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