Skip to content

Commit 8372102

Browse files
committed
Export only transactions since the last run of the scheduled export.
We were getting transactions since the creation of the scheduled export. Fixes #609
1 parent f703603 commit 8372102

2 files changed

Lines changed: 108 additions & 4 deletions

File tree

app/src/main/java/org/gnucash/android/service/ScheduledActionService.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
import org.gnucash.android.model.ScheduledAction;
4242
import org.gnucash.android.model.Transaction;
4343

44+
import java.sql.Timestamp;
4445
import java.util.ArrayList;
4546
import java.util.Date;
4647
import java.util.List;
@@ -168,6 +169,8 @@ private static int executeBackup(ScheduledAction scheduledAction, SQLiteDatabase
168169
return 0;
169170

170171
ExportParams params = ExportParams.parseCsv(scheduledAction.getTag());
172+
// HACK: the tag isn't updated with the new date, so set the correct by hand
173+
params.setExportStartTime(new Timestamp(scheduledAction.getLastRunTime()));
171174
try {
172175
//wait for async task to finish before we proceed (we are holding a wake lock)
173176
new ExportAsyncTask(GnuCashApplication.getAppContext(), db).execute(params).get();

app/src/test/java/org/gnucash/android/test/unit/service/ScheduledActionServiceTest.java

Lines changed: 105 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,13 @@
1515
*/
1616
package org.gnucash.android.test.unit.service;
1717

18+
import android.content.ContentValues;
1819
import android.database.sqlite.SQLiteDatabase;
19-
import android.support.annotation.NonNull;
2020

2121
import org.gnucash.android.BuildConfig;
2222
import org.gnucash.android.R;
2323
import org.gnucash.android.app.GnuCashApplication;
24+
import org.gnucash.android.db.DatabaseSchema;
2425
import org.gnucash.android.db.adapter.AccountsDbAdapter;
2526
import org.gnucash.android.db.adapter.BooksDbAdapter;
2627
import org.gnucash.android.db.adapter.CommoditiesDbAdapter;
@@ -39,10 +40,12 @@
3940
import org.gnucash.android.model.ScheduledAction;
4041
import org.gnucash.android.model.Split;
4142
import org.gnucash.android.model.Transaction;
43+
import org.gnucash.android.model.TransactionType;
4244
import org.gnucash.android.service.ScheduledActionService;
4345
import org.gnucash.android.test.unit.testutil.GnucashTestRunner;
4446
import org.gnucash.android.test.unit.testutil.ShadowCrashlytics;
4547
import org.gnucash.android.test.unit.testutil.ShadowUserVoice;
48+
import org.gnucash.android.util.TimestampHelper;
4649
import org.joda.time.DateTime;
4750
import org.joda.time.LocalDateTime;
4851
import org.joda.time.Weeks;
@@ -57,6 +60,7 @@
5760
import java.io.File;
5861
import java.io.IOException;
5962
import java.math.BigDecimal;
63+
import java.sql.Timestamp;
6064
import java.util.ArrayList;
6165
import java.util.List;
6266

@@ -79,6 +83,7 @@ public class ScheduledActionServiceTest {
7983
private static Account mTransferAccount = new Account("Transfer Account");
8084

8185
private static Transaction mTemplateTransaction;
86+
private TransactionsDbAdapter mTransactionsDbAdapter;
8287

8388
public void createAccounts(){
8489
try {
@@ -117,9 +122,8 @@ public void setUp(){
117122
accountsDbAdapter.addRecord(mBaseAccount);
118123
accountsDbAdapter.addRecord(mTransferAccount);
119124

120-
TransactionsDbAdapter transactionsDbAdapter = TransactionsDbAdapter.getInstance();
121-
transactionsDbAdapter.addRecord(mTemplateTransaction, DatabaseAdapter.UpdateMethod.insert);
122-
125+
mTransactionsDbAdapter = TransactionsDbAdapter.getInstance();
126+
mTransactionsDbAdapter.addRecord(mTemplateTransaction, DatabaseAdapter.UpdateMethod.insert);
123127
}
124128

125129
@Test
@@ -363,6 +367,103 @@ public void scheduledBackups_shouldNotRunBeforeNextScheduledExecution(){
363367
assertThat(backupFolder.listFiles()).hasSize(0);
364368
}
365369

370+
/**
371+
* Tests that an scheduled backup doesn't include transactions added or modified
372+
* previous to the last run.
373+
*/
374+
@Test
375+
public void scheduledBackups_shouldNotIncludeTransactionsPreviousToTheLastRun() {
376+
ScheduledAction scheduledBackup = new ScheduledAction(ScheduledAction.ActionType.BACKUP);
377+
scheduledBackup.setStartTime(LocalDateTime.now().minusDays(15).toDate().getTime());
378+
scheduledBackup.setLastRun(LocalDateTime.now().minusDays(8).toDate().getTime());
379+
long previousLastRun = scheduledBackup.getLastRunTime();
380+
scheduledBackup.setExecutionCount(1);
381+
scheduledBackup.setRecurrence(PeriodType.WEEK, 1);
382+
ExportParams backupParams = new ExportParams(ExportFormat.QIF);
383+
backupParams.setExportTarget(ExportParams.ExportTarget.SD_CARD);
384+
backupParams.setExportStartTime(new Timestamp(scheduledBackup.getStartTime()));
385+
scheduledBackup.setTag(backupParams.toCsv());
386+
387+
// Create a transaction with a modified date previous to the last run
388+
Transaction transaction = new Transaction("Tandoori express");
389+
Split split = new Split(new Money("10", Commodity.DEFAULT_COMMODITY.getCurrencyCode()),
390+
mBaseAccount.getUID());
391+
split.setType(TransactionType.DEBIT);
392+
transaction.addSplit(split);
393+
transaction.addSplit(split.createPair(mTransferAccount.getUID()));
394+
mTransactionsDbAdapter.addRecord(transaction);
395+
// We set the date directly in the database as the corresponding field
396+
// is ignored when the object is stored. It's set through a trigger instead.
397+
setTransactionInDbModifiedTimestamp(transaction.getUID(),
398+
new Timestamp(LocalDateTime.now().minusDays(9).toDate().getTime()));
399+
400+
File backupFolder = new File(
401+
Exporter.getExportFolderPath(BooksDbAdapter.getInstance().getActiveBookUID()));
402+
assertThat(backupFolder).exists();
403+
assertThat(backupFolder.listFiles()).isEmpty();
404+
405+
List<ScheduledAction> actions = new ArrayList<>();
406+
actions.add(scheduledBackup);
407+
ScheduledActionService.processScheduledActions(actions, mDb);
408+
409+
assertThat(scheduledBackup.getExecutionCount()).isEqualTo(2);
410+
assertThat(scheduledBackup.getLastRunTime()).isGreaterThan(previousLastRun);
411+
assertThat(backupFolder.listFiles()).hasSize(0);
412+
}
413+
414+
/**
415+
* Sets the transaction modified timestamp directly in the database.
416+
*
417+
* @param transactionUID UID of the transaction to set the modified timestamp.
418+
* @param timestamp new modified timestamp.
419+
*/
420+
private void setTransactionInDbModifiedTimestamp(String transactionUID, Timestamp timestamp) {
421+
ContentValues values = new ContentValues();
422+
values.put(DatabaseSchema.TransactionEntry.COLUMN_MODIFIED_AT,
423+
TimestampHelper.getUtcStringFromTimestamp(timestamp));
424+
mTransactionsDbAdapter.updateTransaction(values, "uid = ?",
425+
new String[]{transactionUID});
426+
}
427+
428+
/**
429+
* Tests that an scheduled backup includes transactions added or modified
430+
* after the last run.
431+
*/
432+
@Test
433+
public void scheduledBackups_shouldIncludeTransactionsAfterTheLastRun() {
434+
ScheduledAction scheduledBackup = new ScheduledAction(ScheduledAction.ActionType.BACKUP);
435+
scheduledBackup.setStartTime(LocalDateTime.now().minusDays(15).toDate().getTime());
436+
scheduledBackup.setLastRun(LocalDateTime.now().minusDays(8).toDate().getTime());
437+
long previousLastRun = scheduledBackup.getLastRunTime();
438+
scheduledBackup.setExecutionCount(1);
439+
scheduledBackup.setRecurrence(PeriodType.WEEK, 1);
440+
ExportParams backupParams = new ExportParams(ExportFormat.QIF);
441+
backupParams.setExportTarget(ExportParams.ExportTarget.SD_CARD);
442+
backupParams.setExportStartTime(new Timestamp(scheduledBackup.getStartTime()));
443+
scheduledBackup.setTag(backupParams.toCsv());
444+
445+
Transaction transaction = new Transaction("Orient palace");
446+
Split split = new Split(new Money("10", Commodity.DEFAULT_COMMODITY.getCurrencyCode()),
447+
mBaseAccount.getUID());
448+
split.setType(TransactionType.DEBIT);
449+
transaction.addSplit(split);
450+
transaction.addSplit(split.createPair(mTransferAccount.getUID()));
451+
mTransactionsDbAdapter.addRecord(transaction);
452+
453+
File backupFolder = new File(
454+
Exporter.getExportFolderPath(BooksDbAdapter.getInstance().getActiveBookUID()));
455+
assertThat(backupFolder).exists();
456+
assertThat(backupFolder.listFiles()).isEmpty();
457+
458+
List<ScheduledAction> actions = new ArrayList<>();
459+
actions.add(scheduledBackup);
460+
ScheduledActionService.processScheduledActions(actions, mDb);
461+
462+
assertThat(scheduledBackup.getExecutionCount()).isEqualTo(2);
463+
assertThat(scheduledBackup.getLastRunTime()).isGreaterThan(previousLastRun);
464+
assertThat(backupFolder.listFiles()).hasSize(1);
465+
}
466+
366467
@After
367468
public void tearDown(){
368469
TransactionsDbAdapter.getInstance().deleteAllRecords();

0 commit comments

Comments
 (0)