155 lines
6.1 KiB
Go
155 lines
6.1 KiB
Go
package service
|
|
|
|
import (
|
|
"context"
|
|
"math"
|
|
|
|
"apskel-pos-be/internal/constants"
|
|
"apskel-pos-be/internal/contract"
|
|
"apskel-pos-be/internal/models"
|
|
"apskel-pos-be/internal/processor"
|
|
"apskel-pos-be/internal/transformer"
|
|
|
|
"github.com/google/uuid"
|
|
)
|
|
|
|
type NotificationService interface {
|
|
Send(ctx context.Context, req *contract.SendNotificationRequest, createdBy uuid.UUID) *contract.Response
|
|
Broadcast(ctx context.Context, req *contract.BroadcastNotificationRequest, organizationID, createdBy uuid.UUID) *contract.Response
|
|
MarkAsRead(ctx context.Context, receiverID, userID uuid.UUID) *contract.Response
|
|
MarkAllAsRead(ctx context.Context, userID uuid.UUID) *contract.Response
|
|
DeleteForUser(ctx context.Context, receiverID, userID uuid.UUID) *contract.Response
|
|
ListForUser(ctx context.Context, req *contract.ListNotificationsRequest, userID uuid.UUID) *contract.Response
|
|
GetByID(ctx context.Context, id uuid.UUID) *contract.Response
|
|
}
|
|
|
|
type NotificationServiceImpl struct {
|
|
notificationProcessor processor.NotificationProcessor
|
|
}
|
|
|
|
func NewNotificationService(notificationProcessor processor.NotificationProcessor) *NotificationServiceImpl {
|
|
return &NotificationServiceImpl{
|
|
notificationProcessor: notificationProcessor,
|
|
}
|
|
}
|
|
|
|
func (s *NotificationServiceImpl) Send(ctx context.Context, req *contract.SendNotificationRequest, createdBy uuid.UUID) *contract.Response {
|
|
modelReq := &models.SendNotificationRequest{
|
|
Title: req.Title,
|
|
Body: req.Body,
|
|
Type: req.Type,
|
|
Category: req.Category,
|
|
Priority: req.Priority,
|
|
ImageURL: req.ImageURL,
|
|
ActionURL: req.ActionURL,
|
|
NotifiableType: req.NotifiableType,
|
|
NotifiableID: req.NotifiableID,
|
|
Data: req.Data,
|
|
ReceiverIDs: req.ReceiverIDs,
|
|
ScheduledAt: req.ScheduledAt,
|
|
ExpiredAt: req.ExpiredAt,
|
|
CreatedBy: &createdBy,
|
|
}
|
|
|
|
resp, err := s.notificationProcessor.Send(ctx, modelReq)
|
|
if err != nil {
|
|
errResp := contract.NewResponseError(constants.InternalServerErrorCode, constants.NotificationServiceEntity, err.Error())
|
|
return contract.BuildErrorResponse([]*contract.ResponseError{errResp})
|
|
}
|
|
|
|
return contract.BuildSuccessResponse(transformer.NotificationModelResponseToContract(resp))
|
|
}
|
|
|
|
func (s *NotificationServiceImpl) Broadcast(ctx context.Context, req *contract.BroadcastNotificationRequest, organizationID, createdBy uuid.UUID) *contract.Response {
|
|
modelReq := &models.BroadcastNotificationRequest{
|
|
Title: req.Title,
|
|
Body: req.Body,
|
|
Type: req.Type,
|
|
Category: req.Category,
|
|
Priority: req.Priority,
|
|
ImageURL: req.ImageURL,
|
|
ActionURL: req.ActionURL,
|
|
NotifiableType: req.NotifiableType,
|
|
NotifiableID: req.NotifiableID,
|
|
Data: req.Data,
|
|
OrganizationID: organizationID,
|
|
ScheduledAt: req.ScheduledAt,
|
|
ExpiredAt: req.ExpiredAt,
|
|
CreatedBy: &createdBy,
|
|
}
|
|
|
|
resp, err := s.notificationProcessor.Broadcast(ctx, modelReq)
|
|
if err != nil {
|
|
errResp := contract.NewResponseError(constants.InternalServerErrorCode, constants.NotificationServiceEntity, err.Error())
|
|
return contract.BuildErrorResponse([]*contract.ResponseError{errResp})
|
|
}
|
|
|
|
return contract.BuildSuccessResponse(transformer.NotificationModelResponseToContract(resp))
|
|
}
|
|
|
|
func (s *NotificationServiceImpl) MarkAsRead(ctx context.Context, receiverID, userID uuid.UUID) *contract.Response {
|
|
resp, err := s.notificationProcessor.MarkAsRead(ctx, receiverID, userID)
|
|
if err != nil {
|
|
errResp := contract.NewResponseError(constants.InternalServerErrorCode, constants.NotificationServiceEntity, err.Error())
|
|
return contract.BuildErrorResponse([]*contract.ResponseError{errResp})
|
|
}
|
|
|
|
return contract.BuildSuccessResponse(transformer.NotificationReceiverModelResponseToContract(resp))
|
|
}
|
|
|
|
func (s *NotificationServiceImpl) MarkAllAsRead(ctx context.Context, userID uuid.UUID) *contract.Response {
|
|
if err := s.notificationProcessor.MarkAllAsRead(ctx, userID); err != nil {
|
|
errResp := contract.NewResponseError(constants.InternalServerErrorCode, constants.NotificationServiceEntity, err.Error())
|
|
return contract.BuildErrorResponse([]*contract.ResponseError{errResp})
|
|
}
|
|
|
|
return contract.BuildSuccessResponse(map[string]interface{}{"message": "All notifications marked as read"})
|
|
}
|
|
|
|
func (s *NotificationServiceImpl) DeleteForUser(ctx context.Context, receiverID, userID uuid.UUID) *contract.Response {
|
|
if err := s.notificationProcessor.DeleteForUser(ctx, receiverID, userID); err != nil {
|
|
errResp := contract.NewResponseError(constants.InternalServerErrorCode, constants.NotificationServiceEntity, err.Error())
|
|
return contract.BuildErrorResponse([]*contract.ResponseError{errResp})
|
|
}
|
|
|
|
return contract.BuildSuccessResponse(map[string]interface{}{"message": "Notification deleted"})
|
|
}
|
|
|
|
func (s *NotificationServiceImpl) ListForUser(ctx context.Context, req *contract.ListNotificationsRequest, userID uuid.UUID) *contract.Response {
|
|
modelReq := &models.ListNotificationsRequest{
|
|
Page: req.Page,
|
|
Limit: req.Limit,
|
|
UserID: userID,
|
|
IsRead: req.IsRead,
|
|
}
|
|
|
|
receivers, total, unreadCount, err := s.notificationProcessor.ListForUser(ctx, modelReq)
|
|
if err != nil {
|
|
errResp := contract.NewResponseError(constants.InternalServerErrorCode, constants.NotificationServiceEntity, err.Error())
|
|
return contract.BuildErrorResponse([]*contract.ResponseError{errResp})
|
|
}
|
|
|
|
totalPages := int(math.Ceil(float64(total) / float64(req.Limit)))
|
|
|
|
response := contract.ListNotificationsResponse{
|
|
Notifications: transformer.NotificationReceiverModelResponsesToContracts(receivers),
|
|
TotalCount: total,
|
|
UnreadCount: unreadCount,
|
|
Page: req.Page,
|
|
Limit: req.Limit,
|
|
TotalPages: totalPages,
|
|
}
|
|
|
|
return contract.BuildSuccessResponse(response)
|
|
}
|
|
|
|
func (s *NotificationServiceImpl) GetByID(ctx context.Context, id uuid.UUID) *contract.Response {
|
|
resp, err := s.notificationProcessor.GetByID(ctx, id)
|
|
if err != nil {
|
|
errResp := contract.NewResponseError(constants.NotFoundErrorCode, constants.NotificationServiceEntity, err.Error())
|
|
return contract.BuildErrorResponse([]*contract.ResponseError{errResp})
|
|
}
|
|
|
|
return contract.BuildSuccessResponse(transformer.NotificationModelResponseToContract(resp))
|
|
}
|