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() { repeat() {
try { try {
const storedTickets = localStorage.getItem('localTicketsnew'); const storedTickets = localStorage.getItem('localTicketsnew');
@ -209,6 +147,8 @@ export class MiddleSectionComponent implements OnInit, OnDestroy {
} }
} }
parseWinLabelsToRows(winLabels: string, fallbackTotal?: number): SelectionData[] { parseWinLabelsToRows(winLabels: string, fallbackTotal?: number): SelectionData[] {
return (winLabels.split('\n') as string[]) return (winLabels.split('\n') as string[])
.map(line => { .map(line => {
@ -248,12 +188,24 @@ parseWinLabelsToRows(winLabels: string, fallbackTotal?: number): SelectionData[]
} }
//-----------------------REPEAT PRINT LOGIC ---------------------------------- //-------------------------------------------------REPEAT PRINT LOGIC -----------------------------------------------
printRepeat() {
printRepeat() {
console.log('🖨️ [DEBUG] Printing ticket...'); console.log('🖨️ [DEBUG] Printing ticket...');
const userName = localStorage.getItem('userName') || 'Unknown'; const userName = localStorage.getItem('userName') || 'Unknown';
const currentDate = new Date().toLocaleString();
// Keep currentDate as a Date object
const now = new Date();
// 🆕 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 const printableRows = this.filledRows
.filter(row => row.label && row.numbers.length > 0 && row.total > 0) .filter(row => row.label && row.numbers.length > 0 && row.total > 0)
@ -264,25 +216,21 @@ parseWinLabelsToRows(winLabels: string, fallbackTotal?: number): SelectionData[]
.join('\n'); .join('\n');
const ticketContent = ` const ticketContent = `
================================= BTC Race Ticket
🏇 BTC Race Ticket 🏇
=================================
${printableRows} ${printableRows}
Barcode ID : ${barcodeId}
Printed by : ${userName} 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 = { const payload = {
type: 'repeat', type: 'repeat',
printedBy: userName, printedBy: userName,
barcodeId, // send barcode separately
content: ticketContent, content: ticketContent,
timestamp: currentDate timestamp: now.toLocaleString()
}; };
fetch('http://localhost:9100/print', { fetch('http://localhost:9100/print', {
@ -301,33 +249,6 @@ Date : ${currentDate}
console.error("❌ Repeat ticket print failed:", 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);
}
// Hide Confirm and Print buttons before clearing selections // Hide Confirm and Print buttons before clearing selections
this.showConfirmButton = false; this.showConfirmButton = false;
this.showPrintButton = false; this.showPrintButton = false;
@ -340,6 +261,8 @@ Date : ${currentDate}
//------------------------------PRINT REPEAT ENDED HERE-----------------------------------------------------S //------------------------------PRINT REPEAT ENDED HERE-----------------------------------------------------S
erase() { erase() {
this.selectionService.clearSelections(); this.selectionService.clearSelections();
this.resetSelections(); this.resetSelections();

View File

@ -504,3 +504,16 @@ h4{
font-size: 0.9em; font-size: 0.9em;
font-weight: bold; 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" id="ticketNo"
class="modal-input" class="modal-input"
[(ngModel)]="ticketNo" [(ngModel)]="ticketNo"
readonly
/> />
<div class="warning-message" *ngIf="cancelWarning"> <div class="warning-message" *ngIf="cancelWarning">
{{ cancelWarning }} {{ cancelWarning }}
@ -131,6 +132,11 @@
</div> </div>
</div> </div>
<!-- ✅ Warning message -->
<div class="deposit-warning" *ngIf="depositWarning">
{{ depositWarning }}
</div>
<div class="deposit-footer"> <div class="deposit-footer">
<button class="deposit-cancel-btn" (click)="closeDepositPopup()"> <button class="deposit-cancel-btn" (click)="closeDepositPopup()">
CANCEL CANCEL
@ -196,6 +202,11 @@
</div> </div>
</div> </div>
<!-- ✅ Warning message -->
<div class="withdraw-warning" *ngIf="withdrawWarning">
{{ withdrawWarning }}
</div>
<div class="withdraw-footer"> <div class="withdraw-footer">
<button class="withdraw-cancel-btn" (click)="closeWithdrawPopup()"> <button class="withdraw-cancel-btn" (click)="closeWithdrawPopup()">
CANCEL CANCEL

View File

@ -27,18 +27,34 @@ export class SidebarComponent {
depositOperatorId = ''; depositOperatorId = '';
depositShroffId = ''; depositShroffId = '';
depositAmount = ''; depositAmount = '';
depositWarning = '';
showWithdraw: boolean = false; showWithdraw: boolean = false;
withdrawOperatorId = ''; withdrawOperatorId = '';
withdrawShroffId = ''; withdrawShroffId = '';
withdrawAmount = ''; withdrawAmount = '';
withdrawWarning = '';
showViewRc: boolean = false; showViewRc: boolean = false;
// Modal handlers... // Modal handlers...
openCancelPopup() { openCancelPopup() {
this.cancelClick.emit(); this.cancelClick.emit();
this.showCancel = true; 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() { closeCancelPopup() {
@ -46,98 +62,12 @@ export class SidebarComponent {
this.ticketNo = ''; this.ticketNo = '';
} }
// ✅ Declare this at the top of your component
//---------------------------------------ADDED THE CANCEL PRINT ---------------------------
//---------------------------------------ADDED THE CANCEL PRINT -------------------------------------------
cancelWarning: string = ''; // For showing inline warnings 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() { printTicketCancel() {
const enteredTicketNo = this.ticketNo?.trim(); const enteredTicketNo = this.ticketNo?.trim();
console.log('[STEP 1] Entered Ticket No:', enteredTicketNo); 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 --------------------------------------- //--------------------------------COMPLETED THE CANCEL PRINT ---------------------------------------
openPayoutPopup() { openPayoutPopup() {
this.payoutClick.emit(); this.payoutClick.emit();
this.showPayout = true; this.showPayout = true;
@ -335,56 +174,9 @@ Original Total: ₹${cancelTicketData.totalAmount}
this.payoutTicketNo = ''; 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() { printPayoutTicket() {
console.log("🖨️ Print ticket clicked"); console.log("🖨️ Print ticket clicked");
// alert(`Printing Payout Ticket No: ${this.payoutTicketNo}`); // alert(`Printing Payout Ticket No: ${this.payoutTicketNo}`);
@ -453,136 +245,28 @@ Date : ${new Date().toLocaleString()}
this.depositOperatorId = ''; this.depositOperatorId = '';
this.depositShroffId = ''; this.depositShroffId = '';
this.depositAmount = ''; this.depositAmount = '';
this.depositWarning = '';
} }
//----------------------------Print Deposit ticket ------------------------------------------------------- //----------------------------PRINT PAYOUT TICKET ENDS -------------------------------------------------------
// 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()}
// ==============================
// printDeposit() { //------------------------------------PRINT DEPOSIT TICKET STARTS HERE-------------------------------------------
// const userName = localStorage.getItem('userName') || 'Unknown';
// // 🖨️ 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() { printDeposit() {
const userName = localStorage.getItem('userName') || 'Unknown'; 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 // Denomination voucher section
const content = ` const content = `
@ -609,8 +293,8 @@ Total = ____________________________
Bangalore Turf Club Bangalore Turf Club
DEPOSIT RECEIPT DEPOSIT RECEIPT
------------------------------- -------------------------------
Operator : ${this.depositOperatorId || 'N/A'} Operator : ${this.depositOperatorId}
Shroff : ${this.depositShroffId || 'N/A'} Shroff : ${this.depositShroffId}
Amount : ${this.depositAmount} Amount : ${this.depositAmount}
Printed By: ${userName} Printed By: ${userName}
Date : ${date} Date : ${date}
@ -619,7 +303,6 @@ Time : ${time}
${content} ${content}
`; `;
// 🖨️ Console log exactly what will be printed
console.log("🖨️ DEPOSIT PRINT LAYOUT:\n" + previewReceipt); console.log("🖨️ DEPOSIT PRINT LAYOUT:\n" + previewReceipt);
// ✅ Send to print server // ✅ Send to print server
@ -651,8 +334,7 @@ ${content}
this.closeDepositPopup(); this.closeDepositPopup();
} }
//--------------------------------------PRINT DEPOSIT TICKETS ENDS HERE -------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------------------
openWithdrawPopup() { openWithdrawPopup() {
this.withdrawClick.emit(); this.withdrawClick.emit();
@ -664,74 +346,28 @@ ${content}
this.withdrawOperatorId = ''; this.withdrawOperatorId = '';
this.withdrawShroffId = ''; this.withdrawShroffId = '';
this.withdrawAmount = ''; 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() { printWithdraw() {
const userName = localStorage.getItem('userName') || 'Unknown'; 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 = ` const receiptText = `
🧾 Denomination Voucher 🧾 Denomination Voucher
2000 x _____________ = _____________ 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 = { const payload = {
type: 'withdraw', type: 'withdraw',
@ -780,7 +434,9 @@ Total = ____________________________
//----------------------------------------------WITHDRAW TICKET COMPLETED-----------------------------
//----------------------------------------------PRINT WITHDRAW TICKET ENDS HERE -----------------------------
raceCardData: any = null; // ✅ Hold fetched data raceCardData: any = null; // ✅ Hold fetched data

View File

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