Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.eatssu.android.data.remote.dto.response

import com.eatssu.android.domain.model.Partnership
import com.eatssu.common.enums.PeriodType
import com.eatssu.common.enums.StoreType
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
Expand Down Expand Up @@ -37,7 +38,9 @@ data class PartnershipResponse(
@SerialName("startDate")
val startDate: String? = null,
@SerialName("endDate")
val endDate: String? = null
val endDate: String? = null,
@SerialName("periodType")
val periodType: PeriodType = PeriodType.NORMAL
)
}

Expand All @@ -57,7 +60,8 @@ fun PartnershipResponse.toDomain(): Partnership =
isLiked = it.isLiked ?: false,
description = it.description ?: "",
startDate = it.startDate ?: "",
endDate = it.endDate ?: ""
endDate = it.endDate ?: "",
periodType = it.periodType
)
}
)
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.eatssu.android.domain.model

import com.eatssu.common.enums.PeriodType
import com.eatssu.common.enums.StoreType

data class Partnership(
Expand All @@ -18,6 +19,7 @@ data class Partnership(
val isLiked: Boolean,
val description: String,
val startDate: String,
val endDate: String
val endDate: String,
val periodType: PeriodType,
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import com.eatssu.common.UiEvent
import com.eatssu.common.UiState
import com.eatssu.common.analytics.AnalyticsTracker
import com.eatssu.common.analytics.MapAnalyticsEvent
import com.eatssu.common.enums.PeriodType
import com.eatssu.common.enums.StoreType
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.MutableSharedFlow
Expand Down Expand Up @@ -76,25 +77,28 @@ class MapViewModel @Inject constructor(
val userCollegeDepartment = getUserCollegeDepartmentUseCase()
val newDepartmentId = userCollegeDepartment.userDepartment.departmentId.toLong()
val newCollegeId = userCollegeDepartment.userCollege.collegeId.toLong()
// Festival 존재 여부를 판단하고, All/Festival 초기 목록에도 재사용한다.
val allPartnerships = partnershipRepository.getAllPartnerships()

_departmentId.value = newDepartmentId
_collegeId.value = newCollegeId

// departmentId가 변경되면 필터 자동 설정
val current = uiState.value
val currentData = if (current is UiState.Success) current.data else MapState()
val initialFilter = if (newDepartmentId == -1L) FilterType.All else FilterType.Mine

// Festival 제휴가 하나라도 있으면 Festival을 우선하고, 없으면 기존 기본 필터 규칙을 따른다.
val initialFilter = when {
allPartnerships.hasFestivalPartnership() -> FilterType.Festival
newDepartmentId == -1L -> FilterType.All
else -> FilterType.Mine
}
_uiState.value = UiState.Success(
MapState(selectedFilter = initialFilter)
MapState(selectedFilter = initialFilter),
)

// 초기 필터에 따라 데이터 로드
when (initialFilter) {
FilterType.All -> loadPartnerships()
FilterType.All -> loadPartnerships(prefetchedPartnerships = allPartnerships)
FilterType.Festival -> loadFestivalPartnerships(prefetchedPartnerships = allPartnerships)
FilterType.Mine -> loadUserCollegePartnerships()
}

Timber.d("학과 정보 : ${userCollegeDepartment.userDepartment.departmentName}")
}
}
Expand Down Expand Up @@ -130,6 +134,10 @@ class MapViewModel @Inject constructor(
analyticsTracker.track(MapAnalyticsEvent.AllClicked)
}

FilterType.Festival -> {
loadFestivalPartnerships()
}

FilterType.Mine -> {
loadUserCollegePartnerships()
analyticsTracker.track(
Expand All @@ -143,19 +151,51 @@ class MapViewModel @Inject constructor(
}

// 제휴 정보 로딩
private fun loadPartnerships() {
private fun loadPartnerships(
prefetchedPartnerships: List<Partnership>? = null,
) {
viewModelScope.launch {
val current = uiState.value
val currentData = if (current is UiState.Success) current.data else MapState()

_uiState.value = UiState.Loading

val partnerships = partnershipRepository.getAllPartnerships()
if (prefetchedPartnerships == null)
_uiState.value = UiState.Loading

val partnerships = prefetchedPartnerships ?: partnershipRepository.getAllPartnerships()
_uiState.value = UiState.Success(
currentData.copy(
partnerships = partnerships,
filterChangeResult = null
filterChangeResult = null,
),
)
}
}

private fun loadFestivalPartnerships(
prefetchedPartnerships: List<Partnership>? = null,
) {
viewModelScope.launch {
val current = uiState.value
val currentData = if (current is UiState.Success) current.data else MapState()

if (prefetchedPartnerships == null)
_uiState.value = UiState.Loading

val partnerships = partnershipRepository.getAllPartnerships().mapNotNull {
val festivalInfos =
it.partnershipInfos.filter { info -> info.periodType == PeriodType.FESTIVAL }
if (festivalInfos.isEmpty()) return@mapNotNull null

it.copy(
partnershipInfos = festivalInfos
)
}

_uiState.value = UiState.Success(
currentData.copy(
partnerships = partnerships,
filterChangeResult = null,
),
)
}
}
Expand All @@ -172,8 +212,8 @@ class MapViewModel @Inject constructor(
_uiState.value = UiState.Success(
currentData.copy(
partnerships = partnerships,
filterChangeResult = null
)
filterChangeResult = null,
),
)
}
}
Expand Down Expand Up @@ -205,8 +245,22 @@ class MapViewModel @Inject constructor(
data.copy(
restaurantPartnershipInfo = representative,
restaurantInfoList = restaurantInfoList,
storeType = representative.storeType
)
storeType = representative.storeType,
),
)
}
}

