forked from ebhomengo/niki
1
0
Fork 0

feat(service): add admin kind_box_req assign sender agent endpoint.

This commit is contained in:
Iman Mirazimi 2024-02-21 00:04:51 +03:30
parent 0d54a3765b
commit 17b7c4beb2
44 changed files with 256 additions and 53 deletions

View File

@ -1 +0,0 @@
package adminkindboxhandler

View File

@ -1 +0,0 @@
package adminkindboxhandler

View File

@ -1 +0,0 @@
package adminkindboxhandler

View File

@ -1 +0,0 @@
package adminkindboxhandler

View File

@ -1 +0,0 @@
package adminkindboxreqhandler

View File

@ -0,0 +1,46 @@
package adminkindboxreqhandler
import (
"net/http"
"strconv"
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"
echo "github.com/labstack/echo/v4"
)
func (h Handler) AssignSenderAgent(c echo.Context) error {
var req param.AssignSenderRequest
if bErr := c.Bind(&req); bErr != nil {
return echo.NewHTTPError(http.StatusBadRequest)
}
id, cErr := strconv.ParseUint(c.Param("id"), 10, 64)
if cErr != nil {
return c.JSON(http.StatusBadRequest, errmsg.ErrorMsgInvalidInput)
}
req.KindBoxReqID = uint(id)
if fieldErrors, err := h.adminKindBoxReqVld.ValidateAssignSenderAgent(req); err != nil {
msg, code := httpmsg.Error(err)
return c.JSON(code, echo.Map{
"message": msg,
"errors": fieldErrors,
})
}
resp, sErr := h.adminKindBoxReqSvc.AssignSenderAgent(c.Request().Context(), req)
if sErr != nil {
msg, code := httpmsg.Error(sErr)
return echo.NewHTTPError(code, msg)
}
return c.JSON(http.StatusOK, resp)
}

View File

@ -1 +0,0 @@
package adminkindboxreqhandler

View File

@ -12,5 +12,6 @@ func (h Handler) SetRoutes(e *echo.Echo) {
r.PATCH("/accept-kind-box-req/:id", h.Accept) r.PATCH("/accept-kind-box-req/:id", h.Accept)
r.PATCH("/reject-kind-box-req/:id", h.Reject) r.PATCH("/reject-kind-box-req/:id", h.Reject)
r.PATCH("/deliver-kind-box-req/:id", h.Deliver) r.PATCH("/deliver-kind-box-req/:id", h.Deliver)
r.PATCH("/assign-sender-agent/:id", h.AssignSenderAgent)
r.GET("/", h.GetAll, middleware.Auth(h.authSvc, h.authConfig)) r.GET("/", h.GetAll, middleware.Auth(h.authSvc, h.authConfig))
} }

View File

@ -1 +0,0 @@
package adminkindboxreqhandler

View File

@ -1 +0,0 @@
package benefactorkindboxreqhandler

View File

@ -1 +0,0 @@
package benefactorkindboxreqhandler

13
param/admin/admin/get.go Normal file
View File

@ -0,0 +1,13 @@
package adminserviceparam
import (
"git.gocasts.ir/ebhomengo/niki/entity"
)
type AdminExistByIDRequest struct {
AdminID uint
}
type AdminExistByIDResponse struct {
Admin entity.Admin
}

View File

@ -0,0 +1,8 @@
package adminkindboxreqparam
type AssignSenderRequest struct {
KindBoxReqID uint `json:"kind_box_req_id"`
SenderAgentID uint `json:"sender_agent_id"`
}
type AssignSenderResponse struct{}

View File

