# -*- 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://yulong:ohVU1nPITynSZwR2@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://linfang.wang:&*uijknbghyt63er45@172.16.3.184:7306/xyqb_btzt?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_fee_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 >= '' and account_at < ''
    '''
    sql_repay='''
    SELECT plan_id AS plan_ids,batch_id AS package_no,push_at AS package_time,account_at AS repay_time,type,principal AS sum_repay_principle, service_fee AS sum_repay_fee_amount,
    total_fee AS sum_repay_amount 
    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,t1.current_term AS current_stage_no,t1.principal AS repay_principle,t1.service_fee AS repay_fee_amount,t1.over_due_service_fee AS repay_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_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['repay_principle']+df_plan['repay_fee_amount']+df_plan['repay_due_fee_amount'],2)
    df=pd.merge(df_plan,df_repay_out,on='plan_id',how='right')
    df_plan_gp=df.groupby('plan_ids')['plan_all'].sum().reset_index().rename(columns={'plan_all':'sum_plan_all'})
    # df_real_gp=df.groupby('product_no')['sum_repay_amount'].sum().reset_index().rename(columns={'sum_repay_amount':'sum_real_all'})
    df=pd.merge(df,df_plan_gp,on='plan_ids',how='left')
    df['diff']=np.round(df['sum_plan_all']-df['sum_repay_amount'],2)
    df_bad = df.ix[df['diff'] != 0]
    if len(df_bad) > 0:
        df_bad.to_csv('E:/bad.csv')
        print '================需要查看情况=============',len(df_bad)
    else:
        df_good=df.ix[df['diff'] == 0]
        df_good=df_good[['product_no','current_stage_no','repay_principle','plan_all','repay_fee_amount','repay_due_fee_amount','package_no','package_time','repay_time','type']]
        df_good['fund_code'] = 3
        df_good['status'] = 1
        df_good.rename(columns={'plan_all':'repay_amount'},inplace=True)
        df_good.to_sql('fund_repay_detail',engine_qunaer,index=None,if_exists='append',chunksize=10000)











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

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

    # 惠金所还款计划
    # step_2_hjs(year,month)


    # 哈银的还资金方表---这个没有考虑账户问题，需要去财务系统拉数据，考虑账户问题。
    # step_3_hy(year,month)



    # 如果惠金所有 提前结清的，那么还款计划中，应还金额为 0 --使用sql即可---这块在 8和9月进行执行即可；后续无需执行
    # sql='''
    #   UPDATE `fund_repayment_plan` SET interest = 0 ,STATUS = 4 WHERE fund_code = 2 AND product_no IN (
    #     SELECT product_no FROM `fund_repay_detail` WHERE fund_code = 2 AND TYPE=5 AND STATUS=1 AND repay_amount > 0 )
    # '''
    # sql = '''
    #       UPDATE `fund_repayment_plan` SET interest = 0 ,STATUS = 5 WHERE fund_code = 2 AND product_no IN (
    #         SELECT product_no FROM `fund_repay_detail` WHERE fund_code = 2 AND TYPE=7 AND STATUS=1 AND repay_amount > 0 )
    # '''

    # 惠金所的还资金方表
    # 使用脚本 惠金所的还资金方表特殊处理即可.py---执行完后，执行下面的SQL 然后更新资金方的还款状态为已还
    # 还款更新时注意下，有提前结清或退货的，一定要注意状态。
