From 34e555f95860a3a9b07913d79db97436c23f3790 Mon Sep 17 00:00:00 2001 From: Hilman Taris Muttaqin Date: Sun, 27 Nov 2022 12:47:45 +0700 Subject: [PATCH 01/62] add SMTP config in gitlab ci cd --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 79e33be..cf6134b 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -27,7 +27,7 @@ production-build: - docker login -u "$DOCKER_USERNAME" -p "$DOCKER_ACCESS_TOKEN" script: - echo "Build the project into image" - - printf "DATABASE_USER='$DATABASE_USER'\nDATABASE_PASSWORD='$DATABASE_PASSWORD'\nDATABASE_LOCATION='$DATABASE_LOCATION'\nDATABASE_NAME='$DATABASE_NAME'\nJWT_SALT='$JWT_SALT'\nVERSION=v1.0.0\n" > .env + - printf "DATABASE_USER='$DATABASE_USER'\nDATABASE_PASSWORD='$DATABASE_PASSWORD'\nDATABASE_LOCATION='$DATABASE_LOCATION'\nDATABASE_NAME='$DATABASE_NAME'\nJWT_SALT='$JWT_SALT'\nVERSION=v1.0.0\nSMTP_EMAIL='$SMTP_EMAIL'\nSMTP_PASSWORD='$SMTP_PASSWORD'" > .env - docker build -t hilmantm/ubur-backend:latest . - docker push -a hilmantm/ubur-backend rules: -- GitLab From 21d46c1abe72aaa07a981242978d2b087dd8958f Mon Sep 17 00:00:00 2001 From: Hilman Taris Muttaqin Date: Sun, 27 Nov 2022 13:27:34 +0700 Subject: [PATCH 02/62] migrate send email function to send_mail.go --- domain/handler/api_handler.go | 29 ++--------------------------- helper/send_mail.go | 25 +++++++++++++++++++++++++ 2 files changed, 27 insertions(+), 27 deletions(-) diff --git a/domain/handler/api_handler.go b/domain/handler/api_handler.go index b261e69..f530654 100644 --- a/domain/handler/api_handler.go +++ b/domain/handler/api_handler.go @@ -5,7 +5,6 @@ import ( "errors" "github.com/gin-gonic/gin" "golang.org/x/crypto/bcrypt" - "gopkg.in/gomail.v2" "net/http" "os" "strconv" @@ -69,19 +68,7 @@ func (handler *ApiHandler) CustomerRequestOtp(context *gin.Context) { return } - msg := gomail.NewMessage() - msg.SetHeader("From", email.From) - msg.SetHeader("To", email.To) - msg.SetHeader("Subject", email.Subject) - msg.SetBody("text/html", email.Body) - - n := gomail.NewDialer("smtp.gmail.com", 587, email.From, os.Getenv("SMTP_PASSWORD")) - - // Send the email - if err := n.DialAndSend(msg); err != nil { - response.ResponseError(context, http.StatusInternalServerError, err) - return - } + helper.SendEmail(context, email) response.ResponseSuccess(context, http.StatusOK, gin.H{ "message": "success to resend", @@ -239,19 +226,7 @@ func (handler *ApiHandler) CustomerRegister(context *gin.Context) { return } - msg := gomail.NewMessage() - msg.SetHeader("From", email.From) - msg.SetHeader("To", email.To) - msg.SetHeader("Subject", email.Subject) - msg.SetBody("text/html", email.Body) - - n := gomail.NewDialer("smtp.gmail.com", 587, email.From, os.Getenv("SMTP_PASSWORD")) - - // Send the email - if err := n.DialAndSend(msg); err != nil { - response.ResponseError(context, http.StatusInternalServerError, err) - return - } + helper.SendEmail(context, email) response.ResponseSuccess(context, http.StatusCreated, gin.H{ "message": "account success created, please check your email", diff --git a/helper/send_mail.go b/helper/send_mail.go index 2b08c11..6d7ab91 100644 --- a/helper/send_mail.go +++ b/helper/send_mail.go @@ -1,5 +1,14 @@ package helper +import ( + "github.com/gin-gonic/gin" + "gopkg.in/gomail.v2" + "net/http" + "os" + "ubur-backend/data/model" + "ubur-backend/data/response" +) + func GetOtpTemplate(code string) string { return "
\n" + "
\n
\n" + @@ -14,3 +23,19 @@ func GetOtpTemplate(code string) string { "

Ubur

\n

Telkom University

\n

Bandung

\n
\n " + "
\n
" } + +func SendEmail(context *gin.Context, email model.Email) { + msg := gomail.NewMessage() + msg.SetHeader("From", email.From) + msg.SetHeader("To", email.To) + msg.SetHeader("Subject", email.Subject) + msg.SetBody("text/html", email.Body) + + n := gomail.NewDialer("smtp.gmail.com", 587, email.From, os.Getenv("SMTP_PASSWORD")) + + // Send the email + if err := n.DialAndSend(msg); err != nil { + response.ResponseError(context, http.StatusInternalServerError, err) + return + } +} -- GitLab From a900782d01bbe84818f3cc9969a929aab660c59d Mon Sep 17 00:00:00 2001 From: Hilman Taris Muttaqin Date: Sun, 27 Nov 2022 20:11:29 +0700 Subject: [PATCH 03/62] add abort if token invalid --- middleware/auth_middleware.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/middleware/auth_middleware.go b/middleware/auth_middleware.go index ab06339..2cd29ab 100644 --- a/middleware/auth_middleware.go +++ b/middleware/auth_middleware.go @@ -20,6 +20,7 @@ func AuthRequiredMiddleware() gin.HandlerFunc { if err := context.ShouldBindHeader(&authorization); err != nil { message := "please login first to access this resource" response.ResponseError(context, http.StatusUnauthorized, errors.New(message)) + context.Abort() return } @@ -34,6 +35,7 @@ func AuthRequiredMiddleware() gin.HandlerFunc { payload, err := authToken.GetPayload(token) if err != nil { response.ResponseError(context, http.StatusBadRequest, err) + context.Abort() return } -- GitLab From d416f8c98228c09638363ea36cb8ab8fbc72112c Mon Sep 17 00:00:00 2001 From: Hilman Taris Muttaqin Date: Sun, 27 Nov 2022 20:58:37 +0700 Subject: [PATCH 04/62] fixing verify and request otp --- data/request/resend_otp_request.go | 4 +- data/request/verification_otp_request.go | 7 +- domain/handler/api_handler.go | 179 +++++++++++++---------- domain/repository/user_repository.go | 5 +- helper/send_mail.go | 1 + router/route.go | 15 +- 6 files changed, 125 insertions(+), 86 deletions(-) diff --git a/data/request/resend_otp_request.go b/data/request/resend_otp_request.go index d2f5dd1..8252768 100644 --- a/data/request/resend_otp_request.go +++ b/data/request/resend_otp_request.go @@ -1,5 +1,7 @@ package request type ResendOtpRequest struct { - Email string `json:"email"` + Email string `json:"email" binding:"required"` + Role int `json:"role" binding:"required"` + Type string `json:"type" binding:"required"` } diff --git a/data/request/verification_otp_request.go b/data/request/verification_otp_request.go index 92d6a31..55ca258 100644 --- a/data/request/verification_otp_request.go +++ b/data/request/verification_otp_request.go @@ -1,7 +1,8 @@ package request type VerificationOtpRequest struct { - UserId int `json:"user_id"` - Code string `json:"code"` - Type string `json:"type"` + Email string `json:"email" binding:"required"` + Role int `json:"role" binding:"required"` + Code string `json:"code" binding:"required"` + Type string `json:"type" binding:"required"` } diff --git a/domain/handler/api_handler.go b/domain/handler/api_handler.go index f530654..05a3c07 100644 --- a/domain/handler/api_handler.go +++ b/domain/handler/api_handler.go @@ -26,7 +26,12 @@ func GetHandler(userUsecase usecase.UserInteractor) *ApiHandler { } } -func (handler *ApiHandler) CustomerRequestOtp(context *gin.Context) { +/** + * Public API Handler + * API yang dapat diakses tanpa perlu menggunakan token pada body request ataupun pada parameter url + */ + +func (handler *ApiHandler) RequestOtp(context *gin.Context) { // get body var otpRequest request.ResendOtpRequest @@ -36,7 +41,7 @@ func (handler *ApiHandler) CustomerRequestOtp(context *gin.Context) { return } - currentUser, err := handler.userUsecase.GetUserByEmail(otpRequest.Email, 1) + currentUser, err := handler.userUsecase.GetUserByEmail(otpRequest.Email, otpRequest.Role) if err != nil { response.ResponseError(context, http.StatusNotFound, err) return @@ -48,34 +53,41 @@ func (handler *ApiHandler) CustomerRequestOtp(context *gin.Context) { // set otp verification verification := model.VerificationModel{ UserID: currentUser.UserId, - Code: currentUser.Email, - Type: "email", + Code: emailOTP, + Type: otpRequest.Type, CreatedAt: sql.NullTime{Time: time.Now()}, ExpiredAt: sql.NullTime{Time: helper.GetOTPExpiration()}, } - // verify your email - email := model.Email{ - From: os.Getenv("SMTP_EMAIL"), - To: currentUser.Email, - Subject: "Verify Email UBUR App", - Body: helper.GetOtpTemplate(emailOTP), - } - - err = handler.userUsecase.PostOTP(verification) - if err != nil { - response.ResponseError(context, http.StatusInternalServerError, err) + if otpRequest.Type != "email" && otpRequest.Type != "phone" { + response.ResponseError(context, http.StatusInternalServerError, errors.New("Your otp type is wrong")) return } - helper.SendEmail(context, email) + if otpRequest.Type == "email" { + // verify your email + email := model.Email{ + From: os.Getenv("SMTP_EMAIL"), + To: currentUser.Email, + Subject: "Verify Email UBUR App", + Body: helper.GetOtpTemplate(emailOTP), + } + + err = handler.userUsecase.PostOTP(verification) + if err != nil { + response.ResponseError(context, http.StatusInternalServerError, err) + return + } + + helper.SendEmail(context, email) + } response.ResponseSuccess(context, http.StatusOK, gin.H{ "message": "success to resend", }) } -func (handler *ApiHandler) CustomerVerify(context *gin.Context) { +func (handler *ApiHandler) Verify(context *gin.Context) { // get body var otpRequest request.VerificationOtpRequest @@ -85,15 +97,22 @@ func (handler *ApiHandler) CustomerVerify(context *gin.Context) { return } + currentUser, err := handler.userUsecase.GetUserByEmail(otpRequest.Email, otpRequest.Role) + if err != nil { + response.ResponseError(context, http.StatusNotFound, err) + return + } + // get otp verificationModel := model.VerificationModel{ - UserID: otpRequest.UserId, + UserID: currentUser.UserId, Code: otpRequest.Code, Type: otpRequest.Type, } verification, err := handler.userUsecase.GetOTP(verificationModel) if err != nil { response.ResponseError(context, http.StatusInternalServerError, err) + context.Abort() return } @@ -108,60 +127,7 @@ func (handler *ApiHandler) CustomerVerify(context *gin.Context) { }) } -func (handler *ApiHandler) CustomerEditProfile(context *gin.Context) { - userId, err := strconv.Atoi(context.Param("id")) - if err != nil { - response.ResponseError(context, http.StatusInternalServerError, err) - return - } - - var editProfileRequest request.EditProfileRequest - - err = context.ShouldBindJSON(&editProfileRequest) - if err != nil { - HandlerError(context, err) - return - } - - // get exist user - currentUser, err := handler.userUsecase.GetUserById(userId) - if err != nil { - response.ResponseError(context, http.StatusInternalServerError, err) - return - } - - if editProfileRequest.Name != "" { - currentUser.Name = editProfileRequest.Name - } - if editProfileRequest.Email != "" { - // send otp email here - currentUser.Email = editProfileRequest.Email - } - if editProfileRequest.Phone != "" { - // send otp phone here - currentUser.PhoneNumber = editProfileRequest.Phone - } - - err = handler.userUsecase.EditProfile(currentUser) - if err != nil { - response.ResponseError(context, http.StatusInternalServerError, err) - return - } - - response.ResponseSuccess(context, http.StatusOK, gin.H{ - "message": "account has been updated", - "account": gin.H{ - "id": currentUser.UserId, - "name": currentUser.Name, - "email": currentUser.Email, - "phone": currentUser.PhoneNumber, - "role": currentUser.Role, - }, - }) - -} - -func (handler *ApiHandler) CustomerRegister(context *gin.Context) { +func (handler *ApiHandler) Register(context *gin.Context) { var registerRequest request.RegisterRequest err := context.ShouldBindJSON(®isterRequest) @@ -233,7 +199,7 @@ func (handler *ApiHandler) CustomerRegister(context *gin.Context) { }) } -func (handler *ApiHandler) CustomerLogin(context *gin.Context) { +func (handler *ApiHandler) Login(context *gin.Context) { var loginRequest request.LoginRequest err := context.ShouldBindJSON(&loginRequest) @@ -304,7 +270,7 @@ func (handler *ApiHandler) CustomerLogin(context *gin.Context) { }) } -func (handler *ApiHandler) CustomerRefreshToken(context *gin.Context) { +func (handler *ApiHandler) RefreshToken(context *gin.Context) { var refreshTokenRequest request.RefreshTokenRequest refreshTokenRequest.Token = context.Query("refresh-token") @@ -330,6 +296,71 @@ func (handler *ApiHandler) CustomerRefreshToken(context *gin.Context) { }) } +/** + * Customer API Handler + * API yang digunakan customer untuk menggunakan layanan aplikasi ini + * membutuhkan token untuk request semua fitur + */ + +func (handler *ApiHandler) CustomerEditProfile(context *gin.Context) { + userId, err := strconv.Atoi(context.Param("id")) + if err != nil { + response.ResponseError(context, http.StatusInternalServerError, err) + return + } + + var editProfileRequest request.EditProfileRequest + + err = context.ShouldBindJSON(&editProfileRequest) + if err != nil { + HandlerError(context, err) + return + } + + // get exist user + currentUser, err := handler.userUsecase.GetUserById(userId) + if err != nil { + response.ResponseError(context, http.StatusInternalServerError, err) + return + } + + if editProfileRequest.Name != "" { + currentUser.Name = editProfileRequest.Name + } + if editProfileRequest.Email != "" { + // send otp email here + currentUser.Email = editProfileRequest.Email + } + if editProfileRequest.Phone != "" { + // send otp phone here + currentUser.PhoneNumber = editProfileRequest.Phone + } + + err = handler.userUsecase.EditProfile(currentUser) + if err != nil { + response.ResponseError(context, http.StatusInternalServerError, err) + return + } + + response.ResponseSuccess(context, http.StatusOK, gin.H{ + "message": "account has been updated", + "account": gin.H{ + "id": currentUser.UserId, + "name": currentUser.Name, + "email": currentUser.Email, + "phone": currentUser.PhoneNumber, + "role": currentUser.Role, + }, + }) + +} + +/** + * Driver API Handler + * API yang digunakan driver untuk bekerja melalui aplikasi ini + * membutuhkan token untuk request semua fitur + */ + func (handler *ApiHandler) Testing(context *gin.Context) { response.ResponseSuccess(context, http.StatusOK, gin.H{ "message": "Hallo gan, jalan ko", diff --git a/domain/repository/user_repository.go b/domain/repository/user_repository.go index 53a4f06..dfe1a3a 100644 --- a/domain/repository/user_repository.go +++ b/domain/repository/user_repository.go @@ -2,6 +2,7 @@ package repository import ( "database/sql" + "errors" "ubur-backend/data/entity" ) @@ -67,7 +68,7 @@ func (r *Repository) GetUserById(id int) (user entity.UserEntity, err error) { return entity.UserEntity{ Email: "", Password: "", - }, nil + }, errors.New("User with this id not found") } } @@ -96,6 +97,6 @@ func (r *Repository) GetUserByEmail(email string, role int) (user entity.UserEnt return entity.UserEntity{ Email: "", Password: "", - }, nil + }, errors.New("User with this email and role not found") } } diff --git a/helper/send_mail.go b/helper/send_mail.go index 6d7ab91..d96693f 100644 --- a/helper/send_mail.go +++ b/helper/send_mail.go @@ -36,6 +36,7 @@ func SendEmail(context *gin.Context, email model.Email) { // Send the email if err := n.DialAndSend(msg); err != nil { response.ResponseError(context, http.StatusInternalServerError, err) + context.Abort() return } } diff --git a/router/route.go b/router/route.go index 48fe323..a1d91c9 100644 --- a/router/route.go +++ b/router/route.go @@ -5,6 +5,7 @@ import ( "github.com/gin-gonic/gin" "os" "ubur-backend/domain/handler" + "ubur-backend/middleware" ) func PrepareRouter(router *gin.Engine, handler *handler.ApiHandler) *gin.Engine { @@ -15,14 +16,16 @@ func PrepareRouter(router *gin.Engine, handler *handler.ApiHandler) *gin.Engine // route for DRIVER // route for CUSTOMER - customer := v1.Group("/customer") + v1.POST("/login", handler.Login) + v1.POST("/register", handler.Register) + v1.GET("/token", handler.RefreshToken) + v1.POST("/otp", handler.RequestOtp) + v1.POST("/verify", handler.Verify) + + customer := v1.Group("/customer").Use(middleware.AuthRequiredMiddleware()) { - customer.POST("/login", handler.CustomerLogin) - customer.POST("/register", handler.CustomerRegister) - customer.GET("/token", handler.CustomerRefreshToken) - customer.POST("/otp", handler.CustomerRequestOtp) customer.PUT("/:id", handler.CustomerEditProfile) - customer.POST("/:id/verify", handler.CustomerVerify) + } v1.GET("/testing", handler.Testing) -- GitLab From bbe37c702ac9a5251a764cab0226e0e2412fab98 Mon Sep 17 00:00:00 2001 From: Hilman Taris Muttaqin Date: Sun, 27 Nov 2022 23:23:28 +0700 Subject: [PATCH 05/62] add more payload on token userId, role and add implementation for vehicle API --- config/prepare.go | 3 +- data/model/token_payload_model.go | 6 ++- data/model/vehicle_model.go | 2 +- data/request/vehicle_request.go | 6 +++ domain/handler/api_handler.go | 61 ++++++++++++++++++++++++- domain/repository/vehicle_repository.go | 51 +++++++++++++++++++++ domain/usecase/user_usecase.go | 26 ++++++++++- helper/mapper.go | 16 +++++++ helper/token.go | 8 +++- middleware/auth_middleware.go | 4 ++ router/route.go | 28 +++++++----- 11 files changed, 190 insertions(+), 21 deletions(-) create mode 100644 data/request/vehicle_request.go create mode 100644 domain/repository/vehicle_repository.go diff --git a/config/prepare.go b/config/prepare.go index 9054ed9..a39471b 100644 --- a/config/prepare.go +++ b/config/prepare.go @@ -16,9 +16,10 @@ func PrepareAll() *handler.ApiHandler { // prepare repository userRepository := repository2.GetUserRepository(db) verificationRepository := repository2.GetVerificationRepository(db) + vehicleRepository := repository2.GetVehicleRepository(db) // prepare usecase - userUsecase := usecase.GetUserUseCase(userRepository, verificationRepository) + userUsecase := usecase.GetUserUseCase(userRepository, verificationRepository, vehicleRepository) // prepare api handler apiHandler := handler.GetHandler(userUsecase) diff --git a/data/model/token_payload_model.go b/data/model/token_payload_model.go index 67d4660..5aaf010 100644 --- a/data/model/token_payload_model.go +++ b/data/model/token_payload_model.go @@ -1,6 +1,8 @@ package model type TokenPayloadModel struct { - Email string - Exp int64 + Email string + UserId int + Role int + Exp int64 } diff --git a/data/model/vehicle_model.go b/data/model/vehicle_model.go index d358152..faf0fcc 100644 --- a/data/model/vehicle_model.go +++ b/data/model/vehicle_model.go @@ -1,7 +1,7 @@ package model type VehicleModel struct { - VehicleId string + DriverId int RegistrationNoVehicle string VehicleName string } diff --git a/data/request/vehicle_request.go b/data/request/vehicle_request.go new file mode 100644 index 0000000..dad4c8c --- /dev/null +++ b/data/request/vehicle_request.go @@ -0,0 +1,6 @@ +package request + +type VehicleRequest struct { + Name string `json:"name" binding:"required"` + LicensePlate string `json:"license_plate" binding:"required"` +} diff --git a/domain/handler/api_handler.go b/domain/handler/api_handler.go index 05a3c07..4646f28 100644 --- a/domain/handler/api_handler.go +++ b/domain/handler/api_handler.go @@ -232,8 +232,10 @@ func (handler *ApiHandler) Login(context *gin.Context) { salt := []byte(os.Getenv("JWT_SALT")) expirationTime := helper.GetTokenExpiration() payload := model.TokenPayloadModel{ - Email: existUser.Email, - Exp: expirationTime.Unix(), + Email: existUser.Email, + UserId: existUser.UserId, + Role: existUser.Role, + Exp: expirationTime.Unix(), } authToken := helper.GetAuthToken(salt, payload) @@ -361,6 +363,61 @@ func (handler *ApiHandler) CustomerEditProfile(context *gin.Context) { * membutuhkan token untuk request semua fitur */ +func (handler *ApiHandler) NewVehicle(context *gin.Context) { + userId := context.MustGet("userId").(float64) + + var vehicleRequest request.VehicleRequest + err := context.ShouldBindJSON(&vehicleRequest) + if err != nil { + HandlerError(context, err) + return + } + + newVehicleModel := model.VehicleModel{ + DriverId: int(userId), + VehicleName: vehicleRequest.Name, + RegistrationNoVehicle: vehicleRequest.LicensePlate, + } + + err = handler.userUsecase.NewVehicle(newVehicleModel) + if err != nil { + response.ResponseError(context, http.StatusInternalServerError, err) + return + } + + response.ResponseSuccess(context, http.StatusCreated, gin.H{ + "message": "add vehicle success", + "account": gin.H{ + "driver_id": newVehicleModel.DriverId, + "vehicle_name": newVehicleModel.VehicleName, + "license_plate": newVehicleModel.RegistrationNoVehicle, + }, + }) +} + +func (handler *ApiHandler) Vehicle(context *gin.Context) { + userId := context.MustGet("userId").(float64) + + vehicles, err := handler.userUsecase.GetVehicles(int(userId)) + if err != nil { + response.ResponseError(context, http.StatusInternalServerError, err) + return + } + + var results []gin.H + for _, item := range vehicles { + results = append(results, gin.H{ + "driver_id": item.DriverId, + "name": item.VehicleName, + "license_plate": item.RegistrationNoVehicle, + }) + } + + response.ResponseSuccess(context, http.StatusCreated, gin.H{ + "vehicles": results, + }) +} + func (handler *ApiHandler) Testing(context *gin.Context) { response.ResponseSuccess(context, http.StatusOK, gin.H{ "message": "Hallo gan, jalan ko", diff --git a/domain/repository/vehicle_repository.go b/domain/repository/vehicle_repository.go new file mode 100644 index 0000000..92261fa --- /dev/null +++ b/domain/repository/vehicle_repository.go @@ -0,0 +1,51 @@ +package repository + +import ( + "database/sql" + "ubur-backend/data/entity" +) + +type VehicleRepository interface { + InsertNewVehicle(vehicle entity.MotorcycleEntity) (err error) + GetVehicles(driverId int) (results []entity.MotorcycleEntity, err error) +} + +func GetVehicleRepository(db *sql.DB) *Repository { + return &Repository{ + Db: db, + } +} + +func (r *Repository) InsertNewVehicle(vehicle entity.MotorcycleEntity) (err error) { + query := "INSERT INTO motorcycle " + + "(driver_id, name, license_plate) VALUES " + + "(?, ?, ?)" + _, execErr := r.Db.Exec(query, vehicle.DriverID, vehicle.Name, vehicle.LicensePlate) + if execErr != nil { + return execErr + } + return nil +} + +func (r *Repository) GetVehicles(driverId int) (results []entity.MotorcycleEntity, err error) { + query := "SELECT * FROM motorcycle WHERE driver_id=?" + result, err := r.Db.Query(query, driverId) + defer result.Close() + + if err != nil { + panic(err.Error()) + } + + var vehicles []entity.MotorcycleEntity + + for result.Next() { + var vehicle entity.MotorcycleEntity + err := result.Scan(&vehicle.MotorcycleID, &vehicle.DriverID, &vehicle.Name, &vehicle.LicensePlate, &vehicle.CreatedAt, &vehicle.UpdatedAt, &vehicle.DeletedAt) + if err != nil { + return vehicles, err + } + vehicles = append(vehicles, vehicle) + } + + return vehicles, nil +} diff --git a/domain/usecase/user_usecase.go b/domain/usecase/user_usecase.go index a553f14..f4f6eec 100644 --- a/domain/usecase/user_usecase.go +++ b/domain/usecase/user_usecase.go @@ -10,6 +10,7 @@ import ( type UserUseCase struct { userRepository repository.UserRepository verificationRepository repository.VerificationRepository + vehicleRepository repository.VehicleRepository } type UserInteractor interface { @@ -19,17 +20,40 @@ type UserInteractor interface { GetOTP(verificationModel model.VerificationModel) (result model.VerificationModel, err error) PostOTP(verification model.VerificationModel) (err error) EditProfile(user model.UserModel) (err error) + + // Driver Interactor + NewVehicle(vehicle model.VehicleModel) (err error) + GetVehicles(driverId int) (results []model.VehicleModel, err error) } func GetUserUseCase( userRepository repository.UserRepository, - verificationRepository repository.VerificationRepository) *UserUseCase { + verificationRepository repository.VerificationRepository, + vehicleRepository repository.VehicleRepository) *UserUseCase { return &UserUseCase{ userRepository: userRepository, verificationRepository: verificationRepository, + vehicleRepository: vehicleRepository, } } +func (useCase *UserUseCase) NewVehicle(vehicle model.VehicleModel) (err error) { + vehicleEntity := helper.VehicleModelToVehicleEntity(vehicle) + return useCase.vehicleRepository.InsertNewVehicle(vehicleEntity) +} + +func (useCase *UserUseCase) GetVehicles(driverId int) (results []model.VehicleModel, err error) { + var vehicles []model.VehicleModel + + records, err := useCase.vehicleRepository.GetVehicles(driverId) + + for _, item := range records { + vehicles = append(vehicles, helper.VehicleEntityToVehicleModel(item)) + } + + return vehicles, err +} + func (useCase *UserUseCase) GetOTP(verificationModel model.VerificationModel) (result model.VerificationModel, err error) { verificationEntity := helper.VerificationModelToVerificationEntity(verificationModel) otp, error := useCase.verificationRepository.GetSingleVerification(verificationEntity) diff --git a/helper/mapper.go b/helper/mapper.go index d213a46..478356d 100644 --- a/helper/mapper.go +++ b/helper/mapper.go @@ -5,6 +5,22 @@ import ( model2 "ubur-backend/data/model" ) +func VehicleModelToVehicleEntity(model model2.VehicleModel) entity2.MotorcycleEntity { + return entity2.MotorcycleEntity{ + DriverID: model.DriverId, + Name: model.VehicleName, + LicensePlate: model.RegistrationNoVehicle, + } +} + +func VehicleEntityToVehicleModel(entity entity2.MotorcycleEntity) model2.VehicleModel { + return model2.VehicleModel{ + DriverId: entity.DriverID, + VehicleName: entity.Name, + RegistrationNoVehicle: entity.LicensePlate, + } +} + func VerificationEntityToVerificationModel(entity entity2.VerificationEntity) model2.VerificationModel { return model2.VerificationModel{ VerificationID: entity.VerificationID, diff --git a/helper/token.go b/helper/token.go index f7da0b6..5916732 100644 --- a/helper/token.go +++ b/helper/token.go @@ -32,6 +32,8 @@ func (authToken *AuthToken) GenerateToken(random string) (token string, error er jwtToken := jwt.New(jwt.SigningMethodHS512) claims := jwtToken.Claims.(jwt.MapClaims) claims["email"] = authToken.tokenPayload.Email + claims["userId"] = authToken.tokenPayload.UserId + claims["role"] = authToken.tokenPayload.Role claims["rand"] = random if authToken.tokenPayload.Exp != 0 { claims["exp"] = authToken.tokenPayload.Exp @@ -54,8 +56,10 @@ func (authToken *AuthToken) GenerateTokenFromRefreshToken(refreshToken string, r // change payload authToken.tokenPayload = model.TokenPayloadModel{ - Email: payload["email"].(string), - Exp: authToken.tokenPayload.Exp, + Email: payload["email"].(string), + UserId: payload["userId"].(int), + Role: payload["role"].(int), + Exp: authToken.tokenPayload.Exp, } newToken, err := authToken.GenerateToken(random) if err != nil { diff --git a/middleware/auth_middleware.go b/middleware/auth_middleware.go index 2cd29ab..800548d 100644 --- a/middleware/auth_middleware.go +++ b/middleware/auth_middleware.go @@ -2,6 +2,7 @@ package middleware import ( "errors" + "fmt" "github.com/gin-gonic/gin" "log" "net/http" @@ -39,7 +40,10 @@ func AuthRequiredMiddleware() gin.HandlerFunc { return } + fmt.Println("Token Payload", payload) context.Set("email", payload["email"]) + context.Set("userId", payload["userId"]) + context.Set("role", payload["role"]) context.Next() diff --git a/router/route.go b/router/route.go index a1d91c9..6813756 100644 --- a/router/route.go +++ b/router/route.go @@ -13,31 +13,35 @@ func PrepareRouter(router *gin.Engine, handler *handler.ApiHandler) *gin.Engine versionRoute := fmt.Sprintf("/%s", appVersion) v1 := router.Group(versionRoute) { - // route for DRIVER + v1.GET("/testing", handler.Testing) - // route for CUSTOMER v1.POST("/login", handler.Login) v1.POST("/register", handler.Register) v1.GET("/token", handler.RefreshToken) v1.POST("/otp", handler.RequestOtp) v1.POST("/verify", handler.Verify) + /** + * Customer API Enpoint + * API yang digunakan customer untuk menggunakan layanan aplikasi ini + * membutuhkan token untuk request semua fitur + */ customer := v1.Group("/customer").Use(middleware.AuthRequiredMiddleware()) { customer.PUT("/:id", handler.CustomerEditProfile) - } - v1.GET("/testing", handler.Testing) - //v1.POST("/register", handler.Register) - //v1.POST("/login", handler.Login) - //v1.GET("/token", handler.RefreshToken) + /** + * Driver API Enpoint + * API yang digunakan driver untuk bekerja melalui aplikasi ini + * membutuhkan token untuk request semua fitur + */ + driver := v1.Group("/driver").Use(middleware.AuthRequiredMiddleware()) + { + driver.GET("/vehicle", handler.Vehicle) + driver.POST("/vehicle", handler.NewVehicle) + } - //authorized := v1.Group("/resource").Use(middleware.AuthRequiredMiddleware()) - //{ - // authorized.POST("/", handler.InsertSingleResource) - // authorized.GET("/", handler.GetResources) - //} } return router } -- GitLab From a2053fae33915c6971d9685c0d8ff09b72e920c5 Mon Sep 17 00:00:00 2001 From: Hilman Taris Muttaqin Date: Sun, 27 Nov 2022 23:36:55 +0700 Subject: [PATCH 06/62] block user with role customer to access driver endpoint --- data/contant.go | 4 ++++ domain/handler/api_handler.go | 14 ++++++++++++++ 2 files changed, 18 insertions(+) create mode 100644 data/contant.go diff --git a/data/contant.go b/data/contant.go new file mode 100644 index 0000000..c71d899 --- /dev/null +++ b/data/contant.go @@ -0,0 +1,4 @@ +package data + +const ROLE_CUSTOMER = 1 +const ROLE_DRIVER = 2 diff --git a/domain/handler/api_handler.go b/domain/handler/api_handler.go index 4646f28..e61796f 100644 --- a/domain/handler/api_handler.go +++ b/domain/handler/api_handler.go @@ -9,6 +9,7 @@ import ( "os" "strconv" "time" + "ubur-backend/data" "ubur-backend/data/model" "ubur-backend/data/request" "ubur-backend/data/response" @@ -365,6 +366,12 @@ func (handler *ApiHandler) CustomerEditProfile(context *gin.Context) { func (handler *ApiHandler) NewVehicle(context *gin.Context) { userId := context.MustGet("userId").(float64) + role := context.MustGet("role").(float64) + + if int(role) != data.ROLE_DRIVER { + response.ResponseError(context, http.StatusBadRequest, errors.New("you can't add vehicle because you're not a driver")) + return + } var vehicleRequest request.VehicleRequest err := context.ShouldBindJSON(&vehicleRequest) @@ -397,6 +404,13 @@ func (handler *ApiHandler) NewVehicle(context *gin.Context) { func (handler *ApiHandler) Vehicle(context *gin.Context) { userId := context.MustGet("userId").(float64) + role := context.MustGet("role").(float64) + + if int(role) != data.ROLE_DRIVER { + response.ResponseError(context, http.StatusBadRequest, errors.New("you're a customer, so you don't "+ + "have a vehicle assosiated with your account")) + return + } vehicles, err := handler.userUsecase.GetVehicles(int(userId)) if err != nil { -- GitLab From cf546de5b44b60f44ec159590b496051f1f261f7 Mon Sep 17 00:00:00 2001 From: Hilman Taris Muttaqin Date: Sun, 27 Nov 2022 23:50:14 +0700 Subject: [PATCH 07/62] add driver middleware --- domain/handler/api_handler.go | 14 -------------- middleware/driver_middleware.go | 29 +++++++++++++++++++++++++++++ router/route.go | 2 +- 3 files changed, 30 insertions(+), 15 deletions(-) create mode 100644 middleware/driver_middleware.go diff --git a/domain/handler/api_handler.go b/domain/handler/api_handler.go index e61796f..4646f28 100644 --- a/domain/handler/api_handler.go +++ b/domain/handler/api_handler.go @@ -9,7 +9,6 @@ import ( "os" "strconv" "time" - "ubur-backend/data" "ubur-backend/data/model" "ubur-backend/data/request" "ubur-backend/data/response" @@ -366,12 +365,6 @@ func (handler *ApiHandler) CustomerEditProfile(context *gin.Context) { func (handler *ApiHandler) NewVehicle(context *gin.Context) { userId := context.MustGet("userId").(float64) - role := context.MustGet("role").(float64) - - if int(role) != data.ROLE_DRIVER { - response.ResponseError(context, http.StatusBadRequest, errors.New("you can't add vehicle because you're not a driver")) - return - } var vehicleRequest request.VehicleRequest err := context.ShouldBindJSON(&vehicleRequest) @@ -404,13 +397,6 @@ func (handler *ApiHandler) NewVehicle(context *gin.Context) { func (handler *ApiHandler) Vehicle(context *gin.Context) { userId := context.MustGet("userId").(float64) - role := context.MustGet("role").(float64) - - if int(role) != data.ROLE_DRIVER { - response.ResponseError(context, http.StatusBadRequest, errors.New("you're a customer, so you don't "+ - "have a vehicle assosiated with your account")) - return - } vehicles, err := handler.userUsecase.GetVehicles(int(userId)) if err != nil { diff --git a/middleware/driver_middleware.go b/middleware/driver_middleware.go new file mode 100644 index 0000000..536868d --- /dev/null +++ b/middleware/driver_middleware.go @@ -0,0 +1,29 @@ +package middleware + +import ( + "errors" + "github.com/gin-gonic/gin" + "log" + "net/http" + "ubur-backend/data" + "ubur-backend/data/response" +) + +func DriverRequiredMiddleware() gin.HandlerFunc { + return func(context *gin.Context) { + role := context.MustGet("role").(float64) + + if role != data.ROLE_DRIVER { + response.ResponseError(context, http.StatusBadRequest, errors.New("driver enpoint, "+ + "not allowed to use this endpoint")) + context.Abort() + return + } + + context.Next() + + // access the status we are sending + status := context.Writer.Status() + log.Println(status) + } +} diff --git a/router/route.go b/router/route.go index 6813756..c28f4d8 100644 --- a/router/route.go +++ b/router/route.go @@ -36,7 +36,7 @@ func PrepareRouter(router *gin.Engine, handler *handler.ApiHandler) *gin.Engine * API yang digunakan driver untuk bekerja melalui aplikasi ini * membutuhkan token untuk request semua fitur */ - driver := v1.Group("/driver").Use(middleware.AuthRequiredMiddleware()) + driver := v1.Group("/driver").Use(middleware.AuthRequiredMiddleware(), middleware.DriverRequiredMiddleware()) { driver.GET("/vehicle", handler.Vehicle) driver.POST("/vehicle", handler.NewVehicle) -- GitLab From 5dc6d2da3685b47f50b4d4b7559777929b072acb Mon Sep 17 00:00:00 2001 From: Hilman Taris Muttaqin Date: Mon, 28 Nov 2022 05:54:45 +0700 Subject: [PATCH 08/62] add customer middleware in route group customer --- middleware/customer_middleware.go | 29 +++++++++++++++++++++++++++++ router/route.go | 8 ++++++-- 2 files changed, 35 insertions(+), 2 deletions(-) create mode 100644 middleware/customer_middleware.go diff --git a/middleware/customer_middleware.go b/middleware/customer_middleware.go new file mode 100644 index 0000000..b199d53 --- /dev/null +++ b/middleware/customer_middleware.go @@ -0,0 +1,29 @@ +package middleware + +import ( + "errors" + "github.com/gin-gonic/gin" + "log" + "net/http" + "ubur-backend/data" + "ubur-backend/data/response" +) + +func CustomerRequiredMiddleware() gin.HandlerFunc { + return func(context *gin.Context) { + role := context.MustGet("role").(float64) + + if role != data.ROLE_CUSTOMER { + response.ResponseError(context, http.StatusBadRequest, errors.New("customer enpoint, "+ + "not allowed to use this endpoint")) + context.Abort() + return + } + + context.Next() + + // access the status we are sending + status := context.Writer.Status() + log.Println(status) + } +} diff --git a/router/route.go b/router/route.go index c28f4d8..a9b8b48 100644 --- a/router/route.go +++ b/router/route.go @@ -26,7 +26,9 @@ func PrepareRouter(router *gin.Engine, handler *handler.ApiHandler) *gin.Engine * API yang digunakan customer untuk menggunakan layanan aplikasi ini * membutuhkan token untuk request semua fitur */ - customer := v1.Group("/customer").Use(middleware.AuthRequiredMiddleware()) + customer := v1.Group("/customer").Use( + middleware.AuthRequiredMiddleware(), + middleware.CustomerRequiredMiddleware()) { customer.PUT("/:id", handler.CustomerEditProfile) } @@ -36,7 +38,9 @@ func PrepareRouter(router *gin.Engine, handler *handler.ApiHandler) *gin.Engine * API yang digunakan driver untuk bekerja melalui aplikasi ini * membutuhkan token untuk request semua fitur */ - driver := v1.Group("/driver").Use(middleware.AuthRequiredMiddleware(), middleware.DriverRequiredMiddleware()) + driver := v1.Group("/driver").Use( + middleware.AuthRequiredMiddleware(), + middleware.DriverRequiredMiddleware()) { driver.GET("/vehicle", handler.Vehicle) driver.POST("/vehicle", handler.NewVehicle) -- GitLab From 30b8a1ae20b8fc6710443e044b07e3f46affe9f5 Mon Sep 17 00:00:00 2001 From: Hilman Taris Muttaqin Date: Mon, 28 Nov 2022 11:20:42 +0700 Subject: [PATCH 09/62] change auth handler to auth_handler.go file --- config/prepare.go | 5 +- domain/handler/api_handler.go | 277 +------------------------------ domain/handler/auth_handler.go | 293 +++++++++++++++++++++++++++++++++ main.go | 4 +- router/route.go | 23 +-- 5 files changed, 313 insertions(+), 289 deletions(-) create mode 100644 domain/handler/auth_handler.go diff --git a/config/prepare.go b/config/prepare.go index a39471b..3435bba 100644 --- a/config/prepare.go +++ b/config/prepare.go @@ -7,7 +7,7 @@ import ( "ubur-backend/domain/usecase" ) -func PrepareAll() *handler.ApiHandler { +func PrepareAll() (*handler.ApiHandler, *handler.AuthHandler) { // prepare database configuration fmt.Println("Get database connection") @@ -23,6 +23,7 @@ func PrepareAll() *handler.ApiHandler { // prepare api handler apiHandler := handler.GetHandler(userUsecase) + authHandler := handler.GetAuthHandler(userUsecase) - return apiHandler + return apiHandler, authHandler } diff --git a/domain/handler/api_handler.go b/domain/handler/api_handler.go index 4646f28..c516f44 100644 --- a/domain/handler/api_handler.go +++ b/domain/handler/api_handler.go @@ -1,19 +1,13 @@ package handler import ( - "database/sql" - "errors" "github.com/gin-gonic/gin" - "golang.org/x/crypto/bcrypt" "net/http" - "os" "strconv" - "time" "ubur-backend/data/model" "ubur-backend/data/request" "ubur-backend/data/response" "ubur-backend/domain/usecase" - "ubur-backend/helper" ) type ApiHandler struct { @@ -31,270 +25,9 @@ func GetHandler(userUsecase usecase.UserInteractor) *ApiHandler { * API yang dapat diakses tanpa perlu menggunakan token pada body request ataupun pada parameter url */ -func (handler *ApiHandler) RequestOtp(context *gin.Context) { - // get body - var otpRequest request.ResendOtpRequest - - err := context.ShouldBindJSON(&otpRequest) - if err != nil { - HandlerError(context, err) - return - } - - currentUser, err := handler.userUsecase.GetUserByEmail(otpRequest.Email, otpRequest.Role) - if err != nil { - response.ResponseError(context, http.StatusNotFound, err) - return - } - - // set email otp - emailOTP := helper.GetRandomIntString(5) - - // set otp verification - verification := model.VerificationModel{ - UserID: currentUser.UserId, - Code: emailOTP, - Type: otpRequest.Type, - CreatedAt: sql.NullTime{Time: time.Now()}, - ExpiredAt: sql.NullTime{Time: helper.GetOTPExpiration()}, - } - - if otpRequest.Type != "email" && otpRequest.Type != "phone" { - response.ResponseError(context, http.StatusInternalServerError, errors.New("Your otp type is wrong")) - return - } - - if otpRequest.Type == "email" { - // verify your email - email := model.Email{ - From: os.Getenv("SMTP_EMAIL"), - To: currentUser.Email, - Subject: "Verify Email UBUR App", - Body: helper.GetOtpTemplate(emailOTP), - } - - err = handler.userUsecase.PostOTP(verification) - if err != nil { - response.ResponseError(context, http.StatusInternalServerError, err) - return - } - - helper.SendEmail(context, email) - } - - response.ResponseSuccess(context, http.StatusOK, gin.H{ - "message": "success to resend", - }) -} - -func (handler *ApiHandler) Verify(context *gin.Context) { - // get body - var otpRequest request.VerificationOtpRequest - - err := context.ShouldBindJSON(&otpRequest) - if err != nil { - HandlerError(context, err) - return - } - - currentUser, err := handler.userUsecase.GetUserByEmail(otpRequest.Email, otpRequest.Role) - if err != nil { - response.ResponseError(context, http.StatusNotFound, err) - return - } - - // get otp - verificationModel := model.VerificationModel{ - UserID: currentUser.UserId, - Code: otpRequest.Code, - Type: otpRequest.Type, - } - verification, err := handler.userUsecase.GetOTP(verificationModel) - if err != nil { - response.ResponseError(context, http.StatusInternalServerError, err) - context.Abort() - return - } - - if time.Now().After(verification.ExpiredAt.Time) { - response.ResponseError(context, http.StatusBadRequest, errors.New("your token input expired, please request otp again")) - // remove otp - return - } - - response.ResponseSuccess(context, http.StatusOK, gin.H{ - "message": "success to verify", - }) -} - -func (handler *ApiHandler) Register(context *gin.Context) { - var registerRequest request.RegisterRequest - - err := context.ShouldBindJSON(®isterRequest) - if err != nil { - HandlerError(context, err) - return - } - - // pass data - newUser := model.UserModel{ - Email: registerRequest.Email, - Password: registerRequest.Password, - Role: registerRequest.Role, - PhoneNumber: registerRequest.Phone, - } - - passByteArr := []byte(newUser.Password) - passHashByte, err := bcrypt.GenerateFromPassword(passByteArr, 12) - - if err != nil { - response.ResponseError(context, http.StatusInternalServerError, err) - return - } - - passHash := string(passHashByte) - newUser.Password = passHash - - err = handler.userUsecase.Register(newUser) - if err != nil { - response.ResponseError(context, http.StatusInternalServerError, err) - return - } - - currentUser, err := handler.userUsecase.GetUserByEmail(newUser.Email, 1) - if err != nil { - response.ResponseError(context, http.StatusNotFound, err) - return - } - - // set email otp - emailOTP := helper.GetRandomIntString(5) - - // verify your email - email := model.Email{ - From: os.Getenv("SMTP_EMAIL"), - To: newUser.Email, - Subject: "Verify Email UBUR App", - Body: helper.GetOtpTemplate(emailOTP), - } - - // set otp verification - verification := model.VerificationModel{ - UserID: currentUser.UserId, - Code: emailOTP, - Type: "email", - CreatedAt: sql.NullTime{Time: time.Now()}, - ExpiredAt: sql.NullTime{Time: helper.GetOTPExpiration()}, - } - err = handler.userUsecase.PostOTP(verification) - if err != nil { - response.ResponseError(context, http.StatusInternalServerError, err) - return - } - - helper.SendEmail(context, email) - - response.ResponseSuccess(context, http.StatusCreated, gin.H{ - "message": "account success created, please check your email", - }) -} - -func (handler *ApiHandler) Login(context *gin.Context) { - var loginRequest request.LoginRequest - - err := context.ShouldBindJSON(&loginRequest) - if err != nil { - HandlerError(context, err) - return - } - - user := model.UserModel{ - Email: loginRequest.Email, - Password: loginRequest.Password, - Role: loginRequest.Role, - } - - // get user by email - existUser, err := handler.userUsecase.GetUserByEmail(user.Email, user.Role) - if err != nil { - response.ResponseError(context, http.StatusNotFound, err) - return - } - - err = bcrypt.CompareHashAndPassword([]byte(existUser.Password), []byte(user.Password)) - if err != nil { - message := "your email and password combination is wrong" - response.ResponseError(context, http.StatusBadRequest, errors.New(message)) - return - } - - // sign jwt token and refresh token - salt := []byte(os.Getenv("JWT_SALT")) - expirationTime := helper.GetTokenExpiration() - payload := model.TokenPayloadModel{ - Email: existUser.Email, - UserId: existUser.UserId, - Role: existUser.Role, - Exp: expirationTime.Unix(), - } - - authToken := helper.GetAuthToken(salt, payload) - randomString := helper.GetRandomString(50) - generatedToken, err := authToken.GenerateToken(randomString) - if err != nil { - response.ResponseError(context, http.StatusBadRequest, err) - return - } - - payload = model.TokenPayloadModel{ - Email: existUser.Email, - Exp: 0, - } - authToken.ChangePayload(payload) - randomString = helper.GetRandomString(50) - refreshToken, err := authToken.GenerateToken(randomString) - if err != nil { - response.ResponseError(context, http.StatusBadRequest, err) - return - } - - response.ResponseSuccess(context, http.StatusOK, gin.H{ - "message": "Success login", - "token": generatedToken, - "refresh_token": refreshToken, - "account": gin.H{ - "id": existUser.UserId, - "name": existUser.Name, - "email": existUser.Email, - "phone": existUser.PhoneNumber, - "role": existUser.Role, - }, - }) -} - -func (handler *ApiHandler) RefreshToken(context *gin.Context) { - var refreshTokenRequest request.RefreshTokenRequest - - refreshTokenRequest.Token = context.Query("refresh-token") - - // generate new token - salt := []byte(os.Getenv("JWT_SALT")) - expirationTime := helper.GetTokenExpiration() - tempPayload := model.TokenPayloadModel{ - Email: "", - Exp: expirationTime.Unix(), - } - authToken := helper.GetAuthToken(salt, tempPayload) - randomString := helper.GetRandomString(50) - newToken, err := authToken.GenerateTokenFromRefreshToken(refreshTokenRequest.Token, randomString) - if err != nil { - response.ResponseError(context, http.StatusInternalServerError, err) - return - } - +func (handler *ApiHandler) Testing(context *gin.Context) { response.ResponseSuccess(context, http.StatusOK, gin.H{ - "message": "success create new token", - "token": newToken, + "message": "Hallo gan, jalan ko", }) } @@ -417,9 +150,3 @@ func (handler *ApiHandler) Vehicle(context *gin.Context) { "vehicles": results, }) } - -func (handler *ApiHandler) Testing(context *gin.Context) { - response.ResponseSuccess(context, http.StatusOK, gin.H{ - "message": "Hallo gan, jalan ko", - }) -} diff --git a/domain/handler/auth_handler.go b/domain/handler/auth_handler.go new file mode 100644 index 0000000..e399e16 --- /dev/null +++ b/domain/handler/auth_handler.go @@ -0,0 +1,293 @@ +package handler + +import ( + "database/sql" + "errors" + "github.com/gin-gonic/gin" + "golang.org/x/crypto/bcrypt" + "net/http" + "os" + "time" + "ubur-backend/data/model" + "ubur-backend/data/request" + "ubur-backend/data/response" + "ubur-backend/domain/usecase" + "ubur-backend/helper" +) + +type AuthHandler struct { + userUsecase usecase.UserInteractor +} + +func GetAuthHandler(userUsecase usecase.UserInteractor) *AuthHandler { + return &AuthHandler{ + userUsecase: userUsecase, + } +} + +func (handler *AuthHandler) RequestOtp(context *gin.Context) { + // get body + var otpRequest request.ResendOtpRequest + + err := context.ShouldBindJSON(&otpRequest) + if err != nil { + HandlerError(context, err) + return + } + + currentUser, err := handler.userUsecase.GetUserByEmail(otpRequest.Email, otpRequest.Role) + if err != nil { + response.ResponseError(context, http.StatusNotFound, err) + return + } + + // set email otp + emailOTP := helper.GetRandomIntString(5) + + // set otp verification + verification := model.VerificationModel{ + UserID: currentUser.UserId, + Code: emailOTP, + Type: otpRequest.Type, + CreatedAt: sql.NullTime{Time: time.Now()}, + ExpiredAt: sql.NullTime{Time: helper.GetOTPExpiration()}, + } + + if otpRequest.Type != "email" && otpRequest.Type != "phone" { + response.ResponseError(context, http.StatusInternalServerError, errors.New("Your otp type is wrong")) + return + } + + if otpRequest.Type == "email" { + // verify your email + email := model.Email{ + From: os.Getenv("SMTP_EMAIL"), + To: currentUser.Email, + Subject: "Verify Email UBUR App", + Body: helper.GetOtpTemplate(emailOTP), + } + + err = handler.userUsecase.PostOTP(verification) + if err != nil { + response.ResponseError(context, http.StatusInternalServerError, err) + return + } + + helper.SendEmail(context, email) + } + + response.ResponseSuccess(context, http.StatusOK, gin.H{ + "message": "success to resend", + }) +} + +func (handler *AuthHandler) Verify(context *gin.Context) { + // get body + var otpRequest request.VerificationOtpRequest + + err := context.ShouldBindJSON(&otpRequest) + if err != nil { + HandlerError(context, err) + return + } + + currentUser, err := handler.userUsecase.GetUserByEmail(otpRequest.Email, otpRequest.Role) + if err != nil { + response.ResponseError(context, http.StatusNotFound, err) + return + } + + // get otp + verificationModel := model.VerificationModel{ + UserID: currentUser.UserId, + Code: otpRequest.Code, + Type: otpRequest.Type, + } + verification, err := handler.userUsecase.GetOTP(verificationModel) + if err != nil { + response.ResponseError(context, http.StatusInternalServerError, err) + context.Abort() + return + } + + if time.Now().After(verification.ExpiredAt.Time) { + response.ResponseError(context, http.StatusBadRequest, errors.New("your token input expired, please request otp again")) + // remove otp + return + } + + response.ResponseSuccess(context, http.StatusOK, gin.H{ + "message": "success to verify", + }) +} + +func (handler *AuthHandler) Register(context *gin.Context) { + var registerRequest request.RegisterRequest + + err := context.ShouldBindJSON(®isterRequest) + if err != nil { + HandlerError(context, err) + return + } + + // pass data + newUser := model.UserModel{ + Email: registerRequest.Email, + Password: registerRequest.Password, + Role: registerRequest.Role, + PhoneNumber: registerRequest.Phone, + } + + passByteArr := []byte(newUser.Password) + passHashByte, err := bcrypt.GenerateFromPassword(passByteArr, 12) + + if err != nil { + response.ResponseError(context, http.StatusInternalServerError, err) + return + } + + passHash := string(passHashByte) + newUser.Password = passHash + + err = handler.userUsecase.Register(newUser) + if err != nil { + response.ResponseError(context, http.StatusInternalServerError, err) + return + } + + currentUser, err := handler.userUsecase.GetUserByEmail(newUser.Email, 1) + if err != nil { + response.ResponseError(context, http.StatusNotFound, err) + return + } + + // set email otp + emailOTP := helper.GetRandomIntString(5) + + // verify your email + email := model.Email{ + From: os.Getenv("SMTP_EMAIL"), + To: newUser.Email, + Subject: "Verify Email UBUR App", + Body: helper.GetOtpTemplate(emailOTP), + } + + // set otp verification + verification := model.VerificationModel{ + UserID: currentUser.UserId, + Code: emailOTP, + Type: "email", + CreatedAt: sql.NullTime{Time: time.Now()}, + ExpiredAt: sql.NullTime{Time: helper.GetOTPExpiration()}, + } + err = handler.userUsecase.PostOTP(verification) + if err != nil { + response.ResponseError(context, http.StatusInternalServerError, err) + return + } + + helper.SendEmail(context, email) + + response.ResponseSuccess(context, http.StatusCreated, gin.H{ + "message": "account success created, please check your email", + }) +} + +func (handler *AuthHandler) Login(context *gin.Context) { + var loginRequest request.LoginRequest + + err := context.ShouldBindJSON(&loginRequest) + if err != nil { + HandlerError(context, err) + return + } + + user := model.UserModel{ + Email: loginRequest.Email, + Password: loginRequest.Password, + Role: loginRequest.Role, + } + + // get user by email + existUser, err := handler.userUsecase.GetUserByEmail(user.Email, user.Role) + if err != nil { + response.ResponseError(context, http.StatusNotFound, err) + return + } + + err = bcrypt.CompareHashAndPassword([]byte(existUser.Password), []byte(user.Password)) + if err != nil { + message := "your email and password combination is wrong" + response.ResponseError(context, http.StatusBadRequest, errors.New(message)) + return + } + + // sign jwt token and refresh token + salt := []byte(os.Getenv("JWT_SALT")) + expirationTime := helper.GetTokenExpiration() + payload := model.TokenPayloadModel{ + Email: existUser.Email, + UserId: existUser.UserId, + Role: existUser.Role, + Exp: expirationTime.Unix(), + } + + authToken := helper.GetAuthToken(salt, payload) + randomString := helper.GetRandomString(50) + generatedToken, err := authToken.GenerateToken(randomString) + if err != nil { + response.ResponseError(context, http.StatusBadRequest, err) + return + } + + payload = model.TokenPayloadModel{ + Email: existUser.Email, + Exp: 0, + } + authToken.ChangePayload(payload) + randomString = helper.GetRandomString(50) + refreshToken, err := authToken.GenerateToken(randomString) + if err != nil { + response.ResponseError(context, http.StatusBadRequest, err) + return + } + + response.ResponseSuccess(context, http.StatusOK, gin.H{ + "message": "Success login", + "token": generatedToken, + "refresh_token": refreshToken, + "account": gin.H{ + "id": existUser.UserId, + "name": existUser.Name, + "email": existUser.Email, + "phone": existUser.PhoneNumber, + "role": existUser.Role, + }, + }) +} + +func (handler *AuthHandler) RefreshToken(context *gin.Context) { + var refreshTokenRequest request.RefreshTokenRequest + + refreshTokenRequest.Token = context.Query("refresh-token") + + // generate new token + salt := []byte(os.Getenv("JWT_SALT")) + expirationTime := helper.GetTokenExpiration() + tempPayload := model.TokenPayloadModel{ + Email: "", + Exp: expirationTime.Unix(), + } + authToken := helper.GetAuthToken(salt, tempPayload) + randomString := helper.GetRandomString(50) + newToken, err := authToken.GenerateTokenFromRefreshToken(refreshTokenRequest.Token, randomString) + if err != nil { + response.ResponseError(context, http.StatusInternalServerError, err) + return + } + + response.ResponseSuccess(context, http.StatusOK, gin.H{ + "message": "success create new token", + "token": newToken, + }) +} diff --git a/main.go b/main.go index 091cb0a..52961f9 100644 --- a/main.go +++ b/main.go @@ -27,13 +27,13 @@ func main() { // - usecase // - api handler return fmt.Println("Starting prepare all configuration") - apiHandler := config.PrepareAll() + apiHandler, authHandler := config.PrepareAll() // setting cors engine.Use(middleware.CORSMiddleware()) // router - router := router2.PrepareRouter(engine, apiHandler) + router := router2.PrepareRouter(engine, apiHandler, authHandler) router.Run() } diff --git a/router/route.go b/router/route.go index a9b8b48..3a5b3a4 100644 --- a/router/route.go +++ b/router/route.go @@ -8,18 +8,21 @@ import ( "ubur-backend/middleware" ) -func PrepareRouter(router *gin.Engine, handler *handler.ApiHandler) *gin.Engine { +func PrepareRouter( + router *gin.Engine, + apiHandler *handler.ApiHandler, + authHandler *handler.AuthHandler) *gin.Engine { appVersion := os.Getenv("VERSION") versionRoute := fmt.Sprintf("/%s", appVersion) v1 := router.Group(versionRoute) { - v1.GET("/testing", handler.Testing) + v1.GET("/testing", apiHandler.Testing) - v1.POST("/login", handler.Login) - v1.POST("/register", handler.Register) - v1.GET("/token", handler.RefreshToken) - v1.POST("/otp", handler.RequestOtp) - v1.POST("/verify", handler.Verify) + v1.POST("/login", authHandler.Login) + v1.POST("/register", authHandler.Register) + v1.GET("/token", authHandler.RefreshToken) + v1.POST("/otp", authHandler.RequestOtp) + v1.POST("/verify", authHandler.Verify) /** * Customer API Enpoint @@ -30,7 +33,7 @@ func PrepareRouter(router *gin.Engine, handler *handler.ApiHandler) *gin.Engine middleware.AuthRequiredMiddleware(), middleware.CustomerRequiredMiddleware()) { - customer.PUT("/:id", handler.CustomerEditProfile) + customer.PUT("/:id", apiHandler.CustomerEditProfile) } /** @@ -42,8 +45,8 @@ func PrepareRouter(router *gin.Engine, handler *handler.ApiHandler) *gin.Engine middleware.AuthRequiredMiddleware(), middleware.DriverRequiredMiddleware()) { - driver.GET("/vehicle", handler.Vehicle) - driver.POST("/vehicle", handler.NewVehicle) + driver.GET("/vehicle", apiHandler.Vehicle) + driver.POST("/vehicle", apiHandler.NewVehicle) } } -- GitLab From 3f13ac9862fb9fddb531c73702bb41af2545d988 Mon Sep 17 00:00:00 2001 From: Hilman Taris Muttaqin Date: Mon, 28 Nov 2022 12:48:21 +0700 Subject: [PATCH 10/62] implement delete vehicle API --- data/entity/motorcycle_entity.go | 14 ++++----- domain/handler/api_handler.go | 31 +++++++++++++++++++ domain/repository/vehicle_repository.go | 40 ++++++++++++++++++++++++- domain/usecase/user_usecase.go | 18 +++++++++++ middleware/auth_middleware.go | 2 -- router/route.go | 1 + 6 files changed, 96 insertions(+), 10 deletions(-) diff --git a/data/entity/motorcycle_entity.go b/data/entity/motorcycle_entity.go index bbfa84d..6577314 100644 --- a/data/entity/motorcycle_entity.go +++ b/data/entity/motorcycle_entity.go @@ -3,11 +3,11 @@ package entity import "database/sql" type MotorcycleEntity struct { - MotorcycleID int `json:"motorcycle_id"` - DriverID int `json:"driver_id"` - Name string `json:"name"` - LicensePlate string `json:"license_plate"` - CreatedAt string `json:"created_at"` - UpdatedAt sql.NullString `json:"update_at"` - DeletedAt sql.NullString `json:"deleted_at"` + MotorcycleID int `json:"motorcycle_id"` + DriverID int `json:"driver_id"` + Name string `json:"name"` + LicensePlate string `json:"license_plate"` + CreatedAt string `json:"created_at"` + UpdatedAt sql.NullTime `json:"update_at"` + DeletedAt sql.NullTime `json:"deleted_at"` } diff --git a/domain/handler/api_handler.go b/domain/handler/api_handler.go index c516f44..fe0e87e 100644 --- a/domain/handler/api_handler.go +++ b/domain/handler/api_handler.go @@ -1,6 +1,7 @@ package handler import ( + "errors" "github.com/gin-gonic/gin" "net/http" "strconv" @@ -150,3 +151,33 @@ func (handler *ApiHandler) Vehicle(context *gin.Context) { "vehicles": results, }) } + +func (handler *ApiHandler) DeleteVehicle(context *gin.Context) { + userId := context.MustGet("userId").(float64) + vehicleIdQuery, filled := context.GetQuery("vehicle_id") + if !filled { + response.ResponseError(context, http.StatusBadRequest, errors.New("vehicle_id query required")) + return + } + + vehicleId, err := strconv.Atoi(vehicleIdQuery) + if err != nil { + response.ResponseError(context, http.StatusInternalServerError, err) + return + } + + vehicle, err := handler.userUsecase.DeleteVehicle(int(userId), vehicleId) + if err != nil { + response.ResponseError(context, http.StatusInternalServerError, err) + return + } + + response.ResponseSuccess(context, http.StatusOK, gin.H{ + "message": "success delete vehicle", + "vehicle": gin.H{ + "driver_id": vehicle.DriverId, + "name": vehicle.VehicleName, + "license_plate": vehicle.RegistrationNoVehicle, + }, + }) +} diff --git a/domain/repository/vehicle_repository.go b/domain/repository/vehicle_repository.go index 92261fa..d14520c 100644 --- a/domain/repository/vehicle_repository.go +++ b/domain/repository/vehicle_repository.go @@ -2,12 +2,15 @@ package repository import ( "database/sql" + "errors" "ubur-backend/data/entity" ) type VehicleRepository interface { InsertNewVehicle(vehicle entity.MotorcycleEntity) (err error) GetVehicles(driverId int) (results []entity.MotorcycleEntity, err error) + GetVehicleById(driverId int, vehicleId int) (vehicleResult entity.MotorcycleEntity, err error) + EditVehicle(vehicle entity.MotorcycleEntity) (err error) } func GetVehicleRepository(db *sql.DB) *Repository { @@ -28,7 +31,7 @@ func (r *Repository) InsertNewVehicle(vehicle entity.MotorcycleEntity) (err erro } func (r *Repository) GetVehicles(driverId int) (results []entity.MotorcycleEntity, err error) { - query := "SELECT * FROM motorcycle WHERE driver_id=?" + query := "SELECT * FROM motorcycle WHERE driver_id=? AND deleted_at IS NULL" result, err := r.Db.Query(query, driverId) defer result.Close() @@ -49,3 +52,38 @@ func (r *Repository) GetVehicles(driverId int) (results []entity.MotorcycleEntit return vehicles, nil } + +func (r *Repository) GetVehicleById(driverId int, vehicleId int) (vehicleResult entity.MotorcycleEntity, err error) { + query := "SELECT * FROM motorcycle WHERE driver_id=? AND motorcycle_id=? AND deleted_at IS NULL" + result, err := r.Db.Query(query, driverId, vehicleId) + defer result.Close() + + if err != nil { + panic(err.Error()) + } + + if result.Next() { + var vehicle entity.MotorcycleEntity + err := result.Scan(&vehicle.MotorcycleID, &vehicle.DriverID, &vehicle.Name, &vehicle.LicensePlate, + &vehicle.CreatedAt, &vehicle.UpdatedAt, &vehicle.DeletedAt) + + if err != nil { + return vehicleResult, err + } + + return vehicle, nil + } else { + return entity.MotorcycleEntity{}, errors.New("Vehicle Not Found") + } +} + +func (r *Repository) EditVehicle(vehicle entity.MotorcycleEntity) (err error) { + query := "UPDATE motorcycle SET name=?, license_plate=?, deleted_at=? " + + "WHERE driver_id=? AND motorcycle_id=?" + _, execErr := r.Db.Exec(query, vehicle.Name, vehicle.LicensePlate, + vehicle.DeletedAt.Time, vehicle.DriverID, vehicle.MotorcycleID) + if execErr != nil { + return execErr + } + return nil +} diff --git a/domain/usecase/user_usecase.go b/domain/usecase/user_usecase.go index f4f6eec..45101f9 100644 --- a/domain/usecase/user_usecase.go +++ b/domain/usecase/user_usecase.go @@ -1,7 +1,9 @@ package usecase import ( + "database/sql" "strings" + "time" "ubur-backend/data/model" "ubur-backend/domain/repository" "ubur-backend/helper" @@ -24,6 +26,7 @@ type UserInteractor interface { // Driver Interactor NewVehicle(vehicle model.VehicleModel) (err error) GetVehicles(driverId int) (results []model.VehicleModel, err error) + DeleteVehicle(driverId int, vehicleId int) (result model.VehicleModel, err error) } func GetUserUseCase( @@ -37,6 +40,21 @@ func GetUserUseCase( } } +func (useCase *UserUseCase) DeleteVehicle(driverId int, vehicleId int) (result model.VehicleModel, err error) { + vehicle, err := useCase.vehicleRepository.GetVehicleById(driverId, vehicleId) + if err != nil { + return model.VehicleModel{}, err + } + + vehicle.DeletedAt = sql.NullTime{Time: time.Now()} + err = useCase.vehicleRepository.EditVehicle(vehicle) + if err != nil { + return model.VehicleModel{}, err + } + + return helper.VehicleEntityToVehicleModel(vehicle), nil +} + func (useCase *UserUseCase) NewVehicle(vehicle model.VehicleModel) (err error) { vehicleEntity := helper.VehicleModelToVehicleEntity(vehicle) return useCase.vehicleRepository.InsertNewVehicle(vehicleEntity) diff --git a/middleware/auth_middleware.go b/middleware/auth_middleware.go index 800548d..977c4d5 100644 --- a/middleware/auth_middleware.go +++ b/middleware/auth_middleware.go @@ -2,7 +2,6 @@ package middleware import ( "errors" - "fmt" "github.com/gin-gonic/gin" "log" "net/http" @@ -40,7 +39,6 @@ func AuthRequiredMiddleware() gin.HandlerFunc { return } - fmt.Println("Token Payload", payload) context.Set("email", payload["email"]) context.Set("userId", payload["userId"]) context.Set("role", payload["role"]) diff --git a/router/route.go b/router/route.go index 3a5b3a4..d8ce3b0 100644 --- a/router/route.go +++ b/router/route.go @@ -47,6 +47,7 @@ func PrepareRouter( { driver.GET("/vehicle", apiHandler.Vehicle) driver.POST("/vehicle", apiHandler.NewVehicle) + driver.DELETE("/vehicle", apiHandler.DeleteVehicle) } } -- GitLab From 0c91badc1be552ddb86c722834255102b5a722e6 Mon Sep 17 00:00:00 2001 From: Hilman Taris Muttaqin Date: Wed, 30 Nov 2022 13:08:22 +0700 Subject: [PATCH 11/62] implement driver post document function --- data/entity/user_entity.go | 2 +- data/model/user_model.go | 4 +++ data/request/driver_document_request.go | 7 ++++ domain/handler/api_handler.go | 43 +++++++++++++++++++++++++ domain/repository/user_repository.go | 8 +++-- domain/usecase/user_usecase.go | 9 ++++++ helper/mapper.go | 18 ++++++++--- router/route.go | 1 + 8 files changed, 84 insertions(+), 8 deletions(-) create mode 100644 data/request/driver_document_request.go diff --git a/data/entity/user_entity.go b/data/entity/user_entity.go index 1c2bcf5..a4da9da 100644 --- a/data/entity/user_entity.go +++ b/data/entity/user_entity.go @@ -9,7 +9,7 @@ type UserEntity struct { Password string `json:"password"` Phone string `json:"phone"` Role int `json:"role"` - IsActive string `json:"is_active"` + IsActive int `json:"is_active"` ProfilePict sql.NullString `json:"profile_pict"` KTP sql.NullString `json:"ktp"` SIM sql.NullString `json:"sim"` diff --git a/data/model/user_model.go b/data/model/user_model.go index be1cefe..f4d9670 100644 --- a/data/model/user_model.go +++ b/data/model/user_model.go @@ -7,6 +7,10 @@ type UserModel struct { PhoneNumber string Password string Role int + IsActive int + ProfilePict string + KTP string + SIM string CreatedAt string UpdatedAt string BlockedAt string diff --git a/data/request/driver_document_request.go b/data/request/driver_document_request.go new file mode 100644 index 0000000..3ca5068 --- /dev/null +++ b/data/request/driver_document_request.go @@ -0,0 +1,7 @@ +package request + +type DriverDocumentRequest struct { + ProfilePict string `json:"profile_pict" binding:"required"` + KTP string `json:"ktp" binding:"required"` + SIM string `json:"sim" binding:"required"` +} diff --git a/domain/handler/api_handler.go b/domain/handler/api_handler.go index fe0e87e..2274ecf 100644 --- a/domain/handler/api_handler.go +++ b/domain/handler/api_handler.go @@ -181,3 +181,46 @@ func (handler *ApiHandler) DeleteVehicle(context *gin.Context) { }, }) } + +func (handler *ApiHandler) DriverPostDocument(context *gin.Context) { + userId := context.MustGet("userId").(float64) + + var driverDocumentRequest request.DriverDocumentRequest + + err := context.ShouldBindJSON(&driverDocumentRequest) + if err != nil { + HandlerError(context, err) + return + } + + // get user by id + existUser, err := handler.userUsecase.GetUserById(int(userId)) + if err != nil { + response.ResponseError(context, http.StatusNotFound, err) + return + } + + // clone user + updatedUser := existUser + updatedUser.ProfilePict = driverDocumentRequest.ProfilePict + updatedUser.SIM = driverDocumentRequest.SIM + updatedUser.KTP = driverDocumentRequest.KTP + + err = handler.userUsecase.DriverPostDocument(updatedUser) + if err != nil { + response.ResponseError(context, http.StatusInternalServerError, err) + return + } + + response.ResponseSuccess(context, http.StatusCreated, gin.H{ + "message": "Success update data", + "account": gin.H{ + "id": updatedUser.UserId, + "name": updatedUser.Name, + "email": updatedUser.Email, + "phone": updatedUser.PhoneNumber, + "role": updatedUser.Role, + }, + }) + +} diff --git a/domain/repository/user_repository.go b/domain/repository/user_repository.go index dfe1a3a..a3d805a 100644 --- a/domain/repository/user_repository.go +++ b/domain/repository/user_repository.go @@ -3,6 +3,7 @@ package repository import ( "database/sql" "errors" + "fmt" "ubur-backend/data/entity" ) @@ -24,8 +25,11 @@ func GetUserRepository(db *sql.DB) *Repository { } func (r *Repository) UpdateUser(user entity.UserEntity) (err error) { - query := "UPDATE users SET name=?, email=?, phone=? WHERE user_id=?" - _, execErr := r.Db.Exec(query, user.Name, user.Email, user.Phone, user.UserID) + fmt.Println(user) + fmt.Println("ProfilePict", user.ProfilePict.String) + query := "UPDATE users SET name=?, email=?, phone=?, is_active=?, profile_pict=?, ktp=?, sim=? WHERE user_id=?" + _, execErr := r.Db.Exec(query, user.Name, user.Email, user.Phone, user.IsActive, + user.ProfilePict.String, user.KTP.String, user.SIM.String, user.UserID) if execErr != nil { return execErr } diff --git a/domain/usecase/user_usecase.go b/domain/usecase/user_usecase.go index 45101f9..55d26de 100644 --- a/domain/usecase/user_usecase.go +++ b/domain/usecase/user_usecase.go @@ -27,6 +27,7 @@ type UserInteractor interface { NewVehicle(vehicle model.VehicleModel) (err error) GetVehicles(driverId int) (results []model.VehicleModel, err error) DeleteVehicle(driverId int, vehicleId int) (result model.VehicleModel, err error) + DriverPostDocument(user model.UserModel) (err error) } func GetUserUseCase( @@ -108,3 +109,11 @@ func (useCase *UserUseCase) GetUserById(id int) (result model.UserModel, err err userModel := helper.UserEntityToUserModel(user) return userModel, err } + +func (useCase *UserUseCase) DriverPostDocument(user model.UserModel) (err error) { + err = useCase.userRepository.UpdateUser(helper.UserModelToUserEntity(user)) + if err != nil { + return err + } + return nil +} diff --git a/helper/mapper.go b/helper/mapper.go index 478356d..1e3f716 100644 --- a/helper/mapper.go +++ b/helper/mapper.go @@ -1,6 +1,7 @@ package helper import ( + "database/sql" entity2 "ubur-backend/data/entity" model2 "ubur-backend/data/model" ) @@ -45,11 +46,15 @@ func VerificationModelToVerificationEntity(model model2.VerificationModel) entit func UserModelToUserEntity(model model2.UserModel) entity2.UserEntity { return entity2.UserEntity{ - Name: model.Name, - Email: model.Email, - Password: model.Password, - Phone: model.PhoneNumber, - Role: model.Role, + UserID: model.UserId, + Name: model.Name, + Email: model.Email, + Password: model.Password, + Phone: model.PhoneNumber, + Role: model.Role, + ProfilePict: sql.NullString{String: model.ProfilePict}, + KTP: sql.NullString{String: model.KTP}, + SIM: sql.NullString{String: model.SIM}, } } @@ -61,5 +66,8 @@ func UserEntityToUserModel(entity entity2.UserEntity) model2.UserModel { Password: entity.Password, PhoneNumber: entity.Phone, Role: entity.Role, + ProfilePict: entity.ProfilePict.String, + KTP: entity.KTP.String, + SIM: entity.SIM.String, } } diff --git a/router/route.go b/router/route.go index d8ce3b0..a0863b6 100644 --- a/router/route.go +++ b/router/route.go @@ -48,6 +48,7 @@ func PrepareRouter( driver.GET("/vehicle", apiHandler.Vehicle) driver.POST("/vehicle", apiHandler.NewVehicle) driver.DELETE("/vehicle", apiHandler.DeleteVehicle) + driver.POST("/document", apiHandler.DriverPostDocument) } } -- GitLab From b8399b469ed85ec940df3bf38370b790a0aa38f9 Mon Sep 17 00:00:00 2001 From: Hilman Taris Muttaqin Date: Fri, 2 Dec 2022 14:03:38 +0700 Subject: [PATCH 12/62] remove stnk from table user --- domain/repository/user_repository.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/domain/repository/user_repository.go b/domain/repository/user_repository.go index a3d805a..36962b2 100644 --- a/domain/repository/user_repository.go +++ b/domain/repository/user_repository.go @@ -61,7 +61,7 @@ func (r *Repository) GetUserById(id int) (user entity.UserEntity, err error) { err := result.Scan( &user.UserID, &user.Name, &user.Email, &user.Password, &user.Phone, &user.Role, &user.IsActive, &user.ProfilePict, &user.KTP, &user.SIM, - &user.STNK, &user.CreatedAt, &user.UpdatedAt, &user.DeletedAt) + &user.CreatedAt, &user.UpdatedAt, &user.DeletedAt) if err != nil { return user, err @@ -90,7 +90,7 @@ func (r *Repository) GetUserByEmail(email string, role int) (user entity.UserEnt err := result.Scan( &user.UserID, &user.Name, &user.Email, &user.Password, &user.Phone, &user.Role, &user.IsActive, &user.ProfilePict, &user.KTP, &user.SIM, - &user.STNK, &user.CreatedAt, &user.UpdatedAt, &user.DeletedAt) + &user.CreatedAt, &user.UpdatedAt, &user.DeletedAt) if err != nil { return user, err -- GitLab From 4abb6dfd563958344dda334205a935fe701fb400 Mon Sep 17 00:00:00 2001 From: Hilman Taris Muttaqin Date: Wed, 14 Dec 2022 13:03:13 +0700 Subject: [PATCH 13/62] Add filter deleted_at is null for get user --- domain/repository/user_repository.go | 43 ++++++++++++++-------------- 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/domain/repository/user_repository.go b/domain/repository/user_repository.go index 36962b2..56c9714 100644 --- a/domain/repository/user_repository.go +++ b/domain/repository/user_repository.go @@ -2,15 +2,10 @@ package repository import ( "database/sql" - "errors" - "fmt" + errors "errors" "ubur-backend/data/entity" ) -type Repository struct { - Db *sql.DB -} - type UserRepository interface { InsertNewUser(user entity.UserEntity) (err error) GetUserByEmail(email string, role int) (user entity.UserEntity, err error) @@ -25,9 +20,9 @@ func GetUserRepository(db *sql.DB) *Repository { } func (r *Repository) UpdateUser(user entity.UserEntity) (err error) { - fmt.Println(user) - fmt.Println("ProfilePict", user.ProfilePict.String) - query := "UPDATE users SET name=?, email=?, phone=?, is_active=?, profile_pict=?, ktp=?, sim=? WHERE user_id=?" + var query = "UPDATE users SET " + + "name=?, email=?, phone=?, is_active=?, profile_pict=?, ktp=?, sim=? " + + "WHERE user_id=? AND deleted_at IS NULL" _, execErr := r.Db.Exec(query, user.Name, user.Email, user.Phone, user.IsActive, user.ProfilePict.String, user.KTP.String, user.SIM.String, user.UserID) if execErr != nil { @@ -37,7 +32,7 @@ func (r *Repository) UpdateUser(user entity.UserEntity) (err error) { } func (r *Repository) InsertNewUser(user entity.UserEntity) (err error) { - query := "INSERT INTO users " + + var query = "INSERT INTO users " + "(name, email, password, phone, role, is_active) VALUES " + "(?, ?, ?, ?, ?, ?)" _, execErr := r.Db.Exec(query, user.Name, user.Email, user.Password, user.Phone, user.Role, 1) @@ -48,9 +43,14 @@ func (r *Repository) InsertNewUser(user entity.UserEntity) (err error) { } func (r *Repository) GetUserById(id int) (user entity.UserEntity, err error) { - query := "SELECT * FROM users WHERE user_id=?" + var query = "SELECT * FROM users WHERE user_id=? AND deleted_at IS NULL" result, err := r.Db.Query(query, id) - defer result.Close() + defer func(result *sql.Rows) { + err := result.Close() + if err != nil { + panic(err.Error()) + } + }(result) if err != nil { panic(err.Error()) @@ -69,17 +69,19 @@ func (r *Repository) GetUserById(id int) (user entity.UserEntity, err error) { return user, nil } else { - return entity.UserEntity{ - Email: "", - Password: "", - }, errors.New("User with this id not found") + return entity.UserEntity{}, errors.New("User with this id not found") } } func (r *Repository) GetUserByEmail(email string, role int) (user entity.UserEntity, err error) { - query := "SELECT * FROM users WHERE email=? AND role=?" + var query = "SELECT * FROM users WHERE email=? AND role=? AND deleted_at IS NULL" result, err := r.Db.Query(query, email, role) - defer result.Close() + defer func(result *sql.Rows) { + err := result.Close() + if err != nil { + panic(err.Error()) + } + }(result) if err != nil { panic(err.Error()) @@ -98,9 +100,6 @@ func (r *Repository) GetUserByEmail(email string, role int) (user entity.UserEnt return user, nil } else { - return entity.UserEntity{ - Email: "", - Password: "", - }, errors.New("User with this email and role not found") + return entity.UserEntity{}, errors.New("User with this email and role not found") } } -- GitLab From 48daab0d052909f9762a45ea4051064b041bedb2 Mon Sep 17 00:00:00 2001 From: Hilman Taris Muttaqin Date: Wed, 14 Dec 2022 13:09:56 +0700 Subject: [PATCH 14/62] set update deleted_at and updated_at user in user repository --- domain/repository/user_repository.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/domain/repository/user_repository.go b/domain/repository/user_repository.go index 56c9714..615285c 100644 --- a/domain/repository/user_repository.go +++ b/domain/repository/user_repository.go @@ -3,6 +3,7 @@ package repository import ( "database/sql" errors "errors" + "time" "ubur-backend/data/entity" ) @@ -21,10 +22,11 @@ func GetUserRepository(db *sql.DB) *Repository { func (r *Repository) UpdateUser(user entity.UserEntity) (err error) { var query = "UPDATE users SET " + - "name=?, email=?, phone=?, is_active=?, profile_pict=?, ktp=?, sim=? " + + "name=?, email=?, phone=?, is_active=?, profile_pict=?, ktp=?, sim=?, deleted_at=?, updated_at=? " + "WHERE user_id=? AND deleted_at IS NULL" _, execErr := r.Db.Exec(query, user.Name, user.Email, user.Phone, user.IsActive, - user.ProfilePict.String, user.KTP.String, user.SIM.String, user.UserID) + user.ProfilePict.String, user.KTP.String, user.SIM.String, user.DeletedAt.String, + time.Now(), user.UserID) if execErr != nil { return execErr } -- GitLab From 7c5ec8bd3d1b49c2a5b3ea9943a35ea20ea5da44 Mon Sep 17 00:00:00 2001 From: Hilman Taris Muttaqin Date: Wed, 14 Dec 2022 13:16:08 +0700 Subject: [PATCH 15/62] remove stnk from user entity --- data/entity/user_entity.go | 1 - 1 file changed, 1 deletion(-) diff --git a/data/entity/user_entity.go b/data/entity/user_entity.go index a4da9da..081e9ac 100644 --- a/data/entity/user_entity.go +++ b/data/entity/user_entity.go @@ -13,7 +13,6 @@ type UserEntity struct { ProfilePict sql.NullString `json:"profile_pict"` KTP sql.NullString `json:"ktp"` SIM sql.NullString `json:"sim"` - STNK sql.NullString `json:"stnk"` CreatedAt string `json:"created_at"` UpdatedAt sql.NullString `json:"update_at"` DeletedAt sql.NullString `json:"deleted_at"` -- GitLab From 262033f4d75355e446987f473602129223a41ce9 Mon Sep 17 00:00:00 2001 From: Hilman Taris Muttaqin Date: Wed, 14 Dec 2022 13:19:45 +0700 Subject: [PATCH 16/62] fixing wording for phonenumber to phone and swap position password and phone number --- data/model/user_model.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/model/user_model.go b/data/model/user_model.go index f4d9670..481c145 100644 --- a/data/model/user_model.go +++ b/data/model/user_model.go @@ -4,8 +4,8 @@ type UserModel struct { UserId int Name string Email string - PhoneNumber string Password string + Phone string Role int IsActive int ProfilePict string -- GitLab From 1e7b69167a92ff87d1c877282390265fcf518358 Mon Sep 17 00:00:00 2001 From: Hilman Taris Muttaqin Date: Wed, 14 Dec 2022 13:51:54 +0700 Subject: [PATCH 17/62] add stnk in motorcycle entity and model and add filter deleted_at is null in vehicle repository --- data/entity/motorcycle_entity.go | 1 + data/model/motorcycle_model.go | 12 +++++++++++ data/model/vehicle_model.go | 7 ------- domain/repository/vehicle_repository.go | 27 +++++++++++++++---------- 4 files changed, 29 insertions(+), 18 deletions(-) create mode 100644 data/model/motorcycle_model.go delete mode 100644 data/model/vehicle_model.go diff --git a/data/entity/motorcycle_entity.go b/data/entity/motorcycle_entity.go index 6577314..a626223 100644 --- a/data/entity/motorcycle_entity.go +++ b/data/entity/motorcycle_entity.go @@ -7,6 +7,7 @@ type MotorcycleEntity struct { DriverID int `json:"driver_id"` Name string `json:"name"` LicensePlate string `json:"license_plate"` + Stnk string `json:"stnk"` CreatedAt string `json:"created_at"` UpdatedAt sql.NullTime `json:"update_at"` DeletedAt sql.NullTime `json:"deleted_at"` diff --git a/data/model/motorcycle_model.go b/data/model/motorcycle_model.go new file mode 100644 index 0000000..727fb19 --- /dev/null +++ b/data/model/motorcycle_model.go @@ -0,0 +1,12 @@ +package model + +type MotorcycleModel struct { + MotorcycleId int + DriverId int + RegistrationNoVehicle string + VehicleName string + Stnk string + CreatedAt string + UpdatedAt string + DeletedAt string +} diff --git a/data/model/vehicle_model.go b/data/model/vehicle_model.go deleted file mode 100644 index faf0fcc..0000000 --- a/data/model/vehicle_model.go +++ /dev/null @@ -1,7 +0,0 @@ -package model - -type VehicleModel struct { - DriverId int - RegistrationNoVehicle string - VehicleName string -} diff --git a/domain/repository/vehicle_repository.go b/domain/repository/vehicle_repository.go index d14520c..0e5d2a2 100644 --- a/domain/repository/vehicle_repository.go +++ b/domain/repository/vehicle_repository.go @@ -3,6 +3,7 @@ package repository import ( "database/sql" "errors" + "time" "ubur-backend/data/entity" ) @@ -20,10 +21,10 @@ func GetVehicleRepository(db *sql.DB) *Repository { } func (r *Repository) InsertNewVehicle(vehicle entity.MotorcycleEntity) (err error) { - query := "INSERT INTO motorcycle " + - "(driver_id, name, license_plate) VALUES " + - "(?, ?, ?)" - _, execErr := r.Db.Exec(query, vehicle.DriverID, vehicle.Name, vehicle.LicensePlate) + var query = "INSERT INTO motorcycle " + + "(driver_id, name, license_plate, stnk) VALUES " + + "(?, ?, ?, ?)" + _, execErr := r.Db.Exec(query, vehicle.DriverID, vehicle.Name, vehicle.LicensePlate, vehicle.Stnk) if execErr != nil { return execErr } @@ -31,7 +32,7 @@ func (r *Repository) InsertNewVehicle(vehicle entity.MotorcycleEntity) (err erro } func (r *Repository) GetVehicles(driverId int) (results []entity.MotorcycleEntity, err error) { - query := "SELECT * FROM motorcycle WHERE driver_id=? AND deleted_at IS NULL" + var query = "SELECT * FROM motorcycle WHERE driver_id=? AND deleted_at IS NULL" result, err := r.Db.Query(query, driverId) defer result.Close() @@ -43,7 +44,9 @@ func (r *Repository) GetVehicles(driverId int) (results []entity.MotorcycleEntit for result.Next() { var vehicle entity.MotorcycleEntity - err := result.Scan(&vehicle.MotorcycleID, &vehicle.DriverID, &vehicle.Name, &vehicle.LicensePlate, &vehicle.CreatedAt, &vehicle.UpdatedAt, &vehicle.DeletedAt) + err := result.Scan(&vehicle.MotorcycleID, &vehicle.DriverID, &vehicle.Name, + &vehicle.LicensePlate, &vehicle.Stnk, &vehicle.CreatedAt, + &vehicle.UpdatedAt, &vehicle.DeletedAt) if err != nil { return vehicles, err } @@ -54,7 +57,7 @@ func (r *Repository) GetVehicles(driverId int) (results []entity.MotorcycleEntit } func (r *Repository) GetVehicleById(driverId int, vehicleId int) (vehicleResult entity.MotorcycleEntity, err error) { - query := "SELECT * FROM motorcycle WHERE driver_id=? AND motorcycle_id=? AND deleted_at IS NULL" + var query = "SELECT * FROM motorcycle WHERE driver_id=? AND motorcycle_id=? AND deleted_at IS NULL" result, err := r.Db.Query(query, driverId, vehicleId) defer result.Close() @@ -64,7 +67,8 @@ func (r *Repository) GetVehicleById(driverId int, vehicleId int) (vehicleResult if result.Next() { var vehicle entity.MotorcycleEntity - err := result.Scan(&vehicle.MotorcycleID, &vehicle.DriverID, &vehicle.Name, &vehicle.LicensePlate, + err := result.Scan(&vehicle.MotorcycleID, &vehicle.DriverID, + &vehicle.Name, &vehicle.LicensePlate, &vehicle.Stnk, &vehicle.CreatedAt, &vehicle.UpdatedAt, &vehicle.DeletedAt) if err != nil { @@ -78,10 +82,11 @@ func (r *Repository) GetVehicleById(driverId int, vehicleId int) (vehicleResult } func (r *Repository) EditVehicle(vehicle entity.MotorcycleEntity) (err error) { - query := "UPDATE motorcycle SET name=?, license_plate=?, deleted_at=? " + - "WHERE driver_id=? AND motorcycle_id=?" + query := "UPDATE motorcycle SET name=?, license_plate=?, stnk=?, deleted_at=?, updated_at=? " + + "WHERE driver_id=? AND motorcycle_id=? AND deleted_at IS NULL" _, execErr := r.Db.Exec(query, vehicle.Name, vehicle.LicensePlate, - vehicle.DeletedAt.Time, vehicle.DriverID, vehicle.MotorcycleID) + vehicle.Stnk, vehicle.DeletedAt.Time, time.Now(), + vehicle.DriverID, vehicle.MotorcycleID) if execErr != nil { return execErr } -- GitLab From 973aaf330f912362fcd448bf7078c8ec3f1f3ae8 Mon Sep 17 00:00:00 2001 From: Hilman Taris Muttaqin Date: Wed, 14 Dec 2022 13:55:02 +0700 Subject: [PATCH 18/62] remove driver model --- data/model/driver_model.go | 12 ------------ 1 file changed, 12 deletions(-) delete mode 100644 data/model/driver_model.go diff --git a/data/model/driver_model.go b/data/model/driver_model.go deleted file mode 100644 index 1dfc7d1..0000000 --- a/data/model/driver_model.go +++ /dev/null @@ -1,12 +0,0 @@ -package model - -type DriverModel struct { - DriverId string - Name string - PhoneNumber string - Email string - Password string - CreatedAt string - UpdatedAt string - BlockedAt string -} -- GitLab From 65d0194bd4e73fa66486d05b7598c3b5bb289784 Mon Sep 17 00:00:00 2001 From: Hilman Taris Muttaqin Date: Wed, 14 Dec 2022 13:55:24 +0700 Subject: [PATCH 19/62] move repository struct to repository file --- domain/repository/repository.go | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 domain/repository/repository.go diff --git a/domain/repository/repository.go b/domain/repository/repository.go new file mode 100644 index 0000000..33db8e0 --- /dev/null +++ b/domain/repository/repository.go @@ -0,0 +1,7 @@ +package repository + +import "database/sql" + +type Repository struct { + Db *sql.DB +} -- GitLab From 7c3ef5b0bc7c201929db422d074dac6bdba25796 Mon Sep 17 00:00:00 2001 From: Hilman Taris Muttaqin Date: Wed, 14 Dec 2022 14:11:06 +0700 Subject: [PATCH 20/62] implement order repository --- domain/repository/order_repository.go | 41 +++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 domain/repository/order_repository.go diff --git a/domain/repository/order_repository.go b/domain/repository/order_repository.go new file mode 100644 index 0000000..cbe819d --- /dev/null +++ b/domain/repository/order_repository.go @@ -0,0 +1,41 @@ +package repository + +import ( + "database/sql" + "time" + "ubur-backend/data/entity" +) + +type OrderRepository interface { + InsertNewOrder(entity entity.OrdersEntity) (err error) + UpdateOrder(entity entity.OrdersEntity) (err error) +} + +func GetOrderRepository(db *sql.DB) *Repository { + return &Repository{ + Db: db, + } +} + +func (r *Repository) InsertNewOrder(entity entity.OrdersEntity) (err error) { + query := "INSERT INTO orders " + + "(user_id, driver_id, destination, pickup, distance, duration, payment_type, price, income) VALUES " + + "(?, ?, ?, ?, ?, ?, ?, ?, ?)" + _, execErr := r.Db.Exec(query, entity.UserID, entity.DriverID, entity.Destination, + entity.PickUP, entity.Distance, entity.Duration, entity.PaymentType, entity.Price, entity.Income) + if execErr != nil { + return execErr + } + return nil +} + +func (r *Repository) UpdateOrder(entity entity.OrdersEntity) (err error) { + query := "UPDATE orders SET " + + "is_cancel=?, cancel_reason=?, updated_at=? " + + "WHERE order_id=? AND deleted_at IS NULL" + _, execErr := r.Db.Exec(query, entity.IsCancel, entity.CancelReason, time.Now(), entity.OrderID) + if execErr != nil { + return execErr + } + return nil +} -- GitLab From e86722938152c87055c0fdf55293d8cadd58a7cd Mon Sep 17 00:00:00 2001 From: Hilman Taris Muttaqin Date: Wed, 14 Dec 2022 14:15:12 +0700 Subject: [PATCH 21/62] can update finished_at at update order in order repository --- domain/repository/order_repository.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/domain/repository/order_repository.go b/domain/repository/order_repository.go index cbe819d..1d0e7fb 100644 --- a/domain/repository/order_repository.go +++ b/domain/repository/order_repository.go @@ -31,9 +31,10 @@ func (r *Repository) InsertNewOrder(entity entity.OrdersEntity) (err error) { func (r *Repository) UpdateOrder(entity entity.OrdersEntity) (err error) { query := "UPDATE orders SET " + - "is_cancel=?, cancel_reason=?, updated_at=? " + + "is_cancel=?, cancel_reason=?, finished_at=?, updated_at=? " + "WHERE order_id=? AND deleted_at IS NULL" - _, execErr := r.Db.Exec(query, entity.IsCancel, entity.CancelReason, time.Now(), entity.OrderID) + _, execErr := r.Db.Exec(query, entity.IsCancel, entity.CancelReason, + entity.FinishedAt, time.Now(), entity.OrderID) if execErr != nil { return execErr } -- GitLab From edb01824c390cffd3ce0f91f6e396bb316d9d554 Mon Sep 17 00:00:00 2001 From: Hilman Taris Muttaqin Date: Wed, 14 Dec 2022 14:16:48 +0700 Subject: [PATCH 22/62] match the entity --- data/entity/orders_entity.go | 31 ++++++++++++++++--------------- data/model/order_model.go | 32 +++++++++++++++++--------------- 2 files changed, 33 insertions(+), 30 deletions(-) diff --git a/data/entity/orders_entity.go b/data/entity/orders_entity.go index 13ee3b1..ac129d9 100644 --- a/data/entity/orders_entity.go +++ b/data/entity/orders_entity.go @@ -3,19 +3,20 @@ package entity import "database/sql" type OrdersEntity struct { - OrderID int `json:"order_id"` - UserID int `json:"user_id"` - DriverID int `json:"driver_id"` - Destination string `json:"destination"` - PickUP string `json:"pickup"` - Distance string `json:"distance"` - Duration string `json:"duration"` - PaymentType string `json:"payment_type"` - Price int `json:"price"` - Income int `json:"income"` - IsCancel string `json:"is_cancel"` - CancelReason string `json:"cancel_reason"` - CreatedAt string `json:"created_at"` - UpdateAt sql.NullString `json:"update_at"` - DeletedAt sql.NullString `json:"deleted_at"` + OrderID int `json:"order_id"` + UserID int `json:"user_id"` + DriverID int `json:"driver_id"` + Destination string `json:"destination"` + PickUP string `json:"pickup"` + Distance float64 `json:"distance"` + Duration string `json:"duration"` + PaymentType string `json:"payment_type"` + Price float64 `json:"price"` + Income float64 `json:"income"` + IsCancel bool `json:"is_cancel"` + CancelReason string `json:"cancel_reason"` + FinishedAt sql.NullTime `json:"finished_at"` + CreatedAt sql.NullTime `json:"created_at"` + UpdateAt sql.NullTime `json:"update_at"` + DeletedAt sql.NullTime `json:"deleted_at"` } diff --git a/data/model/order_model.go b/data/model/order_model.go index bee55f0..aa1600a 100644 --- a/data/model/order_model.go +++ b/data/model/order_model.go @@ -1,20 +1,22 @@ package model -import "time" +import "database/sql" type OrderModel struct { - OrderId string - IsAccepted bool - IsFinished bool - OrderDate time.Time - PickUpPoint string - Destination string - Distance float64 - TravelTime float64 - Price float64 - CustomerId string - DriverId string - RatingId string - StartAt string - FinishAt string + OrderId int + CustomerId int + DriverId int + Destination string + Pickup string + Distance float64 + Duration float64 + PaymentType string + Price float64 + Income float64 + IsCancel bool + CancelReason string + FinishedAt sql.NullTime + CreatedAt sql.NullTime + UpdatedAt sql.NullTime + DeletedAt sql.NullTime } -- GitLab From e6dab42b5089850fe5d87008986f709242667e94 Mon Sep 17 00:00:00 2001 From: Hilman Taris Muttaqin Date: Wed, 14 Dec 2022 14:18:37 +0700 Subject: [PATCH 23/62] fixing get payload in generate token from refresh token --- helper/token.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/helper/token.go b/helper/token.go index 5916732..285ba63 100644 --- a/helper/token.go +++ b/helper/token.go @@ -57,8 +57,8 @@ func (authToken *AuthToken) GenerateTokenFromRefreshToken(refreshToken string, r // change payload authToken.tokenPayload = model.TokenPayloadModel{ Email: payload["email"].(string), - UserId: payload["userId"].(int), - Role: payload["role"].(int), + UserId: payload["userId"].(float64), + Role: payload["role"].(float64), Exp: authToken.tokenPayload.Exp, } newToken, err := authToken.GenerateToken(random) -- GitLab From abe9c29df97c3604bf9fe941f24f510e98be82bd Mon Sep 17 00:00:00 2001 From: Hilman Taris Muttaqin Date: Wed, 14 Dec 2022 14:19:04 +0700 Subject: [PATCH 24/62] change token payload data type for userId and role --- data/model/token_payload_model.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/data/model/token_payload_model.go b/data/model/token_payload_model.go index 5aaf010..228218d 100644 --- a/data/model/token_payload_model.go +++ b/data/model/token_payload_model.go @@ -2,7 +2,7 @@ package model type TokenPayloadModel struct { Email string - UserId int - Role int + UserId float64 + Role float64 Exp int64 } -- GitLab From 423e0f0fa9d302d537b40a96ccedd8f1b1b12948 Mon Sep 17 00:00:00 2001 From: Hilman Taris Muttaqin Date: Wed, 14 Dec 2022 14:38:56 +0700 Subject: [PATCH 25/62] add add order conversion, stnk to vehicle conversion, change phoneNumber to phone in user conversion --- helper/mapper.go | 52 +++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 47 insertions(+), 5 deletions(-) diff --git a/helper/mapper.go b/helper/mapper.go index 1e3f716..f3b3053 100644 --- a/helper/mapper.go +++ b/helper/mapper.go @@ -6,19 +6,61 @@ import ( model2 "ubur-backend/data/model" ) -func VehicleModelToVehicleEntity(model model2.VehicleModel) entity2.MotorcycleEntity { +func OrderEntityToOrderModel(entity entity2.OrdersEntity) model2.OrderModel { + return model2.OrderModel{ + OrderId: entity.OrderID, + CustomerId: entity.UserID, + DriverId: entity.DriverID, + Destination: entity.Destination, + Pickup: entity.PickUP, + Distance: entity.Distance, + Price: entity.Price, + Income: entity.Price, + IsCancel: entity.IsCancel, + CancelReason: entity.CancelReason, + FinishedAt: entity.FinishedAt, + CreatedAt: entity.CreatedAt, + UpdatedAt: entity.UpdateAt, + DeletedAt: entity.DeletedAt, + } +} + +func OrderModelToOrderEntity(model model2.OrderModel) entity2.OrdersEntity { + return entity2.OrdersEntity{ + OrderID: model.OrderId, + UserID: model.CustomerId, + DriverID: model.DriverId, + Destination: model.Destination, + PickUP: model.Pickup, + Distance: model.Distance, + Price: model.Price, + Income: model.Price, + IsCancel: model.IsCancel, + CancelReason: model.CancelReason, + FinishedAt: model.FinishedAt, + CreatedAt: model.CreatedAt, + UpdateAt: model.UpdatedAt, + DeletedAt: model.DeletedAt, + } +} + +func VehicleModelToVehicleEntity(model model2.MotorcycleModel) entity2.MotorcycleEntity { return entity2.MotorcycleEntity{ + MotorcycleID: model.MotorcycleId, DriverID: model.DriverId, Name: model.VehicleName, LicensePlate: model.RegistrationNoVehicle, + Stnk: model.Stnk, } } -func VehicleEntityToVehicleModel(entity entity2.MotorcycleEntity) model2.VehicleModel { - return model2.VehicleModel{ +func VehicleEntityToVehicleModel(entity entity2.MotorcycleEntity) model2.MotorcycleModel { + return model2.MotorcycleModel{ + MotorcycleId: entity.MotorcycleID, DriverId: entity.DriverID, VehicleName: entity.Name, RegistrationNoVehicle: entity.LicensePlate, + Stnk: entity.Stnk, } } @@ -50,7 +92,7 @@ func UserModelToUserEntity(model model2.UserModel) entity2.UserEntity { Name: model.Name, Email: model.Email, Password: model.Password, - Phone: model.PhoneNumber, + Phone: model.Phone, Role: model.Role, ProfilePict: sql.NullString{String: model.ProfilePict}, KTP: sql.NullString{String: model.KTP}, @@ -64,7 +106,7 @@ func UserEntityToUserModel(entity entity2.UserEntity) model2.UserModel { Name: entity.Name, Email: entity.Email, Password: entity.Password, - PhoneNumber: entity.Phone, + Phone: entity.Phone, Role: entity.Role, ProfilePict: entity.ProfilePict.String, KTP: entity.KTP.String, -- GitLab From 848aa0614d3fa57f7fe5a7e8abdd78b7b5dd6ae0 Mon Sep 17 00:00:00 2001 From: Hilman Taris Muttaqin Date: Wed, 14 Dec 2022 14:40:25 +0700 Subject: [PATCH 26/62] add order request object --- data/request/order_request.go | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 data/request/order_request.go diff --git a/data/request/order_request.go b/data/request/order_request.go new file mode 100644 index 0000000..514a41d --- /dev/null +++ b/data/request/order_request.go @@ -0,0 +1,11 @@ +package request + +type OrderRequest struct { + DriverId int `json:"driver_id" binding:"required"` + Destination string `json:"destination" binding:"required"` + Pickup string `json:"pickup" binding:"required"` + Distance float64 `json:"distance" binding:"required"` + Duration float64 `json:"duration" binding:"required"` + PaymentType string `json:"payment_type" binding:"required"` + Price float64 `json:"price" binding:"required"` +} -- GitLab From fd714e7696cdd6fb5ee83a34f86167aeec6df5bd Mon Sep 17 00:00:00 2001 From: Hilman Taris Muttaqin Date: Wed, 14 Dec 2022 14:41:01 +0700 Subject: [PATCH 27/62] add order repository into user use case --- config/prepare.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/config/prepare.go b/config/prepare.go index 3435bba..c60a824 100644 --- a/config/prepare.go +++ b/config/prepare.go @@ -17,9 +17,14 @@ func PrepareAll() (*handler.ApiHandler, *handler.AuthHandler) { userRepository := repository2.GetUserRepository(db) verificationRepository := repository2.GetVerificationRepository(db) vehicleRepository := repository2.GetVehicleRepository(db) + orderRepository := repository2.GetOrderRepository(db) // prepare usecase - userUsecase := usecase.GetUserUseCase(userRepository, verificationRepository, vehicleRepository) + userUsecase := usecase.GetUserUseCase( + userRepository, + verificationRepository, + vehicleRepository, + orderRepository) // prepare api handler apiHandler := handler.GetHandler(userUsecase) -- GitLab From 2e46b785ab27f19c177a99fdfef82705f1758d0d Mon Sep 17 00:00:00 2001 From: Hilman Taris Muttaqin Date: Wed, 14 Dec 2022 14:42:34 +0700 Subject: [PATCH 28/62] change phone in exist user respons and set token payload exp to 0 when generated refresh token --- domain/handler/auth_handler.go | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/domain/handler/auth_handler.go b/domain/handler/auth_handler.go index e399e16..6c699bb 100644 --- a/domain/handler/auth_handler.go +++ b/domain/handler/auth_handler.go @@ -132,10 +132,10 @@ func (handler *AuthHandler) Register(context *gin.Context) { // pass data newUser := model.UserModel{ - Email: registerRequest.Email, - Password: registerRequest.Password, - Role: registerRequest.Role, - PhoneNumber: registerRequest.Phone, + Email: registerRequest.Email, + Password: registerRequest.Password, + Role: registerRequest.Role, + Phone: registerRequest.Phone, } passByteArr := []byte(newUser.Password) @@ -227,8 +227,8 @@ func (handler *AuthHandler) Login(context *gin.Context) { expirationTime := helper.GetTokenExpiration() payload := model.TokenPayloadModel{ Email: existUser.Email, - UserId: existUser.UserId, - Role: existUser.Role, + UserId: float64(existUser.UserId), + Role: float64(existUser.Role), Exp: expirationTime.Unix(), } @@ -240,10 +240,7 @@ func (handler *AuthHandler) Login(context *gin.Context) { return } - payload = model.TokenPayloadModel{ - Email: existUser.Email, - Exp: 0, - } + payload.Exp = 0 authToken.ChangePayload(payload) randomString = helper.GetRandomString(50) refreshToken, err := authToken.GenerateToken(randomString) @@ -260,7 +257,7 @@ func (handler *AuthHandler) Login(context *gin.Context) { "id": existUser.UserId, "name": existUser.Name, "email": existUser.Email, - "phone": existUser.PhoneNumber, + "phone": existUser.Phone, "role": existUser.Role, }, }) -- GitLab From 0aabcfeaea9b1bafd48660f7de0b06a555f96df4 Mon Sep 17 00:00:00 2001 From: Hilman Taris Muttaqin Date: Wed, 14 Dec 2022 14:43:13 +0700 Subject: [PATCH 29/62] add post order endpoint in router --- router/route.go | 1 + 1 file changed, 1 insertion(+) diff --git a/router/route.go b/router/route.go index a0863b6..09b7413 100644 --- a/router/route.go +++ b/router/route.go @@ -34,6 +34,7 @@ func PrepareRouter( middleware.CustomerRequiredMiddleware()) { customer.PUT("/:id", apiHandler.CustomerEditProfile) + customer.POST("/:id/order", apiHandler.CustomerOrder) } /** -- GitLab From dfae2b0842a9056d2977bf6413cc5e473f5b7ca3 Mon Sep 17 00:00:00 2001 From: Hilman Taris Muttaqin Date: Wed, 14 Dec 2022 14:46:11 +0700 Subject: [PATCH 30/62] fixing phone atribut in user and add handler for customer order --- domain/handler/api_handler.go | 52 +++++++++++++++++++++++++++++++---- 1 file changed, 47 insertions(+), 5 deletions(-) diff --git a/domain/handler/api_handler.go b/domain/handler/api_handler.go index 2274ecf..4f0f582 100644 --- a/domain/handler/api_handler.go +++ b/domain/handler/api_handler.go @@ -69,7 +69,7 @@ func (handler *ApiHandler) CustomerEditProfile(context *gin.Context) { } if editProfileRequest.Phone != "" { // send otp phone here - currentUser.PhoneNumber = editProfileRequest.Phone + currentUser.Phone = editProfileRequest.Phone } err = handler.userUsecase.EditProfile(currentUser) @@ -84,13 +84,55 @@ func (handler *ApiHandler) CustomerEditProfile(context *gin.Context) { "id": currentUser.UserId, "name": currentUser.Name, "email": currentUser.Email, - "phone": currentUser.PhoneNumber, + "phone": currentUser.Phone, "role": currentUser.Role, }, }) } +func (handler *ApiHandler) CustomerOrder(context *gin.Context) { + userId := context.MustGet("userId").(float64) + + var orderRequest request.OrderRequest + err := context.ShouldBindJSON(&orderRequest) + if err != nil { + HandlerError(context, err) + return + } + + orderModel := model.OrderModel{ + CustomerId: int(userId), + DriverId: orderRequest.DriverId, + Destination: orderRequest.Destination, + Pickup: orderRequest.Pickup, + Distance: orderRequest.Distance, + Duration: orderRequest.Duration, + PaymentType: orderRequest.PaymentType, + Price: orderRequest.Price, + Income: orderRequest.Price, + } + + err = handler.userUsecase.CustomerOrder(orderModel) + if err != nil { + response.ResponseError(context, http.StatusInternalServerError, err) + return + } + + response.ResponseSuccess(context, http.StatusCreated, gin.H{ + "message": "order created", + "order": gin.H{ + "driver_id": orderModel.DriverId, + "destination": orderModel.Destination, + "pickup_point": orderModel.Pickup, + "distance": orderModel.Distance, + "duration": orderModel.Duration, + "payment_type": orderModel.PaymentType, + "price": orderModel.Price, + }, + }) +} + /** * Driver API Handler * API yang digunakan driver untuk bekerja melalui aplikasi ini @@ -107,7 +149,7 @@ func (handler *ApiHandler) NewVehicle(context *gin.Context) { return } - newVehicleModel := model.VehicleModel{ + newVehicleModel := model.MotorcycleModel{ DriverId: int(userId), VehicleName: vehicleRequest.Name, RegistrationNoVehicle: vehicleRequest.LicensePlate, @@ -121,7 +163,7 @@ func (handler *ApiHandler) NewVehicle(context *gin.Context) { response.ResponseSuccess(context, http.StatusCreated, gin.H{ "message": "add vehicle success", - "account": gin.H{ + "vehicle": gin.H{ "driver_id": newVehicleModel.DriverId, "vehicle_name": newVehicleModel.VehicleName, "license_plate": newVehicleModel.RegistrationNoVehicle, @@ -218,7 +260,7 @@ func (handler *ApiHandler) DriverPostDocument(context *gin.Context) { "id": updatedUser.UserId, "name": updatedUser.Name, "email": updatedUser.Email, - "phone": updatedUser.PhoneNumber, + "phone": updatedUser.Phone, "role": updatedUser.Role, }, }) -- GitLab From c245fd9048a6f5598cc62dbeab84fadb8855d663 Mon Sep 17 00:00:00 2001 From: Hilman Taris Muttaqin Date: Wed, 14 Dec 2022 14:46:46 +0700 Subject: [PATCH 31/62] implement create order in user use case --- domain/usecase/user_usecase.go | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/domain/usecase/user_usecase.go b/domain/usecase/user_usecase.go index 55d26de..095dbc4 100644 --- a/domain/usecase/user_usecase.go +++ b/domain/usecase/user_usecase.go @@ -13,6 +13,7 @@ type UserUseCase struct { userRepository repository.UserRepository verificationRepository repository.VerificationRepository vehicleRepository repository.VehicleRepository + orderRepository repository.OrderRepository } type UserInteractor interface { @@ -21,48 +22,58 @@ type UserInteractor interface { GetUserById(id int) (result model.UserModel, err error) GetOTP(verificationModel model.VerificationModel) (result model.VerificationModel, err error) PostOTP(verification model.VerificationModel) (err error) + + // Customer Interactor EditProfile(user model.UserModel) (err error) + CustomerOrder(order model.OrderModel) (err error) // Driver Interactor - NewVehicle(vehicle model.VehicleModel) (err error) - GetVehicles(driverId int) (results []model.VehicleModel, err error) - DeleteVehicle(driverId int, vehicleId int) (result model.VehicleModel, err error) + NewVehicle(vehicle model.MotorcycleModel) (err error) + GetVehicles(driverId int) (results []model.MotorcycleModel, err error) + DeleteVehicle(driverId int, vehicleId int) (result model.MotorcycleModel, err error) DriverPostDocument(user model.UserModel) (err error) } func GetUserUseCase( userRepository repository.UserRepository, verificationRepository repository.VerificationRepository, - vehicleRepository repository.VehicleRepository) *UserUseCase { + vehicleRepository repository.VehicleRepository, + orderRepository repository.OrderRepository) *UserUseCase { return &UserUseCase{ userRepository: userRepository, verificationRepository: verificationRepository, vehicleRepository: vehicleRepository, + orderRepository: orderRepository, } } -func (useCase *UserUseCase) DeleteVehicle(driverId int, vehicleId int) (result model.VehicleModel, err error) { +func (useCase *UserUseCase) CustomerOrder(order model.OrderModel) (err error) { + customerOrder := helper.OrderModelToOrderEntity(order) + return useCase.orderRepository.InsertNewOrder(customerOrder) +} + +func (useCase *UserUseCase) DeleteVehicle(driverId int, vehicleId int) (result model.MotorcycleModel, err error) { vehicle, err := useCase.vehicleRepository.GetVehicleById(driverId, vehicleId) if err != nil { - return model.VehicleModel{}, err + return model.MotorcycleModel{}, err } vehicle.DeletedAt = sql.NullTime{Time: time.Now()} err = useCase.vehicleRepository.EditVehicle(vehicle) if err != nil { - return model.VehicleModel{}, err + return model.MotorcycleModel{}, err } return helper.VehicleEntityToVehicleModel(vehicle), nil } -func (useCase *UserUseCase) NewVehicle(vehicle model.VehicleModel) (err error) { +func (useCase *UserUseCase) NewVehicle(vehicle model.MotorcycleModel) (err error) { vehicleEntity := helper.VehicleModelToVehicleEntity(vehicle) return useCase.vehicleRepository.InsertNewVehicle(vehicleEntity) } -func (useCase *UserUseCase) GetVehicles(driverId int) (results []model.VehicleModel, err error) { - var vehicles []model.VehicleModel +func (useCase *UserUseCase) GetVehicles(driverId int) (results []model.MotorcycleModel, err error) { + var vehicles []model.MotorcycleModel records, err := useCase.vehicleRepository.GetVehicles(driverId) -- GitLab From a3c6f4b2db471fd24921c4cdecdc86bb339d66be Mon Sep 17 00:00:00 2001 From: Hilman Taris Muttaqin Date: Wed, 14 Dec 2022 21:15:26 +0700 Subject: [PATCH 32/62] fixing duration and payment type in mapper --- data/entity/orders_entity.go | 2 +- helper/mapper.go | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/data/entity/orders_entity.go b/data/entity/orders_entity.go index ac129d9..39d2e67 100644 --- a/data/entity/orders_entity.go +++ b/data/entity/orders_entity.go @@ -9,7 +9,7 @@ type OrdersEntity struct { Destination string `json:"destination"` PickUP string `json:"pickup"` Distance float64 `json:"distance"` - Duration string `json:"duration"` + Duration float64 `json:"duration"` PaymentType string `json:"payment_type"` Price float64 `json:"price"` Income float64 `json:"income"` diff --git a/helper/mapper.go b/helper/mapper.go index f3b3053..3a1a70d 100644 --- a/helper/mapper.go +++ b/helper/mapper.go @@ -14,8 +14,10 @@ func OrderEntityToOrderModel(entity entity2.OrdersEntity) model2.OrderModel { Destination: entity.Destination, Pickup: entity.PickUP, Distance: entity.Distance, + Duration: entity.Duration, + PaymentType: entity.PaymentType, Price: entity.Price, - Income: entity.Price, + Income: entity.Income, IsCancel: entity.IsCancel, CancelReason: entity.CancelReason, FinishedAt: entity.FinishedAt, @@ -33,8 +35,10 @@ func OrderModelToOrderEntity(model model2.OrderModel) entity2.OrdersEntity { Destination: model.Destination, PickUP: model.Pickup, Distance: model.Distance, + Duration: model.Duration, + PaymentType: model.PaymentType, Price: model.Price, - Income: model.Price, + Income: model.Income, IsCancel: model.IsCancel, CancelReason: model.CancelReason, FinishedAt: model.FinishedAt, -- GitLab From 0911ebd3227695adc3480540bfbe092f151a59c5 Mon Sep 17 00:00:00 2001 From: Hilman Taris Muttaqin Date: Sat, 17 Dec 2022 13:47:11 +0700 Subject: [PATCH 33/62] add endpoint for sister --- domain/handler/auth_handler.go | 69 ++++++++++++++++++++++++++++++++++ router/route.go | 8 ++++ 2 files changed, 77 insertions(+) diff --git a/domain/handler/auth_handler.go b/domain/handler/auth_handler.go index 6c699bb..7865459 100644 --- a/domain/handler/auth_handler.go +++ b/domain/handler/auth_handler.go @@ -3,6 +3,7 @@ package handler import ( "database/sql" "errors" + "fmt" "github.com/gin-gonic/gin" "golang.org/x/crypto/bcrypt" "net/http" @@ -288,3 +289,71 @@ func (handler *AuthHandler) RefreshToken(context *gin.Context) { "token": newToken, }) } + +/** + * Api handler for SISTER + */ +var defaultUsername = "user" +var defaultPassword = "root" + +type SisterPasswordReq struct { + Username string `json:"username"` + Password string `json:"password"` +} + +func (handler *AuthHandler) SisterLogin(context *gin.Context) { + var loginRequest SisterPasswordReq + + err := context.ShouldBindJSON(&loginRequest) + if err != nil { + HandlerError(context, err) + return + } + + fmt.Println("defaultUsername: ", defaultUsername) + fmt.Println("req username: ", loginRequest.Username) + + if loginRequest.Username != defaultUsername && loginRequest.Password != defaultPassword { + response.ResponseError(context, http.StatusInternalServerError, errors.New("your username and password is wrong")) + return + } + + if loginRequest.Username != defaultUsername { + response.ResponseError(context, http.StatusInternalServerError, errors.New("your username is wrong")) + return + } + + if loginRequest.Password != defaultPassword { + response.ResponseError(context, http.StatusInternalServerError, errors.New("your password is wrong")) + return + } + + response.ResponseSuccess(context, http.StatusOK, gin.H{ + "message": "success login", + "account": gin.H{ + "username": defaultUsername, + "password": defaultPassword, + }, + }) +} + +func (handler *AuthHandler) SetSisterPassword(context *gin.Context) { + var setCredentialReq SisterPasswordReq + + err := context.ShouldBindJSON(&setCredentialReq) + if err != nil { + HandlerError(context, err) + return + } + + defaultUsername = setCredentialReq.Username + defaultPassword = setCredentialReq.Password + + response.ResponseSuccess(context, http.StatusOK, gin.H{ + "message": "success set credential", + "account": gin.H{ + "username": defaultUsername, + "password": defaultPassword, + }, + }) +} diff --git a/router/route.go b/router/route.go index 09b7413..1b459e4 100644 --- a/router/route.go +++ b/router/route.go @@ -24,6 +24,14 @@ func PrepareRouter( v1.POST("/otp", authHandler.RequestOtp) v1.POST("/verify", authHandler.Verify) + /** + * SISTER API Enpoint + * API yang digunakan untuk tugas besar SISTER + * Password bruteforce + */ + v1.POST("/sister/login", authHandler.SisterLogin) + v1.POST("/sister/credential", authHandler.SetSisterPassword) + /** * Customer API Enpoint * API yang digunakan customer untuk menggunakan layanan aplikasi ini -- GitLab From 7afe71d957d2a8322ecbaabb46534dd2f895dff7 Mon Sep 17 00:00:00 2001 From: Hilman Taris Muttaqin Date: Sat, 17 Dec 2022 22:31:35 +0700 Subject: [PATCH 34/62] fixing bug in register search user by email and role section --- domain/handler/auth_handler.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/domain/handler/auth_handler.go b/domain/handler/auth_handler.go index 7865459..c1fa69e 100644 --- a/domain/handler/auth_handler.go +++ b/domain/handler/auth_handler.go @@ -156,7 +156,7 @@ func (handler *AuthHandler) Register(context *gin.Context) { return } - currentUser, err := handler.userUsecase.GetUserByEmail(newUser.Email, 1) + currentUser, err := handler.userUsecase.GetUserByEmail(newUser.Email, newUser.Role) if err != nil { response.ResponseError(context, http.StatusNotFound, err) return -- GitLab From 07cfae68c68ffd1b4740cc26b2fda3a81239b698 Mon Sep 17 00:00:00 2001 From: Hilman Taris Muttaqin Date: Fri, 23 Dec 2022 16:03:22 +0700 Subject: [PATCH 35/62] check document exist if login with driver --- domain/handler/auth_handler.go | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/domain/handler/auth_handler.go b/domain/handler/auth_handler.go index c1fa69e..e0b1760 100644 --- a/domain/handler/auth_handler.go +++ b/domain/handler/auth_handler.go @@ -9,6 +9,7 @@ import ( "net/http" "os" "time" + "ubur-backend/data" "ubur-backend/data/model" "ubur-backend/data/request" "ubur-backend/data/response" @@ -250,16 +251,24 @@ func (handler *AuthHandler) Login(context *gin.Context) { return } + documentExist := true + if existUser.Role == data.ROLE_DRIVER { + if existUser.KTP == "" && existUser.ProfilePict == "" && existUser.SIM == "" { + documentExist = false + } + } + response.ResponseSuccess(context, http.StatusOK, gin.H{ "message": "Success login", "token": generatedToken, "refresh_token": refreshToken, "account": gin.H{ - "id": existUser.UserId, - "name": existUser.Name, - "email": existUser.Email, - "phone": existUser.Phone, - "role": existUser.Role, + "id": existUser.UserId, + "name": existUser.Name, + "email": existUser.Email, + "phone": existUser.Phone, + "role": existUser.Role, + "documents_ready": documentExist, }, }) } -- GitLab From de40977920b2ef92ad471fa8efa80f05ea440969 Mon Sep 17 00:00:00 2001 From: Hilman Taris Muttaqin Date: Fri, 23 Dec 2022 17:09:57 +0700 Subject: [PATCH 36/62] add edit driver endpoint --- data/request/edit_profile_request.go | 9 ++-- domain/handler/api_handler.go | 61 ++++++++++++++++++++++++++++ router/route.go | 1 + 3 files changed, 68 insertions(+), 3 deletions(-) diff --git a/data/request/edit_profile_request.go b/data/request/edit_profile_request.go index 71a6316..65f7378 100644 --- a/data/request/edit_profile_request.go +++ b/data/request/edit_profile_request.go @@ -1,7 +1,10 @@ package request type EditProfileRequest struct { - Name string `json:"name"` - Email string `json:"email"` - Phone string `json:"phone"` + Name string `json:"name"` + Email string `json:"email"` + Phone string `json:"phone"` + KTP string `json:"ktp"` + SIM string `json:"sim"` + ProfilePict string `json:"profile_pict"` } diff --git a/domain/handler/api_handler.go b/domain/handler/api_handler.go index 4f0f582..53875ef 100644 --- a/domain/handler/api_handler.go +++ b/domain/handler/api_handler.go @@ -139,6 +139,67 @@ func (handler *ApiHandler) CustomerOrder(context *gin.Context) { * membutuhkan token untuk request semua fitur */ +func (handler *ApiHandler) DriverEditProfile(context *gin.Context) { + userId, err := strconv.Atoi(context.Param("id")) + if err != nil { + response.ResponseError(context, http.StatusInternalServerError, err) + return + } + + var editProfileRequest request.EditProfileRequest + + err = context.ShouldBindJSON(&editProfileRequest) + if err != nil { + HandlerError(context, err) + return + } + + // get exist user + currentUser, err := handler.userUsecase.GetUserById(userId) + if err != nil { + response.ResponseError(context, http.StatusInternalServerError, err) + return + } + + if editProfileRequest.Name != "" { + currentUser.Name = editProfileRequest.Name + } + if editProfileRequest.Email != "" { + // send otp email here + currentUser.Email = editProfileRequest.Email + } + if editProfileRequest.Phone != "" { + // send otp phone here + currentUser.Phone = editProfileRequest.Phone + } + if editProfileRequest.KTP != "" { + currentUser.KTP = editProfileRequest.KTP + } + if editProfileRequest.SIM != "" { + currentUser.SIM = editProfileRequest.SIM + } + if editProfileRequest.ProfilePict != "" { + currentUser.ProfilePict = editProfileRequest.ProfilePict + } + + err = handler.userUsecase.EditProfile(currentUser) + if err != nil { + response.ResponseError(context, http.StatusInternalServerError, err) + return + } + + response.ResponseSuccess(context, http.StatusOK, gin.H{ + "message": "account has been updated", + "account": gin.H{ + "id": currentUser.UserId, + "name": currentUser.Name, + "email": currentUser.Email, + "phone": currentUser.Phone, + "role": currentUser.Role, + }, + }) +} + func (handler *ApiHandler) NewVehicle(context *gin.Context) { userId := context.MustGet("userId").(float64) diff --git a/router/route.go b/router/route.go index 1b459e4..4e7f964 100644 --- a/router/route.go +++ b/router/route.go @@ -58,6 +58,7 @@ func PrepareRouter( driver.POST("/vehicle", apiHandler.NewVehicle) driver.DELETE("/vehicle", apiHandler.DeleteVehicle) driver.POST("/document", apiHandler.DriverPostDocument) + driver.PUT("/:id", apiHandler.DriverEditProfile) } } -- GitLab From 099f07b8efa98db76f710e367ecc1341c84856d4 Mon Sep 17 00:00:00 2001 From: Hilman Taris Muttaqin Date: Fri, 23 Dec 2022 17:33:51 +0700 Subject: [PATCH 37/62] add edit driver --- data/entity/user_entity.go | 4 ++-- domain/repository/user_repository.go | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/data/entity/user_entity.go b/data/entity/user_entity.go index 081e9ac..2a63ad0 100644 --- a/data/entity/user_entity.go +++ b/data/entity/user_entity.go @@ -14,6 +14,6 @@ type UserEntity struct { KTP sql.NullString `json:"ktp"` SIM sql.NullString `json:"sim"` CreatedAt string `json:"created_at"` - UpdatedAt sql.NullString `json:"update_at"` - DeletedAt sql.NullString `json:"deleted_at"` + UpdatedAt sql.NullTime `json:"update_at"` + DeletedAt sql.NullTime `json:"deleted_at"` } diff --git a/domain/repository/user_repository.go b/domain/repository/user_repository.go index 615285c..2d768b8 100644 --- a/domain/repository/user_repository.go +++ b/domain/repository/user_repository.go @@ -25,7 +25,7 @@ func (r *Repository) UpdateUser(user entity.UserEntity) (err error) { "name=?, email=?, phone=?, is_active=?, profile_pict=?, ktp=?, sim=?, deleted_at=?, updated_at=? " + "WHERE user_id=? AND deleted_at IS NULL" _, execErr := r.Db.Exec(query, user.Name, user.Email, user.Phone, user.IsActive, - user.ProfilePict.String, user.KTP.String, user.SIM.String, user.DeletedAt.String, + user.ProfilePict.String, user.KTP.String, user.SIM.String, user.DeletedAt.Time, time.Now(), user.UserID) if execErr != nil { return execErr -- GitLab From ca8b181f9c66c0de504b64b10b9cee37f9b07b6d Mon Sep 17 00:00:00 2001 From: Hilman Taris Muttaqin Date: Sat, 24 Dec 2022 19:16:07 +0700 Subject: [PATCH 38/62] remove update for deleted_at in user repository --- data/model/user_model.go | 8 +++++--- data/request/edit_profile_request.go | 1 + domain/repository/user_repository.go | 4 ++-- helper/mapper.go | 2 ++ 4 files changed, 10 insertions(+), 5 deletions(-) diff --git a/data/model/user_model.go b/data/model/user_model.go index 481c145..111f7b0 100644 --- a/data/model/user_model.go +++ b/data/model/user_model.go @@ -1,5 +1,7 @@ package model +import "database/sql" + type UserModel struct { UserId int Name string @@ -11,7 +13,7 @@ type UserModel struct { ProfilePict string KTP string SIM string - CreatedAt string - UpdatedAt string - BlockedAt string + CreatedAt sql.NullTime + UpdatedAt sql.NullTime + BlockedAt sql.NullTime } diff --git a/data/request/edit_profile_request.go b/data/request/edit_profile_request.go index 65f7378..57f54fb 100644 --- a/data/request/edit_profile_request.go +++ b/data/request/edit_profile_request.go @@ -7,4 +7,5 @@ type EditProfileRequest struct { KTP string `json:"ktp"` SIM string `json:"sim"` ProfilePict string `json:"profile_pict"` + DeletedAt string `json:"deleted_at"` } diff --git a/domain/repository/user_repository.go b/domain/repository/user_repository.go index 2d768b8..7efb892 100644 --- a/domain/repository/user_repository.go +++ b/domain/repository/user_repository.go @@ -22,10 +22,10 @@ func GetUserRepository(db *sql.DB) *Repository { func (r *Repository) UpdateUser(user entity.UserEntity) (err error) { var query = "UPDATE users SET " + - "name=?, email=?, phone=?, is_active=?, profile_pict=?, ktp=?, sim=?, deleted_at=?, updated_at=? " + + "name=?, email=?, phone=?, is_active=?, profile_pict=?, ktp=?, sim=?, updated_at=? " + "WHERE user_id=? AND deleted_at IS NULL" _, execErr := r.Db.Exec(query, user.Name, user.Email, user.Phone, user.IsActive, - user.ProfilePict.String, user.KTP.String, user.SIM.String, user.DeletedAt.Time, + user.ProfilePict.String, user.KTP.String, user.SIM.String, time.Now(), user.UserID) if execErr != nil { return execErr diff --git a/helper/mapper.go b/helper/mapper.go index 3a1a70d..cefdca2 100644 --- a/helper/mapper.go +++ b/helper/mapper.go @@ -101,6 +101,7 @@ func UserModelToUserEntity(model model2.UserModel) entity2.UserEntity { ProfilePict: sql.NullString{String: model.ProfilePict}, KTP: sql.NullString{String: model.KTP}, SIM: sql.NullString{String: model.SIM}, + DeletedAt: sql.NullTime{Time: model.BlockedAt.Time}, } } @@ -115,5 +116,6 @@ func UserEntityToUserModel(entity entity2.UserEntity) model2.UserModel { ProfilePict: entity.ProfilePict.String, KTP: entity.KTP.String, SIM: entity.SIM.String, + BlockedAt: sql.NullTime{Time: entity.DeletedAt.Time}, } } -- GitLab From 67d3215a16dbaa3289ee72e4f4efe2ecddfece25 Mon Sep 17 00:00:00 2001 From: Hilman Taris Muttaqin Date: Sat, 24 Dec 2022 20:04:06 +0700 Subject: [PATCH 39/62] move token and refresh_token to account data --- domain/handler/auth_handler.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/domain/handler/auth_handler.go b/domain/handler/auth_handler.go index e0b1760..55badd7 100644 --- a/domain/handler/auth_handler.go +++ b/domain/handler/auth_handler.go @@ -259,9 +259,7 @@ func (handler *AuthHandler) Login(context *gin.Context) { } response.ResponseSuccess(context, http.StatusOK, gin.H{ - "message": "Success login", - "token": generatedToken, - "refresh_token": refreshToken, + "message": "Success login", "account": gin.H{ "id": existUser.UserId, "name": existUser.Name, @@ -269,6 +267,8 @@ func (handler *AuthHandler) Login(context *gin.Context) { "phone": existUser.Phone, "role": existUser.Role, "documents_ready": documentExist, + "token": generatedToken, + "refresh_token": refreshToken, }, }) } -- GitLab From 0ef16e7160757a08e196bb609bda25221ca95ef4 Mon Sep 17 00:00:00 2001 From: Hilman Taris Muttaqin Date: Thu, 29 Dec 2022 15:19:02 +0700 Subject: [PATCH 40/62] import maps lib to project and add endpoint for get polyline direction --- .idea/go.imports.xml | 10 +++++++ domain/handler/api_handler.go | 23 +++++++++++++++ go.mod | 12 ++++++-- go.sum | 55 ++++++++++++++++++++++++++++++++++- router/route.go | 6 ++++ 5 files changed, 102 insertions(+), 4 deletions(-) create mode 100644 .idea/go.imports.xml diff --git a/.idea/go.imports.xml b/.idea/go.imports.xml new file mode 100644 index 0000000..13d7879 --- /dev/null +++ b/.idea/go.imports.xml @@ -0,0 +1,10 @@ + + + + + + \ No newline at end of file diff --git a/domain/handler/api_handler.go b/domain/handler/api_handler.go index 53875ef..f87fcf0 100644 --- a/domain/handler/api_handler.go +++ b/domain/handler/api_handler.go @@ -3,6 +3,9 @@ package handler import ( "errors" "github.com/gin-gonic/gin" + "golang.org/x/net/context" + "googlemaps.github.io/maps" + "log" "net/http" "strconv" "ubur-backend/data/model" @@ -32,6 +35,26 @@ func (handler *ApiHandler) Testing(context *gin.Context) { }) } +func (handler *ApiHandler) Polyline(con *gin.Context) { + c, err := maps.NewClient(maps.WithAPIKey("AIzaSyBxqt-CvljoKJEvJROr1xlFVQTGOm2Y31M")) + if err != nil { + log.Fatalf("fatal error: %s", err) + } + r := &maps.DirectionsRequest{ + Origin: "-6.971498, 107.671425", + Destination: "-6.969245, 107.628443", + } + route, _, err := c.Directions(context.Background(), r) + if err != nil { + log.Fatalf("fatal error: %s", err) + } + + response.ResponseSuccess(con, http.StatusOK, gin.H{ + "message": "success get direction", + "result": route[0].OverviewPolyline.Points, + }) +} + /** * Customer API Handler * API yang digunakan customer untuk menggunakan layanan aplikasi ini diff --git a/go.mod b/go.mod index 426f060..b1ee21f 100644 --- a/go.mod +++ b/go.mod @@ -8,8 +8,12 @@ require ( github.com/go-sql-driver/mysql v1.6.0 github.com/golang-jwt/jwt/v4 v4.4.2 github.com/joho/godotenv v1.4.0 + github.com/kr/pretty v0.3.0 github.com/stretchr/testify v1.8.0 golang.org/x/crypto v0.1.0 + golang.org/x/net v0.1.0 + googlemaps.github.io/maps v1.3.2 + gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df ) require ( @@ -18,21 +22,23 @@ require ( github.com/go-playground/locales v0.14.0 // indirect github.com/go-playground/universal-translator v0.18.0 // indirect github.com/goccy/go-json v0.9.7 // indirect + github.com/google/uuid v1.1.1 // indirect github.com/json-iterator/go v1.1.12 // indirect + github.com/kr/text v0.2.0 // indirect github.com/leodido/go-urn v1.2.1 // indirect github.com/mattn/go-isatty v0.0.14 // indirect github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/pelletier/go-toml/v2 v2.0.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/stretchr/objx v0.4.0 // indirect + github.com/rogpeppe/go-internal v1.8.0 // indirect github.com/ugorji/go/codec v1.2.7 // indirect - golang.org/x/net v0.1.0 // indirect + go.opencensus.io v0.22.3 // indirect golang.org/x/sys v0.1.0 // indirect golang.org/x/text v0.4.0 // indirect + golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1 // indirect google.golang.org/protobuf v1.28.0 // indirect gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect - gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 730115d..95bf6c3 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,6 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= @@ -20,15 +23,25 @@ github.com/goccy/go-json v0.9.7 h1:IcB+Aqpx/iMHu5Yooh7jEzJk1JZ7Pjtmys2ukPr7EeM= github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/golang-jwt/jwt/v4 v4.4.2 h1:rcc4lwaZgFMCZ5jxF9ABolDcIHdBytAFgqFPbSJQAYs= github.com/golang-jwt/jwt/v4 v4.4.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6 h1:ZgQEtGgCBiWRM39fZuwSd1LwSqqSW0hOdXCYYDX0R3I= +github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/joho/godotenv v1.4.0 h1:3l4+N6zfMWnkbPEXKng2o2/MR5mSwTrBih4ZEkkz1lg= github.com/joho/godotenv v1.4.0/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= @@ -52,10 +65,12 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8= github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= +github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= +github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.4.0 h1:M2gUjqZET1qApGOWNSnZ49BAIMX4F/1plDv3+l31EJ4= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= @@ -64,12 +79,31 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M= github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0= github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= +go.opencensus.io v0.22.3 h1:8sGtKOrtQqkN1bp2AtX+misvLIlOmsEsNd+9NIcPEm8= +go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.1.0 h1:MDRAIl0xIo9Io2xV565hzXHw3zVseKrJKodhohM5CjU= golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.1.0 h1:hZ/3BUoy5aId7sCpA/Tc5lt8DkFgdVS2onTpJsZ/fl0= golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -78,28 +112,47 @@ golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.1.0 h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.4.0 h1:BrVqGRd7+k1DiOgtnFvAkoQEWQvBc25ouMJM6429SFg= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1 h1:NusfzzA6yGQ+ua51ck7E3omNUX/JuqbFSaRGqU8CcLI= +golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +googlemaps.github.io/maps v1.3.2 h1:3YfYdVWFTFi7lVdCdrDYW3dqHvfCSUdC7/x8pbMOuKQ= +googlemaps.github.io/maps v1.3.2/go.mod h1:cCq0JKYAnnCRSdiaBi7Ex9CW15uxIAk7oPi8V/xEh6s= gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc h1:2gGKlE2+asNV9m7xrywl36YYNnBG5ZQ0r/BOOxqPpmk= gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df h1:n7WqCuqOuCbNr617RXOY0AWRXxgwEyPp2z+p0+hgMuE= gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df/go.mod h1:LRQQ+SO6ZHR7tOkpBDuZnXENFzX8qRjMDMyPD6BRkCw= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/router/route.go b/router/route.go index 4e7f964..d81b740 100644 --- a/router/route.go +++ b/router/route.go @@ -24,6 +24,12 @@ func PrepareRouter( v1.POST("/otp", authHandler.RequestOtp) v1.POST("/verify", authHandler.Verify) + /** + * Pulic API Enpoint + * API yang digunakan untuk konsumsi publik tanpa harus authentikasi + */ + v1.GET("/polyline", apiHandler.Polyline) + /** * SISTER API Enpoint * API yang digunakan untuk tugas besar SISTER -- GitLab From 3bab5eae4cd666d11b2ea44b7147c9467915d7d2 Mon Sep 17 00:00:00 2001 From: Hilman Taris Muttaqin Date: Fri, 30 Dec 2022 23:09:42 +0700 Subject: [PATCH 41/62] fixing hardcoded api key, origin, and destination in get polyline handler --- data/request/polyline_request.go | 7 +++++++ domain/handler/api_handler.go | 13 ++++++++++--- 2 files changed, 17 insertions(+), 3 deletions(-) create mode 100644 data/request/polyline_request.go diff --git a/data/request/polyline_request.go b/data/request/polyline_request.go new file mode 100644 index 0000000..308115a --- /dev/null +++ b/data/request/polyline_request.go @@ -0,0 +1,7 @@ +package request + +type PolylineRequest struct { + Origin string `json:"origin" binding:"reqired"` + Destination string `json:"destination" binding:"required"` + ApiKey string `json:"api_key" binding:"required"` +} diff --git a/domain/handler/api_handler.go b/domain/handler/api_handler.go index f87fcf0..650c13b 100644 --- a/domain/handler/api_handler.go +++ b/domain/handler/api_handler.go @@ -36,13 +36,20 @@ func (handler *ApiHandler) Testing(context *gin.Context) { } func (handler *ApiHandler) Polyline(con *gin.Context) { - c, err := maps.NewClient(maps.WithAPIKey("AIzaSyBxqt-CvljoKJEvJROr1xlFVQTGOm2Y31M")) + var polylineRequest request.PolylineRequest + err := con.ShouldBindJSON(&polylineRequest) + if err != nil { + HandlerError(con, err) + return + } + + c, err := maps.NewClient(maps.WithAPIKey(polylineRequest.ApiKey)) if err != nil { log.Fatalf("fatal error: %s", err) } r := &maps.DirectionsRequest{ - Origin: "-6.971498, 107.671425", - Destination: "-6.969245, 107.628443", + Origin: polylineRequest.Origin, + Destination: polylineRequest.Destination, } route, _, err := c.Directions(context.Background(), r) if err != nil { -- GitLab From 18d588af53b5d7247946a9a9f50fc1da74869459 Mon Sep 17 00:00:00 2001 From: Hilman Taris Muttaqin Date: Sat, 31 Dec 2022 00:22:35 +0700 Subject: [PATCH 42/62] fixing error while get polyline --- domain/handler/api_handler.go | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/domain/handler/api_handler.go b/domain/handler/api_handler.go index 650c13b..f5818b9 100644 --- a/domain/handler/api_handler.go +++ b/domain/handler/api_handler.go @@ -2,6 +2,7 @@ package handler import ( "errors" + "fmt" "github.com/gin-gonic/gin" "golang.org/x/net/context" "googlemaps.github.io/maps" @@ -37,16 +38,36 @@ func (handler *ApiHandler) Testing(context *gin.Context) { func (handler *ApiHandler) Polyline(con *gin.Context) { var polylineRequest request.PolylineRequest - err := con.ShouldBindJSON(&polylineRequest) - if err != nil { - HandlerError(con, err) + + originQuery, filled := con.GetQuery("origin") + if !filled { + response.ResponseError(con, http.StatusBadRequest, errors.New("origin query required")) + return + } + + destinationQuery, filled := con.GetQuery("destination") + if !filled { + response.ResponseError(con, http.StatusBadRequest, errors.New("destination query required")) return } + apiKey, filled := con.GetQuery("api_key") + if !filled { + response.ResponseError(con, http.StatusBadRequest, errors.New("api_key query required")) + return + } + + polylineRequest = request.PolylineRequest{ + Origin: originQuery, + Destination: destinationQuery, + ApiKey: apiKey, + } + c, err := maps.NewClient(maps.WithAPIKey(polylineRequest.ApiKey)) if err != nil { log.Fatalf("fatal error: %s", err) } + fmt.Println(polylineRequest.Origin) r := &maps.DirectionsRequest{ Origin: polylineRequest.Origin, Destination: polylineRequest.Destination, -- GitLab From 3fcd1177411a781a7f47b15392bfbdd6f5dd13c0 Mon Sep 17 00:00:00 2001 From: Hilman Taris Muttaqin Date: Mon, 2 Jan 2023 10:37:22 +0700 Subject: [PATCH 43/62] add polyline, distance and duration in gmaps endpoint --- domain/handler/api_handler.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/domain/handler/api_handler.go b/domain/handler/api_handler.go index f5818b9..ef97b4b 100644 --- a/domain/handler/api_handler.go +++ b/domain/handler/api_handler.go @@ -79,7 +79,11 @@ func (handler *ApiHandler) Polyline(con *gin.Context) { response.ResponseSuccess(con, http.StatusOK, gin.H{ "message": "success get direction", - "result": route[0].OverviewPolyline.Points, + "result": gin.H{ + "polyline": route[0].OverviewPolyline.Points, + "distance": route[0].Legs[0].Distance, + "duration": route[0].Legs[0].Duration, + }, }) } -- GitLab From 2ce877099a10d246cd51826d8946050e1c7bf725 Mon Sep 17 00:00:00 2001 From: Hilman Taris Muttaqin Date: Mon, 2 Jan 2023 10:47:57 +0700 Subject: [PATCH 44/62] change distance to meters --- domain/handler/api_handler.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/domain/handler/api_handler.go b/domain/handler/api_handler.go index ef97b4b..9a87e25 100644 --- a/domain/handler/api_handler.go +++ b/domain/handler/api_handler.go @@ -81,7 +81,7 @@ func (handler *ApiHandler) Polyline(con *gin.Context) { "message": "success get direction", "result": gin.H{ "polyline": route[0].OverviewPolyline.Points, - "distance": route[0].Legs[0].Distance, + "distance": route[0].Legs[0].Distance.Meters, "duration": route[0].Legs[0].Duration, }, }) -- GitLab From 539f68cd8d3abeb4d473576973493b2eecb03ae7 Mon Sep 17 00:00:00 2001 From: Hilman Taris Muttaqin Date: Mon, 2 Jan 2023 10:51:21 +0700 Subject: [PATCH 45/62] change distance to meters and duration in minute --- domain/handler/api_handler.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/domain/handler/api_handler.go b/domain/handler/api_handler.go index 9a87e25..e980658 100644 --- a/domain/handler/api_handler.go +++ b/domain/handler/api_handler.go @@ -82,7 +82,7 @@ func (handler *ApiHandler) Polyline(con *gin.Context) { "result": gin.H{ "polyline": route[0].OverviewPolyline.Points, "distance": route[0].Legs[0].Distance.Meters, - "duration": route[0].Legs[0].Duration, + "duration": route[0].Legs[0].Duration.Minutes(), }, }) } -- GitLab From e03e5e2a21cf4827eb730957f49bf9c08cc15bb2 Mon Sep 17 00:00:00 2001 From: Hilman Taris Muttaqin Date: Mon, 2 Jan 2023 12:02:23 +0700 Subject: [PATCH 46/62] remove message and result response in request polyline --- domain/handler/api_handler.go | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/domain/handler/api_handler.go b/domain/handler/api_handler.go index e980658..fdde874 100644 --- a/domain/handler/api_handler.go +++ b/domain/handler/api_handler.go @@ -78,12 +78,9 @@ func (handler *ApiHandler) Polyline(con *gin.Context) { } response.ResponseSuccess(con, http.StatusOK, gin.H{ - "message": "success get direction", - "result": gin.H{ - "polyline": route[0].OverviewPolyline.Points, - "distance": route[0].Legs[0].Distance.Meters, - "duration": route[0].Legs[0].Duration.Minutes(), - }, + "polyline": route[0].OverviewPolyline.Points, + "distance": route[0].Legs[0].Distance.Meters, + "duration": route[0].Legs[0].Duration.Minutes(), }) } -- GitLab From a243912a2c893fac4448e15f7495b69be3a7ea44 Mon Sep 17 00:00:00 2001 From: Hilman Taris Muttaqin Date: Mon, 2 Jan 2023 14:10:57 +0700 Subject: [PATCH 47/62] add pricing when request polyline --- domain/handler/api_handler.go | 4 ++++ helper/price.go | 16 ++++++++++++++++ 2 files changed, 20 insertions(+) create mode 100644 helper/price.go diff --git a/domain/handler/api_handler.go b/domain/handler/api_handler.go index fdde874..0258d2c 100644 --- a/domain/handler/api_handler.go +++ b/domain/handler/api_handler.go @@ -13,6 +13,7 @@ import ( "ubur-backend/data/request" "ubur-backend/data/response" "ubur-backend/domain/usecase" + "ubur-backend/helper" ) type ApiHandler struct { @@ -77,10 +78,13 @@ func (handler *ApiHandler) Polyline(con *gin.Context) { log.Fatalf("fatal error: %s", err) } + pricing := helper.Pricing{Jarak: route[0].Legs[0].Distance.Meters} + response.ResponseSuccess(con, http.StatusOK, gin.H{ "polyline": route[0].OverviewPolyline.Points, "distance": route[0].Legs[0].Distance.Meters, "duration": route[0].Legs[0].Duration.Minutes(), + "price": int64(pricing.GetPrice()), }) } diff --git a/helper/price.go b/helper/price.go new file mode 100644 index 0000000..e89cc07 --- /dev/null +++ b/helper/price.go @@ -0,0 +1,16 @@ +package helper + +type Pricing struct { + Jarak int +} + +const BIAYA_JASA = 1850.0 + +func (pricing Pricing) GetAppPrice() float64 { + price := 0.2 * (BIAYA_JASA * (float64(pricing.Jarak) / 1000.0)) + return price +} + +func (pricing Pricing) GetPrice() float64 { + return BIAYA_JASA*(float64(pricing.Jarak)/1000.0) + pricing.GetAppPrice() +} -- GitLab From 2c549b06cb4c6f78b38ec6ff170f7c76ab1570c7 Mon Sep 17 00:00:00 2001 From: Hilman Taris Muttaqin Date: Wed, 4 Jan 2023 13:03:50 +0700 Subject: [PATCH 48/62] add endpoint for search driver --- domain/handler/api_handler.go | 52 +++++++++++++++++++++++++++++++++++ router/route.go | 10 +++++++ 2 files changed, 62 insertions(+) diff --git a/domain/handler/api_handler.go b/domain/handler/api_handler.go index 0258d2c..a7c5567 100644 --- a/domain/handler/api_handler.go +++ b/domain/handler/api_handler.go @@ -9,6 +9,7 @@ import ( "log" "net/http" "strconv" + "ubur-backend/data" "ubur-backend/data/model" "ubur-backend/data/request" "ubur-backend/data/response" @@ -88,6 +89,57 @@ func (handler *ApiHandler) Polyline(con *gin.Context) { }) } +func (handler *ApiHandler) Search(context *gin.Context) { + driverId, _ := context.GetQuery("driver_id") + + if driverId != "" { + driverIdInt, err := strconv.Atoi(driverId) + if err != nil { + response.ResponseError(context, http.StatusBadRequest, err) + return + } + + // request to get driver id + currentUser, err := handler.userUsecase.GetUserById(driverIdInt) + if err != nil { + response.ResponseError(context, http.StatusInternalServerError, err) + return + } + + fmt.Println(currentUser.Role) + + if currentUser.Role != data.ROLE_DRIVER { + response.ResponseError(context, http.StatusNotFound, errors.New("user with this id not found")) + return + } + + // Get vehicle + vehicles, err := handler.userUsecase.GetVehicles(driverIdInt) + if err != nil { + response.ResponseError(context, http.StatusInternalServerError, err) + return + } + + var vehicleMap []gin.H + for _, item := range vehicles { + vehicleMap = append(vehicleMap, gin.H{ + "driver_id": item.DriverId, + "name": item.VehicleName, + "license_plate": item.RegistrationNoVehicle, + }) + } + + response.ResponseSuccess(context, http.StatusOK, gin.H{ + "id": currentUser.UserId, + "name": currentUser.Name, + "email": currentUser.Email, + "phone": currentUser.Phone, + "role": currentUser.Role, + "vehicle": vehicleMap, + }) + } +} + /** * Customer API Handler * API yang digunakan customer untuk menggunakan layanan aplikasi ini diff --git a/router/route.go b/router/route.go index d81b740..bba770f 100644 --- a/router/route.go +++ b/router/route.go @@ -38,6 +38,16 @@ func PrepareRouter( v1.POST("/sister/login", authHandler.SisterLogin) v1.POST("/sister/credential", authHandler.SetSisterPassword) + /** + * Public API Enpoint + * API yang digunakan customer ataupun driver, tetapi membutuhkan authentikasi + */ + public := v1.Group("/public").Use( + middleware.AuthRequiredMiddleware()) + { + public.GET("/search", apiHandler.Search) + } + /** * Customer API Enpoint * API yang digunakan customer untuk menggunakan layanan aplikasi ini -- GitLab From 54b8ec1379cd12e452ecd0c540bba74be33cdb2b Mon Sep 17 00:00:00 2001 From: Hilman Taris Muttaqin Date: Wed, 4 Jan 2023 14:20:46 +0700 Subject: [PATCH 49/62] change response name to vehicle_name in search driver --- domain/handler/api_handler.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/domain/handler/api_handler.go b/domain/handler/api_handler.go index a7c5567..22011f6 100644 --- a/domain/handler/api_handler.go +++ b/domain/handler/api_handler.go @@ -124,7 +124,7 @@ func (handler *ApiHandler) Search(context *gin.Context) { for _, item := range vehicles { vehicleMap = append(vehicleMap, gin.H{ "driver_id": item.DriverId, - "name": item.VehicleName, + "vehicle_name": item.VehicleName, "license_plate": item.RegistrationNoVehicle, }) } -- GitLab From a10d1f4f9f38c4f13027163cc4211517e430f814 Mon Sep 17 00:00:00 2001 From: Hilman Taris Muttaqin Date: Sat, 7 Jan 2023 08:06:35 +0700 Subject: [PATCH 50/62] add fcm for new order and remove exp from token --- config/prepare.go | 13 +- data/request/find_driver_request.go | 10 ++ domain/handler/api_handler.go | 47 +++++++- domain/handler/auth_handler.go | 4 +- go.mod | 34 +++++- go.sum | 112 ++++++++++++++++++ router/route.go | 1 + ...bd-firebase-adminsdk-j6dj4-d31a4049ec.json | 12 ++ 8 files changed, 223 insertions(+), 10 deletions(-) create mode 100644 data/request/find_driver_request.go create mode 100644 ubur-app-77cbd-firebase-adminsdk-j6dj4-d31a4049ec.json diff --git a/config/prepare.go b/config/prepare.go index c60a824..3c8c0b1 100644 --- a/config/prepare.go +++ b/config/prepare.go @@ -1,7 +1,11 @@ package config import ( + firebase "firebase.google.com/go" "fmt" + "golang.org/x/net/context" + "google.golang.org/api/option" + "log" "ubur-backend/domain/handler" repository2 "ubur-backend/domain/repository" "ubur-backend/domain/usecase" @@ -26,8 +30,15 @@ func PrepareAll() (*handler.ApiHandler, *handler.AuthHandler) { vehicleRepository, orderRepository) + // firebase init + opt := option.WithCredentialsFile("./ubur-app-77cbd-firebase-adminsdk-j6dj4-d31a4049ec.json") + appFirebase, err := firebase.NewApp(context.Background(), nil, opt) + if err != nil { + log.Fatalf("error initializing app: %v\n", err) + } + // prepare api handler - apiHandler := handler.GetHandler(userUsecase) + apiHandler := handler.GetHandler(userUsecase, *appFirebase) authHandler := handler.GetAuthHandler(userUsecase) return apiHandler, authHandler diff --git a/data/request/find_driver_request.go b/data/request/find_driver_request.go new file mode 100644 index 0000000..a507b26 --- /dev/null +++ b/data/request/find_driver_request.go @@ -0,0 +1,10 @@ +package request + +type FindDriverRequest struct { + RegistrationToken string `json:"registration_token"` + NotificationTitle string `json:"notification_title"` + NotificationDesc string `json:"notification_desc"` + Customer string `json:"customer"` + Trip string `json:"trip"` + Meta string `json:"meta"` +} diff --git a/domain/handler/api_handler.go b/domain/handler/api_handler.go index 22011f6..09118b1 100644 --- a/domain/handler/api_handler.go +++ b/domain/handler/api_handler.go @@ -2,6 +2,8 @@ package handler import ( "errors" + firebase "firebase.google.com/go" + "firebase.google.com/go/messaging" "fmt" "github.com/gin-gonic/gin" "golang.org/x/net/context" @@ -19,11 +21,13 @@ import ( type ApiHandler struct { userUsecase usecase.UserInteractor + firebaseApp firebase.App } -func GetHandler(userUsecase usecase.UserInteractor) *ApiHandler { +func GetHandler(userUsecase usecase.UserInteractor, firebaseApp firebase.App) *ApiHandler { return &ApiHandler{ userUsecase: userUsecase, + firebaseApp: firebaseApp, } } @@ -146,6 +150,47 @@ func (handler *ApiHandler) Search(context *gin.Context) { * membutuhkan token untuk request semua fitur */ +func (handler *ApiHandler) CustomerFindDriver(con *gin.Context) { + var findDriverRequest request.FindDriverRequest + + err := con.ShouldBindJSON(&findDriverRequest) + if err != nil { + HandlerError(con, err) + return + } + + ctx := context.Background() + service, err := handler.firebaseApp.Messaging(ctx) + if err != nil { + response.ResponseError(con, http.StatusInternalServerError, err) + return + } + + message := messaging.Message{ + Data: map[string]string{ + "customer": findDriverRequest.Customer, + "trip": findDriverRequest.Trip, + "meta": findDriverRequest.Meta, + }, + Notification: &messaging.Notification{ + Title: findDriverRequest.NotificationTitle, + Body: findDriverRequest.NotificationDesc, + }, + Token: findDriverRequest.RegistrationToken, + } + + res, err := service.Send(ctx, &message) + if err != nil { + response.ResponseError(con, http.StatusInternalServerError, err) + return + } + + response.ResponseSuccess(con, http.StatusOK, gin.H{ + "message": "blbalblba", + "result": res, + }) +} + func (handler *ApiHandler) CustomerEditProfile(context *gin.Context) { userId, err := strconv.Atoi(context.Param("id")) if err != nil { diff --git a/domain/handler/auth_handler.go b/domain/handler/auth_handler.go index 55badd7..d6e59c2 100644 --- a/domain/handler/auth_handler.go +++ b/domain/handler/auth_handler.go @@ -226,12 +226,12 @@ func (handler *AuthHandler) Login(context *gin.Context) { // sign jwt token and refresh token salt := []byte(os.Getenv("JWT_SALT")) - expirationTime := helper.GetTokenExpiration() + //expirationTime := helper.GetTokenExpiration() payload := model.TokenPayloadModel{ Email: existUser.Email, UserId: float64(existUser.UserId), Role: float64(existUser.Role), - Exp: expirationTime.Unix(), + Exp: 0, } authToken := helper.GetAuthToken(salt, payload) diff --git a/go.mod b/go.mod index b1ee21f..0a202e1 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,7 @@ require ( github.com/golang-jwt/jwt/v4 v4.4.2 github.com/joho/godotenv v1.4.0 github.com/kr/pretty v0.3.0 - github.com/stretchr/testify v1.8.0 + github.com/stretchr/testify v1.8.1 golang.org/x/crypto v0.1.0 golang.org/x/net v0.1.0 googlemaps.github.io/maps v1.3.2 @@ -17,12 +17,27 @@ require ( ) require ( + cloud.google.com/go v0.105.0 // indirect + cloud.google.com/go/compute v1.14.0 // indirect + cloud.google.com/go/compute/metadata v0.2.3 // indirect + cloud.google.com/go/firestore v1.9.0 // indirect + cloud.google.com/go/iam v0.8.0 // indirect + cloud.google.com/go/longrunning v0.3.0 // indirect + cloud.google.com/go/storage v1.27.0 // indirect + firebase.google.com/go v3.13.0+incompatible // indirect github.com/davecgh/go-spew v1.1.1 // indirect + github.com/firebase/firebase-admin-go v3.13.0+incompatible // indirect github.com/gin-contrib/sse v0.1.0 // indirect github.com/go-playground/locales v0.14.0 // indirect github.com/go-playground/universal-translator v0.18.0 // indirect github.com/goccy/go-json v0.9.7 // indirect - github.com/google/uuid v1.1.1 // indirect + github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e // indirect + github.com/golang/protobuf v1.5.2 // indirect + github.com/google/go-cmp v0.5.9 // indirect + github.com/google/uuid v1.3.0 // indirect + github.com/googleapis/enterprise-certificate-proxy v0.2.1 // indirect + github.com/googleapis/gax-go v1.0.3 // indirect + github.com/googleapis/gax-go/v2 v2.7.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/kr/text v0.2.0 // indirect github.com/leodido/go-urn v1.2.1 // indirect @@ -33,11 +48,18 @@ require ( github.com/pmezard/go-difflib v1.0.0 // indirect github.com/rogpeppe/go-internal v1.8.0 // indirect github.com/ugorji/go/codec v1.2.7 // indirect - go.opencensus.io v0.22.3 // indirect + go.opencensus.io v0.24.0 // indirect + golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783 // indirect + golang.org/x/sync v0.1.0 // indirect golang.org/x/sys v0.1.0 // indirect - golang.org/x/text v0.4.0 // indirect - golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1 // indirect - google.golang.org/protobuf v1.28.0 // indirect + golang.org/x/text v0.5.0 // indirect + golang.org/x/time v0.1.0 // indirect + golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect + google.golang.org/api v0.106.0 // indirect + google.golang.org/appengine v1.6.7 // indirect + google.golang.org/genproto v0.0.0-20221227171554-f9683d7f8bef // indirect + google.golang.org/grpc v1.51.0 // indirect + google.golang.org/protobuf v1.28.1 // indirect gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index 95bf6c3..fb717ce 100644 --- a/go.sum +++ b/go.sum @@ -1,10 +1,34 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.105.0 h1:DNtEKRBAAzeS4KyIory52wWHuClNaXJ5x1F7xa4q+5Y= +cloud.google.com/go v0.105.0/go.mod h1:PrLgOJNe5nfE9UMxKxgXj4mD3voiP+YQ6gdt6KMFOKM= +cloud.google.com/go/compute v1.14.0 h1:hfm2+FfxVmnRlh6LpB7cg1ZNU+5edAHmW679JePztk0= +cloud.google.com/go/compute v1.14.0/go.mod h1:YfLtxrj9sU4Yxv+sXzZkyPjEyPBZfXHUvjxega5vAdo= +cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY= +cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= +cloud.google.com/go/firestore v1.9.0 h1:IBlRyxgGySXu5VuW0RgGFlTtLukSnNkpDiEOMkQkmpA= +cloud.google.com/go/firestore v1.9.0/go.mod h1:HMkjKHNTtRyZNiMzu7YAsLr9K3X2udY2AMwDaMEQiiE= +cloud.google.com/go/iam v0.8.0 h1:E2osAkZzxI/+8pZcxVLcDtAQx/u+hZXVryUaYQ5O0Kk= +cloud.google.com/go/iam v0.8.0/go.mod h1:lga0/y3iH6CX7sYqypWJ33hf7kkfXJag67naqGESjkE= +cloud.google.com/go/longrunning v0.3.0 h1:NjljC+FYPV3uh5/OwWT6pVU+doBqMg2x/rZlE+CamDs= +cloud.google.com/go/longrunning v0.3.0/go.mod h1:qth9Y41RRSUE69rDcOn6DdK3HfQfsUI0YSmW3iIlLJc= +cloud.google.com/go/storage v1.27.0 h1:YOO045NZI9RKfCj1c5A/ZtuuENUc8OAW+gHdGnDgyMQ= +cloud.google.com/go/storage v1.27.0/go.mod h1:x9DOL8TK/ygDUMieqwfhdpQryTeEkhGKMi80i/iqR2s= +firebase.google.com/go v3.13.0+incompatible h1:3TdYC3DDi6aHn20qoRkxwGqNgdjtblwVAyRLQwGn/+4= +firebase.google.com/go v3.13.0+incompatible/go.mod h1:xlah6XbEyW6tbfSklcfe5FHJIwjt8toICdV5Wh9ptHs= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/firebase/firebase-admin-go v3.13.0+incompatible h1:V4Ezn7K7WCkztOLTzgdR15Mvz6+6s/gnOa0+Usa0ReE= +github.com/firebase/firebase-admin-go v3.13.0+incompatible/go.mod h1:4fTHu128eJSLcZwETOMM+S00nvPZz/1KfMi2gzbC2KY= github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= github.com/gin-gonic/gin v1.8.1 h1:4+fr/el88TOO3ewCmQr8cx/CtZ/umlIRIs5M4NTNjf8= @@ -26,20 +50,51 @@ github.com/golang-jwt/jwt/v4 v4.4.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6 h1:ZgQEtGgCBiWRM39fZuwSd1LwSqqSW0hOdXCYYDX0R3I= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/enterprise-certificate-proxy v0.2.1 h1:RY7tHKZcRlk788d5WSo/e83gOyyy742E8GSs771ySpg= +github.com/googleapis/enterprise-certificate-proxy v0.2.1/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k= +github.com/googleapis/gax-go v1.0.3 h1:9dMLqhaibYONnDRcnHdUs9P8Mw64jLlZTYlDe3leBtQ= +github.com/googleapis/gax-go v1.0.3/go.mod h1:QyXYajJFdARxGzjwUfbDFIse7Spkw81SJ4LrBJXtlQ8= +github.com/googleapis/gax-go/v2 v2.0.2/go.mod h1:LLvjysVCY1JZeum8Z6l8qUty8fiNwE08qbEPm1M08qg= +github.com/googleapis/gax-go/v2 v2.7.0 h1:IcsPKeInNvYi7eqSaDjiZqDDKu5rsmunY0Y1YupQSSQ= +github.com/googleapis/gax-go/v2 v2.7.0/go.mod h1:TEop28CZZQ2y+c0VxMUmu1lV+fQx57QpBWsYpwqHJx8= github.com/joho/godotenv v1.4.0 h1:3l4+N6zfMWnkbPEXKng2o2/MR5mSwTrBih4ZEkkz1lg= github.com/joho/godotenv v1.4.0/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= @@ -62,6 +117,7 @@ github.com/pelletier/go-toml/v2 v2.0.1/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZO github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8= github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= @@ -69,6 +125,7 @@ github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= @@ -76,16 +133,23 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M= github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0= github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= go.opencensus.io v0.22.3 h1:8sGtKOrtQqkN1bp2AtX+misvLIlOmsEsNd+9NIcPEm8= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= +go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.1.0 h1:MDRAIl0xIo9Io2xV565hzXHw3zVseKrJKodhohM5CjU= golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190221220918-438050ddec5e/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= @@ -93,17 +157,27 @@ golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.1.0 h1:hZ/3BUoy5aId7sCpA/Tc5lt8DkFgdVS2onTpJsZ/fl0= golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783 h1:nt+Q6cXKz4MosCSpnbMtqiQ8Oz0pxTef2B4Vca2lvfk= +golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -114,27 +188,63 @@ golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.4.0 h1:BrVqGRd7+k1DiOgtnFvAkoQEWQvBc25ouMJM6429SFg= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.5.0 h1:OLmvp0KP+FVG99Ct/qFiL/Fhk4zp4QQnZ7b2U+5piUM= +golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1 h1:NusfzzA6yGQ+ua51ck7E3omNUX/JuqbFSaRGqU8CcLI= golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.1.0 h1:xYY+Bajn2a7VBmTM5GikTmnK8ZuX8YgnQCqZpbBNtmA= +golang.org/x/time v0.1.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk= +golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +google.golang.org/api v0.106.0 h1:ffmW0faWCwKkpbbtvlY/K/8fUl+JKvNS5CVzRoyfCv8= +google.golang.org/api v0.106.0/go.mod h1:2Ts0XTHNVWxypznxWOYUeI4g3WdP9Pk2Qk58+a/O9MY= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= +google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20221227171554-f9683d7f8bef h1:uQ2vjV/sHTsWSqdKeLqmwitzgvjMl7o4IdtHwUDXSJY= +google.golang.org/genproto v0.0.0-20221227171554-f9683d7f8bef/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= +google.golang.org/grpc v1.51.0 h1:E1eGv1FTqoLIdnBCZufiSHgKjlqG6fKFf6pPWtMTh8U= +google.golang.org/grpc v1.51.0/go.mod h1:wgNDFcnuBGmxLKI/qn4T+m5BtEBYXJPvibbUPsAIPww= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= +google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= googlemaps.github.io/maps v1.3.2 h1:3YfYdVWFTFi7lVdCdrDYW3dqHvfCSUdC7/x8pbMOuKQ= googlemaps.github.io/maps v1.3.2/go.mod h1:cCq0JKYAnnCRSdiaBi7Ex9CW15uxIAk7oPi8V/xEh6s= gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc h1:2gGKlE2+asNV9m7xrywl36YYNnBG5ZQ0r/BOOxqPpmk= @@ -155,4 +265,6 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/router/route.go b/router/route.go index bba770f..7067e98 100644 --- a/router/route.go +++ b/router/route.go @@ -59,6 +59,7 @@ func PrepareRouter( { customer.PUT("/:id", apiHandler.CustomerEditProfile) customer.POST("/:id/order", apiHandler.CustomerOrder) + customer.POST("/:id/order/find-driver", apiHandler.CustomerFindDriver) } /** diff --git a/ubur-app-77cbd-firebase-adminsdk-j6dj4-d31a4049ec.json b/ubur-app-77cbd-firebase-adminsdk-j6dj4-d31a4049ec.json new file mode 100644 index 0000000..18d5988 --- /dev/null +++ b/ubur-app-77cbd-firebase-adminsdk-j6dj4-d31a4049ec.json @@ -0,0 +1,12 @@ +{ + "type": "service_account", + "project_id": "ubur-app-77cbd", + "private_key_id": "d31a4049ecf139e15d575786048c37bf89708047", + "private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCveExIsYNBs9zn\nPVhlkztjznWJJJ+kRXUHMYRy1v+se+YxObLgShfGImnMfIkqgonTDo0cwjAhzeHO\nc5wgZKUIOL1VVUX0WsIcT9BSdkKwe5MkLgayYAVIH/eJLEXp/0oBpjbLj4fp06H5\njkuTPGMuwxbYcinPs1zjYuP5oamZNDWvvt7EmmQX54sxfiCfKj+MLKGc1feTxYrM\ntGdEddPI+oNQFquO1jXj6UWsjquy4C2qbHOhsDLn5lA1m71c3Q0I2UcNy+S4N9j/\nXTp54fUGGJk69/EPAN26ekcQy68b98hEtlfOuiikucX4rnzXTfuR9Bt8WRXieIgb\nTplwYk+ZAgMBAAECggEANas4wd8xg04NGdkkiWTf/GXwgzLldSwdYEbf+PQTnWEE\nBjhcosdmwB5Ud8v7dDobB6fit1IZwK0lDK1Fqo69/2bDWi9LxzJfPqOW1zH+sdYK\nKj29pJ9D3kyQvK8C71A7BYgeKGLNMlKdryO7r9v/hhT7jtZUPYfhuFbN3dN5eTcC\nL3Fg2IEQ5s3IKju6dzuKmg5Xud0KNymCJkplt/rV4VuNxc1PMEns5DPj+mnl8eRx\nV8/6U4yYNNQC3H+ql6Zm9UMxD//5W36RNOKyqtMCM+y2M7TpigEpYyJtowINC+/D\nrNpeHs53Wdh+Y/fTd/dPtQsnU0SrXrDys9pWCYxeJQKBgQDWi2h5Tmf08rf6rpMx\nBr0PipzUzzOB5vIftkrEb4scEZdcn4eDSJ2PG+gJ7ME5a93PaKrN6bQU9RI+SLxS\nksqR/coDzWiMHiH+ePvGVml58x96o8CKCwTpZQ8QLhexUlfMfkUCL+o/i9p2oZqb\nTQr/ekk37h22IJCxtdjUg8a5rwKBgQDRYAk0AAaPR4giNK6sEwFJBHLgOcjf52X9\neW8dZIkSAbkp96Sc+HFdyrcRf3zuiBy5noXWdbqAWIKrgYlJXOdLENsZx+DBXxIA\nIWmLKJIMaXYSahGLlKx2COvZeJCqU9nKi/zzREGi+ps8bsqHsmeQ2Pzp/KcAiwX/\niP08RfAFNwKBgGBeknkazPtsI1QJIri87COVAcldoSdSk6PHAGKoL/ZVuIW0aux/\nq7ZitKHwpQKj/yhxPXfs6CUZyC4OAfmdUjytoRaAJ9v4lRB3S7DVk99hY9x0vcHE\nHVqxOEjuS1otQJ7sgRbwaupMab8r7ASiYLRNO6JR5SqwCg6pPlKHNralAoGATOeB\neeAoiKg1kJrZLcstRaykpUeUSOmtxJS+A4XR8xM+9/NGO4Hl4hV7eKnjMZo9MtDP\nSB6mCk54cJZ73r6JFkFyuN156I0LB5E+OycDvhteixT6rNJHJnPQbWijemyiKouQ\ntan0kfCK5H+tVHprIAETpL5wePqXkWy311O4/bECgYEAnq7qc3J4exUDnA98RyG2\nFzPNHaYqIwOlQXziJf+SG/Lo1bhO+kIc+QM9L2MVjP8wGm801YYdbh8kHOI227Bf\nbS2Qx6We1JTgDQEET5NBefzTaBqAuHJVVf/anBE2mFXpXjZbGZbUImOd+XDwy8C+\n5oKGjUJDpIS6IOxLvM0AnLw=\n-----END PRIVATE KEY-----\n", + "client_email": "firebase-adminsdk-j6dj4@ubur-app-77cbd.iam.gserviceaccount.com", + "client_id": "111582376030180903543", + "auth_uri": "https://accounts.google.com/o/oauth2/auth", + "token_uri": "https://oauth2.googleapis.com/token", + "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs", + "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/firebase-adminsdk-j6dj4%40ubur-app-77cbd.iam.gserviceaccount.com" +} -- GitLab From dbafa73138d81a54be44be7582088704eea68326 Mon Sep 17 00:00:00 2001 From: Hilman Taris Muttaqin Date: Sat, 7 Jan 2023 19:03:33 +0700 Subject: [PATCH 51/62] add get order for customer and driver --- data/entity/orders_entity.go | 32 ++++++++--------- data/model/order_model.go | 16 +++++---- data/request/order_request.go | 2 +- domain/handler/api_handler.go | 32 +++++++++++++++++ domain/repository/order_repository.go | 52 +++++++++++++++++++++++++++ domain/usecase/user_usecase.go | 26 ++++++++++++++ helper/mapper.go | 24 ++++++------- router/route.go | 2 ++ 8 files changed, 150 insertions(+), 36 deletions(-) diff --git a/data/entity/orders_entity.go b/data/entity/orders_entity.go index 39d2e67..543377f 100644 --- a/data/entity/orders_entity.go +++ b/data/entity/orders_entity.go @@ -3,20 +3,20 @@ package entity import "database/sql" type OrdersEntity struct { - OrderID int `json:"order_id"` - UserID int `json:"user_id"` - DriverID int `json:"driver_id"` - Destination string `json:"destination"` - PickUP string `json:"pickup"` - Distance float64 `json:"distance"` - Duration float64 `json:"duration"` - PaymentType string `json:"payment_type"` - Price float64 `json:"price"` - Income float64 `json:"income"` - IsCancel bool `json:"is_cancel"` - CancelReason string `json:"cancel_reason"` - FinishedAt sql.NullTime `json:"finished_at"` - CreatedAt sql.NullTime `json:"created_at"` - UpdateAt sql.NullTime `json:"update_at"` - DeletedAt sql.NullTime `json:"deleted_at"` + OrderID int `json:"order_id"` + UserID int `json:"user_id"` + DriverID int `json:"driver_id"` + Destination string `json:"destination"` + PickUP string `json:"pickup"` + Distance int `json:"distance"` + Duration float64 `json:"duration"` + PaymentType string `json:"payment_type"` + Price float64 `json:"price"` + Income float64 `json:"income"` + IsCancel sql.NullString `json:"is_cancel"` + CancelReason sql.NullString `json:"cancel_reason"` + FinishedAt sql.NullTime `json:"finished_at"` + CreatedAt sql.NullTime `json:"created_at"` + UpdateAt sql.NullTime `json:"update_at"` + DeletedAt sql.NullTime `json:"deleted_at"` } diff --git a/data/model/order_model.go b/data/model/order_model.go index aa1600a..c3681ff 100644 --- a/data/model/order_model.go +++ b/data/model/order_model.go @@ -1,6 +1,8 @@ package model -import "database/sql" +import ( + "time" +) type OrderModel struct { OrderId int @@ -8,15 +10,15 @@ type OrderModel struct { DriverId int Destination string Pickup string - Distance float64 + Distance int Duration float64 PaymentType string Price float64 Income float64 - IsCancel bool + IsCancel string CancelReason string - FinishedAt sql.NullTime - CreatedAt sql.NullTime - UpdatedAt sql.NullTime - DeletedAt sql.NullTime + FinishedAt time.Time + CreatedAt time.Time + UpdatedAt time.Time + DeletedAt time.Time } diff --git a/data/request/order_request.go b/data/request/order_request.go index 514a41d..860571e 100644 --- a/data/request/order_request.go +++ b/data/request/order_request.go @@ -4,7 +4,7 @@ type OrderRequest struct { DriverId int `json:"driver_id" binding:"required"` Destination string `json:"destination" binding:"required"` Pickup string `json:"pickup" binding:"required"` - Distance float64 `json:"distance" binding:"required"` + Distance int `json:"distance" binding:"required"` Duration float64 `json:"duration" binding:"required"` PaymentType string `json:"payment_type" binding:"required"` Price float64 `json:"price" binding:"required"` diff --git a/domain/handler/api_handler.go b/domain/handler/api_handler.go index 09118b1..eee3467 100644 --- a/domain/handler/api_handler.go +++ b/domain/handler/api_handler.go @@ -150,6 +150,22 @@ func (handler *ApiHandler) Search(context *gin.Context) { * membutuhkan token untuk request semua fitur */ +func (handler *ApiHandler) CustomerGetOrder(context *gin.Context) { + userId, err := strconv.Atoi(context.Param("id")) + if err != nil { + response.ResponseError(context, http.StatusInternalServerError, err) + return + } + + customerOrders, err := handler.userUsecase.GetCustomerOrder(userId) + if err != nil { + response.ResponseError(context, http.StatusInternalServerError, err) + return + } + + response.ResponseSuccess(context, http.StatusOK, customerOrders) +} + func (handler *ApiHandler) CustomerFindDriver(con *gin.Context) { var findDriverRequest request.FindDriverRequest @@ -292,6 +308,22 @@ func (handler *ApiHandler) CustomerOrder(context *gin.Context) { * membutuhkan token untuk request semua fitur */ +func (handler *ApiHandler) DriverGetOrder(context *gin.Context) { + userId, err := strconv.Atoi(context.Param("id")) + if err != nil { + response.ResponseError(context, http.StatusInternalServerError, err) + return + } + + customerOrders, err := handler.userUsecase.GetDriverOrder(userId) + if err != nil { + response.ResponseError(context, http.StatusInternalServerError, err) + return + } + + response.ResponseSuccess(context, http.StatusOK, customerOrders) +} + func (handler *ApiHandler) DriverEditProfile(context *gin.Context) { userId, err := strconv.Atoi(context.Param("id")) if err != nil { diff --git a/domain/repository/order_repository.go b/domain/repository/order_repository.go index 1d0e7fb..90906b3 100644 --- a/domain/repository/order_repository.go +++ b/domain/repository/order_repository.go @@ -9,6 +9,8 @@ import ( type OrderRepository interface { InsertNewOrder(entity entity.OrdersEntity) (err error) UpdateOrder(entity entity.OrdersEntity) (err error) + GetOrderForCustomer(userId int) (results []entity.OrdersEntity, err error) + GetOrderForDriver(driverId int) (results []entity.OrdersEntity, err error) } func GetOrderRepository(db *sql.DB) *Repository { @@ -17,6 +19,56 @@ func GetOrderRepository(db *sql.DB) *Repository { } } +func (r *Repository) GetOrderForCustomer(userId int) (results []entity.OrdersEntity, err error) { + var query = "SELECT * FROM orders WHERE user_id=?" + result, err := r.Db.Query(query, userId) + defer result.Close() + + if err != nil { + panic(err.Error()) + } + + var orders []entity.OrdersEntity + + for result.Next() { + var order entity.OrdersEntity + err := result.Scan(&order.OrderID, &order.UserID, &order.DriverID, &order.Destination, &order.PickUP, &order.Distance, + &order.Duration, &order.PaymentType, &order.Price, &order.Income, &order.IsCancel, &order.CancelReason, + &order.FinishedAt, &order.CreatedAt, &order.UpdateAt, &order.DeletedAt) + if err != nil { + return orders, err + } + orders = append(orders, order) + } + + return orders, nil +} + +func (r *Repository) GetOrderForDriver(driverId int) (results []entity.OrdersEntity, err error) { + var query = "SELECT * FROM orders WHERE driver_id=?" + result, err := r.Db.Query(query, driverId) + defer result.Close() + + if err != nil { + panic(err.Error()) + } + + var orders []entity.OrdersEntity + + for result.Next() { + var order entity.OrdersEntity + err := result.Scan(&order.OrderID, &order.UserID, &order.DriverID, &order.Destination, &order.PickUP, &order.Distance, + &order.Duration, &order.PaymentType, &order.Price, &order.Income, &order.IsCancel, &order.CancelReason, + &order.FinishedAt, &order.CreatedAt, &order.UpdateAt, &order.DeletedAt) + if err != nil { + return orders, err + } + orders = append(orders, order) + } + + return orders, nil +} + func (r *Repository) InsertNewOrder(entity entity.OrdersEntity) (err error) { query := "INSERT INTO orders " + "(user_id, driver_id, destination, pickup, distance, duration, payment_type, price, income) VALUES " + diff --git a/domain/usecase/user_usecase.go b/domain/usecase/user_usecase.go index 095dbc4..2b3a1f1 100644 --- a/domain/usecase/user_usecase.go +++ b/domain/usecase/user_usecase.go @@ -26,12 +26,14 @@ type UserInteractor interface { // Customer Interactor EditProfile(user model.UserModel) (err error) CustomerOrder(order model.OrderModel) (err error) + GetCustomerOrder(userId int) (result []model.OrderModel, err error) // Driver Interactor NewVehicle(vehicle model.MotorcycleModel) (err error) GetVehicles(driverId int) (results []model.MotorcycleModel, err error) DeleteVehicle(driverId int, vehicleId int) (result model.MotorcycleModel, err error) DriverPostDocument(user model.UserModel) (err error) + GetDriverOrder(driverId int) (result []model.OrderModel, err error) } func GetUserUseCase( @@ -47,6 +49,30 @@ func GetUserUseCase( } } +func (useCase *UserUseCase) GetCustomerOrder(userId int) (result []model.OrderModel, err error) { + var customerOrders []model.OrderModel + + records, err := useCase.orderRepository.GetOrderForCustomer(userId) + + for _, item := range records { + customerOrders = append(customerOrders, helper.OrderEntityToOrderModel(item)) + } + + return customerOrders, err +} + +func (useCase *UserUseCase) GetDriverOrder(driverId int) (result []model.OrderModel, err error) { + var driverOrders []model.OrderModel + + records, err := useCase.orderRepository.GetOrderForDriver(driverId) + + for _, item := range records { + driverOrders = append(driverOrders, helper.OrderEntityToOrderModel(item)) + } + + return driverOrders, err +} + func (useCase *UserUseCase) CustomerOrder(order model.OrderModel) (err error) { customerOrder := helper.OrderModelToOrderEntity(order) return useCase.orderRepository.InsertNewOrder(customerOrder) diff --git a/helper/mapper.go b/helper/mapper.go index cefdca2..c42c212 100644 --- a/helper/mapper.go +++ b/helper/mapper.go @@ -18,12 +18,12 @@ func OrderEntityToOrderModel(entity entity2.OrdersEntity) model2.OrderModel { PaymentType: entity.PaymentType, Price: entity.Price, Income: entity.Income, - IsCancel: entity.IsCancel, - CancelReason: entity.CancelReason, - FinishedAt: entity.FinishedAt, - CreatedAt: entity.CreatedAt, - UpdatedAt: entity.UpdateAt, - DeletedAt: entity.DeletedAt, + IsCancel: entity.IsCancel.String, + CancelReason: entity.CancelReason.String, + FinishedAt: entity.FinishedAt.Time, + CreatedAt: entity.CreatedAt.Time, + UpdatedAt: entity.UpdateAt.Time, + DeletedAt: entity.DeletedAt.Time, } } @@ -39,12 +39,12 @@ func OrderModelToOrderEntity(model model2.OrderModel) entity2.OrdersEntity { PaymentType: model.PaymentType, Price: model.Price, Income: model.Income, - IsCancel: model.IsCancel, - CancelReason: model.CancelReason, - FinishedAt: model.FinishedAt, - CreatedAt: model.CreatedAt, - UpdateAt: model.UpdatedAt, - DeletedAt: model.DeletedAt, + IsCancel: sql.NullString{String: model.IsCancel}, + CancelReason: sql.NullString{String: model.CancelReason}, + FinishedAt: sql.NullTime{Time: model.FinishedAt}, + CreatedAt: sql.NullTime{Time: model.CreatedAt}, + UpdateAt: sql.NullTime{Time: model.UpdatedAt}, + DeletedAt: sql.NullTime{Time: model.DeletedAt}, } } diff --git a/router/route.go b/router/route.go index 7067e98..93bc0c3 100644 --- a/router/route.go +++ b/router/route.go @@ -58,6 +58,7 @@ func PrepareRouter( middleware.CustomerRequiredMiddleware()) { customer.PUT("/:id", apiHandler.CustomerEditProfile) + customer.GET("/:id/order", apiHandler.CustomerGetOrder) customer.POST("/:id/order", apiHandler.CustomerOrder) customer.POST("/:id/order/find-driver", apiHandler.CustomerFindDriver) } @@ -76,6 +77,7 @@ func PrepareRouter( driver.DELETE("/vehicle", apiHandler.DeleteVehicle) driver.POST("/document", apiHandler.DriverPostDocument) driver.PUT("/:id", apiHandler.DriverEditProfile) + driver.GET("/:id/order", apiHandler.DriverGetOrder) } } -- GitLab From 3869cf40d577c7df8aebd5bb1f199857da38f05c Mon Sep 17 00:00:00 2001 From: Hilman Taris Muttaqin Date: Sat, 7 Jan 2023 21:00:24 +0700 Subject: [PATCH 52/62] add order detail when fetch orders from customer and from driver --- data/model/detail_order_model.go | 7 ++++ domain/usecase/user_usecase.go | 58 +++++++++++++++++++++++++------- 2 files changed, 52 insertions(+), 13 deletions(-) create mode 100644 data/model/detail_order_model.go diff --git a/data/model/detail_order_model.go b/data/model/detail_order_model.go new file mode 100644 index 0000000..ef4f9f4 --- /dev/null +++ b/data/model/detail_order_model.go @@ -0,0 +1,7 @@ +package model + +type DetailOrder struct { + Driver UserModel + Customer UserModel + OrderModel +} diff --git a/domain/usecase/user_usecase.go b/domain/usecase/user_usecase.go index 2b3a1f1..7edf2cf 100644 --- a/domain/usecase/user_usecase.go +++ b/domain/usecase/user_usecase.go @@ -26,14 +26,14 @@ type UserInteractor interface { // Customer Interactor EditProfile(user model.UserModel) (err error) CustomerOrder(order model.OrderModel) (err error) - GetCustomerOrder(userId int) (result []model.OrderModel, err error) + GetCustomerOrder(userId int) (result []model.DetailOrder, err error) // Driver Interactor NewVehicle(vehicle model.MotorcycleModel) (err error) GetVehicles(driverId int) (results []model.MotorcycleModel, err error) DeleteVehicle(driverId int, vehicleId int) (result model.MotorcycleModel, err error) DriverPostDocument(user model.UserModel) (err error) - GetDriverOrder(driverId int) (result []model.OrderModel, err error) + GetDriverOrder(driverId int) (result []model.DetailOrder, err error) } func GetUserUseCase( @@ -49,28 +49,60 @@ func GetUserUseCase( } } -func (useCase *UserUseCase) GetCustomerOrder(userId int) (result []model.OrderModel, err error) { - var customerOrders []model.OrderModel +func (useCase *UserUseCase) GetCustomerOrder(userId int) (result []model.DetailOrder, err error) { + var customerOrders []model.DetailOrder - records, err := useCase.orderRepository.GetOrderForCustomer(userId) + recordsOrder, err := useCase.orderRepository.GetOrderForCustomer(userId) - for _, item := range records { - customerOrders = append(customerOrders, helper.OrderEntityToOrderModel(item)) + for _, item := range recordsOrder { + recordDriver, err := useCase.userRepository.GetUserById(item.DriverID) + if err != nil { + return customerOrders, err + } + + recordCustomer, err := useCase.userRepository.GetUserById(item.UserID) + if err != nil { + return customerOrders, err + } + + customerOrder := model.DetailOrder{ + Driver: helper.UserEntityToUserModel(recordDriver), + Customer: helper.UserEntityToUserModel(recordCustomer), + OrderModel: helper.OrderEntityToOrderModel(item), + } + + customerOrders = append(customerOrders, customerOrder) } return customerOrders, err } -func (useCase *UserUseCase) GetDriverOrder(driverId int) (result []model.OrderModel, err error) { - var driverOrders []model.OrderModel +func (useCase *UserUseCase) GetDriverOrder(driverId int) (result []model.DetailOrder, err error) { + var customerOrders []model.DetailOrder - records, err := useCase.orderRepository.GetOrderForDriver(driverId) + recordsOrder, err := useCase.orderRepository.GetOrderForDriver(driverId) - for _, item := range records { - driverOrders = append(driverOrders, helper.OrderEntityToOrderModel(item)) + for _, item := range recordsOrder { + recordDriver, err := useCase.userRepository.GetUserById(item.DriverID) + if err != nil { + return customerOrders, err + } + + recordCustomer, err := useCase.userRepository.GetUserById(item.UserID) + if err != nil { + return customerOrders, err + } + + customerOrder := model.DetailOrder{ + Driver: helper.UserEntityToUserModel(recordDriver), + Customer: helper.UserEntityToUserModel(recordCustomer), + OrderModel: helper.OrderEntityToOrderModel(item), + } + + customerOrders = append(customerOrders, customerOrder) } - return driverOrders, err + return customerOrders, err } func (useCase *UserUseCase) CustomerOrder(order model.OrderModel) (err error) { -- GitLab From e0e74d13f5f165f47c40458dc49576bf78a8202e Mon Sep 17 00:00:00 2001 From: Hilman Taris Muttaqin Date: Sat, 7 Jan 2023 22:13:35 +0700 Subject: [PATCH 53/62] fixing response format for get orders customer and driver --- data/model/detail_order_model.go | 1 + domain/handler/api_handler.go | 43 ++++++++++++++++++++++++++++++-- domain/usecase/user_usecase.go | 17 +++++-------- 3 files changed, 48 insertions(+), 13 deletions(-) diff --git a/data/model/detail_order_model.go b/data/model/detail_order_model.go index ef4f9f4..be6f472 100644 --- a/data/model/detail_order_model.go +++ b/data/model/detail_order_model.go @@ -3,5 +3,6 @@ package model type DetailOrder struct { Driver UserModel Customer UserModel + Vehicle MotorcycleModel OrderModel } diff --git a/domain/handler/api_handler.go b/domain/handler/api_handler.go index eee3467..3b3bbd9 100644 --- a/domain/handler/api_handler.go +++ b/domain/handler/api_handler.go @@ -163,7 +163,32 @@ func (handler *ApiHandler) CustomerGetOrder(context *gin.Context) { return } - response.ResponseSuccess(context, http.StatusOK, customerOrders) + var results []gin.H + for _, item := range customerOrders { + orderDetail := gin.H{ + "driver": gin.H{ + "id": item.Driver.UserId, + "name": item.Driver.Name, + "profile_pict": item.Driver.ProfilePict, + }, + "vehicle": gin.H{ + "name": item.Vehicle.VehicleName, + "license_plate": item.Vehicle.RegistrationNoVehicle, + }, + "order": gin.H{ + "driver_id": item.DriverId, + "destination": item.Destination, + "pickup_point": item.Pickup, + "distance": item.Distance, + "duration": item.Duration, + "payment_type": item.PaymentType, + "price": item.Price, + }, + } + results = append(results, orderDetail) + } + + response.ResponseSuccess(context, http.StatusOK, results) } func (handler *ApiHandler) CustomerFindDriver(con *gin.Context) { @@ -321,7 +346,21 @@ func (handler *ApiHandler) DriverGetOrder(context *gin.Context) { return } - response.ResponseSuccess(context, http.StatusOK, customerOrders) + var results []gin.H + for _, item := range customerOrders { + orderDetail := gin.H{ + "driver_id": item.DriverId, + "destination": item.Destination, + "pickup_point": item.Pickup, + "distance": item.Distance, + "duration": item.Duration, + "payment_type": item.PaymentType, + "price": item.Price, + } + results = append(results, orderDetail) + } + + response.ResponseSuccess(context, http.StatusOK, results) } func (handler *ApiHandler) DriverEditProfile(context *gin.Context) { diff --git a/domain/usecase/user_usecase.go b/domain/usecase/user_usecase.go index 7edf2cf..0851a9b 100644 --- a/domain/usecase/user_usecase.go +++ b/domain/usecase/user_usecase.go @@ -60,6 +60,11 @@ func (useCase *UserUseCase) GetCustomerOrder(userId int) (result []model.DetailO return customerOrders, err } + vehicleDriver, err := useCase.vehicleRepository.GetVehicles(item.DriverID) + if err != nil { + return customerOrders, err + } + recordCustomer, err := useCase.userRepository.GetUserById(item.UserID) if err != nil { return customerOrders, err @@ -69,6 +74,7 @@ func (useCase *UserUseCase) GetCustomerOrder(userId int) (result []model.DetailO Driver: helper.UserEntityToUserModel(recordDriver), Customer: helper.UserEntityToUserModel(recordCustomer), OrderModel: helper.OrderEntityToOrderModel(item), + Vehicle: helper.VehicleEntityToVehicleModel(vehicleDriver[0]), } customerOrders = append(customerOrders, customerOrder) @@ -83,19 +89,8 @@ func (useCase *UserUseCase) GetDriverOrder(driverId int) (result []model.DetailO recordsOrder, err := useCase.orderRepository.GetOrderForDriver(driverId) for _, item := range recordsOrder { - recordDriver, err := useCase.userRepository.GetUserById(item.DriverID) - if err != nil { - return customerOrders, err - } - - recordCustomer, err := useCase.userRepository.GetUserById(item.UserID) - if err != nil { - return customerOrders, err - } customerOrder := model.DetailOrder{ - Driver: helper.UserEntityToUserModel(recordDriver), - Customer: helper.UserEntityToUserModel(recordCustomer), OrderModel: helper.OrderEntityToOrderModel(item), } -- GitLab From 417c390172218bb225708dfdf1dd9cb6e06be385 Mon Sep 17 00:00:00 2001 From: Hilman Taris Muttaqin Date: Sat, 7 Jan 2023 22:31:53 +0700 Subject: [PATCH 54/62] change response name to vehicle_name in customer get orders --- domain/handler/api_handler.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/domain/handler/api_handler.go b/domain/handler/api_handler.go index 3b3bbd9..6b0d898 100644 --- a/domain/handler/api_handler.go +++ b/domain/handler/api_handler.go @@ -168,7 +168,7 @@ func (handler *ApiHandler) CustomerGetOrder(context *gin.Context) { orderDetail := gin.H{ "driver": gin.H{ "id": item.Driver.UserId, - "name": item.Driver.Name, + "vehicle_name": item.Driver.Name, "profile_pict": item.Driver.ProfilePict, }, "vehicle": gin.H{ -- GitLab From 37c0067f2d5b02bd5aaf38803b31a9fa8603071f Mon Sep 17 00:00:00 2001 From: Hilman Taris Muttaqin Date: Sun, 8 Jan 2023 01:11:50 +0700 Subject: [PATCH 55/62] fixing vehicle_name result in customer orders --- domain/handler/api_handler.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/domain/handler/api_handler.go b/domain/handler/api_handler.go index 6b0d898..3d9b984 100644 --- a/domain/handler/api_handler.go +++ b/domain/handler/api_handler.go @@ -168,11 +168,11 @@ func (handler *ApiHandler) CustomerGetOrder(context *gin.Context) { orderDetail := gin.H{ "driver": gin.H{ "id": item.Driver.UserId, - "vehicle_name": item.Driver.Name, + "name": item.Driver.Name, "profile_pict": item.Driver.ProfilePict, }, "vehicle": gin.H{ - "name": item.Vehicle.VehicleName, + "vehicle_name": item.Vehicle.VehicleName, "license_plate": item.Vehicle.RegistrationNoVehicle, }, "order": gin.H{ -- GitLab From 32ef143b5f2a153e3e54b0597cdf665d6a262d17 Mon Sep 17 00:00:00 2001 From: Hilman Taris Muttaqin Date: Sun, 8 Jan 2023 01:56:42 +0700 Subject: [PATCH 56/62] add income endpoint for driver --- domain/handler/api_handler.go | 21 +++++++++++++++++++++ router/route.go | 1 + 2 files changed, 22 insertions(+) diff --git a/domain/handler/api_handler.go b/domain/handler/api_handler.go index 3d9b984..ce3b0eb 100644 --- a/domain/handler/api_handler.go +++ b/domain/handler/api_handler.go @@ -333,6 +333,27 @@ func (handler *ApiHandler) CustomerOrder(context *gin.Context) { * membutuhkan token untuk request semua fitur */ +func (handler *ApiHandler) DriverIncome(context *gin.Context) { + userId, err := strconv.Atoi(context.Param("id")) + if err != nil { + response.ResponseError(context, http.StatusInternalServerError, err) + return + } + + customerOrders, err := handler.userUsecase.GetDriverOrder(userId) + if err != nil { + response.ResponseError(context, http.StatusInternalServerError, err) + return + } + + var total = 0.0 + for _, item := range customerOrders { + total += item.Price + } + + response.ResponseSuccess(context, http.StatusOK, total) +} + func (handler *ApiHandler) DriverGetOrder(context *gin.Context) { userId, err := strconv.Atoi(context.Param("id")) if err != nil { diff --git a/router/route.go b/router/route.go index 93bc0c3..043519d 100644 --- a/router/route.go +++ b/router/route.go @@ -78,6 +78,7 @@ func PrepareRouter( driver.POST("/document", apiHandler.DriverPostDocument) driver.PUT("/:id", apiHandler.DriverEditProfile) driver.GET("/:id/order", apiHandler.DriverGetOrder) + driver.GET("/:id/order/income", apiHandler.DriverIncome) } } -- GitLab From 2bfb7fb4503f3f5c54cbc4f2e5ebfb8d8232e08d Mon Sep 17 00:00:00 2001 From: Hilman Taris Muttaqin Date: Sun, 8 Jan 2023 19:59:48 +0700 Subject: [PATCH 57/62] add order decision from driver to customer --- data/request/driver_order_decision_request.go | 8 ++++ domain/handler/api_handler.go | 39 +++++++++++++++++++ router/route.go | 1 + 3 files changed, 48 insertions(+) create mode 100644 data/request/driver_order_decision_request.go diff --git a/data/request/driver_order_decision_request.go b/data/request/driver_order_decision_request.go new file mode 100644 index 0000000..46faa44 --- /dev/null +++ b/data/request/driver_order_decision_request.go @@ -0,0 +1,8 @@ +package request + +type DriverOrderDecisionRequest struct { + RegistrationToken string `json:"registration_token"` + NotificationTitle string `json:"notification_title"` + NotificationDesc string `json:"notification_desc"` + Decision string `json:"decision"` +} diff --git a/domain/handler/api_handler.go b/domain/handler/api_handler.go index ce3b0eb..5d6cebf 100644 --- a/domain/handler/api_handler.go +++ b/domain/handler/api_handler.go @@ -333,6 +333,45 @@ func (handler *ApiHandler) CustomerOrder(context *gin.Context) { * membutuhkan token untuk request semua fitur */ +func (handler *ApiHandler) DriverOrderDecision(con *gin.Context) { + var driverOrderDecision request.DriverOrderDecisionRequest + + err := con.ShouldBindJSON(&driverOrderDecision) + if err != nil { + HandlerError(con, err) + return + } + + ctx := context.Background() + service, err := handler.firebaseApp.Messaging(ctx) + if err != nil { + response.ResponseError(con, http.StatusInternalServerError, err) + return + } + + message := messaging.Message{ + Data: map[string]string{ + "decision": driverOrderDecision.Decision, + }, + Notification: &messaging.Notification{ + Title: driverOrderDecision.NotificationTitle, + Body: driverOrderDecision.NotificationDesc, + }, + Token: driverOrderDecision.RegistrationToken, + } + + res, err := service.Send(ctx, &message) + if err != nil { + response.ResponseError(con, http.StatusInternalServerError, err) + return + } + + response.ResponseSuccess(con, http.StatusOK, gin.H{ + "message": "blbalblba", + "result": res, + }) +} + func (handler *ApiHandler) DriverIncome(context *gin.Context) { userId, err := strconv.Atoi(context.Param("id")) if err != nil { diff --git a/router/route.go b/router/route.go index 043519d..9c07a81 100644 --- a/router/route.go +++ b/router/route.go @@ -79,6 +79,7 @@ func PrepareRouter( driver.PUT("/:id", apiHandler.DriverEditProfile) driver.GET("/:id/order", apiHandler.DriverGetOrder) driver.GET("/:id/order/income", apiHandler.DriverIncome) + driver.POST("/:id/order/decision", apiHandler.DriverOrderDecision) } } -- GitLab From bf2c85156da04c30a60594aa2c1c91cc71834bef Mon Sep 17 00:00:00 2001 From: Hilman Taris Muttaqin Date: Wed, 11 Jan 2023 11:20:47 +0700 Subject: [PATCH 58/62] add rating endpoint for customer --- config/prepare.go | 4 ++- data/entity/orders_entity.go | 2 +- data/entity/ratings_entity.go | 8 +++--- data/model/order_model.go | 2 +- data/model/rating_model.go | 4 +-- data/request/rating_request.go | 9 ++++++ domain/handler/api_handler.go | 40 ++++++++++++++++++++++++++ domain/repository/order_repository.go | 6 ++-- domain/repository/rating_repository.go | 28 ++++++++++++++++++ domain/usecase/user_usecase.go | 10 ++++++- helper/mapper.go | 21 ++++++++++++++ router/route.go | 1 + 12 files changed, 122 insertions(+), 13 deletions(-) create mode 100644 data/request/rating_request.go create mode 100644 domain/repository/rating_repository.go diff --git a/config/prepare.go b/config/prepare.go index 3c8c0b1..7496943 100644 --- a/config/prepare.go +++ b/config/prepare.go @@ -22,13 +22,15 @@ func PrepareAll() (*handler.ApiHandler, *handler.AuthHandler) { verificationRepository := repository2.GetVerificationRepository(db) vehicleRepository := repository2.GetVehicleRepository(db) orderRepository := repository2.GetOrderRepository(db) + ratingRepository := repository2.GetRatingRepository(db) // prepare usecase userUsecase := usecase.GetUserUseCase( userRepository, verificationRepository, vehicleRepository, - orderRepository) + orderRepository, + ratingRepository) // firebase init opt := option.WithCredentialsFile("./ubur-app-77cbd-firebase-adminsdk-j6dj4-d31a4049ec.json") diff --git a/data/entity/orders_entity.go b/data/entity/orders_entity.go index 543377f..44c4c3a 100644 --- a/data/entity/orders_entity.go +++ b/data/entity/orders_entity.go @@ -3,7 +3,7 @@ package entity import "database/sql" type OrdersEntity struct { - OrderID int `json:"order_id"` + OrderID string `json:"order_id"` UserID int `json:"user_id"` DriverID int `json:"driver_id"` Destination string `json:"destination"` diff --git a/data/entity/ratings_entity.go b/data/entity/ratings_entity.go index de14c17..e424628 100644 --- a/data/entity/ratings_entity.go +++ b/data/entity/ratings_entity.go @@ -4,11 +4,11 @@ import "database/sql" type RatingsEntity struct { RatingID int `json:"rating_id"` - OrderID int `json:"order_id"` + OrderID string `json:"order_id"` UserID int `json:"user_id"` - FromRatings string `json:"from_ratings"` - ToRatings string `json:"to_ratings"` - Star string `json:"star"` + FromRatings int `json:"from_ratings"` + ToRatings int `json:"to_ratings"` + Star int `json:"star"` Feedback string `json:"feedback"` CreatedAt string `json:"created_at"` UpdatedAt sql.NullString `json:"update_at"` diff --git a/data/model/order_model.go b/data/model/order_model.go index c3681ff..157bbbe 100644 --- a/data/model/order_model.go +++ b/data/model/order_model.go @@ -5,7 +5,7 @@ import ( ) type OrderModel struct { - OrderId int + OrderId string CustomerId int DriverId int Destination string diff --git a/data/model/rating_model.go b/data/model/rating_model.go index ae8f721..962b02c 100644 --- a/data/model/rating_model.go +++ b/data/model/rating_model.go @@ -4,7 +4,7 @@ type RatingModel struct { RatingId string Star int Feedback string - FromId string - ToId string + FromId int + ToId int OrderId string } diff --git a/data/request/rating_request.go b/data/request/rating_request.go new file mode 100644 index 0000000..8f98033 --- /dev/null +++ b/data/request/rating_request.go @@ -0,0 +1,9 @@ +package request + +type RatingRequest struct { + OrderId string `json:"order_id"` + From int `json:"from"` + To int `json:"to" binding:"required"` + Star int `json:"star" binding:"required"` + Feedback string `json:"feedback" binding:"required"` +} diff --git a/domain/handler/api_handler.go b/domain/handler/api_handler.go index 5d6cebf..04e2388 100644 --- a/domain/handler/api_handler.go +++ b/domain/handler/api_handler.go @@ -150,6 +150,44 @@ func (handler *ApiHandler) Search(context *gin.Context) { * membutuhkan token untuk request semua fitur */ +func (handler *ApiHandler) CustomerOrderRating(context *gin.Context) { + // get parameter + orderId := context.Param("idOrder") + userId, err := strconv.Atoi(context.Param("id")) + if err != nil { + response.ResponseError(context, http.StatusInternalServerError, err) + return + } + + // get body request + var ratingRequest request.RatingRequest + + err = context.ShouldBindJSON(&ratingRequest) + if err != nil { + HandlerError(context, err) + return + } + + // convert to rating model + ratingModel := model.RatingModel{ + OrderId: orderId, + FromId: userId, + ToId: ratingRequest.To, + Star: ratingRequest.Star, + Feedback: ratingRequest.Feedback, + } + + err = handler.userUsecase.InsertRating(ratingModel) + if err != nil { + response.ResponseError(context, http.StatusInternalServerError, err) + return + } + + response.ResponseSuccess(context, http.StatusOK, gin.H{ + "messge": "Thanks for the rating", + }) +} + func (handler *ApiHandler) CustomerGetOrder(context *gin.Context) { userId, err := strconv.Atoi(context.Param("id")) if err != nil { @@ -296,6 +334,7 @@ func (handler *ApiHandler) CustomerOrder(context *gin.Context) { } orderModel := model.OrderModel{ + OrderId: helper.GetRandomString(10), CustomerId: int(userId), DriverId: orderRequest.DriverId, Destination: orderRequest.Destination, @@ -316,6 +355,7 @@ func (handler *ApiHandler) CustomerOrder(context *gin.Context) { response.ResponseSuccess(context, http.StatusCreated, gin.H{ "message": "order created", "order": gin.H{ + "order_id": orderModel.OrderId, "driver_id": orderModel.DriverId, "destination": orderModel.Destination, "pickup_point": orderModel.Pickup, diff --git a/domain/repository/order_repository.go b/domain/repository/order_repository.go index 90906b3..490a164 100644 --- a/domain/repository/order_repository.go +++ b/domain/repository/order_repository.go @@ -71,9 +71,9 @@ func (r *Repository) GetOrderForDriver(driverId int) (results []entity.OrdersEnt func (r *Repository) InsertNewOrder(entity entity.OrdersEntity) (err error) { query := "INSERT INTO orders " + - "(user_id, driver_id, destination, pickup, distance, duration, payment_type, price, income) VALUES " + - "(?, ?, ?, ?, ?, ?, ?, ?, ?)" - _, execErr := r.Db.Exec(query, entity.UserID, entity.DriverID, entity.Destination, + "(order_id, user_id, driver_id, destination, pickup, distance, duration, payment_type, price, income) VALUES " + + "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" + _, execErr := r.Db.Exec(query, entity.OrderID, entity.UserID, entity.DriverID, entity.Destination, entity.PickUP, entity.Distance, entity.Duration, entity.PaymentType, entity.Price, entity.Income) if execErr != nil { return execErr diff --git a/domain/repository/rating_repository.go b/domain/repository/rating_repository.go new file mode 100644 index 0000000..c962b1c --- /dev/null +++ b/domain/repository/rating_repository.go @@ -0,0 +1,28 @@ +package repository + +import ( + "database/sql" + "ubur-backend/data/entity" +) + +type RatingRepository interface { + InsertNewRating(entity entity.RatingsEntity) (err error) +} + +func GetRatingRepository(db *sql.DB) *Repository { + return &Repository{ + Db: db, + } +} + +func (r *Repository) InsertNewRating(entity entity.RatingsEntity) (err error) { + query := "INSERT INTO ratings " + + "(order_id, user_id, from_ratings, to_ratings, star, feedback) VALUES " + + "(?, ?, ?, ?, ?, ?)" + _, execErr := r.Db.Exec(query, entity.OrderID, entity.FromRatings, entity.FromRatings, + entity.ToRatings, entity.Star, entity.Feedback) + if execErr != nil { + return execErr + } + return nil +} diff --git a/domain/usecase/user_usecase.go b/domain/usecase/user_usecase.go index 0851a9b..6aaab5d 100644 --- a/domain/usecase/user_usecase.go +++ b/domain/usecase/user_usecase.go @@ -14,6 +14,7 @@ type UserUseCase struct { verificationRepository repository.VerificationRepository vehicleRepository repository.VehicleRepository orderRepository repository.OrderRepository + ratingRepository repository.RatingRepository } type UserInteractor interface { @@ -22,6 +23,7 @@ type UserInteractor interface { GetUserById(id int) (result model.UserModel, err error) GetOTP(verificationModel model.VerificationModel) (result model.VerificationModel, err error) PostOTP(verification model.VerificationModel) (err error) + InsertRating(rating model.RatingModel) (err error) // Customer Interactor EditProfile(user model.UserModel) (err error) @@ -40,15 +42,21 @@ func GetUserUseCase( userRepository repository.UserRepository, verificationRepository repository.VerificationRepository, vehicleRepository repository.VehicleRepository, - orderRepository repository.OrderRepository) *UserUseCase { + orderRepository repository.OrderRepository, + ratingRepository repository.RatingRepository) *UserUseCase { return &UserUseCase{ userRepository: userRepository, verificationRepository: verificationRepository, vehicleRepository: vehicleRepository, orderRepository: orderRepository, + ratingRepository: ratingRepository, } } +func (useCase *UserUseCase) InsertRating(rating model.RatingModel) (err error) { + return useCase.ratingRepository.InsertNewRating(helper.RatingModelToRatingEntity(rating)) +} + func (useCase *UserUseCase) GetCustomerOrder(userId int) (result []model.DetailOrder, err error) { var customerOrders []model.DetailOrder diff --git a/helper/mapper.go b/helper/mapper.go index c42c212..2b9c1db 100644 --- a/helper/mapper.go +++ b/helper/mapper.go @@ -6,6 +6,27 @@ import ( model2 "ubur-backend/data/model" ) +func RatingModelToRatingEntity(model model2.RatingModel) entity2.RatingsEntity { + return entity2.RatingsEntity{ + OrderID: model.OrderId, + UserID: model.FromId, + FromRatings: model.FromId, + ToRatings: model.ToId, + Star: model.Star, + Feedback: model.Feedback, + } +} + +func RatingEntityToRatingModel(entity entity2.RatingsEntity) model2.RatingModel { + return model2.RatingModel{ + OrderId: entity.OrderID, + FromId: entity.FromRatings, + ToId: entity.ToRatings, + Star: entity.Star, + Feedback: entity.Feedback, + } +} + func OrderEntityToOrderModel(entity entity2.OrdersEntity) model2.OrderModel { return model2.OrderModel{ OrderId: entity.OrderID, diff --git a/router/route.go b/router/route.go index 9c07a81..c7b3a50 100644 --- a/router/route.go +++ b/router/route.go @@ -61,6 +61,7 @@ func PrepareRouter( customer.GET("/:id/order", apiHandler.CustomerGetOrder) customer.POST("/:id/order", apiHandler.CustomerOrder) customer.POST("/:id/order/find-driver", apiHandler.CustomerFindDriver) + customer.POST("/:id/order/:idOrder/rating", apiHandler.CustomerOrderRating) } /** -- GitLab From b4842bf67abb8109d045c835f143b87b566f6058 Mon Sep 17 00:00:00 2001 From: Hilman Taris Muttaqin Date: Wed, 11 Jan 2023 11:49:45 +0700 Subject: [PATCH 59/62] implement order rating for driver --- domain/handler/api_handler.go | 38 +++++++++++++++++++++++++++++++++++ router/route.go | 1 + 2 files changed, 39 insertions(+) diff --git a/domain/handler/api_handler.go b/domain/handler/api_handler.go index 04e2388..97dc6ce 100644 --- a/domain/handler/api_handler.go +++ b/domain/handler/api_handler.go @@ -373,6 +373,44 @@ func (handler *ApiHandler) CustomerOrder(context *gin.Context) { * membutuhkan token untuk request semua fitur */ +func (handler *ApiHandler) DriverOrderRating(context *gin.Context) { + // get parameter + orderId := context.Param("idOrder") + userId, err := strconv.Atoi(context.Param("id")) + if err != nil { + response.ResponseError(context, http.StatusInternalServerError, err) + return + } + + // get body request + var ratingRequest request.RatingRequest + + err = context.ShouldBindJSON(&ratingRequest) + if err != nil { + HandlerError(context, err) + return + } + + // convert to rating model + ratingModel := model.RatingModel{ + OrderId: orderId, + FromId: userId, + ToId: ratingRequest.To, + Star: ratingRequest.Star, + Feedback: ratingRequest.Feedback, + } + + err = handler.userUsecase.InsertRating(ratingModel) + if err != nil { + response.ResponseError(context, http.StatusInternalServerError, err) + return + } + + response.ResponseSuccess(context, http.StatusOK, gin.H{ + "messge": "Thanks for the rating", + }) +} + func (handler *ApiHandler) DriverOrderDecision(con *gin.Context) { var driverOrderDecision request.DriverOrderDecisionRequest diff --git a/router/route.go b/router/route.go index c7b3a50..2557870 100644 --- a/router/route.go +++ b/router/route.go @@ -79,6 +79,7 @@ func PrepareRouter( driver.POST("/document", apiHandler.DriverPostDocument) driver.PUT("/:id", apiHandler.DriverEditProfile) driver.GET("/:id/order", apiHandler.DriverGetOrder) + driver.POST("/:id/order/:idOrder/rating", apiHandler.DriverOrderRating) driver.GET("/:id/order/income", apiHandler.DriverIncome) driver.POST("/:id/order/decision", apiHandler.DriverOrderDecision) } -- GitLab From cb87defb70c9b2155d082854b3bccc42ea3527bd Mon Sep 17 00:00:00 2001 From: Hilman Taris Muttaqin Date: Wed, 11 Jan 2023 16:02:29 +0700 Subject: [PATCH 60/62] implement fcm for driver order done --- data/request/driver_order_done_request.go | 8 +++++ domain/handler/api_handler.go | 39 +++++++++++++++++++++++ router/route.go | 2 ++ 3 files changed, 49 insertions(+) create mode 100644 data/request/driver_order_done_request.go diff --git a/data/request/driver_order_done_request.go b/data/request/driver_order_done_request.go new file mode 100644 index 0000000..26952ed --- /dev/null +++ b/data/request/driver_order_done_request.go @@ -0,0 +1,8 @@ +package request + +type DriverOrderDoneRequest struct { + RegistrationToken string `json:"registration_token"` + NotificationTitle string `json:"notification_title"` + NotificationDesc string `json:"notification_desc"` + Done string `json:"done"` +} diff --git a/domain/handler/api_handler.go b/domain/handler/api_handler.go index 97dc6ce..609c463 100644 --- a/domain/handler/api_handler.go +++ b/domain/handler/api_handler.go @@ -373,6 +373,45 @@ func (handler *ApiHandler) CustomerOrder(context *gin.Context) { * membutuhkan token untuk request semua fitur */ +func (handler *ApiHandler) DriverOrderDone(con *gin.Context) { + var driverOrderDoneRequest request.DriverOrderDoneRequest + + err := con.ShouldBindJSON(&driverOrderDoneRequest) + if err != nil { + HandlerError(con, err) + return + } + + ctx := context.Background() + service, err := handler.firebaseApp.Messaging(ctx) + if err != nil { + response.ResponseError(con, http.StatusInternalServerError, err) + return + } + + message := messaging.Message{ + Data: map[string]string{ + "done": driverOrderDoneRequest.Done, + }, + Notification: &messaging.Notification{ + Title: driverOrderDoneRequest.NotificationTitle, + Body: driverOrderDoneRequest.NotificationDesc, + }, + Token: driverOrderDoneRequest.RegistrationToken, + } + + res, err := service.Send(ctx, &message) + if err != nil { + response.ResponseError(con, http.StatusInternalServerError, err) + return + } + + response.ResponseSuccess(con, http.StatusOK, gin.H{ + "message": "blbalblba", + "result": res, + }) +} + func (handler *ApiHandler) DriverOrderRating(context *gin.Context) { // get parameter orderId := context.Param("idOrder") diff --git a/router/route.go b/router/route.go index 2557870..8bf9525 100644 --- a/router/route.go +++ b/router/route.go @@ -82,6 +82,8 @@ func PrepareRouter( driver.POST("/:id/order/:idOrder/rating", apiHandler.DriverOrderRating) driver.GET("/:id/order/income", apiHandler.DriverIncome) driver.POST("/:id/order/decision", apiHandler.DriverOrderDecision) + // driver.POST("/:id/order/pickup", apiHandler.DriverPickup) + driver.POST("/:id/order/done", apiHandler.DriverOrderDone) } } -- GitLab From 30736d039d6573b61adce4b6fe9b11435f3a00a6 Mon Sep 17 00:00:00 2001 From: Hilman Taris Muttaqin Date: Thu, 12 Jan 2023 00:34:38 +0700 Subject: [PATCH 61/62] add implementation for post order from driver --- data/request/driver_order_request.go | 6 ++++ data/request/order_request.go | 2 +- domain/handler/api_handler.go | 44 ++++++++++++++++++++++++++++ router/route.go | 1 + 4 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 data/request/driver_order_request.go diff --git a/data/request/driver_order_request.go b/data/request/driver_order_request.go new file mode 100644 index 0000000..be30f2a --- /dev/null +++ b/data/request/driver_order_request.go @@ -0,0 +1,6 @@ +package request + +type DriverOrderRequest struct { + CustomerId int `json:"customer_id"` + OrderRequest +} diff --git a/data/request/order_request.go b/data/request/order_request.go index 860571e..425c4e7 100644 --- a/data/request/order_request.go +++ b/data/request/order_request.go @@ -1,7 +1,7 @@ package request type OrderRequest struct { - DriverId int `json:"driver_id" binding:"required"` + DriverId int `json:"driver_id"` Destination string `json:"destination" binding:"required"` Pickup string `json:"pickup" binding:"required"` Distance int `json:"distance" binding:"required"` diff --git a/domain/handler/api_handler.go b/domain/handler/api_handler.go index 609c463..159b08a 100644 --- a/domain/handler/api_handler.go +++ b/domain/handler/api_handler.go @@ -373,6 +373,50 @@ func (handler *ApiHandler) CustomerOrder(context *gin.Context) { * membutuhkan token untuk request semua fitur */ +func (handler *ApiHandler) DriverOrder(context *gin.Context) { + userId := context.MustGet("userId").(float64) + + var orderRequest request.DriverOrderRequest + err := context.ShouldBindJSON(&orderRequest) + if err != nil { + HandlerError(context, err) + return + } + + orderModel := model.OrderModel{ + OrderId: helper.GetRandomString(10), + CustomerId: orderRequest.CustomerId, + DriverId: int(userId), + Destination: orderRequest.Destination, + Pickup: orderRequest.Pickup, + Distance: orderRequest.Distance, + Duration: orderRequest.Duration, + PaymentType: orderRequest.PaymentType, + Price: orderRequest.Price, + Income: orderRequest.Price, + } + + err = handler.userUsecase.CustomerOrder(orderModel) + if err != nil { + response.ResponseError(context, http.StatusInternalServerError, err) + return + } + + response.ResponseSuccess(context, http.StatusCreated, gin.H{ + "message": "order created", + "order": gin.H{ + "order_id": orderModel.OrderId, + "driver_id": orderModel.DriverId, + "destination": orderModel.Destination, + "pickup_point": orderModel.Pickup, + "distance": orderModel.Distance, + "duration": orderModel.Duration, + "payment_type": orderModel.PaymentType, + "price": orderModel.Price, + }, + }) +} + func (handler *ApiHandler) DriverOrderDone(con *gin.Context) { var driverOrderDoneRequest request.DriverOrderDoneRequest diff --git a/router/route.go b/router/route.go index 8bf9525..5ea3d09 100644 --- a/router/route.go +++ b/router/route.go @@ -78,6 +78,7 @@ func PrepareRouter( driver.DELETE("/vehicle", apiHandler.DeleteVehicle) driver.POST("/document", apiHandler.DriverPostDocument) driver.PUT("/:id", apiHandler.DriverEditProfile) + driver.POST("/:id/order", apiHandler.DriverOrder) driver.GET("/:id/order", apiHandler.DriverGetOrder) driver.POST("/:id/order/:idOrder/rating", apiHandler.DriverOrderRating) driver.GET("/:id/order/income", apiHandler.DriverIncome) -- GitLab From f9999a7392646a03cfb57bf740efcc10b10da40e Mon Sep 17 00:00:00 2001 From: Hilman Taris Muttaqin Date: Fri, 13 Jan 2023 06:46:00 +0700 Subject: [PATCH 62/62] add order data into driver decision --- data/request/driver_order_decision_request.go | 1 + domain/handler/api_handler.go | 1 + 2 files changed, 2 insertions(+) diff --git a/data/request/driver_order_decision_request.go b/data/request/driver_order_decision_request.go index 46faa44..0010ab5 100644 --- a/data/request/driver_order_decision_request.go +++ b/data/request/driver_order_decision_request.go @@ -5,4 +5,5 @@ type DriverOrderDecisionRequest struct { NotificationTitle string `json:"notification_title"` NotificationDesc string `json:"notification_desc"` Decision string `json:"decision"` + Order string `json:"order"` } diff --git a/domain/handler/api_handler.go b/domain/handler/api_handler.go index 159b08a..d09214b 100644 --- a/domain/handler/api_handler.go +++ b/domain/handler/api_handler.go @@ -513,6 +513,7 @@ func (handler *ApiHandler) DriverOrderDecision(con *gin.Context) { message := messaging.Message{ Data: map[string]string{ "decision": driverOrderDecision.Decision, + "order": driverOrderDecision.Order, }, Notification: &messaging.Notification{ Title: driverOrderDecision.NotificationTitle, -- GitLab