// extra_acts.js v=20260521a const ExtraActs = (function () { "use strict"; function fmt(n) { return Math.round(n||0).toLocaleString("ru-RU") + " ₽"; } function fmtDate(iso) { if(!iso) return "—"; const d=iso.slice(0,10).split("-"); return d[2]+"."+d[1]+"."+d[0]; } function el(html) { const t=document.createElement("div"); t.innerHTML=html.trim(); return t.firstChild; } function showErr(c,msg){ c.innerHTML=`
${msg}
`; } const STATUS = { draft:"Черновик", agreed:"Согласован", signed:"Подписан", cancelled:"Отменён" }; const STATUS_BG = { draft:"#eee", agreed:"#CCE5FF", signed:"#D1E7DD", cancelled:"#f8d7da" }; const STATUS_FG = { draft:"#555", agreed:"#004085", signed:"#0F5132", cancelled:"#721c24" }; function badge(status) { return `${STATUS[status]||status}`; } // ─── LIST ───────────────────────────────────────────────────────── async function mount(container, assemblyId) { container.innerHTML = `
📋 Доп. работы
`; container.querySelector("#new-act-btn").addEventListener("click", () => mountCreate(container, assemblyId)); const body = container.querySelector("#list-body"); body.innerHTML = `
Загрузка…
`; let data; try { data = await _api("/api/extra_acts_list", { assembly_id: assemblyId }); } catch(e) { showErr(body, "Ошибка: "+e.message); return; } if (data.error) { showErr(body, data.error); return; } const acts = data.acts || []; if (!acts.length) { body.innerHTML = `
Нет актов по этой сборке
`; return; } body.innerHTML = ""; acts.forEach(a => { const card = el(`
${fmt(parseFloat(a.total_amount||0))} ${badge(a.status)}
${a.items_count} позиций · ${fmtDate(a.created_at)}
${a.signed_by_name ? `
Подписал: ${a.signed_by_name} · ${fmtDate(a.signed_at)}
` : ""} ${a.notes ? `
${a.notes}
` : ""}
`); body.appendChild(card); }); } // ─── CREATE ─────────────────────────────────────────────────────── async function mountCreate(container, assemblyId) { container.innerHTML = `
➕ Новый акт
`; container.querySelector("#back-btn").addEventListener("click", () => mount(container, assemblyId)); const catalogBody = container.querySelector("#catalog-body"); const basketPanel = container.querySelector("#basket-panel"); // Basket state const basket = {}; // id -> {item, qty} const updateBasket = () => _renderBasket(basketPanel, basket, assemblyId, container); updateBasket(); catalogBody.innerHTML = `
Загрузка каталога…
`; let pb; try { pb = await _api("/api/pricebook_list", {}); } catch(e) { showErr(catalogBody, "Ошибка: "+e.message); return; } if (pb.error) { showErr(catalogBody, pb.error); return; } catalogBody.innerHTML = ""; _renderSection(catalogBody, "Прайс компании", pb.company||[], basket, updateBasket); _renderSection(catalogBody, "Мой прайс (ИП)", pb.personal||[], basket, updateBasket); } function _renderSection(parent, title, items, basket, updateBasket) { if (!items.length) return; const section = el(`
${title}
`); // Group by category const cats = {}; items.forEach(it => { (cats[it.category] = cats[it.category]||[]).push(it); }); Object.entries(cats).forEach(([cat, catItems]) => { const catWrap = el(`
`); const catHead = el(`
${cat}
`); const catList = el(`