Factory Terminal

Scan your ID badge to log in

Or enter code manually

`; // Convert to secure Data URI link const htmlDataUri = "data:text/html;charset=utf-8," + encodeURIComponent(printHtml); // We use 'addDocument' directly so it skips Google Drive const payload = { action: 'addDocument', project_id: p.project_id, doc_label: savedDocName, file_url: htmlDataUri, visible_to_client: false }; try { await fetch(API,{ method:'POST', body: JSON.stringify(payload) }); // Open print preview immediately let printWindow = window.open('', '_blank'); printWindow.document.write(printHtml); printWindow.document.close(); closeDigitalFormsModal(); openItemDetail(p.project_id); } catch (err) { alert('Failed to save document.'); } finally { stopBtnLoading(generateBtn); } } // ========================================== // 7. LOGISTICS HUB (HISTORY TABLES) // ========================================== function openLogisticsHub() { document.getElementById('logistics-modal').classList.remove('hidden'); const select = document.getElementById('logisticsClientSelect'); select.innerHTML = ''; Object.keys(window.dataStore.clientsMap).forEach(clientId => { select.innerHTML += ``; }); } function closeLogisticsHub() { document.getElementById('logistics-modal').classList.add('hidden'); } async function fetchClientLogistics(clientId) { const listDiv = document.getElementById('shipping-items-list'); const btnPL = document.getElementById('btnGenPL'); const btnBOL = document.getElementById('btnGenBOL'); const plBody = document.getElementById('ui-logistics-pl-tbody'); const bolBody = document.getElementById('ui-logistics-bol-tbody'); if(!clientId) { listDiv.innerHTML = '

Select a client to view lots.

'; plBody.innerHTML = 'Select a client.'; bolBody.innerHTML = 'Select a client.'; btnPL.disabled = true; btnBOL.disabled = true; return; } listDiv.innerHTML = '

Fetching data...

'; try { let res = await fetch(`${API}?action=loadClientProfile&client_id=${clientId}`); let data = await res.json(); let packedLots = (data.production || []).filter(l => l.status === 'PACKED' || l.status === 'PREPARED FOR SHIPMENT'); if(packedLots.length === 0) { listDiv.innerHTML = '

No lots marked as PACKED available for this client.

'; } else { listDiv.innerHTML = packedLots.map(l => ` `).join(''); } plBody.innerHTML = data.packingLists && data.packingLists.length ? data.packingLists.map(pl => { let dateStr = pl.date; if (typeof dateStr === 'string' && dateStr.includes('T')) dateStr = dateStr.split('T')[0]; return `${pl.pl_id}${dateStr}`; }).join('') : 'No Packing Lists generated.'; bolBody.innerHTML = data.bols && data.bols.length ? data.bols.map(bol => { let dateStr = bol.date; if (typeof dateStr === 'string' && dateStr.includes('T')) dateStr = dateStr.split('T')[0]; return `${bol.id}${dateStr}${bol.carrier}`; }).join('') : 'No BOLs generated.'; } catch(e) { listDiv.innerHTML = '

Error fetching logistics data.

'; } } function toggleLogisticsBtns() { const checked = document.querySelectorAll('.logistics-checkbox:checked').length > 0; document.getElementById('btnGenPL').disabled = !checked; document.getElementById('btnGenBOL').disabled = !checked; } function getSelectedShippingItems() { return Array.from(document.querySelectorAll('.logistics-checkbox:checked')).map(cb => JSON.parse(cb.value)); } async function generatePackingList(btn) { const clientId = document.getElementById('logisticsClientSelect').value; const items = getSelectedShippingItems(); if(items.length === 0) return; startBtnLoading(btn, 'Saving...'); try { await fetch(API, { method: 'POST', body: JSON.stringify({ action: 'savePackingList', client_id: clientId, items: items }) }); fetchClientLogistics(clientId); } catch(e) { alert("Error"); } finally { stopBtnLoading(btn); } } async function generateBOL(btn) { const clientId = document.getElementById('logisticsClientSelect').value; const carrier = document.getElementById('shipCarrier').value; const dest = document.getElementById('shipRef').value; const items = getSelectedShippingItems(); if(!carrier || !dest) return alert("Carrier and Destination required."); startBtnLoading(btn, 'Generating...'); try { await fetch(API, { method: 'POST', body: JSON.stringify({ action: 'saveBOL', client_id: clientId, date: new Date().toISOString().split('T')[0], carrier: carrier, destination: dest, items: items }) }); fetchClientLogistics(clientId); } catch(e) { alert("Error"); } finally { stopBtnLoading(btn); } } function backToPO() { document.getElementById('item-detail-screen').classList.add('hidden'); document.getElementById('po-detail-screen').classList.remove('hidden'); } function backToDashboard() { document.getElementById('po-detail-screen').classList.add('hidden'); document.getElementById('dashboard-screen').classList.remove('hidden'); }