@ -1,21 +1,23 @@
package errmsg package errmsg
const ( const (
ErrorMsgNotFound = "record not found" ErrorMsgNotFound = "record not found"
ErrorMsgSomethingWentWrong = "something went wrong" ErrorMsgSomethingWentWrong = "something went wrong"
ErrorMsgInvalidInput = "invalid input" ErrorMsgInvalidInput = "invalid input"
ErrorMsgInvalidStatus = "invalid status" ErrorMsgInvalidStatus = "invalid status"
ErrorMsgPhoneNumberIsNotUnique = "phone number is not unique" ErrorMsgPhoneNumberIsNotUnique = "phone number is not unique"
ErrorMsgEmailIsNotUnique = "email is not unique" ErrorMsgEmailIsNotUnique = "email is not unique"
ErrorMsgPhoneNumberIsNotValid = "phone number is not valid" ErrorMsgPhoneNumberIsNotValid = "phone number is not valid"
ErrorMsgUserNotAllowed = "user not allowed" ErrorMsgUserNotAllowed = "user not allowed"
ErrorMsgUserNotFound = "benefactor not found" ErrorMsgUserNotFound = "benefactor not found"
ErrorMsgOtpCodeExist = "please wait a little bit" ErrorMsgOtpCodeExist = "please wait a little bit"
ErrorMsgOtpCodeIsNotValid = "verification code is not valid" ErrorMsgOtpCodeIsNotValid = "verification code is not valid"
ErrorMsgCantScanQueryResult = "can't scan query result" ErrorMsgCantScanQueryResult = "can't scan query result"
ErrorMsgPhoneNumberOrPassIsIncorrect = "phone number or password is incorrect" ErrorMsgPhoneNumberOrPassIsIncorrect = "phone number or password is incorrect"
ErrBadRequest = "Bad request" ErrBadRequest = "Bad request"
ErrorMsgAcceptKindBoxReqStatus = "only pending requests will have the ability to be confirmed" ErrorMsgAcceptKindBoxReqStatus = "only pending requests will have the ability to be confirmed"
ErrorMsgRejectKindBoxReqStatus = "only pending requests will have the ability to be rejected" ErrorMsgRejectKindBoxReqStatus = "only pending requests will have the ability to be rejected"
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" ErrorMsgDeliverKindBoxReqStatus = "only assigned requests will have the ability to be delivered"
ErrorMsgAdminIsNotAgent = "admin is not agent"
) )

View File

@ -5,6 +5,7 @@ import (
"database/sql" "database/sql"
"errors" "errors"
entity "git.gocasts.ir/ebhomengo/niki/entity"
errmsg "git.gocasts.ir/ebhomengo/niki/pkg/err_msg" errmsg "git.gocasts.ir/ebhomengo/niki/pkg/err_msg"
richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error" richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error"
) )
@ -52,3 +53,25 @@ func (d DB) AdminExistByEmail(ctx context.Context, email string) (bool, error) {
return true, nil return true, nil
} }
func (d DB) GetAdminByID(ctx context.Context, adminID uint) (entity.Admin, error) {
const op = "mysqladmin.GetAdminByID"
row := d.conn.Conn().QueryRowContext(ctx, `select * from admins where id = ?`, adminID)
admin, err := scanAdmin(row)
if err != nil {
sErr := sql.ErrNoRows
//TODO-errorsas: second argument to errors.As should not be *error
//nolint
if errors.As(err, &sErr) {
return entity.Admin{}, nil
}
// TODO - log unexpected error for better observability
return entity.Admin{}, richerror.New(op).WithErr(err).
WithMessage(errmsg.ErrorMsgCantScanQueryResult).WithKind(richerror.KindUnexpected)
}
return admin, nil
}

View File

@ -91,18 +91,14 @@ func mapNotNullToBenefactor(data nullableFields, benefactor *entity.Benefactor)
if data.lastName.Valid { if data.lastName.Valid {
benefactor.LastName = data.lastName.String benefactor.LastName = data.lastName.String
} }
//if data.address.Valid {
// benefactor.Address = data.address.String
//}
if data.description.Valid { if data.description.Valid {
benefactor.Description = data.description.String benefactor.Description = data.description.String
} }
if data.email.Valid { if data.email.Valid {
benefactor.Email = data.email.String benefactor.Email = data.email.String
} }
//if data.city.Valid {
// benefactor.City = data.city.String
//}
if data.genderStr.Valid { if data.genderStr.Valid {
benefactor.Gender = entity.MapToGender(data.genderStr.String) benefactor.Gender = entity.MapToGender(data.genderStr.String)
} }

View File

@ -0,0 +1,23 @@
package mysqlkindboxreq
import (
"context"
"time"
entity "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) AssignSenderAgentToKindBoxReq(ctx context.Context, kindBoxReqID, senderAgentID uint) error {
const op = "mysqlkindboxreq.AssignSenderAgentToKindBoxReq"
_, err := d.conn.Conn().ExecContext(ctx, `update kind_box_reqs set sender_agent_id = ?, status = ?, updated_at= ? where id = ?`,
senderAgentID, entity.KindBoxReqAssignedSenderAgentStatus.String(), time.Now(), kindBoxReqID)
if err != nil {
return richerror.New(op).WithErr(err).
WithMessage(errmsg.ErrorMsgSomethingWentWrong).WithKind(richerror.KindUnexpected)
}
return nil
}

