From 2aadeb6458728bb76f3d1dbc51bcc9d40c0f10c9 Mon Sep 17 00:00:00 2001 From: Anan Widianto Date: Tue, 12 Dec 2023 22:53:12 +0700 Subject: [PATCH] feature: order notification fcm --- .github/workflows/main.yml | 2 +- config/config.go | 4 + main.go | 10 +- module/entities/fcm_models.go | 15 +- module/entities/users_models.go | 1 + module/feature/fcm/handler/handler.go | 24 +- module/feature/fcm/interface.go | 3 +- module/feature/fcm/service/service.go | 18 +- module/feature/order/dto/request.go | 20 ++ module/feature/order/service/service.go | 230 ++++++++++++++++-- module/feature/product/handler/handler.go | 2 +- module/feature/users/dto/response.go | 1 + routes/routes.go | 2 +- ...60-firebase-adminsdk-i3rk9-0a642f465e.json | 13 - utils/sendnotif/request.go | 9 + utils/sendnotif/sendnotif.go | 33 ++- 16 files changed, 318 insertions(+), 69 deletions(-) delete mode 100644 utils/sendnotif/contoh-c4760-firebase-adminsdk-i3rk9-0a642f465e.json create mode 100644 utils/sendnotif/request.go diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 572a4e4..73f1ee4 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -40,4 +40,4 @@ jobs: sudo docker stop ${{ secrets.CNAME }} sudo docker rm ${{ secrets.CNAME }} sudo docker rmi ${{ secrets.DOCKERHUB_USERNAME }}/test_disappear - sudo docker run --name ${{ secrets.CNAME }} -p 80:8000 -d -e DBHOST=${{secrets.DBHOST}} -e DBPORT=${{secrets.DBPORT}} -e DBUSER=${{secrets.DBUSER}} -e DBNAME=${{secrets.DBNAME}} -e DBPASS=${{secrets.DBPASS}} -e SECRET=${{secrets.SECRET}} -e SERVER=${{secrets.SERVER}} -e SMTP_PASS=${{secrets.SMTP_PASS}} -e SMTP_USER=${{secrets.SMTP_USER}} -e SMTP_PORT=${{secrets.SMTP_PORT}} -e CCNAME=${{secrets.CCNAME}} -e CCAPIKEY=${{secrets.CCAPIKEY}} -e CCAPISECRET=${{secrets.CCAPISECRET}} -e CCFOLDER=${{secrets.CCFOLDER}} -e OPENAIAPIKEY=${{secrets.OPENAIAPIKEY}} -e MONGOURL=${{secrets.MONGOURL}} -e CLIENTKEY=${{secrets.CLIENTKEY}} -e SERVERKEY=${{secrets.SERVERKEY}} -e REDIS_ADDR=${{secrets.REDIS_ADDR}} -e REDIS_PASS=${{secrets.REDIS_PASS}} -e RESIKEY=${{secrets.RESIKEY}} ${{ secrets.DOCKERHUB_USERNAME }}/test_disappear + sudo docker run --name ${{ secrets.CNAME }} -p 80:8000 -d -e DBHOST=${{secrets.DBHOST}} -e DBPORT=${{secrets.DBPORT}} -e DBUSER=${{secrets.DBUSER}} -e DBNAME=${{secrets.DBNAME}} -e DBPASS=${{secrets.DBPASS}} -e SECRET=${{secrets.SECRET}} -e SERVER=${{secrets.SERVER}} -e SMTP_PASS=${{secrets.SMTP_PASS}} -e SMTP_USER=${{secrets.SMTP_USER}} -e SMTP_PORT=${{secrets.SMTP_PORT}} -e CCNAME=${{secrets.CCNAME}} -e CCAPIKEY=${{secrets.CCAPIKEY}} -e CCAPISECRET=${{secrets.CCAPISECRET}} -e CCFOLDER=${{secrets.CCFOLDER}} -e OPENAIAPIKEY=${{secrets.OPENAIAPIKEY}} -e MONGOURL=${{secrets.MONGOURL}} -e CLIENTKEY=${{secrets.CLIENTKEY}} -e SERVERKEY=${{secrets.SERVERKEY}} -e REDIS_ADDR=${{secrets.REDIS_ADDR}} -e REDIS_PASS=${{secrets.REDIS_PASS}} -e RESIKEY=${{secrets.RESIKEY}} -e FIREBASEKEY=${{secrets.FIREBASEKEY}} ${{ secrets.DOCKERHUB_USERNAME }}/test_disappear diff --git a/config/config.go b/config/config.go index 0e846df..7c20b80 100644 --- a/config/config.go +++ b/config/config.go @@ -26,6 +26,7 @@ type Config struct { ServerKey string Redis Redis ResiKey string + FirebaseKey string } type Redis struct { @@ -116,6 +117,9 @@ func loadConfig() *Config { if value, found := os.LookupEnv("RESIKEY"); found { res.ResiKey = value } + if value, found := os.LookupEnv("FIREBASEKEY"); found { + res.FirebaseKey = value + } return res } diff --git a/main.go b/main.go index 835289b..2e8e7a3 100644 --- a/main.go +++ b/main.go @@ -118,13 +118,17 @@ func main() { reviewService := sReview.NewReviewService(reviewRepo, productService) reviewHandler := hReview.NewReviewHandler(reviewService) + fcmRepo := rFcm.NewFcmRepository(db) + fcmService := sFcm.NewFcmService(fcmRepo) + fcmHandler := hFcm.NewFcmHandler(fcmService) + cartRepo := rCart.NewCartRepository(db) cartService := sCart.NewCartService(cartRepo, productService) cartHandler := hCart.NewCartHandler(cartService) orderRepo := rOrder.NewOrderRepository(db, coreApi) orderService := sOrder.NewOrderService(orderRepo, generatorID, productService, - voucherService, addressService, userService, cartService) + voucherService, addressService, userService, cartService, fcmService) orderHandler := hOrder.NewOrderHandler(orderService) mgodb := database.InitMongoDB(*initConfig) @@ -141,10 +145,6 @@ func main() { homeService := sHome.NewHomepageService(homeRepo) homeHandler := hHome.NewHomepageHandler(homeService) - fcmRepo := rFcm.NewFcmRepository(db) - fcmService := sFcm.NewFcmService(fcmRepo) - fcmHandler := hFcm.NewFcmHandler(fcmService) - e.Pre(middleware.RemoveTrailingSlash()) e.Use(middleware.CORSWithConfig(middleware.CORSConfig{ AllowOrigins: []string{"*"}, diff --git a/module/entities/fcm_models.go b/module/entities/fcm_models.go index 54f9203..ecc1eac 100644 --- a/module/entities/fcm_models.go +++ b/module/entities/fcm_models.go @@ -3,12 +3,15 @@ package entities import "time" type FcmModels struct { - ID uint64 `gorm:"column:id;type:BIGINT UNSIGNED;primaryKey" json:"id"` - UserID uint64 `gorm:"column:user_id;type:BIGINT UNSIGNED" json:"user_id"` - Title string `gorm:"column:title;type:varchar(255)" json:"title"` - Body string `gorm:"column:body;type:text" json:"body"` - CreatedAt time.Time `gorm:"column:created_at;type:timestamp DEFAULT CURRENT_TIMESTAMP" json:"created_at"` - DeletedAt *time.Time `gorm:"column:deleted_at;type:TIMESTAMP NULL;index" json:"deleted_at"` + ID uint64 `gorm:"column:id;type:BIGINT UNSIGNED;primaryKey" json:"id"` + OrderID string `gorm:"column:order_id;type:VARCHAR(255)" json:"order_id"` + UserID uint64 `gorm:"column:user_id;type:BIGINT UNSIGNED" json:"user_id"` + Title string `gorm:"column:title;type:varchar(255)" json:"title"` + Body string `gorm:"column:body;type:text" json:"body"` + CreatedAt time.Time `gorm:"column:created_at;type:timestamp DEFAULT CURRENT_TIMESTAMP" json:"created_at"` + DeletedAt *time.Time `gorm:"column:deleted_at;type:TIMESTAMP NULL;index" json:"deleted_at"` + User UserModels `gorm:"foreignKey:UserID" json:"user"` + Order OrderModels `gorm:"foreignKey:OrderID" json:"order"` } func (FcmModels) TableName() string { diff --git a/module/entities/users_models.go b/module/entities/users_models.go index e050634..c6bba0a 100644 --- a/module/entities/users_models.go +++ b/module/entities/users_models.go @@ -19,6 +19,7 @@ type UserModels struct { IsVerified bool `gorm:"column:is_verified;default:false" json:"is_verified"` LastLogin time.Time `gorm:"column:last_login;type:timestamp;default:CURRENT_TIMESTAMP" json:"last_login"` PreferredTopics string `gorm:"column:preferred_topics;type:TEXT" json:"preferred_topics"` + DeviceToken string `gorm:"column:device_token;type:VARCHAR(255)" json:"device_token"` CreatedAt time.Time `gorm:"column:created_at;type:timestamp DEFAULT CURRENT_TIMESTAMP" json:"created_at"` UpdatedAt time.Time `gorm:"column:updated_at;type:timestamp DEFAULT CURRENT_TIMESTAMP" json:"updated_at"` DeletedAt *time.Time `gorm:"column:deleted_at;type:TIMESTAMP NULL;index" json:"deleted_at"` diff --git a/module/feature/fcm/handler/handler.go b/module/feature/fcm/handler/handler.go index b8fcd3c..44f27cf 100644 --- a/module/feature/fcm/handler/handler.go +++ b/module/feature/fcm/handler/handler.go @@ -1,6 +1,7 @@ package handler import ( + "github.com/capstone-kelompok-7/backend-disappear/utils/sendnotif" "strconv" "github.com/capstone-kelompok-7/backend-disappear/module/entities" @@ -32,30 +33,31 @@ func (h *FcmHandler) CreateFcm() echo.HandlerFunc { return response.SendBadRequestResponse(c, "Validasi gagal: "+err.Error()) } - newFcm := &entities.FcmModels{ + createFcmRequest := sendnotif.SendNotificationRequest{ UserID: fcmRequest.UserID, Title: fcmRequest.Title, Body: fcmRequest.Body, + Token: fcmRequest.Token, } - - res, statusFcm, err := h.service.CreateFcm(newFcm, fcmRequest.Token) + res, statusFcm, err := h.service.CreateFcm(createFcmRequest) if err != nil { - return response.SendStatusInternalServerResponse(c, "Gagal mengirim noifikasi: "+err.Error()) + return response.SendStatusInternalServerResponse(c, "Gagal mengirim notifikasi: "+err.Error()) } - return response.SendStatusCreatedResponse(c, "Berhasil mengirim noifikasi", dto.FormatFcmCreate(res, statusFcm, fcmRequest.Token)) - + return response.SendStatusCreatedResponse(c, "Berhasil mengirim notifikasi", dto.FormatFcmCreate(res, statusFcm, fcmRequest.Token)) } } + func (h *FcmHandler) GetFcmByIdUser() echo.HandlerFunc { return func(c echo.Context) error { + currentUser := c.Get("CurrentUser").(*entities.UserModels) + if currentUser.Role != "customer" { + return response.SendStatusForbiddenResponse(c, "Tidak diizinkan: Anda tidak memiliki izin") + } var fcm []*entities.FcmModels var err error - - idUser := c.Param("id") - idUserConf, _ := strconv.Atoi(idUser) - - fcm, err = h.service.GetFcmByIdUser(uint64(idUserConf)) + + fcm, err = h.service.GetFcmByIdUser(currentUser.ID) if err != nil { return response.SendStatusInternalServerResponse(c, "Gagal mendapatkan daftar notifikasi by iduser: "+err.Error()) } diff --git a/module/feature/fcm/interface.go b/module/feature/fcm/interface.go index 304cb8a..48ee79c 100644 --- a/module/feature/fcm/interface.go +++ b/module/feature/fcm/interface.go @@ -2,6 +2,7 @@ package fcm import ( "github.com/capstone-kelompok-7/backend-disappear/module/entities" + "github.com/capstone-kelompok-7/backend-disappear/utils/sendnotif" "github.com/labstack/echo/v4" ) @@ -12,7 +13,7 @@ type RepositoryFcmInterface interface { DeleteFcmById(id uint64) error } type ServiceFcmInterface interface { - CreateFcm(fcm *entities.FcmModels, token string) (*entities.FcmModels, string, error) + CreateFcm(request sendnotif.SendNotificationRequest) (*entities.FcmModels, string, error) GetFcmByIdUser(id uint64) ([]*entities.FcmModels, error) GetFcmById(id uint64) (*entities.FcmModels, error) DeleteFcmById(id uint64) error diff --git a/module/feature/fcm/service/service.go b/module/feature/fcm/service/service.go index 0e29008..1f20d25 100644 --- a/module/feature/fcm/service/service.go +++ b/module/feature/fcm/service/service.go @@ -19,28 +19,28 @@ func NewFcmService(repo fcm.RepositoryFcmInterface) fcm.ServiceFcmInterface { } } -func (s *FcmService) CreateFcm(fcm *entities.FcmModels, token string) (*entities.FcmModels, string, error) { +func (s *FcmService) CreateFcm(request sendnotif.SendNotificationRequest) (*entities.FcmModels, string, error) { value := &entities.FcmModels{ - UserID: fcm.UserID, - Title: fcm.Title, - Body: fcm.Body, + OrderID: request.OrderID, + UserID: request.UserID, + Title: request.Title, + Body: request.Body, } var err error var response *entities.FcmModels - var sendsuccess string + var sendSuccess string - sendsuccess, err = sendnotif.SendNotification(fcm.Title, fcm.Body, token) + sendSuccess, err = sendnotif.SendNotification(request) if err == nil { response, err = s.repo.CreateFcm(value) if err != nil { logrus.Error("gagal membuat notification ke database") } - } else if err != nil { + } else { logrus.Error("gagal mengirim notification") } - return response, sendsuccess, nil - + return response, sendSuccess, err } func (s *FcmService) GetFcmByIdUser(id uint64) ([]*entities.FcmModels, error) { diff --git a/module/feature/order/dto/request.go b/module/feature/order/dto/request.go index aba4601..21e54cd 100644 --- a/module/feature/order/dto/request.go +++ b/module/feature/order/dto/request.go @@ -39,3 +39,23 @@ type UpdateOrderStatus struct { OrderStatus string `json:"order_status"` ExtraInfo string `json:"extra_info"` } + +type SendNotificationPaymentRequest struct { + PaymentStatus string `json:"payment_status"` + OrderID string `json:"order_id"` + UserID uint64 `json:"user_id"` + UserName string `json:"user_name"` + Title string `json:"title"` + Body string `json:"body"` + Token string `json:"token"` +} + +type SendNotificationOrderRequest struct { + OrderStatus string `json:"order_status"` + OrderID string `json:"order_id"` + UserID uint64 `json:"user_id"` + UserName string `json:"user_name"` + Title string `json:"title"` + Body string `json:"body"` + Token string `json:"token"` +} diff --git a/module/feature/order/service/service.go b/module/feature/order/service/service.go index a85e0be..21486ac 100644 --- a/module/feature/order/service/service.go +++ b/module/feature/order/service/service.go @@ -2,15 +2,19 @@ package service import ( "errors" + "fmt" "github.com/capstone-kelompok-7/backend-disappear/module/entities" "github.com/capstone-kelompok-7/backend-disappear/module/feature/address" "github.com/capstone-kelompok-7/backend-disappear/module/feature/cart" + "github.com/capstone-kelompok-7/backend-disappear/module/feature/fcm" "github.com/capstone-kelompok-7/backend-disappear/module/feature/order" "github.com/capstone-kelompok-7/backend-disappear/module/feature/order/dto" "github.com/capstone-kelompok-7/backend-disappear/module/feature/product" "github.com/capstone-kelompok-7/backend-disappear/module/feature/users" "github.com/capstone-kelompok-7/backend-disappear/module/feature/voucher" "github.com/capstone-kelompok-7/backend-disappear/utils" + "github.com/capstone-kelompok-7/backend-disappear/utils/sendnotif" + "github.com/sirupsen/logrus" "math" "time" ) @@ -23,6 +27,7 @@ type OrderService struct { addressService address.ServiceAddressInterface userService users.ServiceUserInterface cartService cart.ServiceCartInterface + fcmService fcm.ServiceFcmInterface } func NewOrderService( @@ -33,6 +38,7 @@ func NewOrderService( addressService address.ServiceAddressInterface, userService users.ServiceUserInterface, cartService cart.ServiceCartInterface, + fcmService fcm.ServiceFcmInterface, ) order.ServiceOrderInterface { return &OrderService{ repo: repo, @@ -42,6 +48,7 @@ func NewOrderService( addressService: addressService, userService: userService, cartService: cartService, + fcmService: fcmService, } } @@ -198,7 +205,7 @@ func (s *OrderService) CreateOrder(userID uint64, request *dto.CreateOrderReques } grandTotalPrice := totalPrice - totalAmountPaid := grandTotalPrice + 2000 + 24000 - discountFromVoucher + totalAmountPaid := grandTotalPrice + 2000 + 0 - discountFromVoucher newData := &entities.OrderModels{ ID: orderID, @@ -211,7 +218,7 @@ func (s *OrderService) CreateOrder(userID uint64, request *dto.CreateOrderReques GrandTotalExp: totalExp, GrandTotalQuantity: totalQuantity, GrandTotalPrice: grandTotalPrice, - ShipmentFee: 24000, + ShipmentFee: 0, AdminFees: 2000, GrandTotalDiscount: totalDiscount, TotalAmountPaid: totalAmountPaid, @@ -233,6 +240,23 @@ func (s *OrderService) CreateOrder(userID uint64, request *dto.CreateOrderReques } } + user, err := s.userService.GetUsersById(createdOrder.UserID) + if err != nil { + return nil, errors.New("pengguna tidak ditemukan") + } + + notificationRequest := dto.SendNotificationPaymentRequest{ + OrderID: createdOrder.ID, + UserID: createdOrder.UserID, + PaymentStatus: "Menunggu Konfirmasi", + Token: user.DeviceToken, + } + _, err = s.SendNotificationPayment(notificationRequest) + if err != nil { + logrus.Error("Gagal mengirim notifikasi: ", err) + return nil, err + } + switch request.PaymentMethod { case "whatsapp", "telegram": return s.processManualPayment(orderID) @@ -340,7 +364,7 @@ func (s *OrderService) CreateOrderFromCart(userID uint64, request *dto.CreateOrd } grandTotalPrice := totalPrice - totalAmountPaid := grandTotalPrice + 2000 + 24000 - discountFromVoucher + totalAmountPaid := grandTotalPrice + 2000 + 0 - discountFromVoucher newData := &entities.OrderModels{ ID: orderID, @@ -353,7 +377,7 @@ func (s *OrderService) CreateOrderFromCart(userID uint64, request *dto.CreateOrd GrandTotalExp: totalExp, GrandTotalQuantity: totalQuantity, GrandTotalPrice: grandTotalPrice, - ShipmentFee: 24000, + ShipmentFee: 0, AdminFees: 2000, GrandTotalDiscount: totalDiscount, TotalAmountPaid: totalAmountPaid, @@ -375,6 +399,22 @@ func (s *OrderService) CreateOrderFromCart(userID uint64, request *dto.CreateOrd return nil, err } } + user, err := s.userService.GetUsersById(createdOrder.UserID) + if err != nil { + return nil, errors.New("pengguna tidak ditemukan") + } + + notificationRequest := dto.SendNotificationPaymentRequest{ + OrderID: createdOrder.ID, + UserID: createdOrder.UserID, + PaymentStatus: "Menunggu Konfirmasi", + Token: user.DeviceToken, + } + _, err = s.SendNotificationPayment(notificationRequest) + if err != nil { + logrus.Error("Gagal mengirim notifikasi: ", err) + return nil, err + } switch request.PaymentMethod { case "whatsapp", "telegram": @@ -402,29 +442,28 @@ func (s *OrderService) processGatewayPayment(totalAmountPaid uint64, orderID str return result, nil } -func (s *OrderService) CallBack(notifPayload map[string]any) error { +func (s *OrderService) CallBack(notifPayload map[string]interface{}) error { orderID, exist := notifPayload["order_id"].(string) if !exist { return errors.New("invalid notification payload") } + status, err := s.repo.CheckTransaction(orderID) if err != nil { return err } + transaction, err := s.repo.GetOrderById(orderID) if err != nil { return errors.New("transaction data not found") } - if err := s.repo.ConfirmPayment(transaction.ID, status.OrderStatus, status.PaymentStatus); err != nil { - return err - } user, err := s.userService.GetUsersById(transaction.UserID) if err != nil { return errors.New("pengguna tidak ditemukan") } - if status.OrderStatus != "Gagal" { + if status.PaymentStatus == "Konfirmasi" { user.Exp += transaction.GrandTotalExp if _, err := s.userService.UpdateUserExp(user.ID, user.Exp); err != nil { return err @@ -434,17 +473,41 @@ func (s *OrderService) CallBack(notifPayload map[string]any) error { if _, err := s.userService.UpdateUserContribution(user.ID, user.TotalGram); err != nil { return err } - } else { - orders, err := s.repo.GetOrderById(orderID) + + notificationRequest := dto.SendNotificationPaymentRequest{ + OrderID: orderID, + UserID: user.ID, + PaymentStatus: "Konfirmasi", + Token: user.DeviceToken, + } + + _, err = s.SendNotificationPayment(notificationRequest) if err != nil { - return errors.New("failed to retrieve order details") + logrus.Error("Gagal mengirim notifikasi: ", err) + return err } - for _, orderDetail := range orders.OrderDetails { + } else if status.PaymentStatus == "Gagal" { + + for _, orderDetail := range transaction.OrderDetails { if err := s.productService.IncreaseStock(orderDetail.ProductID, orderDetail.Quantity); err != nil { return errors.New("failed to increase product stock") } } + + notificationRequest := dto.SendNotificationPaymentRequest{ + OrderID: orderID, + UserID: user.ID, + PaymentStatus: "Gagal", + Token: user.DeviceToken, + } + + _, err = s.SendNotificationPayment(notificationRequest) + if err != nil { + logrus.Error("Gagal mengirim notifikasi: ", err) + return err + } } + return nil } @@ -476,6 +539,18 @@ func (s *OrderService) ConfirmPayment(orderID string) error { return err } + notificationRequest := dto.SendNotificationPaymentRequest{ + OrderID: orderID, + UserID: user.ID, + PaymentStatus: "Konfirmasi", + Token: user.DeviceToken, + } + _, err = s.SendNotificationPayment(notificationRequest) + if err != nil { + logrus.Error("Gagal mengirim notifikasi: ", err) + return err + } + return nil } @@ -498,11 +573,28 @@ func (s *OrderService) CancelPayment(orderID string) error { return errors.New("gagal membatalkan pesanan") } + user, err := s.userService.GetUsersById(orders.UserID) + if err != nil { + return errors.New("pengguna tidak ditemukan") + } + + notificationRequest := dto.SendNotificationPaymentRequest{ + OrderID: orderID, + UserID: user.ID, + PaymentStatus: "Gagal", + Token: user.DeviceToken, + } + _, err = s.SendNotificationPayment(notificationRequest) + if err != nil { + logrus.Error("Gagal mengirim notifikasi: ", err) + return err + } + return nil } func (s *OrderService) UpdateOrderStatus(req *dto.UpdateOrderStatus) error { - _, err := s.repo.GetOrderById(req.OrderID) + orders, err := s.repo.GetOrderById(req.OrderID) if err != nil { return errors.New("pesanan tidak ditemukan") } @@ -510,6 +602,21 @@ func (s *OrderService) UpdateOrderStatus(req *dto.UpdateOrderStatus) error { if err := s.repo.UpdateOrderStatus(req); err != nil { return err } + user, err := s.userService.GetUsersById(orders.UserID) + if err != nil { + return errors.New("pengguna tidak ditemukan") + } + notificationRequest := dto.SendNotificationOrderRequest{ + OrderID: orders.ID, + UserID: user.ID, + OrderStatus: "Pengiriman", + Token: user.DeviceToken, + } + _, err = s.SendNotificationOrder(notificationRequest) + if err != nil { + logrus.Error("Gagal mengirim notifikasi: ", err) + return err + } return nil } @@ -549,6 +656,23 @@ func (s *OrderService) AcceptOrder(orderID string) error { return err } + user, err := s.userService.GetUsersById(orders.UserID) + if err != nil { + return errors.New("pengguna tidak ditemukan") + } + + notificationRequest := dto.SendNotificationOrderRequest{ + OrderID: orders.ID, + UserID: user.ID, + OrderStatus: "Selesai", + Token: user.DeviceToken, + } + _, err = s.SendNotificationOrder(notificationRequest) + if err != nil { + logrus.Error("Gagal mengirim notifikasi: ", err) + return err + } + return nil } @@ -840,3 +964,81 @@ func (s *OrderService) GetOrdersBySearchAndPaymentStatus(status, search string, return result, totalItems, nil } + +func (s *OrderService) SendNotificationPayment(request dto.SendNotificationPaymentRequest) (string, error) { + var notificationMsg string + var err error + + user, err := s.userService.GetUsersById(request.UserID) + if err != nil { + return "", err + } + orders, err := s.repo.GetOrderById(request.OrderID) + if err != nil { + return "", err + } + + switch request.PaymentStatus { + case "Menunggu Konfirmasi": + notificationMsg = fmt.Sprintf("Alloo, %s! Pesananmu dengan ID %s udah berhasil dibuat, nih. Ditunggu yupp!!", user.Name, orders.IdOrder) + case "Konfirmasi": + notificationMsg = fmt.Sprintf("Thengkyuu, %s! Pembayaran untuk pesananmu dengan ID %s udah kami terima, nih. Semoga harimu menyenangkan!", user.Name, orders.IdOrder) + case "Gagal": + notificationMsg = fmt.Sprintf("Maaf, %s. Pembayaran untuk pesanan dengan ID %s gagal, nih. Beritahu kami apabila kamu butuh bantuan yaa!!", user.Name, orders.IdOrder) + default: + return "", errors.New("Status pesanan tidak valid") + } + + notificationRequest := sendnotif.SendNotificationRequest{ + OrderID: request.OrderID, + UserID: request.UserID, + Title: "Status Pembayaran", + Body: notificationMsg, + Token: user.DeviceToken, + } + _, _, err = s.fcmService.CreateFcm(notificationRequest) + if err != nil { + logrus.Error("Gagal mengirim notifikasi: ", err) + return "", err + } + + return notificationMsg, nil +} + +func (s *OrderService) SendNotificationOrder(request dto.SendNotificationOrderRequest) (string, error) { + var notificationMsg string + var err error + + user, err := s.userService.GetUsersById(request.UserID) + if err != nil { + return "", err + } + orders, err := s.repo.GetOrderById(request.OrderID) + if err != nil { + return "", err + } + + switch request.OrderStatus { + case "Pengiriman": + notificationMsg = fmt.Sprintf("Alloo, %s! Pesanan dengan ID %s udah dalam proses pengiriman, nih. Mohon ditunggu yupp!", user.Name, orders.IdOrder) + case "Selesai": + notificationMsg = fmt.Sprintf("Yeayy, %s! Pesananmu dengan ID %s udah sampai tujuan, nih. Semoga sukakk yupp!", user.Name, orders.IdOrder) + default: + return "", errors.New("Status pengiriman tidak valid") + } + + notificationRequest := sendnotif.SendNotificationRequest{ + OrderID: request.OrderID, + UserID: request.UserID, + Title: "Status Pengiriman", + Body: notificationMsg, + Token: user.DeviceToken, + } + _, _, err = s.fcmService.CreateFcm(notificationRequest) + if err != nil { + logrus.Error("Gagal mengirim notifikasi: ", err) + return "", err + } + + return notificationMsg, nil +} diff --git a/module/feature/product/handler/handler.go b/module/feature/product/handler/handler.go index e151207..0934256 100644 --- a/module/feature/product/handler/handler.go +++ b/module/feature/product/handler/handler.go @@ -297,6 +297,6 @@ func (h *ProductHandler) GetTopRatedProducts() echo.HandlerFunc { if err != nil { return response.SendStatusInternalServerResponse(c, "Gagal mendapatkan detail produk: "+err.Error()) } - return response.SendSuccessResponse(c, "Berhasil mendapatkan detail produk", dto.FormatterOtherProduct(result)) + return response.SendSuccessResponse(c, "Berhasil mendapatkan produk lainnya", dto.FormatterOtherProduct(result)) } } diff --git a/module/feature/users/dto/response.go b/module/feature/users/dto/response.go index d5ef04e..8ac53f0 100644 --- a/module/feature/users/dto/response.go +++ b/module/feature/users/dto/response.go @@ -176,6 +176,7 @@ func FormatUserProfileResponse(user *entities.UserModels) *UserProfileResponse { ID: user.ID, Email: user.Email, Name: user.Name, + Phone: user.Phone, PhotoProfile: user.PhotoProfile, TotalGram: user.TotalGram, TotalChallenge: user.TotalChallenge, diff --git a/routes/routes.go b/routes/routes.go index d418b1e..73983ad 100644 --- a/routes/routes.go +++ b/routes/routes.go @@ -189,7 +189,7 @@ func RouteHomepage(e *echo.Echo, h homepage.HandlerHomepageInterface, jwtService func RouteFcm(e *echo.Echo, h fcm.HandlerFcmInterface, jwtService utils.JWTInterface, userService users.ServiceUserInterface) { fcmGroup := e.Group("/api/v1/fcm") fcmGroup.GET("/:id", h.GetFcmById(), middlewares.AuthMiddleware(jwtService, userService)) - fcmGroup.GET("/iduser/:id", h.GetFcmByIdUser(), middlewares.AuthMiddleware(jwtService, userService)) + fcmGroup.GET("/users", h.GetFcmByIdUser(), middlewares.AuthMiddleware(jwtService, userService)) fcmGroup.POST("", h.CreateFcm(), middlewares.AuthMiddleware(jwtService, userService)) fcmGroup.PUT("/:id", h.DeleteFcmById(), middlewares.AuthMiddleware(jwtService, userService)) } diff --git a/utils/sendnotif/contoh-c4760-firebase-adminsdk-i3rk9-0a642f465e.json b/utils/sendnotif/contoh-c4760-firebase-adminsdk-i3rk9-0a642f465e.json deleted file mode 100644 index 5762ec3..0000000 --- a/utils/sendnotif/contoh-c4760-firebase-adminsdk-i3rk9-0a642f465e.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "type": "service_account", - "project_id": "contoh-c4760", - "private_key_id": "0a642f465eb231a2bc31e520187b7d68aaf9f430", - "private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQC3EYfO0We02Ieg\n+kP7AkSNQJvYmXlYaIWXGIHXu/pLoHGxvKSIpU01/AsJS7Oy8quEOnmVUqyRsGsr\n3fdUOcISuY76gAHsXZvEd6nKN2FTYzARuBmo2a52DCjvHRgD00X7qH7oab0pCcCf\nGOniHHX+Y8+D9TXvviPdPGGnPgskSNDN77ffFVrEwR5MYINSVa9gruVS0NoDSaDR\noC1ORV/SCC77CDKObM6TXPsdU3noa0QZAPL+R/BPDIVQrey0LPDz4j773Q61agGF\ndIWnhURZids401kbYmUyNyj9Yz/ucMIhQ7YJZlOVOzFWEqLUH1dcjqydrtVkyfIN\ncZtAqv53AgMBAAECggEACn3qtqOxud+fBk7RjpU2sJG/XM6O8c4rudkht+eCFMuB\nOJqDI4G1xx5G06WPCvZ1dgKT7UbrtP3TZpQ2FJGq2b/gveKQOaezwbLJ/FjoLwtE\nOf+/GLpBEWro/atBMRbur9mcTF2jBbMVYwjefqL68DVwMzPef3r6Oze2sQsRQGcC\n8BLPctL5x8aupVxSiQHeBwzgQP4YMRhQ2UJJ0uUrMvkivKfoBTs09iv1UUmdufbM\net7XSv1QSG1n895Edxg8VKRxrs3ZpuAXMYtLAmV9qwRWRaQVTxRTavjlw3A/7LFq\nj8Vd4/ntVqqd7qjzogcYy1fwBsAuLuv8axeipk90oQKBgQD0yKB2WAPYbvsqTU27\nVKMiiORW4qqD8WQDtdX8H18saPp9ooAaxFPhf6zo0xTbIqO7Cn3QKOfKj3uGE2R/\nFWYert+l5IgoY/jYwdIM9iExYN05zQ48nIFUW8XoJmCPpDtap7Ttpb6P5JWKIFj3\nty6rI//7OegBy4cCylxUv47fPQKBgQC/dPgL+wsyihY2ybVGrG0YXgAKFb+/Fn8+\nq8wpvdOE6s2CDwOMZdJwHkH2q1+s+lx/Zp5AbOqxfTO7RH8dGfU1LLF34ae/jh6v\nD0GmYTQWNVWS1jU757r/+3+nDawJGmgqDVQN0YmveZQp/Ea8FfA1MA5TsbwhXAtc\n7Bw+vPHvwwKBgQCNXDtGfKej2tuTX1cvgr4/GFz9TCL61XFTrzPnSNq2k91spmZi\njtR+GjRptFSMBGIXhwSHLMhHMzs7f4F+3oW93HFtpR94a9tumefK8mzSzkSTt7as\nDBmn9OPCoD8NVOOuA8G5qAj3oiM1xF58l74MuVp/4733I2lRlDlj+8fvZQKBgQCl\n0a/X6IktL43Hy/F2EXa3aQqNsYKOBPUWGYNND7y33Qk6wLgpDDMzqfElrA3Eal5c\ndUtQr0ShjreUVOHnGYlXkarvEoDQFk4a/pK0gHG1XmIMN/yJMs2yUWehDuVWSQm4\niiynfzjJwvoBVx8IXdParRFriX9QQUESLOjVqZ29MwKBgQCa+WE8fgoYOcplC53W\nx72xFhn/uSaVRw1EATCB/zzB6FZ8IrzMQJdfegPWn0CxOdYkL268cClQA9bn1B6s\nQfxKKuiXPYWdvgBJrdi8cYsjGrz8P0Mcbrj9N5lLRbYMmMLr9lFrPslWDJb6eoiV\nMDCVMv+wa/nOlc5fDghV/01Ckg==\n-----END PRIVATE KEY-----\n", - "client_email": "firebase-adminsdk-i3rk9@contoh-c4760.iam.gserviceaccount.com", - "client_id": "111421688796917578049", - "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-i3rk9%40contoh-c4760.iam.gserviceaccount.com", - "universe_domain": "googleapis.com" -} diff --git a/utils/sendnotif/request.go b/utils/sendnotif/request.go new file mode 100644 index 0000000..8e1498d --- /dev/null +++ b/utils/sendnotif/request.go @@ -0,0 +1,9 @@ +package sendnotif + +type SendNotificationRequest struct { + OrderID string `json:"order_id"` + UserID uint64 `json:"user_id"` + Title string `json:"title"` + Body string `json:"body"` + Token string `json:"token"` +} diff --git a/utils/sendnotif/sendnotif.go b/utils/sendnotif/sendnotif.go index cec89ce..5871ce0 100644 --- a/utils/sendnotif/sendnotif.go +++ b/utils/sendnotif/sendnotif.go @@ -2,16 +2,34 @@ package sendnotif import ( "context" - + "encoding/base64" firebase "firebase.google.com/go" "firebase.google.com/go/messaging" + "github.com/capstone-kelompok-7/backend-disappear/config" "github.com/sirupsen/logrus" "google.golang.org/api/option" ) -func SendNotification(title string, body string, token string) (string, error) { - opt := option.WithCredentialsFile("contoh-c4760-firebase-adminsdk-i3rk9-0a642f465e.json") - app, err := firebase.NewApp(context.Background(), nil, opt) +func getDecodedFireBaseKey() ([]byte, error) { + fireBaseAuthKey := config.InitConfig().FirebaseKey + decodedKey, err := base64.StdEncoding.DecodeString(fireBaseAuthKey) + if err != nil { + return nil, err + } + + return decodedKey, nil +} + +func SendNotification(request SendNotificationRequest) (string, error) { + decodedKey, err := getDecodedFireBaseKey() + + if err != nil { + return "", err + } + + opt := []option.ClientOption{option.WithCredentialsJSON(decodedKey)} + + app, err := firebase.NewApp(context.Background(), nil, opt...) if err != nil { logrus.Error("Error initializing Firebase app", err) } @@ -23,10 +41,11 @@ func SendNotification(title string, body string, token string) (string, error) { message := &messaging.Message{ Data: map[string]string{ - "title": title, - "body": body, + "order_id": request.OrderID, + "title": request.Title, + "body": request.Body, }, - Token: token, + Token: request.Token, } response, err := client.Send(context.Background(), message)