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

[부나] 2단계 재화 미션 제출합니다. #26

Merged
merged 78 commits into from
Jun 5, 2023
Merged
Show file tree
Hide file tree
Changes from 63 commits
Commits
Show all changes
78 commits
Select commit Hold shift + click to select a range
a7a3ad9
feat: 하마드 서버 base url 추가
tmdgh1592 May 26, 2023
b100514
feat(Page): 공통 코드를 Page 클래스로 이동
tmdgh1592 May 29, 2023
79a07c9
docs: 주문 기능 구현 기능 목록 작성
tmdgh1592 May 30, 2023
8b7cc29
chore: Retrofit 라이브러리 추가
tmdgh1592 May 30, 2023
4e05fce
feat: RetrofitServiceCreater 구현
tmdgh1592 May 30, 2023
ffbf8c3
refactor: OkHttpClient를 Retrofit으로 리팩터링
tmdgh1592 May 30, 2023
708d742
feat: 상품 주문하기 ui 구현
tmdgh1592 May 30, 2023
9ad002d
feat: 주문할 상품을 보여주는 화면 구현
tmdgh1592 May 31, 2023
491ff6a
feat: PointEditText 커스텀뷰 구현
tmdgh1592 May 31, 2023
b2de7d3
feat: 장바구니 아이템 주문하는 기능 구현
tmdgh1592 May 31, 2023
902b7c9
feat: 쇼핑 목록 화면으로 이동하는 기능 구현
tmdgh1592 May 31, 2023
4f6292c
feat: 주문 목록을 불러오는 기능 구현
tmdgh1592 May 31, 2023
521ed80
feat: 상세 주문 내역을 보여주는 기능 구현
tmdgh1592 Jun 1, 2023
db6e20d
fix: 상품 주문시, 상품 id와 수량을 서버에 보내는 대신 cartItemId를 전달하도록 변경
tmdgh1592 Jun 1, 2023
cc52965
refactor: RecyclerViewBindingAdapter의 setAdapter 메서드의 인자를 ConcatAdapt…
tmdgh1592 Jun 1, 2023
9b4c856
refactor: ORDER_DETAIL과 ORDER 뷰타입의 value를 OrderProduct에서 관리하도록 변경
tmdgh1592 Jun 1, 2023
c9babbe
refactor: cartItemIds를 orderItems로 변경
tmdgh1592 Jun 1, 2023
4c4311b
chore: kotlinx.serialization 라이브러리 추가
tmdgh1592 Jun 1, 2023
d7e8da7
refactor: Dto에 Serializable 어노테이션 추가
tmdgh1592 Jun 1, 2023
4054061
feat: 각 화면별로 뒤로가기 기능 구현
tmdgh1592 Jun 1, 2023
558c694
refactor: 라인 포맷팅
tmdgh1592 Jun 1, 2023
4b6cfed
refactor: isolatedViewTypeConcatAdapter을 notIsolatedViewTypeConcatAda…
tmdgh1592 Jun 1, 2023
8a05f31
feat: 스낵바를 보여주는 확장함수 구현
tmdgh1592 Jun 1, 2023
15ef714
refactor: 상품 주문 완료시 스낵바로 메시지를 보여주도록 변경
tmdgh1592 Jun 1, 2023
87709b2
refactor: 사용하지 않는 클래스, 메서드 제거
tmdgh1592 Jun 1, 2023
9685128
refactor: ShoppingDatabase를 싱클톤으로 변경
tmdgh1592 Jun 1, 2023
c68c1f1
refactor: inject 메서드명을 명시적으로 변경
tmdgh1592 Jun 1, 2023
471bf9a
refactor: ui의 CartProduct typealias를 제거하고 Model suffix를 붙이도록 변경
tmdgh1592 Jun 1, 2023
05e244c
refactor: ui의 OrderModel typealias를 제거하고 Model suffix를 붙이도록 변경
tmdgh1592 Jun 1, 2023
3f9f6e8
refactor: ui의 OrderProductModel typealias를 제거하고 Model suffix를 붙이도록 변경
tmdgh1592 Jun 1, 2023
f5a1fd1
refactor: ui의 UiPage typealias를 제거하고 Model suffix를 붙이도록 변경
tmdgh1592 Jun 1, 2023
53e96a7
refactor: ui의 UiPayment typealias를 제거하고 Model suffix를 붙이도록 변경
tmdgh1592 Jun 1, 2023
948c74f
refactor: ui의 PointUi typealias를 제거하고 Model suffix를 붙이도록 변경
tmdgh1592 Jun 1, 2023
740390a
refactor: ui의 PriceUi typealias를 제거하고 Model suffix를 붙이도록 변경
tmdgh1592 Jun 1, 2023
ea3d85a
refactor: ui의 UiProduct typealias를 제거하고 Model suffix를 붙이도록 변경
tmdgh1592 Jun 1, 2023
aecf209
refactor: ui의 UiProductCount typealias를 제거하고 Model suffix를 붙이도록 변경
tmdgh1592 Jun 1, 2023
aea0e58
refactor: ui의 UiRecentProduct typealias를 제거하고 Model suffix를 붙이도록 변경
tmdgh1592 Jun 1, 2023
2dd17a1
refactor: 함수 네이밍 통일화
tmdgh1592 Jun 1, 2023
f479f24
refactor: 재화 관련 도메인을 추상화
tmdgh1592 Jun 1, 2023
93b2b76
refactor: OrderPresenter 중복 코드를 메서드로 분리
tmdgh1592 Jun 2, 2023
9a6a1cd
refactor: Ui 모델 파라미터명을 cartProductModel로 변경
tmdgh1592 Jun 2, 2023
3e167d6
refactor: 네이밍 통일화
tmdgh1592 Jun 2, 2023
46b6475
refactor: abstract class를 interface로 변경
tmdgh1592 Jun 2, 2023
0196ee7
refactor: page 관련 뷰 업데이트를 하나의 추상 메서드로 변경
tmdgh1592 Jun 2, 2023
8f88737
refactor: OrderActivity의 showOrders 메서드명 변경
tmdgh1592 Jun 2, 2023
c33533c
refactor: PaymentRequest의 SerializedName 파라미터명 변경
tmdgh1592 Jun 2, 2023
1255597
test: ProductDetailPresenter 테스트 코드 작성
tmdgh1592 Jun 2, 2023
ab5d8e8
test: ShoppingPresenter 테스트 코드 작성
tmdgh1592 Jun 2, 2023
611aca8
test: OrderPresenter 테스트 코드 작성
tmdgh1592 Jun 2, 2023
6211ba8
feat: 응답에 대해 response의 body null 여부를 검사하도록 변경
tmdgh1592 Jun 2, 2023
59459aa
refactor: typealias가 적용되지 않은 ProductId에 typealias 적용
tmdgh1592 Jun 2, 2023
31df852
fix: item_order_history.xml에서 binding type이 맞지 않아 크래시 발생하는 버그 수정
tmdgh1592 Jun 2, 2023
743fb78
fix: item_order_history.xml에서 제품 이미지뷰에 scaleType 적용
tmdgh1592 Jun 2, 2023
c716daa
feat: 상세 주문 내역 뒤로가기 기능 구현
tmdgh1592 Jun 2, 2023
8a67f4f
feat: Gson의 SerializedName을 kotlinx-serialization의 SerialName으로 변경
tmdgh1592 Jun 2, 2023
6637bb7
chore: Gson 라이브러리 의존성 제거
tmdgh1592 Jun 2, 2023
ce80e22
fix: gson 라이브러리 import 제거
tmdgh1592 Jun 2, 2023
ccf431b
fix: 주문 상세 리사이클러뷰에서 아이템이 보여지지 않는 버그 수정
tmdgh1592 Jun 2, 2023
a9a1cbf
feat: 주문 상세 아이템의 상품 이미지에 scaleType(centerCrop) 적용
tmdgh1592 Jun 2, 2023
02836bc
fix: 결제 아이템 뷰의 높이를 wrap_content로 변경
tmdgh1592 Jun 2, 2023
e1fded7
fix: CounterView의 숫자를 클릭하면 뒤의 배경이 클릭되는 버그 수정
tmdgh1592 Jun 2, 2023
23e0295
refactor: Log 출력 제거
tmdgh1592 Jun 2, 2023
6deb885
refactor: 코드 포맷팅
tmdgh1592 Jun 2, 2023
7b5f9a4
fix: 토큰 설정이 안 되었던 버그 수정
tmdgh1592 Jun 4, 2023
a59cc1b
refactor: 주문 목록 가져오는 api body 형식 변경에 따른 dto 변경
tmdgh1592 Jun 4, 2023
5f2fb98
feat: 필요 없는 않는 json 변환 옵션 제거
tmdgh1592 Jun 4, 2023
f2f6a9b
refactor: toText() 시그니처 대신 toString()을 오버라이드하여 사용하도록 변경
tmdgh1592 Jun 4, 2023
4497d33
refactor: 제품 가져오기 페이지네이션 api 적용
tmdgh1592 Jun 4, 2023
a70f99e
refactor: 주문 목록 api 변경에 따른 스펙 변경
tmdgh1592 Jun 4, 2023
0bc40f5
refactor: findCartProductByProductId의 실패 콜백 람다의 인자 변경
tmdgh1592 Jun 5, 2023
f2bd29c
refactor: 장바구니에 담긴 제품 개수를 매번 서버에 요청하도록 변경
tmdgh1592 Jun 5, 2023
a82f66f
refactor: Repository 네이밍의 Impl을 Default로 변경
tmdgh1592 Jun 5, 2023
5c9cea7
feat: 주문 목록 페이징 구현
tmdgh1592 Jun 5, 2023
1e09e7a
fix: 쇼핑 리스트 페이지네이션이 동작하지 않는 버그 수정
tmdgh1592 Jun 5, 2023
1a46c16
refactor: 주문 목록 더 보기 기능에서 take 함수를 호출하지 않도록 변경
tmdgh1592 Jun 5, 2023
1a2b2ff
fix: 최근 상품 목록에서 장바구니 개수가 담기지 않는 버그 수정
tmdgh1592 Jun 5, 2023
39f71be
fix: 최근 상품 디테일 화면에서 상품 개수를 더해지지 않는 버그 수정
tmdgh1592 Jun 5, 2023
d9c98c2
fix: 커스텀뷰에서 TypedArray 인스턴스에 use 사용를 사용하는 대신 recycle() 메서드를 호출하도록 변경
tmdgh1592 Jun 5, 2023
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
34 changes: 30 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,35 @@
# android-shopping-order

