From 20848aab3c2ad0179ca9920ba50a6c1a940df136 Mon Sep 17 00:00:00 2001 From: Aswin Ashar Abdullah Date: Tue, 23 Jul 2024 18:25:14 +0700 Subject: [PATCH 1/4] fix(SPG-644) Sync ketika privileges di update --- .../usecase/managers/base-custom.manager.ts | 28 ++++++++++ .../configuration/couch/couch.module.ts | 2 + .../couch/data/services/couch.service.ts | 1 - .../couch/domain/managers/user.handler.ts | 51 +++++++++++++++++++ ...r-privilege-configuration-updated.event.ts | 5 ++ ...te-user-privilege-configuration.manager.ts | 10 +++- 6 files changed, 95 insertions(+), 2 deletions(-) create mode 100644 src/modules/user-related/user-privilege/domain/entities/event/user-privilege-configuration-updated.event.ts diff --git a/src/core/modules/domain/usecase/managers/base-custom.manager.ts b/src/core/modules/domain/usecase/managers/base-custom.manager.ts index 58215f2..f7f1336 100644 --- a/src/core/modules/domain/usecase/managers/base-custom.manager.ts +++ b/src/core/modules/domain/usecase/managers/base-custom.manager.ts @@ -1,5 +1,6 @@ import { validateRelations } from 'src/core/strings/constants/interface.constants'; import { BaseManager } from '../base.manager'; +import { OPERATION } from 'src/core/strings/constants/base.constants'; export abstract class BaseCustomManager extends BaseManager { protected result: any; @@ -23,4 +24,31 @@ export abstract class BaseCustomManager extends BaseManager { } abstract getResult(): any; + + async publishEvents() { + if (!this.eventTopics.length) return; + for (const topic of this.eventTopics) { + let data; + if (!topic.data) { + data = await this.dataService.getOneByOptions({ + where: { + id: this.result['id'], + }, + relations: topic.relations, + }); + } + + this.eventBus.publishAll([ + new topic.topic({ + id: data?.['id'] ?? topic?.data?.['id'], + old: null, + data: data ?? topic.data, + user: this.user, + description: '', + module: this.tableName, + op: OPERATION.UPDATE, + }), + ]); + } + } } diff --git a/src/modules/configuration/couch/couch.module.ts b/src/modules/configuration/couch/couch.module.ts index e3a4b95..b1b8309 100644 --- a/src/modules/configuration/couch/couch.module.ts +++ b/src/modules/configuration/couch/couch.module.ts @@ -21,6 +21,7 @@ import { } from './domain/managers/item.handler'; import { UserDeletedHandler, + UserPrivilegeUpdateHandler, UserUpdatedHandler, } from './domain/managers/user.handler'; import { TypeOrmModule } from '@nestjs/typeorm'; @@ -69,6 +70,7 @@ import { VipCodeCreatedHandler } from './domain/managers/vip-code.handler'; ItemDeletedHandler, UserDeletedHandler, UserUpdatedHandler, + UserPrivilegeUpdateHandler, TransactionDataService, UserDataService, diff --git a/src/modules/configuration/couch/data/services/couch.service.ts b/src/modules/configuration/couch/data/services/couch.service.ts index 59cc403..7225d50 100644 --- a/src/modules/configuration/couch/data/services/couch.service.ts +++ b/src/modules/configuration/couch/data/services/couch.service.ts @@ -62,7 +62,6 @@ export class CouchService { const nano = this.nanoInstance; const db = nano.use(database); const result = await db.get(data.id); - console.log(result, 'dsa'); await db.insert({ ...data, _rev: result._rev, diff --git a/src/modules/configuration/couch/domain/managers/user.handler.ts b/src/modules/configuration/couch/domain/managers/user.handler.ts index 97c8e18..47389d1 100644 --- a/src/modules/configuration/couch/domain/managers/user.handler.ts +++ b/src/modules/configuration/couch/domain/managers/user.handler.ts @@ -5,6 +5,7 @@ import { UserDeletedEvent } from 'src/modules/user-related/user/domain/entities/ 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 { UserDataService } from 'src/modules/user-related/user/data/services/user-data.service'; +import { UserPrivilegeConfigUpdatedEvent } from 'src/modules/user-related/user-privilege/domain/entities/event/user-privilege-configuration-updated.event'; @EventsHandler(UserDeletedEvent) export class UserDeletedHandler implements IEventHandler { @@ -86,3 +87,53 @@ export class UserUpdatedHandler } } } + +@EventsHandler(UserPrivilegeConfigUpdatedEvent) +export class UserPrivilegeUpdateHandler + implements IEventHandler +{ + constructor( + private couchService: CouchService, + private userService: UserDataService, + ) {} + + async handle(event: UserPrivilegeConfigUpdatedEvent) { + const data = event.data.data; + + const users = await this.userService + .getManyByOptions({ + where: { + user_privilege_id: data.user_privilege_id, + status: STATUS.ACTIVE, + }, + relations: [ + 'user_privilege', + 'user_privilege.user_privilege_configurations', + ], + }) + .then((items) => { + return items?.map((item) => { + console.log(item, 'dsa'); + 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; + }); + }); + + for (const user of users) { + await this.couchService.updateDoc( + { + _id: user.id, + ...user, + }, + 'user', + ); + } + } +} diff --git a/src/modules/user-related/user-privilege/domain/entities/event/user-privilege-configuration-updated.event.ts b/src/modules/user-related/user-privilege/domain/entities/event/user-privilege-configuration-updated.event.ts new file mode 100644 index 0000000..962eea0 --- /dev/null +++ b/src/modules/user-related/user-privilege/domain/entities/event/user-privilege-configuration-updated.event.ts @@ -0,0 +1,5 @@ +import { IEvent } from 'src/core/strings/constants/interface.constants'; + +export class UserPrivilegeConfigUpdatedEvent { + constructor(public readonly data: IEvent) {} +} diff --git a/src/modules/user-related/user-privilege/domain/usecases/user-privilege-configuration/managers/update-user-privilege-configuration.manager.ts b/src/modules/user-related/user-privilege/domain/usecases/user-privilege-configuration/managers/update-user-privilege-configuration.manager.ts index d4a22b3..bb55d0a 100644 --- a/src/modules/user-related/user-privilege/domain/usecases/user-privilege-configuration/managers/update-user-privilege-configuration.manager.ts +++ b/src/modules/user-related/user-privilege/domain/usecases/user-privilege-configuration/managers/update-user-privilege-configuration.manager.ts @@ -6,6 +6,7 @@ import { } from 'src/core/strings/constants/interface.constants'; import { BaseCustomManager } from 'src/core/modules/domain/usecase/managers/base-custom.manager'; import { UserPrivilegeConfigurationModel } from 'src/modules/user-related/user-privilege/data/models/user-privilege-configuration.model'; +import { UserPrivilegeConfigUpdatedEvent } from '../../../entities/event/user-privilege-configuration-updated.event'; @Injectable() export class UpdateUserPrivilegeConfigurationManager extends BaseCustomManager { @@ -24,6 +25,8 @@ export class UpdateUserPrivilegeConfigurationManager extends BaseCustomManager Date: Tue, 23 Jul 2024 18:25:57 +0700 Subject: [PATCH 2/4] fix(SPG-640) Sync harga ketika ditambahkan melalui item rate (case item sudah dibuat) --- .../configuration/couch/couch.module.ts | 4 + .../couch/domain/managers/item.handler.ts | 85 +++++++++++++++++++ 2 files changed, 89 insertions(+) diff --git a/src/modules/configuration/couch/couch.module.ts b/src/modules/configuration/couch/couch.module.ts index b1b8309..ac587d5 100644 --- a/src/modules/configuration/couch/couch.module.ts +++ b/src/modules/configuration/couch/couch.module.ts @@ -17,6 +17,8 @@ import { } from './domain/managers/season-period.handler'; import { ItemDeletedHandler, + ItemPriceUpdatedHandler, + ItemRateUpdatedHandler, ItemUpdatedHandler, } from './domain/managers/item.handler'; import { @@ -68,6 +70,8 @@ import { VipCodeCreatedHandler } from './domain/managers/vip-code.handler'; SeasonPeriodUpdatedHandler, ItemUpdatedHandler, ItemDeletedHandler, + ItemRateUpdatedHandler, + ItemPriceUpdatedHandler, UserDeletedHandler, UserUpdatedHandler, UserPrivilegeUpdateHandler, diff --git a/src/modules/configuration/couch/domain/managers/item.handler.ts b/src/modules/configuration/couch/domain/managers/item.handler.ts index 90dedec..1c02076 100644 --- a/src/modules/configuration/couch/domain/managers/item.handler.ts +++ b/src/modules/configuration/couch/domain/managers/item.handler.ts @@ -5,6 +5,9 @@ import { ItemDeletedEvent } from 'src/modules/item-related/item/domain/entities/ 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 { ItemDataService } from 'src/modules/item-related/item/data/services/item-data.service'; +import { SeasonPeriodUpdatedEvent } from 'src/modules/season-related/season-period/domain/entities/event/season-period-updated.event'; +import { SeasonPeriodChangeStatusEvent } from 'src/modules/season-related/season-period/domain/entities/event/season-period-change-status.event'; +import { ItemRateUpdatedEvent } from 'src/modules/item-related/item-rate/domain/entities/event/item-rate-updated.event'; @EventsHandler(ItemDeletedEvent) export class ItemDeletedHandler implements IEventHandler { @@ -79,3 +82,85 @@ export class ItemUpdatedHandler } } } + +@EventsHandler(SeasonPeriodChangeStatusEvent, SeasonPeriodUpdatedEvent) +export class ItemPriceUpdatedHandler + implements IEventHandler +{ + constructor( + private couchService: CouchService, + private itemService: ItemDataService, + ) {} + + async handle(event: SeasonPeriodChangeStatusEvent) { + const data = event.data.data; + + // change status to active + if (data.status == STATUS.ACTIVE) { + const dataItems = await this.itemService.getManyByOptions({ + where: { + status: STATUS.ACTIVE, + }, + relations: [ + 'item_category', + 'bundling_items', + 'bundling_items.item_category', + 'item_rates', + 'item_rates.item', + 'item_rates.season_period', + 'item_rates.season_period.season_type', + ], + }); + + for (const dataItem of dataItems) { + await this.couchService.updateDoc( + { + _id: dataItem.id, + ...dataItem, + }, + 'item', + ); + } + } + } +} + +@EventsHandler(ItemRateUpdatedEvent) +export class ItemRateUpdatedHandler + implements IEventHandler +{ + constructor( + private couchService: CouchService, + private itemService: ItemDataService, + ) {} + + async handle(event: ItemRateUpdatedEvent) { + const data = event.data.data; + + const dataItems = await this.itemService.getManyByOptions({ + where: { + status: STATUS.ACTIVE, + id: data.item?.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', + ], + }); + + for (const dataItem of dataItems) { + await this.couchService.updateDoc( + { + _id: dataItem.id, + ...dataItem, + }, + 'item', + ); + } + } +} -- 2.40.1 From aa550f9d388435d5f0d3d2c87a4e17723d4d4495 Mon Sep 17 00:00:00 2001 From: Aswin Ashar Abdullah Date: Tue, 23 Jul 2024 19:24:40 +0700 Subject: [PATCH 3/4] feat(SPG-612) Activity Log PoS --- src/app.module.ts | 2 + src/core/strings/constants/table.constants.ts | 1 + .../migrations/1721736523991-pos-log.ts | 15 +++++++ src/modules/configuration/couch/constants.ts | 7 ++- .../log/data/models/pos-log.model.ts | 28 ++++++++++++ .../log/data/services/pos-log.service.ts | 17 ++++++++ .../log/domain/entities/pos-log.entity.ts | 17 ++++++++ .../log/domain/handlers/pos-log.handler.ts | 43 +++++++++++++++++++ src/modules/configuration/log/log.module.ts | 7 ++- 9 files changed, 135 insertions(+), 2 deletions(-) create mode 100644 src/database/migrations/1721736523991-pos-log.ts create mode 100644 src/modules/configuration/log/data/models/pos-log.model.ts create mode 100644 src/modules/configuration/log/data/services/pos-log.service.ts create mode 100644 src/modules/configuration/log/domain/entities/pos-log.entity.ts create mode 100644 src/modules/configuration/log/domain/handlers/pos-log.handler.ts diff --git a/src/app.module.ts b/src/app.module.ts index 08b50d9..652dec6 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -69,6 +69,7 @@ import { NewsModel } from './modules/web-information/news/data/models/news.model import { BannerModule } from './modules/web-information/banner/banner.module'; import { BannerModel } from './modules/web-information/banner/data/models/banner.model'; import { MailModule } from './modules/configuration/mail/mail.module'; +import { PosLogModel } from './modules/configuration/log/data/models/pos-log.model'; @Module({ imports: [ @@ -96,6 +97,7 @@ import { MailModule } from './modules/configuration/mail/mail.module'; LogModel, NewsModel, PaymentMethodModel, + PosLogModel, RefundModel, RefundItemModel, SalesPriceFormulaModel, diff --git a/src/core/strings/constants/table.constants.ts b/src/core/strings/constants/table.constants.ts index 8c14c7d..7950937 100644 --- a/src/core/strings/constants/table.constants.ts +++ b/src/core/strings/constants/table.constants.ts @@ -7,6 +7,7 @@ export enum TABLE_NAME { ITEM_RATE = 'item_rates', GATE = 'gates', LOG = 'logs', + LOG_POS = 'logs_pos', NEWS = 'news', PAYMENT_METHOD = 'payment_methods', PRICE_FORMULA = 'price_formulas', diff --git a/src/database/migrations/1721736523991-pos-log.ts b/src/database/migrations/1721736523991-pos-log.ts new file mode 100644 index 0000000..5f89518 --- /dev/null +++ b/src/database/migrations/1721736523991-pos-log.ts @@ -0,0 +1,15 @@ +import { MigrationInterface, QueryRunner } from 'typeorm'; + +export class PosLog1721736523991 implements MigrationInterface { + name = 'PosLog1721736523991'; + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `CREATE TABLE "logs_pos" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "type" character varying NOT NULL DEFAULT 'cash withdrawal', "pos_number" bigint, "total_balance" numeric, "created_at" bigint, "creator_name" character varying, "creator_id" character varying, CONSTRAINT "PK_60df825558a6b6881d7ad770d26" PRIMARY KEY ("id"))`, + ); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`DROP TABLE "logs_pos"`); + } +} diff --git a/src/modules/configuration/couch/constants.ts b/src/modules/configuration/couch/constants.ts index 031c3c4..8171752 100644 --- a/src/modules/configuration/couch/constants.ts +++ b/src/modules/configuration/couch/constants.ts @@ -1 +1,6 @@ -export const DatabaseListen = ['transaction', 'vip_code']; +export const DatabaseListen = [ + 'transaction', + 'vip_code', + 'pos_activity', + 'pos_cash_activity', +]; diff --git a/src/modules/configuration/log/data/models/pos-log.model.ts b/src/modules/configuration/log/data/models/pos-log.model.ts new file mode 100644 index 0000000..b161889 --- /dev/null +++ b/src/modules/configuration/log/data/models/pos-log.model.ts @@ -0,0 +1,28 @@ +import { TABLE_NAME } from 'src/core/strings/constants/table.constants'; +import { Column, Entity } from 'typeorm'; +import { PosLogEntity, PosLogType } from '../../domain/entities/pos-log.entity'; +import { BaseCoreModel } from 'src/core/modules/data/model/base-core.model'; + +@Entity(TABLE_NAME.LOG_POS) +export class PosLogModel + extends BaseCoreModel + implements PosLogEntity +{ + @Column('varchar', { name: 'type', default: PosLogType.cash_witdrawal }) + type: PosLogType; + + @Column('bigint', { name: 'pos_number', nullable: true }) + pos_number: number; + + @Column('decimal', { name: 'total_balance', nullable: true }) + total_balance: number; + + @Column('bigint', { name: 'created_at', nullable: true }) + created_at: number; + + @Column('varchar', { name: 'creator_name', nullable: true }) + creator_name: string; + + @Column('varchar', { name: 'creator_id', nullable: true }) + creator_id: string; +} diff --git a/src/modules/configuration/log/data/services/pos-log.service.ts b/src/modules/configuration/log/data/services/pos-log.service.ts new file mode 100644 index 0000000..745b929 --- /dev/null +++ b/src/modules/configuration/log/data/services/pos-log.service.ts @@ -0,0 +1,17 @@ +import { Injectable } from '@nestjs/common'; +import { BaseDataService } from 'src/core/modules/data/service/base-data.service'; +import { PosLogEntity } from '../../domain/entities/pos-log.entity'; +import { PosLogModel } from '../models/pos-log.model'; +import { InjectRepository } from '@nestjs/typeorm'; +import { CONNECTION_NAME } from 'src/core/strings/constants/base.constants'; +import { Repository } from 'typeorm'; + +@Injectable() +export class PosLogService extends BaseDataService { + constructor( + @InjectRepository(PosLogModel, CONNECTION_NAME.DEFAULT) + private repo: Repository, + ) { + super(repo); + } +} diff --git a/src/modules/configuration/log/domain/entities/pos-log.entity.ts b/src/modules/configuration/log/domain/entities/pos-log.entity.ts new file mode 100644 index 0000000..f29f780 --- /dev/null +++ b/src/modules/configuration/log/domain/entities/pos-log.entity.ts @@ -0,0 +1,17 @@ +import { BaseCoreEntity } from 'src/core/modules/domain/entities/base-core.entity'; + +export interface PosLogEntity extends BaseCoreEntity { + type: PosLogType; + pos_number: number; + total_balance: number; + created_at: number; + creator_name: string; + creator_id: string; +} + +export enum PosLogType { + cash_witdrawal = 'cash withdrawal', + opening_cash = 'opening_cash', + login = 'login', + logout = 'logout', +} diff --git a/src/modules/configuration/log/domain/handlers/pos-log.handler.ts b/src/modules/configuration/log/domain/handlers/pos-log.handler.ts new file mode 100644 index 0000000..7b794ff --- /dev/null +++ b/src/modules/configuration/log/domain/handlers/pos-log.handler.ts @@ -0,0 +1,43 @@ +import { EventsHandler, IEventHandler } from '@nestjs/cqrs'; +import { ChangeDocEvent } from 'src/modules/configuration/couch/domain/events/change-doc.event'; +import { PosLogService } from '../../data/services/pos-log.service'; +import { PosLogModel } from '../../data/models/pos-log.model'; +import { PosLogType } from '../entities/pos-log.entity'; + +@EventsHandler(ChangeDocEvent) +export class RecordPosLogHandler implements IEventHandler { + constructor(private dataService: PosLogService) {} + + async handle(event: ChangeDocEvent) { + try { + const database = event.data.database; + const data = event.data.data; + + if (!['pos_cash_activity', 'pos_activity'].includes(database)) return; + + const queryRunner = this.dataService + .getRepository() + .manager.connection.createQueryRunner(); + + const activity = new PosLogModel(); + + Object.assign(activity, { + id: data._id, + type: PosLogType[data.type], + total_balance: data.withdrawal_cash ?? data.opening_cash_balance, + pos_number: data.pos_number, + creator_id: data.pos_admin?.id, + creator_name: data.pos_admin?.name, + created_at: data.created_at, + }); + + await this.dataService.create( + queryRunner, + PosLogModel, + activity, + ); + } catch (error) { + console.log('error handling pos activity couch'); + } + } +} diff --git a/src/modules/configuration/log/log.module.ts b/src/modules/configuration/log/log.module.ts index 14c8eef..06002f9 100644 --- a/src/modules/configuration/log/log.module.ts +++ b/src/modules/configuration/log/log.module.ts @@ -9,12 +9,15 @@ import { RecordErrorLogHandler } from './domain/handlers/error-log.handler'; import { RecordLogHandler } from './domain/handlers/log.handler'; import { ErrorLogService } from './data/services/error-log.service'; import { LogService } from './data/services/log.service'; +import { PosLogModel } from './data/models/pos-log.model'; +import { PosLogService } from './data/services/pos-log.service'; +import { RecordPosLogHandler } from './domain/handlers/pos-log.handler'; @Module({ imports: [ ConfigModule.forRoot(), TypeOrmModule.forFeature( - [LogModel, ErrorLogModel], + [LogModel, ErrorLogModel, PosLogModel], CONNECTION_NAME.DEFAULT, ), CqrsModule, @@ -22,9 +25,11 @@ import { LogService } from './data/services/log.service'; controllers: [], providers: [ RecordLogHandler, + RecordPosLogHandler, RecordErrorLogHandler, LogService, + PosLogService, ErrorLogService, ], }) -- 2.40.1 From d0163ae003047cabf325472e1a1b42ccbaf14267 Mon Sep 17 00:00:00 2001 From: Aswin Ashar Abdullah Date: Tue, 23 Jul 2024 19:54:00 +0700 Subject: [PATCH 4/4] feat(SPG-125) Logging --- .../log/domain/handlers/log.handler.ts | 26 ++++++++++++++++++- .../log/domain/handlers/pos-log.handler.ts | 6 +---- 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/src/modules/configuration/log/domain/handlers/log.handler.ts b/src/modules/configuration/log/domain/handlers/log.handler.ts index 1e4fafb..73817e9 100644 --- a/src/modules/configuration/log/domain/handlers/log.handler.ts +++ b/src/modules/configuration/log/domain/handlers/log.handler.ts @@ -1,9 +1,33 @@ import { EventsHandler, IEventHandler } from '@nestjs/cqrs'; import { RecordLog } from '../entities/log.event'; +import { LogService } from '../../data/services/log.service'; +import { LogModel } from '../../data/models/log.model'; @EventsHandler(RecordLog) export class RecordLogHandler implements IEventHandler { + constructor(private dataService: LogService) {} + async handle(event: RecordLog) { - // TODO: Implement logic here + const data = event.data; + + const queryRunner = this.dataService + .getRepository() + .manager.connection.createQueryRunner(); + + const log = new LogModel(); + + Object.assign(log, { + data_id: data.id, + module: data.module, + description: data.description, + process: data.op, + old_data: data.old, + data: data.data, + created_at: new Date().getTime(), + creator_name: data.user.name, + creator_id: data.user.id, + }); + + await this.dataService.create(queryRunner, LogModel, log); } } diff --git a/src/modules/configuration/log/domain/handlers/pos-log.handler.ts b/src/modules/configuration/log/domain/handlers/pos-log.handler.ts index 7b794ff..57f7e07 100644 --- a/src/modules/configuration/log/domain/handlers/pos-log.handler.ts +++ b/src/modules/configuration/log/domain/handlers/pos-log.handler.ts @@ -31,11 +31,7 @@ export class RecordPosLogHandler implements IEventHandler { created_at: data.created_at, }); - await this.dataService.create( - queryRunner, - PosLogModel, - activity, - ); + await this.dataService.create(queryRunner, PosLogModel, activity); } catch (error) { console.log('error handling pos activity couch'); } -- 2.40.1