Compare commits

..

1 Commits

Author SHA1 Message Date
Fatemeh Javadi 66ced2ea9b feat(admin): add e2e testing for kindbox by admin 2024-09-02 21:31:58 +03:30
2414 changed files with 5984 additions and 686550 deletions

4
.gitignore vendored
View File

@ -18,9 +18,9 @@ activate.mise.toml
*.out
# Dependency directories (remove the comment below to include it)
vendor/
.idea
bin
tmp
#.env
*.env
@ -28,5 +28,3 @@ tmp
# Logs
logs/
mise.log
curl

View File

@ -1,29 +1,37 @@
# Build Stage
FROM golang:1.23.0-alpine AS builder
# First pull Golang image
FROM golang:1.21.3-alpine as builder
# Set environment variable
ENV APP_NAME niki
ENV CMD_PATH main.go
# Add a work directory
WORKDIR /$APP_NAME
## Cache and install dependencies
#COPY go.mod go.sum ./
#RUN go mod download
# Copy app files
COPY . .
# Budild application
RUN CGO_ENABLED=0 go build -mod=vendor -v -o $APP_NAME .
RUN CGO_ENABLED=0 go build -mod=mod -v -o $APP_NAME .
# Run Stage
FROM alpine:3.20 AS runtime
# Copy the binary from the builder stage
COPY --from=builder /niki/niki .
# Copy migration files
COPY --from=builder /niki/repository/mysql/migration ./repository/mysql/migration
FROM alpine:3.18 as development
# Set environment variable
ENV APP_NAME niki
# Copy only required data into this image
COPY --from=builder /$APP_NAME .
# Expose application port
EXPOSE 8313
# Start the application
CMD ["./niki", "--migrate"]
EXPOSE 1313
# Start app
CMD ./$APP_NAME

View File

@ -1,9 +1,7 @@
# TODO: add commands for build and run in dev/produciton mode
// TODO: add commands for build and run in dev/produciton mode
ROOT=$(realpath $(dir $(lastword $(MAKEFILE_LIST))))
.PHONY: help confirm lint test format build run docker swagger watch migrate/status migrate/new migrate/up migrate/down
confirm:
@echo -n 'Are you sure? [y/N] ' && read ans && [ $${ans:-N} = y ]
@ -18,12 +16,12 @@ format:
@which gofumpt || (go install mvdan.cc/gofumpt@latest)
@gofumpt -l -w $(ROOT)
@which gci || (go install github.com/daixiang0/gci@latest)
@gci write $(ROOT) --skip-generated --skip-vendor
@gci write $(ROOT)
@which golangci-lint || (go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.54.0)
@golangci-lint run --fix
build:
go build -o niki main.go
go build main.go --migrate
run:
go run main.go --migrate

View File

