# -*- encoding: utf8 -*-
import sys
import datetime
import pandas as pd
from sqlalchemy import create_engine
from dateutil.relativedelta import relativedelta
import multiprocessing as mtp

reload(sys)
sys.setdefaultencoding("utf-8")
pd.options.mode.chained_assignment = None

'''
目标 我方的资金方还款计划 VS 审计的资金方还款计划
注意 is_active = 1 的订单
'''
engine_new_transaction = create_engine(
    'mysql+mysqldb://yulong:ohVU1nPITynSZwR2@172.16.3.201:3306/all_back_0630?charset=utf8', echo=False).connect()

path = "./"
sql_account = '''
select id loan_account_id,accountName  from audit.loan_account
'''
df_account = pd.read_sql(sql_account, engine_new_transaction)
df_account.loan_account_id = df_account.loan_account_id.astype(int)

sql_fund = '''
select id fund_id,name fund_name from new_transaction.funding_corp
'''
df_fund = pd.read_sql(sql_fund, engine_new_transaction)
df_fund.fund_id = df_fund.fund_id.astype(int)


def pay_detail(start_time, end_time):
    sql_pay = '''
    select loan_id,ref_id,funding_code fund_id,DATE(loan_paid_at) loan_paid_at,contract_loan_amount ,loan_account_id,per_term_service_fee*contract_term service_fee
    from loan_manifest
    where is_active in (1,-2) and loan_paid_at >= '%s' and loan_paid_at < '%s'
    ''' % (start_time, end_time)

    sql_contract = '''
    select ref_id,contract_no
    from basic.loan_contract
    where ref_id in %s
    '''

    df_pay = pd.read_sql(sql_pay, engine_new_transaction)
    if len(df_pay) > 0:
        ref_ids = df_pay.ref_id.astype(int)
        df_contract = pd.read_sql(sql_contract % str(tuple(ref_ids)), engine_new_transaction)
        df_pay.ref_id = df_pay.ref_id.astype(int)
        df_contract.ref_id = df_contract.ref_id.astype(int)
        df_pay = pd.merge(df_pay, df_contract, on='ref_id', how='left')
        df_pay.loan_account_id = df_pay.loan_account_id.astype(int)
        df_pay = pd.merge(df_pay, df_account, on='loan_account_id', how='left')
        df_pay = pd.merge(df_pay, df_fund, on='fund_id', how='left')
        df_pay.drop(['loan_account_id'], inplace=True, axis=1)
    return df_pay


# 取资金方还款计划
def fund_repayment_repay_plan_detail(ref_ids):
    df_plan = pd.DataFrame()
    if len(ref_ids) > 0:
        sql_plan = '''
        select loan_id,term_no ,date(deadline) deadline,sum(principle+interest) fund_prin_inst
        from test_linfang.funding_repayment_record
        where is_active in (1,-1) and ref_id in %s
        group by 1,2
        '''
        for i in range(0, len(ref_ids), 50000):
            df_plan = df_plan.append(
                pd.read_sql(sql_plan % str(tuple(ref_ids[i:i + 50000])).replace(',)', ')'), engine_new_transaction))
    return df_plan


# 取acdz
def fund_acdz_repay_plan_detail(ref_ids):
    df_plan = pd.DataFrame()
    if len(ref_ids) > 0:
        sql_plan = '''
        select loan_id,term_no ,date(deadline) deadline,sum(principle+interest) fund_prin_inst
        from test_linfang.funding_repayment_record_acdz
        where  ref_id in %s
        group by 1,2
        '''
        for i in range(0, len(ref_ids), 50000):
            df_plan = df_plan.append(
                pd.read_sql(sql_plan % str(tuple(ref_ids[i:i + 50000])).replace(',)', ')'), engine_new_transaction))
    return df_plan


# 取客户的还款计划
def fund_user_repay_plan_detail(ref_ids):
    df_plan = pd.DataFrame()
    if len(ref_ids) > 0:
        sql_plan = '''
        select real_loan_id loan_id,term_no ,date(deadline) deadline,sum(principle+interest) fund_prin_inst
        from all_back_0630.user_repayment_plan
        where  ref_id in %s
        group by 1,2
        '''
        for i in range(0, len(ref_ids), 50000):
            df_plan = df_plan.append(
                pd.read_sql(sql_plan % str(tuple(ref_ids[i:i + 50000])).replace(',)', ')'), engine_new_transaction))
    return df_plan


