init
This commit is contained in:
@@ -0,0 +1,243 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"apskel-pos-be/internal/models"
|
||||
"apskel-pos-be/internal/processor"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
type AnalyticsService interface {
|
||||
GetPaymentMethodAnalytics(ctx context.Context, req *models.PaymentMethodAnalyticsRequest) (*models.PaymentMethodAnalyticsResponse, error)
|
||||
GetSalesAnalytics(ctx context.Context, req *models.SalesAnalyticsRequest) (*models.SalesAnalyticsResponse, error)
|
||||
GetProductAnalytics(ctx context.Context, req *models.ProductAnalyticsRequest) (*models.ProductAnalyticsResponse, error)
|
||||
GetDashboardAnalytics(ctx context.Context, req *models.DashboardAnalyticsRequest) (*models.DashboardAnalyticsResponse, error)
|
||||
GetProfitLossAnalytics(ctx context.Context, req *models.ProfitLossAnalyticsRequest) (*models.ProfitLossAnalyticsResponse, error)
|
||||
}
|
||||
|
||||
type AnalyticsServiceImpl struct {
|
||||
analyticsProcessor processor.AnalyticsProcessor
|
||||
}
|
||||
|
||||
func NewAnalyticsServiceImpl(analyticsProcessor processor.AnalyticsProcessor) *AnalyticsServiceImpl {
|
||||
return &AnalyticsServiceImpl{
|
||||
analyticsProcessor: analyticsProcessor,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *AnalyticsServiceImpl) GetPaymentMethodAnalytics(ctx context.Context, req *models.PaymentMethodAnalyticsRequest) (*models.PaymentMethodAnalyticsResponse, error) {
|
||||
// Validate request
|
||||
if err := s.validatePaymentMethodAnalyticsRequest(req); err != nil {
|
||||
return nil, fmt.Errorf("validation error: %w", err)
|
||||
}
|
||||
|
||||
// Process analytics request
|
||||
response, err := s.analyticsProcessor.GetPaymentMethodAnalytics(ctx, req)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get payment method analytics: %w", err)
|
||||
}
|
||||
|
||||
return response, nil
|
||||
}
|
||||
|
||||
func (s *AnalyticsServiceImpl) GetSalesAnalytics(ctx context.Context, req *models.SalesAnalyticsRequest) (*models.SalesAnalyticsResponse, error) {
|
||||
// Validate request
|
||||
if err := s.validateSalesAnalyticsRequest(req); err != nil {
|
||||
return nil, fmt.Errorf("validation error: %w", err)
|
||||
}
|
||||
|
||||
// Process analytics request
|
||||
response, err := s.analyticsProcessor.GetSalesAnalytics(ctx, req)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get sales analytics: %w", err)
|
||||
}
|
||||
|
||||
return response, nil
|
||||
}
|
||||
|
||||
func (s *AnalyticsServiceImpl) GetProductAnalytics(ctx context.Context, req *models.ProductAnalyticsRequest) (*models.ProductAnalyticsResponse, error) {
|
||||
// Validate request
|
||||
if err := s.validateProductAnalyticsRequest(req); err != nil {
|
||||
return nil, fmt.Errorf("validation error: %w", err)
|
||||
}
|
||||
|
||||
// Process analytics request
|
||||
response, err := s.analyticsProcessor.GetProductAnalytics(ctx, req)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get product analytics: %w", err)
|
||||
}
|
||||
|
||||
return response, nil
|
||||
}
|
||||
|
||||
func (s *AnalyticsServiceImpl) GetDashboardAnalytics(ctx context.Context, req *models.DashboardAnalyticsRequest) (*models.DashboardAnalyticsResponse, error) {
|
||||
// Validate request
|
||||
if err := s.validateDashboardAnalyticsRequest(req); err != nil {
|
||||
return nil, fmt.Errorf("validation error: %w", err)
|
||||
}
|
||||
|
||||
// Process analytics request
|
||||
response, err := s.analyticsProcessor.GetDashboardAnalytics(ctx, req)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get dashboard analytics: %w", err)
|
||||
}
|
||||
|
||||
return response, nil
|
||||
}
|
||||
|
||||
// Validation methods
|
||||
func (s *AnalyticsServiceImpl) validatePaymentMethodAnalyticsRequest(req *models.PaymentMethodAnalyticsRequest) error {
|
||||
if req.OrganizationID == uuid.Nil {
|
||||
return fmt.Errorf("organization ID is required")
|
||||
}
|
||||
|
||||
if req.DateFrom.IsZero() {
|
||||
return fmt.Errorf("date_from is required")
|
||||
}
|
||||
|
||||
if req.DateTo.IsZero() {
|
||||
return fmt.Errorf("date_to is required")
|
||||
}
|
||||
|
||||
if req.DateFrom.After(req.DateTo) {
|
||||
return fmt.Errorf("date_from cannot be after date_to")
|
||||
}
|
||||
|
||||
// Validate groupBy if provided
|
||||
if req.GroupBy != "" {
|
||||
validGroupBy := map[string]bool{
|
||||
"day": true,
|
||||
"hour": true,
|
||||
"week": true,
|
||||
"month": true,
|
||||
}
|
||||
if !validGroupBy[req.GroupBy] {
|
||||
return fmt.Errorf("invalid group_by value: %s", req.GroupBy)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *AnalyticsServiceImpl) validateSalesAnalyticsRequest(req *models.SalesAnalyticsRequest) error {
|
||||
if req.OrganizationID == uuid.Nil {
|
||||
return fmt.Errorf("organization ID is required")
|
||||
}
|
||||
|
||||
if req.DateFrom.IsZero() {
|
||||
return fmt.Errorf("date_from is required")
|
||||
}
|
||||
|
||||
if req.DateTo.IsZero() {
|
||||
return fmt.Errorf("date_to is required")
|
||||
}
|
||||
|
||||
if req.DateFrom.After(req.DateTo) {
|
||||
return fmt.Errorf("date_from cannot be after date_to")
|
||||
}
|
||||
|
||||
// Validate groupBy if provided
|
||||
if req.GroupBy != "" {
|
||||
validGroupBy := map[string]bool{
|
||||
"day": true,
|
||||
"hour": true,
|
||||
"week": true,
|
||||
"month": true,
|
||||
}
|
||||
if !validGroupBy[req.GroupBy] {
|
||||
return fmt.Errorf("invalid group_by value: %s", req.GroupBy)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *AnalyticsServiceImpl) validateProductAnalyticsRequest(req *models.ProductAnalyticsRequest) error {
|
||||
if req.OrganizationID == uuid.Nil {
|
||||
return fmt.Errorf("organization ID is required")
|
||||
}
|
||||
|
||||
if req.DateFrom.IsZero() {
|
||||
return fmt.Errorf("date_from is required")
|
||||
}
|
||||
|
||||
if req.DateTo.IsZero() {
|
||||
return fmt.Errorf("date_to is required")
|
||||
}
|
||||
|
||||
if req.DateFrom.After(req.DateTo) {
|
||||
return fmt.Errorf("date_from cannot be after date_to")
|
||||
}
|
||||
|
||||
if req.Limit < 1 || req.Limit > 100 {
|
||||
return fmt.Errorf("limit must be between 1 and 100")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *AnalyticsServiceImpl) validateDashboardAnalyticsRequest(req *models.DashboardAnalyticsRequest) error {
|
||||
if req.OrganizationID == uuid.Nil {
|
||||
return fmt.Errorf("organization ID is required")
|
||||
}
|
||||
|
||||
if req.DateFrom.IsZero() {
|
||||
return fmt.Errorf("date_from is required")
|
||||
}
|
||||
|
||||
if req.DateTo.IsZero() {
|
||||
return fmt.Errorf("date_to is required")
|
||||
}
|
||||
|
||||
if req.DateFrom.After(req.DateTo) {
|
||||
return fmt.Errorf("date_from cannot be after date_to")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *AnalyticsServiceImpl) GetProfitLossAnalytics(ctx context.Context, req *models.ProfitLossAnalyticsRequest) (*models.ProfitLossAnalyticsResponse, error) {
|
||||
// Validate request
|
||||
if err := s.validateProfitLossAnalyticsRequest(req); err != nil {
|
||||
return nil, fmt.Errorf("validation error: %w", err)
|
||||
}
|
||||
|
||||
// Call processor
|
||||
response, err := s.analyticsProcessor.GetProfitLossAnalytics(ctx, req)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get profit/loss analytics: %w", err)
|
||||
}
|
||||
|
||||
return response, nil
|
||||
}
|
||||
|
||||
func (s *AnalyticsServiceImpl) validateProfitLossAnalyticsRequest(req *models.ProfitLossAnalyticsRequest) error {
|
||||
if req == nil {
|
||||
return fmt.Errorf("request cannot be nil")
|
||||
}
|
||||
|
||||
if req.OrganizationID == uuid.Nil {
|
||||
return fmt.Errorf("organization_id is required")
|
||||
}
|
||||
|
||||
if req.DateFrom.IsZero() {
|
||||
return fmt.Errorf("date_from is required")
|
||||
}
|
||||
|
||||
if req.DateTo.IsZero() {
|
||||
return fmt.Errorf("date_to is required")
|
||||
}
|
||||
|
||||
if req.DateFrom.After(req.DateTo) {
|
||||
return fmt.Errorf("date_from cannot be after date_to")
|
||||
}
|
||||
|
||||
if req.GroupBy != "" && req.GroupBy != "hour" && req.GroupBy != "day" && req.GroupBy != "week" && req.GroupBy != "month" {
|
||||
return fmt.Errorf("invalid group_by value, must be one of: hour, day, week, month")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,184 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"apskel-pos-be/internal/contract"
|
||||
"apskel-pos-be/internal/models"
|
||||
"apskel-pos-be/internal/transformer"
|
||||
|
||||
"github.com/golang-jwt/jwt/v5"
|
||||
"github.com/google/uuid"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
)
|
||||
|
||||
type AuthService interface {
|
||||
Login(ctx context.Context, req *contract.LoginRequest) (*contract.LoginResponse, error)
|
||||
ValidateToken(tokenString string) (*contract.UserResponse, error)
|
||||
RefreshToken(ctx context.Context, tokenString string) (*contract.LoginResponse, error)
|
||||
Logout(ctx context.Context, tokenString string) error
|
||||
}
|
||||
|
||||
type AuthServiceImpl struct {
|
||||
userProcessor UserProcessor
|
||||
jwtSecret string
|
||||
tokenTTL time.Duration
|
||||
}
|
||||
|
||||
type Claims struct {
|
||||
UserID uuid.UUID `json:"user_id"`
|
||||
Email string `json:"email"`
|
||||
Role string `json:"role"`
|
||||
OrganizationID uuid.UUID `json:"organization_id"`
|
||||
jwt.RegisteredClaims
|
||||
}
|
||||
|
||||
func NewAuthService(userProcessor UserProcessor, jwtSecret string) AuthService {
|
||||
return &AuthServiceImpl{
|
||||
userProcessor: userProcessor,
|
||||
jwtSecret: jwtSecret,
|
||||
tokenTTL: 24 * time.Hour,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *AuthServiceImpl) Login(ctx context.Context, req *contract.LoginRequest) (*contract.LoginResponse, error) {
|
||||
userResponse, err := s.userProcessor.GetUserByEmail(ctx, req.Email)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid credentials")
|
||||
}
|
||||
|
||||
if !userResponse.IsActive {
|
||||
return nil, fmt.Errorf("user account is deactivated")
|
||||
}
|
||||
|
||||
userEntity, err := s.userProcessor.GetUserEntityByEmail(ctx, req.Email)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid credentials")
|
||||
}
|
||||
|
||||
err = bcrypt.CompareHashAndPassword([]byte(userEntity.PasswordHash), []byte(req.Password))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid credentials")
|
||||
}
|
||||
|
||||
contractUserResponse := transformer.UserModelResponseToResponse(userResponse)
|
||||
|
||||
token, expiresAt, err := s.generateToken(userResponse)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to generate token: %w", err)
|
||||
}
|
||||
|
||||
return &contract.LoginResponse{
|
||||
Token: token,
|
||||
ExpiresAt: expiresAt,
|
||||
User: *contractUserResponse,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *AuthServiceImpl) ValidateToken(tokenString string) (*contract.UserResponse, error) {
|
||||
claims, err := s.parseToken(tokenString)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid token: %w", err)
|
||||
}
|
||||
|
||||
userResponse, err := s.userProcessor.GetUserByID(context.Background(), claims.UserID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("user not found: %w", err)
|
||||
}
|
||||
|
||||
if !userResponse.IsActive {
|
||||
return nil, fmt.Errorf("user account is deactivated")
|
||||
}
|
||||
|
||||
contractUserResponse := transformer.UserModelResponseToResponse(userResponse)
|
||||
return contractUserResponse, nil
|
||||
}
|
||||
|
||||
func (s *AuthServiceImpl) RefreshToken(ctx context.Context, tokenString string) (*contract.LoginResponse, error) {
|
||||
claims, err := s.parseToken(tokenString)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid token: %w", err)
|
||||
}
|
||||
|
||||
userResponse, err := s.userProcessor.GetUserByID(ctx, claims.UserID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("user not found: %w", err)
|
||||
}
|
||||
|
||||
if !userResponse.IsActive {
|
||||
return nil, fmt.Errorf("user account is deactivated")
|
||||
}
|
||||
|
||||
contractUserResponse := transformer.UserModelResponseToResponse(userResponse)
|
||||
|
||||
newToken, expiresAt, err := s.generateToken(userResponse)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to generate token: %w", err)
|
||||
}
|
||||
|
||||
return &contract.LoginResponse{
|
||||
Token: newToken,
|
||||
ExpiresAt: expiresAt,
|
||||
User: *contractUserResponse,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *AuthServiceImpl) Logout(ctx context.Context, tokenString string) error {
|
||||
// In a more sophisticated implementation, you might want to blacklist the token
|
||||
// For now, we'll just validate that the token is valid
|
||||
_, err := s.parseToken(tokenString)
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid token: %w", err)
|
||||
}
|
||||
|
||||
// In the future, you could store blacklisted tokens in Redis or database
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *AuthServiceImpl) generateToken(user *models.UserResponse) (string, time.Time, error) {
|
||||
expiresAt := time.Now().Add(s.tokenTTL)
|
||||
|
||||
claims := &Claims{
|
||||
UserID: user.ID,
|
||||
Email: user.Email,
|
||||
Role: string(user.Role),
|
||||
OrganizationID: user.OrganizationID,
|
||||
RegisteredClaims: jwt.RegisteredClaims{
|
||||
ExpiresAt: jwt.NewNumericDate(expiresAt),
|
||||
IssuedAt: jwt.NewNumericDate(time.Now()),
|
||||
NotBefore: jwt.NewNumericDate(time.Now()),
|
||||
Issuer: "apskel-pos",
|
||||
Subject: user.ID.String(),
|
||||
},
|
||||
}
|
||||
|
||||
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
|
||||
tokenString, err := token.SignedString([]byte(s.jwtSecret))
|
||||
if err != nil {
|
||||
return "", time.Time{}, err
|
||||
}
|
||||
|
||||
return tokenString, expiresAt, nil
|
||||
}
|
||||
|
||||
func (s *AuthServiceImpl) parseToken(tokenString string) (*Claims, error) {
|
||||
token, err := jwt.ParseWithClaims(tokenString, &Claims{}, func(token *jwt.Token) (interface{}, error) {
|
||||
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
|
||||
return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])
|
||||
}
|
||||
return []byte(s.jwtSecret), nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if claims, ok := token.Claims.(*Claims); ok && token.Valid {
|
||||
return claims, nil
|
||||
}
|
||||
|
||||
return nil, errors.New("invalid token")
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"apskel-pos-be/internal/appcontext"
|
||||
"apskel-pos-be/internal/constants"
|
||||
"apskel-pos-be/internal/contract"
|
||||
"apskel-pos-be/internal/processor"
|
||||
"apskel-pos-be/internal/transformer"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
type CategoryService interface {
|
||||
CreateCategory(ctx context.Context, apctx *appcontext.ContextInfo, req *contract.CreateCategoryRequest) *contract.Response
|
||||
UpdateCategory(ctx context.Context, id uuid.UUID, req *contract.UpdateCategoryRequest) *contract.Response
|
||||
DeleteCategory(ctx context.Context, id uuid.UUID) *contract.Response
|
||||
GetCategoryByID(ctx context.Context, id uuid.UUID) *contract.Response
|
||||
ListCategories(ctx context.Context, req *contract.ListCategoriesRequest) *contract.Response
|
||||
}
|
||||
|
||||
type CategoryServiceImpl struct {
|
||||
categoryProcessor processor.CategoryProcessor
|
||||
}
|
||||
|
||||
func NewCategoryService(categoryProcessor processor.CategoryProcessor) *CategoryServiceImpl {
|
||||
return &CategoryServiceImpl{
|
||||
categoryProcessor: categoryProcessor,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *CategoryServiceImpl) CreateCategory(ctx context.Context, apctx *appcontext.ContextInfo, req *contract.CreateCategoryRequest) *contract.Response {
|
||||
modelReq := transformer.CreateCategoryRequestToModel(apctx, req)
|
||||
|
||||
categoryResponse, err := s.categoryProcessor.CreateCategory(ctx, modelReq)
|
||||
if err != nil {
|
||||
errorResp := contract.NewResponseError(constants.InternalServerErrorCode, constants.CategoryServiceEntity, err.Error())
|
||||
return contract.BuildErrorResponse([]*contract.ResponseError{errorResp})
|
||||
}
|
||||
|
||||
contractResponse := transformer.CategoryModelResponseToResponse(categoryResponse)
|
||||
return contract.BuildSuccessResponse(contractResponse)
|
||||
}
|
||||
|
||||
func (s *CategoryServiceImpl) UpdateCategory(ctx context.Context, id uuid.UUID, req *contract.UpdateCategoryRequest) *contract.Response {
|
||||
modelReq := transformer.UpdateCategoryRequestToModel(req)
|
||||
|
||||
categoryResponse, err := s.categoryProcessor.UpdateCategory(ctx, id, modelReq)
|
||||
if err != nil {
|
||||
errorResp := contract.NewResponseError(constants.InternalServerErrorCode, constants.CategoryServiceEntity, err.Error())
|
||||
return contract.BuildErrorResponse([]*contract.ResponseError{errorResp})
|
||||
}
|
||||
|
||||
contractResponse := transformer.CategoryModelResponseToResponse(categoryResponse)
|
||||
return contract.BuildSuccessResponse(contractResponse)
|
||||
}
|
||||
|
||||
func (s *CategoryServiceImpl) DeleteCategory(ctx context.Context, id uuid.UUID) *contract.Response {
|
||||
err := s.categoryProcessor.DeleteCategory(ctx, id)
|
||||
if err != nil {
|
||||
errorResp := contract.NewResponseError(constants.InternalServerErrorCode, constants.CategoryServiceEntity, err.Error())
|
||||
return contract.BuildErrorResponse([]*contract.ResponseError{errorResp})
|
||||
}
|
||||
|
||||
return contract.BuildSuccessResponse(map[string]interface{}{
|
||||
"message": "Category deleted successfully",
|
||||
})
|
||||
}
|
||||
|
||||
func (s *CategoryServiceImpl) GetCategoryByID(ctx context.Context, id uuid.UUID) *contract.Response {
|
||||
categoryResponse, err := s.categoryProcessor.GetCategoryByID(ctx, id)
|
||||
if err != nil {
|
||||
errorResp := contract.NewResponseError(constants.InternalServerErrorCode, constants.CategoryServiceEntity, err.Error())
|
||||
return contract.BuildErrorResponse([]*contract.ResponseError{errorResp})
|
||||
}
|
||||
|
||||
contractResponse := transformer.CategoryModelResponseToResponse(categoryResponse)
|
||||
return contract.BuildSuccessResponse(contractResponse)
|
||||
}
|
||||
|
||||
func (s *CategoryServiceImpl) ListCategories(ctx context.Context, req *contract.ListCategoriesRequest) *contract.Response {
|
||||
// Build filters
|
||||
filters := make(map[string]interface{})
|
||||
if req.OrganizationID != nil {
|
||||
filters["organization_id"] = *req.OrganizationID
|
||||
}
|
||||
if req.BusinessType != "" {
|
||||
filters["business_type"] = req.BusinessType
|
||||
}
|
||||
if req.Search != "" {
|
||||
filters["search"] = req.Search
|
||||
}
|
||||
|
||||
categories, totalCount, err := s.categoryProcessor.ListCategories(ctx, filters, req.Page, req.Limit)
|
||||
if err != nil {
|
||||
errorResp := contract.NewResponseError(constants.InternalServerErrorCode, constants.CategoryServiceEntity, err.Error())
|
||||
return contract.BuildErrorResponse([]*contract.ResponseError{errorResp})
|
||||
}
|
||||
|
||||
// Convert to contract responses
|
||||
contractResponses := transformer.CategoriesToResponses(categories)
|
||||
|
||||
// Calculate total pages
|
||||
totalPages := totalCount / req.Limit
|
||||
if totalCount%req.Limit > 0 {
|
||||
totalPages++
|
||||
}
|
||||
|
||||
listResponse := &contract.ListCategoriesResponse{
|
||||
Categories: contractResponses,
|
||||
TotalCount: totalCount,
|
||||
Page: req.Page,
|
||||
Limit: req.Limit,
|
||||
TotalPages: totalPages,
|
||||
}
|
||||
|
||||
return contract.BuildSuccessResponse(listResponse)
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"apskel-pos-be/internal/contract"
|
||||
"apskel-pos-be/internal/processor"
|
||||
"apskel-pos-be/internal/transformer"
|
||||
"context"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
type CustomerService interface {
|
||||
CreateCustomer(ctx context.Context, req *contract.CreateCustomerRequest, organizationID uuid.UUID) (*contract.CustomerResponse, error)
|
||||
GetCustomer(ctx context.Context, customerID, organizationID uuid.UUID) (*contract.CustomerResponse, error)
|
||||
ListCustomers(ctx context.Context, query *contract.ListCustomersRequest, organizationID uuid.UUID) (*contract.PaginatedCustomerResponse, error)
|
||||
UpdateCustomer(ctx context.Context, customerID, organizationID uuid.UUID, req *contract.UpdateCustomerRequest) (*contract.CustomerResponse, error)
|
||||
DeleteCustomer(ctx context.Context, customerID, organizationID uuid.UUID) error
|
||||
SetDefaultCustomer(ctx context.Context, customerID, organizationID uuid.UUID) (*contract.CustomerResponse, error)
|
||||
GetDefaultCustomer(ctx context.Context, organizationID uuid.UUID) (*contract.CustomerResponse, error)
|
||||
EnsureDefaultCustomer(ctx context.Context, organizationID uuid.UUID) (*contract.CustomerResponse, error)
|
||||
}
|
||||
|
||||
type CustomerServiceImpl struct {
|
||||
customerProcessor *processor.CustomerProcessor
|
||||
}
|
||||
|
||||
func NewCustomerService(customerProcessor *processor.CustomerProcessor) *CustomerServiceImpl {
|
||||
return &CustomerServiceImpl{
|
||||
customerProcessor: customerProcessor,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *CustomerServiceImpl) CreateCustomer(ctx context.Context, req *contract.CreateCustomerRequest, organizationID uuid.UUID) (*contract.CustomerResponse, error) {
|
||||
modelReq := transformer.CreateCustomerRequestToModel(req)
|
||||
|
||||
customerResponse, err := s.customerProcessor.CreateCustomer(ctx, modelReq, organizationID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
contractResponse := transformer.CustomerModelToResponse(customerResponse)
|
||||
return contractResponse, nil
|
||||
}
|
||||
|
||||
func (s *CustomerServiceImpl) GetCustomer(ctx context.Context, customerID, organizationID uuid.UUID) (*contract.CustomerResponse, error) {
|
||||
customerResponse, err := s.customerProcessor.GetCustomer(ctx, customerID, organizationID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
contractResponse := transformer.CustomerModelToResponse(customerResponse)
|
||||
return contractResponse, nil
|
||||
}
|
||||
|
||||
func (s *CustomerServiceImpl) ListCustomers(ctx context.Context, query *contract.ListCustomersRequest, organizationID uuid.UUID) (*contract.PaginatedCustomerResponse, error) {
|
||||
modelQuery := transformer.ListCustomersRequestToModel(query)
|
||||
|
||||
customersResponse, err := s.customerProcessor.ListCustomers(ctx, modelQuery, organizationID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
contractResponse := transformer.PaginatedCustomerResponseToContract(customersResponse)
|
||||
return contractResponse, nil
|
||||
}
|
||||
|
||||
func (s *CustomerServiceImpl) UpdateCustomer(ctx context.Context, customerID, organizationID uuid.UUID, req *contract.UpdateCustomerRequest) (*contract.CustomerResponse, error) {
|
||||
modelReq := transformer.UpdateCustomerRequestToModel(req)
|
||||
|
||||
customerResponse, err := s.customerProcessor.UpdateCustomer(ctx, customerID, organizationID, modelReq)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
contractResponse := transformer.CustomerModelToResponse(customerResponse)
|
||||
return contractResponse, nil
|
||||
}
|
||||
|
||||
func (s *CustomerServiceImpl) DeleteCustomer(ctx context.Context, customerID, organizationID uuid.UUID) error {
|
||||
return s.customerProcessor.DeleteCustomer(ctx, customerID, organizationID)
|
||||
}
|
||||
|
||||
func (s *CustomerServiceImpl) SetDefaultCustomer(ctx context.Context, customerID, organizationID uuid.UUID) (*contract.CustomerResponse, error) {
|
||||
customerResponse, err := s.customerProcessor.SetDefaultCustomer(ctx, customerID, organizationID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
contractResponse := transformer.CustomerModelToResponse(customerResponse)
|
||||
return contractResponse, nil
|
||||
}
|
||||
|
||||
func (s *CustomerServiceImpl) GetDefaultCustomer(ctx context.Context, organizationID uuid.UUID) (*contract.CustomerResponse, error) {
|
||||
customerResponse, err := s.customerProcessor.GetDefaultCustomer(ctx, organizationID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
contractResponse := transformer.CustomerModelToResponse(customerResponse)
|
||||
return contractResponse, nil
|
||||
}
|
||||
|
||||
func (s *CustomerServiceImpl) EnsureDefaultCustomer(ctx context.Context, organizationID uuid.UUID) (*contract.CustomerResponse, error) {
|
||||
customerResponse, err := s.customerProcessor.EnsureDefaultCustomer(ctx, organizationID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
contractResponse := transformer.CustomerModelToResponse(customerResponse)
|
||||
return contractResponse, nil
|
||||
}
|
||||
@@ -0,0 +1,166 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"apskel-pos-be/internal/models"
|
||||
"apskel-pos-be/internal/processor"
|
||||
|
||||
"mime/multipart"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
type FileService interface {
|
||||
UploadFile(ctx context.Context, file *multipart.FileHeader, req *models.UploadFileRequest, organizationID, userID uuid.UUID) (*models.FileResponse, error)
|
||||
GetFileByID(ctx context.Context, id uuid.UUID) (*models.FileResponse, error)
|
||||
UpdateFile(ctx context.Context, id uuid.UUID, req *models.UpdateFileRequest) (*models.FileResponse, error)
|
||||
ListFiles(ctx context.Context, req *models.ListFilesRequest) (*models.ListFilesResponse, error)
|
||||
GetFileByOrganizationID(ctx context.Context, organizationID uuid.UUID) ([]*models.FileResponse, error)
|
||||
GetFileByUserID(ctx context.Context, userID uuid.UUID) ([]*models.FileResponse, error)
|
||||
}
|
||||
|
||||
type FileServiceImpl struct {
|
||||
fileProcessor processor.FileProcessor
|
||||
}
|
||||
|
||||
func NewFileServiceImpl(fileProcessor processor.FileProcessor) *FileServiceImpl {
|
||||
return &FileServiceImpl{
|
||||
fileProcessor: fileProcessor,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *FileServiceImpl) UploadFile(ctx context.Context, file *multipart.FileHeader, req *models.UploadFileRequest, organizationID, userID uuid.UUID) (*models.FileResponse, error) {
|
||||
if err := s.validateUploadFileRequest(req); err != nil {
|
||||
return nil, fmt.Errorf("validation error: %w", err)
|
||||
}
|
||||
|
||||
if organizationID == uuid.Nil {
|
||||
return nil, fmt.Errorf("organization ID is required")
|
||||
}
|
||||
if userID == uuid.Nil {
|
||||
return nil, fmt.Errorf("user ID is required")
|
||||
}
|
||||
|
||||
// Process file upload
|
||||
response, err := s.fileProcessor.UploadFile(ctx, file, req, organizationID, userID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to upload file: %w", err)
|
||||
}
|
||||
|
||||
return response, nil
|
||||
}
|
||||
|
||||
func (s *FileServiceImpl) GetFileByID(ctx context.Context, id uuid.UUID) (*models.FileResponse, error) {
|
||||
if id == uuid.Nil {
|
||||
return nil, fmt.Errorf("invalid file ID")
|
||||
}
|
||||
|
||||
response, err := s.fileProcessor.GetFileByID(ctx, id)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get file: %w", err)
|
||||
}
|
||||
|
||||
return response, nil
|
||||
}
|
||||
|
||||
func (s *FileServiceImpl) UpdateFile(ctx context.Context, id uuid.UUID, req *models.UpdateFileRequest) (*models.FileResponse, error) {
|
||||
// Validate inputs
|
||||
if id == uuid.Nil {
|
||||
return nil, fmt.Errorf("invalid file ID")
|
||||
}
|
||||
|
||||
// Validate request
|
||||
if err := s.validateUpdateFileRequest(req); err != nil {
|
||||
return nil, fmt.Errorf("validation error: %w", err)
|
||||
}
|
||||
|
||||
// Process file update
|
||||
response, err := s.fileProcessor.UpdateFile(ctx, id, req)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to update file: %w", err)
|
||||
}
|
||||
|
||||
return response, nil
|
||||
}
|
||||
|
||||
func (s *FileServiceImpl) ListFiles(ctx context.Context, req *models.ListFilesRequest) (*models.ListFilesResponse, error) {
|
||||
// Validate request
|
||||
if err := s.validateListFilesRequest(req); err != nil {
|
||||
return nil, fmt.Errorf("validation error: %w", err)
|
||||
}
|
||||
|
||||
// Process file listing
|
||||
response, err := s.fileProcessor.ListFiles(ctx, req)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to list files: %w", err)
|
||||
}
|
||||
|
||||
return response, nil
|
||||
}
|
||||
|
||||
func (s *FileServiceImpl) GetFileByOrganizationID(ctx context.Context, organizationID uuid.UUID) ([]*models.FileResponse, error) {
|
||||
// Validate organization ID
|
||||
if organizationID == uuid.Nil {
|
||||
return nil, fmt.Errorf("invalid organization ID")
|
||||
}
|
||||
|
||||
// Get files by organization
|
||||
response, err := s.fileProcessor.GetFileByOrganizationID(ctx, organizationID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get files by organization: %w", err)
|
||||
}
|
||||
|
||||
return response, nil
|
||||
}
|
||||
|
||||
func (s *FileServiceImpl) GetFileByUserID(ctx context.Context, userID uuid.UUID) ([]*models.FileResponse, error) {
|
||||
// Validate user ID
|
||||
if userID == uuid.Nil {
|
||||
return nil, fmt.Errorf("invalid user ID")
|
||||
}
|
||||
|
||||
// Get files by user
|
||||
response, err := s.fileProcessor.GetFileByUserID(ctx, userID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get files by user: %w", err)
|
||||
}
|
||||
|
||||
return response, nil
|
||||
}
|
||||
|
||||
// Validation methods
|
||||
func (s *FileServiceImpl) validateUploadFileRequest(req *models.UploadFileRequest) error {
|
||||
if req == nil {
|
||||
return fmt.Errorf("request cannot be nil")
|
||||
}
|
||||
|
||||
// File type validation is handled in the processor
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *FileServiceImpl) validateUpdateFileRequest(req *models.UpdateFileRequest) error {
|
||||
if req == nil {
|
||||
return fmt.Errorf("request cannot be nil")
|
||||
}
|
||||
|
||||
// Additional validation can be added here if needed
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *FileServiceImpl) validateListFilesRequest(req *models.ListFilesRequest) error {
|
||||
if req == nil {
|
||||
return fmt.Errorf("request cannot be nil")
|
||||
}
|
||||
|
||||
if req.Page < 1 {
|
||||
return fmt.Errorf("page must be greater than 0")
|
||||
}
|
||||
|
||||
if req.Limit < 1 || req.Limit > 100 {
|
||||
return fmt.Errorf("limit must be between 1 and 100")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,166 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"apskel-pos-be/internal/appcontext"
|
||||
"apskel-pos-be/internal/constants"
|
||||
"apskel-pos-be/internal/contract"
|
||||
"apskel-pos-be/internal/processor"
|
||||
"apskel-pos-be/internal/transformer"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
type InventoryService interface {
|
||||
CreateInventory(ctx context.Context, apctx *appcontext.ContextInfo, req *contract.CreateInventoryRequest) *contract.Response
|
||||
UpdateInventory(ctx context.Context, id uuid.UUID, req *contract.UpdateInventoryRequest) *contract.Response
|
||||
DeleteInventory(ctx context.Context, id uuid.UUID) *contract.Response
|
||||
GetInventoryByID(ctx context.Context, id uuid.UUID) *contract.Response
|
||||
ListInventory(ctx context.Context, req *contract.ListInventoryRequest) *contract.Response
|
||||
AdjustInventory(ctx context.Context, req *contract.AdjustInventoryRequest) *contract.Response
|
||||
GetLowStockItems(ctx context.Context, outletID uuid.UUID) *contract.Response
|
||||
GetZeroStockItems(ctx context.Context, outletID uuid.UUID) *contract.Response
|
||||
}
|
||||
|
||||
type InventoryServiceImpl struct {
|
||||
inventoryProcessor processor.InventoryProcessor
|
||||
}
|
||||
|
||||
func NewInventoryService(inventoryProcessor processor.InventoryProcessor) *InventoryServiceImpl {
|
||||
return &InventoryServiceImpl{
|
||||
inventoryProcessor: inventoryProcessor,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *InventoryServiceImpl) CreateInventory(ctx context.Context, apctx *appcontext.ContextInfo, req *contract.CreateInventoryRequest) *contract.Response {
|
||||
modelReq := transformer.CreateInventoryRequestToModel(req)
|
||||
|
||||
inventoryResponse, err := s.inventoryProcessor.CreateInventory(ctx, modelReq)
|
||||
if err != nil {
|
||||
errorResp := contract.NewResponseError(constants.InternalServerErrorCode, constants.InventoryServiceEntity, err.Error())
|
||||
return contract.BuildErrorResponse([]*contract.ResponseError{errorResp})
|
||||
}
|
||||
|
||||
contractResponse := transformer.InventoryModelResponseToResponse(inventoryResponse)
|
||||
return contract.BuildSuccessResponse(contractResponse)
|
||||
}
|
||||
|
||||
func (s *InventoryServiceImpl) UpdateInventory(ctx context.Context, id uuid.UUID, req *contract.UpdateInventoryRequest) *contract.Response {
|
||||
modelReq := transformer.UpdateInventoryRequestToModel(req)
|
||||
|
||||
inventoryResponse, err := s.inventoryProcessor.UpdateInventory(ctx, id, modelReq)
|
||||
if err != nil {
|
||||
errorResp := contract.NewResponseError(constants.InternalServerErrorCode, constants.InventoryServiceEntity, err.Error())
|
||||
return contract.BuildErrorResponse([]*contract.ResponseError{errorResp})
|
||||
}
|
||||
|
||||
contractResponse := transformer.InventoryModelResponseToResponse(inventoryResponse)
|
||||
return contract.BuildSuccessResponse(contractResponse)
|
||||
}
|
||||
|
||||
func (s *InventoryServiceImpl) DeleteInventory(ctx context.Context, id uuid.UUID) *contract.Response {
|
||||
err := s.inventoryProcessor.DeleteInventory(ctx, id)
|
||||
if err != nil {
|
||||
errorResp := contract.NewResponseError(constants.InternalServerErrorCode, constants.InventoryServiceEntity, err.Error())
|
||||
return contract.BuildErrorResponse([]*contract.ResponseError{errorResp})
|
||||
}
|
||||
|
||||
return contract.BuildSuccessResponse(map[string]interface{}{
|
||||
"message": "Inventory deleted successfully",
|
||||
})
|
||||
}
|
||||
|
||||
func (s *InventoryServiceImpl) GetInventoryByID(ctx context.Context, id uuid.UUID) *contract.Response {
|
||||
inventoryResponse, err := s.inventoryProcessor.GetInventoryByID(ctx, id)
|
||||
if err != nil {
|
||||
errorResp := contract.NewResponseError(constants.InternalServerErrorCode, constants.InventoryServiceEntity, err.Error())
|
||||
return contract.BuildErrorResponse([]*contract.ResponseError{errorResp})
|
||||
}
|
||||
|
||||
contractResponse := transformer.InventoryModelResponseToResponse(inventoryResponse)
|
||||
return contract.BuildSuccessResponse(contractResponse)
|
||||
}
|
||||
|
||||
func (s *InventoryServiceImpl) ListInventory(ctx context.Context, req *contract.ListInventoryRequest) *contract.Response {
|
||||
// Build filters
|
||||
filters := make(map[string]interface{})
|
||||
if req.OutletID != nil {
|
||||
filters["outlet_id"] = *req.OutletID
|
||||
}
|
||||
if req.ProductID != nil {
|
||||
filters["product_id"] = *req.ProductID
|
||||
}
|
||||
if req.CategoryID != nil {
|
||||
filters["category_id"] = *req.CategoryID
|
||||
}
|
||||
if req.LowStockOnly != nil && *req.LowStockOnly {
|
||||
filters["low_stock"] = true
|
||||
}
|
||||
if req.ZeroStockOnly != nil && *req.ZeroStockOnly {
|
||||
filters["zero_stock"] = true
|
||||
}
|
||||
if req.Search != "" {
|
||||
filters["search"] = req.Search
|
||||
}
|
||||
|
||||
inventory, totalCount, err := s.inventoryProcessor.ListInventory(ctx, filters, req.Page, req.Limit)
|
||||
if err != nil {
|
||||
errorResp := contract.NewResponseError(constants.InternalServerErrorCode, constants.InventoryServiceEntity, err.Error())
|
||||
return contract.BuildErrorResponse([]*contract.ResponseError{errorResp})
|
||||
}
|
||||
|
||||
// Convert to contract responses
|
||||
contractResponses := transformer.InventoryToResponses(inventory)
|
||||
|
||||
// Calculate total pages
|
||||
totalPages := totalCount / req.Limit
|
||||
if totalCount%req.Limit > 0 {
|
||||
totalPages++
|
||||
}
|
||||
|
||||
listResponse := &contract.ListInventoryResponse{
|
||||
Inventory: contractResponses,
|
||||
TotalCount: totalCount,
|
||||
Page: req.Page,
|
||||
Limit: req.Limit,
|
||||
TotalPages: totalPages,
|
||||
}
|
||||
|
||||
return contract.BuildSuccessResponse(listResponse)
|
||||
}
|
||||
|
||||
func (s *InventoryServiceImpl) AdjustInventory(ctx context.Context, req *contract.AdjustInventoryRequest) *contract.Response {
|
||||
modelReq := transformer.AdjustInventoryRequestToModel(req)
|
||||
|
||||
inventoryResponse, err := s.inventoryProcessor.AdjustInventory(ctx, req.ProductID, req.OutletID, modelReq)
|
||||
if err != nil {
|
||||
errorResp := contract.NewResponseError(constants.InternalServerErrorCode, constants.InventoryServiceEntity, err.Error())
|
||||
return contract.BuildErrorResponse([]*contract.ResponseError{errorResp})
|
||||
}
|
||||
|
||||
contractResponse := transformer.InventoryModelResponseToResponse(inventoryResponse)
|
||||
return contract.BuildSuccessResponse(contractResponse)
|
||||
}
|
||||
|
||||
func (s *InventoryServiceImpl) GetLowStockItems(ctx context.Context, outletID uuid.UUID) *contract.Response {
|
||||
inventory, err := s.inventoryProcessor.GetLowStockItems(ctx, outletID)
|
||||
if err != nil {
|
||||
errorResp := contract.NewResponseError(constants.InternalServerErrorCode, constants.InventoryServiceEntity, err.Error())
|
||||
return contract.BuildErrorResponse([]*contract.ResponseError{errorResp})
|
||||
}
|
||||
|
||||
contractResponses := transformer.InventoryToResponses(inventory)
|
||||
return contract.BuildSuccessResponse(contractResponses)
|
||||
}
|
||||
|
||||
func (s *InventoryServiceImpl) GetZeroStockItems(ctx context.Context, outletID uuid.UUID) *contract.Response {
|
||||
inventory, err := s.inventoryProcessor.GetZeroStockItems(ctx, outletID)
|
||||
if err != nil {
|
||||
errorResp := contract.NewResponseError(constants.InternalServerErrorCode, constants.InventoryServiceEntity, err.Error())
|
||||
return contract.BuildErrorResponse([]*contract.ResponseError{errorResp})
|
||||
}
|
||||
|
||||
contractResponses := transformer.InventoryToResponses(inventory)
|
||||
return contract.BuildSuccessResponse(contractResponses)
|
||||
}
|
||||
@@ -0,0 +1,386 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"apskel-pos-be/internal/models"
|
||||
"apskel-pos-be/internal/processor"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
type OrderService interface {
|
||||
CreateOrder(ctx context.Context, req *models.CreateOrderRequest, organizationID uuid.UUID) (*models.OrderResponse, error)
|
||||
AddToOrder(ctx context.Context, orderID uuid.UUID, req *models.AddToOrderRequest) (*models.AddToOrderResponse, error)
|
||||
UpdateOrder(ctx context.Context, id uuid.UUID, req *models.UpdateOrderRequest) (*models.OrderResponse, error)
|
||||
GetOrderByID(ctx context.Context, id uuid.UUID) (*models.OrderResponse, error)
|
||||
ListOrders(ctx context.Context, req *models.ListOrdersRequest) (*models.ListOrdersResponse, error)
|
||||
VoidOrder(ctx context.Context, req *models.VoidOrderRequest, voidedBy uuid.UUID) error
|
||||
RefundOrder(ctx context.Context, id uuid.UUID, req *models.RefundOrderRequest, refundedBy uuid.UUID) error
|
||||
CreatePayment(ctx context.Context, req *models.CreatePaymentRequest) (*models.PaymentResponse, error)
|
||||
RefundPayment(ctx context.Context, paymentID uuid.UUID, refundAmount float64, reason string, refundedBy uuid.UUID) error
|
||||
SetOrderCustomer(ctx context.Context, orderID uuid.UUID, req *models.SetOrderCustomerRequest, organizationID uuid.UUID) (*models.SetOrderCustomerResponse, error)
|
||||
}
|
||||
|
||||
type OrderServiceImpl struct {
|
||||
orderProcessor processor.OrderProcessor
|
||||
}
|
||||
|
||||
func NewOrderServiceImpl(orderProcessor processor.OrderProcessor) *OrderServiceImpl {
|
||||
return &OrderServiceImpl{
|
||||
orderProcessor: orderProcessor,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *OrderServiceImpl) CreateOrder(ctx context.Context, req *models.CreateOrderRequest, organizationID uuid.UUID) (*models.OrderResponse, error) {
|
||||
if err := s.validateCreateOrderRequest(req, organizationID); err != nil {
|
||||
return nil, fmt.Errorf("validation error: %w", err)
|
||||
}
|
||||
|
||||
response, err := s.orderProcessor.CreateOrder(ctx, req, organizationID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create order: %w", err)
|
||||
}
|
||||
|
||||
return response, nil
|
||||
}
|
||||
|
||||
func (s *OrderServiceImpl) AddToOrder(ctx context.Context, orderID uuid.UUID, req *models.AddToOrderRequest) (*models.AddToOrderResponse, error) {
|
||||
// Validate inputs
|
||||
if orderID == uuid.Nil {
|
||||
return nil, fmt.Errorf("invalid order ID")
|
||||
}
|
||||
|
||||
// Validate request
|
||||
if err := s.validateAddToOrderRequest(req); err != nil {
|
||||
return nil, fmt.Errorf("validation error: %w", err)
|
||||
}
|
||||
|
||||
// Process adding items to order
|
||||
response, err := s.orderProcessor.AddToOrder(ctx, orderID, req)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to add items to order: %w", err)
|
||||
}
|
||||
|
||||
return response, nil
|
||||
}
|
||||
|
||||
func (s *OrderServiceImpl) UpdateOrder(ctx context.Context, id uuid.UUID, req *models.UpdateOrderRequest) (*models.OrderResponse, error) {
|
||||
// Validate request
|
||||
if err := s.validateUpdateOrderRequest(req); err != nil {
|
||||
return nil, fmt.Errorf("validation error: %w", err)
|
||||
}
|
||||
|
||||
// Process order update
|
||||
response, err := s.orderProcessor.UpdateOrder(ctx, id, req)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to update order: %w", err)
|
||||
}
|
||||
|
||||
return response, nil
|
||||
}
|
||||
|
||||
func (s *OrderServiceImpl) GetOrderByID(ctx context.Context, id uuid.UUID) (*models.OrderResponse, error) {
|
||||
if id == uuid.Nil {
|
||||
return nil, fmt.Errorf("invalid order ID")
|
||||
}
|
||||
|
||||
response, err := s.orderProcessor.GetOrderByID(ctx, id)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get order: %w", err)
|
||||
}
|
||||
|
||||
return response, nil
|
||||
}
|
||||
|
||||
func (s *OrderServiceImpl) ListOrders(ctx context.Context, req *models.ListOrdersRequest) (*models.ListOrdersResponse, error) {
|
||||
// Validate request
|
||||
if err := s.validateListOrdersRequest(req); err != nil {
|
||||
return nil, fmt.Errorf("validation error: %w", err)
|
||||
}
|
||||
|
||||
// Process order listing
|
||||
response, err := s.orderProcessor.ListOrders(ctx, req)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to list orders: %w", err)
|
||||
}
|
||||
|
||||
return response, nil
|
||||
}
|
||||
|
||||
func (s *OrderServiceImpl) VoidOrder(ctx context.Context, req *models.VoidOrderRequest, voidedBy uuid.UUID) error {
|
||||
if req.OrderID == uuid.Nil {
|
||||
return fmt.Errorf("invalid order ID")
|
||||
}
|
||||
|
||||
if voidedBy == uuid.Nil {
|
||||
return fmt.Errorf("invalid user ID")
|
||||
}
|
||||
|
||||
if err := s.orderProcessor.VoidOrder(ctx, req, voidedBy); err != nil {
|
||||
return fmt.Errorf("failed to void order: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *OrderServiceImpl) RefundOrder(ctx context.Context, id uuid.UUID, req *models.RefundOrderRequest, refundedBy uuid.UUID) error {
|
||||
// Validate inputs
|
||||
if id == uuid.Nil {
|
||||
return fmt.Errorf("invalid order ID")
|
||||
}
|
||||
if refundedBy == uuid.Nil {
|
||||
return fmt.Errorf("invalid user ID")
|
||||
}
|
||||
|
||||
// Validate refund request
|
||||
if err := s.validateRefundOrderRequest(req); err != nil {
|
||||
return fmt.Errorf("validation error: %w", err)
|
||||
}
|
||||
|
||||
// Process order refund
|
||||
if err := s.orderProcessor.RefundOrder(ctx, id, req, refundedBy); err != nil {
|
||||
return fmt.Errorf("failed to refund order: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *OrderServiceImpl) CreatePayment(ctx context.Context, req *models.CreatePaymentRequest) (*models.PaymentResponse, error) {
|
||||
if err := s.validateCreatePaymentRequest(req); err != nil {
|
||||
return nil, fmt.Errorf("validation error: %w", err)
|
||||
}
|
||||
|
||||
// Process payment creation
|
||||
response, err := s.orderProcessor.CreatePayment(ctx, req)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create payment: %w", err)
|
||||
}
|
||||
|
||||
return response, nil
|
||||
}
|
||||
|
||||
func (s *OrderServiceImpl) RefundPayment(ctx context.Context, paymentID uuid.UUID, refundAmount float64, reason string, refundedBy uuid.UUID) error {
|
||||
// Validate inputs
|
||||
if paymentID == uuid.Nil {
|
||||
return fmt.Errorf("invalid payment ID")
|
||||
}
|
||||
if refundAmount <= 0 {
|
||||
return fmt.Errorf("refund amount must be greater than zero")
|
||||
}
|
||||
if refundedBy == uuid.Nil {
|
||||
return fmt.Errorf("invalid user ID")
|
||||
}
|
||||
|
||||
// Process payment refund
|
||||
if err := s.orderProcessor.RefundPayment(ctx, paymentID, refundAmount, reason, refundedBy); err != nil {
|
||||
return fmt.Errorf("failed to refund payment: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *OrderServiceImpl) SetOrderCustomer(ctx context.Context, orderID uuid.UUID, req *models.SetOrderCustomerRequest, organizationID uuid.UUID) (*models.SetOrderCustomerResponse, error) {
|
||||
// Validate inputs
|
||||
if orderID == uuid.Nil {
|
||||
return nil, fmt.Errorf("invalid order ID")
|
||||
}
|
||||
|
||||
if organizationID == uuid.Nil {
|
||||
return nil, fmt.Errorf("invalid organization ID")
|
||||
}
|
||||
|
||||
// Validate request
|
||||
if err := s.validateSetOrderCustomerRequest(req); err != nil {
|
||||
return nil, fmt.Errorf("validation error: %w", err)
|
||||
}
|
||||
|
||||
// Process setting customer for order
|
||||
response, err := s.orderProcessor.SetOrderCustomer(ctx, orderID, req, organizationID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to set customer for order: %w", err)
|
||||
}
|
||||
|
||||
return response, nil
|
||||
}
|
||||
|
||||
func (s *OrderServiceImpl) validateAddToOrderRequest(req *models.AddToOrderRequest) error {
|
||||
if req == nil {
|
||||
return fmt.Errorf("request cannot be nil")
|
||||
}
|
||||
|
||||
if len(req.OrderItems) == 0 {
|
||||
return fmt.Errorf("must add at least one item")
|
||||
}
|
||||
|
||||
for i, item := range req.OrderItems {
|
||||
if item.ProductID == uuid.Nil {
|
||||
return fmt.Errorf("product ID is required for item %d", i+1)
|
||||
}
|
||||
|
||||
if item.Quantity <= 0 {
|
||||
return fmt.Errorf("quantity must be greater than zero for item %d", i+1)
|
||||
}
|
||||
|
||||
if item.UnitPrice != nil && *item.UnitPrice < 0 {
|
||||
return fmt.Errorf("unit price cannot be negative for item %d", i+1)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *OrderServiceImpl) validateCreateOrderRequest(req *models.CreateOrderRequest, organizationID uuid.UUID) error {
|
||||
if req == nil {
|
||||
return fmt.Errorf("request cannot be nil")
|
||||
}
|
||||
|
||||
if organizationID == uuid.Nil {
|
||||
return fmt.Errorf("organization ID is required")
|
||||
}
|
||||
|
||||
if req.OutletID == uuid.Nil {
|
||||
return fmt.Errorf("outlet ID is required")
|
||||
}
|
||||
|
||||
if req.UserID == uuid.Nil {
|
||||
return fmt.Errorf("user ID is required")
|
||||
}
|
||||
|
||||
if len(req.OrderItems) == 0 {
|
||||
return fmt.Errorf("order must have at least one item")
|
||||
}
|
||||
|
||||
for i, item := range req.OrderItems {
|
||||
if item.ProductID == uuid.Nil {
|
||||
return fmt.Errorf("product ID is required for item %d", i+1)
|
||||
}
|
||||
|
||||
if item.Quantity <= 0 {
|
||||
return fmt.Errorf("quantity must be greater than zero for item %d", i+1)
|
||||
}
|
||||
|
||||
if item.UnitPrice != nil && *item.UnitPrice < 0 {
|
||||
return fmt.Errorf("unit price cannot be negative for item %d", i+1)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *OrderServiceImpl) validateUpdateOrderRequest(req *models.UpdateOrderRequest) error {
|
||||
if req == nil {
|
||||
return fmt.Errorf("request cannot be nil")
|
||||
}
|
||||
|
||||
if req.DiscountAmount != nil && *req.DiscountAmount < 0 {
|
||||
return fmt.Errorf("discount amount cannot be negative")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *OrderServiceImpl) validateListOrdersRequest(req *models.ListOrdersRequest) error {
|
||||
if req == nil {
|
||||
return fmt.Errorf("request cannot be nil")
|
||||
}
|
||||
|
||||
if req.Page < 1 {
|
||||
return fmt.Errorf("page must be greater than zero")
|
||||
}
|
||||
|
||||
if req.Limit < 1 || req.Limit > 100 {
|
||||
return fmt.Errorf("limit must be between 1 and 100")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *OrderServiceImpl) validateRefundOrderRequest(req *models.RefundOrderRequest) error {
|
||||
if req == nil {
|
||||
return fmt.Errorf("request cannot be nil")
|
||||
}
|
||||
|
||||
// Must have either refund amount or order items
|
||||
if req.RefundAmount == nil && len(req.OrderItems) == 0 {
|
||||
return fmt.Errorf("must specify either refund amount or order items to refund")
|
||||
}
|
||||
|
||||
// Cannot have both refund amount and order items
|
||||
if req.RefundAmount != nil && len(req.OrderItems) > 0 {
|
||||
return fmt.Errorf("cannot specify both refund amount and order items")
|
||||
}
|
||||
|
||||
if req.RefundAmount != nil && *req.RefundAmount <= 0 {
|
||||
return fmt.Errorf("refund amount must be greater than zero")
|
||||
}
|
||||
|
||||
// Validate order items if provided
|
||||
for i, item := range req.OrderItems {
|
||||
if item.OrderItemID == uuid.Nil {
|
||||
return fmt.Errorf("order item ID is required for item %d", i+1)
|
||||
}
|
||||
|
||||
if item.RefundQuantity < 0 {
|
||||
return fmt.Errorf("refund quantity cannot be negative for item %d", i+1)
|
||||
}
|
||||
|
||||
if item.RefundAmount != nil && *item.RefundAmount < 0 {
|
||||
return fmt.Errorf("refund amount cannot be negative for item %d", i+1)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *OrderServiceImpl) validateCreatePaymentRequest(req *models.CreatePaymentRequest) error {
|
||||
if req == nil {
|
||||
return fmt.Errorf("request cannot be nil")
|
||||
}
|
||||
|
||||
if req.OrderID == uuid.Nil {
|
||||
return fmt.Errorf("order ID is required")
|
||||
}
|
||||
|
||||
if req.PaymentMethodID == uuid.Nil {
|
||||
return fmt.Errorf("payment method ID is required")
|
||||
}
|
||||
|
||||
if req.Amount <= 0 {
|
||||
return fmt.Errorf("payment amount must be greater than zero")
|
||||
}
|
||||
|
||||
if len(req.PaymentOrderItems) > 0 {
|
||||
totalItemAmount := float64(0)
|
||||
for i, item := range req.PaymentOrderItems {
|
||||
if item.OrderItemID == uuid.Nil {
|
||||
return fmt.Errorf("order item ID is required for payment item %d", i+1)
|
||||
}
|
||||
|
||||
if item.Amount <= 0 {
|
||||
return fmt.Errorf("payment item amount must be greater than zero for item %d", i+1)
|
||||
}
|
||||
|
||||
totalItemAmount += item.Amount
|
||||
}
|
||||
|
||||
if totalItemAmount != req.Amount {
|
||||
return fmt.Errorf("sum of payment item amounts must equal total payment amount")
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *OrderServiceImpl) validateSetOrderCustomerRequest(req *models.SetOrderCustomerRequest) error {
|
||||
if req == nil {
|
||||
return fmt.Errorf("request cannot be nil")
|
||||
}
|
||||
|
||||
if req.CustomerID == uuid.Nil {
|
||||
return fmt.Errorf("customer ID is required")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"apskel-pos-be/internal/appcontext"
|
||||
"context"
|
||||
|
||||
"apskel-pos-be/internal/constants"
|
||||
"apskel-pos-be/internal/contract"
|
||||
"apskel-pos-be/internal/processor"
|
||||
"apskel-pos-be/internal/transformer"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
type OrganizationService interface {
|
||||
CreateOrganization(ctx context.Context, apctx *appcontext.ContextInfo, req *contract.CreateOrganizationRequest) *contract.Response
|
||||
UpdateOrganization(ctx context.Context, id uuid.UUID, req *contract.UpdateOrganizationRequest) *contract.Response
|
||||
DeleteOrganization(ctx context.Context, id uuid.UUID) *contract.Response
|
||||
GetOrganizationByID(ctx context.Context, id uuid.UUID) *contract.Response
|
||||
ListOrganizations(ctx context.Context, req *contract.ListOrganizationsRequest) *contract.Response
|
||||
}
|
||||
|
||||
type OrganizationServiceImpl struct {
|
||||
organizationProcessor processor.OrganizationProcessor
|
||||
}
|
||||
|
||||
func NewOrganizationService(organizationProcessor processor.OrganizationProcessor) *OrganizationServiceImpl {
|
||||
return &OrganizationServiceImpl{
|
||||
organizationProcessor: organizationProcessor,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *OrganizationServiceImpl) CreateOrganization(ctx context.Context, apctx *appcontext.ContextInfo, req *contract.CreateOrganizationRequest) *contract.Response {
|
||||
modelReq := transformer.CreateOrganizationRequestToModel(req)
|
||||
|
||||
organizationResponse, err := s.organizationProcessor.CreateOrganization(ctx, modelReq)
|
||||
if err != nil {
|
||||
errorResp := contract.NewResponseError(constants.InternalServerErrorCode, constants.OrganizationServiceEntity, err.Error())
|
||||
return contract.BuildErrorResponse([]*contract.ResponseError{errorResp})
|
||||
}
|
||||
|
||||
contractResponse := transformer.CreateOrganizationResponseToContract(organizationResponse)
|
||||
return contract.BuildSuccessResponse(contractResponse)
|
||||
}
|
||||
|
||||
func (s *OrganizationServiceImpl) UpdateOrganization(ctx context.Context, id uuid.UUID, req *contract.UpdateOrganizationRequest) *contract.Response {
|
||||
modelReq := transformer.UpdateOrganizationRequestToModel(req)
|
||||
|
||||
organizationResponse, err := s.organizationProcessor.UpdateOrganization(ctx, id, modelReq)
|
||||
if err != nil {
|
||||
errorResp := contract.NewResponseError(constants.InternalServerErrorCode, constants.OrganizationServiceEntity, err.Error())
|
||||
return contract.BuildErrorResponse([]*contract.ResponseError{errorResp})
|
||||
}
|
||||
|
||||
contractResponse := transformer.OrganizationModelResponseToResponse(organizationResponse)
|
||||
return contract.BuildSuccessResponse(contractResponse)
|
||||
}
|
||||
|
||||
func (s *OrganizationServiceImpl) DeleteOrganization(ctx context.Context, id uuid.UUID) *contract.Response {
|
||||
err := s.organizationProcessor.DeleteOrganization(ctx, id)
|
||||
if err != nil {
|
||||
errorResp := contract.NewResponseError(constants.InternalServerErrorCode, constants.OrganizationServiceEntity, err.Error())
|
||||
return contract.BuildErrorResponse([]*contract.ResponseError{errorResp})
|
||||
}
|
||||
|
||||
return contract.BuildSuccessResponse(map[string]interface{}{
|
||||
"message": "Organization deleted successfully",
|
||||
})
|
||||
}
|
||||
|
||||
func (s *OrganizationServiceImpl) GetOrganizationByID(ctx context.Context, id uuid.UUID) *contract.Response {
|
||||
organizationResponse, err := s.organizationProcessor.GetOrganizationByID(ctx, id)
|
||||
if err != nil {
|
||||
errorResp := contract.NewResponseError(constants.InternalServerErrorCode, constants.OrganizationServiceEntity, err.Error())
|
||||
return contract.BuildErrorResponse([]*contract.ResponseError{errorResp})
|
||||
}
|
||||
|
||||
contractResponse := transformer.OrganizationModelResponseToResponse(organizationResponse)
|
||||
return contract.BuildSuccessResponse(contractResponse)
|
||||
}
|
||||
|
||||
func (s *OrganizationServiceImpl) ListOrganizations(ctx context.Context, req *contract.ListOrganizationsRequest) *contract.Response {
|
||||
filters := make(map[string]interface{})
|
||||
if req.PlanType != "" {
|
||||
filters["plan_type"] = req.PlanType
|
||||
}
|
||||
if req.Search != "" {
|
||||
filters["name"] = req.Search
|
||||
}
|
||||
|
||||
organizations, totalCount, err := s.organizationProcessor.ListOrganizations(ctx, filters, req.Page, req.Limit)
|
||||
if err != nil {
|
||||
errorResp := contract.NewResponseError(constants.InternalServerErrorCode, constants.OrganizationServiceEntity, err.Error())
|
||||
return contract.BuildErrorResponse([]*contract.ResponseError{errorResp})
|
||||
}
|
||||
|
||||
contractResponses := make([]contract.OrganizationResponse, len(organizations))
|
||||
for i, org := range organizations {
|
||||
response := transformer.OrganizationModelResponseToResponse(&org)
|
||||
if response != nil {
|
||||
contractResponses[i] = *response
|
||||
}
|
||||
}
|
||||
|
||||
totalPages := totalCount / req.Limit
|
||||
if totalCount%req.Limit > 0 {
|
||||
totalPages++
|
||||
}
|
||||
|
||||
listResponse := &contract.ListOrganizationsResponse{
|
||||
Organizations: contractResponses,
|
||||
TotalCount: totalCount,
|
||||
Page: req.Page,
|
||||
Limit: req.Limit,
|
||||
TotalPages: totalPages,
|
||||
}
|
||||
|
||||
return contract.BuildSuccessResponse(listResponse)
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"apskel-pos-be/internal/constants"
|
||||
"apskel-pos-be/internal/contract"
|
||||
"apskel-pos-be/internal/processor"
|
||||
"apskel-pos-be/internal/transformer"
|
||||
"context"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
type OutletService interface {
|
||||
ListOutlets(ctx context.Context, req *contract.ListOutletsRequest) *contract.Response
|
||||
GetOutletByID(ctx context.Context, organizationID, outletID uuid.UUID) *contract.Response
|
||||
CreateOutlet(ctx context.Context, req *contract.CreateOutletRequest) *contract.Response
|
||||
UpdateOutlet(ctx context.Context, outletID uuid.UUID, req *contract.UpdateOutletRequest) *contract.Response
|
||||
DeleteOutlet(ctx context.Context, outletID uuid.UUID) *contract.Response
|
||||
}
|
||||
|
||||
type OutletServiceImpl struct {
|
||||
outletProcessor processor.OutletProcessor
|
||||
}
|
||||
|
||||
func NewOutletService(outletProcessor processor.OutletProcessor) *OutletServiceImpl {
|
||||
return &OutletServiceImpl{
|
||||
outletProcessor: outletProcessor,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *OutletServiceImpl) ListOutlets(ctx context.Context, req *contract.ListOutletsRequest) *contract.Response {
|
||||
// Validate request
|
||||
if req.Page < 1 {
|
||||
req.Page = 1
|
||||
}
|
||||
if req.Limit < 1 {
|
||||
req.Limit = 10
|
||||
}
|
||||
if req.Limit > 100 {
|
||||
req.Limit = 100
|
||||
}
|
||||
|
||||
outlets, total, err := s.outletProcessor.ListOutletsByOrganization(ctx, req.OrganizationID, req.Page, req.Limit)
|
||||
if err != nil {
|
||||
errorResp := contract.NewResponseError(constants.InternalServerErrorCode, constants.OutletServiceEntity, err.Error())
|
||||
return contract.BuildErrorResponse([]*contract.ResponseError{errorResp})
|
||||
}
|
||||
|
||||
contractOutlets := make([]contract.OutletResponse, len(outlets))
|
||||
for i, outlet := range outlets {
|
||||
contractOutlets[i] = transformer.OutletModelResponseToResponse(outlet)
|
||||
}
|
||||
|
||||
// Create paginated response
|
||||
response := transformer.CreateListOutletsResponse(contractOutlets, int(total), req.Page, req.Limit)
|
||||
return contract.BuildSuccessResponse(response)
|
||||
}
|
||||
|
||||
func (s *OutletServiceImpl) GetOutletByID(ctx context.Context, organizationID, outletID uuid.UUID) *contract.Response {
|
||||
outlet, err := s.outletProcessor.GetOutletByID(ctx, organizationID, outletID)
|
||||
if err != nil {
|
||||
errorResp := contract.NewResponseError(constants.InternalServerErrorCode, constants.OutletServiceEntity, err.Error())
|
||||
return contract.BuildErrorResponse([]*contract.ResponseError{errorResp})
|
||||
}
|
||||
|
||||
contractResponse := transformer.OutletModelResponseToResponse(outlet)
|
||||
return contract.BuildSuccessResponse(contractResponse)
|
||||
}
|
||||
|
||||
func (s *OutletServiceImpl) CreateOutlet(ctx context.Context, req *contract.CreateOutletRequest) *contract.Response {
|
||||
modelReq := transformer.CreateOutletRequestToModel(req)
|
||||
|
||||
outlet, err := s.outletProcessor.CreateOutlet(ctx, modelReq)
|
||||
if err != nil {
|
||||
errorResp := contract.NewResponseError(constants.InternalServerErrorCode, constants.OutletServiceEntity, err.Error())
|
||||
return contract.BuildErrorResponse([]*contract.ResponseError{errorResp})
|
||||
}
|
||||
|
||||
contractResponse := transformer.OutletModelResponseToResponse(outlet)
|
||||
return contract.BuildSuccessResponse(contractResponse)
|
||||
}
|
||||
|
||||
func (s *OutletServiceImpl) UpdateOutlet(ctx context.Context, outletID uuid.UUID, req *contract.UpdateOutletRequest) *contract.Response {
|
||||
modelReq := transformer.UpdateOutletRequestToModel(req)
|
||||
|
||||
outlet, err := s.outletProcessor.UpdateOutlet(ctx, outletID, modelReq)
|
||||
if err != nil {
|
||||
errorResp := contract.NewResponseError(constants.InternalServerErrorCode, constants.OutletServiceEntity, err.Error())
|
||||
return contract.BuildErrorResponse([]*contract.ResponseError{errorResp})
|
||||
}
|
||||
|
||||
contractResponse := transformer.OutletModelResponseToResponse(outlet)
|
||||
return contract.BuildSuccessResponse(contractResponse)
|
||||
}
|
||||
|
||||
func (s *OutletServiceImpl) DeleteOutlet(ctx context.Context, outletID uuid.UUID) *contract.Response {
|
||||
err := s.outletProcessor.DeleteOutlet(ctx, outletID)
|
||||
if err != nil {
|
||||
errorResp := contract.NewResponseError(constants.InternalServerErrorCode, constants.OutletServiceEntity, err.Error())
|
||||
return contract.BuildErrorResponse([]*contract.ResponseError{errorResp})
|
||||
}
|
||||
|
||||
return contract.BuildSuccessResponse(map[string]interface{}{
|
||||
"message": "Outlet deleted successfully",
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"apskel-pos-be/internal/models"
|
||||
"apskel-pos-be/internal/processor"
|
||||
"context"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
type OutletSettingService interface {
|
||||
CreateSetting(ctx context.Context, req *models.CreateOutletSettingRequest) (*models.OutletSettingResponse, error)
|
||||
UpdateSetting(ctx context.Context, outletID uuid.UUID, key string, req *models.UpdateOutletSettingRequest) (*models.OutletSettingResponse, error)
|
||||
GetSetting(ctx context.Context, outletID uuid.UUID, key string) (*models.OutletSettingResponse, error)
|
||||
GetPrinterSettings(ctx context.Context, outletID uuid.UUID) (*models.OutletPrinterSettings, error)
|
||||
UpdatePrinterSettings(ctx context.Context, outletID uuid.UUID, req *models.UpdateOutletPrinterSettingsRequest) (*models.OutletPrinterSettings, error)
|
||||
DeleteSetting(ctx context.Context, outletID uuid.UUID, key string) error
|
||||
}
|
||||
|
||||
type OutletSettingServiceImpl struct {
|
||||
outletSettingProcessor *processor.OutletSettingProcessorImpl
|
||||
}
|
||||
|
||||
func NewOutletSettingService(outletSettingProcessor *processor.OutletSettingProcessorImpl) OutletSettingService {
|
||||
return &OutletSettingServiceImpl{
|
||||
outletSettingProcessor: outletSettingProcessor,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *OutletSettingServiceImpl) CreateSetting(ctx context.Context, req *models.CreateOutletSettingRequest) (*models.OutletSettingResponse, error) {
|
||||
return s.outletSettingProcessor.CreateSetting(ctx, req)
|
||||
}
|
||||
|
||||
func (s *OutletSettingServiceImpl) UpdateSetting(ctx context.Context, outletID uuid.UUID, key string, req *models.UpdateOutletSettingRequest) (*models.OutletSettingResponse, error) {
|
||||
return s.outletSettingProcessor.UpdateSetting(ctx, outletID, key, req)
|
||||
}
|
||||
|
||||
func (s *OutletSettingServiceImpl) GetSetting(ctx context.Context, outletID uuid.UUID, key string) (*models.OutletSettingResponse, error) {
|
||||
return s.outletSettingProcessor.GetSetting(ctx, outletID, key)
|
||||
}
|
||||
|
||||
func (s *OutletSettingServiceImpl) GetPrinterSettings(ctx context.Context, outletID uuid.UUID) (*models.OutletPrinterSettings, error) {
|
||||
return s.outletSettingProcessor.GetPrinterSettings(ctx, outletID)
|
||||
}
|
||||
|
||||
func (s *OutletSettingServiceImpl) UpdatePrinterSettings(ctx context.Context, outletID uuid.UUID, req *models.UpdateOutletPrinterSettingsRequest) (*models.OutletPrinterSettings, error) {
|
||||
return s.outletSettingProcessor.UpdatePrinterSettings(ctx, outletID, req)
|
||||
}
|
||||
|
||||
func (s *OutletSettingServiceImpl) DeleteSetting(ctx context.Context, outletID uuid.UUID, key string) error {
|
||||
return s.outletSettingProcessor.DeleteSetting(ctx, outletID, key)
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"apskel-pos-be/internal/appcontext"
|
||||
"apskel-pos-be/internal/contract"
|
||||
"apskel-pos-be/internal/mappers"
|
||||
"apskel-pos-be/internal/processor"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
type PaymentMethodService interface {
|
||||
CreatePaymentMethod(ctx context.Context, contextInfo *appcontext.ContextInfo, req *contract.CreatePaymentMethodRequest) *contract.Response
|
||||
GetPaymentMethodByID(ctx context.Context, id uuid.UUID) *contract.Response
|
||||
ListPaymentMethods(ctx context.Context, req *contract.ListPaymentMethodsRequest) *contract.Response
|
||||
UpdatePaymentMethod(ctx context.Context, id uuid.UUID, req *contract.UpdatePaymentMethodRequest) *contract.Response
|
||||
DeletePaymentMethod(ctx context.Context, id uuid.UUID) *contract.Response
|
||||
GetActivePaymentMethodsByOrganization(ctx context.Context, organizationID uuid.UUID) *contract.Response
|
||||
}
|
||||
|
||||
type PaymentMethodServiceImpl struct {
|
||||
paymentMethodProcessor processor.PaymentMethodProcessor
|
||||
}
|
||||
|
||||
func NewPaymentMethodService(paymentMethodProcessor processor.PaymentMethodProcessor) PaymentMethodService {
|
||||
return &PaymentMethodServiceImpl{
|
||||
paymentMethodProcessor: paymentMethodProcessor,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *PaymentMethodServiceImpl) CreatePaymentMethod(ctx context.Context, contextInfo *appcontext.ContextInfo, req *contract.CreatePaymentMethodRequest) *contract.Response {
|
||||
// Convert contract to model
|
||||
modelReq := mappers.CreatePaymentMethodContractToModel(req)
|
||||
|
||||
// Set organization ID from context if not provided
|
||||
if modelReq.OrganizationID == uuid.Nil && contextInfo != nil {
|
||||
modelReq.OrganizationID = contextInfo.OrganizationID
|
||||
}
|
||||
|
||||
// Process request
|
||||
response, err := s.paymentMethodProcessor.CreatePaymentMethod(ctx, modelReq)
|
||||
if err != nil {
|
||||
return contract.BuildErrorResponse([]*contract.ResponseError{
|
||||
contract.NewResponseError("PAYMENT_METHOD_CREATE_ERROR", "payment_method", err.Error()),
|
||||
})
|
||||
}
|
||||
|
||||
// Convert model to contract
|
||||
contractResponse := mappers.PaymentMethodResponseToContract(response)
|
||||
return contract.BuildSuccessResponse(contractResponse)
|
||||
}
|
||||
|
||||
func (s *PaymentMethodServiceImpl) GetPaymentMethodByID(ctx context.Context, id uuid.UUID) *contract.Response {
|
||||
response, err := s.paymentMethodProcessor.GetPaymentMethodByID(ctx, id)
|
||||
if err != nil {
|
||||
return contract.BuildErrorResponse([]*contract.ResponseError{
|
||||
contract.NewResponseError("PAYMENT_METHOD_NOT_FOUND", "payment_method", err.Error()),
|
||||
})
|
||||
}
|
||||
|
||||
contractResponse := mappers.PaymentMethodResponseToContract(response)
|
||||
return contract.BuildSuccessResponse(contractResponse)
|
||||
}
|
||||
|
||||
func (s *PaymentMethodServiceImpl) ListPaymentMethods(ctx context.Context, req *contract.ListPaymentMethodsRequest) *contract.Response {
|
||||
// Convert contract to model
|
||||
modelReq := mappers.ListPaymentMethodsContractToModel(req)
|
||||
|
||||
// Process request
|
||||
response, err := s.paymentMethodProcessor.ListPaymentMethods(ctx, modelReq)
|
||||
if err != nil {
|
||||
return contract.BuildErrorResponse([]*contract.ResponseError{
|
||||
contract.NewResponseError("PAYMENT_METHOD_LIST_ERROR", "payment_method", err.Error()),
|
||||
})
|
||||
}
|
||||
|
||||
// Convert model to contract
|
||||
contractResponse := mappers.ListPaymentMethodsResponseToContract(response)
|
||||
return contract.BuildSuccessResponse(contractResponse)
|
||||
}
|
||||
|
||||
func (s *PaymentMethodServiceImpl) UpdatePaymentMethod(ctx context.Context, id uuid.UUID, req *contract.UpdatePaymentMethodRequest) *contract.Response {
|
||||
// Convert contract to model
|
||||
modelReq := mappers.UpdatePaymentMethodContractToModel(req)
|
||||
|
||||
// Process request
|
||||
response, err := s.paymentMethodProcessor.UpdatePaymentMethod(ctx, id, modelReq)
|
||||
if err != nil {
|
||||
return contract.BuildErrorResponse([]*contract.ResponseError{
|
||||
contract.NewResponseError("PAYMENT_METHOD_UPDATE_ERROR", "payment_method", err.Error()),
|
||||
})
|
||||
}
|
||||
|
||||
// Convert model to contract
|
||||
contractResponse := mappers.PaymentMethodResponseToContract(response)
|
||||
return contract.BuildSuccessResponse(contractResponse)
|
||||
}
|
||||
|
||||
func (s *PaymentMethodServiceImpl) DeletePaymentMethod(ctx context.Context, id uuid.UUID) *contract.Response {
|
||||
err := s.paymentMethodProcessor.DeletePaymentMethod(ctx, id)
|
||||
if err != nil {
|
||||
return contract.BuildErrorResponse([]*contract.ResponseError{
|
||||
contract.NewResponseError("PAYMENT_METHOD_DELETE_ERROR", "payment_method", err.Error()),
|
||||
})
|
||||
}
|
||||
|
||||
return contract.BuildSuccessResponse(map[string]string{"message": "Payment method deleted successfully"})
|
||||
}
|
||||
|
||||
func (s *PaymentMethodServiceImpl) GetActivePaymentMethodsByOrganization(ctx context.Context, organizationID uuid.UUID) *contract.Response {
|
||||
responses, err := s.paymentMethodProcessor.GetActivePaymentMethodsByOrganization(ctx, organizationID)
|
||||
if err != nil {
|
||||
return contract.BuildErrorResponse([]*contract.ResponseError{
|
||||
contract.NewResponseError("PAYMENT_METHOD_LIST_ERROR", "payment_method", err.Error()),
|
||||
})
|
||||
}
|
||||
|
||||
// Convert models to contracts
|
||||
contractResponses := make([]contract.PaymentMethodResponse, len(responses))
|
||||
for i, response := range responses {
|
||||
contractResponse := mappers.PaymentMethodResponseToContract(&response)
|
||||
if contractResponse != nil {
|
||||
contractResponses[i] = *contractResponse
|
||||
}
|
||||
}
|
||||
|
||||
return contract.BuildSuccessResponse(contractResponses)
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"apskel-pos-be/internal/appcontext"
|
||||
"apskel-pos-be/internal/constants"
|
||||
"apskel-pos-be/internal/contract"
|
||||
"apskel-pos-be/internal/processor"
|
||||
"apskel-pos-be/internal/transformer"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
type ProductService interface {
|
||||
CreateProduct(ctx context.Context, apctx *appcontext.ContextInfo, req *contract.CreateProductRequest) *contract.Response
|
||||
UpdateProduct(ctx context.Context, id uuid.UUID, req *contract.UpdateProductRequest) *contract.Response
|
||||
DeleteProduct(ctx context.Context, id uuid.UUID) *contract.Response
|
||||
GetProductByID(ctx context.Context, id uuid.UUID) *contract.Response
|
||||
ListProducts(ctx context.Context, req *contract.ListProductsRequest) *contract.Response
|
||||
}
|
||||
|
||||
type ProductServiceImpl struct {
|
||||
productProcessor processor.ProductProcessor
|
||||
}
|
||||
|
||||
func NewProductService(productProcessor processor.ProductProcessor) *ProductServiceImpl {
|
||||
return &ProductServiceImpl{
|
||||
productProcessor: productProcessor,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *ProductServiceImpl) CreateProduct(ctx context.Context, apctx *appcontext.ContextInfo, req *contract.CreateProductRequest) *contract.Response {
|
||||
modelReq := transformer.CreateProductRequestToModel(apctx, req)
|
||||
|
||||
productResponse, err := s.productProcessor.CreateProduct(ctx, modelReq)
|
||||
if err != nil {
|
||||
errorResp := contract.NewResponseError(constants.InternalServerErrorCode, constants.ProductServiceEntity, err.Error())
|
||||
return contract.BuildErrorResponse([]*contract.ResponseError{errorResp})
|
||||
}
|
||||
|
||||
contractResponse := transformer.ProductModelResponseToResponse(productResponse)
|
||||
return contract.BuildSuccessResponse(contractResponse)
|
||||
}
|
||||
|
||||
func (s *ProductServiceImpl) UpdateProduct(ctx context.Context, id uuid.UUID, req *contract.UpdateProductRequest) *contract.Response {
|
||||
modelReq := transformer.UpdateProductRequestToModel(req)
|
||||
|
||||
productResponse, err := s.productProcessor.UpdateProduct(ctx, id, modelReq)
|
||||
if err != nil {
|
||||
errorResp := contract.NewResponseError(constants.InternalServerErrorCode, constants.ProductServiceEntity, err.Error())
|
||||
return contract.BuildErrorResponse([]*contract.ResponseError{errorResp})
|
||||
}
|
||||
|
||||
contractResponse := transformer.ProductModelResponseToResponse(productResponse)
|
||||
return contract.BuildSuccessResponse(contractResponse)
|
||||
}
|
||||
|
||||
func (s *ProductServiceImpl) DeleteProduct(ctx context.Context, id uuid.UUID) *contract.Response {
|
||||
err := s.productProcessor.DeleteProduct(ctx, id)
|
||||
if err != nil {
|
||||
errorResp := contract.NewResponseError(constants.InternalServerErrorCode, constants.ProductServiceEntity, err.Error())
|
||||
return contract.BuildErrorResponse([]*contract.ResponseError{errorResp})
|
||||
}
|
||||
|
||||
return contract.BuildSuccessResponse(map[string]interface{}{
|
||||
"message": "Product deleted successfully",
|
||||
})
|
||||
}
|
||||
|
||||
func (s *ProductServiceImpl) GetProductByID(ctx context.Context, id uuid.UUID) *contract.Response {
|
||||
productResponse, err := s.productProcessor.GetProductByID(ctx, id)
|
||||
if err != nil {
|
||||
errorResp := contract.NewResponseError(constants.InternalServerErrorCode, constants.ProductServiceEntity, err.Error())
|
||||
return contract.BuildErrorResponse([]*contract.ResponseError{errorResp})
|
||||
}
|
||||
|
||||
contractResponse := transformer.ProductModelResponseToResponse(productResponse)
|
||||
return contract.BuildSuccessResponse(contractResponse)
|
||||
}
|
||||
|
||||
func (s *ProductServiceImpl) ListProducts(ctx context.Context, req *contract.ListProductsRequest) *contract.Response {
|
||||
// Build filters
|
||||
filters := make(map[string]interface{})
|
||||
if req.OrganizationID != nil {
|
||||
filters["organization_id"] = *req.OrganizationID
|
||||
}
|
||||
if req.CategoryID != nil {
|
||||
filters["category_id"] = *req.CategoryID
|
||||
}
|
||||
if req.BusinessType != "" {
|
||||
filters["business_type"] = req.BusinessType
|
||||
}
|
||||
if req.IsActive != nil {
|
||||
filters["is_active"] = *req.IsActive
|
||||
}
|
||||
if req.Search != "" {
|
||||
filters["search"] = req.Search
|
||||
}
|
||||
if req.MinPrice != nil {
|
||||
filters["price_min"] = *req.MinPrice
|
||||
}
|
||||
if req.MaxPrice != nil {
|
||||
filters["price_max"] = *req.MaxPrice
|
||||
}
|
||||
|
||||
products, totalCount, err := s.productProcessor.ListProducts(ctx, filters, req.Page, req.Limit)
|
||||
if err != nil {
|
||||
errorResp := contract.NewResponseError(constants.InternalServerErrorCode, constants.ProductServiceEntity, err.Error())
|
||||
return contract.BuildErrorResponse([]*contract.ResponseError{errorResp})
|
||||
}
|
||||
|
||||
// Convert to contract responses
|
||||
contractResponses := transformer.ProductsToResponses(products)
|
||||
|
||||
// Calculate total pages
|
||||
totalPages := totalCount / req.Limit
|
||||
if totalCount%req.Limit > 0 {
|
||||
totalPages++
|
||||
}
|
||||
|
||||
listResponse := &contract.ListProductsResponse{
|
||||
Products: contractResponses,
|
||||
TotalCount: totalCount,
|
||||
Page: req.Page,
|
||||
Limit: req.Limit,
|
||||
TotalPages: totalPages,
|
||||
}
|
||||
|
||||
return contract.BuildSuccessResponse(listResponse)
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"apskel-pos-be/internal/appcontext"
|
||||
"apskel-pos-be/internal/constants"
|
||||
"apskel-pos-be/internal/contract"
|
||||
"apskel-pos-be/internal/processor"
|
||||
"apskel-pos-be/internal/transformer"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
type ProductVariantService interface {
|
||||
CreateProductVariant(ctx context.Context, apctx *appcontext.ContextInfo, req *contract.CreateProductVariantRequest) *contract.Response
|
||||
UpdateProductVariant(ctx context.Context, id uuid.UUID, req *contract.UpdateProductVariantRequest) *contract.Response
|
||||
DeleteProductVariant(ctx context.Context, id uuid.UUID) *contract.Response
|
||||
GetProductVariantByID(ctx context.Context, id uuid.UUID) *contract.Response
|
||||
GetProductVariantsByProductID(ctx context.Context, productID uuid.UUID) *contract.Response
|
||||
}
|
||||
|
||||
type ProductVariantServiceImpl struct {
|
||||
productVariantProcessor processor.ProductVariantProcessor
|
||||
}
|
||||
|
||||
func NewProductVariantService(productVariantProcessor processor.ProductVariantProcessor) *ProductVariantServiceImpl {
|
||||
return &ProductVariantServiceImpl{
|
||||
productVariantProcessor: productVariantProcessor,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *ProductVariantServiceImpl) CreateProductVariant(ctx context.Context, apctx *appcontext.ContextInfo, req *contract.CreateProductVariantRequest) *contract.Response {
|
||||
modelReq := transformer.CreateProductVariantRequestToModel(req)
|
||||
|
||||
variantResponse, err := s.productVariantProcessor.CreateProductVariant(ctx, modelReq)
|
||||
if err != nil {
|
||||
errorResp := contract.NewResponseError(constants.InternalServerErrorCode, constants.ProductVariantServiceEntity, err.Error())
|
||||
return contract.BuildErrorResponse([]*contract.ResponseError{errorResp})
|
||||
}
|
||||
|
||||
contractResponse := transformer.ProductVariantModelResponseToResponse(variantResponse)
|
||||
return contract.BuildSuccessResponse(contractResponse)
|
||||
}
|
||||
|
||||
func (s *ProductVariantServiceImpl) UpdateProductVariant(ctx context.Context, id uuid.UUID, req *contract.UpdateProductVariantRequest) *contract.Response {
|
||||
modelReq := transformer.UpdateProductVariantRequestToModel(req)
|
||||
|
||||
variantResponse, err := s.productVariantProcessor.UpdateProductVariant(ctx, id, modelReq)
|
||||
if err != nil {
|
||||
errorResp := contract.NewResponseError(constants.InternalServerErrorCode, constants.ProductVariantServiceEntity, err.Error())
|
||||
return contract.BuildErrorResponse([]*contract.ResponseError{errorResp})
|
||||
}
|
||||
|
||||
contractResponse := transformer.ProductVariantModelResponseToResponse(variantResponse)
|
||||
return contract.BuildSuccessResponse(contractResponse)
|
||||
}
|
||||
|
||||
func (s *ProductVariantServiceImpl) DeleteProductVariant(ctx context.Context, id uuid.UUID) *contract.Response {
|
||||
err := s.productVariantProcessor.DeleteProductVariant(ctx, id)
|
||||
if err != nil {
|
||||
errorResp := contract.NewResponseError(constants.InternalServerErrorCode, constants.ProductVariantServiceEntity, err.Error())
|
||||
return contract.BuildErrorResponse([]*contract.ResponseError{errorResp})
|
||||
}
|
||||
|
||||
return contract.BuildSuccessResponse(map[string]interface{}{
|
||||
"message": "Product variant deleted successfully",
|
||||
})
|
||||
}
|
||||
|
||||
func (s *ProductVariantServiceImpl) GetProductVariantByID(ctx context.Context, id uuid.UUID) *contract.Response {
|
||||
variantResponse, err := s.productVariantProcessor.GetProductVariantByID(ctx, id)
|
||||
if err != nil {
|
||||
errorResp := contract.NewResponseError(constants.InternalServerErrorCode, constants.ProductVariantServiceEntity, err.Error())
|
||||
return contract.BuildErrorResponse([]*contract.ResponseError{errorResp})
|
||||
}
|
||||
|
||||
contractResponse := transformer.ProductVariantModelResponseToResponse(variantResponse)
|
||||
return contract.BuildSuccessResponse(contractResponse)
|
||||
}
|
||||
|
||||
func (s *ProductVariantServiceImpl) GetProductVariantsByProductID(ctx context.Context, productID uuid.UUID) *contract.Response {
|
||||
variants, err := s.productVariantProcessor.GetProductVariantsByProductID(ctx, productID)
|
||||
if err != nil {
|
||||
errorResp := contract.NewResponseError(constants.InternalServerErrorCode, constants.ProductVariantServiceEntity, err.Error())
|
||||
return contract.BuildErrorResponse([]*contract.ResponseError{errorResp})
|
||||
}
|
||||
|
||||
contractResponses := transformer.ProductVariantsToResponses(variants)
|
||||
return contract.BuildSuccessResponse(contractResponses)
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"apskel-pos-be/internal/entities"
|
||||
"apskel-pos-be/internal/models"
|
||||
"context"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
type UserProcessor interface {
|
||||
UpdateUser(ctx context.Context, id uuid.UUID, req *models.UpdateUserRequest) (*models.UserResponse, error)
|
||||
CreateUser(ctx context.Context, req *models.CreateUserRequest) (*models.UserResponse, error)
|
||||
DeleteUser(ctx context.Context, id uuid.UUID) error
|
||||
GetUserByID(ctx context.Context, id uuid.UUID) (*models.UserResponse, error)
|
||||
GetUserByEmail(ctx context.Context, email string) (*models.UserResponse, error)
|
||||
ListUsers(ctx context.Context, organizationID uuid.UUID, page, limit int) ([]models.UserResponse, int, error)
|
||||
GetUserEntityByEmail(ctx context.Context, email string) (*entities.User, error)
|
||||
ChangePassword(ctx context.Context, userID uuid.UUID, req *models.ChangePasswordRequest) error
|
||||
ActivateUser(ctx context.Context, userID uuid.UUID) error
|
||||
DeactivateUser(ctx context.Context, userID uuid.UUID) error
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"apskel-pos-be/internal/contract"
|
||||
"apskel-pos-be/internal/transformer"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
type UserServiceImpl struct {
|
||||
userProcessor UserProcessor
|
||||
}
|
||||
|
||||
func NewUserService(userProcessor UserProcessor) *UserServiceImpl {
|
||||
return &UserServiceImpl{
|
||||
userProcessor: userProcessor,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *UserServiceImpl) CreateUser(ctx context.Context, req *contract.CreateUserRequest) (*contract.UserResponse, error) {
|
||||
modelReq := transformer.CreateUserRequestToModel(req)
|
||||
|
||||
userResponse, err := s.userProcessor.CreateUser(ctx, modelReq)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
contractResponse := transformer.UserModelResponseToResponse(userResponse)
|
||||
return contractResponse, nil
|
||||
}
|
||||
|
||||
func (s *UserServiceImpl) UpdateUser(ctx context.Context, id uuid.UUID, req *contract.UpdateUserRequest) (*contract.UserResponse, error) {
|
||||
modelReq := transformer.UpdateUserRequestToModel(req)
|
||||
|
||||
userResponse, err := s.userProcessor.UpdateUser(ctx, id, modelReq)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
contractResponse := transformer.UserModelResponseToResponse(userResponse)
|
||||
|
||||
return contractResponse, nil
|
||||
}
|
||||
|
||||
func (s *UserServiceImpl) DeleteUser(ctx context.Context, id uuid.UUID) error {
|
||||
return s.userProcessor.DeleteUser(ctx, id)
|
||||
}
|
||||
|
||||
func (s *UserServiceImpl) GetUserByID(ctx context.Context, id uuid.UUID) (*contract.UserResponse, error) {
|
||||
userResponse, err := s.userProcessor.GetUserByID(ctx, id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
contractResponse := transformer.UserModelResponseToResponse(userResponse)
|
||||
|
||||
return contractResponse, nil
|
||||
}
|
||||
|
||||
func (s *UserServiceImpl) GetUserByEmail(ctx context.Context, email string) (*contract.UserResponse, error) {
|
||||
userResponse, err := s.userProcessor.GetUserByEmail(ctx, email)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
contractResponse := transformer.UserModelResponseToResponse(userResponse)
|
||||
|
||||
return contractResponse, nil
|
||||
}
|
||||
|
||||
func (s *UserServiceImpl) ListUsers(ctx context.Context, req *contract.ListUsersRequest) (*contract.ListUsersResponse, error) {
|
||||
page, limit := transformer.PaginationToRequest(req.Page, req.Limit)
|
||||
|
||||
organizationID := uuid.New()
|
||||
userResponses, totalCount, err := s.userProcessor.ListUsers(ctx, organizationID, page, limit)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
contractResponses := transformer.UserResponsesToResponses(userResponses)
|
||||
|
||||
response := transformer.CreateListUsersResponse(contractResponses, totalCount, page, limit)
|
||||
|
||||
return response, nil
|
||||
}
|
||||
|
||||
func (s *UserServiceImpl) ChangePassword(ctx context.Context, userID uuid.UUID, req *contract.ChangePasswordRequest) error {
|
||||
modelReq := transformer.ChangePasswordRequestToModel(req)
|
||||
|
||||
return s.userProcessor.ChangePassword(ctx, userID, modelReq)
|
||||
}
|
||||
|
||||
func (s *UserServiceImpl) ActivateUser(ctx context.Context, userID uuid.UUID) error {
|
||||
return s.userProcessor.ActivateUser(ctx, userID)
|
||||
}
|
||||
|
||||
func (s *UserServiceImpl) DeactivateUser(ctx context.Context, userID uuid.UUID) error {
|
||||
return s.userProcessor.DeactivateUser(ctx, userID)
|
||||
}
|
||||
Reference in New Issue
Block a user