Skip to content

Commit

Permalink
Merge branch 'hotfix/patches'
Browse files Browse the repository at this point in the history
  • Loading branch information
codinguser committed Dec 1, 2015
2 parents eece627 + e589a26 commit 6c320cf
Show file tree
Hide file tree
Showing 49 changed files with 495 additions and 373 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
Change Log
===============================================================================
Version 2.0.4 *(2015-12-02)*
----------------------------
* Fixed: Transaction export time not always working reliably
* Fixed: Renaming account causes transactions to be deleted
* Fixed: Progress dialog not displayed during initial import
* Fixed: Unable to finish first-run wizard if choosing to create accounts manually
* Fixed: Removed inapplicable options in scheduled actions context menu

Version 2.0.3 *(2015-11-21)*
----------------------------
* Fixed: Unable to enter decimal amounts in split editor
Expand Down
2 changes: 1 addition & 1 deletion app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ apply plugin: 'io.fabric'

def versionMajor = 2
def versionMinor = 0
def versionPatch = 3
def versionPatch = 4
def versionBuild = 0

def buildTime() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -794,9 +794,13 @@ private Money computeBalance(String accountUID, long startTimestamp, long endTim
* @param endTimestamp the end timestamp of the time range
* @return Money balance of account list
*/
public Money getAccountsBalance(List<String> accountUIDList, long startTimestamp, long endTimestamp) {
public Money getAccountsBalance(@NonNull List<String> accountUIDList, long startTimestamp, long endTimestamp) {
String currencyCode = GnuCashApplication.getDefaultCurrencyCode();
Money balance = Money.createZeroInstance(currencyCode);

if (accountUIDList.isEmpty())
return balance;

boolean hasDebitNormalBalance = getAccountType(accountUIDList.get(0)).hasDebitNormalBalance();

SplitsDbAdapter splitsDbAdapter = SplitsDbAdapter.getInstance();
Expand Down
16 changes: 15 additions & 1 deletion app/src/main/java/org/gnucash/android/db/DatabaseAdapter.java
Original file line number Diff line number Diff line change
Expand Up @@ -423,7 +423,7 @@ public String getUID(long id){
if (cursor.moveToFirst()) {
uid = cursor.getString(cursor.getColumnIndexOrThrow(DatabaseSchema.CommonColumns.COLUMN_UID));
} else {
throw new IllegalArgumentException("Account record ID " + id + " does not exist in the db");
throw new IllegalArgumentException(mTableName + " Record ID " + id + " does not exist in the db");
}
} finally {
cursor.close();
Expand Down Expand Up @@ -620,6 +620,20 @@ public void setTransactionSuccessful() {
mDb.setTransactionSuccessful();
}

/// Foreign key constraits should be enabled in general.
/// But if it affects speed (check constraints takes time)
/// and the constrained can be assured by the program,
/// or if some SQL exec will cause deletion of records
/// (like use replace in accounts update will delete all transactions)
/// that need not be deleted, then it can be disabled temporarily
public void enableForeignKey(boolean enable) {
if (enable){
mDb.execSQL("PRAGMA foreign_keys=ON");
} else {
mDb.execSQL("PRAGMA foreign_keys=OFF");
}
}

/**
* Expose mDb.endTransaction()
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import org.gnucash.android.model.Split;
import org.gnucash.android.model.Transaction;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;

Expand Down Expand Up @@ -633,6 +634,26 @@ public long getTimestampOfLatestTransaction(AccountType type, String currencyCod
return getTimestamp("MAX", type, currencyCode);
}

/**
* Returns the most recent `modified_at` timestamp of non-template transactions in the database
* @return Last moodified time in milliseconds or current time if there is none in the database
*/
public Timestamp getTimestampOfLastModification(){
Cursor cursor = mDb.query(TransactionEntry.TABLE_NAME,
new String[]{"MAX(" + TransactionEntry.COLUMN_MODIFIED_AT + ")"},
null, null, null, null, null);

Timestamp timestamp = new Timestamp(System.currentTimeMillis());
if (cursor.moveToFirst()){
String timeString = cursor.getString(0);
if (timeString != null){ //in case there were no transactions in the XML file (account structure only)
timestamp = Timestamp.valueOf(timeString);
}
}
cursor.close();
return timestamp;
}

/**
* Returns the earliest or latest timestamp of transactions for a specific account type and currency
* @param mod Mode (either MAX or MIN)
Expand Down
4 changes: 2 additions & 2 deletions app/src/main/java/org/gnucash/android/export/Exporter.java
Original file line number Diff line number Diff line change
Expand Up @@ -201,11 +201,11 @@ public String getExportMimeType(){
public static class ExporterException extends RuntimeException{

public ExporterException(ExportParams params){
super("Failed to generate " + params.getExportFormat().toString());
super("Failed to generate export with parameters: " + params.toString());
}

public ExporterException(@NonNull ExportParams params, @NonNull String msg) {
super("Failed to generate " + params.getExportFormat().toString() + "-" + msg);
super("Failed to generate export with parameters: " + params.toString() + " - " + msg);
}

public ExporterException(ExportParams params, Throwable throwable){
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import android.util.Log;

import org.gnucash.android.app.GnuCashApplication;
import org.gnucash.android.db.TransactionsDbAdapter;
import org.gnucash.android.export.Exporter;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
Expand Down Expand Up @@ -93,8 +94,11 @@ public static void parse(InputStream gncXmlInputStream) throws ParserConfigurati
xr.parse(new InputSource(bos));
long endTime = System.nanoTime();

String timeStamp = new Timestamp(System.currentTimeMillis()).toString();
PreferenceManager.getDefaultSharedPreferences(GnuCashApplication.getAppContext()).edit().putString(Exporter.PREF_LAST_EXPORT_TIME, timeStamp).apply();
Timestamp timeStamp = TransactionsDbAdapter.getInstance().getTimestampOfLastModification();
PreferenceManager.getDefaultSharedPreferences(GnuCashApplication.getAppContext())
.edit()
.putString(Exporter.PREF_LAST_EXPORT_TIME, timeStamp.toString())
.apply();

Log.d(GncXmlImporter.class.getSimpleName(), String.format("%d ns spent on importing the file", endTime-startTime));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -846,7 +846,9 @@ private void saveAccount() {
if (mAccountsDbAdapter == null)
mAccountsDbAdapter = AccountsDbAdapter.getInstance();
// bulk update, will not update transactions
mAccountsDbAdapter.enableForeignKey(false);
mAccountsDbAdapter.bulkAddRecords(accountsToUpdate);
mAccountsDbAdapter.enableForeignKey(true);

finishFragment();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -525,10 +525,11 @@ public static void startXmlFileChooser(Activity activity) {
* <p>This method is usually called in response to {@link AccountsActivity#startXmlFileChooser(Activity)}</p>
* @param context Activity context
* @param data Intent data containing the XML uri
* @param onFinishTask Task to be executed when import is complete
*/
public static void importXmlFileFromIntent(Activity context, Intent data) {
public static void importXmlFileFromIntent(Activity context, Intent data, TaskDelegate onFinishTask) {
GncXmlExporter.createBackup();
new ImportAsyncTask(context).execute(data.getData());
new ImportAsyncTask(context, onFinishTask).execute(data.getData());
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ protected void onActivityResult(int requestCode, int resultCode, Intent data) {

switch (requestCode) {
case AccountsActivity.REQUEST_PICK_ACCOUNTS_FILE:
AccountsActivity.importXmlFileFromIntent(this, data);
AccountsActivity.importXmlFileFromIntent(this, data, null);
break;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -578,7 +578,7 @@ public void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case AccountsActivity.REQUEST_PICK_ACCOUNTS_FILE:
if (resultCode == Activity.RESULT_OK && data != null) {
AccountsActivity.importXmlFileFromIntent(this, data);
AccountsActivity.importXmlFileFromIntent(this, data, null);
}
break;
case GeneralPreferenceFragment.PASSCODE_REQUEST_CODE:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ public class ScheduledActionsListFragment extends ListFragment implements
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
MenuInflater inflater = mode.getMenuInflater();
inflater.inflate(R.menu.transactions_context_menu, menu);
inflater.inflate(R.menu.schedxactions_context_menu, menu);
return true;
}

Expand All @@ -115,16 +115,24 @@ public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
switch (item.getItemId()) {
case R.id.context_menu_delete:
for (long id : getListView().getCheckedItemIds()) {
Log.i(TAG, "Cancelling scheduled transaction(s)");
String trnUID = mTransactionsDbAdapter.getUID(id);
ScheduledActionDbAdapter scheduledActionDbAdapter = GnuCashApplication.getScheduledEventDbAdapter();
List<ScheduledAction> actions = scheduledActionDbAdapter.getScheduledActionsWithUID(trnUID);

if (mTransactionsDbAdapter.deleteRecord(id)){
Toast.makeText(getActivity(), R.string.toast_recurring_transaction_deleted, Toast.LENGTH_SHORT).show();
for (ScheduledAction action : actions) {
scheduledActionDbAdapter.deleteRecord(action.getUID());

if (mActionType == ScheduledAction.ActionType.TRANSACTION) {
Log.i(TAG, "Cancelling scheduled transaction(s)");
String trnUID = mTransactionsDbAdapter.getUID(id);
ScheduledActionDbAdapter scheduledActionDbAdapter = GnuCashApplication.getScheduledEventDbAdapter();
List<ScheduledAction> actions = scheduledActionDbAdapter.getScheduledActionsWithUID(trnUID);

if (mTransactionsDbAdapter.deleteRecord(id)) {
Toast.makeText(getActivity(),
R.string.toast_recurring_transaction_deleted,
Toast.LENGTH_SHORT).show();
for (ScheduledAction action : actions) {
scheduledActionDbAdapter.deleteRecord(action.getUID());
}
}
} else if (mActionType == ScheduledAction.ActionType.BACKUP){
Log.i(TAG, "Removing scheduled exports");
ScheduledActionDbAdapter.getInstance().deleteRecord(id);
}
}
mode.finish();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -785,8 +785,8 @@ private void saveNewTransaction() {
mTransaction.addSplit(split);

String transferAcctUID;
if (mUseDoubleEntry) {
long transferAcctId = mTransferAccountSpinner.getSelectedItemId();
long transferAcctId = mTransferAccountSpinner.getSelectedItemId();
if (mUseDoubleEntry || transferAcctId < 0) {
transferAcctUID = mAccountsDbAdapter.getUID(transferAcctId);
} else {
transferAcctUID = mAccountsDbAdapter.getOrCreateImbalanceAccountUID(currency);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
Expand All @@ -32,6 +33,7 @@
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.widget.Toolbar;
import android.text.format.DateUtils;
import android.util.Log;
import android.util.SparseArray;
import android.view.Menu;
Expand Down Expand Up @@ -60,8 +62,12 @@
import org.gnucash.android.ui.util.OnTransactionClickedListener;
import org.gnucash.android.ui.util.Refreshable;
import org.gnucash.android.util.QualifiedAccountNameCursorAdapter;
import org.joda.time.LocalDate;

import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

import butterknife.Bind;
import butterknife.ButterKnife;
Expand Down Expand Up @@ -92,6 +98,7 @@ public class TransactionsActivity extends BaseDrawerActivity implements
* Number of pages to show
*/
private static final int DEFAULT_NUM_PAGES = 2;
private static SimpleDateFormat mDayMonthDateFormat = new SimpleDateFormat("EEE, d MMM");

/**
* GUID of {@link Account} whose transactions are displayed
Expand Down Expand Up @@ -153,7 +160,6 @@ public void onNothingSelected(AdapterView<?> parent) {
private PagerAdapter mPagerAdapter;



/**
* Adapter for managing the sub-account and transaction fragment pages in the accounts view
*/
Expand Down Expand Up @@ -486,6 +492,29 @@ public static void displayBalance(TextView balanceTextView, Money balance){
balanceTextView.setTextColor(fontColor);
}

/**
* Formats the date to show the the day of the week if the {@code dateMillis} is within 7 days
* of today. Else it shows the actual date formatted as short string. <br>
* It also shows "today", "yesterday" or "tomorrow" if the date is on any of those days
* @param dateMillis
* @return
*/
@NonNull
public static String getPrettyDateFormat(Context context, long dateMillis) {
LocalDate transactionTime = new LocalDate(dateMillis);
LocalDate today = new LocalDate();
String prettyDateText = null;
if (transactionTime.compareTo(today.minusDays(1)) >= 0 && transactionTime.compareTo(today.plusDays(1)) <= 0){
prettyDateText = DateUtils.getRelativeTimeSpanString(dateMillis, System.currentTimeMillis(), DateUtils.DAY_IN_MILLIS).toString();
} else if (transactionTime.getYear() == today.getYear()){
prettyDateText = mDayMonthDateFormat.format(new Date(dateMillis));
} else {
prettyDateText = DateUtils.formatDateTime(context, dateMillis, DateUtils.FORMAT_ABBREV_MONTH | DateUtils.FORMAT_SHOW_YEAR);
}

return prettyDateText;
}

@Override
public void createNewTransaction(String accountUID) {
Intent createTransactionIntent = new Intent(this.getApplicationContext(), FormActivity.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import android.content.res.Configuration;
import android.database.Cursor;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.Fragment;
import android.support.v4.app.LoaderManager.LoaderCallbacks;
import android.support.v4.content.Loader;
Expand All @@ -42,6 +43,7 @@
import android.widget.TextView;

import org.gnucash.android.R;
import org.gnucash.android.app.GnuCashApplication;
import org.gnucash.android.db.AccountsDbAdapter;
import org.gnucash.android.db.DatabaseCursorLoader;
import org.gnucash.android.db.DatabaseSchema;
Expand All @@ -57,8 +59,10 @@
import org.gnucash.android.ui.util.CursorRecyclerAdapter;
import org.gnucash.android.ui.util.Refreshable;
import org.gnucash.android.ui.util.widget.EmptyRecyclerView;
import org.joda.time.LocalDate;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

Expand Down Expand Up @@ -196,7 +200,6 @@ public void onLoaderReset(Loader<Cursor> loader) {
mTransactionRecyclerAdapter.swapCursor(null);
}


/**
* {@link DatabaseCursorLoader} for loading transactions asynchronously from the database
* @author Ngewi Fet <ngewif@gmail.com>
Expand All @@ -221,8 +224,6 @@ public Cursor loadInBackground() {

public class TransactionRecyclerAdapter extends CursorRecyclerAdapter<TransactionRecyclerAdapter.ViewHolder>{

DateFormat simpleDateFormat = DateFormat.getDateInstance(DateFormat.MEDIUM);

public TransactionRecyclerAdapter(Cursor cursor) {
super(cursor);
}
Expand Down Expand Up @@ -264,7 +265,8 @@ public void onBindViewHolderCursor(ViewHolder holder, Cursor cursor) {
holder.transactionNote.setText(text);

long dateMillis = cursor.getLong(cursor.getColumnIndexOrThrow(DatabaseSchema.TransactionEntry.COLUMN_TIMESTAMP));
String dateText = DateUtils.getRelativeTimeSpanString(dateMillis, System.currentTimeMillis(), DateUtils.DAY_IN_MILLIS).toString();
String dateText = TransactionsActivity.getPrettyDateFormat(getActivity(), dateMillis);

holder.transactionDate.setText(dateText);

final long id = holder.transactionId;
Expand All @@ -288,7 +290,6 @@ public void onClick(View v) {

}


public class ViewHolder extends RecyclerView.ViewHolder implements PopupMenu.OnMenuItemClickListener{
@Bind(R.id.primary_text) public TextView transactionDescription;
@Bind(R.id.secondary_text) public TextView transactionNote;
Expand Down
Loading

0 comments on commit 6c320cf

Please sign in to comment.