From 857d26fd1023cbbafbcb16591f95c5c6634f1f91 Mon Sep 17 00:00:00 2001 From: ErfanTech Date: Wed, 12 Jun 2024 11:45:28 +0330 Subject: [PATCH] feat(niki): agent get all delivery awaiting kindboxreqs --- .../http_server/admin/kind_box_req/get_all.go | 17 +- .../kind_box_req/get_all_delivery_awaiting.go | 64 ++++++++ .../http_server/admin/kind_box_req/route.go | 1 + docs/docs.go | 145 +++++++++++++++++- docs/swagger.json | 145 +++++++++++++++++- docs/swagger.yaml | 100 +++++++++++- param/admin/kind_box_req/get_all.go | 14 +- .../kind_box_req/get_all_delivery_awaiting.go | 17 ++ param/filter.go | 3 + param/pagination.go | 11 +- param/sort.go | 13 ++ pkg/err_msg/message.go | 12 +- pkg/query_builder/mysql/filter.go | 17 ++ pkg/query_builder/mysql/get_all.go | 31 ++++ pkg/query_builder/mysql/pagination.go | 9 ++ pkg/query_builder/mysql/sort.go | 14 ++ pkg/query_param/echo.go | 18 +++ repository/mysql/kind_box_req/get_all.go | 64 +++----- repository/mysql/kind_box_req/scan.go | 1 + service/admin/kind_box_req/get_all.go | 11 +- .../kind_box_req/get_all_delivery_awaiting.go | 28 ++++ service/admin/kind_box_req/service.go | 4 +- .../kind_box_req/get_all_delivery_awaiting.go | 43 ++++++ validator/admin/kind_box_req/validator.go | 38 +++++ 24 files changed, 738 insertions(+), 82 deletions(-) create mode 100644 delivery/http_server/admin/kind_box_req/get_all_delivery_awaiting.go create mode 100644 param/admin/kind_box_req/get_all_delivery_awaiting.go create mode 100644 param/filter.go create mode 100644 param/sort.go create mode 100644 pkg/query_builder/mysql/filter.go create mode 100644 pkg/query_builder/mysql/get_all.go create mode 100644 pkg/query_builder/mysql/pagination.go create mode 100644 pkg/query_builder/mysql/sort.go create mode 100644 pkg/query_param/echo.go create mode 100644 service/admin/kind_box_req/get_all_delivery_awaiting.go create mode 100644 validator/admin/kind_box_req/get_all_delivery_awaiting.go 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 fefebdc..08f443e 100644 --- a/delivery/http_server/admin/kind_box_req/get_all.go +++ b/delivery/http_server/admin/kind_box_req/get_all.go @@ -1,13 +1,10 @@ package adminkindboxreqhandler import ( - "net/http" - "strconv" - - paginationparam "git.gocasts.ir/ebhomengo/niki/param" param "git.gocasts.ir/ebhomengo/niki/param/admin/kind_box_req" httpmsg "git.gocasts.ir/ebhomengo/niki/pkg/http_msg" echo "github.com/labstack/echo/v4" + "net/http" ) // GetAll godoc @@ -26,17 +23,7 @@ func (h Handler) GetAll(c echo.Context) error { if bErr := c.Bind(&req); bErr != nil { return echo.NewHTTPError(http.StatusBadRequest) } - - var paginationReq paginationparam.PaginationRequest - // TODO : pkg convert string to uint - //nolint - pageNumber, _ := strconv.ParseUint(c.QueryParam("page_number"), 0, 64) - //nolint - pageSize, _ := strconv.ParseUint(c.QueryParam("page_size"), 0, 64) - paginationReq.PageSize = uint(pageSize) - paginationReq.PageNumber = uint(pageNumber) - - resp, sErr := h.adminKindBoxReqSvc.GetAll(c.Request().Context(), req, paginationReq) + resp, sErr := h.adminKindBoxReqSvc.GetAll(c.Request().Context(), req) if sErr != nil { msg, code := httpmsg.Error(sErr) diff --git a/delivery/http_server/admin/kind_box_req/get_all_delivery_awaiting.go b/delivery/http_server/admin/kind_box_req/get_all_delivery_awaiting.go new file mode 100644 index 0000000..5b4f803 --- /dev/null +++ b/delivery/http_server/admin/kind_box_req/get_all_delivery_awaiting.go @@ -0,0 +1,64 @@ +package adminkindboxreqhandler + +import ( + "git.gocasts.ir/ebhomengo/niki/entity" + "git.gocasts.ir/ebhomengo/niki/pkg/claim" + "net/http" + + 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" + "github.com/labstack/echo/v4" +) + +// 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 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_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 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,kind_box_type,count_requested,count_accepted,deliver_refer_time_id,deliver_refer_date,deliver_address_id) +// @Param sort_direction query string false "Sort order" Enums(asc,desc) +// @Success 200 {object} param.DeliveryAwaitingGetAllResponse +// @Failure 400 {string} "Bad request" +// @Security AuthBearerAdmin +// @Router /admin/kindboxreqs/awaiting-delivery [get] +func (h Handler) GetAllAwaitingDelivery(c echo.Context) error { + var req param.DeliveryAwaitingGetAllRequest + + if bErr := c.Bind(&req); bErr != nil { + + return echo.NewHTTPError(http.StatusBadRequest) + } + + req.Filter = queryparam.GetFilterParams(c) + if fieldErrors, err := h.adminKindBoxReqVld.ValidateGetAllAwaitingDelivery(req); err != nil { + msg, code := httpmsg.Error(err) + + return c.JSON(code, echo.Map{ + "message": msg, + "errors": fieldErrors, + }) + } + req.Filter["sender_agent_id"] = claim.GetClaimsFromEchoContext(c).UserID + req.Filter["status"] = entity.KindBoxReqAssignedSenderAgentStatus.String() + + resp, sErr := h.adminKindBoxReqSvc.GetAllAwaitingDelivery(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/admin/kind_box_req/route.go b/delivery/http_server/admin/kind_box_req/route.go index be36b24..d45c264 100644 --- a/delivery/http_server/admin/kind_box_req/route.go +++ b/delivery/http_server/admin/kind_box_req/route.go @@ -16,4 +16,5 @@ func (h Handler) SetRoutes(e *echo.Echo) { 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)) } diff --git a/docs/docs.go b/docs/docs.go index dbc927c..a20fb41 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -416,6 +416,135 @@ const docTemplate = `{ } } }, + "/admin/kindboxreqs/awaiting-delivery": { + "get": { + "security": [ + { + "AuthBearerAdmin": [] + } + ], + "description": "Retrieves a list of all awaiting KindBox requests with filtering, sorting, and pagination options", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "KindBoxReq" + ], + "summary": "Get all awaiting delivery KindBox requests", + "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" + }, + { + "enum": [ + 1, + 2, + 3 + ], + "type": "integer", + "format": "enum", + "description": "Filter by KindBox type", + "name": "filter_kind_box_type", + "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": "integer", + "description": "Page number", + "name": "page_number", + "in": "query" + }, + { + "type": "integer", + "description": "Page size", + "name": "page_size", + "in": "query" + }, + { + "enum": [ + "id", + "benefactor_id", + "kind_box_type", + "count_requested", + "count_accepted", + "deliver_refer_time_id", + "deliver_refer_date", + "deliver_address_id" + ], + "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.DeliveryAwaitingGetAllResponse" + } + }, + "400": { + "description": "Bad request", + "schema": { + "type": "string" + } + } + } + } + }, "/admin/kindboxreqs/awaiting-delivery/{id}": { "get": { "security": [ @@ -1073,6 +1202,20 @@ const docTemplate = `{ "adminkindboxreqparam.DeliverKindBoxReqResponse": { "type": "object" }, + "adminkindboxreqparam.DeliveryAwaitingGetAllResponse": { + "type": "object", + "properties": { + "all_awaiting_kind_box_req": { + "type": "array", + "items": { + "$ref": "#/definitions/entity.KindBoxReq" + } + }, + "pagination": { + "$ref": "#/definitions/param.PaginationResponse" + } + } + }, "adminkindboxreqparam.DeliveryAwaitingGetResponse": { "type": "object", "properties": { @@ -1148,7 +1291,7 @@ const docTemplate = `{ "adminkindboxreqparam.KindBoxReqGetAllResponse": { "type": "object", "properties": { - "all_kind_box_req": { + "all_awaiting_kind_box_req": { "type": "array", "items": { "$ref": "#/definitions/entity.KindBoxReq" diff --git a/docs/swagger.json b/docs/swagger.json index 567dc95..a0d8720 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -405,6 +405,135 @@ } } }, + "/admin/kindboxreqs/awaiting-delivery": { + "get": { + "security": [ + { + "AuthBearerAdmin": [] + } + ], + "description": "Retrieves a list of all awaiting KindBox requests with filtering, sorting, and pagination options", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "KindBoxReq" + ], + "summary": "Get all awaiting delivery KindBox requests", + "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" + }, + { + "enum": [ + 1, + 2, + 3 + ], + "type": "integer", + "format": "enum", + "description": "Filter by KindBox type", + "name": "filter_kind_box_type", + "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": "integer", + "description": "Page number", + "name": "page_number", + "in": "query" + }, + { + "type": "integer", + "description": "Page size", + "name": "page_size", + "in": "query" + }, + { + "enum": [ + "id", + "benefactor_id", + "kind_box_type", + "count_requested", + "count_accepted", + "deliver_refer_time_id", + "deliver_refer_date", + "deliver_address_id" + ], + "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.DeliveryAwaitingGetAllResponse" + } + }, + "400": { + "description": "Bad request", + "schema": { + "type": "string" + } + } + } + } + }, "/admin/kindboxreqs/awaiting-delivery/{id}": { "get": { "security": [ @@ -1062,6 +1191,20 @@ "adminkindboxreqparam.DeliverKindBoxReqResponse": { "type": "object" }, + "adminkindboxreqparam.DeliveryAwaitingGetAllResponse": { + "type": "object", + "properties": { + "all_awaiting_kind_box_req": { + "type": "array", + "items": { + "$ref": "#/definitions/entity.KindBoxReq" + } + }, + "pagination": { + "$ref": "#/definitions/param.PaginationResponse" + } + } + }, "adminkindboxreqparam.DeliveryAwaitingGetResponse": { "type": "object", "properties": { @@ -1137,7 +1280,7 @@ "adminkindboxreqparam.KindBoxReqGetAllResponse": { "type": "object", "properties": { - "all_kind_box_req": { + "all_awaiting_kind_box_req": { "type": "array", "items": { "$ref": "#/definitions/entity.KindBoxReq" diff --git a/docs/swagger.yaml b/docs/swagger.yaml index 758d76e..70d2a08 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -81,6 +81,15 @@ definitions: type: object adminkindboxreqparam.DeliverKindBoxReqResponse: type: object + adminkindboxreqparam.DeliveryAwaitingGetAllResponse: + properties: + all_awaiting_kind_box_req: + items: + $ref: '#/definitions/entity.KindBoxReq' + type: array + pagination: + $ref: '#/definitions/param.PaginationResponse' + type: object adminkindboxreqparam.DeliveryAwaitingGetResponse: properties: benefactorID: @@ -130,7 +139,7 @@ definitions: type: object adminkindboxreqparam.KindBoxReqGetAllResponse: properties: - all_kind_box_req: + all_awaiting_kind_box_req: items: $ref: '#/definitions/entity.KindBoxReq' type: array @@ -826,6 +835,95 @@ paths: summary: Admin Assign Sender Agent to kindboxreq tags: - KindBoxReq + /admin/kindboxreqs/awaiting-delivery: + get: + consumes: + - application/json + description: Retrieves a list of all awaiting 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 KindBox type + enum: + - 1 + - 2 + - 3 + format: enum + in: query + name: filter_kind_box_type + 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: 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 + - kind_box_type + - count_requested + - count_accepted + - deliver_refer_time_id + - deliver_refer_date + - deliver_address_id + 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.DeliveryAwaitingGetAllResponse' + "400": + description: Bad request + schema: + type: string + security: + - AuthBearerAdmin: [] + summary: Get all awaiting delivery KindBox requests + tags: + - KindBoxReq /admin/kindboxreqs/awaiting-delivery/{id}: get: consumes: diff --git a/param/admin/kind_box_req/get_all.go b/param/admin/kind_box_req/get_all.go index 8a95b05..4973b37 100644 --- a/param/admin/kind_box_req/get_all.go +++ b/param/admin/kind_box_req/get_all.go @@ -1,13 +1,17 @@ package adminkindboxreqparam import ( - entity "git.gocasts.ir/ebhomengo/niki/entity" - paginationparam "git.gocasts.ir/ebhomengo/niki/param" + "git.gocasts.ir/ebhomengo/niki/entity" + "git.gocasts.ir/ebhomengo/niki/param" ) -type KindBoxReqGetAllRequest struct{} +type KindBoxReqGetAllRequest struct { + Pagination param.PaginationRequest + Sort param.SortRequest + Filter param.FilterRequest +} type KindBoxReqGetAllResponse struct { - AllKindBoxReq []entity.KindBoxReq `json:"all_kind_box_req"` - Pagination paginationparam.PaginationResponse `json:"pagination"` + AllKindBoxReq []entity.KindBoxReq `json:"all_awaiting_kind_box_req"` + Pagination param.PaginationResponse `json:"pagination"` } diff --git a/param/admin/kind_box_req/get_all_delivery_awaiting.go b/param/admin/kind_box_req/get_all_delivery_awaiting.go new file mode 100644 index 0000000..7365289 --- /dev/null +++ b/param/admin/kind_box_req/get_all_delivery_awaiting.go @@ -0,0 +1,17 @@ +package adminkindboxreqparam + +import ( + "git.gocasts.ir/ebhomengo/niki/entity" + "git.gocasts.ir/ebhomengo/niki/param" +) + +type DeliveryAwaitingGetAllRequest struct { + Pagination param.PaginationRequest + Sort param.SortRequest + Filter param.FilterRequest +} + +type DeliveryAwaitingGetAllResponse struct { + AllAwaitingKindBoxReq []entity.KindBoxReq `json:"all_awaiting_kind_box_req"` + Pagination param.PaginationResponse `json:"pagination"` +} diff --git a/param/filter.go b/param/filter.go new file mode 100644 index 0000000..62026b9 --- /dev/null +++ b/param/filter.go @@ -0,0 +1,3 @@ +package param + +type FilterRequest map[string]any diff --git a/param/pagination.go b/param/pagination.go index 5657036..8e427ec 100644 --- a/param/pagination.go +++ b/param/pagination.go @@ -2,12 +2,12 @@ package param const ( defaultPageNumber = 1 - dafaultPageSize = 10 + defaultPageSize = 10 ) type PaginationRequest struct { - PageSize uint - PageNumber uint + PageSize uint `query:"page_size" example:"10"` + PageNumber uint `query:"page_number" example:"1"` } type PaginationResponse struct { @@ -32,9 +32,10 @@ func (p *PaginationRequest) GetPageSize() uint { validPageSizes := []uint{10, 25, 50, 100} for _, size := range validPageSizes { if p.PageSize == size { - return size + return p.PageSize } } + p.PageSize = defaultPageSize - return dafaultPageSize + return p.PageSize } diff --git a/param/sort.go b/param/sort.go new file mode 100644 index 0000000..e97324f --- /dev/null +++ b/param/sort.go @@ -0,0 +1,13 @@ +package param + +type SortDirection string + +const ( + AscSortDirection = SortDirection("asc") + DescSortDirection = SortDirection("desc") +) + +type SortRequest struct { + Field string `query:"sort_field"` + Direction SortDirection `query:"sort_direction"` +} diff --git a/pkg/err_msg/message.go b/pkg/err_msg/message.go index ec38276..1f77364 100644 --- a/pkg/err_msg/message.go +++ b/pkg/err_msg/message.go @@ -21,12 +21,16 @@ const ( ErrorMsgAssignSenderAgentKindBoxReqStatus = "only accepted kind_box_reqs will have the ability to be assign sender agent" ErrorMsgDeliverKindBoxReqStatus = "only assigned requests will have the ability to be delivered" ErrorMsgAdminIsNotAgent = "admin is not agent" - ErrorMsgCountAcceptedOverflow = "count accepted is greater than count requested" - ErrorMsgCantInsertRecord = "can't insert record" - ErrorMsgCantRetrieveLastInsertID = "can't retrieve last insert id" - ErrorMsgCantUpdateRecord = "can't update record" + ErrorMsgCountAcceptedOverflow = "count accepted is greater than count requested" + ErrorMsgCantInsertRecord = "can't insert record" + ErrorMsgCantRetrieveLastInsertID = "can't retrieve last insert id" + ErrorMsgCantUpdateRecord = "can't update record" ErrorMsgReferTimeNotFound = "refer time not found" ErrorMsgReferTimeIsNotActive = "refer time is not active" ErrorMsgKindBoxReqDoesntBelongToBenefactor = "kind box req doesnt belong to benefactor" ErrorMsgCantDeleteAddress = "can't delete address" + ErrorMsgFiltersAreNotValid = "filters are not valid" + ErrorMsgSortFieldIsRequired = "sort field is required" + ErrorMsgSortDirectionShouldBeAscOrDesc = "sort direction should be asc or desc" + ErrorMsgSortFieldIsNotValid = "sort field is not valid" ) diff --git a/pkg/query_builder/mysql/filter.go b/pkg/query_builder/mysql/filter.go new file mode 100644 index 0000000..aab04fe --- /dev/null +++ b/pkg/query_builder/mysql/filter.go @@ -0,0 +1,17 @@ +package mysqlquerybuilder + +import "fmt" + +func BuildFilterQuery(filter map[string]interface{}) (string, []any) { + var ( + filterQuery string + args = []any{} + ) + + for key, value := range filter { + filterQuery += fmt.Sprintf("AND %s = ? ", key) + args = append(args, value) + } + + return filterQuery, args +} diff --git a/pkg/query_builder/mysql/get_all.go b/pkg/query_builder/mysql/get_all.go new file mode 100644 index 0000000..ad3368c --- /dev/null +++ b/pkg/query_builder/mysql/get_all.go @@ -0,0 +1,31 @@ +package mysqlquerybuilder + +import ( + "fmt" + + "git.gocasts.ir/ebhomengo/niki/param" +) + +func BuildGetAllQuery(baseQuery string, filter param.FilterRequest, pagination param.PaginationRequest, sort param.SortRequest) (string, []any) { + + filterQuery, fArgs := BuildFilterQuery(filter) + paginationQuery, pArgs := BuildPaginationQuery(pagination) + sortQuery := BuildSortQuery(sort) + + args := []any{} + args = append(args, fArgs...) + args = append(args, pArgs...) + + query := baseQuery + if filterQuery != "" { + query = fmt.Sprintf("%s %s", query, filterQuery) + } + if sortQuery != "" { + query = fmt.Sprintf("%s %s", query, sortQuery) + } + if paginationQuery != "" { + query = fmt.Sprintf("%s %s", query, paginationQuery) + } + + return query, args +} diff --git a/pkg/query_builder/mysql/pagination.go b/pkg/query_builder/mysql/pagination.go new file mode 100644 index 0000000..0399e44 --- /dev/null +++ b/pkg/query_builder/mysql/pagination.go @@ -0,0 +1,9 @@ +package mysqlquerybuilder + +import ( + "git.gocasts.ir/ebhomengo/niki/param" +) + +func BuildPaginationQuery(pagination param.PaginationRequest) (string, []any) { + return "LIMIT ? OFFSET ?", []any{pagination.GetPageSize(), pagination.GetOffset()} +} diff --git a/pkg/query_builder/mysql/sort.go b/pkg/query_builder/mysql/sort.go new file mode 100644 index 0000000..6880c3b --- /dev/null +++ b/pkg/query_builder/mysql/sort.go @@ -0,0 +1,14 @@ +package mysqlquerybuilder + +import ( + "fmt" + + "git.gocasts.ir/ebhomengo/niki/param" +) + +func BuildSortQuery(sort param.SortRequest) string { + if sort.Field == "" && sort.Direction == "" { + return "" + } + return fmt.Sprintf("ORDER BY %s %s", sort.Field, sort.Direction) +} diff --git a/pkg/query_param/echo.go b/pkg/query_param/echo.go new file mode 100644 index 0000000..251f4b4 --- /dev/null +++ b/pkg/query_param/echo.go @@ -0,0 +1,18 @@ +package queryparam + +import ( + "strings" + + "github.com/labstack/echo/v4" +) + +func GetFilterParams(c echo.Context) map[string]any { + queryParams := make(map[string]any) + for key, values := range c.QueryParams() { + if len(values) > 0 && strings.HasPrefix(key, "filter_") { + queryParams[strings.TrimPrefix(key, "filter_")] = values[0] + } + } + + return queryParams +} diff --git a/repository/mysql/kind_box_req/get_all.go b/repository/mysql/kind_box_req/get_all.go index 8d452f6..4e8a40b 100644 --- a/repository/mysql/kind_box_req/get_all.go +++ b/repository/mysql/kind_box_req/get_all.go @@ -2,68 +2,48 @@ package mysqlkindboxreq import ( "context" + "fmt" + "git.gocasts.ir/ebhomengo/niki/param" + builder "git.gocasts.ir/ebhomengo/niki/pkg/query_builder/mysql" "git.gocasts.ir/ebhomengo/niki/entity" - paginationparam "git.gocasts.ir/ebhomengo/niki/param" errmsg "git.gocasts.ir/ebhomengo/niki/pkg/err_msg" richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error" ) -func (d DB) GetAllKindBoxReq(ctx context.Context, pagination paginationparam.PaginationRequest) ([]entity.KindBoxReq, paginationparam.PaginationResponse, error) { +func (d DB) GetAllKindBoxReq(ctx context.Context, filter param.FilterRequest, pagination param.PaginationRequest, sort param.SortRequest) ([]entity.KindBoxReq, uint, error) { const op = "mysqlkindboxreq.GetAllKindBoxReq" - // TODO: create getCount function - var count uint - rows, err := d.conn.Conn().QueryContext(ctx, "SELECT COUNT(*) FROM kind_box_reqs where deleted_at is null") - if err != nil { - return nil, paginationparam.PaginationResponse{}, - richerror.New(op).WithMessage(errmsg.ErrorMsgSomethingWentWrong).WithErr(err).WithKind(richerror.KindUnexpected) + baseQuery := `SELECT * FROM kind_box_reqs WHERE deleted_at IS NULL` + query, args := builder.BuildGetAllQuery(baseQuery, filter, pagination, sort) + rows, qErr := d.conn.Conn().QueryContext(ctx, query, args...) + if qErr != nil { + return nil, 0, richerror.New(op).WithErr(qErr).WithMessage(errmsg.ErrorMsgSomethingWentWrong).WithKind(richerror.KindUnexpected) } defer rows.Close() - - // Iterate through the rows (should only be one) and extract the count: - for rows.Next() { - err := rows.Scan(&count) - if err != nil { - panic(err) - } - } - - if rErr := rows.Err(); rErr != nil { - return nil, paginationparam.PaginationResponse{}, richerror.New(op).WithErr(rErr). - WithMessage(errmsg.ErrorMsgSomethingWentWrong).WithKind(richerror.KindUnexpected) - } - - // TODO - add sort and filter - rows, err = d.conn.Conn().QueryContext(ctx, "select * from kind_box_reqs where deleted_at is null limit ? offset ?", pagination.GetPageSize(), pagination.GetOffset()) - if err != nil { - return nil, paginationparam.PaginationResponse{}, - richerror.New(op).WithMessage(errmsg.ErrorMsgSomethingWentWrong).WithErr(err).WithKind(richerror.KindUnexpected) - } - - defer rows.Close() - - // An album slice to hold data from returned rows. - var kindBoxReqs []entity.KindBoxReq - - // Loop through rows, using Scan to assign column data to struct fields. + kindBoxReqs := make([]entity.KindBoxReq, 0) for rows.Next() { kindBoxReq, sErr := scanKindBoxReq(rows) if sErr != nil { - return nil, paginationparam.PaginationResponse{}, richerror.New(op).WithErr(sErr). + fmt.Println(sErr) + return nil, 0, richerror.New(op).WithErr(sErr). WithMessage(errmsg.ErrorMsgCantScanQueryResult).WithKind(richerror.KindUnexpected) } kindBoxReqs = append(kindBoxReqs, kindBoxReq) } if rErr := rows.Err(); rErr != nil { - return nil, paginationparam.PaginationResponse{}, richerror.New(op).WithErr(rErr). + return nil, 0, richerror.New(op).WithErr(rErr). WithMessage(errmsg.ErrorMsgSomethingWentWrong).WithKind(richerror.KindUnexpected) } - return kindBoxReqs, paginationparam.PaginationResponse{ - PageSize: pagination.GetPageSize(), - PageNumber: pagination.GetPageNumber(), - Total: count, - }, nil + var total uint + baseQuery = `SELECT COUNT(*) FROM kind_box_reqs WHERE deleted_at IS NULL` + query, args = builder.BuildGetAllQuery(baseQuery, filter, pagination, sort) + qErr = d.conn.Conn().QueryRowContext(ctx, query, args...).Scan(&total) + if qErr != nil { + return nil, 0, richerror.New(op).WithErr(qErr).WithMessage(errmsg.ErrorMsgSomethingWentWrong).WithKind(richerror.KindUnexpected) + } + + return kindBoxReqs, total, nil } diff --git a/repository/mysql/kind_box_req/scan.go b/repository/mysql/kind_box_req/scan.go index 530a79c..5dcf1ca 100644 --- a/repository/mysql/kind_box_req/scan.go +++ b/repository/mysql/kind_box_req/scan.go @@ -30,6 +30,7 @@ func scanKindBoxReq(scanner mysql.Scanner) (entity.KindBoxReq, error) { &countAccepted, &description, &status, + &kindBoxReq.DeliverReferTimeID, &kindBoxReq.DeliverReferDate, &kindBoxReq.DeliverAddressID, &senderAgentID, diff --git a/service/admin/kind_box_req/get_all.go b/service/admin/kind_box_req/get_all.go index 9208e55..8c5f959 100644 --- a/service/admin/kind_box_req/get_all.go +++ b/service/admin/kind_box_req/get_all.go @@ -8,11 +8,10 @@ import ( richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error" ) -// TODO: Pagination, Filters, Sort. -func (s Service) GetAll(ctx context.Context, _ param.KindBoxReqGetAllRequest, paginationreq paginationparam.PaginationRequest) (param.KindBoxReqGetAllResponse, error) { +func (s Service) GetAll(ctx context.Context, req param.KindBoxReqGetAllRequest) (param.KindBoxReqGetAllResponse, error) { const op = "adminkindboxreqservice.GetAll" - allKindBoxReq, pagination, err := s.repo.GetAllKindBoxReq(ctx, paginationreq) + allKindBoxReq, total, err := s.repo.GetAllKindBoxReq(ctx, req.Filter, req.Pagination, req.Sort) if err != nil { return param.KindBoxReqGetAllResponse{}, richerror.New(op).WithErr(err).WithKind(richerror.KindUnexpected) } @@ -20,9 +19,9 @@ func (s Service) GetAll(ctx context.Context, _ param.KindBoxReqGetAllRequest, pa return param.KindBoxReqGetAllResponse{ AllKindBoxReq: allKindBoxReq, Pagination: paginationparam.PaginationResponse{ - PageSize: pagination.PageSize, - PageNumber: pagination.PageNumber, - Total: pagination.Total, + PageSize: req.Pagination.GetPageSize(), + PageNumber: req.Pagination.GetPageNumber(), + Total: total, }, }, nil } diff --git a/service/admin/kind_box_req/get_all_delivery_awaiting.go b/service/admin/kind_box_req/get_all_delivery_awaiting.go new file mode 100644 index 0000000..a2be8fd --- /dev/null +++ b/service/admin/kind_box_req/get_all_delivery_awaiting.go @@ -0,0 +1,28 @@ +package adminkindboxreqservice + +import ( + "context" + + paginationparam "git.gocasts.ir/ebhomengo/niki/param" + param "git.gocasts.ir/ebhomengo/niki/param/admin/kind_box_req" + richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error" +) + +func (s Service) GetAllAwaitingDelivery(ctx context.Context, req param.DeliveryAwaitingGetAllRequest) (param.DeliveryAwaitingGetAllResponse, error) { + const op = "adminkindboxreqservice.GetAllAwaitingDelivery" + + allAwaitingKindBoxReq, total, err := s.repo.GetAllKindBoxReq(ctx, req.Filter, req.Pagination, req.Sort) + if err != nil { + + return param.DeliveryAwaitingGetAllResponse{}, richerror.New(op).WithErr(err) + } + + return param.DeliveryAwaitingGetAllResponse{ + AllAwaitingKindBoxReq: allAwaitingKindBoxReq, + Pagination: paginationparam.PaginationResponse{ + PageSize: req.Pagination.GetPageSize(), + PageNumber: req.Pagination.GetPageNumber(), + Total: total, + }, + }, nil +} diff --git a/service/admin/kind_box_req/service.go b/service/admin/kind_box_req/service.go index 1a51878..4d7cc95 100644 --- a/service/admin/kind_box_req/service.go +++ b/service/admin/kind_box_req/service.go @@ -4,7 +4,7 @@ import ( "context" "git.gocasts.ir/ebhomengo/niki/entity" - paginationparam "git.gocasts.ir/ebhomengo/niki/param" + params "git.gocasts.ir/ebhomengo/niki/param" param "git.gocasts.ir/ebhomengo/niki/param/admin/kind_box" ) @@ -13,9 +13,9 @@ type Repository interface { GetByID(ctx context.Context, id uint) (entity.KindBoxReq, error) RejectKindBoxReq(ctx context.Context, kindBoxReqID uint, description string) error RollbackKindBoxRequestStatus(ctx context.Context, id uint) error - GetAllKindBoxReq(ctx context.Context, pagination paginationparam.PaginationRequest) ([]entity.KindBoxReq, paginationparam.PaginationResponse, error) AssignSenderAgentToKindBoxReq(ctx context.Context, kindBoxReqID uint, senderAgentID uint) error DeliverKindBoxReq(ctx context.Context, kindBoxReqID uint) error + GetAllKindBoxReq(ctx context.Context, filter params.FilterRequest, pagination params.PaginationRequest, sort params.SortRequest) ([]entity.KindBoxReq, uint, error) GetAwaitingDeliveryByAgent(ctx context.Context, kindBoxReqID uint, agentID uint) (entity.KindBoxReq, error) } diff --git a/validator/admin/kind_box_req/get_all_delivery_awaiting.go b/validator/admin/kind_box_req/get_all_delivery_awaiting.go new file mode 100644 index 0000000..1925aaf --- /dev/null +++ b/validator/admin/kind_box_req/get_all_delivery_awaiting.go @@ -0,0 +1,43 @@ +package adminkindboxreqvalidator + +import ( + "errors" + + kbrparam "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" + validation "github.com/go-ozzo/ozzo-validation/v4" +) + +func (v Validator) ValidateGetAllAwaitingDelivery(req kbrparam.DeliveryAwaitingGetAllRequest) (map[string]string, error) { + const op = "adminkindboxreqvalidator.ValidateGetAllAwaitingDelivery" + validFields := []string{ + "id", "benefactor_id", "kind_box_type", + "count_requested", "count_accepted", + "deliver_refer_time_id", "deliver_refer_date", "deliver_address_id", + } + if err := validation.ValidateStruct(&req, + validation.Field(&req.Filter, validation.By(v.areFilterFieldsValid(validFields))), + validation.Field(&req.Sort, validation.By(v.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/admin/kind_box_req/validator.go b/validator/admin/kind_box_req/validator.go index 8ca688f..961c4ca 100644 --- a/validator/admin/kind_box_req/validator.go +++ b/validator/admin/kind_box_req/validator.go @@ -4,8 +4,10 @@ import ( "context" "errors" "fmt" + "slices" "git.gocasts.ir/ebhomengo/niki/entity" + params "git.gocasts.ir/ebhomengo/niki/param" param "git.gocasts.ir/ebhomengo/niki/param/admin/admin" errmsg "git.gocasts.ir/ebhomengo/niki/pkg/err_msg" validation "github.com/go-ozzo/ozzo-validation/v4" @@ -82,6 +84,7 @@ func (v Validator) CheckKindBoxReqStatusForRejecting(value interface{}) error { return nil } + func (v Validator) checkKindBoxReqStatusForDelivering(value interface{}) error { kindboxreqID, ok := value.(uint) if !ok { @@ -97,6 +100,7 @@ func (v Validator) checkKindBoxReqStatusForDelivering(value interface{}) error { return nil } + func (v Validator) checkKindBoxReqStatusForAssigningSenderAgent(value interface{}) error { kindboxreqID, ok := value.(uint) if !ok { @@ -147,3 +151,37 @@ func (v Validator) doesAgentAdminExist(value interface{}) error { return nil } + +func (v Validator) 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 + } +} + +func (v Validator) 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 + } +}