# 广源的一部分取资金方 一部分取客户
def fund_guanyuan_repay_plan_detail(ref_ids):
    df_plan = pd.DataFrame()
    if len(ref_ids) > 0:
        sql_fund_plan = '''
                select loan_id,term_no ,date(deadline) deadline,sum(principle+interest) fund_prin_inst,ref_id
        from test_linfang.funding_repayment_record
        where is_active in (1,-1) and ref_id in %s
        group by 1,2
                '''
        for i in range(0, len(ref_ids), 50000):
            df_plan = df_plan.append(
                pd.read_sql(sql_fund_plan % str(tuple(ref_ids[i:i + 50000])).replace(',)', ')'),
                            engine_new_transaction))

        df_plan.ref_id = df_plan.ref_id.astype(int)
        ref_ids_query = df_plan.ref_id.astype(int).tolist()
        ref_ids_other = list(set(ref_ids) - set(ref_ids_query))
        df_plan.drop(['ref_id'], inplace=True, axis=1)
        if len(ref_ids_other) > 0:
            sql_user_plan = '''
            select real_loan_id loan_id,term_no ,date(deadline) deadline,sum(principle+interest) fund_prin_inst
            from all_back_0630.user_repayment_plan
            where  ref_id in %s
            group by 1,2
            '''
            for i in range(0, len(ref_ids_other), 50000):
                df_plan = df_plan.append(
                    pd.read_sql(sql_user_plan % str(tuple(ref_ids_other[i:i + 50000])).replace(',)', ')'),
                                engine_new_transaction))
    return df_plan


# 客户实还计划
def user_repay_plan_detail(ref_ids):
    df_user_plan = pd.DataFrame()

    sql_repay_plan = """
        SELECT
            t1.ref_id,
            t1.term_no,
            SUM(
                t2.principle - t2.mitigate_principle
            ) real_user_principle,
            sum(
                t2.interest - t2.mitigate_interest
            ) real_user_interest,
            sum(
                t2.`service_fee` - t2.mitigate_service_fee
            ) real_user_service_fee
        FROM
            `user_repayment_plan` t1
        LEFT JOIN `xjd_repay_plan_repay_record_ref` t2 ON t1.id = t2.plan_id
        WHERE
            t1.ref_id IN %s GROUP BY ref_id,term_no
    """

    sql_repay_plan_mashang = """
        SELECT
            t3.ref_id,
            t1.term_no,
            SUM(t1.funding_principle) real_user_principle,
            sum(t1.funding_interest) real_user_interest,
            sum(t1.qg_service_fee) real_user_service_fee
        FROM
            new_ms_transaction_with_term t1
        INNER JOIN loan_manifest t3 ON t1.loan_id = t3.loan_id
        AND t3.is_active IN (1 ,- 2)
        WHERE
            t3.ref_id IN %s GROUP BY ref_id,term_no
    """

    for i in range(0, len(ref_ids), 50000):
        df_user_plan = df_user_plan.append(
            pd.read_sql(sql_repay_plan % str(tuple(ref_ids[i:i + 50000])).replace(',)', ')'),
                        engine_new_transaction))

    for i in range(0, len(ref_ids), 50000):
        df_user_plan = df_user_plan.append(
            pd.read_sql(sql_repay_plan_mashang % str(tuple(ref_ids[i:i + 50000])).replace(',)', ')'),
                        engine_new_transaction))
    df_user_plan = df_user_plan.groupby(by=['ref_id', 'term_no']).sum().reset_index()

    return df_user_plan


'''
放款表
'''


