# -*- encoding: utf8 -*-
import sys
import os
import datetime
import numpy as np
import pandas as pd
from sqlalchemy import create_engine
from dateutil.relativedelta import relativedelta
import math
reload(sys)
sys.setdefaultencoding("utf-8")
pd.options.mode.chained_assignment = None

engine_qunaer = create_engine('mysql+mysqldb://linfang.wang:#jkl3453YUGuo99@172.16.3.201:3306/qunaer_new?charset=utf8', echo=False).connect()

engine_btzt = create_engine('mysql+mysqldb://linfang.wang:&*uijknbghyt63er45@172.16.3.184:7306/xyqb_btzt?charset=utf8', echo=False)

engine_fs=create_engine('mysql+mysqldb://bowang:in78u6ytgbhj56r@192.168.4.6:8066/financial_system?charset=utf8', echo=False)

'''
前提是 还资金方数据录入---
惠金所---资金部
哈银----从xyqb_btzt库中拉取
1、从pay_detail 中导入 属于资金方的放款数据
2、生成初始的资金方还款计划
3、根据提前结算，进行计算应还利息 = 0---惠金所的同一天退款还款，利息为0
'''

# 更新哈银的放款的计息时间
def step_1_1(year,month):
    start_time = datetime.datetime(year, month, 1, 0, 0, 0)
    end_time = start_time + relativedelta(months=+1)
    sql_pay = '''
        select id,product_no
        from qunaer_new.pay_detail where trans_time >= '%s' and trans_time < '%s' and status=1 and fund_code = 3 
    ''' % (start_time, end_time)
    sql_btzt='''
        SELECT upstream_order_id,interest_at FROM zt_order
        WHERE fund_id = 1 AND channel_id = 66 AND upstream_order_id IN %s 
    '''
    update_sql='''
    update pay_detail set interest_time=%s where id=%s
    '''
    df_pay=pd.read_sql(sql_pay,engine_qunaer,chunksize=5000)
    for df in df_pay:
        df_btzt=pd.read_sql(sql_btzt % str(tuple(df.product_no.astype(str).tolist())),engine_btzt)
        df=pd.merge(df,df_btzt,left_on='product_no',right_on='upstream_order_id',how='inner')
        df.interest_at=pd.to_datetime(df.interest_at)
        df['id'] = df['id'].map('{:.0f}'.format)
        engine_qunaer.execute(update_sql,df[['interest_at','id']].values.tolist())


# 哈银的还款计划使用 xyqb_btzt库中的数据
def step_2_hy(year,month):
    start_time = datetime.date(year, month, 1)
    end_time = start_time + relativedelta(months=+1)
    sql_pay='''
    select product_no from qunaer_new.pay_detail 
    where trans_time >= '%s' AND trans_time < '%s' and fund_code = 3  AND status=1
    ''' % (start_time,end_time)
    sql_btzt='''
    SELECT t2.upstream_order_id product_no,t1.current_term current_stage_no,t1.principal principle,t1.service_fee fee_amount,t1.over_due_service_fee due_amount,
      t1.deadline,t1.status FROM zt_repayment_plan t1 
      JOIN zt_order t2 ON t1.order_id = t2.id 
      WHERE t2.fund_id = 1 AND t2.channel_id = 66 AND t2.upstream_order_id IN %s 
    '''
    df_pay=pd.read_sql(sql_pay,engine_qunaer,chunksize=5000)
    for df in df_pay:
        df_btzt=pd.read_sql(sql_btzt % str(tuple(df.product_no.astype(str).tolist())),engine_btzt)
        df_btzt['fund_code'] = 3
        df_btzt.to_sql('fund_repayment_plan',engine_qunaer,index=None,if_exists='append',chunksize=5000)


#==更新哈银的还款计划

