pos-be/src/modules/reports/report/report.service.ts

151 lines
5.4 KiB
TypeScript

import { Injectable, Logger } from '@nestjs/common';
import { BaseReportService } from '../shared/services/base-report.service';
import { GetReportConfigDto } from '../shared/dto/report-config.get.dto';
import { GetReportDataDto } from '../shared/dto/report-data.get.dto';
import { ReportConfigs } from '../shared/configs';
import { InjectDataSource } from '@nestjs/typeorm';
import { CONNECTION_NAME } from 'src/core/strings/constants/base.constants';
import { DataSource } from 'typeorm';
import { ReportConfigEntity } from '../shared/entities/report-config.entity';
import { ReportQueryBuilder } from '../shared/helpers';
import { DATA_FORMAT } from '../shared/constant';
import { roundingCurrency } from '../shared/helpers/rounding-currency';
@Injectable()
export class ReportService extends BaseReportService {
private readonly logger = new Logger(ReportService.name);
constructor(
@InjectDataSource(CONNECTION_NAME.DEFAULT)
private dataSource: DataSource,
) {
super();
}
async getReportConfig(query: GetReportConfigDto) {
const { unique_names = [], group_names = [] } = query;
let configs = ReportConfigs;
if (group_names.length > 0) {
configs = configs.filter((item) => group_names.includes(item.group_name));
}
if (unique_names.length > 0) {
configs = configs.filter((item) =>
unique_names.includes(item.unique_name),
);
}
return configs;
}
getReportConfigByUniqueName(unique_name): ReportConfigEntity {
return ReportConfigs.find((item) => item.unique_name === unique_name);
}
async getReportData(body: GetReportDataDto) {
try {
const queryModel = body.query_model;
const reportConfig = this.getReportConfigByUniqueName(body.unique_name);
const builder = new ReportQueryBuilder(reportConfig, queryModel);
const SQL = builder.getSql();
const queryResult = await this.dataSource.query(SQL);
const realData = [];
const configColumns = reportConfig.column_configs;
for (const item of queryResult) {
const realItem = {};
for (const itemKey of Object.keys(item)) {
if (itemKey === 'count_child_group') {
const realValue = item[itemKey] ?? 0;
Object.assign(realItem, { [`${itemKey}`]: Number(realValue) });
} else {
const confCol = configColumns.find((c) => c.column === itemKey);
const isNumber = confCol.format === DATA_FORMAT.NUMBER;
const isCurrency = confCol.format === DATA_FORMAT.CURRENCY;
const isMinusCurrency =
confCol.format === DATA_FORMAT.MINUS_CURRENCY;
const isBoolean = confCol.format === DATA_FORMAT.BOOLEAN;
const isPercentage = confCol.format === DATA_FORMAT.PERCENTAGE;
const isSetInitNull = isNumber || isCurrency || isMinusCurrency;
const isTextUpperCase =
confCol.format === DATA_FORMAT.TEXT_UPPERCASE;
const isTextLowerCase =
confCol.format === DATA_FORMAT.TEXT_LOWERCASE;
if (isSetInitNull) {
const realValue = item[itemKey] ?? 0;
if (isCurrency) {
Object.assign(realItem, {
[`${itemKey}`]: roundingCurrency(realValue),
});
} else if (isMinusCurrency) {
Object.assign(realItem, {
[`${itemKey}`]: roundingCurrency(realValue) * -1,
});
} else {
Object.assign(realItem, { [`${itemKey}`]: realValue });
}
} else if (isPercentage) {
const realValue = item[itemKey]
? `${item[itemKey]}%`
: item[itemKey];
Object.assign(realItem, { [`${itemKey}`]: realValue });
} else if (isBoolean) {
let realValue = '';
if (item[itemKey] === true || item[itemKey] === 1)
realValue = 'Yes';
else if (item[itemKey] === false || item[itemKey] === 0)
realValue = 'No';
Object.assign(realItem, { [`${itemKey}`]: realValue });
} else if (isTextUpperCase) {
Object.assign(realItem, {
[`${itemKey}`]: item[itemKey]?.toUpperCase(),
});
} else if (isTextLowerCase) {
Object.assign(realItem, {
[`${itemKey}`]: item[itemKey]?.toLowerCase(),
});
} else {
Object.assign(realItem, { [`${itemKey}`]: item[itemKey] });
}
}
}
realData.push(realItem);
}
return realData;
} catch (error) {
this.logger.error(error);
throw error;
}
}
async getReportMeta(body: GetReportDataDto) {
try {
const queryModel = body.query_model;
const reportConfig = this.getReportConfigByUniqueName(body.unique_name);
const builder = new ReportQueryBuilder(reportConfig, queryModel);
const SQL_COUNT = builder.getSqlCount();
const queryResult = await this.dataSource.query(SQL_COUNT);
const totalRow = parseInt(queryResult[0].count);
const startRow = queryModel.startRow;
const endRow = queryModel.endRow;
const pageSize = endRow - startRow;
const meta = {
total_row: totalRow,
limit: pageSize,
offset: startRow,
};
return meta;
} catch (error) {
this.logger.error(error);
throw error;
}
}
}