def fund_to_plan(year, month):
    start_time = datetime.date(year, month, 1)
    end_time = start_time + relativedelta(months=+1)
    df_pay = pay_detail(start_time, end_time)
    if len(df_pay) <= 0:
        return

    df_pay.loan_id = df_pay.loan_id.astype(str)
    df_pay.ref_id = df_pay.ref_id.astype(int)
    df_pay.fund_id = df_pay.fund_id.astype(int)
    df_user_pay = df_pay.ix[
        (df_pay.fund_id == 0) | (df_pay.fund_id == 160) | (df_pay.fund_id == 251) | (df_pay.fund_id == 210)]

    df_acdz_pay = df_pay.ix[(df_pay.fund_id == 50) | (df_pay.fund_id == 70)
                            | (df_pay.fund_id == 80) | (df_pay.fund_id == 130)
                            | (df_pay.fund_id == 1)]

    # df_guangyuan_pay = df_pay.ix[df_pay.fund_id == 210]

    df_other_pay = df_pay.ix[(df_pay.fund_id != 0)
                             & (df_pay.fund_id != 160)
                             & (df_pay.fund_id != 251)
                             & (df_pay.fund_id != 210)
                             & (df_pay.fund_id != 50)
                             & (df_pay.fund_id != 70)
                             & (df_pay.fund_id != 80)
                             & (df_pay.fund_id != 130)
                             & (df_pay.fund_id != 1)]

    df_fund_plan = pd.DataFrame()
    if len(df_other_pay) > 0:
        ref_ids_other = df_other_pay.ref_id.astype(str).tolist()
        df_plan_others = fund_repayment_repay_plan_detail(ref_ids_other)
        df_fund_plan = df_fund_plan.append(df_plan_others)

    # if len(df_guangyuan_pay) > 0:
    #     loan_ids_guangyuan = df_guangyuan_pay.ref_id.astype(int).tolist()
    #     df_plan_guangyuan = fund_guanyuan_repay_plan_detail(loan_ids_guangyuan)
    #     df_fund_plan = df_fund_plan.append(df_plan_guangyuan)

    if len(df_user_pay) > 0:
        ref_ids_user = df_user_pay.ref_id.astype(int).tolist()
        df_plan_user = fund_user_repay_plan_detail(ref_ids_user)
        df_fund_plan = df_fund_plan.append(df_plan_user)

    if len(df_acdz_pay) > 0:
        ref_ids_acdz = df_acdz_pay.ref_id.astype(str).tolist()
        df_plan_acdz = fund_acdz_repay_plan_detail(ref_ids_acdz)
        df_fund_plan = df_fund_plan.append(df_plan_acdz)

    ref_ids = df_pay.ref_id.astype(int).tolist()
    df_user_plan = user_repay_plan_detail(ref_ids)

    df_pay.loan_id = df_pay.loan_id.astype(str)
    df_fund_plan.loan_id = df_fund_plan.loan_id.astype(str)
    df_user_plan.ref_id = df_user_plan.ref_id.astype(int)

    df_pay.drop(['fund_id'], inplace=True, axis=1)
    print '-----无资金方还款计划的放款-------------', df_pay.ix[~df_pay.loan_id.isin(df_fund_plan.loan_id)]['loan_id']

    # 华融存在重复的
    df = pd.merge(df_pay, df_user_plan, on='ref_id', how='left')
    df = pd.merge(df, df_fund_plan, on=['loan_id', 'term_no'], how='left')
    df.fillna(0, inplace=True)
    df.term_no = df.term_no.astype(int)
    df.loan_id = df.loan_id.astype(str)

    # loan_id,term_no 排序
    df = df.sort_values(by=['loan_id', 'term_no'])
    df.ix[df.term_no != 1, 'contract_loan_amount'] = ''
    df.ix[df.term_no != 1, 'service_fee'] = ''
    df['term_no_2'] = df['term_no']
    df['term_no_3'] = df['term_no']
    df['deadline_2'] = df['deadline']
    df['fund_prin_inst_2'] = df['fund_prin_inst']
    # df=pd.pivot_table(df,index=['loan_id','contract_no','loan_paid_at','contract_loan_amount','accountName','service_fee','term_no'],
    #                values=['deadline','fund_prin_inst'],aggfunc={'deadline':max,'fund_prin_inst':sum})
    if len(df) > 0:
        df['merge'] = df.apply(lambda x: '%s%s%s%s' % (x.loan_id, x.term_no, x.deadline, x.fund_prin_inst), axis=1)
        df[u'唯一编号'] = df.apply(lambda x: '%s%s' % (x.loan_id, x.term_no), axis=1)
        df.rename(columns={'contract_no': u'合同号', 'loan_paid_at': u'放款时间', 'contract_loan_amount': u'放款金额',
                           'accountName': u'放款渠道', 'service_fee': u'应收总服务费',
                           'term_no': u'应还期数', 'deadline': u'应还资金方时间', 'fund_prin_inst': u'应还资金方本息',
                           'fund_name': u'资金方',
                           'term_no_2': u'应还期数_2', 'deadline_2': u'应还资金方时间_2', 'fund_prin_inst_2': u'应还资金方本息_2',
                           'term_no_3': u'应还期数_3', 'real_user_service_fee': u'实还客户服务费',
                           'real_user_principle': u'实还客户本金', 'real_user_interest': u'实还客户利息'},
                  inplace=True)
        columns = [u'唯一编号', u'资金方', u'loan_id', u'合同号', u'放款时间', u'放款金额', u'放款渠道', u'应收总服务费'
            , u'应还期数', u'应还资金方时间', u'应还资金方本息', u'merge', u'应还期数_2', u'应还资金方时间_2', u'应还资金方本息_2'
            , u'应还期数_3', u'实还客户服务费', u'实还客户本金', u'实还客户利息']
        df.to_excel(path + u'放款明细_%s_%s.xlsx' % (start_time, end_time), index=False, columns=columns)


