Merge remote-tracking branch 'origin/development' into feat/transaction

pull/6/head
Aswin Ashar Abdullah 2024-07-02 23:55:03 +07:00
commit 7bd66b47a4
75 changed files with 1025 additions and 896 deletions

View File

@ -23,12 +23,12 @@ export function setQueryFilterDefault(
// jika searching status terdapat dalam enum, maka dia mencari specific data // jika searching status terdapat dalam enum, maka dia mencari specific data
// ? karena jika tidak, ketika dia search "active" maka "inactive" juga ikut // ? karena jika tidak, ketika dia search "active" maka "inactive" juga ikut
if (STATUS[statusData.toUpperCase()]) if (STATUS[statusData.toUpperCase()])
qb.orWhere(`${ tableName }.status = :statusData`, { qb.orWhere(`${tableName}.status = :statusData`, {
statusData: statusData, statusData: statusData,
}); });
else else
qb['orWhere']( qb['orWhere'](
`${ tableName }.status::text ILIKE '%${ [statusData] }%'`, `${tableName}.status::text ILIKE '%${[statusData]}%'`,
); );
}); });
}), }),
@ -85,17 +85,20 @@ export function getOrderBy(
queryBuilder: SelectQueryBuilder<any>, queryBuilder: SelectQueryBuilder<any>,
tableName: TABLE_NAME, tableName: TABLE_NAME,
) { ) {
let orderBys: string[] = [`${ tableName }.created_at`]; let orderBys: string[] = [`${tableName}.created_at`];
const orderType = baseFilter.order_type ?? ORDER_TYPE.DESC; const orderType = baseFilter.order_type ?? ORDER_TYPE.DESC;
if (!!baseFilter.order_by) { if (!!baseFilter.order_by) {
orderBys = orderBys =
baseFilter.order_by.split('.').length > 1 baseFilter.order_by.split('.').length > 1
? [`${ 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

@ -9,7 +9,7 @@ export class ValidateRelationHelper<Entity> {
private dataService: BaseDataService<Entity>, private dataService: BaseDataService<Entity>,
private relations: validateRelations[], private relations: validateRelations[],
private tableName: string, private tableName: string,
) { } ) {}
async execute() { async execute() {
const repository = this.dataService.getRepository(); const repository = this.dataService.getRepository();
@ -19,30 +19,28 @@ export class ValidateRelationHelper<Entity> {
for (const relation of this.relations) { for (const relation of this.relations) {
if (relation.singleQuery) { if (relation.singleQuery) {
queryBuilder.leftJoinAndMapOne( queryBuilder.leftJoinAndMapOne(
`${ 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}`,
`total_${ relation.relation }`, `total_${relation.relation}`,
); );
} }
} }
// filtering data only with specific data // filtering data only with specific data
queryBuilder.where(`${ this.tableName }.id in ('${ this.dataId }')`); queryBuilder.where(`${this.tableName}.id in ('${this.dataId}')`);
// get data // get data
const data = await queryBuilder.getOne(); const data = await queryBuilder.getOne();
@ -51,13 +49,21 @@ export class ValidateRelationHelper<Entity> {
for (const relation of this.relations) { for (const relation of this.relations) {
const message = const message =
relation.message ?? relation.message ??
`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);
} }
} }
@ -74,4 +80,4 @@ export class ValidateRelationHelper<Entity> {
return column == value; return column == value;
} }
} }
} }

View File

@ -6,7 +6,7 @@ import {
} from 'typeorm'; } from 'typeorm';
export abstract class BaseDataService<Entity> { export abstract class BaseDataService<Entity> {
constructor(private repository: Repository<Entity>) { } constructor(private repository: Repository<Entity>) {}
getRepository(): Repository<Entity> { getRepository(): Repository<Entity> {
return this.repository; return this.repository;
@ -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

@ -38,7 +38,7 @@ export abstract class BaseBatchDeleteManager<Entity> extends BaseManager {
if (!entity) { if (!entity) {
throw new NotFoundException({ throw new NotFoundException({
statusCode: HttpStatus.NOT_FOUND, statusCode: HttpStatus.NOT_FOUND,
message: `Failed! Entity with id ${ id } not found`, message: `Failed! Entity with id ${id} not found`,
error: 'Entity Not Found', error: 'Entity Not Found',
}); });
} }
@ -51,13 +51,13 @@ export abstract class BaseBatchDeleteManager<Entity> extends BaseManager {
this.tableName, this.tableName,
).execute(); ).execute();
const result = await this.dataService.deleteById( await this.dataService.deleteById(
this.queryRunner, this.queryRunner,
this.entityTarget, this.entityTarget,
id, id,
); );
this.publishEvents(entity, result); this.publishEvents(entity, entity);
totalSuccess = totalSuccess + 1; totalSuccess = totalSuccess + 1;
} catch (error) { } catch (error) {
totalFailed = totalFailed + 1; totalFailed = totalFailed + 1;
@ -83,7 +83,7 @@ export abstract class BaseBatchDeleteManager<Entity> extends BaseManager {
old: dataOld, old: dataOld,
data: dataNew, data: dataNew,
user: this.user, user: this.user,
description: `${ this.user.name } delete batch data ${ this.tableName }`, description: `${this.user.name} delete batch data ${this.tableName}`,
module: this.tableName, module: this.tableName,
op: OPERATION.DELETE, op: OPERATION.DELETE,
}), }),

View File

@ -23,7 +23,7 @@ export abstract class BaseDeleteManager<Entity> extends BaseManager {
if (!this.data) if (!this.data)
throw new UnprocessableEntityException({ throw new UnprocessableEntityException({
statusCode: HttpStatus.UNPROCESSABLE_ENTITY, statusCode: HttpStatus.UNPROCESSABLE_ENTITY,
message: `Data with id ${ this.dataId } not found`, message: `Data with id ${this.dataId} not found`,
error: 'Unprocessable Entity', error: 'Unprocessable Entity',
}); });
@ -52,11 +52,11 @@ export abstract class BaseDeleteManager<Entity> extends BaseManager {
async publishEvents() { async publishEvents() {
this.eventBus.publish( this.eventBus.publish(
new RecordLog({ new RecordLog({
id: this.result['id'], id: this.data['id'],
old: null, old: null,
data: this.result, data: this.data,
user: this.user, user: this.user,
description: `${ this.user.name } delete data ${ this.tableName }`, description: `${this.user.name} delete data ${this.tableName}`,
module: this.tableName, module: this.tableName,
op: OPERATION.CREATE, op: OPERATION.CREATE,
}), }),

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, {
@ -60,7 +60,7 @@ export abstract class BaseUpdateStatusManager<Entity> extends BaseManager {
old: this.oldData, old: this.oldData,
data: this.result, data: this.result,
user: this.user, user: this.user,
description: `${ this.user.name } update status data ${ this.tableName } to ${ this.dataStatus }`, description: `${this.user.name} update status data ${this.tableName} to ${this.dataStatus}`,
module: this.tableName, module: this.tableName,
op: OPERATION.UPDATE, op: OPERATION.UPDATE,
}), }),
@ -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

@ -45,7 +45,7 @@ export abstract class BaseUpdateManager<Entity> extends BaseManager {
if (!this.oldData) { if (!this.oldData) {
throw new NotFoundException({ throw new NotFoundException({
statusCode: HttpStatus.NOT_FOUND, statusCode: HttpStatus.NOT_FOUND,
message: `Failed! Entity with id ${ this.dataId } not found`, message: `Failed! Entity with id ${this.dataId} not found`,
error: 'Entity Not Found', error: 'Entity Not Found',
}); });
} }
@ -82,7 +82,7 @@ export abstract class BaseUpdateManager<Entity> extends BaseManager {
old: this.oldData, old: this.oldData,
data: this.result, data: this.result,
user: this.user, user: this.user,
description: `${ this.user.name } update data ${ this.tableName }`, description: `${this.user.name} update data ${this.tableName}`,
module: this.tableName, module: this.tableName,
op: OPERATION.UPDATE, op: OPERATION.UPDATE,
}), }),
@ -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

@ -13,7 +13,7 @@ import { createPaginationResponse } from './utils/pagination-meta.helper';
@Injectable() @Injectable()
export class TransformInterceptor implements NestInterceptor { export class TransformInterceptor implements NestInterceptor {
constructor(protected readonly reflector: Reflector) { } constructor(protected readonly reflector: Reflector) {}
intercept(context: ExecutionContext, next: CallHandler): Observable<any> { intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
const isPagination = this.reflector.getAllAndOverride<boolean>( const isPagination = this.reflector.getAllAndOverride<boolean>(
PAGINATION_RESPONSE, PAGINATION_RESPONSE,

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,
@ -24,4 +30,4 @@ import { SeasonPeriodDeletedHandler, SeasonPeriodUpdatedHandler } from './domain
CouchService, CouchService,
], ],
}) })
export class CouchModule { } export class CouchModule {}

View File

@ -5,7 +5,7 @@ import { ChangeDocEvent } from '../../domain/events/change-doc.event';
@Injectable() @Injectable()
export class CouchService { export class CouchService {
constructor(private eventBus: EventBus) { } constructor(private eventBus: EventBus) {}
async onModuleInit() { async onModuleInit() {
const nano = require('nano')('http://root:password@172.10.10.2:5970'); const nano = require('nano')('http://root:password@172.10.10.2:5970');
@ -15,7 +15,7 @@ export class CouchService {
this.changeDoc(change, database); this.changeDoc(change, database);
}); });
console.log(`start listen database ${ database }`); console.log(`start listen database ${database}`);
} }
} }
@ -30,26 +30,32 @@ export class CouchService {
} }
public async createDoc(data, database) { public async createDoc(data, database) {
const nano = require('nano')('http://root:password@172.10.10.2:5970'); try {
const db = nano.use(database); const nano = require('nano')('http://root:password@172.10.10.2:5970');
return await db.insert(data); const db = nano.use(database);
return await db.insert(data);
} catch (error) {}
} }
public async deleteDoc(data, database) { public async deleteDoc(data, database) {
const nano = require('nano')('http://root:password@172.10.10.2:5970'); try {
const db = nano.use(database); const nano = require('nano')('http://root:password@172.10.10.2:5970');
const result = await db.get(data.id) const db = nano.use(database);
await db.destroy(data.id, result._rev); const result = await db.get(data.id);
await db.destroy(data.id, result._rev);
} catch (error) {}
} }
public async updateDoc(data, database) { public async updateDoc(data, database) {
const nano = require('nano')('http://root:password@172.10.10.2:5970'); try {
const db = nano.use(database); const nano = require('nano')('http://root:password@172.10.10.2:5970');
const result = await db.get(data.id) const db = nano.use(database);
console.log(result, 'dsa') const result = await db.get(data.id);
await db.insert({ console.log(result, 'dsa');
...data, await db.insert({
_rev: result._rev ...data,
}); _rev: result._rev,
});
} catch (error) {}
} }
} }

View File

@ -1,81 +1,81 @@
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, {
...event.data.data _id: event.data.id,
}, 'item'); ...event.data.data,
} },
'item',
);
}
} }
@EventsHandler(ItemChangeStatusEvent, ItemUpdatedEvent) @EventsHandler(ItemChangeStatusEvent, ItemUpdatedEvent)
export class ItemUpdatedHandler implements IEventHandler<ItemChangeStatusEvent> { export class ItemUpdatedHandler
constructor( implements IEventHandler<ItemChangeStatusEvent>
private couchService: CouchService, {
private itemService: ItemDataService, constructor(
) { } private couchService: CouchService,
private itemService: ItemDataService,
) {}
async handle(event: ItemChangeStatusEvent) { async handle(event: ItemChangeStatusEvent) {
const dataOld = event.data.old;
const data = event.data.data;
const dataItem = await this.itemService.getOneByOptions({
where: {
id: data.id,
},
relations: [
'item_category',
'bundling_items',
'bundling_items.item_category',
'item_rates',
'item_rates.item',
'item_rates.season_period',
'item_rates.season_period.season_type',
],
});
const dataOld = event.data.old; // change status to active
const data = event.data.data; if (dataOld?.status != data.status && data.status == STATUS.ACTIVE) {
const dataItem = await this.itemService.getOneByOptions({ await this.couchService.createDoc(
where: { {
id: data.id _id: data.id,
}, ...dataItem,
relations: [ },
'item_category', 'item',
'bundling_items', );
'bundling_items.item_category', } else if (dataOld?.status != data.status) {
'item_rates', await this.couchService.deleteDoc(
'item_rates.item', {
'item_rates.season_period', _id: data.id,
'item_rates.season_period.season_type', ...dataItem,
] },
}) 'item',
);
// change status to active
if (dataOld?.status != data.status && data.status == STATUS.ACTIVE) {
await this.couchService.createDoc(
{
_id: data.id,
...dataItem
},
'item'
);
}
else if (dataOld?.status != data.status) {
await this.couchService.deleteDoc(
{
_id: data.id,
...dataItem
},
'item'
);
}
// update
else {
await this.couchService.updateDoc(
{
_id: data.id,
...dataItem
},
'item'
);
}
} }
// update
else {
await this.couchService.updateDoc(
{
_id: data.id,
...dataItem,
},
'item',
);
}
}
} }

