buhanka-finance-app 1.63.0 → 1.64.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.
Files changed (2) hide show
  1. package/index.html +19 -10
  2. 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:4;background:var(--panel2)}
115
- table.wide thead th.nm{z-index:5;background:var(--panel2)}
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)}
@@ -301,7 +304,7 @@ tr.subtotal>td:first-child{color:var(--accent);box-shadow:inset 3px 0 0 var(--ac
301
304
 
302
305
  <script>
303
306
  /* ============================================================ БУХАНКА · Финансы v2 ============================================================ */
304
- const APP_VERSION='9.6';
307
+ const APP_VERSION='9.7';
305
308
  const SCHEMA=8; /* версия структуры данных; растёт при доработках */
306
309
  const STORE_KEY='buhanka_finance_v9';/* НЕ МЕНЯТЬ НИКОГДА — иначе данные «слетят» при обновлении файла */
307
310
  const LEGACY_KEYS=['buhanka_finance_v8','buhanka_finance_v7','buhanka_finance_v6','buhanka_finance_v5'];
@@ -1675,16 +1678,22 @@ function renderPoints(C){
1675
1678
  const P=ST.ui.period; const useFact=periodLocked(P);
1676
1679
  document.getElementById('pageSub').textContent=`${P} · ${useFact?'период закрыт — факт':'период открыт — бюджет'}`;
1677
1680
  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;
1681
+ const colw=130, pctw=64; const minw=240+(ST.points.length+1)*(colw+pctw);
1682
+ const revOf={}; ST.points.forEach(p=>{ const r=comps[p].find(x=>x.row.role==='value'&&x.row.sign===1);
1683
+ revOf[p]=r?(useFact?r.fact:r.budget):0; });
1684
+ const revTot=ST.points.reduce((s,p)=>s+revOf[p],0);
1685
+ const pctCell=(v,base)=>`<td class="num pctcell">${base?(v/base*100).toFixed(1).replace('.',',')+'%':'—'}</td>`;
1679
1686
  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>`;
1687
+ <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>
1688
+ <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
1689
  struct.forEach((row,i)=>{
1683
- if(row.role==='spacer'){html+=`<tr class="spacer"><td colspan="${ST.points.length+2}"></td></tr>`;return;}
1684
- if(row.role==='header'){html+=`<tr class="header"><td colspan="${ST.points.length+2}" class="nmcell">${esc(row.name)}</td></tr>`;return;}
1690
+ const span=(ST.points.length+1)*2+1;
1691
+ if(row.role==='spacer'){html+=`<tr class="spacer"><td colspan="${span}"></td></tr>`;return;}
1692
+ if(row.role==='header'){html+=`<tr class="header"><td colspan="${span}" class="nmcell">${esc(row.name)}</td></tr>`;return;}
1685
1693
  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; cells+=`<td class="num">${v?fmt(v):'—'}</td>`;});
1687
- html+=`<tr class="${cls}"><td class="nmcell">${esc(row.name)}</td>${cells}<td class="num">${tot?fmt(tot):'—'}</td></tr>`;
1694
+ ST.points.forEach(p=>{const x=comps[p][i]; const v=x?(useFact?x.fact:x.budget):0; tot+=v;
1695
+ cells+=`<td class="num">${v?fmt(v):'—'}</td>`+pctCell(v,revOf[p]);});
1696
+ html+=`<tr class="${cls}"><td class="nmcell">${esc(row.name)}</td>${cells}<td class="num">${tot?fmt(tot):'—'}</td>${pctCell(tot,revTot)}</tr>`;
1688
1697
  });
1689
1698
  html+=`</tbody></table></div></div></div>`;
1690
1699
  // чеки и средний чек
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "buhanka-finance-app",
3
- "version": "1.63.0",
3
+ "version": "1.64.0",
4
4
  "description": "Buhanka bakery finance dashboard — single-file web app",
5
5
  "license": "MIT",
6
6
  "files": [