update bill report
This commit is contained in:
parent
38f849d346
commit
5a6524ffa5
@ -115,6 +115,15 @@ def _round_money(v):
|
|||||||
return round(float(v), 2)
|
return round(float(v), 2)
|
||||||
|
|
||||||
|
|
||||||
|
def _is_reverse_op(business_op):
|
||||||
|
"""退订/红冲类操作(BUY_REVERSE 等 *_REVERSE)。
|
||||||
|
|
||||||
|
数据中退订账单的 bill_detail 方向与正常单一致(均为贷),仅靠 business_op 区分。
|
||||||
|
退订口径:销售额、利润取反(减少);上游结算/应付供应商仍正向累加(增加)。
|
||||||
|
"""
|
||||||
|
return str(business_op or '').upper().endswith('_REVERSE')
|
||||||
|
|
||||||
|
|
||||||
def _salemode_label(code):
|
def _salemode_label(code):
|
||||||
if code is None:
|
if code is None:
|
||||||
return None
|
return None
|
||||||
@ -326,11 +335,13 @@ async def _protocol_snapshot(sor, accounting_orgid, customerid, providerid, prod
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def _estimate_finance(catalog_amount, protocol):
|
def _estimate_finance(catalog_amount, protocol, is_reverse=False):
|
||||||
"""未记账:估算本级利润与本级应付(本级成本)。
|
"""未记账:估算本级利润与本级应付(本级成本)。
|
||||||
|
|
||||||
与已记账口径一致,本级应付取「本级作为采购方(bid)的协议」即 own_*,
|
与已记账口径一致,本级应付取「本级作为采购方(bid)的协议」即 own_*,
|
||||||
对业主机构与分销商统一(own_discount 即上级给本级的折扣/底价)。
|
对业主机构与分销商统一(own_discount 即上级给本级的折扣/底价)。
|
||||||
|
|
||||||
|
退订(is_reverse):利润取反(减少);上游结算仍正向(增加)。
|
||||||
"""
|
"""
|
||||||
catalog_amount = float(catalog_amount or 0)
|
catalog_amount = float(catalog_amount or 0)
|
||||||
qty = protocol.get('quantity') or 1
|
qty = protocol.get('quantity') or 1
|
||||||
@ -356,6 +367,9 @@ def _estimate_finance(catalog_amount, protocol):
|
|||||||
if own_price is not None:
|
if own_price is not None:
|
||||||
settle_upstream = float(own_price) * qty
|
settle_upstream = float(own_price) * qty
|
||||||
|
|
||||||
|
if is_reverse and profit is not None:
|
||||||
|
profit = -profit
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'profit_amount': _round_money(profit),
|
'profit_amount': _round_money(profit),
|
||||||
'settle_upstream_amount': _round_money(settle_upstream),
|
'settle_upstream_amount': _round_money(settle_upstream),
|
||||||
@ -376,12 +390,14 @@ async def _bill_detail_rows(sor, billid):
|
|||||||
))
|
))
|
||||||
|
|
||||||
|
|
||||||
async def _finance_from_bill_detail(sor, billid, accounting_orgid):
|
async def _finance_from_bill_detail(sor, billid, accounting_orgid, is_reverse=False):
|
||||||
"""已记账:从 bill_detail 取本级利润与本级应付。
|
"""已记账:从 bill_detail 取本级利润与本级应付。
|
||||||
|
|
||||||
统一口径(业主机构与分销商一致):
|
统一口径(业主机构与分销商一致):
|
||||||
- profit_amount = 本级账本「折扣收入/底价收入」贷方合计
|
- profit_amount = 本级账本「折扣收入/底价收入」贷方合计
|
||||||
- settle_upstream = 本级账本「待结转*销售收入」贷方合计(本级成本/本级应付上级)
|
- settle_upstream = 本级账本「待结转*销售收入」贷方合计(本级成本/本级应付上级)
|
||||||
|
|
||||||
|
退订(is_reverse):利润取反(减少);上游结算仍正向累加(增加)。
|
||||||
"""
|
"""
|
||||||
rows = await _bill_detail_rows(sor, billid)
|
rows = await _bill_detail_rows(sor, billid)
|
||||||
profit = 0.0
|
profit = 0.0
|
||||||
@ -408,6 +424,9 @@ async def _finance_from_bill_detail(sor, billid, accounting_orgid):
|
|||||||
elif subj.startswith(SUPPLIER_SETTLE_PREFIX):
|
elif subj.startswith(SUPPLIER_SETTLE_PREFIX):
|
||||||
settle_upstream += amt
|
settle_upstream += amt
|
||||||
|
|
||||||
|
if is_reverse:
|
||||||
|
profit = -profit
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'profit_amount': _round_money(profit),
|
'profit_amount': _round_money(profit),
|
||||||
'settle_upstream_amount': _round_money(settle_upstream) if settle_upstream else _round_money(0),
|
'settle_upstream_amount': _round_money(settle_upstream) if settle_upstream else _round_money(0),
|
||||||
@ -426,6 +445,10 @@ async def _build_report_row(sor, row, accounting_orgid, is_owner):
|
|||||||
catalog_amount = _round_money(_row_get(row, 'catalog_amount'))
|
catalog_amount = _round_money(_row_get(row, 'catalog_amount'))
|
||||||
customer_pay = _round_money(_row_get(row, 'customer_pay_amount'))
|
customer_pay = _round_money(_row_get(row, 'customer_pay_amount'))
|
||||||
customer_parentid = _row_get(row, 'customer_parentid')
|
customer_parentid = _row_get(row, 'customer_parentid')
|
||||||
|
is_reverse = _is_reverse_op(_row_get(row, 'business_op'))
|
||||||
|
if is_reverse and customer_pay is not None:
|
||||||
|
# 退订:客户实付(销售额)取负,使汇总相应减少
|
||||||
|
customer_pay = _round_money(-customer_pay)
|
||||||
|
|
||||||
protocol = await _protocol_snapshot(
|
protocol = await _protocol_snapshot(
|
||||||
sor, accounting_orgid, customerid, providerid, productid, bill_date, quantity,
|
sor, accounting_orgid, customerid, providerid, productid, bill_date, quantity,
|
||||||
@ -434,9 +457,9 @@ async def _build_report_row(sor, row, accounting_orgid, is_owner):
|
|||||||
|
|
||||||
bill_state = _row_get(row, 'bill_state')
|
bill_state = _row_get(row, 'bill_state')
|
||||||
if str(bill_state) == '1':
|
if str(bill_state) == '1':
|
||||||
amounts = await _finance_from_bill_detail(sor, bill_id, accounting_orgid)
|
amounts = await _finance_from_bill_detail(sor, bill_id, accounting_orgid, is_reverse)
|
||||||
else:
|
else:
|
||||||
amounts = _estimate_finance(catalog_amount, protocol)
|
amounts = _estimate_finance(catalog_amount, protocol, is_reverse)
|
||||||
amounts['bill_detail_legs'] = []
|
amounts['bill_detail_legs'] = []
|
||||||
|
|
||||||
product_name = _row_get(row, 'product_name')
|
product_name = _row_get(row, 'product_name')
|
||||||
@ -638,14 +661,20 @@ def _customer_segment(customer_parentid, accounting_orgid, reseller_id_set):
|
|||||||
|
|
||||||
|
|
||||||
async def _bill_finance_amounts(sor, row, accounting_orgid):
|
async def _bill_finance_amounts(sor, row, accounting_orgid):
|
||||||
"""单笔:销售额、本级利润、本级应付上级/供应商。"""
|
"""单笔:销售额、本级利润、本级应付上级/供应商。
|
||||||
|
|
||||||
|
退订(BUY_REVERSE 等):销售额、利润取负(减少);应付上级仍正向(增加)。
|
||||||
|
"""
|
||||||
sales = float(_row_get(row, 'customer_pay_amount') or 0)
|
sales = float(_row_get(row, 'customer_pay_amount') or 0)
|
||||||
bill_id = _row_get(row, 'bill_id')
|
bill_id = _row_get(row, 'bill_id')
|
||||||
bill_state = _row_get(row, 'bill_state')
|
bill_state = _row_get(row, 'bill_state')
|
||||||
quantity = int(_row_get(row, 'quantity') or 1)
|
quantity = int(_row_get(row, 'quantity') or 1)
|
||||||
|
is_reverse = _is_reverse_op(_row_get(row, 'business_op'))
|
||||||
|
if is_reverse:
|
||||||
|
sales = -sales
|
||||||
|
|
||||||
if str(bill_state) == '1':
|
if str(bill_state) == '1':
|
||||||
fin = await _finance_from_bill_detail(sor, bill_id, accounting_orgid)
|
fin = await _finance_from_bill_detail(sor, bill_id, accounting_orgid, is_reverse)
|
||||||
else:
|
else:
|
||||||
catalog = float(_row_get(row, 'catalog_amount') or 0)
|
catalog = float(_row_get(row, 'catalog_amount') or 0)
|
||||||
protocol = await _protocol_snapshot(
|
protocol = await _protocol_snapshot(
|
||||||
@ -657,7 +686,7 @@ async def _bill_finance_amounts(sor, row, accounting_orgid):
|
|||||||
_row_get(row, 'bill_date'),
|
_row_get(row, 'bill_date'),
|
||||||
quantity,
|
quantity,
|
||||||
)
|
)
|
||||||
fin = _estimate_finance(catalog, protocol)
|
fin = _estimate_finance(catalog, protocol, is_reverse)
|
||||||
|
|
||||||
profit = float(fin.get('profit_amount') or 0)
|
profit = float(fin.get('profit_amount') or 0)
|
||||||
settle = float(fin.get('settle_upstream_amount') or 0)
|
settle = float(fin.get('settle_upstream_amount') or 0)
|
||||||
@ -769,7 +798,7 @@ async def _fetch_bill_row_via_R(sor, bill_id):
|
|||||||
'customer_pay_amount': b.get('amount'),
|
'customer_pay_amount': b.get('amount'),
|
||||||
'quantity': b.get('quantity'),
|
'quantity': b.get('quantity'),
|
||||||
'order_date': o.get('order_date'),
|
'order_date': o.get('order_date'),
|
||||||
'business_op': o.get('business_op'),
|
'business_op': b.get('business_op') or o.get('business_op'),
|
||||||
'servicename': o.get('servicename'),
|
'servicename': o.get('servicename'),
|
||||||
'customer_name': cust.get('orgname'),
|
'customer_name': cust.get('orgname'),
|
||||||
'customer_parentid': cust.get('parentid'),
|
'customer_parentid': cust.get('parentid'),
|
||||||
|
|||||||
@ -115,6 +115,15 @@ def _round_money(v):
|
|||||||
return round(float(v), 2)
|
return round(float(v), 2)
|
||||||
|
|
||||||
|
|
||||||
|
def _is_reverse_op(business_op):
|
||||||
|
"""退订/红冲类操作(BUY_REVERSE 等 *_REVERSE)。
|
||||||
|
|
||||||
|
数据中退订账单的 bill_detail 方向与正常单一致(均为贷),仅靠 business_op 区分。
|
||||||
|
退订口径:销售额、利润取反(减少);上游结算/应付供应商仍正向累加(增加)。
|
||||||
|
"""
|
||||||
|
return str(business_op or '').upper().endswith('_REVERSE')
|
||||||
|
|
||||||
|
|
||||||
def _salemode_label(code):
|
def _salemode_label(code):
|
||||||
if code is None:
|
if code is None:
|
||||||
return None
|
return None
|
||||||
@ -326,11 +335,13 @@ async def _protocol_snapshot(sor, accounting_orgid, customerid, providerid, prod
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def _estimate_finance(catalog_amount, protocol):
|
def _estimate_finance(catalog_amount, protocol, is_reverse=False):
|
||||||
"""未记账:估算本级利润与本级应付(本级成本)。
|
"""未记账:估算本级利润与本级应付(本级成本)。
|
||||||
|
|
||||||
与已记账口径一致,本级应付取「本级作为采购方(bid)的协议」即 own_*,
|
与已记账口径一致,本级应付取「本级作为采购方(bid)的协议」即 own_*,
|
||||||
对业主机构与分销商统一(own_discount 即上级给本级的折扣/底价)。
|
对业主机构与分销商统一(own_discount 即上级给本级的折扣/底价)。
|
||||||
|
|
||||||
|
退订(is_reverse):利润取反(减少);上游结算仍正向(增加)。
|
||||||
"""
|
"""
|
||||||
catalog_amount = float(catalog_amount or 0)
|
catalog_amount = float(catalog_amount or 0)
|
||||||
qty = protocol.get('quantity') or 1
|
qty = protocol.get('quantity') or 1
|
||||||
@ -356,6 +367,9 @@ def _estimate_finance(catalog_amount, protocol):
|
|||||||
if own_price is not None:
|
if own_price is not None:
|
||||||
settle_upstream = float(own_price) * qty
|
settle_upstream = float(own_price) * qty
|
||||||
|
|
||||||
|
if is_reverse and profit is not None:
|
||||||
|
profit = -profit
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'profit_amount': _round_money(profit),
|
'profit_amount': _round_money(profit),
|
||||||
'settle_upstream_amount': _round_money(settle_upstream),
|
'settle_upstream_amount': _round_money(settle_upstream),
|
||||||
@ -376,12 +390,14 @@ async def _bill_detail_rows(sor, billid):
|
|||||||
))
|
))
|
||||||
|
|
||||||
|
|
||||||
async def _finance_from_bill_detail(sor, billid, accounting_orgid):
|
async def _finance_from_bill_detail(sor, billid, accounting_orgid, is_reverse=False):
|
||||||
"""已记账:从 bill_detail 取本级利润与本级应付。
|
"""已记账:从 bill_detail 取本级利润与本级应付。
|
||||||
|
|
||||||
统一口径(业主机构与分销商一致):
|
统一口径(业主机构与分销商一致):
|
||||||
- profit_amount = 本级账本「折扣收入/底价收入」贷方合计
|
- profit_amount = 本级账本「折扣收入/底价收入」贷方合计
|
||||||
- settle_upstream = 本级账本「待结转*销售收入」贷方合计(本级成本/本级应付上级)
|
- settle_upstream = 本级账本「待结转*销售收入」贷方合计(本级成本/本级应付上级)
|
||||||
|
|
||||||
|
退订(is_reverse):利润取反(减少);上游结算仍正向累加(增加)。
|
||||||
"""
|
"""
|
||||||
rows = await _bill_detail_rows(sor, billid)
|
rows = await _bill_detail_rows(sor, billid)
|
||||||
profit = 0.0
|
profit = 0.0
|
||||||
@ -408,6 +424,9 @@ async def _finance_from_bill_detail(sor, billid, accounting_orgid):
|
|||||||
elif subj.startswith(SUPPLIER_SETTLE_PREFIX):
|
elif subj.startswith(SUPPLIER_SETTLE_PREFIX):
|
||||||
settle_upstream += amt
|
settle_upstream += amt
|
||||||
|
|
||||||
|
if is_reverse:
|
||||||
|
profit = -profit
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'profit_amount': _round_money(profit),
|
'profit_amount': _round_money(profit),
|
||||||
'settle_upstream_amount': _round_money(settle_upstream) if settle_upstream else _round_money(0),
|
'settle_upstream_amount': _round_money(settle_upstream) if settle_upstream else _round_money(0),
|
||||||
@ -426,6 +445,10 @@ async def _build_report_row(sor, row, accounting_orgid, is_owner):
|
|||||||
catalog_amount = _round_money(_row_get(row, 'catalog_amount'))
|
catalog_amount = _round_money(_row_get(row, 'catalog_amount'))
|
||||||
customer_pay = _round_money(_row_get(row, 'customer_pay_amount'))
|
customer_pay = _round_money(_row_get(row, 'customer_pay_amount'))
|
||||||
customer_parentid = _row_get(row, 'customer_parentid')
|
customer_parentid = _row_get(row, 'customer_parentid')
|
||||||
|
is_reverse = _is_reverse_op(_row_get(row, 'business_op'))
|
||||||
|
if is_reverse and customer_pay is not None:
|
||||||
|
# 退订:客户实付(销售额)取负,使汇总相应减少
|
||||||
|
customer_pay = _round_money(-customer_pay)
|
||||||
|
|
||||||
protocol = await _protocol_snapshot(
|
protocol = await _protocol_snapshot(
|
||||||
sor, accounting_orgid, customerid, providerid, productid, bill_date, quantity,
|
sor, accounting_orgid, customerid, providerid, productid, bill_date, quantity,
|
||||||
@ -434,9 +457,9 @@ async def _build_report_row(sor, row, accounting_orgid, is_owner):
|
|||||||
|
|
||||||
bill_state = _row_get(row, 'bill_state')
|
bill_state = _row_get(row, 'bill_state')
|
||||||
if str(bill_state) == '1':
|
if str(bill_state) == '1':
|
||||||
amounts = await _finance_from_bill_detail(sor, bill_id, accounting_orgid)
|
amounts = await _finance_from_bill_detail(sor, bill_id, accounting_orgid, is_reverse)
|
||||||
else:
|
else:
|
||||||
amounts = _estimate_finance(catalog_amount, protocol)
|
amounts = _estimate_finance(catalog_amount, protocol, is_reverse)
|
||||||
amounts['bill_detail_legs'] = []
|
amounts['bill_detail_legs'] = []
|
||||||
|
|
||||||
product_name = _row_get(row, 'product_name')
|
product_name = _row_get(row, 'product_name')
|
||||||
@ -638,14 +661,20 @@ def _customer_segment(customer_parentid, accounting_orgid, reseller_id_set):
|
|||||||
|
|
||||||
|
|
||||||
async def _bill_finance_amounts(sor, row, accounting_orgid):
|
async def _bill_finance_amounts(sor, row, accounting_orgid):
|
||||||
"""单笔:销售额、本级利润、本级应付上级/供应商。"""
|
"""单笔:销售额、本级利润、本级应付上级/供应商。
|
||||||
|
|
||||||
|
退订(BUY_REVERSE 等):销售额、利润取负(减少);应付上级仍正向(增加)。
|
||||||
|
"""
|
||||||
sales = float(_row_get(row, 'customer_pay_amount') or 0)
|
sales = float(_row_get(row, 'customer_pay_amount') or 0)
|
||||||
bill_id = _row_get(row, 'bill_id')
|
bill_id = _row_get(row, 'bill_id')
|
||||||
bill_state = _row_get(row, 'bill_state')
|
bill_state = _row_get(row, 'bill_state')
|
||||||
quantity = int(_row_get(row, 'quantity') or 1)
|
quantity = int(_row_get(row, 'quantity') or 1)
|
||||||
|
is_reverse = _is_reverse_op(_row_get(row, 'business_op'))
|
||||||
|
if is_reverse:
|
||||||
|
sales = -sales
|
||||||
|
|
||||||
if str(bill_state) == '1':
|
if str(bill_state) == '1':
|
||||||
fin = await _finance_from_bill_detail(sor, bill_id, accounting_orgid)
|
fin = await _finance_from_bill_detail(sor, bill_id, accounting_orgid, is_reverse)
|
||||||
else:
|
else:
|
||||||
catalog = float(_row_get(row, 'catalog_amount') or 0)
|
catalog = float(_row_get(row, 'catalog_amount') or 0)
|
||||||
protocol = await _protocol_snapshot(
|
protocol = await _protocol_snapshot(
|
||||||
@ -657,7 +686,7 @@ async def _bill_finance_amounts(sor, row, accounting_orgid):
|
|||||||
_row_get(row, 'bill_date'),
|
_row_get(row, 'bill_date'),
|
||||||
quantity,
|
quantity,
|
||||||
)
|
)
|
||||||
fin = _estimate_finance(catalog, protocol)
|
fin = _estimate_finance(catalog, protocol, is_reverse)
|
||||||
|
|
||||||
profit = float(fin.get('profit_amount') or 0)
|
profit = float(fin.get('profit_amount') or 0)
|
||||||
settle = float(fin.get('settle_upstream_amount') or 0)
|
settle = float(fin.get('settle_upstream_amount') or 0)
|
||||||
@ -769,7 +798,7 @@ async def _fetch_bill_row_via_R(sor, bill_id):
|
|||||||
'customer_pay_amount': b.get('amount'),
|
'customer_pay_amount': b.get('amount'),
|
||||||
'quantity': b.get('quantity'),
|
'quantity': b.get('quantity'),
|
||||||
'order_date': o.get('order_date'),
|
'order_date': o.get('order_date'),
|
||||||
'business_op': o.get('business_op'),
|
'business_op': b.get('business_op') or o.get('business_op'),
|
||||||
'servicename': o.get('servicename'),
|
'servicename': o.get('servicename'),
|
||||||
'customer_name': cust.get('orgname'),
|
'customer_name': cust.get('orgname'),
|
||||||
'customer_parentid': cust.get('parentid'),
|
'customer_parentid': cust.get('parentid'),
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user