Skip to content

Commit 97d97fb

Browse files
author
=
committed
feat: new services for food user and order
1 parent 57685dd commit 97d97fb

File tree

7 files changed

+194
-32
lines changed

7 files changed

+194
-32
lines changed

src/main/kotlin/com/example/service/DatabaseModule.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.example.service
22

33
import com.example.table.Foods
4+
import com.example.table.OrderItems
45
import com.example.table.Orders
56
import com.example.table.Users
67
import kotlinx.coroutines.Dispatchers
@@ -19,6 +20,7 @@ object DatabaseModule {
1920
SchemaUtils.create(Users)
2021
SchemaUtils.create(Foods)
2122
SchemaUtils.create(Orders)
23+
SchemaUtils.create(OrderItems)
2224
}
2325
}
2426

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package com.example.service
2+
3+
import com.example.dto.FoodDto
4+
import com.example.service.impl.FoodServiceImpl
5+
6+
interface FoodService {
7+
suspend fun getFoodDetail(foodId: Int): Result<FoodDto>
8+
suspend fun searchFood(query: String): Result<List<FoodDto>>
9+
suspend fun getAllFoods(): Result<List<FoodDto>>
10+
suspend fun getFoodsByCategory(type: String): Result<List<FoodDto>>
11+
suspend fun registerFood(foodDto: FoodDto): Result<Unit>
12+
companion object {
13+
val foodService: FoodService by lazy { FoodServiceImpl() }
14+
}
15+
}
Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,17 @@
11
package com.example.service
22

3+
import com.example.dto.FoodDto
34
import com.example.dto.OrderDto
4-
import kotlinx.coroutines.flow.Flow
5+
import com.example.service.impl.OrderServiceImpl
6+
import java.util.*
57

68
interface OrderService {
7-
suspend fun getOrder(userId: Int): Flow<List<OrderDto>>
8-
suspend fun createOrder(orderDto: OrderDto): Result<Boolean>
9+
suspend fun getActiveOrder(userId: UUID): Result<OrderDto>
10+
suspend fun addFoodToOrder(userId: UUID, foodDto: FoodDto, quantity: Int): Result<Int>
11+
suspend fun updateItemInOrder(orderId: Int, quantity: Int): Result<Boolean>
12+
suspend fun clearCurrentOrder(userId: UUID): Result<Boolean>
13+
14+
companion object {
15+
val orderService: OrderService by lazy { OrderServiceImpl() }
16+
}
917
}

src/main/kotlin/com/example/service/UserService.kt

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,18 @@ import com.example.dto.UserDto
44
import com.example.dto.UserLoginDto
55
import com.example.dto.UserRegisterDto
66
import com.example.dto.UserUpdateLocationDto
7+
import com.example.service.impl.UserServiceImpl
78
import kotlinx.coroutines.flow.Flow
89
import java.util.UUID
910

