schedule-form-edit.component.ts

mail@pastecode.io avatar
unknown
typescript
2 years ago
21 kB
2
Indexable
Never
import {
  ChangeDetectionStrategy,
  ChangeDetectorRef,
  Component,
  EventEmitter,
  Input,
  OnChanges,
  OnInit,
  Output,
  SimpleChanges,
  ViewChild,
} from '@angular/core';
import {FormArray, FormBuilder, FormControl, FormGroup, Validators} from '@angular/forms';
import {ActivatedRoute, Router} from '@angular/router';
import {NbToastrService} from '@nebular/theme';
import {debounceTime} from 'rxjs/operators';
import {code} from '../../../../../../@core/data/code';
import * as moment from 'moment';
import {ExtracurricularService} from '../../../../../../@core/api/extracurricular.service';
import {PersonnelService} from '../../../../../../@core/api/personnel.service';
import {DateService} from '../../../../../../@core/api/date.service';

@Component({
  selector: 'skr-schedule-form-edit',
  templateUrl: './schedule-form-edit.component.html',
  styleUrls: ['./schedule-form-edit.component.scss'],
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class ScheduleFormEditComponent implements OnInit, OnChanges {

  @ViewChild('tableExtracurricularSupervisorList') tableSupervisor: any;
  @ViewChild('tableExtracurricularCoachList') tableCoaches: any;

  @Input()
  scheduleData = null;

  @Output()
  onNext = new EventEmitter();

  searchSupervisor: FormControl = new FormControl(null);

  loading = {
    sessions: false,
    schooldays: false,
    supervisors: false,
    coaches: false,
    remove_supervisor: {},
    remove_coach: {},
  };

  validation = {
    date: true,
    time: true,
  };

  subscriber = {
    sessions: null,
    schooldays: null,
    search: null,
    supervisors: null,
    coaches: null,
    remove_supervisor: null,
    remove_coach: null,
  };

  schoolDays = [];
  supervisors = [];
  coaches = [];

  reset = 0;

  error = null;
  academicYears = [];
  schoolLocations = [];
  school = [];
  exculCategories = null;

  supervisor = false;
  coach = false;
  exculId = null;

  disabled = true;

  startDate = null;
  endDate = null;
  maxRegistDate = null;
  academicYear = null;

  schedule: FormGroup;

  constructor(
    private router: Router,
    private route: ActivatedRoute,
    private toastr: NbToastrService,
    private formBuilder: FormBuilder,
    private exculService: ExtracurricularService,
    private personnelService: PersonnelService,
    private dateService: DateService,
    private ref: ChangeDetectorRef,
  ) {
  }

  ngOnInit(): void {
    this.getParams();
    this.initScheduleForm();
    this.getSchooldays();
  }

  ngOnChanges(changes: SimpleChanges): void {
    if (changes.scheduleData) {
      if (this.scheduleData === null) {
        return;
      }
      if (this.reset === 0) {
        this.patchScheduleData();
      }
      this.reset++;
    }
  }

  getParams(): void {
    this.route.params.subscribe(res => {
      this.exculId = +res.id;
    });
  }

  initScheduleForm(): void {
    this.schedule = new FormGroup({
      academic_year: new FormControl(null, Validators.required),
      academic_year_label: new FormControl({value: null, disabled: true}, Validators.required),
      school_level_id: new FormControl(null),
      school_location_id: new FormControl(null, Validators.required),
      school_location_name: new FormControl(null, Validators.required),
      school_location_label: new FormControl({value: null, disabled: true}, Validators.required),
      school_id: new FormControl(null),
      school_name: new FormControl(null),
      excul_category_id: new FormControl(null, Validators.required),
      extracurricular_name: new FormControl(null, Validators.required),
      extracurricular_description: new FormControl(null, Validators.required),
      schedules: new FormArray([]),
      start_date: new FormControl(null, Validators.required),
      end_date: new FormControl(null, Validators.required),
      sessions: new FormControl(null, Validators.required),
      sessions_label: new FormControl({value: null, disabled: true}, Validators.required),
      max_registration_date: new FormControl(null, Validators.required),
      has_coach: new FormControl(false),
      has_supervisor: new FormControl(false),
      supervisors: new FormArray([]),
      coaches: new FormArray([]),
    });
  }

  getSchooldays(): void {
    if (this.subscriber.schooldays) {
      this.subscriber.schooldays.unsubscribe();
    }

    this.loading.schooldays = true;
    this.subscriber.schooldays =
      this.dateService
        .getSchoolDays()
        .subscribe(res => {
          if (res.status) {
            this.schoolDays = res.data;
            this.schoolDays.forEach(i => i.checked = false);
          } else {
            this.toastr.danger(res.message, code.error.error);
          }
          this.loading.schooldays = false;
          this.ref.detectChanges();
        }, err => {
          this.toastr.danger(code.error.internal_server_error, code.error.error);
          this.loading.schooldays = false;
          this.ref.detectChanges();
        });
  }

  patchScheduleData(): void {
    this.schedule.patchValue({
      academic_year: this.scheduleData.academic_year,
      academic_year_label: this.scheduleData.academic_year,
      school_id: this.scheduleData.school_id,
      school_name: this.scheduleData.school_name,
      school_level_id: this.scheduleData.school_level_id, // x
      school_location_id: this.scheduleData.school_location_id,
      school_location_name: this.scheduleData.school_location_name,
      school_location_label: this.scheduleData.school_location_name,
      excul_category_id: this.scheduleData.excul_category_id,
      extracurricular_name: this.scheduleData.extracurricular_name,
      extracurricular_description: this.scheduleData.extracurricular_description,
      schedules: this.scheduleData.schedules,
      start_date: this.scheduleData.start_date,
      end_date: this.scheduleData.end_date,
      sessions: this.scheduleData.sessions,
      sessions_label: this.scheduleData.sessions,
      max_registration_date: this.scheduleData.max_registration_date,
      has_coach: this.scheduleData.has_coach,
      has_supervisor: this.scheduleData.has_supervisor,
      supervisors: this.scheduleData.supervisors, // x
      coaches: this.scheduleData.coaches, // x
    });

    // init date
    this.startDate = moment(new Date(this.scheduleData.start_date)).format('MMM DD, YYYY');
    this.endDate = moment(new Date(this.scheduleData.end_date)).format('MMM DD, YYYY');
    this.maxRegistDate = moment(new Date(this.scheduleData.max_registration_date)).format('MMM DD, YYYY');

    // validate checked supervisor and coach table
    this.coach = !!this.scheduleData.has_coach;
    this.supervisor = !!this.scheduleData.has_supervisor;

    this.onCheckExtracurricularSchedules();
    this.getExtracurricularSupervisors(this.scheduleData.school_location_id);
    this.getExtracurricularCoaches(this.scheduleData.school_location_id);
    this.onSearch();
  }

  onCheckExtracurricularSchedules(): void {
    this.scheduleData.schedules ? this.scheduleData.schedules : this.scheduleData.schedules = [];
    if (this.scheduleData.schedules.length <= 0) {
      return;
    }

    for (const schedule of this.scheduleData.schedules) {
      const schooldayIndex = this.schoolDays.findIndex(i => +i.schoolday_id === +schedule.schoolday_id);
      if (schooldayIndex !== -1) {
        schedule.schoolday_name = this.schoolDays[schooldayIndex].schoolday_name;
        this.schoolDays[schooldayIndex].checked = true;
      }
      this.onPushExculSchedules(schedule);
    }
  }

  onSearch(): void {
    if (this.subscriber.search) {
      this.subscriber.search.unsubscribe();
    }

    this.subscriber.search =
      this
        .searchSupervisor
        .valueChanges
        .pipe(debounceTime(1000))
        .subscribe(res => {
          this.getExtracurricularSupervisors(this.scheduleData.school_location_id);
        });
  }

  onCheckSchoolDay(item, index): void {
    const schedules = this.schedule.controls['schedules'].value;
    const scheduleIndex = schedules.findIndex(i => i.schoolday_id === this.schoolDays[index].schoolday_id);
    if (scheduleIndex === -1) {
      this.onGetExculSchedules().push(this.onNewExculSchedules(this.schoolDays[index]));
      schedules.push(this.schoolDays[index]);
      this.sessionCount();
      return;
    }

    this.onGetExculSchedules().removeAt(scheduleIndex);
    schedules.splice(scheduleIndex, 1);
    this.sessionCount();
  }

  onNewSupervisor(supervisor: any = null): FormGroup {
    return new FormGroup({
      'excul_supervisor_id': new FormControl(supervisor ? supervisor.excul_supervisor_id : null),
      'staff_id': new FormControl(supervisor ? supervisor.staff_id : null),
      'personnel_id': new FormControl(supervisor ? supervisor.personnel_id : null),
      'school_name': new FormControl(this.schedule.controls['school_name'].value),
      'email': new FormControl(supervisor ? supervisor.email : null),
      'position': new FormControl(supervisor ? supervisor.position : null),
    });
  }

  onGetSupervisor(): FormArray {
    return (this.schedule.controls['supervisors']) as FormArray;
  }

  onPushSupervisor(supervisor: any = null): void {
    this.onGetSupervisor().push(this.onNewSupervisor(supervisor));
  }

  onNewCoach(coach: any = null): FormGroup {
    return new FormGroup({
      'excul_coach_id': new FormControl(coach ? coach.excul_coach_id : null),
      'coach_id': new FormControl(coach ? coach.coach_id : null),
      'name': new FormControl(coach ? coach.name : null),
      'position': new FormControl(coach ? coach.position : null),
      'coach_fee': new FormControl(coach ? coach.coach_fee : null),
    });
  }

  onGetCoach(): FormArray {
    return (this.schedule.controls['coaches']) as FormArray;
  }

  onPushCoach(coach: any = null): void {
    this.onGetCoach().push(this.onNewCoach(coach));
  }

  onNewExculSchedules(schedule: any = null, isNew = true): FormGroup {
    if (isNew) {
      return new FormGroup({
        'excul_schedule_id': new FormControl(null),
        'schoolday_id': new FormControl(schedule.schoolday_id),
        'schoolday_name': new FormControl(schedule.schoolday_name),
        'start_time': new FormControl(null, Validators.required),
        'end_time': new FormControl( null, Validators.required),
        'venue': new FormControl(null),
        'equipment': new FormControl(null),
        'is_time_valid': new FormControl(true),
      });
    }

    return new FormGroup({
      'excul_schedule_id': new FormControl(schedule ? schedule.excul_schedule_id : null),
      'schoolday_id': new FormControl(schedule ? schedule.schoolday_id : null),
      'schoolday_name': new FormControl(schedule ? schedule.schoolday_name : null),
      'start_time': new FormControl(schedule ? moment(new Date(schedule.start_time)).format('HH:mm') : null, Validators.required),
      'end_time': new FormControl( schedule ? moment(new Date(schedule.end_time)).format('HH:mm') : null, Validators.required),
      'venue': new FormControl(schedule ? schedule.venue : null),
      'equipment': new FormControl(schedule ? schedule.equipment : null),
      'is_time_valid': new FormControl(true),
    });
  }

  onValidateTime(index): void {
    const startTime = moment(this.onGetExculSchedules().at(index).get('start_time').value).format('HH:mm');
    const endTime = moment(this.onGetExculSchedules().at(index).get('end_time').value).format('HH:mm');

    if (startTime > endTime || endTime < startTime) this.validation.time = false;
    else this.validation.time = true;
  }

  onGetExculSchedules(): FormArray {
    return (this.schedule.controls['schedules']) as FormArray;
  }

  onPopExculSchedules(idx: number): void {
    this.onGetExculSchedules().removeAt(idx);
  }

  onPushExculSchedules(schedule): void {
    this.onGetExculSchedules().push(this.onNewExculSchedules(schedule, false));
  }

  checkSupervisor(checked: boolean) {
    this.supervisor = checked;
    this.schedule.controls['has_supervisor'].setValue(checked);
  }

  getExtracurricularSupervisors(schoolLocationId: number): void {
    if (this.subscriber.supervisors) {
      this.subscriber.supervisors.unsubscribe();
    }

    this.loading.supervisors = true;
    this.subscriber.supervisors =
      this
        .personnelService
        .getSupervisorListFiltered({
          search: this.searchSupervisor.value,
          school_location_id: schoolLocationId,
        })
        .subscribe(response => {
          if (response.status) {
            this.supervisors = response.data;
            if (this.supervisors.length > 0 || this.supervisors) {
              this.supervisors.forEach(i => {

                if (this.scheduleData.supervisors) {
                  const index = this.scheduleData.supervisors.findIndex(j => +j.staff_id === +i.staff_id);
                  if (index === -1) {
                    i.checked = false;
                    i.valid = false;
                  } else {
                    i.checked = true;
                    i.valid = true;
                    i.excul_supervisor_id = +this.scheduleData.supervisors[index].excul_supervisor_id;
                  }
                  this.onPushSupervisor(i);
                } else {
                  i.checked = false;
                  i.valid = false;
                }
              });
            }
          } else {
            this.error = response.message;
            this.toastr.danger(this.error, code.error.error);
          }
          this.loading.supervisors = false;
          this.ref.detectChanges();
        }, error => {
          this.error = code.error.internal_server_error;
          this.toastr.danger(this.error, code.error.error);
          this.loading.supervisors = false;
          this.ref.detectChanges();
        });
  }

  getExtracurricularCoaches(schoolLocationId: number): void {
    if (this.subscriber.coaches) {
      this.subscriber.coaches.unsubscribe();
    }

    this.loading.coaches = true;
    this.subscriber.coaches =
      this
        .exculService
        .selectCoaches({
          school_location_id: schoolLocationId,
        })
        .subscribe(response => {
          if (response.status) {
            this.coaches = response.data;
            if (this.coaches.length > 0 || this.coaches) {
              this.coaches.forEach(i => {

                if (this.scheduleData.coaches) {
                  const index = this.scheduleData.coaches.findIndex(j => +j.coach_id === +i.coach_id);
                  if (index === -1) {
                    i.checked = false;
                    i.valid = false;
                  } else {
                    i.checked = true;
                    i.valid = true;
                    i.excul_coach_id = +this.scheduleData.coaches[index].excul_coach_id;
                  }
                  this.onPushCoach(i);
                } else {
                  i.checked = false;
                  i.valid = false;
                }
              });
            }
          } else {
            this.error = response.message;
            this.toastr.danger(this.error, code.error.error);
          }
          this.loading.coaches = false;
          this.ref.detectChanges();
        }, error => {
          this.error = code.error.internal_server_error;
          this.toastr.danger(this.error, code.error.error);
          this.loading.coaches = false;
          this.ref.detectChanges();
        });
  }

  checkCoach(checked: boolean) {
    this.coach = checked;
    this.schedule.controls['has_coach'].setValue(checked);
  }

  onChangeStartTime(item, index): void {
    this.onGetExculSchedules().at(index).value.start_time = moment(new Date(item.time)).format('HH:mm');
    if (this.onGetExculSchedules().at(index).value.start_time && this.onGetExculSchedules().at(index).value.end_time) {
      if (
        this.onGetExculSchedules().at(index).value.start_time > this.onGetExculSchedules().at(index).value.end_time
        || this.onGetExculSchedules().at(index).value.end_time < this.onGetExculSchedules().at(index).value.start_time
      ) {
        this.onGetExculSchedules().at(index).value.is_time_valid = false;
        return;
      }
      this.onGetExculSchedules().at(index).value.is_time_valid = true;
    }
  }

  onChangeEndTime(item, index): void {
    this.onGetExculSchedules().at(index).value.end_time = moment(new Date(item.time)).format('HH:mm');
    if (this.onGetExculSchedules().at(index).value.start_time && this.onGetExculSchedules().at(index).value.end_time) {
      if (
        this.onGetExculSchedules().at(index).value.start_time > this.onGetExculSchedules().at(index).value.end_time
        || this.onGetExculSchedules().at(index).value.end_time < this.onGetExculSchedules().at(index).value.start_time
      ) {
        this.onGetExculSchedules().at(index).value.is_time_valid = false;
        return;
      }
      this.onGetExculSchedules().at(index).value.is_time_valid = true;
    }
  }

  onValidateDate(tag, item): void {
    if (tag === 'start') {
      this.startDate = moment(new Date(item)).format('MMM DD, YYYY');
      this.schedule.controls['start_date'].setValue(item);
    } else if (tag === 'end') {
      this.endDate = moment(new Date(item)).format('MMM DD, YYYY');
      this.schedule.controls['end_date'].setValue(item);
    } else if (tag === 'max') {
      this.maxRegistDate = moment(new Date(item)).format('MMM DD, YYYY');
      this.schedule.controls['max_registration_date'].setValue(item);
    }

    if (this.startDate && this.endDate) {
      if (
        this.startDate > this.endDate
        || this.endDate < this.startDate
      ) {
        this.validation.date = false;
        this.maxRegistrationDateValidation();
        return;
      }

      this.validation.date = true;
      if (this.maxRegistDate) {
        this.maxRegistrationDateValidation();
      }
    }
  }

  maxRegistrationDateValidation(): void {
    if (
      this.maxRegistDate >= this.startDate
      || this.maxRegistDate <= this.endDate
    ) {
      this.validation.date = true;
      return;
    }

    this.validation.date = false;
  }

  sessionCount(): void {
    if (this.schedule.controls['start_date'].value && this.schedule.controls['end_date'].value) {
      if (this.subscriber.sessions) {
        this.subscriber.sessions.unsubscribe();
      }

      this.loading.sessions = true;
      this.subscriber.sessions = this.exculService.masterExtracurricularSessions({
        academic_year: this.schedule.controls['academic_year'].value,
        school_location_id: this.schedule.controls['school_location_id'].value,
        start_date: this.schedule.controls['start_date'].value,
        end_date: this.schedule.controls['end_date'].value,
        schoolday_ids: encodeURIComponent(this.schedule.value.schedules.map(i => i.schoolday_id)),
      })
        .subscribe(res => {
          if (res.status) {
            const data = res.data;
            this.schedule.controls['sessions'].setValue(data.length);
            this.schedule.controls['sessions_label'].setValue(data.length);
          } else {
            this.toastr.danger(res.message, code.error.error);
          }
          this.loading.sessions = false;
          this.ref.detectChanges();
        }, err => {
          this.loading.sessions = false;
          this.toastr.danger(code.error.internal_server_error, code.error.error);
          this.ref.detectChanges();
        });
    }
  }

  onChangeExculCategory(item): void {
    this.schedule.get('excul_category_id').markAsTouched();
    this.schedule.get('excul_category_id').setValue(item ? +item.category_id : null);
  }

  onSelectCoach(item, index): void {
    const coachIndex = this.onGetCoach().at(index);
    if (item) {
      if (!coachIndex) {
        this.onPushCoach(this.coaches[index]);
      }
    } else {
      this.onGetCoach().removeAt(index);
    }
  }

  onSelectSupervisor(item, index): void {
    this.supervisors[index].checked = !!item;
    const supervisorIndex = this.onGetSupervisor().at(index);
    if (item) {
      if (!supervisorIndex) {
        this.onPushSupervisor(this.supervisors[index]);
      }
    } else {
      this.onGetSupervisor().removeAt(index);
    }
  }

  onCancel(): void {
    this.router.navigate(['../../'], {relativeTo: this.route});
  }

  onClickNext(): void {
    this.schedule.value.supervisors = this.supervisors.filter(i => i.checked === true);
    this.onNext.emit(this.schedule.value);
  }

}