From 13eb957c46271eada1976a10b75eb50070420fd6 Mon Sep 17 00:00:00 2001 From: MiguelPelegrina <95084406+MiguelPelegrina@users.noreply.github.com> Date: Mon, 22 Apr 2024 14:44:16 +0200 Subject: [PATCH] implemented generating an pdf from an existing order --- package-lock.json | 29 ++++++++++-- package.json | 3 ++ .../list-order/list-order.component.html | 9 +++- .../order/list-order/list-order.component.ts | 18 +++++++ src/app/services/order/order.service.ts | 47 ++++++++++++++++++- 5 files changed, 100 insertions(+), 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index ba485ee..2662266 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,6 +19,7 @@ "@angular/platform-browser-dynamic": "^16.0.0", "@angular/router": "^16.0.0", "bootstrap": "^5.3.2", + "chart.js": "^4.4.2", "flatted": "^3.2.9", "jwt-decode": "^4.0.0", "moment": "^2.30.1", @@ -27,6 +28,7 @@ "rxjs": "~7.8.0", "sweetalert2": "^11.10.7", "tslib": "^2.3.0", + "uuid": "^9.0.1", "xlsx": "^0.18.5", "zone.js": "~0.13.0" }, @@ -35,6 +37,7 @@ "@angular/cli": "~16.0.1", "@angular/compiler-cli": "^16.0.0", "@types/jasmine": "~4.3.0", + "@types/uuid": "^9.0.8", "jasmine-core": "~4.6.0", "karma": "~6.4.0", "karma-chrome-launcher": "~3.2.0", @@ -4553,6 +4556,12 @@ "@types/node": "*" } }, + "node_modules/@types/uuid": { + "version": "9.0.8", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.8.tgz", + "integrity": "sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA==", + "dev": true + }, "node_modules/@types/ws": { "version": "8.5.10", "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.10.tgz", @@ -12288,6 +12297,15 @@ "websocket-driver": "^0.7.4" } }, + "node_modules/sockjs/node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "dev": true, + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/socks": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/socks/-/socks-2.7.1.tgz", @@ -13240,10 +13258,13 @@ } }, "node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "dev": true, + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], "bin": { "uuid": "dist/bin/uuid" } diff --git a/package.json b/package.json index 696487a..d265f1c 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,7 @@ "@angular/platform-browser-dynamic": "^16.0.0", "@angular/router": "^16.0.0", "bootstrap": "^5.3.2", + "chart.js": "^4.4.2", "flatted": "^3.2.9", "jwt-decode": "^4.0.0", "moment": "^2.30.1", @@ -29,6 +30,7 @@ "rxjs": "~7.8.0", "sweetalert2": "^11.10.7", "tslib": "^2.3.0", + "uuid": "^9.0.1", "xlsx": "^0.18.5", "zone.js": "~0.13.0" }, @@ -37,6 +39,7 @@ "@angular/cli": "~16.0.1", "@angular/compiler-cli": "^16.0.0", "@types/jasmine": "~4.3.0", + "@types/uuid": "^9.0.8", "jasmine-core": "~4.6.0", "karma": "~6.4.0", "karma-chrome-launcher": "~3.2.0", diff --git a/src/app/components/order/list-order/list-order.component.html b/src/app/components/order/list-order/list-order.component.html index 5f15129..4dc4206 100644 --- a/src/app/components/order/list-order/list-order.component.html +++ b/src/app/components/order/list-order/list-order.component.html @@ -105,10 +105,17 @@

List of orders

Actions + + - diff --git a/src/app/components/order/list-order/list-order.component.ts b/src/app/components/order/list-order/list-order.component.ts index d95254c..8a65ae5 100644 --- a/src/app/components/order/list-order/list-order.component.ts +++ b/src/app/components/order/list-order/list-order.component.ts @@ -19,6 +19,7 @@ import { IIndexable } from 'src/app/shared/utils/interfaces/i-indexable'; import { ANIMATION_DURATION, StringValues } from 'src/app/shared/utils/string-values'; import { informUserOfError } from 'src/app/shared/utils/utils'; import Swal from 'sweetalert2'; +import { v4 as uuidv4 } from 'uuid'; /** * Component that lists all orders in a table. @@ -173,6 +174,23 @@ export class ListOrderComponent implements AfterViewInit, OnDestroy, OnInit { } // Protected methods + /** + * Generates a PDF for a specific order and triggers a download of the PDF file. + * + * @param {number} id - The ID of the order for which the PDF should be generated. + */ + protected generateOrderPDF(id: number){ + this.orderService.generateOrderPDF(id).subscribe((blob) => { + const url = window.URL.createObjectURL(blob); + const link = document.createElement('a'); + link.href = url; + link.download = `${uuidv4()}.pdf`; + document.body.appendChild(link); + link.click(); + document.body.removeChild(link); + }); + } + /** * Gets the total cost of the expanded order. * @returns The total cost of the expanded order. diff --git a/src/app/services/order/order.service.ts b/src/app/services/order/order.service.ts index 709e507..6965277 100644 --- a/src/app/services/order/order.service.ts +++ b/src/app/services/order/order.service.ts @@ -1,6 +1,6 @@ import { HttpClient } from '@angular/common/http'; import { Injectable } from '@angular/core'; -import { Observable, catchError } from 'rxjs'; +import { Observable, catchError, throwError } from 'rxjs'; import { Order } from 'src/app/shared/domain/order/order'; import { OrderedBook } from 'src/app/shared/domain/order/ordered-book'; import { AbstractService } from 'src/app/shared/service/abstract.service'; @@ -45,6 +45,21 @@ export class OrderService extends AbstractService { ); } + /** + * Generates a PDF for a specific order and returns it as a Blob. + * + * @param {number} id - The ID of the order for which the PDF should be generated. + * @returns {Observable} An Observable that emits the PDF file as a Blob. + */ + public generateOrderPDF(id: number): Observable{ + return this.httpClient.get( + `${StringValues.BASE_ORDER_URL}/generateOrderPDF/${id}`, + {responseType: 'blob'}, + ).pipe( + catchError(this.handleError) + ); + } + /** * Retrieves a list of orders based on optional query parameters. * @param filter - Optional. Filters orders based on a provided string. @@ -111,4 +126,34 @@ export class OrderService extends AbstractService { catchError(this.handleError) ); } + + /** + * Handles errors that occur during the generation of the PDF. + * + * @param error - The error object. + * @returns An Observable that emits an error. + */ +private handleBlobError(error: any): Observable { + if (error.error instanceof Blob) { + // Handle Blob error + const reader = new FileReader(); + reader.onload = () => { + try { + const errorMessage = JSON.parse(reader.result as string); + console.error('Error generating PDF:', errorMessage); + // You can also display this error message to the user + } catch (e) { + console.error('Error parsing error Blob:', e); + } + }; + reader.onerror = () => { + console.error('Error reading error Blob:', reader.error); + }; + reader.readAsText(error.error); + } else { + // Handle other types of errors + console.error('Error generating PDF:', error); + } + return throwError(error); + } }