Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[feat] 이용예정/완료 API 연동 #27

Merged
merged 7 commits into from
Dec 1, 2023
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
1 change: 0 additions & 1 deletion app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@
android:exported="false"
android:screenOrientation="portrait"
tools:ignore="LockedOrientationActivity" />

<activity
android:name=".presentation.waiting.WaitingDetailActivity"
android:exported="false"
Expand Down
7 changes: 5 additions & 2 deletions app/src/main/java/org/sopt/tabling/data/ApiFactory.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@ import okhttp3.MediaType.Companion.toMediaType
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
import org.sopt.tabling.BuildConfig
import org.sopt.tabling.data.service.ApplyCodeService
import org.sopt.tabling.data.service.PopularStoreService
import org.sopt.tabling.data.service.ReservationListService
import org.sopt.tabling.data.service.ReserveService
import org.sopt.tabling.data.service.ShopDetailService
import org.sopt.tabling.data.service.ShopDetailService
import org.sopt.tabling.data.service.WaitingDetailService
import retrofit2.Retrofit

Expand All @@ -19,7 +20,7 @@ object ApiFactory {
HttpLoggingInterceptor().apply {
level =
if (BuildConfig.DEBUG) HttpLoggingInterceptor.Level.BODY else HttpLoggingInterceptor.Level.NONE
}
},
).build()
}
val retrofit: Retrofit by lazy {
Expand All @@ -32,6 +33,8 @@ object ApiFactory {
}

object ServicePool {
val reservationListService = ApiFactory.create<ReservationListService>()
val applyCodeService = ApiFactory.create<ApplyCodeService>()
val waitingDetailService = ApiFactory.create<WaitingDetailService>()
val shopDetailService = ApiFactory.create<ShopDetailService>()
val popularStoreService = ApiFactory.create<PopularStoreService>()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package org.sopt.tabling.data.model.request

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

@Serializable
data class RequestApplyCodeDto(
@SerialName("order_id")
val orderId: Int
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package org.sopt.tabling.data.model.response

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

@Serializable
data class ResponseApplyCodeDto(
@SerialName("code")
val code: Int,
@SerialName("message")
val message: String,
@SerialName("data")
val data: Data,
Comment on lines +8 to +13
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

저희 api 명세서 보면 code, message, data 이 세 개는 모든 response에 동일하게 존재하는데요
그렇기 때문에 얘네를 BaseResponse로 만들어 사용할 수 있습니당
저는 BaseResponse를 이용해서 작업했어용
코드 한 번 참고해보시면 좋을 것 같네요

) {
@Serializable
data class Data(
@SerialName("order_id")
val orderId: Int,
@SerialName("waiting_number")
val waitingNumber: Int,
@SerialName("before_count")
val beforeCount: Int,
@SerialName("shop_name")
val shopName: String,
@SerialName("person_count")
val personCount: Int,
@SerialName("order_status")
val orderStatus: String,
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package org.sopt.tabling.data.model.response

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

@Serializable
data class ResponseReservationDto(
@SerialName("code")
val code: Int,
@SerialName("message")
val message: String,
@SerialName("data")
val reservationList: List<Reservation>,
) {
@Serializable
data class Reservation(
@SerialName("order_id")
val orderId: Int,
@SerialName("order_status")
val orderStatus: String,
@SerialName("shop_id")
val shopId: Long,
@SerialName("shop_name")
val shopName: String,
@SerialName("order_date")
val orderDate: String,
@SerialName("person_count")
val personCount: Int,
@SerialName("waiting_number")
val waitingNumber: Int,
@SerialName("before_count")
val beforeCount: Int,
@SerialName("remaining_review_period")
val remainingReviewPeriod: Int,
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package org.sopt.tabling.data.service

import org.sopt.tabling.data.model.request.RequestApplyCodeDto
import org.sopt.tabling.data.model.response.ResponseApplyCodeDto
import retrofit2.Call
import retrofit2.http.Body
import retrofit2.http.PATCH

interface ApplyCodeService {
@PATCH("/orders/complete")
fun applyCode(
@Body request: RequestApplyCodeDto,
): Call<ResponseApplyCodeDto>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package org.sopt.tabling.data.service

import org.sopt.tabling.data.model.response.ResponseReservationDto
import retrofit2.Call
import retrofit2.http.GET

interface ReservationListService {
@GET("/orders")
fun getReservationList(): Call<ResponseReservationDto>
}
18 changes: 0 additions & 18 deletions app/src/main/java/org/sopt/tabling/domain/model/ReservationItem.kt

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,19 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import org.sopt.tabling.data.ServicePool
import org.sopt.tabling.data.model.request.RequestApplyCodeDto
import org.sopt.tabling.data.model.response.ResponseApplyCodeDto
import org.sopt.tabling.data.model.response.ResponseReservationDto
import org.sopt.tabling.databinding.FragmentQueueReservationBinding
import org.sopt.tabling.presentation.common.ReservationViewModel
import org.sopt.tabling.util.extension.showToast
import retrofit2.Call
import retrofit2.Response

class QueueReservationFragment : Fragment() {
private var _binding: FragmentQueueReservationBinding? = null
private val binding: FragmentQueueReservationBinding
get() = requireNotNull(_binding) { "바인딩 객체가 생성되지 않았습니다." }
private val viewModel by viewModels<ReservationViewModel>()

override fun onCreateView(
inflater: LayoutInflater,
Expand All @@ -27,13 +31,67 @@ class QueueReservationFragment : Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)

val reservationAdapter = ReservationAdapter(requireContext())
binding.rvReservationItems.adapter = reservationAdapter
reservationAdapter.setReservationList(viewModel.mockReservationList)
setReservationList()
}

override fun onDestroyView() {
super.onDestroyView()
_binding = null
}

private fun setReservationList() {
ServicePool.reservationListService.getReservationList()
.enqueue(object : retrofit2.Callback<ResponseReservationDto> {
override fun onResponse(
call: Call<ResponseReservationDto>,
response: Response<ResponseReservationDto>,
) {
if (response.isSuccessful) {
val data: ResponseReservationDto = response.body()!!
setReservationAdapter(data.reservationList)
if (response.code() == 500) {
context!!.showToast("서버 에러 발생")
}
}
}

override fun onFailure(call: Call<ResponseReservationDto>, t: Throwable) {
context!!.showToast("네트워크 에러 발생")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
context!!.showToast("네트워크 에러 발생")
Log.e("network", t.message.toString())

이런 식으로 토스트 메시지를 이용하는 게 아니라 내려오는 오류 값을 로그를 통해 찍어보면 어떤 것 때문에 실패했는지 알 수 있어서 좋아요

}
})
}

private fun setReservationAdapter(reserveList: List<ResponseReservationDto.Reservation>) {
val reservationAdapter = ReservationAdapter(requireContext(), ::patchApplyCode)
reservationAdapter.setReservationList(reserveList)
binding.rvReservationItems.adapter = reservationAdapter
}

private fun patchApplyCode(orderId: Int) {
ServicePool.applyCodeService.applyCode(RequestApplyCodeDto(orderId))
.enqueue(object : retrofit2.Callback<ResponseApplyCodeDto> {
override fun onResponse(
call: Call<ResponseApplyCodeDto>,
response: Response<ResponseApplyCodeDto>,
) {
if (response.isSuccessful) {
val data: ResponseApplyCodeDto = response.body()!!
if (response.code() == 400) {
context!!.showToast("이미 이용 완료된 주문입니다.")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

나중에 요런 것도 스트링 추출이나 상수화 해주면 좋을 듯요

} else if (response.code() == 404) {
context!!.showToast("일치하는 주문 내역 정보가 없습니다.")
} else if (response.code() == 500) {
context!!.showToast("서버 에러 발생")
} else {
context!!.showToast("변경이 완료되었습니다.")
setReservationList()
}
}
}

override fun onFailure(call: Call<ResponseApplyCodeDto>, t: Throwable) {
context!!.showToast("네트워크 에러 발생")
}
})
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,46 +4,63 @@ import android.content.Context
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import org.sopt.tabling.data.model.response.ResponseReservationDto
import org.sopt.tabling.databinding.ItemDoneReservationBinding
import org.sopt.tabling.databinding.ItemNoneReservationBinding
import org.sopt.tabling.databinding.ItemReservationBinding
import org.sopt.tabling.domain.model.ReservationItem

class ReservationAdapter(context: Context) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
class ReservationAdapter(
context: Context,
private val patchOnClick: (Int) -> Unit,
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
private val inflater by lazy { LayoutInflater.from(context) }

private var reservationList: List<ReservationItem> = emptyList()
private var reservationList: List<ResponseReservationDto.Reservation> = emptyList()

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return when (viewType) {
1 -> ReservationViewHolder(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

상수화 해주면 좋겠네용 ㅋ

ItemReservationBinding.inflate(inflater, parent, false),
patchOnClick,
)

2 -> ReservationDoneViewHolder(
ItemDoneReservationBinding.inflate(inflater, parent, false),
)

3 -> ReservationNoneViewHolder(
ItemNoneReservationBinding.inflate(inflater, parent, false),
)

else -> throw RuntimeException()
}
}

override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
when (holder) {
is ReservationViewHolder -> holder.onBind(reservationList[position] as ReservationItem.ReservationView)
is ReservationDoneViewHolder -> holder.onBind(reservationList[position] as ReservationItem.ReservationDoneView)
is ReservationViewHolder -> holder.onBind(reservationList[position])
is ReservationDoneViewHolder -> holder.onBind(reservationList[position])
is ReservationNoneViewHolder -> holder.onBind(reservationList[position])
}
}

override fun getItemViewType(position: Int): Int {
return when (reservationList[position]) {
is ReservationItem.ReservationView -> 1
is ReservationItem.ReservationDoneView -> 2
if (reservationList[position].orderStatus == "이용 예정") {
return 1
} else if (reservationList[position].orderStatus == "이용 완료") {
if (reservationList[position].remainingReviewPeriod <= 0) {
return 3
}
return 2
} else {
return 1
Comment on lines +48 to +56
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

여기 when문을 사용한다면 가독성이 더 좋아질 것 같아오

}
}

override fun getItemCount(): Int = reservationList.size

fun setReservationList(mockReservationList: List<ReservationItem>) {
reservationList = mockReservationList
fun setReservationList(reservationItemList: List<ResponseReservationDto.Reservation>) {
reservationList = reservationItemList
notifyDataSetChanged()
}
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
package org.sopt.tabling.presentation.queue

import androidx.recyclerview.widget.RecyclerView
import org.sopt.tabling.data.model.response.ResponseReservationDto
import org.sopt.tabling.databinding.ItemDoneReservationBinding
import org.sopt.tabling.domain.model.ReservationItem

class ReservationDoneViewHolder(private val binding: ItemDoneReservationBinding) :
RecyclerView.ViewHolder(binding.root) {
fun onBind(item: ReservationItem.ReservationDoneView) {
binding.tvReservationDate.text = item.reserveDate
binding.tvReservationPeople.text = item.reserveNum + ""
binding.tvStoreName.text = item.reserveName
binding.tvRemainReviewNum.text = item.remainReviewNum + ""
fun onBind(item: ResponseReservationDto.Reservation) {
binding.chipReservationWait.text = item.orderStatus
binding.tvReservationDate.text = item.orderDate
binding.tvReservationPeople.text = item.personCount.toString() + ""
binding.tvStoreName.text = item.shopName
binding.tvRemainReviewNum.text = item.remainingReviewPeriod.toString() + ""
}
}
Loading
Loading