Commit beb5ed30 authored by Omar Luna Hernández's avatar Omar Luna Hernández
Browse files

Se agrega el service para generar el pdf de los puntos de interes

parent 7ef784ce
Loading
Loading
Loading
Loading
+126 −1
Original line number Diff line number Diff line
@@ -10,10 +10,12 @@ import { CreatePointTradDto } from './dto/create-pointTrad.dto';
import { LANGUAGES } from 'src/shared/enum/languages.enum';
import { getPointDto } from './dto/getPoint.dto';
import { ServerConstants } from 'src/constants/server.contants';
import { createReadStream } from 'fs';
import { createReadStream, readFileSync } from 'fs';
import { join } from 'path';
import { generateQRCode } from './utils/qrcode';
import { Place } from 'src/place/entities/place.entity';
import puppeteer from 'puppeteer';
import { printPointInfo } from './dto/printPointInfo.dto';

@Injectable()
export class PointOfInterestService {
@@ -143,4 +145,127 @@ export class PointOfInterestService {
    };
    return point;
  }

  async findAllByIds(idPlace:number, pointsId: number[]): Promise<printPointInfo[]> {
    const place = await this.placeService.findOne(idPlace);
    if (!place) {
      throw new BadRequestException('Place not found');
    }
    let points: printPointInfo[] = await Promise.all(pointsId.map(async (idPoint)=>{
      let point = await this.dataSource
      .getRepository(PointOfInterest)
      .createQueryBuilder('point')
      .leftJoin('point.idPlace', 'place')
      .select([
        'point.idPoint as idPoint',
        'place.name as namePlace',
        'point.name as name',
      ])
      .where('place.idPlace = :idPlace', { idPlace })
      .andWhere('point.idPoint = :idPoint', {idPoint})
      .getRawOne();
      return point;
    }))
    return points;
  }

  async generatePdf(idPlace:number, pointsId: number[]): Promise<Buffer> {
    const points = await this.findAllByIds(idPlace, pointsId);
    const htmlContent = this.generateHtml(points);
    const browser = await puppeteer.launch();
    const page = await browser.newPage();
    
    await page.setContent(htmlContent);
    const pdfBuffer = await page.pdf({
      format: 'A4',
      margin: { top: '10mm', bottom: '10mm', left: '10mm', right: '10mm' }, // Márgenes
    });
  
    await browser.close();
  
    return Buffer.from(pdfBuffer);
  }

  private generateHtml(points: printPointInfo[]): string {
    let cardsHtml = '';

    for(const point of points) {
      const filePath = join(ServerConstants.ROOT_STATIC_PATH, 'qr', point.idPoint.toString() + '.png');
      
      cardsHtml += `
        <div class="card">
          <img class="background" src="data:image/jpeg;base64,${
            readFileSync('./src/pointOfInterest/utils/zac.jpeg').toString('base64')
          }"/>
          <div class="content">
            <h3>${point.namePlace}</h3>
            <p>${point.name}</p>
          </div>
          <img src="data:image/jpeg;base64,${
            readFileSync(filePath).toString('base64')
          }" class="qr-code"/>
        </div>
      `;
    }

    return `
      <!DOCTYPE html>
      <html>
      <head>
        <title>Tarjetas en PDF</title>
        <style>
          body {
            font-family: Arial, sans-serif;
          }
          .card {
            width: 16cm;
            height: 8cm;
            page-break-inside: avoid;
            position: relative;
          }

          .content{
            margin: 2cm;
          }

          .qr-code{
            width: 4cm;
            height: 4cm;
            position: absolute;
            right: 1.5cm;
            top: 0;
            bottom: 0;
            margin: auto 0;
            border: 3px solid black;
            border-radius: 8px;
          }

          .background {
            height: 100%;
            width: 100%;
            object-fit: contain;
            position: absolute;
            z-index: -1;
          }

          @page {
            size: A4;
            margin: 10mm;
          }
          .page {
            display: flex;
            flex-wrap: wrap;
            justify-content: space-between;
            height: calc(100vh - 20mm);
          }
        </style>
      </head>
      <body>
        <div class="page">
          ${cardsHtml}
        </div>
      </body>
      </html>
    `;
  }
}