Implement bankstatement, export, and data interactors #4
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Overview
Implements three independent features that all need a
Contextfor IO:bankstatement—BankStatementImporterinterface + 3 stubs (BRI / Jago / BNI)export—ExportExpensesToCsvinteractordata—ClearAllDatainteractor (wipe-all-data action used bySettingsScreen)Also adds
PDFBoxResourceLoader.init(this)toMainApplication.Depends on #1.
Prerequisites
Issue #1 must be merged first. This gives you:
AppDatabasealready wiredExpense,DateRange,ExpenseWithCategorymodelsExpenseDao,CategoryDaoregisteredWhat to do
1.
bankstatement— interface + 3 stubsCreate
domain/bankstatement/interactor/BankStatementImporter.kt:Create 3 stub implementations, all returning
Result.failure(NotImplementedError("… import not yet implemented")):ImportBRIBankStatement.kt—bankName = "BRI", takesContextImportJagoBankStatement.kt—bankName = "Jago", takesContextImportBNIBankStatement.kt—bankName = "BNI", takesContext2.
export— CSV exporterCreate
domain/export/interactor/ExportExpensesToCsv.kt:(expenseDao: ExpenseDao, categoryDao: CategoryDao, context: Context)await(range: DateRange, outputUri: Uri): Result<Unit>expenseDao.getByDateRange(range.start.toEpochDay(), range.end.toEpochDay()).categoryDao.getAll(). Build aMap<Long, Category>.context.contentResolver.openOutputStream(outputUri). Wrap with OkioBufferedSink(usesink(outputStream).buffer()).0xEF, 0xBB, 0xBF(usesink.writeUtf8("\uFEFF")or write the three bytes directly).Date,Category,Amount,Note\n.expense.date.toString(),category.name,expense.amount,"${expense.note.orEmpty()}"\n. ISO 8601 dates come for free fromLocalDate.toString()(yyyy-MM-dd). Double-quote notes to handle embedded commas/newlines.Result.success(Unit)orResult.failure(e)on any exception.3.
data— wipe-all-dataCreate
domain/data/interactor/ClearAllData.kt:(database: AppDatabase)await():database.withTransaction { database.clearAllTables() }(importandroidx.room.withTransaction).SettingsScreenScreenModel will callinject<SeedDefaultCategories>().await()afterwards.4. Update
MainApplicationAdd the PDFBox init call to the existing
MainApplication.onCreate():5. Wire
DomainModule6. Verify compilation
Run
./gradlew assembleDebug. Must succeed.Acceptance
BankStatementImporterinterface definedNotImplementedErrorfailureExportExpensesToCsvwrites UTF-8 BOM CSVClearAllDatawipes all tables in a transactionMainApplicationcallsPDFBoxResourceLoader.init(this)DomainModulehas the new factories (incl. theList<BankStatementImporter>aggregate)./gradlew assembleDebugsucceedsImplementation rule
Per
AGENTS.md— do not start implementation without explicit user sign-off on this issue. When working, check for related issues in the remote repo first.