更新
This commit is contained in:
1 parent
5718a00e31
commit
1850ac640e
226 files changed
+37772
-12071
No files matched your search
@@ -0,0 +1,265 @@
|
||||
package controllers
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
erp "server/services/erp"
|
||||
)
|
||||
|
||||
// BackendErpFinanceController 往来账(应收/应付)、收付款与核销
|
||||
//
|
||||
// 往来账由单据生效时自动生成,不开放手工新增/修改,保证「业务单据 → 往来账 → 收付款」
|
||||
// 三段可追溯;收付款单可以手工开草稿,确认后按单核销(显式指定或按到期日 FIFO)。
|
||||
// 查询与核销口径统一在 erp_finance_core.go,与移动端 /api/erp/finance* 共用。
|
||||
type BackendErpFinanceController struct {
|
||||
BackendErpBaseController
|
||||
}
|
||||
|
||||
// BillList GET /backend/erp/finance/bill/list 往来账列表
|
||||
func (c *BackendErpFinanceController) BillList() {
|
||||
cl, err := c.claims()
|
||||
if c.denied(err) {
|
||||
return
|
||||
}
|
||||
page, pageSize := c.pageArgs()
|
||||
|
||||
f := erpBillFilter{
|
||||
BillType: strings.TrimSpace(c.GetString("bill_type")),
|
||||
PartnerID: erpUintParam(c.GetString("partner_id")),
|
||||
PartnerType: strings.TrimSpace(c.GetString("partner_type")),
|
||||
SourceDocID: erpUintParam(c.GetString("source_doc_id")),
|
||||
SettleState: strings.TrimSpace(c.GetString("settle_state")),
|
||||
Keyword: strings.TrimSpace(c.GetString("keyword")),
|
||||
DateFrom: strings.TrimSpace(c.GetString("date_from")),
|
||||
DateTo: strings.TrimSpace(c.GetString("date_to")),
|
||||
}
|
||||
list, total, summary, code, msg := erpBillListCore(erpNewActor(cl), f, page, pageSize)
|
||||
if msg != "" {
|
||||
c.fail(code, code, msg)
|
||||
return
|
||||
}
|
||||
c.ok(map[string]interface{}{
|
||||
"list": list, "total": total, "page": page, "pageSize": pageSize,
|
||||
"summary": summary,
|
||||
})
|
||||
}
|
||||
|
||||
// BillDetail GET /backend/erp/finance/bill/:id 往来账详情(含核销记录与原单据)
|
||||
func (c *BackendErpFinanceController) BillDetail() {
|
||||
cl, err := c.claims()
|
||||
if c.denied(err) {
|
||||
return
|
||||
}
|
||||
data, code, msg := erpBillDetailCore(erpNewActor(cl), c.pathID())
|
||||
if msg != "" {
|
||||
c.fail(code, code, msg)
|
||||
return
|
||||
}
|
||||
c.ok(data)
|
||||
}
|
||||
|
||||
// Aging GET /backend/erp/finance/aging 账龄分析(按未结余额分桶)
|
||||
func (c *BackendErpFinanceController) Aging() {
|
||||
cl, err := c.claims()
|
||||
if c.denied(err) {
|
||||
return
|
||||
}
|
||||
data, code, msg := erpAgingCore(erpNewActor(cl))
|
||||
if msg != "" {
|
||||
c.fail(code, code, msg)
|
||||
return
|
||||
}
|
||||
c.ok(data)
|
||||
}
|
||||
|
||||
// FundList GET /backend/erp/finance/fund/list 收付款单列表
|
||||
func (c *BackendErpFinanceController) FundList() {
|
||||
cl, err := c.claims()
|
||||
if c.denied(err) {
|
||||
return
|
||||
}
|
||||
page, pageSize := c.pageArgs()
|
||||
|
||||
f := erpFundFilter{
|
||||
FundType: strings.TrimSpace(c.GetString("fund_type")),
|
||||
Status: strings.TrimSpace(c.GetString("status")),
|
||||
PartnerID: erpUintParam(c.GetString("partner_id")),
|
||||
Keyword: strings.TrimSpace(c.GetString("keyword")),
|
||||
DateFrom: strings.TrimSpace(c.GetString("date_from")),
|
||||
DateTo: strings.TrimSpace(c.GetString("date_to")),
|
||||
}
|
||||
rows, total, code, msg := erpFundListCore(erpNewActor(cl), f, page, pageSize)
|
||||
if msg != "" {
|
||||
c.fail(code, code, msg)
|
||||
return
|
||||
}
|
||||
c.listOK(rows, total, page, pageSize)
|
||||
}
|
||||
|
||||
// FundDetail GET /backend/erp/finance/fund/:id
|
||||
func (c *BackendErpFinanceController) FundDetail() {
|
||||
cl, err := c.claims()
|
||||
if c.denied(err) {
|
||||
return
|
||||
}
|
||||
data, code, msg := erpFundDetailCore(erpNewActor(cl), c.pathID())
|
||||
if msg != "" {
|
||||
c.fail(code, code, msg)
|
||||
return
|
||||
}
|
||||
c.ok(data)
|
||||
}
|
||||
|
||||
type erpFundPayload struct {
|
||||
ID uint64 `json:"id"`
|
||||
FundType int8 `json:"fund_type"`
|
||||
PartnerID uint64 `json:"partner_id"`
|
||||
Amount float64 `json:"amount"`
|
||||
PayMethod string `json:"pay_method"`
|
||||
PayAccount string `json:"pay_account"`
|
||||
BizDate string `json:"biz_date"`
|
||||
Remark string `json:"remark"`
|
||||
}
|
||||
|
||||
// FundSave POST /backend/erp/finance/fund 新建/修改收付款草稿
|
||||
func (c *BackendErpFinanceController) FundSave() {
|
||||
cl, err := c.claims()
|
||||
if c.denied(err) {
|
||||
return
|
||||
}
|
||||
var p erpFundPayload
|
||||
if !c.bindJSON(&p) {
|
||||
return
|
||||
}
|
||||
id, fundNo, code, msg := erpFundSaveCore(erpNewActor(cl), p)
|
||||
if msg != "" {
|
||||
c.fail(code, code, msg)
|
||||
return
|
||||
}
|
||||
c.ok(map[string]interface{}{"id": id, "fund_no": fundNo})
|
||||
}
|
||||
|
||||
// FundConfirm POST /backend/erp/finance/fund/:id/confirm
|
||||
// 确认收付款并核销;body 可选 settles=[{partner_bill_id,amount}],不传则按到期日自动 FIFO。
|
||||
func (c *BackendErpFinanceController) FundConfirm() {
|
||||
cl, err := c.claims()
|
||||
if c.denied(err) {
|
||||
return
|
||||
}
|
||||
var body struct {
|
||||
Settles []erp.SettleItem `json:"settles"`
|
||||
}
|
||||
// 允许空 body(自动核销)
|
||||
_ = c.bindJSON(&body)
|
||||
code, msg := erpFundConfirmCore(erpNewActor(cl), c.pathID(), body.Settles)
|
||||
if msg != "" {
|
||||
c.fail(code, code, msg)
|
||||
return
|
||||
}
|
||||
c.ok(nil)
|
||||
}
|
||||
|
||||
// FundVoid POST /backend/erp/finance/fund/:id/void
|
||||
func (c *BackendErpFinanceController) FundVoid() {
|
||||
cl, err := c.claims()
|
||||
if c.denied(err) {
|
||||
return
|
||||
}
|
||||
code, msg := erpFundVoidCore(erpNewActor(cl), c.pathID())
|
||||
if msg != "" {
|
||||
c.fail(code, code, msg)
|
||||
return
|
||||
}
|
||||
c.ok(nil)
|
||||
}
|
||||
|
||||
// FundDelete DELETE /backend/erp/finance/fund/:id 仅草稿可删
|
||||
func (c *BackendErpFinanceController) FundDelete() {
|
||||
cl, err := c.claims()
|
||||
if c.denied(err) {
|
||||
return
|
||||
}
|
||||
code, msg := erpFundDeleteCore(erpNewActor(cl), c.pathID())
|
||||
if msg != "" {
|
||||
c.fail(code, code, msg)
|
||||
return
|
||||
}
|
||||
c.ok(nil)
|
||||
}
|
||||
|
||||
// FundOpenBills GET /backend/erp/finance/fund/openBills?fund_type=&partner_id=
|
||||
// 收款/付款时列出可核销的往来账,前端据此勾选。
|
||||
func (c *BackendErpFinanceController) FundOpenBills() {
|
||||
cl, err := c.claims()
|
||||
if c.denied(err) {
|
||||
return
|
||||
}
|
||||
ft, _ := erpInt8Query(c.GetString("fund_type"))
|
||||
list, code, msg := erpFundOpenBillsCore(erpNewActor(cl), ft, erpUintParam(c.GetString("partner_id")))
|
||||
if msg != "" {
|
||||
c.fail(code, code, msg)
|
||||
return
|
||||
}
|
||||
c.ok(map[string]interface{}{"list": list})
|
||||
}
|
||||
|
||||
// CashFlow GET /backend/erp/finance/cashflow 资金流水(含单据生成的往来账不在此列,只统计实际收付)
|
||||
func (c *BackendErpFinanceController) CashFlow() {
|
||||
cl, err := c.claims()
|
||||
if c.denied(err) {
|
||||
return
|
||||
}
|
||||
from := time.Now().AddDate(0, 0, -30)
|
||||
if d := strings.TrimSpace(c.GetString("date_from")); d != "" {
|
||||
if t, e := time.ParseInLocation("2006-01-02", d, time.Local); e == nil {
|
||||
from = t
|
||||
}
|
||||
}
|
||||
to := time.Now()
|
||||
if d := strings.TrimSpace(c.GetString("date_to")); d != "" {
|
||||
if t, e := time.ParseInLocation("2006-01-02", d, time.Local); e == nil {
|
||||
to = t
|
||||
}
|
||||
}
|
||||
data, code, msg := erpCashFlowCore(erpNewActor(cl), from, to)
|
||||
if msg != "" {
|
||||
c.fail(code, code, msg)
|
||||
return
|
||||
}
|
||||
c.ok(data)
|
||||
}
|
||||
|
||||
// PartnerSummary GET /backend/erp/finance/partner 往来单位对账汇总
|
||||
func (c *BackendErpFinanceController) PartnerSummary() {
|
||||
cl, err := c.claims()
|
||||
if c.denied(err) {
|
||||
return
|
||||
}
|
||||
data, code, msg := erpPartnerSummaryCore(erpNewActor(cl), strings.TrimSpace(c.GetString("partner_type")))
|
||||
if msg != "" {
|
||||
c.fail(code, code, msg)
|
||||
return
|
||||
}
|
||||
c.ok(data)
|
||||
}
|
||||
|
||||
func erpBillStatusLabel(s int8) string {
|
||||
switch s {
|
||||
case 1:
|
||||
return "部分核销"
|
||||
case 2:
|
||||
return "已结清"
|
||||
default:
|
||||
return "未核销"
|
||||
}
|
||||
}
|
||||
|
||||
func erpInt8Query(v string) (int8, bool) {
|
||||
n, err := strconv.Atoi(strings.TrimSpace(v))
|
||||
if err != nil {
|
||||
return 0, false
|
||||
}
|
||||
return int8(n), true
|
||||
}
|
||||
Reference in new issue
Block a user