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
3b50b307
Commit
3b50b307
authored
Dec 23, 2025
by
Stefy Lanza (nextime / spora )
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
New routeNes
parent
d0d28ab3
Changes
6
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
566 additions
and
429 deletions
+566
-429
barcode_utils.py
mbetterclient/utils/barcode_utils.py
+20
-21
routes.py
mbetterclient/web_dashboard/routes.py
+3
-8
admin_bet_details.html
.../web_dashboard/templates/dashboard/admin_bet_details.html
+136
-96
admin_bets.html
...rclient/web_dashboard/templates/dashboard/admin_bets.html
+129
-100
bet_details.html
...client/web_dashboard/templates/dashboard/bet_details.html
+149
-104
bets.html
mbetterclient/web_dashboard/templates/dashboard/bets.html
+129
-100
No files found.
mbetterclient/utils/barcode_utils.py
View file @
3b50b307
...
@@ -160,12 +160,15 @@ def generate_barcode_image(data: str, standard: str, width: int = 300, height: i
...
@@ -160,12 +160,15 @@ def generate_barcode_image(data: str, standard: str, width: int = 300, height: i
'text'
:
data
'text'
:
data
})
})
#
Gener
ate barcode
#
Cre
ate barcode
barcode_instance
=
barcode_class
(
data
,
writer
=
writer
)
barcode_instance
=
barcode_class
(
data
,
writer
=
writer
)
# Render to bytes
# Get PIL Image using render() method
pil_image
=
barcode_instance
.
render
()
# Save to bytes
buffer
=
BytesIO
()
buffer
=
BytesIO
()
barcode_instance
.
write
(
buffer
)
pil_image
.
save
(
buffer
,
format
=
'PNG'
)
buffer
.
seek
(
0
)
buffer
.
seek
(
0
)
image_bytes
=
buffer
.
getvalue
()
image_bytes
=
buffer
.
getvalue
()
...
@@ -216,16 +219,12 @@ def calculate_ean13_check_digit(data: str) -> str:
...
@@ -216,16 +219,12 @@ def calculate_ean13_check_digit(data: str) -> str:
raise
ValueError
(
"EAN-13 check digit calculation requires exactly 12 digits"
)
raise
ValueError
(
"EAN-13 check digit calculation requires exactly 12 digits"
)
# EAN-13 check digit calculation
# EAN-13 check digit calculation
# Step 1: Sum digits in odd positions (1st, 3rd, 5th, etc.) multiplied by 3
# Weights alternate starting with 1 for leftmost digit, 3 for next, etc.
odd_sum
=
sum
(
int
(
data
[
i
])
for
i
in
range
(
0
,
12
,
2
))
*
3
# This ensures the rightmost data digit gets weight 3
weights
=
[
1
,
3
,
1
,
3
,
1
,
3
,
1
,
3
,
1
,
3
,
1
,
3
]
# Step 2: Sum digits in even positions (2nd, 4th, 6th, etc.)
total
=
sum
(
int
(
data
[
i
])
*
weights
[
i
]
for
i
in
range
(
12
))
even_sum
=
sum
(
int
(
data
[
i
])
for
i
in
range
(
1
,
12
,
2
))
# Step 3: Total sum
total
=
odd_sum
+
even_sum
#
Step 4:
Find the smallest number that makes total divisible by 10
# Find the smallest number that makes total divisible by 10
check_digit
=
(
10
-
(
total
%
10
))
%
10
check_digit
=
(
10
-
(
total
%
10
))
%
10
return
data
+
str
(
check_digit
)
return
data
+
str
(
check_digit
)
...
...
mbetterclient/web_dashboard/routes.py
View file @
3b50b307
...
@@ -5484,16 +5484,11 @@ def generate_bet_barcode(bet_id):
...
@@ -5484,16 +5484,11 @@ def generate_bet_barcode(bet_id):
logger
.
debug
(
f
"Using generated barcode data for bet {bet_uuid}: {barcode_data}"
)
logger
.
debug
(
f
"Using generated barcode data for bet {bet_uuid}: {barcode_data}"
)
# Generate barcode image
# Generate barcode image
barcode_image
=
generate_barcode_image
(
barcode_data
,
standard
,
width
,
height
)
barcode_image_bytes
=
generate_barcode_image
(
barcode_data
,
standard
,
width
,
height
)
if
barcode_image
:
# Convert PIL image to bytes
img_buffer
=
io
.
BytesIO
()
barcode_image
.
save
(
img_buffer
,
format
=
'PNG'
)
img_buffer
.
seek
(
0
)
if
barcode_image_bytes
:
return
Response
(
return
Response
(
img_buffer
.
getvalue
()
,
barcode_image_bytes
,
mimetype
=
'image/png'
,
mimetype
=
'image/png'
,
headers
=
{
'Cache-Control'
:
'public, max-age=3600'
}
# Cache for 1 hour
headers
=
{
'Cache-Control'
:
'public, max-age=3600'
}
# Cache for 1 hour
)
)
...
...
mbetterclient/web_dashboard/templates/dashboard/admin_bet_details.html
View file @
3b50b307
...
@@ -576,9 +576,17 @@ function generateThermalReceipt(betId) {
...
@@ -576,9 +576,17 @@ function generateThermalReceipt(betId) {
const
receiptHtml
=
generateReceiptHtml
(
window
.
betData
);
const
receiptHtml
=
generateReceiptHtml
(
window
.
betData
);
receiptContainer
.
innerHTML
=
receiptHtml
;
receiptContainer
.
innerHTML
=
receiptHtml
;
// Show the modal
// Generate verification codes for preview
generateVerificationCodes
(
window
.
betData
.
uuid
).
then
(()
=>
{
// Show the modal after verification codes are loaded
const
modal
=
new
bootstrap
.
Modal
(
document
.
getElementById
(
'printReceiptModal'
));
const
modal
=
new
bootstrap
.
Modal
(
document
.
getElementById
(
'printReceiptModal'
));
modal
.
show
();
modal
.
show
();
}).
catch
(
error
=>
{
console
.
warn
(
'Error generating verification codes for preview, showing modal anyway:'
,
error
);
// Show modal even if verification codes fail
const
modal
=
new
bootstrap
.
Modal
(
document
.
getElementById
(
'printReceiptModal'
));
modal
.
show
();
});
}
}
function
generateReceiptHtml
(
betData
)
{
function
generateReceiptHtml
(
betData
)
{
...
@@ -685,11 +693,6 @@ function generateReceiptHtml(betData) {
...
@@ -685,11 +693,6 @@ function generateReceiptHtml(betData) {
</div>
</div>
`
;
`
;
// Generate QR code and barcode after inserting HTML (conditional)
setTimeout
(()
=>
{
generateVerificationCodes
(
betData
.
uuid
);
},
100
);
return
receiptHtml
;
return
receiptHtml
;
}
}
...
@@ -704,11 +707,23 @@ function generateQRCode(betUuid) {
...
@@ -704,11 +707,23 @@ function generateQRCode(betUuid) {
}
}
function
generateVerificationCodes
(
betUuid
)
{
function
generateVerificationCodes
(
betUuid
)
{
return
new
Promise
((
resolve
)
=>
{
const
verificationContainer
=
document
.
getElementById
(
`receipt-verification-
${
betUuid
}
`
);
const
verificationContainer
=
document
.
getElementById
(
`receipt-verification-
${
betUuid
}
`
);
if
(
!
verificationContainer
)
{
if
(
!
verificationContainer
)
{
resolve
();
return
;
return
;
}
}
let
completedOperations
=
0
;
const
totalOperations
=
2
;
// QR code check + barcode check
function
checkComplete
()
{
completedOperations
++
;
if
(
completedOperations
>=
totalOperations
)
{
resolve
();
}
}
// Check QR code settings - QR codes should NOT print if disabled
// Check QR code settings - QR codes should NOT print if disabled
// Default to NOT showing QR codes if API fails
// Default to NOT showing QR codes if API fails
let
shouldShowQR
=
false
;
let
shouldShowQR
=
false
;
...
@@ -719,6 +734,7 @@ function generateVerificationCodes(betUuid) {
...
@@ -719,6 +734,7 @@ function generateVerificationCodes(betUuid) {
.
then
(
response
=>
{
.
then
(
response
=>
{
if
(
!
response
.
ok
)
{
if
(
!
response
.
ok
)
{
console
.
warn
(
'QR settings API failed with status:'
,
response
.
status
);
console
.
warn
(
'QR settings API failed with status:'
,
response
.
status
);
checkComplete
();
return
null
;
return
null
;
}
}
return
response
.
json
();
return
response
.
json
();
...
@@ -752,14 +768,17 @@ function generateVerificationCodes(betUuid) {
...
@@ -752,14 +768,17 @@ function generateVerificationCodes(betUuid) {
}
else
{
}
else
{
console
.
log
(
'QR code disabled - not adding to receipt'
);
console
.
log
(
'QR code disabled - not adding to receipt'
);
}
}
checkComplete
();
})
})
.
catch
(
error
=>
{
.
catch
(
error
=>
{
console
.
warn
(
'Failed to check QR code settings, defaulting to disabled:'
,
error
);
console
.
warn
(
'Failed to check QR code settings, defaulting to disabled:'
,
error
);
shouldShowQR
=
false
;
// Default to not showing on error
shouldShowQR
=
false
;
// Default to not showing on error
checkComplete
();
});
});
}
catch
(
error
)
{
}
catch
(
error
)
{
console
.
warn
(
'Error in QR code settings check, defaulting to disabled:'
,
error
);
console
.
warn
(
'Error in QR code settings check, defaulting to disabled:'
,
error
);
shouldShowQR
=
false
;
// Default to not showing on error
shouldShowQR
=
false
;
// Default to not showing on error
checkComplete
();
}
}
// Check barcode settings
// Check barcode settings
...
@@ -782,9 +801,12 @@ function generateVerificationCodes(betUuid) {
...
@@ -782,9 +801,12 @@ function generateVerificationCodes(betUuid) {
barcodeElement
.
innerHTML
=
`<img src="data:image/png;base64,
${
data
.
barcode_data
.
image_base64
}
" alt="Barcode" class="barcode-img" style="width:
${
data
.
barcode_data
.
width
}
px; height:
${
data
.
barcode_data
.
height
}
px;">`
;
barcodeElement
.
innerHTML
=
`<img src="data:image/png;base64,
${
data
.
barcode_data
.
image_base64
}
" alt="Barcode" class="barcode-img" style="width:
${
data
.
barcode_data
.
width
}
px; height:
${
data
.
barcode_data
.
height
}
px;">`
;
}
}
}
}
checkComplete
();
})
})
.
catch
(
error
=>
{
.
catch
(
error
=>
{
console
.
warn
(
'Failed to check barcode settings:'
,
error
);
console
.
warn
(
'Failed to check barcode settings:'
,
error
);
checkComplete
();
});
});
});
}
}
...
@@ -1135,7 +1157,25 @@ function directPrintBet(betId) {
...
@@ -1135,7 +1157,25 @@ function directPrintBet(betId) {
markBetAsPaidForPrinting
(
betId
).
then
(()
=>
{
markBetAsPaidForPrinting
(
betId
).
then
(()
=>
{
// Use the global bet data for direct printing
// Use the global bet data for direct printing
const
receiptHtml
=
generateReceiptHtml
(
window
.
betData
);
const
receiptHtml
=
generateReceiptHtml
(
window
.
betData
);
// Create temporary container for receipt content
const
tempContainer
=
document
.
createElement
(
'div'
);
tempContainer
.
innerHTML
=
receiptHtml
;
tempContainer
.
style
.
display
=
'none'
;
document
.
body
.
appendChild
(
tempContainer
);
// Generate verification codes and wait for completion
generateVerificationCodes
(
window
.
betData
.
uuid
).
then
(()
=>
{
// Get the updated HTML content after verification codes are added
const
updatedReceiptHtml
=
tempContainer
.
innerHTML
;
printDirectly
(
updatedReceiptHtml
);
document
.
body
.
removeChild
(
tempContainer
);
}).
catch
(
error
=>
{
console
.
warn
(
'Error generating verification codes, printing without them:'
,
error
);
// Print anyway even if verification codes fail
printDirectly
(
receiptHtml
);
printDirectly
(
receiptHtml
);
document
.
body
.
removeChild
(
tempContainer
);
});
}).
catch
(
error
=>
{
}).
catch
(
error
=>
{
console
.
error
(
'Failed to mark bet as paid:'
,
error
);
console
.
error
(
'Failed to mark bet as paid:'
,
error
);
// Still print even if marking as paid fails
// Still print even if marking as paid fails
...
...
mbetterclient/web_dashboard/templates/dashboard/admin_bets.html
View file @
3b50b307
...
@@ -636,9 +636,17 @@ function generateThermalReceiptFromList(betId) {
...
@@ -636,9 +636,17 @@ function generateThermalReceiptFromList(betId) {
const
receiptHtml
=
generateReceiptHtml
(
betData
);
const
receiptHtml
=
generateReceiptHtml
(
betData
);
receiptContainer
.
innerHTML
=
receiptHtml
;
receiptContainer
.
innerHTML
=
receiptHtml
;
// Show the modal
// Generate verification codes for preview
generateVerificationCodes
(
betData
.
uuid
).
then
(()
=>
{
// Show the modal after verification codes are loaded
const
modal
=
new
bootstrap
.
Modal
(
document
.
getElementById
(
'printReceiptModal'
));
const
modal
=
new
bootstrap
.
Modal
(
document
.
getElementById
(
'printReceiptModal'
));
modal
.
show
();
modal
.
show
();
}).
catch
(
error
=>
{
console
.
warn
(
'Error generating verification codes for preview, showing modal anyway:'
,
error
);
// Show modal even if verification codes fail
const
modal
=
new
bootstrap
.
Modal
(
document
.
getElementById
(
'printReceiptModal'
));
modal
.
show
();
});
}
else
{
}
else
{
showNotification
(
'Failed to load bet details for printing: '
+
(
data
.
error
||
'Unknown error'
),
'error'
);
showNotification
(
'Failed to load bet details for printing: '
+
(
data
.
error
||
'Unknown error'
),
'error'
);
}
}
...
@@ -757,11 +765,6 @@ function generateReceiptHtml(betData) {
...
@@ -757,11 +765,6 @@ function generateReceiptHtml(betData) {
</div>
</div>
`
;
`
;
// Generate QR code and barcode after inserting HTML (conditional)
setTimeout
(()
=>
{
generateVerificationCodes
(
betData
.
uuid
);
},
100
);
return
receiptHtml
;
return
receiptHtml
;
}
}
...
@@ -776,11 +779,23 @@ function generateQRCode(betUuid) {
...
@@ -776,11 +779,23 @@ function generateQRCode(betUuid) {
}
}
function
generateVerificationCodes
(
betUuid
)
{
function
generateVerificationCodes
(
betUuid
)
{
return
new
Promise
((
resolve
)
=>
{
const
verificationContainer
=
document
.
getElementById
(
`receipt-verification-
${
betUuid
}
`
);
const
verificationContainer
=
document
.
getElementById
(
`receipt-verification-
${
betUuid
}
`
);
if
(
!
verificationContainer
)
{
if
(
!
verificationContainer
)
{
resolve
();
return
;
return
;
}
}
let
completedOperations
=
0
;
const
totalOperations
=
2
;
// QR code check + barcode check
function
checkComplete
()
{
completedOperations
++
;
if
(
completedOperations
>=
totalOperations
)
{
resolve
();
}
}
// Check QR code settings - QR codes should NOT print if disabled
// Check QR code settings - QR codes should NOT print if disabled
// Default to NOT showing QR codes if API fails
// Default to NOT showing QR codes if API fails
let
shouldShowQR
=
false
;
let
shouldShowQR
=
false
;
...
@@ -791,6 +806,7 @@ function generateVerificationCodes(betUuid) {
...
@@ -791,6 +806,7 @@ function generateVerificationCodes(betUuid) {
.
then
(
response
=>
{
.
then
(
response
=>
{
if
(
!
response
.
ok
)
{
if
(
!
response
.
ok
)
{
console
.
warn
(
'QR settings API failed with status:'
,
response
.
status
);
console
.
warn
(
'QR settings API failed with status:'
,
response
.
status
);
checkComplete
();
return
null
;
return
null
;
}
}
return
response
.
json
();
return
response
.
json
();
...
@@ -824,14 +840,17 @@ function generateVerificationCodes(betUuid) {
...
@@ -824,14 +840,17 @@ function generateVerificationCodes(betUuid) {
}
else
{
}
else
{
console
.
log
(
'QR code disabled - not adding to receipt'
);
console
.
log
(
'QR code disabled - not adding to receipt'
);
}
}
checkComplete
();
})
})
.
catch
(
error
=>
{
.
catch
(
error
=>
{
console
.
warn
(
'Failed to check QR code settings, defaulting to disabled:'
,
error
);
console
.
warn
(
'Failed to check QR code settings, defaulting to disabled:'
,
error
);
shouldShowQR
=
false
;
// Default to not showing on error
shouldShowQR
=
false
;
// Default to not showing on error
checkComplete
();
});
});
}
catch
(
error
)
{
}
catch
(
error
)
{
console
.
warn
(
'Error in QR code settings check, defaulting to disabled:'
,
error
);
console
.
warn
(
'Error in QR code settings check, defaulting to disabled:'
,
error
);
shouldShowQR
=
false
;
// Default to not showing on error
shouldShowQR
=
false
;
// Default to not showing on error
checkComplete
();
}
}
// Check barcode settings
// Check barcode settings
...
@@ -854,9 +873,12 @@ function generateVerificationCodes(betUuid) {
...
@@ -854,9 +873,12 @@ function generateVerificationCodes(betUuid) {
barcodeElement
.
innerHTML
=
`<img src="data:image/png;base64,
${
data
.
barcode_data
.
image_base64
}
" alt="Barcode" class="barcode-img" style="width:
${
data
.
barcode_data
.
width
}
px; height:
${
data
.
barcode_data
.
height
}
px;">`
;
barcodeElement
.
innerHTML
=
`<img src="data:image/png;base64,
${
data
.
barcode_data
.
image_base64
}
" alt="Barcode" class="barcode-img" style="width:
${
data
.
barcode_data
.
width
}
px; height:
${
data
.
barcode_data
.
height
}
px;">`
;
}
}
}
}
checkComplete
();
})
})
.
catch
(
error
=>
{
.
catch
(
error
=>
{
console
.
warn
(
'Failed to check barcode settings:'
,
error
);
console
.
warn
(
'Failed to check barcode settings:'
,
error
);
checkComplete
();
});
});
});
}
}
...
@@ -975,11 +997,18 @@ function directPrintBet(betId) {
...
@@ -975,11 +997,18 @@ function directPrintBet(betId) {
tempContainer
.
style
.
display
=
'none'
;
tempContainer
.
style
.
display
=
'none'
;
document
.
body
.
appendChild
(
tempContainer
);
document
.
body
.
appendChild
(
tempContainer
);
// Wait for QR code and barcode to generate, then print directly
// Generate verification codes and wait for completion
setTimeout
(()
=>
{
generateVerificationCodes
(
betData
.
uuid
).
then
(()
=>
{
// Get the updated HTML content after verification codes are added
const
updatedReceiptHtml
=
tempContainer
.
innerHTML
;
printDirectly
(
updatedReceiptHtml
);
document
.
body
.
removeChild
(
tempContainer
);
}).
catch
(
error
=>
{
console
.
warn
(
'Error generating verification codes, printing without them:'
,
error
);
// Print anyway even if verification codes fail
printDirectly
(
receiptHtml
);
printDirectly
(
receiptHtml
);
document
.
body
.
removeChild
(
tempContainer
);
document
.
body
.
removeChild
(
tempContainer
);
}
,
600
);
// Give time for barcode/QR generation
}
);
}
else
{
}
else
{
showNotification
(
'Failed to load bet details for printing: '
+
(
data
.
error
||
'Unknown error'
),
'error'
);
showNotification
(
'Failed to load bet details for printing: '
+
(
data
.
error
||
'Unknown error'
),
'error'
);
}
}
...
...
mbetterclient/web_dashboard/templates/dashboard/bet_details.html
View file @
3b50b307
...
@@ -635,9 +635,17 @@ function generateThermalReceipt(betId) {
...
@@ -635,9 +635,17 @@ function generateThermalReceipt(betId) {
const
receiptHtml
=
generateReceiptHtml
(
window
.
betData
);
const
receiptHtml
=
generateReceiptHtml
(
window
.
betData
);
receiptContainer
.
innerHTML
=
receiptHtml
;
receiptContainer
.
innerHTML
=
receiptHtml
;
// Show the modal
// Generate verification codes for preview
generateVerificationCodes
(
window
.
betData
.
uuid
).
then
(()
=>
{
// Show the modal after verification codes are loaded
const
modal
=
new
bootstrap
.
Modal
(
document
.
getElementById
(
'printReceiptModal'
));
const
modal
=
new
bootstrap
.
Modal
(
document
.
getElementById
(
'printReceiptModal'
));
modal
.
show
();
modal
.
show
();
}).
catch
(
error
=>
{
console
.
warn
(
'Error generating verification codes for preview, showing modal anyway:'
,
error
);
// Show modal even if verification codes fail
const
modal
=
new
bootstrap
.
Modal
(
document
.
getElementById
(
'printReceiptModal'
));
modal
.
show
();
});
}
}
function
generateReceiptHtml
(
betData
)
{
function
generateReceiptHtml
(
betData
)
{
...
@@ -744,20 +752,27 @@ function generateReceiptHtml(betData) {
...
@@ -744,20 +752,27 @@ function generateReceiptHtml(betData) {
</div>
</div>
`
;
`
;
// Generate QR code and barcode after inserting HTML (conditional)
setTimeout
(()
=>
{
generateVerificationCodes
(
betData
.
uuid
);
},
100
);
return
receiptHtml
;
return
receiptHtml
;
}
}
function
generateVerificationCodes
(
betUuid
)
{
function
generateVerificationCodes
(
betUuid
)
{
return
new
Promise
((
resolve
)
=>
{
const
verificationContainer
=
document
.
getElementById
(
`receipt-verification-
${
betUuid
}
`
);
const
verificationContainer
=
document
.
getElementById
(
`receipt-verification-
${
betUuid
}
`
);
if
(
!
verificationContainer
)
{
if
(
!
verificationContainer
)
{
resolve
();
return
;
return
;
}
}
let
completedOperations
=
0
;
const
totalOperations
=
2
;
// QR code check + barcode check
function
checkComplete
()
{
completedOperations
++
;
if
(
completedOperations
>=
totalOperations
)
{
resolve
();
}
}
// Check QR code settings - QR codes should NOT print if disabled
// Check QR code settings - QR codes should NOT print if disabled
// Default to NOT showing QR codes if API fails
// Default to NOT showing QR codes if API fails
let
shouldShowQR
=
false
;
let
shouldShowQR
=
false
;
...
@@ -768,6 +783,7 @@ function generateVerificationCodes(betUuid) {
...
@@ -768,6 +783,7 @@ function generateVerificationCodes(betUuid) {
.
then
(
response
=>
{
.
then
(
response
=>
{
if
(
!
response
.
ok
)
{
if
(
!
response
.
ok
)
{
console
.
warn
(
'QR settings API failed with status:'
,
response
.
status
);
console
.
warn
(
'QR settings API failed with status:'
,
response
.
status
);
checkComplete
();
return
null
;
return
null
;
}
}
return
response
.
json
();
return
response
.
json
();
...
@@ -801,14 +817,17 @@ function generateVerificationCodes(betUuid) {
...
@@ -801,14 +817,17 @@ function generateVerificationCodes(betUuid) {
}
else
{
}
else
{
console
.
log
(
'QR code disabled - not adding to receipt'
);
console
.
log
(
'QR code disabled - not adding to receipt'
);
}
}
checkComplete
();
})
})
.
catch
(
error
=>
{
.
catch
(
error
=>
{
console
.
warn
(
'Failed to check QR code settings, defaulting to disabled:'
,
error
);
console
.
warn
(
'Failed to check QR code settings, defaulting to disabled:'
,
error
);
shouldShowQR
=
false
;
// Default to not showing on error
shouldShowQR
=
false
;
// Default to not showing on error
checkComplete
();
});
});
}
catch
(
error
)
{
}
catch
(
error
)
{
console
.
warn
(
'Error in QR code settings check, defaulting to disabled:'
,
error
);
console
.
warn
(
'Error in QR code settings check, defaulting to disabled:'
,
error
);
shouldShowQR
=
false
;
// Default to not showing on error
shouldShowQR
=
false
;
// Default to not showing on error
checkComplete
();
}
}
// Check barcode settings - use saved barcode data instead of regenerating
// Check barcode settings - use saved barcode data instead of regenerating
...
@@ -842,16 +861,24 @@ function generateVerificationCodes(betUuid) {
...
@@ -842,16 +861,24 @@ function generateVerificationCodes(betUuid) {
}
}
};
};
reader
.
readAsDataURL
(
blob
);
reader
.
readAsDataURL
(
blob
);
checkComplete
();
})
})
.
catch
(
error
=>
{
.
catch
(
error
=>
{
console
.
warn
(
'Failed to generate barcode image:'
,
error
);
console
.
warn
(
'Failed to generate barcode image:'
,
error
);
checkComplete
();
});
});
}
else
{
checkComplete
();
}
}
})
})
.
catch
(
error
=>
{
.
catch
(
error
=>
{
console
.
warn
(
'Failed to check barcode settings:'
,
error
);
console
.
warn
(
'Failed to check barcode settings:'
,
error
);
checkComplete
();
});
});
}
else
{
checkComplete
();
}
}
});
}
}
function
printThermalReceipt
()
{
function
printThermalReceipt
()
{
...
@@ -1144,7 +1171,25 @@ function directPrintBet(betId) {
...
@@ -1144,7 +1171,25 @@ function directPrintBet(betId) {
markBetAsPaidForPrinting
(
betId
).
then
(()
=>
{
markBetAsPaidForPrinting
(
betId
).
then
(()
=>
{
// Use the global bet data for direct printing
// Use the global bet data for direct printing
const
receiptHtml
=
generateReceiptHtml
(
window
.
betData
);
const
receiptHtml
=
generateReceiptHtml
(
window
.
betData
);
// Create temporary container for receipt content
const
tempContainer
=
document
.
createElement
(
'div'
);
tempContainer
.
innerHTML
=
receiptHtml
;
tempContainer
.
style
.
display
=
'none'
;
document
.
body
.
appendChild
(
tempContainer
);
// Generate verification codes and wait for completion
generateVerificationCodes
(
window
.
betData
.
uuid
).
then
(()
=>
{
// Get the updated HTML content after verification codes are added
const
updatedReceiptHtml
=
tempContainer
.
innerHTML
;
printDirectly
(
updatedReceiptHtml
);
document
.
body
.
removeChild
(
tempContainer
);
}).
catch
(
error
=>
{
console
.
warn
(
'Error generating verification codes, printing without them:'
,
error
);
// Print anyway even if verification codes fail
printDirectly
(
receiptHtml
);
printDirectly
(
receiptHtml
);
document
.
body
.
removeChild
(
tempContainer
);
});
}).
catch
(
error
=>
{
}).
catch
(
error
=>
{
console
.
error
(
'Failed to mark bet as paid:'
,
error
);
console
.
error
(
'Failed to mark bet as paid:'
,
error
);
// Still print even if marking as paid fails
// Still print even if marking as paid fails
...
...
mbetterclient/web_dashboard/templates/dashboard/bets.html
View file @
3b50b307
...
@@ -638,9 +638,17 @@ function generateThermalReceiptFromList(betId) {
...
@@ -638,9 +638,17 @@ function generateThermalReceiptFromList(betId) {
const
receiptHtml
=
generateReceiptHtml
(
betData
);
const
receiptHtml
=
generateReceiptHtml
(
betData
);
receiptContainer
.
innerHTML
=
receiptHtml
;
receiptContainer
.
innerHTML
=
receiptHtml
;
// Show the modal
// Generate verification codes for preview
generateVerificationCodes
(
betData
.
uuid
).
then
(()
=>
{
// Show the modal after verification codes are loaded
const
modal
=
new
bootstrap
.
Modal
(
document
.
getElementById
(
'printReceiptModal'
));
const
modal
=
new
bootstrap
.
Modal
(
document
.
getElementById
(
'printReceiptModal'
));
modal
.
show
();
modal
.
show
();
}).
catch
(
error
=>
{
console
.
warn
(
'Error generating verification codes for preview, showing modal anyway:'
,
error
);
// Show modal even if verification codes fail
const
modal
=
new
bootstrap
.
Modal
(
document
.
getElementById
(
'printReceiptModal'
));
modal
.
show
();
});
}
else
{
}
else
{
showNotification
(
'Failed to load bet details for printing: '
+
(
data
.
error
||
'Unknown error'
),
'error'
);
showNotification
(
'Failed to load bet details for printing: '
+
(
data
.
error
||
'Unknown error'
),
'error'
);
}
}
...
@@ -759,11 +767,6 @@ function generateReceiptHtml(betData) {
...
@@ -759,11 +767,6 @@ function generateReceiptHtml(betData) {
</div>
</div>
`
;
`
;
// Generate QR code and barcode after inserting HTML (conditional)
setTimeout
(()
=>
{
generateVerificationCodes
(
betData
.
uuid
);
},
100
);
return
receiptHtml
;
return
receiptHtml
;
}
}
...
@@ -778,11 +781,23 @@ function generateQRCode(betUuid) {
...
@@ -778,11 +781,23 @@ function generateQRCode(betUuid) {
}
}
function
generateVerificationCodes
(
betUuid
)
{
function
generateVerificationCodes
(
betUuid
)
{
return
new
Promise
((
resolve
)
=>
{
const
verificationContainer
=
document
.
getElementById
(
`receipt-verification-
${
betUuid
}
`
);
const
verificationContainer
=
document
.
getElementById
(
`receipt-verification-
${
betUuid
}
`
);
if
(
!
verificationContainer
)
{
if
(
!
verificationContainer
)
{
resolve
();
return
;
return
;
}
}
let
completedOperations
=
0
;
const
totalOperations
=
2
;
// QR code check + barcode check
function
checkComplete
()
{
completedOperations
++
;
if
(
completedOperations
>=
totalOperations
)
{
resolve
();
}
}
// Check QR code settings - QR codes should NOT print if disabled
// Check QR code settings - QR codes should NOT print if disabled
// Default to NOT showing QR codes if API fails
// Default to NOT showing QR codes if API fails
let
shouldShowQR
=
false
;
let
shouldShowQR
=
false
;
...
@@ -793,6 +808,7 @@ function generateVerificationCodes(betUuid) {
...
@@ -793,6 +808,7 @@ function generateVerificationCodes(betUuid) {
.
then
(
response
=>
{
.
then
(
response
=>
{
if
(
!
response
.
ok
)
{
if
(
!
response
.
ok
)
{
console
.
warn
(
'QR settings API failed with status:'
,
response
.
status
);
console
.
warn
(
'QR settings API failed with status:'
,
response
.
status
);
checkComplete
();
return
null
;
return
null
;
}
}
return
response
.
json
();
return
response
.
json
();
...
@@ -826,14 +842,17 @@ function generateVerificationCodes(betUuid) {
...
@@ -826,14 +842,17 @@ function generateVerificationCodes(betUuid) {
}
else
{
}
else
{
console
.
log
(
'QR code disabled - not adding to receipt'
);
console
.
log
(
'QR code disabled - not adding to receipt'
);
}
}
checkComplete
();
})
})
.
catch
(
error
=>
{
.
catch
(
error
=>
{
console
.
warn
(
'Failed to check QR code settings, defaulting to disabled:'
,
error
);
console
.
warn
(
'Failed to check QR code settings, defaulting to disabled:'
,
error
);
shouldShowQR
=
false
;
// Default to not showing on error
shouldShowQR
=
false
;
// Default to not showing on error
checkComplete
();
});
});
}
catch
(
error
)
{
}
catch
(
error
)
{
console
.
warn
(
'Error in QR code settings check, defaulting to disabled:'
,
error
);
console
.
warn
(
'Error in QR code settings check, defaulting to disabled:'
,
error
);
shouldShowQR
=
false
;
// Default to not showing on error
shouldShowQR
=
false
;
// Default to not showing on error
checkComplete
();
}
}
// Check barcode settings
// Check barcode settings
...
@@ -856,9 +875,12 @@ function generateVerificationCodes(betUuid) {
...
@@ -856,9 +875,12 @@ function generateVerificationCodes(betUuid) {
barcodeElement
.
innerHTML
=
`<img src="data:image/png;base64,
${
data
.
barcode_data
.
image_base64
}
" alt="Barcode" class="barcode-img" style="width:
${
data
.
barcode_data
.
width
}
px; height:
${
data
.
barcode_data
.
height
}
px;">`
;
barcodeElement
.
innerHTML
=
`<img src="data:image/png;base64,
${
data
.
barcode_data
.
image_base64
}
" alt="Barcode" class="barcode-img" style="width:
${
data
.
barcode_data
.
width
}
px; height:
${
data
.
barcode_data
.
height
}
px;">`
;
}
}
}
}
checkComplete
();
})
})
.
catch
(
error
=>
{
.
catch
(
error
=>
{
console
.
warn
(
'Failed to check barcode settings:'
,
error
);
console
.
warn
(
'Failed to check barcode settings:'
,
error
);
checkComplete
();
});
});
});
}
}
...
@@ -981,11 +1003,18 @@ function directPrintBet(betId) {
...
@@ -981,11 +1003,18 @@ function directPrintBet(betId) {
tempContainer
.
style
.
display
=
'none'
;
tempContainer
.
style
.
display
=
'none'
;
document
.
body
.
appendChild
(
tempContainer
);
document
.
body
.
appendChild
(
tempContainer
);
// Wait for QR code and barcode to generate, then print directly
// Generate verification codes and wait for completion
setTimeout
(()
=>
{
generateVerificationCodes
(
betData
.
uuid
).
then
(()
=>
{
// Get the updated HTML content after verification codes are added
const
updatedReceiptHtml
=
tempContainer
.
innerHTML
;
printDirectly
(
updatedReceiptHtml
);
document
.
body
.
removeChild
(
tempContainer
);
}).
catch
(
error
=>
{
console
.
warn
(
'Error generating verification codes, printing without them:'
,
error
);
// Print anyway even if verification codes fail
printDirectly
(
receiptHtml
);
printDirectly
(
receiptHtml
);
document
.
body
.
removeChild
(
tempContainer
);
document
.
body
.
removeChild
(
tempContainer
);
}
,
600
);
// Give time for barcode/QR generation
}
);
}
else
{
}
else
{
showNotification
(
'Failed to load bet details for printing: '
+
(
data
.
error
||
'Unknown error'
),
'error'
);
showNotification
(
'Failed to load bet details for printing: '
+
(
data
.
error
||
'Unknown error'
),
'error'
);
}
}
...
...
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