Merge pull request 'fix/transaction' (#23) from fix/transaction into development
continuous-integration/drone/tag Build is passing
Details
continuous-integration/drone/tag Build is passing
Details
Reviewed-on: #23pull/24/head devel_10.6.6
commit
d149a15530
|
@ -34,6 +34,7 @@
|
||||||
"@nestjs/cqrs": "^10.2.7",
|
"@nestjs/cqrs": "^10.2.7",
|
||||||
"@nestjs/jwt": "^10.2.0",
|
"@nestjs/jwt": "^10.2.0",
|
||||||
"@nestjs/platform-express": "^10.0.0",
|
"@nestjs/platform-express": "^10.0.0",
|
||||||
|
"@nestjs/schedule": "^4.1.0",
|
||||||
"@nestjs/swagger": "^7.3.1",
|
"@nestjs/swagger": "^7.3.1",
|
||||||
"@nestjs/typeorm": "^10.0.2",
|
"@nestjs/typeorm": "^10.0.2",
|
||||||
"bcrypt": "^5.1.1",
|
"bcrypt": "^5.1.1",
|
||||||
|
|
|
@ -53,6 +53,7 @@ import { ReportBookmarkModule } from './modules/reports/report-bookmark/report-b
|
||||||
import { ReportExportModule } from './modules/reports/report-export/report-export.module';
|
import { ReportExportModule } from './modules/reports/report-export/report-export.module';
|
||||||
import { ReportBookmarkModel } from './modules/reports/shared/models/report-bookmark.model';
|
import { ReportBookmarkModel } from './modules/reports/shared/models/report-bookmark.model';
|
||||||
import { ExportReportHistoryModel } from './modules/reports/shared/models/export-report-history.model';
|
import { ExportReportHistoryModel } from './modules/reports/shared/models/export-report-history.model';
|
||||||
|
import { CronModule } from './modules/configuration/cron/cron.module';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [
|
imports: [
|
||||||
|
@ -97,6 +98,7 @@ import { ExportReportHistoryModel } from './modules/reports/shared/models/export
|
||||||
ConstantModule,
|
ConstantModule,
|
||||||
CqrsModule,
|
CqrsModule,
|
||||||
CouchModule,
|
CouchModule,
|
||||||
|
CronModule,
|
||||||
GoogleCalendarModule,
|
GoogleCalendarModule,
|
||||||
LogModule,
|
LogModule,
|
||||||
SessionModule,
|
SessionModule,
|
||||||
|
|
|
@ -68,4 +68,8 @@ export abstract class BaseDataService<Entity> {
|
||||||
async getOneByOptions(findOneOptions): Promise<Entity> {
|
async getOneByOptions(findOneOptions): Promise<Entity> {
|
||||||
return await this.repository.findOne(findOneOptions);
|
return await this.repository.findOne(findOneOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async getManyByOptions(findOneOptions): Promise<Entity[]> {
|
||||||
|
return await this.repository.find(findOneOptions);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,18 @@ export abstract class BaseUpdateManager<Entity> extends BaseManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
async prepareData(): Promise<void> {
|
async prepareData(): Promise<void> {
|
||||||
|
this.oldData = await this.dataService.getOneByOptions({
|
||||||
|
where: { id: this.dataId },
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!this.oldData) {
|
||||||
|
throw new NotFoundException({
|
||||||
|
statusCode: HttpStatus.NOT_FOUND,
|
||||||
|
message: `Failed! Entity with id ${this.dataId} not found`,
|
||||||
|
error: 'Entity Not Found',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
Object.assign(this.data, {
|
Object.assign(this.data, {
|
||||||
editor_id: this.user.id,
|
editor_id: this.user.id,
|
||||||
editor_name: this.user.name,
|
editor_name: this.user.name,
|
||||||
|
@ -38,18 +50,6 @@ export abstract class BaseUpdateManager<Entity> extends BaseManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
async process(): Promise<void> {
|
async process(): Promise<void> {
|
||||||
this.oldData = await this.dataService.getOneByOptions({
|
|
||||||
where: { id: this.dataId },
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!this.oldData) {
|
|
||||||
throw new NotFoundException({
|
|
||||||
statusCode: HttpStatus.NOT_FOUND,
|
|
||||||
message: `Failed! Entity with id ${this.dataId} not found`,
|
|
||||||
error: 'Entity Not Found',
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
await new ValidateRelationHelper(
|
await new ValidateRelationHelper(
|
||||||
this.dataId,
|
this.dataId,
|
||||||
this.dataService,
|
this.dataService,
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
import { MigrationInterface, QueryRunner } from "typeorm";
|
||||||
|
|
||||||
|
export class UpdateTableTransaction1720436852936 implements MigrationInterface {
|
||||||
|
name = 'UpdateTableTransaction1720436852936'
|
||||||
|
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(`ALTER TABLE "transaction_taxes" ADD "tax_total_value" numeric`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "transaction_taxes" DROP COLUMN "taxt_value"`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "transaction_taxes" ADD "taxt_value" numeric`);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(`ALTER TABLE "transaction_taxes" DROP COLUMN "taxt_value"`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "transaction_taxes" ADD "taxt_value" character varying`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "transaction_taxes" DROP COLUMN "tax_total_value"`);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -34,28 +34,16 @@ export class ConstantController {
|
||||||
|
|
||||||
@Get('transaction-user-type')
|
@Get('transaction-user-type')
|
||||||
async userType(): Promise<any> {
|
async userType(): Promise<any> {
|
||||||
return [
|
return ['group', 'vip'];
|
||||||
'group',
|
|
||||||
'vip'
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Get('transaction-payment-type')
|
@Get('transaction-payment-type')
|
||||||
async transactionPaymentType(): Promise<any> {
|
async transactionPaymentType(): Promise<any> {
|
||||||
return [
|
return ['midtrans', 'bank transfer', 'qris', 'counter'];
|
||||||
'midtrans',
|
|
||||||
'bank transfer',
|
|
||||||
'qris',
|
|
||||||
'counter',
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Get('transaction-type')
|
@Get('transaction-type')
|
||||||
async transactionType(): Promise<any> {
|
async transactionType(): Promise<any> {
|
||||||
return [
|
return ['counter', 'admin', 'online'];
|
||||||
'counter',
|
|
||||||
'admin',
|
|
||||||
'online'
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,15 +29,34 @@ import { ItemModel } from 'src/modules/item-related/item/data/models/item.model'
|
||||||
import { UserModel } from 'src/modules/user-related/user/data/models/user.model';
|
import { UserModel } from 'src/modules/user-related/user/data/models/user.model';
|
||||||
import { UserDataService } from 'src/modules/user-related/user/data/services/user-data.service';
|
import { UserDataService } from 'src/modules/user-related/user/data/services/user-data.service';
|
||||||
import { ItemDataService } from 'src/modules/item-related/item/data/services/item-data.service';
|
import { ItemDataService } from 'src/modules/item-related/item/data/services/item-data.service';
|
||||||
|
import {
|
||||||
|
BookingDeletedEvent,
|
||||||
|
BookingHandler,
|
||||||
|
} from './domain/managers/booking.handler';
|
||||||
|
import { TransactionDataService } from 'src/modules/transaction/transaction/data/services/transaction-data.service';
|
||||||
|
import { TransactionModel } from 'src/modules/transaction/transaction/data/models/transaction.model';
|
||||||
|
import { TransactionTaxModel } from 'src/modules/transaction/transaction/data/models/transaction-tax.model';
|
||||||
|
import { TransactionItemModel } from 'src/modules/transaction/transaction/data/models/transaction-item.model';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [
|
imports: [
|
||||||
ConfigModule.forRoot(),
|
ConfigModule.forRoot(),
|
||||||
TypeOrmModule.forFeature([ItemModel, UserModel], CONNECTION_NAME.DEFAULT),
|
TypeOrmModule.forFeature(
|
||||||
|
[
|
||||||
|
ItemModel,
|
||||||
|
UserModel,
|
||||||
|
TransactionModel,
|
||||||
|
TransactionTaxModel,
|
||||||
|
TransactionItemModel,
|
||||||
|
],
|
||||||
|
CONNECTION_NAME.DEFAULT,
|
||||||
|
),
|
||||||
CqrsModule,
|
CqrsModule,
|
||||||
],
|
],
|
||||||
controllers: [CouchDataController],
|
controllers: [CouchDataController],
|
||||||
providers: [
|
providers: [
|
||||||
|
BookingHandler,
|
||||||
|
BookingDeletedEvent,
|
||||||
PaymentMethodDeletedHandler,
|
PaymentMethodDeletedHandler,
|
||||||
PaymentMethodUpdatedHandler,
|
PaymentMethodUpdatedHandler,
|
||||||
VipCategoryDeletedHandler,
|
VipCategoryDeletedHandler,
|
||||||
|
@ -49,6 +68,7 @@ import { ItemDataService } from 'src/modules/item-related/item/data/services/ite
|
||||||
UserDeletedHandler,
|
UserDeletedHandler,
|
||||||
UserUpdatedHandler,
|
UserUpdatedHandler,
|
||||||
|
|
||||||
|
TransactionDataService,
|
||||||
UserDataService,
|
UserDataService,
|
||||||
ItemDataService,
|
ItemDataService,
|
||||||
CouchService,
|
CouchService,
|
||||||
|
|
|
@ -0,0 +1,73 @@
|
||||||
|
import { EventsHandler, IEventHandler } from '@nestjs/cqrs';
|
||||||
|
import { TransactionDataService } from 'src/modules/transaction/transaction/data/services/transaction-data.service';
|
||||||
|
import { TransactionChangeStatusEvent } from 'src/modules/transaction/transaction/domain/entities/event/transaction-change-status.event';
|
||||||
|
import { CouchService } from '../../data/services/couch.service';
|
||||||
|
import { STATUS } from 'src/core/strings/constants/base.constants';
|
||||||
|
import { TransactionPaymentType } from 'src/modules/transaction/transaction/constants';
|
||||||
|
import { mappingTransaction } from 'src/modules/transaction/transaction/domain/usecases/managers/helpers/mapping-transaction.helper';
|
||||||
|
import { TransactionDeletedEvent } from 'src/modules/transaction/transaction/domain/entities/event/transaction-deleted.event';
|
||||||
|
import { TransactionUpdatedEvent } from 'src/modules/transaction/transaction/domain/entities/event/transaction-updated.event';
|
||||||
|
|
||||||
|
@EventsHandler(TransactionDeletedEvent)
|
||||||
|
export class BookingDeletedEvent
|
||||||
|
implements IEventHandler<TransactionDeletedEvent>
|
||||||
|
{
|
||||||
|
constructor(private couchService: CouchService) {}
|
||||||
|
|
||||||
|
async handle(event: TransactionDeletedEvent) {
|
||||||
|
await this.couchService.deleteDoc(
|
||||||
|
{
|
||||||
|
_id: event.data.id,
|
||||||
|
...event.data.data,
|
||||||
|
},
|
||||||
|
'item',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventsHandler(TransactionChangeStatusEvent, TransactionUpdatedEvent)
|
||||||
|
export class BookingHandler
|
||||||
|
implements IEventHandler<TransactionChangeStatusEvent>
|
||||||
|
{
|
||||||
|
constructor(
|
||||||
|
private bookingService: TransactionDataService,
|
||||||
|
private couchService: CouchService,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
async handle(event: TransactionChangeStatusEvent) {
|
||||||
|
const old_data = event.data.old;
|
||||||
|
const data = event.data.data;
|
||||||
|
|
||||||
|
if (data.payment_type != TransactionPaymentType.COUNTER) return;
|
||||||
|
|
||||||
|
const booking = await this.bookingService.getOneByOptions({
|
||||||
|
where: {
|
||||||
|
id: data.id,
|
||||||
|
},
|
||||||
|
relations: ['items'],
|
||||||
|
});
|
||||||
|
|
||||||
|
mappingTransaction(booking);
|
||||||
|
|
||||||
|
if (
|
||||||
|
old_data?.status != data.status &&
|
||||||
|
[STATUS.PENDING, STATUS.ACTIVE].includes(data.status)
|
||||||
|
) {
|
||||||
|
await this.couchService.createDoc(
|
||||||
|
{
|
||||||
|
_id: booking.id,
|
||||||
|
...booking,
|
||||||
|
},
|
||||||
|
'booking',
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
await this.couchService.updateDoc(
|
||||||
|
{
|
||||||
|
_id: booking.id,
|
||||||
|
...booking,
|
||||||
|
},
|
||||||
|
'booking',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
import { ConfigModule } from '@nestjs/config';
|
||||||
|
import { MidnightCronManager } from './domain/managers/midnight-cron.manager';
|
||||||
|
import { Module } from '@nestjs/common';
|
||||||
|
import { CqrsModule } from '@nestjs/cqrs';
|
||||||
|
|
||||||
|
@Module({
|
||||||
|
imports: [ConfigModule.forRoot(), CqrsModule],
|
||||||
|
controllers: [MidnightCronManager],
|
||||||
|
providers: [],
|
||||||
|
})
|
||||||
|
export class CronModule {}
|
|
@ -0,0 +1,3 @@
|
||||||
|
export class CronMidnightEvent {
|
||||||
|
constructor(public readonly data: {}) {}
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
import { Controller } from '@nestjs/common';
|
||||||
|
import { EventBus } from '@nestjs/cqrs';
|
||||||
|
import { Cron } from '@nestjs/schedule';
|
||||||
|
import { CronMidnightEvent } from '../entities/cron-midnight.event';
|
||||||
|
|
||||||
|
@Controller()
|
||||||
|
export class MidnightCronManager {
|
||||||
|
constructor(public eventBus: EventBus) {}
|
||||||
|
|
||||||
|
@Cron(`${process.env.CRON_MIDNIGHT}`)
|
||||||
|
async scheduler(): Promise<void> {
|
||||||
|
const local_time = new Date().toLocaleDateString('en-US', {
|
||||||
|
timeZone: 'Asia/Jakarta',
|
||||||
|
});
|
||||||
|
const now = new Date(local_time).getTime();
|
||||||
|
|
||||||
|
console.log('Cron Event executed every 00:00 minutes.', now);
|
||||||
|
|
||||||
|
this.eventBus.publishAll([new CronMidnightEvent({})]);
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,6 +6,7 @@ import {
|
||||||
Param,
|
Param,
|
||||||
RelationParam,
|
RelationParam,
|
||||||
} from 'src/core/modules/domain/entities/base-filter.entity';
|
} from 'src/core/modules/domain/entities/base-filter.entity';
|
||||||
|
import { STATUS } from 'src/core/strings/constants/base.constants';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class CurrentSeasonPeriodManager extends BaseIndexManager<SeasonPeriodEntity> {
|
export class CurrentSeasonPeriodManager extends BaseIndexManager<SeasonPeriodEntity> {
|
||||||
|
@ -19,8 +20,8 @@ export class CurrentSeasonPeriodManager extends BaseIndexManager<SeasonPeriodEnt
|
||||||
|
|
||||||
async afterProcess(): Promise<void> {
|
async afterProcess(): Promise<void> {
|
||||||
Object.assign(this.result, {
|
Object.assign(this.result, {
|
||||||
data: this.result.data.sort((a, b) => a.priority - b.priority)
|
data: this.result.data.sort((a, b) => a.priority - b.priority),
|
||||||
})
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,17 +40,17 @@ export class CurrentSeasonPeriodManager extends BaseIndexManager<SeasonPeriodEnt
|
||||||
|
|
||||||
get selects(): string[] {
|
get selects(): string[] {
|
||||||
return [
|
return [
|
||||||
`${ this.tableName }.id`,
|
`${this.tableName}.id`,
|
||||||
`${ this.tableName }.priority`,
|
`${this.tableName}.priority`,
|
||||||
`${ this.tableName }.created_at`,
|
`${this.tableName}.created_at`,
|
||||||
`${ this.tableName }.creator_name`,
|
`${this.tableName}.creator_name`,
|
||||||
`${ this.tableName }.editor_name`,
|
`${this.tableName}.editor_name`,
|
||||||
`${ this.tableName }.updated_at`,
|
`${this.tableName}.updated_at`,
|
||||||
`${ this.tableName }.status`,
|
`${this.tableName}.status`,
|
||||||
`${ this.tableName }.start_date`,
|
`${this.tableName}.start_date`,
|
||||||
`${ this.tableName }.end_date`,
|
`${this.tableName}.end_date`,
|
||||||
`${ this.tableName }.days`,
|
`${this.tableName}.days`,
|
||||||
`${ this.tableName }.holiday_name`,
|
`${this.tableName}.holiday_name`,
|
||||||
|
|
||||||
'season_type.id',
|
'season_type.id',
|
||||||
'season_type.name',
|
'season_type.name',
|
||||||
|
@ -59,7 +60,7 @@ export class CurrentSeasonPeriodManager extends BaseIndexManager<SeasonPeriodEnt
|
||||||
get specificFilter(): Param[] {
|
get specificFilter(): Param[] {
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
cols: `${ this.tableName }.holiday_name`,
|
cols: `${this.tableName}.holiday_name`,
|
||||||
data: this.filterParam.holiday_names,
|
data: this.filterParam.holiday_names,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
@ -69,13 +70,17 @@ export class CurrentSeasonPeriodManager extends BaseIndexManager<SeasonPeriodEnt
|
||||||
queryBuilder: SelectQueryBuilder<SeasonPeriodEntity>,
|
queryBuilder: SelectQueryBuilder<SeasonPeriodEntity>,
|
||||||
): SelectQueryBuilder<SeasonPeriodEntity> {
|
): SelectQueryBuilder<SeasonPeriodEntity> {
|
||||||
queryBuilder.andWhere(
|
queryBuilder.andWhere(
|
||||||
`${ this.tableName }.start_date BETWEEN :from AND :to`,
|
`${this.tableName}.start_date BETWEEN :from AND :to`,
|
||||||
{
|
{
|
||||||
from: new Date().toLocaleDateString(),
|
from: new Date().toLocaleDateString(),
|
||||||
to: new Date().toLocaleDateString(),
|
to: new Date().toLocaleDateString(),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
queryBuilder.andWhere(`${this.tableName}.status In (:...statuses)`, {
|
||||||
|
statuses: [STATUS.ACTIVE],
|
||||||
|
});
|
||||||
|
|
||||||
return queryBuilder;
|
return queryBuilder;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,10 +42,13 @@ export class SeasonPeriodReadOrchestrator extends BaseReadOrchestrator<SeasonPer
|
||||||
async currentPeriod(): Promise<SeasonPeriodEntity> {
|
async currentPeriod(): Promise<SeasonPeriodEntity> {
|
||||||
const params = new FilterSeasonPeriodDto();
|
const params = new FilterSeasonPeriodDto();
|
||||||
this.currentPeriodManager.setFilterParam(params);
|
this.currentPeriodManager.setFilterParam(params);
|
||||||
this.currentPeriodManager.setService(this.serviceData, TABLE_NAME.SEASON_PERIOD);
|
this.currentPeriodManager.setService(
|
||||||
|
this.serviceData,
|
||||||
|
TABLE_NAME.SEASON_PERIOD,
|
||||||
|
);
|
||||||
await this.currentPeriodManager.execute();
|
await this.currentPeriodManager.execute();
|
||||||
const data = this.currentPeriodManager.getResult();
|
const data = this.currentPeriodManager.getResult();
|
||||||
return data.data[0]
|
return data.data[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
async indexItem(params): Promise<PaginationResponse<ItemRateEntity>> {
|
async indexItem(params): Promise<PaginationResponse<ItemRateEntity>> {
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
import { EventsHandler, IEventHandler } from '@nestjs/cqrs';
|
||||||
|
import { CronMidnightEvent } from 'src/modules/configuration/cron/domain/entities/cron-midnight.event';
|
||||||
|
import { RecapReconciliationManager } from '../managers/recap-reconciliation.manager';
|
||||||
|
import { TransactionModel } from 'src/modules/transaction/transaction/data/models/transaction.model';
|
||||||
|
import { TABLE_NAME } from 'src/core/strings/constants/table.constants';
|
||||||
|
import { TransactionDataService } from 'src/modules/transaction/transaction/data/services/transaction-data.service';
|
||||||
|
|
||||||
|
@EventsHandler(CronMidnightEvent)
|
||||||
|
export class RecapPosTransactionHandler
|
||||||
|
implements IEventHandler<CronMidnightEvent>
|
||||||
|
{
|
||||||
|
constructor(
|
||||||
|
private recapManager: RecapReconciliationManager,
|
||||||
|
private dataService: TransactionDataService,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
async handle(event: CronMidnightEvent) {
|
||||||
|
const data = new TransactionModel();
|
||||||
|
this.recapManager.setData(data);
|
||||||
|
this.recapManager.setService(this.dataService, TABLE_NAME.TRANSACTION);
|
||||||
|
await this.recapManager.execute();
|
||||||
|
return this.recapManager.getResult();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,138 @@
|
||||||
|
import { Injectable } from '@nestjs/common';
|
||||||
|
import { BaseCustomManager } from 'src/core/modules/domain/usecase/managers/base-custom.manager';
|
||||||
|
import { EventTopics } from 'src/core/strings/constants/interface.constants';
|
||||||
|
import { TransactionType } from 'src/modules/transaction/transaction/constants';
|
||||||
|
import { TransactionModel } from 'src/modules/transaction/transaction/data/models/transaction.model';
|
||||||
|
import { TransactionEntity } from 'src/modules/transaction/transaction/domain/entities/transaction.entity';
|
||||||
|
import { Between } from 'typeorm';
|
||||||
|
import * as _ from 'lodash';
|
||||||
|
import * as moment from 'moment';
|
||||||
|
import { STATUS } from 'src/core/strings/constants/base.constants';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class RecapReconciliationManager extends BaseCustomManager<TransactionEntity> {
|
||||||
|
private recapTransactions = {};
|
||||||
|
private startOfDay = moment().startOf('day').unix();
|
||||||
|
private endOfDay = moment().endOf('day').unix();
|
||||||
|
|
||||||
|
get entityTarget(): any {
|
||||||
|
return TransactionModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
getResult() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
get eventTopics(): EventTopics[] {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
async validateProcess(): Promise<void> {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
async beforeProcess(): Promise<void> {
|
||||||
|
const transactions = await this.dataService.getManyByOptions({
|
||||||
|
where: {
|
||||||
|
is_recap_transaction: false,
|
||||||
|
type: TransactionType.COUNTER,
|
||||||
|
created_at: Between(this.startOfDay, this.endOfDay),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
for (const transaction of transactions) {
|
||||||
|
const {
|
||||||
|
creator_counter_no,
|
||||||
|
payment_type_method_name,
|
||||||
|
payment_type_method_number,
|
||||||
|
} = transaction;
|
||||||
|
const group_by =
|
||||||
|
creator_counter_no +
|
||||||
|
'-' +
|
||||||
|
payment_type_method_name +
|
||||||
|
'-' +
|
||||||
|
payment_type_method_number;
|
||||||
|
if (!this.recapTransactions[group_by]) {
|
||||||
|
this.recapTransactions[group_by] = [];
|
||||||
|
}
|
||||||
|
this.recapTransactions[group_by].push(transaction);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
async process(): Promise<void> {
|
||||||
|
const total_recap = Object.keys(this.recapTransactions);
|
||||||
|
for (const recap of total_recap) {
|
||||||
|
const first_transaction = this.recapTransactions[recap][0];
|
||||||
|
const {
|
||||||
|
creator_counter_no,
|
||||||
|
payment_type_method_number,
|
||||||
|
payment_type_method_name,
|
||||||
|
} = first_transaction;
|
||||||
|
|
||||||
|
const exist = await this.dataService.getOneByOptions({
|
||||||
|
where: {
|
||||||
|
is_recap_transaction: true,
|
||||||
|
created_at: Between(this.startOfDay, this.endOfDay),
|
||||||
|
creator_counter_no: creator_counter_no,
|
||||||
|
payment_type_method_number: payment_type_method_number,
|
||||||
|
payment_type_method_name: payment_type_method_name,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const new_recap = new TransactionModel();
|
||||||
|
|
||||||
|
if (exist) {
|
||||||
|
Object.assign(exist, {
|
||||||
|
payment_total: _.sumBy(this.recapTransactions[recap], (recap) =>
|
||||||
|
parseFloat(recap.payment_total),
|
||||||
|
),
|
||||||
|
payment_total_net_profit: _.sumBy(
|
||||||
|
this.recapTransactions[recap],
|
||||||
|
(recap) => parseFloat(recap.payment_total),
|
||||||
|
),
|
||||||
|
editor_id: this.user.id,
|
||||||
|
editor_name: this.user.name,
|
||||||
|
updated_at: new Date().getTime(),
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
Object.assign(new_recap, {
|
||||||
|
is_recap_transaction: true,
|
||||||
|
payment_total: _.sumBy(this.recapTransactions[recap], (recap) =>
|
||||||
|
parseFloat(recap.payment_total),
|
||||||
|
),
|
||||||
|
payment_total_net_profit: _.sumBy(
|
||||||
|
this.recapTransactions[recap],
|
||||||
|
(recap) => parseFloat(recap.payment_total),
|
||||||
|
),
|
||||||
|
reconciliation_status: STATUS.PENDING,
|
||||||
|
status: STATUS.SETTLED,
|
||||||
|
type: TransactionType.COUNTER,
|
||||||
|
booking_date: first_transaction.booking_date,
|
||||||
|
creator_counter_no: first_transaction.creator_counter_no,
|
||||||
|
payment_type: first_transaction.payment_type,
|
||||||
|
payment_type_method_id: first_transaction.payment_type_method_id,
|
||||||
|
payment_type_method_number:
|
||||||
|
first_transaction.payment_type_method_number,
|
||||||
|
payment_type_method_name: first_transaction.payment_type_method_name,
|
||||||
|
payment_type_method_qr: first_transaction.payment_type_method_qr,
|
||||||
|
creator_id: this.user.id,
|
||||||
|
creator_name: this.user.name,
|
||||||
|
created_at: new Date().getTime(),
|
||||||
|
updated_at: new Date().getTime(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
await this.dataService.create(
|
||||||
|
this.queryRunner,
|
||||||
|
TransactionModel,
|
||||||
|
exist ?? new_recap,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
async afterProcess(): Promise<void> {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
|
@ -23,7 +23,7 @@ export class UpdateReconciliationManager extends BaseUpdateManager<TransactionEn
|
||||||
Object.assign(this.data, {
|
Object.assign(this.data, {
|
||||||
reconciliation_mdr: this.data.reconciliation_mdr ?? null,
|
reconciliation_mdr: this.data.reconciliation_mdr ?? null,
|
||||||
payment_total_net_profit: net_profit,
|
payment_total_net_profit: net_profit,
|
||||||
payment_date: this.data.payment_date ?? this.oldData.payment_total,
|
payment_date: this.data.payment_date ?? this.oldData.payment_date,
|
||||||
});
|
});
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -9,6 +9,8 @@ import { CancelReconciliationManager } from './managers/cancel-reconciliation.ma
|
||||||
import { BatchCancelReconciliationManager } from './managers/batch-cancel-reconciliation.manager';
|
import { BatchCancelReconciliationManager } from './managers/batch-cancel-reconciliation.manager';
|
||||||
import { TransactionEntity } from 'src/modules/transaction/transaction/domain/entities/transaction.entity';
|
import { TransactionEntity } from 'src/modules/transaction/transaction/domain/entities/transaction.entity';
|
||||||
import { TransactionDataService } from 'src/modules/transaction/transaction/data/services/transaction-data.service';
|
import { TransactionDataService } from 'src/modules/transaction/transaction/data/services/transaction-data.service';
|
||||||
|
import { RecapReconciliationManager } from './managers/recap-reconciliation.manager';
|
||||||
|
import { TransactionModel } from 'src/modules/transaction/transaction/data/models/transaction.model';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class ReconciliationDataOrchestrator {
|
export class ReconciliationDataOrchestrator {
|
||||||
|
@ -18,6 +20,7 @@ export class ReconciliationDataOrchestrator {
|
||||||
private cancelManager: CancelReconciliationManager,
|
private cancelManager: CancelReconciliationManager,
|
||||||
private batchConfirmManager: BatchConfirmReconciliationManager,
|
private batchConfirmManager: BatchConfirmReconciliationManager,
|
||||||
private batchCancelManager: BatchCancelReconciliationManager,
|
private batchCancelManager: BatchCancelReconciliationManager,
|
||||||
|
private recapManager: RecapReconciliationManager,
|
||||||
private serviceData: TransactionDataService,
|
private serviceData: TransactionDataService,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
|
@ -28,6 +31,14 @@ export class ReconciliationDataOrchestrator {
|
||||||
return this.updateManager.getResult();
|
return this.updateManager.getResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async recap() {
|
||||||
|
const data = new TransactionModel();
|
||||||
|
this.recapManager.setData(data);
|
||||||
|
this.recapManager.setService(this.serviceData, TABLE_NAME.TRANSACTION);
|
||||||
|
await this.recapManager.execute();
|
||||||
|
return this.recapManager.getResult();
|
||||||
|
}
|
||||||
|
|
||||||
async confirm(dataId): Promise<String> {
|
async confirm(dataId): Promise<String> {
|
||||||
this.confirmManager.setData(dataId, STATUS.CONFIRMED);
|
this.confirmManager.setData(dataId, STATUS.CONFIRMED);
|
||||||
this.confirmManager.setService(this.serviceData, TABLE_NAME.TRANSACTION);
|
this.confirmManager.setService(this.serviceData, TABLE_NAME.TRANSACTION);
|
||||||
|
|
|
@ -23,6 +23,11 @@ import { UpdateReconciliationDto } from './dto/reconciliation.dto';
|
||||||
export class ReconciliationDataController {
|
export class ReconciliationDataController {
|
||||||
constructor(private orchestrator: ReconciliationDataOrchestrator) {}
|
constructor(private orchestrator: ReconciliationDataOrchestrator) {}
|
||||||
|
|
||||||
|
@Post('/recap-transaction')
|
||||||
|
async recap(): Promise<any> {
|
||||||
|
return await this.orchestrator.recap();
|
||||||
|
}
|
||||||
|
|
||||||
@Put('/batch-confirm')
|
@Put('/batch-confirm')
|
||||||
async batchConfirm(@Body() body: BatchIdsDto): Promise<BatchResult> {
|
async batchConfirm(@Body() body: BatchIdsDto): Promise<BatchResult> {
|
||||||
return await this.orchestrator.batchConfirm(body.ids);
|
return await this.orchestrator.batchConfirm(body.ids);
|
||||||
|
|
|
@ -17,6 +17,8 @@ import { TransactionReadService } from '../transaction/data/services/transaction
|
||||||
import { CancelReconciliationManager } from './domain/usecases/managers/cancel-reconciliation.manager';
|
import { CancelReconciliationManager } from './domain/usecases/managers/cancel-reconciliation.manager';
|
||||||
import { BatchCancelReconciliationManager } from './domain/usecases/managers/batch-cancel-reconciliation.manager';
|
import { BatchCancelReconciliationManager } from './domain/usecases/managers/batch-cancel-reconciliation.manager';
|
||||||
import { BatchConfirmReconciliationManager } from './domain/usecases/managers/batch-confirm-reconciliation.manager';
|
import { BatchConfirmReconciliationManager } from './domain/usecases/managers/batch-confirm-reconciliation.manager';
|
||||||
|
import { RecapReconciliationManager } from './domain/usecases/managers/recap-reconciliation.manager';
|
||||||
|
import { RecapPosTransactionHandler } from './domain/usecases/handlers/recap-pos-transaction.handler';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [
|
imports: [
|
||||||
|
@ -26,6 +28,8 @@ import { BatchConfirmReconciliationManager } from './domain/usecases/managers/ba
|
||||||
],
|
],
|
||||||
controllers: [ReconciliationDataController, ReconciliationReadController],
|
controllers: [ReconciliationDataController, ReconciliationReadController],
|
||||||
providers: [
|
providers: [
|
||||||
|
RecapPosTransactionHandler,
|
||||||
|
|
||||||
IndexReconciliationManager,
|
IndexReconciliationManager,
|
||||||
DetailReconciliationManager,
|
DetailReconciliationManager,
|
||||||
UpdateReconciliationManager,
|
UpdateReconciliationManager,
|
||||||
|
@ -33,6 +37,7 @@ import { BatchConfirmReconciliationManager } from './domain/usecases/managers/ba
|
||||||
BatchConfirmReconciliationManager,
|
BatchConfirmReconciliationManager,
|
||||||
CancelReconciliationManager,
|
CancelReconciliationManager,
|
||||||
BatchCancelReconciliationManager,
|
BatchCancelReconciliationManager,
|
||||||
|
RecapReconciliationManager,
|
||||||
|
|
||||||
TransactionDataService,
|
TransactionDataService,
|
||||||
TransactionReadService,
|
TransactionReadService,
|
||||||
|
|
|
@ -15,9 +15,12 @@ export class TransactionTaxModel
|
||||||
@Column('varchar', { name: 'tax_name', nullable: true })
|
@Column('varchar', { name: 'tax_name', nullable: true })
|
||||||
tax_name: string;
|
tax_name: string;
|
||||||
|
|
||||||
@Column('varchar', { name: 'taxt_value', nullable: true })
|
@Column('decimal', { name: 'taxt_value', nullable: true })
|
||||||
taxt_value: number;
|
taxt_value: number;
|
||||||
|
|
||||||
|
@Column('decimal', { name: 'tax_total_value', nullable: true })
|
||||||
|
tax_total_value: number;
|
||||||
|
|
||||||
@Column('varchar', { name: 'transaction_id', nullable: true })
|
@Column('varchar', { name: 'transaction_id', nullable: true })
|
||||||
transaction_id: string;
|
transaction_id: string;
|
||||||
@ManyToOne(() => TransactionModel, (model) => model.taxes, {
|
@ManyToOne(() => TransactionModel, (model) => model.taxes, {
|
||||||
|
|
|
@ -4,4 +4,5 @@ export interface TransactionTaxEntity extends BaseCoreEntity {
|
||||||
tax_id: string;
|
tax_id: string;
|
||||||
tax_name: string;
|
tax_name: string;
|
||||||
taxt_value: number;
|
taxt_value: number;
|
||||||
|
tax_total_value: number;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,83 @@
|
||||||
|
import { EventsHandler, IEventHandler } from '@nestjs/cqrs';
|
||||||
|
import { ChangeDocEvent } from 'src/modules/configuration/couch/domain/events/change-doc.event';
|
||||||
|
import { TransactionType } from '../../../constants';
|
||||||
|
import { TransactionDataService } from '../../../data/services/transaction-data.service';
|
||||||
|
import { TaxDataService } from 'src/modules/transaction/tax/data/services/tax-data.service';
|
||||||
|
import { SalesPriceFormulaDataService } from 'src/modules/transaction/sales-price-formula/data/services/sales-price-formula-data.service';
|
||||||
|
import { FormulaType } from 'src/modules/transaction/sales-price-formula/constants';
|
||||||
|
import { STATUS } from 'src/core/strings/constants/base.constants';
|
||||||
|
import { TransactionModel } from '../../../data/models/transaction.model';
|
||||||
|
import { mappingRevertTransaction } from '../managers/helpers/mapping-transaction.helper';
|
||||||
|
|
||||||
|
@EventsHandler(ChangeDocEvent)
|
||||||
|
export class PosTransactionHandler implements IEventHandler<ChangeDocEvent> {
|
||||||
|
constructor(
|
||||||
|
private dataService: TransactionDataService,
|
||||||
|
private taxService: TaxDataService,
|
||||||
|
private formulaService: SalesPriceFormulaDataService,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
async handle(event: ChangeDocEvent) {
|
||||||
|
try {
|
||||||
|
const database = event.data.database;
|
||||||
|
const data = event.data.data;
|
||||||
|
|
||||||
|
// jika bukan database transaksi, return langsung
|
||||||
|
if (database != 'transaction') return;
|
||||||
|
|
||||||
|
const sales_formula = await this.formulaService.getOneByOptions({
|
||||||
|
where: {
|
||||||
|
type: FormulaType.SALES_PRICE,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const profit_formula = await this.formulaService.getOneByOptions({
|
||||||
|
where: {
|
||||||
|
type: FormulaType.PROFIT_SHARE,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const taxes = await this.taxService.getManyByOptions({
|
||||||
|
where: {
|
||||||
|
status: STATUS.ACTIVE,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const queryRunner = this.dataService
|
||||||
|
.getRepository()
|
||||||
|
.manager.connection.createQueryRunner();
|
||||||
|
|
||||||
|
// jika delete
|
||||||
|
if (data._deleted ?? false) {
|
||||||
|
await this.dataService.deleteById(
|
||||||
|
queryRunner,
|
||||||
|
TransactionModel,
|
||||||
|
data._id,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// jika update // create
|
||||||
|
else {
|
||||||
|
const tax_datas = taxes?.map((tax) => {
|
||||||
|
return {
|
||||||
|
tax_id: tax.id,
|
||||||
|
tax_name: tax.name,
|
||||||
|
tax_value: tax.value,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
mappingRevertTransaction(data, TransactionType.COUNTER);
|
||||||
|
|
||||||
|
Object.assign(data, {
|
||||||
|
taxes: tax_datas,
|
||||||
|
profit_share_formula: profit_formula.formula_string,
|
||||||
|
sales_price_formula: sales_formula.formula_string,
|
||||||
|
});
|
||||||
|
|
||||||
|
await this.dataService.create(queryRunner, TransactionModel, data);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log('error handling pos transaction couch');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -9,33 +9,12 @@ import { TransactionModel } from '../../../data/models/transaction.model';
|
||||||
import { BaseCreateManager } from 'src/core/modules/domain/usecase/managers/base-create.manager';
|
import { BaseCreateManager } from 'src/core/modules/domain/usecase/managers/base-create.manager';
|
||||||
import { TransactionCreatedEvent } from '../../entities/event/transaction-created.event';
|
import { TransactionCreatedEvent } from '../../entities/event/transaction-created.event';
|
||||||
import { TransactionType } from '../../../constants';
|
import { TransactionType } from '../../../constants';
|
||||||
|
import { mappingRevertTransaction } from './helpers/mapping-transaction.helper';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class CreateTransactionManager extends BaseCreateManager<TransactionEntity> {
|
export class CreateTransactionManager extends BaseCreateManager<TransactionEntity> {
|
||||||
async beforeProcess(): Promise<void> {
|
async beforeProcess(): Promise<void> {
|
||||||
Object.assign(this.data, {
|
mappingRevertTransaction(this.data, TransactionType.ADMIN);
|
||||||
type: TransactionType.ADMIN,
|
|
||||||
customer_category_id: this.data.customer_category?.id ?? null,
|
|
||||||
customer_category_name: this.data.customer_category?.name ?? null,
|
|
||||||
season_period_id: this.data.season_period?.id ?? null,
|
|
||||||
season_period_name: this.data.season_period?.holiday_name ?? null,
|
|
||||||
season_period_type_id: this.data.season_period?.season_type?.id ?? null,
|
|
||||||
season_period_type_name:
|
|
||||||
this.data.season_period?.season_type?.name ?? null,
|
|
||||||
});
|
|
||||||
|
|
||||||
this.data.items?.map((item) => {
|
|
||||||
Object.assign(item, {
|
|
||||||
item_id: item.item.id,
|
|
||||||
item_name: item.item.name,
|
|
||||||
item_type: item.item.item_type,
|
|
||||||
item_price: item.item.base_price,
|
|
||||||
item_tenant_id: item.item.tenant?.id ?? null,
|
|
||||||
item_tenant_name: item.item.tenant?.id ?? null,
|
|
||||||
item_tenant_percentage: item.item.tenant?.share_margin ?? null,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ import { Injectable } from '@nestjs/common';
|
||||||
import { BaseDetailManager } from 'src/core/modules/domain/usecase/managers/base-detail.manager';
|
import { BaseDetailManager } from 'src/core/modules/domain/usecase/managers/base-detail.manager';
|
||||||
import { TransactionEntity } from '../../entities/transaction.entity';
|
import { TransactionEntity } from '../../entities/transaction.entity';
|
||||||
import { RelationParam } from 'src/core/modules/domain/entities/base-filter.entity';
|
import { RelationParam } from 'src/core/modules/domain/entities/base-filter.entity';
|
||||||
|
import { mappingTransaction } from './helpers/mapping-transaction.helper';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class DetailTransactionManager extends BaseDetailManager<TransactionEntity> {
|
export class DetailTransactionManager extends BaseDetailManager<TransactionEntity> {
|
||||||
|
@ -14,69 +15,7 @@ export class DetailTransactionManager extends BaseDetailManager<TransactionEntit
|
||||||
}
|
}
|
||||||
|
|
||||||
async afterProcess(): Promise<void> {
|
async afterProcess(): Promise<void> {
|
||||||
let payment_type_bank;
|
mappingTransaction(this.result);
|
||||||
|
|
||||||
const season_period = {
|
|
||||||
id: this.result.season_period_id,
|
|
||||||
holiday_name: this.result.season_period_name,
|
|
||||||
season_type: {
|
|
||||||
id: this.result.season_period_type_id,
|
|
||||||
name: this.result.season_period_type_name,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
if (this.result.payment_type_method_id) {
|
|
||||||
payment_type_bank = {
|
|
||||||
id: this.result.payment_type_method_id,
|
|
||||||
issuer_name: this.result.payment_type_method_name,
|
|
||||||
account_number: this.result.payment_type_method_number,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
const items = this.result?.['items']?.map((itemData) => {
|
|
||||||
let tenant;
|
|
||||||
|
|
||||||
if (itemData.item_tenant_id) {
|
|
||||||
tenant = {
|
|
||||||
id: itemData.item_tenant_id,
|
|
||||||
name: itemData.item_tenant_name,
|
|
||||||
share_margin: itemData.item_tenant_share_margin,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
item: {
|
|
||||||
id: itemData.item_id,
|
|
||||||
name: itemData.item_name,
|
|
||||||
item_type: itemData.item_type,
|
|
||||||
base_price: itemData.item_price,
|
|
||||||
hpp: itemData.item_hpp,
|
|
||||||
tenant: tenant,
|
|
||||||
item_category: {
|
|
||||||
id: itemData.item_category_id,
|
|
||||||
name: itemData.item_category_name,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
qty: itemData.qty,
|
|
||||||
total_price: itemData.total_price,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
Object.assign(this.result, {
|
|
||||||
season_period: season_period,
|
|
||||||
items: items,
|
|
||||||
payment_type_bank: payment_type_bank,
|
|
||||||
});
|
|
||||||
|
|
||||||
delete this.result.season_period_id;
|
|
||||||
delete this.result.season_period_name;
|
|
||||||
delete this.result.season_period_type_id;
|
|
||||||
delete this.result.season_period_type_name;
|
|
||||||
|
|
||||||
delete this.result.payment_type_method_id;
|
|
||||||
delete this.result.payment_type_method_name;
|
|
||||||
delete this.result.payment_type_method_number;
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,133 @@
|
||||||
|
import { STATUS } from 'src/core/strings/constants/base.constants';
|
||||||
|
import { TransactionType } from 'src/modules/transaction/transaction/constants';
|
||||||
|
|
||||||
|
export function mappingTransaction(data) {
|
||||||
|
let payment_type_bank;
|
||||||
|
const season_period = {
|
||||||
|
id: data.season_period_id,
|
||||||
|
holiday_name: data.season_period_name,
|
||||||
|
season_type: {
|
||||||
|
id: data.season_period_type_id,
|
||||||
|
name: data.season_period_type_name,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
if (data.payment_type_method_id) {
|
||||||
|
payment_type_bank = {
|
||||||
|
id: data.payment_type_method_id,
|
||||||
|
issuer_name: data.payment_type_method_name,
|
||||||
|
account_number: data.payment_type_method_number,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const items = data?.['items']?.map((itemData) => {
|
||||||
|
let tenant;
|
||||||
|
|
||||||
|
if (itemData.item_tenant_id) {
|
||||||
|
tenant = {
|
||||||
|
id: itemData.item_tenant_id,
|
||||||
|
name: itemData.item_tenant_name,
|
||||||
|
share_margin: itemData.item_tenant_share_margin,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
item: {
|
||||||
|
id: itemData.item_id,
|
||||||
|
name: itemData.item_name,
|
||||||
|
item_type: itemData.item_type,
|
||||||
|
base_price: itemData.item_price,
|
||||||
|
hpp: itemData.item_hpp,
|
||||||
|
tenant: tenant,
|
||||||
|
item_category: {
|
||||||
|
id: itemData.item_category_id,
|
||||||
|
name: itemData.item_category_name,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
qty: itemData.qty,
|
||||||
|
total_price: itemData.total_price,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
Object.assign(data, {
|
||||||
|
season_period: season_period,
|
||||||
|
items: items,
|
||||||
|
payment_type_bank: payment_type_bank,
|
||||||
|
});
|
||||||
|
|
||||||
|
delete data.season_period_id;
|
||||||
|
delete data.season_period_name;
|
||||||
|
delete data.season_period_type_id;
|
||||||
|
delete data.season_period_type_name;
|
||||||
|
|
||||||
|
delete data.payment_type_method_id;
|
||||||
|
delete data.payment_type_method_name;
|
||||||
|
delete data.payment_type_method_number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function mappingRevertTransaction(data, type) {
|
||||||
|
if (type == TransactionType.COUNTER) {
|
||||||
|
Object.assign(data, {
|
||||||
|
id: data._id,
|
||||||
|
creator_counter_no: data.pos_number,
|
||||||
|
creator_id: data.pos_admin?.id,
|
||||||
|
creator_name: data.pos_admin?.name,
|
||||||
|
status: STATUS.SETTLED,
|
||||||
|
booking_date: data.created_at,
|
||||||
|
settlement_date: data.created_at,
|
||||||
|
payment_type: data.payment_type,
|
||||||
|
payment_type_method_id: data.payment_type_bank?._id,
|
||||||
|
payment_type_method_name: data.payment_type_bank?.issuer_name,
|
||||||
|
payment_type_method_number: data.payment_type_bank?.account_number,
|
||||||
|
payment_card_information: data.card_information,
|
||||||
|
payment_code_reference: data.payment_code,
|
||||||
|
discount_code_id: data.discount_code?.id,
|
||||||
|
discount_code: data.discount_code?.code,
|
||||||
|
discount_percentage: data.discount_code?.discount,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// Object.assign(data, {
|
||||||
|
// payment_type:
|
||||||
|
// })
|
||||||
|
}
|
||||||
|
|
||||||
|
Object.assign(data, {
|
||||||
|
type: type,
|
||||||
|
customer_category_id: data.customer_category?.id ?? null,
|
||||||
|
customer_category_name: data.customer_category?.name ?? null,
|
||||||
|
season_period_id: data.season_period?.id ?? null,
|
||||||
|
season_period_name: data.season_period?.holiday_name ?? null,
|
||||||
|
season_period_type_id: data.season_period?.season_type?.id ?? null,
|
||||||
|
season_period_type_name: data.season_period?.season_type?.name ?? null,
|
||||||
|
});
|
||||||
|
|
||||||
|
data.items?.map((item) => {
|
||||||
|
const total_price = Number(item.item.base_price) * Number(item.qty);
|
||||||
|
const share_margin = item.item.tenant?.share_margin ?? 0;
|
||||||
|
const total_share_tenant =
|
||||||
|
share_margin > 0 ? (Number(share_margin) / 100) * total_price : 0;
|
||||||
|
|
||||||
|
Object.assign(item, {
|
||||||
|
item_id: item.item.id,
|
||||||
|
item_name: item.item.name,
|
||||||
|
item_type: item.item.item_type,
|
||||||
|
item_price: item.item.base_price,
|
||||||
|
item_hpp: item.item.hpp,
|
||||||
|
|
||||||
|
item_category_id: item.item.item_category?.id,
|
||||||
|
item_category_name: item.item.item_category?.name,
|
||||||
|
item_bundlings: item.item.bundling_items?.map(
|
||||||
|
(bundling) => bundling.name,
|
||||||
|
),
|
||||||
|
|
||||||
|
item_tenant_id: item.item.tenant?.id ?? null,
|
||||||
|
item_tenant_name: item.item.tenant?.id ?? null,
|
||||||
|
item_tenant_share_margin: item.item.tenant?.share_margin ?? null,
|
||||||
|
|
||||||
|
total_price: total_price,
|
||||||
|
total_hpp: Number(item.item.item_hpp) * Number(item.qty),
|
||||||
|
total_share_tenant: total_share_tenant,
|
||||||
|
total_profit: total_price - Number(total_share_tenant),
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
|
@ -9,6 +9,7 @@ import {
|
||||||
validateRelations,
|
validateRelations,
|
||||||
} from 'src/core/strings/constants/interface.constants';
|
} from 'src/core/strings/constants/interface.constants';
|
||||||
import { TransactionType } from '../../../constants';
|
import { TransactionType } from '../../../constants';
|
||||||
|
import { mappingRevertTransaction } from './helpers/mapping-transaction.helper';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class UpdateTransactionManager extends BaseUpdateManager<TransactionEntity> {
|
export class UpdateTransactionManager extends BaseUpdateManager<TransactionEntity> {
|
||||||
|
@ -17,29 +18,7 @@ export class UpdateTransactionManager extends BaseUpdateManager<TransactionEntit
|
||||||
}
|
}
|
||||||
|
|
||||||
async beforeProcess(): Promise<void> {
|
async beforeProcess(): Promise<void> {
|
||||||
Object.assign(this.data, {
|
mappingRevertTransaction(this.data, TransactionType.ADMIN);
|
||||||
type: TransactionType.ADMIN,
|
|
||||||
customer_category_id: this.data.customer_category?.id ?? null,
|
|
||||||
customer_category_name: this.data.customer_category?.name ?? null,
|
|
||||||
season_period_id: this.data.season_period?.id ?? null,
|
|
||||||
season_period_name: this.data.season_period?.holiday_name ?? null,
|
|
||||||
season_period_type_id: this.data.season_period?.season_type?.id ?? null,
|
|
||||||
season_period_type_name:
|
|
||||||
this.data.season_period?.season_type?.name ?? null,
|
|
||||||
});
|
|
||||||
|
|
||||||
this.data.items?.map((item) => {
|
|
||||||
Object.assign(item, {
|
|
||||||
item_id: item.item.id,
|
|
||||||
item_name: item.item.name,
|
|
||||||
item_type: item.item.item_type,
|
|
||||||
item_price: item.item.base_price,
|
|
||||||
item_tenant_id: item.item.tenant?.id ?? null,
|
|
||||||
item_tenant_name: item.item.tenant?.id ?? null,
|
|
||||||
item_tenant_percentage: item.item.tenant?.share_margin ?? null,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,18 +24,31 @@ import { CancelTransactionManager } from './domain/usecases/managers/cancel-tran
|
||||||
import { BatchCancelTransactionManager } from './domain/usecases/managers/batch-cancel-transaction.manager';
|
import { BatchCancelTransactionManager } from './domain/usecases/managers/batch-cancel-transaction.manager';
|
||||||
import { ConfirmDataTransactionManager } from './domain/usecases/managers/confirm-data-transaction.manager';
|
import { ConfirmDataTransactionManager } from './domain/usecases/managers/confirm-data-transaction.manager';
|
||||||
import { BatchConfirmDataTransactionManager } from './domain/usecases/managers/batch-confirm-data-transaction.manager';
|
import { BatchConfirmDataTransactionManager } from './domain/usecases/managers/batch-confirm-data-transaction.manager';
|
||||||
|
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 { TaxModel } from '../tax/data/models/tax.model';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [
|
imports: [
|
||||||
ConfigModule.forRoot(),
|
ConfigModule.forRoot(),
|
||||||
TypeOrmModule.forFeature(
|
TypeOrmModule.forFeature(
|
||||||
[TransactionModel, TransactionItemModel, TransactionTaxModel],
|
[
|
||||||
|
TransactionModel,
|
||||||
|
TransactionItemModel,
|
||||||
|
TransactionTaxModel,
|
||||||
|
TaxModel,
|
||||||
|
SalesPriceFormulaModel,
|
||||||
|
],
|
||||||
CONNECTION_NAME.DEFAULT,
|
CONNECTION_NAME.DEFAULT,
|
||||||
),
|
),
|
||||||
CqrsModule,
|
CqrsModule,
|
||||||
],
|
],
|
||||||
controllers: [TransactionDataController, TransactionReadController],
|
controllers: [TransactionDataController, TransactionReadController],
|
||||||
providers: [
|
providers: [
|
||||||
|
PosTransactionHandler,
|
||||||
|
|
||||||
IndexTransactionManager,
|
IndexTransactionManager,
|
||||||
DetailTransactionManager,
|
DetailTransactionManager,
|
||||||
CreateTransactionManager,
|
CreateTransactionManager,
|
||||||
|
@ -51,6 +64,8 @@ import { BatchConfirmDataTransactionManager } from './domain/usecases/managers/b
|
||||||
|
|
||||||
TransactionDataService,
|
TransactionDataService,
|
||||||
TransactionReadService,
|
TransactionReadService,
|
||||||
|
TaxDataService,
|
||||||
|
SalesPriceFormulaDataService,
|
||||||
|
|
||||||
TransactionDataOrchestrator,
|
TransactionDataOrchestrator,
|
||||||
TransactionReadOrchestrator,
|
TransactionReadOrchestrator,
|
||||||
|
|
62
yarn.lock
62
yarn.lock
|
@ -832,6 +832,14 @@
|
||||||
multer "1.4.4-lts.1"
|
multer "1.4.4-lts.1"
|
||||||
tslib "2.6.2"
|
tslib "2.6.2"
|
||||||
|
|
||||||
|
"@nestjs/schedule@^4.1.0":
|
||||||
|
version "4.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@nestjs/schedule/-/schedule-4.1.0.tgz#b0ae64519365821f4186416915e502d225836048"
|
||||||
|
integrity sha512-WEc96WTXZW+VI/Ng+uBpiBUwm6TWtAbQ4RKWkfbmzKvmbRGzA/9k/UyAWDS9k0pp+ZcbC+MaZQtt7TjQHrwX6g==
|
||||||
|
dependencies:
|
||||||
|
cron "3.1.7"
|
||||||
|
uuid "10.0.0"
|
||||||
|
|
||||||
"@nestjs/schematics@^10.0.0", "@nestjs/schematics@^10.0.1":
|
"@nestjs/schematics@^10.0.0", "@nestjs/schematics@^10.0.1":
|
||||||
version "10.1.1"
|
version "10.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/@nestjs/schematics/-/schematics-10.1.1.tgz#a67fb178a7ad6025ccc3314910b077ac454fcdf3"
|
resolved "https://registry.yarnpkg.com/@nestjs/schematics/-/schematics-10.1.1.tgz#a67fb178a7ad6025ccc3314910b077ac454fcdf3"
|
||||||
|
@ -1148,6 +1156,11 @@
|
||||||
"@types/fined" "*"
|
"@types/fined" "*"
|
||||||
"@types/node" "*"
|
"@types/node" "*"
|
||||||
|
|
||||||
|
"@types/luxon@~3.4.0":
|
||||||
|
version "3.4.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/luxon/-/luxon-3.4.2.tgz#e4fc7214a420173cea47739c33cdf10874694db7"
|
||||||
|
integrity sha512-TifLZlFudklWlMBfhubvgqTXRzLDI5pCbGa4P8a3wPyUQSW+1xQ5eDsreP9DWHX3tjq1ke96uYG/nwundroWcA==
|
||||||
|
|
||||||
"@types/methods@^1.1.4":
|
"@types/methods@^1.1.4":
|
||||||
version "1.1.4"
|
version "1.1.4"
|
||||||
resolved "https://registry.yarnpkg.com/@types/methods/-/methods-1.1.4.tgz#d3b7ac30ac47c91054ea951ce9eed07b1051e547"
|
resolved "https://registry.yarnpkg.com/@types/methods/-/methods-1.1.4.tgz#d3b7ac30ac47c91054ea951ce9eed07b1051e547"
|
||||||
|
@ -2514,6 +2527,14 @@ create-require@^1.1.0:
|
||||||
resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333"
|
resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333"
|
||||||
integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==
|
integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==
|
||||||
|
|
||||||
|
cron@3.1.7:
|
||||||
|
version "3.1.7"
|
||||||
|
resolved "https://registry.yarnpkg.com/cron/-/cron-3.1.7.tgz#3423d618ba625e78458fff8cb67001672d49ba0d"
|
||||||
|
integrity sha512-tlBg7ARsAMQLzgwqVxy8AZl/qlTc5nibqYwtNGoCrd+cV+ugI+tvZC1oT/8dFH8W455YrywGykx/KMmAqOr7Jw==
|
||||||
|
dependencies:
|
||||||
|
"@types/luxon" "~3.4.0"
|
||||||
|
luxon "~3.4.0"
|
||||||
|
|
||||||
cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@^7.0.3:
|
cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@^7.0.3:
|
||||||
version "7.0.3"
|
version "7.0.3"
|
||||||
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6"
|
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6"
|
||||||
|
@ -4949,6 +4970,11 @@ lru-cache@^5.1.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
yallist "^3.0.2"
|
yallist "^3.0.2"
|
||||||
|
|
||||||
|
luxon@~3.4.0:
|
||||||
|
version "3.4.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/luxon/-/luxon-3.4.4.tgz#cf20dc27dc532ba41a169c43fdcc0063601577af"
|
||||||
|
integrity sha512-zobTr7akeGHnv7eBOXcRgMeCP6+uyYsczwmeRCauvpvaAltgNyTbLH/+VaEAPUeWBT+1GuNmz4wC/6jtQzbbVA==
|
||||||
|
|
||||||
magic-string@0.30.5:
|
magic-string@0.30.5:
|
||||||
version "0.30.5"
|
version "0.30.5"
|
||||||
resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.5.tgz#1994d980bd1c8835dc6e78db7cbd4ae4f24746f9"
|
resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.5.tgz#1994d980bd1c8835dc6e78db7cbd4ae4f24746f9"
|
||||||
|
@ -6476,7 +6502,16 @@ string-length@^4.0.1:
|
||||||
char-regex "^1.0.2"
|
char-regex "^1.0.2"
|
||||||
strip-ansi "^6.0.0"
|
strip-ansi "^6.0.0"
|
||||||
|
|
||||||
"string-width-cjs@npm:string-width@^4.2.0", "string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
|
"string-width-cjs@npm:string-width@^4.2.0":
|
||||||
|
version "4.2.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
|
||||||
|
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
|
||||||
|
dependencies:
|
||||||
|
emoji-regex "^8.0.0"
|
||||||
|
is-fullwidth-code-point "^3.0.0"
|
||||||
|
strip-ansi "^6.0.1"
|
||||||
|
|
||||||
|
"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
|
||||||
version "4.2.3"
|
version "4.2.3"
|
||||||
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
|
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
|
||||||
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
|
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
|
||||||
|
@ -6517,7 +6552,14 @@ string_decoder@~1.1.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
safe-buffer "~5.1.0"
|
safe-buffer "~5.1.0"
|
||||||
|
|
||||||
"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1:
|
"strip-ansi-cjs@npm:strip-ansi@^6.0.1":
|
||||||
|
version "6.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
|
||||||
|
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
|
||||||
|
dependencies:
|
||||||
|
ansi-regex "^5.0.1"
|
||||||
|
|
||||||
|
strip-ansi@^6.0.0, strip-ansi@^6.0.1:
|
||||||
version "6.0.1"
|
version "6.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
|
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
|
||||||
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
|
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
|
||||||
|
@ -7034,6 +7076,11 @@ utils-merge@1.0.1:
|
||||||
resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713"
|
resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713"
|
||||||
integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==
|
integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==
|
||||||
|
|
||||||
|
uuid@10.0.0:
|
||||||
|
version "10.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/uuid/-/uuid-10.0.0.tgz#5a95aa454e6e002725c79055fd42aaba30ca6294"
|
||||||
|
integrity sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==
|
||||||
|
|
||||||
uuid@9.0.1, uuid@^9.0.0, uuid@^9.0.1:
|
uuid@9.0.1, uuid@^9.0.0, uuid@^9.0.1:
|
||||||
version "9.0.1"
|
version "9.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/uuid/-/uuid-9.0.1.tgz#e188d4c8853cc722220392c424cd637f32293f30"
|
resolved "https://registry.yarnpkg.com/uuid/-/uuid-9.0.1.tgz#e188d4c8853cc722220392c424cd637f32293f30"
|
||||||
|
@ -7198,7 +7245,7 @@ wordwrap@^1.0.0:
|
||||||
resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb"
|
resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb"
|
||||||
integrity sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==
|
integrity sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==
|
||||||
|
|
||||||
"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0:
|
"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0":
|
||||||
version "7.0.0"
|
version "7.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
|
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
|
||||||
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
|
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
|
||||||
|
@ -7216,6 +7263,15 @@ wrap-ansi@^6.0.1, wrap-ansi@^6.2.0:
|
||||||
string-width "^4.1.0"
|
string-width "^4.1.0"
|
||||||
strip-ansi "^6.0.0"
|
strip-ansi "^6.0.0"
|
||||||
|
|
||||||
|
wrap-ansi@^7.0.0:
|
||||||
|
version "7.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
|
||||||
|
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
|
||||||
|
dependencies:
|
||||||
|
ansi-styles "^4.0.0"
|
||||||
|
string-width "^4.1.0"
|
||||||
|
strip-ansi "^6.0.0"
|
||||||
|
|
||||||
wrap-ansi@^8.1.0:
|
wrap-ansi@^8.1.0:
|
||||||
version "8.1.0"
|
version "8.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214"
|
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214"
|
||||||
|
|
Loading…
Reference in New Issue