private fun List<Partnership>.hasFestivalPartnership(): Boolean =
any { partnership ->
partnership.partnershipInfos.any { info -> info.periodType == PeriodType.FESTIVAL }
}

private fun List<Partnership>.festivalPartnerships(): List<Partnership> =
mapNotNull { partnership ->
val festivalInfos =
partnership.partnershipInfos.filter { info -> info.periodType == PeriodType.FESTIVAL }
if (festivalInfos.isEmpty()) return@mapNotNull null

partnership.copy(partnershipInfos = festivalInfos)
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,9 @@ import com.eatssu.design_system.theme.White
import timber.log.Timber

enum class FilterType(@StringRes val labelResId: Int) {
Festival(R.string.partnership_filter_festival),
All(R.string.partnership_filter_all),
Mine(R.string.partnership_filter_mine),
All(R.string.partnership_filter_all)
}

@Composable
Expand All @@ -42,6 +43,7 @@ fun FilterType.getLabel(departmentName: String): String {
departmentName
}
}
FilterType.Festival -> stringResource(labelResId)
FilterType.All -> stringResource(labelResId)
}
}
Expand Down
1 change: 1 addition & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,7 @@
<string name="time">영업 시간</string>
<string name="favorite_partnership">찜한 제휴</string>
<string name="partnership_filter_mine">내 제휴</string>
<string name="partnership_filter_festival">축제</string>
<string name="partnership_filter_all">전체</string>
<string name="partnership_filter_department_placeholder">학과</string>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.eatssu.android.domain.usecase.user

import com.eatssu.android.domain.model.Partnership
import com.eatssu.android.test.AppBehaviorSpec
import com.eatssu.common.enums.PeriodType
import com.eatssu.common.enums.StoreType
import io.kotest.matchers.shouldBe

Expand All @@ -20,6 +21,7 @@ class GetPartnershipDetailUseCaseBehaviorSpec : AppBehaviorSpec({
description = "10% 할인",
startDate = "2025-01-01",
endDate = "2025-12-31",
periodType = PeriodType.NORMAL
),
Partnership.PartnershipInfo(
id = 2,
Expand All @@ -31,6 +33,7 @@ class GetPartnershipDetailUseCaseBehaviorSpec : AppBehaviorSpec({
description = "음료 증정",
startDate = "2025-02-01",
endDate = "2025-11-30",
periodType = PeriodType.NORMAL
),
)
val partnerships = listOf(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,18 @@ import com.eatssu.android.test.AppBehaviorSpec
import com.eatssu.android.test.samplePartnership
import com.eatssu.android.test.samplePartnershipRestaurant
import com.eatssu.android.test.sampleUserInfo
import com.eatssu.common.UiState
import com.eatssu.common.analytics.AnalyticsTracker
import com.eatssu.common.analytics.MapAnalyticsEvent
import com.eatssu.common.UiState
import com.eatssu.common.enums.PeriodType
import com.eatssu.common.enums.StoreType
import io.kotest.assertions.nondeterministic.eventually
import io.kotest.matchers.shouldBe
import io.mockk.Runs
import io.mockk.clearMocks
import io.mockk.coEvery
import io.mockk.coVerify
import io.mockk.every
import io.mockk.just
import io.mockk.mockk
import io.mockk.mockkObject
import io.mockk.verify
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.delay
Expand Down Expand Up @@ -170,6 +168,7 @@ class MapViewModelBehaviorSpec : AppBehaviorSpec({
description = "10% 할인",
startDate = "2025-01-01",
endDate = "2025-12-31",
periodType = PeriodType.NORMAL,
),
Partnership.PartnershipInfo(
id = 2,
Expand All @@ -181,6 +180,7 @@ class MapViewModelBehaviorSpec : AppBehaviorSpec({
description = "음료 증정",
startDate = "2025-02-01",
endDate = "2025-11-30",
periodType = PeriodType.NORMAL,
),
)
val partnerships = listOf(
Expand Down Expand Up @@ -310,6 +310,7 @@ class MapViewModelBehaviorSpec : AppBehaviorSpec({
description = "할인",
startDate = "2025-01-01",
endDate = "2025-12-31",
periodType = PeriodType.NORMAL,
)
),
)
Expand Down
2 changes: 2 additions & 0 deletions app/src/test/java/com/eatssu/android/test/TestFixtures.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import com.eatssu.android.domain.model.Review
import com.eatssu.android.domain.model.ReviewInfo
import com.eatssu.android.domain.model.Token
import com.eatssu.android.domain.model.UserInfo
import com.eatssu.common.enums.PeriodType
import com.eatssu.common.enums.StoreType

fun sampleCollege(
Expand Down Expand Up @@ -83,6 +84,7 @@ fun samplePartnership(
description = "desc",
startDate = "2025-01-01",
endDate = "2025-12-31",
periodType = PeriodType.NORMAL,
),
),
type: StoreType = StoreType.CAFE,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.eatssu.common.enums

import kotlinx.serialization.Serializable

@Serializable
enum class PeriodType {
FESTIVAL, NORMAL
}
Loading