# coding: utf-8
import sys
import datetime
import pandas as pd
from sqlalchemy import create_engine

reload(sys)
sys.setdefaultencoding('utf8')


# '''
# 1、2017-05 月份之后的华融赔付 增加了提前结算功能
# 华融加入了提前结清的规则。
# 提前结清：如果用户提前还款完成，则打款给资金方；
# 如果用户还有期数未还，则这笔不进行提前结清。
# 每周周四进行 上周四到本周三的提前结清。
# '''
engine_new_transaction = create_engine(
    'mysql+mysqldb://yulong_rw:TouBStYwN8wkdxVt@172.16.3.201:3306/new_transaction?charset=utf8',
    echo=True)

# 还资金方----2017.5.4包含有历史提前结算
sql_fund_hk_hr = '''
SELECT DATE(repaid_at) day_hk,SUM(`principle`)+SUM(`interest`) plan_all
FROM audit.`funding_repayment_record` WHERE  is_active = 1 and funding_code = 150
and repaid_at >= '%s' AND repaid_at < '%s'
GROUP BY DATE(repaid_at)
'''

# 客户正常还款+逾期还款，按照还款时间统计即可
sql_hk_online_zc = '''
SELECT DATE(t3.xyqb_repaid_at) day_hk,sum(t1.`principle`+t1.`interest`-t1.`mitigate_principle`-t1.`mitigate_interest`) zc_real_all
FROM new_transaction.`xjd_repay_plan_repay_record_ref` t1
JOIN new_transaction.`user_repayment_plan` t3 ON t1.plan_id = t3.id and t1.repay_channel < 13 and t3.fund_code = 150  and DATE(t3.xyqb_repaid_at) = DATE(t3.deadline)
AND t3.xyqb_repaid_at >= '%s' and t3.xyqb_repaid_at < '%s'
GROUP by 1
'''
# 线上还款-逾期还款
sql_hk_online_yq = '''
SELECT DATE(t3.xyqb_repaid_at) day_hk,sum(t1.`principle`+t1.`interest`-t1.`mitigate_principle`-t1.`mitigate_interest`) yq_real_all
FROM new_transaction.`xjd_repay_plan_repay_record_ref` t1
JOIN new_transaction.`user_repayment_plan` t3 ON t1.plan_id = t3.id and t1.repay_channel < 13 and t3.fund_code = 150 and DATE(t3.xyqb_repaid_at) > DATE(t3.deadline)
AND t3.xyqb_repaid_at >= '%s' and t3.xyqb_repaid_at < '%s'
GROUP by 1
'''

sql_hk_ali_zc = '''
SELECT DATE(t2.transfer_time) day_hk,sum(t1.`principle`+t1.`interest`-t1.`mitigate_principle`-t1.`mitigate_interest`) zc_real_all
FROM new_transaction.`xjd_repay_plan_repay_record_ref` t1
join new_transaction.offline_alipay_record t2 on t1.record_id = t2.id and t1.repay_channel = 13 and t2.transfer_time >= '%s' and t2.transfer_time < '%s' 
JOIN new_transaction.`user_repayment_plan` t3 ON t1.plan_id = t3.id  and t3.fund_code = 150 and DATE(t2.transfer_time) = DATE(t3.deadline)
GROUP by 1
'''
# 支付宝还款--逾期还款
sql_hk_ali_yq = '''
SELECT DATE(t2.transfer_time) day_hk,sum(t1.`principle`+t1.`interest`-t1.`mitigate_principle`-t1.`mitigate_interest`) yq_real_all
FROM new_transaction.`xjd_repay_plan_repay_record_ref` t1
join new_transaction.offline_alipay_record t2 on t1.record_id = t2.id and t1.repay_channel = 13 and t2.transfer_time >= '%s' and t2.transfer_time < '%s' 
JOIN new_transaction.`user_repayment_plan` t3 ON t1.plan_id = t3.id  and t3.fund_code = 150 and DATE(t2.transfer_time) > DATE(t3.deadline)
GROUP by 1
'''


