[docx] Generate 4X4 certificate

This commit is contained in:
Fernando 2023-05-24 15:56:32 -05:00
parent 51a32c7617
commit dcc27291c0
6 changed files with 314 additions and 2 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 547 KiB

BIN
img/mtc_transparente.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

View File

@ -32,7 +32,7 @@ console.log(dotenv.config());
synchronize: false, synchronize: false,
}), }),
], ],
controllers: [CertificateController, PersonController, SubjectController, MigratorController], controllers: [CertificateController, PersonController, SubjectController],
providers: [CertificateService, PersonService, SubjectService], providers: [CertificateService, PersonService, SubjectService],
}) })
export class AppModule {} export class AppModule {}

275
src/certs/4X4.ts Normal file
View File

@ -0,0 +1,275 @@
import {
Document, Packer, Paragraph, PageOrientation,
FrameAnchorType,
TextRun,
AlignmentType,
BorderStyle,
} from "docx";
import { cmText, createSimpleText, getImage, getQR } from "./utils";
import { CertData } from "./CertData";
const imgFondoDoc = getImage({
name: "fondo_certificado_4x4.png",
height: 21.03,
width: 29.69,
horizontalOffset: 0,
verticalOffset: 0.01,
behindDocument: true,
});
const imgCIP = getImage({
name: "colegio_ingenieros_logo.png",
height: 2.15,
width: 2.15,
horizontalOffset: 26.76,
verticalOffset: 12.26,
});
const imgCEE = getImage({
name: "cee_dark_logo.png",
height: 1.5,
width: 2.1,
horizontalOffset: 26.89,
verticalOffset: 17.06,
});
const imgMTC = getImage({
name: "mtc_transparente.png",
height: 1.65,
width: 5.16,
horizontalOffset: 23.92,
verticalOffset: 18.83,
});
const tCertificate = createSimpleText({
xPosition: 7.7,
yPosition: 3.7,
width: 11.05,
height: 1.72,
text: "CERTIFICADO",
size: 72,
font: "Times New Roman",
bold: true,
});
// Otorgado a
const tExpediteText = createSimpleText({
xPosition: 4.2,
yPosition: 5.5,
width: 3,
height: 0.7,
text: "Otorgado a:",
size: 22,
});
// MANEJO EN 4x4 ROAD DANGER
const tCourse = createSimpleText({
xPosition: 1.8,
yPosition: 8.4,
width: 20.92,
height: 1.5,
text: "MANEJO EN 4x4 ROAD DANGER",
size: 44,
bold: true,
});
// (caminos peligrosos)
const tCourseDesc = createSimpleText({
xPosition: 9.7,
yPosition: 9.6,
width: 5,
height: 0.5,
text: "(CAMINOS PELIGROSOS)",
size: 20,
bold: true,
});
// En temas de...
const tTopics = createSimpleText({
xPosition: 2.3,
yPosition: 10.4,
width: 20.92,
height: 1.5,
text: "En temas de: Terreno Firme y Complicado, Reacciones ante Eventos, Manejo Adecuado de Unidad, Uso Correcto de 4x4, Control Adecuado en Trocha y Pendientes, Uso de Velocidad Adecuada, equivalente a 12 horas lectivas.",
size: 22,
font: "Times New Roman",
alignment: AlignmentType.LEFT,
});
// Se expide certificado...
const tFinishLabel = createSimpleText({
xPosition: 5.95,
yPosition: 11.65,
width: 12.38,
height: 0.75,
text: "Se expide el presente certificado para los fines que se estime conveniente",
size: 22,
font: "Times New Roman",
alignment: AlignmentType.CENTER,
});
// Recuadro de foto
const photoSection = new Paragraph({
frame: {
position: {
x: cmText(-1.68),
y: cmText(8.6),
},
width: cmText(2.7),
height: cmText(3.57),
anchor: {
horizontal: FrameAnchorType.MARGIN,
vertical: FrameAnchorType.MARGIN,
},
},
children: [],
border: {
top: {
style: BorderStyle.DASHED,
},
bottom: {
style: BorderStyle.DASHED,
},
left: {
style: BorderStyle.DASHED,
},
right: {
style: BorderStyle.DASHED,
},
},
alignment: AlignmentType.LEFT,
});
export async function _4X4Cert(props: CertData<null>): Promise<Buffer> {
const imgQR = await getQR({
dni: props.personDni,
height: 2.04,
width: 2.04,
horizontalOffset: 26.85,
verticalOffset: 14.71,
});
// FERNANDO ARAOZ
const tName = createSimpleText({
xPosition: 1,
yPosition: 6.2,
width: 23.13,
height: 1.5,
text: props.personFullName,
size: 52,
bold: true,
underline: {},
});
// Identificado con DNI...
const tContentPart1 = new Paragraph({
frame: {
position: {
x: cmText(2.5),
y: cmText(7.6),
},
width: cmText(20.92),
height: cmText(1),
anchor: {
horizontal: FrameAnchorType.MARGIN,
vertical: FrameAnchorType.MARGIN,
},
},
children: [
new TextRun({
text: "Identificado con DNI N° ",
font: "Times New Roman",
size: 22,
}),
new TextRun({
text: props.personDni,
font: "Times New Roman",
size: 24,
bold: true,
}),
new TextRun({
text: ", al haber aprobado el curso de capacitación sobre:",
font: "Times New Roman",
size: 22,
}),
],
alignment: AlignmentType.LEFT,
});
// Fecha de Emision: ...
const certificateDate = new Paragraph({
frame: {
position: {
x: cmText(13),
y: cmText(17.3),
},
width: cmText(7.5),
height: cmText(0.5),
anchor: {
horizontal: FrameAnchorType.MARGIN,
vertical: FrameAnchorType.MARGIN,
},
},
children: [
new TextRun({
text: `Fecha de Emisión:\t${props.certDay} / ${props.certMonth} / ${props.certYear}`,
font: "Times New Roman",
size: 20,
}),
],
alignment: AlignmentType.LEFT,
});
// N° XXXX-20XX-EEG
const tCertCode = createSimpleText({
xPosition: -2.15,
yPosition: 12.45,
width: 3.67,
height: 0.8,
text: `${props.certCode}-${props.certYear}-EEG`,
size: 20,
alignment: AlignmentType.CENTER,
});
const doc = new Document({
sections: [
{
properties: {
page: {
size: {
orientation: PageOrientation.LANDSCAPE,
},
},
},
children: [
tCertificate,
tExpediteText,
tName,
tContentPart1,
tCourse,
tTopics,
tFinishLabel,
certificateDate,
photoSection,
tCertCode,
tCourseDesc,
new Paragraph({
children: [
imgFondoDoc,
imgQR,
imgCIP,
imgCEE,
imgMTC,
],
}),
],
},
],
});
// Return document as a buffer
return await Packer.toBuffer(doc);
}

