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
Hide 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
...
...
@@ -92,19 +92,19 @@ def validate_barcode_data(data: str, standard: str) -> bool:
def
generate_barcode_image
(
data
:
str
,
standard
:
str
,
width
:
int
=
300
,
height
:
int
=
100
)
->
Optional
[
bytes
]:
"""
Generate barcode image as PNG bytes
Args:
data: Data to encode in barcode
standard: Barcode standard (code128, code39, ean13, etc.)
width: Image width in pixels
height: Image height in pixels
Returns:
PNG image bytes or None if generation failed
"""
if
standard
==
'none'
:
return
None
try
:
# Special case for UPC-E which is not supported by python-barcode library
if
standard
==
'upce'
:
...
...
@@ -146,7 +146,7 @@ def generate_barcode_image(data: str, standard: str, width: int = 300, height: i
except
Exception
as
e
:
logger
.
error
(
f
"Failed to get barcode class for {barcode_type}: {e}"
)
return
None
# Create image writer with custom options
writer
=
ImageWriter
()
writer
.
set_options
({
...
...
@@ -159,21 +159,24 @@ def generate_barcode_image(data: str, standard: str, width: int = 300, height: i
'write_text'
:
True
,
'text'
:
data
})
#
Gener
ate barcode
#
Cre
ate barcode
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
()
barcode_instance
.
write
(
buffer
)
pil_image
.
save
(
buffer
,
format
=
'PNG'
)
buffer
.
seek
(
0
)
image_bytes
=
buffer
.
getvalue
()
buffer
.
close
()
logger
.
debug
(
f
"Generated {standard} barcode for data: {data}"
)
return
image_bytes
except
Exception
as
e
:
logger
.
error
(
f
"Failed to generate barcode: {e}"
)
return
None
...
...
@@ -216,16 +219,12 @@ def calculate_ean13_check_digit(data: str) -> str:
raise
ValueError
(
"EAN-13 check digit calculation requires exactly 12 digits"
)
# EAN-13 check digit calculation
# Step 1: Sum digits in odd positions (1st, 3rd, 5th, etc.) multiplied by 3
odd_sum
=
sum
(
int
(
data
[
i
])
for
i
in
range
(
0
,
12
,
2
))
*
3
# Step 2: Sum digits in even positions (2nd, 4th, 6th, etc.)
even_sum
=
sum
(
int
(
data
[
i
])
for
i
in
range
(
1
,
12
,
2
))
# Step 3: Total sum
total
=
odd_sum
+
even_sum
# Weights alternate starting with 1 for leftmost digit, 3 for next, etc.
# This ensures the rightmost data digit gets weight 3
weights
=
[
1
,
3
,
1
,
3
,
1
,
3
,
1
,
3
,
1
,
3
,
1
,
3
]
total
=
sum
(
int
(
data
[
i
])
*
weights
[
i
]
for
i
in
range
(
12
))
#
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
return
data
+
str
(
check_digit
)
...
...
mbetterclient/web_dashboard/routes.py
View file @
3b50b307
...
...
@@ -5484,16 +5484,11 @@ def generate_bet_barcode(bet_id):
logger
.
debug
(
f
"Using generated barcode data for bet {bet_uuid}: {barcode_data}"
)
# Generate barcode image
barcode_image
=
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
)
barcode_image_bytes
=
generate_barcode_image
(
barcode_data
,
standard
,
width
,
height
)
if
barcode_image_bytes
:
return
Response
(
img_buffer
.
getvalue
()
,
barcode_image_bytes
,
mimetype
=
'image/png'
,
headers
=
{
'Cache-Control'
:
'public, max-age=3600'
}
# Cache for 1 hour
)
...
...
mbetterclient/web_dashboard/templates/dashboard/admin_bet_details.html
View file @
3b50b307
...
...
@@ -575,25 +575,33 @@ function generateThermalReceipt(betId) {
const
receiptContainer
=
document
.
getElementById
(
'thermal-receipt'
);
const
receiptHtml
=
generateReceiptHtml
(
window
.
betData
);
receiptContainer
.
innerHTML
=
receiptHtml
;
// Show the modal
const
modal
=
new
bootstrap
.
Modal
(
document
.
getElementById
(
'printReceiptModal'
));
modal
.
show
();
// 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'
));
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
)
{
const
currentDateTime
=
new
Date
().
toLocaleString
();
let
receiptHtml
=
`
<div class="thermal-receipt-content">
<!-- Header -->
<div class="receipt-header">
<div class="receipt-title">BETTING SLIP</div>
</div>
<!-- Separator -->
<div class="receipt-separator">================================</div>
<!-- Bet Information -->
<div class="receipt-info">
<div class="receipt-row">
...
...
@@ -613,14 +621,14 @@ function generateReceiptHtml(betData) {
<span>
${
betData
.
bet_count
}
</span>
</div>
</div>
<!-- Separator -->
<div class="receipt-separator">================================</div>
<!-- Bet Details -->
<div class="receipt-bets">
`
;
let
totalAmount
=
0
;
betData
.
bet_details
.
forEach
((
detail
,
index
)
=>
{
totalAmount
+=
parseFloat
(
detail
.
amount
);
...
...
@@ -648,18 +656,18 @@ function generateReceiptHtml(betData) {
</div>
</div>
`
;
if
(
index
<
betData
.
bet_details
.
length
-
1
)
{
receiptHtml
+=
`<div class="receipt-separator">- - - - - - - - - - - - - - - - -</div>`
;
}
});
receiptHtml
+=
`
</div>
<!-- Separator -->
<div class="receipt-separator">================================</div>
<!-- Total -->
<div class="receipt-total">
<div class="receipt-total-line">
...
...
@@ -667,15 +675,15 @@ function generateReceiptHtml(betData) {
<span>
${
formatCurrency
(
totalAmount
)}
</span>
</div>
</div>
<!-- Separator -->
<div class="receipt-separator">================================</div>
<!-- QR Code and Barcode (conditional based on settings) -->
<div class="receipt-verification" id="receipt-verification-
${
betData
.
uuid
}
">
<!-- QR Code and Barcode will be conditionally added here -->
</div>
<!-- Footer -->
<div class="receipt-footer">
<div>Thank you for betting with MBetter!</div>
...
...
@@ -684,12 +692,7 @@ function generateReceiptHtml(betData) {
</div>
</div>
`
;
// Generate QR code and barcode after inserting HTML (conditional)
setTimeout
(()
=>
{
generateVerificationCodes
(
betData
.
uuid
);
},
100
);
return
receiptHtml
;
}
...
...
@@ -704,88 +707,107 @@ function generateQRCode(betUuid) {
}
function
generateVerificationCodes
(
betUuid
)
{
const
verificationContainer
=
document
.
getElementById
(
`receipt-verification-
${
betUuid
}
`
);
if
(
!
verificationContainer
)
{
return
;
}
return
new
Promise
((
resolve
)
=>
{
const
verificationContainer
=
document
.
getElementById
(
`receipt-verification-
${
betUuid
}
`
);
if
(
!
verificationContainer
)
{
resolve
();
return
;
}
// Check QR code settings - QR codes should NOT print if disabled
// Default to NOT showing QR codes if API fails
let
shouldShowQR
=
false
;
try
{
// Try to get QR settings from API
fetch
(
'/api/qrcode-settings'
)
.
then
(
response
=>
{
if
(
!
response
.
ok
)
{
console
.
warn
(
'QR settings API failed with status:'
,
response
.
status
);
return
null
;
}
return
response
.
json
();
})
.
then
(
qrSettings
=>
{
if
(
qrSettings
&&
qrSettings
.
success
&&
qrSettings
.
settings
)
{
shouldShowQR
=
qrSettings
.
settings
.
enabled
===
true
&&
qrSettings
.
settings
.
show_on_thermal
===
true
;
console
.
log
(
'QR settings check result:'
,
shouldShowQR
,
qrSettings
.
settings
);
}
else
{
console
.
warn
(
'Invalid QR settings response:'
,
qrSettings
);
shouldShowQR
=
false
;
// Default to not showing
}
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
// Default to NOT showing QR codes if API fails
let
shouldShowQR
=
false
;
try
{
// Try to get QR settings from API
fetch
(
'/api/qrcode-settings'
)
.
then
(
response
=>
{
if
(
!
response
.
ok
)
{
console
.
warn
(
'QR settings API failed with status:'
,
response
.
status
);
checkComplete
();
return
null
;
}
return
response
.
json
();
})
.
then
(
qrSettings
=>
{
if
(
qrSettings
&&
qrSettings
.
success
&&
qrSettings
.
settings
)
{
shouldShowQR
=
qrSettings
.
settings
.
enabled
===
true
&&
qrSettings
.
settings
.
show_on_thermal
===
true
;
console
.
log
(
'QR settings check result:'
,
shouldShowQR
,
qrSettings
.
settings
);
}
else
{
console
.
warn
(
'Invalid QR settings response:'
,
qrSettings
);
shouldShowQR
=
false
;
// Default to not showing
}
// Add QR code if enabled
if
(
shouldShowQR
)
{
console
.
log
(
'Adding QR code to receipt'
);
const
qrHtml
=
`
<div class="receipt-qr">
<div class="qr-code" id="qr-code-
${
betUuid
}
"></div>
<div class="qr-text">Scan QR for verification</div>
// Add QR code if enabled
if
(
shouldShowQR
)
{
console
.
log
(
'Adding QR code to receipt'
);
const
qrHtml
=
`
<div class="receipt-qr">
<div class="qr-code" id="qr-code-
${
betUuid
}
"></div>
<div class="qr-text">Scan QR for verification</div>
</div>
`
;
verificationContainer
.
insertAdjacentHTML
(
'beforeend'
,
qrHtml
);
// Generate QR code
const
qrContainer
=
document
.
getElementById
(
`qr-code-
${
betUuid
}
`
);
if
(
qrContainer
)
{
const
qrImageUrl
=
`https://api.qrserver.com/v1/create-qr-code/?size=100x100&data=
${
encodeURIComponent
(
betUuid
)}
&format=png`
;
qrContainer
.
innerHTML
=
`<img src="
${
qrImageUrl
}
" alt="QR Code" class="qr-image">`
;
}
}
else
{
console
.
log
(
'QR code disabled - not adding to receipt'
);
}
checkComplete
();
})
.
catch
(
error
=>
{
console
.
warn
(
'Failed to check QR code settings, defaulting to disabled:'
,
error
);
shouldShowQR
=
false
;
// Default to not showing on error
checkComplete
();
});
}
catch
(
error
)
{
console
.
warn
(
'Error in QR code settings check, defaulting to disabled:'
,
error
);
shouldShowQR
=
false
;
// Default to not showing on error
checkComplete
();
}
// Check barcode settings
fetch
(
`/api/barcode-data/
${
betUuid
}
`
)
.
then
(
response
=>
response
.
json
())
.
then
(
data
=>
{
if
(
data
.
success
&&
data
.
enabled
&&
data
.
barcode_data
&&
data
.
barcode_data
.
show_on_thermal
&&
data
.
barcode_data
.
image_base64
)
{
// Add barcode to receipt
const
barcodeHtml
=
`
<div class="receipt-barcode" id="barcode-container-
${
betUuid
}
">
<div class="barcode-image" id="barcode-
${
betUuid
}
"></div>
<div class="barcode-text">Scan barcode for verification</div>
</div>
`
;
verificationContainer
.
insertAdjacentHTML
(
'beforeend'
,
qr
Html
);
verificationContainer
.
insertAdjacentHTML
(
'beforeend'
,
barcode
Html
);
// Generate QR code
const
qrContainer
=
document
.
getElementById
(
`qr-code-
${
betUuid
}
`
);
if
(
qrContainer
)
{
const
qrImageUrl
=
`https://api.qrserver.com/v1/create-qr-code/?size=100x100&data=
${
encodeURIComponent
(
betUuid
)}
&format=png`
;
qrContainer
.
innerHTML
=
`<img src="
${
qrImageUrl
}
" alt="QR Code" class="qr-image">`
;
// Display barcode
const
barcodeElement
=
document
.
getElementById
(
`barcode-
${
betUuid
}
`
);
if
(
barcodeElement
)
{
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;">`
;
}
}
else
{
console
.
log
(
'QR code disabled - not adding to receipt'
);
}
checkComplete
();
})
.
catch
(
error
=>
{
console
.
warn
(
'Failed to check
QR code settings, defaulting to disabled
:'
,
error
);
shouldShowQR
=
false
;
// Default to not showing on error
console
.
warn
(
'Failed to check
barcode settings
:'
,
error
);
checkComplete
();
});
}
catch
(
error
)
{
console
.
warn
(
'Error in QR code settings check, defaulting to disabled:'
,
error
);
shouldShowQR
=
false
;
// Default to not showing on error
}
// Check barcode settings
fetch
(
`/api/barcode-data/
${
betUuid
}
`
)
.
then
(
response
=>
response
.
json
())
.
then
(
data
=>
{
if
(
data
.
success
&&
data
.
enabled
&&
data
.
barcode_data
&&
data
.
barcode_data
.
show_on_thermal
&&
data
.
barcode_data
.
image_base64
)
{
// Add barcode to receipt
const
barcodeHtml
=
`
<div class="receipt-barcode" id="barcode-container-
${
betUuid
}
">
<div class="barcode-image" id="barcode-
${
betUuid
}
"></div>
<div class="barcode-text">Scan barcode for verification</div>
</div>
`
;
verificationContainer
.
insertAdjacentHTML
(
'beforeend'
,
barcodeHtml
);
// Display barcode
const
barcodeElement
=
document
.
getElementById
(
`barcode-
${
betUuid
}
`
);
if
(
barcodeElement
)
{
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;">`
;
}
}
})
.
catch
(
error
=>
{
console
.
warn
(
'Failed to check barcode settings:'
,
error
);
});
});
}
function
printThermalReceipt
()
{
...
...
@@ -1135,7 +1157,25 @@ function directPrintBet(betId) {
markBetAsPaidForPrinting
(
betId
).
then
(()
=>
{
// Use the global bet data for direct printing
const
receiptHtml
=
generateReceiptHtml
(
window
.
betData
);
printDirectly
(
receiptHtml
);
// 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
);
document
.
body
.
removeChild
(
tempContainer
);
});
}).
catch
(
error
=>
{
console
.
error
(
'Failed to mark bet as paid:'
,
error
);
// Still print even if marking as paid fails
...
...
mbetterclient/web_dashboard/templates/dashboard/admin_bets.html
View file @
3b50b307
...
...
@@ -635,10 +635,18 @@ function generateThermalReceiptFromList(betId) {
const
receiptContainer
=
document
.
getElementById
(
'thermal-receipt'
);
const
receiptHtml
=
generateReceiptHtml
(
betData
);
receiptContainer
.
innerHTML
=
receiptHtml
;
// Show the modal
const
modal
=
new
bootstrap
.
Modal
(
document
.
getElementById
(
'printReceiptModal'
));
modal
.
show
();
// 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'
));
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
{
showNotification
(
'Failed to load bet details for printing: '
+
(
data
.
error
||
'Unknown error'
),
'error'
);
}
...
...
@@ -670,17 +678,17 @@ function transformBetDataForReceipt(betData) {
function
generateReceiptHtml
(
betData
)
{
const
currentDateTime
=
new
Date
().
toLocaleString
();
let
receiptHtml
=
`
<div class="thermal-receipt-content">
<!-- Header -->
<div class="receipt-header">
<div class="receipt-title">BETTING SLIP</div>
</div>
<!-- Separator -->
<div class="receipt-separator">================================</div>
<!-- Bet Information -->
<div class="receipt-info">
<div class="receipt-row">
...
...
@@ -692,14 +700,14 @@ function generateReceiptHtml(betData) {
<span>
${
betData
.
bet_datetime
}
</span>
</div>
</div>
<!-- Separator -->
<div class="receipt-separator">================================</div>
<!-- Bet Details -->
<div class="receipt-bets">
`
;
let
totalAmount
=
0
;
betData
.
bet_details
.
forEach
((
detail
,
index
)
=>
{
totalAmount
+=
parseFloat
(
detail
.
amount
);
...
...
@@ -720,18 +728,18 @@ function generateReceiptHtml(betData) {
</div>
</div>
`
;
if
(
index
<
betData
.
bet_details
.
length
-
1
)
{
receiptHtml
+=
`<div class="receipt-separator">- - - - - - - - - - - - - - - - -</div>`
;
}
});
receiptHtml
+=
`
</div>
<!-- Separator -->
<div class="receipt-separator">================================</div>
<!-- Total -->
<div class="receipt-total">
<div class="receipt-total-line">
...
...
@@ -739,15 +747,15 @@ function generateReceiptHtml(betData) {
<span>
${
formatCurrency
(
totalAmount
)}
</span>
</div>
</div>
<!-- Separator -->
<div class="receipt-separator">================================</div>
<!-- QR Code and Barcode (conditional based on settings) -->
<div class="receipt-verification" id="receipt-verification-
${
betData
.
uuid
}
">
<!-- QR Code and Barcode will be conditionally added here -->
</div>
<!-- Footer -->
<div class="receipt-footer">
<div>Thank you for betting with MBetter!</div>
...
...
@@ -756,12 +764,7 @@ function generateReceiptHtml(betData) {
</div>
</div>
`
;
// Generate QR code and barcode after inserting HTML (conditional)
setTimeout
(()
=>
{
generateVerificationCodes
(
betData
.
uuid
);
},
100
);
return
receiptHtml
;
}
...
...
@@ -776,88 +779,107 @@ function generateQRCode(betUuid) {
}
function
generateVerificationCodes
(
betUuid
)
{
const
verificationContainer
=
document
.
getElementById
(
`receipt-verification-
${
betUuid
}
`
);
if
(
!
verificationContainer
)
{
return
;
}
return
new
Promise
((
resolve
)
=>
{
const
verificationContainer
=
document
.
getElementById
(
`receipt-verification-
${
betUuid
}
`
);
if
(
!
verificationContainer
)
{
resolve
();
return
;
}
// Check QR code settings - QR codes should NOT print if disabled
// Default to NOT showing QR codes if API fails
let
shouldShowQR
=
false
;
try
{
// Try to get QR settings from API
fetch
(
'/api/qrcode-settings'
)
.
then
(
response
=>
{
if
(
!
response
.
ok
)
{
console
.
warn
(
'QR settings API failed with status:'
,
response
.
status
);
return
null
;
}
return
response
.
json
();
})
.
then
(
qrSettings
=>
{
if
(
qrSettings
&&
qrSettings
.
success
&&
qrSettings
.
settings
)
{
shouldShowQR
=
qrSettings
.
settings
.
enabled
===
true
&&
qrSettings
.
settings
.
show_on_thermal
===
true
;
console
.
log
(
'QR settings check result:'
,
shouldShowQR
,
qrSettings
.
settings
);
}
else
{
console
.
warn
(
'Invalid QR settings response:'
,
qrSettings
);
shouldShowQR
=
false
;
// Default to not showing
}
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
// Default to NOT showing QR codes if API fails
let
shouldShowQR
=
false
;
try
{
// Try to get QR settings from API
fetch
(
'/api/qrcode-settings'
)
.
then
(
response
=>
{
if
(
!
response
.
ok
)
{
console
.
warn
(
'QR settings API failed with status:'
,
response
.
status
);
checkComplete
();
return
null
;
}
return
response
.
json
();
})
.
then
(
qrSettings
=>
{
if
(
qrSettings
&&
qrSettings
.
success
&&
qrSettings
.
settings
)
{
shouldShowQR
=
qrSettings
.
settings
.
enabled
===
true
&&
qrSettings
.
settings
.
show_on_thermal
===
true
;
console
.
log
(
'QR settings check result:'
,
shouldShowQR
,
qrSettings
.
settings
);
}
else
{
console
.
warn
(
'Invalid QR settings response:'
,
qrSettings
);
shouldShowQR
=
false
;
// Default to not showing
}
// Add QR code if enabled
if
(
shouldShowQR
)
{
console
.
log
(
'Adding QR code to receipt'
);
const
qrHtml
=
`
<div class="receipt-qr">
<div class="qr-code" id="qr-code-
${
betUuid
}
"></div>
<div class="qr-text">Scan QR for verification</div>
// Add QR code if enabled
if
(
shouldShowQR
)
{
console
.
log
(
'Adding QR code to receipt'
);
const
qrHtml
=
`
<div class="receipt-qr">
<div class="qr-code" id="qr-code-
${
betUuid
}
"></div>
<div class="qr-text">Scan QR for verification</div>
</div>
`
;
verificationContainer
.
insertAdjacentHTML
(
'beforeend'
,
qrHtml
);
// Generate QR code
const
qrContainer
=
document
.
getElementById
(
`qr-code-
${
betUuid
}
`
);
if
(
qrContainer
)
{
const
qrImageUrl
=
`https://api.qrserver.com/v1/create-qr-code/?size=100x100&data=
${
encodeURIComponent
(
betUuid
)}
&format=png`
;
qrContainer
.
innerHTML
=
`<img src="
${
qrImageUrl
}
" alt="QR Code" class="qr-image">`
;
}
}
else
{
console
.
log
(
'QR code disabled - not adding to receipt'
);
}
checkComplete
();
})
.
catch
(
error
=>
{
console
.
warn
(
'Failed to check QR code settings, defaulting to disabled:'
,
error
);
shouldShowQR
=
false
;
// Default to not showing on error
checkComplete
();
});
}
catch
(
error
)
{
console
.
warn
(
'Error in QR code settings check, defaulting to disabled:'
,
error
);
shouldShowQR
=
false
;
// Default to not showing on error
checkComplete
();
}
// Check barcode settings
fetch
(
`/api/barcode-data/
${
betUuid
}
`
)
.
then
(
response
=>
response
.
json
())
.
then
(
data
=>
{
if
(
data
.
success
&&
data
.
enabled
&&
data
.
barcode_data
&&
data
.
barcode_data
.
show_on_thermal
&&
data
.
barcode_data
.
image_base64
)
{
// Add barcode to receipt
const
barcodeHtml
=
`
<div class="receipt-barcode" id="barcode-container-
${
betUuid
}
">
<div class="barcode-image" id="barcode-
${
betUuid
}
"></div>
<div class="barcode-text">Scan barcode for verification</div>
</div>
`
;
verificationContainer
.
insertAdjacentHTML
(
'beforeend'
,
qr
Html
);
verificationContainer
.
insertAdjacentHTML
(
'beforeend'
,
barcode
Html
);
// Generate QR code
const
qrContainer
=
document
.
getElementById
(
`qr-code-
${
betUuid
}
`
);
if
(
qrContainer
)
{
const
qrImageUrl
=
`https://api.qrserver.com/v1/create-qr-code/?size=100x100&data=
${
encodeURIComponent
(
betUuid
)}
&format=png`
;
qrContainer
.
innerHTML
=
`<img src="
${
qrImageUrl
}
" alt="QR Code" class="qr-image">`
;
// Display barcode
const
barcodeElement
=
document
.
getElementById
(
`barcode-
${
betUuid
}
`
);
if
(
barcodeElement
)
{
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;">`
;
}
}
else
{
console
.
log
(
'QR code disabled - not adding to receipt'
);
}
checkComplete
();
})
.
catch
(
error
=>
{
console
.
warn
(
'Failed to check
QR code settings, defaulting to disabled
:'
,
error
);
shouldShowQR
=
false
;
// Default to not showing on error
console
.
warn
(
'Failed to check
barcode settings
:'
,
error
);
checkComplete
();
});
}
catch
(
error
)
{
console
.
warn
(
'Error in QR code settings check, defaulting to disabled:'
,
error
);
shouldShowQR
=
false
;
// Default to not showing on error
}
// Check barcode settings
fetch
(
`/api/barcode-data/
${
betUuid
}
`
)
.
then
(
response
=>
response
.
json
())
.
then
(
data
=>
{
if
(
data
.
success
&&
data
.
enabled
&&
data
.
barcode_data
&&
data
.
barcode_data
.
show_on_thermal
&&
data
.
barcode_data
.
image_base64
)
{
// Add barcode to receipt
const
barcodeHtml
=
`
<div class="receipt-barcode" id="barcode-container-
${
betUuid
}
">
<div class="barcode-image" id="barcode-
${
betUuid
}
"></div>
<div class="barcode-text">Scan barcode for verification</div>
</div>
`
;
verificationContainer
.
insertAdjacentHTML
(
'beforeend'
,
barcodeHtml
);
// Display barcode
const
barcodeElement
=
document
.
getElementById
(
`barcode-
${
betUuid
}
`
);
if
(
barcodeElement
)
{
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;">`
;
}
}
})
.
catch
(
error
=>
{
console
.
warn
(
'Failed to check barcode settings:'
,
error
);
});
});
}
function
printThermalReceipt
()
{
...
...
@@ -968,18 +990,25 @@ function directPrintBet(betId) {
if
(
data
.
success
)
{
const
betData
=
transformBetDataForReceipt
(
data
.
bet
);
const
receiptHtml
=
generateReceiptHtml
(
betData
);
// Create temporary container for receipt content
const
tempContainer
=
document
.
createElement
(
'div'
);
tempContainer
.
innerHTML
=
receiptHtml
;
tempContainer
.
style
.
display
=
'none'
;
document
.
body
.
appendChild
(
tempContainer
);
// Wait for QR code and barcode to generate, then print directly
setTimeout
(()
=>
{
// Generate verification codes and wait for completion
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
);
document
.
body
.
removeChild
(
tempContainer
);
}
,
600
);
// Give time for barcode/QR generation
}
);
}
else
{
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) {
const
receiptHtml
=
generateReceiptHtml
(
window
.
betData
);
receiptContainer
.
innerHTML
=
receiptHtml
;
// Show the modal
const
modal
=
new
bootstrap
.
Modal
(
document
.
getElementById
(
'printReceiptModal'
));
modal
.
show
();
// 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'
));
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
)
{
...
...
@@ -744,114 +752,133 @@ function generateReceiptHtml(betData) {
</div>
`
;
// Generate QR code and barcode after inserting HTML (conditional)
setTimeout
(()
=>
{
generateVerificationCodes
(
betData
.
uuid
);
},
100
);
return
receiptHtml
;
}
function
generateVerificationCodes
(
betUuid
)
{
const
verificationContainer
=
document
.
getElementById
(
`receipt-verification-
${
betUuid
}
`
);
if
(
!
verificationContainer
)
{
return
;
}
return
new
Promise
((
resolve
)
=>
{
const
verificationContainer
=
document
.
getElementById
(
`receipt-verification-
${
betUuid
}
`
);
if
(
!
verificationContainer
)
{
resolve
();
return
;
}
// Check QR code settings - QR codes should NOT print if disabled
// Default to NOT showing QR codes if API fails
let
shouldShowQR
=
false
;
try
{
// Try to get QR settings from API
fetch
(
'/api/qrcode-settings'
)
.
then
(
response
=>
{
if
(
!
response
.
ok
)
{
console
.
warn
(
'QR settings API failed with status:'
,
response
.
status
);
return
null
;
}
return
response
.
json
();
})
.
then
(
qrSettings
=>
{
if
(
qrSettings
&&
qrSettings
.
success
&&
qrSettings
.
settings
)
{
shouldShowQR
=
qrSettings
.
settings
.
enabled
===
true
&&
qrSettings
.
settings
.
show_on_thermal
===
true
;
console
.
log
(
'QR settings check result:'
,
shouldShowQR
,
qrSettings
.
settings
);
}
else
{
console
.
warn
(
'Invalid QR settings response:'
,
qrSettings
);
shouldShowQR
=
false
;
// Default to not showing
}
let
completedOperations
=
0
;
const
totalOperations
=
2
;
// QR code check + barcode check
// Add QR code if enabled
if
(
shouldShowQR
)
{
console
.
log
(
'Adding QR code to receipt'
);
const
qrHtml
=
`
<div class="receipt-qr">
<div class="qr-code" id="qr-code-
${
betUuid
}
"></div>
<div class="qr-text">Scan QR for verification</div>
</div>
`
;
verificationContainer
.
insertAdjacentHTML
(
'beforeend'
,
qrHtml
);
// Generate QR code
const
qrContainer
=
document
.
getElementById
(
`qr-code-
${
betUuid
}
`
);
if
(
qrContainer
)
{
const
qrImageUrl
=
`https://api.qrserver.com/v1/create-qr-code/?size=100x100&data=
${
encodeURIComponent
(
betUuid
)}
&format=png`
;
qrContainer
.
innerHTML
=
`<img src="
${
qrImageUrl
}
" alt="QR Code" class="qr-image">`
;
function
checkComplete
()
{
completedOperations
++
;
if
(
completedOperations
>=
totalOperations
)
{
resolve
();
}
}
// Check QR code settings - QR codes should NOT print if disabled
// Default to NOT showing QR codes if API fails
let
shouldShowQR
=
false
;
try
{
// Try to get QR settings from API
fetch
(
'/api/qrcode-settings'
)
.
then
(
response
=>
{
if
(
!
response
.
ok
)
{
console
.
warn
(
'QR settings API failed with status:'
,
response
.
status
);
checkComplete
();
return
null
;
}
return
response
.
json
();
})
.
then
(
qrSettings
=>
{
if
(
qrSettings
&&
qrSettings
.
success
&&
qrSettings
.
settings
)
{
shouldShowQR
=
qrSettings
.
settings
.
enabled
===
true
&&
qrSettings
.
settings
.
show_on_thermal
===
true
;
console
.
log
(
'QR settings check result:'
,
shouldShowQR
,
qrSettings
.
settings
);
}
else
{
console
.
warn
(
'Invalid QR settings response:'
,
qrSettings
);
shouldShowQR
=
false
;
// Default to not showing
}
}
else
{
console
.
log
(
'QR code disabled - not adding to receipt'
);
}
})
.
catch
(
error
=>
{
console
.
warn
(
'Failed to check QR code settings, defaulting to disabled:'
,
error
);
shouldShowQR
=
false
;
// Default to not showing on error
});
}
catch
(
error
)
{
console
.
warn
(
'Error in QR code settings check, defaulting to disabled:'
,
error
);
shouldShowQR
=
false
;
// Default to not showing on error
}
// Check barcode settings - use saved barcode data instead of regenerating
const
betData
=
window
.
betData
;
if
(
betData
&&
betData
.
barcode_data
&&
betData
.
barcode_standard
)
{
// Use saved barcode data from bet
fetch
(
'/api/barcode-settings'
)
.
then
(
response
=>
response
.
json
())
.
then
(
settings
=>
{
if
(
settings
.
success
&&
settings
.
settings
&&
settings
.
settings
.
show_on_thermal
)
{
// Generate barcode image using the saved barcode data
fetch
(
`/api/barcode/
${
betUuid
}
`
)
.
then
(
response
=>
response
.
blob
())
.
then
(
blob
=>
{
const
reader
=
new
FileReader
();
reader
.
onload
=
function
()
{
const
base64
=
reader
.
result
;
// Add barcode to receipt
const
barcodeHtml
=
`
<div class="receipt-barcode" id="barcode-container-
${
betUuid
}
">
<div class="barcode-image" id="barcode-
${
betUuid
}
"></div>
<div class="barcode-text">Scan barcode for verification</div>
</div>
`
;
verificationContainer
.
insertAdjacentHTML
(
'beforeend'
,
barcodeHtml
);
// Display barcode
const
barcodeElement
=
document
.
getElementById
(
`barcode-
${
betUuid
}
`
);
if
(
barcodeElement
)
{
barcodeElement
.
innerHTML
=
`<img src="
${
base64
}
" alt="Barcode" class="barcode-img" style="width: 200px; height: 100px;">`
;
}
};
reader
.
readAsDataURL
(
blob
);
})
.
catch
(
error
=>
{
console
.
warn
(
'Failed to generate barcode image:'
,
error
);
});
}
})
.
catch
(
error
=>
{
console
.
warn
(
'Failed to check barcode settings:'
,
error
);
});
}
// Add QR code if enabled
if
(
shouldShowQR
)
{
console
.
log
(
'Adding QR code to receipt'
);
const
qrHtml
=
`
<div class="receipt-qr">
<div class="qr-code" id="qr-code-
${
betUuid
}
"></div>
<div class="qr-text">Scan QR for verification</div>
</div>
`
;
verificationContainer
.
insertAdjacentHTML
(
'beforeend'
,
qrHtml
);
// Generate QR code
const
qrContainer
=
document
.
getElementById
(
`qr-code-
${
betUuid
}
`
);
if
(
qrContainer
)
{
const
qrImageUrl
=
`https://api.qrserver.com/v1/create-qr-code/?size=100x100&data=
${
encodeURIComponent
(
betUuid
)}
&format=png`
;
qrContainer
.
innerHTML
=
`<img src="
${
qrImageUrl
}
" alt="QR Code" class="qr-image">`
;
}
}
else
{
console
.
log
(
'QR code disabled - not adding to receipt'
);
}
checkComplete
();
})
.
catch
(
error
=>
{
console
.
warn
(
'Failed to check QR code settings, defaulting to disabled:'
,
error
);
shouldShowQR
=
false
;
// Default to not showing on error
checkComplete
();
});
}
catch
(
error
)
{
console
.
warn
(
'Error in QR code settings check, defaulting to disabled:'
,
error
);
shouldShowQR
=
false
;
// Default to not showing on error
checkComplete
();
}
// Check barcode settings - use saved barcode data instead of regenerating
const
betData
=
window
.
betData
;
if
(
betData
&&
betData
.
barcode_data
&&
betData
.
barcode_standard
)
{
// Use saved barcode data from bet
fetch
(
'/api/barcode-settings'
)
.
then
(
response
=>
response
.
json
())
.
then
(
settings
=>
{
if
(
settings
.
success
&&
settings
.
settings
&&
settings
.
settings
.
show_on_thermal
)
{
// Generate barcode image using the saved barcode data
fetch
(
`/api/barcode/
${
betUuid
}
`
)
.
then
(
response
=>
response
.
blob
())
.
then
(
blob
=>
{
const
reader
=
new
FileReader
();
reader
.
onload
=
function
()
{
const
base64
=
reader
.
result
;
// Add barcode to receipt
const
barcodeHtml
=
`
<div class="receipt-barcode" id="barcode-container-
${
betUuid
}
">
<div class="barcode-image" id="barcode-
${
betUuid
}
"></div>
<div class="barcode-text">Scan barcode for verification</div>
</div>
`
;
verificationContainer
.
insertAdjacentHTML
(
'beforeend'
,
barcodeHtml
);
// Display barcode
const
barcodeElement
=
document
.
getElementById
(
`barcode-
${
betUuid
}
`
);
if
(
barcodeElement
)
{
barcodeElement
.
innerHTML
=
`<img src="
${
base64
}
" alt="Barcode" class="barcode-img" style="width: 200px; height: 100px;">`
;
}
};
reader
.
readAsDataURL
(
blob
);
checkComplete
();
})
.
catch
(
error
=>
{
console
.
warn
(
'Failed to generate barcode image:'
,
error
);
checkComplete
();
});
}
else
{
checkComplete
();
}
})
.
catch
(
error
=>
{
console
.
warn
(
'Failed to check barcode settings:'
,
error
);
checkComplete
();
});
}
else
{
checkComplete
();
}
});
}
function
printThermalReceipt
()
{
...
...
@@ -1144,7 +1171,25 @@ function directPrintBet(betId) {
markBetAsPaidForPrinting
(
betId
).
then
(()
=>
{
// Use the global bet data for direct printing
const
receiptHtml
=
generateReceiptHtml
(
window
.
betData
);
printDirectly
(
receiptHtml
);
// 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
);
document
.
body
.
removeChild
(
tempContainer
);
});
}).
catch
(
error
=>
{
console
.
error
(
'Failed to mark bet as paid:'
,
error
);
// Still print even if marking as paid fails
...
...
mbetterclient/web_dashboard/templates/dashboard/bets.html
View file @
3b50b307
...
...
@@ -637,10 +637,18 @@ function generateThermalReceiptFromList(betId) {
const
receiptContainer
=
document
.
getElementById
(
'thermal-receipt'
);
const
receiptHtml
=
generateReceiptHtml
(
betData
);
receiptContainer
.
innerHTML
=
receiptHtml
;
// Show the modal
const
modal
=
new
bootstrap
.
Modal
(
document
.
getElementById
(
'printReceiptModal'
));
modal
.
show
();
// 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'
));
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
{
showNotification
(
'Failed to load bet details for printing: '
+
(
data
.
error
||
'Unknown error'
),
'error'
);
}
...
...
@@ -672,17 +680,17 @@ function transformBetDataForReceipt(betData) {
function
generateReceiptHtml
(
betData
)
{
const
currentDateTime
=
new
Date
().
toLocaleString
();
let
receiptHtml
=
`
<div class="thermal-receipt-content">
<!-- Header -->
<div class="receipt-header">
<div class="receipt-title">BETTING SLIP</div>
</div>
<!-- Separator -->
<div class="receipt-separator">================================</div>
<!-- Bet Information -->
<div class="receipt-info">
<div class="receipt-row">
...
...
@@ -694,14 +702,14 @@ function generateReceiptHtml(betData) {
<span>
${
betData
.
bet_datetime
}
</span>
</div>
</div>
<!-- Separator -->
<div class="receipt-separator">================================</div>
<!-- Bet Details -->
<div class="receipt-bets">
`
;
let
totalAmount
=
0
;
betData
.
bet_details
.
forEach
((
detail
,
index
)
=>
{
totalAmount
+=
parseFloat
(
detail
.
amount
);
...
...
@@ -722,18 +730,18 @@ function generateReceiptHtml(betData) {
</div>
</div>
`
;
if
(
index
<
betData
.
bet_details
.
length
-
1
)
{
receiptHtml
+=
`<div class="receipt-separator">- - - - - - - - - - - - - - - - -</div>`
;
}
});
receiptHtml
+=
`
</div>
<!-- Separator -->
<div class="receipt-separator">================================</div>
<!-- Total -->
<div class="receipt-total">
<div class="receipt-total-line">
...
...
@@ -741,15 +749,15 @@ function generateReceiptHtml(betData) {
<span>
${
formatCurrency
(
totalAmount
)}
</span>
</div>
</div>
<!-- Separator -->
<div class="receipt-separator">================================</div>
<!-- QR Code and Barcode (conditional based on settings) -->
<div class="receipt-verification" id="receipt-verification-
${
betData
.
uuid
}
">
<!-- QR Code and Barcode will be conditionally added here -->
</div>
<!-- Footer -->
<div class="receipt-footer">
<div>Thank you for betting with MBetter!</div>
...
...
@@ -758,12 +766,7 @@ function generateReceiptHtml(betData) {
</div>
</div>
`
;
// Generate QR code and barcode after inserting HTML (conditional)
setTimeout
(()
=>
{
generateVerificationCodes
(
betData
.
uuid
);
},
100
);
return
receiptHtml
;
}
...
...
@@ -778,88 +781,107 @@ function generateQRCode(betUuid) {
}
function
generateVerificationCodes
(
betUuid
)
{
const
verificationContainer
=
document
.
getElementById
(
`receipt-verification-
${
betUuid
}
`
);
if
(
!
verificationContainer
)
{
return
;
}
return
new
Promise
((
resolve
)
=>
{
const
verificationContainer
=
document
.
getElementById
(
`receipt-verification-
${
betUuid
}
`
);
if
(
!
verificationContainer
)
{
resolve
();
return
;
}
// Check QR code settings - QR codes should NOT print if disabled
// Default to NOT showing QR codes if API fails
let
shouldShowQR
=
false
;
try
{
// Try to get QR settings from API
fetch
(
'/api/qrcode-settings'
)
.
then
(
response
=>
{
if
(
!
response
.
ok
)
{
console
.
warn
(
'QR settings API failed with status:'
,
response
.
status
);
return
null
;
}
return
response
.
json
();
})
.
then
(
qrSettings
=>
{
if
(
qrSettings
&&
qrSettings
.
success
&&
qrSettings
.
settings
)
{
shouldShowQR
=
qrSettings
.
settings
.
enabled
===
true
&&
qrSettings
.
settings
.
show_on_thermal
===
true
;
console
.
log
(
'QR settings check result:'
,
shouldShowQR
,
qrSettings
.
settings
);
}
else
{
console
.
warn
(
'Invalid QR settings response:'
,
qrSettings
);
shouldShowQR
=
false
;
// Default to not showing
}
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
// Default to NOT showing QR codes if API fails
let
shouldShowQR
=
false
;
try
{
// Try to get QR settings from API
fetch
(
'/api/qrcode-settings'
)
.
then
(
response
=>
{
if
(
!
response
.
ok
)
{
console
.
warn
(
'QR settings API failed with status:'
,
response
.
status
);
checkComplete
();
return
null
;
}
return
response
.
json
();
})
.
then
(
qrSettings
=>
{
if
(
qrSettings
&&
qrSettings
.
success
&&
qrSettings
.
settings
)
{
shouldShowQR
=
qrSettings
.
settings
.
enabled
===
true
&&
qrSettings
.
settings
.
show_on_thermal
===
true
;
console
.
log
(
'QR settings check result:'
,
shouldShowQR
,
qrSettings
.
settings
);
}
else
{
console
.
warn
(
'Invalid QR settings response:'
,
qrSettings
);
shouldShowQR
=
false
;
// Default to not showing
}
// Add QR code if enabled
if
(
shouldShowQR
)
{
console
.
log
(
'Adding QR code to receipt'
);
const
qrHtml
=
`
<div class="receipt-qr">
<div class="qr-code" id="qr-code-
${
betUuid
}
"></div>
<div class="qr-text">Scan QR for verification</div>
// Add QR code if enabled
if
(
shouldShowQR
)
{
console
.
log
(
'Adding QR code to receipt'
);
const
qrHtml
=
`
<div class="receipt-qr">
<div class="qr-code" id="qr-code-
${
betUuid
}
"></div>
<div class="qr-text">Scan QR for verification</div>
</div>
`
;
verificationContainer
.
insertAdjacentHTML
(
'beforeend'
,
qrHtml
);
// Generate QR code
const
qrContainer
=
document
.
getElementById
(
`qr-code-
${
betUuid
}
`
);
if
(
qrContainer
)
{
const
qrImageUrl
=
`https://api.qrserver.com/v1/create-qr-code/?size=100x100&data=
${
encodeURIComponent
(
betUuid
)}
&format=png`
;
qrContainer
.
innerHTML
=
`<img src="
${
qrImageUrl
}
" alt="QR Code" class="qr-image">`
;
}
}
else
{
console
.
log
(
'QR code disabled - not adding to receipt'
);
}
checkComplete
();
})
.
catch
(
error
=>
{
console
.
warn
(
'Failed to check QR code settings, defaulting to disabled:'
,
error
);
shouldShowQR
=
false
;
// Default to not showing on error
checkComplete
();
});
}
catch
(
error
)
{
console
.
warn
(
'Error in QR code settings check, defaulting to disabled:'
,
error
);
shouldShowQR
=
false
;
// Default to not showing on error
checkComplete
();
}
// Check barcode settings
fetch
(
`/api/barcode-data/
${
betUuid
}
`
)
.
then
(
response
=>
response
.
json
())
.
then
(
data
=>
{
if
(
data
.
success
&&
data
.
enabled
&&
data
.
barcode_data
&&
data
.
barcode_data
.
show_on_thermal
&&
data
.
barcode_data
.
image_base64
)
{
// Add barcode to receipt
const
barcodeHtml
=
`
<div class="receipt-barcode" id="barcode-container-
${
betUuid
}
">
<div class="barcode-image" id="barcode-
${
betUuid
}
"></div>
<div class="barcode-text">Scan barcode for verification</div>
</div>
`
;
verificationContainer
.
insertAdjacentHTML
(
'beforeend'
,
qr
Html
);
verificationContainer
.
insertAdjacentHTML
(
'beforeend'
,
barcode
Html
);
// Generate QR code
const
qrContainer
=
document
.
getElementById
(
`qr-code-
${
betUuid
}
`
);
if
(
qrContainer
)
{
const
qrImageUrl
=
`https://api.qrserver.com/v1/create-qr-code/?size=100x100&data=
${
encodeURIComponent
(
betUuid
)}
&format=png`
;
qrContainer
.
innerHTML
=
`<img src="
${
qrImageUrl
}
" alt="QR Code" class="qr-image">`
;
// Display barcode
const
barcodeElement
=
document
.
getElementById
(
`barcode-
${
betUuid
}
`
);
if
(
barcodeElement
)
{
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;">`
;
}
}
else
{
console
.
log
(
'QR code disabled - not adding to receipt'
);
}
checkComplete
();
})
.
catch
(
error
=>
{
console
.
warn
(
'Failed to check
QR code settings, defaulting to disabled
:'
,
error
);
shouldShowQR
=
false
;
// Default to not showing on error
console
.
warn
(
'Failed to check
barcode settings
:'
,
error
);
checkComplete
();
});
}
catch
(
error
)
{
console
.
warn
(
'Error in QR code settings check, defaulting to disabled:'
,
error
);
shouldShowQR
=
false
;
// Default to not showing on error
}
// Check barcode settings
fetch
(
`/api/barcode-data/
${
betUuid
}
`
)
.
then
(
response
=>
response
.
json
())
.
then
(
data
=>
{
if
(
data
.
success
&&
data
.
enabled
&&
data
.
barcode_data
&&
data
.
barcode_data
.
show_on_thermal
&&
data
.
barcode_data
.
image_base64
)
{
// Add barcode to receipt
const
barcodeHtml
=
`
<div class="receipt-barcode" id="barcode-container-
${
betUuid
}
">
<div class="barcode-image" id="barcode-
${
betUuid
}
"></div>
<div class="barcode-text">Scan barcode for verification</div>
</div>
`
;
verificationContainer
.
insertAdjacentHTML
(
'beforeend'
,
barcodeHtml
);
// Display barcode
const
barcodeElement
=
document
.
getElementById
(
`barcode-
${
betUuid
}
`
);
if
(
barcodeElement
)
{
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;">`
;
}
}
})
.
catch
(
error
=>
{
console
.
warn
(
'Failed to check barcode settings:'
,
error
);
});
});
}
function
printThermalReceipt
()
{
...
...
@@ -974,18 +996,25 @@ function directPrintBet(betId) {
if
(
data
.
success
)
{
const
betData
=
transformBetDataForReceipt
(
data
.
bet
);
const
receiptHtml
=
generateReceiptHtml
(
betData
);
// Create temporary container for receipt content
const
tempContainer
=
document
.
createElement
(
'div'
);
tempContainer
.
innerHTML
=
receiptHtml
;
tempContainer
.
style
.
display
=
'none'
;
document
.
body
.
appendChild
(
tempContainer
);
// Wait for QR code and barcode to generate, then print directly
setTimeout
(()
=>
{
// Generate verification codes and wait for completion
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
);
document
.
body
.
removeChild
(
tempContainer
);
}
,
600
);
// Give time for barcode/QR generation
}
);
}
else
{
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