Merge branch 'main' of git.kaiyuancloud.cn:yumoqing/accounting
This commit is contained in:
commit
90569bf4ef
@ -1,17 +0,0 @@
|
|||||||
from appPublic.registerfunction import RegisterFunction
|
|
||||||
from appPublic.dictOBject import DictObject
|
|
||||||
from appPublic.log import debug, exception, error
|
|
||||||
from ahserver.serverenv import ServerEnv
|
|
||||||
from accounting_config import AccountingOrgs
|
|
||||||
|
|
||||||
def load_accounting():
|
|
||||||
g = ServerEnv()
|
|
||||||
g.recharge_accounting = recharge_accounting
|
|
||||||
g.pay_accounting = pay_accounting
|
|
||||||
g.settle_accounting = settle_accounting
|
|
||||||
g.open_customer_account = open_customer_account
|
|
||||||
g.open_reseller_account = open_reseller_account
|
|
||||||
g.open_provider_account = open_provider_account
|
|
||||||
g.open_owner_account = open_owner_account
|
|
||||||
g.get_customer_balance = get_customer_balance
|
|
||||||
|
|
@ -3,7 +3,7 @@ import re
|
|||||||
from .const import *
|
from .const import *
|
||||||
from .accountingnode import get_parent_orgid
|
from .accountingnode import get_parent_orgid
|
||||||
from .excep import *
|
from .excep import *
|
||||||
from .getaccount import getAccountByName
|
from .getaccount import get_account, getAccountByName
|
||||||
from appPublic.uniqueID import getID
|
from appPublic.uniqueID import getID
|
||||||
from appPublic.log import debug
|
from appPublic.log import debug
|
||||||
from sqlor.dbpools import DBPools
|
from sqlor.dbpools import DBPools
|
||||||
@ -24,7 +24,13 @@ async def get_accounting_config(sor):
|
|||||||
return accounting_config
|
return accounting_config
|
||||||
return None
|
return None
|
||||||
|
|
||||||
class AccountingOrgs:
|
class Accounting:
|
||||||
|
/*
|
||||||
|
需要caller功能:
|
||||||
|
caller中要有分录中的变量
|
||||||
|
get_accounting_orgid(leg) 获得记账机构
|
||||||
|
get_account(leg,accounting_orgid) 获得记账账号(通过科目,机构类型,账务机构确定一个唯一的账号)
|
||||||
|
*/
|
||||||
def __init__(self, caller,
|
def __init__(self, caller,
|
||||||
accounting_orgid,
|
accounting_orgid,
|
||||||
customerid,
|
customerid,
|
||||||
@ -37,7 +43,8 @@ class AccountingOrgs:
|
|||||||
self.timestamp = caller.timestamp
|
self.timestamp = caller.timestamp
|
||||||
self.billid = caller.billid
|
self.billid = caller.billid
|
||||||
self.action = caller.action
|
self.action = caller.action
|
||||||
# self.summary = self.action
|
self.billid = getID()
|
||||||
|
self.summary = f'{self.caller.orderid}:{self.caller.billid}'
|
||||||
self.providerid = caller.providerid
|
self.providerid = caller.providerid
|
||||||
self.productid = caller.productid
|
self.productid = caller.productid
|
||||||
self.accounting_orgid = accounting_orgid
|
self.accounting_orgid = accounting_orgid
|
||||||
@ -45,87 +52,15 @@ class AccountingOrgs:
|
|||||||
self.customerid = customerid
|
self.customerid = customerid
|
||||||
self.own_salemode = None
|
self.own_salemode = None
|
||||||
self.reseller_salemode = None
|
self.reseller_salemode = None
|
||||||
self.variable = {
|
self.variable = self.caller.varable
|
||||||
'交易金额':self.caller.transamount
|
|
||||||
}
|
|
||||||
self.salemode_sql0 = """
|
|
||||||
select a.*, b.providerid, b.productid, b.discount, b.price
|
|
||||||
from saleprotocol a, product_salemode b
|
|
||||||
where a.id = b.protocolid
|
|
||||||
and a.bid_orgid=${bid_orgid}$
|
|
||||||
and (b.productid=${productid}$ or b.productid = '*')
|
|
||||||
and b.providerid = ${providerid}$
|
|
||||||
and a.start_date <= ${curdate}$
|
|
||||||
and a.end_date > ${curdate}$
|
|
||||||
order by productid desc
|
|
||||||
"""
|
|
||||||
self.salemode_sql = """
|
|
||||||
select a.*, b.providerid, b.productid, b.discount, b.price
|
|
||||||
from saleprotocol a, product_salemode b
|
|
||||||
where a.id = b.protocolid
|
|
||||||
and a.offer_orgid=${offer_orgid}$
|
|
||||||
and b.providerid = ${providerid}$
|
|
||||||
and a.bid_orgid=${bid_orgid}$
|
|
||||||
and (b.productid=${productid}$ or b.productid = '*')
|
|
||||||
and a.start_date <= ${curdate}$
|
|
||||||
and a.end_date > ${curdate}$
|
|
||||||
order by productid desc
|
|
||||||
"""
|
|
||||||
|
|
||||||
async def is_business_owner(self):
|
|
||||||
sor = self.sor
|
|
||||||
recs = await sor.sqlExe("select * from organization where id=${orgid}$ and parentid is null",
|
|
||||||
{'orgid':self.accounting_orgid})
|
|
||||||
if len(recs) > 0:
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
async def check_add_realtime_settle_legs(self):
|
|
||||||
sor = self.sor
|
|
||||||
if self.settle_mode == '0':
|
|
||||||
await self.add_online_settle_legs()
|
|
||||||
print('settle legs added ....')
|
|
||||||
else:
|
|
||||||
print(f'{self.providerid=}')
|
|
||||||
|
|
||||||
async def add_online_settle_legs(self):
|
|
||||||
specstr = ACTNAME_SETTLE + '-' + self.own_salemode + '-实时'
|
|
||||||
ls = [r.copy() for r in accounting_config if r['specstr'] == specstr ]
|
|
||||||
for l in ls:
|
|
||||||
if self.action.endswith('_REVERSE'):
|
|
||||||
l['summary'] = 'SETTLE_REVERSE'
|
|
||||||
else:
|
|
||||||
l['summary'] = 'SETTLE'
|
|
||||||
|
|
||||||
self.accounting_legs += ls
|
|
||||||
self.realtimesettled = True
|
|
||||||
|
|
||||||
async def setup_accounting_legs(self):
|
async def setup_accounting_legs(self):
|
||||||
global accounting_config
|
global accounting_config
|
||||||
specstr = await self.get_act_specstr()
|
action = self.action.split('_')[0]
|
||||||
self.specstr = specstr
|
|
||||||
await get_accounting_config(self.sor)
|
await get_accounting_config(self.sor)
|
||||||
aorgtype = '客户所在机构'
|
self.accounting_legs = [r.copy() for r in accounting_config
|
||||||
if self.resellerid:
|
if r.action == action ]
|
||||||
aorgtype = '分销商机构'
|
|
||||||
debug(f'{accounting_config=}, {aorgtype=}')
|
|
||||||
if self.specstr.startswith(ACTNAME_SETTLE):
|
|
||||||
self.accounting_legs = [r.copy() for r in accounting_config
|
|
||||||
if r['specstr'] == specstr ]
|
|
||||||
else:
|
|
||||||
self.accounting_legs = [r.copy() for r in accounting_config
|
|
||||||
if r['specstr'] == specstr
|
|
||||||
and r['accounting_orgtype'] == aorgtype]
|
|
||||||
debug(f'{self.accounting_legs=}')
|
debug(f'{self.accounting_legs=}')
|
||||||
for l in self.accounting_legs:
|
|
||||||
l['summary'] = self.action
|
|
||||||
|
|
||||||
if self.specstr.startswith(ACTNAME_BUY):
|
|
||||||
await self.check_add_realtime_settle_legs()
|
|
||||||
else:
|
|
||||||
print(f'{self.specstr} is notstartswith {ACTNAME_BUY}')
|
|
||||||
|
|
||||||
print(f'setup_accounting_legs():{self.specstr}')
|
|
||||||
rev = self.action.endswith('_REVERSE')
|
rev = self.action.endswith('_REVERSE')
|
||||||
for l in self.accounting_legs:
|
for l in self.accounting_legs:
|
||||||
if rev:
|
if rev:
|
||||||
@ -133,111 +68,20 @@ where a.id = b.protocolid
|
|||||||
else:
|
else:
|
||||||
l['acc_dir'] = l['accounting_dir']
|
l['acc_dir'] = l['accounting_dir']
|
||||||
ac = ArgsConvert('${', '}$')
|
ac = ArgsConvert('${', '}$')
|
||||||
print(f'{l["id"]},{l["amt_pattern"]=}')
|
debug(f'{l["id"]},{l["amt_pattern"]=}')
|
||||||
try:
|
try:
|
||||||
l['amount'] = eval(await ac.convert(
|
amtstr = ac.convert(l['amt_pattern'],
|
||||||
l['amt_pattern'],
|
self.variable.copy()
|
||||||
self.variable.copy(),
|
)
|
||||||
default=self.localamount))
|
l['amount'] = eval(amtstr)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(l['amt_pattern'], l['id'], self.variable)
|
print(l['amt_pattern'], l['id'], self.variable)
|
||||||
raise e
|
raise e
|
||||||
|
|
||||||
if l['amount'] is None:
|
if l['amount'] is None:
|
||||||
print(f'amount is None:{l["amt_pattern"]}, {self.variable=},{self.caller.bill=}')
|
debug(f'amount is None:{l["amt_pattern"]}, {self.variable=},{self.caller.bill=}')
|
||||||
raise AccountingAmountIsNone(self.caller.billid)
|
raise AccountingAmountIsNone(self.caller.billid)
|
||||||
|
|
||||||
async def setup_bill_variable(self):
|
|
||||||
"""
|
|
||||||
'本方折扣'
|
|
||||||
'客户折扣'
|
|
||||||
'分销商折扣'
|
|
||||||
'进价'
|
|
||||||
'客户售价'
|
|
||||||
'分销商售价'
|
|
||||||
"""
|
|
||||||
sor = self.sor
|
|
||||||
recs = await sor.sqlExe(self.salemode_sql0, {
|
|
||||||
'bid_orgid':self.accounting_orgid,
|
|
||||||
'providerid':self.providerid,
|
|
||||||
'productid':self.productid,
|
|
||||||
'curdate':self.curdate})
|
|
||||||
if len(recs) == 0:
|
|
||||||
raise ProductBidProtocolNotDefined(None, self.accounting_orgid,
|
|
||||||
self.providerid,
|
|
||||||
self.productid,
|
|
||||||
self.curdate
|
|
||||||
)
|
|
||||||
rec = recs[0]
|
|
||||||
self.settle_mode = rec['settle_mode']
|
|
||||||
self.quantity = self.caller.bill['quantity']
|
|
||||||
salemode=rec['salemode']
|
|
||||||
if salemode == '0':
|
|
||||||
self.variable['本方折扣'] = rec['discount']
|
|
||||||
elif salemode == '2':
|
|
||||||
self.variable['进价'] = rec['price'] * self.quantity
|
|
||||||
|
|
||||||
recs = await sor.sqlExe(self.salemode_sql, {
|
|
||||||
'offer_orgid':self.accounting_orgid,
|
|
||||||
'bid_orgid':self.customerid,
|
|
||||||
'providerid':self.providerid,
|
|
||||||
'productid':self.productid,
|
|
||||||
'curdate':self.curdate})
|
|
||||||
if len(recs) == 0:
|
|
||||||
recs = await sor.sqlExe(self.salemode_sql, {
|
|
||||||
'offer_orgid':self.accounting_orgid,
|
|
||||||
'bid_orgid':'*',
|
|
||||||
'providerid':self.providerid,
|
|
||||||
'productid':self.productid,
|
|
||||||
'curdate':self.curdate})
|
|
||||||
print(f'get customer price or discount, {recs=}')
|
|
||||||
if len(recs) == 0:
|
|
||||||
raise ProductBidProtocolNotDefined(None, self.customerid,
|
|
||||||
self.providerid,
|
|
||||||
self.productid,
|
|
||||||
self.curdate
|
|
||||||
)
|
|
||||||
rec = recs[0]
|
|
||||||
salemode=rec['salemode']
|
|
||||||
if salemode == '0':
|
|
||||||
self.variable['客户折扣'] = rec['discount']
|
|
||||||
elif salemode == '2':
|
|
||||||
self.variable['客户售价'] = rec['price'] * self.quantity
|
|
||||||
|
|
||||||
if self.resellerid:
|
|
||||||
recs = await sor.sqlExe(self.salemode_sql, {
|
|
||||||
'offer_orgid':self.accounting_orgid,
|
|
||||||
'bid_orgid':self.resellerid,
|
|
||||||
'providerid':self.providerid,
|
|
||||||
'productid':self.productid,
|
|
||||||
'curdate':self.curdate})
|
|
||||||
if len(recs) == 0:
|
|
||||||
raise ProductBidProtocolNotDefined(None, self.resellerid,
|
|
||||||
self.providerid,
|
|
||||||
self.productid,
|
|
||||||
self.curdate
|
|
||||||
)
|
|
||||||
rec = recs[0]
|
|
||||||
salemode=rec['salemode']
|
|
||||||
if salemode == '0':
|
|
||||||
self.variable['分销商折扣'] = rec['discount']
|
|
||||||
elif salemode == '2':
|
|
||||||
self.variable['分销商售价'] = rec['price'] * self.quantity
|
|
||||||
|
|
||||||
async def localamount(self, name):
|
|
||||||
a = name.split('-')
|
|
||||||
if len(a) == 3:
|
|
||||||
for l in self.accounting_legs:
|
|
||||||
if a[0] == l['accounting_dir'] and \
|
|
||||||
a[1] == l['orgtype'] and \
|
|
||||||
a[2] == l['subjectname']:
|
|
||||||
return l['amount']
|
|
||||||
if name[0] == '#':
|
|
||||||
i = int(name[1:])
|
|
||||||
return self.accounting_legs[i]['amount']
|
|
||||||
|
|
||||||
print(f'{name} not found')
|
|
||||||
|
|
||||||
def check_accounting_balance(self, legs):
|
def check_accounting_balance(self, legs):
|
||||||
debt_balance = 0.0
|
debt_balance = 0.0
|
||||||
credit_balance = 0.0
|
credit_balance = 0.0
|
||||||
@ -255,29 +99,18 @@ where a.id = b.protocolid
|
|||||||
self.sor = sor
|
self.sor = sor
|
||||||
|
|
||||||
await self.setup_accounting_legs()
|
await self.setup_accounting_legs()
|
||||||
print('do_accounting() ...', self.accounting_legs)
|
debug(f'do_accounting() ...{self.accounting_legs=}')
|
||||||
self.check_accounting_balance(self.accounting_legs)
|
self.check_accounting_balance(self.accounting_legs)
|
||||||
for leg in self.accounting_legs:
|
for leg in self.accounting_legs:
|
||||||
orgid = self.accounting_orgid
|
accounting_orgid = await self.caller.get_accounting_orgid(sor, leg.accounting_orgtype)
|
||||||
if leg['orgtype'] == '客户':
|
orgid = await self.caller.get_accounting_orgid(sor, leg.orgtype)
|
||||||
orgid = self.customerid
|
org1id = None if leg.org1type is None else \
|
||||||
elif leg['orgtype'] == '分销商':
|
await self.caller.get_account_orgid(sor, leg.org1type)
|
||||||
orgid = self.resellerid
|
acc = await get_account(sor, accounting_orgid, orgid, leg.subjectid, org1id=org1id)
|
||||||
elif leg['orgtype'] == '供应商':
|
if acc is None:
|
||||||
orgid = self.providerid
|
debug('can not get accountid {accounting_orgid=}, {leg=}')
|
||||||
accid = await getAccountByName(sor,
|
|
||||||
self.accounting_orgid,
|
|
||||||
orgid,
|
|
||||||
leg['subjectname'])
|
|
||||||
if accid is None:
|
|
||||||
print('can not get accountid', self.accounting_orgid, orgid, leg['subjectname'], leg['id'])
|
|
||||||
raise AccountIdNone(self.accounting_orgid, orgid, leg['subjectname'])
|
raise AccountIdNone(self.accounting_orgid, orgid, leg['subjectname'])
|
||||||
leg['orgid'] = orgid
|
await self.leg_accounting(sor, acc.id, leg)
|
||||||
await self.leg_accounting(sor, accid, leg)
|
|
||||||
if self.realtimesettled:
|
|
||||||
x = await self.is_business_owner()
|
|
||||||
if x:
|
|
||||||
await self.write_settle_log()
|
|
||||||
|
|
||||||
async def write_settle_log(self):
|
async def write_settle_log(self):
|
||||||
sale_mode = {
|
sale_mode = {
|
||||||
@ -399,57 +232,3 @@ where accountid=${accid}$
|
|||||||
}
|
}
|
||||||
await sor.C('acc_detail', ns.copy())
|
await sor.C('acc_detail', ns.copy())
|
||||||
|
|
||||||
async def get_reseller_salemode(self, orgid):
|
|
||||||
sor = self.sor
|
|
||||||
recs = await sor.sqlExe(self.salemode_sql0,
|
|
||||||
{
|
|
||||||
'bid_orgid':orgid,
|
|
||||||
'providerid':self.providerid,
|
|
||||||
'productid':self.productid,
|
|
||||||
'curdate':self.curdate
|
|
||||||
})
|
|
||||||
if len(recs) == 0:
|
|
||||||
return None
|
|
||||||
return recs[0]['salemode']
|
|
||||||
|
|
||||||
async def get_act_specstr(self):
|
|
||||||
sor = self.sor
|
|
||||||
debug(f'{self.action=} ---')
|
|
||||||
if self.action in [ ACTION_RECHARGE, ACTION_RECHARGE_REVERSE ]:
|
|
||||||
debug(f'{self.action=}, {ACTNAME_RECHARGE=}')
|
|
||||||
return ACTNAME_RECHARGE
|
|
||||||
|
|
||||||
if self.action in [ ACTION_SETTLE, ACTION_SETTLE_REVERSE ]:
|
|
||||||
spec = ACTNAME_SETTLE
|
|
||||||
if self.caller.sale_mode == '0':
|
|
||||||
spec = f'{ACTNAME_SETTLE}-{SALEMODE_DISCOUNT}'
|
|
||||||
elif self.caller.sale_mode == '1':
|
|
||||||
spec = f'{ACTNAME_SETTLE}-{SALEMODE_REBATE}'
|
|
||||||
else:
|
|
||||||
spec = f'{ACTNAME_SETTLE}-{SALEMODE_FLOORPRICE}'
|
|
||||||
debug(f'{self.action=} {spec=}')
|
|
||||||
return spec
|
|
||||||
|
|
||||||
|
|
||||||
ret = ACTNAME_BUY
|
|
||||||
for id in [self.accounting_orgid, self.resellerid]:
|
|
||||||
if id is None:
|
|
||||||
break
|
|
||||||
salemode = await self.get_reseller_salemode(id)
|
|
||||||
if salemode == '0':
|
|
||||||
sale_mode = SALEMODE_DISCOUNT
|
|
||||||
elif salemode == '1':
|
|
||||||
sale_mode = SALEMODE_REBATE
|
|
||||||
else:
|
|
||||||
sale_mode = SALEMODE_FLOORPRICE
|
|
||||||
|
|
||||||
ret += '-' + sale_mode
|
|
||||||
if id == self.accounting_orgid:
|
|
||||||
self.own_salemode = sale_mode
|
|
||||||
else:
|
|
||||||
self.reseller_salemode = sale_mode
|
|
||||||
await self.setup_bill_variable()
|
|
||||||
debug(f'{ret=}')
|
|
||||||
return ret
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -77,6 +77,7 @@ where b.parentid = a.id
|
|||||||
recs = await sor.sqlExe(sql, {'customerid':customerid})
|
recs = await sor.sqlExe(sql, {'customerid':customerid})
|
||||||
if len(recs) == 0:
|
if len(recs) == 0:
|
||||||
debug(f'{customerid=} not found is organziation table')
|
debug(f'{customerid=} not found is organziation table')
|
||||||
|
return ['0']
|
||||||
return []
|
return []
|
||||||
ret = await get_ancestor_orgs(sor, recs[0]['id'])
|
ret = await get_ancestor_orgs(sor, recs[0]['id'])
|
||||||
ret.append(recs[0]['id'])
|
ret.append(recs[0]['id'])
|
||||||
|
@ -1,39 +0,0 @@
|
|||||||
from sqlor.dbpools import DBPools
|
|
||||||
from appPublic.timeUtils import strdate_add
|
|
||||||
from .excep import BusinessDateParamsError
|
|
||||||
from .const import *
|
|
||||||
async def get_business_date(sor=None):
|
|
||||||
async def _f(sor):
|
|
||||||
sql = "select * from params where params_name = 'business_date'"
|
|
||||||
recs = await sor.sqlExe(sql, {})
|
|
||||||
if len(recs) > 0:
|
|
||||||
return recs[0]['params_value']
|
|
||||||
raise BusinessDateParamsError
|
|
||||||
|
|
||||||
if sor:
|
|
||||||
return await _f(sor)
|
|
||||||
db = DBPools()
|
|
||||||
async with db.sqlorContext(DBNAME()) as sor:
|
|
||||||
return await _f(sor)
|
|
||||||
|
|
||||||
async def new_business_date(sor=None):
|
|
||||||
async def _f(sor):
|
|
||||||
dat = await get_business_date(sor)
|
|
||||||
new_dat = strdate_add(dat, days=1)
|
|
||||||
sql = "update params set params_value=${new_dat}$ where params_name='business_date'"
|
|
||||||
await sor.sqlExe(sql, {'new_dat':new_dat})
|
|
||||||
|
|
||||||
if sor:
|
|
||||||
return await _f(sor)
|
|
||||||
db = DBPools()
|
|
||||||
async with db.sqlorContext(DBNAME()) as sor:
|
|
||||||
return await _f(sor)
|
|
||||||
|
|
||||||
async def previous_business_date(sor=None):
|
|
||||||
dat = await get_business_date(sor=sor)
|
|
||||||
return strdate_add(dat, days=-1)
|
|
||||||
|
|
||||||
async def next_business_date(sor=None):
|
|
||||||
dat = await get_business_date(sor=sor)
|
|
||||||
return strdate_add(dat, days=1)
|
|
||||||
|
|
@ -15,7 +15,7 @@ CORP_CUSTOMER = '2'
|
|||||||
PERSONAL = '3'
|
PERSONAL = '3'
|
||||||
PROVIDER = '4'
|
PROVIDER = '4'
|
||||||
|
|
||||||
PARTY_OWNER = '本机构'
|
PARTY_OWNER = '平台'
|
||||||
PARTY_CUSTOMER = '客户'
|
PARTY_CUSTOMER = '客户'
|
||||||
PARTY_RESELLER = '分销商'
|
PARTY_RESELLER = '分销商'
|
||||||
PARTY_PROVIDER = '供应商'
|
PARTY_PROVIDER = '供应商'
|
||||||
|
@ -2,6 +2,55 @@ from sqlor.dbpools import DBPools
|
|||||||
from .const import *
|
from .const import *
|
||||||
from accounting.accountingnode import get_parent_orgid
|
from accounting.accountingnode import get_parent_orgid
|
||||||
|
|
||||||
|
async def get_account(sor, accounting_orgid, orgid, subjectid, org1id=None):
|
||||||
|
ss = "org1id is NULL"
|
||||||
|
if org1id:
|
||||||
|
ss = "org1id = ${org1id}$"
|
||||||
|
|
||||||
|
sql = """select * from account
|
||||||
|
where
|
||||||
|
subjectid = ${subjectid}$ and
|
||||||
|
accounting_orgid = ${accounting_orgid}$ and
|
||||||
|
orgid = ${orgid}$ and
|
||||||
|
""" + ss
|
||||||
|
recs = await sor.sqlExe(sql, {
|
||||||
|
"accounting_orgid":accounting_orgid,
|
||||||
|
"orgid":orgid,
|
||||||
|
"org1id":org1id,
|
||||||
|
"subjectid":subjectid
|
||||||
|
});
|
||||||
|
if len(recs) == 0:
|
||||||
|
return None
|
||||||
|
for rec in recs:
|
||||||
|
if a.org1id == org1id:
|
||||||
|
return rec['id']
|
||||||
|
return None
|
||||||
|
|
||||||
|
async def get_account_by_subjectname(sor, accounting_orgid, orgid, subjectname, org1id=None):
|
||||||
|
ss = "a.org1id is NULL"
|
||||||
|
if org1id:
|
||||||
|
ss = "a.org1id = ${org1id}$"
|
||||||
|
|
||||||
|
sql = """select * from account a, subject b
|
||||||
|
where
|
||||||
|
a.subjectid = b.id and
|
||||||
|
b.name = ${subjectname}$ and
|
||||||
|
a.accounting_orgid = ${accounting_orgid}$ and
|
||||||
|
a.orgid = ${orgid}$ and
|
||||||
|
""" + ss
|
||||||
|
recs = await sor.sqlExe(sql, {
|
||||||
|
"accounting_orgid":accounting_orgid,
|
||||||
|
"orgid":orgid,
|
||||||
|
"org1id":org1id,
|
||||||
|
"subjectname":subjectname
|
||||||
|
});
|
||||||
|
if len(recs) == 0:
|
||||||
|
return None
|
||||||
|
for rec in recs:
|
||||||
|
if a.org1id == org1id:
|
||||||
|
return rec['id']
|
||||||
|
return None
|
||||||
|
|
||||||
async def getAccountByName(sor, accounting_orgid, orgid, name, org1id):
|
async def getAccountByName(sor, accounting_orgid, orgid, name, org1id):
|
||||||
sql = """select a.* from account a, subject b
|
sql = """select a.* from account a, subject b
|
||||||
where a.subjectid = b.id and
|
where a.subjectid = b.id and
|
||||||
|
@ -1,17 +1,17 @@
|
|||||||
|
from appPublic.registerfunction import RegisterFunction
|
||||||
|
from appPublic.dictOBject import DictObject
|
||||||
|
from appPublic.log import debug, exception, error
|
||||||
from ahserver.serverenv import ServerEnv
|
from ahserver.serverenv import ServerEnv
|
||||||
from accounting.openaccount import openAllResellerAccounts
|
from accounting_config import AccountingOrgs
|
||||||
from accounting.openaccount import openAllCustomerAccounts
|
|
||||||
from accounting.openaccount import openAllProviderAccounts
|
|
||||||
from accounting.openaccount import openRetailRelationshipAccounts
|
|
||||||
from accounting.openaccount import openOwnerAccounts
|
|
||||||
from accounting.recharge import recharge_accounting
|
|
||||||
from accounting.getaccount import getAccountBalance, getCustomerBalance
|
|
||||||
|
|
||||||
def load_accounting():
|
def load_accounting():
|
||||||
g = ServerEnv()
|
g = ServerEnv()
|
||||||
g.openAllResellerAccounts = openAllResellerAccounts
|
|
||||||
g.openAllCustomerAccounts = openAllCustomerAccounts
|
|
||||||
g.openAllProviderAccounts = openAllProviderAccounts
|
|
||||||
g.openRetailRelationshipAccounts = openRetailRelationshipAccounts
|
|
||||||
g.openOwnerAccounts = openOwnerAccounts
|
|
||||||
g.recharge_accounting = recharge_accounting
|
g.recharge_accounting = recharge_accounting
|
||||||
|
g.pay_accounting = pay_accounting
|
||||||
|
g.settle_accounting = settle_accounting
|
||||||
|
g.open_customer_account = open_customer_account
|
||||||
|
g.open_reseller_account = open_reseller_account
|
||||||
|
g.open_provider_account = open_provider_account
|
||||||
|
g.open_owner_account = open_owner_account
|
||||||
|
g.get_customer_balance = get_customer_balance
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
from sqlor.dbpools import DBPools
|
from sqlor.dbpools import DBPools
|
||||||
from .const import *
|
from .const import *
|
||||||
from appPublic.uniqueID import getID
|
from appPublic.uniqueID import getID
|
||||||
from appPublic.registerfunction import RegisterFunction
|
from appPublic.registerfunction import RegisterFunction, rfexe
|
||||||
from appPublic.log import debug, exception
|
from appPublic.log import debug, exception
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
@ -28,17 +28,20 @@ async def openPartyAccounts(sor, accounting_orgid, orgid, party_type, org1id=Non
|
|||||||
ns['party1type'] = party1_type
|
ns['party1type'] = party1_type
|
||||||
|
|
||||||
sql = """select a.*, b.id as subjectid, b.balance_side from account_config a, subject b
|
sql = """select a.*, b.id as subjectid, b.balance_side from account_config a, subject b
|
||||||
where a.subjectname = b.name """
|
where a.subjectid = b.id """ \
|
||||||
+ addon_cond + """
|
+ addon_cond + """
|
||||||
and a.partytype=${partytype}$ """
|
and a.partytype=${partytype}$ """
|
||||||
recs = await sor.sqlExe(sql, ns)
|
recs = await sor.sqlExe(sql, ns)
|
||||||
# print(f'select account_config {recs=}', party_type)
|
# print(f'select account_config {recs=}', party_type)
|
||||||
|
debug(f'{sql=}, {orgid=}, {party_type=}')
|
||||||
for r in recs:
|
for r in recs:
|
||||||
|
debug(f'{r=}')
|
||||||
await openAccount(sor, accounting_orgid, orgid, r, org1id=org1id)
|
await openAccount(sor, accounting_orgid, orgid, r, org1id=org1id)
|
||||||
|
|
||||||
async def _openPartyAccounts(accounting_orgid, orgid, party_type):
|
async def _openPartyAccounts(accounting_orgid, orgid, party_type):
|
||||||
db = DBPools()
|
db = DBPools()
|
||||||
async with db.sqlorContext(DBNAME()) as sor:
|
dbname = await rfexe('get_module_dbname', 'accounting')
|
||||||
|
async with db.sqlorContext(dbname) as sor:
|
||||||
await openPartyAccounts(sor, accounting_orgid, orgid, party_type)
|
await openPartyAccounts(sor, accounting_orgid, orgid, party_type)
|
||||||
|
|
||||||
async def openResellerAccounts(sor, accounting_orgid, orgid):
|
async def openResellerAccounts(sor, accounting_orgid, orgid):
|
||||||
@ -89,7 +92,8 @@ async def openAllProviderAccounts(sor, accounting_orgid):
|
|||||||
|
|
||||||
async def openRetailRelationshipAccounts(sor, accounting_orgid, providerid, resellerid):
|
async def openRetailRelationshipAccounts(sor, accounting_orgid, providerid, resellerid):
|
||||||
db = DBPools()
|
db = DBPools()
|
||||||
async with db.sqlorContext(DBNAME()) as sor:
|
dbname = await rfexe('get_module_dbname', 'accounting')
|
||||||
|
async with db.sqlorContext(dbname) as sor:
|
||||||
await openPartyAccounts(sor, accounting_orgid, providerid, PARTY_PROVIDER,
|
await openPartyAccounts(sor, accounting_orgid, providerid, PARTY_PROVIDER,
|
||||||
org1id=resellerid,
|
org1id=resellerid,
|
||||||
party1_type=PARTY_RESELLER)
|
party1_type=PARTY_RESELLER)
|
||||||
|
@ -4,9 +4,8 @@ from appPublic.uniqueID import getID
|
|||||||
from sqlor.dbpools import DBPools
|
from sqlor.dbpools import DBPools
|
||||||
from appPublic.timeUtils import curDateString
|
from appPublic.timeUtils import curDateString
|
||||||
from appPublic.argsConvert import ArgsConvert
|
from appPublic.argsConvert import ArgsConvert
|
||||||
from .accounting_config import get_accounting_config, AccountingOrgs
|
from .accounting_config import get_accounting_config, Accounting
|
||||||
from .const import *
|
from .const import *
|
||||||
from .accountingnode import get_accounting_nodes
|
|
||||||
from .excep import *
|
from .excep import *
|
||||||
from .getaccount import getAccountByName
|
from .getaccount import getAccountByName
|
||||||
from .businessdate import get_business_date
|
from .businessdate import get_business_date
|
||||||
@ -16,9 +15,8 @@ class RechargeAccounting:
|
|||||||
self.db = DBPools()
|
self.db = DBPools()
|
||||||
self.recharge_log = recharge_log
|
self.recharge_log = recharge_log
|
||||||
self.customerid = recharge_log['customerid']
|
self.customerid = recharge_log['customerid']
|
||||||
self.summary = recharge_log['summary']
|
self.orderid = recharge_log['orderid']
|
||||||
self.orderid = None
|
self.curdate = recharge_log['transdate']
|
||||||
self.curdate = recharge_log['recharge_date']
|
|
||||||
self.transamount = recharge_log['recharge_amt']
|
self.transamount = recharge_log['recharge_amt']
|
||||||
self.timestamp = datetime.now()
|
self.timestamp = datetime.now()
|
||||||
self.productid = None
|
self.productid = None
|
||||||
@ -26,6 +24,10 @@ class RechargeAccounting:
|
|||||||
self.action = recharge_log['action']
|
self.action = recharge_log['action']
|
||||||
self.summary = self.action
|
self.summary = self.action
|
||||||
self.billid = getID()
|
self.billid = getID()
|
||||||
|
self.variable = {
|
||||||
|
"交易金额":100,
|
||||||
|
"充值费率":0.003,
|
||||||
|
}
|
||||||
self.bill = {
|
self.bill = {
|
||||||
'id':self.billid,
|
'id':self.billid,
|
||||||
'customerid':self.recharge_log['customerid'],
|
'customerid':self.recharge_log['customerid'],
|
||||||
@ -38,18 +40,15 @@ class RechargeAccounting:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
async def get_account(self, leg):
|
||||||
|
if leg.orgtype == '平台':
|
||||||
async def accounting(self, sor):
|
async def accounting(self, sor):
|
||||||
self.sor = sor
|
self.sor = sor
|
||||||
bz_date = await get_business_date(sor=sor)
|
bz_date = await get_business_date(sor=sor)
|
||||||
if bz_date != self.curdate:
|
if bz_date != self.curdate:
|
||||||
raise AccountingDateNotInBusinessDate(self.curdate, bz_date)
|
raise AccountingDateNotInBusinessDate(self.curdate, bz_date)
|
||||||
|
|
||||||
nodes = await get_accounting_nodes(sor, self.customerid)
|
ao = Accounting(self, nodes[i], self.customerid,
|
||||||
lst = len(nodes) - 1
|
|
||||||
self.accountingOrgs = []
|
|
||||||
for i, n in enumerate(nodes):
|
|
||||||
if i < lst:
|
|
||||||
ao = AccountingOrgs(self, nodes[i], self.customerid,
|
|
||||||
resellerid=nodes[i+1])
|
resellerid=nodes[i+1])
|
||||||
else:
|
else:
|
||||||
ao = AccountingOrgs(self, nodes[i], self.customerid)
|
ao = AccountingOrgs(self, nodes[i], self.customerid)
|
||||||
@ -63,14 +62,14 @@ class RechargeAccounting:
|
|||||||
await sor.C('bill', self.bill.copy())
|
await sor.C('bill', self.bill.copy())
|
||||||
# await sor.C('recharge_log', self.recharge_log.copy())
|
# await sor.C('recharge_log', self.recharge_log.copy())
|
||||||
|
|
||||||
async def recharge_accounting(sor, customerid, action, logid, trnasdate, recharge_amt):
|
async def recharge_accounting(sor, customerid, action, orderid, transdate, recharge_amt):
|
||||||
"""
|
"""
|
||||||
summary:recharge channe(handly, wechat, alipay)
|
summary:recharge channe(handly, wechat, alipay)
|
||||||
"""
|
"""
|
||||||
recharge_log = {
|
recharge_log = {
|
||||||
"customerid":customerid,
|
"customerid":customerid,
|
||||||
"recharge_date":transdate,
|
"transdate":transdate,
|
||||||
"recharge_logid":logid,
|
"orderid":orderid,
|
||||||
"recharge_amt":recharge_amt,
|
"recharge_amt":recharge_amt,
|
||||||
"action":action,
|
"action":action,
|
||||||
}
|
}
|
||||||
|
@ -1,21 +1,14 @@
|
|||||||
|
import asyncio
|
||||||
from sqlor.dbpools import DBPools
|
from sqlor.dbpools import DBPools
|
||||||
from appPublic.jsonConfig import getConfig
|
from appPublic.jsonConfig import getConfig
|
||||||
from appPublic.dictObject import DictObject
|
from appPublic.dictObject import DictObject
|
||||||
from accounting.recharge import RechargeAccounting
|
from accounting.recharge import recharge_accounting
|
||||||
from run_test import run
|
|
||||||
|
|
||||||
async def test1():
|
async def test1():
|
||||||
rl = DictObject()
|
|
||||||
rl.customerid = '4zXVMkBCEaTmR0xwneUBX'
|
|
||||||
rl.recharge_date = '2024-09-21'
|
|
||||||
rl.recharge_amt = 100
|
|
||||||
rl.action = 'RECHARGE'
|
|
||||||
rl.orderid = '1'
|
|
||||||
rl.recharge_channel = 'alipay'
|
|
||||||
ra = RechargeAccounting(rl)
|
|
||||||
db = DBPools()
|
db = DBPools()
|
||||||
async with db.sqlorContext('sage') as sor:
|
dbname = 'sage'
|
||||||
await ra.accounting(sor)
|
async with db.sqlorContext(dbname) as sor:
|
||||||
|
await recharge_accounting(sor, '4twr0MGHMZ4aFHYzQ9Lxh', 'RECHARGE', 'oEdlkg4SfX6JH5xQnCHW', '2025-01-10', 100)
|
||||||
|
|
||||||
async def test2():
|
async def test2():
|
||||||
rl = DictObject()
|
rl = DictObject()
|
||||||
@ -35,4 +28,20 @@ async def test():
|
|||||||
await test2()
|
await test2()
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
run(test)
|
DBPools({
|
||||||
|
"sage":{
|
||||||
|
"driver":"aiomysql",
|
||||||
|
"async_mode":True,
|
||||||
|
"coding":"utf8",
|
||||||
|
"maxconn":100,
|
||||||
|
"dbname":"sage",
|
||||||
|
"kwargs":{
|
||||||
|
"user":"test",
|
||||||
|
"db":"sage",
|
||||||
|
"password":"QUZVcXg5V1p1STMybG5Ia6mX9D0v7+g=",
|
||||||
|
"host":"localhost"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
asyncio.get_event_loop().run_until_complete(test1())
|
||||||
|
|
||||||
|
@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"widgettype":"VBox",
|
|
||||||
"options":{
|
|
||||||
"height":"100%"
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,5 +0,0 @@
|
|||||||
debug(f'{params_kw=}')
|
|
||||||
return {
|
|
||||||
'status':'ok',
|
|
||||||
'message':'is ok'
|
|
||||||
}
|
|
@ -1,5 +0,0 @@
|
|||||||
debug(f'{params_kw=}')
|
|
||||||
return {
|
|
||||||
'status':'ok',
|
|
||||||
'message':'is ok'
|
|
||||||
}
|
|
@ -1,31 +0,0 @@
|
|||||||
{
|
|
||||||
"widgettype":"Form",
|
|
||||||
"options":{
|
|
||||||
"fields":[
|
|
||||||
{
|
|
||||||
"name":"recharge_amt",
|
|
||||||
"uitype":"float",
|
|
||||||
"required":true,
|
|
||||||
"label":"充值金额"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"channel",
|
|
||||||
"label":"选择充值方式",
|
|
||||||
"uitype":"checkbox",
|
|
||||||
"multicheck":false,
|
|
||||||
"required":true,
|
|
||||||
"value":"alipay",
|
|
||||||
"data":[
|
|
||||||
{
|
|
||||||
"value":"alipay",
|
|
||||||
"text":"支付宝"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"value":"wechatpay",
|
|
||||||
"text":"微信支付"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"widgettype":"VBox",
|
|
||||||
"options":{
|
|
||||||
"height":"100%"
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user