buhanka-finance-app 1.63.0 → 1.65.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.html +24 -12
- package/package.json +1 -1
package/index.html
CHANGED
|
@@ -111,8 +111,11 @@ table.stick tr.subtotal .nm{background:var(--subbg)}
|
|
|
111
111
|
table.wide{border-collapse:separate;border-spacing:0;table-layout:fixed}
|
|
112
112
|
table.wide th,table.wide td{padding:5px 8px;white-space:nowrap;font-size:12.5px;border-bottom:1px solid var(--line)}
|
|
113
113
|
table.wide th.nm,table.wide td.nm{position:sticky;left:0;z-index:3;background:var(--panel);width:230px;min-width:230px;max-width:230px;overflow:hidden;text-overflow:ellipsis;border-right:1px solid var(--line2)}
|
|
114
|
-
table.wide thead th{position:sticky;top:0;z-index:
|
|
115
|
-
table.wide thead th.nm{z-index:
|
|
114
|
+
table.wide thead th{position:sticky;top:0;z-index:6;background:var(--panel2)}
|
|
115
|
+
table.wide thead th.nm{z-index:7;background:var(--panel2)}
|
|
116
|
+
/* ячейки тела получают свой слой ниже шапки — иначе поля ввода в Chrome всплывают поверх неё */
|
|
117
|
+
table.wide tbody td{position:relative;z-index:0}
|
|
118
|
+
table.wide tbody td.nm{position:sticky;z-index:3}
|
|
116
119
|
table.wide td.num,table.wide th.num{text-align:right;font-variant-numeric:tabular-nums}
|
|
117
120
|
table.wide tr.sec>td{font-weight:800;background:var(--subbg)}
|
|
118
121
|
table.wide tr.sec>td.nm{color:var(--accent);box-shadow:inset 3px 0 0 var(--accent)}
|
|
@@ -124,7 +127,10 @@ table.wide tr.acc>td{color:var(--muted);font-weight:400}
|
|
|
124
127
|
table.wide tr.bal>td{background:transparent;color:var(--text);font-weight:400}
|
|
125
128
|
table.wide tr.bal>td.nm{font-weight:700;color:var(--text)}
|
|
126
129
|
table.wide tr.bal.brd>td{border-top:1px solid var(--line2)}
|
|
127
|
-
table.wide col.plan
|
|
130
|
+
table.wide col.plan{background:rgba(232,163,61,.06)}
|
|
131
|
+
/* у шапки подсветка кладётся поверх непрозрачного фона, иначе строки просвечивают сквозь неё */
|
|
132
|
+
table.wide thead th.plan{background-color:var(--panel2);
|
|
133
|
+
background-image:linear-gradient(rgba(232,163,61,.06),rgba(232,163,61,.06))}
|
|
128
134
|
table.wide tr.sec>td.nm,table.wide tr.sub>td.nm{background:var(--subbg)}
|
|
129
135
|
table.wide tr.tot>td.nm{background-color:var(--panel);background-image:linear-gradient(var(--grandbg),var(--grandbg))}
|
|
130
136
|
table.wide tr.bal>td.nm,table.wide tr.val>td.nm,table.wide tr.acc>td.nm{background:var(--panel)}
|
|
@@ -301,7 +307,7 @@ tr.subtotal>td:first-child{color:var(--accent);box-shadow:inset 3px 0 0 var(--ac
|
|
|
301
307
|
|
|
302
308
|
<script>
|
|
303
309
|
/* ============================================================ БУХАНКА · Финансы v2 ============================================================ */
|
|
304
|
-
const APP_VERSION='9.
|
|
310
|
+
const APP_VERSION='9.8';
|
|
305
311
|
const SCHEMA=8; /* версия структуры данных; растёт при доработках */
|
|
306
312
|
const STORE_KEY='buhanka_finance_v9';/* НЕ МЕНЯТЬ НИКОГДА — иначе данные «слетят» при обновлении файла */
|
|
307
313
|
const LEGACY_KEYS=['buhanka_finance_v8','buhanka_finance_v7','buhanka_finance_v6','buhanka_finance_v5'];
|
|
@@ -1675,16 +1681,22 @@ function renderPoints(C){
|
|
|
1675
1681
|
const P=ST.ui.period; const useFact=periodLocked(P);
|
|
1676
1682
|
document.getElementById('pageSub').textContent=`${P} · ${useFact?'период закрыт — факт':'период открыт — бюджет'}`;
|
|
1677
1683
|
const struct=ST.structures.point; const comps={}; ST.points.forEach(p=>comps[p]=computePnL(p,P));
|
|
1678
|
-
const colw=130; const minw=240+(ST.points.length+1)*colw;
|
|
1684
|
+
const colw=130, pctw=64; const minw=240+(ST.points.length+1)*(colw+pctw);
|
|
1685
|
+
const revOf={}; ST.points.forEach(p=>{ const r=comps[p].find(x=>x.row.role==='value'&&x.row.sign===1);
|
|
1686
|
+
revOf[p]=r?(useFact?r.fact:r.budget):0; });
|
|
1687
|
+
const revTot=ST.points.reduce((s,p)=>s+revOf[p],0);
|
|
1688
|
+
const pctCell=(v,base)=>`<td class="num pctcell">${base?(v/base*100).toFixed(1).replace('.',',')+'%':'—'}</td>`;
|
|
1679
1689
|
let html=`<div class="panel"><div class="hd"><h3>Сравнение точек · ${P}</h3><div class="spacer"></div><span class="tag ${useFact?'lock':''}">${useFact?'значения: факт':'значения: бюджет'}</span></div><div class="bd" style="padding:0"><div class="tbl-wrap"><table class="pnl" style="table-layout:fixed;min-width:${minw}px">
|
|
1680
|
-
<colgroup><col style="width:240px">${ST.points.map(()=>`<col style="width:${colw}px">`).join('')}<col style="width:${colw+10}px"></colgroup>
|
|
1681
|
-
<thead><tr><th>Статья</th>${ST.points.map(p=>`<th class="num" style="white-space:normal">${p.replace('Скандинавский','Сканд.')}</th>`).join('')}<th class="num">Итого</th></tr></thead><tbody>`;
|
|
1690
|
+
<colgroup><col style="width:240px">${ST.points.map(()=>`<col style="width:${colw}px"><col style="width:${pctw}px">`).join('')}<col style="width:${colw+10}px"><col style="width:${pctw}px"></colgroup>
|
|
1691
|
+
<thead><tr><th>Статья</th>${ST.points.map(p=>`<th class="num" colspan="2" style="white-space:normal">${p.replace('Скандинавский','Сканд.')}</th>`).join('')}<th class="num" colspan="2">Итого</th></tr></thead><tbody>`;
|
|
1682
1692
|
struct.forEach((row,i)=>{
|
|
1683
|
-
|
|
1684
|
-
if(row.role==='
|
|
1693
|
+
const span=(ST.points.length+1)*2+1;
|
|
1694
|
+
if(row.role==='spacer'){html+=`<tr class="spacer"><td colspan="${span}"></td></tr>`;return;}
|
|
1695
|
+
if(row.role==='header'){html+=`<tr class="header"><td colspan="${span}" class="nmcell">${esc(row.name)}</td></tr>`;return;}
|
|
1685
1696
|
const cls=row.grand?'grand':row.role==='subtotal'?'subtotal':'value'; let tot=0,cells='';
|
|
1686
|
-
ST.points.forEach(p=>{const x=comps[p][i]; const v=x?(useFact?x.fact:x.budget):0; tot+=v;
|
|
1687
|
-
|
|
1697
|
+
ST.points.forEach(p=>{const x=comps[p][i]; const v=x?(useFact?x.fact:x.budget):0; tot+=v;
|
|
1698
|
+
cells+=`<td class="num">${v?fmt(v):'—'}</td>`+pctCell(v,revOf[p]);});
|
|
1699
|
+
html+=`<tr class="${cls}"><td class="nmcell">${esc(row.name)}</td>${cells}<td class="num">${tot?fmt(tot):'—'}</td>${pctCell(tot,revTot)}</tr>`;
|
|
1688
1700
|
});
|
|
1689
1701
|
html+=`</tbody></table></div></div></div>`;
|
|
1690
1702
|
// чеки и средний чек
|
|
@@ -1805,7 +1817,7 @@ function renderCF(C){
|
|
|
1805
1817
|
const num=v=>v?fmt(v):'—';
|
|
1806
1818
|
const neg=v=>v?'('+fmt(Math.abs(v))+')':'—';
|
|
1807
1819
|
const cell=(v,cls)=>`<td class="num ${cls||''}">${v}</td>`;
|
|
1808
|
-
/* out=true — строка расхода: в прогнозе показываем
|
|
1820
|
+
/* out=true — строка расхода: в прогнозе показываем в скобках, как и факт */
|
|
1809
1821
|
const planCell=(day,key,shown,out)=>{
|
|
1810
1822
|
if(day.actual) return `<td class="num">${shown}</td>`;
|
|
1811
1823
|
const cur=planVal(M.mo,day.d,key);
|