This commit is contained in:
evenegas
2025-12-08 11:44:34 -06:00
3 changed files with 132 additions and 50 deletions
+18 -36
View File
@@ -234,7 +234,6 @@
"integrity": "sha512-2BCOP7TN8M+gVDj7/ht3hsaO/B/n5oDbiAyyvnRlNOs+u1o+JWNYTQrmpuNp1/Wq2gcFrI01JAW+paEKDMx/CA==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@babel/code-frame": "^7.27.1",
"@babel/generator": "^7.28.3",
@@ -2084,7 +2083,6 @@
"integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"fast-deep-equal": "^3.1.3",
"fast-uri": "^3.0.1",
@@ -2338,7 +2336,6 @@
"resolved": "https://registry.npmjs.org/@nestjs/common/-/common-11.1.6.tgz",
"integrity": "sha512-krKwLLcFmeuKDqngG2N/RuZHCs2ycsKcxWIDgcm7i1lf3sQ0iG03ci+DsP/r3FcT/eJDFsIHnKtNta2LIi7PzQ==",
"license": "MIT",
"peer": true,
"dependencies": {
"file-type": "21.0.0",
"iterare": "1.2.1",
@@ -2400,7 +2397,6 @@
"integrity": "sha512-siWX7UDgErisW18VTeJA+x+/tpNZrJewjTBsRPF3JVxuWRuAB1kRoiJcxHgln8Lb5UY9NdvklITR84DUEXD0Cg==",
"hasInstallScript": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@nuxt/opencollective": "0.4.1",
"fast-safe-stringify": "2.1.1",
@@ -2484,7 +2480,6 @@
"resolved": "https://registry.npmjs.org/@nestjs/platform-express/-/platform-express-11.1.6.tgz",
"integrity": "sha512-HErwPmKnk+loTq8qzu1up+k7FC6Kqa8x6lJ4cDw77KnTxLzsCaPt+jBvOq6UfICmfqcqCCf3dKXg+aObQp+kIQ==",
"license": "MIT",
"peer": true,
"dependencies": {
"cors": "2.8.5",
"express": "5.1.0",
@@ -2937,7 +2932,6 @@
"integrity": "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@types/estree": "*",
"@types/json-schema": "*"
@@ -3079,7 +3073,6 @@
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.18.11.tgz",
"integrity": "sha512-Gd33J2XIrXurb+eT2ktze3rJAfAp9ZNjlBdh4SVgyrKEOADwCbdUDaK7QgJno8Ue4kcajscsKqu6n8OBG3hhCQ==",
"license": "MIT",
"peer": true,
"dependencies": {
"undici-types": "~6.21.0"
}
@@ -3263,7 +3256,6 @@
"integrity": "sha512-6JSSaBZmsKvEkbRUkf7Zj7dru/8ZCrJxAqArcLaVMee5907JdtEbKGsZ7zNiIm/UAkpGUkaSMZEXShnN2D1HZA==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@typescript-eslint/scope-manager": "8.46.1",
"@typescript-eslint/types": "8.46.1",
@@ -3946,7 +3938,6 @@
"integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
"devOptional": true,
"license": "MIT",
"peer": true,
"bin": {
"acorn": "bin/acorn"
},
@@ -3996,7 +3987,6 @@
"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"fast-deep-equal": "^3.1.1",
"fast-json-stable-stringify": "^2.0.0",
@@ -4586,7 +4576,6 @@
}
],
"license": "MIT",
"peer": true,
"dependencies": {
"baseline-browser-mapping": "^2.8.9",
"caniuse-lite": "^1.0.30001746",
@@ -4846,7 +4835,6 @@
"integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"readdirp": "^4.0.1"
},
@@ -4894,15 +4882,13 @@
"version": "0.5.1",
"resolved": "https://registry.npmjs.org/class-transformer/-/class-transformer-0.5.1.tgz",
"integrity": "sha512-SQa1Ws6hUbfC98vKGxZH3KFY0Y1lm5Zm0SY8XX9zbK7FJCyVEac3ATW0RIpwzW+oOfmHE5PMPufDG9hCfoEOMw==",
"license": "MIT",
"peer": true
"license": "MIT"
},
"node_modules/class-validator": {
"version": "0.14.2",
"resolved": "https://registry.npmjs.org/class-validator/-/class-validator-0.14.2.tgz",
"integrity": "sha512-3kMVRF2io8N8pY1IFIXlho9r8IPUUIfHe2hYVtiebvAzU2XeQFXTv+XI4WX+TnXmtwXMDcjngcpkiPM0O9PvLw==",
"license": "MIT",
"peer": true,
"dependencies": {
"@types/validator": "^13.11.8",
"libphonenumber-js": "^1.11.1",
@@ -5713,7 +5699,6 @@
"integrity": "sha512-XyLmROnACWqSxiGYArdef1fItQd47weqB7iwtfr9JHwRrqIXZdcFMvvEcL9xHCmL0SNsOvF0c42lWyM1U5dgig==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.8.0",
"@eslint-community/regexpp": "^4.12.1",
@@ -5775,7 +5760,6 @@
"integrity": "sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w==",
"dev": true,
"license": "MIT",
"peer": true,
"bin": {
"eslint-config-prettier": "bin/cli.js"
},
@@ -7216,7 +7200,6 @@
"integrity": "sha512-F26gjC0yWN8uAA5m5Ss8ZQf5nDHWGlN/xWZIh8S5SRbsEKBovwZhxGd6LJlbZYxBgCYOtreSUyb8hpXyGC5O4A==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@jest/core": "30.2.0",
"@jest/types": "30.2.0",
@@ -7988,12 +7971,12 @@
}
},
"node_modules/jws": {
"version": "3.2.2",
"resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz",
"integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==",
"version": "3.2.3",
"resolved": "https://registry.npmjs.org/jws/-/jws-3.2.3.tgz",
"integrity": "sha512-byiJ0FLRdLdSVSReO/U4E7RoEyOCKnEnEPMjq3HxWtvzLsV08/i5RQKsFVNkCldrCaPr2vDNAOMsfs8T/Hze7g==",
"license": "MIT",
"dependencies": {
"jwa": "^1.4.1",
"jwa": "^1.4.2",
"safe-buffer": "^5.0.1"
}
},
@@ -8651,7 +8634,6 @@
"resolved": "https://registry.npmjs.org/mysql2/-/mysql2-3.15.2.tgz",
"integrity": "sha512-kFm5+jbwR5mC+lo+3Cy46eHiykWSpUtTLOH3GE+AR7GeLq8PgfJcvpMiyVWk9/O53DjQsqm6a3VOOfq7gYWFRg==",
"license": "MIT",
"peer": true,
"dependencies": {
"aws-ssl-profiles": "^1.1.1",
"denque": "^2.1.0",
@@ -9003,7 +8985,6 @@
"resolved": "https://registry.npmjs.org/passport/-/passport-0.7.0.tgz",
"integrity": "sha512-cPLl+qZpSc+ireUvt+IzqbED1cHHkDoVYMo30jbJIdOOjQ1MQYZBPiNvmi8UM6lJuOpTPXJGZQk0DtC4y61MYQ==",
"license": "MIT",
"peer": true,
"dependencies": {
"passport-strategy": "1.x.x",
"pause": "0.0.1",
@@ -9243,7 +9224,6 @@
"integrity": "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==",
"dev": true,
"license": "MIT",
"peer": true,
"bin": {
"prettier": "bin/prettier.cjs"
},
@@ -9486,8 +9466,7 @@
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.2.2.tgz",
"integrity": "sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==",
"license": "Apache-2.0",
"peer": true
"license": "Apache-2.0"
},
"node_modules/require-directory": {
"version": "2.1.1",
@@ -9652,7 +9631,6 @@
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz",
"integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==",
"license": "Apache-2.0",
"peer": true,
"dependencies": {
"tslib": "^2.1.0"
}
@@ -10412,7 +10390,6 @@
"integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"fast-deep-equal": "^3.1.3",
"fast-uri": "^3.0.1",
@@ -10742,7 +10719,6 @@
"integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==",
"devOptional": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@cspotcode/source-map-support": "^0.8.0",
"@tsconfig/node10": "^1.0.7",
@@ -10909,7 +10885,6 @@
"resolved": "https://registry.npmjs.org/typeorm/-/typeorm-0.3.27.tgz",
"integrity": "sha512-pNV1bn+1n8qEe8tUNsNdD8ejuPcMAg47u2lUGnbsajiNUr3p2Js1XLKQjBMH0yMRMDfdX8T+fIRejFmIwy9x4A==",
"license": "MIT",
"peer": true,
"dependencies": {
"@sqltools/formatter": "^1.2.5",
"ansis": "^3.17.0",
@@ -11046,7 +11021,6 @@
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
"devOptional": true,
"license": "Apache-2.0",
"peer": true,
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
@@ -11323,9 +11297,9 @@
}
},
"node_modules/validator": {
"version": "13.15.20",
"resolved": "https://registry.npmjs.org/validator/-/validator-13.15.20.tgz",
"integrity": "sha512-KxPOq3V2LmfQPP4eqf3Mq/zrT0Dqp2Vmx2Bn285LwVahLc+CsxOM0crBHczm8ijlcjZ0Q5Xd6LW3z3odTPnlrw==",
"version": "13.15.23",
"resolved": "https://registry.npmjs.org/validator/-/validator-13.15.23.tgz",
"integrity": "sha512-4yoz1kEWqUjzi5zsPbAS/903QXSYp0UOtHsPpp7p9rHAw/W+dkInskAE386Fat3oKRROwO98d9ZB0G4cObgUyw==",
"license": "MIT",
"engines": {
"node": ">= 0.10"
@@ -11468,6 +11442,7 @@
"integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"ajv": "^8.0.0"
},
@@ -11486,6 +11461,7 @@
"integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"fast-deep-equal": "^3.1.3"
},
@@ -11499,6 +11475,7 @@
"integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==",
"dev": true,
"license": "BSD-2-Clause",
"peer": true,
"dependencies": {
"esrecurse": "^4.3.0",
"estraverse": "^4.1.1"
@@ -11513,6 +11490,7 @@
"integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
"dev": true,
"license": "BSD-2-Clause",
"peer": true,
"engines": {
"node": ">=4.0"
}
@@ -11522,7 +11500,8 @@
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
"integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
"dev": true,
"license": "MIT"
"license": "MIT",
"peer": true
},
"node_modules/webpack/node_modules/mime-db": {
"version": "1.52.0",
@@ -11530,6 +11509,7 @@
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
"dev": true,
"license": "MIT",
"peer": true,
"engines": {
"node": ">= 0.6"
}
@@ -11540,6 +11520,7 @@
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"mime-db": "1.52.0"
},
@@ -11553,6 +11534,7 @@
"integrity": "sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@types/json-schema": "^7.0.9",
"ajv": "^8.9.0",
+112 -10
View File
@@ -62,7 +62,7 @@ export class EquipoService {
private readonly laboratorioRepo: Repository<Laboratorio>,
@InjectRepository(Proyecto)
private readonly proyectoRepo: Repository<Proyecto>,
) {}
) { }
async deleteEquipo(inventario: string): Promise<{ message: string }> {
const equipo = await this.equipoRepository.findOne({
@@ -293,12 +293,12 @@ export class EquipoService {
equipo.isImpresora
? { ...datosBase, periferico: { id_periferico: equipo.id_periferico } }
: {
...datosBase,
sistemaOperativo: {
id_sistema_operativo: equipo.id_sistema_operativo,
},
procesador: { id_procesador: equipo.id_procesador },
...datosBase,
sistemaOperativo: {
id_sistema_operativo: equipo.id_sistema_operativo,
},
procesador: { id_procesador: equipo.id_procesador },
},
);
let equip = await this.equipoRepository.save(nuevoEquipo);
@@ -358,11 +358,14 @@ export class EquipoService {
return await this.procesadorRepo.find();
}
async createEcxel(res: Response) {
const data = await this.generar_reporte();
return this.exportarReporteAExcel(data, res);
}
// async createEcxel(res: Response) {
// const data = await this.generar_reporte();
// return this.exportarReporteAExcel(data, res);
// }
async createEcxel(res: Response) {
return await this.exportarEquiposAExcel(res);
}
@Cron('0 0 0 * * *')
async llenadoDeAntiguedad() {
const result = await this.equipoRepository
@@ -384,6 +387,105 @@ export class EquipoService {
return result;
}
async exportarEquiposAExcel(res: Response) {
const workbook = new ExcelJS.Workbook();
const sheet = workbook.addWorksheet('Equipos');
// =====================================
// ✅ ENCABEZADOS
// =====================================
sheet.columns = [
{ header: 'Inventario', key: 'inventario', width: 70 },
{ header: 'Serie', key: 'serie', width: 70 },
{ header: 'Lugar', key: 'lugar', width: 70 },
{ header: 'Fecha Factura', key: 'fechaFactura', width: 70 },
{ header: 'Antigüedad', key: 'antiguedad', width: 70 },
{ header: 'Modelo', key: 'modelo', width: 70 },
{ header: 'Marca', key: 'marca', width: 70 },
{ header: 'Estado', key: 'estado', width: 70 },
{ header: 'Adscripción', key: 'adscripcion', width: 70 },
{ header: 'Tipo de Equipo', key: 'tipoEquipo', width: 70 },
{ header: 'Sistema Operativo', key: 'sistemaOperativo', width: 70 },
{ header: 'Procesador', key: 'procesador', width: 70 },
{ header: 'Tipo de Uso', key: 'tipoUso', width: 70 },
{ header: 'Periférico', key: 'periferico', width: 70 },
{ header: 'Proyecto', key: 'proyecto', width: 70 },
{ header: 'Laboratorio', key: 'laboratorio', width: 70 },
{ header: 'Observaciones', key: 'observaciones', width: 100 },
{ header: 'Fecha Movimiento', key: 'fechaMovimiento', width: 70 },
{ header: 'Usuario', key: 'user', width: 70 },
];
// =====================================
// ✅ OBTENER EQUIPOS
// =====================================
const equipos = await this.equipoRepository.find({
relations: [
'marca',
'estado',
'adscripcion',
'tipoEquipo',
'sistemaOperativo',
'procesador',
'tipoUso',
'periferico',
'proyecto',
'laboratorio',
],
});
// =====================================
// ✅ LLENAR FILAS
// =====================================
for (const equipo of equipos) {
const movimiento = await this.movimiento.buscar(equipo.id_equipo);
sheet.addRow({
inventario: equipo.inventario,
serie: equipo.serie,
lugar: equipo.lugar,
fechaFactura: equipo.fechaFactura,
antiguedad: equipo.antiguedad,
modelo: equipo.modelo,
marca: equipo.marca?.marca ?? '',
estado: equipo.estado?.estado ?? '',
adscripcion: equipo.adscripcion?.adscripcion ?? '',
tipoEquipo: equipo.tipoEquipo?.tipo_equipo ?? '',
sistemaOperativo: equipo.sistemaOperativo?.sistema_operativo ?? '',
procesador: equipo.procesador?.procesador ?? '',
tipoUso: equipo.tipoUso?.tipo_uso ?? '',
periferico: equipo.periferico?.periferico ?? '',
proyecto: equipo.proyecto?.proyecto ?? '',
laboratorio: equipo.laboratorio?.laboratorio ?? '',
observaciones: movimiento?.observaciones ?? '',
fechaMovimiento: movimiento?.fechaMovimiento ?? '',
user: movimiento?.user?.nombre ?? '',
});
}
// =====================================
// ✅ ESTILO HEADER
// =====================================
sheet.getRow(1).font = { bold: true };
// =====================================
// ✅ RESPUESTA AL NAVEGADOR
// =====================================
res.setHeader(
'Content-Type',
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
);
res.setHeader(
'Content-Disposition',
'attachment; filename=equipos.xlsx',
);
await workbook.xlsx.write(res);
res.end();
}
async exportarReporteAExcel(data: any, res: Response) {
const workbook = new ExcelJS.Workbook();
let count = 1;
+2 -4
View File
@@ -11,7 +11,7 @@ export class MovimientoService {
constructor(
@InjectRepository(Movimiento)
private readonly movimientoRepo: Repository<Movimiento>,
) {}
) { }
async crear(dto: CreateMovimientoDto) {
const movimiento = this.movimientoRepo.create({
@@ -28,7 +28,7 @@ export class MovimientoService {
const movimiento = await this.movimientoRepo.findOne({
where: { equipo: { id_equipo: idEquipo } },
order: { fechaMovimiento: 'DESC' },
relations:['user'],
relations: ['user'],
});
return movimiento;
@@ -66,8 +66,6 @@ export class MovimientoService {
tipo_equipo: mov.equipo?.tipoEquipo?.tipo_equipo,
periferico: mov.equipo?.periferico?.periferico,
fechaMovimiento: mov.fechaMovimiento,
lugar:mov.equipo?.lugar,
observaciones:mov.observaciones,
}));
}