162 lines
5.0 KiB
TypeScript
162 lines
5.0 KiB
TypeScript
import {
|
|
Injectable,
|
|
Logger,
|
|
UnprocessableEntityException,
|
|
} from '@nestjs/common';
|
|
import { BaseDataService } from 'src/core/modules/data/service/base-data.service';
|
|
import {
|
|
SalesPriceFormulaEntity,
|
|
TransactionSetting,
|
|
} from '../../domain/entities/sales-price-formula.entity';
|
|
import { InjectRepository } from '@nestjs/typeorm';
|
|
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';
|
|
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';
|
|
import { TransactionType } from 'src/modules/transaction/transaction/constants';
|
|
|
|
@Injectable()
|
|
export class SalesPriceFormulaDataService extends BaseDataService<SalesPriceFormulaEntity> {
|
|
constructor(
|
|
@InjectRepository(SalesPriceFormulaModel, CONNECTION_NAME.DEFAULT)
|
|
private repo: Repository<SalesPriceFormulaModel>,
|
|
@InjectRepository(TaxModel, CONNECTION_NAME.DEFAULT)
|
|
private tax: Repository<TaxModel>,
|
|
@InjectRepository(ItemModel, CONNECTION_NAME.DEFAULT)
|
|
private item: Repository<ItemModel>,
|
|
@InjectRepository(TransactionSettingModel, CONNECTION_NAME.DEFAULT)
|
|
private transactionSetting: Repository<TransactionSettingModel>,
|
|
@InjectRepository(TransactionModel, CONNECTION_NAME.DEFAULT)
|
|
private transaction: Repository<TransactionModel>,
|
|
private couchService: CouchService,
|
|
) {
|
|
super(repo);
|
|
}
|
|
|
|
profitShareFormula() {
|
|
return this.repo.find({
|
|
where: {
|
|
type: FormulaType.PROFIT_SHARE,
|
|
},
|
|
});
|
|
}
|
|
|
|
async sentToBlackHole() {
|
|
const transactionSettingData = await this.transactionSetting.findOne({
|
|
where: {},
|
|
});
|
|
const percentage = transactionSettingData?.value ?? 100;
|
|
|
|
// const transactionPercentage = Math.floor(Math.random() * 100) + 1;
|
|
const transactionPercentage = await this.dataSaveFactor();
|
|
|
|
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 = parseInt(
|
|
await this.transaction
|
|
.createQueryBuilder('transaction')
|
|
.select('SUM(transaction.payment_total_pay)', 'sum')
|
|
.where('transaction.created_at > :timestamp', {
|
|
timestamp: todayTimestamp,
|
|
})
|
|
.andWhere('transaction.type = :type', { type: TransactionType.COUNTER })
|
|
.getRawOne()
|
|
.then((result) => result.sum || 0),
|
|
);
|
|
|
|
const couchTransaction = await this.couchService.totalTodayTransactions();
|
|
|
|
if (couchTransaction == 0) return 0;
|
|
|
|
const factor = (totalTransactions / couchTransaction) * 100;
|
|
|
|
return factor;
|
|
}
|
|
|
|
async itemTax(id: string) {
|
|
const item = await this.item.findOne({
|
|
relations: ['tenant'],
|
|
where: {
|
|
id,
|
|
},
|
|
});
|
|
|
|
const tenantShareMargin = item?.tenant?.share_margin;
|
|
const profitShare = (item?.share_profit ?? 0) / 100;
|
|
const tenantShare = tenantShareMargin ? (100 - tenantShareMargin) / 100 : 0;
|
|
|
|
return { profitShare, tenantShare };
|
|
}
|
|
|
|
async salesPriceFormula() {
|
|
const salesFormula = await this.repo.findOne({
|
|
where: {
|
|
type: FormulaType.SALES_PRICE,
|
|
},
|
|
});
|
|
|
|
const taxes = await this.tax.find();
|
|
|
|
for (const tax of taxes) {
|
|
salesFormula.formula_string = salesFormula.formula_string.replace(
|
|
tax.name,
|
|
`(${tax.formula_string})`,
|
|
);
|
|
}
|
|
|
|
const counter = {};
|
|
do {
|
|
let isInfinite = false;
|
|
for (const tax of taxes) {
|
|
salesFormula.formula_string = salesFormula.formula_string.replace(
|
|
`${tax.name}_value`,
|
|
`(${tax.formula_string})`,
|
|
);
|
|
|
|
if (salesFormula.formula_string.includes(`${tax.name}_value`))
|
|
counter[tax.name] = counter[tax.name] ? counter[tax.name] + 1 : 1;
|
|
|
|
for (const count of Object.keys(counter)) {
|
|
if (!isInfinite && counter[count] > 50) isInfinite = true;
|
|
}
|
|
}
|
|
|
|
if (isInfinite) {
|
|
throw new UnprocessableEntityException({
|
|
message: 'Infinity Loop Formula, please fix formula',
|
|
error: 'Infinity Loop Formula',
|
|
meta: counter,
|
|
});
|
|
}
|
|
} while (salesFormula.formula_string.includes('_value'));
|
|
|
|
return salesFormula;
|
|
}
|
|
}
|
|
|
|
@Injectable()
|
|
export class TransactionSettingDataService extends BaseDataService<TransactionSetting> {
|
|
constructor(
|
|
@InjectRepository(TransactionSettingModel, CONNECTION_NAME.DEFAULT)
|
|
private repo: Repository<TransactionSettingModel>,
|
|
) {
|
|
super(repo);
|
|
}
|
|
}
|