fix : made group for labels

This commit is contained in:
karthik 2025-08-05 13:50:30 +05:30
parent ac9e377bf3
commit 0779cb38ec
3 changed files with 118 additions and 72 deletions

View File

@ -60,4 +60,4 @@ export class MiddleSectionComponent implements OnInit, OnDestroy {
this.sub1.unsubscribe();
this.sub2.unsubscribe();
}
}
}

View File

@ -0,0 +1,51 @@
import { Injectable } from '@angular/core';
import { SelectionData } from '../selection.service/selection.service';
// Define mutually exclusive label groups
export const LABEL_GROUPS: { [key: string]: string[] } = {
groupA: ['WIN', 'SHP', 'THP', 'PLC', 'SHW'],
groupB: ['FOR', 'QUI', 'TAN', 'EXA'],
groupWSP: ['WSP'],
groupTRE: ['TRE'],
groupMJP: ['MJP'],
groupJKP: ['JKP'],
};
// Reverse index to map labels to their groups
export const LABEL_TO_GROUP: { [label: string]: string } = {};
Object.entries(LABEL_GROUPS).forEach(([group, labels]) => {
labels.forEach(label => (LABEL_TO_GROUP[label] = group));
});
@Injectable({ providedIn: 'root' })
export class LabelRestrictionService {
getBlockedLabels(selections: SelectionData[]): Set<string> {
const selectedGroups = new Set<string>();
for (const row of selections) {
if (row.label && LABEL_TO_GROUP[row.label]) {
selectedGroups.add(LABEL_TO_GROUP[row.label]);
}
}
const blockLabels = new Set<string>();
if (selectedGroups.size > 0) {
// Block all labels from groups not already selected
Object.entries(LABEL_GROUPS).forEach(([group, labels]) => {
if (!selectedGroups.has(group)) {
labels.forEach(label => blockLabels.add(label));
}
});
// Special rule for WSP: if WSP is selected, only allow WIN, SHP, THP in the three rows
if (selectedGroups.has('groupWSP')) {
Object.keys(LABEL_TO_GROUP).forEach(label => {
if (!['WIN', 'SHP', 'THP'].includes(label)) {
blockLabels.add(label);
}
});
}
}
return blockLabels;
}
}

View File

