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 numbers = updated.numbers || [];
|
||||||
const isBoxed = updated.isBoxed ?? false;
|
const isBoxed = updated.isBoxed ?? false;
|
||||||
|
|
||||||
|
// Enforce ticket number limit (1-100)
|
||||||
|
if (value > 100) {
|
||||||
|
updated.value = 100;
|
||||||
|
}
|
||||||
|
|
||||||
updated.total = 0;
|
updated.total = 0;
|
||||||
|
|
||||||
if ((numbers.length > 0 || numbers.includes('F')) && value > 0 && label) {
|
if ((numbers.length > 0 || numbers.includes('F')) && value > 0 && label) {
|
||||||
@ -215,7 +220,10 @@ export class SelectionService {
|
|||||||
finalizeCurrentRow() {
|
finalizeCurrentRow() {
|
||||||
const completed = this.currentRow.value;
|
const completed = this.currentRow.value;
|
||||||
if (!completed.label || completed.numbers.length === 0 || completed.value <= 0) return;
|
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 });
|
this.currentRow.next({ label: '', numbers: [], value: 0, total: 0, isBoxed: false });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -283,8 +283,9 @@ button {
|
|||||||
> div:last-child
|
> div:last-child
|
||||||
button:nth-child(1) {
|
button:nth-child(1) {
|
||||||
min-width: 20%;
|
min-width: 20%;
|
||||||
margin-right: 4rem;
|
/* margin-right: 4rem; */
|
||||||
margin-left: 1rem;
|
margin-left: 0px;
|
||||||
|
padding: 1px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.touch-pad-container
|
.touch-pad-container
|
||||||
@ -683,3 +684,54 @@ button.ready-to-print {
|
|||||||
background-color: #125cac;
|
background-color: #125cac;
|
||||||
color: white;
|
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="col-2 column">
|
||||||
<div class="p-2 rounded wrapper-pad" style="background-color: #f1f1f1df">
|
<div class="p-2 rounded wrapper-pad" style="background-color: #f1f1f1df">
|
||||||
<div class="row gx-1 gy-1 custom-touchpad">
|
<div class="row gx-1 gy-1 custom-touchpad">
|
||||||
|
|
||||||
<div class="col-6">
|
<div class="col-6">
|
||||||
<button class="btn btn-secondary w-100 number-button" [disabled]="!numericPadEnabled" (click)="enterPadVal('0')">0</button>
|
<button class="btn btn-secondary w-100 number-button" [disabled]="!numericPadEnabled" (click)="enterPadVal('0')">0</button>
|
||||||
</div>
|
</div>
|
||||||
@ -110,7 +109,6 @@
|
|||||||
<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)="print()">Print</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -226,3 +224,27 @@
|
|||||||
<button class="btn btn-secondary my-2 w-100" style="opacity: 0.6; pointer-events: none;">TRB3</button>
|
<button class="btn btn-secondary my-2 w-100" style="opacity: 0.6; pointer-events: none;">TRB3</button>
|
||||||
</div>
|
</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 { CommonModule } from '@angular/common';
|
||||||
import { SelectionService } from '../selection.service/selection.service';
|
import { SelectionService } from '../selection.service/selection.service';
|
||||||
|
import { Subscription } from 'rxjs';
|
||||||
|
import { SelectionData } from '../selection.service/selection.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-touch-pad-menu',
|
selector: 'app-touch-pad-menu',
|
||||||
@ -9,7 +11,7 @@ import { SelectionService } from '../selection.service/selection.service';
|
|||||||
templateUrl: './touch-pad-menu.component.html',
|
templateUrl: './touch-pad-menu.component.html',
|
||||||
styleUrls: ['./touch-pad-menu.component.css']
|
styleUrls: ['./touch-pad-menu.component.css']
|
||||||
})
|
})
|
||||||
export class TouchPadMenuComponent implements OnInit {
|
export class TouchPadMenuComponent implements OnInit, OnDestroy {
|
||||||
@Input() ticketingActive: boolean = false;
|
@Input() ticketingActive: boolean = false;
|
||||||
|
|
||||||
public twoGroupLabels = ['FOR', 'QUI'];
|
public twoGroupLabels = ['FOR', 'QUI'];
|
||||||
@ -34,6 +36,8 @@ export class TouchPadMenuComponent implements OnInit {
|
|||||||
calculatorOpen = false;
|
calculatorOpen = false;
|
||||||
calcDisplay = '';
|
calcDisplay = '';
|
||||||
maxRowsReached: boolean = false;
|
maxRowsReached: boolean = false;
|
||||||
|
totalAmountLimitReached: boolean = false;
|
||||||
|
showLimitPopup: boolean = false;
|
||||||
|
|
||||||
disabledLabels: string[] = ['SHW', 'SJP', '.'];
|
disabledLabels: string[] = ['SHW', 'SJP', '.'];
|
||||||
|
|
||||||
@ -63,14 +67,37 @@ export class TouchPadMenuComponent implements OnInit {
|
|||||||
// TRE popup
|
// TRE popup
|
||||||
trePopupVisible = false;
|
trePopupVisible = false;
|
||||||
|
|
||||||
|
private currentRowSubscription: Subscription | null = null;
|
||||||
|
private selectionsSubscription: Subscription | null = null;
|
||||||
|
private currentTotal: number = 0;
|
||||||
|
private currentSelections: SelectionData[] = [];
|
||||||
|
|
||||||
constructor(private selectionService: SelectionService) {}
|
constructor(private selectionService: SelectionService) {}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.labelRowsFlat = this.labelRows.flat();
|
this.labelRowsFlat = this.labelRows.flat();
|
||||||
this.numbersFlat = this.numberRows.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;
|
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() {
|
get labelRows() {
|
||||||
@ -140,13 +167,17 @@ export class TouchPadMenuComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
isLabelDisabled(label: string): boolean {
|
isLabelDisabled(label: string): boolean {
|
||||||
return this.disabledLabels.includes(label);
|
return this.disabledLabels.includes(label) || this.totalAmountLimitReached;
|
||||||
}
|
}
|
||||||
|
|
||||||
selectLabel(label: string) {
|
selectLabel(label: string) {
|
||||||
|
if (this.totalAmountLimitReached) {
|
||||||
|
this.showLimitPopup = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (label === 'TRE') {
|
if (label === 'TRE') {
|
||||||
this.trePopupVisible = true;
|
this.trePopupVisible = true;
|
||||||
return; // Stop further execution until popup interaction
|
return;
|
||||||
}
|
}
|
||||||
this.selectedLabel = label;
|
this.selectedLabel = label;
|
||||||
this.selectedNumbers = [];
|
this.selectedNumbers = [];
|
||||||
@ -171,7 +202,7 @@ export class TouchPadMenuComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
selectNumber(number: number) {
|
selectNumber(number: number) {
|
||||||
if (!this.selectedLabel) return;
|
if (!this.selectedLabel || this.totalAmountLimitReached) return;
|
||||||
|
|
||||||
// TAN Box mode: freestyle selection with dash-separated format
|
// TAN Box mode: freestyle selection with dash-separated format
|
||||||
if (this.selectedLabel === 'TAN' && this.isBoxed) {
|
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 || '')) {
|
if (this.selectedLabel === 'TAN' || this.multiLegLabels.includes(this.selectedLabel || '') || this.twoGroupLabels.includes(this.selectedLabel || '')) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return this.selectedNumbers.includes(number);
|
return this.selectedNumbers.includes(number) || this.totalAmountLimitReached;
|
||||||
}
|
}
|
||||||
|
|
||||||
onPadEnter() {
|
onPadEnter() {
|
||||||
@ -311,11 +342,14 @@ export class TouchPadMenuComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
enterPadVal(key: string) {
|
enterPadVal(key: string) {
|
||||||
if (!this.numericPadEnabled) return;
|
if (!this.numericPadEnabled || this.totalAmountLimitReached) return;
|
||||||
|
|
||||||
if (key === 'X') {
|
if (key === 'X') {
|
||||||
this.padValue = '';
|
this.padValue = '';
|
||||||
} else if (/[0-9]/.test(key)) {
|
} 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;
|
this.padValue += key;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -335,6 +369,11 @@ export class TouchPadMenuComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
print() {
|
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.selectionService.finalizeCurrentRow();
|
||||||
this.resetSelections();
|
this.resetSelections();
|
||||||
}
|
}
|
||||||
@ -367,6 +406,7 @@ export class TouchPadMenuComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
toggleBoxMode() {
|
toggleBoxMode() {
|
||||||
|
if (this.totalAmountLimitReached) return;
|
||||||
this.isBoxed = !this.isBoxed;
|
this.isBoxed = !this.isBoxed;
|
||||||
const value = parseFloat(this.padValue) || 0;
|
const value = parseFloat(this.padValue) || 0;
|
||||||
// For TAN Box mode, reset to freestyle selection
|
// For TAN Box mode, reset to freestyle selection
|
||||||
@ -536,6 +576,7 @@ export class TouchPadMenuComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
canUseField(): boolean {
|
canUseField(): boolean {
|
||||||
|
if (this.totalAmountLimitReached) return false;
|
||||||
if (this.selectedLabel === 'FOR' || this.selectedLabel === 'QUI') {
|
if (this.selectedLabel === 'FOR' || this.selectedLabel === 'QUI') {
|
||||||
if (!this.isFirstGroupComplete && this.firstGroup.length === 0) {
|
if (!this.isFirstGroupComplete && this.firstGroup.length === 0) {
|
||||||
return true;
|
return true;
|
||||||
@ -562,6 +603,7 @@ export class TouchPadMenuComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
openFieldModal() {
|
openFieldModal() {
|
||||||
|
if (this.totalAmountLimitReached) return;
|
||||||
if (['FOR', 'QUI', 'TAN'].includes(this.selectedLabel || '') || this.multiLegLabels.includes(this.selectedLabel || '')) {
|
if (['FOR', 'QUI', 'TAN'].includes(this.selectedLabel || '') || this.multiLegLabels.includes(this.selectedLabel || '')) {
|
||||||
this.handleFieldForSpecialLabels();
|
this.handleFieldForSpecialLabels();
|
||||||
} else {
|
} else {
|
||||||
@ -647,6 +689,7 @@ export class TouchPadMenuComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
openPoolReplaceModal() {
|
openPoolReplaceModal() {
|
||||||
|
if (this.totalAmountLimitReached) return;
|
||||||
this.poolReplaceOpen = true;
|
this.poolReplaceOpen = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -681,4 +724,8 @@ export class TouchPadMenuComponent implements OnInit {
|
|||||||
closeTrePopup() {
|
closeTrePopup() {
|
||||||
this.trePopupVisible = false;
|
this.trePopupVisible = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
closeLimitPopup() {
|
||||||
|
this.showLimitPopup = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue
Block a user