// ── ERPNext Dispatch resource calls ───────────────────────────────────────── // All ERPNext fetch() calls live here. // Swap BASE_URL in config/erpnext.js to change the target server. // ───────────────────────────────────────────────────────────────────────────── import { BASE_URL } from 'src/config/erpnext' import { getCSRF } from './auth' async function apiGet (path) { const res = await fetch(BASE_URL + path, { credentials: 'include' }) const data = await res.json() if (data.exc) throw new Error(data.exc) return data } async function apiPut (doctype, name, body) { const token = await getCSRF() const res = await fetch( `${BASE_URL}/api/resource/${encodeURIComponent(doctype)}/${encodeURIComponent(name)}`, { method: 'PUT', credentials: 'include', headers: { 'Content-Type': 'application/json', 'X-Frappe-CSRF-Token': token, }, body: JSON.stringify(body), }, ) const data = await res.json() if (data.exc) throw new Error(data.exc) return data } export async function fetchTechnicians () { const list = await apiGet('/api/resource/Dispatch%20Technician?fields=["name"]&limit=100') const names = (list.data || []).map(t => t.name) if (!names.length) return [] const docs = await Promise.all( names.map(n => apiGet(`/api/resource/Dispatch%20Technician/${encodeURIComponent(n)}`).then(d => d.data)) ) return docs } // Fetch all jobs with child tables (assistants) export async function fetchJobs (filters = null) { // Step 1: get job names from list endpoint let url = '/api/resource/Dispatch%20Job?fields=["name"]&limit=200' if (filters) url += '&filters=' + encodeURIComponent(JSON.stringify(filters)) const list = await apiGet(url) const names = (list.data || []).map(j => j.name) if (!names.length) return [] // Step 2: fetch each doc individually (includes child tables) const docs = await Promise.all( names.map(n => apiGet(`/api/resource/Dispatch%20Job/${encodeURIComponent(n)}`).then(d => d.data)) ) return docs } export async function updateJob (name, payload) { return apiPut('Dispatch Job', name, payload) } export async function createJob (payload) { const token = await getCSRF() const res = await fetch( `${BASE_URL}/api/resource/Dispatch%20Job`, { method: 'POST', credentials: 'include', headers: { 'Content-Type': 'application/json', 'X-Frappe-CSRF-Token': token }, body: JSON.stringify(payload), }, ) const data = await res.json() if (data.exc) throw new Error(data.exc) return data.data } export async function updateTech (name, payload) { return apiPut('Dispatch Technician', name, payload) } export async function fetchTags () { const data = await apiGet('/api/resource/Dispatch%20Tag?fields=["name","label","color","category"]&limit=200') return data.data || [] } export async function createTag (label, category = 'Custom', color = '#6b7280') { const token = await getCSRF() const res = await fetch( `${BASE_URL}/api/resource/Dispatch%20Tag`, { method: 'POST', credentials: 'include', headers: { 'Content-Type': 'application/json', 'X-Frappe-CSRF-Token': token }, body: JSON.stringify({ label, category, color }), }, ) const data = await res.json() if (data.exc) throw new Error(data.exc) return data.data }