Skip to content

Commit d96e539

Browse files
kkh725comst19
andauthored
[PC-1614] Billing 모듈 의존성 리팩토링 (#201)
* [PC-1614] billing 모듈에 di 추가하고, 기존 dataModule의 의존성 제거 * [PC-1614] 사용하지않는 common 모듈 제거 * [PC-1614] Billing Module 리팩토링 - domain 모듈 의존성 제거 - analytics 사용하는 부분 제거 * [PC-1614] VerifyPurchaseProduct 제거 후 Int로 변경 * [PC-1614] 모델 분리하지않고 패키지밖으로 위치변경 * [PC-1639] Matching, Notificaiton 이슈 수정 (#207) * [PC-1639] 읽지 않은 notification 개수 확인 api 추가 * [PC-1639] matchingScreen 과 안읽은 알람 연동 완료 * [PC-1639] 24시간 이후인지 판단하는 string 확장함수 추가 * [PC-1639] UserInfo에 isApprovalExpired 파라미터 추가. -승인 후 24시간 여부 * [PC-1639] isApprovalExpired 관련 로직 추가 * [PC-1639] 매칭 풀 부족(기본) 다이얼로그 리팩토링 * [PC-1639] 즉시매칭 에러타입 추가 및 매칭풀부족 팝업 이슈 해결 * [PC-1639] unknown_error sideEffect 추가 * [PC-1639] 결제 성공 시 상품리스트 다시 풀러오는 로직 추가 * [PC-1639] 서버가 제공하는 순서로 상품을 넘겨주도록 수정 * [PC-1639] 기본 매칭 풀 부족 다이얼로그 표출 로직 수정 * [PC-1639] 알람 아이콘 res 수정 * [PC-1639] 기존 로직 변경에 따른 테스트 코드 수정 * [PC-1639] 매칭 screen 레이아웃 수정 * [PC-1639] 기존 로직 변경에 따른 테스트 코드 수정 * [PC-1639] pending, waiting 화면에 PiecePullRefreshBox 추가 * [PC-1639] 사용하지 않는 ic_alarm_black_unread.xml 제거 * [PC-1639] isOver24Hours 함수 crash 에러 방지 로직 추가 * [PC-1639] pending 인 경우 24시간 승인 여부 false로 수정 * [PC-1639] hasUnreadNotifications 비즈니스 모델 repository에서 계산하게 변경 --------- Co-authored-by: comst19 <[email protected]> * [PC-1614] notification 테스트 수정 --------- Co-authored-by: comst19 <[email protected]>
1 parent 34e537f commit d96e539

File tree

45 files changed

+452
-320
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+452
-320
lines changed

core/billing/build.gradle.kts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,7 @@ android {
88
}
99

1010
dependencies {
11-
implementation(projects.core.common)
12-
implementation(projects.core.domain)
1311
implementation(projects.core.network)
14-
implementation(projects.core.analytics)
1512

1613
implementation(libs.android.billingclient)
1714
}

core/billing/src/main/java/com/puzzle/billing/data/BillingHelperImpl.kt

Lines changed: 11 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -13,19 +13,16 @@ import com.android.billingclient.api.PurchasesUpdatedListener
1313
import com.android.billingclient.api.QueryProductDetailsParams
1414
import com.android.billingclient.api.QueryPurchasesParams
1515
import com.android.billingclient.api.queryProductDetails
16-
import com.puzzle.analytics.AnalyticsHelper
1716
import com.puzzle.billing.domain.BillingHelper
1817
import com.puzzle.billing.domain.PaymentRepository
1918
import com.puzzle.billing.model.NormalProduct
2019
import com.puzzle.billing.model.PieceProduct
2120
import com.puzzle.billing.model.PromotionProduct
2221
import com.puzzle.billing.model.PurchaseResult
23-
import com.puzzle.domain.model.payment.CashProduct
24-
import com.puzzle.domain.model.payment.Product
25-
import com.puzzle.domain.model.payment.PurchaseProduct
22+
import com.puzzle.billing.model.CashProduct
23+
import com.puzzle.billing.model.Product
24+
import com.puzzle.billing.model.PurchaseProduct
2625
import dagger.hilt.android.qualifiers.ApplicationContext
27-
import kotlinx.collections.immutable.ImmutableList
28-
import kotlinx.collections.immutable.toImmutableList
2926
import kotlinx.coroutines.CoroutineScope
3027
import kotlinx.coroutines.Dispatchers
3128
import kotlinx.coroutines.SupervisorJob
@@ -44,7 +41,6 @@ import kotlin.coroutines.resumeWithException
4441

4542
class BillingHelperImpl @Inject constructor(
4643
private val paymentRepository: PaymentRepository,
47-
private val analyticsHelper: AnalyticsHelper,
4844
@ApplicationContext context: Context,
4945
) : BillingHelper {
5046
private val _purchaseResult = Channel<PurchaseResult>(Channel.BUFFERED)
@@ -104,7 +100,7 @@ class BillingHelperImpl @Inject constructor(
104100
private suspend fun fetchPurchaseReward(purchase: Purchase): Int {
105101
val productId = purchase.products.firstOrNull() ?: throw Exception("상품 ID 없습니다.")
106102

107-
val verifyResult = withContext(Dispatchers.IO) {
103+
val rewardPuzzleCount = withContext(Dispatchers.IO) {
108104
paymentRepository.verifyPurchaseProduct(
109105
PurchaseProduct(
110106
uuid = productId,
@@ -113,14 +109,7 @@ class BillingHelperImpl @Inject constructor(
113109
)
114110
}
115111

116-
if (verifyResult.rewardPuzzleCount > 0) {
117-
analyticsHelper.trackRevenueEvent(
118-
productId = productId,
119-
price = verifyResult.rewardPuzzleCount.toDouble(),
120-
)
121-
}
122-
123-
return verifyResult.rewardPuzzleCount
112+
return rewardPuzzleCount
124113
}
125114

126115
private suspend fun handleSinglePurchase(purchase: Purchase) {
@@ -160,14 +149,15 @@ class BillingHelperImpl @Inject constructor(
160149

161150
val result = withContext(Dispatchers.IO) { billingClient.queryProductDetails(params) }
162151
val products = result.productDetailsList ?: emptyList()
152+
val playProductMap = products.associateBy { it.productId }
163153

164154
// 3. 서버 상품과 Google Play 상품 매칭 후 변환
165-
return products.mapNotNull { product ->
166-
val serverProduct = cashProducts.products.find { it.uuid == product.productId }
167-
serverProduct?.let {
155+
return cashProducts.products.mapNotNull { serverProduct ->
156+
val playProduct = playProductMap[serverProduct.uuid]
157+
playProduct?.let {
168158
convertToPieceProduct(
169-
productDetail = product,
170-
serverProduct = it
159+
productDetail = it,
160+
serverProduct = serverProduct
171161
)
172162
}
173163
}

core/billing/src/main/java/com/puzzle/billing/data/PaymentRepositoryImpl.kt

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
package com.puzzle.billing.data
22

33
import com.puzzle.billing.domain.PaymentRepository
4-
import com.puzzle.domain.model.payment.CashProduct
5-
import com.puzzle.domain.model.payment.PurchaseProduct
6-
import com.puzzle.network.source.payment.PaymentDataSource
4+
import com.puzzle.billing.mapper.payment.toDomain
5+
import com.puzzle.billing.model.CashProduct
6+
import com.puzzle.billing.model.PurchaseProduct
7+
import com.puzzle.billing.network.source.payment.PaymentDataSource
78
import javax.inject.Inject
89

910
class PaymentRepositoryImpl @Inject constructor(
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package com.puzzle.billing.di
2+
3+
import com.puzzle.billing.data.BillingHelperImpl
4+
import com.puzzle.billing.data.PaymentRepositoryImpl
5+
import com.puzzle.billing.domain.BillingHelper
6+
import com.puzzle.billing.domain.PaymentRepository
7+
import com.puzzle.billing.network.source.payment.PaymentDataSource
8+
import com.puzzle.billing.network.source.payment.PaymentDataSourceImpl
9+
import dagger.Binds
10+
import dagger.Module
11+
import dagger.hilt.InstallIn
12+
import dagger.hilt.components.SingletonComponent
13+
import javax.inject.Singleton
14+
15+
@Module
16+
@InstallIn(SingletonComponent::class)
17+
abstract class BillingModule {
18+
@Binds
19+
@Singleton
20+
abstract fun bindPaymentDataSource(
21+
paymentDataSourceImpl: PaymentDataSourceImpl
22+
): PaymentDataSource
23+
24+
@Binds
25+
@Singleton
26+
abstract fun bindPaymentRepository(
27+
paymentRepositoryImpl: PaymentRepositoryImpl
28+
): PaymentRepository
29+
30+
@Binds
31+
@Singleton
32+
abstract fun bindBillingHelper(
33+
billingHelperImpl: BillingHelperImpl
34+
): BillingHelper
35+
}

core/billing/src/main/java/com/puzzle/billing/domain/BillingHelper.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ package com.puzzle.billing.domain
33
import android.app.Activity
44
import com.puzzle.billing.model.PieceProduct
55
import com.puzzle.billing.model.PurchaseResult
6-
import com.puzzle.domain.model.payment.CashProduct
6+
import com.puzzle.billing.model.CashProduct
77
import kotlinx.coroutines.flow.Flow
88

99
interface BillingHelper {
Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
package com.puzzle.billing.domain
22

3-
import com.puzzle.domain.model.payment.CashProduct
4-
import com.puzzle.domain.model.payment.PurchaseProduct
5-
import com.puzzle.domain.model.payment.VerifyPurchaseProduct
3+
import com.puzzle.billing.model.CashProduct
4+
import com.puzzle.billing.model.PurchaseProduct
65

76
interface PaymentRepository {
87
suspend fun getAvailableProduct(): CashProduct
9-
suspend fun verifyPurchaseProduct(purchaseProduct: PurchaseProduct): VerifyPurchaseProduct
8+
suspend fun verifyPurchaseProduct(purchaseProduct: PurchaseProduct): Int
109
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package com.puzzle.billing.mapper.payment
2+
3+
import com.puzzle.billing.model.CashProduct
4+
import com.puzzle.billing.model.Product
5+
import com.puzzle.network.model.UNKNOWN_INT
6+
import com.puzzle.network.model.payment.BasicCashProductResponse
7+
import com.puzzle.network.model.payment.GetAvailableProductResponse
8+
import com.puzzle.network.model.payment.PromotionProductResponse
9+
import com.puzzle.network.model.payment.VerifyPurchaseProductResponse
10+
import java.math.BigDecimal
11+
12+
internal fun GetAvailableProductResponse.toDomain(): CashProduct =
13+
CashProduct(
14+
products = this.promotionCashProducts.map(PromotionProductResponse::toDomain) +
15+
this.basicCashProducts.map(BasicCashProductResponse::toDomain),
16+
)
17+
18+
internal fun BasicCashProductResponse.toDomain(): Product.BasicCashProduct =
19+
Product.BasicCashProduct(
20+
uuid = this.uuid,
21+
name = this.name,
22+
rewardPuzzleCount = this.rewardPuzzleCount,
23+
originalAmount = BigDecimal(this.originalAmount),
24+
discountRate = this.discountRate,
25+
discountedAmount = BigDecimal(this.discountedAmount),
26+
)
27+
28+
internal fun PromotionProductResponse.toDomain(): Product.PromotionProduct =
29+
Product.PromotionProduct(
30+
uuid = this.uuid,
31+
imageUrl = this.cardImageUrl,
32+
)
33+
34+
internal fun VerifyPurchaseProductResponse.toDomain(): Int = this.rewardPuzzleCount ?: UNKNOWN_INT

core/domain/src/main/java/com/puzzle/domain/model/payment/BasicCashProduct.kt renamed to core/billing/src/main/java/com/puzzle/billing/model/BasicCashProduct.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
package com.puzzle.domain.model.payment
1+
package com.puzzle.billing.model
22

33
import java.math.BigDecimal
44

5+
// api
56
data class CashProduct(
67
val products: List<Product>,
78
)

core/billing/src/main/java/com/puzzle/billing/model/PieceProduct.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package com.puzzle.billing.model
22

33
import com.android.billingclient.api.ProductDetails
44

5+
// for ui
56
sealed interface PieceProduct {
67
val id: String
78
val detail: ProductDetails
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package com.puzzle.billing.model
2+
3+
import com.puzzle.network.model.payment.VerifyPurchaseProductRequest
4+
5+
// api
6+
data class PurchaseProduct(
7+
val uuid: String,
8+
val credential: String,
9+
val store: Store = Store.PLAY_STORE,
10+
) {
11+
fun toDto() = VerifyPurchaseProductRequest(
12+
productUUID = uuid,
13+
purchaseCredential = credential,
14+
store = store.name,
15+
)
16+
}
17+
18+
enum class Store {
19+
PLAY_STORE, APP_STORE
20+
}

0 commit comments

Comments
 (0)