Skip to content

Commit

Permalink
Merge pull request #94 from YAPP-Github/feature/MZ-129-my-statistics
Browse files Browse the repository at this point in the history
Feature/mz 129 my statistics
  • Loading branch information
yangsooplus authored Jan 25, 2024
2 parents a093f7e + 120a00f commit 90f0a4e
Show file tree
Hide file tree
Showing 26 changed files with 978 additions and 20 deletions.
15 changes: 15 additions & 0 deletions core/model/src/main/java/com/susu/core/model/MyStatistics.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.susu.core.model

import androidx.compose.runtime.Stable

@Stable
data class MyStatistics(
val highestAmountReceived: StatisticsElement = StatisticsElement(),
val highestAmountSent: StatisticsElement = StatisticsElement(),
val mostCategory: StatisticsElement = StatisticsElement(),
val mostRelationship: StatisticsElement = StatisticsElement(),
val mostSpentMonth: Int = 0,
val recentSpent: List<StatisticsElement> = emptyList(),
val recentTotalSpent: Int = 0,
val recentMaximumSpent: Int = 0,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.susu.core.model

import androidx.compose.runtime.Stable

@Stable
data class StatisticsElement(
val title: String = "",
val value: Int = 0,
)
1 change: 1 addition & 0 deletions core/ui/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
<string name="word_no">아니요</string>
<string name="word_phone_number">연락처</string>
<string name="word_memo">메모</string>
<string name="word_close">닫기</string>
<string name="word_register">등록</string>
<string name="word_free">자유</string>
<string name="content_description_report_button">신고 버튼</string>
Expand Down
7 changes: 7 additions & 0 deletions data/src/main/java/com/susu/data/data/di/RepositoryModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import com.susu.data.data.repository.LedgerRecentSearchRepositoryImpl
import com.susu.data.data.repository.LedgerRepositoryImpl
import com.susu.data.data.repository.LoginRepositoryImpl
import com.susu.data.data.repository.SignUpRepositoryImpl
import com.susu.data.data.repository.StatisticsRepositoryImpl
import com.susu.data.data.repository.TermRepositoryImpl
import com.susu.data.data.repository.TokenRepositoryImpl
import com.susu.data.data.repository.UserRepositoryImpl
Expand All @@ -16,6 +17,7 @@ import com.susu.domain.repository.LedgerRecentSearchRepository
import com.susu.domain.repository.LedgerRepository
import com.susu.domain.repository.LoginRepository
import com.susu.domain.repository.SignUpRepository
import com.susu.domain.repository.StatisticsRepository
import com.susu.domain.repository.TermRepository
import com.susu.domain.repository.TokenRepository
import com.susu.domain.repository.UserRepository
Expand Down Expand Up @@ -74,6 +76,11 @@ abstract class RepositoryModule {
excelRepositoryImpl: ExcelRepositoryImpl,
): ExcelRepository

@Binds
abstract fun bindStatisticsRepository(
statisticsRepositoryImpl: StatisticsRepositoryImpl,
): StatisticsRepository

@Binds
abstract fun bindVoteRepository(
voteRepositoryImpl: VoteRepositoryImpl,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.susu.data.data.repository

import com.susu.core.model.MyStatistics
import com.susu.core.model.StatisticsElement
import com.susu.data.remote.api.StatisticsService
import com.susu.data.remote.model.response.toModel
import com.susu.domain.repository.StatisticsRepository
import javax.inject.Inject

class StatisticsRepositoryImpl @Inject constructor(
private val statisticsService: StatisticsService,
) : StatisticsRepository {
override suspend fun getMyStatistics(): MyStatistics {
val originalStatistic = statisticsService.getMyStatistics().getOrThrow().toModel()
val sortedRecentSpent = originalStatistic.recentSpent.sortedBy { it.title.toInt() }
.map { StatisticsElement(title = it.title.substring(it.title.length - 2).toInt().toString(), value = it.value) }

return MyStatistics(
highestAmountReceived = originalStatistic.highestAmountReceived,
highestAmountSent = originalStatistic.highestAmountSent,
mostCategory = originalStatistic.mostCategory,
mostRelationship = originalStatistic.mostRelationship,
mostSpentMonth = originalStatistic.mostSpentMonth % 100,
recentSpent = sortedRecentSpent,
recentTotalSpent = originalStatistic.recentTotalSpent,
recentMaximumSpent = originalStatistic.recentMaximumSpent,
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,11 @@ class UserRepositoryImpl @Inject constructor(
}.firstOrNull() ?: throw UserNotFoundException()

val uid = json.decodeFromString<UserResponse>(localUserInfo).id
return userService.patchUserInfo(uid = uid, UserPatchRequest(name, gender, birth)).getOrThrow().toModel()
val patchedUserInfo = userService.patchUserInfo(uid = uid, UserPatchRequest(name, gender, birth)).getOrThrow()
dataStore.edit { preferences ->
preferences[userKey] = json.encodeToString(patchedUserInfo)
}
return patchedUserInfo.toModel()
}

override suspend fun logout() {
Expand Down
10 changes: 10 additions & 0 deletions data/src/main/java/com/susu/data/remote/api/StatisticsService.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.susu.data.remote.api

import com.susu.data.remote.model.response.MyStatisticsResponse
import com.susu.data.remote.retrofit.ApiResult
import retrofit2.http.GET

interface StatisticsService {
@GET("statistics/mine")
suspend fun getMyStatistics(): ApiResult<MyStatisticsResponse>
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import com.susu.data.remote.api.AuthService
import com.susu.data.remote.api.CategoryService
import com.susu.data.remote.api.LedgerService
import com.susu.data.remote.api.SignUpService
import com.susu.data.remote.api.StatisticsService
import com.susu.data.remote.api.TermService
import com.susu.data.remote.api.TokenService
import com.susu.data.remote.api.UserService
Expand Down Expand Up @@ -61,6 +62,12 @@ object ApiServiceModule {
return retrofit.create(UserService::class.java)
}

@Singleton
@Provides
fun providesStatisticsService(retrofit: Retrofit): StatisticsService {
return retrofit.create(StatisticsService::class.java)
}

@Singleton
@Provides
fun providesVoteService(retrofit: Retrofit): VoteService {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package com.susu.data.remote.model.response

import com.susu.core.model.MyStatistics
import kotlinx.serialization.Serializable

@Serializable
data class MyStatisticsResponse(
val highestAmountReceived: StatisticsElement,
val highestAmountSent: StatisticsElement,
val mostCategory: StatisticsElement,
val mostRelationship: StatisticsElement,
val mostSpentMonth: Int,
val recentSpent: List<StatisticsElement>,
)

@Serializable
data class StatisticsElement(
val title: String,
val value: Int,
)

fun MyStatisticsResponse.toModel() = MyStatistics(
highestAmountReceived = highestAmountReceived.toModel(),
highestAmountSent = highestAmountSent.toModel(),
mostCategory = mostCategory.toModel(),
mostRelationship = mostRelationship.toModel(),
mostSpentMonth = mostSpentMonth,
recentSpent = recentSpent.map { it.toModel() },
recentMaximumSpent = recentSpent.maxOfOrNull { it.value } ?: 0,
recentTotalSpent = recentSpent.sumOf { it.value },
)

fun StatisticsElement.toModel() = com.susu.core.model.StatisticsElement(
title = title,
value = value,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.susu.domain.repository

import com.susu.core.model.MyStatistics

interface StatisticsRepository {
suspend fun getMyStatistics(): MyStatistics
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.susu.domain.usecase.statistics

import com.susu.core.common.runCatchingIgnoreCancelled
import com.susu.domain.repository.UserRepository
import javax.inject.Inject

class CheckAdditionalUserInfoUseCase @Inject constructor(
private val userRepository: UserRepository,
) {
suspend operator fun invoke() = runCatchingIgnoreCancelled {
val userInfo = userRepository.getUserInfo()
userInfo.birth in 1930..2030 && (userInfo.gender == "M" || userInfo.gender == "F")
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.susu.domain.usecase.statistics

import com.susu.core.common.runCatchingIgnoreCancelled
import com.susu.domain.repository.StatisticsRepository
import javax.inject.Inject

class GetMyStatisticsUseCase @Inject constructor(
private val statisticsRepository: StatisticsRepository,
) {
suspend operator fun invoke() = runCatchingIgnoreCancelled {
statisticsRepository.getMyStatistics()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
Expand Down Expand Up @@ -70,6 +71,10 @@ fun MyPageInfoRoute(

val uiState by viewModel.uiState.collectAsStateWithLifecycle()

LaunchedEffect(key1 = Unit) {
viewModel.getUserInfo()
}

BackHandler {
if (uiState.isEditing) {
viewModel.cancelEdit()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,7 @@ class MyPageInfoViewModel @Inject constructor(
private val patchUserUseCase: PatchUserUseCase,
) : BaseViewModel<MyPageInfoState, MyPageInfoEffect>(MyPageInfoState()) {

init {
getUserInfo()
}

private fun getUserInfo() {
fun getUserInfo() {
viewModelScope.launch {
intent { copy(isLoading = true) }
getUserUseCase().onSuccess {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,9 @@ internal fun MainScreen(
)

statisticsNavGraph(
padding = innerPadding,
navigateToMyInfo = navigator::navigateMyPageInfo,
onShowDialog = viewModel::onShowDialog,
handleException = viewModel::handleException,
)

communityNavGraph(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.susu.feature.statistics

import androidx.annotation.StringRes
import com.susu.core.ui.base.SideEffect
import com.susu.core.ui.base.UiState

enum class StatisticsTab(@StringRes val stringId: Int) {
MY(R.string.statistics_tab_my),
AVERAGE(R.string.statistics_tab_average),
}

data class StatisticsState(
val isLoading: Boolean = false,
val isBlind: Boolean = true,
val currentTab: StatisticsTab = StatisticsTab.MY,
) : UiState

sealed interface StatisticsEffect : SideEffect {
data object ShowAdditionalInfoDialog : StatisticsEffect
data class HandleException(val throwable: Throwable, val retry: () -> Unit) : StatisticsEffect
}
Loading

0 comments on commit 90f0a4e

Please sign in to comment.