diff --git a/src/core/modules/data/service/base-data.service.ts b/src/core/modules/data/service/base-data.service.ts index ac01ff1..f4eb4c3 100644 --- a/src/core/modules/data/service/base-data.service.ts +++ b/src/core/modules/data/service/base-data.service.ts @@ -62,6 +62,14 @@ export abstract class BaseDataService { await this.repository.delete(id); } + async deleteByIds( + queryRunner: QueryRunner, + entityTarget: EntityTarget, + ids: string[], + ): Promise { + await this.repository.delete(ids); + } + async deleteByOptions( queryRunner: QueryRunner, entityTarget: EntityTarget, diff --git a/src/core/modules/domain/entities/base-core.entity.ts b/src/core/modules/domain/entities/base-core.entity.ts index caf7b15..a2b2ce5 100644 --- a/src/core/modules/domain/entities/base-core.entity.ts +++ b/src/core/modules/domain/entities/base-core.entity.ts @@ -1,3 +1,3 @@ export interface BaseCoreEntity { - id: string; + id?: string; } diff --git a/src/core/modules/domain/usecase/managers/base-batch-update-status.manager.ts b/src/core/modules/domain/usecase/managers/base-batch-update-status.manager.ts index 4125276..1d3909a 100644 --- a/src/core/modules/domain/usecase/managers/base-batch-update-status.manager.ts +++ b/src/core/modules/domain/usecase/managers/base-batch-update-status.manager.ts @@ -49,14 +49,14 @@ export abstract class BaseBatchUpdateStatusManager extends BaseManager { }); } this.oldData = _.cloneDeep(entity); + await this.validateData(entity); + Object.assign(entity, { status: this.dataStatus, editor_id: this.user.id, editor_name: this.user.name, updated_at: new Date().getTime(), }); - - await this.validateData(entity); await new ValidateRelationHelper( id, this.dataService, diff --git a/src/core/strings/constants/privilege.constants.ts b/src/core/strings/constants/privilege.constants.ts index 842d240..36ff066 100644 --- a/src/core/strings/constants/privilege.constants.ts +++ b/src/core/strings/constants/privilege.constants.ts @@ -147,6 +147,7 @@ export const PrivilegePOSConstant = [ PrivilegeAction.CREATE, PrivilegeAction.DELETE, PrivilegeAction.EDIT, + PrivilegeAction.CANCEL, ], index: 14, }, @@ -174,4 +175,10 @@ export const PrivilegePOSConstant = [ actions: [PrivilegeAction.CREATE], index: 18, }, + { + menu: 'POS_DISCOUNT_CODE', + menu_label: 'Print Receipt', + actions: [PrivilegeAction.CREATE], + index: 18, + }, ]; diff --git a/src/database/migrations/1722334034920-update-column-to-transaction-table.ts b/src/database/migrations/1722334034920-update-column-to-transaction-table.ts new file mode 100644 index 0000000..64a329b --- /dev/null +++ b/src/database/migrations/1722334034920-update-column-to-transaction-table.ts @@ -0,0 +1,25 @@ +import { MigrationInterface, QueryRunner } from 'typeorm'; + +export class UpdateColumnToTransactionTable1722334034920 + implements MigrationInterface +{ + name = 'UpdateColumnToTransactionTable1722334034920'; + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `ALTER TABLE "transaction_items" ADD "qr_image_url" character varying`, + ); + await queryRunner.query( + `ALTER TABLE "transactions" ADD "payment_code" character varying`, + ); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `ALTER TABLE "transactions" DROP COLUMN "payment_code"`, + ); + await queryRunner.query( + `ALTER TABLE "transaction_items" DROP COLUMN "qr_image_url"`, + ); + } +} diff --git a/src/modules/transaction/reconciliation/domain/usecases/managers/batch-confirm-reconciliation.manager.ts b/src/modules/transaction/reconciliation/domain/usecases/managers/batch-confirm-reconciliation.manager.ts index c8ae532..e9c8347 100644 --- a/src/modules/transaction/reconciliation/domain/usecases/managers/batch-confirm-reconciliation.manager.ts +++ b/src/modules/transaction/reconciliation/domain/usecases/managers/batch-confirm-reconciliation.manager.ts @@ -19,10 +19,7 @@ export class BatchConfirmReconciliationManager extends BaseBatchUpdateStatusMana reconciliation_confirm_date: new Date().getTime(), status: STATUS.SETTLED, reconciliation_status: this.dataStatus, - payment_code_reference: await generateInvoiceCodeHelper( - this.dataService, - 'PMY', - ), + payment_code: await generateInvoiceCodeHelper(this.dataService, 'PMY'), }); return; } diff --git a/src/modules/transaction/reconciliation/domain/usecases/managers/confirm-reconciliation.manager.ts b/src/modules/transaction/reconciliation/domain/usecases/managers/confirm-reconciliation.manager.ts index bb670ca..a2a6bd7 100644 --- a/src/modules/transaction/reconciliation/domain/usecases/managers/confirm-reconciliation.manager.ts +++ b/src/modules/transaction/reconciliation/domain/usecases/managers/confirm-reconciliation.manager.ts @@ -26,10 +26,7 @@ export class ConfirmReconciliationManager extends BaseUpdateStatusManager { validateData(data: RefundEntity): Promise { - if (![STATUS.REFUNDED, STATUS.PENDING].includes(data.status)) { + if ( + ![ + STATUS.REFUNDED, + STATUS.PENDING, + STATUS.PROCESS_REFUND, + STATUS.PARTIAL_REFUND, + ].includes(data.status) + ) { throw new UnprocessableEntityException({ statusCode: HttpStatus.UNPROCESSABLE_ENTITY, - message: `Failed! only data with status ${STATUS.REFUNDED} and ${STATUS.PENDING} can be cancelled`, + message: `Gagal! hanya data dengan status ${STATUS.REFUNDED}, ${STATUS.PROCESS_REFUND} , ${STATUS.PARTIAL_REFUND} dan ${STATUS.PENDING} yang dapat dicancel`, error: 'Unprocessable Entity', }); } diff --git a/src/modules/transaction/refund/domain/usecases/managers/cancel-refund.manager.ts b/src/modules/transaction/refund/domain/usecases/managers/cancel-refund.manager.ts index ec40de3..8b425ed 100644 --- a/src/modules/transaction/refund/domain/usecases/managers/cancel-refund.manager.ts +++ b/src/modules/transaction/refund/domain/usecases/managers/cancel-refund.manager.ts @@ -20,10 +20,17 @@ export class CancelRefundManager extends BaseUpdateStatusManager { } async validateProcess(): Promise { - if (![STATUS.REFUNDED, STATUS.PENDING].includes(this.data.status)) { + if ( + ![ + STATUS.REFUNDED, + STATUS.PENDING, + STATUS.PROCESS_REFUND, + STATUS.PARTIAL_REFUND, + ].includes(this.oldData.status) + ) { throw new UnprocessableEntityException({ statusCode: HttpStatus.UNPROCESSABLE_ENTITY, - message: `Failed! only data with status ${STATUS.REFUNDED} and ${STATUS.PENDING} can be cancelled`, + message: `Gagal! hanya data dengan status ${STATUS.REFUNDED}, ${STATUS.PROCESS_REFUND} , ${STATUS.PARTIAL_REFUND} dan ${STATUS.PENDING} yang dapat dicancel`, error: 'Unprocessable Entity', }); } diff --git a/src/modules/transaction/transaction/data/models/transaction-item.model.ts b/src/modules/transaction/transaction/data/models/transaction-item.model.ts index d00e800..dc5b278 100644 --- a/src/modules/transaction/transaction/data/models/transaction-item.model.ts +++ b/src/modules/transaction/transaction/data/models/transaction-item.model.ts @@ -14,6 +14,9 @@ export class TransactionItemModel @Column('varchar', { name: 'item_id', nullable: true }) item_id: string; + @Column('varchar', { name: 'qr_image_url', nullable: true }) + qr_image_url: string; + @Column('varchar', { name: 'item_name', nullable: true }) item_name: string; diff --git a/src/modules/transaction/transaction/data/models/transaction.model.ts b/src/modules/transaction/transaction/data/models/transaction.model.ts index 768a49d..e8c93a2 100644 --- a/src/modules/transaction/transaction/data/models/transaction.model.ts +++ b/src/modules/transaction/transaction/data/models/transaction.model.ts @@ -107,6 +107,9 @@ export class TransactionModel }) payment_type: TransactionPaymentType; + @Column('varchar', { name: 'payment_code', nullable: true }) + payment_code: string; + @Column('varchar', { name: 'payment_type_method_id', nullable: true }) payment_type_method_id: string; diff --git a/src/modules/transaction/transaction/domain/entities/transaction-item.entity.ts b/src/modules/transaction/transaction/domain/entities/transaction-item.entity.ts index 102355a..68d63cb 100644 --- a/src/modules/transaction/transaction/domain/entities/transaction-item.entity.ts +++ b/src/modules/transaction/transaction/domain/entities/transaction-item.entity.ts @@ -10,6 +10,7 @@ export interface TransactionItemEntity extends BaseCoreEntity { item_category_id: string; item_category_name: string; item_bundlings: string; + qr_image_url: string; // item tenant data item_tenant_id: string; diff --git a/src/modules/transaction/transaction/domain/entities/transaction.entity.ts b/src/modules/transaction/transaction/domain/entities/transaction.entity.ts index 2f3fcec..18761df 100644 --- a/src/modules/transaction/transaction/domain/entities/transaction.entity.ts +++ b/src/modules/transaction/transaction/domain/entities/transaction.entity.ts @@ -47,6 +47,7 @@ export interface TransactionEntity extends BaseStatusEntity { payment_type_method_qr: string; payment_card_information: string; payment_code_reference: string; + payment_code: string; payment_midtrans_token: string; payment_midtrans_url: string; payment_date: Date; diff --git a/src/modules/transaction/transaction/domain/usecases/handlers/midtrans-transaction-callback.handler.ts b/src/modules/transaction/transaction/domain/usecases/handlers/midtrans-transaction-callback.handler.ts index 48ab93f..85d0f1c 100644 --- a/src/modules/transaction/transaction/domain/usecases/handlers/midtrans-transaction-callback.handler.ts +++ b/src/modules/transaction/transaction/domain/usecases/handlers/midtrans-transaction-callback.handler.ts @@ -10,6 +10,7 @@ import { import { TransactionChangeStatusEvent } from '../../entities/event/transaction-change-status.event'; import * as _ from 'lodash'; import { TABLE_NAME } from 'src/core/strings/constants/table.constants'; +import { generateInvoiceCodeHelper } from '../managers/helpers/generate-invoice-code.helper'; @EventsHandler(MidtransCallbackEvent) export class MidtransCallbackHandler @@ -36,6 +37,7 @@ export class MidtransCallbackHandler Object.assign(transaction, { status: STATUS.SETTLED, settlement_date: new Date(data.settlement_time), + payment_code: await generateInvoiceCodeHelper(this.dataService, 'PMY'), payment_code_reference: data.approval_code, }); } else if (['pending'].includes(data['transaction_status'])) { diff --git a/src/modules/transaction/transaction/domain/usecases/managers/batch-cancel-transaction.manager.ts b/src/modules/transaction/transaction/domain/usecases/managers/batch-cancel-transaction.manager.ts index 4fb4157..6f44101 100644 --- a/src/modules/transaction/transaction/domain/usecases/managers/batch-cancel-transaction.manager.ts +++ b/src/modules/transaction/transaction/domain/usecases/managers/batch-cancel-transaction.manager.ts @@ -20,7 +20,7 @@ export class BatchCancelTransactionManager extends BaseBatchUpdateStatusManager< if (![STATUS.EXPIRED, STATUS.PENDING].includes(data.status)) { throw new UnprocessableEntityException({ statusCode: HttpStatus.UNPROCESSABLE_ENTITY, - message: `Failed! only data booking with status ${STATUS.ACTIVE} can be confirm`, + message: `Gagal! hanya tranksaksi dengan status ${STATUS.PENDING} dan ${STATUS.EXPIRED} yang dapat di${this.dataStatus}`, error: 'Unprocessable Entity', }); } diff --git a/src/modules/transaction/transaction/domain/usecases/managers/confirm-transaction.manager.ts b/src/modules/transaction/transaction/domain/usecases/managers/confirm-transaction.manager.ts index 89b6bbe..b1cf03d 100644 --- a/src/modules/transaction/transaction/domain/usecases/managers/confirm-transaction.manager.ts +++ b/src/modules/transaction/transaction/domain/usecases/managers/confirm-transaction.manager.ts @@ -56,10 +56,7 @@ export class ConfirmTransactionManager extends BaseUpdateStatusManager `${this.tableName}.editor_id`, `${this.tableName}.editor_name`, + `${this.tableName}.payment_code`, + `${this.tableName}.payment_card_information`, `${this.tableName}.payment_type`, `${this.tableName}.payment_date`, `${this.tableName}.payment_total_pay`, diff --git a/src/modules/transaction/transaction/domain/usecases/managers/update-transaction.manager.ts b/src/modules/transaction/transaction/domain/usecases/managers/update-transaction.manager.ts index d4d08d5..5fb66e4 100644 --- a/src/modules/transaction/transaction/domain/usecases/managers/update-transaction.manager.ts +++ b/src/modules/transaction/transaction/domain/usecases/managers/update-transaction.manager.ts @@ -42,7 +42,6 @@ export class UpdateTransactionManager extends BaseUpdateManager { + this.invoiceManager.setData({ + id: dataId, + }); + this.invoiceManager.setService(this.serviceData, TABLE_NAME.TRANSACTION); + await this.invoiceManager.execute(); + return this.invoiceManager.getResult(); + } + async delete(dataId): Promise { this.deleteManager.setData(dataId); this.deleteManager.setService(this.serviceData, TABLE_NAME.TRANSACTION); diff --git a/src/modules/user-related/user-privilege/domain/entities/user-privilege-configuration.entity.ts b/src/modules/user-related/user-privilege/domain/entities/user-privilege-configuration.entity.ts index e0b6158..cb350de 100644 --- a/src/modules/user-related/user-privilege/domain/entities/user-privilege-configuration.entity.ts +++ b/src/modules/user-related/user-privilege/domain/entities/user-privilege-configuration.entity.ts @@ -5,13 +5,13 @@ export interface UserPrivilegeConfigurationEntity extends BaseCoreEntity { module_label: string; menu: string; menu_label: string; - sub_menu: string; - sub_menu_label: string; - view: boolean; - create: boolean; - edit: boolean; - delete: boolean; - cancel: boolean; - confirm: boolean; - index: number; + sub_menu?: string; + sub_menu_label?: string; + view?: boolean; + create?: boolean; + edit?: boolean; + delete?: boolean; + cancel?: boolean; + confirm?: boolean; + index?: number; } diff --git a/src/modules/user-related/user-privilege/domain/usecases/user-privilege-configuration/handlers/update-user-privilege-configuration.helper.ts b/src/modules/user-related/user-privilege/domain/usecases/user-privilege-configuration/handlers/update-user-privilege-configuration.helper.ts new file mode 100644 index 0000000..f3f8f62 --- /dev/null +++ b/src/modules/user-related/user-privilege/domain/usecases/user-privilege-configuration/handlers/update-user-privilege-configuration.helper.ts @@ -0,0 +1,66 @@ +import { EventsHandler, IEventHandler } from '@nestjs/cqrs'; +import { UserPrivilegeConfigUpdatedEvent } from '../../../entities/event/user-privilege-configuration-updated.event'; +import { UserPrivilegeConfigurationService } from 'src/modules/user-related/user-privilege/data/service/user-privilege-configuration.service'; +import { UserPrivilegeConfigurationHelper } from '../helpers/generate-user-privilege-configuration.helper'; +import { UserPrivilegeConfigurationModel } from 'src/modules/user-related/user-privilege/data/models/user-privilege-configuration.model'; + +@EventsHandler(UserPrivilegeConfigUpdatedEvent) +export class UserPrivilegeConfigUpdateHandler + implements IEventHandler +{ + constructor(private dataService: UserPrivilegeConfigurationService) {} + + async handle(event: UserPrivilegeConfigUpdatedEvent) { + const data = event.data.data; + console.log(data.user_privilege_id); + const configurations = await this.dataService.getManyByOptions({ + where: { + user_privilege_id: data.user_privilege_id, + }, + }); + const configs = UserPrivilegeConfigurationHelper.createConfigurations(); + + const createdConfig = configs + .filter( + (base) => + !configurations.some((data) => { + return base.menu_label == data.menu_label; + }), + ) + .map((item) => { + return { + ...item, + user_privilege_id: data.user_privilege_id, + }; + }); + + const deletedConfig = configurations + .filter( + (base) => + !configs.some((data) => { + return base.menu_label == data.menu_label; + }), + ) + ?.map((item) => item.id); + + const queryRunner = this.dataService + .getRepository() + .manager.connection.createQueryRunner(); + + if (createdConfig.length) { + await this.dataService.createBatch( + queryRunner, + UserPrivilegeConfigurationModel, + createdConfig, + ); + } + + if (deletedConfig.length) { + await this.dataService.deleteByIds( + queryRunner, + UserPrivilegeConfigurationModel, + deletedConfig, + ); + } + } +} diff --git a/src/modules/user-related/user-privilege/user-privilege.module.ts b/src/modules/user-related/user-privilege/user-privilege.module.ts index d8a52c5..00282cc 100644 --- a/src/modules/user-related/user-privilege/user-privilege.module.ts +++ b/src/modules/user-related/user-privilege/user-privilege.module.ts @@ -28,6 +28,7 @@ import { UserPrivilegeConfigurationDataOrchestrator } from './domain/usecases/us import { IndexUserPrivilegeConfigurationManager } from './domain/usecases/user-privilege-configuration/managers/index-user-privilege-configuration.manager'; import { UserPrivilegeModels } from './constants'; import { MenuUserPrivilegeConfigurationManager } from './domain/usecases/user-privilege-configuration/managers/menu-user-privilege-configuration.manager'; +import { UserPrivilegeConfigUpdateHandler } from './domain/usecases/user-privilege-configuration/handlers/update-user-privilege-configuration.helper'; @Module({ imports: [ @@ -41,6 +42,8 @@ import { MenuUserPrivilegeConfigurationManager } from './domain/usecases/user-pr UserPrivilegeConfigurationController, ], providers: [ + UserPrivilegeConfigUpdateHandler, + IndexUserPrivilegeManager, DetailUserPrivilegeManager, CreateUserPrivilegeManager,