Files
QB-Import-from-Excel/templates/settings.html
T
2026-02-13 10:38:45 -05:00

177 lines
8.5 KiB
HTML

{% extends "base.html" %}
{% block title %}Settings - QBO Excel Sync{% endblock %}
{% block content %}
<div class="settings-page">
<div class="page-header">
<h2>Settings</h2>
<p>Configure import behavior and application preferences.</p>
</div>
<div class="settings-layout">
<section class="card">
<div class="card-header"><h3>Import Settings</h3></div>
<div class="card-body">
<form id="settings-form" class="form">
<div class="form-group">
<label class="checkbox-label">
<input type="checkbox" id="skip_duplicates" {% if import_settings.skip_duplicates %}checked{% endif %}>
<span>Skip duplicate records</span>
</label>
</div>
<div class="form-group">
<label for="duplicate_fields">Duplicate check fields</label>
<input type="text" id="duplicate_fields" value="{{ import_settings.duplicate_check_fields | join(', ') }}" placeholder="DocNumber, RefNumber">
<small>Comma-separated list of fields to check for duplicates</small>
</div>
<div class="form-group">
<label for="batch_size">Batch size</label>
<input type="number" id="batch_size" value="{{ import_settings.batch_size }}" min="1" max="200">
<small>Number of records to process per batch (1-200)</small>
</div>
<div class="form-group">
<label class="checkbox-label">
<input type="checkbox" id="validate_before" {% if import_settings.validate_before_import %}checked{% endif %}>
<span>Validate data before import</span>
</label>
</div>
<div class="form-group">
<label class="checkbox-label">
<input type="checkbox" id="create_missing" {% if import_settings.create_missing_references %}checked{% endif %}>
<span>Auto-create missing customers/vendors</span>
</label>
</div>
</form>
</div>
</section>
<section class="card">
<div class="card-header"><h3>Format Settings</h3></div>
<div class="card-body">
<div class="form-group">
<label for="date_format">Date format</label>
<select id="date_format">
<option value="%Y-%m-%d" {% if import_settings.date_format == '%Y-%m-%d' %}selected{% endif %}>YYYY-MM-DD (2024-01-15)</option>
<option value="%m/%d/%Y" {% if import_settings.date_format == '%m/%d/%Y' %}selected{% endif %}>MM/DD/YYYY (01/15/2024)</option>
<option value="%d/%m/%Y" {% if import_settings.date_format == '%d/%m/%Y' %}selected{% endif %}>DD/MM/YYYY (15/01/2024)</option>
</select>
</div>
<div class="form-group">
<label for="decimal_sep">Decimal separator</label>
<select id="decimal_sep">
<option value="." {% if import_settings.decimal_separator == '.' %}selected{% endif %}>Period (1234.56)</option>
<option value="," {% if import_settings.decimal_separator == ',' %}selected{% endif %}>Comma (1234,56)</option>
</select>
</div>
<div class="form-group">
<label for="thousand_sep">Thousand separator</label>
<select id="thousand_sep">
<option value="," {% if import_settings.thousand_separator == ',' %}selected{% endif %}>Comma (1,234)</option>
<option value="." {% if import_settings.thousand_separator == '.' %}selected{% endif %}>Period (1.234)</option>
<option value=" " {% if import_settings.thousand_separator == ' ' %}selected{% endif %}>Space (1 234)</option>
<option value="" {% if import_settings.thousand_separator == '' %}selected{% endif %}>None (1234)</option>
</select>
</div>
</div>
</section>
<section class="card">
<div class="card-header"><h3>API Settings</h3></div>
<div class="card-body">
<div class="form-group">
<label for="environment">Environment</label>
<select id="environment">
<option value="sandbox" {% if environment == 'sandbox' %}selected{% endif %}>Sandbox (Testing)</option>
<option value="production" {% if environment == 'production' %}selected{% endif %}>Production (Live)</option>
</select>
<small>Sandbox uses test data. Production uses real QuickBooks data.</small>
</div>
</div>
</section>
<section class="card">
<div class="card-header"><h3>Data Management</h3></div>
<div class="card-body">
<div class="button-group">
<button class="btn btn-danger" id="clear-credentials">Clear Saved Credentials</button>
<button class="btn btn-secondary" id="clear-templates">Reset All Templates</button>
</div>
</div>
</section>
<div class="settings-actions">
<button class="btn btn-primary" id="save-settings">Save Settings</button>
</div>
</div>
</div>
{% endblock %}
{% block extra_js %}
<script>
document.addEventListener('DOMContentLoaded', function() {
document.getElementById('save-settings').addEventListener('click', saveSettings);
document.getElementById('clear-credentials').addEventListener('click', clearCredentials);
document.getElementById('clear-templates').addEventListener('click', clearTemplates);
});
async function saveSettings() {
const fields = document.getElementById('duplicate_fields').value;
const duplicateFields = fields.split(',').map(f => f.trim()).filter(f => f);
const settings = {
skip_duplicates: document.getElementById('skip_duplicates').checked,
duplicate_check_fields: duplicateFields,
batch_size: parseInt(document.getElementById('batch_size').value) || 50,
validate_before_import: document.getElementById('validate_before').checked,
create_missing_references: document.getElementById('create_missing').checked,
date_format: document.getElementById('date_format').value,
decimal_separator: document.getElementById('decimal_sep').value,
thousand_separator: document.getElementById('thousand_sep').value,
environment: document.getElementById('environment').value
};
try {
const response = await fetch('/api/settings', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(settings)
});
const result = await response.json();
if (result.success) showToast('Settings saved successfully', 'success');
else showToast(result.error || 'Failed to save settings', 'error');
} catch (error) {
showToast('Error saving settings: ' + error.message, 'error');
}
}
async function clearCredentials() {
if (!confirm('This will remove all saved API credentials. Continue?')) return;
try {
const response = await fetch('/api/settings/clear-credentials', { method: 'POST' });
const result = await response.json();
if (result.success) { showToast('Credentials cleared', 'success'); location.reload(); }
else showToast(result.error || 'Failed to clear', 'error');
} catch (error) { showToast('Error: ' + error.message, 'error'); }
}
async function clearTemplates() {
if (!confirm('This will delete ALL custom templates. Continue?')) return;
try {
const response = await fetch('/api/templates');
const result = await response.json();
if (result.success) {
for (const t of result.templates) {
await fetch('/api/templates/' + encodeURIComponent(t.name), { method: 'DELETE' });
}
showToast('Templates cleared', 'success');
}
} catch (error) { showToast('Error: ' + error.message, 'error'); }
}
</script>
{% endblock %}