// warehouse-data.jsx — Склад / облік майна та інвентаризація // Основні засоби (ОЗ), МШП (малоцінка), ліцензії ПЗ, вимірювальні прилади. // ============ КАТЕГОРІЇ МАЙНА ============ // prefix → маска інвентарного номера: УБП--0001 const ASSET_CATEGORIES = [ { id: "oz", label: "Основні засоби", short: "ОЗ", prefix: "ОЗ", icon: "🖥", depreciable: true, note: "комп'ютери, плотери, авто, меблі" }, { id: "mhp", label: "МШП (малоцінка)", short: "МШП", prefix: "МШП", icon: "🧰", depreciable: true, note: "інструменти, дрібна техніка" }, { id: "lic", label: "Ліцензії ПЗ", short: "ПЗ", prefix: "ПЗ", icon: "💿", depreciable: false, note: "Autodesk, ЛІРА, АВК, M365" }, { id: "dev", label: "Вимірювальні прилади", short: "ВП", prefix: "ВП", icon: "📐", depreciable: true, note: "далекоміри, нівеліри, тахеометри" }, ]; window.ASSET_CATEGORIES = ASSET_CATEGORIES; window.getAssetCategory = (id) => ASSET_CATEGORIES.find(c => c.id === id) || ASSET_CATEGORIES[0]; // ============ СТАТУСИ ============ const ASSET_STATUS = { active: { label: "В експлуатації", tone: "live" }, repair: { label: "На ремонті", tone: "amber" }, written_off: { label: "Списано", tone: "neutral" }, }; window.ASSET_STATUS = ASSET_STATUS; // ============ ЛОКАЦІЇ ============ const ASSET_LOCATIONS = { constr: "Офіс · конструкторський відділ", arch: "Офіс · архітектурна майстерня", gip: "Офіс · кабінет ГІП", meet: "Офіс · переговорна", print: "Офіс · друкарська зона", server: "Серверна", field: "Виїзний (службове авто)", storage: "Склад / архів", }; window.ASSET_LOCATIONS = ASSET_LOCATIONS; // ============ РЕЄСТР МАЙНА ============ // invNo — інвентарний номер за маскою. cost — первісна вартість. // lifeMonths — строк корисного використання. holder — id МВО (window.DATA.TEAM). const ASSETS = [ // — Основні засоби — { id: "as-01", invNo: "УБП-ОЗ-0001", cat: "oz", name: "Робоча станція Dell Precision 5860", model: "Xeon W5-2445 / 64GB / RTX A4000", serial: "CN-0R7TK2-74", cost: 78000, lifeMonths: 36, bought: "2024-02-12", status: "active", holder: "ap", location: "constr", warrantyUntil: "2027-02-12", maintenance: [ { date: "2025-09-04", what: "Чистка, заміна термопасти", cost: 0, by: "ІТ-підрядник" } ] }, { id: "as-02", invNo: "УБП-ОЗ-0002", cat: "oz", name: "Плотер HP DesignJet T1700 (A0)", model: "44\", PostScript", serial: "SG62L8M01R", cost: 165000, lifeMonths: 60, bought: "2022-05-20", status: "active", holder: "ok", location: "print", warrantyUntil: "2025-05-20", maintenance: [ { date: "2026-03-18", what: "Заміна друкуючої головки №3", cost: 6200, by: "HP Service" }, { date: "2025-04-02", what: "ТО, калібрування кольору", cost: 3400, by: "HP Service" }, ] }, { id: "as-03", invNo: "УБП-ОЗ-0003", cat: "oz", name: "МФУ Kyocera TASKalfa 2554ci", model: "A3, кольоровий", serial: "VKQ3201845", cost: 42000, lifeMonths: 48, bought: "2023-09-08", status: "active", holder: "ok", location: "print", warrantyUntil: "2025-09-08", maintenance: [] }, { id: "as-04", invNo: "УБП-ОЗ-0004", cat: "oz", name: "Сервер NAS Synology DS1821+", model: "8-bay / 64TB RAID6", serial: "21A0SVN4920", cost: 95000, lifeMonths: 60, bought: "2023-01-16", status: "active", holder: "ap", location: "server", warrantyUntil: "2026-01-16", maintenance: [ { date: "2025-11-22", what: "Заміна диску 4 (SMART warning)", cost: 8900, by: "ІТ-підрядник" } ] }, { id: "as-05", invNo: "УБП-ОЗ-0005", cat: "oz", name: "Автомобіль Toyota RAV4 Hybrid", model: "2021, держ. № AA 4781 KP", serial: "VIN JTMB1FV40ND004781", cost: 1250000, lifeMonths: 84, bought: "2021-08-30", status: "active", holder: "ok", location: "field", warrantyUntil: "2026-08-30", maintenance: [ { date: "2026-02-11", what: "ТО-90000, гальмівні колодки", cost: 14200, by: "Тойота Центр" } ] }, { id: "as-06", invNo: "УБП-ОЗ-0006", cat: "oz", name: "Конференц-дисплей Samsung Flip 2", model: "65\" WM65R, інтерактивний", serial: "0ATM3PKN200047", cost: 88000, lifeMonths: 60, bought: "2022-11-04", status: "active", holder: "tm", location: "meet", warrantyUntil: "2024-11-04", maintenance: [] }, { id: "as-07", invNo: "УБП-ОЗ-0007", cat: "oz", name: "Комплект робочих місць (10 шт)", model: "столи, крісла Kreslo Ergo, тумби", serial: "—", cost: 120000, lifeMonths: 84, bought: "2020-09-15", status: "active", holder: "ok", location: "constr", warrantyUntil: "2023-09-15", maintenance: [] }, { id: "as-08", invNo: "УБП-ОЗ-0008", cat: "oz", name: "Ноутбук MacBook Pro 16 M3 Max", model: "48GB / 1TB", serial: "C02XL0AAJGH7", cost: 115000, lifeMonths: 36, bought: "2024-06-03", status: "active", holder: "tm", location: "arch", warrantyUntil: "2026-06-03", maintenance: [] }, { id: "as-09", invNo: "УБП-ОЗ-0009", cat: "oz", name: "Робоча станція HP Z4 G5", model: "Xeon W3-2425 / 32GB / RTX A2000", serial: "CZC4189TBR", cost: 72000, lifeMonths: 36, bought: "2023-03-21", status: "active", holder: "vs", location: "constr", warrantyUntil: "2026-03-21", maintenance: [] }, { id: "as-10", invNo: "УБП-ОЗ-0010", cat: "oz", name: "Плотер HP DesignJet 500 (A1)", model: "застарілий, 24\"", serial: "ESA8C1P0KR", cost: 38000, lifeMonths: 60, bought: "2016-04-10", status: "written_off", holder: "ok", location: "storage", warrantyUntil: "2018-04-10", writeOffDate: "2024-12-28", writeOffReason: "Знос 100%, ремонт економічно недоцільний. Акт списання №7 від 28.12.2025.", maintenance: [] }, // — МШП (малоцінка) — { id: "as-11", invNo: "УБП-МШП-0001", cat: "mhp", name: "Монітор Dell UltraSharp U2723QE 27\"", model: "4K IPS", serial: "CN0M4K27", cost: 14000, lifeMonths: 24, bought: "2024-01-22", status: "active", holder: "ap", location: "constr", warrantyUntil: "2027-01-22", maintenance: [] }, { id: "as-12", invNo: "УБП-МШП-0002", cat: "mhp", name: "ДБЖ APC Smart-UPS 1500VA", model: "SMT1500RMI2U", serial: "AS2330142255", cost: 11000, lifeMonths: 36, bought: "2023-07-19", status: "active", holder: "ap", location: "server", warrantyUntil: "2026-07-19", maintenance: [] }, { id: "as-13", invNo: "УБП-МШП-0003", cat: "mhp", name: "Шафа архівна металева (4 секції)", model: "ШАМ-04", serial: "—", cost: 9500, lifeMonths: 84, bought: "2021-04-06", status: "active", holder: "ok", location: "storage", warrantyUntil: "—", maintenance: [] }, { id: "as-14", invNo: "УБП-МШП-0004", cat: "mhp", name: "Проектор Epson EB-2250U", model: "WUXGA, 5000lm", serial: "X4ZF8901234", cost: 13500, lifeMonths: 36, bought: "2022-02-14", status: "repair", holder: "tm", location: "meet", warrantyUntil: "2024-02-14", maintenance: [ { date: "2026-05-12", what: "Не вмикається — діагностика, заміна лампи", cost: null, by: "сервіс-центр (в роботі)" } ] }, // — Ліцензії ПЗ — { id: "as-15", invNo: "УБП-ПЗ-0001", cat: "lic", name: "Autodesk AutoCAD (3 робочі місця)", model: "річна підписка", serial: "ключ 562-87654321", cost: 96000, lifeMonths: 0, bought: "2025-09-01", status: "active", holder: "ok", location: "constr", warrantyUntil: "2026-09-01", subscription: true, maintenance: [] }, { id: "as-16", invNo: "УБП-ПЗ-0002", cat: "lic", name: "ЛІРА-САПР 2024 PROFI", model: "безстрокова ліцензія", serial: "LR-2024-118-2233", cost: 48000, lifeMonths: 0, bought: "2024-03-12", status: "active", holder: "ap", location: "constr", warrantyUntil: "—", maintenance: [] }, { id: "as-17", invNo: "УБП-ПЗ-0003", cat: "lic", name: "АВК-5 (кошторисна програма)", model: "оновлення на рік", serial: "AVK-5-77120", cost: 18000, lifeMonths: 0, bought: "2026-01-15", status: "active", holder: "ok", location: "gip", warrantyUntil: "2027-01-15", subscription: true, maintenance: [] }, { id: "as-18", invNo: "УБП-ПЗ-0004", cat: "lic", name: "Microsoft 365 Business (10 ліцензій)", model: "річна підписка", serial: "тенант ukrbudproiekt.onmicrosoft", cost: 42000, lifeMonths: 0, bought: "2025-11-01", status: "active", holder: "ap", location: "server", warrantyUntil: "2026-11-01", subscription: true, maintenance: [] }, // — Вимірювальні прилади — { id: "as-19", invNo: "УБП-ВП-0001", cat: "dev", name: "Лазерний далекомір Leica DISTO D2", model: "до 100 м, Bluetooth", serial: "LD2-2305-4471", cost: 8500, lifeMonths: 48, bought: "2023-05-18", status: "active", holder: "ap", location: "field", warrantyUntil: "2025-05-18", maintenance: [] }, { id: "as-20", invNo: "УБП-ВП-0002", cat: "dev", name: "Нівелір оптичний Bosch GOL 26 D", model: "комплект зі штативом і рейкою", serial: "BGOL26-0822-188", cost: 12000, lifeMonths: 60, bought: "2022-08-09", status: "active", holder: "dl", location: "field", warrantyUntil: "2025-08-09", maintenance: [] }, { id: "as-21", invNo: "УБП-ВП-0003", cat: "dev", name: "Тахеометр Leica TS07 R500", model: "точність 2\", з ПЗ", serial: "TS07-2110-9920", cost: 320000, lifeMonths: 84, bought: "2021-10-25", status: "repair", holder: "dl", location: "field", warrantyUntil: "2024-10-25", maintenance: [ { date: "2026-05-08", what: "Збій компенсатора — повірка та юстування", cost: null, by: "Leica Geosystems (в роботі)" }, { date: "2024-09-30", what: "Щорічна метрологічна повірка", cost: 5600, by: "ДП «Укрметртестстандарт»" }, ] }, { id: "as-22", invNo: "УБП-ВП-0004", cat: "dev", name: "Тепловізор FLIR C5", model: "160×120, для обстежень", serial: "FC5-2403-3318", cost: 28000, lifeMonths: 48, bought: "2024-03-04", status: "active", holder: "tm", location: "field", warrantyUntil: "2026-03-04", maintenance: [] }, ]; window.DATA = window.DATA || {}; window.DATA.ASSETS = ASSETS; window.getAsset = (id) => ASSETS.find(a => a.id === id); // ============ АМОРТИЗАЦІЯ (прямолінійний метод) ============ // Повертає { monthly, accumulated, residual, wearPct, months } на дату SYS_DATE. function monthsBetween(fromISO, toISO) { const a = new Date(fromISO), b = new Date(toISO); let m = (b.getFullYear() - a.getFullYear()) * 12 + (b.getMonth() - a.getMonth()); if (b.getDate() < a.getDate()) m -= 1; return Math.max(0, m); } window.computeDepreciation = (asset) => { const cat = window.getAssetCategory(asset.cat); if (!cat.depreciable || !asset.lifeMonths) { return { depreciable: false, monthly: 0, accumulated: 0, residual: asset.cost, wearPct: 0, months: 0 }; } const months = Math.min(monthsBetween(asset.bought, window.SYS_DATE || "2026-05-29"), asset.lifeMonths); const monthly = asset.cost / asset.lifeMonths; const accumulated = Math.round(monthly * months); const residual = Math.max(0, asset.cost - accumulated); const wearPct = Math.round(accumulated / asset.cost * 100); return { depreciable: true, monthly: Math.round(monthly), accumulated, residual, wearPct, months }; }; // Наступний інвентарний номер за маскою для категорії window.nextInvNo = (catId) => { const cat = window.getAssetCategory(catId); const nums = ASSETS.filter(a => a.cat === catId) .map(a => parseInt(a.invNo.split("-").pop(), 10)) .filter(n => !isNaN(n)); const next = (nums.length ? Math.max(...nums) : 0) + 1; return `УБП-${cat.prefix}-${String(next).padStart(4, "0")}`; }; // ============ СЕСІЇ ІНВЕНТАРИЗАЦІЇ ============ // reconcile: для кожного майна — результат звірки. // match | wrong_location | not_found (нестача) | surplus (надлишок) const INVENTORY_SESSIONS = [ { id: "inv-2026-05", title: "Інвентаризація перед піврічним звітом", order: "Наказ №12 від 20.05.2026", dateStart: "2026-05-26", dateEnd: null, scope: "Основні засоби та вимірювальні прилади", status: "active", chair: "ok", commission: ["ok", "ap", "tm"], plannedIds: ["as-01","as-02","as-03","as-04","as-05","as-06","as-07","as-08","as-09","as-19","as-20","as-21","as-22"], reconcile: { "as-01": { result: "match" }, "as-02": { result: "match" }, "as-03": { result: "match" }, "as-04": { result: "match" }, "as-05": { result: "match" }, "as-08": { result: "match" }, "as-09": { result: "wrong_location", foundAt: "meet", note: "Перенесено в переговорну, облік не оновлено" }, "as-19": { result: "match" }, "as-22": { result: "match" }, // ще не відскановано: as-06, as-07, as-20, as-21 }, }, { id: "inv-2025-12", title: "Річна інвентаризація 2025", order: "Наказ №47 від 25.12.2025", dateStart: "2025-12-26", dateEnd: "2025-12-28", scope: "Усе майно компанії", status: "done", chair: "ok", commission: ["ok", "ap", "tm", "vs"], plannedIds: ASSETS.filter(a => a.status !== "written_off").map(a => a.id), reconcile: (() => { const r = {}; ASSETS.filter(a => a.status !== "written_off").forEach(a => { r[a.id] = { result: "match" }; }); r["as-11"] = { result: "not_found", note: "Монітор не виявлено на робочому місці. Складено акт, утримано з винної особи." }; r["as-14"] = { result: "wrong_location", foundAt: "storage", note: "Знайдено на складі замість переговорної — повернуто." }; return r; })(), actSigned: true, actNumber: "Акт інвентаризації №3 від 28.12.2025", }, ]; window.DATA.INVENTORY_SESSIONS = INVENTORY_SESSIONS; window.getInventorySession = (id) => INVENTORY_SESSIONS.find(s => s.id === id); const RECONCILE_RESULT = { match: { label: "Збіг", tone: "live" }, wrong_location: { label: "Інша локація", tone: "amber" }, not_found: { label: "Нестача", tone: "warn" }, surplus: { label: "Надлишок", tone: "blue" }, pending: { label: "Не перевірено", tone: "neutral" }, }; window.RECONCILE_RESULT = RECONCILE_RESULT; // Зведення по сесії: підрахунок результатів звірки window.inventoryStats = (session) => { const planned = session.plannedIds.length; let checked = 0, match = 0, issues = 0; session.plannedIds.forEach(id => { const r = session.reconcile[id]; if (r) { checked += 1; if (r.result === "match") match += 1; else issues += 1; } }); return { planned, checked, match, issues, pending: planned - checked }; };