feat(admin): implement update benefactor profile and change status(#196)

This commit is contained in:
Hamed Xamani 2024-10-29 15:04:12 +03:30
parent 0e92213d2e
commit f067686af7
27 changed files with 919 additions and 10 deletions

View File

@ -1,13 +1,13 @@
package adminbenefactorhandler
import (
params "git.gocasts.ir/ebhomengo/niki/param"
adminaddressparam "git.gocasts.ir/ebhomengo/niki/param/admin/address"
adminkindboxparam "git.gocasts.ir/ebhomengo/niki/param/admin/kind_box"
adminkindboxreqparam "git.gocasts.ir/ebhomengo/niki/param/admin/kind_box_req"
"net/http"
params "git.gocasts.ir/ebhomengo/niki/param"
adminaddressparam "git.gocasts.ir/ebhomengo/niki/param/admin/address"
param "git.gocasts.ir/ebhomengo/niki/param/admin/benefactor"
adminkindboxparam "git.gocasts.ir/ebhomengo/niki/param/admin/kind_box"
adminkindboxreqparam "git.gocasts.ir/ebhomengo/niki/param/admin/kind_box_req"
httpmsg "git.gocasts.ir/ebhomengo/niki/pkg/http_msg"
"github.com/labstack/echo/v4"
)

View File

@ -13,4 +13,6 @@ func (h Handler) SetRoutes(e *echo.Echo) {
r.GET("", h.GetAllBenefactor, middleware.AdminAuthorization(h.authorizeSvc, entity.AdminBenefactorGetAllPermission))
r.GET("/:id", h.GetBenefactor, middleware.AdminAuthorization(h.authorizeSvc, entity.AdminBenefactorGetPermission))
r.PUT("/:id", h.Update, middleware.AdminAuthorization(h.authorizeSvc, entity.AdminBenefactorUpdatePermission))
r.PUT("/:id/status", h.UpdateStatus, middleware.AdminAuthorization(h.authorizeSvc, entity.AdminBenefactorUpdateStatusPermission))
}

View File

@ -0,0 +1,47 @@
package adminbenefactorhandler
import (
"net/http"
param "git.gocasts.ir/ebhomengo/niki/param/admin/benefactor"
httpmsg "git.gocasts.ir/ebhomengo/niki/pkg/http_msg"
"github.com/labstack/echo/v4"
)
// Update godoc
// @Summary Update benefactor details by admin
// @Description This endpoint update specific benefactor.
// @Tags Admins Benefactors
// @Accept json
// @Produce json
// @Param id path int true "Benefactor ID"
// @Param Request body param.BenefactorUpdateRequest true "Update Benefactor Body"
// @Success 204
// @Failure 400 {string} "Bad request"
// @Failure 401 {string} "invalid or expired jwt"
// @Failure 403 {string} "user not allowed"
// @Failure 404 {string} "record not found"
// @Failure 500 {string} "something went wrong"
// @Security AuthBearerAdmin
// @Router /admins/benefactors/{id} [put].
func (h Handler) Update(c echo.Context) error {
var req param.BenefactorUpdateRequest
if bErr := c.Bind(&req); bErr != nil {
return echo.NewHTTPError(http.StatusBadRequest)
}
resp, sErr := h.benefactorSvc.Update(c.Request().Context(), req)
if sErr != nil {
msg, code := httpmsg.Error(sErr)
if resp.FieldErrors != nil {
return c.JSON(code, echo.Map{
"message": msg,
"errors": resp.FieldErrors,
})
}
return echo.NewHTTPError(code, msg)
}
return c.JSON(http.StatusNoContent, nil)
}

View File

@ -0,0 +1,46 @@
package adminbenefactorhandler
import (
"net/http"
param "git.gocasts.ir/ebhomengo/niki/param/admin/benefactor"
httpmsg "git.gocasts.ir/ebhomengo/niki/pkg/http_msg"
"github.com/labstack/echo/v4"
)
// UpdateStatus godoc
// @Summary Update benefactor status by admin
// @Description This endpoint update status (active/inactive) benefactor.
// @Tags Admins Benefactors
// @Accept json
// @Produce json
// @Param id path int true "Benefactor ID"
// @Param Request body param.BenefactorUpdateStatusRequest true "Update Benefactor Status"
// @Success 204
// @Failure 400 {string} "Bad request"
// @Failure 401 {string} "invalid or expired jwt"
// @Failure 403 {string} "user not allowed"
// @Failure 404 {string} "record not found"
// @Failure 500 {string} "something went wrong"
// @Security AuthBearerAdmin
// @Router /admins/benefactors/{id}/status [put].
func (h Handler) UpdateStatus(c echo.Context) error {
var req param.BenefactorUpdateStatusRequest
if bErr := c.Bind(&req); bErr != nil {
return echo.NewHTTPError(http.StatusBadRequest)
}
resp, sErr := h.benefactorSvc.UpdateStatus(c.Request().Context(), req)
if sErr != nil {
msg, code := httpmsg.Error(sErr)
if resp.FieldErrors != nil {
return c.JSON(code, echo.Map{
"message": msg,
"errors": resp.FieldErrors,
})
}
return echo.NewHTTPError(code, msg)
}
return c.JSON(http.StatusNoContent, nil)
}

View File

@ -33,7 +33,7 @@ services:
MARIADB_PASSWORD: ${NIKI_STAGE_MARIADB_UR_PASSWORD}
MARIADB_DATABASE: niki_db
MARIADB_ROOT_PASSWORD: ${NIKI_STAGE_MARIADB_RT_PASSWORD}
ALLOW_EMPTY_PASSWORD: no
ALLOW_EMPTY_PASSWORD: "no"
niki-redis:
image: bitnami/redis:6.2

View File

@ -249,6 +249,150 @@ const docTemplate = `{
}
}
}
},
"put": {
"security": [
{
"AuthBearerAdmin": []
}
],
"description": "This endpoint update specific benefactor.",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Admins Benefactors"
],
"summary": "Update benefactor details by admin",
"parameters": [
{
"type": "integer",
"description": "Benefactor ID",
"name": "id",
"in": "path",
"required": true
},
{
"description": "Update Benefactor Body",
"name": "Request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/adminbenefactoreparam.BenefactorUpdateRequest"
}
}
],
"responses": {
"204": {
"description": "No Content"
},
"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"
}
},
"500": {
"description": "something went wrong",
"schema": {
"type": "string"
}
}
}
}
},
"/admins/benefactors/{id}/status": {
"put": {
"security": [
{
"AuthBearerAdmin": []
}
],
"description": "This endpoint update status (active/inactive) benefactor.",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Admins Benefactors"
],
"summary": "Update benefactor status by admin",
"parameters": [
{
"type": "integer",
"description": "Benefactor ID",
"name": "id",
"in": "path",
"required": true
},
{
"description": "Update Benefactor Status",
"name": "Request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/adminbenefactoreparam.BenefactorUpdateStatusRequest"
}
}
],
"responses": {
"204": {
"description": "No Content"
},
"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"
}
},
"500": {
"description": "something went wrong",
"schema": {
"type": "string"
}
}
}
}
},
"/admins/kindboxes": {
@ -3098,6 +3242,22 @@ const docTemplate = `{
}
}
},
"adminbenefactoreparam.BenefactorUpdateRequest": {
"type": "object"
},
"adminbenefactoreparam.BenefactorUpdateStatusRequest": {
"type": "object",
"properties": {
"status": {
"allOf": [
{
"$ref": "#/definitions/entity.BenefactorStatus"
}
],
"example": "inactive"
}
}
},
"adminbenefactoreparam.Data": {
"type": "object",
"properties": {
@ -4450,6 +4610,14 @@ const docTemplate = `{
}
}
},
"param.Date": {
"type": "object",
"properties": {
"time.Time": {
"type": "string"
}
}
},
"param.PaginationResponse": {
"type": "object",
"properties": {

View File

@ -238,6 +238,150 @@
}
}
}
},
"put": {
"security": [
{
"AuthBearerAdmin": []
}
],
"description": "This endpoint update specific benefactor.",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Admins Benefactors"
],
"summary": "Update benefactor details by admin",
"parameters": [
{
"type": "integer",
"description": "Benefactor ID",
"name": "id",
"in": "path",
"required": true
},
{
"description": "Update Benefactor Body",
"name": "Request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/adminbenefactoreparam.BenefactorUpdateRequest"
}
}
],
"responses": {
"204": {
"description": "No Content"
},
"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"
}
},
"500": {
"description": "something went wrong",
"schema": {
"type": "string"
}
}
}
}
},
"/admins/benefactors/{id}/status": {
"put": {
"security": [
{
"AuthBearerAdmin": []
}
],
"description": "This endpoint update status (active/inactive) benefactor.",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Admins Benefactors"
],
"summary": "Update benefactor status by admin",
"parameters": [
{
"type": "integer",
"description": "Benefactor ID",
"name": "id",
"in": "path",
"required": true
},
{
"description": "Update Benefactor Status",
"name": "Request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/adminbenefactoreparam.BenefactorUpdateStatusRequest"
}
}
],
"responses": {
"204": {
"description": "No Content"
},
"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"
}
},
"500": {
"description": "something went wrong",
"schema": {
"type": "string"
}
}
}
}
},
"/admins/kindboxes": {
@ -3087,6 +3231,22 @@
}
}
},
"adminbenefactoreparam.BenefactorUpdateRequest": {
"type": "object"
},
"adminbenefactoreparam.BenefactorUpdateStatusRequest": {
"type": "object",
"properties": {
"status": {
"allOf": [
{
"$ref": "#/definitions/entity.BenefactorStatus"
}
],
"example": "inactive"
}
}
},
"adminbenefactoreparam.Data": {
"type": "object",
"properties": {
@ -4439,6 +4599,14 @@
}
}
},
"param.Date": {
"type": "object",
"properties": {
"time.Time": {
"type": "string"
}
}
},
"param.PaginationResponse": {
"type": "object",
"properties": {

View File

@ -136,6 +136,15 @@ definitions:
pagination:
$ref: '#/definitions/param.PaginationResponse'
type: object
adminbenefactoreparam.BenefactorUpdateRequest:
type: object
adminbenefactoreparam.BenefactorUpdateStatusRequest:
properties:
status:
allOf:
- $ref: '#/definitions/entity.BenefactorStatus'
example: inactive
type: object
adminbenefactoreparam.Data:
properties:
birth_date:
@ -1031,6 +1040,11 @@ definitions:
message:
type: string
type: object
param.Date:
properties:
time.Time:
type: string
type: object
param.PaginationResponse:
properties:
page_number:
@ -1200,6 +1214,99 @@ paths:
summary: Get benefactor details by id
tags:
- Admins Benefactors
put:
consumes:
- application/json
description: This endpoint update specific benefactor.
parameters:
- description: Benefactor ID
in: path
name: id
required: true
type: integer
- description: Update Benefactor Body
in: body
name: Request
required: true
schema:
$ref: '#/definitions/adminbenefactoreparam.BenefactorUpdateRequest'
produces:
- application/json
responses:
"204":
description: No Content
"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
"500":
description: something went wrong
schema:
type: string
security:
- AuthBearerAdmin: []
summary: Update benefactor details by admin
tags:
- Admins Benefactors
/admins/benefactors/{id}/status:
put:
consumes:
- application/json
description: This endpoint update status (active/inactive) benefactor.
parameters:
- description: Benefactor ID
in: path
name: id
required: true
type: integer
- description: Update Benefactor Status
in: body
name: Request
required: true
schema:
$ref: '#/definitions/adminbenefactoreparam.BenefactorUpdateStatusRequest'
produces:
- application/json
responses:
"204":
description: No Content
"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
"500":
description: something went wrong
schema:
type: string
security:
- AuthBearerAdmin: []
summary: Update benefactor status by admin
tags:
- Admins Benefactors
/admins/kindboxes:
get:
consumes:

View File

@ -23,4 +23,6 @@ const (
AdminKindBoxEnumeratePermission = AdminPermission("kindbox-enumerate")
AdminKindBoxUpdatePermission = AdminPermission("kindbox-update")
AdminBenefactorGetPermission = AdminPermission("benefactor-get")
AdminBenefactorUpdatePermission = AdminPermission("benefactor-update")
AdminBenefactorUpdateStatusPermission = AdminPermission("benefactor-update-status")
)

View File

@ -1,8 +1,9 @@
package adminbenefactoreparam
import (
"git.gocasts.ir/ebhomengo/niki/entity"
"time"
"git.gocasts.ir/ebhomengo/niki/entity"
)
type Data struct {

View File

@ -0,0 +1,16 @@
package adminbenefactoreparam
import (
"git.gocasts.ir/ebhomengo/niki/param"
)
type BenefactorUpdateRequest struct {
ID uint `json:"-" param:"id" example:"1"`
FirstName string `json:"first_name" example:"name"`
LastName string `json:"last_name" example:"family"`
BirthDate param.Date `json:"birth_date" example:"2000-01-01"`
}
type BenefactorUpdateResponse struct {
FieldErrors map[string]string `json:"field_errors,omitempty"`
}

View File

@ -0,0 +1,12 @@
package adminbenefactoreparam
import "git.gocasts.ir/ebhomengo/niki/entity"
type BenefactorUpdateStatusRequest struct {
ID uint `json:"-" param:"id" example:"1"`
Status entity.BenefactorStatus `json:"status" example:"inactive"`
}
type BenefactorUpdateStatusResponse struct {
FieldErrors map[string]string `json:"field_errors,omitempty"`
}

29
param/date.go Normal file
View File

@ -0,0 +1,29 @@
package param
import (
"fmt"
"strings"
"time"
)
type Date struct {
time.Time
}
func (t Date) MarshalJSON() ([]byte, error) {
date := t.Time.Format("2006-01-02")
fmt.Println(date)
date = fmt.Sprintf(`"%s"`, date)
return []byte(date), nil
}
func (t *Date) UnmarshalJSON(b []byte) (err error) {
s := strings.Trim(string(b), "\"")
date, err := time.Parse("2006-01-02", s)
if err != nil {
return err
}
t.Time = date
return
}

View File

@ -39,4 +39,5 @@ const (
ErrorMsgInvalidSerialNumberRange = "invalid serial number range"
ErrorMsgInvalidOrExpiredJwt = "invalid or expired jwt"
ErrorMsgInvalidRefreshToken = "invalid refresh token"
ErrorMsgInvalidBenefactorStatus = "invalid benefactor status"
)

View File

@ -0,0 +1,33 @@
package mysqlbenefactor
import (
"context"
"git.gocasts.ir/ebhomengo/niki/entity"
errmsg "git.gocasts.ir/ebhomengo/niki/pkg/err_msg"
richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error"
"git.gocasts.ir/ebhomengo/niki/repository/mysql"
)
func (d *DB) UpdateBenefactor(ctx context.Context, benefactor entity.Benefactor) error {
const op = "mysqlbenefactor.UpdateBenefactor"
query := `UPDATE benefactors
SET first_name = ?, last_name = ?, birth_date = ?
WHERE id = ?`
//nolint
stmt, err := d.conn.PrepareStatement(ctx, mysql.StatementKeyBenefactorUpdate, query)
if err != nil {
return richerror.New(op).WithErr(err).
WithMessage(errmsg.ErrorMsgCantPrepareStatement).WithKind(richerror.KindUnexpected)
}
_, uErr := stmt.ExecContext(ctx, benefactor.FirstName,
benefactor.LastName, benefactor.BirthDate, benefactor.ID)
if uErr != nil {
return richerror.New(op).WithErr(uErr).WithMessage(errmsg.ErrorMsgCantUpdateRecord).
WithKind(richerror.KindUnexpected)
}
return nil
}

View File

@ -0,0 +1,30 @@
package mysqlbenefactor
import (
"context"
"git.gocasts.ir/ebhomengo/niki/entity"
errmsg "git.gocasts.ir/ebhomengo/niki/pkg/err_msg"
richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error"
"git.gocasts.ir/ebhomengo/niki/repository/mysql"
)
func (d *DB) UpdateStatusBenefactor(ctx context.Context, benefactor entity.Benefactor, status entity.BenefactorStatus) error {
const op = "mysqlbenefactor.UpdateStatusBenefactor"
query := `UPDATE benefactors SET status = ? WHERE id = ?`
//nolint
stmt, err := d.conn.PrepareStatement(ctx, mysql.StatementKeyBenefactorUpdateStatus, query)
if err != nil {
return richerror.New(op).WithErr(err).
WithMessage(errmsg.ErrorMsgCantPrepareStatement).WithKind(richerror.KindUnexpected)
}
_, uErr := stmt.ExecContext(ctx, status, benefactor.ID)
if uErr != nil {
return richerror.New(op).WithErr(uErr).WithMessage(errmsg.ErrorMsgCantUpdateRecord).
WithKind(richerror.KindUnexpected)
}
return nil
}

View File

@ -0,0 +1,36 @@
-- +migrate Up
ALTER TABLE `admin_access_controls` MODIFY COLUMN `permission`
enum (
'admin-register',
'kindboxreq-accept',
'kindboxreq-reject',
'kindboxreq-getall',
'kindboxreq-deliver',
'kindboxreq-assign_sender_agent',
'admin-getall_agent',
'kindboxreq-get_awaiting_delivery',
'kindbox-get',
'kindboxreq-add',
'kindbox-assign_receiver_agent',
'kindbox-getall',
'kindboxreq-update',
'kindboxreq-get',
'kindbox-get_awaiting_return',
'kindbox-return',
'kindbox-enumerate',
'kindbox-update',
'benefactor-getall',
'benefactor-get',
'benefactor-update',
'benefactor-update-status'
) NOT NULL;
INSERT INTO `admin_access_controls` (`actor_id`, `actor_type`, `permission`)
VALUES (1, 'role', 'benefactor-update'),
VALUES (2, 'role', 'benefactor-update'),
VALUES (1, 'role', 'benefactor-update-status'),
VALUES (2, 'role', 'benefactor-update-status');
-- +migrate Down
DELETE
FROM `admin_access_controls`;

View File

@ -46,4 +46,6 @@ const (
StatementKeyKindBoxUpdate
StatementKeyReferTimeGetByID
StatementKeyReferTimeGetAll
StatementKeyBenefactorUpdate
StatementKeyBenefactorUpdateStatus
)

View File

@ -2,6 +2,7 @@ package adminaddressservice
import (
"context"
param "git.gocasts.ir/ebhomengo/niki/param/admin/address"
richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error"
)

View File

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

View File

@ -13,6 +13,8 @@ type Repository interface {
IsExistBenefactorByID(ctx context.Context, id uint) (bool, error)
GetByID(ctx context.Context, id uint) (entity.Benefactor, error)
GetAllBenefactor(ctx context.Context, filter param.FilterRequest, pagination param.PaginationRequest, sort param.SortRequest) ([]entity.Benefactor, uint, error)
UpdateBenefactor(ctx context.Context, benefactor entity.Benefactor) error
UpdateStatusBenefactor(ctx context.Context, benefactor entity.Benefactor, status entity.BenefactorStatus) error
}
type AddressSvc interface {
GetAddressByID(ctx context.Context, request adminaddressparam.AddressGetRequest) (adminaddressparam.AddressGetResponse, error)

View File

@ -0,0 +1,31 @@
package adminbenefactorservice
import (
"context"
param "git.gocasts.ir/ebhomengo/niki/param/admin/benefactor"
richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error"
)
func (s Service) Update(ctx context.Context, req param.BenefactorUpdateRequest) (param.BenefactorUpdateResponse, error) {
const op = "adminbenefactorservice.Update"
if fieldErrors, vErr := s.vld.ValidateUpdateRequest(ctx, req); vErr != nil {
return param.BenefactorUpdateResponse{FieldErrors: fieldErrors}, richerror.New(op).WithErr(vErr)
}
benefactor, err := s.repo.GetByID(ctx, req.ID)
if err != nil {
return param.BenefactorUpdateResponse{}, richerror.New(op).WithErr(err)
}
benefactor.FirstName = req.FirstName
benefactor.LastName = req.LastName
benefactor.BirthDate = req.BirthDate.Time
if uErr := s.repo.UpdateBenefactor(ctx, benefactor); uErr != nil {
return param.BenefactorUpdateResponse{}, richerror.New(op).WithErr(uErr)
}
return param.BenefactorUpdateResponse{}, nil
}

View File

@ -0,0 +1,27 @@
package adminbenefactorservice
import (
"context"
param "git.gocasts.ir/ebhomengo/niki/param/admin/benefactor"
richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error"
)
func (s Service) UpdateStatus(ctx context.Context, req param.BenefactorUpdateStatusRequest) (param.BenefactorUpdateStatusResponse, error) {
const op = "adminbenefactorservice.UpdateStatus"
if fieldErrors, vErr := s.vld.ValidateUpdateStatusRequest(ctx, req); vErr != nil {
return param.BenefactorUpdateStatusResponse{FieldErrors: fieldErrors}, richerror.New(op).WithErr(vErr)
}
benefactor, err := s.repo.GetByID(ctx, req.ID)
if err != nil {
return param.BenefactorUpdateStatusResponse{}, richerror.New(op).WithErr(err)
}
if uErr := s.repo.UpdateStatusBenefactor(ctx, benefactor, req.Status); uErr != nil {
return param.BenefactorUpdateStatusResponse{}, richerror.New(op).WithErr(uErr)
}
return param.BenefactorUpdateStatusResponse{}, nil
}

View File

@ -81,7 +81,7 @@ func New(cfg config.Config, db *mysql.DB, rds *redis.Adapter, smsAdapter smscont
AdminReferTimeVld = adminrefertimevalidator.New()
AdminReferTimeSvc = adminrefertimeservice.New(referTimeRepo, AdminReferTimeVld)
AdminAddressSvc = adminaddressservice.New(addressRepo)
AdminBenefactorVld = adminbenefactorvalidator.New()
AdminBenefactorVld = adminbenefactorvalidator.New(benefactorRepo)
AdminBenefactorSvc = adminbenefactorservice.New(benefactorRepo, AdminAddressSvc, AdminBenefactorVld)
AdminAgentSvc = adminagentservice.New(agentRepo)

View File

@ -0,0 +1,46 @@
package adminbenefactorvalidator
import (
"context"
"errors"
param "git.gocasts.ir/ebhomengo/niki/param/admin/benefactor"
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) ValidateUpdateRequest(ctx context.Context, req param.BenefactorUpdateRequest) (map[string]string, error) {
const op = "adminbenefactorvalidator.ValidateUpdateRequest"
if err := validation.ValidateStruct(&req,
validation.Field(&req.ID,
validation.Required,
validation.By(v.doesBenefactorExist(ctx))),
validation.Field(&req.FirstName,
validation.Length(minLengthFirstName, maxLengthFirstName)),
validation.Field(&req.LastName,
validation.Length(minLengthLastName, maxLengthLastName)),
validation.Field(&req.BirthDate,
validation.Required,
validation.By(v.isDateValid),
),
); err != nil {
fieldErrors := make(map[string]string)
vErr := validation.Errors{}
if errors.As(err, &vErr) {
for key, value := range vErr {
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 nil, nil
}

View File

@ -0,0 +1,40 @@
package adminbenefactorvalidator
import (
"context"
"errors"
param "git.gocasts.ir/ebhomengo/niki/param/admin/benefactor"
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) ValidateUpdateStatusRequest(ctx context.Context, req param.BenefactorUpdateStatusRequest) (map[string]string, error) {
const op = "adminbenefactorvalidator.ValidateUpdateStatusRequest"
if err := validation.ValidateStruct(&req,
validation.Field(&req.ID,
validation.Required,
validation.By(v.doesBenefactorExist(ctx))),
validation.Field(&req.Status,
validation.By(v.doesBenefactorStatusExist)),
); err != nil {
fieldErrors := make(map[string]string)
vErr := validation.Errors{}
if errors.As(err, &vErr) {
for key, value := range vErr {
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 nil, nil
}

View File

@ -1,18 +1,35 @@
package adminbenefactorvalidator
import (
"context"
"errors"
"fmt"
"slices"
"time"
"git.gocasts.ir/ebhomengo/niki/entity"
params "git.gocasts.ir/ebhomengo/niki/param"
errmsg "git.gocasts.ir/ebhomengo/niki/pkg/err_msg"
validation "github.com/go-ozzo/ozzo-validation/v4"
)
type Validator struct{}
const (
minLengthFirstName = 3
maxLengthFirstName = 40
minLengthLastName = 3
maxLengthLastName = 40
)
func New() Validator {
return Validator{}
type Repository interface {
IsExistBenefactorByID(ctx context.Context, id uint) (bool, error)
}
type Validator struct {
repo Repository
}
func New(repo Repository) Validator {
return Validator{repo: repo}
}
func (v Validator) AreSortFieldsValid(validSortFields []string) validation.RuleFunc {
@ -50,3 +67,47 @@ func (v Validator) AreFilterFieldsValid(validFilters []string) validation.RuleFu
return nil
}
}
func (v Validator) doesBenefactorExist(ctx context.Context) validation.RuleFunc {
return func(value interface{}) error {
benefactor, ok := value.(uint)
if !ok {
return fmt.Errorf(errmsg.ErrorMsgSomethingWentWrong)
}
if isExist, err := v.repo.IsExistBenefactorByID(ctx, benefactor); !isExist || err != nil {
if err != nil {
return err
}
if !isExist {
return errors.New("benefactor is not exist")
}
}
return nil
}
}
func (v Validator) isDateValid(value interface{}) error {
date, ok := value.(params.Date)
if !ok {
return fmt.Errorf(errmsg.ErrorMsgSomethingWentWrong)
}
if date.After(time.Now()) {
return fmt.Errorf(errmsg.ErrorMsgInvalidInput)
}
return nil
}
func (v Validator) doesBenefactorStatusExist(value interface{}) error {
BenefactorStatus, ok := value.(entity.BenefactorStatus)
if !ok {
return fmt.Errorf(errmsg.ErrorMsgSomethingWentWrong)
}
if !BenefactorStatus.IsValid() {
return fmt.Errorf(errmsg.ErrorMsgInvalidBenefactorStatus)
}
return nil
}