Feat : Cancel added via backend

This commit is contained in:
Sibin Sabu 2025-09-15 14:07:18 +05:30
parent f2d14117e6
commit 06aaa13e00
3 changed files with 219 additions and 145 deletions

View File

@ -121,10 +121,10 @@ liveStatusOk = true;
this.subscription = interval(5000) this.subscription = interval(5000)
.pipe( .pipe(
switchMap(() => { switchMap(() => {
console.log(`[ANGULAR] Fetching latest ABS status at ${new Date().toISOString()}`); // console.log(`[ANGULAR] Fetching latest ABS status at ${new Date().toISOString()}`);
return this.http.get('http://localhost:8080/abs/latest').pipe( return this.http.get('http://localhost:8080/abs/latest').pipe(
catchError((err) => { catchError((err) => {
console.error('[ANGULAR] ABS latest fetch failed ❌', err); // console.error('[ANGULAR] ABS latest fetch failed ❌', err);
this.liveStatusOk = false; this.liveStatusOk = false;
return of(null); return of(null);
}) })
@ -133,7 +133,7 @@ liveStatusOk = true;
) )
.subscribe((res: any) => { .subscribe((res: any) => {
if (res) { if (res) {
console.log('[ANGULAR] ABS latest response ✅', res); // console.log('[ANGULAR] ABS latest response ✅', res);
this.liveStatusOk = res.success === true; this.liveStatusOk = res.success === true;
// If backend eventually returns structured data: // If backend eventually returns structured data:
@ -167,7 +167,7 @@ liveStatusOk = true;
this.multiLegBaseRaceIdx = baseRaceIdx; this.multiLegBaseRaceIdx = baseRaceIdx;
this.currentLegRaceDisplay = `Starting at Race ${baseRaceIdx} for ${label}`; this.currentLegRaceDisplay = `Starting at Race ${baseRaceIdx} for ${label}`;
this.updateEnabledHorseNumbersForMultiLeg(baseRaceIdx); this.updateEnabledHorseNumbersForMultiLeg(baseRaceIdx);
console.log(`[Multi-leg Pool] Selected: ${label}, Base Race: ${baseRaceIdx}`); //console.log(`[Multi-leg Pool] Selected: ${label}, Base Race: ${baseRaceIdx}`);
} }
if (data.type === 'multiLegPoolEnd') { if (data.type === 'multiLegPoolEnd') {
this.currentPool = null; this.currentPool = null;
@ -234,7 +234,7 @@ liveStatusOk = true;
value: this.enabledHorseNumbers, value: this.enabledHorseNumbers,
}); });
console.log('[Multi-leg Pool] Updated enabled horse numbers:', this.enabledHorseNumbers); // console.log('[Multi-leg Pool] Updated enabled horse numbers:', this.enabledHorseNumbers);
} }
private getLegCountForLabel(): number { private getLegCountForLabel(): number {
@ -297,12 +297,12 @@ liveStatusOk = true;
// Use lowercase 'venue' as structuredRaceCard uses .venue // Use lowercase 'venue' as structuredRaceCard uses .venue
this.selectedVenue = this.raceCardData?.venue ?? this.raceCardData?.Venue ?? 'Select Venue'; this.selectedVenue = this.raceCardData?.venue ?? this.raceCardData?.Venue ?? 'Select Venue';
this.updateEnabledHorseNumbers(); this.updateEnabledHorseNumbers();
console.log('[MODAL] Opening venue modal (structured):', this.selectedVenue); // console.log('[MODAL] Opening venue modal (structured):', this.selectedVenue);
this.showVenueModal = true; this.showVenueModal = true;
} }
openRaceModal() { openRaceModal() {
console.log('[MODAL] Opening race modal'); // console.log('[MODAL] Opening race modal');
this.showRaceModal = true; this.showRaceModal = true;
const racesArr = this.raceCardData?.raceVenueRaces?.races ?? []; const racesArr = this.raceCardData?.raceVenueRaces?.races ?? [];
@ -315,7 +315,7 @@ liveStatusOk = true;
} }
closeModals() { closeModals() {
console.log('[MODAL] Closing all modals'); // console.log('[MODAL] Closing all modals');
this.showVenueModal = false; this.showVenueModal = false;
this.showRaceModal = false; this.showRaceModal = false;
this.showWalletModal = false; this.showWalletModal = false;
@ -335,7 +335,7 @@ liveStatusOk = true;
value: this.selectedVenue, value: this.selectedVenue,
}); });
console.log('[VENUE] Venue resolved to (structured):', this.selectedVenue, '| index:', index); // console.log('[VENUE] Venue resolved to (structured):', this.selectedVenue, '| index:', index);
this.closeModals(); this.closeModals();
} }
@ -367,7 +367,7 @@ liveStatusOk = true;
this.sharedStateService.setRunnerCount(runnerCount); this.sharedStateService.setRunnerCount(runnerCount);
this.updateEnabledHorseNumbers(); this.updateEnabledHorseNumbers();
console.log('[RACE] Race selected (structured):', this.selectedRace, '| Runner count:', runnerCount); // console.log('[RACE] Race selected (structured):', this.selectedRace, '| Runner count:', runnerCount);
this.closeModals(); this.closeModals();
} }
@ -399,30 +399,30 @@ liveStatusOk = true;
value: this.enabledHorseNumbers, value: this.enabledHorseNumbers,
}); });
console.log('[HORSE NUMBERS] Enabled horse numbers (structured):', this.enabledHorseNumbers); // console.log('[HORSE NUMBERS] Enabled horse numbers (structured):', this.enabledHorseNumbers);
} }
selectHorseNumber(number: number) { selectHorseNumber(number: number) {
console.log('[HORSE] Selected horse number:', number); // console.log('[HORSE] Selected horse number:', number);
} }
openWalletModal() { openWalletModal() {
console.log('[MODAL] Opening wallet modal'); // console.log('[MODAL] Opening wallet modal');
this.showWalletModal = true; this.showWalletModal = true;
} }
openResultModal() { openResultModal() {
console.log('[MODAL] Opening result modal'); // console.log('[MODAL] Opening result modal');
this.showResultModal = true; this.showResultModal = true;
} }
openMessagesModal() { openMessagesModal() {
console.log('[MODAL] Opening messages modal'); // console.log('[MODAL] Opening messages modal');
this.showMessagesModal = true; this.showMessagesModal = true;
} }
openLogModal() { openLogModal() {
console.log('[MODAL] Opening log modal'); // console.log('[MODAL] Opening log modal');
this.showLogModal = true; this.showLogModal = true;
} }
@ -492,8 +492,8 @@ liveStatusOk = true;
displayBarcode = '********' + last4; displayBarcode = '********' + last4;
} }
console.log(maskedBarcode); // console.log(maskedBarcode);
console.log('Decoded:', atob(maskedBarcode)); // console.log('Decoded:', atob(maskedBarcode));
return { return {
pool, pool,
@ -509,12 +509,12 @@ liveStatusOk = true;
}; };
}); });
} else { } else {
console.log('No tickets found in localStorage.'); // console.log('No tickets found in localStorage.');
this.formattedTicketLogs = []; this.formattedTicketLogs = [];
} }
this.showLogModal = true; this.showLogModal = true;
console.log('Log modal opened. Final formattedTicketLogs:', this.formattedTicketLogs); // console.log('Log modal opened. Final formattedTicketLogs:', this.formattedTicketLogs);
} }
logout(): void { logout(): void {
@ -528,7 +528,7 @@ liveStatusOk = true;
type: 'logout', // This is the missing piece type: 'logout', // This is the missing piece
}; };
console.log('[LOGOUT] Initiating logout with printData:', printData); // console.log('[LOGOUT] Initiating logout with printData:', printData);
fetch('http://localhost:9100/print', { fetch('http://localhost:9100/print', {
method: 'POST', method: 'POST',
@ -537,13 +537,13 @@ liveStatusOk = true;
}) })
.then((res) => { .then((res) => {
if (!res.ok) throw new Error('Logout print failed'); if (!res.ok) throw new Error('Logout print failed');
console.log('[LOGOUT] Print successful'); // console.log('[LOGOUT] Print successful');
(window as any).electronAPI?.closeSecondScreen?.(); (window as any).electronAPI?.closeSecondScreen?.();
localStorage.clear(); localStorage.clear();
this.router.navigate(['/logout']); this.router.navigate(['/logout']);
}) })
.catch((err) => { .catch((err) => {
console.error('[LOGOUT] Error printing:', err); // console.error('[LOGOUT] Error printing:', err);
(window as any).electronAPI?.closeSecondScreen?.(); (window as any).electronAPI?.closeSecondScreen?.();
localStorage.clear(); localStorage.clear();
this.router.navigate(['/logout']); this.router.navigate(['/logout']);
@ -561,3 +561,4 @@ liveStatusOk = true;
return item; return item;
} }
} }

