fix(invoicing): wire emisor config save/load and align fiscal config keys
This commit is contained in:
@@ -759,6 +759,7 @@ def get_business():
|
|||||||
'nombre': cfg.get('tenant_nombre', cfg.get('tenant_razon_social', '')),
|
'nombre': cfg.get('tenant_nombre', cfg.get('tenant_razon_social', '')),
|
||||||
'rfc': cfg.get('tenant_rfc', ''),
|
'rfc': cfg.get('tenant_rfc', ''),
|
||||||
'regimen_fiscal': cfg.get('tenant_regimen_fiscal', ''),
|
'regimen_fiscal': cfg.get('tenant_regimen_fiscal', ''),
|
||||||
|
'cp': cfg.get('tenant_cp', ''),
|
||||||
'direccion': cfg.get('tenant_direccion', ''),
|
'direccion': cfg.get('tenant_direccion', ''),
|
||||||
'telefono': cfg.get('tenant_telefono', ''),
|
'telefono': cfg.get('tenant_telefono', ''),
|
||||||
'email': cfg.get('tenant_email', ''),
|
'email': cfg.get('tenant_email', ''),
|
||||||
@@ -775,14 +776,16 @@ def update_business():
|
|||||||
'nombre': 'tenant_nombre',
|
'nombre': 'tenant_nombre',
|
||||||
'rfc': 'tenant_rfc',
|
'rfc': 'tenant_rfc',
|
||||||
'regimen_fiscal': 'tenant_regimen_fiscal',
|
'regimen_fiscal': 'tenant_regimen_fiscal',
|
||||||
|
'cp': 'tenant_cp',
|
||||||
'direccion': 'tenant_direccion',
|
'direccion': 'tenant_direccion',
|
||||||
'telefono': 'tenant_telefono',
|
'telefono': 'tenant_telefono',
|
||||||
'email': 'tenant_email',
|
'email': 'tenant_email',
|
||||||
# Tax params
|
# Tax params (also keep cfdi_* aliases in sync)
|
||||||
'tax_iva': 'tax_iva',
|
'tax_iva': 'tax_iva',
|
||||||
'tax_ieps': 'tax_ieps',
|
'tax_ieps': 'tax_ieps',
|
||||||
'invoice_serie': 'invoice_serie',
|
'invoice_serie': 'invoice_serie',
|
||||||
'invoice_folio': 'invoice_folio',
|
'invoice_folio': 'invoice_folio',
|
||||||
|
'cfdi_serie': 'cfdi_serie',
|
||||||
'default_currency': 'default_currency',
|
'default_currency': 'default_currency',
|
||||||
'default_payment_method': 'default_payment_method',
|
'default_payment_method': 'default_payment_method',
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,9 +43,9 @@ def _get_issuer_config(cur, branch_id=None):
|
|||||||
result = {
|
result = {
|
||||||
"rfc": config.get("tenant_rfc", ""),
|
"rfc": config.get("tenant_rfc", ""),
|
||||||
"razon_social": config.get("tenant_razon_social", ""),
|
"razon_social": config.get("tenant_razon_social", ""),
|
||||||
"regimen_fiscal": config.get("cfdi_regimen_fiscal", "601"),
|
"regimen_fiscal": config.get("cfdi_regimen_fiscal") or config.get("tenant_regimen_fiscal", "601"),
|
||||||
"cp": config.get("tenant_cp", "00000"),
|
"cp": config.get("tenant_cp", "00000"),
|
||||||
"serie": config.get("cfdi_serie", "A"),
|
"serie": config.get("cfdi_serie") or config.get("invoice_serie", "A"),
|
||||||
"facturapi_key": config.get("cfdi_facturapi_key", ""),
|
"facturapi_key": config.get("cfdi_facturapi_key", ""),
|
||||||
"facturapi_org_id": config.get("cfdi_facturapi_org_id", ""),
|
"facturapi_org_id": config.get("cfdi_facturapi_org_id", ""),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,7 +62,10 @@ const Invoicing = (() => {
|
|||||||
if (name === 'notas') loadNotas();
|
if (name === 'notas') loadNotas();
|
||||||
if (name === 'complementos') loadComplementos();
|
if (name === 'complementos') loadComplementos();
|
||||||
if (name === 'cancelaciones') loadCancelaciones();
|
if (name === 'cancelaciones') loadCancelaciones();
|
||||||
if (name === 'config') loadFacturapiStatus();
|
if (name === 'config') {
|
||||||
|
loadFacturapiStatus();
|
||||||
|
loadEmisorData();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---- Badge helpers ----
|
// ---- Badge helpers ----
|
||||||
@@ -377,6 +380,70 @@ const Invoicing = (() => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---- Emisor data (config tab) ----
|
||||||
|
async function loadEmisorData() {
|
||||||
|
const rfcEl = document.getElementById('rfc-emisor');
|
||||||
|
const cpEl = document.getElementById('cp-fiscal');
|
||||||
|
const razonEl = document.getElementById('razon-social');
|
||||||
|
const regimenEl = document.getElementById('regimen-fiscal');
|
||||||
|
if (!rfcEl || !cpEl || !razonEl || !regimenEl) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const res = await fetch('/pos/api/config/business', { headers: headers() });
|
||||||
|
if (!res.ok) throw new Error('Error al cargar datos fiscales');
|
||||||
|
const data = await res.json();
|
||||||
|
rfcEl.value = data.rfc || '';
|
||||||
|
cpEl.value = data.cp || '';
|
||||||
|
razonEl.value = data.razon_social || '';
|
||||||
|
const regimen = data.regimen_fiscal || '601';
|
||||||
|
regimenEl.value = regimen + ' — ' + (regimenEl.querySelector('option[value^="' + regimen + '"')?.textContent.split('—')[1]?.trim() || '');
|
||||||
|
// If exact value not matched, leave first option selected by SAT code prefix
|
||||||
|
if (!regimenEl.value.startsWith(regimen)) {
|
||||||
|
Array.from(regimenEl.options).forEach(function(opt) {
|
||||||
|
if (opt.value.startsWith(regimen)) opt.selected = true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error('Invoicing.loadEmisorData:', e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function saveEmisorData() {
|
||||||
|
const rfc = (document.getElementById('rfc-emisor')?.value || '').trim();
|
||||||
|
const cp = (document.getElementById('cp-fiscal')?.value || '').trim();
|
||||||
|
const razon_social = (document.getElementById('razon-social')?.value || '').trim();
|
||||||
|
const regimenValue = document.getElementById('regimen-fiscal')?.value || '601';
|
||||||
|
const regimen_fiscal = regimenValue.split('—')[0].trim();
|
||||||
|
const statusEl = document.getElementById('emisor-save-status');
|
||||||
|
|
||||||
|
if (!rfc || !razon_social || !cp) {
|
||||||
|
if (statusEl) statusEl.textContent = 'RFC, Razón Social y C.P. son obligatorios';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const res = await fetch('/pos/api/config/business', {
|
||||||
|
method: 'PUT',
|
||||||
|
headers: headers(),
|
||||||
|
body: JSON.stringify({ rfc, razon_social, regimen_fiscal, cp, cfdi_regimen_fiscal: regimen_fiscal, cfdi_serie: 'A' })
|
||||||
|
});
|
||||||
|
if (!res.ok) {
|
||||||
|
const err = await res.json().catch(() => ({ error: res.statusText }));
|
||||||
|
throw new Error(err.error || 'Error al guardar');
|
||||||
|
}
|
||||||
|
if (statusEl) {
|
||||||
|
statusEl.textContent = 'Datos fiscales guardados';
|
||||||
|
statusEl.style.color = 'var(--color-success)';
|
||||||
|
}
|
||||||
|
setTimeout(() => { if (statusEl) { statusEl.textContent = ''; statusEl.style.color = ''; } }, 4000);
|
||||||
|
} catch (e) {
|
||||||
|
if (statusEl) {
|
||||||
|
statusEl.textContent = e.message;
|
||||||
|
statusEl.style.color = 'var(--color-error)';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function setupFacturapi(btn) {
|
async function setupFacturapi(btn) {
|
||||||
if (!btn) return;
|
if (!btn) return;
|
||||||
btn.disabled = true;
|
btn.disabled = true;
|
||||||
@@ -747,6 +814,7 @@ const Invoicing = (() => {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
switchTab, loadFacturas, loadNotas, loadComplementos, loadCancelaciones, loadFacturapiStatus,
|
switchTab, loadFacturas, loadNotas, loadComplementos, loadCancelaciones, loadFacturapiStatus,
|
||||||
|
loadEmisorData, saveEmisorData,
|
||||||
showDetail, showCancelModal, confirmCancel, processQueue,
|
showDetail, showCancelModal, confirmCancel, processQueue,
|
||||||
showNewInvoiceModal, closeNewInvoiceModal, submitNewInvoice, notaCreditoPlaceholder,
|
showNewInvoiceModal, closeNewInvoiceModal, submitNewInvoice, notaCreditoPlaceholder,
|
||||||
openGlobalInvoiceModal, previewGlobalInvoice, generateGlobalInvoice, setupFacturapi,
|
openGlobalInvoiceModal, previewGlobalInvoice, generateGlobalInvoice, setupFacturapi,
|
||||||
|
|||||||
@@ -759,9 +759,10 @@
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="margin-top:var(--space-4);display:flex;justify-content:flex-end;gap:var(--space-3);">
|
<div style="margin-top:var(--space-4);display:flex;justify-content:flex-end;gap:var(--space-3);align-items:center;">
|
||||||
<button class="btn btn--ghost">Cancelar</button>
|
<span id="emisor-save-status" style="font-size:var(--text-caption);color:var(--color-text-muted);"></span>
|
||||||
<button class="btn btn--primary">
|
<button class="btn btn--ghost" type="button" onclick="Invoicing.loadEmisorData()">Cancelar</button>
|
||||||
|
<button class="btn btn--primary" type="button" onclick="Invoicing.saveEmisorData()">
|
||||||
<svg viewBox="0 0 24 24">
|
<svg viewBox="0 0 24 24">
|
||||||
<path d="M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z"/>
|
<path d="M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z"/>
|
||||||
<polyline points="17 21 17 13 7 13 7 21"/>
|
<polyline points="17 21 17 13 7 13 7 21"/>
|
||||||
@@ -1068,7 +1069,7 @@
|
|||||||
<script src="/pos/static/js/splash-loader.js?v=33" defer></script>
|
<script src="/pos/static/js/splash-loader.js?v=33" defer></script>
|
||||||
<script src="/pos/static/js/pos-utils.js?v=33" defer></script>
|
<script src="/pos/static/js/pos-utils.js?v=33" defer></script>
|
||||||
<script src="/pos/static/js/sidebar.js?v=46" defer></script>
|
<script src="/pos/static/js/sidebar.js?v=46" defer></script>
|
||||||
<script src="/pos/static/js/invoicing.js?v=33" defer></script>
|
<script src="/pos/static/js/invoicing.js?v=34" defer></script>
|
||||||
<script src="/pos/static/js/sync-engine.js" defer></script>
|
<script src="/pos/static/js/sync-engine.js" defer></script>
|
||||||
<script>if('serviceWorker' in navigator){navigator.serviceWorker.register('/pos/sw.js',{scope:'/pos/'});}</script>
|
<script>if('serviceWorker' in navigator){navigator.serviceWorker.register('/pos/sw.js',{scope:'/pos/'});}</script>
|
||||||
<script src="/pos/static/js/pwa-install.js" defer></script>
|
<script src="/pos/static/js/pwa-install.js" defer></script>
|
||||||
|
|||||||
Reference in New Issue
Block a user