From 085989538d672db0e73451d7060d4985d513c597 Mon Sep 17 00:00:00 2001 From: mohammad mahdi rezaei Date: Fri, 19 Jan 2024 20:07:15 +0330 Subject: [PATCH] feat(benefactor): add address --- .../benefactor/benefactor/add_address.go | 36 ++++++++++ .../benefactor/benefactor/handler.go | 23 +++--- .../benefactor/benefactor/route.go | 8 ++- delivery/http_server/server.go | 2 +- main.go | 9 +-- param/benefactor/address/city_exit_by_id.go | 8 +++ .../benefactor/address/province_exit_by_id.go | 8 +++ repository/mysql/address/create.go | 2 +- repository/mysql/address/exist_city.go | 31 ++++++++ repository/mysql/address/exist_province.go | 32 +++++++++ repository/mysql/address/get.go | 2 +- repository/mysql/address/get_all_cities.go | 2 +- repository/mysql/address/get_all_provinces.go | 2 +- service/benefactor/address/add.go | 28 ++++++++ service/benefactor/address/city_exit_by_id.go | 19 +++++ service/benefactor/address/exist_by_id.go | 19 +++++ service/benefactor/address/get_all_cities.go | 19 +++++ .../benefactor/address/get_all_provinces.go | 19 +++++ .../benefactor/address/province_exit_by_id.go | 19 +++++ service/benefactor/address/service.go | 56 +-------------- .../benefactor/benefactor/add_address.go | 59 +++++++++++++++ validator/benefactor/benefactor/validator.go | 72 +++++++++++++++++-- 22 files changed, 397 insertions(+), 78 deletions(-) create mode 100644 delivery/http_server/benefactor/benefactor/add_address.go create mode 100644 param/benefactor/address/city_exit_by_id.go create mode 100644 param/benefactor/address/province_exit_by_id.go create mode 100644 repository/mysql/address/exist_city.go create mode 100644 repository/mysql/address/exist_province.go create mode 100644 service/benefactor/address/add.go create mode 100644 service/benefactor/address/city_exit_by_id.go create mode 100644 service/benefactor/address/exist_by_id.go create mode 100644 service/benefactor/address/get_all_cities.go create mode 100644 service/benefactor/address/get_all_provinces.go create mode 100644 service/benefactor/address/province_exit_by_id.go create mode 100644 validator/benefactor/benefactor/add_address.go diff --git a/delivery/http_server/benefactor/benefactor/add_address.go b/delivery/http_server/benefactor/benefactor/add_address.go new file mode 100644 index 0000000..7f8c668 --- /dev/null +++ b/delivery/http_server/benefactor/benefactor/add_address.go @@ -0,0 +1,36 @@ +package benefactorhandler + +import ( + "net/http" + + param "git.gocasts.ir/ebhomengo/niki/param/benefactor/address" + "git.gocasts.ir/ebhomengo/niki/pkg/claim" + httpmsg "git.gocasts.ir/ebhomengo/niki/pkg/http_msg" + "github.com/labstack/echo/v4" +) + +func (h Handler) AddAddress(c echo.Context) error { + claims := claim.GetClaimsFromEchoContext(c) + req := param.BenefactorAddAddressRequest{BenefactorID: claims.UserID} + if bErr := c.Bind(&req); bErr != nil { + return echo.NewHTTPError(http.StatusBadRequest) + } + + if fieldErrors, err := h.benefactorVld.ValidateAddAddress(req); err != nil { + msg, code := httpmsg.Error(err) + + return c.JSON(code, echo.Map{ + "message": msg, + "errors": fieldErrors, + }) + } + resp, sErr := h.benefactorAddressSvc.Add(c.Request().Context(), req) + + if sErr != nil { + msg, code := httpmsg.Error(sErr) + + return echo.NewHTTPError(code, msg) + } + + return c.JSON(http.StatusCreated, resp) +} diff --git a/delivery/http_server/benefactor/benefactor/handler.go b/delivery/http_server/benefactor/benefactor/handler.go index 14a5114..e0663b4 100644 --- a/delivery/http_server/benefactor/benefactor/handler.go +++ b/delivery/http_server/benefactor/benefactor/handler.go @@ -1,24 +1,31 @@ package benefactorhandler import ( - benefactorauthservice "git.gocasts.ir/ebhomengo/niki/service/auth/benefactor" + authservice "git.gocasts.ir/ebhomengo/niki/service/auth/benefactor" + benefactoraddressservice "git.gocasts.ir/ebhomengo/niki/service/benefactor/address" benefactorservice "git.gocasts.ir/ebhomengo/niki/service/benefactor/benefactor" benefactorvalidator "git.gocasts.ir/ebhomengo/niki/validator/benefactor/benefactor" ) type Handler struct { - authConfig benefactorauthservice.Config - benefactorSvc benefactorservice.Service - benefactorVld benefactorvalidator.Validator + authConfig authservice.Config + authSvc authservice.Service + benefactorSvc benefactorservice.Service + benefactorVld benefactorvalidator.Validator + benefactorAddressSvc benefactoraddressservice.Service } -func New(authConfig benefactorauthservice.Config, +func New(authConfig authservice.Config, + authSvc authservice.Service, benefactorSvc benefactorservice.Service, benefactorVld benefactorvalidator.Validator, + benefactorAddressSvc benefactoraddressservice.Service, ) Handler { return Handler{ - authConfig: authConfig, - benefactorSvc: benefactorSvc, - benefactorVld: benefactorVld, + authConfig: authConfig, + authSvc: authSvc, + benefactorSvc: benefactorSvc, + benefactorVld: benefactorVld, + benefactorAddressSvc: benefactorAddressSvc, } } diff --git a/delivery/http_server/benefactor/benefactor/route.go b/delivery/http_server/benefactor/benefactor/route.go index e53b32d..7a59b57 100644 --- a/delivery/http_server/benefactor/benefactor/route.go +++ b/delivery/http_server/benefactor/benefactor/route.go @@ -1,10 +1,16 @@ package benefactorhandler -import "github.com/labstack/echo/v4" +import ( + "git.gocasts.ir/ebhomengo/niki/delivery/http_server/middleware" + "git.gocasts.ir/ebhomengo/niki/entity" + "github.com/labstack/echo/v4" +) func (h Handler) SetRoutes(e *echo.Echo) { r := e.Group("/benefactor") r.POST("/send-otp", h.SendOtp) r.POST("/login-register", h.loginOrRegister) + r.POST("/address", h.AddAddress, middleware.Auth(h.authSvc, h.authConfig), + middleware.BenefactorAuthorization(entity.UserBenefactorRole)) } diff --git a/delivery/http_server/server.go b/delivery/http_server/server.go index f740c73..0c8dbdf 100644 --- a/delivery/http_server/server.go +++ b/delivery/http_server/server.go @@ -37,7 +37,7 @@ func New( return Server{ Router: echo.New(), config: cfg, - benefactorHandler: benefactorhandler.New(cfg.Auth, benefactorSvc, benefactorVld), + benefactorHandler: benefactorhandler.New(cfg.Auth, authSvc, benefactorSvc, benefactorVld, benefactorAddressSvc), benefactorKindBoxReqHandler: benefactorkindboxreqhandler.New(cfg.Auth, authSvc, benefactorKindBoxReqSvc, benefactorKindBoxReqVld), benefactorBaseHandler: benefactorbasehandler.New(benefactorAddressSvc), } diff --git a/main.go b/main.go index 8640685..9f8dcb2 100644 --- a/main.go +++ b/main.go @@ -50,15 +50,12 @@ func setupServices(cfg config.Config) ( authGenerator := authservice.New(cfg.Auth) benefactorSvc = benefactorservice.New(cfg.BenefactorSvc, RedisOtp, otpSmsProvider, authGenerator, benefactorMysql) - - benefactorVld = benefactorvalidator.New() + benefactorAddressMysql := mysqladdress.New(MysqlRepo) + benefactorAddressSvc = benefactoraddressservice.New(benefactorAddressMysql) + benefactorVld = benefactorvalidator.New(benefactorSvc, benefactorAddressSvc) benefactorKindBoxReqMysql := mysqlkindboxreq.New(MysqlRepo) benefactorKindBoxReqSvc = benefactorkindboxreqservice.New(benefactorKindBoxReqMysql) - - benefactorAddressMysql := mysqladdress.New(MysqlRepo) - benefactorAddressSvc = benefactoraddressservice.New(benefactorAddressMysql) - benefactorKindBoxReqVld = benefactorkindboxreqvalidator.New(benefactorKindBoxReqMysql, benefactorSvc, benefactorAddressSvc) return diff --git a/param/benefactor/address/city_exit_by_id.go b/param/benefactor/address/city_exit_by_id.go new file mode 100644 index 0000000..6e7098b --- /dev/null +++ b/param/benefactor/address/city_exit_by_id.go @@ -0,0 +1,8 @@ +package addressparam + +type CityExistByIDRequest struct { + ID uint +} +type CityExistByIDResponse struct { + Existed bool +} diff --git a/param/benefactor/address/province_exit_by_id.go b/param/benefactor/address/province_exit_by_id.go new file mode 100644 index 0000000..f16e90d --- /dev/null +++ b/param/benefactor/address/province_exit_by_id.go @@ -0,0 +1,8 @@ +package addressparam + +type ProvinceExistByIDRequest struct { + ID uint +} +type ProvinceExistByIDResponse struct { + Existed bool +} diff --git a/repository/mysql/address/create.go b/repository/mysql/address/create.go index 8623217..926c45e 100644 --- a/repository/mysql/address/create.go +++ b/repository/mysql/address/create.go @@ -8,7 +8,7 @@ import ( richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error" ) -func (d DB) CreateBenefactorAddress(ctx context.Context, address entity.Address) (entity.Address, error) { +func (d *DB) CreateBenefactorAddress(ctx context.Context, address entity.Address) (entity.Address, error) { const op = "mysqlbenefactor.createBenefactorAddress" res, err := d.conn.Conn().ExecContext(ctx, `insert into addresses(postal_code, address, lat, lon,province_id,city_id,benefactor_id) values(?, ?, ?,?,?,?,?)`, diff --git a/repository/mysql/address/exist_city.go b/repository/mysql/address/exist_city.go new file mode 100644 index 0000000..929bfdb --- /dev/null +++ b/repository/mysql/address/exist_city.go @@ -0,0 +1,31 @@ +package mysqladdress + +import ( + "context" + "database/sql" + "errors" + + errmsg "git.gocasts.ir/ebhomengo/niki/pkg/err_msg" + richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error" +) + +func (d *DB) IsExistCityByID(ctx context.Context, id uint) (bool, error) { + const op = "mysqladdress.IsExistCityByID" + row := d.conn.Conn().QueryRowContext(ctx, `select * from cities where id = ?`, id) + + _, err := scanCity(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 false, nil + } + + // TODO - log unexpected error for better observability + return false, richerror.New(op).WithErr(err). + WithMessage(errmsg.ErrorMsgCantScanQueryResult).WithKind(richerror.KindUnexpected) + } + + return true, nil +} diff --git a/repository/mysql/address/exist_province.go b/repository/mysql/address/exist_province.go new file mode 100644 index 0000000..fb9d5e8 --- /dev/null +++ b/repository/mysql/address/exist_province.go @@ -0,0 +1,32 @@ +package mysqladdress + +import ( + "context" + "database/sql" + "errors" + + errmsg "git.gocasts.ir/ebhomengo/niki/pkg/err_msg" + richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error" +) + +func (d *DB) IsExistProvinceByID(ctx context.Context, id uint) (bool, error) { + const op = "mysqladdress.IsExistProvinceByID" + + row := d.conn.Conn().QueryRowContext(ctx, `select * from provinces where id = ?`, id) + + _, err := scanProvince(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 false, nil + } + + // TODO - log unexpected error for better observability + return false, richerror.New(op).WithErr(err). + WithMessage(errmsg.ErrorMsgCantScanQueryResult).WithKind(richerror.KindUnexpected) + } + + return true, nil +} diff --git a/repository/mysql/address/get.go b/repository/mysql/address/get.go index e390f3b..bae3d93 100644 --- a/repository/mysql/address/get.go +++ b/repository/mysql/address/get.go @@ -13,7 +13,7 @@ import ( ) // TODO - use this approach or return (bool,entity.Address,error). -func (d DB) GetAddressByID(ctx context.Context, id uint) (*entity.Address, error) { +func (d *DB) GetAddressByID(ctx context.Context, id uint) (*entity.Address, error) { const op = "mysqladdress.IsExistAddressByID" row := d.conn.Conn().QueryRowContext(ctx, `select * from addresses where id = ?`, id) diff --git a/repository/mysql/address/get_all_cities.go b/repository/mysql/address/get_all_cities.go index 4be79d5..a2e6767 100644 --- a/repository/mysql/address/get_all_cities.go +++ b/repository/mysql/address/get_all_cities.go @@ -10,7 +10,7 @@ import ( "git.gocasts.ir/ebhomengo/niki/repository/mysql" ) -func (d DB) GetAllCities(ctx context.Context) ([]entity.City, error) { +func (d *DB) GetAllCities(ctx context.Context) ([]entity.City, error) { const op = "mysqladdress.GetAllCities" cities := make([]entity.City, 0) diff --git a/repository/mysql/address/get_all_provinces.go b/repository/mysql/address/get_all_provinces.go index 077dc52..26b40d3 100644 --- a/repository/mysql/address/get_all_provinces.go +++ b/repository/mysql/address/get_all_provinces.go @@ -10,7 +10,7 @@ import ( "git.gocasts.ir/ebhomengo/niki/repository/mysql" ) -func (d DB) GetAllProvinces(ctx context.Context) ([]entity.Province, error) { +func (d *DB) GetAllProvinces(ctx context.Context) ([]entity.Province, error) { const op = "mysqladdress.GetAllProvinces" provinces := make([]entity.Province, 0) diff --git a/service/benefactor/address/add.go b/service/benefactor/address/add.go new file mode 100644 index 0000000..25a56a6 --- /dev/null +++ b/service/benefactor/address/add.go @@ -0,0 +1,28 @@ +package benefactoraddressservice + +import ( + "context" + + "git.gocasts.ir/ebhomengo/niki/entity" + param "git.gocasts.ir/ebhomengo/niki/param/benefactor/address" + richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error" +) + +func (s Service) Add(ctx context.Context, req param.BenefactorAddAddressRequest) (param.BenefactorAddAddressResponse, error) { + const op = "benefactoraddressservice.Add" + + address, err := s.repo.CreateBenefactorAddress(ctx, entity.Address{ + PostalCode: req.PostalCode, + Address: req.Address, + Lat: req.Lat, + Lon: req.Lon, + CityID: req.CityID, + ProvinceID: req.ProvinceID, + BenefactorID: req.BenefactorID, + }) + if err != nil { + return param.BenefactorAddAddressResponse{}, richerror.New(op).WithErr(err).WithKind(richerror.KindUnexpected) + } + + return param.BenefactorAddAddressResponse{Address: address}, nil +} diff --git a/service/benefactor/address/city_exit_by_id.go b/service/benefactor/address/city_exit_by_id.go new file mode 100644 index 0000000..0ee3501 --- /dev/null +++ b/service/benefactor/address/city_exit_by_id.go @@ -0,0 +1,19 @@ +package benefactoraddressservice + +import ( + "context" + + addressparam "git.gocasts.ir/ebhomengo/niki/param/benefactor/address" + richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error" +) + +func (s Service) CityExistByID(ctx context.Context, req addressparam.CityExistByIDRequest) (addressparam.CityExistByIDResponse, error) { + const op = "benefactoraddressservice.CityExistByID" + + isExisted, err := s.repo.IsExistCityByID(ctx, req.ID) + if err != nil { + return addressparam.CityExistByIDResponse{}, richerror.New(op).WithErr(err).WithKind(richerror.KindUnexpected) + } + + return addressparam.CityExistByIDResponse{Existed: isExisted}, nil +} diff --git a/service/benefactor/address/exist_by_id.go b/service/benefactor/address/exist_by_id.go new file mode 100644 index 0000000..f654ff2 --- /dev/null +++ b/service/benefactor/address/exist_by_id.go @@ -0,0 +1,19 @@ +package benefactoraddressservice + +import ( + "context" + + param "git.gocasts.ir/ebhomengo/niki/param/benefactor/address" + richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error" +) + +func (s Service) AddressExistByID(ctx context.Context, req param.GetAddressByIDRequest) (param.GetAddressByIDResponse, error) { + const op = "benefactoraddressservice.BenefactorExistByID" + + address, err := s.repo.GetAddressByID(ctx, req.ID) + if err != nil { + return param.GetAddressByIDResponse{}, richerror.New(op).WithErr(err).WithKind(richerror.KindUnexpected) + } + + return param.GetAddressByIDResponse{Address: address}, nil +} diff --git a/service/benefactor/address/get_all_cities.go b/service/benefactor/address/get_all_cities.go new file mode 100644 index 0000000..6c6b9da --- /dev/null +++ b/service/benefactor/address/get_all_cities.go @@ -0,0 +1,19 @@ +package benefactoraddressservice + +import ( + "context" + + param "git.gocasts.ir/ebhomengo/niki/param/benefactor/address" + richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error" +) + +func (s Service) GetAllCities(ctx context.Context, _ param.GetAllCitiesRequest) (param.GetAllCitiesResponse, error) { + const op = "benefactoraddressservice.GetAllCities" + + Cities, err := s.repo.GetAllCities(ctx) + if err != nil { + return param.GetAllCitiesResponse{}, richerror.New(op).WithErr(err).WithKind(richerror.KindUnexpected) + } + + return param.GetAllCitiesResponse{Cities: Cities}, nil +} diff --git a/service/benefactor/address/get_all_provinces.go b/service/benefactor/address/get_all_provinces.go new file mode 100644 index 0000000..73ea714 --- /dev/null +++ b/service/benefactor/address/get_all_provinces.go @@ -0,0 +1,19 @@ +package benefactoraddressservice + +import ( + "context" + + param "git.gocasts.ir/ebhomengo/niki/param/benefactor/address" + richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error" +) + +func (s Service) GetAllProvinces(ctx context.Context, _ param.GetAllProvincesRequest) (param.GetAllProvincesResponse, error) { + const op = "benefactoraddressservice.GetAllProvinces" + + provinces, err := s.repo.GetAllProvinces(ctx) + if err != nil { + return param.GetAllProvincesResponse{}, richerror.New(op).WithErr(err).WithKind(richerror.KindUnexpected) + } + + return param.GetAllProvincesResponse{Provinces: provinces}, nil +} diff --git a/service/benefactor/address/province_exit_by_id.go b/service/benefactor/address/province_exit_by_id.go new file mode 100644 index 0000000..a188bd2 --- /dev/null +++ b/service/benefactor/address/province_exit_by_id.go @@ -0,0 +1,19 @@ +package benefactoraddressservice + +import ( + "context" + + addressparam "git.gocasts.ir/ebhomengo/niki/param/benefactor/address" + richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error" +) + +func (s Service) ProvinceExistByID(ctx context.Context, req addressparam.ProvinceExistByIDRequest) (addressparam.ProvinceExistByIDResponse, error) { + const op = "benefactoraddressservice.ProvinceExistByID" + + isExisted, err := s.repo.IsExistProvinceByID(ctx, req.ID) + if err != nil { + return addressparam.ProvinceExistByIDResponse{}, richerror.New(op).WithErr(err).WithKind(richerror.KindUnexpected) + } + + return addressparam.ProvinceExistByIDResponse{Existed: isExisted}, nil +} diff --git a/service/benefactor/address/service.go b/service/benefactor/address/service.go index 7bb92c5..a7310ff 100644 --- a/service/benefactor/address/service.go +++ b/service/benefactor/address/service.go @@ -4,8 +4,6 @@ import ( "context" "git.gocasts.ir/ebhomengo/niki/entity" - param "git.gocasts.ir/ebhomengo/niki/param/benefactor/address" - richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error" ) type Repository interface { @@ -13,6 +11,8 @@ type Repository interface { GetAddressByID(ctx context.Context, id uint) (*entity.Address, error) GetAllProvinces(ctx context.Context) ([]entity.Province, error) GetAllCities(ctx context.Context) ([]entity.City, error) + IsExistProvinceByID(ctx context.Context, id uint) (bool, error) + IsExistCityByID(ctx context.Context, id uint) (bool, error) } type Service struct { @@ -22,55 +22,3 @@ type Service struct { func New(repo Repository) Service { return Service{repo: repo} } - -func (s Service) Add(ctx context.Context, req param.BenefactorAddAddressRequest) (param.BenefactorAddAddressResponse, error) { - const op = "benefactoraddressservice.Add" - - address, err := s.repo.CreateBenefactorAddress(ctx, entity.Address{ - PostalCode: req.PostalCode, - Address: req.Address, - Lat: req.Lat, - Lon: req.Lon, - CityID: req.CityID, - ProvinceID: req.ProvinceID, - BenefactorID: req.BenefactorID, - }) - if err != nil { - return param.BenefactorAddAddressResponse{}, richerror.New(op).WithErr(err).WithKind(richerror.KindUnexpected) - } - - return param.BenefactorAddAddressResponse{Address: address}, nil -} - -func (s Service) AddressExistByID(ctx context.Context, req param.GetAddressByIDRequest) (param.GetAddressByIDResponse, error) { - const op = "benefactorservice.BenefactorExistByID" - - address, err := s.repo.GetAddressByID(ctx, req.ID) - if err != nil { - return param.GetAddressByIDResponse{}, richerror.New(op).WithErr(err).WithKind(richerror.KindUnexpected) - } - - return param.GetAddressByIDResponse{Address: address}, nil -} - -func (s Service) GetAllProvinces(ctx context.Context, _ param.GetAllProvincesRequest) (param.GetAllProvincesResponse, error) { - const op = "benefactoraddressservice.GetAllProvinces" - - provinces, err := s.repo.GetAllProvinces(ctx) - if err != nil { - return param.GetAllProvincesResponse{}, richerror.New(op).WithErr(err).WithKind(richerror.KindUnexpected) - } - - return param.GetAllProvincesResponse{Provinces: provinces}, nil -} - -func (s Service) GetAllCities(ctx context.Context, _ param.GetAllCitiesRequest) (param.GetAllCitiesResponse, error) { - const op = "benefactoraddressservice.GetAllCities" - - Cities, err := s.repo.GetAllCities(ctx) - if err != nil { - return param.GetAllCitiesResponse{}, richerror.New(op).WithErr(err).WithKind(richerror.KindUnexpected) - } - - return param.GetAllCitiesResponse{Cities: Cities}, nil -} diff --git a/validator/benefactor/benefactor/add_address.go b/validator/benefactor/benefactor/add_address.go new file mode 100644 index 0000000..feb0e63 --- /dev/null +++ b/validator/benefactor/benefactor/add_address.go @@ -0,0 +1,59 @@ +package benefactorvalidator + +import ( + "errors" + + param "git.gocasts.ir/ebhomengo/niki/param/benefactor/address" + 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) ValidateAddAddress(req param.BenefactorAddAddressRequest) (map[string]string, error) { + const op = "benefactorvalidator.ValidateAddRequest" + if err := validation.ValidateStruct(&req, + + validation.Field(&req.Address, validation.Required), + + validation.Field(&req.BenefactorID, + validation.Required, + validation.By(v.doesBenefactorExist)), + + validation.Field(&req.Lon, + validation.Required), + + validation.Field(&req.Lat, + validation.Required), + + validation.Field(&req.PostalCode, + validation.Required, + ), + validation.Field(&req.CityID, + validation.Required, + validation.By(v.doesCityExist)), + + validation.Field(&req.ProvinceID, + validation.Required, + validation.By(v.doesProvinceExist)), + ); 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/benefactor/benefactor/validator.go b/validator/benefactor/benefactor/validator.go index 5fe5015..4b25699 100644 --- a/validator/benefactor/benefactor/validator.go +++ b/validator/benefactor/benefactor/validator.go @@ -1,11 +1,75 @@ package benefactorvalidator +import ( + "context" + "fmt" + + addressparam "git.gocasts.ir/ebhomengo/niki/param/benefactor/address" + param "git.gocasts.ir/ebhomengo/niki/param/benefactor/benefactore" + errmsg "git.gocasts.ir/ebhomengo/niki/pkg/err_msg" +) + const ( phoneNumberRegex = "^09\\d{9}$" ) -type Validator struct{} - -func New() Validator { - return Validator{} +type BenefactorSvc interface { + BenefactorExistByID(ctx context.Context, request param.BenefactorExistByIDRequest) (param.BenefactorExistByIDResponse, error) +} +type BenefactorAddressSvc interface { + ProvinceExistByID(ctx context.Context, request addressparam.ProvinceExistByIDRequest) (addressparam.ProvinceExistByIDResponse, error) + CityExistByID(ctx context.Context, request addressparam.CityExistByIDRequest) (addressparam.CityExistByIDResponse, error) +} +type Validator struct { + benefactorSvc BenefactorSvc + benefactorAddressSvc BenefactorAddressSvc +} + +func New(benefactorSvc BenefactorSvc, benefactorAddressSvc BenefactorAddressSvc) Validator { + return Validator{benefactorSvc: benefactorSvc, benefactorAddressSvc: benefactorAddressSvc} +} + +func (v Validator) doesBenefactorExist(value interface{}) error { + benefactorID, ok := value.(uint) + if !ok { + return fmt.Errorf(errmsg.ErrorMsgSomethingWentWrong) + } + _, err := v.benefactorSvc.BenefactorExistByID(context.Background(), param.BenefactorExistByIDRequest{ID: benefactorID}) + if err != nil { + return fmt.Errorf(errmsg.ErrorMsgNotFound) + } + + return nil +} + +func (v Validator) doesProvinceExist(value interface{}) error { + provinceID, ok := value.(uint) + if !ok { + return fmt.Errorf(errmsg.ErrorMsgSomethingWentWrong) + } + province, err := v.benefactorAddressSvc.ProvinceExistByID(context.Background(), addressparam.ProvinceExistByIDRequest{ID: provinceID}) + if err != nil { + return fmt.Errorf(errmsg.ErrorMsgNotFound) + } + if !province.Existed { + return fmt.Errorf(errmsg.ErrorMsgNotFound) + } + + return nil +} + +func (v Validator) doesCityExist(value interface{}) error { + cityID, ok := value.(uint) + if !ok { + return fmt.Errorf(errmsg.ErrorMsgSomethingWentWrong) + } + city, err := v.benefactorAddressSvc.CityExistByID(context.Background(), addressparam.CityExistByIDRequest{ID: cityID}) + if err != nil { + return fmt.Errorf(errmsg.ErrorMsgNotFound) + } + if !city.Existed { + return fmt.Errorf(errmsg.ErrorMsgNotFound) + } + + return nil }