fix : added print , WSP and MJP logic (working)
This commit is contained in:
parent
e358205163
commit
a8a64e064e
@ -165,18 +165,20 @@ export class SelectionService {
|
|||||||
const legCount = this.getLegCount(label);
|
const legCount = this.getLegCount(label);
|
||||||
const legs = this.splitToLegs(numbers, legCount);
|
const legs = this.splitToLegs(numbers, legCount);
|
||||||
|
|
||||||
|
// Override for MJP to always start from race 1
|
||||||
|
const baseIdx = label === 'MJP' ? 0 : this.multiLegBaseRaceIdx - 1;
|
||||||
|
|
||||||
const legCounts = legs.map((leg, idx) => {
|
const legCounts = legs.map((leg, idx) => {
|
||||||
let count = 0;
|
let count = 0;
|
||||||
for (const item of leg) {
|
for (const item of leg) {
|
||||||
if (item === 'F') {
|
if (item === 'F') {
|
||||||
count += this.getRunnerCountForLeg(this.multiLegBaseRaceIdx, idx);
|
count += this.getRunnerCountForLeg(baseIdx + 1, idx);
|
||||||
} else if (typeof item === 'number') {
|
} else if (typeof item === 'number') {
|
||||||
count += 1;
|
count += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return count;
|
return count;
|
||||||
});
|
});
|
||||||
|
|
||||||
const combinations = legCounts.reduce((acc, count) => acc * (count || 1), 1);
|
const combinations = legCounts.reduce((acc, count) => acc * (count || 1), 1);
|
||||||
updated.total = combinations * value * 10;
|
updated.total = combinations * value * 10;
|
||||||
break;
|
break;
|
||||||
@ -259,4 +261,48 @@ export class SelectionService {
|
|||||||
const race = raceCardData?.raceVenueRaces?.races?.[raceIdx] || [];
|
const race = raceCardData?.raceVenueRaces?.races?.[raceIdx] || [];
|
||||||
return Array.isArray(race) ? race.length : 12;
|
return Array.isArray(race) ? race.length : 12;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private calculateTotal(data: SelectionData): number {
|
||||||
|
const temp = new BehaviorSubject<SelectionData>(data);
|
||||||
|
const originalCurrent = this.currentRow;
|
||||||
|
this.currentRow = temp;
|
||||||
|
this.updatePartial(data);
|
||||||
|
const total = temp.value.total;
|
||||||
|
this.currentRow = originalCurrent; // Restore original
|
||||||
|
return total;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------ADDED THIS---------------------------------------------------//
|
||||||
|
createVirtualRowsFromWSP(): SelectionData[] {
|
||||||
|
const base = this.currentRow.value;
|
||||||
|
|
||||||
|
if (!base.numbers.length || base.value <= 0) return [];
|
||||||
|
|
||||||
|
return ['WIN', 'SHP', 'THP'].map(label => {
|
||||||
|
const newRow: SelectionData = {
|
||||||
|
...base,
|
||||||
|
label,
|
||||||
|
total: 0
|
||||||
|
};
|
||||||
|
newRow.total = this.calculateTotal(newRow);
|
||||||
|
return newRow;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
setSelections(rows: SelectionData[]) {
|
||||||
|
this.selections.next(rows);
|
||||||
|
}
|
||||||
|
|
||||||
|
getSelections(): SelectionData[] {
|
||||||
|
return this.selections.getValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
getCurrentRow(): SelectionData {
|
||||||
|
return this.currentRow.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -93,7 +93,7 @@
|
|||||||
<button class="btn btn-secondary w-100 number-button" [disabled]="!numericPadEnabled" (click)="onPadEnter()">Enter</button>
|
<button class="btn btn-secondary w-100 number-button" [disabled]="!numericPadEnabled" (click)="onPadEnter()">Enter</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-6">
|
<div class="col-6">
|
||||||
<button class="btn btn-secondary w-100 number-button" [disabled]="!canPrint" (click)="print()">Print</button>
|
<button class="btn btn-secondary w-100 number-button" [disabled]="!canPrint" (click)="printTicket()">Print</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -31,6 +31,8 @@ export class TouchPadMenuComponent implements OnInit, OnDestroy {
|
|||||||
labelRowsFlat: string[] = [];
|
labelRowsFlat: string[] = [];
|
||||||
numbersFlat: number[] = [];
|
numbersFlat: number[] = [];
|
||||||
|
|
||||||
|
wspTicketStage: number = 0; //added this
|
||||||
|
|
||||||
selectedLabel: string | null = null;
|
selectedLabel: string | null = null;
|
||||||
selectedNumbers: (number | string)[] = [];
|
selectedNumbers: (number | string)[] = [];
|
||||||
padValue: string = '';
|
padValue: string = '';
|
||||||
@ -228,6 +230,39 @@ export class TouchPadMenuComponent implements OnInit, OnDestroy {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//----------------------------------ADDED THIS -----------------------------------------------------
|
||||||
|
|
||||||
|
if (label === 'WSP') {
|
||||||
|
const wspLabels = ['WIN', 'SHP', 'THP'];
|
||||||
|
this.wspTicketStage = 0; // Add this line
|
||||||
|
// Finalize any existing row before creating new ones
|
||||||
|
this.selectionService.finalizeCurrentRow();
|
||||||
|
|
||||||
|
// Immediately add 3 blank rows to the selection list
|
||||||
|
const currentSelections = this.selectionService['selections'].value;
|
||||||
|
const blankRows = wspLabels.map(lbl => ({
|
||||||
|
label: lbl,
|
||||||
|
numbers: [],
|
||||||
|
value: 0,
|
||||||
|
total: 0,
|
||||||
|
isBoxed: false
|
||||||
|
}));
|
||||||
|
|
||||||
|
const totalNew = 0; // Each row is empty initially
|
||||||
|
const totalExisting = currentSelections.reduce((sum, r) => sum + r.total, 0);
|
||||||
|
|
||||||
|
if (totalExisting + totalNew <= 5000) {
|
||||||
|
this.selectionService['selections'].next([...currentSelections, ...blankRows]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear the input area (so no editing conflicts)
|
||||||
|
this.selectionService.updatePartial({ label: '', numbers: [], value: 0, total: 0 });
|
||||||
|
|
||||||
|
return; // Skip default updatePartial below
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------ended here----------------------------------------------------
|
||||||
|
|
||||||
// Reset TAN
|
// Reset TAN
|
||||||
this.tanGroupStage = 0;
|
this.tanGroupStage = 0;
|
||||||
this.tanGroups = [[], [], []];
|
this.tanGroups = [[], [], []];
|
||||||
@ -339,12 +374,33 @@ export class TouchPadMenuComponent implements OnInit, OnDestroy {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Default single-number selection
|
// Default single-number selection (WIN, SHP, THP, etc.)
|
||||||
if (!this.selectedNumbers.includes(number)) {
|
if (!this.selectedNumbers.includes(number)) {
|
||||||
this.selectedNumbers.push(number);
|
this.selectedNumbers.push(number);
|
||||||
this.selectionService.updatePartial({ numbers: [...this.selectedNumbers] });
|
this.selectionService.updatePartial({ numbers: [...this.selectedNumbers] });
|
||||||
|
|
||||||
|
// ✅ Special logic: If WSP, mirror number to WIN, SHP, and THP
|
||||||
|
if (this.selectedLabel === 'WSP') {
|
||||||
|
const labelsToUpdate = ['WIN', 'SHP', 'THP'];
|
||||||
|
const selections = this.selectionService.getSelections();
|
||||||
|
const updated = selections.map(sel => {
|
||||||
|
if (labelsToUpdate.includes(sel.label)) {
|
||||||
|
const newNumbers = [...sel.numbers];
|
||||||
|
if (!newNumbers.includes(number)) {
|
||||||
|
newNumbers.push(number);
|
||||||
|
}
|
||||||
|
return { ...sel, numbers: newNumbers };
|
||||||
|
}
|
||||||
|
return sel;
|
||||||
|
});
|
||||||
|
this.selectionService.setSelections(updated);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private updateMultiLegSelection() {
|
private updateMultiLegSelection() {
|
||||||
const combined: (number | string)[] = [];
|
const combined: (number | string)[] = [];
|
||||||
@ -361,11 +417,54 @@ export class TouchPadMenuComponent implements OnInit, OnDestroy {
|
|||||||
return horsesPerLeg.reduce((acc, v) => acc * v, 1) * units * unitBet;
|
return horsesPerLeg.reduce((acc, v) => acc * v, 1) * units * unitBet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------ON PAD ENTER------------------------------------//
|
||||||
|
|
||||||
|
// onPadEnter() {
|
||||||
|
// if (this.canPrint) {
|
||||||
|
// this.print();
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
onPadEnter() {
|
onPadEnter() {
|
||||||
if (this.canPrint) {
|
if (!this.canPrint) {
|
||||||
this.print();
|
this.print();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const value = parseFloat(this.padValue) || 0;
|
||||||
|
|
||||||
|
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)) {
|
||||||
|
return {
|
||||||
|
...sel,
|
||||||
|
value,
|
||||||
|
total: value * (sel.numbers?.length || 0) * 10
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
return sel;
|
||||||
|
});
|
||||||
|
|
||||||
|
this.selectionService.setSelections(updatedSelections);
|
||||||
|
|
||||||
|
// Move to next stage
|
||||||
|
this.wspTicketStage = (this.wspTicketStage + 1) % 3;
|
||||||
|
this.padValue = '';
|
||||||
|
this.updateCanPrint();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ✅ Default path: finalize row and reset input
|
||||||
|
this.print();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------//
|
||||||
|
|
||||||
onShashEnter() {
|
onShashEnter() {
|
||||||
if (this.selectedLabel === 'TAN' && this.isBoxed) {
|
if (this.selectedLabel === 'TAN' && this.isBoxed) {
|
||||||
@ -404,12 +503,46 @@ export class TouchPadMenuComponent implements OnInit, OnDestroy {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//-----------------------------ENTER PAD VALUE-------------------------------------
|
||||||
|
|
||||||
|
// enterPadVal(key: string) {
|
||||||
|
// if (!this.numericPadEnabled || this.totalAmountLimitReached) return;
|
||||||
|
|
||||||
|
// if (key === 'X') {
|
||||||
|
// this.padValue = '';
|
||||||
|
// } else if (/[0-9]/.test(key)) {
|
||||||
|
// const currentValue = parseInt(this.padValue + key) || 0;
|
||||||
|
// if (currentValue > 100) return;
|
||||||
|
// this.padValue += key;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// this.updateCanPrint();
|
||||||
|
|
||||||
|
// const value = parseFloat(this.padValue) || 0;
|
||||||
|
// this.selectionService.updatePartial({
|
||||||
|
// value,
|
||||||
|
// isBoxed: this.isBoxed,
|
||||||
|
// label: this.selectedLabel || '',
|
||||||
|
// numbers: [...this.selectedNumbers]
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
|
||||||
enterPadVal(key: string) {
|
enterPadVal(key: string) {
|
||||||
if (!this.numericPadEnabled || this.totalAmountLimitReached) return;
|
if (!this.numericPadEnabled || this.totalAmountLimitReached) return;
|
||||||
|
|
||||||
if (key === 'X') {
|
if (key === 'X') {
|
||||||
this.padValue = '';
|
this.padValue = '';
|
||||||
} else if (/[0-9]/.test(key)) {
|
if (this.selectedLabel === 'WSP') {
|
||||||
|
this.wspTicketStage = 0; // Reset stage if WSP
|
||||||
|
}
|
||||||
|
else if (/[0-9]/.test(key)) {
|
||||||
|
const currentValue = parseInt(this.padValue + key) || 0;
|
||||||
|
if (currentValue > 100) return;
|
||||||
|
this.padValue += key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (/[0-9]/.test(key)) {
|
||||||
const currentValue = parseInt(this.padValue + key) || 0;
|
const currentValue = parseInt(this.padValue + key) || 0;
|
||||||
if (currentValue > 100) return;
|
if (currentValue > 100) return;
|
||||||
this.padValue += key;
|
this.padValue += key;
|
||||||
@ -418,6 +551,29 @@ export class TouchPadMenuComponent implements OnInit, OnDestroy {
|
|||||||
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];
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 🔵 Default path for non-WSP
|
||||||
this.selectionService.updatePartial({
|
this.selectionService.updatePartial({
|
||||||
value,
|
value,
|
||||||
isBoxed: this.isBoxed,
|
isBoxed: this.isBoxed,
|
||||||
@ -425,6 +581,7 @@ export class TouchPadMenuComponent implements OnInit, OnDestroy {
|
|||||||
numbers: [...this.selectedNumbers]
|
numbers: [...this.selectedNumbers]
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
//---------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
updateCanPrint() {
|
updateCanPrint() {
|
||||||
this.canPrint = this.padValue.trim().length > 0 && /^[0-9]+$/.test(this.padValue);
|
this.canPrint = this.padValue.trim().length > 0 && /^[0-9]+$/.test(this.padValue);
|
||||||
@ -472,6 +629,138 @@ export class TouchPadMenuComponent implements OnInit, OnDestroy {
|
|||||||
this.resetSelections();
|
this.resetSelections();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//-------------------PRINT LOGIC----------------------------------------
|
||||||
|
printTicket() {
|
||||||
|
const selectionsTotal = this.currentSelections.reduce((sum, sel) => sum + sel.total, 0);
|
||||||
|
if (selectionsTotal + this.currentTotal > 5000) {
|
||||||
|
this.showLimitPopup = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------Added Print here
|
||||||
|
|
||||||
|
console.log("🖨️ Print ticket clicked");
|
||||||
|
|
||||||
|
const selections = this.selectionService['selections'].value;
|
||||||
|
const currentRow = this.selectionService['currentRow'].value;
|
||||||
|
|
||||||
|
let allRows = [...selections];
|
||||||
|
|
||||||
|
// ✅ Calculate total if currentRow is valid and not already finalized
|
||||||
|
if (currentRow.label && currentRow.numbers.length > 0 && currentRow.value > 0) {
|
||||||
|
if (!currentRow.total) {
|
||||||
|
let combinations = 1;
|
||||||
|
|
||||||
|
if (['TAN', 'FOR', 'QUI'].includes(currentRow.label)) {
|
||||||
|
combinations = currentRow.numbers.length * (currentRow.numbers.length - 1);
|
||||||
|
} else if (['TRE', 'JKP', 'MJP'].includes(currentRow.label)) {
|
||||||
|
combinations = 1; // or your specific logic
|
||||||
|
} else if (currentRow.label === 'BOX') {
|
||||||
|
const n = currentRow.numbers.length;
|
||||||
|
combinations = n > 1 ? (n * (n - 1)) / 2 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
currentRow.total = combinations * currentRow.value * 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
allRows.push(currentRow);
|
||||||
|
}
|
||||||
|
|
||||||
|
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 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');
|
||||||
|
|
||||||
|
// ✅ Print preview
|
||||||
|
const printData = {
|
||||||
|
ticketId,
|
||||||
|
barcodeId,
|
||||||
|
venue,
|
||||||
|
date: `${day}-${month}-${fullYear}`,
|
||||||
|
winLabels,
|
||||||
|
ticketCount,
|
||||||
|
totalAmount,
|
||||||
|
gstNumber: '29ABCDE1234F2Z5'
|
||||||
|
};
|
||||||
|
|
||||||
|
// 🧾 Simulated console ticket
|
||||||
|
console.log('--- Simulated Ticket Print ---');
|
||||||
|
console.log(`Ticket ID : ${printData.ticketId}`);
|
||||||
|
console.log(`Barcode ID : ${printData.barcodeId}`);
|
||||||
|
console.log(`|||||| ||| | ||||| |||| |`); // Dummy barcode
|
||||||
|
console.log(`WIN Labels :`);
|
||||||
|
printData.winLabels.split('\n').forEach(row => console.log(row));
|
||||||
|
console.log(`*${printData.ticketCount} ₹${printData.totalAmount}`);
|
||||||
|
console.log(`GST Number : ${printData.gstNumber}`);
|
||||||
|
console.log(`Date/Time : ${now.toLocaleString()}`);
|
||||||
|
console.log('-----------------------------');
|
||||||
|
|
||||||
|
// 🖨️ Send to printer API
|
||||||
|
const payload = {
|
||||||
|
type: 'ticket',
|
||||||
|
ticketId: printData.ticketId,
|
||||||
|
barcodeId: printData.barcodeId,
|
||||||
|
winLabels: printData.winLabels,
|
||||||
|
ticketCount: printData.ticketCount,
|
||||||
|
totalAmount: printData.totalAmount,
|
||||||
|
gstNumber: printData.gstNumber,
|
||||||
|
dateTime: now.toLocaleString()
|
||||||
|
};
|
||||||
|
|
||||||
|
fetch('http://localhost:9100/print', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify(payload)
|
||||||
|
})
|
||||||
|
.then(response => {
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error(`Printer error: ${response.status}`);
|
||||||
|
}
|
||||||
|
return response.text();
|
||||||
|
})
|
||||||
|
.then(result => {
|
||||||
|
console.log("✅ Print successful:", result);
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.error("❌ Print failed:", error);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
//--------------------Ended Print here -----------------------------
|
||||||
|
|
||||||
|
this.selectionService.finalizeCurrentRow();
|
||||||
|
this.resetSelections();
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------PRINT ENDS HERE ------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
erase() {
|
erase() {
|
||||||
this.selectionService.clearSelections();
|
this.selectionService.clearSelections();
|
||||||
this.resetSelections();
|
this.resetSelections();
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user