-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathserver.js
More file actions
265 lines (223 loc) · 8.77 KB
/
server.js
File metadata and controls
265 lines (223 loc) · 8.77 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
'use strict';
const cors = require('cors');
const path = require('path');
const multer = require('multer');
const archiver = require('archiver');
const XLSX = require('xlsx');
const fs = require('fs-extra');
const express = require('express');
const main = require('./app.js');
const paths = require('./paths.js');
const { buildClientDte } = require('./generate-dtes.js');
const { waitForFileReady, clearOldFiles, checkFileExists } = require('./util-file.js');
const { buildRcof } = require('./generate-rcof.js');
const { generateBarcodes } = require('./generate-timbres.js');
const { compileAndSignSobre } = require('./generate-sobre.js');
const { generatePDF } = require('./generate-pdf.js');
const { generateChart } = require('./generate-chart.js');
const app = express();
const port = 5000;
// Path constants
const pdfPath = paths.getPDFBoletaFolderPath();
const pdfFilePath = path.join(pdfPath, 'Utility-Bil.pdf');
const signedBoletaDtePath = paths.getSignedBoletaDteFolderPath();
const unsignedBoletaDtePath = paths.getUnsignedBoletaDteFolderPath();
const sobreBoletaPath = paths.getSobreBoletaFolderPath();
const timbresBoletaFolderPath = paths.getTimbresBoletaFolderPath();
const boletaSobreFolderPath = paths.getSobreBoletaFolderPath();
const barCodesBoletaFolderPath = paths.getBarCodesBoletaFolderPath();
const fechaFirmaTxtPath = paths.getFechaFirmaTxtPath();
const fechaEmisionTxtPath = paths.getFechaEmisionTxtPath();
const fechaVencimientoTxtPath = paths.getFechaVencimientoTxtPath();
const fechaDesdeTxtPath = paths.getFechaDesdeTxtPath();
const fechaHastaTxtPath = paths.getFechaHastaTxtPath();
const databaseJsonPath = paths.getDatabaseJsonPath();
const foldersToDelete = [sobreBoletaPath, signedBoletaDtePath, unsignedBoletaDtePath, timbresBoletaFolderPath, barCodesBoletaFolderPath];
// Middleware
app.use(cors());
app.use('/files', express.static('public'));
app.use(express.json());
// Configure multer for file upload
const upload = multer({ dest: 'uploads/' });
// Routes
app.post('/api/upload-excel', upload.single('file'), async (req, res) => {
try {
if (!req.file) {
return res.status(400).send('No file uploaded.');
}
const workbook = XLSX.readFile(req.file.path);
const sheetName = req.body.sheet;
const fechaFirma = req.body.fechaFirma;
const fechaEmision = req.body.fechaEmision;
const fechaVencimiento = req.body.fechaVencimiento;
const fechaDesde = req.body.fechaDesde;
const fechaHasta = req.body.fechaHasta;
if (!workbook.SheetNames.includes(sheetName)) {
return res.status(400).send('Selected sheet not found in the workbook.');
}
const worksheet = workbook.Sheets[sheetName];
const jsonData = XLSX.utils.sheet_to_json(worksheet);
await fs.outputJSON(databaseJsonPath, jsonData, { spaces: 2 });
await fs.outputFile(fechaFirmaTxtPath, fechaFirma);
await fs.outputFile(fechaEmisionTxtPath, fechaEmision);
await fs.outputFile(fechaVencimientoTxtPath, fechaVencimiento);
await fs.outputFile(fechaDesdeTxtPath, fechaDesde);
await fs.outputFile(fechaHastaTxtPath, fechaHasta);
await fs.remove(req.file.path);
res.status(200).send({
message: `${sheetName} sheet processed successfully `,
sheet: sheetName,
rowCount: jsonData.length,
});
} catch (error) {
console.error('Error processing Excel file:', error);
res.status(500).send(`Error processing file: ${error.message}`);
}
});
app.get('/api/generate-barcodes', async (req, res) => {
await buildClientDte();
await compileAndSignSobre();
const logGenerateBarcodes = await generateBarcodes();
res.send(logGenerateBarcodes);
});
app.post('/api/process-data', async (req, res) => {
res.json(req.body);
await generateChart(req.body);
await generatePDF(req.body);
});
app.get('/api/list', (req, res) => {
const directoryPath = path.join(__dirname, 'public');
fs.readdir(directoryPath, function (err, files) {
if (err) {
res.status(500).send({
message: 'Unable to scan files!',
error: err,
});
} else {
let fileList = files.map(file => {
return { name: file, url: `/files/${file}` };
});
res.send(fileList);
}
});
});
app.get('/api/get-token', async (req, res) => {
const logOutput = [];
const { semillaData, getSemillaLog } = await main.getSemilla();
const { semilla, processSemillaResponseLog } = await main.processSemillaResponse(semillaData);
const { semillaXml, createSemillaXmlLog } = await main.createSemillaXml(semilla);
const { signedSemillaXml, signSemillaXmlLog } = await main.signSemillaXml(semillaXml);
const { tokenData, getTokenLog } = await main.getToken(signedSemillaXml);
const { token, processTokenResponseLog } = await main.processTokenResponse(tokenData);
logOutput.push(getSemillaLog, processSemillaResponseLog, createSemillaXmlLog, signSemillaXmlLog, getTokenLog, processTokenResponseLog);
res.send({ token, logOutput });
});
app.get('/api/delete-files', async (req, res) => {
const logOutput = await clearOldFiles(foldersToDelete);
res.send(logOutput);
});
app.get('/api/generate-dtes', async (req, res) => {
const logOutput = await buildClientDte();
res.send(logOutput);
});
app.get('/api/generate-sobre', async (req, res) => {
const logOutput = [];
try {
const filePath = path.join(unsignedBoletaDtePath, 'dte1.xml');
const fileExists = await checkFileExists(filePath);
if (!fileExists) {
logOutput.push(`File does not exist: ${filePath}`);
return res.status(404).json({ success: false, logOutput });
}
await waitForFileReady(filePath);
const signResult = await compileAndSignSobre();
logOutput.push(`${signResult.length} sobres generated successfully:`);
signResult.forEach(element => {
logOutput.push(element);
});
res.status(200).json({ success: true, logOutput });
} catch (error) {
logOutput.push(`Error: ${error.message}`);
res.status(500).json({ success: false, logOutput });
}
});
app.get('/api/generate-rcof', async (req, res) => {
const logBuildRcof = await buildRcof();
res.send(logBuildRcof);
});
app.get('/api/download-sobre', async (req, res) => {
try {
const sobreFiles = await fs.readdir(boletaSobreFolderPath);
if (sobreFiles.length === 0) {
res.status(404).send('No files found in the directory');
return;
}
if (sobreFiles.length === 1) {
res.download(path.join(boletaSobreFolderPath, sobreFiles[0]));
} else {
res.writeHead(200, {
'Content-Type': 'application/zip',
'Content-Disposition': 'attachment; filename=sobre_COAB.zip',
});
const archive = archiver('zip', {
zlib: { level: 9 },
});
archive.on('error', function (err) {
res.status(500).send({ error: err.message });
});
archive.pipe(res);
for (const file of sobreFiles) {
const filePath = path.join(boletaSobreFolderPath, file);
archive.file(filePath, { name: file });
}
await archive.finalize();
}
} catch (error) {
console.error(`ERROR: Failed to download sobre: ${error}`);
res.status(500).send(`Error downloading the file(s): ${error.message}`);
}
});
// New endpoint for fetching dropdown options
app.get('/api/get-dropdown-options/:fieldName', async (req, res) => {
const { fieldName } = req.params;
const optionsPath = path.join(__dirname, 'public', 'read-values', 'boletas', 'options', `${fieldName}.txt`);
try {
if (!(await fs.pathExists(optionsPath))) {
return res.status(404).json({ error: `Options file for ${fieldName} not found` });
}
const optionsContent = await fs.readFile(optionsPath, 'utf-8');
const options = optionsContent
.split('\n')
.map(option => option.trim())
.filter(Boolean);
res.json(options);
} catch (error) {
console.error(`Error reading options for ${fieldName}:`, error);
res.status(500).json({ error: `Failed to fetch options for ${fieldName}` });
}
});
// Start the server
app.listen(port, () => {
console.log(`Server listening on port ${port}`);
});
// Run function (if needed)
async function run() {
try {
await clearOldFiles(foldersToDelete);
const semillaData = await main.getSemilla();
const semilla = await main.processSemillaResponse(semillaData);
const semillaXml = await main.createSemillaXml(semilla);
const signedSemillaXml = await main.signSemillaXml(semillaXml);
const tokenData = await main.getToken(signedSemillaXml);
await main.processTokenResponse(tokenData);
await buildClientDte();
await waitForFileReady(path.join(unsignedBoletaDtePath, 'dte1.xml'));
await compileAndSignSobre();
await buildRcof();
await generateBarcodes();
} catch (error) {
console.error(`An error occurred: ${error.message}`);
}
}
// Uncomment the following line if you want to run the function when the server starts
// run();