Skip to content

Commit 344a59f

Browse files
committed
feat: conflict requests
1 parent d2bafa9 commit 344a59f

File tree

21 files changed

+481
-50
lines changed

21 files changed

+481
-50
lines changed

backend/src/app/analytic/analytic.module.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ import { ProgramService } from "../program/program.service";
2424
import { Program } from "../program/entities/program.entity";
2525
import { RequestProgramService } from "../request-program/request-program.service";
2626
import { RequestProgram } from "../request-program/entities/request-program.entity";
27+
import { PassportProgram } from "../passport-program/entities/passport-program.entity";
28+
import { PassportProgramService } from "../passport-program/passport-program.service";
2729

2830
@Module({
2931
imports: [
@@ -39,6 +41,7 @@ import { RequestProgram } from "../request-program/entities/request-program.enti
3941
Student,
4042
Program,
4143
RequestProgram,
44+
PassportProgram,
4245
]),
4346
SSEModule,
4447
],
@@ -55,6 +58,7 @@ import { RequestProgram } from "../request-program/entities/request-program.enti
5558
PeriodService,
5659
StudentService,
5760
RequestProgramService,
61+
PassportProgramService,
5862
],
5963
})
6064
export class AnalyticModule {}

backend/src/app/app.module.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import { ServeStaticModule } from "@nestjs/serve-static";
2727
import { SSEModule } from "./sse/sse.module";
2828
import { ProgramModule } from "./program/program.module";
2929
import { RequestProgramModule } from "./request-program/request-program.module";
30+
import { PassportProgramModule } from "./passport-program/passport-program.module";
3031

