Commit 2e47a235 authored by 李宗熹's avatar 李宗熹

添加对账单接口

parent 94d66863
# -*- coding: UTF-8 -*-
"""
@author:Zongxi.Li
@file:statement.py
@time:2021/02/02
"""
import json
from datetime import datetime, date
from decimal import Decimal
from flask_restful import Resource, reqparse
from app.service.statement_service import Statement
from app.utils.auth import login_require
from flask import g
class DateEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, (datetime, date)):
return obj.__str__()
if isinstance(obj, Decimal):
return obj.__float__()
return json.JSONEncoder.default(self, obj)
class StatementController(Resource):
def __init__(self):
"""."""
self.parser = reqparse.RequestParser()
@login_require
def get(self):
""""""
# self.parser.add_argument('user_id', type=str, required=True, help='用户id不能为空')
self.parser.add_argument('statement_time', required=False, help='对账单时间戳')
args = self.parser.parse_args()
print(args.get('statement_time'))
# user_id = args.get('user_id')
user_id = g.ifa_id
print(user_id)
if args.get('statement_time') != '':
year = datetime.fromtimestamp(int(args.get('statement_time')) / 1000).year
month = datetime.fromtimestamp(int(args.get('statement_time')) / 1000).month
else:
year = datetime.now().year
month = datetime.now().month - 1
data = Statement(user_id=user_id, year=year, month=month).summary()
resp = {
"statusCode": "0000",
"message": "成功",
"attributes": data
}
return json.loads(json.dumps(resp, cls=DateEncoder, ensure_ascii=False))
\ No newline at end of file
......@@ -10,6 +10,7 @@ from app.controller.customer import CustomerList
from app.controller.fund import FundEvaluation
from app.controller.report import *
from app.controller.template_manage import *
from app.controller.statement import StatementController
def add_route(api):
"""注册路由"""
......@@ -20,4 +21,6 @@ def add_route(api):
api.add_resource(TemplateList, '/api/template_list')
api.add_resource(CustomerList, '/api/customer_list')
api.add_resource(FundEvaluation, '/api/fund_evaluation')
api.add_resource(StatementController, '/api/statement')
# -*- coding: UTF-8 -*-
"""
@author:Zongxi.Li
@file:statement_service.py
@time:2021/02/01
"""
import json
import pandas as pd
import numpy as np
from datetime import datetime, date
from decimal import Decimal
from app.api.engine import tamp_order_engine, tamp_user_engine, tamp_diagnose_app_engine, TAMP_SQL
# from app.service.data_service_v2_1 import *
from app.service.customer import get_customer_list
from app.service.portfolio_diagnose import get_fund_name
class DateEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, (datetime, date)):
return obj.__str__()
if isinstance(obj, Decimal):
return obj.__float__()
return json.JSONEncoder.default(self, obj)
def get_order_info(user_id):
with TAMP_SQL(tamp_diagnose_app_engine) as tamp_diagnose_app:
tamp_diagnose_app_session = tamp_diagnose_app.session
sql_user = """select f1.fund_id, f2.realname, f3.customer_name, f1.customer_id, f3.valueSex,f1.type,f1.order_type,f1.pay_date,f1.subscription_fee,f1.confirm_share_date,f1.confirm_share,f1.confirm_amount,f1.nav,f1.folio_name from tamp_diagnose_app.customer_order_view f1, tamp_user.user_info f2,tamp_diagnose_app.customer_view f3 where f2.id=f1.user_id and f3.id=f1.customer_id and f1.delete_tag=0 and user_id='{}'""".format(
user_id)
cur = tamp_diagnose_app_session.execute(sql_user)
data = cur.fetchall()
order_df = pd.DataFrame(list(data),
columns=['fund_id', 'username', 'customer_name', 'customer_id', 'valueSex', 'type',
'order_type',
'pay_date',
'subscription_fee', 'confirm_share_date', 'confirm_share',
'confirm_amount', 'nav', 'folio_name'])
return order_df
def get_provision_info(user_id):
with TAMP_SQL(tamp_order_engine) as tamp_order, TAMP_SQL(tamp_user_engine) as tamp_user:
tamp_order_session = tamp_order.session
# sql = """select f1.ifa_id, f1.customer_id, f1.fund_id, f1.fund_nav,
# f1.fund_nav_date, f1.predict_date, f1.pro_date, f1.manage_predict_fee, f1.permc_exc_predict_fee, f1.permc_rem_fee,
# f1.recommend_ifa_id, f1.recommend_fee, f1.permc_recommend_fee, f1.incentive_fee_ratio, f1.retention_shares
# from ifa_provision_day_info as f1 where f1.ifa_id='{}'""".format(user_id)
sql = """SELECT * FROM `ifa_provision_day_info` WHERE `ifa_id` = '{}'""".format(user_id)
cur = tamp_order_session.execute(sql)
data = cur.fetchall()
provision_df = pd.DataFrame(list(data),
columns=['id', 'ifa_id', 'customer_id', 'fund_id', 'order_id', 'fund_nav', 'fund_nav_date',
'predict_date', 'pro_date','pro_type',
'manage_predict_fee', 'permc_exc_predict_fee', 'permc_rem_predict_fee',
'manage_fee', 'permc_exc_fee','permc_rem_fee', 'recommend_ifa_id',
'recommend_fee','permc_recommend_fee', 'incentive_fee_ratio',
'deduction','retention_shares','status'])
return provision_df
def get_end_date(year, month):
if month == 12:
end_date = datetime(year=year + 1, month=1, day=1)
else:
end_date = datetime(year=year, month=month + 1, day=1)
return end_date
def get_month_list(quarter, year):
if quarter == 4:
year = year - 1
else:
year = year
month_list = range((quarter - 1) * 3 + 1, quarter * 3 + 1)
return year, month_list
def type2note(type):
type2note_dict = {1: "申购",
2: "追加",
3: "赎回",
4: "分红再投",
5: "现金分红"}
return type2note_dict.get(type)
def cal_total_amount(df):
purchase_amount = df[df['order_type'].isin([1, 2])]['confirm_amount'].sum()
redem_amount = df[df['order_type'] == 3]['confirm_amount'].sum()
total_amount = purchase_amount - redem_amount
return total_amount
def num2chinese(number):
num2chinese_dict = {1: '一',
2: '二',
3: '三',
4: '四'}
return num2chinese_dict.get(number)
class Statement(object):
def __init__(self, user_id, year, month):
self.user_id = user_id
self.year = year
self.month = month
self.quarter = (self.month - 1) // 3
if self.quarter == 0:
self.quarter = 4
self.ifa_order = self.order_history()
self.ifa_provision = self.provision_history()
def order_history(self):
ifa_order = get_order_info(self.user_id)
end_date = get_end_date(self.year, self.month)
order_history = ifa_order[ifa_order['pay_date'] < end_date]
# ifa_order['fund_name'] = ifa_order['fund_id'].apply(lambda x: get_fund_name(x, fund_type=2).values[0][0])
return order_history
def provision_history(self):
ifa_provision = get_provision_info(self.user_id)
end_date = get_end_date(self.year, self.month)
provision_history = ifa_provision[ifa_provision['predict_date'] < end_date.date()]
return provision_history
def process_provision(self):
year, month_list = get_month_list(self.quarter, self.year)
start_date = date(year=year, month=min(month_list), day=1)
end_date = get_end_date(year, max(month_list))
provision_quarterly = self.ifa_provision[
(self.ifa_provision['predict_date'] >= start_date) &
(self.ifa_provision['predict_date'] < end_date.date())]
processed_provision = list(provision_quarterly.groupby([provision_quarterly.customer_id,
provision_quarterly.fund_id]))
return processed_provision
def trade_record(self):
ifa_cus_order_info = list(self.ifa_order.groupby(self.ifa_order.customer_id))
trade_record_data = []
for customer in ifa_cus_order_info:
customer_df = customer[1]
df_length = customer_df['fund_id'].count()
detail = []
for i in range(df_length):
detail.append({'fund': customer_df['fund_id'].values[i],
'pay_date': np.datetime_as_string(customer_df['pay_date'].values[i], unit='D'),
'confirm_share_date': np.datetime_as_string(customer_df['confirm_share_date'].values[i],
unit='D'),
'confirm_amount': customer_df['confirm_amount'].values[i],
'nav': customer_df['nav'].values[i],
'confirm_share': customer_df['confirm_share'].values[i],
'note': type2note(customer_df['order_type'].values[i])
})
purchase_amount = customer_df[customer_df['order_type'].isin([1, 2])]['confirm_amount'].sum()
redam_amount = customer_df[customer_df['order_type'] == 3]['confirm_amount'].sum()
total_amount = purchase_amount - redam_amount
trade_record_data.append({'customer': customer_df['customer_name'].values[0],
'total_amount': Decimal(round(float(total_amount) / 10000.0, 2)),
'detail': detail})
if len(ifa_cus_order_info) == 0:
trade_record_data = [{'customer': '',
'total_amount': '',
'detail': [{'fund': '',
'pay_date': '',
'confirm_share_date': '',
'confirm_amount': '',
'nav': '',
'confirm_share': '',
'note': ''}]}]
return trade_record_data
def month_remain(self):
year, month_list = get_month_list(self.quarter, self.year)
month_remain_data = {}
month_detail = []
quarter_amount = 0
for month in month_list:
end_date = get_end_date(year, month)
order_history = self.ifa_order[self.ifa_order['pay_date'] < end_date]
df_length = order_history['fund_id'].count()
if df_length > 0:
month_amount = cal_total_amount(order_history)
else:
month_amount = 0
single_month = {'month': str(month) + '月', 'month_amount': month_amount}
quarter_amount += month_amount
month_detail.append(single_month)
quarter = num2chinese(self.quarter)
month_detail.append(
{'month': quarter + '季度月均存量', 'month_amount': Decimal(round(float(quarter_amount) / 3.0, 2))})
month_remain_data['month_detail'] = month_detail
bonus_policy = []
bonus_policy.append({'month_achieve': '达到1000万以上', 'bonus_policy_item': '标准管理费分成+0.1%'})
month_remain_data['bonus_policy'] = bonus_policy
bonus_image = 'https://tamp-pro.oss-cn-shanghai.aliyuncs.com/upload/CS_FILE_RECORD16081436133319.png'
month_remain_data['bonus_image'] = bonus_image
return month_remain_data
def subscription_fee(self):
year, month_list = get_month_list(self.quarter, self.year)
subscription_data = {}
customer_detail = []
total_before_tax = 0
total_after_tax = 0
start_date = datetime(year=year, month=min(month_list), day=1)
end_date = get_end_date(year, max(month_list))
order_quarterly = self.ifa_order[(self.ifa_order['pay_date'] >= start_date) &
(self.ifa_order['pay_date'] < end_date) &
(self.ifa_order['order_type'] != 4)]
ifa_cus_order_monthly = list(order_quarterly.groupby(order_quarterly.customer_id))
for customer in ifa_cus_order_monthly:
customer_df = customer[1]
df_length = customer_df['fund_id'].count()
before_tax = 0
after_tax = 0
detail = []
for i in range(df_length):
try:
tax_rate = get_tax_rate()
except:
tax_rate = 0
detail.append({'fund': customer_df['fund_id'].values[i],
'confirm_amount': customer_df['confirm_amount'].values[i],
'pay_date': np.datetime_as_string(customer_df['pay_date'].values[i], unit='D'),
'subscription_fee': customer_df['subscription_fee'].values[i],
'tax': customer_df['subscription_fee'].values[i] * tax_rate
})
before_tax += customer_df['subscription_fee'].values[i]
after_tax += customer_df['subscription_fee'].values[i] * (1 - tax_rate)
customer_detail.append({'customer': customer_df['customer_name'].values[0],
'before_tax': Decimal(round(float(before_tax), 2)),
'after_tax': Decimal(round(float(after_tax), 2)),
'detail': detail})
total_before_tax += before_tax
total_after_tax += after_tax
subscription_data['total_before_tax'] = total_before_tax
subscription_data['total_tax'] = total_before_tax - total_after_tax
subscription_data['total_after_tax'] = total_after_tax
subscription_data['customer_detail'] = customer_detail
if len(ifa_cus_order_monthly) == 0:
subscription_data['customer_detail'] = [{'customer': '',
'before_tax': '',
'after_tax': '',
'detail': [{'fund': '',
'confirm_amount': '',
'pay_date': '',
'subscription_fee': '',
'tax': ''}]}]
return subscription_data
def manage_fee(self):
manage_data = {}
total_before_tax = 0
total_after_tax = 0
customer_detail = []
processed_provision = self.process_provision()
for customer_fund in processed_provision:
customer_fund_df = customer_fund[1]
df_length = customer_fund_df['predict_date'].count()
before_tax = 0
after_tax = 0
detail = []
for i in range(df_length):
try:
tax_rate = get_tax_rate()
except:
tax_rate = 0
detail.append({
'hold_share': customer_fund_df['retention_shares'].values[i],
'date': customer_fund_df['predict_date'].values[i].strftime('%Y-%m-%d'),
'manage_fee': customer_fund_df['manage_fee'].values[i],
'tax': customer_fund_df['manage_fee'].values[i] * tax_rate
})
before_tax += customer_fund_df['manage_fee'].values[i]
after_tax += customer_fund_df['manage_fee'].values[i] * (1 - tax_rate)
customer_detail.append({'customer': customer_fund_df['customer_id'].values[0],
'fund': customer_fund_df['fund_id'].values[0],
'before_tax': round(float(before_tax), 2),
'after_tax': round(float(after_tax), 2),
'detail': detail})
total_before_tax += before_tax
total_after_tax += after_tax
manage_data['total_before_tax'] = total_before_tax
manage_data['total_tax'] = total_before_tax - total_after_tax
manage_data['total_after_tax'] = total_after_tax
manage_data['customer_detail'] = customer_detail
if len(processed_provision) == 0:
manage_data['customer_detail'] = [{'customer': '',
'before_tax': '',
'after_tax': '',
'detail': [{'fund': '',
'confirm_amount': '',
'pay_date': '',
'manage_fee': '',
'tax': ''}]}]
return manage_data
def bill_month(self):
return str(self.year) + '年' + str(self.month) + '月'
def user_name(self):
return "王菲女士"
def summary(self):
summary_data = {}
summary_data['bill_month'] = self.bill_month()
summary_data['user_name'] = self.user_name()
summary_data['quarter'] = num2chinese(self.quarter)
summary_data['trade_record'] = self.trade_record()
summary_data['month_remain'] = self.month_remain()
summary_data['subscription_fee'] = self.subscription_fee()
summary_data['manage_fee'] = self.manage_fee()
# summary_data['manage_fee'] = {'total_before_tax': Decimal('20000.00'),
# 'total_after_tax': Decimal('20000.00'),
# 'total_tax': Decimal('0.00'),
# 'customer_detail':
# [{'customer': "王小帅",
# 'before_tax': 2000.01,
# 'detail': [
# {'date': "2020-09-01",
# 'hold_share': Decimal('2000.00'),
# 'nav': Decimal(1.0083),
# 'manage_fee_day': Decimal('10.00')}
# ]}]}
summary_data['carry'] = {'total_before_tax': Decimal('20000.00'),
'total_after_tax': Decimal('20000.00'),
'total_tax': Decimal('0.00'),
'fund_detail':
[{'fund': "无量",
'before_tax': 2000.01,
'detail': [
{'customer': "王小帅",
'order_type': "申购",
'confirm_date': "2020-09-01",
'native_amount': Decimal('10000000.00'),
'nav': Decimal(1.0083),
'provision_date': "2020-09-01",
'provision_carry': Decimal('10000000.00')}]}]}
summary_data['incentive'] = {'total_before_tax': Decimal('20000.00'),
'total_after_tax': Decimal('20000.00'),
'total_tax': Decimal('0.00'),
'customer_detail':
[{
'customer': '熊大',
'fund': "无量",
'before_tax': 2000.01,
'detail': [
{
'date': "2020-09-01",
'hold_share': Decimal('10000000.00'),
'nav': Decimal(1.0083),
'incentive_day': Decimal(10.00)}]}]}
summary_data['recommend_bonus'] = {'total_before_tax': Decimal('20000.00'),
'total_after_tax': Decimal('20000.00'),
'total_tax': Decimal('0.00'),
'referral_detail':
[{'referral': "王铁柱",
'customer': '熊大',
'fund': "无量",
'before_tax': 2000.01,
'detail': [
{
'date': "2020-09-01",
'hold_share': Decimal('10000000.00'),
'nav': Decimal(1.0083),
'recommend_bonus_day': Decimal(10.00)}]}]}
summary_data['summary'] = {'total_after_tax': Decimal('1000000.00'),
'detail': [{'item': "已结算申购费用", 'amount': Decimal('100000.00'), 'note': ''},
{'item': "已结算管理费用", 'amount': Decimal('100000.00'), 'note': ''},
{'item': "已结算业绩报酬费用", 'amount': Decimal('100000.00'), 'note': ''},
{'item': "已结算业绩激励奖金", 'amount': Decimal('100000.00'), 'note': ''},
{'item': "已结算推荐费", 'amount': Decimal('100000.00'), 'note': ''},
{'item': "2020年三季度待结算佣金", 'amount': Decimal('100000.00'), 'note': ''}
]}
return summary_data
if __name__ == '__main__':
ret = Statement(user_id='USER_INFO15914346866762', year=2020, month=12).summary()
print(json.dumps(ret, cls=DateEncoder, ensure_ascii=False))
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment