Yimaru-BackEnd/q
2025-05-15 01:50:59 +03:00

257 lines
12 KiB
Plaintext
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

diff --git a/internal/domain/result.go b/internal/domain/result.go
index e43476b..def8719 100644
--- a/internal/domain/result.go
+++ b/internal/domain/result.go
@@ -210,6 +210,45 @@ type CricketResultResponse struct {
Bet365ID string `json:"bet365_id"`
}

+type VolleyballResultResponse struct {
+ ID string `json:"id"`
+ SportID string `json:"sport_id"`
+ Time string `json:"time"`
+ TimeStatus string `json:"time_status"`
+ League struct {
+ ID string `json:"id"`
+ Name string `json:"name"`
+ CC string `json:"cc"`
+ } `json:"league"`
+ Home struct {
+ ID string `json:"id"`
+ Name string `json:"name"`
+ ImageID string `json:"image_id"`
+ CC string `json:"cc"`
+ } `json:"home"`
+ Away struct {
+ ID string `json:"id"`
+ Name string `json:"name"`
+ ImageID string `json:"image_id"`
+ CC string `json:"cc"`
+ } `json:"away"`
+ SS string `json:"ss"`
+ Scores struct {
+ FirstSet Score `json:"1"`
+ SecondSet Score `json:"2"`
+ ThirdSet Score `json:"3"`
+ FourthSet Score `json:"4"`
+ FivethSet Score `json:"5"`
+ } `json:"scores"`
+ Stats struct {
+ PointsWonOnServe []string `json:"points_won_on_serve"`
+ LongestStreak []string `json:"longest_streak"`
+ } `json:"stats"`
+ InplayCreatedAt string `json:"inplay_created_at"`
+ InplayUpdatedAt string `json:"inplay_updated_at"`
+ Bet365ID string `json:"bet365_id"`
+}
+
type Score struct {
Home string `json:"home"`
Away string `json:"away"`
diff --git a/internal/domain/sportmarket.go b/internal/domain/sportmarket.go
index f442f9c..fc25e36 100644
--- a/internal/domain/sportmarket.go
+++ b/internal/domain/sportmarket.go
@@ -114,6 +114,17 @@ const (
CRICKET_TOP_MATCH_BOWLER CricketMarket = 30246
)

+type VolleyballMarket int64
+
+const (
+ VOLLEYBALL_GAME_LINES VolleyballMarket = 910000
+ VOLLEYBALL_CORRECT_SET_SCORE VolleyballMarket = 910201
+ VOLLEYBALL_MATCH_TOTAL_ODD_EVEN VolleyballMarket = 910217
+ VOLLEYBALL_SET_ONE_LINES VolleyballMarket = 910204
+ VOLLEYBALL_SET_ONE_TO_GO_TO_EXTRA_POINTS VolleyballMarket = 910209
+ VOLLEYBALL_SET_ONE_TOTAL_ODD_EVEN VolleyballMarket = 910218
+)
+
// TODO: Move this into the database so that it can be modified dynamically

var SupportedMarkets = map[int64]bool{
@@ -189,16 +200,26 @@ var SupportedMarkets = map[int64]bool{
int64(ICE_HOCKEY_ALTERNATIVE_TOTAL_TWO_WAY): false,

// Cricket Markets
- int64(CRICKET_TO_WIN_THE_MATCH): true,
- int64(CRICKET_FIRST_OVER_TOTAL_RUNS_Odd_Even): true,
- int64(CRICKET_FIRST_INNINIGS_SCORE): true,
-
- int64(CRICKET_INNINGS_OF_MATCH_BOWLED_OUT): false,
- int64(CRICKET_FIRST_OVER_TOTAL_RUNS): false,
- int64(CRICKET_TEAM_TOP_BATTER): false,
- int64(CRICKET_TEAM_TOP_BOWLE): false,
- int64(CRICKET_PLAYER_OF_THE_MATCH): false,
- int64(CRICKET_FIRST_WICKET_METHOD): false,
- int64(CRICKET_TOP_MATCH_BATTER): false,
- int64(CRICKET_TOP_MATCH_BOWLER): false,
+ int64(CRICKET_TO_WIN_THE_MATCH): true,
+
+ int64(CRICKET_FIRST_OVER_TOTAL_RUNS_Odd_Even): false,
+ int64(CRICKET_FIRST_INNINIGS_SCORE): false,
+ int64(CRICKET_INNINGS_OF_MATCH_BOWLED_OUT): false,
+ int64(CRICKET_FIRST_OVER_TOTAL_RUNS): false,
+ int64(CRICKET_TEAM_TOP_BATTER): false,
+ int64(CRICKET_TEAM_TOP_BOWLE): false,
+ int64(CRICKET_PLAYER_OF_THE_MATCH): false,
+ int64(CRICKET_FIRST_WICKET_METHOD): false,
+ int64(CRICKET_TOP_MATCH_BATTER): false,
+ int64(CRICKET_TOP_MATCH_BOWLER): false,
+
+ // Volleyball Markets
+ int64(VOLLEYBALL_GAME_LINES): false,
+
+ int64(VOLLEYBALL_CORRECT_SET_SCORE): true,
+ int64(VOLLEYBALL_MATCH_TOTAL_ODD_EVEN): true,
+
+ int64(VOLLEYBALL_SET_ONE_LINES): false,
+ int64(VOLLEYBALL_SET_ONE_TO_GO_TO_EXTRA_POINTS): false,
+ int64(VOLLEYBALL_SET_ONE_TOTAL_ODD_EVEN): false,
}
diff --git a/internal/services/result/eval.go b/internal/services/result/eval.go
index 8c21390..5d7cd66 100644
--- a/internal/services/result/eval.go
+++ b/internal/services/result/eval.go
@@ -708,47 +708,3 @@ func evaluateTiedAfterRegulation(outcome domain.BetOutcome, scores []struct{ Hom

return domain.OUTCOME_STATUS_PENDING, fmt.Errorf("invalid oddname: %s", outcome.OddName)
}
-
-// Cricket evalations
-func evaluateInningScore(outcome domain.BetOutcome, score struct{ Home, Away int }) (domain.OutcomeStatus, error) {
- var inningsScore int
- if outcome.OddName == "1" {
- inningsScore = score.Home
- } else if outcome.OddName == "2" {
- inningsScore = score.Away
- } else {
- return domain.OUTCOME_STATUS_PENDING, fmt.Errorf("invalid odd header: %s", outcome.OddHeader)
- }
-
- parts := strings.Fields(outcome.OddHeader)
- if len(parts) != 2 {
- return domain.OUTCOME_STATUS_PENDING, fmt.Errorf("invalid odd format: %s", outcome.OddHeader)
- }
-
- evalType := parts[0]
-
- threshold, err := strconv.ParseFloat(parts[1], 64)
- if err != nil {
- return domain.OUTCOME_STATUS_PENDING, fmt.Errorf("invalid threshold value: %s", parts[1])
- }
-
- switch evalType {
- case "Over":
- if float64(inningsScore) > threshold {
- return domain.OUTCOME_STATUS_WIN, nil
- }
- return domain.OUTCOME_STATUS_LOSS, nil
- case "Under":
- if float64(inningsScore) < threshold {
- return domain.OUTCOME_STATUS_WIN, nil
- }
- return domain.OUTCOME_STATUS_LOSS, nil
- case "Exactly":
- if float64(inningsScore) == threshold {
- return domain.OUTCOME_STATUS_WIN, nil
- }
- return domain.OUTCOME_STATUS_LOSS, nil
- default:
- return domain.OUTCOME_STATUS_PENDING, fmt.Errorf("invalid comparison operator: %s", evalType)
- }
-}
diff --git a/internal/services/result/service.go b/internal/services/result/service.go
index fcbff6b..92886c3 100644
--- a/internal/services/result/service.go
+++ b/internal/services/result/service.go
@@ -226,6 +226,12 @@ func (s *Service) fetchResult(ctx context.Context, eventID, oddID, marketID, spo
s.logger.Error("Failed to parse cricket", "event id", eventID, "market_id", marketID, "error", err)
return domain.CreateResult{}, err
}
+ case domain.VOLLEYBALL:
+ result, err = s.parseVolleyball(resultResp.Results[0], eventID, oddID, marketID, outcome)
+ if err != nil {
+ s.logger.Error("Failed to parse cricket", "event id", eventID, "market_id", marketID, "error", err)
+ return domain.CreateResult{}, err
+ }
default:
s.logger.Error("Unsupported sport", "sport", sportID)
return domain.CreateResult{}, fmt.Errorf("unsupported sport: %v", sportID)
@@ -271,9 +277,6 @@ func (s *Service) parseFootball(resultRes json.RawMessage, eventID, oddID, marke
func (s *Service) parseBasketball(response json.RawMessage, eventID, oddID, marketID int64, outcome domain.BetOutcome) (domain.CreateResult, error) {
var basketBallRes domain.BasketballResultResponse

- // TODO: here !!
- fmt.Println(string(response))
-
if err := json.Unmarshal(response, &basketBallRes); err != nil {
s.logger.Error("Failed to unmarshal football result", "event_id", eventID, "error", err)
return domain.CreateResult{}, err
@@ -355,6 +358,34 @@ func (s *Service) parseCricket(response json.RawMessage, eventID, oddID, marketI
}, nil
}

+func (s *Service) parseVolleyball(response json.RawMessage, eventID, oddID, marketID int64, outcome domain.BetOutcome) (domain.CreateResult, error) {
+ var volleyballRes domain.VolleyballResultResponse
+
+ if err := json.Unmarshal(response, &volleyballRes); err != nil {
+ s.logger.Error("Failed to unmarshal football result", "event_id", eventID, "error", err)
+ return domain.CreateResult{}, err
+ }
+ if volleyballRes.TimeStatus != "3" {
+ s.logger.Warn("Match not yet completed", "event_id", eventID)
+ return domain.CreateResult{}, fmt.Errorf("match not yet completed")
+ }
+
+ status, err := s.evaluateVolleyballOutcome(outcome, volleyballRes)
+ if err != nil {
+ s.logger.Error("Failed to evaluate outcome", "event_id", eventID, "market_id", marketID, "error", err)
+ return domain.CreateResult{}, err
+ }
+
+ return domain.CreateResult{
+ BetOutcomeID: 0,
+ EventID: eventID,
+ OddID: oddID,
+ MarketID: marketID,
+ Status: status,
+ }, nil
+
+}
+
func parseScore(home string, away string) struct{ Home, Away int } {
homeVal, _ := strconv.Atoi(strings.TrimSpace(home))
awaVal, _ := strconv.Atoi(strings.TrimSpace(away))
@@ -537,10 +568,27 @@ func (s *Service) evaluateCricketOutcome(outcome domain.BetOutcome, res domain.C
switch outcome.MarketID {
case int64(domain.CRICKET_TO_WIN_THE_MATCH):
return evaluateFullTimeResult(outcome, score)
- case int64(domain.CRICKET_FIRST_OVER_TOTAL_RUNS_Odd_Even):
+ }
+
+ return domain.OUTCOME_STATUS_PENDING, nil
+}
+
+func (s *Service) evaluateVolleyballOutcome(outcome domain.BetOutcome, res domain.VolleyballResultResponse) (domain.OutcomeStatus, error) {
+ if !domain.SupportedMarkets[outcome.MarketID] {
+ s.logger.Warn("Unsupported market type", "market_name", outcome.MarketName)
+ return domain.OUTCOME_STATUS_PENDING, fmt.Errorf("unsupported market type: %s", outcome.MarketName)
+ }
+
+ score := parseSS(res.SS)
+
+ switch outcome.MarketID {
+ // new Game line since its different from basket ball
+ case int64(domain.VOLLEYBALL_GAME_LINES):
+ return evaluateGameLines(outcome, score)
+ case int64(domain.VOLLEYBALL_CORRECT_SET_SCORE):
+ return evaluateCorrectScore(outcome, score)
+ case int64(domain.VOLLEYBALL_MATCH_TOTAL_ODD_EVEN):
return evaluateGoalsOddEven(outcome, score)
- case int64(domain.CRICKET_FIRST_INNINIGS_SCORE):
- return evaluateInningScore(outcome, score)
}

return domain.OUTCOME_STATUS_PENDING, nil