@ -1,70 +0,0 @@
# Niki
---
## Prerequisites
- **Go 1.25.4** (Ensure your Go version matches this requirement)
- **Docker 20.10+** (or higher)
- **Git**
---
## Installation
### 1. Configure Go Module Mirror
To accelerate dependency downloads, set the Go module mirror to **Megan** (Iranian Go mirror):
```url
https://megan.ir/hub/go
```
### 2. Install Dependencies
```bash
go mod tidy
go mod vendor
```
### 3. Configure Environment
Copy the example environment file and customize it:
```bash
cp .env.example .env
```
---
## Running the Application
### 1. Start Services
Launch the database and Redis services using Docker Compose:
```bash
docker compose up -d
```
> 🌐 *Docker images are sourced from [Arvan Cloud's Docker repositories](https://www.arvancloud.ir/fa/dev/docker). Ensure
your environment has access to these repositories.*
### 2. Apply Database Migrations
Initialize the database schema:
```bash
go run main.go --migrate
```
### 3. Start the Application
Run the application in development mode:
```bash
go run main.go
```
> ✨ **Alternative**: Use the provided `Makefile` for streamlined execution:
> [Makefile](Makefile)

View File

@ -1,8 +0,0 @@
package benefactorapp
import "net/http"
type Application struct {
Config Config
HTTPServer *http.Server
}

View File

@ -1,11 +0,0 @@
package benefactorapp
type Config struct {
// HTTP server config
// Database config
// Logger config
// Service config
}

View File

@ -1,17 +0,0 @@
package http
import (
"net/http"
"github.com/labstack/echo/v4"
)
type Handler struct{}
func NewHandler() *Handler {
return &Handler{}
}
func (h Handler) HealthCheck(c echo.Context) error {
return c.JSON(http.StatusOK, map[string]string{"status": "ok"})
}

View File

@ -1 +0,0 @@
package http

View File

@ -1,23 +0,0 @@
package http
import httpserver "git.gocasts.ir/ebhomengo/niki/delivery/http_server"
type Server struct {
HTTPServer *httpserver.Server
Handler *Handler
}
func NewServer(httpserver *httpserver.Server) *Server {
return &Server{
HTTPServer: httpserver,
Handler: NewHandler(),
}
}
func (s *Server) Serve() {
}
func (s *Server) Stop() {}
func (s *Server) RegisterRoutes() {}

View File

@ -1,13 +0,0 @@
package database
import "git.gocasts.ir/ebhomengo/niki/repository/mysql"
type DB struct {
conn *mysql.DB
}
func New(conn *mysql.DB) *DB {
return &DB{
conn: conn,
}
}

View File

@ -1 +0,0 @@
package service

View File

@ -1 +0,0 @@
package service

View File

@ -1 +0,0 @@
package service

View File

@ -1 +0,0 @@
package service

View File

@ -20,6 +20,10 @@ redis:
password: ""
db: 0
sms_provider:
host: localhost
port: 443
benefactor_service:
length_of_otp_code: 5
@ -29,7 +33,6 @@ kavenegar_sms_provider:
admin_auth:
sign_key: admin-jwt_secret_test_nik
token: "e18Ef8EAf2116e09A737c0b23B2Bd08D"

View File

@ -10,12 +10,7 @@ import (
)
type HTTPServer struct {
Port int `koanf:"port"`
Cors Cors `koanf:"cors"`
}
type Cors struct {
AllowOrigins []string `koanf:"allow_origins"`
Port int `koanf:"port"`
}
type Config struct {

View File

@ -1,13 +0,0 @@
package adminaddresshandler
import (
param "git.gocasts.ir/ebhomengo/niki/param/admin/address"
admincityparam "git.gocasts.ir/ebhomengo/niki/param/admin/city"
adminprovinceparam "git.gocasts.ir/ebhomengo/niki/param/admin/province"
)
type Address struct {
Address param.Data `json:"address"`
Province adminprovinceparam.Data `json:"province"`
City admincityparam.Data `json:"city"`
}

View File

@ -10,7 +10,7 @@ import (
// LoginByPhoneNumber godoc
// @Summary Admin login by PhoneNumber
// @Tags Admins
// @Tags Admin
// @Accept json
// @Produce json
// @Param Request body adminserviceparam.LoginWithPhoneNumberRequest true "Admin login request body"

View File

@ -1,47 +0,0 @@
package adminhandler
import (
"net/http"
adminserviceparam "git.gocasts.ir/ebhomengo/niki/param/admin/admin"
"git.gocasts.ir/ebhomengo/niki/pkg/claim"
httpmsg "git.gocasts.ir/ebhomengo/niki/pkg/http_msg"
"github.com/labstack/echo/v4"
)
// Profile godoc
// @Summary Admin profile
// @Tags Admins
// @Accept json
// @Produce json
// @Success 200 {object} adminserviceparam.ProfileResponse
// @Failure 400 {string} "Bad request"
// @Failure 401 {string} "invalid or expired jwt"
// @Failure 403 {string} "user not allowed"
// @Failure 404 {string} "record not found"
// @Failure 500 {string} "something went wrong"
// @Security AuthBearerAdmin
// @Router /admins/profile [get].
func (h Handler) Profile(c echo.Context) error {
var req adminserviceparam.ProfileRequest
if bErr := c.Bind(&req); bErr != nil {
return echo.NewHTTPError(http.StatusBadRequest)
}
req.AdminID = claim.GetClaimsFromEchoContext(c).UserID
resp, sErr := h.adminSvc.AdminGetProfile(c.Request().Context(), req)
if sErr != nil {
msg, code := httpmsg.Error(sErr)
if resp.FieldErrors != nil {
return c.JSON(code, echo.Map{
"message": msg,
"errors": resp.FieldErrors,
})
}
return echo.NewHTTPError(code, msg)
}
return c.JSON(http.StatusOK, resp)
}

View File

@ -1,37 +0,0 @@
package adminhandler
import (
"net/http"
adminserviceparam "git.gocasts.ir/ebhomengo/niki/param/admin/admin"
httpmsg "git.gocasts.ir/ebhomengo/niki/pkg/http_msg"
"github.com/labstack/echo/v4"
)
// RefreshAccess godoc
// @Summary Get a new access token by providing a refresh token
// @Tags Admins
// @Accept json
// @Produce json
// @Param Request body adminserviceparam.RefreshAccessRequest true "Refresh access request body"
// @Success 200 {object} adminserviceparam.RefreshAccessResponse
// @Failure 400 {string} "Bad Request"
// @Failure 422 {string} "invalid or expired jwt"
// @Failure 500 {string} "something went wrong"
// @Router /admins/refresh-access [post].
func (h Handler) RefreshAccess(c echo.Context) error {
var req adminserviceparam.RefreshAccessRequest
if err := c.Bind(&req); err != nil {
return echo.NewHTTPError(http.StatusBadRequest)
}
resp, err := h.adminSvc.RefreshAccess(c.Request().Context(), req)
if err != nil {
msg, code := httpmsg.Error(err)
return echo.NewHTTPError(code, msg)
}
return c.JSON(http.StatusOK, resp)
}

View File

@ -10,7 +10,7 @@ import (
// Register godoc
// @Summary Register an admin by super-admin
// @Tags Admins
// @Tags Admin
// @Accept json
// @Produce json
// @Param Request body adminserviceparam.RegisterRequest true "Admin Register Request Body"

View File

@ -13,8 +13,6 @@ func (h Handler) SetRoutes(e *echo.Echo) {
//r.POST("/", h.Add).Name = "admin-addkindboxreq"
r.POST("/register", h.Register, middleware.Auth(h.authSvc), middleware.AdminAuthorization(h.adminAuthorizeSvc, entity.AdminAdminRegisterPermission))
r.POST("/login-by-phone", h.LoginByPhoneNumber)
r.POST("/refresh-access", h.RefreshAccess)
r.GET("/profile", h.Profile, middleware.Auth(h.authSvc))
//nolint:gocritic
//r.PATCH("/:id", h.Update).Name = "admin-updatekindboxreq"
}

View File

@ -10,7 +10,7 @@ import (
// GetAllAgent godoc
// @Summary Get all agents by admin
// @Tags Admins
// @Tags Admin
// @Accept json
// @Produce json
// @Success 200 {object} adminagentparam.GetAllAgentResponse

View File

@ -1,25 +0,0 @@
package adminbenefactorhandler
import (
"time"
"git.gocasts.ir/ebhomengo/niki/entity"
adminaddressparam "git.gocasts.ir/ebhomengo/niki/param/admin/address"
adminkindboxparam "git.gocasts.ir/ebhomengo/niki/param/admin/kind_box"
adminkindboxreqparam "git.gocasts.ir/ebhomengo/niki/param/admin/kind_box_req"
)
type BenefactorAggregatedResponse struct {
ID uint `json:"id"`
FirstName string `json:"first_name"`
LastName string `json:"last_name"`
PhoneNumber string `json:"phone_number"`
Description string `json:"description"`
Email string `json:"email"`
Gender entity.Gender `json:"gender"`
BirthDate *time.Time `json:"birth_date"`
Status entity.BenefactorStatus `json:"status"`
Addresses []adminaddressparam.Data `json:"addresses"`
KindBoxes []adminkindboxparam.Data `json:"kind_boxes"`
KindBoxReqs []adminkindboxreqparam.Data `json:"kind_box_reqs"`
}

View File

@ -1,106 +0,0 @@
package adminbenefactorhandler
import (
"net/http"
params "git.gocasts.ir/ebhomengo/niki/param"
adminaddressparam "git.gocasts.ir/ebhomengo/niki/param/admin/address"
param "git.gocasts.ir/ebhomengo/niki/param/admin/benefactor"
adminkindboxparam "git.gocasts.ir/ebhomengo/niki/param/admin/kind_box"
adminkindboxreqparam "git.gocasts.ir/ebhomengo/niki/param/admin/kind_box_req"
httpmsg "git.gocasts.ir/ebhomengo/niki/pkg/http_msg"
"github.com/labstack/echo/v4"
)
// GetBenefactor godoc
// @Summary Get benefactor details by id
// @Description This endpoint retrieves details for a specific benefactor.
// @Tags Admins Benefactors
// @Accept json
// @Produce json
// @Param id path int true "Benefactor ID"
// @Success 200 {object} BenefactorAggregatedResponse
// @Failure 400 {string} "Bad request"
// @Failure 401 {string} "invalid or expired jwt"
// @Failure 403 {string} "user not allowed"
// @Failure 404 {string} "record not found"
// @Failure 500 {string} "something went wrong"
// @Security AuthBearerAdmin
// @Router /admins/benefactors/{id} [get].
func (h Handler) GetBenefactor(c echo.Context) error {
var req param.GetBenefactorByIDRequest
if err := c.Bind(&req); err != nil {
return echo.NewHTTPError(http.StatusBadRequest)
}
bnf, err := h.benefactorSvc.GetByID(c.Request().Context(), req)
if err != nil {
msg, code := httpmsg.Error(err)
return echo.NewHTTPError(code, msg)
}
addresses, err := h.addressSvc.GetAll(c.Request().Context(), adminaddressparam.GetAllAddressesRequest{
BenefactorID: bnf.Data.ID,
})
if err != nil {
msg, code := httpmsg.Error(err)
return echo.NewHTTPError(code, msg)
}
kindBoxes, err := h.kindBoxSvc.GetAll(c.Request().Context(), adminkindboxparam.KindBoxGetAllRequest{
Pagination: params.PaginationRequest{
PageSize: 50,
PageNumber: 1,
},
Sort: params.SortRequest{
Field: "created_at",
Direction: params.DescSortDirection,
},
Filter: map[string]any{
"benefactor_id": bnf.Data.ID,
},
})
if err != nil {
msg, code := httpmsg.Error(err)
return echo.NewHTTPError(code, msg)
}
kindBoxReqs, err := h.kindBoxReqSvc.GetAll(c.Request().Context(), adminkindboxreqparam.KindBoxReqGetAllRequest{
Pagination: params.PaginationRequest{
PageSize: 50,
PageNumber: 1,
},
Sort: params.SortRequest{
Field: "created_at",
Direction: params.DescSortDirection,
},
Filter: map[string]any{
"benefactor_id": bnf.Data.ID,
},
})
if err != nil {
msg, code := httpmsg.Error(err)
return echo.NewHTTPError(code, msg)
}
resp := BenefactorAggregatedResponse{
ID: bnf.Data.ID,
FirstName: bnf.Data.FirstName,
LastName: bnf.Data.LastName,
PhoneNumber: bnf.Data.PhoneNumber,
Description: bnf.Data.Description,
Email: bnf.Data.Email,
Gender: bnf.Data.Gender,
BirthDate: bnf.Data.BirthDate,
Status: bnf.Data.Status,
Addresses: addresses.Data,
KindBoxes: kindBoxes.Data,
KindBoxReqs: kindBoxReqs.Data,
}
return c.JSON(http.StatusOK, resp)
}

View File

@ -1,59 +0,0 @@
package adminbenefactorhandler
import (
"net/http"
param "git.gocasts.ir/ebhomengo/niki/param/admin/benefactor"
httpmsg "git.gocasts.ir/ebhomengo/niki/pkg/http_msg"
queryparam "git.gocasts.ir/ebhomengo/niki/pkg/query_param"
"github.com/labstack/echo/v4"
)
// GetAllBenefactor godoc
// @Summary Get all benefactors by admin
// @Tags Admins Benefactors
// @Accept json
// @Produce json
// @Param search query string false "Search by id, phone_number, concat(first_name, last_name) benefactor"
// @Param filter_id query int false "Filter by ID"
// @Param filter_first_name query string false "Filter by first_name"
// @Param filter_last_name query string false "Filter by last_name"
// @Param filter_phone_number query string false "Filter by phone_number"
// @Param filter_email query string false "Filter by email"
// @Param filter_status query string false "Filter by status" Enums(active,inactive)
// @Param page_number query int false "Page number"
// @Param page_size query int false "Page size"
// @Param sort_field query string false "Sort by field" Enums(id,first_name,last_name,phone_number,email,status,created_at)
// @Param sort_direction query string false "Sort order" Enums(asc,desc)
// @Success 200 {object} param.BenefactorGetAllResponse
// @Failure 400 {string} "Bad Request"
// @Failure 401 {string} "invalid or expired jwt"
// @Failure 403 {string} "user not allowed"
// @Failure 422 {object} httpmsg.ErrorResponse
// @Failure 500 {string} "something went wrong"
// @Security AuthBearerAdmin
// @Router /admins/benefactors [get].
func (h Handler) GetAllBenefactor(c echo.Context) error {
var req param.BenefactorGetAllRequest
if bErr := c.Bind(&req); bErr != nil {
return echo.NewHTTPError(http.StatusBadRequest)
}
req.Filter = queryparam.GetFilterParams(c)
resp, sErr := h.benefactorSvc.GetAllBenefactor(c.Request().Context(), req)
if sErr != nil {
msg, code := httpmsg.Error(sErr)
if resp.FieldErrors != nil {
return c.JSON(code, echo.Map{
"message": msg,
"errors": resp.FieldErrors,
})
}
return echo.NewHTTPError(code, msg)
}
return c.JSON(http.StatusOK, resp)
}

View File

@ -1,36 +0,0 @@
package adminbenefactorhandler
import (
adminaddressservice "git.gocasts.ir/ebhomengo/niki/service/admin/address"
authorizeservice "git.gocasts.ir/ebhomengo/niki/service/admin/authorization"
benefactorservice "git.gocasts.ir/ebhomengo/niki/service/admin/benefactor"
adminkindboxservice "git.gocasts.ir/ebhomengo/niki/service/admin/kind_box"
adminkindboxreqservice "git.gocasts.ir/ebhomengo/niki/service/admin/kind_box_req"
authservice "git.gocasts.ir/ebhomengo/niki/service/auth"
)
type Handler struct {
authSvc authservice.Service
authorizeSvc authorizeservice.Service
benefactorSvc benefactorservice.Service
addressSvc adminaddressservice.Service
kindBoxSvc adminkindboxservice.Service
kindBoxReqSvc adminkindboxreqservice.Service
}
func New(authSvc authservice.Service,
authorizeSvc authorizeservice.Service,
benefactorSvc benefactorservice.Service,
addressSvc adminaddressservice.Service,
kindBoxSvc adminkindboxservice.Service,
kindBoxReqSvc adminkindboxreqservice.Service,
) Handler {
return Handler{
authSvc: authSvc,
authorizeSvc: authorizeSvc,
benefactorSvc: benefactorSvc,
addressSvc: addressSvc,
kindBoxSvc: kindBoxSvc,
kindBoxReqSvc: kindBoxReqSvc,
}
}

View File

@ -1,18 +0,0 @@
package adminbenefactorhandler
import (
"git.gocasts.ir/ebhomengo/niki/delivery/http_server/middleware"
"git.gocasts.ir/ebhomengo/niki/entity"
"github.com/labstack/echo/v4"
)
func (h Handler) SetRoutes(e *echo.Echo) {
r := e.Group("/admins/benefactors")
r.Use(middleware.Auth(h.authSvc))
r.GET("", h.GetAllBenefactor, middleware.AdminAuthorization(h.authorizeSvc, entity.AdminBenefactorGetAllPermission))
r.GET("/:id", h.GetBenefactor, middleware.AdminAuthorization(h.authorizeSvc, entity.AdminBenefactorGetPermission))
r.PUT("/:id", h.Update, middleware.AdminAuthorization(h.authorizeSvc, entity.AdminBenefactorUpdatePermission))
r.PUT("/:id/status", h.UpdateStatus, middleware.AdminAuthorization(h.authorizeSvc, entity.AdminBenefactorUpdateStatusPermission))
}

View File

@ -1,47 +0,0 @@
package adminbenefactorhandler
import (
"net/http"
param "git.gocasts.ir/ebhomengo/niki/param/admin/benefactor"
httpmsg "git.gocasts.ir/ebhomengo/niki/pkg/http_msg"
"github.com/labstack/echo/v4"
)
// Update godoc
// @Summary Update benefactor details by admin
// @Description This endpoint update specific benefactor.
// @Tags Admins Benefactors
// @Accept json
// @Produce json
// @Param id path int true "Benefactor ID"
// @Param Request body param.BenefactorUpdateRequest true "Update Benefactor Body"
// @Success 204
// @Failure 400 {string} "Bad request"
// @Failure 401 {string} "invalid or expired jwt"
// @Failure 403 {string} "user not allowed"
// @Failure 404 {string} "record not found"
// @Failure 500 {string} "something went wrong"
// @Security AuthBearerAdmin
// @Router /admins/benefactors/{id} [put].
func (h Handler) Update(c echo.Context) error {
var req param.BenefactorUpdateRequest
if bErr := c.Bind(&req); bErr != nil {
return echo.NewHTTPError(http.StatusBadRequest)
}
resp, sErr := h.benefactorSvc.Update(c.Request().Context(), req)
if sErr != nil {
msg, code := httpmsg.Error(sErr)
if resp.FieldErrors != nil {
return c.JSON(code, echo.Map{
"message": msg,
"errors": resp.FieldErrors,
})
}
return echo.NewHTTPError(code, msg)
}
return c.JSON(http.StatusNoContent, nil)
}

View File

@ -1,46 +0,0 @@
package adminbenefactorhandler
import (
"net/http"
param "git.gocasts.ir/ebhomengo/niki/param/admin/benefactor"
httpmsg "git.gocasts.ir/ebhomengo/niki/pkg/http_msg"
"github.com/labstack/echo/v4"
)
// UpdateStatus godoc
// @Summary Update benefactor status by admin
// @Description This endpoint update status (active/inactive) benefactor.
// @Tags Admins Benefactors
// @Accept json
// @Produce json
// @Param id path int true "Benefactor ID"
// @Param Request body param.BenefactorUpdateStatusRequest true "Update Benefactor Status"
// @Success 204
// @Failure 400 {string} "Bad request"
// @Failure 401 {string} "invalid or expired jwt"
// @Failure 403 {string} "user not allowed"
// @Failure 404 {string} "record not found"
// @Failure 500 {string} "something went wrong"
// @Security AuthBearerAdmin
// @Router /admins/benefactors/{id}/status [put].
func (h Handler) UpdateStatus(c echo.Context) error {
var req param.BenefactorUpdateStatusRequest
if bErr := c.Bind(&req); bErr != nil {
return echo.NewHTTPError(http.StatusBadRequest)
}
resp, sErr := h.benefactorSvc.UpdateStatus(c.Request().Context(), req)
if sErr != nil {
msg, code := httpmsg.Error(sErr)
if resp.FieldErrors != nil {
return c.JSON(code, echo.Map{
"message": msg,
"errors": resp.FieldErrors,
})
}
return echo.NewHTTPError(code, msg)
}
return c.JSON(http.StatusNoContent, nil)
}

View File

@ -11,7 +11,7 @@ import (
// AssignReceiverAgent godoc
// @Summary Admin assign receiver agent to kindbox
// @Tags Admins KindBoxes
// @Tags KindBox
// @Accept json
// @Produce json
// @Param id path int true "KindBox ID"
@ -19,7 +19,7 @@ import (
// @Success 204
// @Failure 400 {string} "Bad request"
// @Security AuthBearerAdmin
// @Router /admins/kindboxes/{id}/assign-receiver-agent [patch].
// @Router /admin/kindboxes/assign-receiver-agent/{id} [patch].
func (h Handler) AssignReceiverAgent(c echo.Context) error {
var req param.AssignReceiverRequest

View File

@ -1,65 +0,0 @@
package adminkindboxhandler
import (
"time"
adminaddresshandler "git.gocasts.ir/ebhomengo/niki/delivery/http_server/admin/address"
"git.gocasts.ir/ebhomengo/niki/entity"
"git.gocasts.ir/ebhomengo/niki/param"
adminbenefactorparam "git.gocasts.ir/ebhomengo/niki/param/admin/benefactor"
adminrefertimeparam "git.gocasts.ir/ebhomengo/niki/param/admin/refer_time"
)
type KindBoxAggregatedResponse struct {
ID uint `json:"id"`
KindBoxReqID uint `json:"kind_box_req_id"`
BenefactorID uint `json:"benefactor_id"`
KindBoxType entity.KindBoxType `json:"kind_box_type"`
Amount uint `json:"amount"`
SerialNumber string `json:"serial_number"`
Status entity.KindBoxStatus `json:"status"`
DeliverReferTimeID uint `json:"deliver_refer_time_id"`
DeliverReferDate time.Time `json:"deliver_refer_date"`
DeliverAddressID uint `json:"deliver_address_id"`
SenderAgentID uint `json:"sender_agent_id"`
DeliveredAt time.Time `json:"delivered_at"`
ReturnReferTimeID uint `json:"return_refer_time_id"`
ReturnReferDate *time.Time `json:"return_refer_date"`
ReturnAddressID uint `json:"return_address_id"`
ReceiverAgentID uint `json:"receiver_agent_id"`
ReturnedAt *time.Time `json:"returned_at"`
Benefactor adminbenefactorparam.Data `json:"benefactor"`
DeliverAddress adminaddresshandler.Address `json:"deliver_address"`
DeliverReferTime adminrefertimeparam.Data `json:"deliver_refer_time"`
ReturnAddress adminaddresshandler.Address `json:"return_address"`
ReturnReferTime adminrefertimeparam.Data `json:"return_refer_time"`
}
type KindBoxAggregatedListResponse struct {
ID uint `json:"id"`
KindBoxReqID uint `json:"kind_box_req_id"`
BenefactorID uint `json:"benefactor_id"`
KindBoxType entity.KindBoxType `json:"kind_box_type"`
Amount uint `json:"amount"`
SerialNumber string `json:"serial_number"`
Status entity.KindBoxStatus `json:"status"`
DeliverReferTimeID uint `json:"deliver_refer_time_id"`
DeliverReferDate time.Time `json:"deliver_refer_date"`
DeliverAddressID uint `json:"deliver_address_id"`
SenderAgentID uint `json:"sender_agent_id"`
DeliveredAt time.Time `json:"delivered_at"`
ReturnReferTimeID uint `json:"return_refer_time_id"`
ReturnReferDate *time.Time `json:"return_refer_date"`
ReturnAddressID uint `json:"return_address_id"`
ReceiverAgentID uint `json:"receiver_agent_id"`
ReturnedAt *time.Time `json:"returned_at"`
Benefactor adminbenefactorparam.Data `json:"benefactor"`
DeliverReferTime adminrefertimeparam.Data `json:"deliver_refer_time"`
ReturnReferTime adminrefertimeparam.Data `json:"return_refer_time"`
}
type KindBoxesAggregatedResponse struct {
Data []KindBoxAggregatedListResponse `json:"data"`
Pagination param.PaginationResponse `json:"pagination"`
FieldErrors map[string]string `json:"field_errors,omitempty"`
}

View File

@ -11,7 +11,7 @@ import (
// Enumerate godoc
// @Summary Admin enumerate kindbox
// @Tags Admins KindBoxes
// @Tags KindBox
// @Accept json
// @Produce json
// @Param id path int true "KindBox ID"
@ -23,7 +23,7 @@ import (
// @Failure 422 {object} httpmsg.ErrorResponse
// @Failure 500 {string} "something went wrong"
// @Security AuthBearerAdmin
// @Router /admins/kindboxes/{id}/enumerate [patch].
// @Router /admin/kindboxes/{id}/enumerate [patch].
func (h Handler) Enumerate(c echo.Context) error {
var req param.EnumerateKindBoxRequest

View File

@ -11,95 +11,32 @@ import (
// Get godoc
// @Summary Get a specific kind box by admin
// @Description This endpoint retrieves a specific kind box by admin
// @Tags Admins KindBoxes
// @Tags KindBox
// @Accept json
// @Produce json
// @Param id path int true "Kind box ID"
// @Success 200 {object} KindBoxAggregatedResponse
// @Success 200 {object} param.KindBoxGetResponse
// @Failure 400 {string} "Bad request"
// @Failure 401 {string} "invalid or expired jwt"
// @Failure 403 {string} "user not allowed"
// @Failure 404 {string} "record not found"
// @Failure 500 {string} "something went wrong"
// @Security AuthBearerAdmin
// @Router /admins/kindboxes/{id} [get].
// @Router /admin/kindboxes/{id} [get].
func (h Handler) Get(c echo.Context) error {
var req param.KindBoxGetRequest
if bErr := c.Bind(&req); bErr != nil {
return echo.NewHTTPError(http.StatusBadRequest)
}
kindBox, sErr := h.adminKindBoxSvc.Get(c.Request().Context(), req)
resp, sErr := h.adminKindBoxSvc.Get(c.Request().Context(), req)
if sErr != nil {
msg, code := httpmsg.Error(sErr)
if kindBox.FieldErrors != nil {
if resp.FieldErrors != nil {
return c.JSON(code, echo.Map{
"message": msg,
"errors": kindBox.FieldErrors,
"errors": resp.FieldErrors,
})
}
return echo.NewHTTPError(code, msg)
}
benefactor, bErr := h.adminBenefactorAggSvc.GetByID(c.Request().Context(), kindBox.Data.BenefactorID)
if bErr != nil {
msg, code := httpmsg.Error(bErr)
return echo.NewHTTPError(code, msg)
}
deliverAddress, dAErr := h.addressAggSvc.GetAggregatedByID(c.Request().Context(), kindBox.Data.DeliverAddressID)
if dAErr != nil {
msg, code := httpmsg.Error(dAErr)
return echo.NewHTTPError(code, msg)
}
returnAddress, rAErr := h.addressAggSvc.GetAggregatedByID(c.Request().Context(), kindBox.Data.ReturnAddressID)
if rAErr != nil {
msg, code := httpmsg.Error(rAErr)
return echo.NewHTTPError(code, msg)
}
deliverReferTime, dRErr := h.referTimeAggSvc.GetReferTimeByID(c.Request().Context(), kindBox.Data.DeliverReferTimeID)
if dRErr != nil {
msg, code := httpmsg.Error(dRErr)
return echo.NewHTTPError(code, msg)
}
returnReferTime, rRErr := h.referTimeAggSvc.GetReferTimeByID(c.Request().Context(), kindBox.Data.ReturnReferTimeID)
if rRErr != nil {
msg, code := httpmsg.Error(rRErr)
return echo.NewHTTPError(code, msg)
}
resp := KindBoxAggregatedResponse{
ID: kindBox.Data.ID,
KindBoxReqID: kindBox.Data.KindBoxReqID,
BenefactorID: kindBox.Data.BenefactorID,
KindBoxType: kindBox.Data.KindBoxType,
Amount: kindBox.Data.Amount,
SerialNumber: kindBox.Data.SerialNumber,
Status: kindBox.Data.Status,
DeliverReferTimeID: kindBox.Data.DeliverReferTimeID,
DeliverReferDate: kindBox.Data.DeliverReferDate,
DeliverAddressID: kindBox.Data.DeliverAddressID,
SenderAgentID: kindBox.Data.SenderAgentID,
DeliveredAt: kindBox.Data.DeliveredAt,
ReturnReferTimeID: kindBox.Data.ReturnReferTimeID,
ReturnReferDate: kindBox.Data.ReturnReferDate,
ReturnAddressID: kindBox.Data.ReturnAddressID,
ReceiverAgentID: kindBox.Data.ReceiverAgentID,
ReturnedAt: kindBox.Data.ReturnedAt,
Benefactor: benefactor,
DeliverAddress: deliverAddress,
ReturnAddress: returnAddress,
DeliverReferTime: deliverReferTime,
ReturnReferTime: returnReferTime,
}
return c.JSON(http.StatusOK, resp)
}

View File

@ -4,7 +4,6 @@ import (
"net/http"
param "git.gocasts.ir/ebhomengo/niki/param/admin/kind_box"
arrayfunc "git.gocasts.ir/ebhomengo/niki/pkg/array_func"
httpmsg "git.gocasts.ir/ebhomengo/niki/pkg/http_msg"
queryparam "git.gocasts.ir/ebhomengo/niki/pkg/query_param"
"github.com/labstack/echo/v4"
@ -13,14 +12,13 @@ import (
// GetAll godoc
// @Summary Get all KindBoxes by admin
// @Description Retrieves a list of all KindBoxes with filtering, sorting, and pagination options
// @Tags Admins KindBoxes
// @Tags KindBox
// @Accept json
// @Produce json
// @Param search query string false "Search by id, phone_number, concat(first_name, last_name) benefactor"
// @Param filter_id query int false "Filter by ID"
// @Param filter_kind_box_req_id query int false "Filter by KindBox request ID"
// @Param filter_benefactor_id query int false "Filter by benefactor ID"
// @Param filter_type query string false "Filter by KindBox type" Enums(on-table,cylindrical,stand-up)
// @Param filter_kind_box_type query string false "Filter by KindBox type" Enums(on-table,cylindrical,stand-up)
// @Param filter_amount query int false "Filter by amount"
// @Param filter_serial_number query string false "Filter by serial number"
// @Param filter_status query string false "Filter by status" Enums(delivered,ready-to-return,assigned-receiver-agent,returned,enumerated)
@ -38,10 +36,10 @@ import (
// @Param page_size query int false "Page size"
// @Param sort_field query string false "Sort by field" Enums(id,kind_box_req_id,benefactor_id,kind_box_type,amount,serial_number,status,delivered_at,return_refer_time_id,return_refer_date,return_address_id,receiver_agent_id,returned_at,sender_agent_id,deliver_refer_date,deliver_address_id,deliver_refer_time_id)
// @Param sort_direction query string false "Sort order" Enums(asc,desc)
// @Success 200 {array} KindBoxesAggregatedResponse
// @Success 200 {object} param.KindBoxGetAllResponse
// @Failure 400 {string} "Bad request"
// @Security AuthBearerAdmin
// @Router /admins/kindboxes [get].
// @Router /admin/kindboxes [get].
func (h Handler) GetAll(c echo.Context) error {
var req param.KindBoxGetAllRequest
@ -51,94 +49,18 @@ func (h Handler) GetAll(c echo.Context) error {
req.Filter = queryparam.GetFilterParams(c)
kindBoxes, sErr := h.adminKindBoxSvc.GetAll(c.Request().Context(), req)
resp, sErr := h.adminKindBoxSvc.GetAll(c.Request().Context(), req)
if sErr != nil {
msg, code := httpmsg.Error(sErr)
if kindBoxes.FieldErrors != nil {
if resp.FieldErrors != nil {
return c.JSON(code, echo.Map{
"message": msg,
"errors": kindBoxes.FieldErrors,
"errors": resp.FieldErrors,
})
}
return echo.NewHTTPError(code, msg)
}
benefactors, bErr := h.adminBenefactorAggSvc.GetByIDs(c.Request().Context(), getBenefactorIDs(kindBoxes.Data))
if bErr != nil {
msg, code := httpmsg.Error(sErr)
return echo.NewHTTPError(code, msg)
}
deliverReferTime, dRErr := h.referTimeAggSvc.GetReferTimeByIDs(c.Request().Context(), getDeliverReferTimeIDs(kindBoxes.Data))
if dRErr != nil {
msg, code := httpmsg.Error(dRErr)
return echo.NewHTTPError(code, msg)
}
returnReferTime, rRErr := h.referTimeAggSvc.GetReferTimeByIDs(c.Request().Context(), getReturnReferTimeIDs(kindBoxes.Data))
if rRErr != nil {
msg, code := httpmsg.Error(rRErr)
return echo.NewHTTPError(code, msg)
}
var data []KindBoxAggregatedListResponse
for _, kindBox := range kindBoxes.Data {
data = append(data, KindBoxAggregatedListResponse{
ID: kindBox.ID,
KindBoxReqID: kindBox.KindBoxReqID,
BenefactorID: kindBox.BenefactorID,
KindBoxType: kindBox.KindBoxType,
Amount: kindBox.Amount,
SerialNumber: kindBox.SerialNumber,
Status: kindBox.Status,
DeliverReferTimeID: kindBox.DeliverReferTimeID,
DeliverReferDate: kindBox.DeliverReferDate,
DeliverAddressID: kindBox.DeliverAddressID,
SenderAgentID: kindBox.SenderAgentID,
DeliveredAt: kindBox.DeliveredAt,
ReturnReferTimeID: kindBox.ReturnReferTimeID,
ReturnReferDate: kindBox.ReturnReferDate,
ReturnAddressID: kindBox.ReturnAddressID,
ReceiverAgentID: kindBox.ReceiverAgentID,
ReturnedAt: kindBox.ReturnedAt,
Benefactor: benefactors[kindBox.BenefactorID],
DeliverReferTime: deliverReferTime[kindBox.DeliverReferTimeID],
ReturnReferTime: returnReferTime[kindBox.ReturnReferTimeID],
})
}
resp := KindBoxesAggregatedResponse{
Data: data,
Pagination: kindBoxes.Pagination,
}
return c.JSON(http.StatusOK, resp)
}
func getBenefactorIDs(kindBoxes []param.Data) []any {
benefactorsMap := make(map[uint]bool)
for _, kindBox := range kindBoxes {
benefactorsMap[kindBox.BenefactorID] = true
}
return arrayfunc.MapToSlice(benefactorsMap)
}
func getDeliverReferTimeIDs(kindBoxes []param.Data) []any {
deliverReferTimesMap := make(map[uint]bool)
for _, kindBox := range kindBoxes {
deliverReferTimesMap[kindBox.DeliverReferTimeID] = true
}
return arrayfunc.MapToSlice(deliverReferTimesMap)
}
func getReturnReferTimeIDs(kindBoxes []param.Data) []any {
returnReferTimesMap := make(map[uint]bool)
for _, kindBox := range kindBoxes {
returnReferTimesMap[kindBox.ReturnReferTimeID] = true
}
return arrayfunc.MapToSlice(returnReferTimesMap)
}

View File

@ -1,40 +1,28 @@
package adminkindboxhandler
import (
adminaddressaggservice "git.gocasts.ir/ebhomengo/niki/service/admin/address_aggregator"
adminauthorizationservice "git.gocasts.ir/ebhomengo/niki/service/admin/authorization"
adminbenefactoraggsvc "git.gocasts.ir/ebhomengo/niki/service/admin/benefactor_aggregator"
adminkindboxservice "git.gocasts.ir/ebhomengo/niki/service/admin/kind_box"
adminrefertimeaggregatorservice "git.gocasts.ir/ebhomengo/niki/service/admin/refer_time_aggregator"
authservice "git.gocasts.ir/ebhomengo/niki/service/auth"
"git.gocasts.ir/ebhomengo/niki/service/notification"
)
type Handler struct {
authSvc authservice.Service
adminKindBoxSvc adminkindboxservice.Service
adminBenefactorAggSvc adminbenefactoraggsvc.Service
addressAggSvc adminaddressaggservice.Service
referTimeAggSvc adminrefertimeaggregatorservice.Service
adminAuthorizeSvc adminauthorizationservice.Service
notificationSvc notification.Service
authSvc authservice.Service
adminKindBoxSvc adminkindboxservice.Service
adminAuthorizeSvc adminauthorizationservice.Service
notificationSvc notification.Service
}
func New(authSvc authservice.Service,
adminKindBoxSvc adminkindboxservice.Service,
adminBenefactorAggSvc adminbenefactoraggsvc.Service,
addressAggSvc adminaddressaggservice.Service,
referTimeAggSvc adminrefertimeaggregatorservice.Service,
adminAuthorizeSvc adminauthorizationservice.Service,
notificationSvc notification.Service,
) Handler {
return Handler{
authSvc: authSvc,
adminKindBoxSvc: adminKindBoxSvc,
adminBenefactorAggSvc: adminBenefactorAggSvc,
addressAggSvc: addressAggSvc,
referTimeAggSvc: referTimeAggSvc,
adminAuthorizeSvc: adminAuthorizeSvc,
notificationSvc: notificationSvc,
authSvc: authSvc,
adminKindBoxSvc: adminKindBoxSvc,
adminAuthorizeSvc: adminAuthorizeSvc,
notificationSvc: notificationSvc,
}
}

View File

@ -7,13 +7,12 @@ import (
)
func (h Handler) SetRoutes(e *echo.Echo) {
r := e.Group("/admins/kindboxes")
r := e.Group("/admin/kindboxes")
r.Use(middleware.Auth(h.authSvc))
r.GET("/:id", h.Get, middleware.AdminAuthorization(h.adminAuthorizeSvc, entity.AdminKindBoxGetPermission))
r.PATCH("/:id/assign-receiver-agent", h.AssignReceiverAgent, middleware.AdminAuthorization(h.adminAuthorizeSvc, entity.AdminKindBoxAssignReceiverAgentPermission))
r.PATCH("/assign-receiver-agent/:id", h.AssignReceiverAgent, middleware.AdminAuthorization(h.adminAuthorizeSvc, entity.AdminKindBoxAssignReceiverAgentPermission))
r.GET("", h.GetAll, middleware.AdminAuthorization(h.adminAuthorizeSvc, entity.AdminKindBoxGetAllPermission))
r.PATCH("/:id/enumerate", h.Enumerate, middleware.AdminAuthorization(h.adminAuthorizeSvc, entity.AdminKindBoxEnumeratePermission))
r.PUT("/update/:id", h.Update, middleware.AdminAuthorization(h.adminAuthorizeSvc, entity.AdminKindBoxUpdatePermission))
}

View File

@ -1,49 +0,0 @@
package adminkindboxhandler
import (
"net/http"
param "git.gocasts.ir/ebhomengo/niki/param/admin/kind_box"
httpmsg "git.gocasts.ir/ebhomengo/niki/pkg/http_msg"
"github.com/labstack/echo/v4"
)
// Update godoc
// @Summary Update kind Box by admin
// @Tags Admins KindBoxes
// @Accept json
// @Produce json
// @Param id path int true "Kind Box ID"
// @Param Request body param.KindBoxUpdateRequest true "Update KindBox Request Body"
// @Success 204
// @Failure 400 {string} "Bad Request"
// @Failure 401 {string} "invalid or expired jwt"
// @Failure 403 {string} "user not allowed"
// @Failure 422 {object} httpmsg.ErrorResponse
// @Failure 500 {string} "something went wrong"
// @Security AuthBearerAdmin
// @Router /admins/kindboxes/update/{id} [put].
func (h Handler) Update(c echo.Context) error {
var req param.KindBoxUpdateRequest
if bErr := c.Bind(&req); bErr != nil {
return c.JSON(http.StatusBadRequest, httpmsg.ErrorResponse{
Message: "Invalid request body",
})
}
resp, sErr := h.adminKindBoxSvc.Update(c.Request().Context(), req)
if sErr != nil {
msg, code := httpmsg.Error(sErr)
if resp.FieldErrors != nil {
return c.JSON(code, echo.Map{
"message": msg,
"errors": resp.FieldErrors,
})
}
return echo.NewHTTPError(code, msg)
}
return c.JSON(http.StatusNoContent, nil)
}

View File

@ -13,7 +13,7 @@ import (
// Accept godoc
// @Summary Accept kind box request by admin
// @Tags Admins KindBoxReqs
// @Tags KindBoxReq
// @Accept json
// @Produce json
// @Param id path int true "KindBoxReq ID"
@ -21,7 +21,7 @@ import (
// @Success 200 {object} param.KindBoxReqAcceptResponse
// @Failure 400 {string} "Bad request"
// @Security AuthBearerAdmin
// @Router /admins/kindboxreqs/{id}/accept-kind-box-req [patch].
// @Router /admin/kindboxreqs/accept-kind-box-req/{id} [patch].
func (h Handler) Accept(c echo.Context) error {
var req param.KindBoxReqAcceptRequest
if bErr := c.Bind(&req); bErr != nil {

View File

@ -11,14 +11,14 @@ import (
// AddKindBoxReq godoc
// @Summary Add a new kind box request for a benefactor by admin
// @Tags Admins KindBoxReqs
// @Tags KindBoxReq
// @Accept json
// @Produce json
// @Param Request body param.KindBoxReqAddRequest true "New kind box request details"
// @Success 200 {object} param.KindBoxReqAddResponse
// @Failure 400 {string} "Bad request"
// @Security AuthBearerAdmin
// @Router /admins/kindboxreqs [post].
// @Router /admin/kindboxreqs [post].
func (h Handler) AddKindBoxReq(c echo.Context) error {
req := param.KindBoxReqAddRequest{}
if err := c.Bind(&req); err != nil {

View File

@ -13,7 +13,7 @@ import (
// AssignSenderAgent godoc
// @Summary Admin Assign Sender Agent to kindboxreq
// @Tags Admins KindBoxReqs
// @Tags KindBoxReq
// @Accept json
// @Produce json
// @Param id path int true "KindBoxReq ID"
@ -21,7 +21,7 @@ import (
// @Success 200 {object} param.AssignSenderResponse
// @Failure 400 {string} "Bad request"
// @Security AuthBearerAdmin
// @Router /admins/kindboxreqs/{id}/assign-sender-agent [patch].
// @Router /admin/kindboxreqs/assign-sender-agent/{id} [patch].
func (h Handler) AssignSenderAgent(c echo.Context) error {
var req param.AssignSenderRequest

View File

@ -1,11 +1,10 @@
package agentkindboxreqhandler
package adminkindboxreqhandler
import (
"context"
"net/http"
params "git.gocasts.ir/ebhomengo/niki/param"
param "git.gocasts.ir/ebhomengo/niki/param/agent/kind_box_req"
param "git.gocasts.ir/ebhomengo/niki/param/admin/kind_box_req"
errmsg "git.gocasts.ir/ebhomengo/niki/pkg/err_msg"
httpmsg "git.gocasts.ir/ebhomengo/niki/pkg/http_msg"
querier "git.gocasts.ir/ebhomengo/niki/pkg/query_transaction/sql"
@ -13,8 +12,8 @@ import (
)
// Deliver godoc
// @Summary Agent deliver a kindboxreq
// @Tags Agents KindBoxReqs
// @Summary Admin deliver a kindboxreq
// @Tags KindBoxReq
// @Accept json
// @Produce json
// @Param id path int true "KindBoxReq ID"
@ -22,7 +21,7 @@ import (
// @Success 200 {object} param.DeliverKindBoxReqResponse
// @Failure 400 {string} "Bad request"
// @Security AuthBearerAdmin
// @Router /agents/kindboxreqs/{id}/deliver-kind-box-req [patch].
// @Router /admin/kindboxreqs/deliver-kind-box-req/{id} [patch].
func (h Handler) Deliver(c echo.Context) error {
var req param.DeliverKindBoxReqRequest
@ -32,7 +31,7 @@ func (h Handler) Deliver(c echo.Context) error {
q := querier.GetQuerierFromContextOrNew(c.Request().Context()).Begin()
ctx := context.WithValue(c.Request().Context(), querier.QuerierContextKey, q)
resp, sErr := h.agentKindBoxReqSvc.Deliver(ctx, req)
resp, sErr := h.adminKindBoxReqSvc.Deliver(ctx, req)
if sErr != nil {
msg, code := httpmsg.Error(sErr)
if resp.FieldErrors != nil {
@ -53,9 +52,5 @@ func (h Handler) Deliver(c echo.Context) error {
return echo.NewHTTPError(http.StatusInternalServerError, errmsg.ErrorMsgSomethingWentWrong)
}
go h.notificationSvc.KindBoxReqDelivered(params.NotificationKindBoxReqDelivered{
KindBoxReqID: req.KindBoxReqID,
})
return c.JSON(http.StatusOK, resp)
}

View File

@ -1,51 +0,0 @@
package adminkindboxreqhandler
import (
"time"
adminaddresshandler "git.gocasts.ir/ebhomengo/niki/delivery/http_server/admin/address"
"git.gocasts.ir/ebhomengo/niki/entity"
"git.gocasts.ir/ebhomengo/niki/param"
adminbenefactorparam "git.gocasts.ir/ebhomengo/niki/param/admin/benefactor"
adminrefertimeparam "git.gocasts.ir/ebhomengo/niki/param/admin/refer_time"
)
type KindBoxReqAggregatedResponse struct {
ID uint `json:"id"`
BenefactorID uint `json:"benefactor_id"`
KindBoxType entity.KindBoxType `json:"kind_box_type"`
CountRequested uint `json:"count_requested"`
CountAccepted uint `json:"count_accepted"`
Description string `json:"description"`
Status entity.KindBoxReqStatus `json:"status"`
DeliverReferTimeID uint `json:"deliver_refer_time_id"`
DeliverReferDate time.Time `json:"deliver_refer_date"`
DeliverAddressID uint `json:"deliver_address_id"`
SenderAgentID uint `json:"sender_agent_id"`
DeliveredAt *time.Time `json:"delivered_at"`
Benefactor adminbenefactorparam.Data `json:"benefactor"`
DeliverAddress adminaddresshandler.Address `json:"deliver_address"`
DeliverReferTime adminrefertimeparam.Data `json:"deliver_refer_time"`
}
type KindBoxReqAggregatedListResponse struct {
ID uint `json:"id"`
BenefactorID uint `json:"benefactor_id"`
KindBoxType entity.KindBoxType `json:"kind_box_type"`
CountRequested uint `json:"count_requested"`
CountAccepted uint `json:"count_accepted"`
Description string `json:"description"`
Status entity.KindBoxReqStatus `json:"status"`
DeliverReferTimeID uint `json:"deliver_refer_time_id"`
DeliverReferDate time.Time `json:"deliver_refer_date"`
DeliverAddressID uint `json:"deliver_address_id"`
SenderAgentID uint `json:"sender_agent_id"`
DeliveredAt *time.Time `json:"delivered_at"`
Benefactor adminbenefactorparam.Data `json:"benefactor"`
}
type KindBoxReqsAggregatedResponse struct {
Data []KindBoxReqAggregatedListResponse `json:"data"`
Pagination param.PaginationResponse `json:"pagination"`
FieldErrors map[string]string `json:"field_errors,omitempty"`
}

View File

@ -10,11 +10,11 @@ import (
// Get godoc
// @Summary Get a specific kind box req by ID
// @Tags Admins KindBoxReqs
// @Tags KindBoxReq
// @Accept json
// @Produce json
// @Param id path int true "KindBoxReq ID"
// @Success 200 {object} KindBoxReqAggregatedResponse
// @Success 200 {object} param.GetKindBoxReqResponse
// @Failure 400 {string} "Bad Request"
// @Failure 401 {string} "invalid or expired jwt"
// @Failure 403 {string} "user not allowed"
@ -28,56 +28,18 @@ func (h Handler) Get(c echo.Context) error {
return echo.NewHTTPError(http.StatusBadRequest)
}
kindBoxReq, err := h.adminKindBoxReqSvc.Get(c.Request().Context(), req)
resp, err := h.adminKindBoxReqSvc.Get(c.Request().Context(), req)
if err != nil {
msg, code := httpmsg.Error(err)
if kindBoxReq.FieldErrors != nil {
if resp.FieldErrors != nil {
return c.JSON(code, echo.Map{
"message": msg,
"errors": kindBoxReq.FieldErrors,
"errors": resp.FieldErrors,
})
}
return echo.NewHTTPError(code, msg)
}
benefactor, bErr := h.adminBenefactorAggSvc.GetByID(c.Request().Context(), kindBoxReq.Data.BenefactorID)
if bErr != nil {
msg, code := httpmsg.Error(bErr)
return echo.NewHTTPError(code, msg)
}
deliverAddress, dAErr := h.addressAggSvc.GetAggregatedByID(c.Request().Context(), kindBoxReq.Data.DeliverAddressID)
if dAErr != nil {
msg, code := httpmsg.Error(dAErr)
return echo.NewHTTPError(code, msg)
}
deliverReferTime, dRErr := h.referTimeAggSvc.GetReferTimeByID(c.Request().Context(), kindBoxReq.Data.DeliverReferTimeID)
if dRErr != nil {
msg, code := httpmsg.Error(dRErr)
return echo.NewHTTPError(code, msg)
}
resp := KindBoxReqAggregatedResponse{
ID: kindBoxReq.Data.ID,
BenefactorID: kindBoxReq.Data.BenefactorID,
KindBoxType: kindBoxReq.Data.KindBoxType,
CountRequested: kindBoxReq.Data.CountRequested,
CountAccepted: kindBoxReq.Data.CountAccepted,
Description: kindBoxReq.Data.Description,
Status: kindBoxReq.Data.Status,
DeliverReferTimeID: kindBoxReq.Data.DeliverReferTimeID,
DeliverReferDate: kindBoxReq.Data.DeliverReferDate,
DeliverAddressID: kindBoxReq.Data.DeliverAddressID,
SenderAgentID: kindBoxReq.Data.SenderAgentID,
DeliveredAt: kindBoxReq.Data.DeliveredAt,
Benefactor: benefactor,
DeliverAddress: deliverAddress,
DeliverReferTime: deliverReferTime,
}
return c.JSON(http.StatusOK, resp)
}

View File

@ -4,7 +4,6 @@ import (
"net/http"
param "git.gocasts.ir/ebhomengo/niki/param/admin/kind_box_req"
arrayfunc "git.gocasts.ir/ebhomengo/niki/pkg/array_func"
httpmsg "git.gocasts.ir/ebhomengo/niki/pkg/http_msg"
queryparam "git.gocasts.ir/ebhomengo/niki/pkg/query_param"
echo "github.com/labstack/echo/v4"
@ -13,10 +12,9 @@ import (
// GetAll godoc
// @Summary Admin get all kindboxreq
// @Description Retrieves a list of all KindBox requests with filtering, sorting, and pagination options
// @Tags Admins KindBoxReqs
// @Tags KindBoxReq
// @Accept json
// @Produce json
// @Param search query string false "Search by id, phone_number, concat(first_name, last_name) benefactor"
// @Param filter_id query int false "Filter by ID"
// @Param filter_benefactor_id query int false "Filter by benefactor ID"
// @Param filter_sender_agent_id query int false "Filter by sender agent ID"
@ -32,7 +30,7 @@ import (
// @Param page_size query int false "Page size"
// @Param sort_field query string false "Sort by field" Enums(id,benefactor_id,sender_agent_id,kind_box_type,status,count_requested,count_accepted,deliver_refer_time_id,deliver_refer_date,deliver_address_id,delivered_at)
// @Param sort_direction query string false "Sort order" Enums(asc,desc)
// @Success 200 {array} KindBoxReqsAggregatedResponse
// @Success 200 {object} param.KindBoxReqGetAllResponse
// @Failure 400 {string} "Bad Request"
// @Failure 401 {string} "invalid or expired jwt"
// @Failure 403 {string} "user not allowed"
@ -49,55 +47,18 @@ func (h Handler) GetAll(c echo.Context) error {
req.Filter = queryparam.GetFilterParams(c)
kindBoxReqs, err := h.adminKindBoxReqSvc.GetAll(c.Request().Context(), req)
resp, err := h.adminKindBoxReqSvc.GetAll(c.Request().Context(), req)
if err != nil {
msg, code := httpmsg.Error(err)
if kindBoxReqs.FieldErrors != nil {
if resp.FieldErrors != nil {
return c.JSON(code, httpmsg.ErrorResponse{
Message: msg,
Errors: kindBoxReqs.FieldErrors,
Errors: resp.FieldErrors,
})
}
return echo.NewHTTPError(code, msg)
}
benefactors, bErr := h.adminBenefactorAggSvc.GetByIDs(c.Request().Context(), getBenefactorIDs(kindBoxReqs.Data))
if bErr != nil {
msg, code := httpmsg.Error(bErr)
return echo.NewHTTPError(code, msg)
}
var data []KindBoxReqAggregatedListResponse
for _, kindBoxReq := range kindBoxReqs.Data {
data = append(data, KindBoxReqAggregatedListResponse{
ID: kindBoxReq.ID,
BenefactorID: kindBoxReq.BenefactorID,
KindBoxType: kindBoxReq.KindBoxType,
CountRequested: kindBoxReq.CountRequested,
CountAccepted: kindBoxReq.CountAccepted,
Description: kindBoxReq.Description,
Status: kindBoxReq.Status,
DeliverReferTimeID: kindBoxReq.DeliverReferTimeID,
DeliverReferDate: kindBoxReq.DeliverReferDate,
DeliverAddressID: kindBoxReq.DeliverAddressID,
SenderAgentID: kindBoxReq.SenderAgentID,
DeliveredAt: kindBoxReq.DeliveredAt,
Benefactor: benefactors[kindBoxReq.BenefactorID],
})
}
resp := KindBoxReqsAggregatedResponse{
Data: data,
Pagination: kindBoxReqs.Pagination,
}
return c.JSON(http.StatusOK, resp)
}
func getBenefactorIDs(kindBoxReqs []param.Data) []any {
benefactorsMap := make(map[uint]bool)
for _, kindBox := range kindBoxReqs {
benefactorsMap[kindBox.BenefactorID] = true
}
return arrayfunc.MapToSlice(benefactorsMap)
}

View File

@ -1,10 +1,10 @@
package agentkindboxreqhandler
package adminkindboxreqhandler
import (
"net/http"
"git.gocasts.ir/ebhomengo/niki/entity"
param "git.gocasts.ir/ebhomengo/niki/param/agent/kind_box_req"
param "git.gocasts.ir/ebhomengo/niki/param/admin/kind_box_req"
"git.gocasts.ir/ebhomengo/niki/pkg/claim"
httpmsg "git.gocasts.ir/ebhomengo/niki/pkg/http_msg"
queryparam "git.gocasts.ir/ebhomengo/niki/pkg/query_param"
@ -14,7 +14,7 @@ import (
// GetAllAwaitingDelivery godoc
// @Summary Get all awaiting delivery KindBox requests
// @Description Retrieves a list of all awaiting KindBox requests with filtering, sorting, and pagination options
// @Tags Agents KindBoxReqs
// @Tags KindBoxReq
// @Accept json
// @Produce json
// @Param filter_id query int false "Filter by ID"
@ -32,7 +32,7 @@ import (
// @Success 200 {object} param.DeliveryAwaitingGetAllResponse
// @Failure 400 {string} "Bad request"
// @Security AuthBearerAdmin
// @Router /agents/kindboxreqs/awaiting-delivery [get].
// @Router /admin/kindboxreqs/awaiting-delivery [get].
func (h Handler) GetAllAwaitingDelivery(c echo.Context) error {
var req param.DeliveryAwaitingGetAllRequest
@ -40,11 +40,9 @@ func (h Handler) GetAllAwaitingDelivery(c echo.Context) error {
return echo.NewHTTPError(http.StatusBadRequest)
}
req.Filter = queryparam.GetFilterParams(c)
req.SenderAgentId = claim.GetClaimsFromEchoContext(c).UserID
req.Status = entity.KindBoxReqAssignedSenderAgentStatus
resp, sErr := h.agentKindBoxReqSvc.GetAllAwaitingDelivery(c.Request().Context(), req)
req.Filter["sender_agent_id"] = claim.GetClaimsFromEchoContext(c).UserID
req.Filter["status"] = entity.KindBoxReqAssignedSenderAgentStatus
resp, sErr := h.adminKindBoxReqSvc.GetAllAwaitingDelivery(c.Request().Context(), req)
if sErr != nil {
msg, code := httpmsg.Error(sErr)
if resp.FieldErrors != nil {

View File

@ -1,9 +1,9 @@
package agentkindboxreqhandler
package adminkindboxreqhandler
import (
"net/http"
param "git.gocasts.ir/ebhomengo/niki/param/agent/kind_box_req"
param "git.gocasts.ir/ebhomengo/niki/param/admin/kind_box_req"
"git.gocasts.ir/ebhomengo/niki/pkg/claim"
httpmsg "git.gocasts.ir/ebhomengo/niki/pkg/http_msg"
"github.com/labstack/echo/v4"
@ -11,14 +11,14 @@ import (
// GetAwaitingDelivery godoc
// @Summary Get a kind box reqs that is awaiting delivery by agent
// @Tags Agents KindBoxReqs
// @Tags KindBoxReq
// @Accept json
// @Produce json
// @Param id path int true "KindBoxReq ID"
// @Success 200 {object} param.DeliveryAwaitingGetResponse
// @Failure 400 {string} "Bad request"
// @Security AuthBearerAdmin
// @Router /agents/kindboxreqs/awaiting-delivery/{id} [get].
// @Router /admin/kindboxreqs/awaiting-delivery/{id} [get].
func (h Handler) GetAwaitingDelivery(c echo.Context) error {
var req param.DeliveryAwaitingGetRequest
if bErr := c.Bind(&req); bErr != nil {
@ -28,7 +28,7 @@ func (h Handler) GetAwaitingDelivery(c echo.Context) error {
claims := claim.GetClaimsFromEchoContext(c)
req.AgentID = claims.UserID
resp, sErr := h.agentKindBoxReqSvc.GetAwaitingDelivery(c.Request().Context(), req)
resp, sErr := h.adminKindBoxReqSvc.GetAwaitingDelivery(c.Request().Context(), req)
if sErr != nil {
msg, code := httpmsg.Error(sErr)
if resp.FieldErrors != nil {

View File

@ -1,40 +1,27 @@
package adminkindboxreqhandler
import (
adminaddressaggservice "git.gocasts.ir/ebhomengo/niki/service/admin/address_aggregator"
adminauthorizationservice "git.gocasts.ir/ebhomengo/niki/service/admin/authorization"
adminbenefactoraggsvc "git.gocasts.ir/ebhomengo/niki/service/admin/benefactor_aggregator"
adminkindboxreqservice "git.gocasts.ir/ebhomengo/niki/service/admin/kind_box_req"
adminrefertimeaggregatorservice "git.gocasts.ir/ebhomengo/niki/service/admin/refer_time_aggregator"
authservice "git.gocasts.ir/ebhomengo/niki/service/auth"
"git.gocasts.ir/ebhomengo/niki/service/notification"
)
type Handler struct {
authSvc authservice.Service
adminKindBoxReqSvc adminkindboxreqservice.Service
adminBenefactorAggSvc adminbenefactoraggsvc.Service
addressAggSvc adminaddressaggservice.Service
referTimeAggSvc adminrefertimeaggregatorservice.Service
adminAuthorizeSvc adminauthorizationservice.Service
notificationSvc notification.Service
authSvc authservice.Service
adminKindBoxReqSvc adminkindboxreqservice.Service
adminAuthorizeSvc adminauthorizationservice.Service
notificationSvc notification.Service
}
func New(authSvc authservice.Service,
adminKindBoxReqSvc adminkindboxreqservice.Service,
adminBenefactorAggSvc adminbenefactoraggsvc.Service,
addressAggSvc adminaddressaggservice.Service,
referTimeAggSvc adminrefertimeaggregatorservice.Service,
adminAuthorizeSvc adminauthorizationservice.Service,
notificationSvc notification.Service,
adminAuthorizeSvc adminauthorizationservice.Service, notificationSvc notification.Service,
) Handler {
return Handler{
authSvc: authSvc,
adminKindBoxReqSvc: adminKindBoxReqSvc,
adminBenefactorAggSvc: adminBenefactorAggSvc,
addressAggSvc: addressAggSvc,
referTimeAggSvc: referTimeAggSvc,
adminAuthorizeSvc: adminAuthorizeSvc,
notificationSvc: notificationSvc,
authSvc: authSvc,
adminKindBoxReqSvc: adminKindBoxReqSvc,
adminAuthorizeSvc: adminAuthorizeSvc,
notificationSvc: notificationSvc,
}
}

View File

@ -13,7 +13,7 @@ import (
// Reject godoc
// @Summary Reject a kindboxreq by admin
// @Tags Admins KindBoxReqs
// @Tags KindBoxReq
// @Accept json
// @Produce json
// @Param id path int true "KindBoxReq id"
@ -21,7 +21,7 @@ import (
// @Success 200 {object} param.KindBoxReqRejectResponse
// @Failure 400 {string} "Bad request"
// @Security AuthBearerAdmin
// @Router /admins/kindboxreqs/{id}/reject-kind-box-req [patch].
// @Router /admin/kindboxreqs/reject-kind-box-req/{id} [patch].
func (h Handler) Reject(c echo.Context) error {
var req param.KindBoxReqRejectRequest
if bErr := c.Bind(&req); bErr != nil {

View File

@ -11,10 +11,13 @@ func (h Handler) SetRoutes(e *echo.Echo) {
r.Use(middleware.Auth(h.authSvc))
r.POST("", h.AddKindBoxReq, middleware.AdminAuthorization(h.adminAuthorizeSvc, entity.AdminKindBoxReqAddPermission))
r.PATCH("/:id/accept-kind-box-req", h.Accept, middleware.AdminAuthorization(h.adminAuthorizeSvc, entity.AdminKindBoxReqAcceptPermission))
r.PATCH("/:id/reject-kind-box-req", h.Reject, middleware.AdminAuthorization(h.adminAuthorizeSvc, entity.AdminKindBoxReqRejectPermission))
r.PATCH("/:id/assign-sender-agent", h.AssignSenderAgent, middleware.AdminAuthorization(h.adminAuthorizeSvc, entity.AdminKindBoxReqAssignSenderAgentPermission))
r.PATCH("/accept-kind-box-req/:id", h.Accept, middleware.AdminAuthorization(h.adminAuthorizeSvc, entity.AdminKindBoxReqAcceptPermission))
r.PATCH("/reject-kind-box-req/:id", h.Reject, middleware.AdminAuthorization(h.adminAuthorizeSvc, entity.AdminKindBoxReqRejectPermission))
r.PATCH("/deliver-kind-box-req/:id", h.Deliver, middleware.AdminAuthorization(h.adminAuthorizeSvc, entity.AdminKindBoxReqDeliverPermission))
r.PATCH("/assign-sender-agent/:id", h.AssignSenderAgent, middleware.AdminAuthorization(h.adminAuthorizeSvc, entity.AdminKindBoxReqAssignSenderAgentPermission))
r.GET("", h.GetAll, middleware.AdminAuthorization(h.adminAuthorizeSvc, entity.AdminKindBoxReqGetAllPermission))
r.GET("/awaiting-delivery/:id", h.GetAwaitingDelivery, middleware.AdminAuthorization(h.adminAuthorizeSvc, entity.AdminKindBoxReqGetAwaitingDeliveryPermission))
r.GET("/awaiting-delivery", h.GetAllAwaitingDelivery, middleware.AdminAuthorization(h.adminAuthorizeSvc, entity.AdminKindBoxReqGetAwaitingDeliveryPermission))
r.PUT("/:id", h.Update, middleware.AdminAuthorization(h.adminAuthorizeSvc, entity.AdminKindBoxReqUpdatePermission))
r.GET("/:id", h.Get, middleware.AdminAuthorization(h.adminAuthorizeSvc, entity.AdminKindBoxReqGetPermission))
}

View File

@ -10,7 +10,7 @@ import (
// Update godoc
// @Summary Update kind box request by admin
// @Tags Admins KindBoxReqs
// @Tags KindBoxReq
// @Accept json
// @Produce json
// @Param id path int true "KindBoxReq ID"
@ -18,7 +18,7 @@ import (
// @Success 204
// @Failure 400 {string} "Bad request"
// @Security AuthBearerAdmin
// @Router /admins/kindboxreqs/{id} [put].
// @Router /admin/kindboxreqs/{id} [put].
func (h Handler) Update(c echo.Context) error {
var req param.KindBoxReqUpdateRequest
if bErr := c.Bind(&req); bErr != nil {

View File

@ -1,45 +0,0 @@
package adminrefertimehandler
import (
"net/http"
refertimeparam "git.gocasts.ir/ebhomengo/niki/param/admin/refer_time"
httpmsg "git.gocasts.ir/ebhomengo/niki/pkg/http_msg"
queryparam "git.gocasts.ir/ebhomengo/niki/pkg/query_param"
echo "github.com/labstack/echo/v4"
)
// GetAll godoc
// @Summary Get all refer times
// @Tags Admins ReferTimes
// @Accept json
// @Produce json
// @Param filter_status query entity.ReferTimeStatus false "Filter by KindBoxReq status" Format(enum)
// @Success 200 {object} adminrefertimeparam.GetAllReferTimeResponse
// @Failure 400 {string} "Bad request"
// @Security AuthBearerAdmin
// @Router /admins/refer-times [get].
func (h Handler) GetAll(c echo.Context) error {
var req refertimeparam.GetAllReferTimeRequest
if err := c.Bind(&req); err != nil {
return echo.NewHTTPError(http.StatusBadRequest)
}
req.Filter = queryparam.GetFilterParams(c)
resp, err := h.adminReferTimeSvc.GetAll(c.Request().Context(), req)
if err != nil {
msg, code := httpmsg.Error(err)
if resp.FieldErrors != nil {
return c.JSON(code, httpmsg.ErrorResponse{
Message: msg,
Errors: resp.FieldErrors,
})
}
return echo.NewHTTPError(code, msg)
}
return c.JSON(http.StatusOK, resp)
}

View File

@ -1,24 +0,0 @@
package adminrefertimehandler
import (
adminauthorizationservice "git.gocasts.ir/ebhomengo/niki/service/admin/authorization"
adminrefertimeservice "git.gocasts.ir/ebhomengo/niki/service/admin/refer_time"
authservice "git.gocasts.ir/ebhomengo/niki/service/auth"
)
type Handler struct {
authSvc authservice.Service
adminReferTimeSvc adminrefertimeservice.Service
adminAuthorizeSvc adminauthorizationservice.Service
}
func New(authSvc authservice.Service,
adminReferTimeSvc adminrefertimeservice.Service,
adminAuthorizeSvc adminauthorizationservice.Service,
) Handler {
return Handler{
authSvc: authSvc,
adminReferTimeSvc: adminReferTimeSvc,
adminAuthorizeSvc: adminAuthorizeSvc,
}
}

View File

@ -1,15 +0,0 @@
package adminrefertimehandler
import (
"git.gocasts.ir/ebhomengo/niki/delivery/http_server/middleware"
"git.gocasts.ir/ebhomengo/niki/entity"
echo "github.com/labstack/echo/v4"
)
func (h Handler) SetRoutes(e *echo.Echo) {
r := e.Group("/admins/refer-times")
r.Use(middleware.Auth(h.authSvc))
r.GET("", h.GetAll, middleware.AdminAuthorization(h.adminAuthorizeSvc, entity.AdminReferTimeGetAllPermission))
}

View File

@ -1,43 +0,0 @@
package adminseedhandler
import (
"errors"
errmsg "git.gocasts.ir/ebhomengo/niki/pkg/err_msg"
"net/http"
"git.gocasts.ir/ebhomengo/niki/entity"
adminseedparam "git.gocasts.ir/ebhomengo/niki/param/admin/seed"
httpmsg "git.gocasts.ir/ebhomengo/niki/pkg/http_msg"
echo "github.com/labstack/echo/v4"
)
func (h Handler) Call(c echo.Context) error {
var req adminseedparam.CallSeedRequest
if err := c.Bind(&req); err != nil {
return echo.NewHTTPError(http.StatusBadRequest)
}
var err error
switch req.Action {
case adminseedparam.ActionAddBenefactor:
_, err = h.adminSeedSvc.AddBenefactor(c.Request().Context())
case adminseedparam.AddKindBoxReq:
_, err = h.adminSeedSvc.AddKindBoxReq(c.Request().Context(), entity.KindBoxReqAcceptedStatus)
case adminseedparam.AssignSenderToKindBoxReq:
_, err = h.adminSeedSvc.AssignSenderToKindBoxReq(c.Request().Context(), req.UserId)
case adminseedparam.AddKindBox:
_, err = h.adminSeedSvc.AddKindBox(c.Request().Context(), req.UserId, entity.KindBoxDeliveredStatus)
case adminseedparam.AssignReceiverAgentKindBox:
_, err = h.adminSeedSvc.AssignReceiverAgentKindBox(c.Request().Context(), req.UserId)
default:
err = errors.New(errmsg.ErrorMsgInvalidAction)
}
if err != nil {
msg, code := httpmsg.Error(err)
return echo.NewHTTPError(code, msg)
}
return c.JSON(http.StatusNoContent, "success!")
}

View File

@ -1,20 +0,0 @@
package adminseedhandler
import (
authservice "git.gocasts.ir/ebhomengo/niki/service/auth"
adminseederservice "git.gocasts.ir/ebhomengo/niki/service/seeder"
)
type Handler struct {
authSvc authservice.Service
adminSeedSvc adminseederservice.Service
}
func New(authSvc authservice.Service,
adminSeedSvc adminseederservice.Service,
) Handler {
return Handler{
authSvc: authSvc,
adminSeedSvc: adminSeedSvc,
}
}

View File

@ -1,14 +0,0 @@
package adminseedhandler
import (
"git.gocasts.ir/ebhomengo/niki/delivery/http_server/middleware"
echo "github.com/labstack/echo/v4"
)
func (h Handler) SetRoutes(e *echo.Echo) {
r := e.Group("/admins/seed")
r.Use(middleware.Auth(h.authSvc), middleware.TokenSeed(h.authSvc))
r.POST("", h.Call)
}

View File

@ -11,7 +11,7 @@ import (
// Get godoc
// @Summary Get a kind box that is awaiting return by agent
// @Tags Agents KindBoxes
// @Tags KindBox
// @Accept json
// @Produce json
// @Param id path int true "KindBox ID"

View File

@ -14,7 +14,7 @@ import (
// GetAll godoc
// @Summary Get all awaiting return KindBoxes by agent
// @Description Retrieves a list of all awaiting return KindBoxes for agent with filtering, sorting, and pagination options
// @Tags Agents KindBoxes
// @Tags KindBox
// @Accept json
// @Produce json
// @Param filter_id query int false "Filter by ID"
@ -44,8 +44,8 @@ func (h Handler) GetAll(c echo.Context) error {
}
req.Filter = queryparam.GetFilterParams(c)
req.ReceiverAgentId = claim.GetClaimsFromEchoContext(c).UserID
req.Status = entity.KindBoxAssignedReceiverAgentStatus
req.Filter["receiver_agent_id"] = claim.GetClaimsFromEchoContext(c).UserID
req.Filter["status"] = entity.KindBoxAssignedReceiverAgentStatus
resp, err := h.agentKindBoxSvc.GetAll(c.Request().Context(), req)
if err != nil {

View File

@ -4,25 +4,21 @@ import (
adminauthorizationservice "git.gocasts.ir/ebhomengo/niki/service/admin/authorization"
agentkindboxservice "git.gocasts.ir/ebhomengo/niki/service/agent/kind_box"
authservice "git.gocasts.ir/ebhomengo/niki/service/auth"
"git.gocasts.ir/ebhomengo/niki/service/notification"
)
type Handler struct {
authSvc authservice.Service
agentKindBoxSvc agentkindboxservice.Service
adminAuthorizeSvc adminauthorizationservice.Service
notificationSvc notification.Service
}
func New(authSvc authservice.Service,
agentKindBoxSvc agentkindboxservice.Service,
adminAuthorizeSvc adminauthorizationservice.Service,
notificationSvc notification.Service,
) Handler {
return Handler{
authSvc: authSvc,
agentKindBoxSvc: agentKindBoxSvc,
adminAuthorizeSvc: adminAuthorizeSvc,
notificationSvc: notificationSvc,
}
}

View File

@ -3,7 +3,6 @@ package agentkindboxhandler
import (
"net/http"
params "git.gocasts.ir/ebhomengo/niki/param"
param "git.gocasts.ir/ebhomengo/niki/param/agent/kind_box"
"git.gocasts.ir/ebhomengo/niki/pkg/claim"
httpmsg "git.gocasts.ir/ebhomengo/niki/pkg/http_msg"
@ -12,7 +11,7 @@ import (
// Return godoc
// @Summary Return KindBox from benefactor by agent
// @Tags Agents KindBoxes
// @Tags KindBox
// @Accept json
// @Produce json
// @Param id path int true "KindBox ID"
@ -24,7 +23,7 @@ import (
// @Failure 422 {object} httpmsg.ErrorResponse
// @Failure 500 {string} "something went wrong"
// @Security AuthBearerAdmin
// @Router /agents/kindboxes/{id}/return [patch].
// @Router /agents/kindboxes/return/{id} [patch].
func (h Handler) Return(c echo.Context) error {
var req param.ReturnKindBoxRequest
if err := c.Bind(&req); err != nil {
@ -47,9 +46,5 @@ func (h Handler) Return(c echo.Context) error {
return echo.NewHTTPError(code, msg)
}
go h.notificationSvc.KindBoxReturned(params.NotificationKindBoxReturned{
KindBoxID: req.KindBoxID,
})
return c.NoContent(http.StatusNoContent)
}

View File

@ -13,5 +13,5 @@ func (h Handler) SetRoutes(e *echo.Echo) {
r.GET("/:id", h.Get, middleware.AdminAuthorization(h.adminAuthorizeSvc, entity.AdminKindBoxGetAwaitingReturnPermission))
r.GET("", h.GetAll, middleware.AdminAuthorization(h.adminAuthorizeSvc, entity.AdminKindBoxGetAwaitingReturnPermission))
r.PATCH("/:id/return", h.Return, middleware.AdminAuthorization(h.adminAuthorizeSvc, entity.AdminKindBoxReturnPermission))
r.PATCH("/return/:id", h.Return, middleware.AdminAuthorization(h.adminAuthorizeSvc, entity.AdminKindBoxReturnPermission))
}

View File

@ -1,28 +0,0 @@
package agentkindboxreqhandler
import (
adminauthorizationservice "git.gocasts.ir/ebhomengo/niki/service/admin/authorization"
agentkindboxreqservice "git.gocasts.ir/ebhomengo/niki/service/agent/kind_box_req"
authservice "git.gocasts.ir/ebhomengo/niki/service/auth"
"git.gocasts.ir/ebhomengo/niki/service/notification"
)
type Handler struct {
authSvc authservice.Service
agentKindBoxReqSvc agentkindboxreqservice.Service
adminAuthorizeSvc adminauthorizationservice.Service
notificationSvc notification.Service
}
func New(authSvc authservice.Service,
agentKindBoxReqSvc agentkindboxreqservice.Service,
adminAuthorizeSvc adminauthorizationservice.Service,
notificationSvc notification.Service,
) Handler {
return Handler{
authSvc: authSvc,
agentKindBoxReqSvc: agentKindBoxReqSvc,
adminAuthorizeSvc: adminAuthorizeSvc,
notificationSvc: notificationSvc,
}
}

View File

@ -1,16 +0,0 @@
package agentkindboxreqhandler
import (
"git.gocasts.ir/ebhomengo/niki/delivery/http_server/middleware"
"git.gocasts.ir/ebhomengo/niki/entity"
"github.com/labstack/echo/v4"
)
func (h Handler) SetRoutes(e *echo.Echo) {
r := e.Group("/agents/kindboxreqs")
r.Use(middleware.Auth(h.authSvc))
r.GET("/awaiting-delivery/:id", h.GetAwaitingDelivery, middleware.AdminAuthorization(h.adminAuthorizeSvc, entity.AdminKindBoxReqGetAwaitingDeliveryPermission))
r.GET("/awaiting-delivery", h.GetAllAwaitingDelivery, middleware.AdminAuthorization(h.adminAuthorizeSvc, entity.AdminKindBoxReqGetAwaitingDeliveryPermission))
r.PATCH("/:id/deliver-kind-box-req", h.Deliver, middleware.AdminAuthorization(h.adminAuthorizeSvc, entity.AdminKindBoxReqDeliverPermission))
}

View File

@ -12,14 +12,14 @@ import (
// AddAddress godoc
// @Summary Add a new address for a benefactor
// @Description This endpoint allows an authenticated benefactor to add a new address to their account.
// @Tags Benefactors Addresses
// @Tags Address
// @Accept json
// @Produce json
// @Param Request body param.BenefactorAddAddressRequest true "New address details"
// @Success 201 {object} param.BenefactorAddAddressResponse
// @Failure 400 {string} "Bad request"
// @Security AuthBearerBenefactor
// @Router /benefactors/addresses [post].
// @Security AuthBearerBenefactor
// @Router /address/ [post].
func (h Handler) AddAddress(c echo.Context) error {
req := param.BenefactorAddAddressRequest{}
if bErr := c.Bind(&req); bErr != nil {

View File

@ -12,12 +12,12 @@ import (
// DeleteAddress godoc
// @Summary Delete address by benefactor
// @Description This endpoint is used to delete an address by benefactor
// @Tags Benefactors Addresses
// @Tags Address
// @Param id path int true "Address ID"
// @Success 204
// @Failure 400 {string} "Bad request"
// @Security AuthBearerBenefactor
// @Router /benefactors/addresses/{id} [delete].
// @Router /address/{id} [delete].
func (h Handler) DeleteAddress(c echo.Context) error {
var req param.DeleteAddressRequest

View File

@ -11,14 +11,14 @@ import (
// GetAddress godoc
// @Summary Get a benefactor address
// @Tags Benefactors Addresses
// @Tags Address
// @Accept json
// @Produce json
// @Param id path int true "Address ID"
// @Success 200 {object} param.GetAddressResponse
// @Failure 400 {string} "Bad request"
// @Security AuthBearerBenefactor
// @Router /benefactors/addresses/{id} [get].
// @Router /address/{id} [get].
func (h Handler) GetAddress(c echo.Context) error {
var req param.GetAddressRequest
if bErr := echo.PathParamsBinder(c).Uint("id", &req.AddressID).BindError(); bErr != nil {

View File

@ -11,13 +11,13 @@ import (
// GetAddresses godoc
// @Summary Get all benefactor addresses
// @Tags Benefactors Addresses
// @Tags Address
// @Accept json
// @Produce json
// @Success 200 {object} param.GetAllAddressesResponse
// @Failure 400 {string} "Bad request"
// @Security AuthBearerBenefactor
// @Router /benefactors/addresses [get].
// @Router /address/ [get].
func (h Handler) GetAddresses(c echo.Context) error {
var req param.GetAllAddressesRequest

View File

@ -10,12 +10,12 @@ import (
// GetAllCities godoc
// @Summary Get all cities
// @Tags Benefactors Addresses
// @Tags Address
// @Accept json
// @Produce json
// @Success 200 {object} addressparam.GetAllCitiesResponse
// @Failure 400 {string} "Bad request"
// @Router /benefactors/addresses/cities [get].
// @Router /address/cities [get].
func (h Handler) GetAllCities(c echo.Context) error {
var req addressparam.GetAllCitiesRequest

View File

@ -10,12 +10,12 @@ import (
// GetAllProvinces godoc
// @Summary Get all provinces
// @Tags Benefactors Addresses
// @Tags Address
// @Accept json
// @Produce json
// @Success 200 {object} addressparam.GetAllProvincesResponse
// @Failure 400 {string} "Bad request"
// @Router /benefactors/addresses/provinces [get].
// @Router /address/provinces [get].
func (h Handler) GetAllProvinces(c echo.Context) error {
var req addressparam.GetAllProvincesRequest

View File

@ -7,18 +7,18 @@ import (
)
func (h Handler) SetRoutes(e *echo.Echo) {
r := e.Group("/benefactors/addresses")
r := e.Group("/address")
r.GET("/provinces", h.GetAllProvinces)
r.GET("/cities", h.GetAllCities)
r.POST("", h.AddAddress, middleware.Auth(h.authSvc),
r.POST("/", h.AddAddress, middleware.Auth(h.authSvc),
middleware.BenefactorAuthorization(entity.UserBenefactorRole))
r.GET("/:id", h.GetAddress, middleware.Auth(h.authSvc),
middleware.BenefactorAuthorization(entity.UserBenefactorRole))
r.GET("", h.GetAddresses, middleware.Auth(h.authSvc),
r.GET("/", h.GetAddresses, middleware.Auth(h.authSvc),
middleware.BenefactorAuthorization(entity.UserBenefactorRole))
r.DELETE("/:id", h.DeleteAddress, middleware.Auth(h.authSvc),
middleware.BenefactorAuthorization(entity.UserBenefactorRole))
r.PUT("/:id", h.UpdateAddress, middleware.Auth(h.authSvc),
r.PATCH("/:id", h.UpdateAddress, middleware.Auth(h.authSvc),
middleware.BenefactorAuthorization(entity.UserBenefactorRole))
}

View File

@ -10,8 +10,8 @@ import (
)
// UpdateAddress godoc
// @Summary Update benefactor address
// @Tags Benefactors Addresses
// @Summary Edit benefactor address
// @Tags Address
// @Accept json
// @Produce json
// @Param id path int true "Address ID"
@ -19,7 +19,7 @@ import (
// @Success 204
// @Failure 400 {string} "Bad request"
// @Security AuthBearerBenefactor
// @Router /benefactors/addresses/{id} [put].
// @Router /address/{id} [patch].
func (h Handler) UpdateAddress(c echo.Context) error {
var req param.UpdateAddressRequest
if bErr := c.Bind(&req); bErr != nil {

View File

@ -11,13 +11,13 @@ import (
// loginOrRegister godoc
// @Summary Login or register a benefactor
// @Description This endpoint is used to authenticate an existing benefactor account or register a new one.
// @Tags Benefactors
// @Tags Benefactor
// @Accept json
// @Produce json
// @Param Request body benefactoreparam.LoginOrRegisterRequest true "Login or register request details"
// @Success 200 {object} benefactoreparam.LoginOrRegisterResponse
// @Failure 400 {string} "Bad request"
// @Router /benefactors/login-register [post].
// @Router /benefactor/login-register [post].
func (h Handler) loginOrRegister(c echo.Context) error {
var req benefactoreparam.LoginOrRegisterRequest

View File

@ -1,36 +0,0 @@
package benefactorhandler
import (
"net/http"
benefactorparam "git.gocasts.ir/ebhomengo/niki/param/benefactor/benefactor"
httpmsg "git.gocasts.ir/ebhomengo/niki/pkg/http_msg"
"github.com/labstack/echo/v4"
)
// RefreshAccess godoc
// @Summary Get a new access token by providing your refresh token
// @Tags Benefactors
// @Accept json
// @Produce json
// @Param Request body benefactorparam.RefreshAccessRequest true "Refresh access token request body"
// @Success 200 {object} benefactorparam.RefreshAccessResponse
// @Failure 400 {string} "Bad Request"
// @Failure 500 {string} "something went wrong"
// @Router /benefactors/refresh-access [post].
func (h Handler) RefreshAccess(c echo.Context) error {
var req benefactorparam.RefreshAccessRequest
if err := c.Bind(&req); err != nil {
return echo.NewHTTPError(http.StatusBadRequest)
}
resp, err := h.benefactorSvc.RefreshAccess(c.Request().Context(), req)
if err != nil {
msg, code := httpmsg.Error(err)
return echo.NewHTTPError(code, msg)
}
return c.JSON(http.StatusOK, resp)
}

View File

@ -5,9 +5,8 @@ import (
)
func (h Handler) SetRoutes(e *echo.Echo) {
r := e.Group("/benefactors")
r := e.Group("/benefactor")
r.POST("/send-otp", h.SendOtp)
r.POST("/login-register", h.loginOrRegister)
r.POST("/refresh-access", h.RefreshAccess)
}

View File

@ -11,13 +11,13 @@ import (
// SendOtp godoc
// @Summary Send OTP to benefactor
// @Description This endpoint sends an OTP to the benefactor's phone number for verification purposes.
// @Tags Benefactors
// @Tags Benefactor
// @Accept json
// @Produce json
// @Param Request body benefactoreparam.SendOtpRequest true "Send OTP request details"
// @Success 200 {object} benefactoreparam.SendOtpResponse
// @Failure 400 {string} "Bad request"
// @Router /benefactors/send-otp [post].
// @Router /benefactor/send-otp [post].
func (h Handler) SendOtp(c echo.Context) error {
var req benefactoreparam.SendOtpRequest

View File

@ -4,7 +4,6 @@ import (
"net/http"
param "git.gocasts.ir/ebhomengo/niki/param/benefactor/kind_box"
"git.gocasts.ir/ebhomengo/niki/pkg/claim"
httpmsg "git.gocasts.ir/ebhomengo/niki/pkg/http_msg"
echo "github.com/labstack/echo/v4"
)
@ -12,21 +11,19 @@ import (
// Get godoc
// @Summary Get a specific kind box for a benefactor
// @Description This endpoint retrieves a specific kind box associated with an authenticated benefactor.
// @Tags Benefactors KindBoxes
// @Tags KindBox
// @Accept json
// @Produce json
// @Param id path int true "Kind box ID"
// @Success 200 {object} param.KindBoxGetResponse
// @Failure 400 {string} "Bad request"
// @Security AuthBearerBenefactor
// @Router /benefactors/kindboxes/{id} [get].
// @Router /benefactor/kindboxes/{id} [get].
func (h Handler) Get(c echo.Context) error {
var req param.KindBoxGetRequest
if bErr := c.Bind(&req); bErr != nil {
return echo.NewHTTPError(http.StatusBadRequest)
}
claims := claim.GetClaimsFromEchoContext(c)
req.BenefactorID = claims.UserID
resp, sErr := h.benefactorKindBoxSvc.Get(c.Request().Context(), req)
if sErr != nil {

View File

@ -13,11 +13,12 @@ import (
// GetAll godoc
// @Summary Get all KindBoxes by benefactor
// @Description Retrieves a list of all KindBoxes with filtering, sorting, and pagination options
// @Tags Benefactors KindBoxes
// @Tags KindBox
// @Accept json
// @Produce json
// @Param filter_id query int false "Filter by ID"
// @Param filter_kind_box_req_id query int false "Filter by KindBox request ID"
// @Param filter_benefactor_id query int false "Filter by benefactor ID"
// @Param filter_kind_box_type query string false "Filter by KindBox type" Enums(on-table,cylindrical,stand-up)
// @Param filter_amount query int false "Filter by amount"
// @Param filter_serial_number query string false "Filter by serial number"
@ -39,7 +40,7 @@ import (
// @Success 200 {object} param.KindBoxGetAllResponse
// @Failure 400 {string} "Bad request"
// @Security AuthBearerBenefactor
// @Router /benefactors/kindboxes [get].
// @Router /benefactor/kindboxes [get].
func (h Handler) GetAll(c echo.Context) error {
var req param.KindBoxGetAllRequest
@ -48,8 +49,7 @@ func (h Handler) GetAll(c echo.Context) error {
}
req.Filter = queryparam.GetFilterParams(c)
req.BenefactorId = claim.GetClaimsFromEchoContext(c).UserID
req.Filter["benefactor_id"] = claim.GetClaimsFromEchoContext(c).UserID
resp, sErr := h.benefactorKindBoxSvc.GetAll(c.Request().Context(), req)
if sErr != nil {
msg, code := httpmsg.Error(sErr)

View File

@ -12,7 +12,7 @@ import (
// RegisterEmptyingRequest godoc
// @Summary Register a new emptying request for a kind box by benefactor
// @Tags Benefactors KindBoxes
// @Tags Benefactor
// @Accept json
// @Produce json
// @Param id path int true "KindBox ID"
@ -20,7 +20,7 @@ import (
// @Success 204 {string} "No content"
// @Failure 400 {string} "Bad request"
// @Security AuthBearerBenefactor
// @Router /benefactors/kindboxes/{id}/emptying-requests [patch].
// @Router /benefactor/kindboxes/{id}/emptying-requests [patch].
func (h Handler) RegisterEmptyingRequest(c echo.Context) error {
var req param.KindBoxRegisterEmptyingRequest
if bErr := c.Bind(&req); bErr != nil {
@ -44,7 +44,7 @@ func (h Handler) RegisterEmptyingRequest(c echo.Context) error {
}
go h.notificationSvc.KindBoxRegisteredEmptyingRequest(params.NotificationKindBoxRegisteredEmptyingRequest{
KindBoxID: resp.Data.ID,
KindBoxID: resp.ID,
})
return c.JSON(http.StatusNoContent, nil)

View File

@ -7,7 +7,7 @@ import (
)
func (h Handler) SetRoutes(e *echo.Echo) {
r := e.Group("/benefactors/kindboxes")
r := e.Group("/benefactor/kindboxes")
r.Use(
middleware.Auth(h.authSvc),

View File

@ -13,14 +13,14 @@ import (
// Add godoc
// @Summary Add a new kind box request for a benefactor
// @Tags Benefactors KindBoxReqs
// @Tags KindBoxReq
// @Accept json
// @Produce json
// @Param Request body param.KindBoxReqAddRequest true "New kind box request details"
// @Success 200 {object} param.KindBoxReqAddResponse
// @Failure 400 {string} "Bad request"
// @Security AuthBearerBenefactor
// @Router /benefactors/kindboxreqs [post].
// @Router /benefactor/kindboxreqs/ [post].
func (h Handler) Add(c echo.Context) error {
req := param.KindBoxReqAddRequest{}
if err := c.Bind(&req); err != nil {
@ -46,7 +46,7 @@ func (h Handler) Add(c echo.Context) error {
}
go h.notificationSvc.KindBoxReqAdded(params.NotificationKindBoxReqAdded{
KindBoxReqID: resp.Data.ID,
KindBoxReqID: resp.KindBoxReq.ID,
})
return c.JSON(http.StatusCreated, resp)

View File

@ -9,17 +9,17 @@ import (
"github.com/labstack/echo/v4"
)
// Delete godoc
// @Summary Delete kindboxreq by benefactor
// delete godoc
// @Summary delete kindboxreq by benefactor
// @Description This endpoint is used to delete benefactor's kindboxreq at pending status
// @Tags Benefactors KindBoxReqs
// @Tags KindBoxReq
// @Accept json
// @Produce json
// @Param id path int true "Kind box request ID"
// @Success 200 {object} param.KindBoxReqDeleteResponse
// @Failure 400 {string} "Bad request"
// @Security AuthBearerBenefactor
// @Router /benefactors/kindboxreqs/{id} [delete].
// @Router /benefactor/kindboxreqs/{id} [delete].
func (h Handler) Delete(c echo.Context) error {
req := param.KindBoxReqDeleteRequest{}
if bErr := echo.PathParamsBinder(c).Uint("id", &req.KindBoxReqID).BindError(); bErr != nil {

View File

@ -11,14 +11,14 @@ import (
// Get godoc
// @Summary Get a kind box request for a benefactor
// @Tags Benefactors KindBoxReqs
// @Tags KindBoxReq
// @Accept json
// @Produce json
// @Param id path int true "Kind box request ID"
// @Success 200 {object} param.KindBoxReqGetResponse
// @Failure 400 {string} "Bad request"
// @Security AuthBearerBenefactor
// @Router /benefactors/kindboxreqs/{id} [get].
// @Router /benefactor/kindboxreqs/{id} [get].
func (h Handler) Get(c echo.Context) error {
var req param.KindBoxReqGetRequest
if bErr := echo.PathParamsBinder(c).Uint("id", &req.KindBoxReqID).BindError(); bErr != nil {

View File

@ -13,10 +13,11 @@ import (
// GetAll godoc
// @Summary Get all KindBox requests
// @Description Retrieves a list of all KindBox requests with filtering, sorting, and pagination options
// @Tags Benefactors KindBoxReqs
// @Tags KindBoxReq
// @Accept json
// @Produce json
// @Param filter_id query int false "Filter by ID"
// @Param filter_benefactor_id query int false "Filter by benefactor ID"
// @Param filter_kind_box_type query entity.KindBoxType false "Filter by KindBox type" Format(enum)
// @Param filter_status query string false "Filter by KindBoxReq Status" Enums(pending,accepted,assigned-sender-agent,rejected,delivered)
// @Param filter_count_requested query int false "Filter by count requested"
@ -31,7 +32,7 @@ import (
// @Success 200 {object} param.GetAllResponse
// @Failure 400 {string} "Bad request"
// @Security AuthBearerBenefactor
// @Router /benefactors/kindboxreqs [get].
// @Router /benefactor/kindboxreqs/ [get].
func (h Handler) GetAll(c echo.Context) error {
var req param.GetAllRequest
@ -40,7 +41,7 @@ func (h Handler) GetAll(c echo.Context) error {
}
req.Filter = queryparam.GetFilterParams(c)
req.BenefactorId = claim.GetClaimsFromEchoContext(c).UserID
req.Filter["benefactor_id"] = claim.GetClaimsFromEchoContext(c).UserID
resp, sErr := h.benefactorKindBoxReqSvc.GetAll(c.Request().Context(), req)
if sErr != nil {

View File

@ -7,16 +7,16 @@ import (
)
func (h Handler) SetRoutes(e *echo.Echo) {
r := e.Group("/benefactors/kindboxreqs")
r := e.Group("/benefactor/kindboxreqs")
r.Use(
middleware.Auth(h.authSvc),
middleware.BenefactorAuthorization(entity.UserBenefactorRole),
)
r.POST("", h.Add)
r.POST("/", h.Add)
r.GET("/:id", h.Get)
r.DELETE("/:id", h.Delete)
r.GET("", h.GetAll)
r.GET("/", h.GetAll)
r.PUT("/:id", h.Update)
}

View File

@ -11,7 +11,7 @@ import (
// Update godoc
// @Summary Update kind box request by benefactor
// @Tags Benefactors KindBoxReqs
// @Tags KindBoxReq
// @Accept json
// @Produce json
// @Param id path int true "KindBoxReq ID"
@ -23,7 +23,7 @@ import (
// @Failure 422 {object} httpmsg.ErrorResponse
// @Failure 500 {string} "something went wrong"
// @Security AuthBearerBenefactor
// @Router /benefactors/kindboxreqs/{id} [put].
// @Router /benefactor/kindboxreqs/{id} [put].
func (h Handler) Update(c echo.Context) error {
var req param.KindBoxReqUpdateRequest
if bErr := c.Bind(&req); bErr != nil {

View File

@ -1,31 +0,0 @@
package benefactorrefertimehandler
import (
"net/http"
refertimeparam "git.gocasts.ir/ebhomengo/niki/param/benefactor/refer_time"
httpmsg "git.gocasts.ir/ebhomengo/niki/pkg/http_msg"
"github.com/labstack/echo/v4"
)
// GetAll godoc
// @Summary Get all refer times
// @Tags Benefactors ReferTimes
// @Accept json
// @Produce json
// @Success 200 {object} benefactorrefertimeparam.GetAllReferTimeResponse
// @Failure 400 {string} "Bad request"
// @Security AuthBearerBenefactor
// @Router /benefactors/refer-times [get].
func (h Handler) GetAll(c echo.Context) error {
var req refertimeparam.GetAllReferTimeRequest
listReferTimes, err := h.benefactorReferTimeSvc.GetAll(c.Request().Context(), req)
if err != nil {
msg, code := httpmsg.Error(err)
return echo.NewHTTPError(code, msg)
}
return c.JSON(http.StatusOK, listReferTimes)
}

View File

@ -1,20 +0,0 @@
package benefactorrefertimehandler
import (
authservice "git.gocasts.ir/ebhomengo/niki/service/auth"
benefactorrefertimeservice "git.gocasts.ir/ebhomengo/niki/service/benefactor/refer_time"
)
type Handler struct {
authSvc authservice.Service
benefactorReferTimeSvc benefactorrefertimeservice.Service
}
func New(authSvc authservice.Service,
benefactorReferTimeSvc benefactorrefertimeservice.Service,
) Handler {
return Handler{
authSvc: authSvc,
benefactorReferTimeSvc: benefactorReferTimeSvc,
}
}

View File

@ -1,18 +0,0 @@
package benefactorrefertimehandler
import (
"git.gocasts.ir/ebhomengo/niki/delivery/http_server/middleware"
"git.gocasts.ir/ebhomengo/niki/entity"
"github.com/labstack/echo/v4"
)
func (h Handler) SetRoutes(e *echo.Echo) {
r := e.Group("/benefactors/refer-times")
r.Use(
middleware.Auth(h.authSvc),
middleware.BenefactorAuthorization(entity.UserBenefactorRole),
)
r.GET("", h.GetAll)
}

View File

@ -1,43 +0,0 @@
//go:build end2end
// +build end2end
package end2end
import (
"context"
"fmt"
"net/http"
"net/http/httptest"
"testing"
"git.gocasts.ir/ebhomengo/niki/delivery/http_server/end2end/setup"
adminserviceparam "git.gocasts.ir/ebhomengo/niki/param/admin/admin"
"github.com/labstack/echo/v4"
"github.com/stretchr/testify/assert"
)
func TestAdmin_KindBox_Get(t *testing.T) {
teardown := setup.SeedMariaDB(testContainer.GetMariaDBConfig())
t.Cleanup(teardown)
// Get token
lRes, err := services.AdminSvc.LoginWithPhoneNumber(context.Background(), adminserviceparam.LoginWithPhoneNumberRequest{
PhoneNumber: "09384664402",
Password: "Abc123456",
})
if err != nil {
t.Fatalf("could not login: %s", err)
}
// Create a request
req := httptest.NewRequest(http.MethodGet, "/admin/kindboxes/1", nil)
req.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON)
req.Header.Set(echo.HeaderAuthorization, fmt.Sprintf("Bearer %s", lRes.Tokens.AccessToken))
rec := httptest.NewRecorder()
// Serve the request
testServer.Serve(rec, req)
// Assertions
assert.Equal(t, http.StatusOK, rec.Code)
}

View File

@ -0,0 +1,194 @@
//go:build end2end
// +build end2end
package end2end
import (
"context"
"encoding/json"
"fmt"
"net/http"
"net/http/httptest"
"strings"
"testing"
"git.gocasts.ir/ebhomengo/niki/delivery/http_server/end2end/setup"
httpmsg "git.gocasts.ir/ebhomengo/niki/pkg/http_msg"
adminserviceparam "git.gocasts.ir/ebhomengo/niki/param/admin/admin"
param "git.gocasts.ir/ebhomengo/niki/param/admin/kind_box"
"github.com/labstack/echo/v4"
"github.com/stretchr/testify/assert"
)
// Utility function to log in as an admin with dynamic credentials
func loginAsAdmin(t *testing.T, phoneNumber, password string) (*adminserviceparam.LoginWithPhoneNumberResponse, error) {
lRes, err := services.AdminSvc.LoginWithPhoneNumber(context.Background(), adminserviceparam.LoginWithPhoneNumberRequest{
PhoneNumber: phoneNumber,
Password: password,
})
if err != nil {
t.Fatalf("could not login: %s", err)
return nil, err
}
return &lRes, nil // Return address of lRes
}
func TestAdmin_KindBox_Enumerate(t *testing.T) {
teardown := setup.SeedMariaDB(testContainer.GetMariaDBConfig())
t.Cleanup(teardown)
lRes, err := loginAsAdmin(t, "09384664401", "Abc123456")
if err != nil {
return
}
reqBody := `{
"amount": 5
}`
req := httptest.NewRequest(http.MethodPatch, "/admin/kindboxes/1/enumerate", strings.NewReader(reqBody))
req.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON)
req.Header.Set(echo.HeaderAuthorization, fmt.Sprintf("Bearer %s", lRes.Tokens.AccessToken))
rec := httptest.NewRecorder()
testServer.Serve(rec, req)
assert.Equal(t, http.StatusNoContent, rec.Code)
}
func TestAdmin_KindBox_Enumerate_MissingAmount(t *testing.T) {
teardown := setup.SeedMariaDB(testContainer.GetMariaDBConfig())
t.Cleanup(teardown)
lRes, err := loginAsAdmin(t, "09384664401", "Abc123456")
if err != nil {
return
}
reqBody := `{}`
req := httptest.NewRequest(http.MethodPatch, "/admin/kindboxes/1/enumerate", strings.NewReader(reqBody))
req.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON)
req.Header.Set(echo.HeaderAuthorization, fmt.Sprintf("Bearer %s", lRes.Tokens.AccessToken))
rec := httptest.NewRecorder()
testServer.Serve(rec, req)
assert.Equal(t, http.StatusUnprocessableEntity, rec.Code)
}
func TestAdmin_KindBox_Enumerate_NegativeAmount(t *testing.T) {
teardown := setup.SeedMariaDB(testContainer.GetMariaDBConfig())
t.Cleanup(teardown)
lRes, err := loginAsAdmin(t, "09384664401", "Abc123456")
if err != nil {
return
}
reqBody := `{
"amount": -5
}`
req := httptest.NewRequest(http.MethodPatch, "/admin/kindboxes/1/enumerate", strings.NewReader(reqBody))
req.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON)
req.Header.Set(echo.HeaderAuthorization, fmt.Sprintf("Bearer %s", lRes.Tokens.AccessToken))
rec := httptest.NewRecorder()
testServer.Serve(rec, req)
assert.Equal(t, http.StatusBadRequest, rec.Code)
}
func TestAdmin_KindBox_Enumeration_Forbidden(t *testing.T) {
lRes, err := loginAsAdmin(t, "09384664403", "Abc123456")
if err != nil {
return
}
req := httptest.NewRequest(http.MethodGet, "/admin/kindboxes/1/enumerate", nil)
req.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON)
req.Header.Set(echo.HeaderAuthorization, fmt.Sprintf("Bearer %s", lRes.Tokens.AccessToken))
rec := httptest.NewRecorder()
testServer.Serve(rec, req)
assert.Equal(t, http.StatusForbidden, rec.Code)
var response httpmsg.ErrorResponse
err = json.NewDecoder(rec.Body).Decode(&response)
if err != nil {
t.Fatalf("could not decode response: %s", err)
}
}
func TestAdmin_KindBox_GetAll(t *testing.T) {
teardown := setup.SeedMariaDB(testContainer.GetMariaDBConfig())
t.Cleanup(teardown)
lRes, err := loginAsAdmin(t, "09384664401", "Abc123456")
if err != nil {
return
}
req := httptest.NewRequest(http.MethodGet, "/admin/kindboxes?page_number=1&page_size=10&sort=created_at&order=desc&filter=status:active", nil)
req.Header.Set(echo.HeaderAuthorization, fmt.Sprintf("Bearer %s", lRes.Tokens.AccessToken))
rec := httptest.NewRecorder()
testServer.Serve(rec, req)
assert.Equal(t, http.StatusOK, rec.Code)
var response param.KindBoxGetAllResponse
err = json.NewDecoder(rec.Body).Decode(&response)
if err != nil {
t.Fatalf("could not decode response: %s", err)
}
assert.NotEmpty(t, response.AllKindBox, "expected kind boxes in response")
assert.Equal(t, uint(1), response.Pagination.PageNumber, "expected page 1")
assert.Equal(t, uint(10), response.Pagination.PageSize, "expected limit 10")
assert.Empty(t, response.FieldErrors, "expected no field errors")
}
func TestAdmin_KindBox_AssignReceiver(t *testing.T) {
teardown := setup.SeedMariaDB(testContainer.GetMariaDBConfig())
t.Cleanup(teardown)
lRes, err := loginAsAdmin(t, "09384664401", "Abc123456")
if err != nil {
return
}
reqBody := `{
"receiver_agent_id": 4
}`
req := httptest.NewRequest(http.MethodPatch, "/admin/kindboxes/assign-receiver-agent/1", strings.NewReader(reqBody))
req.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON)
req.Header.Set(echo.HeaderAuthorization, fmt.Sprintf("Bearer %s", lRes.Tokens.AccessToken))
rec := httptest.NewRecorder()
testServer.Serve(rec, req)
assert.Equal(t, http.StatusUnprocessableEntity, rec.Code)
}
func TestAdmin_KindBox_Get(t *testing.T) {
teardown := setup.SeedMariaDB(testContainer.GetMariaDBConfig())
t.Cleanup(teardown)
lRes, err := loginAsAdmin(t, "09384664401", "Abc123456")
if err != nil {
return
}
req := httptest.NewRequest(http.MethodGet, "/admin/kindboxes/1", nil)
req.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON)
req.Header.Set(echo.HeaderAuthorization, fmt.Sprintf("Bearer %s", lRes.Tokens.AccessToken))
rec := httptest.NewRecorder()
testServer.Serve(rec, req)
assert.Equal(t, http.StatusOK, rec.Code)
}

View File

@ -1,193 +0,0 @@
//go:build end2end
package end2end
import (
"context"
"encoding/json"
"fmt"
"net/http"
"testing"
"git.gocasts.ir/ebhomengo/niki/delivery/http_server/end2end/setup"
addressparam "git.gocasts.ir/ebhomengo/niki/param/benefactor/address"
errmsg "git.gocasts.ir/ebhomengo/niki/pkg/err_msg"
httpmsg "git.gocasts.ir/ebhomengo/niki/pkg/http_msg"
"github.com/stretchr/testify/suite"
)
type BenefactorAddressTestSuit struct {
suite.Suite
benefactorPhone string
benefactorID uint
addressID uint
getAllExpected map[string]interface{}
getExpected addressparam.GetAddressResponse
createData addressparam.BenefactorAddAddressRequest
updateData addressparam.UpdateAddressRequest
teardown func()
}
func TestBenefactorAddressTestSuit(t *testing.T) {
suite.Run(t, new(BenefactorAddressTestSuit))
}
// SetupTest runs before each test in the suite
func (suite *BenefactorAddressTestSuit) SetupTest() {
teardown := setup.SeedMariaDB(testContainer.GetMariaDBConfig())
suite.T().Cleanup(teardown)
suite.benefactorPhone = "09384664404"
suite.benefactorID = 1
suite.addressID = 1
suite.getAllExpected = map[string]interface{}{
"count": 1,
}
suite.createData = addressparam.BenefactorAddAddressRequest{
PostalCode: "3719655861",
Address: "create shiraz kaf sharo",
Lat: 29.62949,
Lon: 52.497287,
CityID: 194,
Name: "create shiraz",
}
suite.updateData = addressparam.UpdateAddressRequest{
PostalCode: "3719655861",
Address: "update shiraz kaf sharo",
Lat: 29.62949,
Lon: 52.497287,
CityID: 194,
Name: "update shiraz",
}
}
func (suite *BenefactorAddressTestSuit) TestBenefactorAddressGet() {
token := LoginBenefactor(suite.benefactorPhone)
url := fmt.Sprintf("/benefactors/addresses/%d", suite.addressID)
suite.T().Run("Success", func(t *testing.T) {
responseRecord := CreateRequest("GET", url, token, nil)
suite.Require().Equal(http.StatusOK, responseRecord.Code)
var response addressparam.GetAddressResponse
err := json.NewDecoder(responseRecord.Body).Decode(&response)
suite.Require().NoError(err, "could not decode response body")
address, sErr := services.BenefactorAddressSvc.Get(context.Background(),
addressparam.GetAddressRequest{
AddressID: suite.addressID,
BenefactorID: suite.benefactorID,
})
suite.Require().NoError(sErr, "failed to get benefactor address")
suite.Require().Equal(address.Data.PostalCode, response.Data.PostalCode)
suite.Require().Equal(address.Data.Address, response.Data.Address)
suite.Require().Equal(address.Data.Name, response.Data.Name)
suite.Require().Equal(address.Data.CityID, response.Data.CityID)
})
suite.T().Run("Failure_Unauthorized", func(t *testing.T) {
responseRecord := CreateRequest("GET", url, "", nil) // No token provided
suite.Require().Equal(http.StatusUnauthorized, responseRecord.Code)
})
}
func (suite *BenefactorAddressTestSuit) TestBenefactorAddressGetAll() {
token := LoginBenefactor(suite.benefactorPhone)
url := fmt.Sprintf("/benefactors/addresses")
suite.T().Run("Success", func(t *testing.T) {
responseRecord := CreateRequest("GET", url, token, nil)
suite.Require().Equal(http.StatusOK, responseRecord.Code)
var response addressparam.GetAllAddressesResponse
err := json.NewDecoder(responseRecord.Body).Decode(&response)
suite.Require().NoError(err, "could not decode response body")
suite.Require().Equal(suite.getAllExpected["count"], len(response.Data))
})
suite.T().Run("Failure_Unauthorized", func(t *testing.T) {
responseRecord := CreateRequest("GET", url, "", nil) // No token provided
suite.Require().Equal(http.StatusUnauthorized, responseRecord.Code)
})
}
func (suite *BenefactorAddressTestSuit) TestBenefactorAddressCreate() {
token := LoginBenefactor(suite.benefactorPhone)
url := fmt.Sprintf("/benefactors/addresses")
suite.T().Run("Success", func(t *testing.T) {
responseRecord := CreateRequest("POST", url, token, suite.createData)
suite.Require().Equal(http.StatusCreated, responseRecord.Code)
var response addressparam.BenefactorAddAddressResponse
err := json.NewDecoder(responseRecord.Body).Decode(&response)
suite.Require().NoError(err, "could not decode response body")
suite.Require().Equal(suite.benefactorID, response.Data.BenefactorID)
suite.Require().Equal(suite.createData.Address, response.Data.Address)
suite.Require().Equal(suite.createData.PostalCode, response.Data.PostalCode)
suite.Require().Equal(suite.createData.Name, response.Data.Name)
suite.Require().Equal(suite.createData.CityID, response.Data.CityID)
})
suite.T().Run("Failure_BadRequest", func(t *testing.T) {
responseRecord := CreateRequest("POST", url, token, nil) // No data provided
suite.Require().Equal(http.StatusUnprocessableEntity, responseRecord.Code)
})
}
func (suite *BenefactorAddressTestSuit) TestBenefactorAddressUpdate() {
token := LoginBenefactor(suite.benefactorPhone)
url := fmt.Sprintf("/benefactors/addresses/%d", suite.addressID)
suite.T().Run("Success", func(t *testing.T) {
responseRecord := CreateRequest("PUT", url, token, suite.updateData)
suite.Require().Equal(http.StatusNoContent, responseRecord.Code)
updatedAddress, sErr := services.BenefactorAddressSvc.Get(context.Background(),
addressparam.GetAddressRequest{
AddressID: suite.addressID,
BenefactorID: suite.benefactorID,
})
suite.Require().NoError(sErr, "failed to get benefactor address")
suite.Require().Equal(suite.updateData.PostalCode, updatedAddress.Data.PostalCode)
suite.Require().Equal(suite.updateData.Address, updatedAddress.Data.Address)
suite.Require().Equal(suite.updateData.Name, updatedAddress.Data.Name)
suite.Require().Equal(suite.updateData.CityID, updatedAddress.Data.CityID)
})
suite.T().Run("Failure_Unauthorized", func(t *testing.T) {
responseRecord := CreateRequest("PUT", url, "", suite.updateData) // No token provided
suite.Require().Equal(http.StatusUnauthorized, responseRecord.Code)
})
}
// TestBenefactorAddressDelete tests the DELETE /address/:id endpoint
func (suite *BenefactorAddressTestSuit) TestBenefactorAddressDelete() {
token := LoginBenefactor(suite.benefactorPhone)
url := fmt.Sprintf("/benefactors/addresses/%d", suite.addressID)
suite.T().Run("Success", func(t *testing.T) {
responseRecord := CreateRequest("DELETE", url, token, nil)
suite.Require().Equal(http.StatusNoContent, responseRecord.Code)
_, err := services.BenefactorAddressSvc.Get(context.Background(),
addressparam.GetAddressRequest{
AddressID: suite.addressID,
BenefactorID: suite.benefactorID,
},
)
message, code := httpmsg.Error(err)
suite.Require().Error(err)
suite.Equal(http.StatusNotFound, code)
suite.Equal(errmsg.ErrorMsgNotFound, message)
})
suite.T().Run("Failure_Unauthorized", func(t *testing.T) {
responseRecord := CreateRequest("DELETE", url, "", nil) // No token provided
suite.Require().Equal(http.StatusUnauthorized, responseRecord.Code)
})
}

View File

@ -1,104 +0,0 @@
//go:build end2end
package end2end
import (
"context"
"encoding/json"
"fmt"
"net/http"
"testing"
"git.gocasts.ir/ebhomengo/niki/delivery/http_server/end2end/setup"
benefactorkindboxparam "git.gocasts.ir/ebhomengo/niki/param/benefactor/kind_box"
"github.com/stretchr/testify/suite"
)
type BenefactorKindBoxTestSuite struct {
suite.Suite
benefactorPhone string
benefactorID uint
kindBoxID uint
kindBboxGetAllExpected map[string]interface{}
kindBoxGetExpected benefactorkindboxparam.KindBoxGetResponse
}
func TestBenefactorKindBoxTestSuite(t *testing.T) {
suite.Run(t, new(BenefactorKindBoxTestSuite))
}
func (suite *BenefactorKindBoxTestSuite) SetupTest() {
teardown := setup.SeedMariaDB(testContainer.GetMariaDBConfig())
suite.T().Cleanup(teardown)
suite.benefactorPhone = "09384664404"
suite.benefactorID = 1
suite.kindBoxID = 1
suite.kindBboxGetAllExpected = map[string]interface{}{
"count": 1,
}
}
// Test for GET /benefactor/kindboxes (Get All Kind Boxes)
func (suite *BenefactorKindBoxTestSuite) TestBenefactorKindBoxGetAll() {
suite.Run("Success", func() {
token := LoginBenefactor(suite.benefactorPhone)
url := fmt.Sprintf("/benefactors/kindboxes")
responseRecord := CreateRequest("GET", url, token, nil)
suite.Require().Equal(http.StatusOK, responseRecord.Code)
var response benefactorkindboxparam.KindBoxGetAllResponse
err := json.NewDecoder(responseRecord.Body).Decode(&response)
suite.Require().NoError(err, "could not decode response")
suite.Require().Equal(suite.kindBboxGetAllExpected["count"], len(response.Data))
})
suite.Run("Failure_Unauthorized", func() {
url := fmt.Sprintf("/benefactors/kindboxes")
responseRecord := CreateRequest("GET", url, "invalid_token", nil)
suite.Require().Equal(http.StatusUnauthorized, responseRecord.Code)
})
}
// Test for GET /benefactor/kindboxes/:id (Get Single Kind Box)
func (suite *BenefactorKindBoxTestSuite) TestBenefactorKindBoxGet() {
suite.Run("Success", func() {
token := LoginBenefactor(suite.benefactorPhone)
url := fmt.Sprintf("/benefactors/kindboxes/%d", suite.kindBoxID)
responseRecord := CreateRequest("GET", url, token, nil)
suite.Require().Equal(http.StatusOK, responseRecord.Code)
var response benefactorkindboxparam.KindBoxGetResponse
err := json.NewDecoder(responseRecord.Body).Decode(&response)
suite.Require().NoError(err, "could not decode response body")
kindBox, sErr := services.BenefactorKindBoxSvc.Get(context.Background(),
benefactorkindboxparam.KindBoxGetRequest{
BenefactorID: suite.benefactorID,
KindBoxID: suite.kindBoxID,
})
suite.Require().NoError(sErr, "failed to get benefactor kind box")
suite.Require().Equal(kindBox.Data.ID, response.Data.ID)
suite.Require().Equal(kindBox.Data.KindBoxReqID, response.Data.KindBoxReqID)
suite.Require().Equal(kindBox.Data.BenefactorID, response.Data.BenefactorID)
suite.Require().Equal(kindBox.Data.KindBoxType, response.Data.KindBoxType)
suite.Require().Equal(kindBox.Data.Amount, response.Data.Amount)
suite.Require().Equal(kindBox.Data.SerialNumber, response.Data.SerialNumber)
suite.Require().Equal(kindBox.Data.Status, response.Data.Status)
suite.Require().Equal(kindBox.Data.DeliverReferTimeID, response.Data.DeliverReferTimeID)
suite.Require().Equal(kindBox.Data.DeliverReferDate, response.Data.DeliverReferDate)
})
suite.Run("Failure_NotFound", func() {
token := LoginBenefactor(suite.benefactorPhone)
url := fmt.Sprintf("/benefactors/kindboxes/%d", 9999) // Non-existent ID
responseRecord := CreateRequest("GET", url, token, nil)
suite.Require().Equal(http.StatusUnprocessableEntity, responseRecord.Code)
})
suite.Run("Failure_Unauthorized", func() {
url := fmt.Sprintf("/benefactors/kindboxes/%d", suite.kindBoxID)
responseRecord := CreateRequest("GET", url, "invalid_token", nil)
suite.Require().Equal(http.StatusUnauthorized, responseRecord.Code)
})
}

View File

@ -1,206 +0,0 @@
//go:build end2end
package end2end
import (
"context"
"encoding/json"
"fmt"
"net/http"
"testing"
"time"
"git.gocasts.ir/ebhomengo/niki/delivery/http_server/end2end/setup"
"git.gocasts.ir/ebhomengo/niki/entity"
benefactorkindboxreqparam "git.gocasts.ir/ebhomengo/niki/param/benefactor/kind_box_req"
errmsg "git.gocasts.ir/ebhomengo/niki/pkg/err_msg"
httpmsg "git.gocasts.ir/ebhomengo/niki/pkg/http_msg"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/suite"
)
type BenefactorKindBoxReqsTestSuite struct {
suite.Suite
benefactorPhone string
benefactorID uint
kindBoxReqID uint
getAllExpected map[string]interface{}
createData benefactorkindboxreqparam.KindBoxReqAddRequest
updateData benefactorkindboxreqparam.KindBoxReqUpdateRequest
}
func TestBenefactorKindBoxReqsTestSuite(t *testing.T) {
suite.Run(t, new(BenefactorKindBoxReqsTestSuite))
}
func (suite *BenefactorKindBoxReqsTestSuite) SetupTest() {
teardown := setup.SeedMariaDB(testContainer.GetMariaDBConfig())
suite.T().Cleanup(teardown)
suite.benefactorPhone = "09384664404"
suite.benefactorID = uint(1)
suite.kindBoxReqID = uint(1)
suite.getAllExpected = map[string]interface{}{
"count": 5,
}
suite.createData = benefactorkindboxreqparam.KindBoxReqAddRequest{
KindBoxType: entity.KindBoxCylindrical,
DeliverAddressID: uint(1),
DeliverReferDate: time.Now().AddDate(0, 0, 7).UTC(),
DeliverReferTimeID: uint(1),
CountRequested: uint(5),
}
suite.updateData = benefactorkindboxreqparam.KindBoxReqUpdateRequest{
KindBoxType: entity.KindBoxCylindrical,
CountRequested: uint(10),
Description: "updated description",
DeliverReferTimeID: uint(1),
DeliverReferDate: time.Now().AddDate(0, 0, 7).UTC(),
DeliverAddressID: uint(1),
}
}
func (suite *BenefactorKindBoxReqsTestSuite) TestBenefactorKindBoxReqs_GetAll_Success() {
suite.Run("Success", func() {
token := LoginBenefactor(suite.benefactorPhone)
url := fmt.Sprintf("/benefactors/kindboxreqs")
responseRecord := CreateRequest(http.MethodGet, url, token, nil)
suite.Require().Equal(http.StatusOK, responseRecord.Code)
var response benefactorkindboxreqparam.GetAllResponse
err := json.NewDecoder(responseRecord.Body).Decode(&response)
suite.Require().NoError(err, "failed to decode response body")
assert.Equal(suite.T(), suite.getAllExpected["count"], len(response.Data))
})
suite.Run("Failure_Unauthorized", func() {
url := fmt.Sprintf("/benefactors/kindboxreqs")
responseRecord := CreateRequest(http.MethodGet, url, "invalid_token", nil)
suite.Require().Equal(http.StatusUnauthorized, responseRecord.Code)
})
}
func (suite *BenefactorKindBoxReqsTestSuite) TestBenefactorKindBoxReqs_Get_Success() {
suite.Run("Success", func() {
token := LoginBenefactor(suite.benefactorPhone)
url := fmt.Sprintf("/benefactors/kindboxreqs/%d", suite.kindBoxReqID)
responseRecord := CreateRequest(http.MethodGet, url, token, nil)
suite.Require().Equal(http.StatusOK, responseRecord.Code)
var response benefactorkindboxreqparam.KindBoxReqGetResponse
err := json.NewDecoder(responseRecord.Body).Decode(&response)
suite.Require().NoError(err, "failed to decode response body")
kinBoxReq, err := services.BenefactorKindBoxReqSvc.Get(context.Background(),
benefactorkindboxreqparam.KindBoxReqGetRequest{
BenefactorID: suite.benefactorID,
KindBoxReqID: suite.kindBoxReqID,
})
suite.Require().NoError(err, "failed to get kind box request")
assert.Equal(suite.T(), kinBoxReq.Data.KindBoxType, response.Data.KindBoxType)
assert.Equal(suite.T(), kinBoxReq.Data.CountRequested, response.Data.CountRequested)
assert.Equal(suite.T(), kinBoxReq.Data.Description, response.Data.Description)
assert.Equal(suite.T(), kinBoxReq.Data.DeliverReferTimeID, response.Data.DeliverReferTimeID)
})
suite.Run("Failure_NotFound", func() {
token := LoginBenefactor(suite.benefactorPhone)
url := fmt.Sprintf("/benefactors/kindboxreqs/%d", 9999) // Non-existent ID
responseRecord := CreateRequest(http.MethodGet, url, token, nil)
suite.Require().Equal(http.StatusNotFound, responseRecord.Code)
})
suite.Run("Failure_Unauthorized", func() {
url := fmt.Sprintf("/benefactors/kindboxreqs/%d", suite.kindBoxReqID)
responseRecord := CreateRequest(http.MethodGet, url, "invalid_token", nil)
suite.Require().Equal(http.StatusUnauthorized, responseRecord.Code)
})
}
func (suite *BenefactorKindBoxReqsTestSuite) TestBenefactorKindBoxReqs_Create_Success() {
suite.Run("Success", func() {
token := LoginBenefactor(suite.benefactorPhone)
url := fmt.Sprintf("/benefactors/kindboxreqs")
rec := CreateRequest(http.MethodPost, url, token, suite.createData)
suite.Require().Equal(http.StatusCreated, rec.Code)
var response benefactorkindboxreqparam.KindBoxReqAddResponse
err := json.NewDecoder(rec.Body).Decode(&response)
suite.Require().NoError(err, "failed to decode response body")
assert.Equal(suite.T(), suite.createData.KindBoxType, response.Data.KindBoxType)
assert.Equal(suite.T(), suite.createData.DeliverAddressID, response.Data.DeliverAddressID)
assert.Equal(suite.T(), suite.createData.DeliverReferDate, response.Data.DeliverReferDate)
assert.Equal(suite.T(), suite.createData.CountRequested, response.Data.CountRequested)
})
suite.Run("Failure_Unauthorized", func() {
url := fmt.Sprintf("/benefactors/kindboxreqs")
rec := CreateRequest(http.MethodPost, url, "invalid_token", suite.createData)
suite.Require().Equal(http.StatusUnauthorized, rec.Code)
})
}
func (suite *BenefactorKindBoxReqsTestSuite) TestBenefactorKindBoxReqs_Update_Success() {
suite.Run("Success", func() {
token := LoginBenefactor(suite.benefactorPhone)
url := fmt.Sprintf("/benefactors/kindboxreqs/%d", suite.kindBoxReqID)
rec := CreateRequest(http.MethodPut, url, token, suite.updateData)
suite.Require().Equal(http.StatusNoContent, rec.Code)
kindBoxReq, err := services.BenefactorKindBoxReqSvc.Get(context.Background(),
benefactorkindboxreqparam.KindBoxReqGetRequest{
BenefactorID: suite.benefactorID,
KindBoxReqID: suite.kindBoxReqID,
},
)
suite.Require().NoError(err, "failed to get kind box request")
assert.Equal(suite.T(), suite.updateData.CountRequested, kindBoxReq.Data.CountRequested)
assert.Equal(suite.T(), suite.updateData.Description, kindBoxReq.Data.Description)
assert.Equal(suite.T(), suite.updateData.DeliverReferTimeID, kindBoxReq.Data.DeliverReferTimeID)
assert.Equal(
suite.T(),
suite.updateData.DeliverReferDate.Format("2006-01-02"),
kindBoxReq.Data.DeliverReferDate.Format("2006-01-02"),
)
assert.Equal(suite.T(), suite.updateData.DeliverAddressID, kindBoxReq.Data.DeliverAddressID)
})
suite.Run("Failure_Unauthorized", func() {
url := fmt.Sprintf("/benefactors/kindboxreqs/%d", suite.kindBoxReqID)
rec := CreateRequest(http.MethodPut, url, "invalid_token", suite.updateData)
suite.Require().Equal(http.StatusUnauthorized, rec.Code)
})
}
func (suite *BenefactorKindBoxReqsTestSuite) TestBenefactorKindBoxReqs_Delete_Success() {
suite.Run("Success", func() {
token := LoginBenefactor(suite.benefactorPhone)
url := fmt.Sprintf("/benefactors/kindboxreqs/%d", suite.kindBoxReqID)
rec := CreateRequest(http.MethodDelete, url, token, nil)
suite.Require().Equal(http.StatusOK, rec.Code)
_, err := services.BenefactorKindBoxReqSvc.Get(context.Background(),
benefactorkindboxreqparam.KindBoxReqGetRequest{
BenefactorID: suite.benefactorID,
KindBoxReqID: suite.kindBoxReqID,
},
)
message, code := httpmsg.Error(err)
suite.Require().Error(err)
assert.Equal(suite.T(), http.StatusNotFound, code)
assert.Equal(suite.T(), errmsg.ErrorMsgNotFound, message)
})
suite.Run("Failure_Unauthorized", func() {
url := fmt.Sprintf("/benefactors/kindboxreqs/%d", suite.kindBoxReqID)
rec := CreateRequest(http.MethodDelete, url, "invalid_token", nil)
suite.Require().Equal(http.StatusUnauthorized, rec.Code)
})
}

View File

@ -1,54 +0,0 @@
//go:build end2end
package end2end
import (
"bytes"
"context"
"encoding/json"
"fmt"
"log"
"net/http/httptest"
param "git.gocasts.ir/ebhomengo/niki/param/benefactor/benefactor"
"github.com/labstack/echo/v4"
)
// CreateRequest is a utility function to create and send HTTP requests
func CreateRequest(method, url, token string, body interface{}) *httptest.ResponseRecorder {
var buf bytes.Buffer
if body != nil {
err := json.NewEncoder(&buf).Encode(body)
if err != nil {
log.Fatalf("could not encode body: %v", err)
}
}
req := httptest.NewRequest(method, url, &buf)
req.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON)
req.Header.Set(echo.HeaderAuthorization, fmt.Sprintf("Bearer %s", token))
rec := httptest.NewRecorder()
testServer.Serve(rec, req)
return rec
}
// LoginBenefactor is a utility function to login a benefactor and return the access token
func LoginBenefactor(phoneNumber string) string {
sendOTPRes, err := services.BenefactorSvc.SendOtp(context.Background(), param.SendOtpRequest{
PhoneNumber: phoneNumber,
})
if err != nil {
log.Fatalf("failed to send OTP: %v", err)
}
registerRes, err := services.BenefactorSvc.LoginOrRegister(context.Background(), param.LoginOrRegisterRequest{
PhoneNumber: phoneNumber,
VerificationCode: sendOTPRes.Code,
})
if err != nil {
log.Fatalf("failed to register: %v", err)
}
return registerRes.Tokens.AccessToken
}

View File

@ -1,12 +1,12 @@
package setup
import (
"github.com/labstack/echo/v4"
"net/http"
"git.gocasts.ir/ebhomengo/niki/config"
httpserver "git.gocasts.ir/ebhomengo/niki/delivery/http_server"
"git.gocasts.ir/ebhomengo/niki/service"
"github.com/labstack/echo/v4"
)
type TestServer struct {

View File

@ -14,7 +14,7 @@ func Auth(service authservice.Service) echo.MiddlewareFunc {
// TODO - as sign method string to config
SigningMethod: "HS256",
ParseTokenFunc: func(c echo.Context, auth string) (interface{}, error) {
claims, err := service.ParseBearerToken(auth)
claims, err := service.ParseToken(auth)
if err != nil {
return nil, err
}

View File

@ -9,7 +9,7 @@ import (
"github.com/labstack/echo/v4"
)
// nolint
//nolint
func BenefactorAuthorization(role entity.UserRole) echo.MiddlewareFunc {
return func(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) error {

View File

@ -1,23 +0,0 @@
package middleware
import (
"net/http"
errmsg "git.gocasts.ir/ebhomengo/niki/pkg/err_msg"
authservice "git.gocasts.ir/ebhomengo/niki/service/auth"
"github.com/labstack/echo/v4"
)
// nolint
func TokenSeed(cfg authservice.Service) echo.MiddlewareFunc {
return func(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) error {
token := c.Request().Header.Get("token")
if token != cfg.Config.SeedToken {
return c.JSON(http.StatusForbidden, echo.Map{"message": errmsg.ErrorMsgUserNotAllowed})
}
return next(c)
}
}
}

View File

@ -6,18 +6,13 @@ import (
"git.gocasts.ir/ebhomengo/niki/config"
adminhandler "git.gocasts.ir/ebhomengo/niki/delivery/http_server/admin/admin"
adminagenthandler "git.gocasts.ir/ebhomengo/niki/delivery/http_server/admin/agent"
adminbenefactorhandler "git.gocasts.ir/ebhomengo/niki/delivery/http_server/admin/benefactor"
adminKindBoxHandler "git.gocasts.ir/ebhomengo/niki/delivery/http_server/admin/kind_box"
adminkindboxreqhandler "git.gocasts.ir/ebhomengo/niki/delivery/http_server/admin/kind_box_req"
adminrefertimehandler "git.gocasts.ir/ebhomengo/niki/delivery/http_server/admin/refer_time"
adminseedhandler "git.gocasts.ir/ebhomengo/niki/delivery/http_server/admin/seed"
agentkindboxhandler "git.gocasts.ir/ebhomengo/niki/delivery/http_server/agent/kind_box"
agentkindboxreqhandler "git.gocasts.ir/ebhomengo/niki/delivery/http_server/agent/kind_box_req"
benefactoraddresshandler "git.gocasts.ir/ebhomengo/niki/delivery/http_server/benefactor/address"
benefactorhandler "git.gocasts.ir/ebhomengo/niki/delivery/http_server/benefactor/benefactor"
benefactorkindboxhandler "git.gocasts.ir/ebhomengo/niki/delivery/http_server/benefactor/kind_box"
benefactorkindboxreqhandler "git.gocasts.ir/ebhomengo/niki/delivery/http_server/benefactor/kind_box_req"
benefactorrefertimehandler "git.gocasts.ir/ebhomengo/niki/delivery/http_server/benefactor/refer_time"
"git.gocasts.ir/ebhomengo/niki/docs"
"git.gocasts.ir/ebhomengo/niki/service"
echo "github.com/labstack/echo/v4"
@ -32,16 +27,11 @@ type Server struct {
adminKindBoxReqHandler adminkindboxreqhandler.Handler
adminKindBoxHandler adminKindBoxHandler.Handler
adminAgentHandler adminagenthandler.Handler
adminBenefactorHandler adminbenefactorhandler.Handler
adminReferTimeHandler adminrefertimehandler.Handler
agentKindBoxHandler agentkindboxhandler.Handler
agentKindBoxReqHandler agentkindboxreqhandler.Handler
benefactorHandler benefactorhandler.Handler
benefactorKindBoxReqHandler benefactorkindboxreqhandler.Handler
benefactorAddressHandler benefactoraddresshandler.Handler
benefactorKindBoxHandler benefactorkindboxhandler.Handler
benefactorReferTimeHandler benefactorrefertimehandler.Handler
adminSeedHandler adminseedhandler.Handler
}
func New(
@ -52,19 +42,14 @@ func New(
Router: echo.New(),
config: cfg,
adminHandler: adminhandler.New(svc.AdminAuthSvc, svc.AdminSvc, svc.AdminAuthorizeSvc),
adminKindBoxReqHandler: adminkindboxreqhandler.New(svc.AdminAuthSvc, svc.AdminKindBoxReqSvc, svc.AdminBenefactorAggSvc, svc.AdminAddressAggSvc, svc.AdminReferTimeAggSvc, svc.AdminAuthorizeSvc, svc.NotificationSvc),
adminKindBoxHandler: adminKindBoxHandler.New(svc.AdminAuthSvc, svc.AdminKindBoxSvc, svc.AdminBenefactorAggSvc, svc.AdminAddressAggSvc, svc.AdminReferTimeAggSvc, svc.AdminAuthorizeSvc, svc.NotificationSvc),
adminKindBoxReqHandler: adminkindboxreqhandler.New(svc.AdminAuthSvc, svc.AdminKindBoxReqSvc, svc.AdminAuthorizeSvc, svc.NotificationSvc),
adminKindBoxHandler: adminKindBoxHandler.New(svc.AdminAuthSvc, svc.AdminKindBoxSvc, svc.AdminAuthorizeSvc, svc.NotificationSvc),
adminAgentHandler: adminagenthandler.New(svc.AdminAuthSvc, svc.AdminAgentSvc, svc.AdminAuthorizeSvc),
adminBenefactorHandler: adminbenefactorhandler.New(svc.AdminAuthSvc, svc.AdminAuthorizeSvc, svc.AdminBenefactorSvc, svc.AdminAddressSvc, svc.AdminKindBoxSvc, svc.AdminKindBoxReqSvc),
adminReferTimeHandler: adminrefertimehandler.New(svc.AdminAuthSvc, svc.AdminReferTimeSvc, svc.AdminAuthorizeSvc),
adminSeedHandler: adminseedhandler.New(svc.AdminAuthSvc, svc.AdminSeedSvc),
agentKindBoxHandler: agentkindboxhandler.New(svc.AdminAuthSvc, svc.AgentKindBoxSvc, svc.AdminAuthorizeSvc, svc.NotificationSvc),
agentKindBoxReqHandler: agentkindboxreqhandler.New(svc.AdminAuthSvc, svc.AgentKindBoxReqSvc, svc.AdminAuthorizeSvc, svc.NotificationSvc),
agentKindBoxHandler: agentkindboxhandler.New(svc.AdminAuthSvc, svc.AgentKindBoxSvc, svc.AdminAuthorizeSvc),
benefactorHandler: benefactorhandler.New(svc.BenefactorAuthSvc, svc.BenefactorSvc),
benefactorKindBoxReqHandler: benefactorkindboxreqhandler.New(svc.BenefactorAuthSvc, svc.BenefactorKindBoxReqSvc, svc.NotificationSvc),
benefactorAddressHandler: benefactoraddresshandler.New(svc.BenefactorAuthSvc, svc.BenefactorAddressSvc),
benefactorKindBoxHandler: benefactorkindboxhandler.New(svc.BenefactorAuthSvc, svc.BenefactorKindBoxSvc, svc.NotificationSvc),
benefactorReferTimeHandler: benefactorrefertimehandler.New(svc.BenefactorAuthSvc, svc.BenefactorReferTimeSvc),
}
}
@ -82,10 +67,7 @@ func (s Server) Serve() {
func (s Server) RegisterRoutes() {
s.Router.Use(middleware.RequestID())
s.Router.Use(middleware.Recover())
s.Router.Use(middleware.CORSWithConfig(middleware.CORSConfig{
AllowOrigins: s.config.HTTPServer.Cors.AllowOrigins,
}))
registerSwagger(s.Router)
registerSwagger(s.Router, s.config)
// Routes
s.Router.GET("/health-check", s.healthCheck)
@ -93,23 +75,18 @@ func (s Server) RegisterRoutes() {
s.benefactorKindBoxReqHandler.SetRoutes(s.Router)
s.benefactorAddressHandler.SetRoutes(s.Router)
s.benefactorKindBoxHandler.SetRoutes(s.Router)
s.benefactorReferTimeHandler.SetRoutes(s.Router)
s.adminHandler.SetRoutes(s.Router)
s.adminAgentHandler.SetRoutes(s.Router)
s.adminKindBoxReqHandler.SetRoutes(s.Router)
s.adminKindBoxHandler.SetRoutes(s.Router)
s.adminReferTimeHandler.SetRoutes(s.Router)
s.adminBenefactorHandler.SetRoutes(s.Router)
s.agentKindBoxHandler.SetRoutes(s.Router)
s.agentKindBoxReqHandler.SetRoutes(s.Router)
s.adminSeedHandler.SetRoutes(s.Router)
}
func registerSwagger(s *echo.Echo) {
func registerSwagger(s *echo.Echo, c config.Config) {
// TODO: move this to a better place and make it more dynamic and configurable
docs.SwaggerInfo.Title = "NIKI API"
docs.SwaggerInfo.Description = "This is the API documentation for the NIKI project"
docs.SwaggerInfo.Version = "1.0.0"
docs.SwaggerInfo.Host = fmt.Sprintf("localhost:%d", c.HTTPServer.Port)
s.GET("/swagger/*any", echoSwagger.WrapHandler)
}

Some files were not shown because too many files have changed in this diff Show More