fix(SPG-549) BE - Validasi tgl periode unique based on level

pull/3/head
Aswin Ashar Abdullah 2024-06-24 18:26:48 +07:00
parent 067025312e
commit cc7a345fff
7 changed files with 80 additions and 4 deletions

View File

@ -0,0 +1,14 @@
import { MigrationInterface, QueryRunner } from "typeorm";
export class AddColumnPrioritySeasonPeriod1719227554657 implements MigrationInterface {
name = 'AddColumnPrioritySeasonPeriod1719227554657'
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`ALTER TABLE "season_periods" ADD "priority" integer NOT NULL DEFAULT '3'`);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`ALTER TABLE "season_periods" DROP COLUMN "priority"`);
}
}

View File

@ -9,8 +9,7 @@ import { ItemRateModel } from 'src/modules/item-related/item-rate/data/models/it
@Entity(TABLE_NAME.SEASON_PERIOD)
export class SeasonPeriodModel
extends BaseStatusModel<SeasonPeriodEntity>
implements SeasonPeriodEntity
{
implements SeasonPeriodEntity {
@Column('date', { name: 'start_date', nullable: true })
start_date: Date;
@ -23,6 +22,9 @@ export class SeasonPeriodModel
@Column('varchar', { name: 'holiday_name', nullable: true })
holiday_name: string;
@Column('int', { name: 'priority', default: 3 })
priority: number;
@Column('varchar', { name: 'season_type_id', nullable: true })
season_type_id: string;
@ManyToOne(() => SeasonTypeModel, (model) => model.season_periods, {

View File

@ -6,4 +6,5 @@ export interface SeasonPeriodEntity extends BaseStatusEntity {
end_date: Date;
days: EnumDays[];
holiday_name: string;
priority?: number;
}

View File

@ -29,6 +29,7 @@ export class SeasonPeriodHolidayHandler
holidayDate.updated_at = event.data.data.updated_at;
holidayDate.season_type = event.data.data.season_type;
holidayDate.item_rates = event.data.data.item_rates;
holidayDate.priority = 1;
holidayDates.push(holidayDate);
}

View File

@ -1,4 +1,4 @@
import { Injectable } from '@nestjs/common';
import { HttpStatus, Injectable, UnprocessableEntityException } from '@nestjs/common';
import {
EventTopics,
columnUniques,
@ -8,10 +8,16 @@ import { SeasonPeriodEntity } from '../../entities/season-period.entity';
import { SeasonPeriodModel } from '../../../data/models/season-period.model';
import { BaseCreateManager } from 'src/core/modules/domain/usecase/managers/base-create.manager';
import { SeasonPeriodCreatedEvent } from '../../entities/event/season-period-created.event';
import { ValidateSeasonPeriodHelper } from './helpers/validate.helper';
@Injectable()
export class CreateSeasonPeriodManager extends BaseCreateManager<SeasonPeriodEntity> {
async beforeProcess(): Promise<void> {
const priority = await ValidateSeasonPeriodHelper(this.dataService, this.data);
Object.assign(this.data, {
priority: priority
})
return;
}

View File

@ -0,0 +1,46 @@
import { HttpStatus, UnprocessableEntityException } from "@nestjs/common";
// 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 })
}
const datas = await query
.andWhere('data.priority = :priority', { priority: priority })
.andWhere('data.start_date BETWEEN :inputStartDate AND :inputEndDate', { inputStartDate: data.start_date, inputEndDate: data.end_date })
.andWhere('data.end_date BETWEEN :inputStartDate AND :inputEndDate', { inputStartDate: data.start_date, inputEndDate: data.end_date }).getCount();
if (datas > 0) {
throw new UnprocessableEntityException({
statusCode: HttpStatus.UNPROCESSABLE_ENTITY,
message: `Failed! there is another season period in same range date`,
error: 'Unprocessable Entity',
});
}
return priority;
}

View File

@ -8,10 +8,16 @@ import {
columnUniques,
validateRelations,
} from 'src/core/strings/constants/interface.constants';
import { ValidateSeasonPeriodHelper } from './helpers/validate.helper';
@Injectable()
export class UpdateSeasonPeriodManager extends BaseUpdateManager<SeasonPeriodEntity> {
async validateProcess(): Promise<void> {
const priority = await ValidateSeasonPeriodHelper(this.dataService, this.data);
Object.assign(this.data, {
priority: priority
})
return;
}