manager.go handler + some pieces of order.go service
This commit is contained in:
@@ -1,11 +1,131 @@
|
|||||||
package handler
|
package handler
|
||||||
|
|
||||||
import "net/http"
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"log/slog"
|
||||||
|
"net/http"
|
||||||
|
"time"
|
||||||
|
|
||||||
func (s *Server) ListManagers(w http.ResponseWriter, r *http.Request) {}
|
"github.com/anxi0uz/logiflow/internal/api"
|
||||||
|
"github.com/anxi0uz/logiflow/internal/models"
|
||||||
|
storage "github.com/anxi0uz/logiflow/pkg"
|
||||||
|
"github.com/google/uuid"
|
||||||
|
"github.com/huandu/go-sqlbuilder"
|
||||||
|
"golang.org/x/crypto/bcrypt"
|
||||||
|
)
|
||||||
|
|
||||||
func (s *Server) CreateManager(w http.ResponseWriter, r *http.Request) {}
|
func (s *Server) ListManagers(w http.ResponseWriter, r *http.Request) {
|
||||||
|
ctx := r.Context()
|
||||||
|
|
||||||
func (s *Server) GetManager(w http.ResponseWriter, r *http.Request, slug string) {}
|
managers, err := storage.GetAll[models.Manager](ctx, "managers", s.DB)
|
||||||
|
if err != nil {
|
||||||
|
slog.ErrorContext(ctx, "Error while getting managers", slog.String("error", err.Error()))
|
||||||
|
s.JSON(w, r, http.StatusInternalServerError, MsgInternalError, RespError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
s.JSON(w, r, http.StatusOK, managers, RespSuccess)
|
||||||
|
}
|
||||||
|
|
||||||
func (s *Server) DeleteManager(w http.ResponseWriter, r *http.Request, slug string) {}
|
func (s *Server) CreateManager(w http.ResponseWriter, r *http.Request) {
|
||||||
|
ctx := r.Context()
|
||||||
|
|
||||||
|
var req api.ManagerCreate
|
||||||
|
|
||||||
|
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
||||||
|
slog.ErrorContext(ctx, "Error while decoding body", slog.Any("request", req), slog.String("Error", err.Error()))
|
||||||
|
s.JSON(w, r, http.StatusBadRequest, MsgInvalidBody, RespError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
passwordHash, err := bcrypt.GenerateFromPassword([]byte(req.Password), bcrypt.DefaultCost)
|
||||||
|
if err != nil {
|
||||||
|
slog.ErrorContext(ctx, "error while generating passwordhash", slog.String("error", err.Error()))
|
||||||
|
s.JSON(w, r, http.StatusInternalServerError, MsgInternalError, RespError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
userid := uuid.New()
|
||||||
|
now := time.Now()
|
||||||
|
|
||||||
|
userModel := models.User{
|
||||||
|
ID: userid,
|
||||||
|
Slug: s.GenerateUserSlug(req.FullName, userid),
|
||||||
|
CreatedAt: now,
|
||||||
|
UpdatedAt: now,
|
||||||
|
Role: "manager",
|
||||||
|
Email: string(req.Email),
|
||||||
|
PasswordHash: string(passwordHash),
|
||||||
|
FullName: req.FullName,
|
||||||
|
}
|
||||||
|
|
||||||
|
tx, err := s.DB.Begin(ctx)
|
||||||
|
if err != nil {
|
||||||
|
slog.ErrorContext(ctx, "Error while opening transaction", slog.String("error", err.Error()))
|
||||||
|
s.JSON(w, r, http.StatusInternalServerError, MsgInternalError, RespError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer tx.Rollback(ctx)
|
||||||
|
|
||||||
|
if err := storage.Create(ctx, "users", userModel, tx); err != nil {
|
||||||
|
slog.ErrorContext(ctx, "Error while creating user", slog.String("error", err.Error()))
|
||||||
|
s.JSON(w, r, http.StatusInternalServerError, MsgInternalError, RespError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
managerid := uuid.New()
|
||||||
|
managerModel := models.Manager{
|
||||||
|
ID: managerid,
|
||||||
|
WarehouseID: req.WarehouseId,
|
||||||
|
UserID: userid,
|
||||||
|
Slug: s.GenerateUserSlug(req.FullName, managerid),
|
||||||
|
}
|
||||||
|
if err := storage.Create(ctx, "managers", managerModel, tx); err != nil {
|
||||||
|
slog.ErrorContext(ctx, "Error while creating manager", slog.String("error", err.Error()))
|
||||||
|
s.JSON(w, r, http.StatusInternalServerError, MsgInternalError, RespError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := tx.Commit(ctx); err != nil {
|
||||||
|
slog.ErrorContext(ctx, "Error while commiting transaction", slog.String("error", err.Error()))
|
||||||
|
s.JSON(w, r, http.StatusInternalServerError, MsgInternalError, RespError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
s.JSON(w, r, http.StatusCreated, map[string]any{
|
||||||
|
"user": userModel,
|
||||||
|
"manager": managerModel,
|
||||||
|
}, RespSuccess)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Server) GetManager(w http.ResponseWriter, r *http.Request, slug string) {
|
||||||
|
ctx := r.Context()
|
||||||
|
|
||||||
|
manager, err := storage.GetOne[models.Manager](ctx, s.DB, "managers", func(sb *sqlbuilder.SelectBuilder) {
|
||||||
|
sb.Where(sb.EQ("slug", slug))
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, storage.ErrNotFound) {
|
||||||
|
slog.ErrorContext(ctx, "No manager was found with that slug", slog.String("slug", slug))
|
||||||
|
s.JSON(w, r, http.StatusNotFound, MsgNotFound, RespNotFound)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
slog.ErrorContext(ctx, "Error while getting manager with that slug", slog.String("slug", slug), slog.String("error", err.Error()))
|
||||||
|
s.JSON(w, r, http.StatusInternalServerError, MsgInternalError, RespError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
s.JSON(w, r, http.StatusOK, manager, RespSuccess)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Server) DeleteManager(w http.ResponseWriter, r *http.Request, slug string) {
|
||||||
|
ctx := r.Context()
|
||||||
|
|
||||||
|
err := storage.Delete[models.Manager](ctx, "managers", s.DB, func(db *sqlbuilder.DeleteBuilder) {
|
||||||
|
db.Where(db.EQ("slug", slug))
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
slog.ErrorContext(ctx, "Error while deleting manager with that slug", slog.String("slug", slug), slog.String("error", err.Error()))
|
||||||
|
s.JSON(w, r, http.StatusInternalServerError, MsgInternalError, RespError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
s.JSON(w, r, http.StatusOK, "Deleted", RespSuccess)
|
||||||
|
}
|
||||||
|
|||||||
@@ -9,7 +9,19 @@ import (
|
|||||||
openapi_types "github.com/oapi-codegen/runtime/types"
|
openapi_types "github.com/oapi-codegen/runtime/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (s *Server) ListOrders(w http.ResponseWriter, r *http.Request, params api.ListOrdersParams) {}
|
func (s *Server) ListOrders(w http.ResponseWriter, r *http.Request, params api.ListOrdersParams) {
|
||||||
|
ctx := r.Context()
|
||||||
|
claims, ok := ctx.Value("user").(*Claims)
|
||||||
|
if !ok {
|
||||||
|
slog.ErrorContext(ctx, "Error while casting claims")
|
||||||
|
s.JSON(w, r, http.StatusInternalServerError, MsgInternalError, RespError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
switch claims.Role {
|
||||||
|
case "client":
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (s *Server) CreateOrder(w http.ResponseWriter, r *http.Request) {
|
func (s *Server) CreateOrder(w http.ResponseWriter, r *http.Request) {
|
||||||
ctx := r.Context()
|
ctx := r.Context()
|
||||||
|
|||||||
@@ -3,12 +3,13 @@ package services
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log/slog"
|
"log/slog"
|
||||||
"net/http"
|
"net/http"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/anxi0uz/logiflow/internal/api"
|
api "github.com/anxi0uz/logiflow/internal/api"
|
||||||
"github.com/anxi0uz/logiflow/internal/config"
|
"github.com/anxi0uz/logiflow/internal/config"
|
||||||
"github.com/anxi0uz/logiflow/internal/models"
|
"github.com/anxi0uz/logiflow/internal/models"
|
||||||
storage "github.com/anxi0uz/logiflow/pkg"
|
storage "github.com/anxi0uz/logiflow/pkg"
|
||||||
@@ -24,6 +25,8 @@ type OrderService struct {
|
|||||||
config config.Config
|
config config.Config
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var ErrForbidden = errors.New("forbidden")
|
||||||
|
|
||||||
type CreateOrderResult struct {
|
type CreateOrderResult struct {
|
||||||
Order models.Order
|
Order models.Order
|
||||||
Route models.Route
|
Route models.Route
|
||||||
@@ -70,7 +73,7 @@ func (s *OrderService) CreateOrder(ctx context.Context, req api.OrderCreate, use
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
var err error
|
var err error
|
||||||
destLat, originLon, err = geocode.Geocode(ctx, req.DestinationAddress)
|
destLat, destLon, err = geocode.Geocode(ctx, req.DestinationAddress)
|
||||||
return err
|
return err
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -162,3 +165,50 @@ func (s *OrderService) CreateOrder(ctx context.Context, req api.OrderCreate, use
|
|||||||
|
|
||||||
return &CreateOrderResult{Order: order, Route: routeModel}, nil
|
return &CreateOrderResult{Order: order, Route: routeModel}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *OrderService) ListOrders(ctx context.Context, userID uuid.UUID, role string, params api.ListOrdersParams) ([]models.Order, error) {
|
||||||
|
var driverID *uuid.UUID
|
||||||
|
if role == "driver" {
|
||||||
|
driver, err := storage.GetOne[models.Driver](ctx, s.db, "driver", func(sb *sqlbuilder.SelectBuilder) {
|
||||||
|
sb.Where(sb.EQ("user_id", userID))
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("get driver: %w", err)
|
||||||
|
}
|
||||||
|
driverID = &driver.ID
|
||||||
|
}
|
||||||
|
orders, err := storage.GetAll[models.Order](ctx, "orders", s.db, func(sb *sqlbuilder.SelectBuilder) {
|
||||||
|
switch role {
|
||||||
|
case "client":
|
||||||
|
sb.Where(sb.EQ("created_by_id", userID))
|
||||||
|
case "driver":
|
||||||
|
sb.Where(sb.EQ("driver_id", driverID))
|
||||||
|
default:
|
||||||
|
if params.Status != nil {
|
||||||
|
sb.Where(sb.EQ("status", params.Status))
|
||||||
|
}
|
||||||
|
if params.DriverId != nil {
|
||||||
|
sb.Where(sb.EQ("driver_id", params.DriverId))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("list orders: %w", err)
|
||||||
|
}
|
||||||
|
return orders, nil
|
||||||
|
}
|
||||||
|
func (s *OrderService) GetOrder(ctx context.Context, id uuid.UUID, userID uuid.UUID, role string) (*models.Order, error) {
|
||||||
|
order, err := storage.GetOne[models.Order](ctx, s.db, "orders", func(sb *sqlbuilder.SelectBuilder) {
|
||||||
|
sb.Where(sb.EQ("id", id))
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if role == "client" && (order.CreatedByID == nil || *order.CreatedByID != userID) {
|
||||||
|
return nil, ErrForbidden
|
||||||
|
}
|
||||||
|
return order, nil
|
||||||
|
}
|
||||||
|
func (s *OrderService) CancelOrder(ctx context.Context, id uuid.UUID, userID uuid.UUID, role string) error
|
||||||
|
func (s *OrderService) UpdateOrderStatus(ctx context.Context, id uuid.UUID, userID uuid.UUID, role string, req api.OrderStatusUpdate) (*models.Order, error)
|
||||||
|
func (s *OrderService) GetOrdersReport(ctx context.Context, role string, params api.GetOrdersReportParams) ([]models.Order, error)
|
||||||
|
|||||||
Reference in New Issue
Block a user