diff --git a/img/fondo_super_escolta.png b/img/fondo_super_escolta.png new file mode 100644 index 0000000..3e742d0 Binary files /dev/null and b/img/fondo_super_escolta.png differ diff --git a/img/logo_matpel_transparente.png b/img/logo_matpel_transparente.png new file mode 100644 index 0000000..6147bbc Binary files /dev/null and b/img/logo_matpel_transparente.png differ diff --git a/src/certs/SUPERVISOR_ESCOLTA.ts b/src/certs/SUPERVISOR_ESCOLTA.ts new file mode 100644 index 0000000..24bf49d --- /dev/null +++ b/src/certs/SUPERVISOR_ESCOLTA.ts @@ -0,0 +1,330 @@ +import { + Document, Packer, Paragraph, PageOrientation, + FrameAnchorType, + TextRun, + AlignmentType, + BorderStyle, +} from "docx"; +import { cmText, createSimpleText, createSimpleTextP, getImage, getQR } from "./utils"; +import { CertData } from "./CertData"; + +const imgFondoDoc = getImage({ + name: "fondo_super_escolta.png", + height: 20.99, + width: 29.69, + horizontalOffset: 0, + verticalOffset: 0, + behindDocument: true, +}); + +const imgEEG = getImage({ + name: "eeg_f_logo.png", + height: 4.39, + width: 6.4, + horizontalOffset: 1.19, + verticalOffset: 0.94, +}); + +const imgEATE = getImage({ + name: "eate_logo.jpg", + height: 2.28, + width: 3.39, + horizontalOffset: 0.94, + verticalOffset: 13.77, +}); + +const imgMTC = getImage({ + name: "mtc_logo.png", + height: 1.6, + width: 5, + horizontalOffset: 0.9, + verticalOffset: 17.22, +}); + +const imgOSHA = getImage({ + name: "osha_logo.png", + height: 1.99, + width: 5.72, + horizontalOffset: 22.58, + verticalOffset: 1.29, +}); + +const imgMatpelTransparent = getImage({ + name: "logo_matpel_transparente.png", + height: 18.63, + width: 18.63, + horizontalOffset: 5.38, + verticalOffset: 1.38, +}); + + + +const tCertificate = createSimpleTextP({ + xPosition: 9.18, + yPosition: 2.91, + width: 11.3, + height: 1.46, + text: "CERTIFICADO", + size: 72, + font: "Times New Roman", + bold: true, +}); + +// Se expide el presente +const tLabel3 = createSimpleTextP({ + xPosition: 11.08, + yPosition: 4.62, + width: 7.74, + height: 0.5, + text: "Se expide el presente a:", + size: 22, + font: "Arial", +}); + +// SUPERVISOR ESCOLTA MATPEL +const tCourse = createSimpleTextP({ + xPosition: 7.28, + yPosition: 7.94, + width: 15.42, + height: 1.5, + text: "SUPERVISOR ESCOLTA MATPEL", + size: 52, + bold: true, +}); + +// Por haber aprobado la dormacion... +const tLabel2 = createSimpleTextP({ + xPosition: 10.93, + yPosition: 7.14, + width: 7.74, + height: 0.6, + text: "Por haber aprobado la formación en el curso", + size: 22, + font: "Arial", +}); + +// Temas tratados... +const tTopics = createSimpleTextP({ + xPosition: 5.04, + yPosition: 9.49, + width: 19.34, + height: 1.5, + text: "Temas tratados: Inspección de Unidades y Llenado de Herramientas de Gestión Check List, IPERC, Inspección básica de Kit de Emergencias, Parada de Controles e Inspección, Delimitación y Evaluación del Evento, Sistemas de Comando de Incidentes, Practicas Reales en caso de Derrames de MATPEL con Trajes, Evacuación de Pacientes Afectados con Camioneta, Primeros Auxilios básico, Con una duración de 36 horas lectivas.", + size: 22, + font: "Arial", + alignment: AlignmentType.JUSTIFIED, +}); + +// Respaldado por: +const tHours = createSimpleTextP({ + xPosition: 1.15, + yPosition: 13.15, + width: 3.07, + height: 0.5, + text: "Respaldado por:", + size: 22, + font: "Arial", + italics: true, + alignment: AlignmentType.LEFT, +}); + +// Chile +const tChile = createSimpleTextP({ + xPosition: 3.07, + yPosition: 15.98, + width: 1.43, + height: 0.5, + text: "CHILE", + size: 22, + font: "Times New Roman", + bold: true, + alignment: AlignmentType.LEFT, +}); + +// Se expide certificado... +const tFinishLabel = createSimpleTextP({ + xPosition: 8.22, + yPosition: 11.87, + width: 13.15, + height: 0.5, + text: "Se expide el presente certificado para los fines que se estime conveniente", + size: 22, + font: "Arial", + italics: true, + alignment: AlignmentType.CENTER, +}); + + +// Recuadro de foto +const photoSection = new Paragraph({ + frame: { + position: { + x: cmText(25), + y: cmText(4.37), + }, + height: cmText(3.57), + width: cmText(2.81), + anchor: { + horizontal: FrameAnchorType.PAGE, + vertical: FrameAnchorType.PAGE, + }, + }, + children: [], + border: { + top: { + style: BorderStyle.DASHED, + size: 2, + }, + bottom: { + style: BorderStyle.DASHED, + size: 2, + }, + left: { + style: BorderStyle.DASHED, + size: 2, + }, + right: { + style: BorderStyle.DASHED, + size: 2, + }, + }, + alignment: AlignmentType.LEFT, +}); + + +export async function supervisorEscolta(props: CertData): Promise { + const imgQR = await getQR({ + iid: props.certIId, + dni: props.personDni, + height: 2.5, + width: 2.5, + horizontalOffset: 25.85, + verticalOffset: 15.88, + }); + + // FERNANDO ARAOZ + const tName = createSimpleTextP({ + xPosition: 3.78, + yPosition: 5.21, + width: 22.07, + height: 1.5, + text: props.personFullName, + size: 52, + bold: true, + underline: {}, + }); + + // Identificado con DNI... + const tContentPart1 = new Paragraph({ + frame: { + position: { + x: cmText(11.84), + y: cmText(6.54), + }, + width: cmText(6.02), + height: cmText(0.6), + anchor: { + horizontal: FrameAnchorType.PAGE, + vertical: FrameAnchorType.PAGE, + }, + }, + children: [ + new TextRun({ + text: "Identificado con DNI N° ", + font: "Arial", + size: 20, + }), + new TextRun({ + text: props.personDni, + font: "Arial", + size: 20, + bold: true, + }), + ], + alignment: AlignmentType.CENTER, + }); + + // Fecha de Emision: ... + const certificateDate = new Paragraph({ + frame: { + position: { + x: cmText(19.62), + y: cmText(17.58), + }, + width: cmText(5.87), + height: cmText(0.75), + anchor: { + horizontal: FrameAnchorType.PAGE, + vertical: FrameAnchorType.PAGE, + }, + }, + children: [ + new TextRun({ + text: `Fecha de Emisión:\t${props.certDay} / ${props.certMonth} / ${props.certYear}`, + font: "Arial", + size: 18, + }), + new TextRun({ + text: `Fecha de Expiración:\t${props.certDay} / ${props.certMonth} / ${parseInt(props.certYear, 10) + 1}`, + font: "Arial", + size: 18, + break: 1, + }), + ], + alignment: AlignmentType.LEFT, + }); + + // N° XXXX-20XX-EEG + const tCertCode = createSimpleTextP({ + xPosition: 24.59, + yPosition: 8.07, + width: 3.67, + height: 0.5, + text: `N° ${props.certCode}-${props.certYear}-EEG`, + size: 20, + alignment: AlignmentType.CENTER, + }); + + const doc = new Document({ + sections: [ + { + properties: { + page: { + size: { + orientation: PageOrientation.LANDSCAPE, + }, + }, + }, + children: [ + tCertificate, + tLabel3, + tName, + tLabel2, + tContentPart1, + tCourse, + tTopics, + tHours, + tFinishLabel, + certificateDate, + photoSection, + tCertCode, + tChile, + new Paragraph({ + children: [ + imgFondoDoc, + imgQR, + imgEATE, + imgMTC, + imgOSHA, + imgEEG, + imgMatpelTransparent, + ], + }), + ], + }, + ], + }); + + // Return document as a buffer + return await Packer.toBuffer(doc); +} diff --git a/src/certs/utils.ts b/src/certs/utils.ts index babe6f3..06d58f6 100644 --- a/src/certs/utils.ts +++ b/src/certs/utils.ts @@ -127,6 +127,49 @@ export function createSimpleText(data: { }); } +export function createSimpleTextP(data: { + xPosition: number, + yPosition: number, + width: number, + height: number, + text: string, + font?: string, + bold?: boolean, + size: number, + underline?: Record, + alignment?: AlignmentType, + italics?: boolean, + color?: string, +}): Paragraph { + + return new Paragraph({ + frame: { + position: { + x: cmText(data.xPosition), + y: cmText(data.yPosition), + }, + width: cmText(data.width), + height: cmText(data.height), + anchor: { + horizontal: FrameAnchorType.PAGE, + vertical: FrameAnchorType.PAGE, + }, + }, + children: [ + new TextRun({ + text: data.text, + bold: data.bold, + font: data.font ?? "Arial", + size: data.size, + underline: data.underline, + italics: data.italics, + color: data.color, + }), + ], + alignment: data.alignment ?? AlignmentType.CENTER, + }); +} + export enum Matpel { _1, diff --git a/src/controller/certificate/certificate.service.ts b/src/controller/certificate/certificate.service.ts index 6f56ca1..ca53a49 100644 --- a/src/controller/certificate/certificate.service.ts +++ b/src/controller/certificate/certificate.service.ts @@ -11,8 +11,9 @@ import { getMecanicaBasica } from "./generator/mecanicaBasica"; import { getManejoDefensivo } from "./generator/manejoDefensivo"; import { get4x4 } from "./generator/4x4"; import { getSegOpMaqPesada } from "./generator/segOpMaqPes"; +import { getSupervisorEscolta } from "./generator/supervisorEscolta"; -const generatable = [1, 2, 3, 10, 11, 12, 72]; +const generatable = [1, 2, 3, 10, 11, 12, 14, 72]; @Injectable() export class CertificateService { @@ -137,6 +138,16 @@ export class CertificateService { certDay, ); } + // SUPERVISOR ESCOLTA + case 14: { + return await getSupervisorEscolta( + person, + register, + certYear, + certMonth, + certDay, + ); + } // Seguridad en la Operacion de Maquinaria Pesada case 72: { return await getSegOpMaqPesada( diff --git a/src/controller/certificate/generator/supervisorEscolta.ts b/src/controller/certificate/generator/supervisorEscolta.ts new file mode 100644 index 0000000..301878d --- /dev/null +++ b/src/controller/certificate/generator/supervisorEscolta.ts @@ -0,0 +1,27 @@ +import { CertData } from "src/certs/CertData"; +import { supervisorEscolta } from "src/certs/SUPERVISOR_ESCOLTA"; +import { Persona } from "src/model/Persona/persona.entity"; +import { RegistroGIE } from "src/model/RegistroGIE/registroGIE.entity"; + +export async function getSupervisorEscolta( + person: Persona, + register: RegistroGIE, + certYear: string, + certMonth: string, + certDay: string +): Promise<[Buffer, string]> { + const personFullName = `${person.nombres} ${person.apellidoPaterno} ${person.apellidoMaterno}`; + + const data: CertData = { + matpel: null, + personFullName: personFullName, + personDni: register.dni, + certCode: register.codigo.toString().padStart(4, "0"), + certYear, + certMonth, + certDay, + certIId: register.id, + }; + + return [await supervisorEscolta(data), `SUPERVISOR ESCOLTA - ${personFullName.toUpperCase()}.docx`]; +}