# 资金方实还表
def step_3_hy(year,month):
    start_time = datetime.date(year, month, 1)
    end_time = start_time + relativedelta(months=+1)
    sql_fs='''
    SELECT plan_id,account_at,withdraw_account,guarantee_account,income_account,factoring_account 
    from btzt_hyqn_cash_detail
    where fund_id = 2 and account_at >= '%s' and account_at < '%s'
    ''' % (start_time,end_time)

    sql_repay='''
    SELECT plan_id AS plan_ids,batch_id AS package_no,push_at AS package_time,account_at AS repay_time,type
    FROM zt_hrb_repay_account_detail WHERE account_at >= '%s' AND account_at < '%s' 
    ''' % (start_time,end_time)

    sql_plan='''SELECT t1.id AS plan_id,t2.upstream_order_id AS product_no,t2.repay_term as stages,t1.current_term AS current_stage_no,t1.principal AS plan_principle,t1.service_fee AS plan_fee_amount,t1.over_due_service_fee AS plan_due_fee_amount 
          FROM zt_repayment_plan t1 JOIN zt_order t2 ON t1.order_id = t2.id WHERE t1.id IN %s 
    '''

    df_repay = pd.read_sql(sql_repay,engine_btzt)
    df_repay.reset_index(inplace=True)
    df_fs = pd.read_sql(sql_fs,engine_fs)

    df_repay_out=pd.DataFrame()
    for index,row in df_repay.iterrows():
        plan_ids=str(row['plan_ids'])
        df=df_repay.iloc[index:index+1,:]
        plan_ids = plan_ids.split(',')
        for plan_id in plan_ids:
            df['plan_id']=int(plan_id)
            df_repay_out=df_repay_out.append(df)
    plan_ids=str(tuple(df_repay_out['plan_id'].astype(str).tolist()))
    #===应还金额
    df_plan=pd.read_sql(sql_plan % plan_ids,engine_btzt)
    df_plan['plan_all']=np.round(df_plan['plan_principle']+df_plan['plan_fee_amount']+df_plan['plan_due_fee_amount'],2)
    df_plan['plan_prin_fee'] = np.round(df_plan['plan_principle'] + df_plan['plan_fee_amount'], 2)
    df_repay_out=df_repay_out[['plan_id','package_no','package_time','repay_time','type']]
    df=pd.merge(df_plan,df_repay_out,on='plan_id',how='inner')
    #TODO ===如果有重复的，需要进行处理，本次代码中没有做处理
    print '----plan_id 有重复的------',df.ix[df.plan_id.duplicated()]
    df=pd.merge(df,df_fs,on='plan_id',how='inner')
    #===质保金账户---有罚息的
    df_guarantee = df.ix[df.guarantee_account > 0]
    df_guarantee['account_id']=2
    #===有罚息的
    df_guarantee_good=df_guarantee.ix[(df_guarantee.guarantee_account == df_guarantee.plan_due_fee_amount) |
                                      (df_guarantee.guarantee_account ==df_guarantee.plan_prin_fee) |
                                      (df_guarantee.guarantee_account ==df_guarantee.plan_all)]
    df_guarantee_good.ix[(df_guarantee.guarantee_account == df_guarantee.plan_due_fee_amount),'plan_fee_amount'] =0
    df_guarantee_good.ix[(df_guarantee.guarantee_account == df_guarantee.plan_due_fee_amount), 'plan_principle'] = 0
    df_guarantee_good.ix[(df_guarantee.guarantee_account == df_guarantee.plan_prin_fee), 'plan_due_fee_amount'] = 0
    df_guarantee_bad = df_guarantee.ix[(df_guarantee.guarantee_account != df_guarantee.plan_due_fee_amount) &
                                      (df_guarantee.guarantee_account !=df_guarantee.plan_prin_fee) &
                                      (df_guarantee.guarantee_account !=df_guarantee.plan_all)]

    #====收入账户====,利息
    df_income = df.ix[df.income_account > 0]
    df_income['account_id'] = 3
    df_income_good=df_income.ix[(df_income.income_account == df_income.plan_fee_amount) |
                                (df_income.income_account == df_income.plan_prin_fee ) |
                                (df_income.income_account == df_income.plan_all)]
    df_income_good.ix[(df_income.income_account == df_income.plan_fee_amount),'plan_principle'] = 0
    df_income_good.ix[(df_income.income_account == df_income.plan_fee_amount), 'plan_due_fee_amount'] = 0
    df_income_good.ix[(df_income.income_account == df_income.plan_prin_fee), 'plan_due_fee_amount'] = 0

    df_income_bad = df_income.ix[(df_income.income_account != df_income.plan_fee_amount) &
                                (df_income.income_account != df_income.plan_prin_fee ) &
                                (df_income.income_account != df_income.plan_all)]

    #===保理账户====，退款,退本金
    df_factoring = df.ix[df.factoring_account > 0]
    df_factoring['account_id'] = 4
    df_factoring_good=df_factoring.ix[(df_factoring.factoring_account == df_factoring.plan_principle) |
                                      (df_factoring.factoring_account == df_factoring.plan_prin_fee) |
                                      (df_factoring.factoring_account == df_factoring.plan_all)]
    df_factoring_good.ix[(df_factoring.factoring_account == df_factoring.plan_principle), 'plan_fee_amount'] = 0
    df_factoring_good.ix[(df_factoring.factoring_account == df_factoring.plan_principle),'plan_due_fee_amount'] =0
    df_factoring_good.ix[(df_factoring.factoring_account == df_factoring.plan_prin_fee), 'plan_due_fee_amount'] = 0

    df_factoring_bad = df_factoring.ix[(df_factoring.factoring_account != df_factoring.plan_principle) &
                                      (df_factoring.factoring_account != df_factoring.plan_prin_fee) &
                                      (df_factoring.factoring_account != df_factoring.plan_all)]

    #====提现账户====，本息
    df_withdraw=df.ix[df.withdraw_account > 0]
    df_withdraw['account_id'] = 1
    #===提现账户，有的有本金，有的是本息
    df_withdraw_good=df_withdraw.ix[(df_withdraw.withdraw_account == df_withdraw.plan_principle) |
                                    (df_withdraw.withdraw_account == df_withdraw.plan_prin_fee) |
                                    (df_withdraw.withdraw_account == df_withdraw.plan_all)]
    df_withdraw_good.ix[df_withdraw.withdraw_account == df_withdraw.plan_principle,'plan_fee_amount'] = 0
    df_withdraw_good.ix[df_withdraw.withdraw_account == df_withdraw.plan_principle, 'plan_due_fee_amount'] = 0
    df_withdraw_good.ix[df_withdraw.withdraw_account == df_withdraw.plan_prin_fee, 'plan_due_fee_amount'] = 0


    df_withdraw_bad=df_withdraw.ix[(df_withdraw.withdraw_account != df_withdraw.plan_principle) &
                                   (df_withdraw.withdraw_account != df_withdraw.plan_prin_fee) &
                                   (df_withdraw.withdraw_account != df_withdraw.plan_all)]

    df_bad=pd.concat([df_guarantee_bad[['plan_id','package_no','package_time','repay_time','type','product_no','current_stage_no','plan_due_fee_amount']],
                      df_income_bad[['plan_id','package_no','package_time','repay_time','type','product_no','current_stage_no','plan_fee_amount']],
                      df_factoring_bad[['plan_id','package_no','package_time','repay_time','type','product_no','current_stage_no','plan_principle']],
                      df_withdraw_bad[['plan_id','package_no','package_time','repay_time','type','product_no','current_stage_no','plan_principle','plan_fee_amount']]
                      ],ignore_index=True)
    df_good=pd.concat([df_guarantee_good[['account_id','package_no','package_time','repay_time','type','product_no','current_stage_no','plan_due_fee_amount','plan_principle','plan_fee_amount']],
                      df_income_good[['account_id','package_no','package_time','repay_time','type','product_no','current_stage_no','plan_due_fee_amount','plan_principle','plan_fee_amount']],
                      df_factoring_good[['account_id','package_no','package_time','repay_time','type','product_no','current_stage_no','plan_due_fee_amount','plan_principle','plan_fee_amount']],
                      df_withdraw_good[['account_id','package_no','package_time','repay_time','type','product_no','current_stage_no','plan_due_fee_amount','plan_principle','plan_fee_amount']]
                      ],ignore_index=True)

    if len(df_bad) > 0:
        df_bad.to_csv('E:/bad.csv')
        print '================需要查看情况=============',len(df_bad)
    else:
        df_good.fillna(0,inplace=True)
        df_good['plan_all']=np.round(df_good['plan_principle']+df_good['plan_fee_amount']+df_good['plan_due_fee_amount'],2)
        df_good['fund_code'] = 3
        df_good['status'] = 1
        df_good.rename(columns={'plan_all':'repay_amount','plan_principle':'repay_principle','plan_fee_amount':'repay_fee_amount','plan_due_fee_amount':'repay_due_amount'},inplace=True)
        df_good.to_sql('fund_repay_detail',engine_qunaer,index=None,if_exists='append',chunksize=10000)

