format(code) formatting code

pull/6/head^2
Aswin Ashar Abdullah 2024-07-01 01:13:26 +07:00
parent 4b31dd40b5
commit 0b1cdabea4
77 changed files with 1016 additions and 904 deletions

View File

@ -94,8 +94,11 @@ export function getOrderBy(
? [`${baseFilter.order_by}`] ? [`${baseFilter.order_by}`]
: [`${tableName}.${baseFilter.order_by}`]; : [`${tableName}.${baseFilter.order_by}`];
if (baseFilter.order_by.split('.').length == 1 && baseFilter.order_by.split('.').pop() != 'id') { if (
orderBys.push(`${ tableName }.created_at`) baseFilter.order_by.split('.').length == 1 &&
baseFilter.order_by.split('.').pop() != 'id'
) {
orderBys.push(`${tableName}.created_at`);
} }
} }

View File

@ -22,17 +22,15 @@ export class ValidateRelationHelper<Entity> {
`${this.tableName}.${relation.relation}`, `${this.tableName}.${relation.relation}`,
`${this.tableName}.${relation.relation}`, `${this.tableName}.${relation.relation}`,
relation.relation, relation.relation,
) );
} } else if (relation.query) {
else if (relation.query) {
queryBuilder.loadRelationCountAndMap( queryBuilder.loadRelationCountAndMap(
`${this.tableName}.total_${relation.relation}`, `${this.tableName}.total_${relation.relation}`,
`${this.tableName}.${relation.relation}`, `${this.tableName}.${relation.relation}`,
`total_${relation.relation}`, `total_${relation.relation}`,
relation.query, relation.query,
); );
} } else {
else {
queryBuilder.loadRelationCountAndMap( queryBuilder.loadRelationCountAndMap(
`${this.tableName}.total_${relation.relation}`, `${this.tableName}.total_${relation.relation}`,
`${this.tableName}.${relation.relation}`, `${this.tableName}.${relation.relation}`,
@ -54,8 +52,16 @@ export class ValidateRelationHelper<Entity> {
`Failed! this data already connected to ${relation.relation}`; `Failed! this data already connected to ${relation.relation}`;
if (relation.singleQuery) { if (relation.singleQuery) {
const relationColumn = data[relation.relation]?.[`${ relation.singleQuery[0] }`] const relationColumn =
if (!!relationColumn && this.mappingValidator(relationColumn, relation.singleQuery[1], relation.singleQuery[2])) data[relation.relation]?.[`${relation.singleQuery[0]}`];
if (
!!relationColumn &&
this.mappingValidator(
relationColumn,
relation.singleQuery[1],
relation.singleQuery[2],
)
)
throw new UnprocessableEntityException(message); throw new UnprocessableEntityException(message);
} else if (data[`total_${relation.relation} `]) } else if (data[`total_${relation.relation} `])
throw new UnprocessableEntityException(message); throw new UnprocessableEntityException(message);

View File

@ -58,8 +58,11 @@ export abstract class BaseDataService<Entity> {
entityTarget: EntityTarget<Entity>, entityTarget: EntityTarget<Entity>,
findManyOptions: FindManyOptions<Entity>, findManyOptions: FindManyOptions<Entity>,
): Promise<void> { ): Promise<void> {
const datas = await queryRunner.manager.find(entityTarget, findManyOptions) const datas = await queryRunner.manager.find(entityTarget, findManyOptions);
await queryRunner.manager.delete(entityTarget, datas?.map(item => item['id'])); await queryRunner.manager.delete(
entityTarget,
datas?.map((item) => item['id']),
);
} }
async getOneByOptions(findOneOptions): Promise<Entity> { async getOneByOptions(findOneOptions): Promise<Entity> {

View File

@ -38,7 +38,12 @@ export abstract class BaseManager {
} }
} }
setService(dataService, tableName, dataServiceOpt = null, dataServiceSecondOpt = null) { setService(
dataService,
tableName,
dataServiceOpt = null,
dataServiceSecondOpt = null,
) {
this.dataService = dataService; this.dataService = dataService;
this.tableName = tableName; this.tableName = tableName;
this.queryRunner = this.dataService this.queryRunner = this.dataService

View File

@ -100,7 +100,6 @@ export abstract class BaseBatchUpdateStatusManager<Entity> extends BaseManager {
if (!this.eventTopics.length) return; if (!this.eventTopics.length) return;
for (const topic of this.eventTopics) { for (const topic of this.eventTopics) {
let data; let data;
if (!topic.relations) { if (!topic.relations) {
data = await this.dataService.getOneByOptions({ data = await this.dataService.getOneByOptions({
@ -108,7 +107,7 @@ export abstract class BaseBatchUpdateStatusManager<Entity> extends BaseManager {
id: dataNew.id, id: dataNew.id,
}, },
relations: topic.relations, relations: topic.relations,
}) });
} }
this.eventBus.publishAll([ this.eventBus.publishAll([

View File

@ -21,8 +21,8 @@ export abstract class BaseUpdateStatusManager<Entity> extends BaseManager {
this.data = await this.dataService.getOneByOptions({ this.data = await this.dataService.getOneByOptions({
where: { where: {
id: this.dataId, id: this.dataId,
} },
}) });
this.oldData = _.cloneDeep(this.data); this.oldData = _.cloneDeep(this.data);
Object.assign(this.data, { Object.assign(this.data, {
@ -68,15 +68,14 @@ export abstract class BaseUpdateStatusManager<Entity> extends BaseManager {
if (!this.eventTopics.length) return; if (!this.eventTopics.length) return;
for (const topic of this.eventTopics) { for (const topic of this.eventTopics) {
let data; let data;
if (!topic.data) { if (!topic.data) {
data = await this.dataService.getOneByOptions({ data = await this.dataService.getOneByOptions({
where: { where: {
id: this.dataId id: this.dataId,
}, },
relations: topic.relations, relations: topic.relations,
}) });
} }
this.eventBus.publishAll([ this.eventBus.publishAll([

View File

@ -90,15 +90,14 @@ export abstract class BaseUpdateManager<Entity> extends BaseManager {
if (!this.eventTopics.length) return; if (!this.eventTopics.length) return;
for (const topic of this.eventTopics) { for (const topic of this.eventTopics) {
let data; let data;
if (!topic.data) { if (!topic.data) {
data = await this.dataService.getOneByOptions({ data = await this.dataService.getOneByOptions({
where: { where: {
id: this.dataId id: this.dataId,
}, },
relations: topic.relations, relations: topic.relations,
}) });
} }
this.eventBus.publishAll([ this.eventBus.publishAll([

View File

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

View File

@ -3,15 +3,21 @@ import { CouchDataController } from './infrastructure/couch.controller';
import { Module } from '@nestjs/common'; import { Module } from '@nestjs/common';
import { CouchService } from './data/services/couch.service'; import { CouchService } from './data/services/couch.service';
import { CqrsModule } from '@nestjs/cqrs'; import { CqrsModule } from '@nestjs/cqrs';
import { PaymentMethodUpdatedHandler, PaymentMethodDeletedHandler } from './domain/managers/payment-method.handler'; import {
import { VipCategoryDeletedHandler, VipCategoryUpdatedHandler } from './domain/managers/vip-category.handler'; PaymentMethodUpdatedHandler,
import { SeasonPeriodDeletedHandler, SeasonPeriodUpdatedHandler } from './domain/managers/season-period.handler'; PaymentMethodDeletedHandler,
} from './domain/managers/payment-method.handler';
import {
VipCategoryDeletedHandler,
VipCategoryUpdatedHandler,
} from './domain/managers/vip-category.handler';
import {
SeasonPeriodDeletedHandler,
SeasonPeriodUpdatedHandler,
} from './domain/managers/season-period.handler';
@Module({ @Module({
imports: [ imports: [ConfigModule.forRoot(), CqrsModule],
ConfigModule.forRoot(),
CqrsModule,
],
controllers: [CouchDataController], controllers: [CouchDataController],
providers: [ providers: [
PaymentMethodDeletedHandler, PaymentMethodDeletedHandler,

View File

@ -38,18 +38,18 @@ export class CouchService {
public async deleteDoc(data, database) { public async deleteDoc(data, database) {
const nano = require('nano')('http://root:password@172.10.10.2:5970'); const nano = require('nano')('http://root:password@172.10.10.2:5970');
const db = nano.use(database); const db = nano.use(database);
const result = await db.get(data.id) const result = await db.get(data.id);
await db.destroy(data.id, result._rev); await db.destroy(data.id, result._rev);
} }
public async updateDoc(data, database) { public async updateDoc(data, database) {
const nano = require('nano')('http://root:password@172.10.10.2:5970'); const nano = require('nano')('http://root:password@172.10.10.2:5970');
const db = nano.use(database); const db = nano.use(database);
const result = await db.get(data.id) const result = await db.get(data.id);
console.log(result, 'dsa') console.log(result, 'dsa');
await db.insert({ await db.insert({
...data, ...data,
_rev: result._rev _rev: result._rev,
}); });
} }
} }

View File

@ -1,39 +1,41 @@
import { EventsHandler, IEventHandler } from "@nestjs/cqrs"; import { EventsHandler, IEventHandler } from '@nestjs/cqrs';
import { CouchService } from "../../data/services/couch.service"; import { CouchService } from '../../data/services/couch.service';
import { STATUS } from "src/core/strings/constants/base.constants"; import { STATUS } from 'src/core/strings/constants/base.constants';
import { ItemDeletedEvent } from "src/modules/item-related/item/domain/entities/event/item-deleted.event"; import { ItemDeletedEvent } from 'src/modules/item-related/item/domain/entities/event/item-deleted.event';
import { ItemUpdatedEvent } from "src/modules/item-related/item/domain/entities/event/item-updated.event"; import { ItemUpdatedEvent } from 'src/modules/item-related/item/domain/entities/event/item-updated.event';
import { ItemChangeStatusEvent } from "src/modules/item-related/item/domain/entities/event/item-change-status.event"; import { ItemChangeStatusEvent } from 'src/modules/item-related/item/domain/entities/event/item-change-status.event';
import { ItemDataService } from "src/modules/item-related/item/data/services/item-data.service"; import { ItemDataService } from 'src/modules/item-related/item/data/services/item-data.service';
@EventsHandler(ItemDeletedEvent) @EventsHandler(ItemDeletedEvent)
export class ItemDeletedHandler implements IEventHandler<ItemDeletedEvent> { export class ItemDeletedHandler implements IEventHandler<ItemDeletedEvent> {
constructor( constructor(private couchService: CouchService) {}
private couchService: CouchService
) { }
async handle(event: ItemDeletedEvent) { async handle(event: ItemDeletedEvent) {
const data = await this.couchService.deleteDoc({ const data = await this.couchService.deleteDoc(
{
_id: event.data.id, _id: event.data.id,
...event.data.data ...event.data.data,
}, 'item'); },
'item',
);
} }
} }
@EventsHandler(ItemChangeStatusEvent, ItemUpdatedEvent) @EventsHandler(ItemChangeStatusEvent, ItemUpdatedEvent)
export class ItemUpdatedHandler implements IEventHandler<ItemChangeStatusEvent> { export class ItemUpdatedHandler
implements IEventHandler<ItemChangeStatusEvent>
{
constructor( constructor(
private couchService: CouchService, private couchService: CouchService,
private itemService: ItemDataService, private itemService: ItemDataService,
) {} ) {}
async handle(event: ItemChangeStatusEvent) { async handle(event: ItemChangeStatusEvent) {
const dataOld = event.data.old; const dataOld = event.data.old;
const data = event.data.data; const data = event.data.data;
const dataItem = await this.itemService.getOneByOptions({ const dataItem = await this.itemService.getOneByOptions({
where: { where: {
id: data.id id: data.id,
}, },
relations: [ relations: [
'item_category', 'item_category',
@ -43,27 +45,25 @@ export class ItemUpdatedHandler implements IEventHandler<ItemChangeStatusEvent>
'item_rates.item', 'item_rates.item',
'item_rates.season_period', 'item_rates.season_period',
'item_rates.season_period.season_type', 'item_rates.season_period.season_type',
] ],
}) });
// change status to active // change status to active
if (dataOld?.status != data.status && data.status == STATUS.ACTIVE) { if (dataOld?.status != data.status && data.status == STATUS.ACTIVE) {
await this.couchService.createDoc( await this.couchService.createDoc(
{ {
_id: data.id, _id: data.id,
...dataItem ...dataItem,
}, },
'item' 'item',
); );
} } else if (dataOld?.status != data.status) {
else if (dataOld?.status != data.status) {
await this.couchService.deleteDoc( await this.couchService.deleteDoc(
{ {
_id: data.id, _id: data.id,
...dataItem ...dataItem,
}, },
'item' 'item',
); );
} }
@ -72,9 +72,9 @@ export class ItemUpdatedHandler implements IEventHandler<ItemChangeStatusEvent>
await this.couchService.updateDoc( await this.couchService.updateDoc(
{ {
_id: data.id, _id: data.id,
...dataItem ...dataItem,
}, },
'item' 'item',
); );
} }
} }

View File

@ -1,32 +1,34 @@
import { EventsHandler, IEventHandler } from "@nestjs/cqrs"; import { EventsHandler, IEventHandler } from '@nestjs/cqrs';
import { CouchService } from "../../data/services/couch.service"; import { CouchService } from '../../data/services/couch.service';
import { STATUS } from "src/core/strings/constants/base.constants"; import { STATUS } from 'src/core/strings/constants/base.constants';
import { PaymentMethodDeletedEvent } from "src/modules/transaction/payment-method/domain/entities/event/payment-method-deleted.event"; import { PaymentMethodDeletedEvent } from 'src/modules/transaction/payment-method/domain/entities/event/payment-method-deleted.event';
import { PaymentMethodUpdatedEvent } from "src/modules/transaction/payment-method/domain/entities/event/payment-method-updated.event"; import { PaymentMethodUpdatedEvent } from 'src/modules/transaction/payment-method/domain/entities/event/payment-method-updated.event';
import { PaymentMethodChangeStatusEvent } from "src/modules/transaction/payment-method/domain/entities/event/payment-method-change-status.event"; import { PaymentMethodChangeStatusEvent } from 'src/modules/transaction/payment-method/domain/entities/event/payment-method-change-status.event';
@EventsHandler(PaymentMethodDeletedEvent) @EventsHandler(PaymentMethodDeletedEvent)
export class PaymentMethodDeletedHandler implements IEventHandler<PaymentMethodDeletedEvent> { export class PaymentMethodDeletedHandler
constructor( implements IEventHandler<PaymentMethodDeletedEvent>
private couchService: CouchService {
) { } constructor(private couchService: CouchService) {}
async handle(event: PaymentMethodDeletedEvent) { async handle(event: PaymentMethodDeletedEvent) {
const data = await this.couchService.deleteDoc({ const data = await this.couchService.deleteDoc(
{
_id: event.data.id, _id: event.data.id,
...event.data.data ...event.data.data,
}, 'payment_method'); },
'payment_method',
);
} }
} }
@EventsHandler(PaymentMethodChangeStatusEvent, PaymentMethodUpdatedEvent) @EventsHandler(PaymentMethodChangeStatusEvent, PaymentMethodUpdatedEvent)
export class PaymentMethodUpdatedHandler implements IEventHandler<PaymentMethodChangeStatusEvent> { export class PaymentMethodUpdatedHandler
constructor( implements IEventHandler<PaymentMethodChangeStatusEvent>
private couchService: CouchService {
) { } constructor(private couchService: CouchService) {}
async handle(event: PaymentMethodChangeStatusEvent) { async handle(event: PaymentMethodChangeStatusEvent) {
const dataOld = event.data.old; const dataOld = event.data.old;
const data = event.data.data; const data = event.data.data;
@ -35,19 +37,17 @@ export class PaymentMethodUpdatedHandler implements IEventHandler<PaymentMethodC
await this.couchService.createDoc( await this.couchService.createDoc(
{ {
_id: data.id, _id: data.id,
...data ...data,
}, },
'payment_method' 'payment_method',
); );
} } else if (dataOld?.status != data.status) {
else if (dataOld?.status != data.status) {
await this.couchService.deleteDoc( await this.couchService.deleteDoc(
{ {
_id: data.id, _id: data.id,
...data ...data,
}, },
'payment_method' 'payment_method',
); );
} }
@ -56,9 +56,9 @@ export class PaymentMethodUpdatedHandler implements IEventHandler<PaymentMethodC
await this.couchService.updateDoc( await this.couchService.updateDoc(
{ {
_id: data.id, _id: data.id,
...data ...data,
}, },
'payment_method' 'payment_method',
); );
} }
} }

View File

@ -1,32 +1,34 @@
import { EventsHandler, IEventHandler } from "@nestjs/cqrs"; import { EventsHandler, IEventHandler } from '@nestjs/cqrs';
import { CouchService } from "../../data/services/couch.service"; import { CouchService } from '../../data/services/couch.service';
import { STATUS } from "src/core/strings/constants/base.constants"; import { STATUS } from 'src/core/strings/constants/base.constants';
import { SeasonPeriodDeletedEvent } from "src/modules/season-related/season-period/domain/entities/event/season-period-deleted.event"; import { SeasonPeriodDeletedEvent } from 'src/modules/season-related/season-period/domain/entities/event/season-period-deleted.event';
import { SeasonPeriodChangeStatusEvent } from "src/modules/season-related/season-period/domain/entities/event/season-period-change-status.event"; import { SeasonPeriodChangeStatusEvent } from 'src/modules/season-related/season-period/domain/entities/event/season-period-change-status.event';
import { SeasonPeriodUpdatedEvent } from "src/modules/season-related/season-period/domain/entities/event/season-period-updated.event"; import { SeasonPeriodUpdatedEvent } from 'src/modules/season-related/season-period/domain/entities/event/season-period-updated.event';
@EventsHandler(SeasonPeriodDeletedEvent) @EventsHandler(SeasonPeriodDeletedEvent)
export class SeasonPeriodDeletedHandler implements IEventHandler<SeasonPeriodDeletedEvent> { export class SeasonPeriodDeletedHandler
constructor( implements IEventHandler<SeasonPeriodDeletedEvent>
private couchService: CouchService {
) { } constructor(private couchService: CouchService) {}
async handle(event: SeasonPeriodDeletedEvent) { async handle(event: SeasonPeriodDeletedEvent) {
const data = await this.couchService.deleteDoc({ const data = await this.couchService.deleteDoc(
{
_id: event.data.id, _id: event.data.id,
...event.data.data ...event.data.data,
}, 'season_period'); },
'season_period',
);
} }
} }
@EventsHandler(SeasonPeriodChangeStatusEvent, SeasonPeriodUpdatedEvent) @EventsHandler(SeasonPeriodChangeStatusEvent, SeasonPeriodUpdatedEvent)
export class SeasonPeriodUpdatedHandler implements IEventHandler<SeasonPeriodChangeStatusEvent> { export class SeasonPeriodUpdatedHandler
constructor( implements IEventHandler<SeasonPeriodChangeStatusEvent>
private couchService: CouchService {
) { } constructor(private couchService: CouchService) {}
async handle(event: SeasonPeriodChangeStatusEvent) { async handle(event: SeasonPeriodChangeStatusEvent) {
const dataOld = event.data.old; const dataOld = event.data.old;
const data = event.data.data; const data = event.data.data;
@ -35,19 +37,17 @@ export class SeasonPeriodUpdatedHandler implements IEventHandler<SeasonPeriodCha
await this.couchService.createDoc( await this.couchService.createDoc(
{ {
_id: data.id, _id: data.id,
...data ...data,
}, },
'season_period' 'season_period',
); );
} } else if (dataOld?.status != data.status) {
else if (dataOld?.status != data.status) {
await this.couchService.deleteDoc( await this.couchService.deleteDoc(
{ {
_id: data.id, _id: data.id,
...data ...data,
}, },
'season_period' 'season_period',
); );
} }
@ -56,9 +56,9 @@ export class SeasonPeriodUpdatedHandler implements IEventHandler<SeasonPeriodCha
await this.couchService.updateDoc( await this.couchService.updateDoc(
{ {
_id: data.id, _id: data.id,
...data ...data,
}, },
'season_period' 'season_period',
); );
} }
} }

View File

@ -1,70 +1,76 @@
import { EventsHandler, IEventHandler } from "@nestjs/cqrs"; import { EventsHandler, IEventHandler } from '@nestjs/cqrs';
import { CouchService } from "../../data/services/couch.service"; import { CouchService } from '../../data/services/couch.service';
import { STATUS } from "src/core/strings/constants/base.constants"; import { STATUS } from 'src/core/strings/constants/base.constants';
import { UserDeletedEvent } from "src/modules/user-related/user/domain/entities/event/user-deleted.event"; import { UserDeletedEvent } from 'src/modules/user-related/user/domain/entities/event/user-deleted.event';
import { UserChangeStatusEvent } from "src/modules/user-related/user/domain/entities/event/user-change-status.event"; import { UserChangeStatusEvent } from 'src/modules/user-related/user/domain/entities/event/user-change-status.event';
import { UserUpdatedEvent } from "src/modules/user-related/user/domain/entities/event/user-updated.event"; import { UserUpdatedEvent } from 'src/modules/user-related/user/domain/entities/event/user-updated.event';
import { UserDataService } from "src/modules/user-related/user/data/services/user-data.service"; import { UserDataService } from 'src/modules/user-related/user/data/services/user-data.service';
@EventsHandler(UserDeletedEvent) @EventsHandler(UserDeletedEvent)
export class UserDeletedHandler implements IEventHandler<UserDeletedEvent> { export class UserDeletedHandler implements IEventHandler<UserDeletedEvent> {
constructor( constructor(private couchService: CouchService) {}
private couchService: CouchService
) { }
async handle(event: UserDeletedEvent) { async handle(event: UserDeletedEvent) {
const data = await this.couchService.deleteDoc({ const data = await this.couchService.deleteDoc(
{
_id: event.data.id, _id: event.data.id,
...event.data.data ...event.data.data,
}, 'user'); },
'user',
);
} }
} }
@EventsHandler(UserChangeStatusEvent, UserUpdatedEvent) @EventsHandler(UserChangeStatusEvent, UserUpdatedEvent)
export class UserUpdatedHandler implements IEventHandler<UserChangeStatusEvent> { export class UserUpdatedHandler
implements IEventHandler<UserChangeStatusEvent>
{
constructor( constructor(
private couchService: CouchService, private couchService: CouchService,
private userService: UserDataService, private userService: UserDataService,
) {} ) {}
async handle(event: UserChangeStatusEvent) { async handle(event: UserChangeStatusEvent) {
const dataOld = event.data.old; const dataOld = event.data.old;
const data = event.data.data; const data = event.data.data;
const user = await this.userService.getOneByOptions({ const user = await this.userService
.getOneByOptions({
where: { where: {
id: data.id id: data.id,
}, },
relations: [ relations: [
'user_privilege', 'user_privilege',
'user_privilege.user_privilege_configurations' 'user_privilege.user_privilege_configurations',
] ],
}).then(item => { })
const user_privilege_configurations = item['user_privilege']?.user_privilege_configurations?.filter(config => config.module == "POS") .then((item) => {
const user_privilege_configurations = item[
'user_privilege'
]?.user_privilege_configurations?.filter(
(config) => config.module == 'POS',
);
Object.assign(item['user_privilege'], { Object.assign(item['user_privilege'], {
user_privilege_configurations: user_privilege_configurations user_privilege_configurations: user_privilege_configurations,
}) });
return item return item;
}) });
// change status to active // change status to active
if (dataOld?.status != data.status && data.status == STATUS.ACTIVE) { if (dataOld?.status != data.status && data.status == STATUS.ACTIVE) {
await this.couchService.createDoc( await this.couchService.createDoc(
{ {
_id: data.id, _id: data.id,
...user ...user,
}, },
'user' 'user',
); );
} } else if (dataOld?.status != data.status) {
else if (dataOld?.status != data.status) {
await this.couchService.deleteDoc( await this.couchService.deleteDoc(
{ {
_id: data.id, _id: data.id,
...user ...user,
}, },
'user' 'user',
); );
} }
@ -73,9 +79,9 @@ export class UserUpdatedHandler implements IEventHandler<UserChangeStatusEvent>
await this.couchService.updateDoc( await this.couchService.updateDoc(
{ {
_id: data.id, _id: data.id,
...user ...user,
}, },
'user' 'user',
); );
} }
} }

View File

@ -1,32 +1,34 @@
import { EventsHandler, IEventHandler } from "@nestjs/cqrs"; import { EventsHandler, IEventHandler } from '@nestjs/cqrs';
import { CouchService } from "../../data/services/couch.service"; import { CouchService } from '../../data/services/couch.service';
import { VipCategoryDeletedEvent } from "src/modules/transaction/vip-category/domain/entities/event/vip-category-deleted.event"; import { VipCategoryDeletedEvent } from 'src/modules/transaction/vip-category/domain/entities/event/vip-category-deleted.event';
import { VipCategoryChangeStatusEvent } from "src/modules/transaction/vip-category/domain/entities/event/vip-category-change-status.event"; import { VipCategoryChangeStatusEvent } from 'src/modules/transaction/vip-category/domain/entities/event/vip-category-change-status.event';
import { VipCategoryUpdatedEvent } from "src/modules/transaction/vip-category/domain/entities/event/vip-category-updated.event"; import { VipCategoryUpdatedEvent } from 'src/modules/transaction/vip-category/domain/entities/event/vip-category-updated.event';
import { STATUS } from "src/core/strings/constants/base.constants"; import { STATUS } from 'src/core/strings/constants/base.constants';
@EventsHandler(VipCategoryDeletedEvent) @EventsHandler(VipCategoryDeletedEvent)
export class VipCategoryDeletedHandler implements IEventHandler<VipCategoryDeletedEvent> { export class VipCategoryDeletedHandler
constructor( implements IEventHandler<VipCategoryDeletedEvent>
private couchService: CouchService {
) { } constructor(private couchService: CouchService) {}
async handle(event: VipCategoryDeletedEvent) { async handle(event: VipCategoryDeletedEvent) {
const data = await this.couchService.deleteDoc({ const data = await this.couchService.deleteDoc(
{
_id: event.data.id, _id: event.data.id,
...event.data.data ...event.data.data,
}, 'vip_category'); },
'vip_category',
);
} }
} }
@EventsHandler(VipCategoryChangeStatusEvent, VipCategoryUpdatedEvent) @EventsHandler(VipCategoryChangeStatusEvent, VipCategoryUpdatedEvent)
export class VipCategoryUpdatedHandler implements IEventHandler<VipCategoryChangeStatusEvent> { export class VipCategoryUpdatedHandler
constructor( implements IEventHandler<VipCategoryChangeStatusEvent>
private couchService: CouchService {
) { } constructor(private couchService: CouchService) {}
async handle(event: VipCategoryChangeStatusEvent) { async handle(event: VipCategoryChangeStatusEvent) {
const dataOld = event.data.old; const dataOld = event.data.old;
const data = event.data.data; const data = event.data.data;
@ -35,19 +37,17 @@ export class VipCategoryUpdatedHandler implements IEventHandler<VipCategoryChang
await this.couchService.createDoc( await this.couchService.createDoc(
{ {
_id: data.id, _id: data.id,
...data ...data,
}, },
'vip_category' 'vip_category',
); );
} } else if (dataOld?.status != data.status) {
else if (dataOld?.status != data.status) {
await this.couchService.deleteDoc( await this.couchService.deleteDoc(
{ {
_id: data.id, _id: data.id,
...data ...data,
}, },
'vip_category' 'vip_category',
); );
} }
@ -56,9 +56,9 @@ export class VipCategoryUpdatedHandler implements IEventHandler<VipCategoryChang
await this.couchService.updateDoc( await this.couchService.updateDoc(
{ {
_id: data.id, _id: data.id,
...data ...data,
}, },
'vip_category' 'vip_category',
); );
} }
} }

View File

@ -14,8 +14,12 @@ export class IndexHolidayCalendarManager {
const res = await calendar.events.list({ const res = await calendar.events.list({
calendarId: calendarId, calendarId: calendarId,
timeMin: param.start_date ? param.start_date + 'T00:00:00Z' : new Date().getFullYear() + '-01-01T00:00:00Z', timeMin: param.start_date
timeMax: param.end_date ? param.end_date + 'T23:59:59Z' : new Date().getFullYear() + '-12-31T23:59:59Z', ? param.start_date + 'T00:00:00Z'
: new Date().getFullYear() + '-01-01T00:00:00Z',
timeMax: param.end_date
? param.end_date + 'T23:59:59Z'
: new Date().getFullYear() + '-12-31T23:59:59Z',
singleEvents: true, singleEvents: true,
orderBy: 'startTime', orderBy: 'startTime',
}); });

View File

@ -1,18 +1,18 @@
import { ApiProperty } from "@nestjs/swagger"; import { ApiProperty } from '@nestjs/swagger';
import { FilterGoogleCalendarEntity } from "../../domain/entities/filter-google-calendar.entity"; import { FilterGoogleCalendarEntity } from '../../domain/entities/filter-google-calendar.entity';
export class FilterGoogleCalendarDto implements FilterGoogleCalendarEntity { export class FilterGoogleCalendarDto implements FilterGoogleCalendarEntity {
@ApiProperty({ @ApiProperty({
required: false, required: false,
type: Date, type: Date,
example: '2024-04-01' example: '2024-04-01',
}) })
start_date: Date; start_date: Date;
@ApiProperty({ @ApiProperty({
required: false, required: false,
type: Date, type: Date,
example: '2024-04-30' example: '2024-04-30',
}) })
end_date: Date; end_date: Date;
} }

View File

@ -26,7 +26,7 @@ export class ItemRateReadOrchestrator extends BaseReadOrchestrator<ItemRateEntit
// this.indexManager.setService(this.itemServiceRead, TABLE_NAME.ITEM_RATE); // this.indexManager.setService(this.itemServiceRead, TABLE_NAME.ITEM_RATE);
// await this.indexManager.execute(); // await this.indexManager.execute();
// return this.indexManager.getResult(); // return this.indexManager.getResult();
return return;
} }
async indexItem(params): Promise<PaginationResponse<ItemEntity>> { async indexItem(params): Promise<PaginationResponse<ItemEntity>> {

View File

@ -18,13 +18,17 @@ export class IndexItemRateManager extends BaseIndexManager<ItemEntity> {
} }
async afterProcess(): Promise<void> { async afterProcess(): Promise<void> {
this.result.data?.map((item) => {
this.result.data?.map(item => { let prices = [];
let prices = [] for (
for (let d = new Date(this.filterParam.start_date); d <= new Date(this.filterParam.end_date); d.setDate(d.getDate() + 1)) { let d = new Date(this.filterParam.start_date);
d <= new Date(this.filterParam.end_date);
d.setDate(d.getDate() + 1)
) {
const rate = item['item_rates']?.find( const rate = item['item_rates']?.find(
rate => d >= new Date(rate.season_period.start_date) && d <= new Date(rate.season_period.end_date) (rate) =>
d >= new Date(rate.season_period.start_date) &&
d <= new Date(rate.season_period.end_date),
); );
prices.push({ prices.push({
@ -37,9 +41,9 @@ export class IndexItemRateManager extends BaseIndexManager<ItemEntity> {
delete item['item_rates']; delete item['item_rates'];
Object.assign(item, { Object.assign(item, {
dates: prices dates: prices,
}) });
}) });
return; return;
} }
@ -55,7 +59,7 @@ export class IndexItemRateManager extends BaseIndexManager<ItemEntity> {
'tenant', 'tenant',
'item_rates', 'item_rates',
'item_rates.season_period', 'item_rates.season_period',
'season_period.season_type' 'season_period.season_type',
], ],
// relation yang hanya ingin dihitung (akan return number) // relation yang hanya ingin dihitung (akan return number)

View File

@ -5,18 +5,19 @@ import { Transform } from 'class-transformer';
export class FilterItemRateDto export class FilterItemRateDto
extends BaseFilterDto extends BaseFilterDto
implements FilterItemRateEntity { implements FilterItemRateEntity
{
@ApiProperty({ @ApiProperty({
required: false, required: false,
type: Date, type: Date,
example: '2024-04-01' example: '2024-04-01',
}) })
start_date: Date; start_date: Date;
@ApiProperty({ @ApiProperty({
required: false, required: false,
type: Date, type: Date,
example: '2024-04-30' example: '2024-04-30',
}) })
end_date: Date; end_date: Date;
@ -31,6 +32,4 @@ export class FilterItemRateDto
return Array.isArray(body.value) ? body.value : [body.value]; return Array.isArray(body.value) ? body.value : [body.value];
}) })
season_period_ids: string[]; season_period_ids: string[];
} }

View File

@ -39,9 +39,6 @@ import { ItemRateModel } from './data/models/item-rate.model';
ItemRateDataOrchestrator, ItemRateDataOrchestrator,
ItemRateReadOrchestrator, ItemRateReadOrchestrator,
], ],
exports: [ exports: [ItemRateDataService, ItemRateReadService],
ItemRateDataService,
ItemRateReadService,
]
}) })
export class ItemRateModule {} export class ItemRateModule {}

View File

@ -1,4 +1,8 @@
import { HttpStatus, Injectable, UnprocessableEntityException } from '@nestjs/common'; import {
HttpStatus,
Injectable,
UnprocessableEntityException,
} from '@nestjs/common';
import { BaseUpdateStatusManager } from 'src/core/modules/domain/usecase/managers/base-update-status.manager'; import { BaseUpdateStatusManager } from 'src/core/modules/domain/usecase/managers/base-update-status.manager';
import { ItemEntity } from '../../entities/item.entity'; import { ItemEntity } from '../../entities/item.entity';
import { import {
@ -28,11 +32,13 @@ export class ActiveItemManager extends BaseUpdateStatusManager<ItemEntity> {
} }
get validateRelations(): validateRelations[] { get validateRelations(): validateRelations[] {
return [{ return [
{
relation: 'tenant', relation: 'tenant',
singleQuery: ['status', '!=', STATUS.ACTIVE], singleQuery: ['status', '!=', STATUS.ACTIVE],
message: `Failed! Tenant of item must be active first`, message: `Failed! Tenant of item must be active first`,
}]; },
];
} }
get entityTarget(): any { get entityTarget(): any {

View File

@ -7,7 +7,11 @@ import {
import { ItemModel } from '../../../data/models/item.model'; import { ItemModel } from '../../../data/models/item.model';
import { ItemChangeStatusEvent } from '../../entities/event/item-change-status.event'; import { ItemChangeStatusEvent } from '../../entities/event/item-change-status.event';
import { BatchResult } from 'src/core/response/domain/ok-response.interface'; import { BatchResult } from 'src/core/response/domain/ok-response.interface';
import { HttpStatus, Injectable, UnprocessableEntityException } from '@nestjs/common'; import {
HttpStatus,
Injectable,
UnprocessableEntityException,
} from '@nestjs/common';
import { STATUS } from 'src/core/strings/constants/base.constants'; import { STATUS } from 'src/core/strings/constants/base.constants';
@Injectable() @Injectable()
@ -25,11 +29,13 @@ export class BatchActiveItemManager extends BaseBatchUpdateStatusManager<ItemEnt
} }
get validateRelations(): validateRelations[] { get validateRelations(): validateRelations[] {
return [{ return [
{
relation: 'tenant', relation: 'tenant',
singleQuery: ['status', '!=', STATUS.ACTIVE], singleQuery: ['status', '!=', STATUS.ACTIVE],
message: `Failed! Tenant of item must be active first`, message: `Failed! Tenant of item must be active first`,
}]; },
];
} }
get entityTarget(): any { get entityTarget(): any {

View File

@ -25,11 +25,13 @@ export class BatchConfirmItemManager extends BaseBatchUpdateStatusManager<ItemEn
} }
get validateRelations(): validateRelations[] { get validateRelations(): validateRelations[] {
return [{ return [
{
relation: 'tenant', relation: 'tenant',
singleQuery: ['status', '!=', STATUS.ACTIVE], singleQuery: ['status', '!=', STATUS.ACTIVE],
message: `Failed! Tenant of item must be active first`, message: `Failed! Tenant of item must be active first`,
}]; },
];
} }
get entityTarget(): any { get entityTarget(): any {

View File

@ -28,11 +28,13 @@ export class ConfirmItemManager extends BaseUpdateStatusManager<ItemEntity> {
} }
get validateRelations(): validateRelations[] { get validateRelations(): validateRelations[] {
return [{ return [
{
relation: 'tenant', relation: 'tenant',
singleQuery: ['status', '!=', STATUS.ACTIVE], singleQuery: ['status', '!=', STATUS.ACTIVE],
message: `Failed! Tenant of item must be active first`, message: `Failed! Tenant of item must be active first`,
}]; },
];
} }
get entityTarget(): any { get entityTarget(): any {

View File

@ -23,11 +23,7 @@ export class DetailItemManager extends BaseDetailManager<ItemEntity> {
joinRelations: [], joinRelations: [],
// relation join and select (relasi yang ingin ditampilkan), // relation join and select (relasi yang ingin ditampilkan),
selectRelations: [ selectRelations: ['item_category', 'bundling_items', 'tenant'],
'item_category',
'bundling_items',
'tenant',
],
// relation yang hanya ingin dihitung (akan return number) // relation yang hanya ingin dihitung (akan return number)
countRelations: [], countRelations: [],
@ -59,7 +55,7 @@ export class DetailItemManager extends BaseDetailManager<ItemEntity> {
'bundling_items.base_price', 'bundling_items.base_price',
'tenant.id', 'tenant.id',
'tenant.name' 'tenant.name',
]; ];
} }

View File

@ -10,7 +10,7 @@ import { ItemRateEntity } from 'src/modules/item-related/item-rate/domain/entiti
@Injectable() @Injectable()
export class IndexItemRatesManager extends BaseIndexManager<ItemRateEntity> { export class IndexItemRatesManager extends BaseIndexManager<ItemRateEntity> {
async prepareData(): Promise<void> { async prepareData(): Promise<void> {
this.filterParam.order_by = `${ this.tableName }.id` this.filterParam.order_by = `${this.tableName}.id`;
return; return;
} }
@ -63,11 +63,10 @@ export class IndexItemRatesManager extends BaseIndexManager<ItemRateEntity> {
setQueryFilter( setQueryFilter(
queryBuilder: SelectQueryBuilder<ItemRateEntity>, queryBuilder: SelectQueryBuilder<ItemRateEntity>,
): SelectQueryBuilder<ItemRateEntity> { ): SelectQueryBuilder<ItemRateEntity> {
if (this.filterParam.item_ids) { if (this.filterParam.item_ids) {
queryBuilder.andWhere(`${this.tableName}.item_id In (:...itemIds)`, { queryBuilder.andWhere(`${this.tableName}.item_id In (:...itemIds)`, {
itemIds: this.filterParam.item_ids itemIds: this.filterParam.item_ids,
}) });
} }
return queryBuilder; return queryBuilder;
} }

View File

@ -27,11 +27,7 @@ export class IndexItemManager extends BaseIndexManager<ItemEntity> {
joinRelations: [], joinRelations: [],
// relation join and select (relasi yang ingin ditampilkan), // relation join and select (relasi yang ingin ditampilkan),
selectRelations: [ selectRelations: ['item_category', 'bundling_items', 'tenant'],
'item_category',
'bundling_items',
'tenant',
],
// relation yang hanya ingin dihitung (akan return number) // relation yang hanya ingin dihitung (akan return number)
countRelations: [], countRelations: [],
@ -57,7 +53,7 @@ export class IndexItemManager extends BaseIndexManager<ItemEntity> {
'bundling_items.name', 'bundling_items.name',
'tenant.id', 'tenant.id',
'tenant.name' 'tenant.name',
]; ];
} }

View File

@ -30,7 +30,10 @@ import { IndexItemRatesManager } from './domain/usecases/managers/index-item-rat
@Module({ @Module({
imports: [ imports: [
ConfigModule.forRoot(), ConfigModule.forRoot(),
TypeOrmModule.forFeature([ItemModel, ItemRateModel], CONNECTION_NAME.DEFAULT), TypeOrmModule.forFeature(
[ItemModel, ItemRateModel],
CONNECTION_NAME.DEFAULT,
),
CqrsModule, CqrsModule,
], ],
controllers: [ItemDataController, ItemReadController], controllers: [ItemDataController, ItemReadController],

View File

@ -9,7 +9,8 @@ import { ItemRateModel } from 'src/modules/item-related/item-rate/data/models/it
@Entity(TABLE_NAME.SEASON_PERIOD) @Entity(TABLE_NAME.SEASON_PERIOD)
export class SeasonPeriodModel export class SeasonPeriodModel
extends BaseStatusModel<SeasonPeriodEntity> extends BaseStatusModel<SeasonPeriodEntity>
implements SeasonPeriodEntity { implements SeasonPeriodEntity
{
@Column('date', { name: 'start_date', nullable: true }) @Column('date', { name: 'start_date', nullable: true })
start_date: Date; start_date: Date;

View File

@ -1,15 +1,16 @@
import { EventsHandler, IEventHandler } from "@nestjs/cqrs"; import { EventsHandler, IEventHandler } from '@nestjs/cqrs';
import { SeasonPeriodPriceUpdatedEvent } from "../../entities/event/season-period-price-updated.event"; import { SeasonPeriodPriceUpdatedEvent } from '../../entities/event/season-period-price-updated.event';
import { SeasonPeriodReadService } from "../../../data/services/season-period-read.service"; import { SeasonPeriodReadService } from '../../../data/services/season-period-read.service';
import { SeasonPeriodDataService } from "../../../data/services/season-period-data.service"; import { SeasonPeriodDataService } from '../../../data/services/season-period-data.service';
import { SeasonPeriodModel } from "../../../data/models/season-period.model"; import { SeasonPeriodModel } from '../../../data/models/season-period.model';
import { ItemRateDataService } from "src/modules/item-related/item-rate/data/services/item-rate-data.service"; import { ItemRateDataService } from 'src/modules/item-related/item-rate/data/services/item-rate-data.service';
import { ItemRateModel } from "src/modules/item-related/item-rate/data/models/item-rate.model"; import { ItemRateModel } from 'src/modules/item-related/item-rate/data/models/item-rate.model';
import { IsNull } from "typeorm"; import { IsNull } from 'typeorm';
@EventsHandler(SeasonPeriodPriceUpdatedEvent) @EventsHandler(SeasonPeriodPriceUpdatedEvent)
export class SeasonPeriodPriceUpdatedHandler implements IEventHandler<SeasonPeriodPriceUpdatedEvent> { export class SeasonPeriodPriceUpdatedHandler
implements IEventHandler<SeasonPeriodPriceUpdatedEvent>
{
constructor( constructor(
private readService: SeasonPeriodReadService, private readService: SeasonPeriodReadService,
private dataService: SeasonPeriodDataService, private dataService: SeasonPeriodDataService,
@ -17,30 +18,28 @@ export class SeasonPeriodPriceUpdatedHandler implements IEventHandler<SeasonPeri
) {} ) {}
async handle(event: SeasonPeriodPriceUpdatedEvent) { async handle(event: SeasonPeriodPriceUpdatedEvent) {
const datas = await this.readService.getManyByOptions({ const datas = await this.readService
.getManyByOptions({
where: { where: {
season_type_id: event.data.data.season_period?.id season_type_id: event.data.data.season_period?.id,
} },
}).then(data => { })
return data.map(item => { .then((data) => {
return data.map((item) => {
return { return {
...item, ...item,
item_rates: event.data.data.item_rates, item_rates: event.data.data.item_rates,
} };
}) });
}) });
const queryRunner = this.dataService const queryRunner = this.dataService
.getRepository() .getRepository()
.manager.connection.createQueryRunner(); .manager.connection.createQueryRunner();
await this.dataService.createBatch( await this.dataService.createBatch(queryRunner, SeasonPeriodModel, datas);
queryRunner,
SeasonPeriodModel,
datas
)
await this.deleteUnusedItem() await this.deleteUnusedItem();
} }
async deleteUnusedItem() { async deleteUnusedItem() {
@ -48,15 +47,10 @@ export class SeasonPeriodPriceUpdatedHandler implements IEventHandler<SeasonPeri
.getRepository() .getRepository()
.manager.connection.createQueryRunner(); .manager.connection.createQueryRunner();
await this.rateDataService.deleteByOptions( await this.rateDataService.deleteByOptions(queryRunnerItem, ItemRateModel, {
queryRunnerItem,
ItemRateModel,
{
where: { where: {
season_period_id: IsNull() season_period_id: IsNull(),
} },
} });
)
} }
} }

View File

@ -38,9 +38,7 @@ export class ActiveSeasonPeriodManager extends BaseUpdateStatusManager<SeasonPer
return [ return [
{ {
topic: SeasonPeriodChangeStatusEvent, topic: SeasonPeriodChangeStatusEvent,
relations: [ relations: ['season_type'],
'season_type'
]
}, },
]; ];
} }

View File

@ -35,9 +35,7 @@ export class BatchActiveSeasonPeriodManager extends BaseBatchUpdateStatusManager
return [ return [
{ {
topic: SeasonPeriodChangeStatusEvent, topic: SeasonPeriodChangeStatusEvent,
relations: [ relations: ['season_type'],
'season_type'
]
}, },
]; ];
} }

View File

@ -35,9 +35,7 @@ export class BatchConfirmSeasonPeriodManager extends BaseBatchUpdateStatusManage
return [ return [
{ {
topic: SeasonPeriodChangeStatusEvent, topic: SeasonPeriodChangeStatusEvent,
relations: [ relations: ['season_type'],
'season_type'
]
}, },
]; ];
} }

View File

@ -35,9 +35,7 @@ export class BatchInactiveSeasonPeriodManager extends BaseBatchUpdateStatusManag
return [ return [
{ {
topic: SeasonPeriodChangeStatusEvent, topic: SeasonPeriodChangeStatusEvent,
relations: [ relations: ['season_type'],
'season_type'
]
}, },
]; ];
} }

View File

@ -38,9 +38,7 @@ export class ConfirmSeasonPeriodManager extends BaseUpdateStatusManager<SeasonPe
return [ return [
{ {
topic: SeasonPeriodChangeStatusEvent, topic: SeasonPeriodChangeStatusEvent,
relations: [ relations: ['season_type'],
'season_type'
]
}, },
]; ];
} }

View File

@ -1,4 +1,8 @@
import { HttpStatus, Injectable, UnprocessableEntityException } from '@nestjs/common'; import {
HttpStatus,
Injectable,
UnprocessableEntityException,
} from '@nestjs/common';
import { import {
EventTopics, EventTopics,
columnUniques, columnUniques,
@ -13,11 +17,14 @@ import { ValidateSeasonPeriodHelper } from './helpers/validate.helper';
@Injectable() @Injectable()
export class CreateSeasonPeriodManager extends BaseCreateManager<SeasonPeriodEntity> { export class CreateSeasonPeriodManager extends BaseCreateManager<SeasonPeriodEntity> {
async beforeProcess(): Promise<void> { async beforeProcess(): Promise<void> {
const priority = await ValidateSeasonPeriodHelper(this.dataService, this.data); const priority = await ValidateSeasonPeriodHelper(
this.dataService,
this.data,
);
Object.assign(this.data, { Object.assign(this.data, {
priority: priority priority: priority,
}) });
return; return;
} }

View File

@ -1,5 +1,5 @@
import { HttpStatus, UnprocessableEntityException } from "@nestjs/common"; import { HttpStatus, UnprocessableEntityException } from '@nestjs/common';
import { Brackets } from "typeorm"; import { Brackets } from 'typeorm';
import * as _ from 'lodash'; import * as _ from 'lodash';
// function ini bergungsi untuk validasi season period yang sama // function ini bergungsi untuk validasi season period yang sama
@ -20,51 +20,65 @@ export async function ValidateSeasonPeriodHelper(dataService, data) {
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 [] 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) => 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') const query = dataService.getRepository().createQueryBuilder('data');
let priority: number = 3; let priority: number = 3;
// libur / specific date // libur / specific date
if (data.holidays?.length > 0 || data.start_date == data.end_date || data.holiday_name) priority = 1 if (
data.holidays?.length > 0 ||
data.start_date == data.end_date ||
data.holiday_name
)
priority = 1;
// specific day // specific day
else if (data.days?.length > 0) priority = 2 else if (data.days?.length > 0) priority = 2;
if (data.id) { if (data.id) {
query.andWhere('data.id != :dataId', { dataId: data.id }) query.andWhere('data.id != :dataId', { dataId: data.id });
} }
let datas = await query let datas = await query
.andWhere('data.priority = :priority', { priority: priority }) .andWhere('data.priority = :priority', { priority: priority })
.andWhere( .andWhere(
new Brackets(query => { new Brackets((query) => {
// contoh data tanggal 1 Agustus - 31 Agustus // contoh data tanggal 1 Agustus - 31 Agustus
query.orWhere( query.orWhere(
new Brackets(q => { new Brackets((q) => {
return q.andWhere('data.start_date <= :inputStartDate ', { inputStartDate: data.start_date }) return q
.andWhere('data.end_date >= :inputEndDate', { inputEndDate: data.end_date }); .andWhere('data.start_date <= :inputStartDate ', {
inputStartDate: data.start_date,
}) })
) .andWhere('data.end_date >= :inputEndDate', {
inputEndDate: data.end_date,
});
}),
);
query.orWhere( query.orWhere(
new Brackets(q => { new Brackets((q) => {
return q.andWhere('data.start_date >= :inputStartDate ', { inputStartDate: data.start_date }) return q
.andWhere('data.end_date <= :inputEndDate', { inputEndDate: data.end_date }); .andWhere('data.start_date >= :inputStartDate ', {
inputStartDate: data.start_date,
}) })
) .andWhere('data.end_date <= :inputEndDate', {
inputEndDate: data.end_date,
});
}),
);
return query; return query;
}) }),
) )
.getMany(); .getMany();
if (priority == 2) { if (priority == 2) {
datas = datas?.filter(item => { datas = datas?.filter((item) => {
const sameDate = item.days.filter((day) => { const sameDate = item.days.filter((day) => {
return data.days.some((day2) => { return data.days.some((day2) => {
return day == day2; return day == day2;
}); });
}); });
return sameDate.length > 0 return sameDate.length > 0;
}) });
} }
if (datas.length > 0) { if (datas.length > 0) {

View File

@ -38,9 +38,7 @@ export class InactiveSeasonPeriodManager extends BaseUpdateStatusManager<SeasonP
return [ return [
{ {
topic: SeasonPeriodChangeStatusEvent, topic: SeasonPeriodChangeStatusEvent,
relations: [ relations: ['season_type'],
'season_type'
]
}, },
]; ];
} }

View File

@ -10,7 +10,7 @@ import { ItemRateEntity } from 'src/modules/item-related/item-rate/domain/entiti
@Injectable() @Injectable()
export class IndexSeasonPeriodeItemManager extends BaseIndexManager<ItemRateEntity> { export class IndexSeasonPeriodeItemManager extends BaseIndexManager<ItemRateEntity> {
async prepareData(): Promise<void> { async prepareData(): Promise<void> {
this.filterParam.order_by = `${ this.tableName }.id` this.filterParam.order_by = `${this.tableName}.id`;
return; return;
} }
@ -70,11 +70,13 @@ export class IndexSeasonPeriodeItemManager extends BaseIndexManager<ItemRateEnti
setQueryFilter( setQueryFilter(
queryBuilder: SelectQueryBuilder<ItemRateEntity>, queryBuilder: SelectQueryBuilder<ItemRateEntity>,
): SelectQueryBuilder<ItemRateEntity> { ): SelectQueryBuilder<ItemRateEntity> {
if (this.filterParam.season_period_ids) { if (this.filterParam.season_period_ids) {
queryBuilder.andWhere(`${ this.tableName }.season_period_id In (:...periodIds)`, { queryBuilder.andWhere(
periodIds: this.filterParam.season_period_ids `${this.tableName}.season_period_id In (:...periodIds)`,
}) {
periodIds: this.filterParam.season_period_ids,
},
);
} }
return queryBuilder; return queryBuilder;

View File

@ -1,20 +1,23 @@
import { HttpStatus, Injectable, UnprocessableEntityException } from "@nestjs/common"; import {
import { BaseCustomManager } from "src/core/modules/domain/usecase/managers/base-custom.manager"; HttpStatus,
import { SeasonPeriodEntity } from "../../entities/season-period.entity"; Injectable,
import { EventTopics } from "src/core/strings/constants/interface.constants"; UnprocessableEntityException,
import { SeasonPeriodModel } from "../../../data/models/season-period.model"; } from '@nestjs/common';
import { SeasonPeriodPriceUpdatedEvent } from "../../entities/event/season-period-price-updated.event"; import { BaseCustomManager } from 'src/core/modules/domain/usecase/managers/base-custom.manager';
import { OPERATION } from "src/core/strings/constants/base.constants"; import { SeasonPeriodEntity } from '../../entities/season-period.entity';
import { EventTopics } from 'src/core/strings/constants/interface.constants';
import { SeasonPeriodModel } from '../../../data/models/season-period.model';
import { SeasonPeriodPriceUpdatedEvent } from '../../entities/event/season-period-price-updated.event';
import { OPERATION } from 'src/core/strings/constants/base.constants';
@Injectable() @Injectable()
export class UpdateSeasonPeriodPriceManager extends BaseCustomManager<SeasonPeriodEntity> { export class UpdateSeasonPeriodPriceManager extends BaseCustomManager<SeasonPeriodEntity> {
async validateProcess(): Promise<void> { async validateProcess(): Promise<void> {
const existSeason = await this.dataService.getOneByOptions({ const existSeason = await this.dataService.getOneByOptions({
where: { where: {
season_type_id: this.data.season_period.id season_type_id: this.data.season_period.id,
} },
}) });
if (!existSeason) { if (!existSeason) {
throw new UnprocessableEntityException({ throw new UnprocessableEntityException({
statusCode: HttpStatus.UNPROCESSABLE_ENTITY, statusCode: HttpStatus.UNPROCESSABLE_ENTITY,
@ -39,8 +42,8 @@ export class UpdateSeasonPeriodPriceManager extends BaseCustomManager<SeasonPeri
description: '', description: '',
module: this.tableName, module: this.tableName,
op: OPERATION.CREATE, op: OPERATION.CREATE,
}) }),
) );
return; return;
} }
@ -49,7 +52,7 @@ export class UpdateSeasonPeriodPriceManager extends BaseCustomManager<SeasonPeri
} }
get entityTarget(): any { get entityTarget(): any {
return SeasonPeriodModel;; return SeasonPeriodModel;
} }
getResult() { getResult() {
@ -59,5 +62,4 @@ export class UpdateSeasonPeriodPriceManager extends BaseCustomManager<SeasonPeri
get eventTopics(): EventTopics[] { get eventTopics(): EventTopics[] {
return []; return [];
} }
} }

View File

@ -13,11 +13,14 @@ import { ValidateSeasonPeriodHelper } from './helpers/validate.helper';
@Injectable() @Injectable()
export class UpdateSeasonPeriodManager extends BaseUpdateManager<SeasonPeriodEntity> { export class UpdateSeasonPeriodManager extends BaseUpdateManager<SeasonPeriodEntity> {
async validateProcess(): Promise<void> { async validateProcess(): Promise<void> {
const priority = await ValidateSeasonPeriodHelper(this.dataService, this.data); const priority = await ValidateSeasonPeriodHelper(
this.dataService,
this.data,
);
Object.assign(this.data, { Object.assign(this.data, {
priority: priority priority: priority,
}) });
return; return;
} }
@ -45,9 +48,7 @@ export class UpdateSeasonPeriodManager extends BaseUpdateManager<SeasonPeriodEnt
return [ return [
{ {
topic: SeasonPeriodUpdatedEvent, topic: SeasonPeriodUpdatedEvent,
relations: [ relations: ['season_type'],
'season_type'
]
}, },
]; ];
} }

View File

@ -52,7 +52,10 @@ export class SeasonPeriodDataOrchestrator extends BaseDataTransactionOrchestrato
async updatePrice(data): Promise<any> { async updatePrice(data): Promise<any> {
this.updatePriceManager.setData(data); this.updatePriceManager.setData(data);
this.updatePriceManager.setService(this.serviceData, TABLE_NAME.SEASON_PERIOD); this.updatePriceManager.setService(
this.serviceData,
TABLE_NAME.SEASON_PERIOD,
);
await this.updatePriceManager.execute(); await this.updatePriceManager.execute();
return this.updatePriceManager.getResult(); return this.updatePriceManager.getResult();
} }

View File

@ -39,7 +39,10 @@ export class SeasonPeriodReadOrchestrator extends BaseReadOrchestrator<SeasonPer
async indexItem(params): Promise<PaginationResponse<ItemRateEntity>> { async indexItem(params): Promise<PaginationResponse<ItemRateEntity>> {
this.indexItemManager.setFilterParam(params); this.indexItemManager.setFilterParam(params);
this.indexItemManager.setService(this.itemServiceRead, TABLE_NAME.SEASON_PERIOD); this.indexItemManager.setService(
this.itemServiceRead,
TABLE_NAME.SEASON_PERIOD,
);
await this.indexItemManager.execute(); await this.indexItemManager.execute();
return this.indexItemManager.getResult(); return this.indexItemManager.getResult();
} }

View File

@ -9,7 +9,8 @@ import { SeasonPeriodHolidayDto } from './season-period-holiday.dto';
export class UpdateSeasonPeriodDto export class UpdateSeasonPeriodDto
extends BaseStatusDto extends BaseStatusDto
implements SeasonPeriodEntity { implements SeasonPeriodEntity
{
@ApiProperty({ @ApiProperty({
type: Object, type: Object,
required: true, required: true,

View File

@ -1,7 +1,7 @@
import { ApiProperty } from "@nestjs/swagger"; import { ApiProperty } from '@nestjs/swagger';
import { IsObject } from "class-validator"; import { IsObject } from 'class-validator';
import { ItemRateModel } from "src/modules/item-related/item-rate/data/models/item-rate.model"; import { ItemRateModel } from 'src/modules/item-related/item-rate/data/models/item-rate.model';
import { SeasonTypeModel } from "src/modules/season-related/season-type/data/models/season-type.model"; import { SeasonTypeModel } from 'src/modules/season-related/season-type/data/models/season-type.model';
export class UpdateSeasonPriceDto { export class UpdateSeasonPriceDto {
@ApiProperty({ @ApiProperty({

View File

@ -32,7 +32,10 @@ import { UpdateSeasonPeriodPriceManager } from './domain/usecases/managers/updat
@Module({ @Module({
imports: [ imports: [
ConfigModule.forRoot(), ConfigModule.forRoot(),
TypeOrmModule.forFeature([SeasonPeriodModel, ItemRateModel], CONNECTION_NAME.DEFAULT), TypeOrmModule.forFeature(
[SeasonPeriodModel, ItemRateModel],
CONNECTION_NAME.DEFAULT,
),
CqrsModule, CqrsModule,
], ],
controllers: [SeasonPeriodDataController, SeasonPeriodReadController], controllers: [SeasonPeriodDataController, SeasonPeriodReadController],

View File

@ -17,7 +17,10 @@ export class BatchDeleteTaxManager extends BaseBatchDeleteManager<TaxEntity> {
} }
async validateData(data: TaxEntity): Promise<void> { async validateData(data: TaxEntity): Promise<void> {
await validateUsedInFormula(this.dataServiceFirstOpt, data.name.toLowerCase()); await validateUsedInFormula(
this.dataServiceFirstOpt,
data.name.toLowerCase(),
);
return; return;
} }

View File

@ -12,11 +12,13 @@ import { validateUsedInFormula } from './helpers/validation.helper';
@Injectable() @Injectable()
export class BatchInactiveTaxManager extends BaseBatchUpdateStatusManager<TaxEntity> { export class BatchInactiveTaxManager extends BaseBatchUpdateStatusManager<TaxEntity> {
// dataServiceFirstOpt adalah formula service // dataServiceFirstOpt adalah formula service
async validateData(data: TaxEntity): Promise<void> { async validateData(data: TaxEntity): Promise<void> {
await validateUsedInFormula(this.dataServiceFirstOpt, data.name.toLowerCase()); await validateUsedInFormula(
this.dataServiceFirstOpt,
data.name.toLowerCase(),
);
return; return;
} }

View File

@ -16,7 +16,10 @@ export class DeleteTaxManager extends BaseDeleteManager<TaxEntity> {
} }
async validateProcess(): Promise<void> { async validateProcess(): Promise<void> {
await validateUsedInFormula(this.dataServiceFirstOpt, this.data.name.toLowerCase()); await validateUsedInFormula(
this.dataServiceFirstOpt,
this.data.name.toLowerCase(),
);
return; return;
} }

View File

@ -1,14 +1,16 @@
import { HttpStatus, UnprocessableEntityException } from "@nestjs/common"; import { HttpStatus, UnprocessableEntityException } from '@nestjs/common';
export async function validateUsedInFormula(formulaDataService, name) { export async function validateUsedInFormula(formulaDataService, name) {
const formulas = await formulaDataService.getManyByOptions(); const formulas = await formulaDataService.getManyByOptions();
formulas?.forEach(formula => { formulas?.forEach((formula) => {
const allWords = formula?.formula_string?.replace(/[^a-zA-Z0-9]/g, ' ').split(' '); const allWords = formula?.formula_string
if (allWords.find(item => item.toLowerCase() == name)) ?.replace(/[^a-zA-Z0-9]/g, ' ')
.split(' ');
if (allWords.find((item) => item.toLowerCase() == name))
throw new UnprocessableEntityException({ throw new UnprocessableEntityException({
statusCode: HttpStatus.UNPROCESSABLE_ENTITY, statusCode: HttpStatus.UNPROCESSABLE_ENTITY,
message: `Failed! tax ${name} already used in ${formula.type} formula`, message: `Failed! tax ${name} already used in ${formula.type} formula`,
error: 'Unprocessable Entity', error: 'Unprocessable Entity',
}) });
}); });
} }

View File

@ -16,7 +16,10 @@ export class InactiveTaxManager extends BaseUpdateStatusManager<TaxEntity> {
} }
async validateProcess(): Promise<void> { async validateProcess(): Promise<void> {
await validateUsedInFormula(this.dataServiceFirstOpt, this.data.name.toLowerCase()); await validateUsedInFormula(
this.dataServiceFirstOpt,
this.data.name.toLowerCase(),
);
return; return;
} }

View File

@ -52,14 +52,22 @@ export class TaxDataOrchestrator extends BaseDataTransactionOrchestrator<TaxEnti
async delete(dataId): Promise<String> { async delete(dataId): Promise<String> {
this.deleteManager.setData(dataId); this.deleteManager.setData(dataId);
this.deleteManager.setService(this.serviceData, TABLE_NAME.TAX, this.formulaServiceData); this.deleteManager.setService(
this.serviceData,
TABLE_NAME.TAX,
this.formulaServiceData,
);
await this.deleteManager.execute(); await this.deleteManager.execute();
return this.deleteManager.getResult(); return this.deleteManager.getResult();
} }
async batchDelete(dataIds: string[]): Promise<BatchResult> { async batchDelete(dataIds: string[]): Promise<BatchResult> {
this.batchDeleteManager.setData(dataIds); this.batchDeleteManager.setData(dataIds);
this.batchDeleteManager.setService(this.serviceData, TABLE_NAME.TAX, this.formulaServiceData); this.batchDeleteManager.setService(
this.serviceData,
TABLE_NAME.TAX,
this.formulaServiceData,
);
await this.batchDeleteManager.execute(); await this.batchDeleteManager.execute();
return this.batchDeleteManager.getResult(); return this.batchDeleteManager.getResult();
} }
@ -94,14 +102,22 @@ export class TaxDataOrchestrator extends BaseDataTransactionOrchestrator<TaxEnti
async inactive(dataId): Promise<String> { async inactive(dataId): Promise<String> {
this.inactiveManager.setData(dataId, STATUS.INACTIVE); this.inactiveManager.setData(dataId, STATUS.INACTIVE);
this.inactiveManager.setService(this.serviceData, TABLE_NAME.TAX, this.formulaServiceData); this.inactiveManager.setService(
this.serviceData,
TABLE_NAME.TAX,
this.formulaServiceData,
);
await this.inactiveManager.execute(); await this.inactiveManager.execute();
return this.inactiveManager.getResult(); return this.inactiveManager.getResult();
} }
async batchInactive(dataIds: string[]): Promise<BatchResult> { async batchInactive(dataIds: string[]): Promise<BatchResult> {
this.batchInactiveManager.setData(dataIds, STATUS.INACTIVE); this.batchInactiveManager.setData(dataIds, STATUS.INACTIVE);
this.batchInactiveManager.setService(this.serviceData, TABLE_NAME.TAX, this.formulaServiceData); this.batchInactiveManager.setService(
this.serviceData,
TABLE_NAME.TAX,
this.formulaServiceData,
);
await this.batchInactiveManager.execute(); await this.batchInactiveManager.execute();
return this.batchInactiveManager.getResult(); return this.batchInactiveManager.getResult();
} }

View File

@ -28,7 +28,10 @@ import { SalesPriceFormulaModel } from '../sales-price-formula/data/models/sales
@Module({ @Module({
imports: [ imports: [
ConfigModule.forRoot(), ConfigModule.forRoot(),
TypeOrmModule.forFeature([TaxModel, SalesPriceFormulaModel], CONNECTION_NAME.DEFAULT), TypeOrmModule.forFeature(
[TaxModel, SalesPriceFormulaModel],
CONNECTION_NAME.DEFAULT,
),
CqrsModule, CqrsModule,
], ],
controllers: [TaxDataController, TaxReadController], controllers: [TaxDataController, TaxReadController],

View File

@ -14,13 +14,17 @@ import { STATUS } from 'src/core/strings/constants/base.constants';
@Injectable() @Injectable()
export class BatchDeleteTenantManager extends BaseBatchDeleteManager<UserEntity> { export class BatchDeleteTenantManager extends BaseBatchDeleteManager<UserEntity> {
get validateRelations(): validateRelations[] { get validateRelations(): validateRelations[] {
return [{ return [
{
relation: 'items', relation: 'items',
query: (qb: SelectQueryBuilder<any>) => { query: (qb: SelectQueryBuilder<any>) => {
return qb.andWhere('total_items.status In (:...statuses)', { statuses: [STATUS.ACTIVE] }); return qb.andWhere('total_items.status In (:...statuses)', {
statuses: [STATUS.ACTIVE],
});
}, },
message: 'Failed! There is active item' message: 'Failed! There is active item',
}]; },
];
} }
async beforeProcess(): Promise<void> { async beforeProcess(): Promise<void> {

View File

@ -14,13 +14,17 @@ import { STATUS } from 'src/core/strings/constants/base.constants';
@Injectable() @Injectable()
export class BatchInactiveTenantManager extends BaseBatchUpdateStatusManager<UserEntity> { export class BatchInactiveTenantManager extends BaseBatchUpdateStatusManager<UserEntity> {
get validateRelations(): validateRelations[] { get validateRelations(): validateRelations[] {
return [{ return [
{
relation: 'items', relation: 'items',
query: (qb: SelectQueryBuilder<any>) => { query: (qb: SelectQueryBuilder<any>) => {
return qb.andWhere('total_items.status In (:...statuses)', { statuses: [STATUS.ACTIVE] }); return qb.andWhere('total_items.status In (:...statuses)', {
statuses: [STATUS.ACTIVE],
});
}, },
message: 'Failed! There is active item' message: 'Failed! There is active item',
}]; },
];
} }
validateData(data: UserEntity): Promise<void> { validateData(data: UserEntity): Promise<void> {

View File

@ -13,13 +13,17 @@ import { STATUS } from 'src/core/strings/constants/base.constants';
@Injectable() @Injectable()
export class DeleteTenantManager extends BaseDeleteManager<UserEntity> { export class DeleteTenantManager extends BaseDeleteManager<UserEntity> {
get validateRelations(): validateRelations[] { get validateRelations(): validateRelations[] {
return [{ return [
{
relation: 'items', relation: 'items',
query: (qb: SelectQueryBuilder<any>) => { query: (qb: SelectQueryBuilder<any>) => {
return qb.andWhere('total_items.status In (:...statuses)', { statuses: [STATUS.ACTIVE] }); return qb.andWhere('total_items.status In (:...statuses)', {
statuses: [STATUS.ACTIVE],
});
}, },
message: 'Failed! There is active item' message: 'Failed! There is active item',
}]; },
];
} }
getResult(): string { getResult(): string {

View File

@ -13,13 +13,17 @@ import { STATUS } from 'src/core/strings/constants/base.constants';
@Injectable() @Injectable()
export class InactiveTenantManager extends BaseUpdateStatusManager<UserEntity> { export class InactiveTenantManager extends BaseUpdateStatusManager<UserEntity> {
get validateRelations(): validateRelations[] { get validateRelations(): validateRelations[] {
return [{ return [
{
relation: 'items', relation: 'items',
query: (qb: SelectQueryBuilder<any>) => { query: (qb: SelectQueryBuilder<any>) => {
return qb.andWhere('total_items.status In (:...statuses)', { statuses: [STATUS.ACTIVE] }); return qb.andWhere('total_items.status In (:...statuses)', {
statuses: [STATUS.ACTIVE],
});
}, },
message: 'Failed! There is active item' message: 'Failed! There is active item',
}]; },
];
} }
getResult(): string { getResult(): string {