# -*- encoding: utf8 -*-
import sys
import datetime
import pandas as pd
from sqlalchemy import create_engine
from dateutil.relativedelta import relativedelta
import multiprocessing as mtp
import numpy as np
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', 'fund_id'], inplace=True, axis=1)
#     return df_pay
#
#
# # 资金方还款计划
# def fund_repay_plan_detail(loan_ids):
#     df_plan = pd.DataFrame()
#     sql_plan = '''
#     SELECT loan_id,term_no ,date(deadline) deadline,sum(principle+interest) fund_prin_inst
#     FROM test_linfang.funding_repayment_record
#     WHERE lkb_to_fund_type = 2 AND is_active IN (1,-1) AND loan_id IN %s
#     GROUP BY 1,2
#     '''
#     for i in range(0, len(loan_ids), 50000):
#         df_plan = df_plan.append(
#             pd.read_sql(sql_plan % str(tuple(loan_ids[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 t1.ref_id, t1.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))
#     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
#
#     loan_ids = df_pay.loan_id.astype(str).tolist()
#     ref_ids = df_pay.ref_id.astype(int).tolist()
#
#     df_plan = fund_repay_plan_detail(loan_ids)
#     df_user_plan = user_repay_plan_detail(ref_ids)
#
#     df_pay.loan_id = df_pay.loan_id.astype(str)
#     df_plan.loan_id = df_plan.loan_id.astype(str)
#     df_user_plan.ref_id = df_user_plan.ref_id.astype(int)
#     print '-----无还款计划的放款-------------', df_pay.ix[~df_pay.loan_id.isin(df_plan.loan_id)]
#
#     print '-----无客户还款计划的放款-------------', df_pay.ix[~df_pay.ref_id.isin(df_user_plan.ref_id)]['ref_id']
#
#     df = pd.merge(df_pay, df_user_plan, on='ref_id', how='left')
#     df = pd.merge(df, df_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.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.loan_id = t2.loan_id AND t2.is_active = 1 AND t2.funding_code <> 150
#   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_fund_huarong = """
# SELECT
#   t3.`name`            '资金方',
#   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 AND t2.funding_code = 150
#   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 lkb_id IN %s
'''
#
# sql_lkb_to_fund = '''
# SELECT id lkb2fund_id ,transfer_amount '银行打款金额',transfer_time '银行打款时间' FROM lkb_to_fund WHERE id IN %s
# '''

'''
流水明细
还资金方表
'''
step = 10000
max_limit = 900000
#
# def ban_flow_detail(year, month):
#     start_time = datetime.date(year, month, 1)
#     end_time = start_time + relativedelta(months=+1)
#     df_repay_gen = pd.read_sql(sql_repay_fund % (start_time, end_time), engine_new_transaction, chunksize=step)
#     df_repay = pd.DataFrame()
#     for tmp in df_repay_gen:
#         df_repay = df_repay.append(tmp)
#
#     df_repay_huarong_gen = pd.read_sql(sql_fund_huarong % (start_time, end_time), engine_new_transaction, chunksize=step)
#     for tmp in df_repay_huarong_gen:
#         df_repay = df_repay.append(tmp)
#     if len(df_repay) > 0:
#         df_repay.lkb2fund_id = df_repay.lkb2fund_id.astype(int)
#         df_repay.loan_id = df_repay.loan_id.astype(str)
#         # lkb_ids = df_repay.lkb2fund_id.astype(int).tolist()
#         # loan_ids = df_repay.loan_id.astype(str).tolist()
#
#         # df_plan = fund_repay_plan_detail(loan_ids)
#         # df_plan.loan_id = df_plan.loan_id.astype(str)
#         df_flow_id = pd.read_sql(sql=sql_query_flowid % (start_time, end_time, 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_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 t1.lkb2fund_id lkb_id
FROM test_linfang.funding_repayment_record t1
  JOIN loan_manifest t2 ON t1.ref_id = t2.ref_id AND t2.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.ref_id = t3.ref_id AND t3.is_active =1 AND t1.lkb_to_fund_type = 2 AND  t1.lkb2fund_id IN %s
"""

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


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

    if len(df_lkb_id) > 0:
        lkb_ids = df_lkb_id['lkb_id'].tolist()
        df_flow = pd.read_sql(sql_flow % (str(tuple(lkb_ids)).replace(',)', ')'),),
                              engine_new_transaction)
        df_flow.to_excel(path + u"流水明细(%d-%02d).xlsx" % (start_time.year, start_time.month), index=None)

        df_all_gen = pd.read_sql(sql=sql_query_detail % (str(tuple(lkb_ids)).replace(',)', ')'),),
                                 con=engine_new_transaction, chunksize=step)
        df_all = pd.DataFrame()
        for tmp in df_all_gen:
            df_all = df_all.append(tmp)
        all_excel = pd.ExcelWriter(path + u'流水明细对应的实还资金方表(%d-%02d).xlsx' % (start_time.year, start_time.month))
        for i in xrange(0, len(df_all), max_limit):
            df_all[i:i+max_limit].to_excel(all_excel, str(int(i / max_limit + 1)), index=None)
        all_excel.close()
        gp = df_all.groupby([u'流水号'])[u'实还总额'].agg('sum').reset_index()
        df_diff = pd.merge(df_flow, gp, on=u'流水号', how='outer')
        df_diff.fillna(0, inplace=True)
        df_diff['diff'] = np.round(df_diff[u'转账金额'] - df_diff[u'实还总额'], 2)
        print '%d-%02d 差异：%s' % (start_time.year, start_time.month, df_diff['diff'].sum())
        df_diff.to_excel(path + u'流水差异(%d-%02d).xlsx' % (start_time.year, start_time.month), index=None)


import multiprocessing as mtp

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__':
    # handle(2016, 11)
    # handle(2016, 12)
    # pool = mtp.Pool(processes=6)
    for year in [2015, 2016]:
        for month in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]:
            if (year == 2015 and month <= 6) or (year == 2016 and month == 12):
                continue
            else:
                handle(year,month)
                # handle(year, month)
                # pool.apply_async(handle, (year, month))
    # pool.close()
    # pool.join()
    print '-----------------all main done---------------------'
