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 }