1011
interface UserService {
1112
suspend fun login(userLoginDto: UserLoginDto): Result<String>
1213
suspend fun register(userRegisterDto: UserRegisterDto): Result<Boolean>
13-
suspend fun getProfileFlow(userId: Int): Result<Flow<UserDto>>
14+
suspend fun getProfileFlow(userId: UUID): Result<Flow<UserDto>>
1415
suspend fun getProfile(userId: UUID): Result<UserDto>
15-
suspend fun updateUserLocation(userId: Int, userUpdateLocationDto: UserUpdateLocationDto): Result<Boolean>
16+
suspend fun updateUserLocation(userId: UUID, userUpdateLocationDto: UserUpdateLocationDto): Result<Boolean>
17+
18+
companion object {
19+
val userService: UserService by lazy { UserServiceImpl() }
20+
}
1621
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package com.example.service.impl
2+
3+
import com.example.dto.FoodDto
4+
import com.example.service.DatabaseModule.dbQuery
5+
import com.example.service.FoodService
6+
import com.example.table.Foods
7+
import com.example.util.ext.toFoodDto
8+
import org.jetbrains.exposed.sql.insert
9+
import org.jetbrains.exposed.sql.lowerCase
10+
import org.jetbrains.exposed.sql.select
11+
import org.jetbrains.exposed.sql.selectAll
12+
13+
class FoodServiceImpl : FoodService {
14+
override suspend fun getFoodDetail(foodId: Int): Result<FoodDto> = dbQuery {
15+
val food = Foods.select { Foods.id eq foodId }.singleOrNull()
16+
food?.toFoodDto() ?: throw Exception("Food not found")
17+
}
18+
19+
override suspend fun searchFood(query: String): Result<List<FoodDto>> = dbQuery {
20+
val searchStatement = Foods.select {
21+
(Foods.name.lowerCase() like "%$query%")
22+
}
23+
val foods = searchStatement.map { it.toFoodDto() }
24+
foods
25+
}
26+
27+
override suspend fun getAllFoods(): Result<List<FoodDto>> = dbQuery {
28+
val allFoods = Foods.selectAll()
29+
val foods = allFoods.map { it.toFoodDto() }
30+
foods
31+
}
32+
33+
override suspend fun getFoodsByCategory(type: String): Result<List<FoodDto>> = dbQuery {
34+
val foodsByCategory = Foods.select { Foods.category eq type }
35+
val foods = foodsByCategory.map { it.toFoodDto() }
36+
foods
37+
}
38+
39+
override suspend fun registerFood(foodDto: FoodDto): Result<Unit> = dbQuery {
40+
Foods.insert {
41+
it[name] = foodDto.name
42+
it[description] = foodDto.description
43+
it[price] = foodDto.price
44+
it[rating] = foodDto.rating
45+
it[orderCount] = foodDto.orderCount
46+
it[category] = foodDto.category
47+
it[imageUrl] = foodDto.imageUrl
48+
}
49+
}
50+
}
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
package com.example.service.impl
2+
3+
import com.example.dto.FoodDto
4+
import com.example.dto.OrderDto
5+
import com.example.dto.OrderStatus
6+
import com.example.service.DatabaseModule.dbQuery
7+
import com.example.service.OrderService
8+
import com.example.table.Foods
9+
import com.example.table.OrderItems
10+
import com.example.table.Orders
11+
import com.example.util.ext.toFoodDto
12+
import com.example.util.ext.toOrderDto
13+
import org.jetbrains.exposed.sql.and
14+
import org.jetbrains.exposed.sql.insert
15+
import org.jetbrains.exposed.sql.select
16+
import org.jetbrains.exposed.sql.update
17+
import java.util.*
18+
19+
class OrderServiceImpl : OrderService {
20+
override suspend fun getActiveOrder(userId: UUID): Result<OrderDto> = dbQuery {
21+
val card = Orders.select {
22+
(Orders.userId eq userId) and (Orders.orderStatus eq OrderStatus.Started)
23+
}
24+
if (card.empty()) {
25+
throw Exception("No active order found")
26+
}
27+
card.single().toOrderDto()
28+
}
29+
30+
override suspend fun addFoodToOrder(userId: UUID, foodDto: FoodDto, quantity: Int): Result<Int> = dbQuery {
31+
val order = Orders.select {
32+
(Orders.userId eq userId) and (Orders.orderStatus eq OrderStatus.Started)
33+
}.forUpdate()
34+
35+
if (order.empty()) {
36+
createOrder(userId)
37+
}
38+
39+
val activeOrder = Orders.select {
40+
(Orders.userId eq userId) and (Orders.orderStatus eq OrderStatus.Started)
41+
}.forUpdate().single()
42+
43+
val orderId = OrderItems.insert {
44+
it[OrderItems.orderId] = activeOrder[Orders.id]
45+
it[OrderItems.foodId] = foodDto.id
46+
it[OrderItems.quantity] = quantity
47+
it[OrderItems.price] = foodDto.price.toBigDecimal()
48+
}[OrderItems.id]
49+
50+
val totalPrice = activeOrder[Orders.totalPrice] + (foodDto.price * quantity).toBigDecimal()
51+
Orders.update({ Orders.id eq activeOrder[Orders.id] }) {
52+
it[Orders.totalPrice] = totalPrice
53+
}
54+
55+
orderId
56+
}
57+
58+
override suspend fun updateItemInOrder(orderId: Int, quantity: Int): Result<Boolean> = dbQuery {
59+
val orderItem = OrderItems.select { OrderItems.id eq orderId }.singleOrNull()
60+
if (orderItem == null) {
61+
throw Exception("Order item not found")
62+
}
63+
64+
val food = Foods.select { Foods.id eq orderItem[OrderItems.foodId] }.single()
65+
val totalPrice = (food[Foods.price] * quantity).toBigDecimal()
66+
OrderItems.update({ OrderItems.id eq orderId }) {
67+
it[OrderItems.quantity] = quantity
68+
it[OrderItems.price] = totalPrice
69+
}
70+
71+
val activeOrder = Orders.select { Orders.id eq orderItem[OrderItems.orderId] }.single()
72+
val orderItems = OrderItems.select { OrderItems.orderId eq activeOrder[Orders.id] }
73+
val newTotalPrice = orderItems.sumOf { it[OrderItems.price].toDouble() }.toBigDecimal()
74+
Orders.update({ Orders.id eq activeOrder[Orders.id] }) {
75+
it[Orders.totalPrice] = newTotalPrice
76+
}
77+
78+
true
79+
}
80+
81+
override suspend fun clearCurrentOrder(userId: UUID): Result<Boolean> {
82+
TODO("Not yet implemented")
83+
}
84+
85+
private fun createOrder(userId: UUID) {
86+
Orders.insert {
87+
it[Orders.userId] = userId
88+
it[Orders.orderStatus] = OrderStatus.Started
89+
}
90+
}
91+
}

src/main/kotlin/com/example/service/impl/UserServiceImpl.kt

Lines changed: 18 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,10 @@ import com.example.dto.UserUpdateLocationDto
77
import com.example.service.DatabaseModule.dbQuery
88
import com.example.service.UserService
99
import com.example.table.Users
10+
import com.example.util.ext.toUserDto
1011
import kotlinx.coroutines.flow.Flow
1112
import kotlinx.coroutines.flow.asFlow
12-
import org.jetbrains.exposed.sql.ResultRow
13-
import org.jetbrains.exposed.sql.and
14-
import org.jetbrains.exposed.sql.insert
15-
import org.jetbrains.exposed.sql.select
13+
import org.jetbrains.exposed.sql.*
1614
import java.util.UUID
1715

1816
class UserServiceImpl : UserService {
@@ -43,12 +41,12 @@ class UserServiceImpl : UserService {
4341
}
4442
}
4543

46-
override suspend fun getProfileFlow(userId: Int): Result<Flow<UserDto>> = dbQuery {
47-
val user = Users.select { Users.id eq userId }
44+
override suspend fun getProfileFlow(userId: UUID): Result<Flow<UserDto>> = dbQuery {
45+
val user = Users.select { Users.userId eq userId }
4846
if (user.empty()) {
4947
throw Exception("User not found")
5048
} else {
51-
val userFlow = user.map(::resultRowToUserDto).asFlow()
49+
val userFlow = user.map { it.toUserDto() }.asFlow()
5250
userFlow
5351
}
5452
}
@@ -58,30 +56,23 @@ class UserServiceImpl : UserService {
5856
if (user.empty()) {
5957
throw Exception("User not found")
6058
} else {
61-
resultRowToUserDto(user.single())
59+
user.single().toUserDto()
6260
}
6361
}
6462

6563
override suspend fun updateUserLocation(
66-
userId: Int,
64+
userId: UUID,
6765
userUpdateLocationDto: UserUpdateLocationDto
68-
): Result<Boolean> {
69-
TODO("Not yet implemented")
66+
): Result<Boolean> = dbQuery {
67+
val user = Users.select { Users.userId eq userId }
68+
if (user.empty()) {
69+
throw Exception("User not found")
70+
} else {
71+
Users.update({ Users.userId eq userId }) {
72+
it[latitude] = userUpdateLocationDto.latitude
73+
it[longitude] = userUpdateLocationDto.longitude
74+
}
75+
true
76+
}
7077
}
71-
72-
private fun resultRowToUserDto(row: ResultRow): UserDto = UserDto(
73-
id = row[Users.id],
74-
userId = row[Users.userId].toString(),
75-
fullName = row[Users.fullName],
76-
email = row[Users.email],
77-
password = row[Users.password],
78-
phoneNumber = row[Users.phoneNumber],
79-
occupation = row[Users.occupation],
80-
employer = row[Users.employer],
81-
country = row[Users.country],
82-
latitude = row[Users.latitude],
83-
longitude = row[Users.longitude]
84-
)
8578
}
86-
87-
val userService: UserService = UserServiceImpl()

0 commit comments

Comments
 (0)