fix(SPG-641) Validasi ketika process save untuk aksi di rekonsiliasi, save data di refund, dan aksi di booking

pull/33/head
Aswin Ashar Abdullah 2024-07-20 22:12:09 +07:00
parent cc92ef26a1
commit c5cec31ab5
9 changed files with 80 additions and 10 deletions

View File

@ -11,10 +11,25 @@ import {
} from '@nestjs/common'; } from '@nestjs/common';
import { TransactionEntity } from 'src/modules/transaction/transaction/domain/entities/transaction.entity'; import { TransactionEntity } from 'src/modules/transaction/transaction/domain/entities/transaction.entity';
import { TransactionModel } from 'src/modules/transaction/transaction/data/models/transaction.model'; import { TransactionModel } from 'src/modules/transaction/transaction/data/models/transaction.model';
import { STATUS } from 'src/core/strings/constants/base.constants';
@Injectable() @Injectable()
export class BatchCancelReconciliationManager extends BaseBatchUpdateStatusManager<TransactionEntity> { export class BatchCancelReconciliationManager extends BaseBatchUpdateStatusManager<TransactionEntity> {
validateData(data: TransactionEntity): Promise<void> { async validateData(data: TransactionEntity): Promise<void> {
const transaction = await this.dataService.getOneByOptions({
where: {
id: data.id,
},
});
if (transaction.status != STATUS.SETTLED) {
throw new UnprocessableEntityException({
statusCode: HttpStatus.UNPROCESSABLE_ENTITY,
message: `Failed! cant cancel transaction not settled`,
error: 'Unprocessable Entity',
});
}
Object.assign(data, { Object.assign(data, {
reconciliation_mdr: this.data.reconciliation_mdr ?? null, reconciliation_mdr: this.data.reconciliation_mdr ?? null,
reconciliation_confirm_by: this.user.name, reconciliation_confirm_by: this.user.name,

View File

@ -4,6 +4,7 @@ import {
UnprocessableEntityException, UnprocessableEntityException,
} from '@nestjs/common'; } 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 { STATUS } from 'src/core/strings/constants/base.constants';
import { import {
EventTopics, EventTopics,
validateRelations, validateRelations,
@ -18,7 +19,20 @@ export class CancelReconciliationManager extends BaseUpdateStatusManager<Transac
} }
async validateProcess(): Promise<void> { async validateProcess(): Promise<void> {
if (this.data.is_recap_transaction) { // untuk dapat current status
const transaction = await this.dataService.getOneByOptions({
where: {
id: this.dataId,
},
});
if (transaction.status != STATUS.SETTLED) {
throw new UnprocessableEntityException({
statusCode: HttpStatus.UNPROCESSABLE_ENTITY,
message: `Failed! cant cancel transaction not settled`,
error: 'Unprocessable Entity',
});
} else if (this.data.is_recap_transaction) {
throw new UnprocessableEntityException({ throw new UnprocessableEntityException({
statusCode: HttpStatus.UNPROCESSABLE_ENTITY, statusCode: HttpStatus.UNPROCESSABLE_ENTITY,
message: `Failed! cant cancel recap data`, message: `Failed! cant cancel recap data`,

View File

@ -16,8 +16,14 @@ import { STATUS } from 'src/core/strings/constants/base.constants';
@Injectable() @Injectable()
export class BatchConfirmRefundManager extends BaseBatchUpdateStatusManager<RefundEntity> { export class BatchConfirmRefundManager extends BaseBatchUpdateStatusManager<RefundEntity> {
validateData(data: RefundEntity): Promise<void> { async validateData(data: RefundEntity): Promise<void> {
if (![STATUS.DRAFT, STATUS.PENDING].includes(data.status)) { if (data?.['transaction']?.status != STATUS.SETTLED) {
throw new UnprocessableEntityException({
statusCode: HttpStatus.UNPROCESSABLE_ENTITY,
message: `Failed! only transaction with status ${STATUS.SETTLED} can be refund`,
error: 'Unprocessable Entity',
});
} else if (![STATUS.DRAFT, STATUS.PENDING].includes(data.status)) {
throw new UnprocessableEntityException({ throw new UnprocessableEntityException({
statusCode: HttpStatus.UNPROCESSABLE_ENTITY, statusCode: HttpStatus.UNPROCESSABLE_ENTITY,
message: `Failed! only data with status ${STATUS.DRAFT} and ${STATUS.PENDING} can be confirmed`, message: `Failed! only data with status ${STATUS.DRAFT} and ${STATUS.PENDING} can be confirmed`,

View File

@ -38,6 +38,14 @@ export class ConfirmRefundManager extends BaseUpdateStatusManager<RefundEntity>
relations: ['transaction'], relations: ['transaction'],
}); });
if (data.transaction.status != STATUS.SETTLED) {
throw new UnprocessableEntityException({
statusCode: HttpStatus.UNPROCESSABLE_ENTITY,
message: `Failed! only transaction with status ${STATUS.SETTLED} can be refund`,
error: 'Unprocessable Entity',
});
}
if (data.status == STATUS.DRAFT) { if (data.status == STATUS.DRAFT) {
Object.assign(this.data, { Object.assign(this.data, {
code: `RF-${data.transaction?.invoice_code?.split('-')[1]}`, code: `RF-${data.transaction?.invoice_code?.split('-')[1]}`,

View File

@ -30,7 +30,14 @@ export class CreateRefundManager extends BaseCreateManager<RefundEntity> {
refund_items: refund_items, refund_items: refund_items,
}); });
if (this.data.transaction?.status != STATUS.SETTLED) { const transaction = await this.dataServiceFirstOpt.getOneByOptions({
where: {
id: this.data.transaction.id,
status: STATUS.SETTLED,
},
});
if (!transaction) {
throw new UnprocessableEntityException({ throw new UnprocessableEntityException({
statusCode: HttpStatus.UNPROCESSABLE_ENTITY, statusCode: HttpStatus.UNPROCESSABLE_ENTITY,
message: `Failed! only transaction with status ${STATUS.SETTLED} can be refund`, message: `Failed! only transaction with status ${STATUS.SETTLED} can be refund`,

View File

@ -17,7 +17,14 @@ import { STATUS } from 'src/core/strings/constants/base.constants';
@Injectable() @Injectable()
export class UpdateRefundManager extends BaseUpdateManager<RefundEntity> { export class UpdateRefundManager extends BaseUpdateManager<RefundEntity> {
async validateProcess(): Promise<void> { async validateProcess(): Promise<void> {
if (this.data.transaction?.status != STATUS.SETTLED) { const transaction = await this.dataServiceFirstOpt.getOneByOptions({
where: {
id: this.data.transaction.id,
status: STATUS.SETTLED,
},
});
if (!transaction) {
throw new UnprocessableEntityException({ throw new UnprocessableEntityException({
statusCode: HttpStatus.UNPROCESSABLE_ENTITY, statusCode: HttpStatus.UNPROCESSABLE_ENTITY,
message: `Failed! only transaction with status ${STATUS.SETTLED} can be refund`, message: `Failed! only transaction with status ${STATUS.SETTLED} can be refund`,

View File

@ -12,6 +12,7 @@ import { BatchDeleteRefundManager } from './managers/batch-delete-refund.manager
import { TABLE_NAME } from 'src/core/strings/constants/table.constants'; import { TABLE_NAME } from 'src/core/strings/constants/table.constants';
import { CancelRefundManager } from './managers/cancel-refund.manager'; import { CancelRefundManager } from './managers/cancel-refund.manager';
import { BatchCancelRefundManager } from './managers/batch-cancel-refund.manager'; import { BatchCancelRefundManager } from './managers/batch-cancel-refund.manager';
import { TransactionDataService } from 'src/modules/transaction/transaction/data/services/transaction-data.service';
@Injectable() @Injectable()
export class RefundDataOrchestrator { export class RefundDataOrchestrator {
@ -25,18 +26,27 @@ export class RefundDataOrchestrator {
private batchCancelManager: BatchCancelRefundManager, private batchCancelManager: BatchCancelRefundManager,
private batchConfirmManager: BatchConfirmRefundManager, private batchConfirmManager: BatchConfirmRefundManager,
private serviceData: RefundDataService, private serviceData: RefundDataService,
private transactionDataService: TransactionDataService,
) {} ) {}
async create(data): Promise<RefundEntity> { async create(data): Promise<RefundEntity> {
this.createManager.setData(data); this.createManager.setData(data);
this.createManager.setService(this.serviceData, TABLE_NAME.REFUND); this.createManager.setService(
this.serviceData,
TABLE_NAME.REFUND,
this.transactionDataService,
);
await this.createManager.execute(); await this.createManager.execute();
return this.createManager.getResult(); return this.createManager.getResult();
} }
async update(dataId, data): Promise<RefundEntity> { async update(dataId, data): Promise<RefundEntity> {
this.updateManager.setData(dataId, data); this.updateManager.setData(dataId, data);
this.updateManager.setService(this.serviceData, TABLE_NAME.REFUND); this.updateManager.setService(
this.serviceData,
TABLE_NAME.REFUND,
this.transactionDataService,
);
await this.updateManager.execute(); await this.updateManager.execute();
return this.updateManager.getResult(); return this.updateManager.getResult();
} }

View File

@ -21,12 +21,14 @@ import { RefundModel } from './data/models/refund.model';
import { BatchCancelRefundManager } from './domain/usecases/managers/batch-cancel-refund.manager'; import { BatchCancelRefundManager } from './domain/usecases/managers/batch-cancel-refund.manager';
import { CancelRefundManager } from './domain/usecases/managers/cancel-refund.manager'; import { CancelRefundManager } from './domain/usecases/managers/cancel-refund.manager';
import { RefundItemModel } from './data/models/refund-item.model'; import { RefundItemModel } from './data/models/refund-item.model';
import { TransactionDataService } from '../transaction/data/services/transaction-data.service';
import { TransactionModel } from '../transaction/data/models/transaction.model';
@Module({ @Module({
imports: [ imports: [
ConfigModule.forRoot(), ConfigModule.forRoot(),
TypeOrmModule.forFeature( TypeOrmModule.forFeature(
[RefundModel, RefundItemModel], [RefundModel, RefundItemModel, TransactionModel],
CONNECTION_NAME.DEFAULT, CONNECTION_NAME.DEFAULT,
), ),
CqrsModule, CqrsModule,
@ -46,6 +48,7 @@ import { RefundItemModel } from './data/models/refund-item.model';
RefundDataService, RefundDataService,
RefundReadService, RefundReadService,
TransactionDataService,
RefundDataOrchestrator, RefundDataOrchestrator,
RefundReadOrchestrator, RefundReadOrchestrator,

View File

@ -18,7 +18,7 @@ export class RefundUpdatedHandler
if ( if (
old_data.status != current_data.data || old_data.status != current_data.data ||
event.data.op == OPERATION.DELETE (event.data.op == OPERATION.DELETE && current_data.status != STATUS.DRAFT)
) { ) {
const queryRunner = this.dataService const queryRunner = this.dataService
.getRepository() .getRepository()