perf: parallelize dispatch API fetches + add sales_order/order_source fields
Dispatch performance: - Replace sequential batch fetches (batches of 15, one after another) with full parallel Promise.all — all doc fetches fire simultaneously - With 20 jobs: was ~3 sequential round-trips, now ~2 (1 list + 1 parallel) Order traceability: - Add sales_order (Link) and order_source (Select) fields to Dispatch Job - checkout.js sets order_source='Online' + sales_order link on job creation - acceptance.js sets order_source='Quotation' on quotation-sourced jobs - Store maps new fields: salesOrder, orderSource Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
c6b2dd1491
commit
fd326ac52e
|
|
@ -29,34 +29,31 @@ async function apiPut (doctype, name, body) {
|
|||
return data
|
||||
}
|
||||
|
||||
// Fetch docs in parallel batches to avoid browser connection limits
|
||||
async function batchFetchDocs (doctype, names, batchSize = 10) {
|
||||
const docs = []
|
||||
for (let i = 0; i < names.length; i += batchSize) {
|
||||
const batch = names.slice(i, i + batchSize)
|
||||
const results = await Promise.all(
|
||||
batch.map(n => apiGet(`/api/resource/${encodeURIComponent(doctype)}/${encodeURIComponent(n)}`).then(d => d.data))
|
||||
)
|
||||
docs.push(...results)
|
||||
}
|
||||
return docs
|
||||
// Single-call fetch with all fields + child tables
|
||||
async function listDocs (doctype, fields = '["*"]', filters = null, limit = 200) {
|
||||
let url = `/api/resource/${encodeURIComponent(doctype)}?fields=${fields}&limit_page_length=${limit}`
|
||||
if (filters) url += '&filters=' + encodeURIComponent(JSON.stringify(filters))
|
||||
const data = await apiGet(url)
|
||||
return data.data || []
|
||||
}
|
||||
|
||||
// Fetch single doc (needed for child tables not returned by list)
|
||||
async function fetchDoc (doctype, name) {
|
||||
return (await apiGet(`/api/resource/${encodeURIComponent(doctype)}/${encodeURIComponent(name)}`)).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)
|
||||
const names = (await listDocs('Dispatch Technician', '["name"]', null, 100)).map(t => t.name)
|
||||
if (!names.length) return []
|
||||
return batchFetchDocs('Dispatch Technician', names, 15)
|
||||
// All individual fetches in parallel (child tables: tags)
|
||||
return Promise.all(names.map(n => fetchDoc('Dispatch Technician', n)))
|
||||
}
|
||||
|
||||
// Fetch all jobs with child tables (assistants)
|
||||
export async function fetchJobs (filters = null) {
|
||||
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)
|
||||
const names = (await listDocs('Dispatch Job', '["name"]', filters, 200)).map(j => j.name)
|
||||
if (!names.length) return []
|
||||
return batchFetchDocs('Dispatch Job', names, 15)
|
||||
// All individual fetches in parallel (child tables: assistants, tags)
|
||||
return Promise.all(names.map(n => fetchDoc('Dispatch Job', n)))
|
||||
}
|
||||
|
||||
export async function updateJob (name, payload) {
|
||||
|
|
|
|||
|
|
@ -51,7 +51,9 @@ export const useDispatchStore = defineStore('dispatch', () => {
|
|||
stepOrder: j.step_order || 0,
|
||||
onOpenWebhook: j.on_open_webhook || null,
|
||||
onCloseWebhook: j.on_close_webhook || null,
|
||||
published: j.published === undefined ? true : !!j.published, // backwards compat: existing jobs default published
|
||||
salesOrder: j.sales_order || null,
|
||||
orderSource: j.order_source || 'Manual',
|
||||
published: j.published === undefined ? true : !!j.published,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -182,6 +182,7 @@ async function createDeferredJobs (steps, ctx, quotationName) {
|
|||
source_issue: ctx.issue || '',
|
||||
customer: ctx.customer || '',
|
||||
service_location: ctx.service_location || '',
|
||||
order_source: 'Quotation',
|
||||
depends_on: dependsOn,
|
||||
parent_job: parentJob,
|
||||
step_order: step.step_order || (i + 1),
|
||||
|
|
|
|||
|
|
@ -231,6 +231,8 @@ async function processCheckout (body) {
|
|||
status: 'open',
|
||||
job_type: step.job_type || 'Autre',
|
||||
customer: customerName,
|
||||
sales_order: orderName || '',
|
||||
order_source: 'Online',
|
||||
depends_on: dependsOn,
|
||||
parent_job: parentJob,
|
||||
step_order: i + 1,
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user