438 lines
22 KiB
JavaScript
438 lines
22 KiB
JavaScript
/**
|
||
* 仓库管理模块 —— 借出单 / 借出还入单
|
||
*/
|
||
window.Warehouse = (() => {
|
||
let currentTab = 'borrow';
|
||
let currentUser = null;
|
||
let _approvedBorrows = [];
|
||
|
||
const statusLabel = (s) => {
|
||
const map = { pending: '待确认', approved: '已批准', rejected: '已拒绝', received: '已同意', not_received: '未收到', partial: '部分收到', returned_back: '已退回' };
|
||
return map[s] || s;
|
||
};
|
||
const statusColor = (s) => {
|
||
const map = { pending: '#f59e0b', approved: '#10b981', rejected: '#ef4444', received: '#10b981', not_received: '#ef4444', partial: '#f59e0b', returned_back: '#6b7280' };
|
||
return map[s] || '#94a3b8';
|
||
};
|
||
|
||
const isSuperadmin = () => currentUser && currentUser.role === 'superadmin';
|
||
const isAdmin = () => currentUser && currentUser.role === 'admin';
|
||
|
||
// ── 主渲染 ──────────────────────────────────
|
||
const render = async () => {
|
||
|
||
return `
|
||
<div style="padding:20px;max-width:1200px;margin:0 auto">
|
||
<div style="display:flex;align-items:center;gap:12px;margin-bottom:20px">
|
||
<div style="display:flex;gap:8px;background:var(--bg);border:1px solid var(--border);border-radius:10px;padding:4px">
|
||
${tabBtn('borrow', '借出单', currentTab)}
|
||
${tabBtn('return', '借出还入单', currentTab)}
|
||
</div>
|
||
</div>
|
||
<div id="warehouse-content"></div>
|
||
</div>
|
||
<style>
|
||
.wh-tab-btn { padding:8px 18px;border:none;border-radius:7px;cursor:pointer;font-size:13px;font-weight:500;transition:all .15s;background:transparent;color:var(--text-secondary); }
|
||
.wh-tab-btn.active { background:var(--primary,#3b82f6);color:#fff; }
|
||
.wh-table { width:100%;border-collapse:collapse;font-size:13px; }
|
||
.wh-table th,.wh-table td { padding:11px 14px;text-align:left;border-bottom:1px solid var(--border); }
|
||
.wh-table th { background:var(--bg);font-weight:600;color:var(--text-secondary); }
|
||
.wh-table tr:hover td { background:var(--bg); }
|
||
.wh-btn { padding:6px 14px;border:none;border-radius:6px;cursor:pointer;font-size:12px;font-weight:500; }
|
||
.wh-btn-primary { background:var(--primary,#3b82f6);color:#fff; }
|
||
.wh-btn-success { background:#10b981;color:#fff; }
|
||
.wh-btn-danger { background:#ef4444;color:#fff; }
|
||
.wh-btn-ghost { background:var(--bg);color:var(--text);border:1px solid var(--border); }
|
||
.wh-modal-overlay { position:fixed;inset:0;background:rgba(0,0,0,.45);display:flex;align-items:center;justify-content:center;z-index:2000; }
|
||
.wh-modal { background:var(--surface);border-radius:16px;padding:28px;width:90%;max-width:480px;box-shadow:0 20px 60px rgba(0,0,0,.25); }
|
||
.wh-form-row { margin-bottom:14px; }
|
||
.wh-form-row label { display:block;font-size:12px;font-weight:600;color:var(--text-secondary);margin-bottom:5px; }
|
||
.wh-form-row input,.wh-form-row textarea,.wh-form-row select { width:100%;padding:9px 12px;border:1px solid var(--border);border-radius:7px;background:var(--bg);color:var(--text);font-size:13px;box-sizing:border-box; }
|
||
.wh-form-row textarea { height:80px;resize:vertical; }
|
||
.wh-status-badge { display:inline-block;padding:3px 9px;border-radius:99px;font-size:11px;font-weight:600; }
|
||
</style>
|
||
`;
|
||
};
|
||
|
||
const tabBtn = (key, label, cur) =>
|
||
`<button class="wh-tab-btn${cur === key ? ' active' : ''}" onclick="Warehouse.switchTab('${key}')">${label}</button>`;
|
||
|
||
const renderUnreturnedCard = async () => {
|
||
try {
|
||
const res = await fetch('/api/warehouse/unreturned-summary', { credentials: 'include' });
|
||
const data = res.ok ? await res.json() : { summary: [], total_unreturned: 0 };
|
||
const summary = data.summary || [];
|
||
if (summary.length === 0) return '';
|
||
const rows = summary.map(s =>
|
||
`<span style="display:inline-flex;align-items:center;gap:6px;background:var(--bg);border:1px solid var(--border);border-radius:8px;padding:4px 12px;font-size:12px">
|
||
<span style="font-weight:600">${s.model}</span>
|
||
<span style="color:#ef4444;font-weight:700">未还 ${s.unreturned}</span>
|
||
<span style="color:var(--text-secondary)">(借 ${s.borrowed} / 还 ${s.returned})</span>
|
||
</span>`
|
||
).join('');
|
||
return `<div style="background:#fff7ed;border:1px solid #fed7aa;border-radius:10px;padding:12px 16px;margin-bottom:16px;display:flex;flex-wrap:wrap;gap:8px;align-items:center">
|
||
<span style="font-size:13px;font-weight:700;color:#ea580c;margin-right:4px">⚠️ 未还汇总</span>
|
||
${rows}
|
||
</div>`;
|
||
} catch (e) { return ''; }
|
||
};
|
||
|
||
const init = async () => {
|
||
renderTab();
|
||
};
|
||
|
||
const switchTab = (tab) => {
|
||
currentTab = tab;
|
||
document.querySelectorAll('.wh-tab-btn').forEach(b => {
|
||
b.classList.toggle('active', b.textContent.trim() === (tab === 'borrow' ? '借出单' : '借出还入单'));
|
||
});
|
||
renderTab();
|
||
};
|
||
|
||
// ── 借出单列表 ──────────────────────────────
|
||
const renderTab = async () => {
|
||
const el = document.getElementById('warehouse-content');
|
||
if (!el) return;
|
||
if (currentTab === 'borrow') await renderBorrowTab(el);
|
||
else await renderReturnTab(el);
|
||
};
|
||
|
||
const renderBorrowTab = async (el) => {
|
||
el.innerHTML = '<div style="color:var(--text-secondary);padding:20px">加载中...</div>';
|
||
const [res, retRes] = await Promise.all([
|
||
fetch('/api/warehouse/borrow-orders', { credentials: 'include' }),
|
||
fetch('/api/warehouse/return-orders', { credentials: 'include' })
|
||
]);
|
||
const data = res.ok ? await res.json() : { list: [] };
|
||
const retData = retRes.ok ? await retRes.json() : { list: [] };
|
||
const list = data.list || [];
|
||
|
||
// 按borrow_order_no聚合已同意的还入数量
|
||
const receivedMap = {};
|
||
(retData.list || []).forEach(r => {
|
||
if (r.status === 'received') {
|
||
receivedMap[r.borrow_order_no] = (receivedMap[r.borrow_order_no] || 0) + (r.received_qty != null ? r.received_qty : r.qty);
|
||
}
|
||
});
|
||
|
||
const pendingCount = list.filter(r => r.status === 'pending').length;
|
||
|
||
el.innerHTML = `
|
||
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:16px">
|
||
<div style="display:flex;align-items:center;gap:10px">
|
||
<span style="font-size:15px;font-weight:600">借出单列表</span>
|
||
${pendingCount > 0 ? `<span style="background:#f59e0b;color:#fff;border-radius:99px;padding:2px 8px;font-size:11px;font-weight:700">${pendingCount} 待确认</span>` : ''}
|
||
</div>
|
||
${isSuperadmin() ? `<button class="wh-btn wh-btn-primary" onclick="Warehouse.showCreateBorrowModal()">+ 新建借出单</button>` : ''}
|
||
</div>
|
||
<div style="background:var(--surface);border-radius:12px;overflow:hidden;border:1px solid var(--border)">
|
||
<table class="wh-table">
|
||
<thead><tr>
|
||
<th>单号</th><th>型号</th><th>数量</th><th>未还数</th><th>借出理由</th>
|
||
<th>申请人</th><th>申请时间</th><th>状态</th><th>拒绝原因</th><th>确认人</th>
|
||
${isAdmin() ? '<th>操作</th>' : ''}
|
||
</tr></thead>
|
||
<tbody>
|
||
${list.length === 0 ? `<tr><td colspan="10" style="text-align:center;color:var(--text-secondary);padding:30px">暂无数据</td></tr>` : ''}
|
||
${list.map(r => {
|
||
const received = receivedMap[r.order_no] || 0;
|
||
const unreturned = r.status === 'approved' ? Math.max(r.qty - received, 0) : null;
|
||
return `
|
||
<tr>
|
||
<td style="font-family:monospace;font-size:12px">${r.order_no}</td>
|
||
<td>${r.model}</td>
|
||
<td>${r.qty}</td>
|
||
<td style="font-weight:700;color:${unreturned > 0 ? '#ef4444' : (unreturned === 0 ? '#10b981' : 'var(--text-secondary)')}">${unreturned == null ? '—' : unreturned}</td>
|
||
<td style="max-width:180px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap" title="${r.reason}">${r.reason}</td>
|
||
<td>${r.created_by}</td>
|
||
<td style="font-size:12px;color:var(--text-secondary)">${(r.created_at || '').replace('T',' ').slice(0, 16)}</td>
|
||
<td><span class="wh-status-badge" style="background:${statusColor(r.status)}22;color:${statusColor(r.status)}">${statusLabel(r.status)}</span></td>
|
||
<td style="font-size:12px;color:#ef4444">${r.reject_reason || '—'}</td>
|
||
<td style="font-size:12px;color:var(--text-secondary)">${r.confirmed_by || '—'}</td>
|
||
${isAdmin() ? `<td style="white-space:nowrap">
|
||
${r.status === 'pending' && currentUser.role === 'admin'
|
||
? `<button class="wh-btn wh-btn-success" style="margin-right:6px" onclick="Warehouse.confirmBorrow('${r.order_no}','approve')">批准</button>
|
||
<button class="wh-btn wh-btn-danger" onclick="Warehouse.showRejectModal('borrow','${r.order_no}')">拒绝</button>`
|
||
: '—'}
|
||
</td>` : ''}
|
||
</tr>
|
||
`;}).join('')}
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
`;
|
||
};
|
||
|
||
// ── 还入单列表 ──────────────────────────────
|
||
const renderReturnTab = async (el) => {
|
||
el.innerHTML = '<div style="color:var(--text-secondary);padding:20px">加载中...</div>';
|
||
const [retRes, borrowRes] = await Promise.all([
|
||
fetch('/api/warehouse/return-orders', { credentials: 'include' }),
|
||
fetch('/api/warehouse/borrow-orders?status=approved', { credentials: 'include' })
|
||
]);
|
||
const retData = retRes.ok ? await retRes.json() : { list: [] };
|
||
const borrowData = borrowRes.ok ? await borrowRes.json() : { list: [] };
|
||
const list = retData.list || [];
|
||
_approvedBorrows = borrowData.list || [];
|
||
|
||
const pendingCount = list.filter(r => r.status === 'pending').length;
|
||
|
||
el.innerHTML = `
|
||
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:16px">
|
||
<div style="display:flex;align-items:center;gap:10px">
|
||
<span style="font-size:15px;font-weight:600">借出还入单列表</span>
|
||
${pendingCount > 0 ? `<span style="background:#f59e0b;color:#fff;border-radius:99px;padding:2px 8px;font-size:11px;font-weight:700">${pendingCount} 待确认</span>` : ''}
|
||
</div>
|
||
${isSuperadmin() ? `<button class="wh-btn wh-btn-primary" onclick="Warehouse.showCreateReturnModal()">+ 新建还入单</button>` : ''}
|
||
</div>
|
||
<div style="background:var(--surface);border-radius:12px;overflow:hidden;border:1px solid var(--border)">
|
||
<table class="wh-table">
|
||
<thead><tr>
|
||
<th>还入单号</th><th>对应借出单</th><th>型号</th><th>还入数</th>
|
||
<th>申请人</th><th>申请时间</th><th>状态</th><th>备注</th><th>确认人</th>
|
||
${isAdmin() ? '<th>操作</th>' : ''}
|
||
</tr></thead>
|
||
<tbody>
|
||
${list.length === 0 ? `<tr><td colspan="9" style="text-align:center;color:var(--text-secondary);padding:30px">暂无数据</td></tr>` : ''}
|
||
${list.map(r => `
|
||
<tr>
|
||
<td style="font-family:monospace;font-size:12px">${r.order_no}</td>
|
||
<td style="font-family:monospace;font-size:12px">${r.borrow_order_no}</td>
|
||
<td>${r.model}</td>
|
||
<td>${r.qty}</td>
|
||
<td>${r.created_by}</td>
|
||
<td style="font-size:12px;color:var(--text-secondary)">${(r.created_at || '').replace('T',' ').slice(0, 16)}</td>
|
||
<td><span class="wh-status-badge" style="background:${statusColor(r.status)}22;color:${statusColor(r.status)}">${statusLabel(r.status)}</span></td>
|
||
<td style="font-size:12px;color:var(--text-secondary)">${r.reject_reason || '—'}</td>
|
||
<td style="font-size:12px;color:var(--text-secondary)">${r.confirmed_by || '—'}</td>
|
||
${isAdmin() ? `<td style="white-space:nowrap">
|
||
${r.status === 'pending' && currentUser.role === 'admin'
|
||
? `<button class="wh-btn wh-btn-success" style="margin-right:6px" onclick="Warehouse.confirmReturn('${r.order_no}','approve')">同意</button>
|
||
<button class="wh-btn wh-btn-danger" onclick="Warehouse.showNotReceivedModal('${r.order_no}',${r.qty})">退回</button>`
|
||
: '—'}
|
||
</td>` : ''}
|
||
</tr>
|
||
`).join('')}
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
`;
|
||
};
|
||
|
||
// ── 新建借出单弹窗 ──────────────────────────
|
||
const showCreateBorrowModal = () => {
|
||
const html = `
|
||
<div class="wh-modal-overlay" id="wh-modal">
|
||
<div class="wh-modal">
|
||
<div style="font-size:16px;font-weight:700;margin-bottom:20px">新建借出单</div>
|
||
<div class="wh-form-row"><label>借出型号 *</label><input id="wh-b-model" placeholder="请输入型号"></div>
|
||
<div class="wh-form-row"><label>数量 *</label><input id="wh-b-qty" type="number" min="1" placeholder="请输入数量"></div>
|
||
<div class="wh-form-row"><label>借出理由 *</label><textarea id="wh-b-reason" placeholder="请说明借出原因"></textarea></div>
|
||
<div style="display:flex;justify-content:flex-end;gap:10px;margin-top:20px">
|
||
<button class="wh-btn wh-btn-ghost" onclick="Warehouse.closeModal()">取消</button>
|
||
<button class="wh-btn wh-btn-primary" onclick="Warehouse.submitBorrow()">提交</button>
|
||
</div>
|
||
</div>
|
||
</div>`;
|
||
document.body.insertAdjacentHTML('beforeend', html);
|
||
};
|
||
|
||
const submitBorrow = async () => {
|
||
const model = document.getElementById('wh-b-model')?.value.trim();
|
||
const qty = document.getElementById('wh-b-qty')?.value;
|
||
const reason = document.getElementById('wh-b-reason')?.value.trim();
|
||
if (!model || !qty || !reason) { API.toast('请填写所有必填项'); return; }
|
||
const res = await fetch('/api/warehouse/borrow-orders', {
|
||
method: 'POST', credentials: 'include',
|
||
headers: { 'Content-Type': 'application/json' },
|
||
body: JSON.stringify({ model, qty: parseInt(qty), reason })
|
||
});
|
||
const data = await res.json();
|
||
if (data.ok) {
|
||
API.toast(`借出单 ${data.order_no} 已提交,等待仓管确认`);
|
||
closeModal();
|
||
renderTab();
|
||
} else {
|
||
API.toast(data.error || '提交失败');
|
||
}
|
||
};
|
||
|
||
// ── 新建还入单弹窗 ──────────────────────────
|
||
const showCreateReturnModal = () => {
|
||
const options = (_approvedBorrows || []).map(b =>
|
||
`<option value="${b.order_no}" data-model="${b.model}">${b.order_no} — ${b.model} × ${b.qty}</option>`
|
||
).join('');
|
||
const html = `
|
||
<div class="wh-modal-overlay" id="wh-modal">
|
||
<div class="wh-modal">
|
||
<div style="font-size:16px;font-weight:700;margin-bottom:20px">新建借出还入单</div>
|
||
<div class="wh-form-row">
|
||
<label>对应借出单 *</label>
|
||
<select id="wh-r-borrow" onchange="Warehouse.onBorrowSelect(this)">
|
||
<option value="">-- 请选择已批准的借出单 --</option>
|
||
${options || '<option disabled>暂无已批准的借出单</option>'}
|
||
</select>
|
||
</div>
|
||
<div class="wh-form-row"><label>还入型号 *</label><input id="wh-r-model" placeholder="自动填充或手动输入"></div>
|
||
<div class="wh-form-row"><label>还入数量 *</label><input id="wh-r-qty" type="number" min="1" placeholder="请输入数量"></div>
|
||
<div style="display:flex;justify-content:flex-end;gap:10px;margin-top:20px">
|
||
<button class="wh-btn wh-btn-ghost" onclick="Warehouse.closeModal()">取消</button>
|
||
<button class="wh-btn wh-btn-primary" onclick="Warehouse.submitReturn()">提交</button>
|
||
</div>
|
||
</div>
|
||
</div>`;
|
||
document.body.insertAdjacentHTML('beforeend', html);
|
||
};
|
||
|
||
const onBorrowSelect = (sel) => {
|
||
const opt = sel.options[sel.selectedIndex];
|
||
const model = opt.getAttribute('data-model') || '';
|
||
const modelEl = document.getElementById('wh-r-model');
|
||
if (modelEl) modelEl.value = model;
|
||
};
|
||
|
||
const submitReturn = async () => {
|
||
const borrow_order_no = document.getElementById('wh-r-borrow')?.value;
|
||
const model = document.getElementById('wh-r-model')?.value.trim();
|
||
const qty = document.getElementById('wh-r-qty')?.value;
|
||
if (!borrow_order_no || !model || !qty) { API.toast('请填写所有必填项'); return; }
|
||
const res = await fetch('/api/warehouse/return-orders', {
|
||
method: 'POST', credentials: 'include',
|
||
headers: { 'Content-Type': 'application/json' },
|
||
body: JSON.stringify({ borrow_order_no, model, qty: parseInt(qty) })
|
||
});
|
||
const data = await res.json();
|
||
if (data.ok) {
|
||
API.toast(`还入单 ${data.order_no} 已提交,等待仓管确认`);
|
||
closeModal();
|
||
renderTab();
|
||
} else {
|
||
API.toast(data.error || '提交失败');
|
||
}
|
||
};
|
||
|
||
// ── 拒绝弹窗 ────────────────────────────────
|
||
const showRejectModal = (type, orderNo) => {
|
||
const html = `
|
||
<div class="wh-modal-overlay" id="wh-modal">
|
||
<div class="wh-modal">
|
||
<div style="font-size:16px;font-weight:700;margin-bottom:20px;color:#ef4444">拒绝单据</div>
|
||
<div style="font-size:13px;color:var(--text-secondary);margin-bottom:16px">单号:${orderNo}</div>
|
||
<div class="wh-form-row"><label>拒绝原因 *</label><textarea id="wh-reject-reason" placeholder="请填写拒绝原因"></textarea></div>
|
||
<div style="display:flex;justify-content:flex-end;gap:10px;margin-top:20px">
|
||
<button class="wh-btn wh-btn-ghost" onclick="Warehouse.closeModal()">取消</button>
|
||
<button class="wh-btn wh-btn-danger" onclick="Warehouse.doReject('${type}','${orderNo}')">确认拒绝</button>
|
||
</div>
|
||
</div>
|
||
</div>`;
|
||
document.body.insertAdjacentHTML('beforeend', html);
|
||
};
|
||
|
||
const doReject = async (type, orderNo) => {
|
||
const reject_reason = document.getElementById('wh-reject-reason')?.value.trim();
|
||
if (!reject_reason) { API.toast('请填写拒绝原因'); return; }
|
||
const url = type === 'borrow'
|
||
? `/api/warehouse/borrow-orders/${orderNo}/confirm`
|
||
: `/api/warehouse/return-orders/${orderNo}/confirm`;
|
||
const res = await fetch(url, {
|
||
method: 'POST', credentials: 'include',
|
||
headers: { 'Content-Type': 'application/json' },
|
||
body: JSON.stringify({ action: 'reject', reject_reason })
|
||
});
|
||
const data = await res.json();
|
||
if (data.ok) { API.toast('已拒绝'); closeModal(); renderTab(); }
|
||
else API.toast(data.error || '操作失败');
|
||
};
|
||
|
||
// ── 批准操作 ────────────────────────────────
|
||
const confirmBorrow = async (orderNo, action) => {
|
||
const res = await fetch(`/api/warehouse/borrow-orders/${orderNo}/confirm`, {
|
||
method: 'POST', credentials: 'include',
|
||
headers: { 'Content-Type': 'application/json' },
|
||
body: JSON.stringify({ action })
|
||
});
|
||
const data = await res.json();
|
||
if (data.ok) { API.toast('操作成功'); renderTab(); }
|
||
else API.toast(data.error || '操作失败');
|
||
};
|
||
|
||
const confirmReturn = async (orderNo, action) => {
|
||
const res = await fetch(`/api/warehouse/return-orders/${orderNo}/confirm`, {
|
||
method: 'POST', credentials: 'include',
|
||
headers: { 'Content-Type': 'application/json' },
|
||
body: JSON.stringify({ action })
|
||
});
|
||
const data = await res.json();
|
||
if (data.ok) { API.toast('操作成功'); renderTab(); }
|
||
else API.toast(data.error || '操作失败');
|
||
};
|
||
|
||
const showNotReceivedModal = (orderNo, totalQty) => {
|
||
const html = `
|
||
<div class="wh-modal-overlay" id="wh-modal">
|
||
<div class="wh-modal">
|
||
<div style="font-size:16px;font-weight:700;margin-bottom:20px">退回还入单</div>
|
||
<div class="wh-form-row">
|
||
<label>还入单号</label>
|
||
<input value="${orderNo}" disabled style="background:var(--bg);color:var(--text-secondary)">
|
||
</div>
|
||
<div class="wh-form-row">
|
||
<label>还入申请数量</label>
|
||
<input value="${totalQty}" disabled style="background:var(--bg);color:var(--text-secondary)">
|
||
</div>
|
||
<div class="wh-form-row">
|
||
<label>退回备注(可选)</label>
|
||
<textarea id="wh-not-recv-note" placeholder="说明退回原因"></textarea>
|
||
</div>
|
||
<div style="display:flex;justify-content:flex-end;gap:10px;margin-top:20px">
|
||
<button class="wh-btn wh-btn-ghost" onclick="Warehouse.closeModal()">取消</button>
|
||
<button class="wh-btn wh-btn-danger" onclick="Warehouse.submitNotReceived('${orderNo}',${totalQty})">确认退回</button>
|
||
</div>
|
||
</div>
|
||
</div>`;
|
||
document.body.insertAdjacentHTML('beforeend', html);
|
||
};
|
||
|
||
const submitNotReceived = async (orderNo, totalQty) => {
|
||
const note = document.getElementById('wh-not-recv-note')?.value || '';
|
||
const res = await fetch(`/api/warehouse/return-orders/${orderNo}/confirm`, {
|
||
method: 'POST', credentials: 'include',
|
||
headers: { 'Content-Type': 'application/json' },
|
||
body: JSON.stringify({ action: 'reject', note })
|
||
});
|
||
const data = await res.json();
|
||
if (data.ok) { closeModal(); API.toast('已退回'); renderTab(); }
|
||
else API.toast(data.error || '操作失败');
|
||
};
|
||
|
||
const closeModal = () => {
|
||
document.getElementById('wh-modal')?.remove();
|
||
};
|
||
|
||
const renderPage = async (tab) => {
|
||
currentTab = tab;
|
||
try {
|
||
const res = await fetch('/api/auth/me', { credentials: 'include' });
|
||
currentUser = res.ok ? await res.json() : null;
|
||
} catch (e) { currentUser = null; }
|
||
return render();
|
||
};
|
||
|
||
return { render, renderPage, init, switchTab, showCreateBorrowModal, submitBorrow,
|
||
showCreateReturnModal, onBorrowSelect, submitReturn,
|
||
showRejectModal, doReject, confirmBorrow, confirmReturn,
|
||
showNotReceivedModal, submitNotReceived, closeModal };
|
||
})();
|
||
|
||
Router.register('/warehouse/borrow', async () => {
|
||
const html = await window.Warehouse.renderPage('borrow');
|
||
setTimeout(() => { window.Warehouse.init(); }, 0);
|
||
return html;
|
||
});
|
||
|
||
Router.register('/warehouse/return', async () => {
|
||
const html = await window.Warehouse.renderPage('return');
|
||
setTimeout(() => { window.Warehouse.init(); }, 0);
|
||
return html;
|
||
});
|