## UI
- [ ] 데이터가 로딩되기 전 상태에서는 스켈레톤 UI를 노출한다.
- [ ] 메인 액티비티가 로딩되기 전에 서버를 선택한다.
- [x] 데이터가 로딩되기 전 상태에서는 스켈레톤 UI를 노출한다.
- [x] 메인 액티비티가 로딩되기 전에 서버를 선택한다.

## Domain
- [ ] 사용자 인증 정보를 저장한다.
- [ ] 서버를 선택하여 교체할 수 있다.
- [x] 사용자 인증 정보를 저장한다.
- [x] 서버를 선택하여 교체할 수 있다.
- [x] 장바구니에 담은 상품을 주문할 수 있다.
```gherkin
Given 장바구니에서 주문할 상품을 선택한다.
When 상품을 주문한다.
Then 주문이 완료되면 성공 메시지를 보여준다.
```
- [x] 상품 주문시 포인트를 적용할 수 있다.
```gherkin
Given 장바구니에서 선택된 상품이 존재한다.
And 포인트가 존재한다.
When 상품을 주문한다.
Then 포인트가 적용된 가격으로 주문한다.
```
- [x] 사용자 별로 주문 목록을 확인할 수 있다.
```gherkin
Given 사용자가 주문한 상품이 존재한다.
When 주문 목록을 확인한다.
Then 주문 목록을 보여준다.
```
- [x] 특정 주문의 상세 정보를 확인할 수 있다.
```gherkin
Given 주문한 목록이 존재한다.
When 특정 주문을 조회한다.
Then 특정 주문의 상세 정보를 보여준다.
```
- [x] 서버 통신을 Retrofit으로 리팩터링한다.
11 changes: 11 additions & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ plugins {
id("org.jetbrains.kotlin.android")
id("kotlin-kapt")
id("kotlin-parcelize")
kotlin("plugin.serialization") version "1.8.21"
}

