package transaction import ( "Yimaru-Backend/internal/domain" "Yimaru-Backend/internal/ports" "Yimaru-Backend/internal/services/user" "context" "errors" ) var ( ErrBranchRequiredForRole = errors.New("branch_id is required to be passed for this role") ErrInvalidBranchID = errors.New("invalid branch id") ErrUnauthorizedCompanyID = errors.New("unauthorized company id") ErrUnauthorizedBranchManager = errors.New("unauthorized branch manager") ErrCustomerRoleNotAuthorized = errors.New("customer role not authorized") ErrDepositCannotBeUnverified = errors.New("deposit cannot be unverified") ErrShopBetHasExpired = errors.New("shop bet has already been expired") ) type Service struct { transactionStore ports.TransactionStore userSvc user.Service } func NewService( transactionStore ports.TransactionStore, userSvc user.Service, ) *Service { return &Service{ transactionStore: transactionStore, userSvc: userSvc, } } // func (s *Service) CreateShopTransaction(ctx context.Context, transaction domain.CreateShopTransaction) (domain.ShopTransaction, error) { // return s.transactionStore.CreateShopTransaction(ctx, transaction) // } // func (s *Service) GetShopTransactionByID(ctx context.Context, id int64) (domain.ShopTransactionDetail, error) { // return s.transactionStore.GetShopTransactionByID(ctx, id) // } // func (s *Service) GetAllShopTransactions(ctx context.Context, filter domain.ShopTransactionFilter) ([]domain.ShopTransactionDetail, error) { // return s.transactionStore.GetAllShopTransactions(ctx, filter) // } // func (s *Service) GetShopTransactionByBranch(ctx context.Context, id int64) ([]domain.ShopTransactionDetail, error) { // return s.transactionStore.GetShopTransactionByBranch(ctx, id) // } // func (s *Service) UpdateShopTransactionVerified(ctx context.Context, id int64, verified bool, approvedBy int64, role domain.Role, companyID domain.ValidInt64, branchID domain.ValidInt64) error { // // TODO: Move this into a service role verification service // // Checks to make sure only the same company and branch can modify this // transaction, err := s.GetShopTransactionByID(ctx, id) // if role != domain.RoleSuperAdmin { // if !companyID.Valid || companyID.Value != transaction.CompanyID { // // s.logger.Error("Failed to parse UpdateTransactionVerified request", "error", err) // return fmt.Errorf("user cannot modify another companies data") // } // if role == domain.RoleCashier { // if !branchID.Valid || branchID.Value != transaction.BranchID { // // h.logger.Error("Failed to parse UpdateTransactionVerified request", "error", "Unauthorized") // return fmt.Errorf("user cannot modify another companies data") // } // } // } // if err != nil { // return err // } // // switch transaction.Type { // // case domain.TRANSACTION_BET: // // if verified { // // bet, err := s.GetShopBetByShopTransactionID(ctx, transaction.ID) // // if err != nil { // // return err // // } // // var firstEvent time.Time = bet.Outcomes[0].Expires // // for _, outcome := range bet.Outcomes { // // if outcome.Expires.Before(firstEvent) { // // firstEvent = outcome.Expires // // } // // } // // fmt.Printf("\n\n Shop bet expire %v - now %v \n\n", firstEvent, time.Now().UTC()) // // if firstEvent.Before(time.Now()) { // // return ErrShopBetHasExpired // // } // // } // // case domain.TRANSACTION_DEPOSIT: // // if !verified { // // // TODO: Figure out what to do here? Should i return the money or verify the faulty verify // // return ErrDepositCannotBeUnverified // // } // // deposit, err := s.GetShopDepositByShopTransactionID(ctx, transaction.ID) // // if err != nil { // // return err // // } // // customerWallet, err := s.walletSvc.GetCustomerWallet(ctx, deposit.CustomerID) // // if err != nil { // // return ErrUserHasNoCustomerWallet // // } // // transfer, err := s.walletSvc.TransferToWallet(ctx, // // deposit.BranchWalletID, customerWallet.RegularID, transaction.Amount, domain.TRANSFER_DIRECT, domain.ValidInt64{ // // Value: transaction.UserID, // // Valid: true, // // }, // // fmt.Sprintf("Transferred %v to customer wallet due to shop deposit", transaction.Amount), // // ) // // if err != nil { // // return err // // } // // err = s.UpdateShopDepositTransferID(ctx, deposit.ID, domain.ValidInt64{ // // Value: transfer.ID, // // Valid: true, // // }) // // if err != nil { // // return err // // } // // } // return s.transactionStore.UpdateShopTransactionVerified(ctx, id, verified, approvedBy) // } func (s *Service) GetBranchByRole(ctx context.Context, branchID *int64, role domain.Role, userID int64, userCompanyID domain.ValidInt64) (*int64, *int64, error) { // var branchID int64 // var companyID int64 switch role { case domain.RoleAdmin, domain.RoleSuperAdmin: if branchID == nil { // h.logger.Error("CashoutReq Branch ID is required for this user role") return nil, nil, ErrBranchRequiredForRole } // branch, err := s.branchSvc.GetBranchByID(ctx, *branchID) // if err != nil { // // h.logger.Error("CashoutReq no branches") // return nil, nil, err // } // Check if the user has access to the company if role != domain.RoleSuperAdmin { // if userCompanyID.Valid && userCompanyID.Value != branch.CompanyID { // return nil, nil, ErrUnauthorizedCompanyID // } } // if role == domain.RoleBranchManager { // // if branch.BranchManagerID != userID { // // return nil, nil, ErrUnauthorizedBranchManager // // } // } // return &branch.ID, &branch.CompanyID, nil case domain.RoleInstructor: // branch, err := s.branchSvc.GetBranchByCashier(ctx, userID) // if err != nil { // // h.logger.Error("CashoutReq failed, branch id invalid") // return nil, nil, ErrInvalidBranchID // } // return &branch.ID, &branch.CompanyID, nil default: return nil, nil, ErrCustomerRoleNotAuthorized } return nil, nil, ErrCustomerRoleNotAuthorized }