agmission/Development/client/src/app/customers/trial/trial.component.ts

178 lines
5.5 KiB
TypeScript

import { AfterContentInit, Component, HostListener, Input, OnDestroy, OnInit, forwardRef } from '@angular/core';
import { FormBuilder, FormControl, FormGroup, NG_VALIDATORS, NG_VALUE_ACCESSOR } from '@angular/forms';
import { Trial } from '@app/domain/models/subscription.model';
import { BaseComp } from '@app/shared/base/base.component';
import { GC } from '@app/shared/global';
import { DateUtils } from '@app/shared/utils';
import { SelectItem } from 'primeng-lts/api';
const MIN_DAYS = 7;
@Component({
selector: 'trial',
templateUrl: './trial.component.html',
styleUrls: ['./trial.component.css'],
providers: [
{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => TrialComponent), multi: true },
{ provide: NG_VALIDATORS, useExisting: forwardRef(() => TrialComponent), multi: true }
]
})
export class TrialComponent extends BaseComp implements OnDestroy, OnInit, AfterContentInit {
@Input() trialDays: number[];
@Input() trials: Trial;
@Input() disable: boolean;
DAYS = GC.DAYS;
BYDATE = GC.BYDATE;
dayItems: SelectItem[];
form: FormGroup;
toDate: Date;
error: string;
calMinDate: Date;
calMaxDate: Date;
onChange: any = () => { };
onTouched: any = () => { };
constructor(
private readonly fb: FormBuilder
) {
super();
const ONE_YEAR = 1;
this.calMinDate = new Date();
this.calMinDate.setDate(this.calMinDate.getDate() + MIN_DAYS);
this.calMinDate.setHours(0, 0, 0);
this.calMaxDate = new Date();
this.calMaxDate.setFullYear(this.calMaxDate.getFullYear() + ONE_YEAR);
}
get value() {
return this.form.value;
}
set value(val) {
this.writeValue(val);
this.onChange(val);
this.onTouched(val);
}
ngOnInit(): void {
this.form = this.fb.group({
selected: new FormControl({ value: false, disabled: this.disable }),
type: new FormControl({ value: '', disabled: this.disable }),
startDate: [],
lastEndDate: [],
lastStartDate: [],
trialDays: new FormControl({ value: '', disabled: this.disable }),
byDate: []
});
this.dayItems = this.trialDays?.map((day) => ({ label: `${day}`, value: day }));
this.sub$.add(this.form.valueChanges.subscribe((val) => {
this.onChange(val);
this.onTouched(val);
}));
}
ngAfterContentInit() {
const hasExistingTrial = this.trials?.type && (this.trials.trialDays >= MIN_DAYS || this.trials.byDate);
if (hasExistingTrial) {
if (this.trials.type === this.BYDATE && this.trials.byDate) {
this.toDate = new Date(this.trials.byDate);
this.form.patchValue({ ...this.trials, selected: true });
} else if (this.trials.type === this.DAYS && this.trials.trialDays >= MIN_DAYS) {
this.form.patchValue({ ...this.trials, selected: true });
} else {
this.form.patchValue({ ...this.trials });
}
}
}
writeValue(val): void {
if (val) {
this.form.patchValue(val);
}
}
registerOnChange(fn: any): void {
this.onChange = fn;
}
registerOnTouched(fn: any): void {
this.onTouched = fn;
}
validate() {
this.checkAndDisplayErr();
const isTrial = this.form.value.selected;
const isInValid = !this.isValidTrialDays() && !this.isValidBydate();
return isTrial ? isInValid ? { trials: { valid: false } } : null : null;
}
isValidTrialDays() {
return this.form.value.type === this.DAYS && this.form.value.trialDays && !isNaN(this.form.value.trialDays) && this.form.value.trialDays >= MIN_DAYS;
}
isValidBydate() {
return this.form.value.type === this.BYDATE && this.form.value.byDate;
}
change() {
const noPrevTrial = !this.form.value.type;
if (noPrevTrial) {
this.form.patchValue({ type: this.DAYS });
}
const trialDays = this.form.value.trialDays;
const notExistItem = this.dayItems?.every((item) => item.value != trialDays);
if (this.isValidTrialDays() && notExistItem) {
this.dayItems.push({ label: `${trialDays}`, value: Number(trialDays) });
this.dayItems.sort((a, b) => a.value - b.value);
this.appConf.saveTrialDays(this.dayItems?.map((item) => item.value));
}
this.form.updateValueAndValidity();
}
changeCal() {
this.form.patchValue({
...this.trials,
type: this.BYDATE,
byDate: DateUtils.tsToDate(
DateUtils.endUtcTS(
DateUtils.dateToTS(this.toDate)))
});
this.form.updateValueAndValidity();
}
checkAndDisplayErr() {
this.error = '';
if (this.form.value.selected && this.form.value.type === this.BYDATE) {
if (!this.toDate) {
return this.error = `Please fill in end date MM/DD/YYYY from <the mininum ${MIN_DAYS} days ahead>`;
}
} else if (this.form.value.selected && this.form.value.type === this.DAYS) {
if (!this.form.value.trialDays) {
return this.error = 'Please fill in the number of end days';
} else if (isNaN(this.form.value.trialDays) || this.form.value.trialDays < MIN_DAYS) {
return this.error = `Number of days must be number greater than <the mininum ${MIN_DAYS} days ahead>.`;
}
}
return this.error;
}
remove(item) {
this.dayItems = this.dayItems?.filter((day) => day.label !== item.label);
this.appConf.saveTrialDays(this.dayItems?.map((item) => item.value));
}
@HostListener('document:keydown.enter', ['$event']) onKeydownHandler(e: KeyboardEvent) {
const target = <HTMLInputElement>e.target;
if (target.name === this.BYDATE) this.changeCal();
}
ngOnDestroy(): void {
super.ngOnDestroy();
}
}