fix : Re labeled multilegpools for ticket issue

This commit is contained in:
Sibin Sabu 2025-09-17 13:00:19 +05:30
parent ba40f4dd52
commit ed83f86c91
3 changed files with 56 additions and 29 deletions

View File

@ -6,9 +6,9 @@ export const LABEL_GROUPS: { [key: string]: string[] } = {
groupA: ['WNP', 'SHP', 'THP', 'PLP', 'SHW'], groupA: ['WNP', 'SHP', 'THP', 'PLP', 'SHW'],
groupB: ['FRP', 'QNP', 'TNP', 'EXA'], groupB: ['FRP', 'QNP', 'TNP', 'EXA'],
groupWSP: ['WSP'], groupWSP: ['WSP'],
groupTRE: ['TRE'], groupTBP: ['TBP'],
groupMJP: ['MJP'], groupMJP: ['MJP'],
groupJKP: ['JKP'], groupJPP: ['JPP'],
}; };
// Reverse index to map labels to their groups // Reverse index to map labels to their groups

View File

@ -198,9 +198,9 @@ export class SelectionService {
break; break;
} }
case 'TRE': case 'TBP':
case 'MJP': case 'MJP':
case 'JKP': { case 'JPP': {
const legCount = this.getLegCount(label); const legCount = this.getLegCount(label);
const legs = this.splitToLegs(numbers, legCount); const legs = this.splitToLegs(numbers, legCount);
@ -287,9 +287,9 @@ export class SelectionService {
private getLegCount(label: string): number { private getLegCount(label: string): number {
switch (label) { switch (label) {
case 'TRE': return 3; case 'TBP': return 3;
case 'MJP': return 4; case 'MJP': return 4;
case 'JKP': return 5; case 'JPP': return 5;
default: return 3; default: return 3;
} }
} }

View File

@ -28,14 +28,14 @@ export class TouchPadMenuComponent implements OnInit, OnDestroy {
@Input() ticketingActive: boolean = false; @Input() ticketingActive: boolean = false;
public twoGroupLabels = ['FRP', 'QNP']; public twoGroupLabels = ['FRP', 'QNP'];
public multiLegLabels = ['TRE', 'MJP', 'JKP']; public multiLegLabels = ['TBP', 'MJP', 'JPP'];
public threeGroupLabels = ['TNP']; public threeGroupLabels = ['TNP'];
public allowedFieldLabels = ['WNP', 'SHP', 'THP', 'PLP', 'SHW']; public allowedFieldLabels = ['WNP', 'SHP', 'THP', 'PLP', 'SHW'];
labels: string[] = [ labels: string[] = [
'WNP', 'SHP', 'THP', 'PLP', 'SHW', 'FRP', 'WNP', 'SHP', 'THP', 'PLP', 'SHW', 'FRP',
'QNP', 'TNP', 'EXA', 'WSP', 'TRE', 'MJP', 'QNP', 'TNP', 'EXA', 'WSP', 'TBP', 'MJP',
'JKP', 'SJP', '.' 'JPP', 'SJP', '.'
]; ];
numbers: number[] = Array.from({ length: 30 }, (_, i) => i + 1); numbers: number[] = Array.from({ length: 30 }, (_, i) => i + 1);
@ -65,12 +65,12 @@ export class TouchPadMenuComponent implements OnInit, OnDestroy {
firstGroup: (number | string)[] = []; firstGroup: (number | string)[] = [];
secondGroup: (number | string)[] = []; secondGroup: (number | string)[] = [];
// Multi-leg logic (TRE, MJP, JKP) // Multi-leg logic (TRE, MJP, JPP)
multiLegStage = 0; multiLegStage = 0;
multiLegGroups: (number | string)[][] = [[], [], [], [], []]; multiLegGroups: (number | string)[][] = [[], [], [], [], []];
multiLegBaseRaceIdx: number = 0; // Track starting race index (1-based) multiLegBaseRaceIdx: number = 0; // Track starting race index (1-based)
currentLegRaceDisplay: string = ''; // Display current leg's race currentLegRaceDisplay: string = ''; // Display current leg's race
currentPool: string | null = null; // canonical pool key like 'mjp1','trb1','jkp1' currentPool: string | null = null; // canonical pool key like 'mjp1','trb1','JPP1'
isBoxed: boolean = false; isBoxed: boolean = false;
@ -283,7 +283,7 @@ export class TouchPadMenuComponent implements OnInit, OnDestroy {
if (['FRP', 'QNP', 'TNP'].includes(label) && this.isBoxed) { if (['FRP', 'QNP', 'TNP'].includes(label) && this.isBoxed) {
return false; return false;
} }
const specialLabels = ['FRP', 'QNP', 'TNP', 'EXA', 'TRE', 'MJP', 'JKP', '.']; const specialLabels = ['FRP', 'QNP', 'TNP', 'EXA', 'TBP', 'MJP', 'JPP', '.'];
if (this.multiLegLabels.includes(label)) { if (this.multiLegLabels.includes(label)) {
const maxLegs = this.getMaxLegs(this.currentPool || ''); const maxLegs = this.getMaxLegs(this.currentPool || '');
// Hide Shash Enter if on the final leg // Hide Shash Enter if on the final leg
@ -315,7 +315,7 @@ export class TouchPadMenuComponent implements OnInit, OnDestroy {
get isBoxToggleDisabled(): boolean { get isBoxToggleDisabled(): boolean {
if (!this.selectedLabel) return true; if (!this.selectedLabel) return true;
const disallowedBoxLabels = ['WNP', 'SHP', 'THP', 'PLP', 'WSP', 'SHW', 'TRE', 'MJP', 'JKP']; const disallowedBoxLabels = ['WNP', 'SHP', 'THP', 'PLP', 'WSP', 'SHW', 'TBP', 'MJP', 'JPP'];
if (disallowedBoxLabels.includes(this.selectedLabel)) { if (disallowedBoxLabels.includes(this.selectedLabel)) {
return true; return true;
} }
@ -346,7 +346,7 @@ export class TouchPadMenuComponent implements OnInit, OnDestroy {
// Additional check for multi-leg pools: disable if any race in the pool is stopped // Additional check for multi-leg pools: disable if any race in the pool is stopped
if (this.multiLegLabels.includes(label)) { if (this.multiLegLabels.includes(label)) {
const poolName = label === 'MJP' ? 'mjp1' : label === 'JKP' ? 'jkp1' : 'trb1'; const poolName = label === 'MJP' ? 'mjp1' : label === 'JPP' ? 'jkp1' : 'trb1';
const raceIndices = this.getRaceIndicesForPool(poolName); const raceIndices = this.getRaceIndicesForPool(poolName);
if (raceIndices.some(race => !this.isOpen(race))) { if (raceIndices.some(race => !this.isOpen(race))) {
return true; return true;
@ -403,7 +403,7 @@ export class TouchPadMenuComponent implements OnInit, OnDestroy {
this.showLimitPopup = true; this.showLimitPopup = true;
return; return;
} }
if (label === 'TRE') { if (label === 'TBP') {
this.trePopupVisible = true; this.trePopupVisible = true;
return; return;
} }
@ -417,7 +417,7 @@ export class TouchPadMenuComponent implements OnInit, OnDestroy {
// Store base race index and pool name for multi-leg pools // Store base race index and pool name for multi-leg pools
if (this.multiLegLabels.includes(label)) { if (this.multiLegLabels.includes(label)) {
// Map to canonical pool key // Map to canonical pool key
const poolName = label === 'MJP' ? 'mjp1' : label === 'JKP' ? 'jkp1' : 'trb1'; const poolName = label === 'MJP' ? 'mjp1' : label === 'JPP' ? 'jkp1' : 'trb1';
this.currentPool = poolName; this.currentPool = poolName;
this.multiLegBaseRaceIdx = this.getBaseRaceIndexForPool(poolName); // Broadcast race and pool info for navbar this.multiLegBaseRaceIdx = this.getBaseRaceIndexForPool(poolName); // Broadcast race and pool info for navbar
// Broadcast race and pool info for navbar // Broadcast race and pool info for navbar
@ -657,7 +657,7 @@ if (this.twoGroupLabels.includes(this.selectedLabel || '')) {
this.updateLegRaceDisplay(this.currentPool || ''); this.updateLegRaceDisplay(this.currentPool || '');
} }
private calculateMultiLegAmount(poolType: 'TRE' | 'MJP' | 'JKP', horsesPerLeg: number[], units: number, unitBet: number = 10): number { private calculateMultiLegAmount(poolType: 'TBP' | 'MJP' | 'JPP', horsesPerLeg: number[], units: number, unitBet: number = 10): number {
return horsesPerLeg.reduce((acc, v) => acc * v, 1) * units * unitBet; return horsesPerLeg.reduce((acc, v) => acc * v, 1) * units * unitBet;
} }
@ -684,7 +684,7 @@ if (this.twoGroupLabels.includes(this.selectedLabel || '')) {
let combinations = 1; let combinations = 1;
if (['TNP', 'FRP', 'QNP'].includes(row.label)) { if (['TNP', 'FRP', 'QNP'].includes(row.label)) {
combinations = row.numbers.length * (row.numbers.length - 1); combinations = row.numbers.length * (row.numbers.length - 1);
} else if (['TRE', 'JKP', 'MJP'].includes(row.label)) { } else if (['TBP', 'JPP', 'MJP'].includes(row.label)) {
const legs = row.numbers.join('').split('/').map(leg => leg.split(',').length); const legs = row.numbers.join('').split('/').map(leg => leg.split(',').length);
combinations = legs.reduce((a, b) => a * b, 1); combinations = legs.reduce((a, b) => a * b, 1);
} else if (row.isBoxed) { } else if (row.isBoxed) {
@ -1001,7 +1001,7 @@ if (this.twoGroupLabels.includes(this.selectedLabel || '')) {
return group.length; return group.length;
}).slice(0, maxLegs); }).slice(0, maxLegs);
const units = parseFloat(this.padValue) || 0; const units = parseFloat(this.padValue) || 0;
currentRowAmount = this.calculateMultiLegAmount(this.selectedLabel as 'TRE' | 'MJP' | 'JKP', horsesPerLeg, units); currentRowAmount = this.calculateMultiLegAmount(this.selectedLabel as 'TBP' | 'MJP' | 'JPP', horsesPerLeg, units);
if (currentRowAmount > 5000 || selectionsTotal + currentRowAmount > 5000) { if (currentRowAmount > 5000 || selectionsTotal + currentRowAmount > 5000) {
this.totalAmountLimitReached = true; this.totalAmountLimitReached = true;
this.showLimitPopup = true; this.showLimitPopup = true;
@ -1098,7 +1098,7 @@ async printTicket() {
if (['TNP', 'FRP', 'QNP'].includes(currentRow.label)) { if (['TNP', 'FRP', 'QNP'].includes(currentRow.label)) {
combinations = currentRow.numbers.length * (currentRow.numbers.length - 1); combinations = currentRow.numbers.length * (currentRow.numbers.length - 1);
} else if (['TRE', 'JKP', 'MJP'].includes(currentRow.label)) { } else if (['TBP', 'JPP', 'MJP'].includes(currentRow.label)) {
combinations = 1; // or your specific logic combinations = 1; // or your specific logic
} else if (currentRow.label === 'BOX') { } else if (currentRow.label === 'BOX') {
const n = currentRow.numbers.length; const n = currentRow.numbers.length;
@ -1131,7 +1131,7 @@ async printTicket() {
// const ticketId = `${venue}/${fullYear}${month}${day}/1`; // const ticketId = `${venue}/${fullYear}${month}${day}/1`;
// For multi-leg pools (TRE, MJP, JKP), show the pool name (trb1, trb2, mjp1, jkp1) instead of race number // For multi-leg pools (TRE, MJP, JKP), show the pool name (trb1, trb2, mjp1, jkp1) instead of race number
let ticketId: string; let ticketId: string;
if (['TRE', 'MJP', 'JKP'].includes(this.selectedLabel || '') && this.currentPool) { if (['TBP', 'MJP', 'JPP'].includes(this.selectedLabel || '') && this.currentPool) {
ticketId = `${venue}/${fullYear}${month}${day}/${this.currentPool}`; ticketId = `${venue}/${fullYear}${month}${day}/${this.currentPool}`;
} else { } else {
ticketId = `${venue}/${fullYear}${month}${day}/${this.selectedRaceNumber}`; ticketId = `${venue}/${fullYear}${month}${day}/${this.selectedRaceNumber}`;
@ -1145,12 +1145,12 @@ const winLabels = allRows.map(row => {
let displayLabel = row.label; // Use row.label by default let displayLabel = row.label; // Use row.label by default
// Override label for TRE to use currentPool (trb1 or trb2) // Override label for TRE to use currentPool (trb1 or trb2)
if (row.label === 'TRE' && this.currentPool) { if (row.label === 'TBP' && this.currentPool) {
displayLabel = this.currentPool; // Use trb1 or trb2 displayLabel = this.currentPool; // Use trb1 or trb2
} }
// --- Multi-leg pools: Expand 'F' for each leg --- // --- Multi-leg pools: Expand 'F' for each leg ---
if (['TRE', 'MJP', 'JKP'].includes(row.label)) { if (['TBP', 'MJP', 'JPP'].includes(row.label)) {
// Split by '/' for legs // Split by '/' for legs
let legs: (number | string)[][] = []; let legs: (number | string)[][] = [];
let currentLeg: (number | string)[] = []; let currentLeg: (number | string)[] = [];
@ -1165,7 +1165,7 @@ const winLabels = allRows.map(row => {
if (currentLeg.length) legs.push(currentLeg); if (currentLeg.length) legs.push(currentLeg);
// For each leg, expand 'F' to correct horse numbers for that leg // For each leg, expand 'F' to correct horse numbers for that leg
const poolName = row.label === 'MJP' ? 'mjp1' : row.label === 'JKP' ? 'jkp1' : this.currentPool || 'trb1'; const poolName = row.label === 'MJP' ? 'mjp1' : row.label === 'JPP' ? 'jkp1' : this.currentPool || 'trb1';
const raceCardData = JSON.parse(localStorage.getItem('raceCardData') || '{}'); const raceCardData = JSON.parse(localStorage.getItem('raceCardData') || '{}');
const poolRaces = raceCardData?.raceVenueRaces?.pools?.[poolName] || []; const poolRaces = raceCardData?.raceVenueRaces?.pools?.[poolName] || [];
// Fallback to hardcoded mapping if needed // Fallback to hardcoded mapping if needed
@ -1440,8 +1440,35 @@ const dateStr = ticketParts[1] || ''; // "20250907"
const raceDt = dateStr && dateStr.length === 8 const raceDt = dateStr && dateStr.length === 8
? `${dateStr.slice(0,4)}/${dateStr.slice(4,6)}/${dateStr.slice(6,8)}` ? `${dateStr.slice(0,4)}/${dateStr.slice(4,6)}/${dateStr.slice(6,8)}`
: (new Date()).toISOString().slice(0,10).replace(/-/g,'/'); : (new Date()).toISOString().slice(0,10).replace(/-/g,'/');
const raceNumRaw = ticketParts[2] || '1'; // const raceNumRaw = ticketParts[2] || '1';
const raceNum = String(Number(raceNumRaw)).padStart(2,'0'); // const raceNum = String(Number(raceNumRaw)).padStart(2,'0');
// --- with this improved extraction (keeps safe fallbacks) ---
const raceNumRaw = (ticketParts[2] || '').trim(); // e.g. "jkp1", "mjp1", "trb2"
let raceNum = '01'; // default/fallback
const sufMatch = raceNumRaw.match(/^([a-zA-Z]+)(\d+)$/);
if (sufMatch) {
const prefix = sufMatch[1].toLowerCase(); // "jkp", "mjp", "trb"
const num = sufMatch[2]; // "1", "2", ...
// map known prefixes to desired single-letter codes
const prefixMap: Record<string, string> = {
jkp: 'J',
mjp: 'M',
trb: 'T'
// add more mappings if you have other station codes
};
const letter = prefixMap[prefix] ?? prefix.charAt(0).toUpperCase();
raceNum = `${letter}${num}`; // "J1", "M1", "T2", ...
} else {
// if suffix was purely numeric, preserve old numeric behavior (zero-padded)
const asNum = Number(raceNumRaw);
if (Number.isFinite(asNum) && raceNumRaw !== '') {
raceNum = String(Math.floor(asNum)).padStart(2, '0'); // "01", "02", etc.
} else {
// fallback stays '01' (change if you prefer different fallback)
raceNum = '01';
}
}
const btId_bc = (printData.barcodeId || '0000').toString().slice(0,4); const btId_bc = (printData.barcodeId || '0000').toString().slice(0,4);
const betInfo = formattedWinLabels || printData.winLabels || ''; const betInfo = formattedWinLabels || printData.winLabels || '';
const nHorseBits = [0,0,0,0,0,0,0,0]; const nHorseBits = [0,0,0,0,0,0,0,0];
@ -1952,7 +1979,7 @@ try {
} }
private _selectTreAfterPopup(btnNum: number) { private _selectTreAfterPopup(btnNum: number) {
this.selectedLabel = 'TRE'; this.selectedLabel = 'TBP';
this.selectedNumbers = []; this.selectedNumbers = [];
this.padValue = ''; this.padValue = '';
this.canPrint = false; this.canPrint = false;
@ -1976,14 +2003,14 @@ try {
}); });
this.updateLegRaceDisplay(poolInfo.name); this.updateLegRaceDisplay(poolInfo.name);
this.selectionService.updatePartial({ label: 'TRE' }); this.selectionService.updatePartial({ label: 'TBP' });
this.actualRunners = this.getActualRunnersForCurrentPoolLeg(); this.actualRunners = this.getActualRunnersForCurrentPoolLeg();
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 // Call after pool change
this.refreshBlockedLabels('TRE'); this.refreshBlockedLabels('TBP');
} }
closeTrePopup() { this.trePopupVisible = false; } closeTrePopup() { this.trePopupVisible = false; }