import { HttpStatus, UnprocessableEntityException } from '@nestjs/common'; import { Brackets } from 'typeorm'; import * as _ from 'lodash'; // function ini bergungsi untuk validasi season period yang sama export async function ValidateSeasonPeriodHelper(dataService, data) { /* singkatnya, ada 3 level priority season period level 1 hari libur atau specific date ( mempunyai holiday_name atau start_date sama dengan end_date ) level 2 specific day (array daysnya tidak kosong contoh [Senin, Selasa]) level 3 range date ( array daynya kosong, bukan holiday ) priority 1,2,3 bisa saling tumpang tindih, dan diperhatikan tingkatnya ( semakin besar angkanya , maka semakin kecil priority ) tapi priority tidak dapat ditindih oleh season period dengan tingkat priority yang sama pada range tanggal yang sama contohnya : 1. Season period holiday start_date 2024-08-28, end_date 2024-08-28 tidak dapat ditindih oleh season period holiday lainnya pada range tanggal yang sama 2. Season period start_date: 2024-08-15, end_date 2024-08-28, dan days [Senin, Selasa] tidak dapat ditindih oleh Season period 2024-07-08, 2024-08-20 days [Sabtu, Senin] => akan tetap dapat ditindih oleh season period 2024-08-15, 2024-08-28, days [Rabu, Kamis] (karena beberapa day) 3. Season period range 2024-08-15 hingga 2024-08-28, days [] tidak dapat ditindih oleh Season period 2024-07-08, 2024-08-20 days [] => akan tetapi dapat ditindih oleh season period 2024-08-15, 2024-08-28 days [Sabtu, Senin] (karena ini naik prio menjadi priority 2) */ const query = dataService.getRepository().createQueryBuilder('data'); let priority: number = 3; // libur / specific date if ( data.holidays?.length > 0 || data.start_date == data.end_date || data.holiday_name ) priority = 1; // specific day else if (data.days?.length > 0) priority = 2; if (data.id) { query.andWhere('data.id != :dataId', { dataId: data.id }); } let datas = await query .andWhere('data.priority = :priority', { priority: priority }) .andWhere( new Brackets((query) => { // contoh data tanggal 1 Agustus - 31 Agustus query.orWhere( new Brackets((q) => { return q .andWhere('data.start_date <= :inputStartDate ', { inputStartDate: data.start_date, }) .andWhere('data.end_date >= :inputEndDate', { inputEndDate: data.end_date, }); }), ); query.orWhere( new Brackets((q) => { return q .andWhere('data.start_date >= :inputStartDate ', { inputStartDate: data.start_date, }) .andWhere('data.end_date <= :inputEndDate', { inputEndDate: data.end_date, }); }), ); return query; }), ) .getMany(); if (priority == 2) { datas = datas?.filter((item) => { const sameDate = item.days.filter((day) => { return data.days.some((day2) => { return day == day2; }); }); return sameDate.length > 0; }); } if (datas.length > 0) { throw new UnprocessableEntityException({ statusCode: HttpStatus.UNPROCESSABLE_ENTITY, message: `Failed! there is another season period in same range date`, error: 'Unprocessable Entity', }); } return priority; }