View File

@ -1,65 +1,65 @@
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, {
...event.data.data _id: event.data.id,
}, 'payment_method'); ...event.data.data,
} },
'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 data = event.data.data;
const dataOld = event.data.old; // change status to active
const data = event.data.data; if (dataOld?.status != data.status && data.status == STATUS.ACTIVE) {
await this.couchService.createDoc(
// change status to active {
if (dataOld?.status != data.status && data.status == STATUS.ACTIVE) { _id: data.id,
await this.couchService.createDoc( ...data,
{ },
_id: data.id, 'payment_method',
...data );
}, } else if (dataOld?.status != data.status) {
'payment_method' await this.couchService.deleteDoc(
); {
} _id: data.id,
...data,
else if (dataOld?.status != data.status) { },
await this.couchService.deleteDoc( 'payment_method',
{ );
_id: data.id,
...data
},
'payment_method'
);
}
// update
else {
await this.couchService.updateDoc(
{
_id: data.id,
...data
},
'payment_method'
);
}
} }
// update
else {
await this.couchService.updateDoc(
{
_id: data.id,
...data,
},
'payment_method',
);
}
}
} }

View File

@ -1,65 +1,65 @@
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, {
...event.data.data _id: event.data.id,
}, 'season_period'); ...event.data.data,
} },
'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 data = event.data.data;
const dataOld = event.data.old; // change status to active
const data = event.data.data; if (dataOld?.status != data.status && data.status == STATUS.ACTIVE) {
await this.couchService.createDoc(
// change status to active {
if (dataOld?.status != data.status && data.status == STATUS.ACTIVE) { _id: data.id,
await this.couchService.createDoc( ...data,
{ },
_id: data.id, 'season_period',
...data );
}, } else if (dataOld?.status != data.status) {
'season_period' await this.couchService.deleteDoc(
); {
} _id: data.id,
...data,
else if (dataOld?.status != data.status) { },
await this.couchService.deleteDoc( 'season_period',
{ );
_id: data.id,
...data
},
'season_period'
);
}
// update
else {
await this.couchService.updateDoc(
{
_id: data.id,
...data
},
'season_period'
);
}
} }
// update
else {
await this.couchService.updateDoc(
{
_id: data.id,
...data,
},
'season_period',
);
}
}
} }

View File

@ -1,82 +1,88 @@
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, {
...event.data.data _id: event.data.id,
}, 'user'); ...event.data.data,
} },
'user',
);
}
} }
@EventsHandler(UserChangeStatusEvent, UserUpdatedEvent) @EventsHandler(UserChangeStatusEvent, UserUpdatedEvent)
export class UserUpdatedHandler implements IEventHandler<UserChangeStatusEvent> { export class UserUpdatedHandler
constructor( implements IEventHandler<UserChangeStatusEvent>
private couchService: CouchService, {
private userService: UserDataService, constructor(
) { } private couchService: CouchService,
private userService: UserDataService,
) {}
async handle(event: UserChangeStatusEvent) { async handle(event: UserChangeStatusEvent) {
const dataOld = event.data.old;
const data = event.data.data;
const user = await this.userService
.getOneByOptions({
where: {
id: data.id,
},
relations: [
'user_privilege',
'user_privilege.user_privilege_configurations',
],
})
.then((item) => {
const user_privilege_configurations = item[
'user_privilege'
]?.user_privilege_configurations?.filter(
(config) => config.module == 'POS',
);
Object.assign(item['user_privilege'], {
user_privilege_configurations: user_privilege_configurations,
});
return item;
});
const dataOld = event.data.old; // change status to active
const data = event.data.data; if (dataOld?.status != data.status && data.status == STATUS.ACTIVE) {
const user = await this.userService.getOneByOptions({ await this.couchService.createDoc(
where: { {
id: data.id _id: data.id,
}, ...user,
relations: [ },
'user_privilege', 'user',
'user_privilege.user_privilege_configurations' );
] } else if (dataOld?.status != data.status) {
}).then(item => { await this.couchService.deleteDoc(
const user_privilege_configurations = item['user_privilege']?.user_privilege_configurations?.filter(config => config.module == "POS") {
Object.assign(item['user_privilege'], { _id: data.id,
user_privilege_configurations: user_privilege_configurations ...user,
}) },
return item 'user',
}) );
// change status to active
if (dataOld?.status != data.status && data.status == STATUS.ACTIVE) {
await this.couchService.createDoc(
{
_id: data.id,
...user
},
'user'
);
}
else if (dataOld?.status != data.status) {
await this.couchService.deleteDoc(
{
_id: data.id,
...user
},
'user'
);
}
// update
else {
await this.couchService.updateDoc(
{
_id: data.id,
...user
},
'user'
);
}
} }
// update
else {
await this.couchService.updateDoc(
{
_id: data.id,
...user,
},
'user',
);
}
}
} }

View File

@ -1,65 +1,65 @@
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, {
...event.data.data _id: event.data.id,
}, 'vip_category'); ...event.data.data,
} },
'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 data = event.data.data;
const dataOld = event.data.old; // change status to active
const data = event.data.data; if (dataOld?.status != data.status && data.status == STATUS.ACTIVE) {
await this.couchService.createDoc(
// change status to active {
if (dataOld?.status != data.status && data.status == STATUS.ACTIVE) { _id: data.id,
await this.couchService.createDoc( ...data,
{ },
_id: data.id, 'vip_category',
...data );
}, } else if (dataOld?.status != data.status) {
'vip_category' await this.couchService.deleteDoc(
); {
} _id: data.id,
...data,
else if (dataOld?.status != data.status) { },
await this.couchService.deleteDoc( 'vip_category',
{ );
_id: data.id,
...data
},
'vip_category'
);
}
// update
else {
await this.couchService.updateDoc(
{
_id: data.id,
...data
},
'vip_category'
);
}
} }
// update
else {
await this.couchService.updateDoc(
{
_id: data.id,
...data,
},
'vip_category',
);
}
}
} }

View File

@ -1,4 +1,4 @@
export interface FilterGoogleCalendarEntity { export interface FilterGoogleCalendarEntity {
start_date: Date; start_date: Date;
end_date: Date; end_date: Date;
} }

View File

