fix : validation before print , auto fetch ticket id and wsp function (bug wsp)

This commit is contained in:
Sibin Sabu 2025-08-14 12:07:17 +05:30
parent 494e40d17d
commit 554fdffa23
5 changed files with 247 additions and 594 deletions

View File

@ -112,69 +112,7 @@ export class MiddleSectionComponent implements OnInit, OnDestroy {
// repeat() {
// try {
// const storedTickets = localStorage.getItem('localTicketsnew');
// if (storedTickets) {
// const tickets = JSON.parse(storedTickets);
// const latestTicket = Array.isArray(tickets)
// ? (tickets.length > 0 ? tickets[tickets.length - 1] : null)
// : tickets;
// if (latestTicket && latestTicket.winLabels) {
// const parsedRows = this.parseWinLabelsToRows(latestTicket.winLabels);
// // ✅ Always make sure we have exactly 5 rows
// this.updateFilledRows(parsedRows, { label: '', numbers: [], value: 0, total: 0 });
// console.log('📜 Updated Filled Rows:', parsedRows); // debug output
// this.showConfirmButton = true;
// this.showPrintButton = false;
// this.lastTicket = latestTicket;
// } else {
// console.warn('⚠️ No valid ticket data found in localStorage.');
// }
// } else {
// console.warn('⚠️ No tickets found in localStorage.');
// }
// } catch (error) {
// console.error('❌ Failed to load ticket from localStorage:', error);
// }
// }
// parseWinLabelsToRows(winLabels: string): SelectionData[] {
// // Match: LABEL <spaces> NUMBERS <spaces> *VALUE [Rs TOTAL optional]
// return (winLabels.split('\n') as string[])
// .map(line => {
// // Works for both single-leg and multi-leg tickets
// const match = line.match(/^(\S+)\s+(.+?)\s+\*([\d.]+)(?:\s+Rs\s*(\d+))?/);
// if (!match) return null;
// const label = match[1].trim();
// const numbersRaw = match[2].trim();
// const value = Number(match[3]);
// const total = match[4] ? Number(match[4]) : 0;
// // If multi-leg ticket (MJP, TRE, etc.), split by '/'
// let numbers: string[] | string[][];
// if (numbersRaw.includes('/')) {
// numbers = numbersRaw
// .split('/')
// .map(part => part.split(',').map(s => s.trim()).filter(Boolean));
// } else {
// numbers = numbersRaw.split(',').map(s => s.trim()).filter(Boolean);
// }
// return {
// label,
// numbers,
// value,
// total,
// isBoxed: numbersRaw.startsWith('#')
// };
// })
// .filter(Boolean) as SelectionData[];
// }
repeat() {
try {
const storedTickets = localStorage.getItem('localTicketsnew');
@ -209,6 +147,8 @@ export class MiddleSectionComponent implements OnInit, OnDestroy {
}
}
parseWinLabelsToRows(winLabels: string, fallbackTotal?: number): SelectionData[] {
return (winLabels.split('\n') as string[])
.map(line => {
@ -248,85 +188,66 @@ parseWinLabelsToRows(winLabels: string, fallbackTotal?: number): SelectionData[]
}
//-----------------------REPEAT PRINT LOGIC ----------------------------------
printRepeat() {
console.log('🖨️ [DEBUG] Printing ticket...');
//-------------------------------------------------REPEAT PRINT LOGIC -----------------------------------------------
printRepeat() {
console.log('🖨️ [DEBUG] Printing ticket...');
const userName = localStorage.getItem('userName') || 'Unknown';
const currentDate = new Date().toLocaleString();
const printableRows = this.filledRows
.filter(row => row.label && row.numbers.length > 0 && row.total > 0)
.map(row => {
const horses = Array.isArray(row.numbers) ? row.numbers.join(',') : row.numbers;
return `${row.label.padEnd(6)} ${horses.padEnd(15)} * ${String(row.value).padEnd(3)}${row.total}`;
})
.join('\n');
// Keep currentDate as a Date object
const now = new Date();
const ticketContent = `
=================================
🏇 BTC Race Ticket 🏇
=================================
// 🆕 Create Barcode ID (same combo format)
const day = String(now.getDate()).padStart(2, '0');
const month = String(now.getMonth() + 1).padStart(2, '0');
const year = String(now.getFullYear()).slice(-2);
const timeStr = `${String(now.getHours()).padStart(2, '0')}${String(now.getMinutes()).padStart(2, '0')}${String(now.getSeconds()).padStart(2, '0')}`;
const millis = String(now.getMilliseconds()).padStart(3, '0');
const barcodeId = `1111${day}${month}${year}${timeStr}${millis}`;
const printableRows = this.filledRows
.filter(row => row.label && row.numbers.length > 0 && row.total > 0)
.map(row => {
const horses = Array.isArray(row.numbers) ? row.numbers.join(',') : row.numbers;
return `${row.label.padEnd(6)} ${horses.padEnd(15)} * ${String(row.value).padEnd(3)}${row.total}`;
})
.join('\n');
const ticketContent = `
BTC Race Ticket
${printableRows}
Barcode ID : ${barcodeId}
Printed by : ${userName}
Date : ${currentDate}
=================================
`;
Date : ${now.toLocaleString()}`;
// ✅ Log preview in console
console.log('%c\n' + ticketContent, 'font-family: monospace; color: green');
console.log('%c\n' + ticketContent, 'font-family: monospace; color: green');
// ✅ Send to print server
const payload = {
type: 'repeat',
const payload = {
type: 'repeat',
printedBy: userName,
content: ticketContent,
timestamp: currentDate
};
barcodeId, // send barcode separately
content: ticketContent,
timestamp: now.toLocaleString()
};
fetch('http://localhost:9100/print', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
})
.then(response => {
if (!response.ok) throw new Error(`Printer error: ${response.status}`);
return response.text();
})
.then(result => {
console.log("✅ Repeat ticket print successful:", result);
})
.catch(error => {
console.error("❌ Repeat ticket print failed:", error);
});
// --- Update localStorage for transaction summary like normal print ---
// 1. Increment printClickCount
let clickCount = Number(localStorage.getItem('printClickCount') || '0');
clickCount += 1;
localStorage.setItem('printClickCount', clickCount.toString());
// 2. Add a new ticket entry to localTickets (type: 'ticket', totalAmount)
try {
const existingTicketsStr = localStorage.getItem('localTickets');
const existingTickets = existingTicketsStr ? JSON.parse(existingTicketsStr) : [];
// Calculate totalAmount for this repeat print
const totalAmount = this.filledRows
.filter(row => row.label && row.numbers.length > 0 && row.total > 0)
.reduce((sum, row) => sum + (row.total || 0), 0);
const ticketEntry = {
type: 'ticket',
printedBy: userName,
totalAmount,
content: ticketContent,
timestamp: currentDate
};
existingTickets.push(ticketEntry);
localStorage.setItem('localTickets', JSON.stringify(existingTickets));
} catch (error) {
console.error('❌ Failed to update localTickets for repeat print:', error);
}
fetch('http://localhost:9100/print', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
})
.then(response => {
if (!response.ok) throw new Error(`Printer error: ${response.status}`);
return response.text();
})
.then(result => {
console.log("✅ Repeat ticket print successful:", result);
})
.catch(error => {
console.error("❌ Repeat ticket print failed:", error);
});
// Hide Confirm and Print buttons before clearing selections
this.showConfirmButton = false;
@ -340,6 +261,8 @@ Date : ${currentDate}
//------------------------------PRINT REPEAT ENDED HERE-----------------------------------------------------S
erase() {
this.selectionService.clearSelections();
this.resetSelections();

View File

@ -504,3 +504,16 @@ h4{
font-size: 0.9em;
font-weight: bold;
}
.deposit-warning {
margin-top: 0;
color: red;
font-weight: normal;
}
.withdraw-warning {
margin-top: 8px;
color: red;
font-weight:normal;
}

View File

@ -34,6 +34,7 @@
id="ticketNo"
class="modal-input"
[(ngModel)]="ticketNo"
readonly
/>
<div class="warning-message" *ngIf="cancelWarning">
{{ cancelWarning }}
@ -131,6 +132,11 @@
</div>
</div>
<!-- ✅ Warning message -->
<div class="deposit-warning" *ngIf="depositWarning">
{{ depositWarning }}
</div>
<div class="deposit-footer">
<button class="deposit-cancel-btn" (click)="closeDepositPopup()">
CANCEL
@ -196,6 +202,11 @@
</div>
</div>
<!-- ✅ Warning message -->
<div class="withdraw-warning" *ngIf="withdrawWarning">
{{ withdrawWarning }}
</div>
<div class="withdraw-footer">
<button class="withdraw-cancel-btn" (click)="closeWithdrawPopup()">
CANCEL

View File

@ -27,18 +27,34 @@ export class SidebarComponent {
depositOperatorId = '';
depositShroffId = '';
depositAmount = '';
depositWarning = '';
showWithdraw: boolean = false;
withdrawOperatorId = '';
withdrawShroffId = '';
withdrawAmount = '';
withdrawWarning = '';
showViewRc: boolean = false;
// Modal handlers...
openCancelPopup() {
this.cancelClick.emit();
this.showCancel = true;
this.cancelWarning = '';
const localTicketsStr = localStorage.getItem('localTicketsnew');
if (localTicketsStr) {
try {
const localTickets = JSON.parse(localTicketsStr);
if (Array.isArray(localTickets) && localTickets.length > 0) {
const lastTicket = localTickets[localTickets.length - 1];
if (lastTicket && lastTicket.barcodeId) {
this.ticketNo = lastTicket.barcodeId.trim();
}
}
} catch (e) {
console.error('Error reading localTicketsnew:', e);
}
}
}
closeCancelPopup() {
@ -46,98 +62,12 @@ export class SidebarComponent {
this.ticketNo = '';
}
// ✅ Declare this at the top of your component
//---------------------------------------ADDED THE CANCEL PRINT -------------------------------------------
//---------------------------------------ADDED THE CANCEL PRINT ---------------------------
cancelWarning: string = ''; // For showing inline warnings
// printTicketCancel() {
// const enteredTicketNo = this.ticketNo?.trim();
// console.log('[STEP 1] Entered Ticket No:', enteredTicketNo);
// this.cancelWarning = '';
// const localTicketsStr = localStorage.getItem('localTicketsnew');
// if (!localTicketsStr) {
// console.error('[STEP 2] No localTickets found in localStorage.');
// this.cancelWarning = '❌ No ticket history found.';
// return;
// }
// let localTickets;
// try {
// localTickets = JSON.parse(localTicketsStr);
// } catch (e) {
// console.error('[STEP 3] Error parsing localTickets:', e);
// this.cancelWarning = '❌ Error reading stored tickets.';
// return;
// }
// if (!Array.isArray(localTickets) || localTickets.length === 0) {
// console.warn('[STEP 4] localTickets is empty.');
// this.cancelWarning = '❌ No tickets available to verify.';
// return;
// }
// const lastTicket = localTickets[localTickets.length - 1];
// console.log('[STEP 5] Last Ticket:', lastTicket);
// if (!lastTicket || !lastTicket.barcodeId) {
// console.warn('[STEP 6] Last ticket missing barcodeId.');
// this.cancelWarning = '❌ Invalid stored ticket.';
// return;
// }
// const storedBarcode = lastTicket.barcodeId.trim();
// console.log('[STEP 7] Stored Barcode ID:', storedBarcode);
// if (enteredTicketNo === storedBarcode) {
// console.log('[✅ MATCH] Ticket No matches barcode. Proceeding to print...');
// // 🧾 Construct cancel print layout (only showing total from original ticket)
// const cancelTicketData = {
// type: 'CANCEL_TICKET',
// ticketId: lastTicket.ticketId || '',
// barcodeId: lastTicket.barcodeId,
// cancelDate: new Date().toLocaleString(),
// total: lastTicket.total || 0 // <-- only keeping total
// };
// // 🔍 Console Preview
// console.log('🧾 [CANCEL TICKET LAYOUT]');
// console.log(`
// ========================================
// ⚠️ TICKET CANCELLED ⚠️
// ----------------------------------------
// Ticket ID : ${cancelTicketData.ticketId}
// Barcode ID : ${cancelTicketData.barcodeId}
// Cancelled At : ${cancelTicketData.cancelDate}
// Original Total: ₹${cancelTicketData.total}
// ========================================
// `);
// // 🖨️ Send to printer server
// fetch('http://localhost:9100/print', {
// method: 'POST',
// headers: { 'Content-Type': 'application/json' },
// body: JSON.stringify(cancelTicketData)
// })
// .then(response => {
// if (!response.ok) throw new Error(`Printer error: ${response.status}`);
// return response.text();
// })
// .then(result => {
// console.log("✅ Cancel ticket print successful:", result);
// })
// .catch(error => {
// console.error("❌ Cancel ticket print failed:", error);
// });
// this.closeCancelPopup();
// } else {
// console.warn('[❌ MISMATCH] Entered Ticket No does NOT match last stored barcode.');
// this.cancelWarning = '❌ Invalid ticket number. Please check and try again.';
// }
// }
printTicketCancel() {
const enteredTicketNo = this.ticketNo?.trim();
console.log('[STEP 1] Entered Ticket No:', enteredTicketNo);
@ -227,100 +157,9 @@ Original Total: ₹${cancelTicketData.totalAmount}
}
}
// printTicketCancel() {
// const enteredTicketNo = this.ticketNo?.trim();
// console.log('[STEP 1] Entered Ticket No:', enteredTicketNo);
// this.cancelWarning = '';
// const localTicketsStr = localStorage.getItem('localTicketsnew');
// if (!localTicketsStr) {
// console.error('[STEP 2] No localTickets found in localStorage.');
// this.cancelWarning = '❌ No ticket history found.';
// return;
// }
// let localTickets;
// try {
// localTickets = JSON.parse(localTicketsStr);
// } catch (e) {
// console.error('[STEP 3] Error parsing localTickets:', e);
// this.cancelWarning = '❌ Error reading stored tickets.';
// return;
// }
// if (!Array.isArray(localTickets) || localTickets.length === 0) {
// console.warn('[STEP 4] localTickets is empty.');
// this.cancelWarning = '❌ No tickets available to verify.';
// return;
// }
// const lastTicket = localTickets[localTickets.length - 1];
// console.log('[STEP 5] Last Ticket:', lastTicket);
// if (!lastTicket || !lastTicket.barcodeId) {
// console.warn('[STEP 6] Last ticket missing barcodeId.');
// this.cancelWarning = '❌ Invalid stored ticket.';
// return;
// }
// const storedBarcode = lastTicket.barcodeId.trim();
// console.log('[STEP 7] Stored Barcode ID:', storedBarcode);
// if (enteredTicketNo === storedBarcode) {
// console.log('[✅ MATCH] Ticket No matches barcode. Proceeding to print...');
// // 🧾 Construct cancel print layout (DEMO)
// const cancelTicketData = {
// type: 'CANCEL_TICKET',
// ticketId: lastTicket.ticketId || '',
// barcodeId: lastTicket.barcodeId,
// cancelDate: new Date().toLocaleString(),
// originalTicket: lastTicket
// };
// // 🔍 DEMO CONSOLE PRINT LAYOUT
// console.log('🧾 [CANCEL TICKET LAYOUT]');
// console.log(`
// ========================================
// ⚠️ TICKET CANCELLED ⚠️
// ----------------------------------------
// Ticket ID : ${cancelTicketData.ticketId}
// Barcode ID : ${cancelTicketData.barcodeId}
// Cancelled At : ${cancelTicketData.cancelDate}
// ❗ Original Ticket:
// ${JSON.stringify(cancelTicketData.originalTicket, null, 2)}
// ========================================
// `);
// // 🖨️ SEND TO PORT 9100
// fetch('http://localhost:9100/print', {
// method: 'POST',
// headers: { 'Content-Type': 'application/json' },
// body: JSON.stringify(cancelTicketData)
// })
// .then(response => {
// if (!response.ok) throw new Error(`Printer error: ${response.status}`);
// return response.text();
// })
// .then(result => {
// console.log("✅ Cancel ticket print successful:", result);
// })
// .catch(error => {
// console.error("❌ Cancel ticket print failed:", error);
// });
// this.closeCancelPopup();
// } else {
// console.warn('[❌ MISMATCH] Entered Ticket No does NOT match last stored barcode.');
// this.cancelWarning = '❌ Invalid ticket number. Please check and try again.';
// }
// }
//--------------------------------COMPLETED THE CANCEL PRINT ---------------------------------------
openPayoutPopup() {
this.payoutClick.emit();
this.showPayout = true;
@ -335,56 +174,9 @@ Original Total: ₹${cancelTicketData.totalAmount}
this.payoutTicketNo = '';
}
//--------------------Printer Logic added here ----------------------------------------------
//--------------------------------------------PRINT PAYOUT TICKET -----------------------------------------------------------------
//---------------------------------Print Payout Ticket --------------------------------------------------------
// printPayoutTicket() {
// console.log("🖨️ Print ticket clicked");
// alert(`Printing Payout Ticket No: ${this.payoutTicketNo}`);
// const TicketNumber = this.payoutTicketNo;
// // 🔓 Retrieve userName from localStorage
// const userName = localStorage.getItem('userName') || 'Unknown';
// const printData = {
// TicketNumber: TicketNumber,
// printedBy: userName, // Optional if you want to show it
// Dividend: '10'
// };
// // 🖨️ Actual print request
// const payload = {
// type: 'payout',
// ticketNumber: printData.TicketNumber,
// printedBy: printData.printedBy, // Optional
// dividend: printData.Dividend
// };
// fetch('http://localhost:9100/print', {
// method: 'POST',
// headers: { 'Content-Type': 'application/json' },
// body: JSON.stringify(payload)
// })
// .then(response => {
// if (!response.ok) {
// throw new Error(`Printer error: ${response.status}`);
// }
// return response.text();
// })
// .then(result => {
// console.log("✅ Print successful:", result);
// })
// .catch(error => {
// console.error("❌ Print failed:", error);
// });
// this.closePayoutPopup();
// }
printPayoutTicket() {
console.log("🖨️ Print ticket clicked");
// alert(`Printing Payout Ticket No: ${this.payoutTicketNo}`);
@ -453,136 +245,28 @@ Date : ${new Date().toLocaleString()}
this.depositOperatorId = '';
this.depositShroffId = '';
this.depositAmount = '';
this.depositWarning = '';
}
//----------------------------Print Deposit ticket -------------------------------------------------------
// printDeposit() {
// const userName = localStorage.getItem('userName') || 'Unknown';
// const receiptText = `
// ==============================
// 💰 DEPOSIT RECEIPT
// ==============================
// Operator ID : ${this.depositOperatorId}
// Shroff ID : ${this.depositShroffId}
// Amount : ₹${this.depositAmount}
// Printed By : ${userName}
// Date : ${new Date().toLocaleString()}
// ==============================
// 🧾 Denomination Voucher
// 1000 x _____________ = _____________
// 500 x _____________ = _____________
// 100 x _____________ = _____________
// 50 x _____________ = _____________
// 20 x _____________ = _____________
// 10 x _____________ = _____________
// 5 x _____________ = _____________
// ==============================
// `;
// // ✅ Send to print server
// const payload = {
// type: 'deposit',
// printedBy: userName,
// operatorId: this.depositOperatorId,
// shroffId: this.depositShroffId,
// amount: this.depositAmount,
// content: receiptText // 🧾 Include formatted text
// };
// fetch('http://localhost:9100/print', {
// method: 'POST',
// headers: { 'Content-Type': 'application/json' },
// body: JSON.stringify(payload)
// })
// .then(response => {
// if (!response.ok) throw new Error(`Printer error: ${response.status}`);
// return response.text();
// })
// .then(result => {
// console.log("✅ Deposit print successful:", result);
// })
// .catch(error => {
// console.error("❌ Deposit print failed:", error);
// });
// this.closeDepositPopup();
// }
// ==============================
// 💰 DEPOSIT RECEIPT
// ==============================
// Operator ID : ${this.depositOperatorId}
// Shroff ID : ${this.depositShroffId}
// Amount : ₹${this.depositAmount}
// Printed By : ${userName}
// Date : ${new Date().toLocaleString()}
// ==============================
//----------------------------PRINT PAYOUT TICKET ENDS -------------------------------------------------------
// printDeposit() {
// const userName = localStorage.getItem('userName') || 'Unknown';
//------------------------------------PRINT DEPOSIT TICKET STARTS HERE-------------------------------------------
// // 🖨️ Console log the exact print layout
// console.log(`
// ==============================
// 💰 DEPOSIT RECEIPT
// ==============================
// Operator ID : ${this.depositOperatorId}
// Shroff ID : ${this.depositShroffId}
// Amount : ₹${this.depositAmount}
// Printed By : ${userName}
// Date : ${new Date().toLocaleString()}
// ==============================
// 🧾 Denomination Voucher
// 1000 x _____________ = _____________
// 500 x _____________ = _____________
// 100 x _____________ = _____________
// 50 x _____________ = _____________
// 20 x _____________ = _____________
// 10 x _____________ = _____________
// 5 x _____________ = _____________
// ==============================
// `);
// // ✅ Send to print server
// const payload = {
// type: 'deposit',
// printedBy: userName,
// operatorId: this.depositOperatorId,
// shroffId: this.depositShroffId,
// amount: this.depositAmount,
// //content: receiptText
// };
// fetch('http://localhost:9100/print', {
// method: 'POST',
// headers: { 'Content-Type': 'application/json' },
// body: JSON.stringify(payload)
// })
// .then(response => {
// if (!response.ok) throw new Error(`Printer error: ${response.status}`);
// return response.text();
// })
// .then(result => {
// console.log("✅ Deposit print successful:", result);
// })
// .catch(error => {
// console.error("❌ Deposit print failed:", error);
// });
// this.closeDepositPopup();
// }
printDeposit() {
const userName = localStorage.getItem('userName') || 'Unknown';
this.depositWarning = '';
// ✅ Validation — stop if any of the required fields are missing
if (
!this.depositOperatorId?.toString().trim() ||
!this.depositShroffId?.toString().trim() ||
!this.depositAmount?.toString().trim()
) {
console.warn("❌ Cannot print deposit — missing required fields.");
this.depositWarning = '❌ Please fill Operator ID, Shroff ID, and Amount before printing.';
return; // Stop here — no print
}
// Denomination voucher section
const content = `
@ -609,8 +293,8 @@ Total = ____________________________
Bangalore Turf Club
DEPOSIT RECEIPT
-------------------------------
Operator : ${this.depositOperatorId || 'N/A'}
Shroff : ${this.depositShroffId || 'N/A'}
Operator : ${this.depositOperatorId}
Shroff : ${this.depositShroffId}
Amount : ${this.depositAmount}
Printed By: ${userName}
Date : ${date}
@ -619,7 +303,6 @@ Time : ${time}
${content}
`;
// 🖨️ Console log exactly what will be printed
console.log("🖨️ DEPOSIT PRINT LAYOUT:\n" + previewReceipt);
// ✅ Send to print server
@ -651,8 +334,7 @@ ${content}
this.closeDepositPopup();
}
//-----------------------------------------------------------------------------------------------------------------
//--------------------------------------PRINT DEPOSIT TICKETS ENDS HERE -------------------------------------------------------------
openWithdrawPopup() {
this.withdrawClick.emit();
@ -664,74 +346,28 @@ ${content}
this.withdrawOperatorId = '';
this.withdrawShroffId = '';
this.withdrawAmount = '';
this.withdrawWarning = '';
}
// printWithdraw() {
// alert(`Withdraw: ₹${this.withdrawAmount}`);
// this.closeWithdrawPopup();
// }
//---------------------------------------WITHDRAW TICKET --------------------------------------
// printWithdraw() {
// const userName = localStorage.getItem('userName') || 'Unknown';
// const receiptText = `
// ==============================
// 💸 WITHDRAW RECEIPT
// ==============================
// Operator ID : ${this.withdrawOperatorId}
// Shroff ID : ${this.withdrawShroffId}
// Amount : ₹${this.withdrawAmount}
// Printed By : ${userName}
// Date : ${new Date().toLocaleString()}
// ==============================
// 🧾 Denomination Voucher
// 1000 x _____________ = _____________
// 500 x _____________ = _____________
// 100 x _____________ = _____________
// 50 x _____________ = _____________
// 20 x _____________ = _____________
// 10 x _____________ = _____________
// 5 x _____________ = _____________
// ==============================
// `;
// const payload = {
// type: 'withdraw',
// printedBy: userName,
// operatorId: this.withdrawOperatorId,
// shroffId: this.withdrawShroffId,
// amount: this.withdrawAmount,
// content: receiptText
// };
// fetch('http://localhost:9100/print', {
// method: 'POST',
// headers: { 'Content-Type': 'application/json' },
// body: JSON.stringify(payload)
// })
// .then(response => {
// if (!response.ok) throw new Error(`Printer error: ${response.status}`);
// return response.text();
// })
// .then(result => {
// console.log("✅ Withdraw print successful:", result);
// })
// .catch(error => {
// console.error("❌ Withdraw print failed:", error);
// });
// this.closeWithdrawPopup();
// }
//---------------------------------------PRINT WITHDRAW STARTS HERE --------------------------------------------------------
printWithdraw() {
const userName = localStorage.getItem('userName') || 'Unknown';
// Clear previous warning
this.withdrawWarning = '';
// ✅ Validation
if (
!this.withdrawOperatorId?.toString().trim() ||
!this.withdrawShroffId?.toString().trim() ||
!this.withdrawAmount?.toString().trim()
) {
this.withdrawWarning = '❌ Please fill Operator ID, Shroff ID, and Amount before printing.';
return; // Stop here — no print
}
const receiptText = `
🧾 Denomination Voucher
2000 x _____________ = _____________
@ -747,8 +383,26 @@ Total = ____________________________
=====================================
`;
// 🖨️ Log the exact print layout
console.log(receiptText);
const now = new Date();
const date = now.toISOString().split('T')[0];
const time = now.toTimeString().split(' ')[0];
const previewReceipt = `
Bangalore Turf Club
DEPOSIT RECEIPT
-------------------------------
Operator : ${this.withdrawOperatorId}
Shroff : ${this.withdrawShroffId}
Amount : ${this.withdrawAmount}
Printed By: ${userName}
Date : ${date}
Time : ${time}
-------------------------------
${receiptText}
`;
console.log(previewReceipt);
const payload = {
type: 'withdraw',
@ -780,7 +434,9 @@ Total = ____________________________
//----------------------------------------------WITHDRAW TICKET COMPLETED-----------------------------
//----------------------------------------------PRINT WITHDRAW TICKET ENDS HERE -----------------------------
raceCardData: any = null; // ✅ Hold fetched data

View File

@ -254,6 +254,12 @@ export class TouchPadMenuComponent implements OnInit, OnDestroy {
return false;
}
get isWSPSelection(): boolean {
const currentRow = this.selectionService.getCurrentRow();
return ['WIN', 'SHP', 'PLC'].includes(currentRow.label) ||
this.selectionService.getSelections().some(sel => ['WIN', 'SHP', 'PLC'].includes(sel.label));
}
private chunk<T>(array: T[], size: number): T[][] {
return Array.from({ length: Math.ceil(array.length / size) }, (_, i) =>
array.slice(i * size, i * size + size)
@ -338,24 +344,24 @@ export class TouchPadMenuComponent implements OnInit, OnDestroy {
this.wspTicketStage = 0;
this.selectionService.finalizeCurrentRow();
const currentSelections = this.selectionService.getSelections();
const blankRows = wspLabels.map(lbl => ({
label: lbl,
numbers: [],
value: 0,
total: 0,
isBoxed: false
}));
const totalNew = 0; // Each row is empty initially
const totalExisting = currentSelections.reduce((sum, r) => sum + r.total, 0);
if (totalExisting + totalNew <= 5000) {
this.selectionService.setSelections([...currentSelections, ...blankRows]);
const existingWSP = currentSelections.filter(sel => wspLabels.includes(sel.label));
if (existingWSP.length === 0) {
const blankRows = wspLabels.map(lbl => ({
label: lbl,
numbers: [],
value: 0,
total: 0,
isBoxed: false
}));
const totalNew = 0;
const totalExisting = currentSelections.reduce((sum, r) => sum + r.total, 0);
if (totalExisting + totalNew <= 5000) {
this.selectionService.setSelections([...currentSelections, ...blankRows]);
}
}
// Clear the input area (so no editing conflicts)
this.selectionService.updatePartial({ label: '', numbers: [], value: 0, total: 0 });
return; // Skip default updatePartial below
return;
}
//----------------------------------ended here----------------------------------------------------
@ -372,7 +378,6 @@ export class TouchPadMenuComponent implements OnInit, OnDestroy {
// Reset Multi-leg
this.multiLegStage = 0;
this.multiLegGroups = [[], [], [], [], []];
this.selectionService.updatePartial({ label });
}
@ -524,15 +529,61 @@ if (this.twoGroupLabels.includes(this.selectedLabel || '')) {
return horsesPerLeg.reduce((acc, v) => acc * v, 1) * units * unitBet;
}
createVirtualRowsFromWSP(): SelectionData[] {
const base = this.selectionService.getCurrentRow();
if (!base.numbers.length || base.value <= 0 || ['WIN', 'SHP', 'PLC'].includes(base.label)) {
return [];
}
return ['WIN', 'SHP', 'PLC'].map(label => {
const newRow: SelectionData = {
...base,
label,
total: 0
};
newRow.total = this.calculateTotal(newRow);
return newRow;
});
}
//-------------------------ON PAD ENTER------------------------------------//
private calculateTotal(row: SelectionData): number {
if (!row.numbers || row.numbers.length === 0 || row.value <= 0) {
return 0;
}
let combinations = 1;
if (['TAN', 'FOR', 'QUI'].includes(row.label)) {
combinations = row.numbers.length * (row.numbers.length - 1);
} else if (['TRE', 'JKP', 'MJP'].includes(row.label)) {
const legs = row.numbers.join('').split('/').map(leg => leg.split(',').length);
combinations = legs.reduce((a, b) => a * b, 1);
} else if (row.isBoxed) {
const n = row.numbers.length;
combinations = n > 1 ? (n * (n - 1)) / 2 : 0;
}
return combinations * row.value * 10;
}
// onPadEnter() {
// if (this.canPrint) {
// this.print();
// }
// }
clearWSPSelection() {
if (this.selectedLabel !== 'WSP') return;
const labels = ['WIN', 'SHP', 'PLC'];
const targetLabel = labels[this.wspTicketStage];
// Update only the current WSP stage's value to 0
const updatedSelections = this.selectionService.getSelections().map(sel => {
if (sel.label === targetLabel && JSON.stringify(sel.numbers) === JSON.stringify(this.selectedNumbers)) {
return {
...sel,
value: 0,
total: 0
};
}
return sel;
});
this.selectionService.setSelections(updatedSelections);
this.padValue = '';
this.updateCanPrint();
}
onPadEnter() {
// Disable Enter if maxRowsReached
@ -565,7 +616,6 @@ if (this.twoGroupLabels.includes(this.selectedLabel || '')) {
this.wspTicketStage = (this.wspTicketStage + 1) % 3;
this.padValue = '';
this.updateCanPrint();
return;
}
@ -573,9 +623,6 @@ if (this.twoGroupLabels.includes(this.selectedLabel || '')) {
this.print();
}
//--------------------------------------------------------------------------//
onShashEnter() {
if (this.selectedLabel === 'TAN' && this.isBoxed) {
return;
@ -620,10 +667,11 @@ enterPadVal(key: string) {
if (!this.numericPadEnabled || this.totalAmountLimitReached) return;
if (key === 'X') {
this.padValue = '';
if (this.selectedLabel === 'WSP') {
this.wspTicketStage = 0;
this.clearWSPSelection();
return;
}
this.padValue = '';
this.selectionService.updatePartial({
label: this.selectedLabel || '',
numbers: [...this.selectedNumbers],
@ -672,6 +720,7 @@ enterPadVal(key: string) {
this.wspTicketStage = 0;
this.padValue = '';
this.selectedNumbers = [];
this.selectedLabel = null;
this.selectionService.updatePartial({
label: '',
numbers: [],
@ -834,6 +883,12 @@ enterPadVal(key: string) {
return;
}
}
if (this.selectedLabel === 'WSP') {
const virtualRows = this.createVirtualRowsFromWSP();
const currentSelections = this.selectionService.getSelections();
const nonWSPSelections = currentSelections.filter(sel => !['WIN', 'SHP', 'PLC'].includes(sel.label));
this.selectionService.setSelections([...nonWSPSelections, ...virtualRows]);
}
this.selectionService.finalizeCurrentRow();
this.resetSelections();
}
@ -932,9 +987,13 @@ printTicket() {
console.log("🖨️ Print ticket clicked");
const selections = this.selectionService.getSelections();
let selections = this.selectionService.getSelections();
const currentRow = this.selectionService.getCurrentRow();
if (this.selectedLabel === 'WSP') {
selections = selections.filter(sel => ['WIN', 'SHP', 'PLC'].includes(sel.label));
}
let allRows = [...selections];
// ✅ Just count clicks — update click count in localStorage
@ -1199,11 +1258,6 @@ try {
this.selectionService.clearSelections();
this.resetSelections();
}
// eraseAndReload() {
// this.erase();
// window.location.reload();
// }
resetSelections() {
this.selectedLabel = null;
@ -1615,7 +1669,6 @@ try {
this.padValue = '';
this.canPrint = false;
this.isBoxed = false;
this.tanGroupStage = 0;
this.tanGroups = [[], [], []];
this.isFirstGroupComplete = false;
@ -1639,7 +1692,6 @@ try {
type: 'multiLegPoolStart',
value: { label: poolInfo.name, baseRaceIdx: this.multiLegBaseRaceIdx }
});
this.updateLegRaceDisplay(poolInfo.name);
this.selectionService.updatePartial({ label: 'TRE' });
// --- NEW: Update runners and number pad immediately ---
@ -1656,6 +1708,7 @@ try {
closeLimitPopup() {
this.showLimitPopup = false;
}
copyNumbers() {
if (!this.selectedLabel) {
console.warn('Please select a label before copying numbers.');
@ -1738,7 +1791,6 @@ get canEnterRow(): boolean {
currentRow.value >= 1 &&
currentRow.value <= 100 &&
currentRow.total > 0;
console.log('[DEBUG] canEnterRow (non-WSP):', {
label: currentRow.label,
numbers: currentRow.numbers,
@ -1748,6 +1800,4 @@ get canEnterRow(): boolean {
});
return result;
}
}
}