Добавлена генерация отчёта для дейли по расписанию

This commit is contained in:
Pavel Gnedov 2022-11-14 19:19:59 +07:00
parent 4452a3fa2b
commit cc34a620f1
6 changed files with 158 additions and 1 deletions

View file

@ -7,5 +7,9 @@
"name": "", "name": "",
"people": [""] "people": [""]
} }
] ],
"dailyTime": {
"hour": 9,
"minute": 0
}
} }

76
package-lock.json generated
View file

@ -14,6 +14,7 @@
"@nestjs/core": "^8.0.0", "@nestjs/core": "^8.0.0",
"@nestjs/platform-express": "^8.0.0", "@nestjs/platform-express": "^8.0.0",
"@nestjs/platform-socket.io": "^8.4.4", "@nestjs/platform-socket.io": "^8.4.4",
"@nestjs/schedule": "^2.1.0",
"@nestjs/serve-static": "^2.2.2", "@nestjs/serve-static": "^2.2.2",
"@nestjs/websockets": "^8.4.4", "@nestjs/websockets": "^8.4.4",
"axios": "^0.27.2", "axios": "^0.27.2",
@ -35,6 +36,7 @@
"@nestjs/schematics": "^8.0.0", "@nestjs/schematics": "^8.0.0",
"@nestjs/testing": "^8.0.0", "@nestjs/testing": "^8.0.0",
"@types/cache-manager": "^4.0.1", "@types/cache-manager": "^4.0.1",
"@types/cron": "^2.0.0",
"@types/express": "^4.17.13", "@types/express": "^4.17.13",
"@types/jest": "27.4.0", "@types/jest": "27.4.0",
"@types/luxon": "^3.1.0", "@types/luxon": "^3.1.0",
@ -1630,6 +1632,20 @@
"rxjs": "^7.1.0" "rxjs": "^7.1.0"
} }
}, },
"node_modules/@nestjs/schedule": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/@nestjs/schedule/-/schedule-2.1.0.tgz",
"integrity": "sha512-4Xaw56WiW3VsxEPPnj/iDtfjcO+sUZyYAeRxD0gnF5havncxjAnv52Iw7UH3DuzzUA784xPGgGje3Fq0Gu925g==",
"dependencies": {
"cron": "2.0.0",
"uuid": "8.3.2"
},
"peerDependencies": {
"@nestjs/common": "^7.0.0 || ^8.0.0 || ^9.0.0",
"@nestjs/core": "^7.0.0 || ^8.0.0 || ^9.0.0",
"reflect-metadata": "^0.1.12"
}
},
"node_modules/@nestjs/schematics": { "node_modules/@nestjs/schematics": {
"version": "8.0.11", "version": "8.0.11",
"resolved": "https://registry.npmjs.org/@nestjs/schematics/-/schematics-8.0.11.tgz", "resolved": "https://registry.npmjs.org/@nestjs/schematics/-/schematics-8.0.11.tgz",
@ -1986,6 +2002,16 @@
"resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.12.tgz", "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.12.tgz",
"integrity": "sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw==" "integrity": "sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw=="
}, },
"node_modules/@types/cron": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/@types/cron/-/cron-2.0.0.tgz",
"integrity": "sha512-xZM08fqvwIXgghtPVkSPKNgC+JoMQ2OHazEvyTKnNf7aWu1aB6/4lBbQFrb03Td2cUGG7ITzMv3mFYnMu6xRaQ==",
"dev": true,
"dependencies": {
"@types/luxon": "*",
"@types/node": "*"
}
},
"node_modules/@types/eslint": { "node_modules/@types/eslint": {
"version": "8.4.5", "version": "8.4.5",
"resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.4.5.tgz", "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.4.5.tgz",
@ -3640,6 +3666,22 @@
"integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
"dev": true "dev": true
}, },
"node_modules/cron": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/cron/-/cron-2.0.0.tgz",
"integrity": "sha512-RPeRunBCFr/WEo7WLp8Jnm45F/ziGJiHVvVQEBSDTSGu6uHW49b2FOP2O14DcXlGJRLhwE7TIoDzHHK4KmlL6g==",
"dependencies": {
"luxon": "^1.23.x"
}
},
"node_modules/cron/node_modules/luxon": {
"version": "1.28.0",
"resolved": "https://registry.npmjs.org/luxon/-/luxon-1.28.0.tgz",
"integrity": "sha512-TfTiyvZhwBYM/7QdAVDh+7dBTBA29v4ik0Ce9zda3Mnf8on1S5KJI8P2jKFZ8+5C0jhmr0KwJEO/Wdpm0VeWJQ==",
"engines": {
"node": "*"
}
},
"node_modules/cross-spawn": { "node_modules/cross-spawn": {
"version": "7.0.3", "version": "7.0.3",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
@ -11534,6 +11576,15 @@
"tslib": "2.4.0" "tslib": "2.4.0"
} }
}, },
"@nestjs/schedule": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/@nestjs/schedule/-/schedule-2.1.0.tgz",
"integrity": "sha512-4Xaw56WiW3VsxEPPnj/iDtfjcO+sUZyYAeRxD0gnF5havncxjAnv52Iw7UH3DuzzUA784xPGgGje3Fq0Gu925g==",
"requires": {
"cron": "2.0.0",
"uuid": "8.3.2"
}
},
"@nestjs/schematics": { "@nestjs/schematics": {
"version": "8.0.11", "version": "8.0.11",
"resolved": "https://registry.npmjs.org/@nestjs/schematics/-/schematics-8.0.11.tgz", "resolved": "https://registry.npmjs.org/@nestjs/schematics/-/schematics-8.0.11.tgz",
@ -11813,6 +11864,16 @@
"resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.12.tgz", "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.12.tgz",
"integrity": "sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw==" "integrity": "sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw=="
}, },
"@types/cron": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/@types/cron/-/cron-2.0.0.tgz",
"integrity": "sha512-xZM08fqvwIXgghtPVkSPKNgC+JoMQ2OHazEvyTKnNf7aWu1aB6/4lBbQFrb03Td2cUGG7ITzMv3mFYnMu6xRaQ==",
"dev": true,
"requires": {
"@types/luxon": "*",
"@types/node": "*"
}
},
"@types/eslint": { "@types/eslint": {
"version": "8.4.5", "version": "8.4.5",
"resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.4.5.tgz", "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.4.5.tgz",
@ -13124,6 +13185,21 @@
"integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
"dev": true "dev": true
}, },
"cron": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/cron/-/cron-2.0.0.tgz",
"integrity": "sha512-RPeRunBCFr/WEo7WLp8Jnm45F/ziGJiHVvVQEBSDTSGu6uHW49b2FOP2O14DcXlGJRLhwE7TIoDzHHK4KmlL6g==",
"requires": {
"luxon": "^1.23.x"
},
"dependencies": {
"luxon": {
"version": "1.28.0",
"resolved": "https://registry.npmjs.org/luxon/-/luxon-1.28.0.tgz",
"integrity": "sha512-TfTiyvZhwBYM/7QdAVDh+7dBTBA29v4ik0Ce9zda3Mnf8on1S5KJI8P2jKFZ8+5C0jhmr0KwJEO/Wdpm0VeWJQ=="
}
}
},
"cross-spawn": { "cross-spawn": {
"version": "7.0.3", "version": "7.0.3",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",

View file

@ -26,6 +26,7 @@
"@nestjs/core": "^8.0.0", "@nestjs/core": "^8.0.0",
"@nestjs/platform-express": "^8.0.0", "@nestjs/platform-express": "^8.0.0",
"@nestjs/platform-socket.io": "^8.4.4", "@nestjs/platform-socket.io": "^8.4.4",
"@nestjs/schedule": "^2.1.0",
"@nestjs/serve-static": "^2.2.2", "@nestjs/serve-static": "^2.2.2",
"@nestjs/websockets": "^8.4.4", "@nestjs/websockets": "^8.4.4",
"axios": "^0.27.2", "axios": "^0.27.2",
@ -47,6 +48,7 @@
"@nestjs/schematics": "^8.0.0", "@nestjs/schematics": "^8.0.0",
"@nestjs/testing": "^8.0.0", "@nestjs/testing": "^8.0.0",
"@types/cache-manager": "^4.0.1", "@types/cache-manager": "^4.0.1",
"@types/cron": "^2.0.0",
"@types/express": "^4.17.13", "@types/express": "^4.17.13",
"@types/jest": "27.4.0", "@types/jest": "27.4.0",
"@types/luxon": "^3.1.0", "@types/luxon": "^3.1.0",

View file

@ -30,6 +30,8 @@ import { DailyEccmReportController } from './reports/daily-eccm.report.controlle
import { DailyEccmReportService } from './reports/daily-eccm.report.service'; import { DailyEccmReportService } from './reports/daily-eccm.report.service';
import { ChangesService } from './changes/changes.service'; import { ChangesService } from './changes/changes.service';
import { DailyEccmReportsDatasource } from './couchdb-datasources/daily-eccm-reports.datasource'; import { DailyEccmReportsDatasource } from './couchdb-datasources/daily-eccm-reports.datasource';
import { ScheduleModule } from '@nestjs/schedule';
import { DailyEccmReportTask } from './reports/daily-eccm.report.task';
@Module({ @Module({
imports: [ imports: [
@ -40,6 +42,7 @@ import { DailyEccmReportsDatasource } from './couchdb-datasources/daily-eccm-rep
CacheModule.register({ CacheModule.register({
isGlobal: true, isGlobal: true,
}), }),
ScheduleModule.forRoot(),
], ],
controllers: [ controllers: [
AppController, AppController,
@ -66,6 +69,7 @@ import { DailyEccmReportsDatasource } from './couchdb-datasources/daily-eccm-rep
DailyEccmReportService, DailyEccmReportService,
ChangesService, ChangesService,
DailyEccmReportsDatasource, DailyEccmReportsDatasource,
DailyEccmReportTask,
], ],
}) })
export class AppModule implements OnModuleInit { export class AppModule implements OnModuleInit {

View file

@ -10,5 +10,9 @@ export namespace EccmConfig {
projectName: string; projectName: string;
currentIssuesStatuses: string[]; currentIssuesStatuses: string[];
groups: UserGroup[]; groups: UserGroup[];
dailyTime: {
hour: number;
minute: number;
};
}; };
} }

View file

@ -0,0 +1,67 @@
import { Injectable, Logger } from '@nestjs/common';
import { Cron } from '@nestjs/schedule';
import { DailyEccmReportService } from './daily-eccm.report.service';
import { DateTime, Duration } from 'luxon';
import { ConfigService } from '@nestjs/config';
// eslint-disable-next-line @typescript-eslint/no-namespace
namespace Models {
export type Time = {
hour: number;
minute: number;
};
}
@Injectable()
export class DailyEccmReportTask {
private logger = new Logger(DailyEccmReportTask.name);
private eccmDailyTime: Models.Time;
constructor(
private dailyEccmReportService: DailyEccmReportService,
private configService: ConfigService,
) {
this.eccmDailyTime = this.configService.get<Models.Time>(
'redmineEccm.dailyTime',
);
}
@Cron('25 9,10 1-5 * *')
async generateReport(): Promise<void> {
this.logger.log(`Generate daily eccm report by cron task started`);
const now = DateTime.now();
const toDate = DateTime.local(
now.year,
now.month,
now.day,
this.eccmDailyTime.hour,
this.eccmDailyTime.minute,
);
let duration: Duration;
if (now.weekday == 1) {
duration = Duration.fromObject({ days: -3 });
} else {
duration = Duration.fromObject({ days: -1 });
}
const fromDate = toDate.plus(duration);
const name = now.toFormat('yyyy-MM-dd');
const params = this.dailyEccmReportService.generateParams(
fromDate.toJSDate().toISOString(),
toDate.toJSDate().toISOString(),
name,
);
const reportData = await this.dailyEccmReportService.generateReport(params);
const saveResult = await this.dailyEccmReportService.saveReport(
reportData,
true,
);
this.logger.log(
`Generate daily eccm report by cron task ` +
`finished with params = ${JSON.stringify(params)} ` +
`and result = ${saveResult}`,
);
return;
}
}