@ -3,7 +3,7 @@ import { IndexHolidayCalendarManager } from './managers/index-holiday-google-cal
@Injectable() @Injectable()
export class GoogleCalendarOrchestrator { export class GoogleCalendarOrchestrator {
constructor(private indexHoliday: IndexHolidayCalendarManager) { } constructor(private indexHoliday: IndexHolidayCalendarManager) {}
async holiday(params) { async holiday(params) {
return await this.indexHoliday.execute(params); return await this.indexHoliday.execute(params);

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

@ -1,8 +1,8 @@
import { BaseFilterEntity } from 'src/core/modules/domain/entities/base-filter.entity'; import { BaseFilterEntity } from 'src/core/modules/domain/entities/base-filter.entity';
export interface FilterItemRateEntity extends BaseFilterEntity { export interface FilterItemRateEntity extends BaseFilterEntity {
item_ids: string[]; item_ids: string[];
season_period_ids: string[]; season_period_ids: string[];
start_date: Date; start_date: Date;
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)
@ -65,10 +69,10 @@ export class IndexItemRateManager extends BaseIndexManager<ItemEntity> {
get selects(): string[] { get selects(): string[] {
return [ return [
`${ this.tableName }.id`, `${this.tableName}.id`,
`${ this.tableName }.created_at`, `${this.tableName}.created_at`,
`${ this.tableName }.name`, `${this.tableName}.name`,
`${ this.tableName }.base_price`, `${this.tableName}.base_price`,
'tenant.id', 'tenant.id',
'tenant.name', 'tenant.name',
@ -92,15 +96,15 @@ export class IndexItemRateManager extends BaseIndexManager<ItemEntity> {
get specificFilter(): Param[] { get specificFilter(): Param[] {
return [ return [
{ {
cols: `${ this.tableName }.name`, cols: `${this.tableName}.name`,
data: this.filterParam.names, data: this.filterParam.names,
}, },
{ {
cols: `${ this.tableName }.item_type::text`, cols: `${this.tableName}.item_type::text`,
data: this.filterParam.item_types, data: this.filterParam.item_types,
}, },
{ {
cols: `${ this.tableName }.limit_type::text`, cols: `${this.tableName}.limit_type::text`,
data: this.filterParam.limit_types, data: this.filterParam.limit_types,
}, },
{ {
@ -114,11 +118,11 @@ export class IndexItemRateManager extends BaseIndexManager<ItemEntity> {
queryBuilder: SelectQueryBuilder<ItemEntity>, queryBuilder: SelectQueryBuilder<ItemEntity>,
): SelectQueryBuilder<ItemEntity> { ): SelectQueryBuilder<ItemEntity> {
if (this.filterParam.tenant_ids?.length) { if (this.filterParam.tenant_ids?.length) {
queryBuilder.andWhere(`${ this.tableName }.tenant_id In (:...tenantIds)`, { queryBuilder.andWhere(`${this.tableName}.tenant_id In (:...tenantIds)`, {
tenantIds: this.filterParam.tenant_ids, tenantIds: this.filterParam.tenant_ids,
}); });
} else if (!this.filterParam.all_item) { } else if (!this.filterParam.all_item) {
queryBuilder.andWhere(`${ this.tableName }.tenant_id Is Null`); queryBuilder.andWhere(`${this.tableName}.tenant_id Is Null`);
} }
return queryBuilder; return queryBuilder;

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

@ -4,15 +4,15 @@ import { ApiProperty } from '@nestjs/swagger';
import { Exclude } from 'class-transformer'; import { Exclude } from 'class-transformer';
export class UpdateItemRateDto extends BaseCoreDto implements ItemRateEntity { export class UpdateItemRateDto extends BaseCoreDto implements ItemRateEntity {
@Exclude() @Exclude()
item_id: string; item_id: string;
@Exclude() @Exclude()
season_period_id: string; season_period_id: string;
@ApiProperty({ @ApiProperty({
type: Number, type: Number,
required: true, required: true,
}) })
price: number; price: number;
} }

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 {
@ -12,7 +16,7 @@ import { STATUS } from 'src/core/strings/constants/base.constants';
@Injectable() @Injectable()
export class ActiveItemManager extends BaseUpdateStatusManager<ItemEntity> { export class ActiveItemManager extends BaseUpdateStatusManager<ItemEntity> {
getResult(): string { getResult(): string {
return `Success active data ${ this.result.name }`; return `Success active data ${this.result.name}`;
} }
async validateProcess(): Promise<void> { async validateProcess(): Promise<void> {
@ -28,11 +32,13 @@ export class ActiveItemManager extends BaseUpdateStatusManager<ItemEntity> {
} }
get validateRelations(): validateRelations[] { get validateRelations(): validateRelations[] {
return [{ return [
relation: 'tenant', {
singleQuery: ['status', '!=', STATUS.ACTIVE], relation: 'tenant',
message: `Failed! Tenant of item must be active first`, singleQuery: ['status', '!=', STATUS.ACTIVE],
}]; 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', {
singleQuery: ['status', '!=', STATUS.ACTIVE], relation: 'tenant',
message: `Failed! Tenant of item must be active first`, singleQuery: ['status', '!=', STATUS.ACTIVE],
}]; 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', {
singleQuery: ['status', '!=', STATUS.ACTIVE], relation: 'tenant',
message: `Failed! Tenant of item must be active first`, singleQuery: ['status', '!=', STATUS.ACTIVE],
}]; message: `Failed! Tenant of item must be active first`,
},
];
} }
get entityTarget(): any { get entityTarget(): any {

View File

@ -12,7 +12,7 @@ import { STATUS } from 'src/core/strings/constants/base.constants';
@Injectable() @Injectable()
export class ConfirmItemManager extends BaseUpdateStatusManager<ItemEntity> { export class ConfirmItemManager extends BaseUpdateStatusManager<ItemEntity> {
getResult(): string { getResult(): string {
return `Success active data ${ this.result.name }`; return `Success active data ${this.result.name}`;
} }
async validateProcess(): Promise<void> { async validateProcess(): Promise<void> {
@ -28,11 +28,13 @@ export class ConfirmItemManager extends BaseUpdateStatusManager<ItemEntity> {
} }
get validateRelations(): validateRelations[] { get validateRelations(): validateRelations[] {
return [{ return [
relation: 'tenant', {
singleQuery: ['status', '!=', STATUS.ACTIVE], relation: 'tenant',
message: `Failed! Tenant of item must be active first`, singleQuery: ['status', '!=', STATUS.ACTIVE],
}]; 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: [],
@ -36,19 +32,19 @@ export class DetailItemManager extends BaseDetailManager<ItemEntity> {
get selects(): string[] { get selects(): string[] {
return [ return [
`${ this.tableName }.id`, `${this.tableName}.id`,
`${ this.tableName }.created_at`, `${this.tableName}.created_at`,
`${ this.tableName }.status`, `${this.tableName}.status`,
`${ this.tableName }.item_type`, `${this.tableName}.item_type`,
`${ this.tableName }.name`, `${this.tableName}.name`,
`${ this.tableName }.limit_type`, `${this.tableName}.limit_type`,
`${ this.tableName }.limit_value`, `${this.tableName}.limit_value`,
`${ this.tableName }.hpp`, `${this.tableName}.hpp`,
`${ this.tableName }.sales_margin`, `${this.tableName}.sales_margin`,
`${ this.tableName }.total_price`, `${this.tableName}.total_price`,
`${ this.tableName }.base_price`, `${this.tableName}.base_price`,
`${ this.tableName }.use_queue`, `${this.tableName}.use_queue`,
`${ this.tableName }.show_to_booking`, `${this.tableName}.show_to_booking`,
`item_category.id`, `item_category.id`,
`item_category.name`, `item_category.name`,
@ -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

@ -2,73 +2,72 @@ import { Injectable } from '@nestjs/common';
import { BaseIndexManager } from 'src/core/modules/domain/usecase/managers/base-index.manager'; import { BaseIndexManager } from 'src/core/modules/domain/usecase/managers/base-index.manager';
import { SelectQueryBuilder } from 'typeorm'; import { SelectQueryBuilder } from 'typeorm';
import { import {
Param, Param,
RelationParam, RelationParam,
} from 'src/core/modules/domain/entities/base-filter.entity'; } from 'src/core/modules/domain/entities/base-filter.entity';
import { ItemRateEntity } from 'src/modules/item-related/item-rate/domain/entities/item-rate.entity'; import { ItemRateEntity } from 'src/modules/item-related/item-rate/domain/entities/item-rate.entity';
@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;
} }
async beforeProcess(): Promise<void> { async beforeProcess(): Promise<void> {
return; return;
} }
async afterProcess(): Promise<void> { async afterProcess(): Promise<void> {
return; return;
} }
get relations(): RelationParam { get relations(): RelationParam {
return { return {
// relation only join (for query purpose) // relation only join (for query purpose)
joinRelations: [], joinRelations: [],
// relation join and select (relasi yang ingin ditampilkan), // relation join and select (relasi yang ingin ditampilkan),
selectRelations: ['season_period', 'season_period.season_type'], selectRelations: ['season_period', 'season_period.season_type'],
// relation yang hanya ingin dihitung (akan return number) // relation yang hanya ingin dihitung (akan return number)
countRelations: [], countRelations: [],
}; };
} }
get selects(): string[] { get selects(): string[] {
return [ return [
`${ this.tableName }.id`, `${this.tableName}.id`,
`${ this.tableName }.price`, `${this.tableName}.price`,
`season_period.id`, `season_period.id`,
`season_period.created_at`, `season_period.created_at`,
`season_period.creator_name`, `season_period.creator_name`,
`season_period.editor_name`, `season_period.editor_name`,
`season_period.updated_at`, `season_period.updated_at`,
`season_period.status`, `season_period.status`,
`season_period.start_date`, `season_period.start_date`,
`season_period.end_date`, `season_period.end_date`,
`season_period.days`, `season_period.days`,
`season_period.holiday_name`, `season_period.holiday_name`,
'season_type.id', 'season_type.id',
'season_type.name', 'season_type.name',
]; ];
} }
get specificFilter(): Param[] { get specificFilter(): Param[] {
return []; return [];
} }
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: [],
@ -40,15 +36,15 @@ export class IndexItemManager extends BaseIndexManager<ItemEntity> {
get selects(): string[] { get selects(): string[] {
return [ return [
`${ this.tableName }.id`, `${this.tableName}.id`,
`${ this.tableName }.created_at`, `${this.tableName}.created_at`,
`${ this.tableName }.status`, `${this.tableName}.status`,
`${ this.tableName }.item_type`, `${this.tableName}.item_type`,
`${ this.tableName }.name`, `${this.tableName}.name`,
`${ this.tableName }.hpp`, `${this.tableName}.hpp`,
`${ this.tableName }.limit_type`, `${this.tableName}.limit_type`,
`${ this.tableName }.limit_value`, `${this.tableName}.limit_value`,
`${ this.tableName }.base_price`, `${this.tableName}.base_price`,
`item_category.id`, `item_category.id`,
`item_category.name`, `item_category.name`,
@ -57,22 +53,22 @@ export class IndexItemManager extends BaseIndexManager<ItemEntity> {
'bundling_items.name', 'bundling_items.name',
'tenant.id', 'tenant.id',
'tenant.name' 'tenant.name',
]; ];
} }
get specificFilter(): Param[] { get specificFilter(): Param[] {
return [ return [
{ {
cols: `${ this.tableName }.name`, cols: `${this.tableName}.name`,
data: this.filterParam.names, data: this.filterParam.names,
}, },
{ {
cols: `${ this.tableName }.item_type::text`, cols: `${this.tableName}.item_type::text`,
data: this.filterParam.item_types, data: this.filterParam.item_types,
}, },
{ {
cols: `${ this.tableName }.limit_type::text`, cols: `${this.tableName}.limit_type::text`,
data: this.filterParam.limit_types, data: this.filterParam.limit_types,
}, },
{ {
@ -86,11 +82,11 @@ export class IndexItemManager extends BaseIndexManager<ItemEntity> {
queryBuilder: SelectQueryBuilder<ItemEntity>, queryBuilder: SelectQueryBuilder<ItemEntity>,
): SelectQueryBuilder<ItemEntity> { ): SelectQueryBuilder<ItemEntity> {
if (this.filterParam.tenant_ids?.length) { if (this.filterParam.tenant_ids?.length) {
queryBuilder.andWhere(`${ this.tableName }.tenant_id In (:...tenantIds)`, { queryBuilder.andWhere(`${this.tableName}.tenant_id In (:...tenantIds)`, {
tenantIds: this.filterParam.tenant_ids, tenantIds: this.filterParam.tenant_ids,
}); });
} else if (!this.filterParam.all_item) { } else if (!this.filterParam.all_item) {
queryBuilder.andWhere(`${ this.tableName }.tenant_id Is Null`); queryBuilder.andWhere(`${this.tableName}.tenant_id Is Null`);
} }
return queryBuilder; return queryBuilder;

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],
@ -79,4 +82,4 @@ import { IndexItemRatesManager } from './domain/usecases/managers/index-item-rat
ItemReadOrchestrator, ItemReadOrchestrator,
], ],
}) })
export class ItemModule { } export class ItemModule {}

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,5 +1,5 @@
import { IEvent } from 'src/core/strings/constants/interface.constants'; import { IEvent } from 'src/core/strings/constants/interface.constants';
export class SeasonPeriodPriceUpdatedEvent { export class SeasonPeriodPriceUpdatedEvent {
constructor(public readonly data: IEvent) { } constructor(public readonly data: IEvent) {}
} }

View File

@ -7,7 +7,7 @@ import { SeasonPeriodModel } from '../../../data/models/season-period.model';
export class SeasonPeriodHolidayHandler export class SeasonPeriodHolidayHandler
implements IEventHandler<SeasonPeriodCreatedEvent> implements IEventHandler<SeasonPeriodCreatedEvent>
{ {
constructor(private dataService: SeasonPeriodDataService) { } constructor(private dataService: SeasonPeriodDataService) {}
async handle(event: SeasonPeriodCreatedEvent) { async handle(event: SeasonPeriodCreatedEvent) {
const queryRunner = this.dataService const queryRunner = this.dataService

View File

@ -1,62 +1,56 @@
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(
private readService: SeasonPeriodReadService,
private dataService: SeasonPeriodDataService,
private rateDataService: ItemRateDataService,
) {}
constructor( async handle(event: SeasonPeriodPriceUpdatedEvent) {
private readService: SeasonPeriodReadService, const datas = await this.readService
private dataService: SeasonPeriodDataService, .getManyByOptions({
private rateDataService: ItemRateDataService, where: {
) { } season_type_id: event.data.data.season_period?.id,
},
})
.then((data) => {
return data.map((item) => {
return {
...item,
item_rates: event.data.data.item_rates,
};
});
});
async handle(event: SeasonPeriodPriceUpdatedEvent) { const queryRunner = this.dataService
const datas = await this.readService.getManyByOptions({ .getRepository()
where: { .manager.connection.createQueryRunner();
season_type_id: event.data.data.season_period?.id
}
}).then(data => {
return data.map(item => {
return {
...item,
item_rates: event.data.data.item_rates,
}
})
})
const queryRunner = this.dataService await this.dataService.createBatch(queryRunner, SeasonPeriodModel, datas);
.getRepository()
.manager.connection.createQueryRunner();
await this.dataService.createBatch( await this.deleteUnusedItem();
queryRunner, }
SeasonPeriodModel,
datas
)
await this.deleteUnusedItem() async deleteUnusedItem() {
} const queryRunnerItem = this.rateDataService
.getRepository()
.manager.connection.createQueryRunner();
async deleteUnusedItem() { await this.rateDataService.deleteByOptions(queryRunnerItem, ItemRateModel, {
const queryRunnerItem = this.rateDataService where: {
.getRepository() season_period_id: IsNull(),
.manager.connection.createQueryRunner(); },
});
await this.rateDataService.deleteByOptions( }
queryRunnerItem, }
ItemRateModel,
{
where: {
season_period_id: IsNull()
}
}
)
}
}

View File

@ -11,7 +11,7 @@ import { SeasonPeriodChangeStatusEvent } from '../../entities/event/season-perio
@Injectable() @Injectable()
export class ActiveSeasonPeriodManager extends BaseUpdateStatusManager<SeasonPeriodEntity> { export class ActiveSeasonPeriodManager extends BaseUpdateStatusManager<SeasonPeriodEntity> {
getResult(): string { getResult(): string {
return `Success active data ${ this.result.id }`; return `Success active data ${this.result.id}`;
} }
async validateProcess(): Promise<void> { async validateProcess(): Promise<void> {
@ -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

@ -11,7 +11,7 @@ import { SeasonPeriodChangeStatusEvent } from '../../entities/event/season-perio
@Injectable() @Injectable()
export class ConfirmSeasonPeriodManager extends BaseUpdateStatusManager<SeasonPeriodEntity> { export class ConfirmSeasonPeriodManager extends BaseUpdateStatusManager<SeasonPeriodEntity> {
getResult(): string { getResult(): string {
return `Success active data ${ this.result.id }`; return `Success active data ${this.result.id}`;
} }
async validateProcess(): Promise<void> { async validateProcess(): Promise<void> {
@ -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,43 +20,68 @@ 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 });
} }
const 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;
}) }),
) )
.getCount(); .getMany();
if (datas > 0) { 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({ throw new UnprocessableEntityException({
statusCode: HttpStatus.UNPROCESSABLE_ENTITY, statusCode: HttpStatus.UNPROCESSABLE_ENTITY,
message: `Failed! there is another season period in same range date`, message: `Failed! there is another season period in same range date`,
@ -65,4 +90,4 @@ export async function ValidateSeasonPeriodHelper(dataService, data) {
} }
return priority; return priority;
} }

View File

@ -11,7 +11,7 @@ import { SeasonPeriodChangeStatusEvent } from '../../entities/event/season-perio
@Injectable() @Injectable()
export class InactiveSeasonPeriodManager extends BaseUpdateStatusManager<SeasonPeriodEntity> { export class InactiveSeasonPeriodManager extends BaseUpdateStatusManager<SeasonPeriodEntity> {
getResult(): string { getResult(): string {
return `Success inactive data ${ this.result.id }`; return `Success inactive data ${this.result.id}`;
} }
async validateProcess(): Promise<void> { async validateProcess(): Promise<void> {
@ -38,9 +38,7 @@ export class InactiveSeasonPeriodManager extends BaseUpdateStatusManager<SeasonP
return [ return [
{ {
topic: SeasonPeriodChangeStatusEvent, topic: SeasonPeriodChangeStatusEvent,
relations: [ relations: ['season_type'],
'season_type'
]
}, },
]; ];
} }

View File

@ -2,81 +2,83 @@ import { Injectable } from '@nestjs/common';
import { BaseIndexManager } from 'src/core/modules/domain/usecase/managers/base-index.manager'; import { BaseIndexManager } from 'src/core/modules/domain/usecase/managers/base-index.manager';
import { SelectQueryBuilder } from 'typeorm'; import { SelectQueryBuilder } from 'typeorm';
import { import {
Param, Param,
RelationParam, RelationParam,
} from 'src/core/modules/domain/entities/base-filter.entity'; } from 'src/core/modules/domain/entities/base-filter.entity';
import { ItemRateEntity } from 'src/modules/item-related/item-rate/domain/entities/item-rate.entity'; import { ItemRateEntity } from 'src/modules/item-related/item-rate/domain/entities/item-rate.entity';
@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;
}
async beforeProcess(): Promise<void> {
return;
}
async afterProcess(): Promise<void> {
return;
}
get relations(): RelationParam {
return {
// relation only join (for query purpose)
joinRelations: [],
// relation join and select (relasi yang ingin ditampilkan),
selectRelations: ['item', 'item.item_category', 'item.bundling_items'],
// relation yang hanya ingin dihitung (akan return number)
countRelations: [],
};
}
get selects(): string[] {
return [
`${this.tableName}.id`,
`${this.tableName}.price`,
`item.id`,
`item.created_at`,
`item.status`,
`item.item_type`,
`item.name`,
`item.hpp`,
`item.limit_type`,
`item.limit_value`,
`item.base_price`,
`item_category.id`,
`item_category.name`,
'bundling_items.id',
'bundling_items.name',
];
}
get specificFilter(): Param[] {
return [
{
cols: `${this.tableName}.name`,
data: this.filterParam.names,
},
];
}
setQueryFilter(
queryBuilder: SelectQueryBuilder<ItemRateEntity>,
): SelectQueryBuilder<ItemRateEntity> {
if (this.filterParam.season_period_ids) {
queryBuilder.andWhere(
`${this.tableName}.season_period_id In (:...periodIds)`,
{
periodIds: this.filterParam.season_period_ids,
},
);
} }
async beforeProcess(): Promise<void> { return queryBuilder;
return; }
}
async afterProcess(): Promise<void> {
return;
}
get relations(): RelationParam {
return {
// relation only join (for query purpose)
joinRelations: [],
// relation join and select (relasi yang ingin ditampilkan),
selectRelations: ['item', 'item.item_category', 'item.bundling_items'],
// relation yang hanya ingin dihitung (akan return number)
countRelations: [],
};
}
get selects(): string[] {
return [
`${ this.tableName }.id`,
`${ this.tableName }.price`,
`item.id`,
`item.created_at`,
`item.status`,
`item.item_type`,
`item.name`,
`item.hpp`,
`item.limit_type`,
`item.limit_value`,
`item.base_price`,
`item_category.id`,
`item_category.name`,
'bundling_items.id',
'bundling_items.name',
];
}
get specificFilter(): Param[] {
return [
{
cols: `${ this.tableName }.name`,
data: this.filterParam.names,
},
];
}
setQueryFilter(
queryBuilder: SelectQueryBuilder<ItemRateEntity>,
): SelectQueryBuilder<ItemRateEntity> {
if (this.filterParam.season_period_ids) {
queryBuilder.andWhere(`${ this.tableName }.season_period_id In (:...periodIds)`, {
periodIds: this.filterParam.season_period_ids
})
}
return queryBuilder;
}
} }

View File

@ -1,59 +1,65 @@
import { Injectable } 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 { SeasonPeriodPriceUpdatedHandler } from "../handlers/season-period-price-updated.handler"; import { BaseCustomManager } from 'src/core/modules/domain/usecase/managers/base-custom.manager';
import { SeasonPeriodPriceUpdatedEvent } from "../../entities/event/season-period-price-updated.event"; import { SeasonPeriodEntity } from '../../entities/season-period.entity';
import { OPERATION } from "src/core/strings/constants/base.constants"; 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({
return; where: {
season_type_id: this.data.season_period.id,
},
});
if (!existSeason) {
throw new UnprocessableEntityException({
statusCode: HttpStatus.UNPROCESSABLE_ENTITY,
message: `Failed! There is no season type ${this.data.season_period.name}`,
error: 'Unprocessable Entity',
});
} }
return;
}
async beforeProcess(): Promise<void> { async beforeProcess(): Promise<void> {
return; return;
} }
async process(): Promise<void> { async process(): Promise<void> {
// this.publishEvents(); this.eventBus.publish(
new SeasonPeriodPriceUpdatedEvent({
id: '',
old: null,
data: this.data,
user: this.user,
description: '',
module: this.tableName,
op: OPERATION.CREATE,
}),
);
return;
}
this.eventBus.publish( async afterProcess(): Promise<void> {
new SeasonPeriodPriceUpdatedEvent({ return;
id: '', }
old: null,
data: this.data,
user: this.user,
description: '',
module: this.tableName,
op: OPERATION.CREATE,
})
)
return;
}
async afterProcess(): Promise<void> { get entityTarget(): any {
return; return SeasonPeriodModel;
} }
get entityTarget(): any { getResult() {
return SeasonPeriodModel;; return;
} }
getResult() { get eventTopics(): EventTopics[] {
return; return [];
} }
}
get eventTopics(): EventTopics[] {
return [
// {
// topic: SeasonPeriodPriceUpdatedEvent,
// data: this.data,
// }
];
}
}

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,31 +1,31 @@
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({
type: Object, type: Object,
required: true, required: true,
example: { example: {
id: 'uuid', id: 'uuid',
name: 'High Season', name: 'High Season',
}, },
}) })
@IsObject() @IsObject()
season_period: SeasonTypeModel; season_period: SeasonTypeModel;
@ApiProperty({ @ApiProperty({
type: [Object], type: [Object],
example: [ example: [
{ {
item: { item: {
id: 'uuid', id: 'uuid',
name: 'Entrance Ticket', name: 'Entrance Ticket',
}, },
price: 10000, price: 10000,
}, },
], ],
}) })
item_rates: ItemRateModel[]; item_rates: ItemRateModel[];
} }

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],
@ -63,4 +66,4 @@ import { UpdateSeasonPeriodPriceManager } from './domain/usecases/managers/updat
SeasonPeriodReadOrchestrator, SeasonPeriodReadOrchestrator,
], ],
}) })
export class SeasonPeriodModule { } export class SeasonPeriodModule {}

View File

@ -11,7 +11,7 @@ import { PaymentMethodChangeStatusEvent } from '../../entities/event/payment-met
@Injectable() @Injectable()
export class ActivePaymentMethodManager extends BaseUpdateStatusManager<PaymentMethodEntity> { export class ActivePaymentMethodManager extends BaseUpdateStatusManager<PaymentMethodEntity> {
getResult(): string { getResult(): string {
return `Success active data ${ this.result.account_name }`; return `Success active data ${this.result.account_name}`;
} }
async validateProcess(): Promise<void> { async validateProcess(): Promise<void> {

View File

@ -11,7 +11,7 @@ import { PaymentMethodChangeStatusEvent } from '../../entities/event/payment-met
@Injectable() @Injectable()
export class ConfirmPaymentMethodManager extends BaseUpdateStatusManager<PaymentMethodEntity> { export class ConfirmPaymentMethodManager extends BaseUpdateStatusManager<PaymentMethodEntity> {
getResult(): string { getResult(): string {
return `Success active data ${ this.result.account_name }`; return `Success active data ${this.result.account_name}`;
} }
async validateProcess(): Promise<void> { async validateProcess(): Promise<void> {

View File

@ -11,7 +11,7 @@ import { PaymentMethodChangeStatusEvent } from '../../entities/event/payment-met
@Injectable() @Injectable()
export class InactivePaymentMethodManager extends BaseUpdateStatusManager<PaymentMethodEntity> { export class InactivePaymentMethodManager extends BaseUpdateStatusManager<PaymentMethodEntity> {
getResult(): string { getResult(): string {
return `Success inactive data ${ this.result.account_name }`; return `Success inactive data ${this.result.account_name}`;
} }
async validateProcess(): Promise<void> { async validateProcess(): Promise<void> {

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, ' ')
throw new UnprocessableEntityException({ .split(' ');
statusCode: HttpStatus.UNPROCESSABLE_ENTITY, if (allWords.find((item) => item.toLowerCase() == name))
message: `Failed! tax ${ name } already used in ${ formula.type } formula`, throw new UnprocessableEntityException({
error: 'Unprocessable Entity', statusCode: HttpStatus.UNPROCESSABLE_ENTITY,
}) message: `Failed! tax ${name} already used in ${formula.type} formula`,
}); error: 'Unprocessable Entity',
} });
});
}

View File

@ -12,11 +12,14 @@ import { validateUsedInFormula } from './helpers/validation.helper';
@Injectable() @Injectable()
export class InactiveTaxManager extends BaseUpdateStatusManager<TaxEntity> { export class InactiveTaxManager extends BaseUpdateStatusManager<TaxEntity> {
getResult(): string { getResult(): string {
return `Success inactive data ${ this.result.name }`; return `Success inactive data ${this.result.name}`;
} }
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],
@ -54,4 +57,4 @@ import { SalesPriceFormulaModel } from '../sales-price-formula/data/models/sales
TaxReadOrchestrator, TaxReadOrchestrator,
], ],
}) })
export class TaxModule { } export class TaxModule {}

View File

@ -11,7 +11,7 @@ import { VipCategoryChangeStatusEvent } from '../../entities/event/vip-category-
@Injectable() @Injectable()
export class ActiveVipCategoryManager extends BaseUpdateStatusManager<VipCategoryEntity> { export class ActiveVipCategoryManager extends BaseUpdateStatusManager<VipCategoryEntity> {
getResult(): string { getResult(): string {
return `Success active data ${ this.result.name }`; return `Success active data ${this.result.name}`;
} }
async validateProcess(): Promise<void> { async validateProcess(): Promise<void> {

View File

@ -11,7 +11,7 @@ import { VipCategoryChangeStatusEvent } from '../../entities/event/vip-category-
@Injectable() @Injectable()
export class ConfirmVipCategoryManager extends BaseUpdateStatusManager<VipCategoryEntity> { export class ConfirmVipCategoryManager extends BaseUpdateStatusManager<VipCategoryEntity> {
getResult(): string { getResult(): string {
return `Success active data ${ this.result.name }`; return `Success active data ${this.result.name}`;
} }
async validateProcess(): Promise<void> { async validateProcess(): Promise<void> {

View File

@ -11,7 +11,7 @@ import { VipCategoryChangeStatusEvent } from '../../entities/event/vip-category-
@Injectable() @Injectable()
export class InactiveVipCategoryManager extends BaseUpdateStatusManager<VipCategoryEntity> { export class InactiveVipCategoryManager extends BaseUpdateStatusManager<VipCategoryEntity> {
getResult(): string { getResult(): string {
return `Success inactive data ${ this.result.name }`; return `Success inactive data ${this.result.name}`;
} }
async validateProcess(): Promise<void> { async validateProcess(): Promise<void> {

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', {
query: (qb: SelectQueryBuilder<any>) => { relation: 'items',
return qb.andWhere('total_items.status In (:...statuses)', { statuses: [STATUS.ACTIVE] }); query: (qb: SelectQueryBuilder<any>) => {
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', {
query: (qb: SelectQueryBuilder<any>) => { relation: 'items',
return qb.andWhere('total_items.status In (:...statuses)', { statuses: [STATUS.ACTIVE] }); query: (qb: SelectQueryBuilder<any>) => {
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', {
query: (qb: SelectQueryBuilder<any>) => { relation: 'items',
return qb.andWhere('total_items.status In (:...statuses)', { statuses: [STATUS.ACTIVE] }); query: (qb: SelectQueryBuilder<any>) => {
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,17 +13,21 @@ 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', {
query: (qb: SelectQueryBuilder<any>) => { relation: 'items',
return qb.andWhere('total_items.status In (:...statuses)', { statuses: [STATUS.ACTIVE] }); query: (qb: SelectQueryBuilder<any>) => {
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 {
return `Success inactive data ${ this.result.name }`; return `Success inactive data ${this.result.name}`;
} }
async validateProcess(): Promise<void> { async validateProcess(): Promise<void> {

View File

@ -11,7 +11,7 @@ import { UserChangeStatusEvent } from '../../entities/event/user-change-status.e
@Injectable() @Injectable()
export class ActiveUserManager extends BaseUpdateStatusManager<UserEntity> { export class ActiveUserManager extends BaseUpdateStatusManager<UserEntity> {
getResult(): string { getResult(): string {
return `Success active data ${ this.result.name }`; return `Success active data ${this.result.name}`;
} }
async validateProcess(): Promise<void> { async validateProcess(): Promise<void> {

View File

@ -11,7 +11,7 @@ import { UserChangeStatusEvent } from '../../entities/event/user-change-status.e
@Injectable() @Injectable()
export class ConfirmUserManager extends BaseUpdateStatusManager<UserEntity> { export class ConfirmUserManager extends BaseUpdateStatusManager<UserEntity> {
getResult(): string { getResult(): string {
return `Success active data ${ this.result.name }`; return `Success active data ${this.result.name}`;
} }
async validateProcess(): Promise<void> { async validateProcess(): Promise<void> {

View File

@ -31,7 +31,7 @@ export class CreateUserManager extends BaseCreateManager<UserEntity> {
return; return;
} }
async generateConfig(): Promise<void> { } async generateConfig(): Promise<void> {}
get validateRelations(): validateRelations[] { get validateRelations(): validateRelations[] {
return []; return [];

View File

@ -11,7 +11,7 @@ import { UserChangeStatusEvent } from '../../entities/event/user-change-status.e
@Injectable() @Injectable()
export class InactiveUserManager extends BaseUpdateStatusManager<UserEntity> { export class InactiveUserManager extends BaseUpdateStatusManager<UserEntity> {
getResult(): string { getResult(): string {
return `Success inactive data ${ this.result.name }`; return `Success inactive data ${this.result.name}`;
} }
async validateProcess(): Promise<void> { async validateProcess(): Promise<void> {