View File

@ -64,11 +64,105 @@ export class SidebarComponent {
//---------------------------------------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 totalAmount)
// const cancelTicketData = {
// type: 'CANCEL_TICKET',
// ticketId: lastTicket.ticketId || '',
// barcodeId: lastTicket.barcodeId,
// cancelDate: new Date().toLocaleString(),
// totalAmount: lastTicket.totalAmount || 0 // <-- only totalAmount
// };
// // 🔍 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.totalAmount}
// ========================================
// `);
// // 🖨️ 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.';
// }
// }
// //--------------------------------COMPLETED THE CANCEL PRINT ---------------------------------------
//--------------------------------------- UPDATED CANCEL PRINT -------------------------------------------
cancelWarning: string = ''; // For showing inline warnings cancelWarning: string = ''; // For showing inline warnings
printTicketCancel() { async 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);
this.cancelWarning = ''; this.cancelWarning = '';
@ -108,20 +202,45 @@ printTicketCancel() {
console.log('[STEP 7] Stored Barcode ID:', storedBarcode); console.log('[STEP 7] Stored Barcode ID:', storedBarcode);
if (enteredTicketNo === storedBarcode) { if (enteredTicketNo === storedBarcode) {
console.log('[✅ MATCH] Ticket No matches barcode. Proceeding to print...'); console.log('[✅ MATCH] Ticket No matches barcode. Proceeding to cancel...');
// 🧾 Construct cancel print layout (only totalAmount) try {
const cancelTicketData = { // 🔗 Call cancel API first
type: 'CANCEL_TICKET', const cancelReq = {
ticketId: lastTicket.ticketId || '', ticketNo: lastTicket.barcodeId,
barcodeId: lastTicket.barcodeId, btId: lastTicket.btId || "0485", // <-- put correct btId here
cancelDate: new Date().toLocaleString(), usrId: lastTicket.usrId || "341" // <-- put correct usrId here
totalAmount: lastTicket.totalAmount || 0 // <-- only totalAmount };
};
// 🔍 Console Preview console.log("📡 Sending cancel request:", cancelReq);
console.log('🧾 [CANCEL TICKET LAYOUT]');
console.log(` const response = await fetch("http://localhost:8085/cancel/ticket", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(cancelReq)
});
const data = await response.json();
console.log("📩 Cancel API Response:", data);
if (!data.ok) {
console.error("❌ Cancel failed:", data.error);
this.cancelWarning = `❌ Cancel failed: ${data.error}`;
return;
}
// ✅ Only print if cancel API succeeded
const cancelTicketData = {
type: 'CANCEL_TICKET',
ticketId: lastTicket.ticketId || '',
barcodeId: lastTicket.barcodeId,
cancelDate: new Date().toLocaleString(),
totalAmount: lastTicket.totalAmount || 0
};
// 🔍 Console Preview
console.log('🧾 [CANCEL TICKET LAYOUT]');
console.log(`
======================================== ========================================
TICKET CANCELLED TICKET CANCELLED
---------------------------------------- ----------------------------------------
@ -130,26 +249,28 @@ Barcode ID : ${cancelTicketData.barcodeId}
Cancelled At : ${cancelTicketData.cancelDate} Cancelled At : ${cancelTicketData.cancelDate}
Original Total: ${cancelTicketData.totalAmount} Original Total: ${cancelTicketData.totalAmount}
======================================== ========================================
`); `);
// 🖨️ Send to printer server // 🖨️ Send to printer server
fetch('http://localhost:9100/print', { fetch('http://localhost:9100/print', {
method: 'POST', method: 'POST',
headers: { 'Content-Type': 'application/json' }, headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(cancelTicketData) body: JSON.stringify(cancelTicketData)
})
.then(response => {
if (!response.ok) throw new Error(`Printer error: ${response.status}`);
return response.text();
}) })
.then(result => { .then(r => r.text())
console.log("✅ Cancel ticket print successful:", result); .then(result => {
}) console.log("✅ Cancel ticket print successful:", result);
.catch(error => { })
console.error("❌ Cancel ticket print failed:", error); .catch(error => {
}); console.error("❌ Cancel ticket print failed:", error);
});
this.closeCancelPopup(); this.closeCancelPopup();
} catch (e) {
console.error("❌ Cancel API call failed:", e);
this.cancelWarning = '❌ Cancel API call failed. Please try again.';
}
} else { } else {
console.warn('[❌ MISMATCH] Entered Ticket No does NOT match last stored barcode.'); console.warn('[❌ MISMATCH] Entered Ticket No does NOT match last stored barcode.');
@ -157,7 +278,7 @@ Original Total: ₹${cancelTicketData.totalAmount}
} }
} }
//--------------------------------COMPLETED THE CANCEL PRINT --------------------------------------- //-------------------------------- COMPLETED THE CANCEL PRINT WITH API CALL --------------------------------
openPayoutPopup() { openPayoutPopup() {
@ -524,3 +645,4 @@ objectKeys = Object.keys;
} }
} }
} }

