From f2bc4dd46d3766ce56a05d7ab7d20d51e752108c Mon Sep 17 00:00:00 2001 From: shancheas Date: Tue, 20 Aug 2024 11:52:20 +0700 Subject: [PATCH 1/6] feat: add breakdown item to transaction --- src/app.module.ts | 6 ++- src/core/strings/constants/table.constants.ts | 1 + ...27202672-add-breakdown-item-transaction.ts | 23 +++++++++++ .../data/models/transaction-item.model.ts | 41 ++++++++++++++++++- .../entities/transaction-item.entity.ts | 9 ++++ .../domain/entities/transaction.entity.ts | 3 ++ .../managers/detail-transaction.manager.ts | 2 + .../helpers/mapping-transaction.helper.ts | 10 +++++ .../transaction/transaction.module.ts | 6 ++- 9 files changed, 98 insertions(+), 3 deletions(-) create mode 100644 src/database/migrations/1724127202672-add-breakdown-item-transaction.ts diff --git a/src/app.module.ts b/src/app.module.ts index 0a6811f..c21e956 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -44,7 +44,10 @@ import { ItemRateModel } from './modules/item-related/item-rate/data/models/item import { GoogleCalendarModule } from './modules/configuration/google-calendar/google-calendar.module'; import { TransactionModule } from './modules/transaction/transaction/transaction.module'; import { TransactionModel } from './modules/transaction/transaction/data/models/transaction.model'; -import { TransactionItemModel } from './modules/transaction/transaction/data/models/transaction-item.model'; +import { + TransactionItemBreakdownModel, + TransactionItemModel, +} from './modules/transaction/transaction/data/models/transaction-item.model'; import { TransactionTaxModel } from './modules/transaction/transaction/data/models/transaction-tax.model'; import { ReconciliationModule } from './modules/transaction/reconciliation/reconciliation.module'; import { ReportModule } from './modules/reports/report/report.module'; @@ -111,6 +114,7 @@ import { TransactionDemographyModel } from './modules/transaction/transaction/da TransactionItemModel, TransactionTaxModel, TransactionDemographyModel, + TransactionItemBreakdownModel, UserModel, VipCategoryModel, VipCodeModel, diff --git a/src/core/strings/constants/table.constants.ts b/src/core/strings/constants/table.constants.ts index 2417a09..9fa6af6 100644 --- a/src/core/strings/constants/table.constants.ts +++ b/src/core/strings/constants/table.constants.ts @@ -20,6 +20,7 @@ export enum TABLE_NAME { TENANT = 'tenants', TRANSACTION = 'transactions', TRANSACTION_ITEM = 'transaction_items', + TRANSACTION_ITEM_BREAKDOWN = 'transaction_item_breakdowns', TRANSACTION_TAX = 'transaction_taxes', TRANSACTION_DEMOGRAPHY = 'transaction_demographies', USER = 'users', diff --git a/src/database/migrations/1724127202672-add-breakdown-item-transaction.ts b/src/database/migrations/1724127202672-add-breakdown-item-transaction.ts new file mode 100644 index 0000000..1e8fb6b --- /dev/null +++ b/src/database/migrations/1724127202672-add-breakdown-item-transaction.ts @@ -0,0 +1,23 @@ +import { MigrationInterface, QueryRunner } from 'typeorm'; + +export class AddBreakdownItemTransaction1724127202672 + implements MigrationInterface +{ + name = 'AddBreakdownItemTransaction1724127202672'; + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `CREATE TABLE "transaction_item_breakdowns" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "item_id" character varying NOT NULL, "item_name" character varying NOT NULL, "hpp" bigint, "base_price" bigint, "item_rates" bigint, "transaction_item_id" uuid, CONSTRAINT "PK_e04a30c648d3ba8778e9fb67fdd" PRIMARY KEY ("id"))`, + ); + await queryRunner.query( + `ALTER TABLE "transaction_item_breakdowns" ADD CONSTRAINT "FK_b8c63b1f3ecace500587da713ae" FOREIGN KEY ("transaction_item_id") REFERENCES "transaction_items"("id") ON DELETE CASCADE ON UPDATE CASCADE`, + ); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `ALTER TABLE "transaction_item_breakdowns" DROP CONSTRAINT "FK_b8c63b1f3ecace500587da713ae"`, + ); + await queryRunner.query(`DROP TABLE "transaction_item_breakdowns"`); + } +} 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 78807dd..9a0560c 100644 --- a/src/modules/transaction/transaction/data/models/transaction-item.model.ts +++ b/src/modules/transaction/transaction/data/models/transaction-item.model.ts @@ -1,7 +1,10 @@ import { TABLE_NAME } from 'src/core/strings/constants/table.constants'; import { Column, Entity, JoinColumn, ManyToOne, OneToMany } from 'typeorm'; import { BaseCoreModel } from 'src/core/modules/data/model/base-core.model'; -import { TransactionItemEntity } from '../../domain/entities/transaction-item.entity'; +import { + TransactionBundlingItemEntity, + TransactionItemEntity, +} from '../../domain/entities/transaction-item.entity'; import { TransactionModel } from './transaction.model'; import { RefundItemModel } from 'src/modules/transaction/refund/data/models/refund-item.model'; @@ -86,4 +89,40 @@ export class TransactionItemModel onUpdate: 'CASCADE', }) refunds: RefundItemModel[]; + + @OneToMany( + () => TransactionItemBreakdownModel, + (model) => model.transaction_item, + { + cascade: true, + onDelete: 'CASCADE', + onUpdate: 'CASCADE', + }, + ) + bundling_items: TransactionItemBreakdownModel[]; +} + +@Entity(TABLE_NAME.TRANSACTION_ITEM_BREAKDOWN) +export class TransactionItemBreakdownModel extends BaseCoreModel { + @Column('varchar') + item_id: string; + + @Column('varchar') + item_name: string; + + @Column('bigint', { nullable: true }) + hpp: number; + + @Column('bigint', { nullable: true }) + base_price: number; + + @Column('bigint', { nullable: true }) + item_rates: number; + + @ManyToOne(() => TransactionItemModel, (model) => model.bundling_items, { + onDelete: 'CASCADE', + onUpdate: 'CASCADE', + }) + @JoinColumn({ name: 'transaction_item_id' }) + transaction_item: TransactionItemModel; } 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 68d63cb..9d3a575 100644 --- a/src/modules/transaction/transaction/domain/entities/transaction-item.entity.ts +++ b/src/modules/transaction/transaction/domain/entities/transaction-item.entity.ts @@ -25,4 +25,13 @@ export interface TransactionItemEntity extends BaseCoreEntity { qty: number; qty_remaining: number; taxes: string; + bundling_items?: TransactionBundlingItemEntity[]; +} + +export interface TransactionBundlingItemEntity extends BaseCoreEntity { + item_id: string; + item_name: string; + hpp: number; + base_price: number; + item_rates: number; } diff --git a/src/modules/transaction/transaction/domain/entities/transaction.entity.ts b/src/modules/transaction/transaction/domain/entities/transaction.entity.ts index aa1814b..d9d507b 100644 --- a/src/modules/transaction/transaction/domain/entities/transaction.entity.ts +++ b/src/modules/transaction/transaction/domain/entities/transaction.entity.ts @@ -5,6 +5,7 @@ import { TransactionUserType, } from '../../constants'; import { STATUS } from 'src/core/strings/constants/base.constants'; +import { TransactionItemEntity } from './transaction-item.entity'; export interface TransactionEntity extends BaseStatusEntity { // general info @@ -84,4 +85,6 @@ export interface TransactionEntity extends BaseStatusEntity { calendar_id?: string; calendar_link?: string; + + items: TransactionItemEntity[]; } diff --git a/src/modules/transaction/transaction/domain/usecases/managers/detail-transaction.manager.ts b/src/modules/transaction/transaction/domain/usecases/managers/detail-transaction.manager.ts index 806b602..d577c4d 100644 --- a/src/modules/transaction/transaction/domain/usecases/managers/detail-transaction.manager.ts +++ b/src/modules/transaction/transaction/domain/usecases/managers/detail-transaction.manager.ts @@ -27,6 +27,7 @@ export class DetailTransactionManager extends BaseDetailManager bundling.name, ), + bundling_items: item.item.bundling_items?.map((bundling) => { + return { + ...bundling, + item_id: bundling.id, + item_name: bundling.name, + id: uuidv4(), + }; + }), item_tenant_id: item.item.tenant?.id ?? null, item_tenant_name: item.item.tenant?.id ?? null, diff --git a/src/modules/transaction/transaction/transaction.module.ts b/src/modules/transaction/transaction/transaction.module.ts index 2071ea0..f4a2e61 100644 --- a/src/modules/transaction/transaction/transaction.module.ts +++ b/src/modules/transaction/transaction/transaction.module.ts @@ -18,7 +18,10 @@ import { DetailTransactionManager } from './domain/usecases/managers/detail-tran import { BatchDeleteTransactionManager } from './domain/usecases/managers/batch-delete-transaction.manager'; import { BatchConfirmTransactionManager } from './domain/usecases/managers/batch-confirm-transaction.manager'; import { TransactionModel } from './data/models/transaction.model'; -import { TransactionItemModel } from './data/models/transaction-item.model'; +import { + TransactionItemBreakdownModel, + TransactionItemModel, +} from './data/models/transaction-item.model'; import { TransactionTaxModel } from './data/models/transaction-tax.model'; import { CancelTransactionManager } from './domain/usecases/managers/cancel-transaction.manager'; import { BatchCancelTransactionManager } from './domain/usecases/managers/batch-cancel-transaction.manager'; @@ -46,6 +49,7 @@ import { TransactionDemographyModel } from './data/models/transaction-demography TransactionModel, TransactionItemModel, TransactionDemographyModel, + TransactionItemBreakdownModel, TransactionTaxModel, TaxModel, SalesPriceFormulaModel, From 9a72c40984db79f643134463ae8c56a2b6263635 Mon Sep 17 00:00:00 2001 From: shancheas Date: Tue, 20 Aug 2024 12:05:36 +0700 Subject: [PATCH 2/6] feat: add bundling item to refund --- .../refund/domain/usecases/managers/detail-refund.manager.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/modules/transaction/refund/domain/usecases/managers/detail-refund.manager.ts b/src/modules/transaction/refund/domain/usecases/managers/detail-refund.manager.ts index b5f332e..722f94b 100644 --- a/src/modules/transaction/refund/domain/usecases/managers/detail-refund.manager.ts +++ b/src/modules/transaction/refund/domain/usecases/managers/detail-refund.manager.ts @@ -28,6 +28,7 @@ export class DetailRefundManager extends BaseDetailManager { selectRelations: [ 'transaction', 'transaction.items', + 'items.bundling_items', 'items.refunds item_refunds', 'item_refunds.refund item_refunds_refund', ], @@ -60,6 +61,7 @@ export class DetailRefundManager extends BaseDetailManager { 'transaction', 'items', + 'bundling_items', 'item_refunds', 'item_refunds_refund.id', 'item_refunds_refund.status', From fc15cb9db6588d74925bcf261794b9135a479af2 Mon Sep 17 00:00:00 2001 From: shancheas Date: Tue, 20 Aug 2024 13:22:04 +0700 Subject: [PATCH 3/6] fix: update transaction --- .../usecases/managers/helpers/mapping-transaction.helper.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/modules/transaction/transaction/domain/usecases/managers/helpers/mapping-transaction.helper.ts b/src/modules/transaction/transaction/domain/usecases/managers/helpers/mapping-transaction.helper.ts index 855e9b4..bedc6ec 100644 --- a/src/modules/transaction/transaction/domain/usecases/managers/helpers/mapping-transaction.helper.ts +++ b/src/modules/transaction/transaction/domain/usecases/managers/helpers/mapping-transaction.helper.ts @@ -190,6 +190,7 @@ export function mappingRevertTransaction(data, type) { (bundling) => bundling.name, ), bundling_items: item.item.bundling_items?.map((bundling) => { + if (bundling.item_id) return bundling; return { ...bundling, item_id: bundling.id, From 8abdbb7b55e2e0a27a5dafeb503413929d7a7df9 Mon Sep 17 00:00:00 2001 From: shancheas Date: Tue, 20 Aug 2024 15:44:32 +0700 Subject: [PATCH 4/6] fix: add mix nationality to demography --- .../migrations/1723716561482-fix-demography-nationality.ts | 2 +- src/modules/transaction/transaction/constants.ts | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/database/migrations/1723716561482-fix-demography-nationality.ts b/src/database/migrations/1723716561482-fix-demography-nationality.ts index d893bad..8e23f74 100644 --- a/src/database/migrations/1723716561482-fix-demography-nationality.ts +++ b/src/database/migrations/1723716561482-fix-demography-nationality.ts @@ -13,7 +13,7 @@ export class FixDemographyNationality1723716561482 `ALTER TABLE "transaction_demographies" DROP COLUMN "foreign"`, ); await queryRunner.query( - `CREATE TYPE "public"."transaction_demographies_nationality_enum" AS ENUM('local', 'foreign')`, + `CREATE TYPE "public"."transaction_demographies_nationality_enum" AS ENUM('local', 'foreign', 'mix')`, ); await queryRunner.query( `ALTER TABLE "transaction_demographies" ADD "nationality" "public"."transaction_demographies_nationality_enum" NOT NULL DEFAULT 'local'`, diff --git a/src/modules/transaction/transaction/constants.ts b/src/modules/transaction/transaction/constants.ts index 41052f7..d289f01 100644 --- a/src/modules/transaction/transaction/constants.ts +++ b/src/modules/transaction/transaction/constants.ts @@ -33,4 +33,5 @@ export const TransactionModels = [ export enum DemographyNationality { LOCAL = 'local', FOREIGN = 'foreign', + MIX = 'mix', } From 7c7b121b493822febae105376156e594f9eef546 Mon Sep 17 00:00:00 2001 From: shancheas Date: Tue, 20 Aug 2024 17:16:14 +0700 Subject: [PATCH 5/6] fix: fix break down bundling item rates --- .../data/services/item-rate-data.service.ts | 52 ++++++++++++++++++- .../usecases/item-rate-data.orchestrator.ts | 1 - .../managers/update-item-rate.manager.ts | 22 ++++++++ .../item-rate-data.controller.ts | 4 +- .../item-rate/item-rate.module.ts | 3 +- 5 files changed, 76 insertions(+), 6 deletions(-) diff --git a/src/modules/item-related/item-rate/data/services/item-rate-data.service.ts b/src/modules/item-related/item-rate/data/services/item-rate-data.service.ts index 1c8862f..3e7668a 100644 --- a/src/modules/item-related/item-rate/data/services/item-rate-data.service.ts +++ b/src/modules/item-related/item-rate/data/services/item-rate-data.service.ts @@ -4,14 +4,64 @@ import { ItemRateEntity } from '../../domain/entities/item-rate.entity'; import { InjectRepository } from '@nestjs/typeorm'; import { ItemRateModel } from '../models/item-rate.model'; import { CONNECTION_NAME } from 'src/core/strings/constants/base.constants'; -import { Repository } from 'typeorm'; +import { In, Repository } from 'typeorm'; +import { ItemModel } from 'src/modules/item-related/item/data/models/item.model'; @Injectable() export class ItemRateDataService extends BaseDataService { constructor( @InjectRepository(ItemRateModel, CONNECTION_NAME.DEFAULT) private repo: Repository, + @InjectRepository(ItemModel, CONNECTION_NAME.DEFAULT) + private itemRepo: Repository, ) { super(repo); } + + async itemsRateTotal(season_id: string, items: string[]): Promise { + const rates = await this.repo.find({ + where: { + season_period_id: season_id, + item_id: In(items), + }, + }); + + return rates.reduce((total, current) => total + Number(current.price), 0); + } + + async updateRatesBySeasonItem( + season_id: string, + item_id: string, + price: number, + ): Promise { + this.repo.update( + { + season_period_id: season_id, + item_id, + }, + { price }, + ); + } + + async findBundlingByItem(item_id: string): Promise { + const bundlings = await this.itemRepo.find({ + where: { + breakdown_bundling: true, + bundling_items: { + id: item_id, + }, + }, + }); + + return Promise.all( + await bundlings.map(async (bundling) => { + return await this.itemRepo.findOne({ + relations: ['bundling_items'], + where: { + id: bundling.id, + }, + }); + }), + ); + } } diff --git a/src/modules/item-related/item-rate/domain/usecases/item-rate-data.orchestrator.ts b/src/modules/item-related/item-rate/domain/usecases/item-rate-data.orchestrator.ts index f383d6f..b24ff1c 100644 --- a/src/modules/item-related/item-rate/domain/usecases/item-rate-data.orchestrator.ts +++ b/src/modules/item-related/item-rate/domain/usecases/item-rate-data.orchestrator.ts @@ -5,7 +5,6 @@ import { ItemRateEntity } from '../entities/item-rate.entity'; import { DeleteItemRateManager } from './managers/delete-item-rate.manager'; import { UpdateItemRateManager } from './managers/update-item-rate.manager'; import { BaseDataOrchestrator } from 'src/core/modules/domain/usecase/orchestrators/base-data.orchestrator'; -import { STATUS } from 'src/core/strings/constants/base.constants'; import { BatchResult } from 'src/core/response/domain/ok-response.interface'; import { BatchDeleteItemRateManager } from './managers/batch-delete-item-rate.manager'; import { TABLE_NAME } from 'src/core/strings/constants/table.constants'; diff --git a/src/modules/item-related/item-rate/domain/usecases/managers/update-item-rate.manager.ts b/src/modules/item-related/item-rate/domain/usecases/managers/update-item-rate.manager.ts index 42c13c5..5768aa4 100644 --- a/src/modules/item-related/item-rate/domain/usecases/managers/update-item-rate.manager.ts +++ b/src/modules/item-related/item-rate/domain/usecases/managers/update-item-rate.manager.ts @@ -20,6 +20,7 @@ export class UpdateItemRateManager extends BaseUpdateManager { } async afterProcess(): Promise { + this.updateBundlingBreakdown(this.dataId); return; } @@ -42,4 +43,25 @@ export class UpdateItemRateManager extends BaseUpdateManager { }, ]; } + + async updateBundlingBreakdown(id: string) { + const { item_id, season_period_id } = + await this.dataService.getOneByOptions({ + where: { id }, + }); + const bundlings = await this.dataService.findBundlingByItem(item_id); + + for (const bundling of bundlings) { + const ids = bundling.bundling_items.map((item) => item.id); + const totalRates = await this.dataService.itemsRateTotal( + season_period_id, + ids, + ); + this.dataService.updateRatesBySeasonItem( + season_period_id, + bundling.id, + totalRates, + ); + } + } } diff --git a/src/modules/item-related/item-rate/infrastructure/item-rate-data.controller.ts b/src/modules/item-related/item-rate/infrastructure/item-rate-data.controller.ts index 82dfa2b..d8252a3 100644 --- a/src/modules/item-related/item-rate/infrastructure/item-rate-data.controller.ts +++ b/src/modules/item-related/item-rate/infrastructure/item-rate-data.controller.ts @@ -1,11 +1,9 @@ -import { Body, Controller, Delete, Param, Post, Put } from '@nestjs/common'; +import { Body, Controller, Get, Param, Put } from '@nestjs/common'; import { ItemRateDataOrchestrator } from '../domain/usecases/item-rate-data.orchestrator'; import { ItemRateDto } from './dto/item-rate.dto'; import { MODULE_NAME } from 'src/core/strings/constants/module.constants'; import { ApiBearerAuth, ApiTags } from '@nestjs/swagger'; import { ItemRateEntity } from '../domain/entities/item-rate.entity'; -import { BatchResult } from 'src/core/response/domain/ok-response.interface'; -import { BatchIdsDto } from 'src/core/modules/infrastructure/dto/base-batch.dto'; import { Public } from 'src/core/guards'; @ApiTags(`${MODULE_NAME.ITEM_RATE.split('-').join(' ')} - data`) diff --git a/src/modules/item-related/item-rate/item-rate.module.ts b/src/modules/item-related/item-rate/item-rate.module.ts index c0012e3..c4acfc1 100644 --- a/src/modules/item-related/item-rate/item-rate.module.ts +++ b/src/modules/item-related/item-rate/item-rate.module.ts @@ -19,13 +19,14 @@ import { ItemRateModel } from './data/models/item-rate.model'; import { SeasonPeriodHolidayHandler } from './domain/usecases/handlers/item-created.handler'; import { SeasonPeriodDataService } from 'src/modules/season-related/season-period/data/services/season-period-data.service'; import { SeasonPeriodModel } from 'src/modules/season-related/season-period/data/models/season-period.model'; +import { ItemModel } from '../item/data/models/item.model'; @Global() @Module({ imports: [ ConfigModule.forRoot(), TypeOrmModule.forFeature( - [ItemRateModel, SeasonPeriodModel], + [ItemRateModel, SeasonPeriodModel, ItemModel], CONNECTION_NAME.DEFAULT, ), CqrsModule, From 009576c841c97612695e74eded35a253c6a2b953 Mon Sep 17 00:00:00 2001 From: shancheas Date: Tue, 20 Aug 2024 18:37:10 +0700 Subject: [PATCH 6/6] feat: add bundling relation for couch db --- .../usecases/managers/confirm-data-transaction.manager.ts | 1 + .../domain/usecases/managers/confirm-transaction.manager.ts | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/modules/transaction/transaction/domain/usecases/managers/confirm-data-transaction.manager.ts b/src/modules/transaction/transaction/domain/usecases/managers/confirm-data-transaction.manager.ts index 3961cbb..3b7a295 100644 --- a/src/modules/transaction/transaction/domain/usecases/managers/confirm-data-transaction.manager.ts +++ b/src/modules/transaction/transaction/domain/usecases/managers/confirm-data-transaction.manager.ts @@ -16,6 +16,7 @@ import { TransactionPaymentType } from '../../../constants'; @Injectable() export class ConfirmDataTransactionManager extends BaseUpdateStatusManager { + protected relations = ['items', 'items.bundling_items']; getResult(): string { return `Success active data ${this.result.invoice_code}`; } 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 f122f0e..8a955e4 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 @@ -18,7 +18,7 @@ import { apm } from 'src/core/apm'; @Injectable() export class ConfirmTransactionManager extends BaseUpdateStatusManager { - protected relations = ['items']; + protected relations = ['items', 'items.bundling_items']; getResult(): string { return `Success active data ${this.result.invoice_code}`;