/*
- * Copyright © 2019 Damyan Ivanov.
+ * Copyright © 2020 Damyan Ivanov.
* This file is part of MoLe.
* MoLe is free software: you can distribute it and/or modify it
* under the term of the GNU General Public License as published by
import net.ktnx.mobileledger.utils.Globals;
import net.ktnx.mobileledger.utils.Logger;
import net.ktnx.mobileledger.utils.NetworkUtil;
+import net.ktnx.mobileledger.utils.SimpleDate;
import net.ktnx.mobileledger.utils.UrlEncodedFormData;
import java.io.BufferedReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.nio.charset.StandardCharsets;
-import java.util.Date;
-import java.util.GregorianCalendar;
import java.util.List;
import java.util.Locale;
import java.util.Map;
if (token != null)
params.addPair("_token", token);
- Date transactionDate = ltr.getDate();
+ SimpleDate transactionDate = ltr.getDate();
if (transactionDate == null) {
- transactionDate = new GregorianCalendar().getTime();
+ transactionDate = SimpleDate.today();
}
params.addPair("date", Globals.formatLedgerDate(transactionDate));
/*
- * Copyright © 2019 Damyan Ivanov.
+ * Copyright © 2020 Damyan Ivanov.
* This file is part of MoLe.
* MoLe is free software: you can distribute it and/or modify it
* under the term of the GNU General Public License as published by
import net.ktnx.mobileledger.model.LedgerTransaction;
import net.ktnx.mobileledger.model.MobileLedgerProfile;
import net.ktnx.mobileledger.model.TransactionListItem;
-import net.ktnx.mobileledger.utils.Globals;
+import net.ktnx.mobileledger.utils.SimpleDate;
-import java.text.ParseException;
import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.Date;
import static net.ktnx.mobileledger.utils.Logger.debug;
String[] params;
if (filterAccName[0] == null) {
- sql = "SELECT id, date FROM transactions WHERE profile=? ORDER BY date desc, id " +
- "desc";
+ sql = "SELECT id, year, month, day FROM transactions WHERE profile=? ORDER BY " +
+ "year desc, month desc, day desc, id desc";
params = new String[]{profile_uuid};
}
else {
- sql = "SELECT distinct tr.id, tr.date from transactions tr JOIN " +
- "transaction_accounts ta " +
+ sql = "SELECT distinct tr.id, tr.year, tr.month, tr.day from transactions tr " +
+ "JOIN " + "transaction_accounts ta " +
"ON ta.transaction_id=tr.id AND ta.profile=tr.profile WHERE tr.profile=? " +
"and ta.account_name LIKE ?||'%' AND ta" +
- ".amount <> 0 ORDER BY tr.date desc, tr.id desc";
+ ".amount <> 0 ORDER BY tr.year desc, tr.month desc, tr.day desc, tr.id " +
+ "desc";
params = new String[]{profile_uuid, filterAccName[0]};
}
debug("UTT", sql);
SQLiteDatabase db = App.getDatabase();
- String lastDateString = Globals.formatLedgerDate(new Date());
- Calendar lastDate = Globals.parseLedgerDateAsCalendar(lastDateString);
boolean odd = true;
+ SimpleDate lastDate = SimpleDate.today();
try (Cursor cursor = db.rawQuery(sql, params)) {
while (cursor.moveToNext()) {
if (isCancelled())
return null;
int transaction_id = cursor.getInt(0);
- String dateString = cursor.getString(1);
- Calendar date = Globals.parseLedgerDateAsCalendar(dateString);
+ SimpleDate date =
+ new SimpleDate(cursor.getInt(1), cursor.getInt(2), cursor.getInt(3));
- if (!lastDateString.equals(dateString)) {
+ if (!date.equals(lastDate)) {
boolean showMonth =
- (date.get(Calendar.MONTH) != lastDate.get(Calendar.MONTH)) ||
- (date.get(Calendar.YEAR) != lastDate.get(Calendar.YEAR));
- newList.add(new TransactionListItem(date.getTime(), showMonth));
+ (date.month != lastDate.month) || (date.year != lastDate.year);
+ newList.add(new TransactionListItem(date, showMonth));
}
newList.add(
new TransactionListItem(new LedgerTransaction(transaction_id), odd));
// debug("UTT", String.format("got transaction %d", transaction_id));
lastDate = date;
- lastDateString = dateString;
odd = !odd;
}
Data.transactions.setList(newList);
return null;
}
- catch (ParseException e) {
- return String.format("Error parsing stored date '%s'", e.getMessage());
- }
finally {
Data.backgroundTaskFinished();
}
/*
- * Copyright © 2019 Damyan Ivanov.
+ * Copyright © 2020 Damyan Ivanov.
* This file is part of MoLe.
* MoLe is free software: you can distribute it and/or modify it
* under the term of the GNU General Public License as published by
import net.ktnx.mobileledger.model.LedgerTransactionAccount;
import net.ktnx.mobileledger.utils.Globals;
import net.ktnx.mobileledger.utils.Misc;
+import net.ktnx.mobileledger.utils.SimpleDate;
import java.text.ParseException;
import java.util.ArrayList;
-import java.util.Date;
-import java.util.GregorianCalendar;
import java.util.List;
@JsonIgnoreProperties(ignoreUnknown = true)
}
result.setTpostings(postings);
- Date transactionDate = tr.getDate();
+ SimpleDate transactionDate = tr.getDate();
if (transactionDate == null) {
- transactionDate = new GregorianCalendar().getTime();
+ transactionDate = SimpleDate.today();
}
result.setTdate(Globals.formatIsoDate(transactionDate));
result.setTdate2(null);
tpostings.add(posting);
}
public LedgerTransaction asLedgerTransaction() throws ParseException {
- Date date = Globals.parseIsoDate(tdate);
+ SimpleDate date = Globals.parseIsoDate(tdate);
LedgerTransaction tr = new LedgerTransaction(tindex, date, tdescription);
tr.setComment(Misc.trim(Misc.emptyIsNull(tcomment)));
/*
- * Copyright © 2019 Damyan Ivanov.
+ * Copyright © 2020 Damyan Ivanov.
* This file is part of MoLe.
* MoLe is free software: you can distribute it and/or modify it
* under the term of the GNU General Public License as published by
import net.ktnx.mobileledger.model.LedgerTransactionAccount;
import net.ktnx.mobileledger.utils.Globals;
import net.ktnx.mobileledger.utils.Misc;
+import net.ktnx.mobileledger.utils.SimpleDate;
import java.text.ParseException;
import java.util.ArrayList;
-import java.util.Date;
-import java.util.GregorianCalendar;
import java.util.List;
@JsonIgnoreProperties(ignoreUnknown = true)
}
result.setTpostings(postings);
- Date transactionDate = tr.getDate();
+ SimpleDate transactionDate = tr.getDate();
if (transactionDate == null) {
- transactionDate = new GregorianCalendar().getTime();
+ transactionDate = SimpleDate.today();
}
result.setTdate(Globals.formatIsoDate(transactionDate));
result.setTdate2(null);
tpostings.add(posting);
}
public LedgerTransaction asLedgerTransaction() throws ParseException {
- Date date = Globals.parseIsoDate(tdate);
+ SimpleDate date = Globals.parseIsoDate(tdate);
LedgerTransaction tr = new LedgerTransaction(tindex, date, tdescription);
tr.setComment(Misc.trim(Misc.emptyIsNull(tcomment)));
/*
- * Copyright © 2019 Damyan Ivanov.
+ * Copyright © 2020 Damyan Ivanov.
* This file is part of MoLe.
* MoLe is free software: you can distribute it and/or modify it
* under the term of the GNU General Public License as published by
import net.ktnx.mobileledger.utils.Digest;
import net.ktnx.mobileledger.utils.Globals;
+import net.ktnx.mobileledger.utils.SimpleDate;
import java.nio.charset.StandardCharsets;
import java.security.NoSuchAlgorithmException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Comparator;
-import java.util.Date;
public class LedgerTransaction {
private static final String DIGEST_TYPE = "SHA-256";
};
private String profile;
private Integer id;
- private Date date;
+ private SimpleDate date;
private String description;
private String comment;
private ArrayList<LedgerTransactionAccount> accounts;
throws ParseException {
this(id, Globals.parseLedgerDate(dateString), description);
}
- public LedgerTransaction(Integer id, Date date, String description,
+ public LedgerTransaction(Integer id, SimpleDate date, String description,
MobileLedgerProfile profile) {
this.profile = profile.getUuid();
this.id = id;
this.dataHash = null;
dataLoaded = false;
}
- public LedgerTransaction(Integer id, Date date, String description) {
+ public LedgerTransaction(Integer id, SimpleDate date, String description) {
this(id, date, description, Data.profile.getValue());
}
- public LedgerTransaction(Date date, String description) {
+ public LedgerTransaction(SimpleDate date, String description) {
this(null, date, description);
}
public LedgerTransaction(int id) {
- this(id, (Date) null, null);
+ this(id, (SimpleDate) null, null);
}
public LedgerTransaction(int id, String profileUUID) {
this.profile = profileUUID;
accounts.add(item);
dataHash = null;
}
- public Date getDate() {
+ public SimpleDate getDate() {
return date;
}
- public void setDate(Date date) {
+ public void setDate(SimpleDate date) {
this.date = date;
dataHash = null;
}
return;
try (Cursor cTr = db.rawQuery(
- "SELECT date, description, comment from transactions WHERE profile=? AND id=?",
- new String[]{profile, String.valueOf(id)}))
+ "SELECT year, month, day, description, comment from transactions WHERE profile=? " +
+ "AND id=?", new String[]{profile, String.valueOf(id)}))
{
if (cTr.moveToFirst()) {
- String dateString = cTr.getString(0);
- try {
- date = Globals.parseLedgerDate(dateString);
- }
- catch (ParseException e) {
- e.printStackTrace();
- throw new RuntimeException(
- String.format("Error parsing date '%s' from " + "transaction %d",
- dateString, id));
- }
- description = cTr.getString(1);
- comment = cTr.getString(2);
+ date = new SimpleDate(cTr.getInt(0), cTr.getInt(1), cTr.getInt(2));
+ description = cTr.getString(3);
+ comment = cTr.getString(4);
accounts.clear();
/*
- * Copyright © 2019 Damyan Ivanov.
+ * Copyright © 2020 Damyan Ivanov.
* This file is part of MoLe.
* MoLe is free software: you can distribute it and/or modify it
* under the term of the GNU General Public License as published by
new Object[]{uuid, tr.getId()});
db.execSQL(
- "INSERT INTO transactions(profile, id, date, description, comment, data_hash, " +
- "keep) " +
- "values(?,?,?,?,?,?,1)",
- new Object[]{uuid, tr.getId(), Globals.formatLedgerDate(tr.getDate()),
- tr.getDescription(), tr.getComment(), tr.getDataHash()
+ "INSERT INTO transactions(profile, id, year, month, day, description, "+
+ "comment, data_hash, keep) " +
+ "values(?,?,?,?,?,?,?,?,1)",
+ new Object[]{uuid, tr.getId(), tr.getDate().year, tr.getDate().month,
+ tr.getDate().day, tr.getDescription(),
+ tr.getComment(), tr.getDataHash()
});
for (LedgerTransactionAccount item : tr.getAccounts()) {
/*
- * Copyright © 2019 Damyan Ivanov.
+ * Copyright © 2020 Damyan Ivanov.
* This file is part of MoLe.
* MoLe is free software: you can distribute it and/or modify it
* under the term of the GNU General Public License as published by
package net.ktnx.mobileledger.model;
-import java.util.Date;
-
import androidx.annotation.NonNull;
+import net.ktnx.mobileledger.utils.SimpleDate;
+
public class TransactionListItem {
private Type type;
- private Date date;
+ private SimpleDate date;
private boolean monthShown;
private LedgerTransaction transaction;
private boolean odd;
- public TransactionListItem(Date date, boolean monthShown) {
+ public TransactionListItem(SimpleDate date, boolean monthShown) {
this.type = Type.DELIMITER;
this.date = date;
this.monthShown = monthShown;
public Type getType() {
return type;
}
- public Date getDate() {
+ public SimpleDate getDate() {
return date;
}
public boolean isMonthShown() {
/*
- * Copyright © 2019 Damyan Ivanov.
+ * Copyright © 2020 Damyan Ivanov.
* This file is part of MoLe.
* MoLe is free software: you can distribute it and/or modify it
* under the term of the GNU General Public License as published by
import android.widget.CalendarView;
import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatDialogFragment;
import net.ktnx.mobileledger.R;
import net.ktnx.mobileledger.model.MobileLedgerProfile;
+import net.ktnx.mobileledger.utils.SimpleDate;
import java.util.Calendar;
import java.util.GregorianCalendar;
-import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
static final Pattern reD = Pattern.compile("\\s*(\\d+)\\s*$");
private Calendar presentDate = GregorianCalendar.getInstance();
private DatePickedListener onDatePickedListener;
- private MobileLedgerProfile.FutureDates futureDates = MobileLedgerProfile.FutureDates.None;
- public MobileLedgerProfile.FutureDates getFutureDates() {
- return futureDates;
+ private long minDate = 0;
+ private long maxDate = Long.MAX_VALUE;
+ public void setDateRange(@Nullable SimpleDate minDate, @Nullable SimpleDate maxDate) {
+ if (minDate == null)
+ this.minDate = 0;
+ else
+ this.minDate = minDate.toDate().getTime();
+
+ if (maxDate == null)
+ this.maxDate = Long.MAX_VALUE;
+ else
+ this.maxDate = maxDate.toDate().getTime();
}
public void setFutureDates(MobileLedgerProfile.FutureDates futureDates) {
- this.futureDates = futureDates;
+ if (futureDates == MobileLedgerProfile.FutureDates.All) {
+ maxDate = Long.MAX_VALUE;
+ }
+ else {
+ final Calendar dateLimit = GregorianCalendar.getInstance();
+ switch (futureDates) {
+ case None:
+ // already there
+ break;
+ case OneWeek:
+ dateLimit.add(Calendar.DAY_OF_MONTH, 7);
+ break;
+ case TwoWeeks:
+ dateLimit.add(Calendar.DAY_OF_MONTH, 14);
+ break;
+ case OneMonth:
+ dateLimit.add(Calendar.MONTH, 1);
+ break;
+ case TwoMonths:
+ dateLimit.add(Calendar.MONTH, 2);
+ break;
+ case ThreeMonths:
+ dateLimit.add(Calendar.MONTH, 3);
+ break;
+ case SixMonths:
+ dateLimit.add(Calendar.MONTH, 6);
+ break;
+ case OneYear:
+ dateLimit.add(Calendar.YEAR, 1);
+ break;
+ }
+ maxDate = dateLimit.getTime()
+ .getTime();
+ }
}
public void setCurrentDateFromText(CharSequence present) {
final Calendar now = GregorianCalendar.getInstance();
cv.setDate(presentDate.getTime()
.getTime());
- if (futureDates == MobileLedgerProfile.FutureDates.All) {
- cv.setMaxDate(Long.MAX_VALUE);
- }
- else {
- final Calendar dateLimit = GregorianCalendar.getInstance();
- switch (futureDates) {
- case None:
- // already there
- break;
- case OneWeek:
- dateLimit.add(Calendar.DAY_OF_MONTH, 7);
- break;
- case TwoWeeks:
- dateLimit.add(Calendar.DAY_OF_MONTH, 14);
- break;
- case OneMonth:
- dateLimit.add(Calendar.MONTH, 1);
- break;
- case TwoMonths:
- dateLimit.add(Calendar.MONTH, 2);
- break;
- case ThreeMonths:
- dateLimit.add(Calendar.MONTH, 3);
- break;
- case SixMonths:
- dateLimit.add(Calendar.MONTH, 6);
- break;
- case OneYear:
- dateLimit.add(Calendar.YEAR, 1);
- break;
- }
- cv.setMaxDate(dateLimit.getTime()
- .getTime());
- }
+ cv.setMinDate(minDate);
+ cv.setMaxDate(maxDate);
cv.setOnDateChangeListener(this);
/*
- * Copyright © 2019 Damyan Ivanov.
+ * Copyright © 2020 Damyan Ivanov.
* This file is part of MoLe.
* MoLe is free software: you can distribute it and/or modify it
* under the term of the GNU General Public License as published by
import net.ktnx.mobileledger.model.MobileLedgerProfile;
import net.ktnx.mobileledger.utils.Logger;
import net.ktnx.mobileledger.utils.Misc;
+import net.ktnx.mobileledger.utils.SimpleDate;
import org.jetbrains.annotations.NotNull;
-import java.util.Date;
-
/**
* A simple {@link Fragment} subclass.
* Activities that contain this fragment must implement the
fab.setEnabled(false);
Misc.hideSoftKeyboard(this);
if (mListener != null) {
- Date date = viewModel.getDate();
+ SimpleDate date = viewModel.getDate();
LedgerTransaction tr =
new LedgerTransaction(null, date, viewModel.getDescription(), mProfile);
import net.ktnx.mobileledger.utils.Logger;
import net.ktnx.mobileledger.utils.MLDB;
import net.ktnx.mobileledger.utils.Misc;
+import net.ktnx.mobileledger.utils.SimpleDate;
import java.text.DecimalFormatSymbols;
-import java.util.Calendar;
+import java.text.ParseException;
import java.util.Date;
-import java.util.GregorianCalendar;
import java.util.Locale;
import static net.ktnx.mobileledger.ui.activity.NewTransactionModel.ItemType;
private FrameLayout lPadding;
private MobileLedgerProfile mProfile;
private Date date;
- private Observer<Date> dateObserver;
+ private Observer<SimpleDate> dateObserver;
private Observer<String> descriptionObserver;
private Observer<String> transactionCommentObserver;
private Observer<String> hintObserver;
return true;
}
+ catch (ParseException e) {
+ throw new RuntimeException("Should not happen", e);
+ }
finally {
syncingData = false;
}
}
@Override
public void onDatePicked(int year, int month, int day) {
- final Calendar c = GregorianCalendar.getInstance();
- c.set(year, month, day);
- item.setDate(c.getTime());
+ item.setDate(new SimpleDate(year, month+1, day));
boolean focused = tvDescription.requestFocus();
if (focused)
Misc.showSoftKeyboard((NewTransactionActivity) tvAccount.getContext());
/*
- * Copyright © 2019 Damyan Ivanov.
+ * Copyright © 2020 Damyan Ivanov.
* This file is part of MoLe.
* MoLe is free software: you can distribute it and/or modify it
* under the term of the GNU General Public License as published by
import net.ktnx.mobileledger.model.Data;
import net.ktnx.mobileledger.model.LedgerTransactionAccount;
import net.ktnx.mobileledger.model.MobileLedgerProfile;
+import net.ktnx.mobileledger.utils.Globals;
+import net.ktnx.mobileledger.utils.SimpleDate;
import org.jetbrains.annotations.NotNull;
+import java.text.ParseException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
-import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Locale;
import java.util.concurrent.atomic.AtomicInteger;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
public class NewTransactionModel extends ViewModel {
- private static final Pattern reYMD =
- Pattern.compile("^\\s*(\\d+)\\d*/\\s*(\\d+)\\s*/\\s*(\\d+)\\s*$");
- private static final Pattern reMD = Pattern.compile("^\\s*(\\d+)\\s*/\\s*(\\d+)\\s*$");
- private static final Pattern reD = Pattern.compile("\\s*(\\d+)\\s*$");
final MutableLiveData<Boolean> showCurrency = new MutableLiveData<>(false);
final ArrayList<Item> items = new ArrayList<>();
final MutableLiveData<Boolean> isSubmittable = new MutableLiveData<>(false);
int getAccountCount() {
return items.size();
}
- public Date getDate() {
+ public SimpleDate getDate() {
return header.date.getValue();
}
public String getDescription() {
static class Item {
private ItemType type;
- private MutableLiveData<Date> date = new MutableLiveData<>();
+ private MutableLiveData<SimpleDate> date = new MutableLiveData<>();
private MutableLiveData<String> description = new MutableLiveData<>();
private LedgerTransactionAccount account;
private MutableLiveData<String> amountHint = new MutableLiveData<>(null);
type = ItemType.bottomFiller;
editable.setValue(false);
}
- Item(NewTransactionModel model, Date date, String description) {
+ Item(NewTransactionModel model, SimpleDate date, String description) {
this.model = model;
this.type = ItemType.generalData;
this.date.setValue(date);
wantedType));
}
}
- public Date getDate() {
+ public SimpleDate getDate() {
ensureType(ItemType.generalData);
return date.getValue();
}
- public void setDate(Date date) {
+ public void setDate(SimpleDate date) {
ensureType(ItemType.generalData);
this.date.setValue(date);
}
- public void setDate(String text) {
+ public void setDate(String text) throws ParseException {
if ((text == null) || text.trim()
.isEmpty())
{
- setDate((Date) null);
+ setDate((SimpleDate) null);
return;
}
- int year, month, day;
- final Calendar c = GregorianCalendar.getInstance();
- Matcher m = reYMD.matcher(text);
- if (m.matches()) {
- year = Integer.parseInt(m.group(1));
- month = Integer.parseInt(m.group(2)) - 1; // month is 0-based
- day = Integer.parseInt(m.group(3));
- }
- else {
- year = c.get(Calendar.YEAR);
- m = reMD.matcher(text);
- if (m.matches()) {
- month = Integer.parseInt(m.group(1)) - 1;
- day = Integer.parseInt(m.group(2));
- }
- else {
- month = c.get(Calendar.MONTH);
- m = reD.matcher(text);
- if (m.matches()) {
- day = Integer.parseInt(m.group(1));
- }
- else {
- day = c.get(Calendar.DAY_OF_MONTH);
- }
- }
- }
-
- c.set(year, month, day);
-
- this.setDate(c.getTime());
+ SimpleDate date = Globals.parseLedgerDate(text);
+ this.setDate(date);
}
void observeDate(@NonNull @NotNull androidx.lifecycle.LifecycleOwner owner,
- @NonNull androidx.lifecycle.Observer<? super Date> observer) {
+ @NonNull androidx.lifecycle.Observer<? super SimpleDate> observer) {
this.date.observe(owner, observer);
}
- void stopObservingDate(@NonNull androidx.lifecycle.Observer<? super Date> observer) {
+ void stopObservingDate(@NonNull androidx.lifecycle.Observer<? super SimpleDate> observer) {
this.date.removeObserver(observer);
}
public String getDescription() {
String getFormattedDate() {
if (date == null)
return null;
- Date time = date.getValue();
- if (time == null)
+ SimpleDate d = date.getValue();
+ if (d == null)
return null;
- Calendar c = GregorianCalendar.getInstance();
- c.setTime(time);
Calendar today = GregorianCalendar.getInstance();
- final int myYear = c.get(Calendar.YEAR);
- final int myMonth = c.get(Calendar.MONTH);
- final int myDay = c.get(Calendar.DAY_OF_MONTH);
-
- if (today.get(Calendar.YEAR) != myYear) {
- return String.format(Locale.US, "%d/%02d/%02d", myYear, myMonth + 1, myDay);
+ if (today.get(Calendar.YEAR) != d.year) {
+ return String.format(Locale.US, "%d/%02d/%02d", d.year, d.month, d.day);
}
- if (today.get(Calendar.MONTH) != myMonth) {
- return String.format(Locale.US, "%d/%02d", myMonth + 1, myDay);
+ if (today.get(Calendar.MONTH) != d.month - 1) {
+ return String.format(Locale.US, "%d/%02d", d.month, d.day);
}
- return String.valueOf(myDay);
+ return String.valueOf(d.day);
}
void observeEditableFlag(NewTransactionActivity activity, Observer<Boolean> observer) {
editable.observe(activity, observer);
/*
- * Copyright © 2019 Damyan Ivanov.
+ * Copyright © 2020 Damyan Ivanov.
* This file is part of MoLe.
* MoLe is free software: you can distribute it and/or modify it
* under the term of the GNU General Public License as published by
import net.ktnx.mobileledger.utils.Colors;
import net.ktnx.mobileledger.utils.Globals;
import net.ktnx.mobileledger.utils.Misc;
+import net.ktnx.mobileledger.utils.SimpleDate;
import java.text.DateFormat;
-import java.util.Date;
import java.util.GregorianCalendar;
import java.util.TimeZone;
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
break;
case DELIMITER:
- Date date = item.getDate();
+ SimpleDate date = item.getDate();
holder.vTransaction.setVisibility(View.GONE);
holder.vDelimiter.setVisibility(View.VISIBLE);
holder.tvDelimiterDate.setText(DateFormat.getDateInstance()
- .format(date));
+ .format(date.toDate()));
if (item.isMonthShown()) {
GregorianCalendar cal = new GregorianCalendar(TimeZone.getDefault());
- cal.setTime(date);
+ cal.setTime(date.toDate());
holder.tvDelimiterMonth.setText(
Globals.monthNames[cal.get(GregorianCalendar.MONTH)]);
holder.tvDelimiterMonth.setVisibility(View.VISIBLE);
/*
- * Copyright © 2019 Damyan Ivanov.
+ * Copyright © 2020 Damyan Ivanov.
* This file is part of MoLe.
* MoLe is free software: you can distribute it and/or modify it
* under the term of the GNU General Public License as published by
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
-import java.util.Date;
import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
}
}
- public static Date parseLedgerDate(String dateString) throws ParseException {
+ public static SimpleDate parseLedgerDate(String dateString) throws ParseException {
Matcher m = reLedgerDate.matcher(dateString);
if (!m.matches()) throw new ParseException(
String.format("'%s' does not match expected pattern '%s'", dateString,
reLedgerDate.toString()), 0);
- String year = m.group(1);
- String month = m.group(2);
- String day = m.group(3);
+ String yearStr = m.group(1);
+ String monthStr = m.group(2);
+ String dayStr = m.group(3);
+
+ int year, month, day;
String toParse;
- if (year == null) {
- Calendar now = Calendar.getInstance();
- int thisYear = now.get(Calendar.YEAR);
- if (month == null) {
- int thisMonth = now.get(Calendar.MONTH) + 1;
- toParse = String.format(Locale.US, "%04d/%02d/%s", thisYear, thisMonth, dateString);
+ if (yearStr == null) {
+ SimpleDate today = SimpleDate.today();
+ year = today.year;
+ if (monthStr == null) {
+ month = today.month;
}
- else toParse = String.format(Locale.US, "%04d/%s", thisYear, dateString);
+ else month = Integer.parseInt(monthStr);
+ }
+ else {
+ year = Integer.parseInt(yearStr);
+ assert monthStr != null;
+ month = Integer.parseInt(monthStr);
}
- else toParse = dateString;
- return dateFormatter.get().parse(toParse);
+ assert dayStr != null;
+ day = Integer.parseInt(dayStr);
+
+ return new SimpleDate(year, month, day);
}
public static Calendar parseLedgerDateAsCalendar(String dateString) throws ParseException {
- Date date = parseLedgerDate(dateString);
- Calendar calendar = Calendar.getInstance();
- calendar.setTime(date);
- return calendar;
+ return parseLedgerDate(dateString).toCalendar();
}
- public static Date parseIsoDate(String dateString) throws ParseException {
- return isoDateFormatter.get().parse(dateString);
+ public static SimpleDate parseIsoDate(String dateString) throws ParseException {
+ return SimpleDate.fromDate(isoDateFormatter.get().parse(dateString));
}
- public static String formatLedgerDate(Date date) {
- return dateFormatter.get().format(date);
+ public static String formatLedgerDate(SimpleDate date) {
+ return dateFormatter.get().format(date.toDate());
}
- public static String formatIsoDate(Date date) {
- return isoDateFormatter.get().format(date);
+ public static String formatIsoDate(SimpleDate date) {
+ return isoDateFormatter.get().format(date.toDate());
}
}
\ No newline at end of file
/*
- * Copyright © 2019 Damyan Ivanov.
+ * Copyright © 2020 Damyan Ivanov.
* This file is part of MoLe.
* MoLe is free software: you can distribute it and/or modify it
* under the term of the GNU General Public License as published by
public class MobileLedgerDatabase extends SQLiteOpenHelper {
private static final String DB_NAME = "MoLe.db";
- private static final int LATEST_REVISION = 33;
+ private static final int LATEST_REVISION = 34;
private static final String CREATE_DB_SQL = "create_db";
private final Application mContext;
--- /dev/null
+/*
+ * Copyright © 2020 Damyan Ivanov.
+ * This file is part of MoLe.
+ * MoLe is free software: you can distribute it and/or modify it
+ * under the term of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your opinion), any later version.
+ *
+ * MoLe is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License terms for details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MoLe. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package net.ktnx.mobileledger.utils;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import java.util.Calendar;
+import java.util.Date;
+
+public class SimpleDate {
+ public int year;
+ public int month;
+ public int day;
+ public SimpleDate(int y, int m, int d) {
+ year = y;
+ month = m;
+ day = d;
+ }
+ public static SimpleDate fromDate(Date date) {
+ Calendar calendar = Calendar.getInstance();
+ calendar.setTime(date);
+ return fromCalendar(calendar);
+ }
+ public static SimpleDate fromCalendar(Calendar calendar) {
+ return new SimpleDate(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH) + 1,
+ calendar.get(Calendar.DATE));
+ }
+ public static SimpleDate today() {
+ return fromCalendar(Calendar.getInstance());
+ }
+ public Calendar toCalendar() {
+ Calendar result = Calendar.getInstance();
+ result.set(year, month - 1, day);
+ return result;
+ }
+ public Date toDate() {
+ return toCalendar().getTime();
+ }
+ public boolean equals(@Nullable SimpleDate date) {
+ if (date == null)
+ return false;
+
+ if (year != date.year)
+ return false;
+ if (month != date.month)
+ return false;
+ if (day != date.day)
+ return false;
+
+ return true;
+ }
+ public boolean earlierThan(@NonNull SimpleDate date) {
+ if (year < date.year)
+ return true;
+ if (year > date.year)
+ return false;
+ if (month < date.month)
+ return true;
+ if (month > date.month)
+ return false;
+ return (day < date.day);
+ }
+ public boolean laterThan(@NonNull SimpleDate date) {
+ if (year > date.year)
+ return true;
+ if (year < date.year)
+ return false;
+ if (month > date.month)
+ return true;
+ if (month < date.month)
+ return false;
+ return (day > date.day);
+ }
+}
+-- Copyright © 2020 Damyan Ivanov.
+-- This file is part of MoLe.
+-- MoLe is free software: you can distribute it and/or modify it
+-- under the term of the GNU General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your opinion), any later version.
+--
+-- MoLe is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+-- GNU General Public License terms for details.
+--
+-- You should have received a copy of the GNU General Public License
+-- along with MoLe. If not, see <https://www.gnu.org/licenses/>.
create table accounts(profile varchar not null, name varchar not null, name_upper varchar not null, hidden boolean not null default 0, keep boolean not null default 0, level integer not null, parent_name varchar, expanded default 1, amounts_expanded boolean default 0);
create unique index un_accounts on accounts(profile, name);
create table options(profile varchar not null, name varchar not null, value varchar);
create unique index un_account_values on account_values(profile,account,currency);
create table description_history(description varchar not null primary key, keep boolean, description_upper varchar);
create table profiles(uuid varchar not null primary key, name not null, url not null, use_authentication boolean not null, auth_user varchar, auth_password varchar, order_no integer, permit_posting boolean default 0, theme integer default -1, preferred_accounts_filter varchar, future_dates integer, api_version integer, show_commodity_by_default boolean default 0, default_commodity varchar, show_comments_by_default boolean default 1);
-create table transactions(profile varchar not null, id integer not null, data_hash varchar not null, date varchar not null, description varchar not null, comment varchar, keep boolean not null default 0);
+create table transactions(profile varchar not null, id integer not null, data_hash varchar not null, year integer not null, month integer not null, day integer not null, description varchar not null, comment varchar, keep boolean not null default 0);
create unique index un_transactions_id on transactions(profile,id);
create unique index un_transactions_data_hash on transactions(profile,data_hash);
create index idx_transaction_description on transactions(description);
create table transaction_accounts(profile varchar not null, transaction_id integer not null, account_name varchar not null, currency varchar not null default '', amount decimal not null, comment varchar, constraint fk_transaction_accounts_acc foreign key(profile,account_name) references accounts(profile,account_name), constraint fk_transaction_accounts_trn foreign key(profile, transaction_id) references transactions(profile,id));
create table currencies(id integer not null primary key, name varchar not null, position varchar not null, has_gap boolean not null);
--- updated to revision 33
\ No newline at end of file
+-- updated to revision 34
\ No newline at end of file
--- /dev/null
+-- Copyright © 2020 Damyan Ivanov.
+-- This file is part of MoLe.
+-- MoLe is free software: you can distribute it and/or modify it
+-- under the term of the GNU General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your opinion), any later version.
+--
+-- MoLe is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+-- GNU General Public License terms for details.
+--
+-- You should have received a copy of the GNU General Public License
+-- along with MoLe. If not, see <https://www.gnu.org/licenses/>.
+alter table transactions add year integer not null default 0;
+alter table transactions add month integer not null default 0;
+alter table transactions add day integer not null default 0;
+alter table transactions add tmp_md varchar;
+update transactions set year= cast(substr(date, 1,instr(date, '/')-1) as integer);
+update transactions set tmp_md= substr(date, instr(date, '/')+1);
+update transactions set month=cast(substr(tmp_md,1,instr(tmp_md,'/')-1) as integer);
+update transactions set day= cast(substr(tmp_md, instr(tmp_md,'/')+1) as integer);
+-- alter table transactions drop date
+create table transactions_2(profile varchar not null, id integer not null, data_hash varchar not null, year integer not null, month integer not null, day integer not null, description varchar not null, comment varchar, keep boolean not null default 0);
+insert into transactions_2(profile, id, data_hash, year, month, day, description, comment, keep) select profile, id, data_hash, year, month, day, description, comment, keep from transactions;
+drop table transactions;
+alter table transactions_2 rename to transactions;