88244cb56f
Release package / release (push) Successful in 30m1s
Co-authored-by: TakahashiNg <83152264+TakahashiNguyen@users.noreply.github.com> Reviewed-on: #52
197 lines
5.2 KiB
Java
197 lines
5.2 KiB
Java
package com.drinkool.services;
|
|
|
|
import com.drinkool.InternalValue;
|
|
import com.drinkool.controllers.EateryController;
|
|
import com.drinkool.controllers.ManagerController;
|
|
import com.drinkool.dtos.Cart;
|
|
import com.drinkool.dtos.CartItem;
|
|
import io.quarkus.redis.datasource.RedisDataSource;
|
|
import io.quarkus.redis.datasource.hash.HashCommands;
|
|
import io.quarkus.redis.datasource.value.ValueCommands;
|
|
import io.smallrye.mutiny.Uni;
|
|
import io.smallrye.mutiny.infrastructure.Infrastructure;
|
|
import io.vertx.core.http.HttpServerRequest;
|
|
import jakarta.enterprise.context.ApplicationScoped;
|
|
import jakarta.inject.Inject;
|
|
import jakarta.ws.rs.core.Response;
|
|
import java.time.Duration;
|
|
import java.util.ArrayList;
|
|
import java.util.Map;
|
|
import java.util.UUID;
|
|
import org.eclipse.microprofile.graphql.GraphQLApi;
|
|
import org.eclipse.microprofile.graphql.GraphQLException;
|
|
import org.eclipse.microprofile.graphql.Mutation;
|
|
import org.eclipse.microprofile.graphql.Name;
|
|
import org.eclipse.microprofile.graphql.Query;
|
|
import org.eclipse.microprofile.rest.client.inject.RestClient;
|
|
|
|
@ApplicationScoped
|
|
@GraphQLApi
|
|
public class CartService {
|
|
|
|
@Inject
|
|
HttpServerRequest request;
|
|
|
|
@Inject
|
|
@RestClient
|
|
EateryController eateryController;
|
|
|
|
@Inject
|
|
@RestClient
|
|
ManagerController managerController;
|
|
|
|
private final HashCommands<String, String, String> hashCommands;
|
|
private final ValueCommands<String, String> valueCommands;
|
|
|
|
@Inject
|
|
public CartService(RedisDataSource ds) {
|
|
this.hashCommands = ds.hash(String.class);
|
|
this.valueCommands = ds.value(String.class);
|
|
}
|
|
|
|
@Mutation("createCart")
|
|
public Uni<String> createCart(@Name("eateryId") UUID eateryId) {
|
|
String userId = request.getHeader(InternalValue.userId);
|
|
|
|
return eateryController
|
|
.getEateryById(eateryId)
|
|
.emitOn(Infrastructure.getDefaultWorkerPool())
|
|
.onItem()
|
|
.transform(response -> {
|
|
if (response.getStatus() != Response.Status.OK.getStatusCode()) {
|
|
throw new RuntimeException("NotFoundEatery");
|
|
}
|
|
|
|
String cartId = UUID.randomUUID().toString();
|
|
String redisKey = "cart:" + cartId;
|
|
String ownerId = response.getEntity().toString();
|
|
|
|
hashCommands.hset(
|
|
redisKey,
|
|
Map.of(
|
|
"_metadata_owner",
|
|
userId != null ? userId : "GUEST",
|
|
"_metadata_eatery",
|
|
eateryId.toString(),
|
|
"_metadata_eateryManagerId",
|
|
ownerId
|
|
)
|
|
);
|
|
|
|
valueCommands
|
|
.getDataSource()
|
|
.key()
|
|
.expire(redisKey, Duration.ofDays(30));
|
|
|
|
return cartId;
|
|
})
|
|
.onFailure()
|
|
.transform(f ->
|
|
new GraphQLException(
|
|
"Lỗi kết nối đến dịch vụ nhà hàng: " + f.getMessage()
|
|
)
|
|
);
|
|
}
|
|
|
|
@Query("getCart")
|
|
public Cart getCart(@Name("cartId") UUID cartId) throws GraphQLException {
|
|
String key = "cart:" + cartId;
|
|
String priceKey = "cart_prices:" + cartId;
|
|
|
|
Map<String, String> data = hashCommands.hgetall(key);
|
|
Map<String, String> itemPrices = hashCommands.hgetall(priceKey);
|
|
String managerId = hashCommands.hget(key, "_metadata_eateryManagerId");
|
|
|
|
if (data.isEmpty()) {
|
|
throw new GraphQLException("NotFoundCart");
|
|
}
|
|
|
|
Cart cart = new Cart();
|
|
cart.Id = cartId;
|
|
cart.eateryId = UUID.fromString(data.get("_metadata_eatery"));
|
|
cart.userId = UUID.fromString(data.get("_metadata_owner"));
|
|
cart.items = new ArrayList<>();
|
|
|
|
long total = 0;
|
|
|
|
for (Map.Entry<String, String> entry : data.entrySet()) {
|
|
String field = entry.getKey();
|
|
if (field.startsWith("_metadata_")) continue;
|
|
|
|
Integer qty = Integer.parseInt(entry.getValue());
|
|
Double price = Double.parseDouble(itemPrices.getOrDefault(field, "0"));
|
|
Double subTotal = qty * price;
|
|
|
|
CartItem item = new CartItem();
|
|
item.productId = field;
|
|
item.quantity = qty;
|
|
item.priceAtTimeOfAdding = price;
|
|
item.subTotal = subTotal;
|
|
|
|
cart.items.add(item);
|
|
total += subTotal;
|
|
}
|
|
cart.totalAmount = total;
|
|
|
|
try {
|
|
Response response = managerController.getManagerPaymentQr(
|
|
UUID.fromString(managerId),
|
|
total,
|
|
cartId.toString()
|
|
);
|
|
|
|
cart.paymentQrUrl = response.readEntity(String.class);
|
|
} catch (Exception e) {
|
|
cart.paymentQrUrl = "";
|
|
}
|
|
|
|
return cart;
|
|
}
|
|
|
|
@Mutation("addItem")
|
|
public Uni<Cart> addItem(
|
|
@Name("cartId") UUID cartId,
|
|
@Name("menuItemId") UUID menuItemId,
|
|
@Name("quantity") long quantity
|
|
) {
|
|
String key = "cart:" + cartId;
|
|
String priceKey = "cart_prices:" + cartId;
|
|
|
|
String eateryIdStr = hashCommands.hget(key, "_metadata_eatery");
|
|
if (eateryIdStr == null) throw new RuntimeException("CartNotFound");
|
|
|
|
UUID eateryId = UUID.fromString(eateryIdStr);
|
|
|
|
return eateryController
|
|
.checkMenuItemExists(eateryId, menuItemId)
|
|
.onItem()
|
|
.transform(response -> {
|
|
if (response.getStatus() != Response.Status.OK.getStatusCode()) {
|
|
throw new RuntimeException("NotFoundMenuItemInEatery");
|
|
}
|
|
|
|
Double menuItemPrice = response.readEntity(Double.class);
|
|
|
|
hashCommands.hincrby(key, menuItemId.toString(), quantity);
|
|
|
|
hashCommands.hset(
|
|
priceKey,
|
|
menuItemId.toString(),
|
|
String.valueOf(menuItemPrice)
|
|
);
|
|
|
|
hashCommands.getDataSource().key().expire(key, Duration.ofDays(30));
|
|
hashCommands
|
|
.getDataSource()
|
|
.key()
|
|
.expire(priceKey, Duration.ofDays(30));
|
|
|
|
try {
|
|
return getCart(cartId);
|
|
} catch (Exception e) {
|
|
throw new RuntimeException(e.getMessage());
|
|
}
|
|
});
|
|
}
|
|
}
|