@ -1,10 +1,9 @@
import { Component, Input, OnInit, OnDestroy } from '@angular/core';
import { CommonModule } from '@angular/common';
import { Subscription } from 'rxjs';
import { SelectionService } from '../selection.service/selection.service';
import { SelectionData } from '../selection.service/selection.service';
import { SelectionService, SelectionData } from '../selection.service/selection.service';
import { SharedStateService } from '../../service/shared-state.service';
import { LabelRestrictionService } from '../selection.service/label-restriction.service';
@Component({
selector: 'app-touch-pad-menu',
standalone: true,
@ -27,15 +26,12 @@ export class TouchPadMenuComponent implements OnInit, OnDestroy {
];
numbers: number[] = Array.from({ length: 30 }, (_, i) => i + 1);
runnerCount: number = 12; // Fallback
runnerCount: number = 12;
labelRowsFlat: string[] = [];
numbersFlat: number[] = [];
// --- NEW PROPERTY ---
public actualRunners: Set<number> = new Set();
wspTicketStage: number = 0; //added this
blockedLabels = new Set<string>();
actualRunners: Set<number> = new Set();
wspTicketStage: number = 0;
selectedLabel: string | null = null;
selectedNumbers: (number | string)[] = [];
padValue: string = '';
@ -45,7 +41,6 @@ export class TouchPadMenuComponent implements OnInit, OnDestroy {
maxRowsReached: boolean = false;
totalAmountLimitReached: boolean = false;
showLimitPopup: boolean = false;
disabledLabels: string[] = ['SHW', 'SJP', '.'];
// TAN logic
@ -85,7 +80,8 @@ export class TouchPadMenuComponent implements OnInit, OnDestroy {
constructor(
private selectionService: SelectionService,
private sharedStateService: SharedStateService
private sharedStateService: SharedStateService,
private labelRestrictionService: LabelRestrictionService
) {}
ngOnInit() {
@ -104,6 +100,7 @@ export class TouchPadMenuComponent implements OnInit, OnDestroy {
this.maxRowsReached = selections.length >= 5;
const totalAmount = selections.reduce((sum, selection) => sum + selection.total, 0);
this.totalAmountLimitReached = totalAmount >= 5000;
this.blockedLabels = this.labelRestrictionService.getBlockedLabels(selections);
if (!this.totalAmountLimitReached) {
this.showLimitPopup = false;
}
@ -208,7 +205,9 @@ export class TouchPadMenuComponent implements OnInit, OnDestroy {
}
isLabelDisabled(label: string): boolean {
return this.disabledLabels.includes(label) || this.totalAmountLimitReached;
return this.disabledLabels.includes(label) ||
this.totalAmountLimitReached ||
this.blockedLabels.has(label);
}
// --- MODIFIED METHOD ---
@ -234,7 +233,7 @@ export class TouchPadMenuComponent implements OnInit, OnDestroy {
}
selectLabel(label: string) {
if (this.totalAmountLimitReached) {
if (this.totalAmountLimitReached || this.blockedLabels.has(label)) {
this.showLimitPopup = true;
return;
}
@ -277,12 +276,10 @@ export class TouchPadMenuComponent implements OnInit, OnDestroy {
if (label === 'WSP') {
const wspLabels = ['WIN', 'SHP', 'THP'];
this.wspTicketStage = 0; // Add this line
// Finalize any existing row before creating new ones
this.wspTicketStage = 0;
this.selectionService.finalizeCurrentRow();
// Immediately add 3 blank rows to the selection list
const currentSelections = this.selectionService['selections'].value;
const currentSelections = this.selectionService.getSelections();
const blankRows = wspLabels.map(lbl => ({
label: lbl,
numbers: [],
@ -294,7 +291,7 @@ export class TouchPadMenuComponent implements OnInit, OnDestroy {
const totalNew = 0; // Each row is empty initially
const totalExisting = currentSelections.reduce((sum, r) => sum + r.total, 0);
if (totalExisting + totalNew <= 5000) {
this.selectionService['selections'].next([...currentSelections, ...blankRows]);
this.selectionService.setSelections([...currentSelections, ...blankRows]);
}
// Clear the input area (so no editing conflicts)
@ -584,30 +581,29 @@ export class TouchPadMenuComponent implements OnInit, OnDestroy {
this.padValue += key;
}
this.updateCanPrint();
this.updateCanPrint();
const value = parseFloat(this.padValue) || 0;
const value = parseFloat(this.padValue) || 0;
if (this.selectedLabel === 'WSP') {
const labels = ['WIN', 'SHP', 'THP'];
const targetLabel = labels[this.wspTicketStage];
if (this.selectedLabel === 'WSP') {
const labels = ['WIN', 'SHP', 'THP'];
const targetLabel = labels[this.wspTicketStage];
const updatedSelections = this.selectionService.getSelections().map(sel => {
if (sel.label === targetLabel && JSON.stringify(sel.numbers) === JSON.stringify(this.selectedNumbers)) {
const total = value * (sel.numbers?.length || 0) * 10;
return {
...sel,
value,
total
};
}
return sel;
});
const updatedSelections = this.selectionService.getSelections().map(sel => {
if (sel.label === targetLabel && JSON.stringify(sel.numbers) === JSON.stringify(this.selectedNumbers)) {
const total = value * (sel.numbers?.length || 0) * 10;
return {
...sel,
value,
total
};
}
return sel;
});
this.selectionService.setSelections(updatedSelections);
return;
}
this.selectionService.setSelections(updatedSelections);
return;
}
// 🔵 Default path for non-WSP
this.selectionService.updatePartial({
@ -677,10 +673,10 @@ printTicket() {
console.log("🖨️ Print ticket clicked");
const selections = this.selectionService['selections'].value;
const currentRow = this.selectionService['currentRow'].value;
const selections = this.selectionService.getSelections();
const currentRow = this.selectionService.getCurrentRow();
let allRows = [...selections];
let allRows = [...selections];
// ✅ Calculate total if currentRow is valid and not already finalized
if (currentRow.label && currentRow.numbers.length > 0 && currentRow.value > 0) {
@ -696,38 +692,38 @@ printTicket() {
combinations = n > 1 ? (n * (n - 1)) / 2 : 0;
}
currentRow.total = combinations * currentRow.value * 10;
currentRow.total = combinations * currentRow.value * 10;
}
allRows.push(currentRow);
}
allRows.push(currentRow);
}
if (allRows.length === 0) {
console.warn("No valid rows to print.");
return;
}
if (allRows.length === 0) {
console.warn("No valid rows to print.");
return;
}
const ticketCount = allRows.reduce((sum, row) => sum + (row.value || 0), 0);
const totalAmount = allRows.reduce((sum, row) => sum + (row.total || 0), 0);
const ticketCount = allRows.reduce((sum, row) => sum + (row.value || 0), 0);
const totalAmount = allRows.reduce((sum, row) => sum + (row.total || 0), 0);
const now = new Date();
const venue = 'MYS';
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 fullYear = now.getFullYear();
const timeStr = now.toTimeString().slice(0, 8).replace(/:/g, '');
const millis = now.getMilliseconds().toString().padStart(3, '0');
const ticketId = `${venue}/${fullYear}${month}${day}/1`;
const barcodeId = `1111${day}${month}${year}${timeStr}${millis}`;
const now = new Date();
const venue = 'MYS';
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 fullYear = now.getFullYear();
const timeStr = now.toTimeString().slice(0, 8).replace(/:/g, '');
const millis = now.getMilliseconds().toString().padStart(3, '0');
const ticketId = `${venue}/${fullYear}${month}${day}/1`;
const barcodeId = `1111${day}${month}${year}${timeStr}${millis}`;
const winLabels = allRows.map(row => {
const label = row.label.padEnd(10); // WIN (or SHP)
const numbers = row.numbers.join(',').padEnd(15); // 1,2,3
const value = (`*${row.value || 0}`).padEnd(8); // *4
const total = `Rs ${row.total || 0}`.padStart(8); // Rs 80
return `${label}${numbers}${value}${total}`;
}).join('\n');
const winLabels = allRows.map(row => {
const label = row.label.padEnd(10);
const numbers = row.numbers.join(',').padEnd(15);
const value = (`*${row.value || 0}`).padEnd(8);
const total = `Rs ${row.total || 0}`.padStart(8);
return `${label}${numbers}${value}${total}`;
}).join('\n');
// ✅ Print preview
const printData = {
@ -808,7 +804,6 @@ const winLabels = allRows.map(row => {
this.isBoxed = false;
this.totalAmountLimitReached = false;
this.showLimitPopup = false;
this.tanGroupStage = 0;
this.tanGroups = [[], [], []];
this.isFirstGroupComplete = false;
@ -819,10 +814,10 @@ const winLabels = allRows.map(row => {
this.multiLegBaseRaceIdx = 0;
this.currentLegRaceDisplay = '';
this.currentPool = null;
this.fieldModalOpen = false;
this.fieldInput = '';
this.fieldFEntered = false;
this.wspTicketStage = 0;
// Clear multi-leg display in Navbar
this.sharedStateService.updateSharedData({