# =========================================================================



sql_repay_fund = '''
select t3.`name` '资金方',t1.ref_id, t2.funding_code fund_id,t1.loan_id,t1.term_no,t2.loan_paid_at '放款时间',t1.term_no '期数',date(t1.repaid_at) '实还时间',t1.current_repayment '实还总额',
t1.principle '实还本金',t1.interest '实还利息',t1.flow_id '流水号',t1.lkb2fund_id
from test_linfang.funding_repayment_record t1
join loan_manifest t2 on t1.ref_id=t2.ref_id and t2.is_active =1
JOIN new_transaction.funding_corp t3 on t2.funding_code = t3.id
and t1.is_active = 1 and t2.loan_paid_at >= '%s' and t2.loan_paid_at < '%s' AND t1.lkb_to_fund_type = 2
and t1.repaid_at < '2017-07-01' and t1.lkb2fund_id IS not NULL
'''

sql_flow = '''
SELECT flow_id '流水号',transfer_time '转账时间',ref_amount '转账金额'
FROM basic.lkb_to_fund_ref
where flow_id in %s
'''

sql_lkb_to_fund = '''
SELECT id lkb2fund_id ,transfer_amount '银行打款金额',transfer_time '银行打款时间' FROM lkb_to_fund WHERE id IN %s
'''

'''
流水明细
还资金方表
'''


def ban_flow_detail(year, month):
    start_time = datetime.date(year, month, 1)
    end_time = start_time + relativedelta(months=+1)
    df_repay = pd.read_sql(sql_repay_fund % (start_time, end_time), engine_new_transaction)
    if len(df_repay) > 0:
        df_repay.lkb2fund_id = df_repay.lkb2fund_id.astype(int)
        df_repay.fund_id = df_repay.fund_id.astype(int)
        df_repay.ref_id = df_repay.ref_id.astype(int)
        df_repay.loan_id = df_repay.loan_id.astype(str)
        lkb_ids = df_repay.lkb2fund_id.astype(int).tolist()

        df_user_repay = df_repay.ix[
            (df_repay.fund_id == 0) | (df_repay.fund_id == 160) | (df_repay.fund_id == 251) | (df_repay.fund_id == 210)]

        df_acdz_repay = df_repay.ix[(df_repay.fund_id == 50) | (df_repay.fund_id == 70)
                                    | (df_repay.fund_id == 80) | (df_repay.fund_id == 130)
                                    | (df_repay.fund_id == 1)]

        # df_guangyuan_repay = df_repay.ix[df_repay.fund_id == 210]

        df_other_repay = df_repay.ix[(df_repay.fund_id != 0)
                                     & (df_repay.fund_id != 160)
                                     & (df_repay.fund_id != 251)
                                     & (df_repay.fund_id != 210)
                                     & (df_repay.fund_id != 50)
                                     & (df_repay.fund_id != 70)
                                     & (df_repay.fund_id != 80)
                                     & (df_repay.fund_id != 130)
                                     & (df_repay.fund_id != 1)]

        df_fund_plan = pd.DataFrame()
        if len(df_other_repay) > 0:
            ref_ids_other = df_other_repay.ref_id.astype(int).tolist()
            df_plan_others = fund_repayment_repay_plan_detail(ref_ids_other)
            df_fund_plan = df_fund_plan.append(df_plan_others)

        # if len(df_guangyuan_repay) > 0:
        #     loan_ids_guangyuan = df_guangyuan_repay.loan_id.astype(str).tolist()
        #     df_plan_guangyuan = fund_guanyuan_repay_plan_detail(loan_ids_guangyuan)
        #     df_fund_plan = df_fund_plan.append(df_plan_guangyuan)

        if len(df_user_repay) > 0:
            ref_ids_user = df_user_repay.ref_id.astype(int).tolist()
            df_plan_user = fund_user_repay_plan_detail(ref_ids_user)
            df_fund_plan = df_fund_plan.append(df_plan_user)

        if len(df_acdz_repay) > 0:
            ref_ids_acdz = df_acdz_repay.ref_id.astype(int).tolist()
            df_plan_acdz = fund_acdz_repay_plan_detail(ref_ids_acdz)
            df_fund_plan = df_fund_plan.append(df_plan_acdz)

        df_fund_plan.loan_id = df_fund_plan.loan_id.astype(str)

        df_repay.drop(['fund_id'], inplace=True, axis=1)
        df_repay.drop(['ref_id'], inplace=True, axis=1)

        print '-----无资金方还款计划的还资金方表-------------', df_repay.ix[~df_repay.loan_id.isin(df_fund_plan.loan_id)]['loan_id']
        # df_flow_id = pd.read_sql(sql=sql_query_flowid % (start_time, end_time), con=engine_new_transaction)
        # df_flow_id['flow_id'].fillna(0, inplace=True)
        # df_flow_id['flow_id'] = df_flow_id['flow_id'].astype(str)
        # df_flow = pd.read_sql(sql_flow % (str(tuple(df_flow_id['flow_id'])).replace(',)', ')'),),
        #                       engine_new_transaction)
        df_lkb_to_fund = pd.read_sql(sql_lkb_to_fund % str(tuple(lkb_ids)), engine_new_transaction)
        df_lkb_to_fund.lkb2fund_id = df_lkb_to_fund.lkb2fund_id.astype(int)
        df_repay = pd.merge(df_repay, df_lkb_to_fund, on='lkb2fund_id', how='left')
        df_repay = pd.merge(df_repay, df_fund_plan, on=['loan_id', 'term_no'], how='left')
        df_repay[u'唯一编号'] = df_repay.apply(lambda x: '%s%s' % (x.loan_id, x.term_no), axis=1)
        df_repay.drop_duplicates(subset=['loan_id', u'term_no', u'实还总额'], inplace=True)
        df_repay.rename(columns={'term_no': '应还期数', 'deadline': '应还资金方时间', 'fund_prin_inst': '应还资金方本息'}, inplace=True)
        df_repay.to_excel(path + u"还资金方表_%s_%s.xlsx" % (start_time, end_time), index=None)
        # df_flow.to_excel(path + u"流水明细_%s_%s.xlsx" % (start_time, end_time), index=None)


