async def zj_get_bill(nss={}): """ if nss['user_id'] can get single person bill passing parameters: billMonth, payTime, user_id :param nss: "billMonth": "2023-08" / "payTime": "2023/08/07" :return: """ # logger = logging.getLogger('job_info') # logging.basicConfig(level=logging.INFO, # format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s', # datefmt='%Y-%m-%d %H:%M:%S', # filename='zj_bill_scheduler.log', # filemode='a') # nss = { # 'orgid': '', # 'billMonth': '', # 'payTime': '' # } # if not begin and end time, get current day # 获取当前时间 now_time = datetime.datetime.now() # 获取前一天时间 end_time = now_time + datetime.timedelta(days=-1) # 前一天时间只保留 年-月-日 enddate = end_time.strftime('%Y/%m/%d') if not nss.get('billMonth'): nss['billMonth'] = time.strftime('%Y-%m') if not nss.get('payTime'): nss['payTime'] = enddate print("中金账单时间billMonth: %s, payTime: %s" % (nss.get('billMonth'), nss.get('payTime'))) ns = { 'ak': 'c752863753f8', 'sk': 'c6efdbd682084a2f96e7500e5a535449', 'appId': 'cdz-server', # 'userid': 'sa-9_B-VjlnhaUzAzUvZt', "supId": "99", "page": "1", "limit": "1000", # "billMonth": "2023-08", "billMonth": nss.get('billMonth'), # "payTime": "2023/08/07" "payTime": nss.get('payTime') } ak = ns.get('ak') sk = ns.get('sk') appId = ns.get('appId') if not (ak and sk and appId): return { "code":"1", "msg":"ak or sk or appId is None" } timestamp = str(int(time.time() * 1000)) token = str(uuid()) sign = sk + appId + token + timestamp md5_object = hashlib.md5() md5_object.update(sign.encode()) sign = md5_object.hexdigest() db = DBPools() async with db.sqlorContext('kboss') as sor: # 获取中金id jncs_li = await sor.R('organization', {'orgname': '中金超算', 'del_flg': '0'}) jscs_id = jncs_li[0].get('id') # get sync already user users_li = await sor.R('zj_users', {'sync_status': 1, 'del_flg': '0'}) # filter single person if nss.get('user_id'): users_li = [1] for user in users_li: nss['orgid'] = user.get('orgid') # find uin from zj_user if nss.get('orgid'): orgid = nss.get('orgid') else: orgid_li = await sor.R('users', {'id': await get_user()}) orgid = orgid_li[0].get('orgid') if orgid_li else '' # 这个人所在的销售机构id parent_find_li = await sor.R('organization', {'id': orgid}) parent_id = parent_find_li[0].get('parentid') if parent_find_li else '' uin_li = await sor.R('zj_users', {'orgid': orgid}) uin = uin_li[0].get('thirdid') if uin_li else '' if not (orgid and uin): return { 'status': False, 'msg': 'get bill failed, orgid or uin is empty...' } url = 'http://101.36.139.188:8888/cdz-admin/zjapi/v1/bill/list' header = { 'content-type': 'application/json', 'appId': appId, 'ak': ak, 'timestamp': timestamp, 'token': token, 'sign': sign } data = { "supId": '99', "uin": uin, "page": ns.get('page'), "limit": ns.get('limit') or '1000', "billMonth": ns.get('billMonth'), "payTime": ns.get('payTime') } res = requests.post(url=url, headers=header, json=data) res_data = json.loads(res.text) code = json.loads(res.text).get('code') if code != 200: return res_data else: data_list = res_data.get('data').get('list') if res_data.get('data') else [] # get all bill id bills = await sor.R('zj_bill', {}) orderid_list = [bill.get('zj_orderid') for bill in bills] if data_list: try: for bill_local in data_list: existid = bill_local.get('orderId') # TODO 字段唯一性 如何去重字段 if existid in orderid_list: continue bill_local['id'] = uuid() bill_local['customerid'] = orgid bill_local['zj_orderid'] = bill_local.get('orderId') lowercase_dict = {key.lower(): value for key, value in bill_local.items()} # add zj_bill await sor.C('zj_bill', lowercase_dict) # TODO zj_orderId 字段修改 payTime不是null create_at字段失效 # modify the starting time through fee time update_order_time_sql = """UPDATE customer_goods set start_date = '%s', expire_date = '%s'WHERE orderid = '%s';""" % \ (lowercase_dict['feebegintime'], lowercase_dict['feeendtime'], lowercase_dict['orderid']) await sor.sqlExe(update_order_time_sql, {}) actionTypeName = bill_local['actionTypeName'] if '退款' in actionTypeName: business_op = 'BUY_REVERSE' else: business_op = 'BUY' # 计算折扣后的价格 # 获取针对个人的折扣配置 real_discount = 1.0 person_discount_sql = """select * from saleprotocol where offer_orgid = '%s' and bid_orgid = '%s' and salemode = '0' and del_flg = '0' and CURRENT_DATE <= end_date and CURRENT_DATE >= start_date""" % (parent_id, orgid) tongyi_discount_sql = """select * from saleprotocol where offer_orgid = '%s' and bid_orgid = '*' and salemode = '0' and del_flg = '0' and CURRENT_DATE <= end_date and CURRENT_DATE >= start_date""" % parent_id # 没有个人配置 获取中金产品统一配置折扣 for sql_detail in [person_discount_sql, tongyi_discount_sql]: person_discount_li = await sor.sqlExe(sql_detail, {}) for person_discount in person_discount_li: protocolid = person_discount['id'] xieyi_zi_search_li = await sor.R('product_salemode', {'protocolid': protocolid, 'del_flg': '0'}) for xieyi_zi in xieyi_zi_search_li: # 协议会同时存在两个产品 一个是正常产品id 另外一个是* # *会存在 此处过滤 不会影响折扣设置 if xieyi_zi['productid'] == '*': continue provider_zi_id = xieyi_zi['providerid'] zi_discount = xieyi_zi['discount'] if provider_zi_id == jscs_id: # 判断产品是否存在 有可能在产品表已经删除 prd_res_exists_li = await sor.R('product', {'id': xieyi_zi['productid'], 'del_flg': '0'}) if not prd_res_exists_li: continue real_discount = float(zi_discount) break if real_discount != 1.0: break realcost = float(bill_local.get('realCost')) if bill_local.get('realCost') else 0 # if not realcost assume mistake, but postPay realcost is 0 # if not realcost: # raise ValueError("bill realcost is empty") amount = real_discount * realcost # add bill nss_bill = { 'id': uuid(), 'customerid': orgid, 'orderid': bill_local.get('orderId'), 'business_op': business_op, 'provider_amt': bill_local.get('realCost'), 'amount': amount, 'bill_date': bill_local.get('payTime').split(" ")[0].replace('/', '-'), 'bill_timestamp': bill_local.get('payTime'), 'bill_state': 0, # TODO 字段调整 'productid': bill_local.get('productCode'), 'providerid': jscs_id, 'provider_billid': bill_local['id'], 'resourceid': bill_local.get('resourceId'), 'quantity': 1 } # add data to bill await sor.C('bill', nss_bill) # 比对账户余额和账单金额 balance_yuan = await getCustomerBalance(sor, orgid) print('%s orgid: %s, 余额为: %s' % (time.strftime('%Y-%m-%d %H:%M:%S'), orgid, balance_yuan)) print('将要扣除的金额: %s' % nss_bill['amount']) if not balance_yuan: print('%s 用户%s 余额为空' % (time.strftime('%Y-%m-%d %H:%M:%S'), orgid)) raise ValueError("用户余额为空") if balance_yuan < amount: print('%s 用户%s 余额不足' % (time.strftime('%Y-%m-%d %H:%M:%S'), orgid)) raise ValueError("用户余额不足") # 记账 ba = BillAccounting(nss_bill) await ba.accounting(sor) # 修改本地bill状态 0:未支付,1:已支付;2:已取消 ns_bill_status = { 'id': nss_bill['id'], 'bill_state': 1 } await sor.U('bill', ns_bill_status) # 修改订单状态 0:未支付,1:已交付;2:已关闭;3:已取消;4:后付费 # 获取订单id if not '按量' in bill_local['payModeName']: orderid_get_sql = """SELECT zo.*, bo.id AS boid FROM zj_order zo, bz_order bo WHERE zo.id = bo.provider_orderid AND zo.customerid = '%s' AND zo.orderId = '%s';""" \ % (orgid, bill_local['zj_orderid']) bz_order_id_li = await sor.sqlExe(orderid_get_sql, {}) if not bz_order_id_li: print('无法从zj_order中获取指定orderid, %s' % bill_local) with open('zj_bill.log', 'a+') as f: f.write('%s orgid: %s, 无法从zj_order表中获取orderid: %s' % (time.strftime('%Y-%m-%d %H:%M:%S'), orgid, bill_local)) else: bz_order_id = bz_order_id_li[0]['boid'] ns_order_status = { 'id': bz_order_id, 'order_status': 1 } await sor.U('bz_order', ns_order_status) print('orgid: %s, res_data: %s' % (orgid, res_data)) except Exception as e: print('%s get bill failed' % time.strftime('%Y-%m-%d %H:%M:%S')) raise e else: print('%s orgid: %s bill is emtpy' % (time.strftime('%Y-%m-%d %H:%M:%S'), orgid)) print('%s get all users bill success' % time.strftime('%Y-%m-%d %H:%M:%S')) return { 'status': True, 'msg': 'get bill success' } ret = await zj_get_bill(params_kw) return ret