def hr_table(fund_code, fund_name, start_time, end_time, last_week_time, next_first_week_time,
             last_month_last_week_time):
    df_online_zc = pd.read_sql(sql_hk_online_zc % (start_time, end_time), engine_new_transaction)
    df_online_yq = pd.read_sql(sql_hk_online_yq % (start_time, end_time), engine_new_transaction)
    df_ali_zc = pd.read_sql(sql_hk_ali_zc % (start_time, end_time), engine_new_transaction)
    df_ali_yq = pd.read_sql(sql_hk_ali_yq % (start_time, end_time), engine_new_transaction)
    df_fund = pd.read_sql(sql_fund_hk_hr % (start_time, end_time), engine_new_transaction)

    df_zc = pd.concat([df_online_zc, df_ali_zc], axis=0, ignore_index=True)
    df_zc = df_zc.groupby('day_hk')['zc_real_all'].sum().reset_index()
    df_yq = pd.concat([df_online_yq, df_ali_yq], axis=0, ignore_index=True)
    df_yq = df_yq.groupby('day_hk')['yq_real_all'].sum().reset_index()

    # 提前还款特殊，需要提取明细
    sql_online_tq = '''
    SELECT t3.xyqb_repaid_at repaid_at,t3.deadline,t3.ref_id,t3.term_no,t4.contract_term ,t1.`principle`+t1.`interest`-t1.`mitigate_principle`-t1.`mitigate_interest` tq_amount
    FROM new_transaction.`xjd_repay_plan_repay_record_ref` t1
    JOIN new_transaction.`user_repayment_plan` t3 ON t1.plan_id = t3.id and t1.repay_channel < 13 and t3.fund_code = 150  and DATE(t3.xyqb_repaid_at) < DATE(t3.deadline)
    AND t3.xyqb_repaid_at < '%s'
    join audit.loan_manifest t4 on t3.ref_id = t4.ref_id
    '''
    sql_ali_tq = '''
    SELECT t2.transfer_time repaid_at,t3.deadline,t3.ref_id,t3.term_no,t4.contract_term ,t1.`principle`+t1.`interest`-t1.`mitigate_principle`-t1.`mitigate_interest` tq_amount
    FROM new_transaction.`xjd_repay_plan_repay_record_ref` t1
    join new_transaction.offline_alipay_record t2 on t1.record_id = t2.id and t1.repay_channel = 13 and  t2.transfer_time < '%s'
    JOIN new_transaction.`user_repayment_plan` t3 ON t1.plan_id = t3.id and t3.fund_code = 150  and DATE(t2.transfer_time) < DATE(t3.deadline)
    join audit.loan_manifest t4 on t3.ref_id = t4.ref_id
    '''

    df_online_tq = pd.read_sql(sql_online_tq % (end_time), engine_new_transaction)

    df_ali_tq = pd.read_sql(sql_ali_tq % (end_time), engine_new_transaction)

    # 使用 max(repaid_at)
    df_tq = pd.concat([df_online_tq, df_ali_tq], ignore_index=True)
    df_tq_tmp = df_tq.groupby(['ref_id', 'term_no']).agg({'tq_amount': 'sum', 'repaid_at': 'max'}).reset_index()
    df_tq.drop(['tq_amount', 'repaid_at'], axis=1, inplace=True)
    df_tq = df_tq.merge(df_tq_tmp)
    df_tq.drop_duplicates(subset=['ref_id', 'term_no'], inplace=True)

    # 提前还款分为 提前还款+提前结算
    df_tq_tmp = df_tq.ix[df_tq.contract_term == df_tq.term_no]
    df_tq_js = df_tq.ix[df_tq.ref_id.isin(df_tq_tmp.ref_id)]
    df_tq_hk = df_tq.ix[~df_tq.ref_id.isin(df_tq_tmp.ref_id)]

    df_tq_js.tq_amount.sum() + df_tq_hk.tq_amount.sum()

    # 提前还款按照deadline进行统计
    df_tq_hk = df_tq_hk.groupby('deadline')['tq_amount'].sum().reset_index().rename(
        columns={'deadline': 'day_hk', 'tq_amount': 'tq_real_all'})

    df_tq_hk.ix[(df_tq_hk.day_hk >= start_time) & (df_tq_hk.day_hk < end_time)].tq_real_all.sum()
    df_tq_js.repaid_at = pd.to_datetime(df_tq_js.repaid_at).dt.date
    df_tq_js.deadline = pd.to_datetime(df_tq_js.deadline).dt.date

    # 本月的提前结算扣除本月之前的提前结算
    df_tq_js_tmp = df_tq_js.ix[
        (df_tq_js.repaid_at < last_month_last_week_time) & (df_tq_js.contract_term == df_tq_js.term_no)]
    df_tq_js = df_tq_js.ix[~df_tq_js.ref_id.isin(df_tq_js_tmp.ref_id)]

    # 提取 deadline > start_time
    df_tq_js = df_tq_js.ix[df_tq_js.deadline >= start_time]
    # 上个月最后提前结清的，放到这个月处理
    if start_time.month > 5:
        df_tq_js.ix[(df_tq_js.repaid_at >= last_month_last_week_time) & (
            df_tq_js.repaid_at < start_time) & (df_tq_js.deadline >= start_time), 'repaid_at'] = start_time
    # 本月最后一个周四后的放到下个月处理
    df_tq_js.ix[
        (df_tq_js.repaid_at >= last_week_time) & (df_tq_js.deadline >= end_time), 'repaid_at'] = next_first_week_time
    df_tq_js = df_tq_js.ix[df_tq_js.repaid_at < end_time]

    # 提前结算，根据指定的时间进行结算
    # 2017.5.4 结算 deadline 在 2017.5.1之后的
    df_tq_js_5_4 = df_tq_js.ix[
        (df_tq_js.repaid_at < datetime.date(2017, 5, 1)) & (df_tq_js.term_no == df_tq_js.contract_term)]
    df_tq_js.ix[(df_tq_js.repaid_at < datetime.date(2017, 5, 1)) & (df_tq_js.deadline >= datetime.date(2017, 5, 1)) & (
        df_tq_js.ref_id.isin(df_tq_js_5_4.ref_id)), 'repaid_at'] = datetime.date(2017, 5, 4)



    df_tq_js = df_tq_js.groupby('repaid_at')['tq_amount'].sum().reset_index().rename(
        columns={'repaid_at': 'day_hk', 'tq_amount': 'tq_real_all'})

    df_tq_all = pd.concat([df_tq_hk, df_tq_js], ignore_index=True, axis=0)
    df_tq_all.day_hk = pd.to_datetime(df_tq_all.day_hk).dt.date
    df_tq_all = df_tq_all.groupby('day_hk')['tq_real_all'].sum().reset_index()

    # 合并所有的还款数据
    df_fund.day_hk = pd.to_datetime(df_fund.day_hk).dt.date
    df_zc.day_hk = pd.to_datetime(df_zc.day_hk).dt.date
    df_yq.day_hk = pd.to_datetime(df_yq.day_hk).dt.date
    df_tq_all.day_hk = pd.to_datetime(df_tq_all.day_hk).dt.date
    df = pd.merge(df_fund, df_zc, on='day_hk', how='outer')
    df = pd.merge(df, df_yq, on='day_hk', how='outer')
    df = pd.merge(df, df_tq_all, on='day_hk', how='outer')
    df.fillna(0, inplace=True)
    df.sort_values(['day_hk'], inplace=True)
    df = df.ix[(df.day_hk >= start_time) & (df.day_hk < end_time)]
    df['fund_name'] = fund_name
    df['real_all'] = df['zc_real_all'] + df['tq_real_all'] + df['yq_real_all']
    df = df[
        ['fund_name', 'day_hk', 'plan_all', 'real_all', 'zc_real_all',
         'tq_real_all', 'yq_real_all']]

    df['peifu'] = df['plan_all'] - df['real_all']
    df.rename(columns={'fund_name': '资金方', 'day_hk': '日期', 'plan_all': '应还资金方本息', 'real_all': '客户实还本息可用',
                              'zc_real_all': '客户正常还款本息', 'yq_real_all': '当天客户逾期还款本息',
                              'tq_real_all': '客户提前还款本息当天到期可用', 'peifu': '当日不可用累计本息'},inplace=True)
    return df


