import { api } from '../../lib/api.mjs';
const CODE_TYPES = [
{ key: 'gl_account', label: 'GL Account Code', placeholder: 'e.g. 6100-Operations' },
{ key: 'cost_center', label: 'Cost Center / Department', placeholder: 'e.g. CC-4200' },
{ key: 'wbs', label: 'Project WBS / Phase', placeholder: 'e.g. P-1234-A' },
{ key: 'billing_ref', label: 'Billing Reference', placeholder: 'e.g. INV-2024-001' },
];
class WoAccounting extends HTMLElement {
#woId = null;
#codes = {};
#saving = false;
#loading = true;
static get observedAttributes() { return ['wo-id']; }
connectedCallback() {
if (!this.shadowRoot) this.attachShadow({ mode: 'open' });
if (this.#woId) this.#load();
}
attributeChangedCallback(_, __, val) {
this.#woId = val ? +val : null;
if (this.shadowRoot && this.#woId) this.#load();
}
async #load() {
this.#loading = true;
this.#render();
try {
const rows = await api.get(`/work-orders/${this.#woId}/accounting`) || [];
this.#codes = {};
rows.forEach(r => { this.#codes[r.code_type] = { value: r.code_value, description: r.description }; });
} catch { this.#codes = {}; }
this.#loading = false;
this.#render();
}
async #save() {
if (this.#saving) return;
this.#saving = true;
this.#updateSaveIndicator('saving');
try {
const s = this.shadowRoot;
const payload = CODE_TYPES
.filter(ct => {
const v = s.querySelector(`[data-key="${ct.key}"] .code-value`)?.value?.trim();
return v;
})
.map(ct => ({
code_type: ct.key,
code_value: s.querySelector(`[data-key="${ct.key}"] .code-value`).value.trim(),
description: s.querySelector(`[data-key="${ct.key}"] .code-desc`).value.trim(),
}));
await api.put(`/work-orders/${this.#woId}/accounting`, payload);
this.#updateSaveIndicator('saved');
} catch (err) {
this.#updateSaveIndicator('error');
window.dispatchEvent(new CustomEvent('wo:toast', { detail: { message: err.message, type: 'error' } }));
} finally {
this.#saving = false;
}
}
#updateSaveIndicator(state) {
const el = this.shadowRoot?.querySelector('#save-indicator');
if (!el) return;
const msgs = { saving: '⋯ Saving…', saved: '✓ Saved', error: '✗ Error' };
const colors = { saving: 'var(--text-muted)', saved: 'var(--success)', error: 'var(--danger)' };
el.textContent = msgs[state];
el.style.color = colors[state];
if (state !== 'saving') setTimeout(() => { if (el) el.textContent = ''; }, 2500);
}
#render() {
const s = this.shadowRoot;
if (this.#loading) {
s.innerHTML = `