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("/reject-kind-box-req/:id", h.Reject)
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))
}

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

View File

@ -5,6 +5,7 @@ import (
"database/sql"
"errors"
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"
)
@ -52,3 +53,25 @@ func (d DB) AdminExistByEmail(ctx context.Context, email string) (bool, error) {
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 {
benefactor.LastName = data.lastName.String
}
//if data.address.Valid {
// benefactor.Address = data.address.String
//}
if data.description.Valid {
benefactor.Description = data.description.String
}
if data.email.Valid {
benefactor.Email = data.email.String
}
//if data.city.Valid {
// benefactor.City = data.city.String
//}
if data.genderStr.Valid {
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
-- what can we do for password?
INSERT INTO `admins` (`id`, `phone_number`, `email`,`password`,`role`,`status`)
VALUES
(1, '09122702856', 'keshvari@gmail.com','Abc123456','super-admin','active');
VALUES
(1, '09122702856', 'keshvari@gmail.com','Abc123456','super-admin','active');
-- +migrate Down
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 {
AddAdmin(ctx context.Context, admin entity.Admin) (entity.Admin, error)
GetAdminByPhoneNumber(ctx context.Context, phoneNumber string) (entity.Admin, error)
GetAdminByID(ctx context.Context, adminID uint) (entity.Admin, error)
}
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 (
"context"
entity "git.gocasts.ir/ebhomengo/niki/entity"
"git.gocasts.ir/ebhomengo/niki/entity"
paginationparam "git.gocasts.ir/ebhomengo/niki/param"
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
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
}

View File

@ -1 +0,0 @@
package adminkindboxreqservice

View File

@ -2,6 +2,7 @@ package benefactorkindboxreqservice
import (
"context"
"git.gocasts.ir/ebhomengo/niki/entity"
param "git.gocasts.ir/ebhomengo/niki/param/benefactor/kind_box_req"
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"
"git.gocasts.ir/ebhomengo/niki/entity"
param "git.gocasts.ir/ebhomengo/niki/param/admin/admin"
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)
}
type AdminSvc interface {
AdminExistByID(ctx context.Context, req param.AdminExistByIDRequest) (param.AdminExistByIDResponse, error)
}
type Validator struct {
repo Repository
repo Repository
adminSvc AdminSvc
}
func New(repo Repository) Validator {
@ -76,6 +82,38 @@ func (v Validator) CheckKindBoxReqStatusForRejecting(value interface{}) error {
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 {
kindboxreqID, ok := value.(uint)
if !ok {