android {
Expand All @@ -28,13 +29,16 @@ android {
)
}
}

compileOptions {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
}

kotlinOptions {
jvmTarget = "11"
}

dataBinding {
enable = true
}
Expand Down Expand Up @@ -68,4 +72,11 @@ dependencies {
implementation("com.squareup.okhttp3:okhttp:4.11.0")
implementation("com.squareup.okhttp3:mockwebserver:4.11.0")
testImplementation("com.squareup.okhttp3:mockwebserver:4.11.0")

// Retrofit
implementation("com.squareup.retrofit2:retrofit:2.9.0")
implementation("com.jakewharton.retrofit:retrofit2-kotlinx-serialization-converter:1.0.0")

// kotlinx-serializable
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.5.1")
}
11 changes: 10 additions & 1 deletion app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@
android:theme="@style/Theme.Shopping"
android:usesCleartextTraffic="true"
tools:targetApi="31">
<activity
android:name=".ui.orderdetail.OrderDetailActivity"
android:exported="false" />
<activity
android:name=".ui.orderhistory.OrderHistoryActivity"
android:exported="false" />
<activity
android:name=".ui.serversetting.ServerSettingActivity"
android:exported="true">
Expand All @@ -24,11 +30,14 @@
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".ui.order.OrderActivity"
android:exported="false" />
<activity
android:name=".ui.cart.CartActivity"
android:exported="true" />
<activity
android:name=".ui.detail.ProductDetailActivity"
android:name=".ui.productdetail.ProductDetailActivity"
android:exported="true" />
<activity
android:name=".ui.shopping.ShoppingActivity"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package woowacourse.shopping.data.dao.recentproduct

