Fix barcode direct print

parent 69e46405
......@@ -4291,6 +4291,10 @@ def get_cashier_bets():
else:
target_date = date.today()
# Get filter parameters
status_filter = request.args.get('status', '').strip()
match_number_filter = request.args.get('match_number', '').strip()
session = api_bp.db_manager.get_session()
try:
# Import models
......@@ -4326,6 +4330,17 @@ def get_cashier_bets():
BetModel.bet_datetime <= end_datetime
).order_by(BetModel.bet_datetime.desc())
# Apply match number filter if specified
if match_number_filter:
try:
match_number = int(match_number_filter)
# Filter bets that have details for the specified match number
bets_query = bets_query.join(BetDetailModel).join(MatchModel).filter(
MatchModel.match_number == match_number
).distinct()
except ValueError:
return jsonify({"error": "Invalid match number format"}), 400
bets = bets_query.all()
logger.info(f"Found {len(bets)} bets in database for date {date_param}")
bets_data = []
......@@ -4347,13 +4362,14 @@ def get_cashier_bets():
# Calculate total amount for this bet
bet_total = sum(float(detail.amount) for detail in bet_details)
bet_data['total_amount'] = bet_total
total_amount += bet_total
# Determine overall bet status for statistics using same logic as bet details page
# Determine overall bet status for filtering and statistics using same logic as bet details page
overall_status = 'pending'
if bet_details:
won_count = 0
lost_count = 0
pending_count = 0
cancelled_count = 0
for detail in bet_details:
# Get match information for winning check
......@@ -4366,16 +4382,33 @@ def get_cashier_bets():
elif detail.result == 'pending':
pending_count += 1
elif detail.result == 'cancelled':
lost_count += 1 # Treat cancelled as lost for statistics
cancelled_count += 1
# Determine overall status
if pending_count > 0:
overall_status = 'pending'
elif won_count > 0 and lost_count == 0 and cancelled_count == 0:
overall_status = 'won'
elif lost_count > 0 or cancelled_count > 0:
overall_status = 'lost'
elif cancelled_count > 0:
overall_status = 'cancelled'
bet_data['overall_status'] = overall_status
if won_count > 0 and lost_count == 0 and pending_count == 0:
# Apply status filter if specified
if status_filter and status_filter != overall_status:
continue # Skip this bet if it doesn't match the status filter
total_amount += bet_total
# Update statistics counters
if overall_status == 'won':
won_bets += 1
elif lost_count > 0:
elif overall_status == 'lost':
lost_bets += 1
else:
pending_bets += 1
else:
pending_bets += 1
bets_data.append(bet_data)
......
......@@ -330,13 +330,7 @@ body {
}
}
/* Dark mode support (future enhancement) */
@media (prefers-color-scheme: dark) {
:root {
--bs-body-bg: #1a1a1a;
--bs-body-color: #f8f9fa;
}
}
/* Dark mode support disabled - forced light mode */
/* Loading states */
.loading {
......
<!DOCTYPE html>
<html lang="en">
<html lang="en" data-bs-theme="light">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
......
......@@ -47,13 +47,13 @@
<div class="card mb-4">
<div class="card-header">
<div class="row">
<div class="col-md-8">
<div class="col-md-4">
<h5 class="card-title mb-0">
<i class="fas fa-calendar-alt me-2"></i>Bets for Today
<span class="badge bg-info ms-2" id="bets-count">0</span>
</h5>
</div>
<div class="col-md-4">
<div class="col-md-2">
<div class="input-group">
<span class="input-group-text">
<i class="fas fa-calendar"></i>
......@@ -62,6 +62,19 @@
value="{{ today_date }}" max="{{ today_date }}">
</div>
</div>
<div class="col-md-3">
<select class="form-select" id="bet-status-filter">
<option value="">All Status</option>
<option value="won">Won</option>
<option value="lost">Lost</option>
<option value="pending">Pending</option>
<option value="cancelled">Cancelled</option>
</select>
</div>
<div class="col-md-3">
<input type="number" class="form-control" id="match-number-filter"
placeholder="Match # (optional)" min="1">
</div>
</div>
</div>
<div class="card-body">
......@@ -331,6 +344,16 @@ document.addEventListener('DOMContentLoaded', function() {
loadBets();
});
// Status filter change event
document.getElementById('bet-status-filter').addEventListener('change', function() {
loadBets();
});
// Match number filter change event
document.getElementById('match-number-filter').addEventListener('input', function() {
loadBets();
});
// New bet button
document.getElementById('btn-new-bet').addEventListener('click', function() {
window.location.href = '/bets/new';
......@@ -398,14 +421,23 @@ function loadBets() {
const container = document.getElementById('bets-container');
const countBadge = document.getElementById('bets-count');
const dateInput = document.getElementById('bet-date-picker');
const statusFilter = document.getElementById('bet-status-filter');
const matchFilter = document.getElementById('match-number-filter');
const selectedDate = dateInput.value;
const selectedStatus = statusFilter.value;
const selectedMatch = matchFilter.value;
if (!container) {
console.error('❌ bets-container not found');
return;
}
console.log('📡 Making API request to /api/cashier/bets for date:', selectedDate);
console.log('📡 Making API request to /api/cashier/bets with filters:', {
date: selectedDate,
status: selectedStatus,
match: selectedMatch
});
// Show loading state
container.innerHTML = `
......@@ -414,7 +446,16 @@ function loadBets() {
</div>
`;
fetch(`/api/cashier/bets?date=${selectedDate}`)
// Build query string with filters
let queryParams = `date=${selectedDate}`;
if (selectedStatus) {
queryParams += `&status=${selectedStatus}`;
}
if (selectedMatch) {
queryParams += `&match_number=${selectedMatch}`;
}
fetch(`/api/cashier/bets?${queryParams}`)
.then(response => {
console.log('📡 API response status:', response.status);
if (!response.ok) {
......
......@@ -839,9 +839,10 @@ function generateVerificationCodes(betUuid) {
.then(settings => {
if (settings.success && settings.settings && settings.settings.show_on_thermal) {
// Generate barcode image using the saved barcode data
fetch(`/api/barcode/${betUuid}`)
return fetch(`/api/barcode/${betUuid}`)
.then(response => response.blob())
.then(blob => {
return new Promise((resolve) => {
const reader = new FileReader();
reader.onload = function() {
const base64 = reader.result;
......@@ -859,8 +860,12 @@ function generateVerificationCodes(betUuid) {
if (barcodeElement) {
barcodeElement.innerHTML = `<img src="${base64}" alt="Barcode" class="barcode-img" style="width: 200px; height: 100px;">`;
}
resolve();
};
reader.readAsDataURL(blob);
});
})
.then(() => {
checkComplete();
})
.catch(error => {
......
......@@ -47,13 +47,13 @@
<div class="card mb-4">
<div class="card-header">
<div class="row">
<div class="col-md-8">
<div class="col-md-4">
<h5 class="card-title mb-0">
<i class="fas fa-calendar-alt me-2"></i>Bets for Today
<span class="badge bg-info ms-2" id="bets-count">0</span>
</h5>
</div>
<div class="col-md-4">
<div class="col-md-2">
<div class="input-group">
<span class="input-group-text">
<i class="fas fa-calendar"></i>
......@@ -62,6 +62,19 @@
value="{{ today_date }}" max="{{ today_date }}">
</div>
</div>
<div class="col-md-3">
<select class="form-select" id="bet-status-filter">
<option value="">All Status</option>
<option value="won">Won</option>
<option value="lost">Lost</option>
<option value="pending">Pending</option>
<option value="cancelled">Cancelled</option>
</select>
</div>
<div class="col-md-3">
<input type="number" class="form-control" id="match-number-filter"
placeholder="Match # (optional)" min="1">
</div>
</div>
</div>
<div class="card-body">
......@@ -328,6 +341,16 @@ document.addEventListener('DOMContentLoaded', function() {
loadBets();
});
// Status filter change event
document.getElementById('bet-status-filter').addEventListener('change', function() {
loadBets();
});
// Match number filter change event
document.getElementById('match-number-filter').addEventListener('input', function() {
loadBets();
});
// New bet button
document.getElementById('btn-new-bet').addEventListener('click', function() {
window.location.href = '/cashier/bets/new';
......@@ -398,14 +421,23 @@ function loadBets() {
const container = document.getElementById('bets-container');
const countBadge = document.getElementById('bets-count');
const dateInput = document.getElementById('bet-date-picker');
const statusFilter = document.getElementById('bet-status-filter');
const matchFilter = document.getElementById('match-number-filter');
const selectedDate = dateInput.value;
const selectedStatus = statusFilter.value;
const selectedMatch = matchFilter.value;
if (!container) {
console.error('❌ bets-container not found');
return;
}
console.log('📡 Making API request to /api/cashier/bets for date:', selectedDate);
console.log('📡 Making API request to /api/cashier/bets with filters:', {
date: selectedDate,
status: selectedStatus,
match: selectedMatch
});
// Show loading state
container.innerHTML = `
......@@ -414,7 +446,16 @@ function loadBets() {
</div>
`;
fetch(`/api/cashier/bets?date=${selectedDate}`)
// Build query string with filters
let queryParams = `date=${selectedDate}`;
if (selectedStatus) {
queryParams += `&status=${selectedStatus}`;
}
if (selectedMatch) {
queryParams += `&match_number=${selectedMatch}`;
}
fetch(`/api/cashier/bets?${queryParams}`)
.then(response => {
console.log('📡 API response status:', response.status);
if (!response.ok) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment