Кабинет: операции по счетам депо и доходы с удержанным налогом из учётной системы
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -221,6 +221,34 @@ type portfolioResp struct {
|
||||
Priced int `json:"priced"`
|
||||
}
|
||||
|
||||
// operationRow — движение по счёту депо.
|
||||
type operationRow struct {
|
||||
Date string `json:"date"`
|
||||
DoneAt string `json:"done_at"`
|
||||
Kind string `json:"kind"`
|
||||
Number string `json:"number"`
|
||||
Account string `json:"account"`
|
||||
ISIN string `json:"isin"`
|
||||
Security string `json:"security"`
|
||||
Quantity float64 `json:"quantity"`
|
||||
State string `json:"state"`
|
||||
Note string `json:"note"`
|
||||
}
|
||||
|
||||
// incomeRow — выплата дохода.
|
||||
type incomeRow struct {
|
||||
Date string `json:"date"`
|
||||
Kind string `json:"kind"`
|
||||
ISIN string `json:"isin"`
|
||||
Security string `json:"security"`
|
||||
Quantity float64 `json:"quantity"`
|
||||
Accrued float64 `json:"accrued"`
|
||||
Tax float64 `json:"tax"`
|
||||
Paid float64 `json:"paid"`
|
||||
State string `json:"state"`
|
||||
Account string `json:"account"`
|
||||
}
|
||||
|
||||
// securityCard — карточка бумаги из ядра.
|
||||
type securityCard struct {
|
||||
ISIN string `json:"isin"`
|
||||
@@ -444,6 +472,69 @@ func (s *Server) Handler() http.Handler {
|
||||
s.render(w, r, "security", map[string]any{"Nav": "p", "S": out.Security, "ISIN": isin})
|
||||
})
|
||||
|
||||
// Операции по счетам депо
|
||||
mux.HandleFunc("/operations", func(w http.ResponseWriter, r *http.Request) {
|
||||
sess := sessionW(w, r)
|
||||
if sess == "" {
|
||||
http.Redirect(w, r, "/login", http.StatusSeeOther)
|
||||
return
|
||||
}
|
||||
from, to := r.URL.Query().Get("from"), r.URL.Query().Get("to")
|
||||
if from == "" {
|
||||
from = time.Now().AddDate(-1, 0, 0).Format("2006-01-02")
|
||||
}
|
||||
if to == "" {
|
||||
to = time.Now().Format("2006-01-02")
|
||||
}
|
||||
var out struct {
|
||||
Operations []operationRow `json:"operations"`
|
||||
}
|
||||
path := "/api/lk/operations?from=" + url.QueryEscape(from) + "&to=" + url.QueryEscape(to)
|
||||
if err := bj.call(r.Context(), http.MethodGet, path, sess, nil, &out); err != nil {
|
||||
s.render(w, r, "operations", map[string]any{"Nav": "o", "Error": err.Error(), "From": from, "To": to})
|
||||
return
|
||||
}
|
||||
var in, outq int
|
||||
for _, o := range out.Operations {
|
||||
if o.Quantity < 0 {
|
||||
outq++
|
||||
} else {
|
||||
in++
|
||||
}
|
||||
}
|
||||
s.render(w, r, "operations", map[string]any{"Nav": "o", "Operations": out.Operations,
|
||||
"From": from, "To": to, "Total": len(out.Operations), "In": in, "Out": outq})
|
||||
})
|
||||
|
||||
// Доходы и налоги
|
||||
mux.HandleFunc("/income", func(w http.ResponseWriter, r *http.Request) {
|
||||
sess := sessionW(w, r)
|
||||
if sess == "" {
|
||||
http.Redirect(w, r, "/login", http.StatusSeeOther)
|
||||
return
|
||||
}
|
||||
from, to := r.URL.Query().Get("from"), r.URL.Query().Get("to")
|
||||
if from == "" {
|
||||
from = time.Now().Format("2006") + "-01-01"
|
||||
}
|
||||
if to == "" {
|
||||
to = time.Now().Format("2006-01-02")
|
||||
}
|
||||
var out struct {
|
||||
Income []incomeRow `json:"income"`
|
||||
Accrued float64 `json:"accrued"`
|
||||
Paid float64 `json:"paid"`
|
||||
Tax float64 `json:"tax"`
|
||||
}
|
||||
path := "/api/lk/income?from=" + url.QueryEscape(from) + "&to=" + url.QueryEscape(to)
|
||||
if err := bj.call(r.Context(), http.MethodGet, path, sess, nil, &out); err != nil {
|
||||
s.render(w, r, "income", map[string]any{"Nav": "i", "Error": err.Error(), "From": from, "To": to})
|
||||
return
|
||||
}
|
||||
s.render(w, r, "income", map[string]any{"Nav": "i", "Income": out.Income, "From": from, "To": to,
|
||||
"Accrued": out.Accrued, "Paid": out.Paid, "Tax": out.Tax})
|
||||
})
|
||||
|
||||
// Профиль: договор, счета депо, доступ
|
||||
mux.HandleFunc("/profile", func(w http.ResponseWriter, r *http.Request) {
|
||||
sess := sessionW(w, r)
|
||||
|
||||
Reference in New Issue
Block a user