Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/#15/feat-payment-ui' into #21/fe…
Browse files Browse the repository at this point in the history
…at-search-api
  • Loading branch information
gitsuhyun committed Nov 28, 2024
2 parents 529c671 + 90de28c commit 97f98bb
Show file tree
Hide file tree
Showing 22 changed files with 915 additions and 9 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.sopt.korailtalk.data.mapper.todata

import com.sopt.korailtalk.data.remote.model.request.TicketBuyingRequestDto
import com.sopt.korailtalk.domain.model.TicketBuying

fun TicketBuying.toData(): TicketBuyingRequestDto = TicketBuyingRequestDto(
ticketId = this.ticketId,
totalPrice = this.totalPrice,
usedPoint = this.usedPoint
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.sopt.korailtalk.data.mapper.todomain

import com.sopt.korailtalk.data.remote.model.response.LPointResponseDto
import com.sopt.korailtalk.domain.model.LPoint

fun LPointResponseDto.toDomain(): LPoint = LPoint(
isValid = this.isValid,
point = this.point
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.sopt.korailtalk.data.remote.datasource

import com.sopt.korailtalk.data.remote.model.base.ApiResponse
import com.sopt.korailtalk.data.remote.model.request.TicketBuyingRequestDto
import com.sopt.korailtalk.data.remote.model.response.LPointResponseDto

interface PaymentRemoteDataSource {
suspend fun getLpoint(userId: Long, pointPassword: Int): ApiResponse<LPointResponseDto>
suspend fun buyTicket(ticketBuyingRequestDto: TicketBuyingRequestDto): ApiResponse<Unit>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.sopt.korailtalk.data.remote.datasourceimpl

import com.sopt.korailtalk.data.remote.datasource.PaymentRemoteDataSource
import com.sopt.korailtalk.data.remote.model.request.TicketBuyingRequestDto
import com.sopt.korailtalk.data.remote.service.PaymentService
import javax.inject.Inject

class PaymentRemoteDataSourceImpl @Inject constructor(
private val paymentService: PaymentService
) : PaymentRemoteDataSource {
override suspend fun getLpoint(userId: Long, pointPassword: Int) =
paymentService.getLpoint(userId, pointPassword)

override suspend fun buyTicket(ticketBuyingRequestDto: TicketBuyingRequestDto) =
paymentService.buyTicket(ticketBuyingRequestDto)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.sopt.korailtalk.data.remote.model.request

import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

@Serializable
data class TicketBuyingRequestDto(
@SerialName("ticketId") val ticketId: Long,
@SerialName("totalPrice") val totalPrice: Int,
@SerialName("usedPoint") val usedPoint: Int
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.sopt.korailtalk.data.remote.model.response

import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

@Serializable
data class LPointResponseDto(
@SerialName("isValid") val isValid: Boolean,
@SerialName("point") val point: Int
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.sopt.korailtalk.data.remote.service

import com.sopt.korailtalk.data.remote.model.base.ApiResponse
import com.sopt.korailtalk.data.remote.model.request.TicketBuyingRequestDto
import com.sopt.korailtalk.data.remote.model.response.LPointResponseDto
import retrofit2.http.Body
import retrofit2.http.GET
import retrofit2.http.Header
import retrofit2.http.PATCH
import retrofit2.http.Query

interface PaymentService {
@GET("/users/points")
suspend fun getLpoint(
@Header("userId") userId: Long,
@Query("pointPassword") pointPassword: Int
): ApiResponse<LPointResponseDto>

@PATCH("/tickets")
suspend fun buyTicket(
@Body ticketBuyingRequestDto: TicketBuyingRequestDto
): ApiResponse<Unit>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.sopt.korailtalk.data.repositoryimpl

import com.sopt.korailtalk.data.mapper.todata.toData
import com.sopt.korailtalk.data.mapper.todomain.toDomain
import com.sopt.korailtalk.data.remote.datasource.PaymentRemoteDataSource
import com.sopt.korailtalk.data.remote.util.handleApiResponse
import com.sopt.korailtalk.domain.model.LPoint
import com.sopt.korailtalk.domain.model.TicketBuying
import com.sopt.korailtalk.domain.repository.PaymentRepository
import javax.inject.Inject

class PaymentRepositoryImpl @Inject constructor(
private val paymentRemoteDataSource: PaymentRemoteDataSource
) : PaymentRepository {
override suspend fun getLpoint(userId: Long, pointPassword: Int): Result<LPoint> {
return runCatching {
paymentRemoteDataSource.getLpoint(userId = userId, pointPassword = pointPassword)
.handleApiResponse().getOrThrow().toDomain()
}
}

override suspend fun buyTicket(ticketBuying: TicketBuying): Result<Unit> {
return runCatching {
paymentRemoteDataSource.buyTicket(ticketBuyingRequestDto = ticketBuying.toData())
}
}
}
8 changes: 8 additions & 0 deletions app/src/main/java/com/sopt/korailtalk/di/DataSourceModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ package com.sopt.korailtalk.di
import com.sopt.korailtalk.data.local.datasource.ExampleLocalDataSource
import com.sopt.korailtalk.data.local.datasourceimpl.ExampleLocalDataSourceImpl
import com.sopt.korailtalk.data.remote.datasource.ExampleRemoteDataSource
import com.sopt.korailtalk.data.remote.datasource.PaymentRemoteDataSource
import com.sopt.korailtalk.data.remote.datasourceimpl.ExampleRemoteDataSourceImpl
import com.sopt.korailtalk.data.remote.datasourceimpl.PaymentRemoteDataSourceImpl
import dagger.Binds
import dagger.Module
import dagger.hilt.InstallIn
Expand All @@ -24,4 +26,10 @@ abstract class DataSourceModule {
abstract fun bindExampleRemoteDataSource(
exampleRemoteDataSourceImpl: ExampleRemoteDataSourceImpl
): ExampleRemoteDataSource

@Binds
@Singleton
abstract fun bindPaymentRemoteDataSource(
paymentRemoteDataSourceImpl: PaymentRemoteDataSourceImpl
): PaymentRemoteDataSource
}
56 changes: 51 additions & 5 deletions app/src/main/java/com/sopt/korailtalk/di/NetworkModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,49 @@ package com.sopt.korailtalk.di

import com.jakewharton.retrofit2.converter.kotlinx.serialization.asConverterFactory
import com.sopt.korailtalk.BuildConfig
import com.sopt.korailtalk.BuildConfig.DEBUG
import com.sopt.korailtalk.di.qualifier.Auth
import com.sopt.korailtalk.di.qualifier.KorailTalk
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import kotlinx.serialization.json.Json
import okhttp3.Interceptor
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Retrofit
import java.util.concurrent.TimeUnit
import javax.inject.Singleton

@Module
@InstallIn(SingletonComponent::class)
object NetworkModule {
@Provides
@Singleton
fun providesOkHttpClient(
loggingInterceptor: HttpLoggingInterceptor,
@Auth authInterceptor: Interceptor
): OkHttpClient =
OkHttpClient.Builder().apply {
connectTimeout(10, TimeUnit.SECONDS)
writeTimeout(10, TimeUnit.SECONDS)
readTimeout(10, TimeUnit.SECONDS)
addInterceptor(authInterceptor)
if (DEBUG) addInterceptor(loggingInterceptor)
}.build()

@Provides
@Singleton
fun providesJson(): Json =
Json {
isLenient = true
prettyPrint = true
explicitNulls = false
ignoreUnknownKeys = true
}

@Provides
@Singleton
fun provideLoggingInterceptor(): HttpLoggingInterceptor = HttpLoggingInterceptor().apply {
Expand All @@ -25,20 +53,38 @@ object NetworkModule {

@Provides
@Singleton
@KorailTalk
fun provideKorailTalkBaseUrl(): String = BuildConfig.BASE_URL
@Auth
fun provideAuthInterceptor(): Interceptor = Interceptor { chain ->
val request = chain.request().newBuilder()
.addHeader("Authorization", "Bearer <Your_Token_Here>")
.build()
chain.proceed(request)
}

@Provides
@Singleton
fun provideRetrofit(
okHttpClient: OkHttpClient,
baseUrl: String
json: Json
): Retrofit {
val json = Json { ignoreUnknownKeys = true }
return Retrofit.Builder()
.baseUrl(BuildConfig.BASE_URL)
.client(okHttpClient)
.addConverterFactory(json.asConverterFactory("application/json".toMediaType()))
.baseUrl(baseUrl)
.build()
}

@Provides
@Singleton
@KorailTalk
fun provideKorailTalkRetrofit(
okHttpClient: OkHttpClient,
json: Json
): Retrofit {
return Retrofit.Builder()
.baseUrl(BuildConfig.BASE_URL)
.client(okHttpClient)
.addConverterFactory(json.asConverterFactory("application/json".toMediaType()))
.build()
}
}
8 changes: 8 additions & 0 deletions app/src/main/java/com/sopt/korailtalk/di/RepositoryModule.kt
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package com.sopt.korailtalk.di

import com.sopt.korailtalk.data.repositoryimpl.ExampleRepositoryImpl
import com.sopt.korailtalk.data.repositoryimpl.PaymentRepositoryImpl
import com.sopt.korailtalk.domain.repository.ExampleRepository
import com.sopt.korailtalk.domain.repository.PaymentRepository
import dagger.Binds
import dagger.Module
import dagger.hilt.InstallIn
Expand All @@ -16,4 +18,10 @@ abstract class RepositoryModule {
abstract fun bindExampleRepository(
exampleRepositoryImpl: ExampleRepositoryImpl
): ExampleRepository

@Binds
@Singleton
abstract fun bindPaymentRepository(
paymentRepositoryImpl: PaymentRepositoryImpl
): PaymentRepository
}
6 changes: 6 additions & 0 deletions app/src/main/java/com/sopt/korailtalk/di/ServiceModule.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.sopt.korailtalk.di

import com.sopt.korailtalk.data.remote.service.ExampleService
import com.sopt.korailtalk.data.remote.service.PaymentService
import com.sopt.korailtalk.di.qualifier.KorailTalk
import dagger.Module
import dagger.Provides
Expand All @@ -16,4 +17,9 @@ object ServiceModule {
@Singleton
fun provideExampleService(@KorailTalk retrofit: Retrofit): ExampleService =
retrofit.create(ExampleService::class.java)

@Provides
@Singleton
fun providePaymentService(@KorailTalk retrofit: Retrofit): PaymentService =
retrofit.create(PaymentService::class.java)
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ package com.sopt.korailtalk.di.qualifier
import javax.inject.Qualifier

@Qualifier
@Retention(AnnotationRetention.BINARY)
annotation class KorailTalk

@Qualifier
@Retention(AnnotationRetention.BINARY)
annotation class Auth
6 changes: 6 additions & 0 deletions app/src/main/java/com/sopt/korailtalk/domain/model/LPoint.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.sopt.korailtalk.domain.model

data class LPoint(
val isValid: Boolean,
val point: Int,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.sopt.korailtalk.domain.model

data class TicketBuying (
val ticketId: Long,
val totalPrice: Int,
val usedPoint: Int,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.sopt.korailtalk.domain.repository

import com.sopt.korailtalk.domain.model.LPoint
import com.sopt.korailtalk.domain.model.TicketBuying

interface PaymentRepository {
suspend fun getLpoint(userId: Long, pointPassword: Int): Result<LPoint>
suspend fun buyTicket(ticketBuying: TicketBuying): Result<Unit>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.sopt.korailtalk.presentation.ui.payment

import com.sopt.korailtalk.domain.model.LPoint

sealed class LPointState {
data object Idle: LPointState()
data object Loading: LPointState()
data class Success(val data: LPoint): LPointState()
data class Failure(val message: String): LPointState()
}
Loading

0 comments on commit 97f98bb

Please sign in to comment.