Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in
Toggle navigation
M
MBetterc
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Mbetter
MBetterc
Commits
32d6926c
Commit
32d6926c
authored
May 14, 2026
by
Your Name
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Align report views with settled bets
parent
03d2e1c8
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
80 additions
and
19 deletions
+80
-19
client.py
mbetterclient/api_client/client.py
+3
-2
routes.py
mbetterclient/web_dashboard/routes.py
+27
-12
test_reports_daily_alignment.py
test_reports_daily_alignment.py
+39
-5
test_reports_sync_summary.py
test_reports_sync_summary.py
+11
-0
No files found.
mbetterclient/api_client/client.py
View file @
32d6926c
...
@@ -1120,8 +1120,7 @@ class ReportsSyncResponseHandler(ResponseHandler):
...
@@ -1120,8 +1120,7 @@ class ReportsSyncResponseHandler(ResponseHandler):
stats_to_sync
.
append
(
stat
)
stats_to_sync
.
append
(
stat
)
logger
.
debug
(
f
"Extraction stat {stat.match_id} is new, including in sync"
)
logger
.
debug
(
f
"Extraction stat {stat.match_id} is new, including in sync"
)
# Get cap compensation balance (accumulated shortfall)
# Get global redistribution carryover separately from day totals.
# Use the global record (date 1970-01-01) to match dashboard display
cap_compensation_balance
=
0.0
cap_compensation_balance
=
0.0
try
:
try
:
from
datetime
import
date
from
datetime
import
date
...
@@ -1155,10 +1154,12 @@ class ReportsSyncResponseHandler(ResponseHandler):
...
@@ -1155,10 +1154,12 @@ class ReportsSyncResponseHandler(ResponseHandler):
'bets'
:
[],
'bets'
:
[],
'extraction_stats'
:
[],
'extraction_stats'
:
[],
'cap_compensation_balance'
:
cap_compensation_balance
,
'cap_compensation_balance'
:
cap_compensation_balance
,
'global_carryover_balance'
:
cap_compensation_balance
,
'summary'
:
self
.
_calculate_summary
(
bets_to_sync
,
stats
),
# Use bets_to_sync which have bet_details loaded
'summary'
:
self
.
_calculate_summary
(
bets_to_sync
,
stats
),
# Use bets_to_sync which have bet_details loaded
'is_incremental'
:
True
,
# Flag to indicate this is an incremental sync
'is_incremental'
:
True
,
# Flag to indicate this is an incremental sync
'sync_type'
:
'incremental'
if
last_sync_time
else
'full'
'sync_type'
:
'incremental'
if
last_sync_time
else
'full'
}
}
report_data
[
'summary'
][
'global_carryover_balance'
]
=
float
(
cap_compensation_balance
)
# Add bets data (only new/updated bets)
# Add bets data (only new/updated bets)
for
bet
in
bets_to_sync
:
for
bet
in
bets_to_sync
:
...
...
mbetterclient/web_dashboard/routes.py
View file @
32d6926c
...
@@ -88,6 +88,17 @@ def is_bet_detail_winning(detail, match, session):
...
@@ -88,6 +88,17 @@ def is_bet_detail_winning(detail, match, session):
return
False
return
False
def
is_settled_bet_detail_winning
(
detail
,
match
,
session
):
"""Prefer settled row status for completed matches, fallback to inferred logic otherwise."""
if
detail
.
result
==
'win'
:
return
True
if
detail
.
result
in
[
'lost'
,
'cancelled'
]:
return
False
if
match
and
getattr
(
match
,
'status'
,
None
)
==
'done'
:
return
False
return
is_bet_detail_winning
(
detail
,
match
,
session
)
def
get_api_auth_decorator
(
require_admin
=
False
):
def
get_api_auth_decorator
(
require_admin
=
False
):
"""Get API auth decorator that works with lazy initialization"""
"""Get API auth decorator that works with lazy initialization"""
def
decorator
(
func
):
def
decorator
(
func
):
...
@@ -448,7 +459,7 @@ def bet_details(bet_id):
...
@@ -448,7 +459,7 @@ def bet_details(bet_id):
if
detail
.
result
==
'pending'
:
if
detail
.
result
==
'pending'
:
results
[
'pending'
]
+=
1
results
[
'pending'
]
+=
1
has_pending
=
True
has_pending
=
True
elif
is_bet_detail_winning
(
detail
,
match
,
session
):
elif
is_
settled_
bet_detail_winning
(
detail
,
match
,
session
):
results
[
'won'
]
+=
1
results
[
'won'
]
+=
1
results
[
'winnings'
]
+=
float
(
detail
.
amount
)
*
float
(
odds
)
# Use actual odds
results
[
'winnings'
]
+=
float
(
detail
.
amount
)
*
float
(
odds
)
# Use actual odds
elif
detail
.
result
==
'lost'
:
elif
detail
.
result
==
'lost'
:
...
@@ -1112,7 +1123,7 @@ def cashier_bet_details(bet_id):
...
@@ -1112,7 +1123,7 @@ def cashier_bet_details(bet_id):
if
detail
.
result
==
'pending'
:
if
detail
.
result
==
'pending'
:
results
[
'pending'
]
+=
1
results
[
'pending'
]
+=
1
has_pending
=
True
has_pending
=
True
elif
is_bet_detail_winning
(
detail
,
match
,
session
):
elif
is_
settled_
bet_detail_winning
(
detail
,
match
,
session
):
results
[
'won'
]
+=
1
results
[
'won'
]
+=
1
results
[
'winnings'
]
+=
float
(
detail
.
win_amount
or
0
)
# Use actual win amount
results
[
'winnings'
]
+=
float
(
detail
.
win_amount
or
0
)
# Use actual win amount
elif
detail
.
result
==
'lost'
:
elif
detail
.
result
==
'lost'
:
...
@@ -6579,7 +6590,7 @@ def get_cashier_bets():
...
@@ -6579,7 +6590,7 @@ def get_cashier_bets():
# Get match information for winning check
# Get match information for winning check
match
=
session
.
query
(
MatchModel
)
.
filter_by
(
id
=
detail
.
match_id
)
.
first
()
match
=
session
.
query
(
MatchModel
)
.
filter_by
(
id
=
detail
.
match_id
)
.
first
()
if
is_bet_detail_winning
(
detail
,
match
,
session
):
if
is_
settled_
bet_detail_winning
(
detail
,
match
,
session
):
won_count
+=
1
won_count
+=
1
elif
detail
.
result
==
'lost'
:
elif
detail
.
result
==
'lost'
:
lost_count
+=
1
lost_count
+=
1
...
@@ -6933,7 +6944,7 @@ def get_cashier_bet_details(bet_id):
...
@@ -6933,7 +6944,7 @@ def get_cashier_bet_details(bet_id):
for
detail
in
bet_details
:
for
detail
in
bet_details
:
if
detail
.
result
==
'pending'
:
if
detail
.
result
==
'pending'
:
results
[
'pending'
]
+=
1
results
[
'pending'
]
+=
1
elif
is_bet_detail_winning
(
detail
,
session
.
query
(
MatchModel
)
.
filter_by
(
id
=
detail
.
match_id
)
.
first
(),
session
):
elif
is_
settled_
bet_detail_winning
(
detail
,
session
.
query
(
MatchModel
)
.
filter_by
(
id
=
detail
.
match_id
)
.
first
(),
session
):
results
[
'won'
]
+=
1
results
[
'won'
]
+=
1
# Get odds for this outcome
# Get odds for this outcome
odds
=
0.0
odds
=
0.0
...
@@ -7467,7 +7478,7 @@ def verify_barcode():
...
@@ -7467,7 +7478,7 @@ def verify_barcode():
for
detail
in
bet_details
:
for
detail
in
bet_details
:
if
detail
.
result
==
'pending'
:
if
detail
.
result
==
'pending'
:
results
[
'pending'
]
+=
1
results
[
'pending'
]
+=
1
elif
is_bet_detail_winning
(
detail
,
session
.
query
(
MatchModel
)
.
filter_by
(
id
=
detail
.
match_id
)
.
first
(),
session
):
elif
is_
settled_
bet_detail_winning
(
detail
,
session
.
query
(
MatchModel
)
.
filter_by
(
id
=
detail
.
match_id
)
.
first
(),
session
):
results
[
'won'
]
+=
1
results
[
'won'
]
+=
1
# Get odds for this outcome
# Get odds for this outcome
odds
=
0.0
odds
=
0.0
...
@@ -7850,7 +7861,7 @@ def get_daily_reports_summary():
...
@@ -7850,7 +7861,7 @@ def get_daily_reports_summary():
total_payout
=
0.0
total_payout
=
0.0
for
detail
in
bet_details
:
for
detail
in
bet_details
:
match
=
session
.
query
(
MatchModel
)
.
filter_by
(
id
=
detail
.
match_id
)
.
first
()
match
=
session
.
query
(
MatchModel
)
.
filter_by
(
id
=
detail
.
match_id
)
.
first
()
if
is_bet_detail_winning
(
detail
,
match
,
session
):
if
is_
settled_
bet_detail_winning
(
detail
,
match
,
session
):
total_payout
+=
float
(
detail
.
win_amount
or
0
)
total_payout
+=
float
(
detail
.
win_amount
or
0
)
# Get unique matches count
# Get unique matches count
...
@@ -7951,7 +7962,7 @@ def get_match_reports():
...
@@ -7951,7 +7962,7 @@ def get_match_reports():
# Calculate payout using actual win_amount (stored when bet was settled)
# Calculate payout using actual win_amount (stored when bet was settled)
# This ensures consistency with bet list and avoids recalculation issues
# This ensures consistency with bet list and avoids recalculation issues
if
is_bet_detail_winning
(
detail
,
match
,
session
):
if
is_
settled_
bet_detail_winning
(
detail
,
match
,
session
):
# Use the actual win_amount stored when the bet was settled
# Use the actual win_amount stored when the bet was settled
match_stats
[
match_id
][
'payout'
]
+=
float
(
detail
.
win_amount
or
0
)
match_stats
[
match_id
][
'payout'
]
+=
float
(
detail
.
win_amount
or
0
)
...
@@ -8029,7 +8040,9 @@ def get_match_details():
...
@@ -8029,7 +8040,9 @@ def get_match_details():
logger
.
info
(
f
"Querying match details for match {match_id}, local date {date_param}: UTC range {start_datetime} to {end_datetime}"
)
logger
.
info
(
f
"Querying match details for match {match_id}, local date {date_param}: UTC range {start_datetime} to {end_datetime}"
)
# Get bet details for this match on this date
# Get bet details for this match on this date
bet_details_query
=
session
.
query
(
BetDetailModel
)
.
join
(
BetModel
)
.
filter
(
bet_details_query
=
session
.
query
(
BetDetailModel
)
.
join
(
BetModel
,
BetDetailModel
.
bet_id
==
BetModel
.
uuid
)
.
filter
(
BetDetailModel
.
match_id
==
match_id
,
BetDetailModel
.
match_id
==
match_id
,
BetModel
.
bet_datetime
>=
start_datetime
,
BetModel
.
bet_datetime
>=
start_datetime
,
BetModel
.
bet_datetime
<=
end_datetime
BetModel
.
bet_datetime
<=
end_datetime
...
@@ -8057,7 +8070,7 @@ def get_match_details():
...
@@ -8057,7 +8070,7 @@ def get_match_details():
# Determine actual result status using is_bet_detail_winning function
# Determine actual result status using is_bet_detail_winning function
# This checks if bet detail is winning based on match's winning outcomes
# This checks if bet detail is winning based on match's winning outcomes
actual_result
=
detail
.
result
actual_result
=
detail
.
result
if
is_bet_detail_winning
(
detail
,
match
,
session
):
if
is_
settled_
bet_detail_winning
(
detail
,
match
,
session
):
actual_result
=
'won'
actual_result
=
'won'
elif
detail
.
result
==
'lost'
:
elif
detail
.
result
==
'lost'
:
actual_result
=
'lost'
actual_result
=
'lost'
...
@@ -8190,7 +8203,7 @@ def download_excel_report():
...
@@ -8190,7 +8203,7 @@ def download_excel_report():
total_payout
=
0.0
total_payout
=
0.0
for
detail
in
bet_details
:
for
detail
in
bet_details
:
match
=
session
.
query
(
MatchModel
)
.
filter_by
(
id
=
detail
.
match_id
)
.
first
()
match
=
session
.
query
(
MatchModel
)
.
filter_by
(
id
=
detail
.
match_id
)
.
first
()
if
is_bet_detail_winning
(
detail
,
match
,
session
):
if
is_
settled_
bet_detail_winning
(
detail
,
match
,
session
):
total_payout
+=
float
(
detail
.
win_amount
or
0
)
total_payout
+=
float
(
detail
.
win_amount
or
0
)
unique_match_ids
=
{
detail
.
match_id
for
detail
in
bet_details
}
unique_match_ids
=
{
detail
.
match_id
for
detail
in
bet_details
}
...
@@ -8237,7 +8250,9 @@ def download_excel_report():
...
@@ -8237,7 +8250,9 @@ def download_excel_report():
cell
.
alignment
=
Alignment
(
horizontal
=
'center'
)
cell
.
alignment
=
Alignment
(
horizontal
=
'center'
)
# Get match data (excluding cancelled bets)
# Get match data (excluding cancelled bets)
bet_details_query
=
session
.
query
(
BetDetailModel
)
.
join
(
BetModel
)
.
filter
(
bet_details_query
=
session
.
query
(
BetDetailModel
)
.
join
(
BetModel
,
BetDetailModel
.
bet_id
==
BetModel
.
uuid
)
.
filter
(
BetModel
.
bet_datetime
>=
start_datetime
,
BetModel
.
bet_datetime
>=
start_datetime
,
BetModel
.
bet_datetime
<=
end_datetime
,
BetModel
.
bet_datetime
<=
end_datetime
,
BetDetailModel
.
result
!=
'cancelled'
BetDetailModel
.
result
!=
'cancelled'
...
@@ -8261,7 +8276,7 @@ def download_excel_report():
...
@@ -8261,7 +8276,7 @@ def download_excel_report():
# Add actual payout for winning bets (use same logic as bet list)
# Add actual payout for winning bets (use same logic as bet list)
match
=
session
.
query
(
MatchModel
)
.
filter_by
(
id
=
match_id
)
.
first
()
match
=
session
.
query
(
MatchModel
)
.
filter_by
(
id
=
match_id
)
.
first
()
if
is_bet_detail_winning
(
detail
,
match
,
session
):
if
is_
settled_
bet_detail_winning
(
detail
,
match
,
session
):
match_stats
[
match_id
][
'payout'
]
+=
float
(
detail
.
win_amount
or
0
)
match_stats
[
match_id
][
'payout'
]
+=
float
(
detail
.
win_amount
or
0
)
# Write match data
# Write match data
...
...
test_reports_daily_alignment.py
View file @
32d6926c
...
@@ -11,7 +11,7 @@ from openpyxl import load_workbook
...
@@ -11,7 +11,7 @@ from openpyxl import load_workbook
sys
.
path
.
insert
(
0
,
os
.
path
.
dirname
(
os
.
path
.
abspath
(
__file__
)))
sys
.
path
.
insert
(
0
,
os
.
path
.
dirname
(
os
.
path
.
abspath
(
__file__
)))
from
mbetterclient.web_dashboard
import
routes
as
routes_module
from
mbetterclient.web_dashboard
import
routes
as
routes_module
from
mbetterclient.web_dashboard.routes
import
api_bp
,
is_bet_detail_winning
from
mbetterclient.web_dashboard.routes
import
api_bp
,
is_bet_detail_winning
,
is_settled_bet_detail_winning
class
DummyDetail
:
class
DummyDetail
:
...
@@ -167,6 +167,9 @@ class DummyModelColumn:
...
@@ -167,6 +167,9 @@ class DummyModelColumn:
def
__ne__
(
self
,
other
):
def
__ne__
(
self
,
other
):
return
(
'!='
,
self
.
name
,
other
)
return
(
'!='
,
self
.
name
,
other
)
def
desc
(
self
):
return
self
def
_dummy_model
(
name
,
**
columns
):
def
_dummy_model
(
name
,
**
columns
):
attrs
=
{
'__name__'
:
name
}
attrs
=
{
'__name__'
:
name
}
...
@@ -237,6 +240,7 @@ def build_sample_excel_bytes(monkeypatch, blueprint):
...
@@ -237,6 +240,7 @@ def build_sample_excel_bytes(monkeypatch, blueprint):
cancelled_bet
=
DummyBet
(
uuid
=
'bet-cancelled'
,
bet_datetime
=
datetime
(
2026
,
5
,
1
,
13
,
0
,
0
))
cancelled_bet
=
DummyBet
(
uuid
=
'bet-cancelled'
,
bet_datetime
=
datetime
(
2026
,
5
,
1
,
13
,
0
,
0
))
out_of_window_bet
=
DummyBet
(
uuid
=
'bet-outside'
,
bet_datetime
=
datetime
(
2026
,
5
,
2
,
12
,
0
,
0
))
out_of_window_bet
=
DummyBet
(
uuid
=
'bet-outside'
,
bet_datetime
=
datetime
(
2026
,
5
,
2
,
12
,
0
,
0
))
match
=
DummyMatch
(
match_id
=
10
)
match
=
DummyMatch
(
match_id
=
10
)
match
.
status
=
'ingame'
outside_match
=
DummyMatch
(
match_id
=
99
,
match_number
=
2
)
outside_match
=
DummyMatch
(
match_id
=
99
,
match_number
=
2
)
extraction_stat
=
type
(
'ExtractionStat'
,
(),
{
'match_datetime'
:
datetime
(
2026
,
5
,
1
,
15
,
0
,
0
),
'total_redistributed'
:
999.0
})()
extraction_stat
=
type
(
'ExtractionStat'
,
(),
{
'match_datetime'
:
datetime
(
2026
,
5
,
1
,
15
,
0
,
0
),
'total_redistributed'
:
999.0
})()
session
=
DummySession
(
session
=
DummySession
(
...
@@ -254,14 +258,27 @@ def build_sample_excel_bytes(monkeypatch, blueprint):
...
@@ -254,14 +258,27 @@ def build_sample_excel_bytes(monkeypatch, blueprint):
def
test_match_report_payout_uses_loaded_match
():
def
test_match_report_payout_uses_loaded_match
():
detail
=
DummyDetail
(
match_id
=
10
,
amount
=
100.0
,
win_amount
=
250.0
,
result
=
'lost'
)
detail
=
DummyDetail
(
match_id
=
10
,
amount
=
100.0
,
win_amount
=
250.0
,
result
=
'lost'
)
match
=
DummyMatch
(
match_id
=
10
)
match
=
DummyMatch
(
match_id
=
10
)
match
.
status
=
'ingame'
session
=
Mock
()
session
=
Mock
()
assert
is_bet_detail_winning
(
detail
,
match
,
session
)
is
True
assert
is_bet_detail_winning
(
detail
,
match
,
session
)
is
True
def
test_settled_winning_check_prefers_explicit_lost_for_completed_match
():
detail
=
DummyDetail
(
match_id
=
10
,
amount
=
100.0
,
win_amount
=
250.0
,
result
=
'lost'
)
match
=
DummyMatch
(
match_id
=
10
)
match
.
status
=
'ingame'
match
.
status
=
'done'
session
=
Mock
()
assert
is_bet_detail_winning
(
detail
,
match
,
session
)
is
True
assert
is_settled_bet_detail_winning
(
detail
,
match
,
session
)
is
False
def
test_match_reports_route_counts_winning_payout_after_loading_match
(
monkeypatch
,
isolated_api_blueprint
):
def
test_match_reports_route_counts_winning_payout_after_loading_match
(
monkeypatch
,
isolated_api_blueprint
):
install_route_test_doubles
(
monkeypatch
)
install_route_test_doubles
(
monkeypatch
)
match
=
DummyMatch
(
match_id
=
10
)
match
=
DummyMatch
(
match_id
=
10
)
match
.
status
=
'ingame'
detail
=
DummyDetail
(
match_id
=
10
,
amount
=
100.0
,
win_amount
=
250.0
,
result
=
'lost'
)
detail
=
DummyDetail
(
match_id
=
10
,
amount
=
100.0
,
win_amount
=
250.0
,
result
=
'lost'
)
cancelled_detail
=
DummyDetail
(
match_id
=
10
,
amount
=
15.0
,
win_amount
=
0.0
,
result
=
'cancelled'
,
bet_id
=
'bet-cancelled'
)
cancelled_detail
=
DummyDetail
(
match_id
=
10
,
amount
=
15.0
,
win_amount
=
0.0
,
result
=
'cancelled'
,
bet_id
=
'bet-cancelled'
)
out_of_window_detail
=
DummyDetail
(
match_id
=
99
,
amount
=
50.0
,
win_amount
=
500.0
,
result
=
'lost'
,
bet_id
=
'bet-outside'
)
out_of_window_detail
=
DummyDetail
(
match_id
=
99
,
amount
=
50.0
,
win_amount
=
500.0
,
result
=
'lost'
,
bet_id
=
'bet-outside'
)
...
@@ -284,8 +301,8 @@ def test_match_reports_route_counts_winning_payout_after_loading_match(monkeypat
...
@@ -284,8 +301,8 @@ def test_match_reports_route_counts_winning_payout_after_loading_match(monkeypat
payload
=
response
.
get_json
()
payload
=
response
.
get_json
()
assert
payload
[
'total'
]
==
1
assert
payload
[
'total'
]
==
1
assert
payload
[
'matches'
][
0
][
'payin'
]
==
100.0
assert
payload
[
'matches'
][
0
][
'payin'
]
==
100.0
assert
payload
[
'matches'
][
0
][
'payout'
]
==
25
0.0
assert
payload
[
'matches'
][
0
][
'payout'
]
==
0.0
assert
payload
[
'matches'
][
0
][
'net'
]
==
-
15
0.0
assert
payload
[
'matches'
][
0
][
'net'
]
==
10
0.0
def
test_excel_summary_uses_same_payout_basis_as_daily_summary
(
monkeypatch
,
isolated_api_blueprint
):
def
test_excel_summary_uses_same_payout_basis_as_daily_summary
(
monkeypatch
,
isolated_api_blueprint
):
...
@@ -293,8 +310,8 @@ def test_excel_summary_uses_same_payout_basis_as_daily_summary(monkeypatch, isol
...
@@ -293,8 +310,8 @@ def test_excel_summary_uses_same_payout_basis_as_daily_summary(monkeypatch, isol
sheet
=
workbook
[
'Daily Summary'
]
sheet
=
workbook
[
'Daily Summary'
]
assert
sheet
[
'B4'
]
.
value
==
'100.00'
assert
sheet
[
'B4'
]
.
value
==
'100.00'
assert
sheet
[
'B5'
]
.
value
==
'
25
0.00'
assert
sheet
[
'B5'
]
.
value
==
'0.00'
assert
sheet
[
'B6'
]
.
value
==
'
-15
0.00'
assert
sheet
[
'B6'
]
.
value
==
'
10
0.00'
assert
sheet
[
'B7'
]
.
value
==
'1'
assert
sheet
[
'B7'
]
.
value
==
'1'
assert
sheet
[
'B8'
]
.
value
==
'1'
assert
sheet
[
'B8'
]
.
value
==
'1'
...
@@ -316,3 +333,20 @@ def test_excel_download_returns_xlsx_response(monkeypatch, isolated_api_blueprin
...
@@ -316,3 +333,20 @@ def test_excel_download_returns_xlsx_response(monkeypatch, isolated_api_blueprin
assert
response
.
status_code
==
200
assert
response
.
status_code
==
200
assert
response
.
mimetype
==
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
assert
response
.
mimetype
==
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
def
test_match_details_route_uses_explicit_join_for_bet_lookup
(
monkeypatch
,
isolated_api_blueprint
):
install_route_test_doubles
(
monkeypatch
)
detail
=
DummyDetail
(
match_id
=
10
,
amount
=
100.0
,
win_amount
=
250.0
,
result
=
'lost'
)
bet
=
DummyBet
(
uuid
=
'bet1'
,
bet_datetime
=
datetime
(
2026
,
5
,
1
,
12
,
0
,
0
))
match
=
DummyMatch
(
match_id
=
10
)
client
=
make_test_client
(
DummySession
([
detail
],
[
bet
],
[
match
]),
isolated_api_blueprint
,
)
response
=
client
.
get
(
'/api/reports/match-details?date=2026-05-01&match_id=10'
)
assert
response
.
status_code
==
200
payload
=
response
.
get_json
()
assert
payload
[
'total'
]
==
0
test_reports_sync_summary.py
View file @
32d6926c
...
@@ -46,3 +46,14 @@ def test_calculate_summary_uses_settled_rows_and_unique_matches(tmp_path):
...
@@ -46,3 +46,14 @@ def test_calculate_summary_uses_settled_rows_and_unique_matches(tmp_path):
finally
:
finally
:
session
.
close
()
session
.
close
()
db_manager
.
close
()
db_manager
.
close
()
def
test_calculate_summary_payload_can_carry_global_balance_separately
(
tmp_path
):
handler
,
db_manager
=
_build_handler
(
tmp_path
)
try
:
summary
=
handler
.
_calculate_summary
([],
stats
=
[])
assert
summary
[
'total_payin'
]
==
0.0
assert
summary
[
'total_payout'
]
==
0.0
assert
summary
[
'total_matches'
]
==
0
finally
:
db_manager
.
close
()
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment