Skip to content

Commit

Permalink
Refactor currency formatter & handle currencies with zero decimals (#65)
Browse files Browse the repository at this point in the history
Signed-off-by: starry-shivam <[email protected]>
  • Loading branch information
starry-shivam authored Jan 13, 2024
1 parent e9da129 commit 199f683
Show file tree
Hide file tree
Showing 11 changed files with 162 additions and 153 deletions.
6 changes: 3 additions & 3 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -82,10 +82,10 @@ dependencies {
// Android core components.
implementation 'androidx.core:core-ktx:1.12.0'
implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.6.2'
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.7.0'
implementation 'androidx.activity:activity-compose:1.8.2'
implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.6.2"
implementation "androidx.lifecycle:lifecycle-viewmodel-compose:2.6.2"
implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.7.0"
implementation "androidx.lifecycle:lifecycle-viewmodel-compose:2.7.0"
implementation "androidx.navigation:navigation-compose:2.7.6"
// Jetpack compose.
implementation "androidx.compose.ui:ui"
Expand Down
1 change: 1 addition & 0 deletions app/src/main/java/com/starry/greenstash/di/MainModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ class MainModule {
fun provideWidgetDao(appDatabase: AppDatabase) = appDatabase.getWidgetDao()

@Provides
@Singleton
fun providePreferenceUtil(@ApplicationContext context: Context) = PreferenceUtil(context)

@Provides
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ class ReminderNotificationSender(
.setContentIntent(createActivityIntent())

val remainingAmount = (goal.targetAmount - goalItem.getCurrentlySavedAmount())
val defCurrency = preferenceUtil.getString(PreferenceUtil.DEFAULT_CURRENCY_STR, "")
val defCurrency = preferenceUtil.getString(PreferenceUtil.DEFAULT_CURRENCY_STR, "")!!

if (goal.deadline.isNotEmpty() && goal.deadline.isNotBlank()) {
val calculatedDays = GoalTextUtils(preferenceUtil).calcRemainingDays(goal)
Expand All @@ -92,8 +92,8 @@ class ReminderNotificationSender(
val amountDay = remainingAmount / calculatedDays.remainingDays
notification.addAction(
R.drawable.ic_notification_deposit,
"${context.getString(R.string.deposit_button)} $defCurrency${
Utils.formatCurrency(Utils.roundDecimal(amountDay))
"${context.getString(R.string.deposit_button)} ${
Utils.formatCurrency(Utils.roundDecimal(amountDay), defCurrency)
}",
createDepositIntent(goal.goalId, amountDay)
)
Expand All @@ -103,8 +103,8 @@ class ReminderNotificationSender(
val amountSemiWeek = remainingAmount / (calculatedDays.remainingDays / 4)
notification.addAction(
R.drawable.ic_notification_deposit,
"${context.getString(R.string.deposit_button)} $defCurrency${
Utils.formatCurrency(Utils.roundDecimal(amountSemiWeek))
"${context.getString(R.string.deposit_button)} ${
Utils.formatCurrency(Utils.roundDecimal(amountSemiWeek), defCurrency)
}",
createDepositIntent(goal.goalId, amountSemiWeek)
)
Expand All @@ -114,8 +114,8 @@ class ReminderNotificationSender(
val amountWeek = remainingAmount / (calculatedDays.remainingDays / 7)
notification.addAction(
R.drawable.ic_notification_deposit,
"${context.getString(R.string.deposit_button)} $defCurrency${
Utils.formatCurrency(Utils.roundDecimal(amountWeek))
"${context.getString(R.string.deposit_button)} ${
Utils.formatCurrency(Utils.roundDecimal(amountWeek), defCurrency)
}",
createDepositIntent(goal.goalId, amountWeek)
)
Expand All @@ -138,11 +138,7 @@ class ReminderNotificationSender(
.setContentTitle(context.getString(R.string.notification_deposited_title))
.setContentText(
context.getString(R.string.notification_deposited_desc)
.format(
"$defCurrency${
Utils.formatCurrency(Utils.roundDecimal(amount))
}"
)
.format(Utils.formatCurrency(Utils.roundDecimal(amount), defCurrency!!))
)
.setStyle(NotificationCompat.BigTextStyle())
.setContentIntent(createActivityIntent())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@ import com.starry.greenstash.R

sealed class DrawerScreens(val route: String, val nameResId: Int, val iconResId: Int) {
data object Home : DrawerScreens("home", R.string.drawer_home, R.drawable.ic_nav_home)
data object Backups : DrawerScreens("backups", R.string.drawer_backups, R.drawable.ic_nav_backups)
data object Backups :
DrawerScreens("backups", R.string.drawer_backups, R.drawable.ic_nav_backups)

data object Settings :
DrawerScreens("settings", R.string.drawer_settings, R.drawable.ic_nav_settings)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -225,8 +225,10 @@ fun GoalInfoCard(
daysLeftText: String,
progress: Float
) {
val formattedTargetAmount = Utils.formatCurrency(Utils.roundDecimal(targetAmount))
val formattedSavedAmount = Utils.formatCurrency(Utils.roundDecimal(savedAmount))
val formattedTargetAmount =
Utils.formatCurrency(Utils.roundDecimal(targetAmount), currencySymbol)
val formattedSavedAmount =
Utils.formatCurrency(Utils.roundDecimal(savedAmount), currencySymbol)

Card(
modifier = Modifier
Expand Down Expand Up @@ -254,25 +256,21 @@ fun GoalInfoCard(

Spacer(modifier = Modifier.height(8.dp))

Row {
Text(
text = currencySymbol,
fontWeight = FontWeight.Bold,
fontSize = 38.sp,
modifier = Modifier.padding(start = 12.dp)
)
Text(
text = formattedSavedAmount,
fontWeight = FontWeight.Bold,
fontSize = 38.sp,
modifier = Modifier.padding(start = 4.dp)
)
}
Text(
text = formattedSavedAmount,
fontWeight = FontWeight.Bold,
fontSize = 38.sp,
modifier = Modifier.padding(start = 4.dp)
)


Spacer(modifier = Modifier.height(2.dp))

Text(
text = stringResource(id = R.string.info_card_remaining_amount).format("$currencySymbol $formattedTargetAmount"),
text = stringResource(
id = R.string.info_card_remaining_amount,
formattedTargetAmount
),
fontSize = 14.sp,
fontWeight = FontWeight.SemiBold,
modifier = Modifier.padding(start = 12.dp)
Expand Down Expand Up @@ -363,7 +361,7 @@ fun TransactionCard(transactions: List<Transaction>, currencySymbol: String) {
transactions.forEach {
TransactionItem(
transactionType = it.type,
amount = "$currencySymbol${Utils.formatCurrency(Utils.roundDecimal(it.amount))}",
amount = Utils.formatCurrency(Utils.roundDecimal(it.amount), currencySymbol),
date = it.getTransactionDate()
)
}
Expand Down
27 changes: 13 additions & 14 deletions app/src/main/java/com/starry/greenstash/utils/GoalTextUtils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,8 @@ class GoalTextUtils(private val preferenceUtil: PreferenceUtil) {
"\n" + context.getString(R.string.currently_saved_complete)
}
text = text.format(
"$defCurrency${Utils.formatCurrency(item.getCurrentlySavedAmount())}",
"$defCurrency${Utils.formatCurrency(item.goal.targetAmount)}"
Utils.formatCurrency(item.getCurrentlySavedAmount(), defCurrency!!),
Utils.formatCurrency(item.goal.targetAmount, defCurrency)
)
return text
}
Expand All @@ -84,29 +84,28 @@ class GoalTextUtils(private val preferenceUtil: PreferenceUtil) {
if ((remainingAmount > 0f)) {
if (item.goal.deadline.isNotEmpty() && item.goal.deadline.isNotBlank()) {
val calculatedDays = calcRemainingDays(item.goal)
val defCurrency = preferenceUtil.getString(PreferenceUtil.DEFAULT_CURRENCY_STR, "")
val defCurrency =
preferenceUtil.getString(PreferenceUtil.DEFAULT_CURRENCY_STR, "")!!
// build description string.
var text = context.getString(R.string.goal_days_left)
.format(calculatedDays.parsedEndDate, calculatedDays.remainingDays) + "\n"
if (calculatedDays.remainingDays > 2) {
text += context.getString(R.string.goal_approx_saving).format(
"$defCurrency${
Utils.formatCurrency(
Utils.roundDecimal(
remainingAmount / calculatedDays.remainingDays
)
)
}"
Utils.formatCurrency(
Utils.roundDecimal(
remainingAmount / calculatedDays.remainingDays
), defCurrency
)
)
text += context.getString(R.string.goal_approx_saving_day)
if (calculatedDays.remainingDays > 14) {
val weeks = calculatedDays.remainingDays / 7
text = text.dropLast(1) // remove full stop
text += ", $defCurrency${
text += ", ${
Utils.formatCurrency(
Utils.roundDecimal(
remainingAmount / weeks
)
), defCurrency
)
}/${
context.getString(
Expand All @@ -116,11 +115,11 @@ class GoalTextUtils(private val preferenceUtil: PreferenceUtil) {
if (calculatedDays.remainingDays > 60) {
val months = calculatedDays.remainingDays / 30
text = text.dropLast(1) // remove full stop
text += ", $defCurrency${
text += ", ${
Utils.formatCurrency(
Utils.roundDecimal(
remainingAmount / months
)
), defCurrency
)
}/${
context.getString(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ class PreferenceUtil(context: Context) {
// Preference keys
const val APP_THEME_INT = "theme_settings"
const val MATERIAL_YOU_BOOL = "material_you"
const val DEFAULT_CURRENCY_STR = "default_currency"
const val DEFAULT_CURRENCY_STR = "default_currency_code"
const val DATE_FORMAT_STR = "date_format"
const val APP_LOCK_BOOL = "app_lock"
}
Expand All @@ -48,7 +48,7 @@ class PreferenceUtil(context: Context) {
prefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE)
// Pre-populate some preference data with default values
if (!keyExists(DEFAULT_CURRENCY_STR)) {
putString(DEFAULT_CURRENCY_STR, "$")
putString(DEFAULT_CURRENCY_STR, "USD")
}
if (!keyExists(DATE_FORMAT_STR)) {
putString(DATE_FORMAT_STR, DateStyle.DateMonthYear.pattern)
Expand Down
15 changes: 12 additions & 3 deletions app/src/main/java/com/starry/greenstash/utils/Utils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@ import androidx.biometric.BiometricManager.Authenticators.DEVICE_CREDENTIAL
import java.math.RoundingMode
import java.text.DecimalFormat
import java.text.DecimalFormatSymbols
import java.text.NumberFormat
import java.text.SimpleDateFormat
import java.util.Currency
import java.util.Date
import java.util.Locale

Expand Down Expand Up @@ -64,9 +66,16 @@ object Utils {
}

/** Convert double into currency format */
fun formatCurrency(number: Double): String {
val df = DecimalFormat("#,###.00")
return df.format(number)
fun formatCurrency(amount: Double, currencyCode: String): String {
val nf = NumberFormat.getCurrencyInstance().apply {
currency = Currency.getInstance(currencyCode)
maximumFractionDigits = if (currencyCode in setOf(
"JPY", "DJF", "GNF", "IDR", "KMF", "KRW", "LAK",
"PYG", "RWF", "VND", "VUV", "XAF", "XOF", "XPF"
)
) 0 else 2
}
return nf.format(amount)
}

/**
Expand Down
17 changes: 10 additions & 7 deletions app/src/main/java/com/starry/greenstash/widget/GoalWidget.kt
Original file line number Diff line number Diff line change
Expand Up @@ -105,13 +105,16 @@ class GoalWidget : AppWidgetProvider() {
views.setCharSequence(R.id.widgetTitle, "setText", goalItem.goal.title)

// Set Widget description.
val defCurrency = preferenceUtil.getString(PreferenceUtil.DEFAULT_CURRENCY_STR, "$")
val defCurrency = preferenceUtil.getString(PreferenceUtil.DEFAULT_CURRENCY_STR, "")!!
val widgetDesc = context.getString(R.string.goal_widget_desc)
.format(
"$defCurrency${Utils.formatCurrency(goalItem.getCurrentlySavedAmount())} / $defCurrency${
"${
Utils.formatCurrency(
goalItem.goal.targetAmount
goalItem.getCurrentlySavedAmount(),
defCurrency
)
} / $defCurrency${
Utils.formatCurrency(goalItem.goal.targetAmount, defCurrency)
}"
)
views.setCharSequence(R.id.widgetDesc, "setText", widgetDesc)
Expand All @@ -122,22 +125,22 @@ class GoalWidget : AppWidgetProvider() {
if (goalItem.goal.deadline.isNotEmpty() && goalItem.goal.deadline.isNotBlank()) {
val calculatedDays = goalTextUtils.calcRemainingDays(goalItem.goal)
if (calculatedDays.remainingDays > 2) {
val amountDays = "$defCurrency${
val amountDays = "${
Utils.formatCurrency(
Utils.roundDecimal(
remainingAmount / calculatedDays.remainingDays
)
), defCurrency
)
}/${context.getString(R.string.goal_approx_saving_day)}"
views.setCharSequence(R.id.widgetAmountDay, "setText", amountDays)
views.setViewVisibility(R.id.widgetAmountDay, View.VISIBLE)
}
if (calculatedDays.remainingDays > 7) {
val amountWeeks = "$defCurrency${
val amountWeeks = "${
Utils.formatCurrency(
Utils.roundDecimal(
remainingAmount / (calculatedDays.remainingDays / 7)
)
), defCurrency
)
}/${
context.getString(
Expand Down
Loading

0 comments on commit 199f683

Please sign in to comment.