diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
index ba7f073466..b26d2f8a9b 100644
--- a/.github/PULL_REQUEST_TEMPLATE.md
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -1,7 +1,5 @@
## Pull Request (PR) Checklist
-
Please check if your pull request fulfills the following requirements:
-
- [ ] The PR is submitted to the `develop` branch.
- [ ] I've read the **[Contribution Guidelines](https://github.com/ILIYANGERMANOV/ivy-wallet/blob/main/CONTRIBUTING.md)**.
- [ ] The code builds and is tested on an actual Android device.
@@ -12,41 +10,16 @@ Please check if your pull request fulfills the following requirements:
_Important: Don't worry if you experience flaky UI tests. Just re-run the failed ones again and if they pass => it's all good!_
_Put an `x` in the boxes that apply._
-
- [x] Demo: Checking checkbox using `[x]`
-### How to run Ivy Wallet's UI tests (`androidTest`)
-
-**Connect Android Emulator**
-- Pixel 5 API 29+ AVD emulator _(recommended)_
-- Pixel 3XL API 29+ AVD emulator _(recommended)_
-- Large screen physical device _(might also work)_
-
-**Method 1: Android Studio UI**
-- Find `com (androidTest)` package
-- Right click
-- `Run 'Tests in 'com''`
-
-_Note: If you've checked "Compact Middle Packages" the option will appear as `com.ivy.wallet (androidTest)`._
-
-**Method 2: Gradle Wrapper**
-- `chmod +x gradlew` (Linux)
-- `./gradlew connectedDebugAndroidTest`
-
-**Method 3: Fastlane**
-- Install Ruby 2.7
-- `bundle install`
-- `bundle exec fastlane ui_tests`
## Pull Request Type
-
Please check the type of change your PR introduces:
-
- [ ] Bugfix
- [ ] Feature
- [ ] Code style update (formatting, renaming)
- [ ] Refactoring (no functional changes)
-- [ ] Small update (fix typo, UI fine-tune, change color or something small)
+- [ ] Small improvement (fix typo, UI fine-tune, change color or something small)
- [ ] Gradle Build related changes
- [ ] Dependencies update (updating libraries)
- [ ] Documentation
@@ -55,18 +28,37 @@ Please check the type of change your PR introduces:
_Put an `x` in the boxes that apply._
-## Does this PR closes any GitHub Issues?
+## Does this PR closes any GitHub Issues?
Check **[Ivy Wallet Issues](https://github.com/ILIYANGERMANOV/ivy-wallet/issues)**.
-
- Closes #N/A (type issue number here)
-## What's changed?
+## What's changed?
Describe with a few bullets **what's new:**
+- a
+- b
+- c
+- d
+
+## How to run Ivy Wallet's UI tests (`androidTest`)
+**Connect Android Emulator**
+- Pixel 5 API 29+ AVD emulator _(recommended)_
+- Pixel 3XL API 29+ AVD emulator _(recommended)_
+- Large screen physical device _(might also work)_
+
+**Method 1: Android Studio UI**
+- Find `com (androidTest)` package
+- Right click
+- `Run 'Tests in 'com''`
+
+_Note: If you've checked "Compact Middle Packages" the option will appear as `com.ivy.wallet (androidTest)`._
--
--
--
+**Method 2: Gradle Wrapper**
+- `chmod +x gradlew` (Linux)
+- `./gradlew connectedDebugAndroidTest`
-_This PR template style was inspired by [ionic-framework](https://github.com/ionic-team/ionic-framework/blob/main/.github/PULL_REQUEST_TEMPLATE.md)._
\ No newline at end of file
+**Method 3: Fastlane**
+- Install Ruby 2.7
+- `bundle install`
+- `bundle exec fastlane ui_tests`
\ No newline at end of file
diff --git a/app/src/main/java/com/ivy/wallet/logic/csv/CSVImporter.kt b/app/src/main/java/com/ivy/wallet/logic/csv/CSVImporter.kt
index 31d4c04792..96fd4e540d 100644
--- a/app/src/main/java/com/ivy/wallet/logic/csv/CSVImporter.kt
+++ b/app/src/main/java/com/ivy/wallet/logic/csv/CSVImporter.kt
@@ -171,14 +171,18 @@ class CSVImporter(
val dateTime = mapDate(
- if (rowMapping.timeOnly != null) {
+ rowMapping = rowMapping,
+ dateString = if (rowMapping.timeOnly != null) {
// date and time are separated in csv, join them with space
row.extract(rowMapping.date) + " " + row.extract(rowMapping.timeOnly)
} else {
row.extract(rowMapping.date)
}
)
- val dueDate = mapDate(row.extract(rowMapping.dueDate))
+ val dueDate = mapDate(
+ rowMapping = rowMapping,
+ dateString = row.extract(rowMapping.dueDate)
+ )
if (dateTime == null && dueDate == null) {
//Cannot save transactions without any date
return null
@@ -241,9 +245,11 @@ class CSVImporter(
normalizedType.contains("income") -> TransactionType.INCOME
normalizedType.contains("expense") -> TransactionType.EXPENSE
normalizedType.contains("transfer") -> TransactionType.TRANSFER
- // Default to Expense because Financisto messed up its CSV Export
- // and mixes it with another (ignored) column
- else -> TransactionType.EXPENSE
+ else -> {
+ // Default to Expense because Financisto messed up its CSV Export
+ // and mixes it with another (ignored) column
+ if (rowMapping.defaultTypeToExpense) TransactionType.EXPENSE else null
+ }
}
}
@@ -255,9 +261,28 @@ class CSVImporter(
.toDoubleOrNull()
}
- private fun mapDate(dateString: String?): LocalDateTime? {
+ private fun mapDate(
+ rowMapping: RowMapping,
+ dateString: String?
+ ): LocalDateTime? {
if (dateString == null || dateString.isBlank()) return null
+ if (rowMapping.dateOnlyFormat != null) {
+ try {
+ return dateString.parseDateOnly(rowMapping.dateOnlyFormat)
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+ }
+
+ if (rowMapping.dateTimeFormat != null) {
+ try {
+ return dateString.parseDateTime(rowMapping.dateTimeFormat)
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+ }
+
val supportedPatterns = listOf(
"dd/MM/yyyy HH:mm",
"dd/MM/yyyy HH:mm:ss",
@@ -316,10 +341,7 @@ class CSVImporter(
for (pattern in supportedPatterns) {
try {
- return LocalDateTime.parse(
- dateString,
- DateTimeFormatter.ofPattern(pattern)
- ).convertLocalToUTC()
+ return dateString.parseDateTime(dateTimeFormat = pattern)
} catch (e: Exception) {
}
}
@@ -333,11 +355,7 @@ class CSVImporter(
for (pattern in supportedDateOnlyPatterns) {
try {
- return LocalDate.parse(
- dateString,
- DateTimeFormatter.ofPattern(pattern)
- ).atTime(12, 0)
- .convertLocalToUTC()
+ return dateString.parseDateOnly(dateFormat = pattern)
} catch (e: Exception) {
}
}
@@ -367,6 +385,24 @@ class CSVImporter(
.minusYears(1)
}
+ private fun String.parseDateOnly(
+ dateFormat: String
+ ): LocalDateTime {
+ return LocalDate.parse(
+ this,
+ DateTimeFormatter.ofPattern(dateFormat)
+ ).atTime(12, 0).convertLocalToUTC()
+ }
+
+ private fun String.parseDateTime(
+ dateTimeFormat: String
+ ): LocalDateTime {
+ return LocalDateTime.parse(
+ this,
+ DateTimeFormatter.ofPattern(dateTimeFormat)
+ ).convertLocalToUTC()
+ }
+
private fun mapAccount(
baseCurrency: String,
accountNameString: String?,
diff --git a/app/src/main/java/com/ivy/wallet/logic/csv/CSVMapper.kt b/app/src/main/java/com/ivy/wallet/logic/csv/CSVMapper.kt
index 9ff1209a1d..13b66caa67 100644
--- a/app/src/main/java/com/ivy/wallet/logic/csv/CSVMapper.kt
+++ b/app/src/main/java/com/ivy/wallet/logic/csv/CSVMapper.kt
@@ -18,9 +18,10 @@ class CSVMapper {
ivyMappingV1()
}
}
- ImportType.MONEY_MANAGER_PRASE -> moneyManagerPrase()
+ ImportType.MONEY_MANAGER -> moneyManager()
ImportType.WALLET_BY_BUDGET_BAKERS -> walletByBudgetBakers()
ImportType.SPENDEE -> spendee()
+ ImportType.MONEFY -> monefy()
ImportType.ONE_MONEY -> oneMoney()
ImportType.BLUE_COINS -> blueCoins()
ImportType.KTW_MONEY_MANAGER -> ktwMoneyManager()
@@ -74,7 +75,7 @@ class CSVMapper {
)
//Praseto - https://play.google.com/store/apps/details?id=com.realbyteapps.moneymanagerfree&hl=en&gl=US
- private fun moneyManagerPrase() = RowMapping(
+ private fun moneyManager() = RowMapping(
type = 6,
amount = 8,
account = 1,
@@ -123,6 +124,26 @@ class CSVMapper {
title = 6
)
+ private fun monefy() = RowMapping(
+ date = 0,
+ dateOnlyFormat = "dd/MM/yyyy",
+ account = 1,
+ category = 2,
+ amount = 3,
+ accountCurrency = 4,
+ //converted amount = 5
+ //currency = 6
+ title = 7,
+ defaultTypeToExpense = true, //Monefy doesn't have transaction type, it uses amount +/- sign,
+
+ transformTransaction = { transaction, _, csvAmount ->
+ //Monefy doesn't have transaction type, it uses amount +/- sign
+ transaction.copy(
+ type = if (csvAmount > 0) TransactionType.INCOME else TransactionType.EXPENSE
+ )
+ }
+ )
+
private fun oneMoney() = RowMapping(
date = 0,
type = 1,
@@ -188,6 +209,7 @@ class CSVMapper {
// parent transaction = 8
title = 9,
type = 10,
+ defaultTypeToExpense = true,
// project = 11
description = 12,
diff --git a/app/src/main/java/com/ivy/wallet/logic/csv/model/ImportType.kt b/app/src/main/java/com/ivy/wallet/logic/csv/model/ImportType.kt
index e6dfec4268..8ddba26d87 100644
--- a/app/src/main/java/com/ivy/wallet/logic/csv/model/ImportType.kt
+++ b/app/src/main/java/com/ivy/wallet/logic/csv/model/ImportType.kt
@@ -9,9 +9,10 @@ import com.ivy.wallet.ui.theme.*
enum class ImportType {
IVY,
- MONEY_MANAGER_PRASE,
+ MONEY_MANAGER,
WALLET_BY_BUDGET_BAKERS,
SPENDEE,
+ MONEFY,
ONE_MONEY,
BLUE_COINS,
KTW_MONEY_MANAGER,
@@ -20,9 +21,10 @@ enum class ImportType {
fun color(): Color = when (this) {
IVY -> Ivy
- MONEY_MANAGER_PRASE -> Red
+ MONEY_MANAGER -> Red
WALLET_BY_BUDGET_BAKERS -> Green
SPENDEE -> RedLight
+ MONEFY -> Green
ONE_MONEY -> Red3
BLUE_COINS -> Blue
KTW_MONEY_MANAGER -> Yellow
@@ -32,9 +34,10 @@ enum class ImportType {
fun appId(): String = when (this) {
IVY -> "com.ivy.wallet"
- MONEY_MANAGER_PRASE -> "com.realbyteapps.moneymanagerfree"
+ MONEY_MANAGER -> "com.realbyteapps.moneymanagerfree"
WALLET_BY_BUDGET_BAKERS -> "com.droid4you.application.wallet"
SPENDEE -> "com.cleevio.spendee"
+ MONEFY -> "com.monefy.app.lite"
ONE_MONEY -> "org.pixelrush.moneyiq"
BLUE_COINS -> "com.rammigsoftware.bluecoins"
KTW_MONEY_MANAGER -> "com.ktwapps.walletmanager"
@@ -44,10 +47,11 @@ enum class ImportType {
@DrawableRes
fun logo(): Int = when (this) {
- IVY -> R.drawable.ivy_wallet_logo_import
- MONEY_MANAGER_PRASE -> R.drawable.ic_money_manager_prase
+ IVY -> R.drawable.ivywallet_logo
+ MONEY_MANAGER -> R.drawable.moneymanager_logo
WALLET_BY_BUDGET_BAKERS -> R.drawable.wallet_by_budgetbakers_logo
- SPENDEE -> R.drawable.speende_logo_png
+ SPENDEE -> R.drawable.spendee_logo
+ MONEFY -> R.drawable.monefy_logo
ONE_MONEY -> R.drawable.one_money_logo
BLUE_COINS -> R.drawable.bluecoins
KTW_MONEY_MANAGER -> R.drawable.ktw_money_manager_logo
@@ -57,9 +61,10 @@ enum class ImportType {
fun listName(): String = when (this) {
IVY -> "Ivy Wallet CSV"
- MONEY_MANAGER_PRASE -> "Money Manager"
+ MONEY_MANAGER -> "Money Manager"
WALLET_BY_BUDGET_BAKERS -> "Wallet by BudgetBakers"
SPENDEE -> "Spendee"
+ MONEFY -> "Monefy"
ONE_MONEY -> "1Money"
BLUE_COINS -> "Bluecoins Finance"
KTW_MONEY_MANAGER -> "Money Manager (KTW)"
@@ -69,14 +74,7 @@ enum class ImportType {
fun appName(): String = when (this) {
IVY -> "Ivy Wallet"
- MONEY_MANAGER_PRASE -> "Money Manager"
- WALLET_BY_BUDGET_BAKERS -> "Wallet by BudgetBakers"
- SPENDEE -> "Spendee"
- ONE_MONEY -> "1Money"
- BLUE_COINS -> "Bluecoins Finance"
- KTW_MONEY_MANAGER -> "Money Manager (KTW)"
- FORTUNE_CITY -> "Fortune City"
- FINANCISTO -> "Financisto"
+ else -> listName()
}
@Composable
@@ -89,7 +87,7 @@ enum class ImportType {
onUploadClick = onUploadClick
)
}
- MONEY_MANAGER_PRASE -> {
+ MONEY_MANAGER -> {
MoneyManagerPraseSteps(
onUploadClick = onUploadClick
)
@@ -102,6 +100,9 @@ enum class ImportType {
SPENDEE -> SpendeeSteps(
onUploadClick = onUploadClick
)
+ MONEFY -> MonefySteps(
+ onUploadClick = onUploadClick
+ )
ONE_MONEY -> OneMoneySteps(
onUploadClick = onUploadClick
)
diff --git a/app/src/main/java/com/ivy/wallet/logic/csv/model/RowMapping.kt b/app/src/main/java/com/ivy/wallet/logic/csv/model/RowMapping.kt
index 17a15c70ab..9fdd0bf250 100644
--- a/app/src/main/java/com/ivy/wallet/logic/csv/model/RowMapping.kt
+++ b/app/src/main/java/com/ivy/wallet/logic/csv/model/RowMapping.kt
@@ -5,6 +5,7 @@ import com.ivy.wallet.model.entity.Transaction
data class RowMapping(
val type: Int? = null,
+ val defaultTypeToExpense: Boolean = false,
val amount: Int,
val account: Int,
@@ -14,6 +15,8 @@ data class RowMapping(
val accountIcon: Int? = null,
val date: Int,
+ val dateOnlyFormat: String? = null,
+ val dateTimeFormat: String? = null,
val timeOnly: Int? = null,
val dueDate: Int? = null,
diff --git a/app/src/main/java/com/ivy/wallet/ui/csvimport/flow/instructions/ImportInstructions.kt b/app/src/main/java/com/ivy/wallet/ui/csvimport/flow/instructions/ImportInstructions.kt
index 3abfc19e04..abef498ee3 100644
--- a/app/src/main/java/com/ivy/wallet/ui/csvimport/flow/instructions/ImportInstructions.kt
+++ b/app/src/main/java/com/ivy/wallet/ui/csvimport/flow/instructions/ImportInstructions.kt
@@ -355,7 +355,7 @@ private fun Preview() {
IvyAppPreview {
ImportInstructions(
hasSkip = true,
- importType = ImportType.MONEY_MANAGER_PRASE,
+ importType = ImportType.MONEY_MANAGER,
onSkip = {}
) {
diff --git a/app/src/main/java/com/ivy/wallet/ui/csvimport/flow/instructions/MonefySteps.kt b/app/src/main/java/com/ivy/wallet/ui/csvimport/flow/instructions/MonefySteps.kt
new file mode 100644
index 0000000000..a32953f21b
--- /dev/null
+++ b/app/src/main/java/com/ivy/wallet/ui/csvimport/flow/instructions/MonefySteps.kt
@@ -0,0 +1,27 @@
+package com.ivy.wallet.ui.csvimport.flow.instructions
+
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.height
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.unit.dp
+
+@Composable
+fun MonefySteps(
+ onUploadClick: () -> Unit
+) {
+ Spacer(Modifier.height(12.dp))
+
+ StepTitle(
+ number = 1,
+ title = "Export to file",
+ description = "Character set: UTF-8\nDecimal separator: Decimal point '.'\nDelimiter character: Comma ','"
+ )
+
+ Spacer(Modifier.height(24.dp))
+
+ UploadFileStep(
+ stepNumber = 2,
+ onUploadClick = onUploadClick
+ )
+}
\ No newline at end of file
diff --git a/app/src/main/res/drawable-nodpi/ivywallet_logo.png b/app/src/main/res/drawable-nodpi/ivywallet_logo.png
new file mode 100644
index 0000000000..5c7dcd3203
Binary files /dev/null and b/app/src/main/res/drawable-nodpi/ivywallet_logo.png differ
diff --git a/app/src/main/res/drawable-nodpi/monefy_logo.png b/app/src/main/res/drawable-nodpi/monefy_logo.png
new file mode 100644
index 0000000000..d8e502fad8
Binary files /dev/null and b/app/src/main/res/drawable-nodpi/monefy_logo.png differ
diff --git a/app/src/main/res/drawable-nodpi/moneymanager_logo.png b/app/src/main/res/drawable-nodpi/moneymanager_logo.png
new file mode 100644
index 0000000000..f312b31ff7
Binary files /dev/null and b/app/src/main/res/drawable-nodpi/moneymanager_logo.png differ
diff --git a/app/src/main/res/drawable-nodpi/spendee_logo.png b/app/src/main/res/drawable-nodpi/spendee_logo.png
new file mode 100644
index 0000000000..5d480a9fe9
Binary files /dev/null and b/app/src/main/res/drawable-nodpi/spendee_logo.png differ
diff --git a/app/src/main/res/drawable-nodpi/wallet_by_budgetbakers_logo.png b/app/src/main/res/drawable-nodpi/wallet_by_budgetbakers_logo.png
new file mode 100644
index 0000000000..1a8e14d67b
Binary files /dev/null and b/app/src/main/res/drawable-nodpi/wallet_by_budgetbakers_logo.png differ
diff --git a/app/src/main/res/drawable/ic_money_manager_prase.xml b/app/src/main/res/drawable/ic_money_manager_prase.xml
deleted file mode 100644
index 4d07a5e058..0000000000
--- a/app/src/main/res/drawable/ic_money_manager_prase.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
-
diff --git a/app/src/main/res/drawable/ivy_wallet_logo_import.xml b/app/src/main/res/drawable/ivy_wallet_logo_import.xml
deleted file mode 100644
index 55ebf179df..0000000000
--- a/app/src/main/res/drawable/ivy_wallet_logo_import.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/app/src/main/res/drawable/speende_logo_png.png b/app/src/main/res/drawable/speende_logo_png.png
deleted file mode 100644
index 59f526e8a5..0000000000
Binary files a/app/src/main/res/drawable/speende_logo_png.png and /dev/null differ
diff --git a/app/src/main/res/drawable/wallet_by_budgetbakers_logo.png b/app/src/main/res/drawable/wallet_by_budgetbakers_logo.png
deleted file mode 100644
index 38ffa52f2a..0000000000
Binary files a/app/src/main/res/drawable/wallet_by_budgetbakers_logo.png and /dev/null differ