From da024606ffc2af845e67b9c7cdf2a9eeea6ea8bd Mon Sep 17 00:00:00 2001 From: shancheas Date: Wed, 30 Apr 2025 07:46:19 +0700 Subject: [PATCH 1/6] feat: add logic to skip save transaction --- .../data/services/sales-price-formula-data.service.ts | 8 ++++++++ .../usecases/handlers/pos-transaction.handler.ts | 11 ++++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/modules/transaction/sales-price-formula/data/services/sales-price-formula-data.service.ts b/src/modules/transaction/sales-price-formula/data/services/sales-price-formula-data.service.ts index d3f667d..de23563 100644 --- a/src/modules/transaction/sales-price-formula/data/services/sales-price-formula-data.service.ts +++ b/src/modules/transaction/sales-price-formula/data/services/sales-price-formula-data.service.ts @@ -30,6 +30,14 @@ export class SalesPriceFormulaDataService extends BaseDataService percentage; + } + async itemTax(id: string) { const item = await this.item.findOne({ relations: ['tenant'], diff --git a/src/modules/transaction/transaction/domain/usecases/handlers/pos-transaction.handler.ts b/src/modules/transaction/transaction/domain/usecases/handlers/pos-transaction.handler.ts index fce39cc..012655d 100644 --- a/src/modules/transaction/transaction/domain/usecases/handlers/pos-transaction.handler.ts +++ b/src/modules/transaction/transaction/domain/usecases/handlers/pos-transaction.handler.ts @@ -104,7 +104,16 @@ export class PosTransactionHandler implements IEventHandler { apmTransactions.setLabel('Code', data?.code); apmTransactions.setLabel('Status', data?.status); - await this.dataService.create(queryRunner, TransactionModel, data); + // Check if this transaction should be sent to the "black hole" (not saved) + // This is only applicable for SETTLED transactions + const shouldSkipSaving = + data.status === STATUS.SETTLED && + (await this.formulaService.sentToBlackHole()); + + // If we shouldn't skip saving, then save the transaction + if (!shouldSkipSaving) { + await this.dataService.create(queryRunner, TransactionModel, data); + } /** * When transaction is cancel, set booking to Pending -- 2.40.1 From 714b075e1d0868cfd1d80befe78b562f1a49f082 Mon Sep 17 00:00:00 2001 From: shancheas Date: Wed, 30 Apr 2025 13:06:36 +0700 Subject: [PATCH 2/6] fix: add transaction setting api --- src/app.module.ts | 6 ++- src/core/strings/constants/table.constants.ts | 1 + ...1745991391299-transaction-setting-model.ts | 17 ++++++++ .../data/models/sales-price-formula.model.ts | 14 ++++++- .../sales-price-formula-data.service.ts | 20 +++++++++- .../sales-price-formula-read.service.ts | 23 ++++++++++- .../entities/sales-price-formula.entity.ts | 5 +++ .../update-transaction-setting.manager.ts | 40 +++++++++++++++++++ .../sales-price-formula-data.orchestrator.ts | 23 ++++++++++- .../sales-price-formula-read.orchestrator.ts | 8 ++++ .../dto/sales-price-formula.dto.ts | 16 ++++++++ .../sales-price-formula-data.controller.ts | 21 ++++++++-- .../sales-price-formula-read.controller.ts | 7 +++- .../sales-price-formula.module.ts | 15 +++++-- src/modules/transaction/tax/tax.module.ts | 7 +++- 15 files changed, 206 insertions(+), 17 deletions(-) create mode 100644 src/database/migrations/1745991391299-transaction-setting-model.ts create mode 100644 src/modules/transaction/sales-price-formula/domain/usecases/managers/update-transaction-setting.manager.ts diff --git a/src/app.module.ts b/src/app.module.ts index 3015ab4..462276d 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -33,7 +33,10 @@ import { SeasonTypeModel } from './modules/season-related/season-type/data/model import { TaxModule } from './modules/transaction/tax/tax.module'; import { TaxModel } from './modules/transaction/tax/data/models/tax.model'; import { SalesPriceFormulaModule } from './modules/transaction/sales-price-formula/sales-price-formula.module'; -import { SalesPriceFormulaModel } from './modules/transaction/sales-price-formula/data/models/sales-price-formula.model'; +import { + SalesPriceFormulaModel, + TransactionSettingModel, +} from './modules/transaction/sales-price-formula/data/models/sales-price-formula.model'; import { ProfitShareFormulaModule } from './modules/transaction/profit-share-formula/profit-share-formula.module'; import { PaymentMethodModule } from './modules/transaction/payment-method/payment-method.module'; import { PaymentMethodModel } from './modules/transaction/payment-method/data/models/payment-method.model'; @@ -137,6 +140,7 @@ import { QueueBucketModel } from './modules/queue/data/models/queue-bucket.model TransactionItemBreakdownModel, TransactionItemTaxModel, TransactionBreakdownTaxModel, + TransactionSettingModel, UserModel, UserLoginModel, diff --git a/src/core/strings/constants/table.constants.ts b/src/core/strings/constants/table.constants.ts index 27eb096..4725e10 100644 --- a/src/core/strings/constants/table.constants.ts +++ b/src/core/strings/constants/table.constants.ts @@ -12,6 +12,7 @@ export enum TABLE_NAME { NEWS = 'news', PAYMENT_METHOD = 'payment_methods', PRICE_FORMULA = 'price_formulas', + TRANSACTION_SETTING = 'transaction_settings', REFUND = 'refunds', REFUND_ITEM = 'refund_items', SEASON_TYPE = 'season_types', diff --git a/src/database/migrations/1745991391299-transaction-setting-model.ts b/src/database/migrations/1745991391299-transaction-setting-model.ts new file mode 100644 index 0000000..f59344a --- /dev/null +++ b/src/database/migrations/1745991391299-transaction-setting-model.ts @@ -0,0 +1,17 @@ +import { MigrationInterface, QueryRunner } from 'typeorm'; + +export class TransactionSettingModel1745991391299 + implements MigrationInterface +{ + name = 'TransactionSettingModel1745991391299'; + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `CREATE TABLE "transaction_settings" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "creator_id" character varying(36), "creator_name" character varying(125), "editor_id" character varying(36), "editor_name" character varying(125), "created_at" bigint NOT NULL, "updated_at" bigint NOT NULL, "value" numeric NOT NULL DEFAULT '100', CONSTRAINT "PK_db7fb38a439358b499ebdee4761" PRIMARY KEY ("id"))`, + ); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`DROP TABLE "transaction_settings"`); + } +} diff --git a/src/modules/transaction/sales-price-formula/data/models/sales-price-formula.model.ts b/src/modules/transaction/sales-price-formula/data/models/sales-price-formula.model.ts index 9787733..eecbf02 100644 --- a/src/modules/transaction/sales-price-formula/data/models/sales-price-formula.model.ts +++ b/src/modules/transaction/sales-price-formula/data/models/sales-price-formula.model.ts @@ -1,5 +1,8 @@ import { TABLE_NAME } from 'src/core/strings/constants/table.constants'; -import { SalesPriceFormulaEntity } from '../../domain/entities/sales-price-formula.entity'; +import { + SalesPriceFormulaEntity, + TransactionSetting, +} from '../../domain/entities/sales-price-formula.entity'; import { Column, Entity } from 'typeorm'; import { BaseModel } from 'src/core/modules/data/model/base.model'; import { FormulaType } from '../../constants'; @@ -31,3 +34,12 @@ export class SalesPriceFormulaModel @Column('numeric', { name: 'example_result', nullable: true }) example_result: number; } + +@Entity(TABLE_NAME.TRANSACTION_SETTING) +export class TransactionSettingModel + extends BaseModel + implements TransactionSetting +{ + @Column('numeric', { default: 100 }) + value: number; +} diff --git a/src/modules/transaction/sales-price-formula/data/services/sales-price-formula-data.service.ts b/src/modules/transaction/sales-price-formula/data/services/sales-price-formula-data.service.ts index de23563..fa15a81 100644 --- a/src/modules/transaction/sales-price-formula/data/services/sales-price-formula-data.service.ts +++ b/src/modules/transaction/sales-price-formula/data/services/sales-price-formula-data.service.ts @@ -1,8 +1,14 @@ import { Injectable, UnprocessableEntityException } from '@nestjs/common'; import { BaseDataService } from 'src/core/modules/data/service/base-data.service'; -import { SalesPriceFormulaEntity } from '../../domain/entities/sales-price-formula.entity'; +import { + SalesPriceFormulaEntity, + TransactionSetting, +} from '../../domain/entities/sales-price-formula.entity'; import { InjectRepository } from '@nestjs/typeorm'; -import { SalesPriceFormulaModel } from '../models/sales-price-formula.model'; +import { + SalesPriceFormulaModel, + TransactionSettingModel, +} from '../models/sales-price-formula.model'; import { CONNECTION_NAME } from 'src/core/strings/constants/base.constants'; import { Repository } from 'typeorm'; import { FormulaType } from '../../constants'; @@ -98,3 +104,13 @@ export class SalesPriceFormulaDataService extends BaseDataService { + constructor( + @InjectRepository(TransactionSettingModel, CONNECTION_NAME.DEFAULT) + private repo: Repository, + ) { + super(repo); + } +} diff --git a/src/modules/transaction/sales-price-formula/data/services/sales-price-formula-read.service.ts b/src/modules/transaction/sales-price-formula/data/services/sales-price-formula-read.service.ts index 8bb9ed8..da538f2 100644 --- a/src/modules/transaction/sales-price-formula/data/services/sales-price-formula-read.service.ts +++ b/src/modules/transaction/sales-price-formula/data/services/sales-price-formula-read.service.ts @@ -1,7 +1,10 @@ import { Injectable } from '@nestjs/common'; import { SalesPriceFormulaEntity } from '../../domain/entities/sales-price-formula.entity'; import { InjectRepository } from '@nestjs/typeorm'; -import { SalesPriceFormulaModel } from '../models/sales-price-formula.model'; +import { + SalesPriceFormulaModel, + TransactionSettingModel, +} from '../models/sales-price-formula.model'; import { CONNECTION_NAME } from 'src/core/strings/constants/base.constants'; import { Repository } from 'typeorm'; import { BaseReadService } from 'src/core/modules/data/service/base-read.service'; @@ -11,7 +14,25 @@ export class SalesPriceFormulaReadService extends BaseReadService, + + @InjectRepository(TransactionSettingModel, CONNECTION_NAME.DEFAULT) + private transactionSetting: Repository, ) { super(repo); } + + async getTransactionSetting(): Promise { + try { + const data = await this.transactionSetting.findOne({ + where: {}, + order: { + created_at: 'DESC', + }, + }); + + return data; + } catch (error) { + throw error; + } + } } diff --git a/src/modules/transaction/sales-price-formula/domain/entities/sales-price-formula.entity.ts b/src/modules/transaction/sales-price-formula/domain/entities/sales-price-formula.entity.ts index aa57e47..bfbbd7e 100644 --- a/src/modules/transaction/sales-price-formula/domain/entities/sales-price-formula.entity.ts +++ b/src/modules/transaction/sales-price-formula/domain/entities/sales-price-formula.entity.ts @@ -1,5 +1,6 @@ import { BaseEntity } from 'src/core/modules/domain/entities/base.entity'; import { FormulaType } from '../../constants'; +import { BaseCoreEntity } from 'src/core/modules/domain/entities/base-core.entity'; export interface SalesPriceFormulaEntity extends BaseEntity { formula_render: any; // json type @@ -16,3 +17,7 @@ export interface AdditionalFormula { formula_string: string; value_for: string; } + +export interface TransactionSetting extends BaseCoreEntity { + value: number; +} diff --git a/src/modules/transaction/sales-price-formula/domain/usecases/managers/update-transaction-setting.manager.ts b/src/modules/transaction/sales-price-formula/domain/usecases/managers/update-transaction-setting.manager.ts new file mode 100644 index 0000000..76e9805 --- /dev/null +++ b/src/modules/transaction/sales-price-formula/domain/usecases/managers/update-transaction-setting.manager.ts @@ -0,0 +1,40 @@ +import { Injectable } from '@nestjs/common'; +import { BaseUpdateManager } from 'src/core/modules/domain/usecase/managers/base-update.manager'; +import { TransactionSetting } from '../../entities/sales-price-formula.entity'; +import { TransactionSettingModel } from '../../../data/models/sales-price-formula.model'; +import { + EventTopics, + columnUniques, + validateRelations, +} from 'src/core/strings/constants/interface.constants'; + +@Injectable() +export class UpdateTransactionSettingManager extends BaseUpdateManager { + async validateProcess(): Promise { + return; + } + + async beforeProcess(): Promise { + return; + } + + async afterProcess(): Promise { + return; + } + + get validateRelations(): validateRelations[] { + return []; + } + + get uniqueColumns(): columnUniques[] { + return []; + } + + get entityTarget(): any { + return TransactionSettingModel; + } + + get eventTopics(): EventTopics[] { + return []; + } +} diff --git a/src/modules/transaction/sales-price-formula/domain/usecases/sales-price-formula-data.orchestrator.ts b/src/modules/transaction/sales-price-formula/domain/usecases/sales-price-formula-data.orchestrator.ts index 70408d4..b6c6fc1 100644 --- a/src/modules/transaction/sales-price-formula/domain/usecases/sales-price-formula-data.orchestrator.ts +++ b/src/modules/transaction/sales-price-formula/domain/usecases/sales-price-formula-data.orchestrator.ts @@ -1,10 +1,17 @@ import { Injectable } from '@nestjs/common'; -import { SalesPriceFormulaDataService } from '../../data/services/sales-price-formula-data.service'; -import { SalesPriceFormulaEntity } from '../entities/sales-price-formula.entity'; +import { + SalesPriceFormulaDataService, + TransactionSettingDataService, +} from '../../data/services/sales-price-formula-data.service'; +import { + SalesPriceFormulaEntity, + TransactionSetting, +} from '../entities/sales-price-formula.entity'; import { UpdateSalesPriceFormulaManager } from './managers/update-sales-price-formula.manager'; import { TABLE_NAME } from 'src/core/strings/constants/table.constants'; import { FormulaType } from '../../constants'; import { TaxDataService } from 'src/modules/transaction/tax/data/services/tax-data.service'; +import { UpdateTransactionSettingManager } from './managers/update-transaction-setting.manager'; @Injectable() export class SalesPriceFormulaDataOrchestrator { @@ -12,6 +19,8 @@ export class SalesPriceFormulaDataOrchestrator { private updateManager: UpdateSalesPriceFormulaManager, private serviceData: SalesPriceFormulaDataService, private taxService: TaxDataService, + private transactionSettingService: TransactionSettingDataService, + private transactionSettingManager: UpdateTransactionSettingManager, ) {} async update(data): Promise { @@ -30,4 +39,14 @@ export class SalesPriceFormulaDataOrchestrator { await this.updateManager.execute(); return this.updateManager.getResult(); } + + async updateTransactionSetting(data): Promise { + this.transactionSettingManager.setData(data.id, data); + this.transactionSettingManager.setService( + this.transactionSettingService, + TABLE_NAME.TRANSACTION_SETTING, + ); + await this.transactionSettingManager.execute(); + return this.transactionSettingManager.getResult(); + } } diff --git a/src/modules/transaction/sales-price-formula/domain/usecases/sales-price-formula-read.orchestrator.ts b/src/modules/transaction/sales-price-formula/domain/usecases/sales-price-formula-read.orchestrator.ts index 4923bcc..1f00184 100644 --- a/src/modules/transaction/sales-price-formula/domain/usecases/sales-price-formula-read.orchestrator.ts +++ b/src/modules/transaction/sales-price-formula/domain/usecases/sales-price-formula-read.orchestrator.ts @@ -17,4 +17,12 @@ export class SalesPriceFormulaReadOrchestrator { await this.detailManager.execute(); return this.detailManager.getResult(); } + + async getTransactionSetting(): Promise { + try { + return await this.serviceData.getTransactionSetting(); + } catch (error) { + throw error; + } + } } diff --git a/src/modules/transaction/sales-price-formula/infrastructure/dto/sales-price-formula.dto.ts b/src/modules/transaction/sales-price-formula/infrastructure/dto/sales-price-formula.dto.ts index 6fab1d8..398f02e 100644 --- a/src/modules/transaction/sales-price-formula/infrastructure/dto/sales-price-formula.dto.ts +++ b/src/modules/transaction/sales-price-formula/infrastructure/dto/sales-price-formula.dto.ts @@ -2,6 +2,7 @@ import { BaseDto } from 'src/core/modules/infrastructure/dto/base.dto'; import { AdditionalFormula, SalesPriceFormulaEntity, + TransactionSetting, } from '../../domain/entities/sales-price-formula.entity'; import { ApiProperty } from '@nestjs/swagger'; import { ValidateIf, ValidateNested } from 'class-validator'; @@ -32,6 +33,21 @@ export class AdditionalFormulaDto implements AdditionalFormula { value_for: string; } +export class TransactionSettingDto implements TransactionSetting { + @ApiProperty({ + type: String, + required: true, + }) + @ValidateIf((body) => body.id) + id?: string; + + @ApiProperty({ + type: Number, + required: true, + }) + value: number; +} + export class SalesPriceFormulaDto extends BaseDto implements SalesPriceFormulaEntity diff --git a/src/modules/transaction/sales-price-formula/infrastructure/sales-price-formula-data.controller.ts b/src/modules/transaction/sales-price-formula/infrastructure/sales-price-formula-data.controller.ts index 272ea32..bae2628 100644 --- a/src/modules/transaction/sales-price-formula/infrastructure/sales-price-formula-data.controller.ts +++ b/src/modules/transaction/sales-price-formula/infrastructure/sales-price-formula-data.controller.ts @@ -1,12 +1,18 @@ -import { Body, Controller, Post } from '@nestjs/common'; +import { Body, Controller, Post, Put } from '@nestjs/common'; import { SalesPriceFormulaDataOrchestrator } from '../domain/usecases/sales-price-formula-data.orchestrator'; -import { SalesPriceFormulaDto } from './dto/sales-price-formula.dto'; +import { + SalesPriceFormulaDto, + TransactionSettingDto, +} from './dto/sales-price-formula.dto'; import { ApiBearerAuth, ApiTags } from '@nestjs/swagger'; -import { SalesPriceFormulaEntity } from '../domain/entities/sales-price-formula.entity'; +import { + SalesPriceFormulaEntity, + TransactionSetting, +} from '../domain/entities/sales-price-formula.entity'; import { Public } from 'src/core/guards'; @ApiTags(`sales price formulas - data`) -@Controller('v1/sales-price-formula') +@Controller(['v1/sales-price-formula', 'v1/transaction-setting']) @Public(false) @ApiBearerAuth('JWT') export class SalesPriceFormulaDataController { @@ -18,4 +24,11 @@ export class SalesPriceFormulaDataController { ): Promise { return await this.orchestrator.update(data); } + + @Put() + async updateTransactionSetting( + @Body() data: TransactionSettingDto, + ): Promise { + return await this.orchestrator.updateTransactionSetting(data); + } } diff --git a/src/modules/transaction/sales-price-formula/infrastructure/sales-price-formula-read.controller.ts b/src/modules/transaction/sales-price-formula/infrastructure/sales-price-formula-read.controller.ts index 1a5de5b..fad9dc9 100644 --- a/src/modules/transaction/sales-price-formula/infrastructure/sales-price-formula-read.controller.ts +++ b/src/modules/transaction/sales-price-formula/infrastructure/sales-price-formula-read.controller.ts @@ -5,7 +5,7 @@ import { ApiBearerAuth, ApiTags } from '@nestjs/swagger'; import { Public } from 'src/core/guards'; @ApiTags(`sales price formulas - read`) -@Controller('v1/sales-price-formula') +@Controller(['v1/sales-price-formula', 'v1/transaction-setting']) @Public(false) @ApiBearerAuth('JWT') export class SalesPriceFormulaReadController { @@ -15,4 +15,9 @@ export class SalesPriceFormulaReadController { async detail(): Promise { return await this.orchestrator.detail(); } + + @Get('detail') + async getTransactionSetting(): Promise { + return await this.orchestrator.getTransactionSetting(); + } } diff --git a/src/modules/transaction/sales-price-formula/sales-price-formula.module.ts b/src/modules/transaction/sales-price-formula/sales-price-formula.module.ts index 02be135..5750c47 100644 --- a/src/modules/transaction/sales-price-formula/sales-price-formula.module.ts +++ b/src/modules/transaction/sales-price-formula/sales-price-formula.module.ts @@ -2,7 +2,10 @@ import { Global, Module } from '@nestjs/common'; import { ConfigModule } from '@nestjs/config'; import { TypeOrmModule } from '@nestjs/typeorm'; import { CONNECTION_NAME } from 'src/core/strings/constants/base.constants'; -import { SalesPriceFormulaDataService } from './data/services/sales-price-formula-data.service'; +import { + SalesPriceFormulaDataService, + TransactionSettingDataService, +} from './data/services/sales-price-formula-data.service'; import { SalesPriceFormulaReadService } from './data/services/sales-price-formula-read.service'; import { SalesPriceFormulaReadController } from './infrastructure/sales-price-formula-read.controller'; import { SalesPriceFormulaReadOrchestrator } from './domain/usecases/sales-price-formula-read.orchestrator'; @@ -11,17 +14,21 @@ import { SalesPriceFormulaDataOrchestrator } from './domain/usecases/sales-price import { CqrsModule } from '@nestjs/cqrs'; import { UpdateSalesPriceFormulaManager } from './domain/usecases/managers/update-sales-price-formula.manager'; import { DetailSalesPriceFormulaManager } from './domain/usecases/managers/detail-sales-price-formula.manager'; -import { SalesPriceFormulaModel } from './data/models/sales-price-formula.model'; +import { + SalesPriceFormulaModel, + TransactionSettingModel, +} from './data/models/sales-price-formula.model'; import { TaxDataService } from '../tax/data/services/tax-data.service'; import { TaxModel } from '../tax/data/models/tax.model'; import { ItemModel } from 'src/modules/item-related/item/data/models/item.model'; +import { UpdateTransactionSettingManager } from './domain/usecases/managers/update-transaction-setting.manager'; @Global() @Module({ imports: [ ConfigModule.forRoot(), TypeOrmModule.forFeature( - [SalesPriceFormulaModel, TaxModel, ItemModel], + [SalesPriceFormulaModel, TransactionSettingModel, TaxModel, ItemModel], CONNECTION_NAME.DEFAULT, ), CqrsModule, @@ -33,10 +40,12 @@ import { ItemModel } from 'src/modules/item-related/item/data/models/item.model' providers: [ DetailSalesPriceFormulaManager, UpdateSalesPriceFormulaManager, + UpdateTransactionSettingManager, TaxDataService, SalesPriceFormulaDataService, SalesPriceFormulaReadService, + TransactionSettingDataService, SalesPriceFormulaDataOrchestrator, SalesPriceFormulaReadOrchestrator, diff --git a/src/modules/transaction/tax/tax.module.ts b/src/modules/transaction/tax/tax.module.ts index 97be019..bab9bb6 100644 --- a/src/modules/transaction/tax/tax.module.ts +++ b/src/modules/transaction/tax/tax.module.ts @@ -23,14 +23,17 @@ import { BatchConfirmTaxManager } from './domain/usecases/managers/batch-confirm import { BatchInactiveTaxManager } from './domain/usecases/managers/batch-inactive-tax.manager'; import { TaxModel } from './data/models/tax.model'; import { SalesPriceFormulaReadService } from '../sales-price-formula/data/services/sales-price-formula-read.service'; -import { SalesPriceFormulaModel } from '../sales-price-formula/data/models/sales-price-formula.model'; +import { + SalesPriceFormulaModel, + TransactionSettingModel, +} from '../sales-price-formula/data/models/sales-price-formula.model'; import { IndexTaxFormulaManager } from './domain/usecases/managers/index-tax-formula.manager'; @Module({ imports: [ ConfigModule.forRoot(), TypeOrmModule.forFeature( - [TaxModel, SalesPriceFormulaModel], + [TaxModel, SalesPriceFormulaModel, TransactionSettingModel], CONNECTION_NAME.DEFAULT, ), CqrsModule, -- 2.40.1 From b91080906eac2ebceb21d162f303f94bf9b83e4f Mon Sep 17 00:00:00 2001 From: shancheas Date: Fri, 2 May 2025 07:33:08 +0700 Subject: [PATCH 3/6] feat: change save factor formula --- .../couch/data/services/couch.service.ts | 30 ++++++++++++ .../sales-price-formula-data.service.ts | 46 +++++++++++++++++-- .../sales-price-formula.module.ts | 11 ++++- .../transaction/transaction.module.ts | 9 +++- 4 files changed, 89 insertions(+), 7 deletions(-) diff --git a/src/modules/configuration/couch/data/services/couch.service.ts b/src/modules/configuration/couch/data/services/couch.service.ts index 3aa6132..c92a38b 100644 --- a/src/modules/configuration/couch/data/services/couch.service.ts +++ b/src/modules/configuration/couch/data/services/couch.service.ts @@ -97,6 +97,36 @@ export class CouchService { } } + public async totalTodayTransactions(database = 'transaction') { + try { + const nano = this.nanoInstance; + const db = nano.use(database); + + // Get today's start timestamp (midnight) + const today = new Date(); + today.setHours(0, 0, 0, 0); + const todayTimestamp = today.getTime(); + + // Query for documents created today + const selector = { + created_at: { + $gte: todayTimestamp, + }, + }; + + const result = await db.find({ + selector: selector, + fields: ['_id'], + }); + + return result.docs.length; + } catch (error) { + console.log(error); + apm.captureError(error); + return 0; + } + } + getUnixTimestampLast7Days() { const date = new Date(); date.setDate(date.getDate() - 4); diff --git a/src/modules/transaction/sales-price-formula/data/services/sales-price-formula-data.service.ts b/src/modules/transaction/sales-price-formula/data/services/sales-price-formula-data.service.ts index fa15a81..9919cb7 100644 --- a/src/modules/transaction/sales-price-formula/data/services/sales-price-formula-data.service.ts +++ b/src/modules/transaction/sales-price-formula/data/services/sales-price-formula-data.service.ts @@ -1,4 +1,8 @@ -import { Injectable, UnprocessableEntityException } from '@nestjs/common'; +import { + Injectable, + Logger, + UnprocessableEntityException, +} from '@nestjs/common'; import { BaseDataService } from 'src/core/modules/data/service/base-data.service'; import { SalesPriceFormulaEntity, @@ -10,10 +14,12 @@ import { TransactionSettingModel, } from '../models/sales-price-formula.model'; import { CONNECTION_NAME } from 'src/core/strings/constants/base.constants'; -import { Repository } from 'typeorm'; +import { MoreThan, Repository } from 'typeorm'; import { FormulaType } from '../../constants'; import { TaxModel } from 'src/modules/transaction/tax/data/models/tax.model'; import { ItemModel } from 'src/modules/item-related/item/data/models/item.model'; +import { TransactionModel } from 'src/modules/transaction/transaction/data/models/transaction.model'; +import { CouchService } from 'src/modules/configuration/couch/data/services/couch.service'; @Injectable() export class SalesPriceFormulaDataService extends BaseDataService { @@ -24,6 +30,11 @@ export class SalesPriceFormulaDataService extends BaseDataService, @InjectRepository(ItemModel, CONNECTION_NAME.DEFAULT) private item: Repository, + @InjectRepository(TransactionSettingModel, CONNECTION_NAME.DEFAULT) + private transactionSetting: Repository, + @InjectRepository(TransactionModel, CONNECTION_NAME.DEFAULT) + private transaction: Repository, + private couchService: CouchService, ) { super(repo); } @@ -37,11 +48,36 @@ export class SalesPriceFormulaDataService extends BaseDataService percentage; + Logger.log(`Factor ${transactionPercentage} from ${percentage}`); + + return transactionPercentage > percentage; + } + + async dataSaveFactor() { + const today = new Date(); + today.setHours(0, 0, 0, 0); + + const todayTimestamp = today.getTime(); + + const totalTransactions = await this.transaction.count({ + where: { + created_at: MoreThan(todayTimestamp), + }, + }); + + const couchTransaction = await this.couchService.totalTodayTransactions(); + + if (couchTransaction == 0) return 0; + + const factor = (totalTransactions / couchTransaction) * 100; + + return factor; } async itemTax(id: string) { diff --git a/src/modules/transaction/sales-price-formula/sales-price-formula.module.ts b/src/modules/transaction/sales-price-formula/sales-price-formula.module.ts index 5750c47..8066a77 100644 --- a/src/modules/transaction/sales-price-formula/sales-price-formula.module.ts +++ b/src/modules/transaction/sales-price-formula/sales-price-formula.module.ts @@ -22,13 +22,21 @@ import { TaxDataService } from '../tax/data/services/tax-data.service'; import { TaxModel } from '../tax/data/models/tax.model'; import { ItemModel } from 'src/modules/item-related/item/data/models/item.model'; import { UpdateTransactionSettingManager } from './domain/usecases/managers/update-transaction-setting.manager'; +import { TransactionModel } from '../transaction/data/models/transaction.model'; +import { CouchService } from 'src/modules/configuration/couch/data/services/couch.service'; @Global() @Module({ imports: [ ConfigModule.forRoot(), TypeOrmModule.forFeature( - [SalesPriceFormulaModel, TransactionSettingModel, TaxModel, ItemModel], + [ + SalesPriceFormulaModel, + TransactionSettingModel, + TransactionModel, + TaxModel, + ItemModel, + ], CONNECTION_NAME.DEFAULT, ), CqrsModule, @@ -49,6 +57,7 @@ import { UpdateTransactionSettingManager } from './domain/usecases/managers/upda SalesPriceFormulaDataOrchestrator, SalesPriceFormulaReadOrchestrator, + CouchService, ], exports: [SalesPriceFormulaDataService, SalesPriceFormulaReadService], }) diff --git a/src/modules/transaction/transaction/transaction.module.ts b/src/modules/transaction/transaction/transaction.module.ts index e08f2db..54f96c3 100644 --- a/src/modules/transaction/transaction/transaction.module.ts +++ b/src/modules/transaction/transaction/transaction.module.ts @@ -32,7 +32,10 @@ import { BatchConfirmDataTransactionManager } from './domain/usecases/managers/b import { PosTransactionHandler } from './domain/usecases/handlers/pos-transaction.handler'; import { TaxDataService } from '../tax/data/services/tax-data.service'; import { SalesPriceFormulaDataService } from '../sales-price-formula/data/services/sales-price-formula-data.service'; -import { SalesPriceFormulaModel } from '../sales-price-formula/data/models/sales-price-formula.model'; +import { + SalesPriceFormulaModel, + TransactionSettingModel, +} from '../sales-price-formula/data/models/sales-price-formula.model'; import { TaxModel } from '../tax/data/models/tax.model'; import { SettledTransactionHandler } from './domain/usecases/handlers/settled-transaction.handler'; import { RefundUpdatedHandler } from './domain/usecases/handlers/refund-update.handler'; @@ -43,6 +46,7 @@ import { PaymentMethodModel } from '../payment-method/data/models/payment-method import { TransactionDemographyModel } from './data/models/transaction-demography.model'; import { PriceCalculator } from './domain/usecases/calculator/price.calculator'; import { ItemModel } from 'src/modules/item-related/item/data/models/item.model'; +import { CouchService } from 'src/modules/configuration/couch/data/services/couch.service'; @Module({ exports: [TransactionReadService], @@ -57,6 +61,7 @@ import { ItemModel } from 'src/modules/item-related/item/data/models/item.model' TransactionTaxModel, TransactionItemTaxModel, TransactionBreakdownTaxModel, + TransactionSettingModel, TaxModel, SalesPriceFormulaModel, PaymentMethodModel, @@ -96,6 +101,8 @@ import { ItemModel } from 'src/modules/item-related/item/data/models/item.model' TransactionDataOrchestrator, TransactionReadOrchestrator, + + CouchService, ], }) export class TransactionModule {} -- 2.40.1 From 66d76634b7ff12e429606bd140c527cf567191df Mon Sep 17 00:00:00 2001 From: shancheas Date: Fri, 2 May 2025 09:02:45 +0700 Subject: [PATCH 4/6] fix: find transactionSettingData with parameter --- .../data/services/sales-price-formula-data.service.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/modules/transaction/sales-price-formula/data/services/sales-price-formula-data.service.ts b/src/modules/transaction/sales-price-formula/data/services/sales-price-formula-data.service.ts index 9919cb7..c38bc82 100644 --- a/src/modules/transaction/sales-price-formula/data/services/sales-price-formula-data.service.ts +++ b/src/modules/transaction/sales-price-formula/data/services/sales-price-formula-data.service.ts @@ -48,7 +48,9 @@ export class SalesPriceFormulaDataService extends BaseDataService Date: Fri, 2 May 2025 11:25:33 +0700 Subject: [PATCH 5/6] fix: make transaction setting public --- .../infrastructure/sales-price-formula-data.controller.ts | 1 + .../infrastructure/sales-price-formula-read.controller.ts | 1 + 2 files changed, 2 insertions(+) diff --git a/src/modules/transaction/sales-price-formula/infrastructure/sales-price-formula-data.controller.ts b/src/modules/transaction/sales-price-formula/infrastructure/sales-price-formula-data.controller.ts index bae2628..cada99d 100644 --- a/src/modules/transaction/sales-price-formula/infrastructure/sales-price-formula-data.controller.ts +++ b/src/modules/transaction/sales-price-formula/infrastructure/sales-price-formula-data.controller.ts @@ -25,6 +25,7 @@ export class SalesPriceFormulaDataController { return await this.orchestrator.update(data); } + @Public(true) @Put() async updateTransactionSetting( @Body() data: TransactionSettingDto, diff --git a/src/modules/transaction/sales-price-formula/infrastructure/sales-price-formula-read.controller.ts b/src/modules/transaction/sales-price-formula/infrastructure/sales-price-formula-read.controller.ts index fad9dc9..4ab1255 100644 --- a/src/modules/transaction/sales-price-formula/infrastructure/sales-price-formula-read.controller.ts +++ b/src/modules/transaction/sales-price-formula/infrastructure/sales-price-formula-read.controller.ts @@ -16,6 +16,7 @@ export class SalesPriceFormulaReadController { return await this.orchestrator.detail(); } + @Public(true) @Get('detail') async getTransactionSetting(): Promise { return await this.orchestrator.getTransactionSetting(); -- 2.40.1 From 94baf956dd02d8e7180ea4375f38bae74c9cd29a Mon Sep 17 00:00:00 2001 From: shancheas Date: Fri, 9 May 2025 06:44:17 +0700 Subject: [PATCH 6/6] feat: add env to active skip transaction feature --- .../domain/usecases/handlers/pos-transaction.handler.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/modules/transaction/transaction/domain/usecases/handlers/pos-transaction.handler.ts b/src/modules/transaction/transaction/domain/usecases/handlers/pos-transaction.handler.ts index 012655d..41e5128 100644 --- a/src/modules/transaction/transaction/domain/usecases/handlers/pos-transaction.handler.ts +++ b/src/modules/transaction/transaction/domain/usecases/handlers/pos-transaction.handler.ts @@ -31,6 +31,9 @@ export class PosTransactionHandler implements IEventHandler { ) {} async handle(event: ChangeDocEvent) { + const envSkipTransaction = process.env.SKIP_TRANSACTION_FEATURE ?? 'false'; + const activeSkipTransaction = envSkipTransaction == 'true'; + const apmTransactions = apm.startTransaction( `ChangeDocEvent ${event?.data?.database}`, 'handler', @@ -107,6 +110,7 @@ export class PosTransactionHandler implements IEventHandler { // Check if this transaction should be sent to the "black hole" (not saved) // This is only applicable for SETTLED transactions const shouldSkipSaving = + activeSkipTransaction && data.status === STATUS.SETTLED && (await this.formulaService.sentToBlackHole()); -- 2.40.1