import woowacourse.shopping.data.model.DataRecentProduct
import woowacourse.shopping.data.entity.RecentProductEntity

interface RecentProductDao {
fun getSize(): Int
fun getRecentProductsPartially(size: Int): List<DataRecentProduct>
fun addRecentProduct(item: DataRecentProduct)
fun removeLast()
fun getRecentProducts(size: Int): List<RecentProductEntity>
fun saveRecentProduct(item: RecentProductEntity)
fun deleteLast()
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,8 @@ import android.content.ContentValues
import android.database.sqlite.SQLiteOpenHelper
import android.provider.BaseColumns
import woowacourse.shopping.data.database.contract.RecentProductContract
import woowacourse.shopping.data.model.DataPrice
import woowacourse.shopping.data.model.DataRecentProduct
import woowacourse.shopping.data.model.Product
import woowacourse.shopping.data.entity.ProductEntity
import woowacourse.shopping.data.entity.RecentProductEntity

class RecentProductDaoImpl(private val database: SQLiteOpenHelper) : RecentProductDao {

Expand All @@ -23,8 +22,8 @@ class RecentProductDaoImpl(private val database: SQLiteOpenHelper) : RecentProdu
}

@SuppressLint("Range")
override fun getRecentProductsPartially(size: Int): List<DataRecentProduct> {
val products = mutableListOf<DataRecentProduct>()
override fun getRecentProducts(size: Int): List<RecentProductEntity> {
val products = mutableListOf<RecentProductEntity>()
val db = database.writableDatabase
val cursor = db.rawQuery(GET_PARTIALLY_QUERY, arrayOf(size.toString()))
while (cursor.moveToNext()) {
Expand All @@ -33,27 +32,27 @@ class RecentProductDaoImpl(private val database: SQLiteOpenHelper) : RecentProdu
cursor.getInt(cursor.getColumnIndex(RecentProductContract.COLUMN_PRODUCT_ID))
val name: String =
cursor.getString(cursor.getColumnIndex(RecentProductContract.COLUMN_NAME))
val price: DataPrice =
DataPrice(cursor.getInt(cursor.getColumnIndex(RecentProductContract.COLUMN_PRICE)))
val price =
cursor.getInt(cursor.getColumnIndex(RecentProductContract.COLUMN_PRICE))
val imageUrl: String =
cursor.getString(cursor.getColumnIndex(RecentProductContract.COLUMN_IMAGE_URL))
products.add(DataRecentProduct(id, Product(productId, name, price, imageUrl)))
products.add(RecentProductEntity(id, ProductEntity(productId, name, price, imageUrl)))
}
cursor.close()
return products
}

override fun addRecentProduct(item: DataRecentProduct) {
override fun saveRecentProduct(item: RecentProductEntity) {
val contentValues = ContentValues().apply {
put(RecentProductContract.COLUMN_NAME, item.product.name)
put(RecentProductContract.COLUMN_PRICE, item.product.price.value)
put(RecentProductContract.COLUMN_PRICE, item.product.price)
put(RecentProductContract.COLUMN_IMAGE_URL, item.product.imageUrl)
}

database.writableDatabase.insert(RecentProductContract.TABLE_NAME, null, contentValues)
}

override fun removeLast() {
override fun deleteLast() {
val db = database.writableDatabase
db.rawQuery(REMOVE_LAST_QUERY, null).close()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import woowacourse.shopping.data.database.contract.RecentProductContract
const val DATABASE_NAME = "ShoppingDatabase.db"
const val DATABASE_VERSION = 12

class ShoppingDatabase(context: Context) :
class ShoppingDatabase private constructor(context: Context) :
SQLiteOpenHelper(context, DATABASE_NAME, null, DATABASE_VERSION) {
override fun onCreate(db: SQLiteDatabase?) {
db?.execSQL(RecentProductContract.CREATE_TABLE_QUERY)
Expand All @@ -18,4 +18,17 @@ class ShoppingDatabase(context: Context) :
db?.execSQL(RecentProductContract.DELETE_TABLE_QUERY)
onCreate(db)
}

companion object {
private var database: ShoppingDatabase? = null

fun get(context: Context): ShoppingDatabase {
if (database == null) {
synchronized(this) {
if (database == null) database = ShoppingDatabase(context)
}
}
return database!!
}
}
}
26 changes: 26 additions & 0 deletions app/src/main/java/woowacourse/shopping/data/dto/CartDto.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package woowacourse.shopping.data.dto

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

@Serializable
data class CartGetResponse(
@SerialName("id")
Copy link

Choose a reason for hiding this comment

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

SerialName 어노테이션을 붙이는 이유는 무엇일까요?
만약 SerialName 어노테이션을 붙이지 않았을 경우에는 어떤 일이 발생할까요?

Copy link
Member Author

Choose a reason for hiding this comment

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

Gson의 @SerializedName 어노테이션과 동일하게,
@SerialName 어노테이션을 붙이지 않아도 property명과 response body 각각의 json key 이름이 동일하면 문제가 없는 것으로 알고 있습니다 : )

어노테이션을 사용한 이유는,
미션을 진행하면서 서버에서 제공하는 json의 key값과 클라이언트에서 사용하고자 하는 이름이 다른 경우가 있었습니다.

@SerialName("point")
val usedPoint: Int

이 외에도, 클라이언트에서는 그대로 프로퍼티명을 유지하고 싶은데,
서버에서 제공해주는 key 이름만 변경되는 상황에는 @SerialName("...")만 변경하여 코드의 수정을 최소화하고자 하였습니다.

Copy link

Choose a reason for hiding this comment

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

잘 알고 계시네요. 👍
추가로 "난독화" 관련해서도 알아보시면 도움이 될 거에요.

val id: Int,
@SerialName("quantity")
val quantity: Int,
@SerialName("product")
val product: ProductGetResponse,
)

@Serializable
data class CartAddRequest(
@SerialName("productId")
val productId: Int,
)

@Serializable
data class CartPatchRequest(
@SerialName("quantity")
val quantity: Int,
)
40 changes: 40 additions & 0 deletions app/src/main/java/woowacourse/shopping/data/dto/OrderDto.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package woowacourse.shopping.data.dto

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

@Serializable
data class OrderResponse(
@SerialName("orderId")
val orderId: Int,
@SerialName("orderedProducts")
val orderedProducts: List<OrderProductResponse> = listOf(),
@SerialName("payment")
val payment: PaymentResponse,
)

@Serializable
data class OrderPostRequest(
@SerialName("orderItems")
val orderItems: List<OrderItem>,
@SerialName("payment")
val payment: PaymentRequest,
)

@Serializable
data class OrderItem(
@SerialName("cartItemId")
val cartItemId: Int,
)

@Serializable
data class OrderProductResponse(
@SerialName("name")
val name: String,
@SerialName("price")
val price: Int,
@SerialName("quantity")
val quantity: Int,
@SerialName("imageUrl")
val imageUrl: String,
)
24 changes: 24 additions & 0 deletions app/src/main/java/woowacourse/shopping/data/dto/PaymentDto.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package woowacourse.shopping.data.dto

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

@Serializable
data class PaymentResponse(
@SerialName("originalPayment")
val originalPayment: Int = 0,
@SerialName("finalPayment")
val finalPayment: Int = 0,
@SerialName("point")
val point: Int = 0,
)

@Serializable
data class PaymentRequest(
@SerialName("originalPayment")
val originalPayment: Int,
@SerialName("finalPayment")
val finalPayment: Int,
@SerialName("point")
val usedPoint: Int,
)
10 changes: 10 additions & 0 deletions app/src/main/java/woowacourse/shopping/data/dto/PointDto.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package woowacourse.shopping.data.dto

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

@Serializable
data class PointResponse(
@SerialName("availablePoint")
val availablePoint: Int = 0,
)
46 changes: 46 additions & 0 deletions app/src/main/java/woowacourse/shopping/data/dto/ProductDto.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package woowacourse.shopping.data.dto

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

@Serializable
data class ProductGetResponse(
@SerialName("id")
val id: Int,
@SerialName("imageUrl")
val imageUrl: String,
@SerialName("name")
val name: String,
@SerialName("price")
val price: Int,
)

@Serializable
data class ProductPostRequest(
@SerialName("name")
val name: String,
@SerialName("price")
val price: Int,
@SerialName("imageUrl")
val imageUrl: String,
)

@Serializable
data class ProductPutRequest(
@SerialName("name")
val name: String,
@SerialName("price")
val price: Int,
@SerialName("imageUrl")
val imageUrl: String,
)

@Serializable
data class ProductDeleteRequest(
@SerialName("name")
val name: String,
@SerialName("price")
val price: Int,
@SerialName("imageUrl")
val imageUrl: String,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package woowacourse.shopping.data.dto.mapper

import woowacourse.shopping.data.dto.CartGetResponse
import woowacourse.shopping.domain.model.DomainCartProduct
import woowacourse.shopping.domain.model.ProductCount

fun CartGetResponse.toDomain(): DomainCartProduct = DomainCartProduct(
id = id,
product = product.toDomain(),
selectedCount = ProductCount(quantity),
isChecked = true,
)

fun List<CartGetResponse>.toDomain(): List<DomainCartProduct> = map { it.toDomain() }
Loading