update bill
This commit is contained in:
parent
cf47ee13db
commit
38f849d346
18
b/.mcp.json
Normal file
18
b/.mcp.json
Normal file
@ -0,0 +1,18 @@
|
||||
{
|
||||
"mcpServers": {
|
||||
"mysql": {
|
||||
"command": "npx",
|
||||
"args": ["-y", "mcp-mysql-multi-db"],
|
||||
"env": { // <-- 就是这里!env 是一个对象
|
||||
"MYSQL_HOST": "localhost",
|
||||
"MYSQL_PORT": "3306",
|
||||
"MYSQL_USER": "root",
|
||||
"MYSQL_PASSWORD": "lima2018",
|
||||
"MYSQL_DATABASE": "kprod",
|
||||
// 👇 要执行 INSERT/UPDATE 等写操作,就在这里添加下面两行
|
||||
// "ALLOW_DML": "true",
|
||||
// "ALLOW_DDL": "true"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -75,7 +75,6 @@ SALEMODE_LABEL = {
|
||||
}
|
||||
|
||||
INCOME_SUBJECTS = ('折扣收入', '底价收入')
|
||||
PARENT_SETTLE_SUBJECT = '分销商存放资金'
|
||||
SUPPLIER_SETTLE_PREFIX = '待结转'
|
||||
|
||||
_SALEMODE_SQL_OWN = """
|
||||
@ -194,9 +193,12 @@ async def _org_name(sor, orgid):
|
||||
|
||||
|
||||
async def _is_business_owner(sor, orgid):
|
||||
# 业主机构 parentid 为空串(非 NULL),org_type='0';两者都视为顶级机构。
|
||||
rows = await sor.sqlExe(
|
||||
"SELECT id FROM organization WHERE id=${id}$ AND parentid IS NULL AND del_flg='0'",
|
||||
{'id': orgid},
|
||||
"""SELECT id FROM organization
|
||||
WHERE id=${id}$ AND del_flg='0'
|
||||
AND ((parentid IS NULL OR parentid='') OR org_type=${owner_type}$)""",
|
||||
{'id': orgid, 'owner_type': OWNER_OGR},
|
||||
)
|
||||
return len(rows) > 0
|
||||
|
||||
@ -324,8 +326,12 @@ async def _protocol_snapshot(sor, accounting_orgid, customerid, providerid, prod
|
||||
}
|
||||
|
||||
|
||||
def _estimate_finance(catalog_amount, protocol, is_owner):
|
||||
"""未记账:估算本级利润与本级应付(不含代付费单独字段)。"""
|
||||
def _estimate_finance(catalog_amount, protocol):
|
||||
"""未记账:估算本级利润与本级应付(本级成本)。
|
||||
|
||||
与已记账口径一致,本级应付取「本级作为采购方(bid)的协议」即 own_*,
|
||||
对业主机构与分销商统一(own_discount 即上级给本级的折扣/底价)。
|
||||
"""
|
||||
catalog_amount = float(catalog_amount or 0)
|
||||
qty = protocol.get('quantity') or 1
|
||||
profit = None
|
||||
@ -335,29 +341,20 @@ def _estimate_finance(catalog_amount, protocol, is_owner):
|
||||
cust_mode = protocol.get('customer_salemode')
|
||||
own_disc = protocol.get('own_discount')
|
||||
cust_disc = protocol.get('customer_discount')
|
||||
reseller_disc = protocol.get('reseller_discount')
|
||||
|
||||
if own_mode == '0' or cust_mode == '0':
|
||||
if own_disc is not None and cust_disc is not None:
|
||||
profit = catalog_amount * (float(cust_disc) - float(own_disc))
|
||||
if is_owner:
|
||||
if own_disc is not None:
|
||||
settle_upstream = catalog_amount * float(own_disc)
|
||||
elif reseller_disc is not None:
|
||||
settle_upstream = catalog_amount * float(reseller_disc)
|
||||
if own_disc is not None:
|
||||
settle_upstream = catalog_amount * float(own_disc)
|
||||
|
||||
elif own_mode == '2' or cust_mode == '2':
|
||||
own_price = protocol.get('own_floor_unit_price')
|
||||
cust_price = protocol.get('customer_floor_unit_price')
|
||||
reseller_price = protocol.get('reseller_floor_unit_price')
|
||||
if own_price is not None and cust_price is not None:
|
||||
profit = (float(cust_price) - float(own_price)) * qty
|
||||
if is_owner and own_price is not None:
|
||||
if own_price is not None:
|
||||
settle_upstream = float(own_price) * qty
|
||||
elif not is_owner and reseller_price is not None:
|
||||
settle_upstream = float(reseller_price) * qty
|
||||
elif not is_owner and cust_price is not None:
|
||||
settle_upstream = float(cust_price) * qty
|
||||
|
||||
return {
|
||||
'profit_amount': _round_money(profit),
|
||||
@ -379,8 +376,13 @@ async def _bill_detail_rows(sor, billid):
|
||||
))
|
||||
|
||||
|
||||
async def _finance_from_bill_detail(sor, billid, accounting_orgid, is_owner, parent_orgid):
|
||||
"""已记账:从 bill_detail 取本级利润与本级应付。"""
|
||||
async def _finance_from_bill_detail(sor, billid, accounting_orgid):
|
||||
"""已记账:从 bill_detail 取本级利润与本级应付。
|
||||
|
||||
统一口径(业主机构与分销商一致):
|
||||
- profit_amount = 本级账本「折扣收入/底价收入」贷方合计
|
||||
- settle_upstream = 本级账本「待结转*销售收入」贷方合计(本级成本/本级应付上级)
|
||||
"""
|
||||
rows = await _bill_detail_rows(sor, billid)
|
||||
profit = 0.0
|
||||
settle_upstream = 0.0
|
||||
@ -400,24 +402,10 @@ async def _finance_from_bill_detail(sor, billid, accounting_orgid, is_owner, par
|
||||
subj = r['subjectname'] or ''
|
||||
direction = r['accounting_dir']
|
||||
|
||||
if book == accounting_orgid and subj in INCOME_SUBJECTS and direction == '贷':
|
||||
profit += amt
|
||||
|
||||
if is_owner:
|
||||
if (
|
||||
book == accounting_orgid
|
||||
and subj.startswith(SUPPLIER_SETTLE_PREFIX)
|
||||
and direction == '贷'
|
||||
):
|
||||
settle_upstream += amt
|
||||
else:
|
||||
if (
|
||||
parent_orgid
|
||||
and book == parent_orgid
|
||||
and subj == PARENT_SETTLE_SUBJECT
|
||||
and direction == '借'
|
||||
and r.get('participantid') == accounting_orgid
|
||||
):
|
||||
if book == accounting_orgid and direction == '贷':
|
||||
if subj in INCOME_SUBJECTS:
|
||||
profit += amt
|
||||
elif subj.startswith(SUPPLIER_SETTLE_PREFIX):
|
||||
settle_upstream += amt
|
||||
|
||||
return {
|
||||
@ -442,16 +430,13 @@ async def _build_report_row(sor, row, accounting_orgid, is_owner):
|
||||
protocol = await _protocol_snapshot(
|
||||
sor, accounting_orgid, customerid, providerid, productid, bill_date, quantity,
|
||||
)
|
||||
parent_orgid = protocol['parent_orgid']
|
||||
settle_meta = await _settle_upstream_meta(sor, accounting_orgid, providerid)
|
||||
|
||||
bill_state = _row_get(row, 'bill_state')
|
||||
if str(bill_state) == '1':
|
||||
amounts = await _finance_from_bill_detail(
|
||||
sor, bill_id, accounting_orgid, is_owner, parent_orgid,
|
||||
)
|
||||
amounts = await _finance_from_bill_detail(sor, bill_id, accounting_orgid)
|
||||
else:
|
||||
amounts = _estimate_finance(catalog_amount, protocol, is_owner)
|
||||
amounts = _estimate_finance(catalog_amount, protocol)
|
||||
amounts['bill_detail_legs'] = []
|
||||
|
||||
product_name = _row_get(row, 'product_name')
|
||||
@ -652,7 +637,7 @@ def _customer_segment(customer_parentid, accounting_orgid, reseller_id_set):
|
||||
return None
|
||||
|
||||
|
||||
async def _bill_finance_amounts(sor, row, accounting_orgid, is_owner, parent_orgid):
|
||||
async def _bill_finance_amounts(sor, row, accounting_orgid):
|
||||
"""单笔:销售额、本级利润、本级应付上级/供应商。"""
|
||||
sales = float(_row_get(row, 'customer_pay_amount') or 0)
|
||||
bill_id = _row_get(row, 'bill_id')
|
||||
@ -660,9 +645,7 @@ async def _bill_finance_amounts(sor, row, accounting_orgid, is_owner, parent_org
|
||||
quantity = int(_row_get(row, 'quantity') or 1)
|
||||
|
||||
if str(bill_state) == '1':
|
||||
fin = await _finance_from_bill_detail(
|
||||
sor, bill_id, accounting_orgid, is_owner, parent_orgid,
|
||||
)
|
||||
fin = await _finance_from_bill_detail(sor, bill_id, accounting_orgid)
|
||||
else:
|
||||
catalog = float(_row_get(row, 'catalog_amount') or 0)
|
||||
protocol = await _protocol_snapshot(
|
||||
@ -674,7 +657,7 @@ async def _bill_finance_amounts(sor, row, accounting_orgid, is_owner, parent_org
|
||||
_row_get(row, 'bill_date'),
|
||||
quantity,
|
||||
)
|
||||
fin = _estimate_finance(catalog, protocol, is_owner)
|
||||
fin = _estimate_finance(catalog, protocol)
|
||||
|
||||
profit = float(fin.get('profit_amount') or 0)
|
||||
settle = float(fin.get('settle_upstream_amount') or 0)
|
||||
@ -878,9 +861,9 @@ async def finance_order_report(ns=None):
|
||||
userid, start_date, end_date, customerid, productid, order_id, bill_state
|
||||
current_page (默认1), page_size (默认20, 最大100)
|
||||
|
||||
返回 finance.settle_upstream_*:
|
||||
- 本机构:应付供应商(待结转* 贷方,仅本机构账本)
|
||||
- 分销商:应付直接上级(上级账本「分销商存放资金」借方,participant=本级)
|
||||
返回 finance.settle_upstream_*(统一口径,取本级账本「待结转*销售收入」贷方):
|
||||
- 本机构:应付供应商
|
||||
- 分销商:应付直接上级机构(金额=本级成本,与本级账本待结转一致)
|
||||
"""
|
||||
ns = ns or {}
|
||||
accounting_orgid = ns.get('accounting_orgid')
|
||||
@ -1053,7 +1036,7 @@ async def finance_billing_overview(ns=None):
|
||||
口径(与订单明细接口一致):
|
||||
sales_total = 客户实付合计 bill.amount
|
||||
profit_total = 本级账本折扣收入+底价收入(bill_detail)或协议估算
|
||||
settle_upstream_total= 本机构→供应商待结转;分销→上级账本分销商存放资金借方
|
||||
settle_upstream_total= 本级账本「待结转*销售收入」贷方合计(本级成本/应付上级,业主与分销统一)
|
||||
|
||||
分段:
|
||||
direct_customers 直属客户(cust.parentid = accounting_orgid)
|
||||
@ -1084,7 +1067,6 @@ async def finance_billing_overview(ns=None):
|
||||
sor, accounting_orgid, include_sub,
|
||||
)
|
||||
is_owner = await _is_business_owner(sor, accounting_orgid)
|
||||
parent_orgid = await get_parent_orgid(sor, accounting_orgid)
|
||||
|
||||
conditions = ["b.del_flg = '0'", "o.del_flg = '0'", scope_sql]
|
||||
params = dict(scope_params)
|
||||
@ -1128,7 +1110,7 @@ async def finance_billing_overview(ns=None):
|
||||
continue
|
||||
try:
|
||||
sales, profit, settle, _src = await _bill_finance_amounts(
|
||||
sor, row, accounting_orgid, is_owner, parent_orgid,
|
||||
sor, row, accounting_orgid,
|
||||
)
|
||||
except Exception as exc:
|
||||
errors.append({
|
||||
@ -1230,11 +1212,10 @@ async def finance_billing_overview(ns=None):
|
||||
|
||||
# _report = params_kw.get('report') or params_kw.get('api') or 'order_list'
|
||||
_report = None
|
||||
if _report in ('overview', 'billing_overview', 'finance_billing_overview'):
|
||||
ret = await finance_billing_overview(params_kw)
|
||||
elif _report in ('detail', 'order_detail'):
|
||||
ret = await finance_order_report_detail(params_kw)
|
||||
else:
|
||||
ret = await finance_order_report(params_kw)
|
||||
# if _report in ('overview', 'billing_overview', 'finance_billing_overview'):
|
||||
# ret = await finance_billing_overview(params_kw)
|
||||
# elif _report in ('detail', 'order_detail'):
|
||||
# ret = await finance_order_report_detail(params_kw)
|
||||
# else:
|
||||
ret = await finance_order_report(params_kw)
|
||||
return ret
|
||||
return ret
|
||||
@ -75,7 +75,6 @@ SALEMODE_LABEL = {
|
||||
}
|
||||
|
||||
INCOME_SUBJECTS = ('折扣收入', '底价收入')
|
||||
PARENT_SETTLE_SUBJECT = '分销商存放资金'
|
||||
SUPPLIER_SETTLE_PREFIX = '待结转'
|
||||
|
||||
_SALEMODE_SQL_OWN = """
|
||||
@ -194,9 +193,12 @@ async def _org_name(sor, orgid):
|
||||
|
||||
|
||||
async def _is_business_owner(sor, orgid):
|
||||
# 业主机构 parentid 为空串(非 NULL),org_type='0';两者都视为顶级机构。
|
||||
rows = await sor.sqlExe(
|
||||
"SELECT id FROM organization WHERE id=${id}$ AND parentid IS NULL AND del_flg='0'",
|
||||
{'id': orgid},
|
||||
"""SELECT id FROM organization
|
||||
WHERE id=${id}$ AND del_flg='0'
|
||||
AND ((parentid IS NULL OR parentid='') OR org_type=${owner_type}$)""",
|
||||
{'id': orgid, 'owner_type': OWNER_OGR},
|
||||
)
|
||||
return len(rows) > 0
|
||||
|
||||
@ -324,8 +326,12 @@ async def _protocol_snapshot(sor, accounting_orgid, customerid, providerid, prod
|
||||
}
|
||||
|
||||
|
||||
def _estimate_finance(catalog_amount, protocol, is_owner):
|
||||
"""未记账:估算本级利润与本级应付(不含代付费单独字段)。"""
|
||||
def _estimate_finance(catalog_amount, protocol):
|
||||
"""未记账:估算本级利润与本级应付(本级成本)。
|
||||
|
||||
与已记账口径一致,本级应付取「本级作为采购方(bid)的协议」即 own_*,
|
||||
对业主机构与分销商统一(own_discount 即上级给本级的折扣/底价)。
|
||||
"""
|
||||
catalog_amount = float(catalog_amount or 0)
|
||||
qty = protocol.get('quantity') or 1
|
||||
profit = None
|
||||
@ -335,29 +341,20 @@ def _estimate_finance(catalog_amount, protocol, is_owner):
|
||||
cust_mode = protocol.get('customer_salemode')
|
||||
own_disc = protocol.get('own_discount')
|
||||
cust_disc = protocol.get('customer_discount')
|
||||
reseller_disc = protocol.get('reseller_discount')
|
||||
|
||||
if own_mode == '0' or cust_mode == '0':
|
||||
if own_disc is not None and cust_disc is not None:
|
||||
profit = catalog_amount * (float(cust_disc) - float(own_disc))
|
||||
if is_owner:
|
||||
if own_disc is not None:
|
||||
settle_upstream = catalog_amount * float(own_disc)
|
||||
elif reseller_disc is not None:
|
||||
settle_upstream = catalog_amount * float(reseller_disc)
|
||||
if own_disc is not None:
|
||||
settle_upstream = catalog_amount * float(own_disc)
|
||||
|
||||
elif own_mode == '2' or cust_mode == '2':
|
||||
own_price = protocol.get('own_floor_unit_price')
|
||||
cust_price = protocol.get('customer_floor_unit_price')
|
||||
reseller_price = protocol.get('reseller_floor_unit_price')
|
||||
if own_price is not None and cust_price is not None:
|
||||
profit = (float(cust_price) - float(own_price)) * qty
|
||||
if is_owner and own_price is not None:
|
||||
if own_price is not None:
|
||||
settle_upstream = float(own_price) * qty
|
||||
elif not is_owner and reseller_price is not None:
|
||||
settle_upstream = float(reseller_price) * qty
|
||||
elif not is_owner and cust_price is not None:
|
||||
settle_upstream = float(cust_price) * qty
|
||||
|
||||
return {
|
||||
'profit_amount': _round_money(profit),
|
||||
@ -379,8 +376,13 @@ async def _bill_detail_rows(sor, billid):
|
||||
))
|
||||
|
||||
|
||||
async def _finance_from_bill_detail(sor, billid, accounting_orgid, is_owner, parent_orgid):
|
||||
"""已记账:从 bill_detail 取本级利润与本级应付。"""
|
||||
async def _finance_from_bill_detail(sor, billid, accounting_orgid):
|
||||
"""已记账:从 bill_detail 取本级利润与本级应付。
|
||||
|
||||
统一口径(业主机构与分销商一致):
|
||||
- profit_amount = 本级账本「折扣收入/底价收入」贷方合计
|
||||
- settle_upstream = 本级账本「待结转*销售收入」贷方合计(本级成本/本级应付上级)
|
||||
"""
|
||||
rows = await _bill_detail_rows(sor, billid)
|
||||
profit = 0.0
|
||||
settle_upstream = 0.0
|
||||
@ -400,24 +402,10 @@ async def _finance_from_bill_detail(sor, billid, accounting_orgid, is_owner, par
|
||||
subj = r['subjectname'] or ''
|
||||
direction = r['accounting_dir']
|
||||
|
||||
if book == accounting_orgid and subj in INCOME_SUBJECTS and direction == '贷':
|
||||
profit += amt
|
||||
|
||||
if is_owner:
|
||||
if (
|
||||
book == accounting_orgid
|
||||
and subj.startswith(SUPPLIER_SETTLE_PREFIX)
|
||||
and direction == '贷'
|
||||
):
|
||||
settle_upstream += amt
|
||||
else:
|
||||
if (
|
||||
parent_orgid
|
||||
and book == parent_orgid
|
||||
and subj == PARENT_SETTLE_SUBJECT
|
||||
and direction == '借'
|
||||
and r.get('participantid') == accounting_orgid
|
||||
):
|
||||
if book == accounting_orgid and direction == '贷':
|
||||
if subj in INCOME_SUBJECTS:
|
||||
profit += amt
|
||||
elif subj.startswith(SUPPLIER_SETTLE_PREFIX):
|
||||
settle_upstream += amt
|
||||
|
||||
return {
|
||||
@ -442,16 +430,13 @@ async def _build_report_row(sor, row, accounting_orgid, is_owner):
|
||||
protocol = await _protocol_snapshot(
|
||||
sor, accounting_orgid, customerid, providerid, productid, bill_date, quantity,
|
||||
)
|
||||
parent_orgid = protocol['parent_orgid']
|
||||
settle_meta = await _settle_upstream_meta(sor, accounting_orgid, providerid)
|
||||
|
||||
bill_state = _row_get(row, 'bill_state')
|
||||
if str(bill_state) == '1':
|
||||
amounts = await _finance_from_bill_detail(
|
||||
sor, bill_id, accounting_orgid, is_owner, parent_orgid,
|
||||
)
|
||||
amounts = await _finance_from_bill_detail(sor, bill_id, accounting_orgid)
|
||||
else:
|
||||
amounts = _estimate_finance(catalog_amount, protocol, is_owner)
|
||||
amounts = _estimate_finance(catalog_amount, protocol)
|
||||
amounts['bill_detail_legs'] = []
|
||||
|
||||
product_name = _row_get(row, 'product_name')
|
||||
@ -652,7 +637,7 @@ def _customer_segment(customer_parentid, accounting_orgid, reseller_id_set):
|
||||
return None
|
||||
|
||||
|
||||
async def _bill_finance_amounts(sor, row, accounting_orgid, is_owner, parent_orgid):
|
||||
async def _bill_finance_amounts(sor, row, accounting_orgid):
|
||||
"""单笔:销售额、本级利润、本级应付上级/供应商。"""
|
||||
sales = float(_row_get(row, 'customer_pay_amount') or 0)
|
||||
bill_id = _row_get(row, 'bill_id')
|
||||
@ -660,9 +645,7 @@ async def _bill_finance_amounts(sor, row, accounting_orgid, is_owner, parent_org
|
||||
quantity = int(_row_get(row, 'quantity') or 1)
|
||||
|
||||
if str(bill_state) == '1':
|
||||
fin = await _finance_from_bill_detail(
|
||||
sor, bill_id, accounting_orgid, is_owner, parent_orgid,
|
||||
)
|
||||
fin = await _finance_from_bill_detail(sor, bill_id, accounting_orgid)
|
||||
else:
|
||||
catalog = float(_row_get(row, 'catalog_amount') or 0)
|
||||
protocol = await _protocol_snapshot(
|
||||
@ -674,7 +657,7 @@ async def _bill_finance_amounts(sor, row, accounting_orgid, is_owner, parent_org
|
||||
_row_get(row, 'bill_date'),
|
||||
quantity,
|
||||
)
|
||||
fin = _estimate_finance(catalog, protocol, is_owner)
|
||||
fin = _estimate_finance(catalog, protocol)
|
||||
|
||||
profit = float(fin.get('profit_amount') or 0)
|
||||
settle = float(fin.get('settle_upstream_amount') or 0)
|
||||
@ -878,9 +861,9 @@ async def finance_order_report(ns=None):
|
||||
userid, start_date, end_date, customerid, productid, order_id, bill_state
|
||||
current_page (默认1), page_size (默认20, 最大100)
|
||||
|
||||
返回 finance.settle_upstream_*:
|
||||
- 本机构:应付供应商(待结转* 贷方,仅本机构账本)
|
||||
- 分销商:应付直接上级(上级账本「分销商存放资金」借方,participant=本级)
|
||||
返回 finance.settle_upstream_*(统一口径,取本级账本「待结转*销售收入」贷方):
|
||||
- 本机构:应付供应商
|
||||
- 分销商:应付直接上级机构(金额=本级成本,与本级账本待结转一致)
|
||||
"""
|
||||
ns = ns or {}
|
||||
accounting_orgid = ns.get('accounting_orgid')
|
||||
@ -1053,7 +1036,7 @@ async def finance_billing_overview(ns=None):
|
||||
口径(与订单明细接口一致):
|
||||
sales_total = 客户实付合计 bill.amount
|
||||
profit_total = 本级账本折扣收入+底价收入(bill_detail)或协议估算
|
||||
settle_upstream_total= 本机构→供应商待结转;分销→上级账本分销商存放资金借方
|
||||
settle_upstream_total= 本级账本「待结转*销售收入」贷方合计(本级成本/应付上级,业主与分销统一)
|
||||
|
||||
分段:
|
||||
direct_customers 直属客户(cust.parentid = accounting_orgid)
|
||||
@ -1084,7 +1067,6 @@ async def finance_billing_overview(ns=None):
|
||||
sor, accounting_orgid, include_sub,
|
||||
)
|
||||
is_owner = await _is_business_owner(sor, accounting_orgid)
|
||||
parent_orgid = await get_parent_orgid(sor, accounting_orgid)
|
||||
|
||||
conditions = ["b.del_flg = '0'", "o.del_flg = '0'", scope_sql]
|
||||
params = dict(scope_params)
|
||||
@ -1128,7 +1110,7 @@ async def finance_billing_overview(ns=None):
|
||||
continue
|
||||
try:
|
||||
sales, profit, settle, _src = await _bill_finance_amounts(
|
||||
sor, row, accounting_orgid, is_owner, parent_orgid,
|
||||
sor, row, accounting_orgid,
|
||||
)
|
||||
except Exception as exc:
|
||||
errors.append({
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user