View File

@ -9,8 +9,9 @@ import { Matpel } from "src/certs/utils";
import { getMatpel } from "./generator/matpel"; import { getMatpel } from "./generator/matpel";
import { getMecanicaBasica } from "./generator/mecanicaBasica"; import { getMecanicaBasica } from "./generator/mecanicaBasica";
import { getManejoDefensivo } from "./generator/manejoDefensivo"; import { getManejoDefensivo } from "./generator/manejoDefensivo";
import { get4x4 } from "./generator/4x4";
const generatable = [1, 2, 10, 11, 12]; const generatable = [1, 2, 3, 10, 11, 12];
@Injectable() @Injectable()
export class CertificateService { export class CertificateService {
@ -92,6 +93,16 @@ export class CertificateService {
certDay, certDay,
); );
} }
// 4x4
case 3: {
return await get4x4(
person,
register,
certYear,
certMonth,
certDay,
);
}
// MATPEL 1 // MATPEL 1
case 10: { case 10: {
return await getMatpel( return await getMatpel(

View File

@ -0,0 +1,26 @@
import { _4X4Cert } from "src/certs/4X4";
import { CertData } from "src/certs/CertData";
import { Persona } from "src/model/Persona/persona.entity";
import { RegistroGIE } from "src/model/RegistroGIE/registroGIE.entity";
export async function get4x4(
person: Persona,
register: RegistroGIE,
certYear: string,
certMonth: string,
certDay: string
): Promise<[Buffer, string]> {
const personFullName = `${person.nombres} ${person.apellidoPaterno} ${person.apellidoMaterno}`;
const data: CertData<null> = {
matpel: null,
personFullName: personFullName,
personDni: register.dni,
certCode: register.codigo.toString().padStart(4, "0"),
certYear,
certMonth,
certDay,
};
return [await _4X4Cert(data), `4X4 - ${personFullName.toUpperCase()}.docx`];
}