3132
@Module({
3233
imports: [
@@ -72,6 +73,7 @@ import { RequestProgramModule } from "./request-program/request-program.module";
7273
SSEModule,
7374
ProgramModule,
7475
RequestProgramModule,
76+
PassportProgramModule,
7577
],
7678
controllers: [AppController],
7779
providers: [AppService],

backend/src/app/partner/partner.controller.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,13 @@ export class PartnerController {
4141
createRequestReport(@Body() createRequestReportDto: CreateRequestReportDto) {
4242
return this.partnerService.createRequestReport(createRequestReportDto);
4343
}
44+
@ApiBearerAuth()
45+
@Post("request-conflict/report")
46+
@UsePipes(new ValidationPipe())
47+
@UseGuards(JwtAuthGuard)
48+
createRequestConflictReport(@Body() dto: CreateRequestReportDto) {
49+
return this.partnerService.createRequestConflictReport(dto);
50+
}
4451

4552
@ApiBearerAuth()
4653
@Post("passport/report")

backend/src/app/partner/partner.module.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ import { Program } from "../program/entities/program.entity";
2020
import { ProgramService } from "../program/program.service";
2121
import { RequestProgramService } from "../request-program/request-program.service";
2222
import { RequestProgram } from "../request-program/entities/request-program.entity";
23+
import { PassportProgramService } from "../passport-program/passport-program.service";
24+
import { PassportProgram } from "../passport-program/entities/passport-program.entity";
2325

2426
@Module({
2527
imports: [
@@ -33,6 +35,7 @@ import { RequestProgram } from "../request-program/entities/request-program.enti
3335
Period,
3436
Program,
3537
RequestProgram,
38+
PassportProgram,
3639
]),
3740
SSEModule,
3841
],
@@ -42,6 +45,7 @@ import { RequestProgram } from "../request-program/entities/request-program.enti
4245
PassportService,
4346
ProgramService,
4447
RequestProgramService,
48+
PassportProgramService,
4549
RequestService,
4650
CourseService,
4751
CustomerCompanyService,

backend/src/app/partner/partner.service.ts

Lines changed: 221 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import { RequestProgramService } from "../request-program/request-program.servic
3232
import { v4 as uuidv4 } from "uuid";
3333
import { CreateRequestReportDto } from "./dto/create-request-report.dto";
3434
import { CreatePassportReportDto } from "./dto/create-passport-report.dto";
35+
import { PassportProgramService } from "../passport-program/passport-program.service";
3536

3637
const XLSX = require("xlsx");
3738
const JS_XLSX = require("js-xlsx");
@@ -50,6 +51,7 @@ export class PartnerService {
5051
private readonly periodService: PeriodService,
5152
private readonly programService: ProgramService,
5253
private readonly requestProgramService: RequestProgramService,
54+
private readonly passportProgramService: PassportProgramService,
5355
private readonly sseService: SSEService,
5456
) {}
5557

@@ -317,21 +319,6 @@ export class PartnerService {
317319
await this.requestService.update(currentRequest.id, RequestMappers.toUpdateDto(currentRequest));
318320
}
319321

320-
for (let program of currentPassport.programs) {
321-
if (!(await this.requestProgramService.isCreate(currentRequest.id, program.program.id))) {
322-
// Программы для заявки не существует
323-
if (await this.programService.isCreate(program.program.id)) {
324-
const requestProgram = await this.requestProgramService.create({
325-
requestId: currentRequest.id,
326-
programId: program.program.id,
327-
});
328-
this.logger.log(
329-
"\tCreate request program: (id:" + requestProgram.requestProgramID + ")",
330-
);
331-
}
332-
}
333-
}
334-
335322
if (!(await this.passportService.isCreate(passport.id))) {
336323
// Паспорта не существует
337324
this.logger.log("\tCreate passport: (id:" + passport.id + ")");
@@ -343,6 +330,21 @@ export class PartnerService {
343330
PassportMappers.toUpdateDto(currentPassport),
344331
);
345332
}
333+
334+
for (let program of currentPassport.programs) {
335+
if (!(await this.passportProgramService.isCreate(currentPassport.id, program.program.id))) {
336+
// Программы для паспорта не существует
337+
if (await this.programService.isCreate(program.program.id)) {
338+
const passportProgram = await this.passportProgramService.create({
339+
passportId: currentPassport.id,
340+
programId: program.program.id,
341+
});
342+
this.logger.log(
343+
"\tCreate passport program: (id:" + passportProgram.passportProgramID + ")",
344+
);
345+
}
346+
}
347+
}
346348
}
347349
} catch (error) {
348350
throw new BadRequestException(error);
@@ -765,4 +767,208 @@ export class PartnerService {
765767
console.log("End of create report");
766768
return { reportFile: `${bookId}.xlsx` };
767769
}
770+
771+
async createRequestConflictReport(dto: CreateRequestReportDto) {
772+
let requests = await this.requestService.findConflicts({
773+
period_id: dto.periodId,
774+
programs: [],
775+
});
776+
777+
let workbook = XLSX.utils.book_new();
778+
779+
let requestsWithMixedSheet = {
780+
"!ref": "A1:K" + (requests.requestsWithMixed.length + 1),
781+
A1: {
782+
t: "s",
783+
v: "Номер заявки",
784+
},
785+
B1: {
786+
t: "s",
787+
v: "Название",
788+
},
789+
C1: {
790+
t: "s",
791+
v: "Описание",
792+
},
793+
D1: {
794+
t: "s",
795+
v: "Цель",
796+
},
797+
E1: {
798+
t: "s",
799+
v: "Критерии",
800+
},
801+
F1: {
802+
t: "s",
803+
v: "Статус",
804+
},
805+
G1: {
806+
t: "s",
807+
v: "Заказчик",
808+
},
809+
H1: {
810+
t: "s",
811+
v: "Представитель заказчика",
812+
},
813+
I1: {
814+
t: "s",
815+
v: "Количество паспортов",
816+
},
817+
J1: {
818+
t: "s",
819+
v: "Ссылка",
820+
},
821+
K1: {
822+
t: "s",
823+
v: "Программы",
824+
},
825+
};
826+
827+
requests.requestsWithMixed.forEach((request, index) => {
828+
requestsWithMixedSheet["A" + (index + 2)] = { t: "s", v: request.uid };
829+
requestsWithMixedSheet["B" + (index + 2)] = { t: "s", v: request.name };
830+
requestsWithMixedSheet["C" + (index + 2)] = {
831+
t: "s",
832+
v: htmlToText(request.description),
833+
};
834+
requestsWithMixedSheet["D" + (index + 2)] = {
835+
t: "s",
836+
v: htmlToText(request.goal),
837+
};
838+
requestsWithMixedSheet["E" + (index + 2)] = {
839+
t: "s",
840+
v: htmlToText(request.criteria),
841+
};
842+
requestsWithMixedSheet["F" + (index + 2)] = {
843+
t: "s",
844+
v: htmlToText(request.status),
845+
};
846+
requestsWithMixedSheet["G" + (index + 2)] = {
847+
t: "s",
848+
v: htmlToText(request.customer_user.customer_company.name),
849+
};
850+
requestsWithMixedSheet["H" + (index + 2)] = {
851+
t: "s",
852+
v:
853+
(request.customer_user.last_name || "") +
854+
" " +
855+
(request.customer_user.first_name || "") +
856+
" " +
857+
(request.customer_user.middle_name || ""),
858+
};
859+
requestsWithMixedSheet["I" + (index + 2)] = {
860+
t: "s",
861+
v: request.passports.length,
862+
};
863+
requestsWithMixedSheet["J" + (index + 2)] = {
864+
t: "s",
865+
v: "https://partner.urfu.ru/ptraining/services/learning/#/requests/" + request.id,
866+
};
867+
requestsWithMixedSheet["K" + (index + 2)] = {
868+
t: "s",
869+
v: request.programs.map((p) => `${p.program.uid} ${p.program.name}`).join("\n"),
870+
};
871+
});
872+
873+
let requestsWithoutShesterov = {
874+
"!ref": "A1:K" + (requests.requestsWithoutShesterov.length + 1),
875+
A1: {
876+
t: "s",
877+
v: "Номер заявки",
878+
},
879+
B1: {
880+
t: "s",
881+
v: "Название",
882+
},
883+
C1: {
884+
t: "s",
885+
v: "Описание",
886+
},
887+
D1: {
888+
t: "s",
889+
v: "Цель",
890+
},
891+
E1: {
892+
t: "s",
893+
v: "Критерии",
894+
},
895+
F1: {
896+
t: "s",
897+
v: "Статус",
898+
},
899+
G1: {
900+
t: "s",
901+
v: "Заказчик",
902+
},
903+
H1: {
904+
t: "s",
905+
v: "Представитель заказчика",
906+
},
907+
I1: {
908+
t: "s",
909+
v: "Количество паспортов",
910+
},
911+
J1: {
912+
t: "s",
913+
v: "Ссылка",
914+
},
915+
K1: {
916+
t: "s",
917+
v: "Программы",
918+
},
919+
};
920+
921+
requests.requestsWithoutShesterov.forEach((request, index) => {
922+
requestsWithoutShesterov["A" + (index + 2)] = { t: "s", v: request.uid };
923+
requestsWithoutShesterov["B" + (index + 2)] = { t: "s", v: request.name };
924+
requestsWithoutShesterov["C" + (index + 2)] = {
925+
t: "s",
926+
v: htmlToText(request.description),
927+
};
928+
requestsWithoutShesterov["D" + (index + 2)] = {
929+
t: "s",
930+
v: htmlToText(request.goal),
931+
};
932+
requestsWithoutShesterov["E" + (index + 2)] = {
933+
t: "s",
934+
v: htmlToText(request.criteria),
935+
};
936+
requestsWithoutShesterov["F" + (index + 2)] = {
937+
t: "s",
938+
v: htmlToText(request.status),
939+
};
940+
requestsWithoutShesterov["G" + (index + 2)] = {
941+
t: "s",
942+
v: htmlToText(request.customer_user.customer_company.name),
943+
};
944+
requestsWithoutShesterov["H" + (index + 2)] = {
945+
t: "s",
946+
v:
947+
(request.customer_user.last_name || "") +
948+
" " +
949+
(request.customer_user.first_name || "") +
950+
" " +
951+
(request.customer_user.middle_name || ""),
952+
};
953+
requestsWithoutShesterov["I" + (index + 2)] = {
954+
t: "s",
955+
v: request.passports.length,
956+
};
957+
requestsWithoutShesterov["J" + (index + 2)] = {
958+
t: "s",
959+
v: "https://partner.urfu.ru/ptraining/services/learning/#/requests/" + request.id,
960+
};
961+
requestsWithoutShesterov["K" + (index + 2)] = {
962+
t: "s",
963+
v: request.programs.map((p) => `${p.program.uid} ${p.program.name}`).join("\n"),
964+
};
965+
});
966+
967+
XLSX.utils.book_append_sheet(workbook, requestsWithMixedSheet, "Есть целевые и другие");
968+
XLSX.utils.book_append_sheet(workbook, requestsWithoutShesterov, "Есть только другие");
969+
const bookId = uuidv4();
970+
JS_XLSX.writeFile(workbook, `static/${bookId}.xlsx`);
971+
console.log("End of create report");
972+
return { reportFile: `${bookId}.xlsx` };
973+
}
768974
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { IsNumber } from "class-validator";
2+
import { ApiProperty } from "@nestjs/swagger";
3+
4+
export class CreatePassportProgramDto {
5+
@ApiProperty()
6+
@IsNumber()
7+
passportId: number;
8+
9+
@ApiProperty()
10+
@IsNumber()
11+
programId: number;
12+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { Column, Entity, JoinColumn, ManyToOne, PrimaryGeneratedColumn } from "typeorm";
2+
import { ApiProperty } from "@nestjs/swagger";
3+
import { Program } from "../../program/entities/program.entity";
4+
import { Passport } from "../../passport/entities/passport.entity";
5+
6+
@Entity()
7+
export class PassportProgram {
8+
@ApiProperty()
9+
@PrimaryGeneratedColumn()
10+
id: number;
11+
12+
@Column({ nullable: true })
13+
status: string;
14+
15+
@ManyToOne(() => Passport, (passport) => passport.id, { nullable: true })
16+
@JoinColumn({ name: "passport" })
17+
passport: Passport;
18+
19+
@ManyToOne(() => Program, (program) => program.id, { nullable: true })
20+
@JoinColumn({ name: "program" })
21+
program: Program;
22+
}

0 commit comments

Comments
 (0)