# ================================================================================================




# 还资金方流水明细--1
sql_query_flowid = """
SELECT DISTINCT flow_id from test_linfang.funding_repayment_record t1
join loan_manifest t2 on t1.loan_id=t2.loan_id and t2.is_active =1
and t1.is_active = 1 and t2.loan_paid_at >= '%s' and t2.loan_paid_at < '%s'
and t1.repaid_at < '2017-07-01' and t1.lkb_to_fund_type = 2 AND  t1.lkb2fund_id IS not NULL ;
"""

# 流水明细对应的实还资金方表
sql_query_detail = """
SELECT t1.loan_id,t2.`name` '资金方',t3.loan_paid_at '放款时间',t1.term_no '期数',date(t1.repaid_at) '实还时间',t1.current_repayment '实还总额',
t1.principle '实还本金',t1.interest '实还利息',t1.flow_id '流水号'
FROM test_linfang.funding_repayment_record t1
JOIN new_transaction.funding_corp t2 on t1.funding_code = t2.id
JOIN loan_manifest t3 on t1.loan_id = t3.loan_id AND t3.is_active =1 AND t1.is_active = 1 AND t1.lkb_to_fund_type = 2 AND  t1.flow_id in %s;
"""

'''
流水明细对应的实还资金方表
'''


def flow_detail(year, month):
    start_time = datetime.date(year, month, 1)
    end_time = start_time + relativedelta(months=+1)
    df_flow_id = pd.read_sql(sql=sql_query_flowid % (start_time, end_time), con=engine_new_transaction)
    df_flow_id['flow_id'].fillna(0, inplace=True)
    df_flow_id['flow_id'] = df_flow_id['flow_id'].astype(str)

    if len(df_flow_id['flow_id']) > 0:
        df_detail = pd.read_sql(sql=sql_query_detail % (str(tuple(df_flow_id['flow_id'])).replace(',)', ')'),),
                                con=engine_new_transaction)
        df_detail.to_excel(path + u"流水明细对应的实还资金方表_%s_%s.xlsx" % (start_time, end_time), index=None)


def handle(year, month):
    print "start year %s month %s" % (year, month)
    fund_to_plan(year, month)
    # ban_flow_detail(year, month)
    # flow_detail(year, month)
    print "end year %s month %s" % (year, month)


if __name__ == '__main__':
    for year in [2015, 2016]:
        for month in [1,2,3, 4, 5, 6, 7, 8, 9, 10, 11, 12]:
            if ((year == 2015 & month < 6) | (year == 2016 & month > 3)):
                continue
            else:
                handle(year, month)
    print '-----------------all main done---------------------'
