227 lines
6.6 KiB
Python
227 lines
6.6 KiB
Python
|
|
from appPublic.log import debug, exception
|
|
from ahserver.serverenv import get_serverenv
|
|
from traceback import format_exc
|
|
|
|
def get_date_between(use_date, step_type):
|
|
if step_type == '0':
|
|
# 总金额
|
|
return '1000-01-01', '9999-12-31'
|
|
y = int(use_date[:4])
|
|
m = int(use_date[6:7])
|
|
if step_type == '1':
|
|
y = int(use_date[:4])
|
|
return '%04d-01-01' % y, '%04d-01-01' % (y+1)
|
|
if step_type == '2':
|
|
ss = [1,4,7,10, 13]
|
|
for i, s in enumerate(ss):
|
|
if m >=s and m < ss[i+1]:
|
|
if i < 3:
|
|
return '%04d-%02d-01' % (y, s), '%04d-%02d-01' % (y, ss[i+1])
|
|
else:
|
|
return '%04d-%02d-01' % (y, s), '%04d-01-01' % (y+1)
|
|
if step_type == '3':
|
|
if m < 12:
|
|
return '%04d-%02d-01' % (y, m), '%04d-%02d-01' % (y, m+1)
|
|
else:
|
|
return '%04d-%02d-01' % (y, m), '%04d-01-01' % (yi+1)
|
|
e = Exception(f'unknown {step_type=}')
|
|
exception(f'{e=}')
|
|
raise e
|
|
|
|
async def get_biz_date(sor):
|
|
biz_date = ''
|
|
f = get_serverenv('get_business_date')
|
|
if f:
|
|
biz_date = await f(sor)
|
|
return biz_date
|
|
e = Exception(f'get_serverenv("get_business_date") return None')
|
|
exception(f'{e=}')
|
|
raise e
|
|
|
|
async def get_step_discount(sor, agreedetailid, step_type, sellerid, buyerid):
|
|
amount = await get_sale_amount(sor, step_type, sellerid, buyerid)
|
|
sql = """select * from agreedetailstep
|
|
where adid = ${adid}
|
|
and minamt <= ${amount}$
|
|
and maxamt > ${amount}$
|
|
"""
|
|
recs = await sor.sqlExe(sql, {'adid':agreedetailid,
|
|
'amount':amount
|
|
})
|
|
if len(recs) < 1:
|
|
e = Exception(f'{sql=} not data, {agreedetailid=}, {amount=}')
|
|
exception(f'{e=}')
|
|
raise e
|
|
return rec.discount
|
|
|
|
async def get_sale_amount(sor, step_type, sellerid, buyerid):
|
|
|
|
subjectname = '供应商分销收入'
|
|
f = get_serverenv('getAccountByName')
|
|
if f is None:
|
|
e = Exception(f'get_serverenv("getAccountByName") return None')
|
|
exception(f'{e=}')
|
|
raise e
|
|
|
|
acc = await f(sor, accounting_orgid, sellerid, subjectname, buyerid)
|
|
biz_date = await get_biz_date(sor)
|
|
from_date, to_date = get_date_between(biz_date, step_type)
|
|
f = get_serverenv('get_account_total_amount')
|
|
if f is None:
|
|
e = Exception(f'get_serverenv("get_account_total_amount") return None')
|
|
exception(f'{e=}')
|
|
raise e
|
|
amount = await f(sor, acc.id, acc.blance_at, from_date, to_date)
|
|
return amount
|
|
|
|
async def get_product_agreement(sor, sellerid, buyerid, productid, biz_date):
|
|
sql = """select a.*,
|
|
c.id as agreedetailid,
|
|
c.prodtypeid as agree_prodtypeid,
|
|
c.discount,
|
|
c.step_type
|
|
from product as a, agreement as b, agreedetail as c
|
|
where a.agreeid = b.id
|
|
and ( a.prodtypeid = c.prodtypeid or c.prodtypeid is NULL)
|
|
and b.agreeid = a.id
|
|
and a.ownerid = b.providerid
|
|
and b.start_date <= ${biz_date}$
|
|
and b.end_date > ${biz_date}$
|
|
and a.ownerid = ${sellerid}$
|
|
and b.resellerid = ${buyerid}$
|
|
and a.id = ${productid}$
|
|
"""
|
|
recs = await sor.sqlExe(sql, {'sellerid':selllerid,
|
|
'buyerid':buyerid,
|
|
'biz_date':biz_date,
|
|
'productid':productid
|
|
})
|
|
if len(recs) == 0:
|
|
e = Exception(f'there is no agreement for {sellerid=} and {buyerid=}, {productid=} at {biz_date=} ')
|
|
exception(f'{e=}')
|
|
raise e
|
|
rec = None:
|
|
for r in recs:
|
|
if r.prodtypeid = r.agree_prodtypeid:
|
|
rec = r
|
|
break
|
|
if rec is None:
|
|
for r in recs:
|
|
if r.agree_prodtypeid is None:
|
|
rec = r
|
|
break
|
|
if rec is None:
|
|
e = Exception(f'Not agreements for {sellerid=} and {buyerid=}, {productid=} at {biz_date=} ')
|
|
exception(f'{e=}')
|
|
raise e
|
|
return rec
|
|
|
|
async def get_fact_price(sor, productid, fact_config):
|
|
sql = "select * from prodpricingtab where prodid=${productid}$"
|
|
recs = await sor.sqlExe(sql, {'productid':productid})
|
|
if len(recs) < 1:
|
|
e = Exception(f'{sql=}, {productid=} return not data')
|
|
exception(f'{e=}')
|
|
raise e
|
|
price = 0.0
|
|
for r in recs:
|
|
if r.fact_value is None or r.fact_value == 0:
|
|
r.fact_value = 1
|
|
count = fact_config.get(r.fact_name, 0)
|
|
price += r.unit_amt * count / r.fact_value
|
|
return price
|
|
|
|
async def get_sell_price(sor, sellerid, buyerid, productid, list_price):
|
|
"""
|
|
获得商品售价
|
|
"""
|
|
|
|
biz_date = await get_biz_date(sor)
|
|
rec = get_product_agreement(sor, sellerid, buyerid, productid, biz_date)
|
|
if rec.discount:
|
|
return list_price * rec.discount
|
|
# amount = await get_sale_amount(sor, rec.step_type, sellerid, buyerid)
|
|
discount = await get_step_discount(sor, rec.agreedetailid, rec.step_type, selllerid, buyerid)
|
|
return discount * list_price
|
|
|
|
async def get_price(sor, sellerid, buyerid, productid, prod_config):
|
|
"""
|
|
获得商品价格
|
|
resellerid:商户id
|
|
productid:商品id
|
|
prod_config:商品配置
|
|
返回
|
|
[
|
|
{ownerid, list_price, price}, ...
|
|
]
|
|
"""
|
|
cost_pricing_infos = []
|
|
sql1 = """select a.*,
|
|
b.pricing_mode,
|
|
b.count_price,
|
|
b.pricingapiid
|
|
from product a left join prodpricing b on a.id=b.prodid
|
|
where a.id = ${productid}$
|
|
and a.ownerid = ${sellerid}$"""
|
|
prods = await sor.sqlExe(sql1, {'productid':productid, 'sellerid':sellerid})
|
|
if len(prods) < 1:
|
|
e = Exception(f'{resellerid=} {productid=} product not found')
|
|
exception(f'{e=}')
|
|
raise e
|
|
prod = prods[0]
|
|
if prod.agreeid is not None:
|
|
cost_pricing_infos = get_price(sor, prod.providerid, sellerid, prod.providerpid, prod_config)
|
|
|
|
if prod.pricing_mode == '0' and prod.count_price:
|
|
# 按数量计费
|
|
list_price = prod_config.get('count',1) * prod.count_price
|
|
sell_price = await get_sell_price(sor, sellerid, buyerid, productid, list_price)
|
|
pricing_info = {
|
|
'sellerid': sellerid,
|
|
'buyerid': buyerid,
|
|
'productid': productid,
|
|
'list_price': list_price,
|
|
'sell_price': sell_price
|
|
}
|
|
elif prod.pricing_mode == '1':
|
|
# 按资源因子计费
|
|
list_price = await get_fact_price(sor, productid, prod_config)
|
|
sell_price = await get_sell_price(sor, sellerid, buyerid, productid, list_price)
|
|
pricing_info = {
|
|
'sellerid': sellerid,
|
|
'buyerid': buyerid,
|
|
'productid': productid,
|
|
'list_price': list_price,
|
|
'sell_price': sell_price
|
|
}
|
|
elif prod_pricing_mode == '2':
|
|
# 外部计费
|
|
f = get_serverenv('pricing_api')
|
|
list_price = await f(sor, prod.pricingapiid, providerpid, prod_config)
|
|
sell_price = await get_sell_price(sor, sellerid, buyerid, productid, list_price)
|
|
pricing_info = {
|
|
'sellerid': sellerid,
|
|
'buyerid': buyerid,
|
|
'productid': productid,
|
|
'list_price': list_price,
|
|
'sell_price': sell_price
|
|
}
|
|
else:
|
|
# 供应商计费
|
|
if len(cost_pricing_info) < 1:
|
|
e = Exception(f'{sellerid=}, {buyerid=}, {productid=} has not resell agreement')
|
|
exception(e)
|
|
raise e
|
|
list_price = cost_pricing_info[-1]['list_price']
|
|
sell_price = await get_sell_price(sor, sellerid, buyerid, productid, list_price)
|
|
pricing_info = {
|
|
'sellerid': sellerid,
|
|
'buyerid': buyerid,
|
|
'productid': productid,
|
|
'list_price': list_price,
|
|
'sell_price': sell_price
|
|
}
|
|
cost_pricing_info.append(pricing_info)
|
|
return cost_pricing_info
|