Skip to content

Commit

Permalink
Dynamically calculate ranges for budget
Browse files Browse the repository at this point in the history
Remove hardcoded values and update Blaze default constants
  • Loading branch information
JorgeMucientes committed Jan 24, 2024
1 parent 7aa3c98 commit 997dd8d
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,12 @@ class BlazeRepository @Inject constructor(
private val timezoneProvider: TimezoneProvider,
) {
companion object {
const val DEFAULT_CURRENCY_CODE = "USD" // For now only USD are supported
const val BLAZE_DEFAULT_CURRENCY_CODE = "USD" // For now only USD are supported
const val DEFAULT_CAMPAIGN_DURATION = 7 // Days
const val CAMPAIGN_MAX_DURATION = 28 // Days
const val DEFAULT_CAMPAIGN_TOTAL_BUDGET = 35F // USD
const val CAMPAIGN_MINIMUM_DAILY_SPEND_LIMIT = 5F // USD
const val CAMPAIGN_MAXIMUM_DAILY_SPEND_LIMIT = 50F // USD
const val CAMPAIGN_MAX_DURATION = 28 // Days
const val ONE_DAY_IN_MILLIS = 1000 * 60 * 60 * 24
}

Expand All @@ -31,7 +33,7 @@ class BlazeRepository @Inject constructor(
budget = Budget(
totalBudget = DEFAULT_CAMPAIGN_TOTAL_BUDGET,
spentBudget = 0f,
currencyCode = DEFAULT_CURRENCY_CODE,
currencyCode = BLAZE_DEFAULT_CURRENCY_CODE,
durationInDays = DEFAULT_CAMPAIGN_DURATION,
startDate = Date().apply { time += ONE_DAY_IN_MILLIS }, // By default start tomorrow
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ import com.woocommerce.android.R
import com.woocommerce.android.R.color
import com.woocommerce.android.R.dimen
import com.woocommerce.android.R.drawable
import com.woocommerce.android.ui.blaze.BlazeRepository.Companion.CAMPAIGN_MAX_DURATION
import com.woocommerce.android.ui.compose.component.BottomSheetHandle
import com.woocommerce.android.ui.compose.component.Toolbar
import com.woocommerce.android.ui.compose.component.WCColoredButton
Expand Down Expand Up @@ -101,6 +100,7 @@ private fun CampaignBudgetScreen(
duration = state.durationInDays,
startDate = state.startDateMmmDdYyyy,
onDurationChanged = { onCampaignDurationUpdated(it.toInt()) },
durationRange = state.durationRangeDays,
onApplyTapped = { coroutineScope.launch { modalSheetState.hide() } }
)
}
Expand Down Expand Up @@ -182,7 +182,7 @@ private fun EditBudgetSection(
Slider(
modifier = Modifier.padding(top = 8.dp, bottom = 8.dp),
value = state.totalBudget,
valueRange = 35f..350f,
valueRange = state.budgetRange,
onValueChange = { onBudgetUpdated(it) },
colors = SliderDefaults.colors(
inactiveTrackColor = colorResource(id = color.divider_color)
Expand Down Expand Up @@ -287,6 +287,7 @@ private fun ImpressionsInfoBottomSheet(
private fun EditDurationBottomSheet(
duration: Int,
startDate: String,
durationRange: ClosedFloatingPointRange<Float>,
onDurationChanged: (Float) -> Unit,
onApplyTapped: () -> Unit,
modifier: Modifier = Modifier,
Expand All @@ -311,7 +312,7 @@ private fun EditDurationBottomSheet(
.padding(top = 8.dp, bottom = 8.dp)
.fillMaxWidth(),
value = duration.toFloat(),
valueRange = 0f..CAMPAIGN_MAX_DURATION.toFloat(),
valueRange = durationRange,
onValueChange = onDurationChanged,
colors = SliderDefaults.colors(
inactiveTrackColor = colorResource(id = color.divider_color)
Expand Down Expand Up @@ -347,10 +348,12 @@ private fun CampaignBudgetScreenPreview() {
state = BlazeCampaignBudgetViewModel.BudgetUiState(
totalBudget = 35f,
spentBudget = 0f,
budgetRange = 35f..350f,
currencyCode = "USD",
durationInDays = 7,
dailySpending = "$5 USD",
dailySpending = "$5",
startDateMmmDdYyyy = "Dec 13, 2023",
durationRangeDays = 1f..28f,
forecast = BlazeCampaignBudgetViewModel.ForecastUi(
isLoaded = false,
impressionsMin = 0,
Expand All @@ -377,6 +380,7 @@ private fun EditDurationBottomSheetPreview() {
EditDurationBottomSheet(
duration = 7,
startDate = "Dec 13, 2023",
durationRange = 1f..28f,
onDurationChanged = {},
onApplyTapped = {},
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@ package com.woocommerce.android.ui.blaze.creation.budget
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.SavedStateHandle
import com.woocommerce.android.extensions.formatToMMMddYYYY
import com.woocommerce.android.ui.blaze.BlazeRepository.Companion.BLAZE_DEFAULT_CURRENCY_CODE
import com.woocommerce.android.ui.blaze.BlazeRepository.Companion.CAMPAIGN_MAXIMUM_DAILY_SPEND_LIMIT
import com.woocommerce.android.ui.blaze.BlazeRepository.Companion.CAMPAIGN_MAX_DURATION
import com.woocommerce.android.ui.blaze.BlazeRepository.Companion.CAMPAIGN_MINIMUM_DAILY_SPEND_LIMIT
import com.woocommerce.android.ui.blaze.BlazeRepository.Companion.DEFAULT_CAMPAIGN_DURATION
import com.woocommerce.android.ui.blaze.BlazeRepository.Companion.DEFAULT_CAMPAIGN_TOTAL_BUDGET
import com.woocommerce.android.util.CurrencyFormatter
import com.woocommerce.android.viewmodel.MultiLiveEvent.Event.Exit
import com.woocommerce.android.viewmodel.ScopedViewModel
Expand All @@ -17,11 +23,13 @@ class BlazeCampaignBudgetViewModel @Inject constructor(
) : ScopedViewModel(savedStateHandle) {
private val _viewState = MutableLiveData(
BudgetUiState(
totalBudget = 35f,
currencyCode = BLAZE_DEFAULT_CURRENCY_CODE,
totalBudget = DEFAULT_CAMPAIGN_TOTAL_BUDGET,
spentBudget = 0f,
dailySpending = "$5",
currencyCode = "USD",
durationInDays = 7,
budgetRange = getBudgetRange(DEFAULT_CAMPAIGN_DURATION),
dailySpending = getDailySpending(DEFAULT_CAMPAIGN_TOTAL_BUDGET, DEFAULT_CAMPAIGN_DURATION),
durationInDays = DEFAULT_CAMPAIGN_DURATION,
durationRangeDays = getDurationRange(),
startDateMmmDdYyyy = Date().formatToMMMddYYYY(),
forecast = ForecastUi(
isLoaded = false,
Expand Down Expand Up @@ -53,27 +61,33 @@ class BlazeCampaignBudgetViewModel @Inject constructor(
fun onTotalBudgetUpdated(totalBudget: Float) {
_viewState.value = _viewState.value?.copy(
totalBudget = totalBudget,
dailySpending = currencyFormatter.formatCurrency(
(totalBudget / viewState.value?.durationInDays!!).toBigDecimal()
)
dailySpending = getDailySpending(totalBudget, viewState.value?.durationInDays!!)
)
}

fun onCampaignDurationUpdated(duration: Int) {
_viewState.value = _viewState.value?.copy(
durationInDays = duration,
dailySpending = currencyFormatter.formatCurrency(
(viewState.value?.totalBudget!! / duration).toBigDecimal()
)
dailySpending = getDailySpending(viewState.value?.totalBudget!!, duration)
)
}

private fun getDailySpending(totalBudget: Float, duration: Int) =
currencyFormatter.formatCurrency((totalBudget / duration).toBigDecimal(), BLAZE_DEFAULT_CURRENCY_CODE)

private fun getBudgetRange(currentDuration: Int) =
currentDuration * CAMPAIGN_MINIMUM_DAILY_SPEND_LIMIT..currentDuration * CAMPAIGN_MAXIMUM_DAILY_SPEND_LIMIT

private fun getDurationRange() = 1f..CAMPAIGN_MAX_DURATION.toFloat()

data class BudgetUiState(
val currencyCode: String,
val totalBudget: Float,
val spentBudget: Float,
val budgetRange: ClosedFloatingPointRange<Float>,
val dailySpending: String,
val currencyCode: String,
val durationInDays: Int,
val durationRangeDays: ClosedFloatingPointRange<Float>,
val startDateMmmDdYyyy: String,
val forecast: ForecastUi,
val showImpressionsBottomSheet: Boolean = false,
Expand Down

0 comments on commit 997dd8d

Please sign in to comment.