View File

@ -143,10 +143,7 @@ export class TouchPadMenuComponent implements OnInit, OnDestroy {
this.maxRowsReached = selections.length >= 5; this.maxRowsReached = selections.length >= 5;
const totalAmount = selections.reduce((sum: number, selection: SelectionData) => sum + (selection.total || 0), 0); const totalAmount = selections.reduce((sum: number, selection: SelectionData) => sum + (selection.total || 0), 0);
this.totalAmountLimitReached = totalAmount >= 5000; this.totalAmountLimitReached = totalAmount >= 5000;
this.blockedLabels = this.labelRestrictionService.getBlockedLabels(selections);
// NEW:
this.refreshBlockedLabels(this.selectedLabel);
if (!this.totalAmountLimitReached) { if (!this.totalAmountLimitReached) {
this.showLimitPopup = false; this.showLimitPopup = false;
} }
@ -392,8 +389,6 @@ export class TouchPadMenuComponent implements OnInit, OnDestroy {
this.runnerCount = this.getRunnerCountForLeg(this.multiLegBaseRaceIdx, 0) || 12; this.runnerCount = this.getRunnerCountForLeg(this.multiLegBaseRaceIdx, 0) || 12;
this.numbers = Array.from({ length: 30 }, (_, i) => i + 1); this.numbers = Array.from({ length: 30 }, (_, i) => i + 1);
this.numbersFlat = this.numberRows.flat(); this.numbersFlat = this.numberRows.flat();
// Call after pool change
this.refreshBlockedLabels(label);
} else { } else {
this.currentPool = null; this.currentPool = null;
this.multiLegBaseRaceIdx = 0; this.multiLegBaseRaceIdx = 0;
@ -404,8 +399,6 @@ export class TouchPadMenuComponent implements OnInit, OnDestroy {
}); });
// --- NEW: Update actualRunners for single race --- // --- NEW: Update actualRunners for single race ---
this.setActualRunners(); this.setActualRunners();
// Call after pool change
this.refreshBlockedLabels(label);
} }
//----------------------------------ADDED THIS ----------------------------------------------------- //----------------------------------ADDED THIS -----------------------------------------------------
@ -428,13 +421,9 @@ export class TouchPadMenuComponent implements OnInit, OnDestroy {
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]);
// Call after setSelections
this.refreshBlockedLabels(label);
} }
} }
this.selectionService.updatePartial({ label: '', numbers: [], value: 0, total: 0 }); this.selectionService.updatePartial({ label: '', numbers: [], value: 0, total: 0 });
// Call before return in WSP
this.refreshBlockedLabels(label);
return; return;
} }
//----------------------------------ended here---------------------------------------------------- //----------------------------------ended here----------------------------------------------------
@ -451,8 +440,6 @@ export class TouchPadMenuComponent implements OnInit, OnDestroy {
this.multiLegGroups = [[], [], [], [], []]; this.multiLegGroups = [[], [], [], [], []];
this.selectionService.updatePartial({ label }); this.selectionService.updatePartial({ label });
// recompute blocked labels including newly-selected label
this.refreshBlockedLabels(label);
} }
private getBaseRaceIndexForPool(poolName: string): number { private getBaseRaceIndexForPool(poolName: string): number {
@ -577,8 +564,6 @@ if (this.twoGroupLabels.includes(this.selectedLabel || '')) {
return sel; return sel;
}); });
this.selectionService.setSelections(updated); this.selectionService.setSelections(updated);
// Call after setSelections
this.refreshBlockedLabels(this.selectedLabel);
} }
} }
} }
@ -645,8 +630,6 @@ if (this.twoGroupLabels.includes(this.selectedLabel || '')) {
}); });
this.selectionService.setSelections(updatedSelections); this.selectionService.setSelections(updatedSelections);
// Call after setSelections
this.refreshBlockedLabels(this.selectedLabel);
this.padValue = ''; this.padValue = '';
this.updateCanPrint(); this.updateCanPrint();
} }
@ -679,8 +662,6 @@ if (this.twoGroupLabels.includes(this.selectedLabel || '')) {
}); });
this.selectionService.setSelections(updatedSelections); this.selectionService.setSelections(updatedSelections);
// Call after setSelections
this.refreshBlockedLabels(this.selectedLabel);
// Only increment stage if not at the last stage (PLP) // Only increment stage if not at the last stage (PLP)
if (this.wspTicketStage < 2) { if (this.wspTicketStage < 2) {
@ -778,8 +759,6 @@ if (this.twoGroupLabels.includes(this.selectedLabel || '')) {
}); });
this.selectionService.setSelections(updatedSelections); this.selectionService.setSelections(updatedSelections);
// Call after setSelections
this.refreshBlockedLabels(this.selectedLabel);
const currentTotal = updatedSelections.find(sel => sel.label === targetLabel)?.total || 0; const currentTotal = updatedSelections.find(sel => sel.label === targetLabel)?.total || 0;
if (currentTotal === 0 && value > 0) { if (currentTotal === 0 && value > 0) {
@ -787,8 +766,6 @@ if (this.twoGroupLabels.includes(this.selectedLabel || '')) {
this.selectionService.setSelections( this.selectionService.setSelections(
updatedSelections.filter(sel => sel.label !== targetLabel || sel.numbers.length > 0) updatedSelections.filter(sel => sel.label !== targetLabel || sel.numbers.length > 0)
); );
// Call after setSelections
this.refreshBlockedLabels(this.selectedLabel);
this.wspTicketStage = 0; this.wspTicketStage = 0;
this.padValue = ''; this.padValue = '';
this.selectedNumbers = []; this.selectedNumbers = [];
@ -960,13 +937,9 @@ if (this.twoGroupLabels.includes(this.selectedLabel || '')) {
const currentSelections = this.selectionService.getSelections(); const currentSelections = this.selectionService.getSelections();
const nonWSPSelections = currentSelections.filter(sel => !['WNP', 'SHP', 'PLP'].includes(sel.label)); const nonWSPSelections = currentSelections.filter(sel => !['WNP', 'SHP', 'PLP'].includes(sel.label));
this.selectionService.setSelections([...nonWSPSelections, ...virtualRows]); this.selectionService.setSelections([...nonWSPSelections, ...virtualRows]);
// Call after setSelections
this.refreshBlockedLabels(this.selectedLabel);
} }
this.selectionService.finalizeCurrentRow(); this.selectionService.finalizeCurrentRow();
// Call after finalizeCurrentRow
this.refreshBlockedLabels(null);
this.resetSelections(); this.resetSelections();
} }
@ -1119,23 +1092,7 @@ const winLabels = allRows.map(row => {
let expandedLegs: string[] = legs.map((leg, i) => { let expandedLegs: string[] = legs.map((leg, i) => {
// Find race index for this leg // Find race index for this leg
let raceIdx = raceIndices.length > i ? raceIndices[i] - 1 : (baseRaceIdx - 1 + i); let raceIdx = raceIndices.length > i ? raceIndices[i] - 1 : (baseRaceIdx - 1 + i);
// let expanded = leg.flatMap(n =>
// n === 'F'
// ? this.getHorseNumbersForRaceIdx(raceIdx).map(num => num.toString())
// : [n]
// );
// let expanded = leg.flatMap((n, idx) => {
// if (n === 'F') {
// const horses = this.getHorseNumbersForRaceIdx(raceIdx).map(num => num.toString()).join(',');
// const isFirst = idx === 0;
// const isLast = idx === leg.length - 1;
// if (isFirst && !isLast) return [`${horses}-`];
// if (!isFirst && isLast) return [`-${horses}`];
// if (isFirst && isLast) return [horses]; // only F in the leg
// return [`-${horses}-`];
// }
// return [n];
// });
let expanded = leg.flatMap((n) => { let expanded = leg.flatMap((n) => {
if (n === 'F') { if (n === 'F') {
// Expand F → horse numbers, no extra dashes // Expand F → horse numbers, no extra dashes
@ -1159,21 +1116,7 @@ const winLabels = allRows.map(row => {
// 🐎 Expand 'F' to full horse numbers for other pools // 🐎 Expand 'F' to full horse numbers for other pools
if (displayNumbers.includes('F')) { if (displayNumbers.includes('F')) {
// displayNumbers = displayNumbers.flatMap(n =>
// n === 'F' ? this.getHorseNumbersForSelectedRace().map(num => num.toString()) : [n]
// );
// displayNumbers = displayNumbers.flatMap((n, idx, arr) => {
// if (n === 'F') {
// const horses = this.getHorseNumbersForSelectedRace().map(num => num.toString()).join(',');
// const isFirst = idx === 0;
// const isLast = idx === arr.length - 1;
// if (isFirst && !isLast) return [`${horses}-`];
// if (!isFirst && isLast) return [`-${horses}`];
// if (isFirst && isLast) return [horses]; // only F
// return [`-${horses}-`];
// }
// return [n];
// });
displayNumbers = displayNumbers.flatMap((n) => { displayNumbers = displayNumbers.flatMap((n) => {
if (n === 'F') { if (n === 'F') {
// Expand F → horse numbers, no extra dashes // Expand F → horse numbers, no extra dashes
@ -1434,6 +1377,14 @@ try {
// If we reach here, commit succeeded // If we reach here, commit succeeded
console.log('✅ /isr/commit success:', commitJson); console.log('✅ /isr/commit success:', commitJson);
this.erase(); // <-- Clear selections after successful print this.erase(); // <-- Clear selections after successful print
// 👉 Save whole response into localStorage under key "issueT"
try {
localStorage.setItem('issueT', JSON.stringify(commitJson));
console.log('Saved commitJson into localStorage key: issueT');
} catch (e) {
console.warn('Failed to save issueT:', e);
}
} catch (error) { } catch (error) {
console.error("❌ Print failed:", error); console.error("❌ Print failed:", error);
this.cdr.markForCheck(); // <-- Ensure UI updates on error this.cdr.markForCheck(); // <-- Ensure UI updates on error
@ -1441,18 +1392,33 @@ try {
// this.erase(); // Uncomment if you want to clear on error // this.erase(); // Uncomment if you want to clear on error
} }
//---------------------------------------------- BACK END ENDS HERE ----------------------------------------------------- //---------------------------------------------- BACK END ENDS HERE -----------------------------------------------------
// 🖨️ Send to printer API // read issueT from localStorage
const payload = { let issueT: any = null;
type: 'ticket', try {
ticketId: printData.ticketId, const raw = localStorage.getItem('issueT');
barcodeId: printData.barcodeId, issueT = raw ? JSON.parse(raw) : null;
winLabels: printData.winLabels, } catch (e) {
ticketCount: printData.ticketCount, console.warn('Could not parse issueT from localStorage:', e);
totalAmount: printData.totalAmount, }
gstNumber: printData.gstNumber,
dateTime: now.toLocaleString() // fallback to printData.barcodeId if issueT is missing
}; const barcodeIdToUse = issueT?.tktNumUsed ?? printData.barcodeId;
const payload = {
type: 'ticket',
ticketId: printData.ticketId,
barcodeId: barcodeIdToUse, // ✅ use tktNumUsed from issueT
winLabels: printData.winLabels,
ticketCount: printData.ticketCount,
totalAmount: printData.totalAmount,
gstNumber: printData.gstNumber,
dateTime: now.toLocaleString()
};
console.log('Printer payload:', payload);
fetch('http://localhost:9100/print', { fetch('http://localhost:9100/print', {
method: 'POST', method: 'POST',
@ -1534,8 +1500,6 @@ try {
//--------------------Ended Print here ----------------------------- //--------------------Ended Print here -----------------------------
this.selectionService.finalizeCurrentRow(); this.selectionService.finalizeCurrentRow();
// Call after finalizeCurrentRow
this.refreshBlockedLabels(null);
this.resetSelections(); this.resetSelections();
} }
@ -1543,7 +1507,6 @@ try {
erase() { erase() {
this.selectionService.clearSelections(); this.selectionService.clearSelections();
this.resetSelections(); this.resetSelections();
this.refreshBlockedLabels(null);
this.cdr.markForCheck(); // <-- Force UI update this.cdr.markForCheck(); // <-- Force UI update
} }
@ -1569,8 +1532,8 @@ try {
this.fieldInput = ''; this.fieldInput = '';
this.fieldFEntered = false; this.fieldFEntered = false;
this.wspTicketStage = 0; this.wspTicketStage = 0;
// Explicitly reset blocked labels (no current label) // Explicitly reset blocked labels
this.refreshBlockedLabels(null); this.blockedLabels = this.labelRestrictionService.getBlockedLabels([]);
this.updateCanPrint(); this.updateCanPrint();
this.sharedStateService.updateSharedData({ type: 'multiLegPoolEnd', value: null }); this.sharedStateService.updateSharedData({ type: 'multiLegPoolEnd', value: null });
this.cdr.markForCheck(); // <-- Force UI update this.cdr.markForCheck(); // <-- Force UI update
@ -1853,8 +1816,6 @@ try {
this.poolReplaceOpen = false; this.poolReplaceOpen = false;
// Update selection service with new label // Update selection service with new label
this.selectionService.updatePartial({ label }); this.selectionService.updatePartial({ label });
// recompute blocked labels including newly-selected label
this.refreshBlockedLabels(label);
} }
closePoolReplaceModal() { this.poolReplaceOpen = false; } closePoolReplaceModal() { this.poolReplaceOpen = false; }
@ -1895,8 +1856,6 @@ try {
this.runnerCount = this.getRunnerCountForLeg(this.multiLegBaseRaceIdx, 0) || 12; this.runnerCount = this.getRunnerCountForLeg(this.multiLegBaseRaceIdx, 0) || 12;
this.numbers = Array.from({ length: 30 }, (_, i) => i + 1); this.numbers = Array.from({ length: 30 }, (_, i) => i + 1);
this.numbersFlat = this.numberRows.flat(); this.numbersFlat = this.numberRows.flat();
// Call after pool change
this.refreshBlockedLabels('TRE');
} }
closeTrePopup() { this.trePopupVisible = false; } closeTrePopup() { this.trePopupVisible = false; }
@ -1961,14 +1920,6 @@ try {
currentRow.value <= 100 && currentRow.value <= 100 &&
currentRow.total > 0; currentRow.total > 0;
} }
}
// add this in the component class (near other helpers)
private refreshBlockedLabels(currentLabel?: string | null) {
// Pass finalized selections and optionally the in-progress/current label
const finalized = this.selectionService.getSelections();
this.blockedLabels = this.labelRestrictionService.getBlockedLabels(finalized, currentLabel ?? this.selectedLabel);
console.log('[DEBUG] refreshBlockedLabels -> selectedLabel:', currentLabel ?? this.selectedLabel, 'blocked:', Array.from(this.blockedLabels));
// Ensure OnPush UI updates
try { this.cdr.markForCheck(); } catch (e) { /* ignore */ }
}
}