fix : added limit of tickets and amount
This commit is contained in:
parent
855512bedf
commit
e66842d510
@ -32,6 +32,11 @@ export class SelectionService {
|
||||
const numbers = updated.numbers || [];
|
||||
const isBoxed = updated.isBoxed ?? false;
|
||||
|
||||
// Enforce ticket number limit (1-100)
|
||||
if (value > 100) {
|
||||
updated.value = 100;
|
||||
}
|
||||
|
||||
updated.total = 0;
|
||||
|
||||
if ((numbers.length > 0 || numbers.includes('F')) && value > 0 && label) {
|
||||
@ -111,7 +116,7 @@ export class SelectionService {
|
||||
const nonFieldNumbers = (group1_is_field ? group2 : group1).filter(n => typeof n === 'number') as number[];
|
||||
const pairSet = new Set<string>();
|
||||
const fieldNumbers = fieldSide.length > 0 ? fieldSide : Array.from({ length: 12 }, (_, i) => i + 1);
|
||||
for (let j of nonFieldNumbers) {
|
||||
for (let j of nonFieldNumbers) {
|
||||
for (let i of fieldNumbers) {
|
||||
if (i !== j) {
|
||||
let min = Math.min(i, j);
|
||||
@ -215,7 +220,10 @@ export class SelectionService {
|
||||
finalizeCurrentRow() {
|
||||
const completed = this.currentRow.value;
|
||||
if (!completed.label || completed.numbers.length === 0 || completed.value <= 0) return;
|
||||
this.selections.next([...this.selections.value, { ...completed }]);
|
||||
const currentSelections = this.selections.value;
|
||||
const totalAmount = currentSelections.reduce((sum, sel) => sum + sel.total, 0);
|
||||
if (totalAmount + completed.total > 5000) return;
|
||||
this.selections.next([...currentSelections, { ...completed }]);
|
||||
this.currentRow.next({ label: '', numbers: [], value: 0, total: 0, isBoxed: false });
|
||||
}
|
||||
|
||||
|
||||
@ -283,8 +283,9 @@ button {
|
||||
> div:last-child
|
||||
button:nth-child(1) {
|
||||
min-width: 20%;
|
||||
margin-right: 4rem;
|
||||
margin-left: 1rem;
|
||||
/* margin-right: 4rem; */
|
||||
margin-left: 0px;
|
||||
padding: 1px;
|
||||
}
|
||||
|
||||
.touch-pad-container
|
||||
@ -682,4 +683,55 @@ button.ready-to-print {
|
||||
.pool-replace-btn{
|
||||
background-color: #125cac;
|
||||
color: white;
|
||||
}
|
||||
}
|
||||
.limit-overlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
background: rgba(0, 0, 0, 0.15);
|
||||
z-index: 2000;
|
||||
}
|
||||
|
||||
.limit-dialog {
|
||||
background: #ffffff;
|
||||
border-radius: 8px;
|
||||
padding: 24px 16px;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
min-width: 400px;
|
||||
box-shadow: 0 3px 16px rgba(0, 0, 0, 0.25);
|
||||
}
|
||||
|
||||
.limit-title {
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
font-size: 1.25rem;
|
||||
margin-bottom: 1.25rem;
|
||||
}
|
||||
|
||||
.limit-message {
|
||||
text-align: center;
|
||||
margin-bottom: 1.25rem;
|
||||
}
|
||||
|
||||
.limit-button {
|
||||
width: 25%;
|
||||
margin-left: 38%;
|
||||
padding: 10px 0;
|
||||
font-size: 1rem;
|
||||
font-weight: 500;
|
||||
background-color: #007bff;
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
transition: background-color 0.2s ease;
|
||||
}
|
||||
|
||||
.limit-button:hover {
|
||||
background-color: #0056b3;
|
||||
}
|
||||
|
||||
@ -88,7 +88,6 @@
|
||||
<div class="col-2 column">
|
||||
<div class="p-2 rounded wrapper-pad" style="background-color: #f1f1f1df">
|
||||
<div class="row gx-1 gy-1 custom-touchpad">
|
||||
|
||||
<div class="col-6">
|
||||
<button class="btn btn-secondary w-100 number-button" [disabled]="!numericPadEnabled" (click)="enterPadVal('0')">0</button>
|
||||
</div>
|
||||
@ -110,7 +109,6 @@
|
||||
<div class="col-6">
|
||||
<button class="btn btn-secondary w-100 number-button" [disabled]="!canPrint" (click)="print()">Print</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -225,4 +223,28 @@
|
||||
<button class="btn btn-primary my-2 w-100" (click)="treButtonClick(2)">TRB2</button>
|
||||
<button class="btn btn-secondary my-2 w-100" style="opacity: 0.6; pointer-events: none;">TRB3</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 🟥 Limit Popup Modal -->
|
||||
<div
|
||||
class="limit-overlay"
|
||||
*ngIf="showLimitPopup"
|
||||
style="position: fixed; top: 0; left: 0; width: 100vw; height: 100vh; background: rgba(0,0,0,0.15); z-index: 2000;"
|
||||
(click)="closeLimitPopup()"
|
||||
>
|
||||
<div
|
||||
class="limit-dialog"
|
||||
(click)="$event.stopPropagation()"
|
||||
style="background: #fff; border-radius: 8px; padding: 24px 16px; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); min-width: 400px; box-shadow: 0 3px 16px rgba(0,0,0,0.25);height: 200px;"
|
||||
>
|
||||
<div class="limit-title" style="font-weight: bold; text-align: center; font-size: 1.25rem; margin-bottom: 1.25rem;">
|
||||
Limit Reached
|
||||
</div>
|
||||
<p class="limit-message" style="text-align: center; margin-bottom: 1.25rem;">
|
||||
Total amount limit of 5000 rupees has been reached. No further selections can be made.
|
||||
</p>
|
||||
<button class="limit-button" (click)="closeLimitPopup()">OK</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@ -1,6 +1,8 @@
|
||||
import { Component, Input, OnInit } from '@angular/core';
|
||||
import { Component, Input, OnInit, OnDestroy } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { SelectionService } from '../selection.service/selection.service';
|
||||
import { Subscription } from 'rxjs';
|
||||
import { SelectionData } from '../selection.service/selection.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-touch-pad-menu',
|
||||
@ -9,7 +11,7 @@ import { SelectionService } from '../selection.service/selection.service';
|
||||
templateUrl: './touch-pad-menu.component.html',
|
||||
styleUrls: ['./touch-pad-menu.component.css']
|
||||
})
|
||||
export class TouchPadMenuComponent implements OnInit {
|
||||
export class TouchPadMenuComponent implements OnInit, OnDestroy {
|
||||
@Input() ticketingActive: boolean = false;
|
||||
|
||||
public twoGroupLabels = ['FOR', 'QUI'];
|
||||
@ -34,6 +36,8 @@ export class TouchPadMenuComponent implements OnInit {
|
||||
calculatorOpen = false;
|
||||
calcDisplay = '';
|
||||
maxRowsReached: boolean = false;
|
||||
totalAmountLimitReached: boolean = false;
|
||||
showLimitPopup: boolean = false;
|
||||
|
||||
disabledLabels: string[] = ['SHW', 'SJP', '.'];
|
||||
|
||||
@ -63,14 +67,37 @@ export class TouchPadMenuComponent implements OnInit {
|
||||
// TRE popup
|
||||
trePopupVisible = false;
|
||||
|
||||
private currentRowSubscription: Subscription | null = null;
|
||||
private selectionsSubscription: Subscription | null = null;
|
||||
private currentTotal: number = 0;
|
||||
private currentSelections: SelectionData[] = [];
|
||||
|
||||
constructor(private selectionService: SelectionService) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.labelRowsFlat = this.labelRows.flat();
|
||||
this.numbersFlat = this.numberRows.flat();
|
||||
this.selectionService.selections$.subscribe(selections => {
|
||||
this.selectionsSubscription = this.selectionService.selections$.subscribe(selections => {
|
||||
this.currentSelections = selections;
|
||||
this.maxRowsReached = selections.length >= 5;
|
||||
const totalAmount = selections.reduce((sum, selection) => sum + selection.total, 0);
|
||||
this.totalAmountLimitReached = totalAmount >= 5000;
|
||||
if (this.totalAmountLimitReached) {
|
||||
this.showLimitPopup = true;
|
||||
}
|
||||
});
|
||||
this.currentRowSubscription = this.selectionService.currentRow$.subscribe(row => {
|
||||
this.currentTotal = row.total;
|
||||
});
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
if (this.currentRowSubscription) {
|
||||
this.currentRowSubscription.unsubscribe();
|
||||
}
|
||||
if (this.selectionsSubscription) {
|
||||
this.selectionsSubscription.unsubscribe();
|
||||
}
|
||||
}
|
||||
|
||||
get labelRows() {
|
||||
@ -140,13 +167,17 @@ export class TouchPadMenuComponent implements OnInit {
|
||||
}
|
||||
|
||||
isLabelDisabled(label: string): boolean {
|
||||
return this.disabledLabels.includes(label);
|
||||
return this.disabledLabels.includes(label) || this.totalAmountLimitReached;
|
||||
}
|
||||
|
||||
selectLabel(label: string) {
|
||||
if (this.totalAmountLimitReached) {
|
||||
this.showLimitPopup = true;
|
||||
return;
|
||||
}
|
||||
if (label === 'TRE') {
|
||||
this.trePopupVisible = true;
|
||||
return; // Stop further execution until popup interaction
|
||||
return;
|
||||
}
|
||||
this.selectedLabel = label;
|
||||
this.selectedNumbers = [];
|
||||
@ -171,7 +202,7 @@ export class TouchPadMenuComponent implements OnInit {
|
||||
}
|
||||
|
||||
selectNumber(number: number) {
|
||||
if (!this.selectedLabel) return;
|
||||
if (!this.selectedLabel || this.totalAmountLimitReached) return;
|
||||
|
||||
// TAN Box mode: freestyle selection with dash-separated format
|
||||
if (this.selectedLabel === 'TAN' && this.isBoxed) {
|
||||
@ -264,7 +295,7 @@ export class TouchPadMenuComponent implements OnInit {
|
||||
if (this.selectedLabel === 'TAN' || this.multiLegLabels.includes(this.selectedLabel || '') || this.twoGroupLabels.includes(this.selectedLabel || '')) {
|
||||
return false;
|
||||
}
|
||||
return this.selectedNumbers.includes(number);
|
||||
return this.selectedNumbers.includes(number) || this.totalAmountLimitReached;
|
||||
}
|
||||
|
||||
onPadEnter() {
|
||||
@ -311,11 +342,14 @@ export class TouchPadMenuComponent implements OnInit {
|
||||
}
|
||||
|
||||
enterPadVal(key: string) {
|
||||
if (!this.numericPadEnabled) return;
|
||||
if (!this.numericPadEnabled || this.totalAmountLimitReached) return;
|
||||
|
||||
if (key === 'X') {
|
||||
this.padValue = '';
|
||||
} else if (/[0-9]/.test(key)) {
|
||||
// Limit ticket number to 1-100 for all labels
|
||||
const currentValue = parseInt(this.padValue + key) || 0;
|
||||
if (currentValue > 100) return;
|
||||
this.padValue += key;
|
||||
}
|
||||
|
||||
@ -335,6 +369,11 @@ export class TouchPadMenuComponent implements OnInit {
|
||||
}
|
||||
|
||||
print() {
|
||||
const selectionsTotal = this.currentSelections.reduce((sum, sel) => sum + sel.total, 0);
|
||||
if (selectionsTotal + this.currentTotal > 5000) {
|
||||
this.showLimitPopup = true;
|
||||
return;
|
||||
}
|
||||
this.selectionService.finalizeCurrentRow();
|
||||
this.resetSelections();
|
||||
}
|
||||
@ -367,6 +406,7 @@ export class TouchPadMenuComponent implements OnInit {
|
||||
}
|
||||
|
||||
toggleBoxMode() {
|
||||
if (this.totalAmountLimitReached) return;
|
||||
this.isBoxed = !this.isBoxed;
|
||||
const value = parseFloat(this.padValue) || 0;
|
||||
// For TAN Box mode, reset to freestyle selection
|
||||
@ -536,6 +576,7 @@ export class TouchPadMenuComponent implements OnInit {
|
||||
}
|
||||
|
||||
canUseField(): boolean {
|
||||
if (this.totalAmountLimitReached) return false;
|
||||
if (this.selectedLabel === 'FOR' || this.selectedLabel === 'QUI') {
|
||||
if (!this.isFirstGroupComplete && this.firstGroup.length === 0) {
|
||||
return true;
|
||||
@ -562,6 +603,7 @@ export class TouchPadMenuComponent implements OnInit {
|
||||
}
|
||||
|
||||
openFieldModal() {
|
||||
if (this.totalAmountLimitReached) return;
|
||||
if (['FOR', 'QUI', 'TAN'].includes(this.selectedLabel || '') || this.multiLegLabels.includes(this.selectedLabel || '')) {
|
||||
this.handleFieldForSpecialLabels();
|
||||
} else {
|
||||
@ -647,6 +689,7 @@ export class TouchPadMenuComponent implements OnInit {
|
||||
}
|
||||
|
||||
openPoolReplaceModal() {
|
||||
if (this.totalAmountLimitReached) return;
|
||||
this.poolReplaceOpen = true;
|
||||
}
|
||||
|
||||
@ -681,4 +724,8 @@ export class TouchPadMenuComponent implements OnInit {
|
||||
closeTrePopup() {
|
||||
this.trePopupVisible = false;
|
||||
}
|
||||
|
||||
closeLimitPopup() {
|
||||
this.showLimitPopup = false;
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user