View File

@ -1,8 +1,8 @@
-- +migrate Up -- +migrate Up
-- what can we do for password? -- what can we do for password?
INSERT INTO `admins` (`id`, `phone_number`, `email`,`password`,`role`,`status`) INSERT INTO `admins` (`id`, `phone_number`, `email`,`password`,`role`,`status`)
VALUES VALUES
(1, '09122702856', 'keshvari@gmail.com','Abc123456','super-admin','active'); (1, '09122702856', 'keshvari@gmail.com','Abc123456','super-admin','active');
-- +migrate Down -- +migrate Down
DELETE DELETE

View File

@ -0,0 +1,19 @@
package adminservice
import (
"context"
param "git.gocasts.ir/ebhomengo/niki/param/admin/admin"
richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error"
)
func (s Service) AdminExistByID(ctx context.Context, req param.AdminExistByIDRequest) (param.AdminExistByIDResponse, error) {
const op = "adminservice.AdminExistByID"
admin, err := s.repo.GetAdminByID(ctx, req.AdminID)
if err != nil {
return param.AdminExistByIDResponse{}, richerror.New(op).WithErr(err).WithKind(richerror.KindUnexpected)
}
return param.AdminExistByIDResponse{Admin: admin}, nil
}

View File

@ -17,6 +17,7 @@ type AuthGenerator interface {
type Repository interface { type Repository interface {
AddAdmin(ctx context.Context, admin entity.Admin) (entity.Admin, error) AddAdmin(ctx context.Context, admin entity.Admin) (entity.Admin, error)
GetAdminByPhoneNumber(ctx context.Context, phoneNumber string) (entity.Admin, error) GetAdminByPhoneNumber(ctx context.Context, phoneNumber string) (entity.Admin, error)
GetAdminByID(ctx context.Context, adminID uint) (entity.Admin, error)
} }
type Service struct { type Service struct {

View File

@ -1 +0,0 @@
package adminkindboxservice

View File

@ -1 +0,0 @@
package adminkindboxservice

View File

@ -1 +0,0 @@
package adminkindboxservice

View File

@ -1 +0,0 @@
package adminkindboxservice

View File

@ -1 +0,0 @@
package adminkindboxreqservice

View File

@ -0,0 +1,19 @@
package adminkindboxreqservice
import (
"context"
param "git.gocasts.ir/ebhomengo/niki/param/admin/kind_box_req"
richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error"
)
func (s Service) AssignSenderAgent(ctx context.Context, req param.AssignSenderRequest) (param.AssignSenderResponse, error) {
const op = "adminkindboxreqservice.AssignSenderAgent"
err := s.repo.AssignSenderAgentToKindBoxReq(ctx, req.KindBoxReqID, req.SenderAgentID)
if err != nil {
return param.AssignSenderResponse{}, richerror.New(op).WithErr(err).WithKind(richerror.KindUnexpected)
}
return param.AssignSenderResponse{}, nil
}

View File

@ -1 +0,0 @@
package adminkindboxreqservice

View File

@ -1 +0,0 @@
package adminkindboxreqservice

View File

@ -3,7 +3,7 @@ package adminkindboxreqservice
import ( import (
"context" "context"
entity "git.gocasts.ir/ebhomengo/niki/entity" "git.gocasts.ir/ebhomengo/niki/entity"
paginationparam "git.gocasts.ir/ebhomengo/niki/param" paginationparam "git.gocasts.ir/ebhomengo/niki/param"
param "git.gocasts.ir/ebhomengo/niki/param/admin/kind_box" param "git.gocasts.ir/ebhomengo/niki/param/admin/kind_box"
) )
@ -14,6 +14,7 @@ type Repository interface {
RejectKindBoxReq(ctx context.Context, kindBoxReqID uint, description string) error RejectKindBoxReq(ctx context.Context, kindBoxReqID uint, description string) error
RollbackKindBoxRequestStatus(ctx context.Context, id uint) error RollbackKindBoxRequestStatus(ctx context.Context, id uint) error
GetAllKindBoxReq(ctx context.Context, pagination paginationparam.PaginationRequest) ([]entity.KindBoxReq, paginationparam.PaginationResponse, 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 DeliverKindBoxReq(ctx context.Context, kindBoxReqID uint) error
} }

View File

@ -1 +0,0 @@
package adminkindboxreqservice

View File

@ -2,6 +2,7 @@ package benefactorkindboxreqservice
import ( import (
"context" "context"
"git.gocasts.ir/ebhomengo/niki/entity" "git.gocasts.ir/ebhomengo/niki/entity"
param "git.gocasts.ir/ebhomengo/niki/param/benefactor/kind_box_req" param "git.gocasts.ir/ebhomengo/niki/param/benefactor/kind_box_req"
richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error" richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error"

View File

@ -1 +0,0 @@
package benefactorkindboxreqservice

View File

@ -1 +0,0 @@
package benefactorkindboxreqservice

View File

@ -1 +0,0 @@
package benefactorkindboxreqservice

View File

@ -1 +0,0 @@
package adminkindboxvalidator

View File

@ -1 +0,0 @@
package adminkindboxvalidator

View File

@ -1 +0,0 @@
package adminkindboxvalidator

View File

@ -1 +0,0 @@
package adminkindboxvalidator

View File

@ -1 +0,0 @@
package adminkindboxreqvalidator

View File

@ -0,0 +1,40 @@
package adminkindboxreqvalidator
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"
validation "github.com/go-ozzo/ozzo-validation/v4"
)
func (v Validator) ValidateAssignSenderAgent(req param.AssignSenderRequest) (map[string]string, error) {
const op = "adminkindboxreqvalidator.ValidateAssignSenderAgent"
if err := validation.ValidateStruct(&req,
validation.Field(&req.KindBoxReqID, validation.Required, validation.By(v.doesKindBoxRequestExist), validation.By(v.checkKindBoxReqStatusForAssigningSenderAgent)),
validation.Field(&req.SenderAgentID, validation.Required, validation.By(v.doesAgentAdminExist))); 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
}

View File

@ -1 +0,0 @@
package adminkindboxreqvalidator

View File

@ -1 +0,0 @@
package adminkindboxreqvalidator

View File

@ -1 +0,0 @@
package adminkindboxreqvalidator

View File

@ -6,6 +6,7 @@ import (
"fmt" "fmt"
"git.gocasts.ir/ebhomengo/niki/entity" "git.gocasts.ir/ebhomengo/niki/entity"
param "git.gocasts.ir/ebhomengo/niki/param/admin/admin"
errmsg "git.gocasts.ir/ebhomengo/niki/pkg/err_msg" errmsg "git.gocasts.ir/ebhomengo/niki/pkg/err_msg"
) )
@ -19,8 +20,13 @@ type Repository interface {
GetByID(ctx context.Context, id uint) (entity.KindBoxReq, error) GetByID(ctx context.Context, id uint) (entity.KindBoxReq, error)
} }
type AdminSvc interface {
AdminExistByID(ctx context.Context, req param.AdminExistByIDRequest) (param.AdminExistByIDResponse, error)
}
type Validator struct { type Validator struct {
repo Repository repo Repository
adminSvc AdminSvc
} }
func New(repo Repository) Validator { func New(repo Repository) Validator {
@ -76,6 +82,38 @@ func (v Validator) CheckKindBoxReqStatusForRejecting(value interface{}) error {
return nil return nil
} }
func (v Validator) checkKindBoxReqStatusForAssigningSenderAgent(value interface{}) error {
kindboxreqID, ok := value.(uint)
if !ok {
return fmt.Errorf(errmsg.ErrorMsgSomethingWentWrong)
}
kindBoxReq, err := v.repo.GetByID(context.Background(), kindboxreqID)
if err != nil {
return err
}
if kindBoxReq.Status != entity.KindBoxReqAcceptedStatus {
return fmt.Errorf(errmsg.ErrorMsgAssignSenderAgentKindBoxReqStatus)
}
return nil
}
func (v Validator) doesAgentAdminExist(value interface{}) error {
adminID, ok := value.(uint)
if !ok {
return fmt.Errorf(errmsg.ErrorMsgSomethingWentWrong)
}
resp, err := v.adminSvc.AdminExistByID(context.Background(), param.AdminExistByIDRequest{AdminID: adminID})
if err != nil {
return err
}
if resp.Admin.Role != entity.AdminAgentRole {
return fmt.Errorf(errmsg.ErrorMsgAdminIsNotAgent)
}
return nil
}
func (v Validator) checkKindBoxReqStatusForDelivering(value interface{}) error { func (v Validator) checkKindBoxReqStatusForDelivering(value interface{}) error {
kindboxreqID, ok := value.(uint) kindboxreqID, ok := value.(uint)
if !ok { if !ok {