feat: integration export report

pull/12/head
Firman Ramdhani 2024-07-04 18:32:03 +07:00
parent ed66b88dd0
commit f9c36582e1
4 changed files with 154 additions and 12 deletions

View File

@ -43,6 +43,7 @@
"elastic-apm-node": "^4.5.4",
"exceljs": "^4.4.0",
"googleapis": "^140.0.0",
"moment": "^2.30.1",
"nano": "^10.1.3",
"pg": "^8.11.5",
"plop": "^4.0.1",

View File

@ -1,4 +1,10 @@
import { Injectable, Logger, Scope } from '@nestjs/common';
import {
Injectable,
Logger,
NotFoundException,
Scope,
UnprocessableEntityException,
} from '@nestjs/common';
import { BaseReportService } from '../shared/services/base-report.service';
import { CreateReportExportDto } from '../shared/dto/report-export.create.dto';
import {
@ -19,6 +25,8 @@ import * as fs from 'fs';
import * as path from 'path';
import * as ExcelJS from 'exceljs';
import { roundingCurrency } from '../shared/helpers';
import { createPaginationMeta } from 'src/core/response/domain/utils/pagination-meta.helper';
import * as moment from 'moment';
@Injectable({ scope: Scope.REQUEST })
export class ReportExportService extends BaseReportService {
@ -97,7 +105,7 @@ export class ReportExportService extends BaseReportService {
group_name: config.group_name,
unique_name: config.unique_name,
label: config.label,
file_name: fileName,
file_name: fName,
file_url: null,
total_data: totalRow,
processing_data: 0,
@ -304,18 +312,152 @@ export class ReportExportService extends BaseReportService {
}
async getAll(query: GetReportExportDto) {
return 'you hit API for get all report export';
const modelName = ExportReportHistoryModel.name;
const page = query.page;
const limit = query.limit;
const creator_id = this.getUser().id;
const group_names = query.group_names;
const unique_names = query.unique_names;
const statuses = query.statuses;
const qb = this.exportHistoryRepo
.createQueryBuilder(modelName)
.where((query) => {
if (unique_names) {
query.andWhere(`unique_name IN (:...unique_names)`, { unique_names });
}
if (group_names) {
query.andWhere(`group_name IN (:...group_names)`, { group_names });
}
if (statuses) {
query.andWhere(`status IN (:...statuses)`, { statuses });
}
query.andWhere(`creator_id = :creator_id`, { creator_id });
})
.orderBy(`${modelName}.created_at`, 'DESC');
const [data, total] = await qb
.take(+limit)
.skip(+limit * +page - +limit)
.getManyAndCount();
const meta = createPaginationMeta(page, limit, data.length, total);
return { data, meta };
}
async delete(id: string) {
return 'you hit API for delete report export';
const findData = await this.exportHistoryRepo.findOneBy({ id });
if (findData && findData?.file_url) {
try {
const directory = './uploads/report-data/';
const filePath = path.join(directory, findData.file_url);
if (fs.existsSync(filePath)) {
fs.unlinkSync(filePath);
await this.exportHistoryRepo.delete(id);
this.logger.warn(
`Successfully deleted the ${findData.file_url} file`,
);
return { success: true, message: 'File deleted successfully' };
} else {
throw new NotFoundException('File not found');
}
} catch (error) {
throw new UnprocessableEntityException('File could not be deleted');
}
}
throw new UnprocessableEntityException();
}
async updateFailedData(group_names, unique_names) {
const creator_id = this.getUser().id;
const aMinutesAgo = moment().subtract(5, 'minutes').valueOf();
await this.exportHistoryRepo
.createQueryBuilder()
.update(ExportReportHistoryModel)
.set({
status: REPORT_HISTORY_STATUS.FAILED,
updated_at: moment().valueOf(),
})
.where((query) => {
if (group_names) {
query.andWhere(`group_name IN (:...group_names)`, { group_names });
}
if (unique_names) {
query.andWhere(`unique_name IN (:...unique_names)`, { unique_names });
}
query.andWhere(`status = :status`, {
status: REPORT_HISTORY_STATUS.PROCESSING,
});
query.andWhere(`updated_at < :aMinutesAgo`, { aMinutesAgo });
query.andWhere(`creator_id = :creator_id`, { creator_id });
})
.execute();
}
async getAllProcessing(query: GetReportExportProcessingDto) {
return 'you hit API for get all processing report export';
const creator_id = this.getUser().id;
const modelName = ExportReportHistoryModel.name;
const group_names = query.group_names;
const unique_names = query.unique_names;
await this.updateFailedData(group_names, unique_names);
const aMinutesAgo = moment().subtract(100, 'seconds').valueOf();
const qb = this.exportHistoryRepo
.createQueryBuilder(modelName)
.where((query) => {
if (group_names) {
query.andWhere(`unique_name IN (:...unique_names)`, { unique_names });
}
if (unique_names) {
query.andWhere(`group_name IN (:...group_names)`, { group_names });
}
query.andWhere(`status IN (:...status)`, {
status: ['processing', 'failed', 'done'],
});
query.andWhere(`updated_at > :aMinutesAgo`, { aMinutesAgo });
query.andWhere(`creator_id = :creator_id`, { creator_id });
})
.orderBy(`${modelName}.created_at`, 'DESC');
const data = await qb.getMany();
return {
data: data,
};
}
async getListHistoryFileName(query: GetReportExportFileNameDto) {
return 'you hit API for get all file name report export';
const modelName = ExportReportHistoryModel.name;
const creator_id = this.getUser().id;
const unique_names = query.unique_names;
const group_names = query.group_names;
const qb = this.exportHistoryRepo
.createQueryBuilder(modelName)
.select(`${modelName}.file_name`)
.where((query) => {
if (unique_names) {
query.andWhere(`unique_name IN (:...unique_names)`, { unique_names });
}
if (group_names) {
query.andWhere(`group_name IN (:...group_names)`, { group_names });
}
query.andWhere(`creator_id = :creator_id`, { creator_id });
})
.distinct(true);
const newData = await qb.getRawMany();
return newData.map((el) => el.ExportReportHistoryModel_file_name);
}
}

View File

@ -46,12 +46,6 @@ export class GetReportExportProcessingDto {
return Array.isArray(body.value) ? body.value : [body.value];
})
unique_names?: string[];
@ApiProperty({ type: ['string'], required: false })
@Transform((body) => {
return Array.isArray(body.value) ? body.value : [body.value];
})
statuses?: string;
}
export class GetReportExportFileNameDto {

View File

@ -5174,6 +5174,11 @@ module-details-from-path@^1.0.3:
resolved "https://registry.yarnpkg.com/module-details-from-path/-/module-details-from-path-1.0.3.tgz#114c949673e2a8a35e9d35788527aa37b679da2b"
integrity sha512-ySViT69/76t8VhE1xXHK6Ch4NcDd26gx0MzKXLO+F7NOtnqH68d9zF94nT8ZWSxXh8ELOERsnJO/sWt1xZYw5A==
moment@^2.30.1:
version "2.30.1"
resolved "https://registry.yarnpkg.com/moment/-/moment-2.30.1.tgz#f8c91c07b7a786e30c59926df530b4eac96974ae"
integrity sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==
monitor-event-loop-delay@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/monitor-event-loop-delay/-/monitor-event-loop-delay-1.0.0.tgz#b5ab78165a3bb93f2b275c50d01430c7f155d1f7"