319 lines
12 KiB
JavaScript
319 lines
12 KiB
JavaScript
// Orders page JavaScript
|
|
|
|
let routes = {};
|
|
let csrfToken = '';
|
|
|
|
// Initialize on page load
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
if (window.orderRoutes) {
|
|
routes = window.orderRoutes;
|
|
csrfToken = document.querySelector('meta[name="csrf-token"]')?.content || '';
|
|
}
|
|
|
|
// Attach event listener to the button instead of using inline onclick
|
|
const startButton = document.getElementById('startOrderMigrationBtn');
|
|
if (startButton) {
|
|
startButton.addEventListener('click', function(e) {
|
|
e.preventDefault();
|
|
startOrderMigration();
|
|
});
|
|
}
|
|
});
|
|
|
|
function startOrderMigration() {
|
|
try {
|
|
const button = document.getElementById('startOrderMigrationBtn');
|
|
if (!button) {
|
|
console.error('Start order migration button not found');
|
|
alert('Error: Button not found. Please refresh the page.');
|
|
return;
|
|
}
|
|
|
|
const logContent = document.getElementById('orderMigrationLogContent');
|
|
if (!logContent) {
|
|
console.error('Order migration log content not found');
|
|
alert('Error: Log container not found. Please refresh the page.');
|
|
return;
|
|
}
|
|
|
|
const originalText = button.textContent || 'Start Order Migration';
|
|
if (button) {
|
|
button.disabled = true;
|
|
button.textContent = 'Migrating...';
|
|
button.style.cursor = 'not-allowed';
|
|
}
|
|
|
|
const progressContainer = document.getElementById('migrationProgressContainer');
|
|
|
|
// Show progress bar
|
|
if (progressContainer) {
|
|
progressContainer.style.display = 'block';
|
|
updateProgressBar(0, 0, 0, 0, 0, 'Starting migration...', '');
|
|
}
|
|
|
|
logContent.innerHTML = '<div class="log-entry">Starting migration...</div>';
|
|
|
|
// Generate progress key for tracking
|
|
const progressKey = 'order_migration_progress_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9);
|
|
let progressInterval = null;
|
|
|
|
// Check if routes are available
|
|
if (!routes || !routes.migrateOrders) {
|
|
console.error('Order routes not available', routes);
|
|
if (button) {
|
|
button.disabled = false;
|
|
button.textContent = originalText;
|
|
button.style.cursor = 'pointer';
|
|
}
|
|
alert('Error: Routes not initialized. Please refresh the page.');
|
|
return;
|
|
}
|
|
|
|
progressInterval = pollMigrationProgress(progressKey, button, originalText, logContent);
|
|
|
|
fetch(routes.migrateOrders, {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
'X-CSRF-TOKEN': csrfToken,
|
|
'Accept': 'application/json'
|
|
},
|
|
body: JSON.stringify({ dry_run: false, progress_key: progressKey })
|
|
})
|
|
.then(async response => {
|
|
const contentType = response.headers.get('content-type');
|
|
|
|
// Check if response is JSON
|
|
if (contentType && contentType.includes('application/json')) {
|
|
return response.json();
|
|
} else {
|
|
// Response is HTML (error page), get text and show error
|
|
const text = await response.text();
|
|
throw new Error(`Server returned HTML instead of JSON. Status: ${response.status}. This usually means there was a server error. Check the browser console or server logs for details.`);
|
|
}
|
|
})
|
|
.then(data => {
|
|
// Stop polling
|
|
if (progressInterval) {
|
|
clearInterval(progressInterval);
|
|
}
|
|
|
|
// Hide progress bar
|
|
if (progressContainer) {
|
|
progressContainer.style.display = 'none';
|
|
}
|
|
|
|
if (button) {
|
|
button.disabled = false;
|
|
button.textContent = originalText;
|
|
button.style.cursor = 'pointer';
|
|
}
|
|
|
|
if (data.success) {
|
|
// Update progress bar to 100% before hiding
|
|
if (progressContainer) {
|
|
updateProgressBar(100, data.added + data.updated, data.added + data.updated, data.added, data.updated, data.errors, 'completed', '');
|
|
}
|
|
|
|
// Update order statistics
|
|
updateOrderStatistics();
|
|
|
|
const successEntry = document.createElement('div');
|
|
successEntry.className = 'log-entry success';
|
|
successEntry.textContent = `✓ Migration completed! Added: ${data.added || 0}, Updated: ${data.updated || 0}, Errors: ${data.errors || 0}`;
|
|
logContent.appendChild(successEntry);
|
|
|
|
if (data.log && data.log.length > 0) {
|
|
data.log.forEach(log => {
|
|
const entry = document.createElement('div');
|
|
entry.className = 'log-entry ' + (log.includes('ERROR') ? 'error' : 'success');
|
|
entry.textContent = log;
|
|
logContent.appendChild(entry);
|
|
});
|
|
}
|
|
|
|
const logContainer = document.getElementById('orderMigrationLogContainer');
|
|
logContainer.scrollTop = logContainer.scrollHeight;
|
|
} else {
|
|
const errorEntry = document.createElement('div');
|
|
errorEntry.className = 'log-entry error';
|
|
errorEntry.textContent = '✗ Migration failed: ' + (data.message || 'Unknown error');
|
|
logContent.appendChild(errorEntry);
|
|
}
|
|
})
|
|
.catch(error => {
|
|
// Stop polling
|
|
if (progressInterval) {
|
|
clearInterval(progressInterval);
|
|
}
|
|
|
|
// Hide progress bar
|
|
if (progressContainer) {
|
|
progressContainer.style.display = 'none';
|
|
}
|
|
|
|
if (button) {
|
|
button.disabled = false;
|
|
button.textContent = originalText;
|
|
button.style.cursor = 'pointer';
|
|
}
|
|
|
|
if (logContent) {
|
|
const errorEntry = document.createElement('div');
|
|
errorEntry.className = 'log-entry error';
|
|
errorEntry.textContent = '✗ Error: ' + error.message;
|
|
logContent.appendChild(errorEntry);
|
|
} else {
|
|
console.error('Error during migration:', error);
|
|
alert('Error: ' + error.message);
|
|
}
|
|
});
|
|
} catch (error) {
|
|
console.error('Error in startOrderMigration:', error);
|
|
alert('An unexpected error occurred. Please refresh the page and try again.');
|
|
}
|
|
}
|
|
|
|
function pollMigrationProgress(progressKey, button, originalText, logContent) {
|
|
return setInterval(() => {
|
|
if (!routes.migrationProgress) {
|
|
console.error('Migration progress route not available');
|
|
return;
|
|
}
|
|
|
|
fetch(routes.migrationProgress + '?progress_key=' + encodeURIComponent(progressKey), {
|
|
method: 'GET',
|
|
headers: {
|
|
'X-CSRF-TOKEN': csrfToken
|
|
}
|
|
})
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
if (data.success && data.progress) {
|
|
const progress = data.progress;
|
|
const percentage = progress.total > 0 ? Math.round((progress.current / progress.total) * 100) : 0;
|
|
|
|
updateProgressBar(
|
|
percentage,
|
|
progress.current,
|
|
progress.total,
|
|
progress.added,
|
|
progress.updated,
|
|
progress.errors,
|
|
progress.status,
|
|
progress.current_increment_id
|
|
);
|
|
} else if (data.success === false && data.message === 'Progress not found') {
|
|
// Progress not found yet, migration might not have started
|
|
// This is okay, just continue polling
|
|
}
|
|
})
|
|
.catch(error => {
|
|
console.error('Error polling progress:', error);
|
|
});
|
|
}, 500); // Poll every 500ms for smoother updates
|
|
}
|
|
|
|
function updateProgressBar(percentage, current, total, added, updated, errors, status, currentIncrementId) {
|
|
const progressBar = document.getElementById('progressBar');
|
|
const progressPercentage = document.getElementById('progressPercentage');
|
|
const progressStatus = document.getElementById('progressStatus');
|
|
const currentOrder = document.getElementById('currentOrder');
|
|
const progressAdded = document.getElementById('progressAdded');
|
|
const progressUpdated = document.getElementById('progressUpdated');
|
|
const progressErrors = document.getElementById('progressErrors');
|
|
|
|
if (progressBar) {
|
|
progressBar.style.width = percentage + '%';
|
|
}
|
|
if (progressPercentage) {
|
|
progressPercentage.textContent = percentage + '%';
|
|
}
|
|
if (progressStatus) {
|
|
const statusText = status === 'running' ? 'Migrating...' :
|
|
status === 'completed' ? 'Migration completed!' :
|
|
status === 'failed' ? 'Migration failed!' : 'Starting...';
|
|
progressStatus.textContent = statusText;
|
|
}
|
|
if (currentOrder) {
|
|
currentOrder.textContent = currentIncrementId ? `Current: ${currentIncrementId}` : `Processing ${current} of ${total}`;
|
|
}
|
|
if (progressAdded) {
|
|
progressAdded.textContent = added;
|
|
}
|
|
if (progressUpdated) {
|
|
progressUpdated.textContent = updated;
|
|
}
|
|
if (progressErrors) {
|
|
progressErrors.textContent = errors;
|
|
}
|
|
}
|
|
|
|
function updateOrderStatistics() {
|
|
if (!routes.statistics) {
|
|
console.error('Statistics route not available');
|
|
return;
|
|
}
|
|
|
|
fetch(routes.statistics, {
|
|
method: 'GET',
|
|
headers: {
|
|
'X-CSRF-TOKEN': csrfToken,
|
|
'Accept': 'application/json'
|
|
}
|
|
})
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
if (data.success && data.statistics) {
|
|
const stats = data.statistics;
|
|
|
|
const m1OrdersEl = document.getElementById('statM1Orders');
|
|
const m2OrdersEl = document.getElementById('statM2Orders');
|
|
const m1NotInM2El = document.getElementById('statM1NotInM2');
|
|
const m2NotInM1El = document.getElementById('statM2NotInM1');
|
|
|
|
if (m1OrdersEl) m1OrdersEl.textContent = stats.m1Orders;
|
|
if (m2OrdersEl) m2OrdersEl.textContent = stats.m2Orders;
|
|
if (m1NotInM2El) m1NotInM2El.textContent = stats.m1OrdersNotInM2;
|
|
if (m2NotInM1El) m2NotInM1El.textContent = stats.m2OrdersNotInM1;
|
|
}
|
|
})
|
|
.catch(error => {
|
|
console.error('Error updating order statistics:', error);
|
|
});
|
|
}
|
|
|
|
function deleteM2Order(orderId, incrementId) {
|
|
const orderLabel = incrementId !== 'N/A' ? incrementId : `ID ${orderId}`;
|
|
|
|
if (!confirm(`Are you sure you want to delete order "${orderLabel}"?`)) {
|
|
return;
|
|
}
|
|
|
|
const url = routes.deleteOrder.replace(':id', orderId);
|
|
|
|
fetch(url, {
|
|
method: 'DELETE',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
'X-CSRF-TOKEN': csrfToken
|
|
}
|
|
})
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
if (data.success) {
|
|
alert('Order deleted successfully!');
|
|
location.reload();
|
|
} else {
|
|
alert('Error: ' + (data.message || 'Failed to delete order'));
|
|
}
|
|
})
|
|
.catch(error => {
|
|
alert('Error: ' + error.message);
|
|
});
|
|
}
|
|
|
|
// Make functions available globally
|
|
window.startOrderMigration = startOrderMigration;
|
|
window.deleteM2Order = deleteM2Order;
|