Tag material list by discipline for multi-discipline WPs
When a package carries 2+ disciplines, the BOM gains a per-line Discipline column (hidden otherwise). Split by Discipline routes each instance only the material lines tagged to it; untagged lines stay on the kept master, and the split summary flags how many were untagged. Rendered doc shows the column when any line is tagged. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -207,12 +207,24 @@ function unitOptions(cur){
|
||||
if(c && !list.includes(c)) list.unshift(c);
|
||||
return `<option value="">Unit…</option>`+list.map(u=>`<option ${c===u?'selected':''}>${esc(u)}</option>`).join('');
|
||||
}
|
||||
// Discipline column on the BOM appears only for multi-discipline packages, so a
|
||||
// split hands each instance just its own materials. Keeps a stale value as an
|
||||
// option (mirrors unitOptions) if the discipline was later removed.
|
||||
function matDisciplineOptions(cur){
|
||||
const list=pkgDisciplines.slice(); const c=cur||'';
|
||||
if(c && !list.includes(c)) list.unshift(c);
|
||||
return `<option value="">—</option>`+list.map(d=>`<option ${c===d?'selected':''}>${esc(d)}</option>`).join('');
|
||||
}
|
||||
function buildMaterials(){
|
||||
const multi=isMultiDiscipline();
|
||||
const th=document.getElementById('mat-disc-th'); if(th) th.style.display=multi?'':'none';
|
||||
const tb=document.getElementById('material-body'); tb.innerHTML='';
|
||||
pkgMaterials.forEach((m,i)=>{ const tr=document.createElement('tr');
|
||||
const discCell = multi ? `<td><select onchange="pkgMaterials[${i}].discipline=this.value">${matDisciplineOptions(m.discipline)}</select></td>` : '';
|
||||
tr.innerHTML=`<td><input type="text" value="${(m.qty||'').replace(/"/g,'"')}" placeholder="20" oninput="pkgMaterials[${i}].qty=this.value"></td>
|
||||
<td><select onchange="pkgMaterials[${i}].unit=this.value">${unitOptions(m.unit)}</select></td>
|
||||
<td><input type="text" value="${(m.desc||'').replace(/"/g,'"')}" placeholder="3/8 lock washers gold" oninput="pkgMaterials[${i}].desc=this.value"></td>
|
||||
${discCell}
|
||||
<td class="center"><button class="row-del" onclick="removeMaterial(${i})">✕</button></td>`;
|
||||
tb.appendChild(tr); });
|
||||
}
|
||||
@@ -305,7 +317,7 @@ function toggleDiscipline(d,on){
|
||||
pkgDisciplines.forEach(x=>{ if(!pkgScope[x]) pkgScope[x]=['']; if(!pkgDiscStatus[x]) pkgDiscStatus[x]=getRadio('status')||'Draft'; });
|
||||
Object.keys(pkgScope).forEach(x=>{ if(!pkgDisciplines.includes(x)) delete pkgScope[x]; });
|
||||
Object.keys(pkgDiscStatus).forEach(x=>{ if(!pkgDisciplines.includes(x)) delete pkgDiscStatus[x]; });
|
||||
buildDisciplinePicker(); renderScope(); track('discipline_toggle',{count:pkgDisciplines.length});
|
||||
buildDisciplinePicker(); renderScope(); buildMaterials(); track('discipline_toggle',{count:pkgDisciplines.length});
|
||||
}
|
||||
|
||||
// Show the flat work-step list for 0–1 disciplines; per-discipline sections for 2+.
|
||||
@@ -399,6 +411,7 @@ function splitByDiscipline(){
|
||||
scope:{[d]:steps.length?steps:['']},
|
||||
discStatus:{[d]: (pkgDiscStatus[d]||base.status||'Draft')},
|
||||
status: pkgDiscStatus[d]||base.status||'Draft',
|
||||
materials: (base.materials||[]).filter(m=>m.discipline===d),
|
||||
workSteps: steps, work: steps.join('\n'),
|
||||
instanceOf: masterId, instanceLabel: suffix, parentNumber: baseNumber,
|
||||
split:false, children:undefined,
|
||||
@@ -412,7 +425,9 @@ function splitByDiscipline(){
|
||||
editingId=masterId; saveStore(); renderSavedList();
|
||||
track('wp_split',{disciplines:pkgDisciplines.length});
|
||||
toast('Split into '+children.length+' discipline instances');
|
||||
alert('Created '+children.length+' instances:\n\n• '+children.map(c=>c.number+' ('+c.disciplines[0]+')').join('\n• ')+'\n\nThe master '+baseNumber+' is kept as a roll-up. Edit each instance from the Saved Work Packages list.');
|
||||
const untagged=(base.materials||[]).filter(m=>!m.discipline).length;
|
||||
const matNote = untagged ? `\n\nNote: ${untagged} material line${untagged===1?'':'s'} had no discipline tag and stayed on the master only — tag them before splitting to route them to an instance.` : '';
|
||||
alert('Created '+children.length+' instances:\n\n• '+children.map(c=>c.number+' ('+c.disciplines[0]+', '+(c.materials?c.materials.length:0)+' material line'+((c.materials&&c.materials.length===1)?'':'s')+')').join('\n• ')+'\n\nThe master '+baseNumber+' is kept as a roll-up.'+matNote);
|
||||
}
|
||||
|
||||
// ── ASSETS (controls.dev) ────────────────────────────────────────────────────
|
||||
@@ -690,8 +705,9 @@ function renderPackage(pkg){
|
||||
<tr><th>Labor Est. Hrs.</th><td>${cell(pkg.hours)}</td></tr>
|
||||
<tr><th>Package Predecessor</th><td>${pkg.seq?('After: '+esc(pkg.seq)):'None (no predecessor)'}</td></tr>
|
||||
</tbody></table>`;
|
||||
if(pkg.materials&&pkg.materials.length){ h+=`<h2>4.0 Material List</h2><table><thead><tr><th style="width:80px">Qty</th><th style="width:80px">Unit</th><th>Description</th></tr></thead><tbody>`;
|
||||
pkg.materials.forEach(m=>h+=`<tr><td>${cell(m.qty)}</td><td>${cell(m.unit)}</td><td>${cell(m.desc)}</td></tr>`); h+=`</tbody></table>`; }
|
||||
if(pkg.materials&&pkg.materials.length){ const showDisc=pkg.materials.some(m=>m.discipline);
|
||||
h+=`<h2>4.0 Material List</h2><table><thead><tr><th style="width:80px">Qty</th><th style="width:80px">Unit</th><th>Description</th>${showDisc?'<th style="width:120px">Discipline</th>':''}</tr></thead><tbody>`;
|
||||
pkg.materials.forEach(m=>h+=`<tr><td>${cell(m.qty)}</td><td>${cell(m.unit)}</td><td>${cell(m.desc)}</td>${showDisc?`<td>${cell(m.discipline)}</td>`:''}</tr>`); h+=`</tbody></table>`; }
|
||||
if(pkg.attachments&&pkg.attachments.length){ h+=`<h2>5.0 Drawings & Attachments</h2><table><thead><tr><th>Document</th><th style="width:60px">Rev</th><th>Link / Note</th></tr></thead><tbody>`;
|
||||
pkg.attachments.forEach(a=>h+=`<tr><td>${cell(a.doc)}</td><td>${cell(a.rev)}</td><td>${a.link?linkify(a.link):ns()}</td></tr>`); h+=`</tbody></table>`; }
|
||||
h+=`<h2>6.0 Kitting & MIMO</h2><table><tbody>
|
||||
|
||||
@@ -114,7 +114,7 @@
|
||||
<div class="card">
|
||||
<div class="sub-heading">Material List</div>
|
||||
<div class="notice">Structured bill of materials. Feeds kitting and the delivery forecast. Unit is from the Acumatica unit list.</div>
|
||||
<div class="table-wrap"><table><thead><tr><th style="width:90px">Qty</th><th style="width:120px">Unit</th><th>Description</th><th style="width:44px"></th></tr></thead><tbody id="material-body"></tbody></table></div>
|
||||
<div class="table-wrap"><table><thead><tr><th style="width:90px">Qty</th><th style="width:120px">Unit</th><th>Description</th><th id="mat-disc-th" style="width:140px;display:none">Discipline</th><th style="width:44px"></th></tr></thead><tbody id="material-body"></tbody></table></div>
|
||||
<div class="material-actions">
|
||||
<button class="add-btn" onclick="addMaterial()">+ Add Material Line</button>
|
||||
<button class="add-btn" onclick="document.getElementById('material-import').click()">⤒ Import from Excel/CSV</button>
|
||||
|
||||
Reference in New Issue
Block a user