order-service/src/internal/service/order.go

94 lines
2.5 KiB
Go

package service
import (
"context"
"git.pbiernat.io/egommerce/api-entities/model"
"git.pbiernat.io/egommerce/order-service/internal/event"
"git.pbiernat.io/egommerce/go-api-pkg/api"
"git.pbiernat.io/egommerce/go-api-pkg/fluentd"
"git.pbiernat.io/egommerce/go-api-pkg/rabbitmq"
"github.com/georgysavva/scany/v2/pgxscan"
"github.com/go-redis/redis/v8"
"github.com/jackc/pgx/v5/pgxpool"
amqp "github.com/rabbitmq/amqp091-go"
)
const (
SERVICE_USER_AGENT = "order-httpclient"
)
type OrderService struct {
dbConn *pgxpool.Pool
redis *redis.Client
ebCh *amqp.Channel
log *fluentd.Logger
}
func NewOrderService(dbConn *pgxpool.Pool, redis *redis.Client, chn *amqp.Channel, log *fluentd.Logger) *OrderService {
return &OrderService{dbConn, redis, chn, log}
}
func (s *OrderService) Log(format string, val ...any) {
s.log.Log(format, val...)
}
func (s *OrderService) GetOrder(ctx context.Context, id string) (*model.OrderModel, error) {
order := new(model.OrderModel)
err := pgxscan.Get(ctx, s.dbConn, order, `SELECT id, state, created_at, updated_at FROM ordering."order" WHERE id=$1`, id)
if err != nil {
return nil, err
}
return order, nil
}
func (s *OrderService) CreateOrder(ctx context.Context, basketID string) (*model.OrderModel, error) {
basketAPI := api.NewBasketAPI(SERVICE_USER_AGENT, s.redis)
basket, err := basketAPI.GetBasket(basketID)
if err != nil {
return nil, err
}
order := new(model.OrderModel)
order.ID = basketID
order.State = basket.State // FIXME: are the same status?
sql := `INSERT INTO "ordering"."order"(id,state) VALUES($1,$2) RETURNING id`
if err := s.dbConn.QueryRow(ctx, sql, order.ID, order.State).Scan(&order.ID); err != nil {
return order, err
}
items, err := basketAPI.GetBasketItems(basket.ID)
if err != nil {
return order, err
}
for _, item := range items {
sql := `INSERT INTO ordering.order_item(order_id,product_id,price,quantity) VALUES($1,$2,$3,$4)`
if _, err := s.dbConn.Exec(ctx, sql, order.ID, item.ProductID, item.Price, item.Quantity); err != nil {
return order, err
}
}
return order, nil
}
// func (s *OrderService) UpdateOrder(ctx context.Context, orderID string, data any) (*model.OrderModel, error) {
// }
func (s *OrderService) UpdateOrderStatus(reqID, orderID, status string) (string, error) {
s.log.Log("Update order#%s status to %s", orderID, status)
msg := &event.StatusUpdateEvent{
Event: event.NewEvent("UpdateOrderStatus", reqID),
OrderID: orderID,
Status: status,
}
rabbitmq.Publish(s.ebCh, "api-events", "order.email.statusUpdate", msg)
return orderID, nil
}