Get registers of a user
This commit is contained in:
parent
bcea70c52d
commit
92291b1ec3
2
frontend-dev/.gitignore
vendored
Normal file
2
frontend-dev/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
node_modules
|
||||||
|
dist
|
@ -19,6 +19,7 @@
|
|||||||
"test:e2e": "jest --config ./test/jest-e2e.json",
|
"test:e2e": "jest --config ./test/jest-e2e.json",
|
||||||
"ssr:watch": "node esbuild.js",
|
"ssr:watch": "node esbuild.js",
|
||||||
"ssr:hydration": "node esbuild-client.js",
|
"ssr:hydration": "node esbuild-client.js",
|
||||||
|
"ssr": "concurrently \"node esbuild.js\" \"node esbuild-client.js\" \"tailwindcss -i static/tailwind.css -o ./static/styles.css --watch\"",
|
||||||
"tailwind": "tailwindcss -i static/tailwind.css -o ./static/styles.css --watch"
|
"tailwind": "tailwindcss -i static/tailwind.css -o ./static/styles.css --watch"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@ -48,6 +49,7 @@
|
|||||||
"@typescript-eslint/eslint-plugin": "^5.0.0",
|
"@typescript-eslint/eslint-plugin": "^5.0.0",
|
||||||
"@typescript-eslint/parser": "^5.0.0",
|
"@typescript-eslint/parser": "^5.0.0",
|
||||||
"autoprefixer": "^10.4.14",
|
"autoprefixer": "^10.4.14",
|
||||||
|
"concurrently": "^8.0.1",
|
||||||
"esbuild": "^0.17.18",
|
"esbuild": "^0.17.18",
|
||||||
"esbuild-plugin-solid": "^0.5.0",
|
"esbuild-plugin-solid": "^0.5.0",
|
||||||
"eslint": "^8.0.1",
|
"eslint": "^8.0.1",
|
||||||
|
@ -20,6 +20,7 @@ specifiers:
|
|||||||
axios: ^1.4.0
|
axios: ^1.4.0
|
||||||
class-transformer: ^0.5.1
|
class-transformer: ^0.5.1
|
||||||
class-validator: ^0.14.0
|
class-validator: ^0.14.0
|
||||||
|
concurrently: ^8.0.1
|
||||||
esbuild: ^0.17.18
|
esbuild: ^0.17.18
|
||||||
esbuild-plugin-solid: ^0.5.0
|
esbuild-plugin-solid: ^0.5.0
|
||||||
eslint: ^8.0.1
|
eslint: ^8.0.1
|
||||||
@ -72,6 +73,7 @@ devDependencies:
|
|||||||
'@typescript-eslint/eslint-plugin': 5.59.2_fwbwffxiq4bvaw374ga4sdje4y
|
'@typescript-eslint/eslint-plugin': 5.59.2_fwbwffxiq4bvaw374ga4sdje4y
|
||||||
'@typescript-eslint/parser': 5.59.2_jgkqkwom7vrxl4kyi454n2sy2i
|
'@typescript-eslint/parser': 5.59.2_jgkqkwom7vrxl4kyi454n2sy2i
|
||||||
autoprefixer: 10.4.14_postcss@8.4.23
|
autoprefixer: 10.4.14_postcss@8.4.23
|
||||||
|
concurrently: 8.0.1
|
||||||
esbuild: 0.17.18
|
esbuild: 0.17.18
|
||||||
esbuild-plugin-solid: 0.5.0_rilwjtuydoglaxv66d4vlm6yn4
|
esbuild-plugin-solid: 0.5.0_rilwjtuydoglaxv66d4vlm6yn4
|
||||||
eslint: 8.40.0
|
eslint: 8.40.0
|
||||||
@ -618,6 +620,13 @@ packages:
|
|||||||
- supports-color
|
- supports-color
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/@babel/runtime/7.21.5:
|
||||||
|
resolution: {integrity: sha512-8jI69toZqqcsnqGGqwGS4Qb1VwLOEp4hz+CXPywcvjs60u3B4Pom/U/7rm4W8tMOYEB+E9wgD0mW1l3r8qlI9Q==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
dependencies:
|
||||||
|
regenerator-runtime: 0.13.11
|
||||||
|
dev: true
|
||||||
|
|
||||||
/@babel/template/7.20.7:
|
/@babel/template/7.20.7:
|
||||||
resolution: {integrity: sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==}
|
resolution: {integrity: sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==}
|
||||||
engines: {node: '>=6.9.0'}
|
engines: {node: '>=6.9.0'}
|
||||||
@ -2674,6 +2683,22 @@ packages:
|
|||||||
readable-stream: 2.3.8
|
readable-stream: 2.3.8
|
||||||
typedarray: 0.0.6
|
typedarray: 0.0.6
|
||||||
|
|
||||||
|
/concurrently/8.0.1:
|
||||||
|
resolution: {integrity: sha512-Sh8bGQMEL0TAmAm2meAXMjcASHZa7V0xXQVDBLknCPa9TPtkY9yYs+0cnGGgfdkW0SV1Mlg+hVGfXcoI8d3MJA==}
|
||||||
|
engines: {node: ^14.13.0 || >=16.0.0}
|
||||||
|
hasBin: true
|
||||||
|
dependencies:
|
||||||
|
chalk: 4.1.2
|
||||||
|
date-fns: 2.30.0
|
||||||
|
lodash: 4.17.21
|
||||||
|
rxjs: 7.8.1
|
||||||
|
shell-quote: 1.8.1
|
||||||
|
spawn-command: 0.0.2-1
|
||||||
|
supports-color: 8.1.1
|
||||||
|
tree-kill: 1.2.2
|
||||||
|
yargs: 17.7.2
|
||||||
|
dev: true
|
||||||
|
|
||||||
/consola/2.15.3:
|
/consola/2.15.3:
|
||||||
resolution: {integrity: sha512-9vAdYbHj6x2fLKC4+oPH0kFzY/orMZyG2Aj+kNylHxKGJ/Ed4dpNyAQYwJOdqO4zdM7XpVHmyejQDcQHrnuXbw==}
|
resolution: {integrity: sha512-9vAdYbHj6x2fLKC4+oPH0kFzY/orMZyG2Aj+kNylHxKGJ/Ed4dpNyAQYwJOdqO4zdM7XpVHmyejQDcQHrnuXbw==}
|
||||||
|
|
||||||
@ -2748,6 +2773,13 @@ packages:
|
|||||||
/csstype/3.1.2:
|
/csstype/3.1.2:
|
||||||
resolution: {integrity: sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==}
|
resolution: {integrity: sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==}
|
||||||
|
|
||||||
|
/date-fns/2.30.0:
|
||||||
|
resolution: {integrity: sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==}
|
||||||
|
engines: {node: '>=0.11'}
|
||||||
|
dependencies:
|
||||||
|
'@babel/runtime': 7.21.5
|
||||||
|
dev: true
|
||||||
|
|
||||||
/debug/2.6.9:
|
/debug/2.6.9:
|
||||||
resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==}
|
resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@ -5305,6 +5337,10 @@ packages:
|
|||||||
/reflect-metadata/0.1.13:
|
/reflect-metadata/0.1.13:
|
||||||
resolution: {integrity: sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==}
|
resolution: {integrity: sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==}
|
||||||
|
|
||||||
|
/regenerator-runtime/0.13.11:
|
||||||
|
resolution: {integrity: sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==}
|
||||||
|
dev: true
|
||||||
|
|
||||||
/require-directory/2.1.1:
|
/require-directory/2.1.1:
|
||||||
resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==}
|
resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
@ -5575,6 +5611,10 @@ packages:
|
|||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/shell-quote/1.8.1:
|
||||||
|
resolution: {integrity: sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==}
|
||||||
|
dev: true
|
||||||
|
|
||||||
/shelljs/0.8.5:
|
/shelljs/0.8.5:
|
||||||
resolution: {integrity: sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==}
|
resolution: {integrity: sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==}
|
||||||
engines: {node: '>=4'}
|
engines: {node: '>=4'}
|
||||||
@ -5651,6 +5691,10 @@ packages:
|
|||||||
engines: {node: '>= 8'}
|
engines: {node: '>= 8'}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/spawn-command/0.0.2-1:
|
||||||
|
resolution: {integrity: sha512-n98l9E2RMSJ9ON1AKisHzz7V42VDiBQGY6PB1BwRglz99wpVsSuGzQ+jOi6lFXBGVTCrRpltvjm+/XA+tpeJrg==}
|
||||||
|
dev: true
|
||||||
|
|
||||||
/split2/4.2.0:
|
/split2/4.2.0:
|
||||||
resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==}
|
resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==}
|
||||||
engines: {node: '>= 10.x'}
|
engines: {node: '>= 10.x'}
|
||||||
|
@ -1,22 +0,0 @@
|
|||||||
import { Test, TestingModule } from "@nestjs/testing";
|
|
||||||
import { AppController } from "./app.controller";
|
|
||||||
import { AppService } from "./app.service";
|
|
||||||
|
|
||||||
describe("AppController", () => {
|
|
||||||
let appController: AppController;
|
|
||||||
|
|
||||||
beforeEach(async() => {
|
|
||||||
const app: TestingModule = await Test.createTestingModule({
|
|
||||||
controllers: [AppController],
|
|
||||||
providers: [AppService],
|
|
||||||
}).compile();
|
|
||||||
|
|
||||||
appController = app.get<AppController>(AppController);
|
|
||||||
});
|
|
||||||
|
|
||||||
describe("root", () => {
|
|
||||||
it("should return \"Hello World!\"", () => {
|
|
||||||
expect(appController.getHello()).toBe("Hello World!");
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,13 +0,0 @@
|
|||||||
import { Controller, Get } from "@nestjs/common";
|
|
||||||
import { AppService } from "./app.service";
|
|
||||||
|
|
||||||
@Controller()
|
|
||||||
export class AppController {
|
|
||||||
constructor(private appService: AppService) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Get()
|
|
||||||
getHello(): string {
|
|
||||||
return "Hello!";
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,9 +1,7 @@
|
|||||||
import { Module } from "@nestjs/common";
|
import { Module } from "@nestjs/common";
|
||||||
import { AppController } from "./app.controller";
|
|
||||||
import { AppService } from "./app.service";
|
|
||||||
import { TypeOrmModule } from "@nestjs/typeorm";
|
import { TypeOrmModule } from "@nestjs/typeorm";
|
||||||
import { CertificateController } from "./certificate/certificate.controller";
|
import { CertificateController } from "./controller/certificate/certificate.controller";
|
||||||
import { CertificateService } from "./certificate/certificate.service";
|
import { CertificateService } from "./controller/certificate/certificate.service";
|
||||||
import { Persona } from "./model/Persona/persona.entity";
|
import { Persona } from "./model/Persona/persona.entity";
|
||||||
import { CursoGIE } from "./model/CursoGIE/cursoGIE.entity";
|
import { CursoGIE } from "./model/CursoGIE/cursoGIE.entity";
|
||||||
import { RegistroGIE } from "./model/RegistroGIE/registroGIE.entity";
|
import { RegistroGIE } from "./model/RegistroGIE/registroGIE.entity";
|
||||||
@ -27,7 +25,7 @@ import { PersonService } from "./controller/person/person.service";
|
|||||||
synchronize: false,
|
synchronize: false,
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
controllers: [AppController, CertificateController, PersonController],
|
controllers: [CertificateController, PersonController],
|
||||||
providers: [AppService, CertificateService, PersonService],
|
providers: [CertificateService, PersonService],
|
||||||
})
|
})
|
||||||
export class AppModule {}
|
export class AppModule {}
|
||||||
|
@ -1,10 +0,0 @@
|
|||||||
import { Injectable } from "@nestjs/common";
|
|
||||||
|
|
||||||
@Injectable()
|
|
||||||
export class AppService {
|
|
||||||
getHello(): string {
|
|
||||||
const html = ":D"; // renderToString(SolidAppJSX);
|
|
||||||
console.log(`SSR? ${html}`);
|
|
||||||
return `Hello world! ${html}`;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,22 +0,0 @@
|
|||||||
import { Controller, Get, Param } from "@nestjs/common";
|
|
||||||
import { renderToString } from "solid-js/web";
|
|
||||||
import { Certs } from "../views/Certs";
|
|
||||||
import { template } from "./certificate.template";
|
|
||||||
import { CertificateService } from "./certificate.service";
|
|
||||||
|
|
||||||
@Controller("certificate")
|
|
||||||
export class CertificateController {
|
|
||||||
constructor(private certificateService: CertificateService) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Get()
|
|
||||||
entry(): string {
|
|
||||||
const html = renderToString(Certs);
|
|
||||||
return template(html);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Get(":id")
|
|
||||||
getById(@Param() param: {id: string}) {
|
|
||||||
return this.certificateService.getByDni(param.id);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,81 +0,0 @@
|
|||||||
import { Injectable, NotFoundException } from "@nestjs/common";
|
|
||||||
import { Person } from "../types/Person";
|
|
||||||
import { DataSource, Repository } from "typeorm";
|
|
||||||
import { Persona } from "../model/Persona/persona.entity";
|
|
||||||
import { RegistroGIE } from "../model/RegistroGIE/registroGIE.entity";
|
|
||||||
import axios from "axios";
|
|
||||||
|
|
||||||
interface SunatPerson {
|
|
||||||
apellidoPaterno: string,
|
|
||||||
apellidoMaterno: string,
|
|
||||||
nombres: string,
|
|
||||||
}
|
|
||||||
|
|
||||||
@Injectable()
|
|
||||||
export class CertificateService {
|
|
||||||
personaRepository: Repository<Persona>;
|
|
||||||
registroGIERepository;
|
|
||||||
|
|
||||||
constructor(private dataSource: DataSource) {
|
|
||||||
this.personaRepository = dataSource.getRepository(Persona);
|
|
||||||
this.registroGIERepository = dataSource.getRepository(RegistroGIE);
|
|
||||||
}
|
|
||||||
|
|
||||||
async getByDni(dni: string): Promise<Person> {
|
|
||||||
// Search person in new tables
|
|
||||||
const person = await this.personaRepository.findOneBy({
|
|
||||||
dni,
|
|
||||||
});
|
|
||||||
|
|
||||||
if (person !== null) {
|
|
||||||
return {
|
|
||||||
id: person.id,
|
|
||||||
apellidoMaterno: person.apellidoMaterno,
|
|
||||||
apellidoPaterno: person.apellidoPaterno,
|
|
||||||
nombres: person.nombres,
|
|
||||||
nombreCompleto: `${person.nombres} ${person.apellidoPaterno} ${person.apellidoMaterno}`,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Move to env variables
|
|
||||||
const token = "apis-token-1.aTSI1U7KEuT-6bbbCguH-4Y8TI6KS73N";
|
|
||||||
|
|
||||||
// Search person in SUNAT API
|
|
||||||
let personSunat: SunatPerson | null = null;
|
|
||||||
try {
|
|
||||||
const personSunatR = await axios.get<SunatPerson>(`https://api.apis.net.pe/v1/dni?numero=${dni}`, {
|
|
||||||
headers: {
|
|
||||||
"Authorization": `Bearer ${token}`,
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
"charset": "utf-8",
|
|
||||||
},
|
|
||||||
});
|
|
||||||
personSunat = personSunatR.data;
|
|
||||||
} catch (e) { /* empty */
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// If person exists in SUNAT, add to DB and return
|
|
||||||
if (personSunat !== null) {
|
|
||||||
const p = new Persona();
|
|
||||||
p.dni = dni;
|
|
||||||
p.apellidoPaterno = personSunat.apellidoPaterno;
|
|
||||||
p.apellidoMaterno = personSunat.apellidoMaterno;
|
|
||||||
p.nombres = personSunat.nombres;
|
|
||||||
await this.personaRepository.save(p);
|
|
||||||
|
|
||||||
return {
|
|
||||||
id: p.id,
|
|
||||||
apellidoPaterno: p.apellidoPaterno,
|
|
||||||
apellidoMaterno: p.apellidoMaterno,
|
|
||||||
nombres: p.nombres,
|
|
||||||
nombreCompleto: `${p.nombres} ${p.apellidoPaterno} ${p.apellidoMaterno}`,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// 404
|
|
||||||
throw new NotFoundException("Persona no encontrada", {
|
|
||||||
description: "La persona no se encontró ni en BD ni en API",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
32
src/controller/certificate/certificate.controller.ts
Normal file
32
src/controller/certificate/certificate.controller.ts
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
import { Controller, Delete, Get, InternalServerErrorException, Param } from "@nestjs/common";
|
||||||
|
import { renderToString } from "solid-js/web";
|
||||||
|
import { Certs } from "../../views/Certs";
|
||||||
|
import { template } from "./certificate.template";
|
||||||
|
import { CertificateService } from "./certificate.service";
|
||||||
|
|
||||||
|
@Controller("certificate")
|
||||||
|
export class CertificateController {
|
||||||
|
constructor(private certificateService: CertificateService) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Get()
|
||||||
|
entry(): string {
|
||||||
|
const html = renderToString(Certs);
|
||||||
|
return template(html);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Get(":dni")
|
||||||
|
getByDni(@Param() param: {dni: string}) {
|
||||||
|
return this.certificateService.getByDni(param.dni);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Delete(":id")
|
||||||
|
async delete(@Param() param: {id: number}) {
|
||||||
|
console.log(param);
|
||||||
|
const result = await this.certificateService.deleteById(param.id);
|
||||||
|
if (!result) {
|
||||||
|
throw new InternalServerErrorException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
34
src/controller/certificate/certificate.service.ts
Normal file
34
src/controller/certificate/certificate.service.ts
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
import { Injectable } from "@nestjs/common";
|
||||||
|
import { DataSource, Repository } from "typeorm";
|
||||||
|
import { RegistroGIE } from "../../model/RegistroGIE/registroGIE.entity";
|
||||||
|
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class CertificateService {
|
||||||
|
registroGIERepository: Repository<RegistroGIE>;
|
||||||
|
|
||||||
|
constructor(private dataSource: DataSource) {
|
||||||
|
this.registroGIERepository = dataSource.getRepository(RegistroGIE);
|
||||||
|
}
|
||||||
|
|
||||||
|
async getByDni(dni: string) {
|
||||||
|
return await this.registroGIERepository.findBy({
|
||||||
|
dni,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async deleteById(id: number) {
|
||||||
|
// TODO: Should do logical deletion
|
||||||
|
const certificate = await this.registroGIERepository.findOneBy({
|
||||||
|
id,
|
||||||
|
});
|
||||||
|
console.log(certificate);
|
||||||
|
|
||||||
|
if (certificate !== null) {
|
||||||
|
await this.registroGIERepository.delete(certificate);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,10 +1,24 @@
|
|||||||
import { Body, Controller, InternalServerErrorException, Post, ValidationPipe } from "@nestjs/common";
|
import {
|
||||||
|
Body,
|
||||||
|
Controller,
|
||||||
|
Delete,
|
||||||
|
Get,
|
||||||
|
InternalServerErrorException,
|
||||||
|
Param,
|
||||||
|
Post,
|
||||||
|
ValidationPipe,
|
||||||
|
} from "@nestjs/common";
|
||||||
import { PersonDto } from "./person.dto";
|
import { PersonDto } from "./person.dto";
|
||||||
import { PersonService } from "./person.service";
|
import { PersonService } from "./person.service";
|
||||||
|
import { CertificateService } from "../certificate/certificate.service";
|
||||||
|
|
||||||
@Controller("person")
|
@Controller("person")
|
||||||
export class PersonController {
|
export class PersonController {
|
||||||
constructor(private personService: PersonService) {
|
constructor(private personService: PersonService,) {}
|
||||||
|
|
||||||
|
@Get(":dni")
|
||||||
|
getById(@Param() param: {dni: string}) {
|
||||||
|
return this.personService.getByDni(param.dni);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Post()
|
@Post()
|
||||||
|
@ -1,7 +1,15 @@
|
|||||||
import { Injectable, InternalServerErrorException } from "@nestjs/common";
|
import { Injectable, InternalServerErrorException, NotFoundException } from "@nestjs/common";
|
||||||
import { PersonDto } from "./person.dto";
|
import { PersonDto } from "./person.dto";
|
||||||
import { DataSource, Repository } from "typeorm";
|
import { DataSource, Repository } from "typeorm";
|
||||||
import { Persona } from "../../model/Persona/persona.entity";
|
import { Persona } from "../../model/Persona/persona.entity";
|
||||||
|
import { Person } from "../../types/Person";
|
||||||
|
import axios from "axios";
|
||||||
|
|
||||||
|
interface SunatPerson {
|
||||||
|
apellidoPaterno: string,
|
||||||
|
apellidoMaterno: string,
|
||||||
|
nombres: string,
|
||||||
|
}
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class PersonService {
|
export class PersonService {
|
||||||
@ -25,4 +33,64 @@ export class PersonService {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async getByDni(dni: string): Promise<Person> {
|
||||||
|
// Search person in new tables
|
||||||
|
const person = await this.personaRepository.findOneBy({
|
||||||
|
dni,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (person !== null) {
|
||||||
|
return {
|
||||||
|
id: person.id,
|
||||||
|
apellidoMaterno: person.apellidoMaterno,
|
||||||
|
apellidoPaterno: person.apellidoPaterno,
|
||||||
|
nombres: person.nombres,
|
||||||
|
nombreCompleto: `${person.nombres} ${person.apellidoPaterno} ${person.apellidoMaterno}`,
|
||||||
|
dni,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Move to env variables
|
||||||
|
const token = "apis-token-1.aTSI1U7KEuT-6bbbCguH-4Y8TI6KS73N";
|
||||||
|
|
||||||
|
// Search person in SUNAT API
|
||||||
|
let personSunat: SunatPerson | null = null;
|
||||||
|
try {
|
||||||
|
const personSunatR = await axios.get<SunatPerson>(`https://api.apis.net.pe/v1/dni?numero=${dni}`, {
|
||||||
|
headers: {
|
||||||
|
"Authorization": `Bearer ${token}`,
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
"charset": "utf-8",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
personSunat = personSunatR.data;
|
||||||
|
} catch (e) { /* empty */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// If person exists in SUNAT, add to DB and return
|
||||||
|
if (personSunat !== null) {
|
||||||
|
const p = new Persona();
|
||||||
|
p.dni = dni;
|
||||||
|
p.apellidoPaterno = personSunat.apellidoPaterno;
|
||||||
|
p.apellidoMaterno = personSunat.apellidoMaterno;
|
||||||
|
p.nombres = personSunat.nombres;
|
||||||
|
await this.personaRepository.save(p);
|
||||||
|
|
||||||
|
return {
|
||||||
|
id: p.id,
|
||||||
|
apellidoPaterno: p.apellidoPaterno,
|
||||||
|
apellidoMaterno: p.apellidoMaterno,
|
||||||
|
nombres: p.nombres,
|
||||||
|
nombreCompleto: `${p.nombres} ${p.apellidoPaterno} ${p.apellidoMaterno}`,
|
||||||
|
dni,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// 404
|
||||||
|
throw new NotFoundException("Persona no encontrada", {
|
||||||
|
description: "La persona no se encontró ni en BD ni en API",
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
import { NestFactory } from "@nestjs/core";
|
import { NestFactory } from "@nestjs/core";
|
||||||
import { FastifyAdapter, NestFastifyApplication } from "@nestjs/platform-fastify";
|
|
||||||
import { AppModule } from "./app.module";
|
import { AppModule } from "./app.module";
|
||||||
import * as express from "express";
|
import * as express from "express";
|
||||||
import * as path from "path";
|
import * as path from "path";
|
||||||
import { ValidationPipe } from "@nestjs/common";
|
|
||||||
|
|
||||||
async function bootstrap() {
|
async function bootstrap() {
|
||||||
const app = await NestFactory.create(AppModule);
|
const app = await NestFactory.create(AppModule);
|
||||||
|
@ -8,4 +8,5 @@ export interface Person {
|
|||||||
apellidoMaterno: string,
|
apellidoMaterno: string,
|
||||||
/** Names of the person. May be more than 1 word. */
|
/** Names of the person. May be more than 1 word. */
|
||||||
nombres: string,
|
nombres: string,
|
||||||
|
dni: string,
|
||||||
}
|
}
|
||||||
|
@ -1,20 +1,35 @@
|
|||||||
import { Show, createEffect, createSignal } from "solid-js";
|
import { Show, createEffect, createSignal, For } from "solid-js";
|
||||||
import { Person } from "../../types/Person";
|
import { Person } from "../../types/Person";
|
||||||
|
import type { RegistroGIE } from "../../model/RegistroGIE/registroGIE.entity";
|
||||||
|
|
||||||
export function Registers(props: {person: Person | null}) {
|
export function Registers(props: { person: Person | null }) {
|
||||||
const [loading, setLoading] = createSignal(false);
|
const [loading, setLoading] = createSignal(false);
|
||||||
|
const [registers, setRegisters] = createSignal<Array<RegistroGIE>>([]);
|
||||||
|
|
||||||
|
const x: Array<RegistroGIE> = JSON.parse("[{\"id\":12086,\"dni\":\"47269725\",\"nombre\":\"PEÑAFIEL ROJAS NATHALY\",\"curso\":10,\"codigo\":5619,\"fecha_actual\":\"2023-05-06\",\"fecha_inscripcion\":\"2023-05-04\",\"curso_nombre\":\"Matpel I\"},{\"id\":12087,\"dni\":\"47269725\",\"nombre\":\"PEÑAFIEL ROJAS NATHALY\",\"curso\":11,\"codigo\":5620,\"fecha_actual\":\"2023-05-06\",\"fecha_inscripcion\":\"2023-05-05\",\"curso_nombre\":\"Matpel II\"},{\"id\":12088,\"dni\":\"47269725\",\"nombre\":\"PEÑAFIEL ROJAS NATHALY\",\"curso\":1,\"codigo\":1620,\"fecha_actual\":\"2023-05-06\",\"fecha_inscripcion\":\"2023-05-06\",\"curso_nombre\":\"Manejo Defensivo\"}]");
|
||||||
|
|
||||||
createEffect(() => {
|
createEffect(() => {
|
||||||
const person = props.person;
|
const person = props.person;
|
||||||
if (person !== null) {
|
|
||||||
// Load certificates from DB
|
// Load certificates from DB
|
||||||
loadCertificates();
|
loadCertificates();
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const loadCertificates = () => {
|
const loadCertificates = async() => {
|
||||||
console.log("loading from db...");
|
console.log("loading from db...");
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
|
|
||||||
|
if (props.person === null) return;
|
||||||
|
|
||||||
|
const response = await fetch(`/certificate/${props.person.dni}`);
|
||||||
|
if (response.ok) {
|
||||||
|
const data: Array<RegistroGIE> = await response.json();
|
||||||
|
setRegisters(data);
|
||||||
|
} else {
|
||||||
|
setRegisters([]);
|
||||||
|
}
|
||||||
|
|
||||||
|
setLoading(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -23,6 +38,8 @@ export function Registers(props: {person: Person | null}) {
|
|||||||
|
|
||||||
<div class="px-4">
|
<div class="px-4">
|
||||||
<Show when={props.person !== null}>
|
<Show when={props.person !== null}>
|
||||||
|
<span>Nombres y Apellidos</span>
|
||||||
|
<br/>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
disabled
|
disabled
|
||||||
@ -32,10 +49,31 @@ export function Registers(props: {person: Person | null}) {
|
|||||||
/>
|
/>
|
||||||
<p
|
<p
|
||||||
class="my-2"
|
class="my-2"
|
||||||
style={{display: loading() ? "block" : "none"}}
|
style={{ display: loading() ? "block" : "none" }}
|
||||||
>
|
>
|
||||||
Recuperando registros...
|
Recuperando registros...
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
<Show when={!loading()}>
|
||||||
|
<table class="table-auto border border-c-outline my-4">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th class="p-2">APELLIDOS Y NOMBRES</th>
|
||||||
|
<th class="p-2">CURSO</th>
|
||||||
|
<th class="p-2">FECHA</th>
|
||||||
|
<th class="p-2">CÓDIGO</th>
|
||||||
|
<th class="p-2"></th>
|
||||||
|
<th class="p-2"></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
|
||||||
|
<tbody>
|
||||||
|
<For each={registers()}>
|
||||||
|
{(register) => <Register cert={register} onUpdate={loadCertificates} />}
|
||||||
|
</For>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</Show>
|
||||||
</Show>
|
</Show>
|
||||||
|
|
||||||
|
|
||||||
@ -43,3 +81,63 @@ export function Registers(props: {person: Person | null}) {
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function Register(props: {cert: RegistroGIE, onUpdate: () => void}) {
|
||||||
|
const [deleteConfirmation, setDeleteConfirmation] = createSignal(false);
|
||||||
|
const [deleteText, setDeleteText] = createSignal("Eliminar");
|
||||||
|
|
||||||
|
const deleteRegister = async() => {
|
||||||
|
console.log(":D");
|
||||||
|
if (deleteConfirmation()) {
|
||||||
|
// Actually delete from DB
|
||||||
|
const response = await fetch(`/certificate/${props.cert.id}`,{
|
||||||
|
method: "DELETE",
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.ok) {
|
||||||
|
props.onUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// Show delete confirmation
|
||||||
|
setDeleteText("Estas seguro?");
|
||||||
|
setDeleteConfirmation(true);
|
||||||
|
|
||||||
|
// Exit confirmation after 3 seconds
|
||||||
|
setTimeout(() => {
|
||||||
|
setDeleteText("Eliminar");
|
||||||
|
setDeleteConfirmation(false);
|
||||||
|
}, 3000);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<tr class="odd:bg-c-surface-variant">
|
||||||
|
<td class="py-2 px-4">{props.cert.nombre}</td>
|
||||||
|
<td class="py-2 px-4">{props.cert.curso_nombre}</td>
|
||||||
|
<td class="py-2 px-4 font-mono">{props.cert.fecha_inscripcion.toString()}</td>
|
||||||
|
<td class="py-2 px-4">{props.cert.codigo}</td>
|
||||||
|
<td class="py-2 pl-8 pr-4">
|
||||||
|
<button
|
||||||
|
class="rounded-full py-1 px-2 shadow
|
||||||
|
bg-c-primary
|
||||||
|
text-c-on-primary
|
||||||
|
disabled:opacity-50 disabled:cursor-not-allowed"
|
||||||
|
disabled
|
||||||
|
>
|
||||||
|
Editar
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
<td class="py-2 pl-4 pr-8">
|
||||||
|
<button
|
||||||
|
class={`rounded-full py-1 px-2 shadow
|
||||||
|
${deleteConfirmation() ? "bg-c-error-container text-c-on-error-container" : "bg-c-error text-c-on-error"}
|
||||||
|
cursor-pointer`}
|
||||||
|
onclick={deleteRegister}
|
||||||
|
>
|
||||||
|
{deleteText()}
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
@ -15,7 +15,7 @@ export function Search(props: {setPerson: (p: Person | null) => void}) {
|
|||||||
const [dni, setDni] = createSignal("");
|
const [dni, setDni] = createSignal("");
|
||||||
const [loading, setLoading] = createSignal(false);
|
const [loading, setLoading] = createSignal(false);
|
||||||
const [error, setError] = createSignal("");
|
const [error, setError] = createSignal("");
|
||||||
const [advertencia, setAdvertencia] = createSignal("");
|
const [warning, setWarning] = createSignal("");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Get the user data from the DB
|
Get the user data from the DB
|
||||||
@ -28,17 +28,17 @@ export function Search(props: {setPerson: (p: Person | null) => void}) {
|
|||||||
const search = async() => {
|
const search = async() => {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
setError("");
|
setError("");
|
||||||
setAdvertencia("");
|
setWarning("");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await fetch(`/certificate/${dni()}`);
|
const response = await fetch(`/person/${dni()}`);
|
||||||
const body = await response.json();
|
const body = await response.json();
|
||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
props.setPerson(body);
|
props.setPerson(body);
|
||||||
} else if (response.status === 404) {
|
} else if (response.status === 404) {
|
||||||
console.error(body);
|
console.error(body);
|
||||||
|
|
||||||
setAdvertencia("Persona no encontrada. Se debe insertar manualmente sus datos.");
|
setWarning("Persona no encontrada. Se debe insertar manualmente sus datos.");
|
||||||
} else {
|
} else {
|
||||||
setError(body);
|
setError(body);
|
||||||
}
|
}
|
||||||
@ -93,14 +93,14 @@ export function Search(props: {setPerson: (p: Person | null) => void}) {
|
|||||||
|
|
||||||
<p
|
<p
|
||||||
class="my-2 mx-4 p-1 rounded border border-c-error text-c-error font-medium w-fit"
|
class="my-2 mx-4 p-1 rounded border border-c-error text-c-error font-medium w-fit"
|
||||||
style={{display: advertencia() === "" ? "none" : "block"}}
|
style={{display: warning() === "" ? "none" : "block"}}
|
||||||
>
|
>
|
||||||
Advertencia:
|
Advertencia:
|
||||||
<br />
|
<br />
|
||||||
{advertencia()}
|
{warning()}
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<Show when={advertencia() !== ""}>
|
<Show when={warning() !== ""}>
|
||||||
<RegisterPerson dni={dni()} onSuccess={search} />
|
<RegisterPerson dni={dni()} onSuccess={search} />
|
||||||
</Show>
|
</Show>
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
Reference in New Issue
Block a user