From ab21d638549bc999ff271643b8238f48a4b88f1a Mon Sep 17 00:00:00 2001 From: Ruhollah Date: Sat, 13 Jul 2024 16:06:07 +0330 Subject: [PATCH] feat(niki): agent get return awaiting kindbox (#81) --- .../admin/kind_box/get_return_awaiting.go | 53 +++++++ .../middleware/admin_authorization.go | 8 +- docs/docs.go | 139 ++++++++++++++++++ docs/swagger.json | 139 ++++++++++++++++++ docs/swagger.yaml | 90 ++++++++++++ param/admin/kind_box/get_return_awaiting.go | 12 ++ pkg/http_msg/err_response.go | 6 + .../mysql/kind_box/get_return_awaiting.go | 30 ++++ service/admin/kind_box/get_return_awaiting.go | 20 +++ service/admin/kind_box/service.go | 1 + .../admin/kind_box/get_return_awaiting.go | 36 +++++ 11 files changed, 528 insertions(+), 6 deletions(-) create mode 100644 delivery/http_server/admin/kind_box/get_return_awaiting.go create mode 100644 param/admin/kind_box/get_return_awaiting.go create mode 100644 pkg/http_msg/err_response.go create mode 100644 repository/mysql/kind_box/get_return_awaiting.go create mode 100644 service/admin/kind_box/get_return_awaiting.go create mode 100644 validator/admin/kind_box/get_return_awaiting.go diff --git a/delivery/http_server/admin/kind_box/get_return_awaiting.go b/delivery/http_server/admin/kind_box/get_return_awaiting.go new file mode 100644 index 0000000..ef10802 --- /dev/null +++ b/delivery/http_server/admin/kind_box/get_return_awaiting.go @@ -0,0 +1,53 @@ +package adminkindboxhandler + +import ( + "net/http" + + param "git.gocasts.ir/ebhomengo/niki/param/admin/kind_box" + "git.gocasts.ir/ebhomengo/niki/pkg/claim" + httpmsg "git.gocasts.ir/ebhomengo/niki/pkg/http_msg" + "github.com/labstack/echo/v4" +) + +// GetAwaitingReturn godoc +// @Summary Get a kind box that is awaiting return by agent +// @Tags KindBox +// @Accept json +// @Produce json +// @Param id path int true "KindBox ID" +// @Success 200 {object} param.ReturnAwaitingGetResponse +// @Failure 400 {string} "Bad Request" +// @Failure 401 {string} "invalid or expired jwt" +// @Failure 403 {string} "user not allowed" +// @Failure 422 {object} httpmsg.ErrorResponse +// @Failure 404 {string} "record not found" +// @Failure 500 {string} "something went wrong" +// @Security AuthBearerAdmin +// @Router /admin/kindboxes/awaiting-return/{id} [get] +func (h Handler) GetAwaitingReturn(c echo.Context) error { + var req param.ReturnAwaitingGetRequest + if bErr := c.Bind(&req); bErr != nil { + return echo.NewHTTPError(http.StatusBadRequest) + } + + claims := claim.GetClaimsFromEchoContext(c) + req.AgentID = claims.UserID + + if fieldErrors, err := h.adminKindBoxVld.ValidateGetAwaitingReturnRequest(req); err != nil { + msg, code := httpmsg.Error(err) + + return c.JSON(code, httpmsg.ErrorResponse{ + Message: msg, + Errors: fieldErrors, + }) + } + + resp, sErr := h.adminKindBoxSvc.GetAwaitingReturn(c.Request().Context(), req) + if sErr != nil { + msg, code := httpmsg.Error(sErr) + + return echo.NewHTTPError(code, msg) + } + + return c.JSON(http.StatusOK, resp) +} 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 9dbb080..d702d37 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -509,6 +509,78 @@ const docTemplate = `{ } } }, + "/admin/kindboxes/awaiting-return/{id}": { + "get": { + "security": [ + { + "AuthBearerAdmin": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "KindBox" + ], + "summary": "Get a kind box that is awaiting return by agent", + "parameters": [ + { + "type": "integer", + "description": "KindBox ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/adminkindboxparam.ReturnAwaitingGetResponse" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "type": "string" + } + }, + "401": { + "description": "invalid or expired jwt", + "schema": { + "type": "string" + } + }, + "403": { + "description": "user not allowed", + "schema": { + "type": "string" + } + }, + "404": { + "description": "record not found", + "schema": { + "type": "string" + } + }, + "422": { + "description": "Unprocessable Entity", + "schema": { + "$ref": "#/definitions/httpmsg.ErrorResponse" + } + }, + "500": { + "description": "something went wrong", + "schema": { + "type": "string" + } + } + } + } + }, "/admin/kindboxes/{id}": { "get": { "security": [ @@ -1829,6 +1901,59 @@ const docTemplate = `{ } } }, + "adminkindboxparam.ReturnAwaitingGetResponse": { + "type": "object", + "properties": { + "amount": { + "type": "integer" + }, + "benefactorID": { + "type": "integer" + }, + "deliverAddressID": { + "type": "integer" + }, + "deliverReferDate": { + "type": "string" + }, + "deliveredAt": { + "type": "string" + }, + "id": { + "type": "integer" + }, + "kindBoxReqID": { + "type": "integer" + }, + "kindBoxType": { + "$ref": "#/definitions/entity.KindBoxType" + }, + "receiverAgentID": { + "type": "integer" + }, + "returnAddressID": { + "type": "integer" + }, + "returnReferDate": { + "type": "string" + }, + "returnReferTimeID": { + "type": "integer" + }, + "returnedAt": { + "type": "string" + }, + "senderAgentID": { + "type": "integer" + }, + "serialNumber": { + "type": "string" + }, + "status": { + "$ref": "#/definitions/entity.KindBoxStatus" + } + } + }, "adminkindboxreqparam.AssignSenderRequest": { "type": "object", "properties": { @@ -2738,6 +2863,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 32d90b1..3dcf1a8 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -498,6 +498,78 @@ } } }, + "/admin/kindboxes/awaiting-return/{id}": { + "get": { + "security": [ + { + "AuthBearerAdmin": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "KindBox" + ], + "summary": "Get a kind box that is awaiting return by agent", + "parameters": [ + { + "type": "integer", + "description": "KindBox ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/adminkindboxparam.ReturnAwaitingGetResponse" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "type": "string" + } + }, + "401": { + "description": "invalid or expired jwt", + "schema": { + "type": "string" + } + }, + "403": { + "description": "user not allowed", + "schema": { + "type": "string" + } + }, + "404": { + "description": "record not found", + "schema": { + "type": "string" + } + }, + "422": { + "description": "Unprocessable Entity", + "schema": { + "$ref": "#/definitions/httpmsg.ErrorResponse" + } + }, + "500": { + "description": "something went wrong", + "schema": { + "type": "string" + } + } + } + } + }, "/admin/kindboxes/{id}": { "get": { "security": [ @@ -1818,6 +1890,59 @@ } } }, + "adminkindboxparam.ReturnAwaitingGetResponse": { + "type": "object", + "properties": { + "amount": { + "type": "integer" + }, + "benefactorID": { + "type": "integer" + }, + "deliverAddressID": { + "type": "integer" + }, + "deliverReferDate": { + "type": "string" + }, + "deliveredAt": { + "type": "string" + }, + "id": { + "type": "integer" + }, + "kindBoxReqID": { + "type": "integer" + }, + "kindBoxType": { + "$ref": "#/definitions/entity.KindBoxType" + }, + "receiverAgentID": { + "type": "integer" + }, + "returnAddressID": { + "type": "integer" + }, + "returnReferDate": { + "type": "string" + }, + "returnReferTimeID": { + "type": "integer" + }, + "returnedAt": { + "type": "string" + }, + "senderAgentID": { + "type": "integer" + }, + "serialNumber": { + "type": "string" + }, + "status": { + "$ref": "#/definitions/entity.KindBoxStatus" + } + } + }, "adminkindboxreqparam.AssignSenderRequest": { "type": "object", "properties": { @@ -2727,6 +2852,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 b98638b..a740fcb 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -121,6 +121,41 @@ definitions: status: $ref: '#/definitions/entity.KindBoxStatus' type: object + adminkindboxparam.ReturnAwaitingGetResponse: + properties: + amount: + type: integer + benefactorID: + type: integer + deliverAddressID: + type: integer + deliverReferDate: + type: string + deliveredAt: + type: string + id: + type: integer + kindBoxReqID: + type: integer + kindBoxType: + $ref: '#/definitions/entity.KindBoxType' + receiverAgentID: + type: integer + returnAddressID: + type: integer + returnReferDate: + type: string + returnReferTimeID: + type: integer + returnedAt: + type: string + senderAgentID: + type: integer + serialNumber: + type: string + status: + $ref: '#/definitions/entity.KindBoxStatus' + type: object adminkindboxreqparam.AssignSenderRequest: properties: sender_agent_id: @@ -727,6 +762,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: @@ -1095,6 +1139,52 @@ paths: summary: Admin assign receiver agent to kindbox tags: - KindBox + /admin/kindboxes/awaiting-return/{id}: + get: + consumes: + - application/json + parameters: + - description: KindBox ID + in: path + name: id + required: true + type: integer + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/adminkindboxparam.ReturnAwaitingGetResponse' + "400": + description: Bad Request + schema: + type: string + "401": + description: invalid or expired jwt + schema: + type: string + "403": + description: user not allowed + schema: + type: string + "404": + description: record not found + schema: + type: string + "422": + description: Unprocessable Entity + schema: + $ref: '#/definitions/httpmsg.ErrorResponse' + "500": + description: something went wrong + schema: + type: string + security: + - AuthBearerAdmin: [] + summary: Get a kind box that is awaiting return by agent + tags: + - KindBox /admin/kindboxreqs: get: consumes: diff --git a/param/admin/kind_box/get_return_awaiting.go b/param/admin/kind_box/get_return_awaiting.go new file mode 100644 index 0000000..ce99e0b --- /dev/null +++ b/param/admin/kind_box/get_return_awaiting.go @@ -0,0 +1,12 @@ +package adminkindboxparam + +import "git.gocasts.ir/ebhomengo/niki/entity" + +type ReturnAwaitingGetRequest struct { + KindBoxID uint `param:"id"` + AgentID uint +} + +type ReturnAwaitingGetResponse struct { + entity.KindBox +} 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/repository/mysql/kind_box/get_return_awaiting.go b/repository/mysql/kind_box/get_return_awaiting.go new file mode 100644 index 0000000..384a153 --- /dev/null +++ b/repository/mysql/kind_box/get_return_awaiting.go @@ -0,0 +1,30 @@ +package mysqlkindbox + +import ( + "context" + "database/sql" + "errors" + "git.gocasts.ir/ebhomengo/niki/entity" + errmsg "git.gocasts.ir/ebhomengo/niki/pkg/err_msg" + richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error" +) + +func (d DB) GetAwaitingReturnByAgent(ctx context.Context, kindBoxID uint, agentID uint) (entity.KindBox, error) { + const op = "mysqlkindbox.GetAwaitingReturnByAgent" + + query := `SELECT * FROM kind_boxes WHERE id = ? AND receiver_agent_id = ? AND status = ? AND deleted_at IS NULL ` + row := d.conn.Conn().QueryRowContext(ctx, query, kindBoxID, agentID, entity.KindBoxAssignedReceiverAgentStatus.String()) + k, err := scanKindBox(row) + if err != nil { + if errors.Is(err, sql.ErrNoRows) { + + return entity.KindBox{}, richerror.New(op).WithErr(err). + WithMessage(errmsg.ErrorMsgNotFound).WithKind(richerror.KindNotFound) + } + + return entity.KindBox{}, richerror.New(op).WithErr(err). + WithMessage(errmsg.ErrorMsgCantScanQueryResult).WithKind(richerror.KindUnexpected) + } + + return k, nil +} diff --git a/service/admin/kind_box/get_return_awaiting.go b/service/admin/kind_box/get_return_awaiting.go new file mode 100644 index 0000000..df5e03b --- /dev/null +++ b/service/admin/kind_box/get_return_awaiting.go @@ -0,0 +1,20 @@ +package adminkindboxservice + +import ( + "context" + param "git.gocasts.ir/ebhomengo/niki/param/admin/kind_box" +) + +func (s Service) GetAwaitingReturn(ctx context.Context, req param.ReturnAwaitingGetRequest) (param.ReturnAwaitingGetResponse, error) { + const op = "adminkindboxservice.GetAwaitingReturn" + + kindBox, err := s.repo.GetAwaitingReturnByAgent(ctx, req.KindBoxID, req.AgentID) + if err != nil { + + return param.ReturnAwaitingGetResponse{}, err + } + + return param.ReturnAwaitingGetResponse{ + KindBox: kindBox, + }, nil +} diff --git a/service/admin/kind_box/service.go b/service/admin/kind_box/service.go index dca638d..8e10be5 100644 --- a/service/admin/kind_box/service.go +++ b/service/admin/kind_box/service.go @@ -13,6 +13,7 @@ type Repository interface { GetKindBox(ctx context.Context, kindBoxID uint) (entity.KindBox, error) AssignReceiverAgent(ctx context.Context, kindBox entity.KindBox) error GetAllKindBox(ctx context.Context, filter params.FilterRequest, pagination params.PaginationRequest, sort params.SortRequest) ([]entity.KindBox, uint, error) + GetAwaitingReturnByAgent(ctx context.Context, kindBoxID uint, agentID uint) (entity.KindBox, error) } type Service struct { diff --git a/validator/admin/kind_box/get_return_awaiting.go b/validator/admin/kind_box/get_return_awaiting.go new file mode 100644 index 0000000..a089a5c --- /dev/null +++ b/validator/admin/kind_box/get_return_awaiting.go @@ -0,0 +1,36 @@ +package adminkindboxvalidator + +import ( + "errors" + param "git.gocasts.ir/ebhomengo/niki/param/admin/kind_box" + errmsg "git.gocasts.ir/ebhomengo/niki/pkg/err_msg" + richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error" + validation "github.com/go-ozzo/ozzo-validation/v4" +) + +func (v Validator) ValidateGetAwaitingReturnRequest(req param.ReturnAwaitingGetRequest) (map[string]string, error) { + const op = "adminkindboxvalidator.ValidateGetAwaitingReturnRequest" + + if err := validation.ValidateStruct(&req, + validation.Field(&req.KindBoxID, validation.Required), + ); 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 +}