buhanka-finance-app 1.4.0 → 1.6.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 +38 -26
- package/package.json +1 -1
package/index.html
CHANGED
|
@@ -107,6 +107,10 @@ table.wide tr.tot>td{font-weight:800;background:var(--grandbg);border-top:1px so
|
|
|
107
107
|
table.wide tr.sub>td{font-weight:700;background:var(--subbg)}
|
|
108
108
|
table.wide tr.val td.nm{padding-left:22px;color:var(--muted)}
|
|
109
109
|
table.wide tr.acc td.nm{padding-left:22px;color:var(--muted2);font-style:italic}
|
|
110
|
+
table.wide tr.acc>td{color:var(--text);font-weight:400}
|
|
111
|
+
table.wide tr.bal>td{background:transparent;color:var(--text);font-weight:400}
|
|
112
|
+
table.wide tr.bal>td.nm{font-weight:700;color:var(--text)}
|
|
113
|
+
table.wide tr.bal.brd>td{border-top:1px solid var(--line2)}
|
|
110
114
|
table.wide col.plan,table.wide th.plan{background:rgba(232,163,61,.06)}
|
|
111
115
|
table.wide input.p{background:transparent;border:1px solid transparent;text-align:right;width:100%;padding:2px 0;font-size:12.5px;font-variant-numeric:tabular-nums;color:var(--accent)}
|
|
112
116
|
table.wide input.p:hover{border-color:var(--line2)}
|
|
@@ -228,7 +232,7 @@ tr.subtotal>td:first-child{color:var(--accent);box-shadow:inset 3px 0 0 var(--ac
|
|
|
228
232
|
|
|
229
233
|
<script>
|
|
230
234
|
/* ============================================================ БУХАНКА · Финансы v2 ============================================================ */
|
|
231
|
-
const APP_VERSION='3.
|
|
235
|
+
const APP_VERSION='3.7';
|
|
232
236
|
const SCHEMA=3; /* версия структуры данных; растёт при доработках */
|
|
233
237
|
const STORE_KEY='buhanka_finance_v9';/* НЕ МЕНЯТЬ НИКОГДА — иначе данные «слетят» при обновлении файла */
|
|
234
238
|
const LEGACY_KEYS=['buhanka_finance_v8','buhanka_finance_v7','buhanka_finance_v6','buhanka_finance_v5'];
|
|
@@ -1187,7 +1191,7 @@ function renderCF(C){
|
|
|
1187
1191
|
|
|
1188
1192
|
/* ── 2. наличные по точкам ── */
|
|
1189
1193
|
const m=primaryMonth(), lk=isLocked(m);
|
|
1190
|
-
html+=`<div class="panel"><div class="hd"><h3>Наличные по точкам · ${m}</h3><div class="spacer"></div>
|
|
1194
|
+
html+=`<div class="panel"><div class="hd"><h3>Наличные по точкам и карты · ${m}</h3><div class="spacer"></div>
|
|
1191
1195
|
${lk?'<span class="tag lock">🔒 закрыт</span>':'<span class="muted small">факт — то, что реально в кассе точки</span>'}</div>
|
|
1192
1196
|
<div class="bd" style="padding:0"><div class="tbl-wrap"><table>
|
|
1193
1197
|
<thead><tr><th>Точка / счёт</th><th class="num" style="width:130px">На начало</th><th class="num">Приход нал.</th><th class="num">Расход нал.</th>
|
|
@@ -1205,31 +1209,39 @@ function renderCF(C){
|
|
|
1205
1209
|
<td class="num neg">${c.out?fmt(c.out):'—'}</td><td class="num" style="font-weight:600">${fmt(c.calc)}</td>
|
|
1206
1210
|
<td class="num"><input class="money" ${lk?'disabled':''} value="${fv!=null&&fv!==''?fmtNum(fv):''}" placeholder="—" style="width:120px" onchange="cashFactSet('${m}','${p}',this.value)"></td>
|
|
1207
1211
|
<td class="num ${diff==null?'muted':Math.abs(diff)<1?'pos':'neg'}">${diff==null?'—':(diff>0?'+':'')+fmt(diff)}</td></tr>`; });
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1212
|
+
/* итог по точкам */
|
|
1213
|
+
const tD_pt = nF ? tF-tCf : null;
|
|
1214
|
+
html+=`<tr class="subtotal"><td>Итого по точкам</td><td class="num">${fmt(tS)}</td><td class="num">${fmt(tI)}</td>
|
|
1215
|
+
<td class="num">${fmt(tO)}</td><td class="num">${fmt(tC)}</td><td class="num">${nF?fmt(tF):'—'}</td>
|
|
1216
|
+
<td class="num ${tD_pt==null?'':Math.abs(tD_pt)<1?'pos':'neg'}">${tD_pt==null?'—':(tD_pt>0?'+':'')+fmt(tD_pt)}</td></tr>`;
|
|
1217
|
+
|
|
1218
|
+
const mi2=MONTHS.indexOf(m);
|
|
1219
|
+
const accFlow=(a)=>{ let inc=0,out=0;
|
|
1220
|
+
(ST.operations||[]).filter(o=>o.month===m&&isCashOp(o)).forEach(o=>{ const d=accDelta(o,a.name); if(d>0)inc+=d; else out-=d; });
|
|
1221
|
+
return {open:accountBalance(a,mi2-1), close:accountBalance(a,mi2), inc, out}; };
|
|
1222
|
+
|
|
1223
|
+
/* контрольная строка: счёт «наличные» целиком должен совпасть с суммой по точкам */
|
|
1224
|
+
ST.accounts.filter(a=>accType(a)==='cash').forEach(a=>{ const f=accFlow(a); const d=f.close-tC;
|
|
1225
|
+
html+=`<tr><td class="muted">Счёт «${esc(a.name)}» — всего</td><td class="num muted">${fmt(f.open)}</td>
|
|
1226
|
+
<td class="num pos">${f.inc?fmt(f.inc):'—'}</td><td class="num neg">${f.out?fmt(f.out):'—'}</td>
|
|
1227
|
+
<td class="num" style="font-weight:600">${fmt(f.close)}</td><td class="num muted small">сверка с точками</td>
|
|
1228
|
+
<td class="num ${Math.abs(d)<1?'pos':'neg'}">${Math.abs(d)<1?'сходится':(d>0?'+':'')+fmt(d)}</td></tr>`; });
|
|
1229
|
+
|
|
1230
|
+
/* карты — отдельные счета, в кассу точек не входят */
|
|
1231
|
+
const cards=ST.accounts.filter(a=>accType(a)==='card');
|
|
1232
|
+
if(cards.length){
|
|
1233
|
+
html+=`<tr class="header"><td colspan="7" style="color:var(--muted2);font-size:11px;text-transform:uppercase;letter-spacing:.05em;padding-top:14px">Карты — отдельные счета</td></tr>`;
|
|
1234
|
+
cards.forEach(a=>{ const f=accFlow(a); const key='acc:'+a.name;
|
|
1235
|
+
const fv=(ST.cashFact[m]||{})[key]; const has=!(fv==null||fv==='');
|
|
1236
|
+
const diff=has?Number(fv)-f.close:null;
|
|
1237
|
+
html+=`<tr><td>${esc(a.name)}</td><td class="num muted">${fmt(f.open)}</td>
|
|
1238
|
+
<td class="num pos">${f.inc?fmt(f.inc):'—'}</td><td class="num neg">${f.out?fmt(f.out):'—'}</td>
|
|
1239
|
+
<td class="num" style="font-weight:600">${fmt(f.close)}</td>
|
|
1224
1240
|
<td class="num"><input class="money" ${lk?'disabled':''} value="${has?fmtNum(fv):''}" placeholder="—" style="width:120px" onchange="cashFactSet('${m}','${key}',this.value)"></td>
|
|
1225
1241
|
<td class="num ${diff==null?'muted':Math.abs(diff)<1?'pos':'neg'}">${diff==null?'—':(diff>0?'+':'')+fmt(diff)}</td></tr>`; });
|
|
1226
1242
|
}
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
<td class="num">${fmt(tC)}</td><td class="num">${nF?fmt(tF):'—'}</td>
|
|
1230
|
-
<td class="num ${tD==null?'':Math.abs(tD)<1?'pos':'neg'}">${tD==null?'—':(tD>0?'+':'')+fmt(tD)}</td></tr>
|
|
1231
|
-
</tbody></table></div></div>
|
|
1232
|
-
<p class="hint" style="padding:0 15px 12px;margin:0">По точкам: «На начало» в первом месяце учёта вводится вручную, дальше подставляется факт предыдущего месяца. Приход и расход — наличные операции и переводы, привязанные к точке. Ниже — наличные счета и карты целиком, по данным всех операций и переводов. Расхождение считается только там, где заполнен факт${nF?` (заполнено ${nF})`:''}.</p></div>`;
|
|
1243
|
+
html+=`</tbody></table></div></div>
|
|
1244
|
+
<p class="hint" style="padding:0 15px 12px;margin:0">Наличные — это деньги на точках: «На начало» в первом месяце учёта вводится вручную, дальше подставляется факт предыдущего месяца. Строка «Счёт "Наличные" — всего» сверяет остаток счёта с суммой по точкам: если сходится, вся касса разнесена по точкам. Карты — отдельные счета, в кассу точек не входят; перевод из кассы на карту уменьшает наличку точки.</p></div>`;
|
|
1233
1245
|
|
|
1234
1246
|
/* ── 3. деньги по дням в разрезе статей ── */
|
|
1235
1247
|
if(agg){ html+=`<div class="note">Таблица по дням доступна при выборе конкретного месяца — сейчас выбран период «${P}».</div>`; }
|
|
@@ -1275,11 +1287,11 @@ function renderCF(C){
|
|
|
1275
1287
|
(()=>{const t=sumOf(x=>x.inv[c]||0);return t>=0?num(t):neg(t);})()); });
|
|
1276
1288
|
}
|
|
1277
1289
|
|
|
1278
|
-
html+=row('
|
|
1290
|
+
html+=row('bal brd','Деньги на начало периода',M.days.map(d=>cell(fmt(d.openTot))).join(''),fmt(M.days.length?M.days[0].openTot:0));
|
|
1279
1291
|
M.accs.forEach(a=>{ html+=row('acc',esc(a),M.days.map(d=>cell(fmt(d.open[a]))).join(''),fmt(M.days.length?M.days[0].open[a]:0)); });
|
|
1280
1292
|
html+=row('tot','Денежный поток за период',M.days.map(d=>cell(d.net>=0?num(d.net):neg(d.net),d.net>=0?'pos':'neg')).join(''),
|
|
1281
1293
|
(()=>{const t=sumOf(x=>x.net);return `<b class="${t>=0?'pos':'neg'}">${t>=0?num(t):neg(t)}</b>`;})());
|
|
1282
|
-
html+=row('
|
|
1294
|
+
html+=row('bal','Деньги на конец периода',M.days.map(d=>cell(fmt(d.closeTot))).join(''),fmt(M.days.length?M.days[M.days.length-1].closeTot:0));
|
|
1283
1295
|
M.accs.forEach(a=>{ html+=row('acc',esc(a),M.days.map(d=>cell(fmt(d.close[a]))).join(''),fmt(M.days.length?M.days[M.days.length-1].close[a]:0)); });
|
|
1284
1296
|
|
|
1285
1297
|
html+=`</tbody></table></div></div>
|