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 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) => {
|
||||
let count = 0;
|
||||
for (const item of leg) {
|
||||
if (item === 'F') {
|
||||
count += this.getRunnerCountForLeg(this.multiLegBaseRaceIdx, idx);
|
||||
count += this.getRunnerCountForLeg(baseIdx + 1, idx);
|
||||
} else if (typeof item === 'number') {
|
||||
count += 1;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
});
|
||||
|
||||
const combinations = legCounts.reduce((acc, count) => acc * (count || 1), 1);
|
||||
updated.total = combinations * value * 10;
|
||||
break;
|
||||
@ -259,4 +261,48 @@ export class SelectionService {
|
||||
const race = raceCardData?.raceVenueRaces?.races?.[raceIdx] || [];
|
||||
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>
|
||||
</div>
|
||||
<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>
|
||||
|
||||
@ -31,6 +31,8 @@ export class TouchPadMenuComponent implements OnInit, OnDestroy {
|
||||
labelRowsFlat: string[] = [];
|
||||
numbersFlat: number[] = [];
|
||||
|
||||
wspTicketStage: number = 0; //added this
|
||||
|
||||
selectedLabel: string | null = null;
|
||||
selectedNumbers: (number | 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
|
||||
this.tanGroupStage = 0;
|
||||
this.tanGroups = [[], [], []];
|
||||
@ -339,12 +374,33 @@ export class TouchPadMenuComponent implements OnInit, OnDestroy {
|
||||
return;
|
||||
}
|
||||
|
||||
// Default single-number selection
|
||||
if (!this.selectedNumbers.includes(number)) {
|
||||
this.selectedNumbers.push(number);
|
||||
this.selectionService.updatePartial({ numbers: [...this.selectedNumbers] });
|
||||
// Default single-number selection (WIN, SHP, THP, etc.)
|
||||
if (!this.selectedNumbers.includes(number)) {
|
||||
this.selectedNumbers.push(number);
|
||||
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() {
|
||||
const combined: (number | string)[] = [];
|
||||
@ -361,12 +417,55 @@ export class TouchPadMenuComponent implements OnInit, OnDestroy {
|
||||
return horsesPerLeg.reduce((acc, v) => acc * v, 1) * units * unitBet;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------ON PAD ENTER------------------------------------//
|
||||
|
||||
// onPadEnter() {
|
||||
// if (this.canPrint) {
|
||||
// this.print();
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
onPadEnter() {
|
||||
if (this.canPrint) {
|
||||
this.print();
|
||||
}
|
||||
if (!this.canPrint) {
|
||||
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() {
|
||||
if (this.selectedLabel === 'TAN' && this.isBoxed) {
|
||||
return;
|
||||
@ -404,28 +503,86 @@ 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) {
|
||||
if (!this.numericPadEnabled || this.totalAmountLimitReached) return;
|
||||
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;
|
||||
if (key === 'X') {
|
||||
this.padValue = '';
|
||||
if (this.selectedLabel === 'WSP') {
|
||||
this.wspTicketStage = 0; // Reset stage if WSP
|
||||
}
|
||||
|
||||
this.updateCanPrint();
|
||||
|
||||
const value = parseFloat(this.padValue) || 0;
|
||||
this.selectionService.updatePartial({
|
||||
value,
|
||||
isBoxed: this.isBoxed,
|
||||
label: this.selectedLabel || '',
|
||||
numbers: [...this.selectedNumbers]
|
||||
});
|
||||
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;
|
||||
if (currentValue > 100) return;
|
||||
this.padValue += key;
|
||||
}
|
||||
|
||||
this.updateCanPrint();
|
||||
|
||||
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({
|
||||
value,
|
||||
isBoxed: this.isBoxed,
|
||||
label: this.selectedLabel || '',
|
||||
numbers: [...this.selectedNumbers]
|
||||
});
|
||||
}
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
updateCanPrint() {
|
||||
this.canPrint = this.padValue.trim().length > 0 && /^[0-9]+$/.test(this.padValue);
|
||||
if (this.multiLegLabels.includes(this.selectedLabel || '')) {
|
||||
@ -472,6 +629,138 @@ export class TouchPadMenuComponent implements OnInit, OnDestroy {
|
||||
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() {
|
||||
this.selectionService.clearSelections();
|
||||
this.resetSelections();
|
||||
|
||||
Loading…
Reference in New Issue
Block a user