diff --git a/delivery/http_server/admin/kind_box_req/get_all.go b/delivery/http_server/admin/kind_box_req/get_all.go index 560a09e..59667d1 100644 --- a/delivery/http_server/admin/kind_box_req/get_all.go +++ b/delivery/http_server/admin/kind_box_req/get_all.go @@ -3,29 +3,60 @@ package adminkindboxreqhandler import ( param "git.gocasts.ir/ebhomengo/niki/param/admin/kind_box_req" httpmsg "git.gocasts.ir/ebhomengo/niki/pkg/http_msg" + queryparam "git.gocasts.ir/ebhomengo/niki/pkg/query_param" echo "github.com/labstack/echo/v4" "net/http" ) // GetAll godoc // @Summary Admin get all kindboxreq +// @Description Retrieves a list of all KindBox requests with filtering, sorting, and pagination options // @Tags KindBoxReq // @Accept json // @Produce json -// @Param page_number query int false "page_number" -// @Param page_size query int false "page_size" +// @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" +// @Param filter_kind_box_type query entity.KindBoxType false "Filter by KindBox type" Format(enum) +// @Param filter_status query entity.KindBoxReqStatus false "Filter by KindBoxReq status" Format(enum) +// @Param filter_count_requested query int false "Filter by count requested" +// @Param filter_count_accepted query int false "Filter by count accepted" +// @Param filter_deliver_refer_time_id query int false "Filter by deliver refer time ID" +// @Param filter_deliver_refer_date query string false "Filter by deliver refer date" Format(date) +// @Param filter_deliver_address_id query int false "Filter by deliver address ID" +// @Param filter_delivered_at query string false "Filter by delivered at" Format(date) +// @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,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 {object} param.KindBoxReqGetAllResponse -// @Failure 400 {string} "Bad request" +// @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 /admin/kindboxreqs [get]. +// @Router /admins/kindboxreqs [get]. func (h Handler) GetAll(c echo.Context) error { var req param.KindBoxReqGetAllRequest - if bErr := c.Bind(&req); bErr != nil { + + if err := c.Bind(&req); err != nil { return echo.NewHTTPError(http.StatusBadRequest) } - resp, sErr := h.adminKindBoxReqSvc.GetAll(c.Request().Context(), req) - if sErr != nil { - msg, code := httpmsg.Error(sErr) + + req.Filter = queryparam.GetFilterParams(c) + if fieldErrors, err := h.adminKindBoxReqVld.ValidateGetAll(req); err != nil { + msg, code := httpmsg.Error(err) + + return c.JSON(code, httpmsg.ErrorResponse{ + Message: msg, + Errors: fieldErrors, + }) + } + + resp, err := h.adminKindBoxReqSvc.GetAll(c.Request().Context(), req) + if err != nil { + msg, code := httpmsg.Error(err) return echo.NewHTTPError(code, msg) } diff --git a/delivery/http_server/admin/kind_box_req/route.go b/delivery/http_server/admin/kind_box_req/route.go index be1cdfd..c14a0df 100644 --- a/delivery/http_server/admin/kind_box_req/route.go +++ b/delivery/http_server/admin/kind_box_req/route.go @@ -7,7 +7,7 @@ import ( ) func (h Handler) SetRoutes(e *echo.Echo) { - r := e.Group("/admin/kindboxreqs") + r := e.Group("/admins/kindboxreqs") r.Use(middleware.Auth(h.authSvc, h.authConfig)) r.POST("", h.AddKindBoxReq, middleware.AdminAuthorization(h.adminAuthorizeSvc, entity.AdminKindBoxReqAddPermission)) diff --git a/delivery/http_server/middleware/admin_authorization.go b/delivery/http_server/middleware/admin_authorization.go index cee306d..f395f50 100644 --- a/delivery/http_server/middleware/admin_authorization.go +++ b/delivery/http_server/middleware/admin_authorization.go @@ -19,15 +19,11 @@ func AdminAuthorization(service adminauthorizationservice.Service, isAllowed, err := service.CheckAccess(claims.UserID, entity.MapToAdminRole(claims.Role), permissions...) if err != nil { - return c.JSON(http.StatusInternalServerError, echo.Map{ - "message": errmsg.ErrorMsgSomethingWentWrong, - }) + return echo.NewHTTPError(http.StatusInternalServerError, errmsg.ErrorMsgSomethingWentWrong) } if !isAllowed { - return c.JSON(http.StatusForbidden, echo.Map{ - "message": errmsg.ErrorMsgUserNotAllowed, - }) + return echo.NewHTTPError(http.StatusForbidden, errmsg.ErrorMsgUserNotAllowed) } return next(c) diff --git a/docs/docs.go b/docs/docs.go index 9a06026..380c121 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -560,51 +560,6 @@ const docTemplate = `{ } }, "/admin/kindboxreqs": { - "get": { - "security": [ - { - "AuthBearerAdmin": [] - } - ], - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "KindBoxReq" - ], - "summary": "Admin get all kindboxreq", - "parameters": [ - { - "type": "integer", - "description": "page_number", - "name": "page_number", - "in": "query" - }, - { - "type": "integer", - "description": "page_size", - "name": "page_size", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/adminkindboxreqparam.KindBoxReqGetAllResponse" - } - }, - "400": { - "description": "Bad request", - "schema": { - "type": "string" - } - } - } - }, "post": { "security": [ { @@ -1104,6 +1059,189 @@ const docTemplate = `{ } } }, + "/admins/kindboxreqs": { + "get": { + "security": [ + { + "AuthBearerAdmin": [] + } + ], + "description": "Retrieves a list of all KindBox requests with filtering, sorting, and pagination options", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "KindBoxReq" + ], + "summary": "Admin get all kindboxreq", + "parameters": [ + { + "type": "integer", + "description": "Filter by ID", + "name": "filter_id", + "in": "query" + }, + { + "type": "integer", + "description": "Filter by benefactor ID", + "name": "filter_benefactor_id", + "in": "query" + }, + { + "type": "integer", + "description": "Filter by sender agent ID", + "name": "filter_sender_agent_id", + "in": "query" + }, + { + "enum": [ + 1, + 2, + 3 + ], + "type": "integer", + "format": "enum", + "description": "Filter by KindBox type", + "name": "filter_kind_box_type", + "in": "query" + }, + { + "enum": [ + 1, + 2, + 3, + 4, + 5 + ], + "type": "integer", + "format": "enum", + "description": "Filter by KindBoxReq status", + "name": "filter_status", + "in": "query" + }, + { + "type": "integer", + "description": "Filter by count requested", + "name": "filter_count_requested", + "in": "query" + }, + { + "type": "integer", + "description": "Filter by count accepted", + "name": "filter_count_accepted", + "in": "query" + }, + { + "type": "integer", + "description": "Filter by deliver refer time ID", + "name": "filter_deliver_refer_time_id", + "in": "query" + }, + { + "type": "string", + "format": "date", + "description": "Filter by deliver refer date", + "name": "filter_deliver_refer_date", + "in": "query" + }, + { + "type": "integer", + "description": "Filter by deliver address ID", + "name": "filter_deliver_address_id", + "in": "query" + }, + { + "type": "string", + "format": "date", + "description": "Filter by delivered at", + "name": "filter_delivered_at", + "in": "query" + }, + { + "type": "integer", + "description": "Page number", + "name": "page_number", + "in": "query" + }, + { + "type": "integer", + "description": "Page size", + "name": "page_size", + "in": "query" + }, + { + "enum": [ + "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" + ], + "type": "string", + "description": "Sort by field", + "name": "sort_field", + "in": "query" + }, + { + "enum": [ + "asc", + "desc" + ], + "type": "string", + "description": "Sort order", + "name": "sort_direction", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/adminkindboxreqparam.KindBoxReqGetAllResponse" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "type": "string" + } + }, + "401": { + "description": "invalid or expired jwt", + "schema": { + "type": "string" + } + }, + "403": { + "description": "user not allowed", + "schema": { + "type": "string" + } + }, + "422": { + "description": "Unprocessable Entity", + "schema": { + "$ref": "#/definitions/httpmsg.ErrorResponse" + } + }, + "500": { + "description": "something went wrong", + "schema": { + "type": "string" + } + } + } + } + }, "/admins/login-by-phone": { "post": { "consumes": [ @@ -2961,6 +3099,20 @@ const docTemplate = `{ } } }, + "httpmsg.ErrorResponse": { + "type": "object", + "properties": { + "errors": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "message": { + "type": "string" + } + } + }, "param.PaginationResponse": { "type": "object", "properties": { diff --git a/docs/swagger.json b/docs/swagger.json index 742f3be..68397d4 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -549,51 +549,6 @@ } }, "/admin/kindboxreqs": { - "get": { - "security": [ - { - "AuthBearerAdmin": [] - } - ], - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "KindBoxReq" - ], - "summary": "Admin get all kindboxreq", - "parameters": [ - { - "type": "integer", - "description": "page_number", - "name": "page_number", - "in": "query" - }, - { - "type": "integer", - "description": "page_size", - "name": "page_size", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/adminkindboxreqparam.KindBoxReqGetAllResponse" - } - }, - "400": { - "description": "Bad request", - "schema": { - "type": "string" - } - } - } - }, "post": { "security": [ { @@ -1093,6 +1048,189 @@ } } }, + "/admins/kindboxreqs": { + "get": { + "security": [ + { + "AuthBearerAdmin": [] + } + ], + "description": "Retrieves a list of all KindBox requests with filtering, sorting, and pagination options", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "KindBoxReq" + ], + "summary": "Admin get all kindboxreq", + "parameters": [ + { + "type": "integer", + "description": "Filter by ID", + "name": "filter_id", + "in": "query" + }, + { + "type": "integer", + "description": "Filter by benefactor ID", + "name": "filter_benefactor_id", + "in": "query" + }, + { + "type": "integer", + "description": "Filter by sender agent ID", + "name": "filter_sender_agent_id", + "in": "query" + }, + { + "enum": [ + 1, + 2, + 3 + ], + "type": "integer", + "format": "enum", + "description": "Filter by KindBox type", + "name": "filter_kind_box_type", + "in": "query" + }, + { + "enum": [ + 1, + 2, + 3, + 4, + 5 + ], + "type": "integer", + "format": "enum", + "description": "Filter by KindBoxReq status", + "name": "filter_status", + "in": "query" + }, + { + "type": "integer", + "description": "Filter by count requested", + "name": "filter_count_requested", + "in": "query" + }, + { + "type": "integer", + "description": "Filter by count accepted", + "name": "filter_count_accepted", + "in": "query" + }, + { + "type": "integer", + "description": "Filter by deliver refer time ID", + "name": "filter_deliver_refer_time_id", + "in": "query" + }, + { + "type": "string", + "format": "date", + "description": "Filter by deliver refer date", + "name": "filter_deliver_refer_date", + "in": "query" + }, + { + "type": "integer", + "description": "Filter by deliver address ID", + "name": "filter_deliver_address_id", + "in": "query" + }, + { + "type": "string", + "format": "date", + "description": "Filter by delivered at", + "name": "filter_delivered_at", + "in": "query" + }, + { + "type": "integer", + "description": "Page number", + "name": "page_number", + "in": "query" + }, + { + "type": "integer", + "description": "Page size", + "name": "page_size", + "in": "query" + }, + { + "enum": [ + "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" + ], + "type": "string", + "description": "Sort by field", + "name": "sort_field", + "in": "query" + }, + { + "enum": [ + "asc", + "desc" + ], + "type": "string", + "description": "Sort order", + "name": "sort_direction", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/adminkindboxreqparam.KindBoxReqGetAllResponse" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "type": "string" + } + }, + "401": { + "description": "invalid or expired jwt", + "schema": { + "type": "string" + } + }, + "403": { + "description": "user not allowed", + "schema": { + "type": "string" + } + }, + "422": { + "description": "Unprocessable Entity", + "schema": { + "$ref": "#/definitions/httpmsg.ErrorResponse" + } + }, + "500": { + "description": "something went wrong", + "schema": { + "type": "string" + } + } + } + } + }, "/admins/login-by-phone": { "post": { "consumes": [ @@ -2950,6 +3088,20 @@ } } }, + "httpmsg.ErrorResponse": { + "type": "object", + "properties": { + "errors": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "message": { + "type": "string" + } + } + }, "param.PaginationResponse": { "type": "object", "properties": { diff --git a/docs/swagger.yaml b/docs/swagger.yaml index b698d8a..ab87ebc 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -753,6 +753,15 @@ definitions: name: type: string type: object + httpmsg.ErrorResponse: + properties: + errors: + additionalProperties: + type: string + type: object + message: + type: string + type: object param.PaginationResponse: properties: page_number: @@ -1127,34 +1136,6 @@ paths: tags: - KindBox /admin/kindboxreqs: - get: - consumes: - - application/json - parameters: - - description: page_number - in: query - name: page_number - type: integer - - description: page_size - in: query - name: page_size - type: integer - produces: - - application/json - responses: - "200": - description: OK - schema: - $ref: '#/definitions/adminkindboxreqparam.KindBoxReqGetAllResponse' - "400": - description: Bad request - schema: - type: string - security: - - AuthBearerAdmin: [] - summary: Admin get all kindboxreq - tags: - - KindBoxReq post: consumes: - application/json @@ -1474,6 +1455,134 @@ paths: summary: Get all agents by admin tags: - Admin + /admins/kindboxreqs: + get: + consumes: + - application/json + description: Retrieves a list of all KindBox requests with filtering, sorting, + and pagination options + parameters: + - description: Filter by ID + in: query + name: filter_id + type: integer + - description: Filter by benefactor ID + in: query + name: filter_benefactor_id + type: integer + - description: Filter by sender agent ID + in: query + name: filter_sender_agent_id + type: integer + - description: Filter by KindBox type + enum: + - 1 + - 2 + - 3 + format: enum + in: query + name: filter_kind_box_type + type: integer + - description: Filter by KindBoxReq status + enum: + - 1 + - 2 + - 3 + - 4 + - 5 + format: enum + in: query + name: filter_status + type: integer + - description: Filter by count requested + in: query + name: filter_count_requested + type: integer + - description: Filter by count accepted + in: query + name: filter_count_accepted + type: integer + - description: Filter by deliver refer time ID + in: query + name: filter_deliver_refer_time_id + type: integer + - description: Filter by deliver refer date + format: date + in: query + name: filter_deliver_refer_date + type: string + - description: Filter by deliver address ID + in: query + name: filter_deliver_address_id + type: integer + - description: Filter by delivered at + format: date + in: query + name: filter_delivered_at + type: string + - description: Page number + in: query + name: page_number + type: integer + - description: Page size + in: query + name: page_size + type: integer + - description: Sort by field + enum: + - 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 + in: query + name: sort_field + type: string + - description: Sort order + enum: + - asc + - desc + in: query + name: sort_direction + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/adminkindboxreqparam.KindBoxReqGetAllResponse' + "400": + description: Bad Request + schema: + type: string + "401": + description: invalid or expired jwt + schema: + type: string + "403": + description: user not allowed + schema: + type: string + "422": + description: Unprocessable Entity + schema: + $ref: '#/definitions/httpmsg.ErrorResponse' + "500": + description: something went wrong + schema: + type: string + security: + - AuthBearerAdmin: [] + summary: Admin get all kindboxreq + tags: + - KindBoxReq /admins/login-by-phone: post: consumes: diff --git a/pkg/http_msg/err_response.go b/pkg/http_msg/err_response.go new file mode 100644 index 0000000..7e5c42a --- /dev/null +++ b/pkg/http_msg/err_response.go @@ -0,0 +1,6 @@ +package httpmsg + +type ErrorResponse struct { + Message string `json:"message"` + Errors map[string]string `json:"errors"` +} diff --git a/validator/admin/kind_box_req/get_all.go b/validator/admin/kind_box_req/get_all.go index 7623f43..172bc20 100644 --- a/validator/admin/kind_box_req/get_all.go +++ b/validator/admin/kind_box_req/get_all.go @@ -1,5 +1,43 @@ package adminkindboxreqvalidator -func (v Validator) ValidateGetAllRequest() (map[string]string, error) { +import ( + "errors" + param "git.gocasts.ir/ebhomengo/niki/param/admin/kind_box_req" + errmsg "git.gocasts.ir/ebhomengo/niki/pkg/err_msg" + richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error" + "git.gocasts.ir/ebhomengo/niki/validator" + validation "github.com/go-ozzo/ozzo-validation/v4" +) + +func (v Validator) ValidateGetAll(req param.KindBoxReqGetAllRequest) (map[string]string, error) { + const op = "adminkindboxreqvalidator.ValidateGetAll" + validFields := []string{ + "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", + } + if err := validation.ValidateStruct(&req, + validation.Field(&req.Filter, validation.By(validator.AreFilterFieldsValid(validFields))), + validation.Field(&req.Sort, validation.By(validator.AreSortFieldsValid(validFields))), + ); err != nil { + fieldErrors := make(map[string]string) + + var errV validation.Errors + if errors.As(err, &errV) { + for key, value := range errV { + if value != nil { + fieldErrors[key] = value.Error() + } + } + } + + return fieldErrors, richerror.New(op). + WithMessage(errmsg.ErrorMsgInvalidInput). + WithKind(richerror.KindInvalid). + WithMeta(map[string]interface{}{"req": req}). + WithErr(err) + } + return map[string]string{}, nil } diff --git a/validator/filter.go b/validator/filter.go new file mode 100644 index 0000000..205729c --- /dev/null +++ b/validator/filter.go @@ -0,0 +1,24 @@ +package validator + +import ( + "fmt" + params "git.gocasts.ir/ebhomengo/niki/param" + errmsg "git.gocasts.ir/ebhomengo/niki/pkg/err_msg" + validation "github.com/go-ozzo/ozzo-validation/v4" + "slices" +) + +func AreFilterFieldsValid(validFilters []string) validation.RuleFunc { + return func(value interface{}) error { + filters, ok := value.(params.FilterRequest) + if !ok { + return fmt.Errorf(errmsg.ErrorMsgSomethingWentWrong) + } + for filter := range filters { + if !slices.Contains(validFilters, filter) { + return fmt.Errorf(errmsg.ErrorMsgFiltersAreNotValid) + } + } + return nil + } +} diff --git a/validator/sort.go b/validator/sort.go new file mode 100644 index 0000000..864c030 --- /dev/null +++ b/validator/sort.go @@ -0,0 +1,28 @@ +package validator + +import ( + "fmt" + params "git.gocasts.ir/ebhomengo/niki/param" + errmsg "git.gocasts.ir/ebhomengo/niki/pkg/err_msg" + validation "github.com/go-ozzo/ozzo-validation/v4" + "slices" +) + +func AreSortFieldsValid(validSortFields []string) validation.RuleFunc { + return func(value interface{}) error { + sort, ok := value.(params.SortRequest) + if !ok { + return fmt.Errorf(errmsg.ErrorMsgSomethingWentWrong) + } + if sort.Field == "" && sort.Direction != "" { + return fmt.Errorf(errmsg.ErrorMsgSortFieldIsRequired) + } + if sort.Direction != "" && sort.Direction != params.AscSortDirection && sort.Direction != params.DescSortDirection { + return fmt.Errorf(errmsg.ErrorMsgSortDirectionShouldBeAscOrDesc) + } + if sort.Field != "" && !slices.Contains(validSortFields, sort.Field) { + return fmt.Errorf(errmsg.ErrorMsgSortFieldIsNotValid) + } + return nil + } +}