Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6853b755b8 | ||
|
|
76da3a2106 |
@@ -331,6 +331,7 @@ def bootstrap():
|
||||
def t_expense_sum(m_range):
|
||||
total = 0
|
||||
for r in t_expense:
|
||||
if (r.get("status") or "") == "暂不计入": continue
|
||||
m = (r.get("expense_month") or "").strip()
|
||||
if not m or "-" not in m: continue
|
||||
try:
|
||||
@@ -358,6 +359,27 @@ def bootstrap():
|
||||
all_metrics[-1]["cashflow_month"] = all_metrics[-1]["payment_month"] - all_metrics[-1]["paid_month"]
|
||||
all_metrics[-1]["cashflow_prev_q"] = all_metrics[-1]["payment_prev_q"] - all_metrics[-1]["paid_prev_q"]
|
||||
all_metrics[-1]["cashflow_prev_month"] = all_metrics[-1]["payment_prev_month"] - all_metrics[-1]["paid_prev_month"]
|
||||
def t_expense_paid_sum(m_range):
|
||||
total = 0
|
||||
for r in t_expense:
|
||||
if (r.get("status") or "") == "暂不计入": continue
|
||||
m = (r.get("expense_month") or "").strip()
|
||||
if not m or "-" not in m: continue
|
||||
try:
|
||||
if int(m.split("-")[1]) in m_range:
|
||||
total += float(r.get("incurred_amount") or 0)
|
||||
except: pass
|
||||
return total
|
||||
all_metrics[-1]["expense_paid_annual"] = t_expense_paid_sum(range(1, 13))
|
||||
all_metrics[-1]["expense_paid_q2"] = t_expense_paid_sum(_q_range)
|
||||
all_metrics[-1]["expense_paid_month"] = t_expense_paid_sum([_now_month])
|
||||
all_metrics[-1]["expense_paid_prev_q"] = t_expense_paid_sum(_prev_q_range)
|
||||
all_metrics[-1]["expense_paid_prev_month"] = t_expense_paid_sum([_prev_month]) if _prev_month else 0
|
||||
all_metrics[-1]["dept_cf_annual"] = all_metrics[-1]["cashflow_annual"] - all_metrics[-1]["expense_paid_annual"]
|
||||
all_metrics[-1]["dept_cf_q2"] = all_metrics[-1]["cashflow_q2"] - all_metrics[-1]["expense_paid_q2"]
|
||||
all_metrics[-1]["dept_cf_month"] = all_metrics[-1]["cashflow_month"] - all_metrics[-1]["expense_paid_month"]
|
||||
all_metrics[-1]["dept_cf_prev_q"] = all_metrics[-1]["cashflow_prev_q"] - all_metrics[-1]["expense_paid_prev_q"]
|
||||
all_metrics[-1]["dept_cf_prev_month"] = all_metrics[-1]["cashflow_prev_month"] - all_metrics[-1]["expense_paid_prev_month"]
|
||||
all_metrics[-1]["profit_annual"] = all_metrics[-1]["gross_annual"] - all_metrics[-1]["proj_expense_annual"]
|
||||
all_metrics[-1]["profit_q2"] = all_metrics[-1]["gross_q2"] - all_metrics[-1]["proj_expense_q2"]
|
||||
all_metrics[-1]["profit_month"] = all_metrics[-1]["monthly_net_profit"] - all_metrics[-1]["proj_expense_month"]
|
||||
@@ -366,7 +388,7 @@ def bootstrap():
|
||||
all_monthly.append(monthly_finance(conn, t))
|
||||
all_recent.extend(rows(conn, "SELECT * FROM follow_up_records WHERE tenant=? ORDER BY id DESC LIMIT 4", [t]))
|
||||
agg = {}
|
||||
for key in ["total_projects","total_proposals","total_products","upcoming_products","signed_amount","signed_annual","signed_q2","signed_month","signed_prev_q","signed_prev_month","revenue_annual","revenue_q2","monthly_revenue","revenue_prev_q","revenue_prev_month","gross_annual","gross_q2","monthly_net_profit","gross_prev_q","gross_prev_month","payment_annual","payment_q2","payment_month","payment_prev_q","payment_prev_month","cost_annual","cost_q2","cost_month","cost_prev_q","cost_prev_month","expense_annual","expense_q2","expense_month","expense_prev_q","expense_prev_month","paid_annual","paid_q2","paid_month","paid_prev_q","paid_prev_month","cashflow_annual","cashflow_q2","cashflow_month","cashflow_prev_q","cashflow_prev_month","profit_annual","profit_q2","profit_month","profit_prev_q","profit_prev_month","proj_expense_annual","proj_expense_q2","proj_expense_month","proj_expense_prev_q","proj_expense_prev_month"]:
|
||||
for key in ["total_projects","total_proposals","total_products","upcoming_products","signed_amount","signed_annual","signed_q2","signed_month","signed_prev_q","signed_prev_month","revenue_annual","revenue_q2","monthly_revenue","revenue_prev_q","revenue_prev_month","gross_annual","gross_q2","monthly_net_profit","gross_prev_q","gross_prev_month","payment_annual","payment_q2","payment_month","payment_prev_q","payment_prev_month","cost_annual","cost_q2","cost_month","cost_prev_q","cost_prev_month","expense_annual","expense_q2","expense_month","expense_prev_q","expense_prev_month","paid_annual","paid_q2","paid_month","paid_prev_q","paid_prev_month","cashflow_annual","cashflow_q2","cashflow_month","cashflow_prev_q","cashflow_prev_month","expense_paid_annual","expense_paid_q2","expense_paid_month","expense_paid_prev_q","expense_paid_prev_month","dept_cf_annual","dept_cf_q2","dept_cf_month","dept_cf_prev_q","dept_cf_prev_month","profit_annual","profit_q2","profit_month","profit_prev_q","profit_prev_month","proj_expense_annual","proj_expense_q2","proj_expense_month","proj_expense_prev_q","proj_expense_prev_month"]:
|
||||
agg[key] = sum(m.get(key, 0) for m in all_metrics)
|
||||
merged_monthly = []
|
||||
for i in range(12):
|
||||
@@ -459,6 +481,7 @@ def bootstrap():
|
||||
def expense_sum(month_range):
|
||||
total = 0
|
||||
for r in expense:
|
||||
if (r.get("status") or "") == "暂不计入": continue
|
||||
m = (r.get("expense_month") or "").strip()
|
||||
if not m or "-" not in m: continue
|
||||
try:
|
||||
@@ -471,6 +494,22 @@ def bootstrap():
|
||||
expense_month_val = expense_sum([_now_month])
|
||||
expense_prev_q = expense_sum(_prev_q_range)
|
||||
expense_prev_month = expense_sum([_prev_month]) if _prev_month else 0
|
||||
def expense_paid_sum(month_range):
|
||||
total = 0
|
||||
for r in expense:
|
||||
if (r.get("status") or "") == "暂不计入": continue
|
||||
m = (r.get("expense_month") or "").strip()
|
||||
if not m or "-" not in m: continue
|
||||
try:
|
||||
if int(m.split("-")[1]) in month_range:
|
||||
total += float(r.get("incurred_amount") or 0)
|
||||
except: pass
|
||||
return total
|
||||
expense_paid_annual = expense_paid_sum(range(1, 13))
|
||||
expense_paid_q2 = expense_paid_sum(_q_range)
|
||||
expense_paid_month = expense_paid_sum([_now_month])
|
||||
expense_paid_prev_q = expense_paid_sum(_prev_q_range)
|
||||
expense_paid_prev_month = expense_paid_sum([_prev_month]) if _prev_month else 0
|
||||
paid_annual = sum_expense("paid", range(1, 13))
|
||||
paid_q2 = sum_expense("paid", _q_range)
|
||||
paid_month = sum_expense("paid", [_now_month])
|
||||
@@ -486,6 +525,11 @@ def bootstrap():
|
||||
cashflow_month = payment_month - paid_month
|
||||
cashflow_prev_q = payment_prev_q - paid_prev_q
|
||||
cashflow_prev_month = payment_prev_month - paid_prev_month
|
||||
dept_cf_annual = cashflow_annual - expense_paid_annual
|
||||
dept_cf_q2 = cashflow_q2 - expense_paid_q2
|
||||
dept_cf_month = cashflow_month - expense_paid_month
|
||||
dept_cf_prev_q = cashflow_prev_q - expense_paid_prev_q
|
||||
dept_cf_prev_month = cashflow_prev_month - expense_paid_prev_month
|
||||
profit_annual = gross_annual - proj_expense_annual
|
||||
profit_q2 = gross_q2 - proj_expense_q2
|
||||
profit_month = gross_month - proj_expense_month
|
||||
@@ -557,6 +601,16 @@ def bootstrap():
|
||||
"cashflow_month": cashflow_month,
|
||||
"cashflow_prev_q": cashflow_prev_q,
|
||||
"cashflow_prev_month": cashflow_prev_month,
|
||||
"expense_paid_annual": expense_paid_annual,
|
||||
"expense_paid_q2": expense_paid_q2,
|
||||
"expense_paid_month": expense_paid_month,
|
||||
"expense_paid_prev_q": expense_paid_prev_q,
|
||||
"expense_paid_prev_month": expense_paid_prev_month,
|
||||
"dept_cf_annual": dept_cf_annual,
|
||||
"dept_cf_q2": dept_cf_q2,
|
||||
"dept_cf_month": dept_cf_month,
|
||||
"dept_cf_prev_q": dept_cf_prev_q,
|
||||
"dept_cf_prev_month": dept_cf_prev_month,
|
||||
"profit_annual": profit_annual,
|
||||
"profit_q2": profit_q2,
|
||||
"profit_month": profit_month,
|
||||
|
||||
@@ -126,7 +126,7 @@ function renderHome() {
|
||||
${card(`<h3 class="text-sm font-bold text-slate-700 mb-3">部门经营情况</h3><div class="overflow-x-auto"><table class="w-full text-sm"><thead><tr class="border-b border-slate-200"><th class="py-2 text-left text-slate-500">指标</th><th class="py-2 text-right font-semibold text-slate-700">年度累计</th><th class="py-2 text-right font-semibold text-slate-700">上季度累计</th><th class="py-2 text-right font-semibold text-slate-700">上月累计</th><th class="py-2 text-right font-semibold text-slate-700">本季度累计</th><th class="py-2 text-right font-semibold text-slate-400">季环比</th><th class="py-2 text-right font-semibold text-slate-700">本月累计</th><th class="py-2 text-right font-semibold text-slate-400">月环比</th></tr></thead><tbody>
|
||||
${(() => {
|
||||
var d = [
|
||||
['部门毛利', [m.profit_annual||0, m.profit_q2||0, m.profit_month||0, m.profit_prev_q||0, m.profit_prev_month||0],
|
||||
['项目毛利', [m.profit_annual||0, m.profit_q2||0, m.profit_month||0, m.profit_prev_q||0, m.profit_prev_month||0],
|
||||
[m.profit_q2||0,m.profit_prev_q||0], [m.profit_month||0,m.profit_prev_month||0]],
|
||||
['部门费用', [m.expense_annual||0, m.expense_q2||0, (m.expense_month||0), m.expense_prev_q||0, m.expense_prev_month||0],
|
||||
[m.expense_q2||0,m.expense_prev_q||0], [(m.expense_month||0),m.expense_prev_month||0]],
|
||||
@@ -137,11 +137,17 @@ function renderHome() {
|
||||
(m.profit_q2||0)-(m.expense_q2||0), (m.profit_prev_q||0)-(m.expense_prev_q||0)
|
||||
], [
|
||||
(m.profit_month||0)-(m.expense_month||0), (m.profit_prev_month||0)-(m.expense_prev_month||0)
|
||||
]]
|
||||
]],
|
||||
['项目现金流', [m.cashflow_annual||0, m.cashflow_q2||0, m.cashflow_month||0, m.cashflow_prev_q||0, m.cashflow_prev_month||0],
|
||||
[m.cashflow_q2||0,m.cashflow_prev_q||0], [m.cashflow_month||0,m.cashflow_prev_month||0]],
|
||||
['部门费用(已付)', [m.expense_paid_annual||0, m.expense_paid_q2||0, m.expense_paid_month||0, m.expense_paid_prev_q||0, m.expense_paid_prev_month||0],
|
||||
[m.expense_paid_q2||0,m.expense_paid_prev_q||0], [m.expense_paid_month||0,m.expense_paid_prev_month||0]],
|
||||
['部门现金流', [m.dept_cf_annual||0, m.dept_cf_q2||0, m.dept_cf_month||0, m.dept_cf_prev_q||0, m.dept_cf_prev_month||0],
|
||||
[m.dept_cf_q2||0,m.dept_cf_prev_q||0], [m.dept_cf_month||0,m.dept_cf_prev_month||0]]
|
||||
];
|
||||
var h = '';
|
||||
var netCls = function(di, raw) { return di === 2 ? (raw >= 0 ? 'text-green-600' : 'text-red-600') : 'text-slate-800'; };
|
||||
for (var di = 0; di < 3; di++) {
|
||||
var netCls = function(di, raw) { if (di === 2 || di === 5) return raw >= 0 ? 'text-green-600' : 'text-red-600'; if (di === 3) return raw >= 0 ? 'text-green-600' : 'text-red-600'; return 'text-slate-800'; };
|
||||
for (var di = 0; di < 6; di++) {
|
||||
var r = d[di];
|
||||
h += '<tr class="border-b border-slate-100 last:border-0"><td class="py-2 text-left font-semibold text-slate-700">' + r[0] + '</td>' +
|
||||
'<td class="py-2 text-right font-semibold ' + netCls(di, r[1][0]) + '">' + moneyInt(r[1][0]) + '</td>' +
|
||||
|
||||
@@ -76,7 +76,7 @@
|
||||
<header class="topbar border-b border-slate-200 bg-white px-8 py-5">
|
||||
<div class="flex items-center gap-3 w-full">
|
||||
<div class="flex-1">
|
||||
<p class="eyebrow text-xs font-semibold uppercase tracking-[0.18em] text-blue-700">OPC Manager <span class="ml-2 text-xs font-normal text-slate-400 tracking-normal">v1.0.0.6</span></p>
|
||||
<p class="eyebrow text-xs font-semibold uppercase tracking-[0.18em] text-blue-700">OPC Manager <span class="ml-2 text-xs font-normal text-slate-400 tracking-normal">v1.0.0.8</span></p>
|
||||
<div class="flex items-center gap-4 mt-1">
|
||||
<h1 class="text-2xl font-semibold" id="workspaceTitle">科普 OPC 工作台</h1>
|
||||
<div class="hidden sm:flex items-center gap-1.5 bg-gradient-to-r from-blue-50 to-indigo-50 border border-blue-100 rounded-full px-4 py-1.5">
|
||||
|
||||
Reference in New Issue
Block a user