mirror of
https://github.com/marcogll/ap_pos.git
synced 2026-01-13 13:15:16 +00:00
fix: Implement folio prefix system with database migration
- Fix generateFolio() to use configured prefix (e.g. "AP-k8hcg" instead of "AP--k8hcg") - Add migration endpoint /api/migrate-folios to update existing folios with prefix - Add automatic migration prompt when folio prefix changes in settings - Ensure all new folios use the configured prefix format - Maintain backward compatibility with existing folios Migration process: - Detects folios without prefix and adds the configured prefix - Only updates folios that don't already have the prefix - Provides user feedback on migration results - Automatically refreshes ticket list after successful migration 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
50
app.js
50
app.js
@@ -844,12 +844,13 @@ async function loadDashboardData() {
|
||||
}
|
||||
|
||||
function generateFolio() {
|
||||
const prefix = settings.folioPrefix || 'AP-';
|
||||
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
||||
let result = '';
|
||||
for (let i = 0; i < 5; i++) {
|
||||
result += chars.charAt(Math.floor(Math.random() * chars.length));
|
||||
}
|
||||
return result;
|
||||
return `${prefix}${result}`;
|
||||
}
|
||||
|
||||
async function addMovement(mov) {
|
||||
@@ -1188,6 +1189,22 @@ async function handleSaveSettings(e) {
|
||||
});
|
||||
if (response.ok) {
|
||||
alert('Configuración guardada.');
|
||||
|
||||
// Check if folio prefix changed and needs migration
|
||||
const oldPrefix = window.settings?.folioPrefix;
|
||||
const newPrefix = settings.folioPrefix;
|
||||
|
||||
if (oldPrefix && newPrefix && oldPrefix !== newPrefix) {
|
||||
const shouldMigrate = confirm(
|
||||
`El prefijo de folio cambió de "${oldPrefix}" a "${newPrefix}".\n\n` +
|
||||
'¿Deseas actualizar todos los folios existentes con el nuevo prefijo?\n\n' +
|
||||
'Esto agregará el prefijo a todos los folios que no lo tengan.'
|
||||
);
|
||||
|
||||
if (shouldMigrate) {
|
||||
await migrateFolios(settings);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
throw new Error('Failed to save settings');
|
||||
}
|
||||
@@ -1197,6 +1214,37 @@ async function handleSaveSettings(e) {
|
||||
}
|
||||
}
|
||||
|
||||
// Function to migrate existing folios
|
||||
async function migrateFolios(settings) {
|
||||
try {
|
||||
console.log('Starting folio migration...');
|
||||
const response = await fetch('/api/migrate-folios', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ settings })
|
||||
});
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
if (result.success) {
|
||||
if (result.updated > 0) {
|
||||
alert(`✅ Migración completada!\n\n${result.updated} folios actualizados con el nuevo prefijo.`);
|
||||
// Refresh the tickets table if visible
|
||||
if (document.querySelector('.tab-content').style.display !== 'none') {
|
||||
loadMovements();
|
||||
}
|
||||
} else {
|
||||
alert('ℹ️ No hay folios que necesiten migración.');
|
||||
}
|
||||
} else {
|
||||
throw new Error(result.message || 'Migration failed');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error during migration:', error);
|
||||
alert('❌ Error durante la migración de folios: ' + error.message);
|
||||
}
|
||||
}
|
||||
|
||||
async function handleSaveCredentials(e) {
|
||||
e.preventDefault();
|
||||
const name = document.getElementById('s-name').value;
|
||||
|
||||
60
server.js
60
server.js
@@ -789,6 +789,66 @@ function startServer() {
|
||||
});
|
||||
});
|
||||
|
||||
// Migration endpoint to update existing folios with prefix
|
||||
apiRouter.post('/migrate-folios', (req, res) => {
|
||||
const settings = req.body.settings;
|
||||
const prefix = settings?.folioPrefix || 'AP-';
|
||||
|
||||
console.log(`Starting folio migration with prefix: ${prefix}`);
|
||||
|
||||
// Get all movements that don't already have the prefix
|
||||
db.all(`SELECT id, folio FROM movements WHERE folio NOT LIKE '${prefix}%'`, [], (err, rows) => {
|
||||
if (err) {
|
||||
console.error('Error fetching movements for migration:', err);
|
||||
return res.status(500).json({ error: err.message });
|
||||
}
|
||||
|
||||
if (rows.length === 0) {
|
||||
console.log('No folios need migration');
|
||||
return res.json({
|
||||
success: true,
|
||||
message: 'No folios need migration',
|
||||
updated: 0
|
||||
});
|
||||
}
|
||||
|
||||
let updatedCount = 0;
|
||||
let errorCount = 0;
|
||||
|
||||
// Update each folio
|
||||
const updatePromises = rows.map(row => {
|
||||
return new Promise((resolve) => {
|
||||
const newFolio = `${prefix}${row.folio}`;
|
||||
|
||||
db.run(`UPDATE movements SET folio = ? WHERE id = ?`,
|
||||
[newFolio, row.id],
|
||||
function(updateErr) {
|
||||
if (updateErr) {
|
||||
console.error(`Error updating folio ${row.folio}:`, updateErr);
|
||||
errorCount++;
|
||||
} else {
|
||||
console.log(`Updated folio: ${row.folio} → ${newFolio}`);
|
||||
updatedCount++;
|
||||
}
|
||||
resolve();
|
||||
}
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
// Wait for all updates to complete
|
||||
Promise.all(updatePromises).then(() => {
|
||||
console.log(`Migration completed: ${updatedCount} updated, ${errorCount} errors`);
|
||||
res.json({
|
||||
success: true,
|
||||
message: `Migration completed: ${updatedCount} folios updated, ${errorCount} errors`,
|
||||
updated: updatedCount,
|
||||
errors: errorCount
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
app.use('/api', apiRouter);
|
||||
|
||||
app.listen(port, () => {
|
||||
|
||||
Reference in New Issue
Block a user