#-- 流水勾稽
def step_4(year,month):
    start_time = datetime.date(year, month, 1)
    end_time = start_time + relativedelta(months=+1)
    sql_flow='''
    select flow_id,trans_amount from bank_flow where status=0 and trans_type = 4 
    and trans_time >= '%s' and trans_time < '%s'
    ''' % (start_time,end_time)
    sql_repay='''
    select date(repay_time) repay_time,account_id,sum(repay_amount) repay_amount from fund_repay_detail 
    where fund_code = 3 AND flow_id is NULL and status =1 and repay_time >= '%s' and repay_time <= '%s'
    GROUP by 1,2
    ''' % (start_time,end_time)
    update_repay='''
    update fund_repay_detail set flow_id = %s WHERE fund_code=3 and flow_id is NULL and status=1 and date(repay_time) =%s and account_id = %s
    '''
    update_flow='''
    update bank_flow set status=1 where flow_id = %s
    '''
    df_flow=pd.read_sql(sql_flow,engine_qunaer)
    df_repay = pd.read_sql(sql_repay,engine_qunaer)
    df_diff=pd.merge(df_flow,df_repay,left_on='trans_amount',right_on='repay_amount',how='inner')
    df_diff['repay_time']=pd.to_datetime(df_diff.repay_time).dt.date
    df_diff=df_diff.ix[df_diff.trans_amount == df_diff.repay_amount]
    df_diff.flow_id=df_diff.flow_id.astype(str)
    df_diff.account_id=df_diff.account_id.astype(str)
    engine_qunaer.execute(update_repay,df_diff[['flow_id','repay_time','account_id']].values.tolist())
    engine_qunaer.execute(update_flow,df_diff[['flow_id']].values.tolist())




if __name__ == '__main__':
    # 资金方放款数据录入
    year=2017
    month = 10
    # 放款数据录入
    # step_1(year,month)
    # 更新哈银的 利息计算时间
    # step_1_1(year,month)

    # 资金方还款计划录入
    # 哈银
    # step_2_hy(year,month)


    # 哈银的还资金方表---,没有进行拆分QG 贴息
    # step_3_hy(year,month)

    #TODO === 更新还款计划===

    # 还款更新时注意下，有提前结清或退货的，一定要注意状态。

    # 流水勾稽
    # step_4(year,month)
