feat: integration export report
parent
ed66b88dd0
commit
f9c36582e1
|
@ -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",
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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"
|
||||
|
|
Loading…
Reference in New Issue