if __name__ == '__main__':
    start_time = datetime.date(2017, 6, 1)
    end_time = datetime.date(2017, 9, 1)
    # 本月最后一个周四
    last_week_time_six = datetime.date(2017, 6, 29)
    # 下个月第一个周四
    first_week_time_six = datetime.date(2017, 7, 6)
    # 上个月最后一个周四
    last_month_last_week_time_six = datetime.date(2017, 5, 25)

    # time_list = [[datetime.date(2017, 8, 1), datetime.date(2017, 9, 1), datetime.date(2017, 8, 31), datetime.date(2017, 9, 7),
    #      datetime.date(2017, 7, 27)],
    #     [datetime.date(2017, 7, 1), datetime.date(2017, 8, 1), datetime.date(2017, 7, 27), datetime.date(2017, 8, 3),
    #      datetime.date(2017, 6, 29)],
    #     [datetime.date(2017, 6, 1), datetime.date(2017, 7, 1), datetime.date(2017, 6, 29), datetime.date(2017, 7, 6),
    #      datetime.date(2017, 5, 25)],
    #     [datetime.date(2017, 5, 1), datetime.date(2017, 6, 1), datetime.date(2017, 5, 25), datetime.date(2017, 6, 2),
    #      None]]
    time_list = [
        [datetime.date(2017, 8, 1), datetime.date(2017, 9, 1), datetime.date(2017, 8, 24), datetime.date(2017, 9, 1),
         datetime.date(2017, 7, 27)]]
    fund_code = 150
    fund_name = u'华融'
    print '------begin---', fund_name
    try:
        df_total = pd.DataFrame()
        for time_month_list in time_list:
            df_month = hr_table(fund_code, fund_name, time_month_list[0], time_month_list[1], time_month_list[2],
                                time_month_list[3], time_month_list[4])
            df_total = pd.concat([df_total, df_month], ignore_index=True)

        df_total.to_excel('./' + str(fund_code) + '_settle.xlsx', index=None,
                          columns=df_month.columns, encoding='utf8')
    except Exception, e:
        print e.message
        raise e

    print '=====================main done======================'
