# -*- encoding: utf8 -*-

"""
目标：
    收入确认表-以loan_id为维度比较风险金及客户实还服务费
数据库：

字段名：
    loan_id，资金方，风险等级，本金债权，放款日期，计提风险金比例，计提风险金，实还服务费（减免后，含一次性服务费），Asset余额，收入确认金额
注意：
    加入一次性服务费，计提风险金比例
    每个时间点用对应时间点的备份库，eg：17年4月30号之前的用430数据库，5月31号之前的用531库。。。
"""

import os

import datetime
import numpy as np
import pandas as pd

from db_con.db_connect import sql_engine

# ----------------------------------------------
step = 10000
max_limit = 900000
pd.options.mode.chained_assignment = None
pd.set_option('display.float_format', lambda x: '%.5f' % x)
db_name = 'all_back_0830'
end_date = datetime.date(2017, 9, 1)
file_path = u'E:/审计出表/现金贷'
file_name = u'现金贷收入确认表'
if not os.path.exists(file_path):
    os.makedirs(file_path)
mysql = sql_engine('audit', 'all_back_0830').get_engine()
loan_col = [u'loan_id', u'ref_id', u'风险等级', u'funding_code', u'资金方', u'is_active', u'本金债权', u'qg_one_time_service_fee',
            u'放款日期', u'计提风险金比例']
res_cols = [u'loan_id', u'风险等级', u'资金方', u'本金债权', u'放款日期', u'计提风险金比例', u'计提风险金',
            u'实还服务费（减免后、含一次性服务费）', u'asset余额', u'收入确认金额']

sql_loan_plan = """
 SELECT
   lm.loan_id,
   lm.ref_id,
   lc.class                风险等级,
   lm.funding_code,
   fc.name                 资金方,
   lm.is_active,
   lm.contract_loan_amount 本金债权,
   lm.qg_one_time_service_fee,
   date(lm.loan_paid_at)   放款日期,
   year(lm.loan_paid_at)   年,
   month(lm.loan_paid_at)  月
 FROM %s.loan_manifest lm
   JOIN basic.loan_class_0912 lc ON lc.ref_id = lm.ref_id
   JOIN basic.funding_corp fc ON fc.funding_code = lm.funding_code
 WHERE lm.loan_paid_at < '%s';
 """ % (db_name, end_date)

sql_ref = """SELECT
   urp.ref_id,
   xrprrr.service_fee - xrprrr.mitigate_service_fee `实还服务费（减免后）`,
   DATE(xrprrrrd.repaid_at)                         `repaid_at`
 FROM %s.xjd_repay_plan_repay_record_ref xrprrr
   JOIN test_mzh.xjd_repay_plan_repay_record_ref_repay_date_flow xrprrrrd ON xrprrr.id = xrprrrrd.xjd_ref_id
   JOIN %s.user_repayment_plan urp ON urp.id = xrprrr.plan_id
 WHERE xrprrrrd.repaid_at < '%s';
 """ % (db_name, db_name, end_date)
sql_ms = """SELECT
   nmtwtd.loan_id,
   nmtwtd.term_no,
   nmtwtd.qg_service_fee  `实还服务费（减免后）`,
   DATE(nmtwtd.repaid_at) `repaid_at`
 FROM test_8_2.new_ms_transaction_with_term_details nmtwtd
 WHERE nmtwtd.repaid_at < '%s'
 """ % (end_date,)
# ----------------------------------------------

# ##############################################
# 查数据库，并保存文件，时间较长，服务器上在15分钟左右，本机25分钟左右
df_gen = pd.read_sql(sql=sql_loan_plan, con=mysql, chunksize=step)
res = []
for tmp in df_gen:
    res.append(tmp)
df_loan = pd.concat(res)
df_loan['qg_one_time_service_fee'].fillna(0, inplace=True)
df_loan.to_csv(os.path.join(file_path, 'all_loan_%s.csv' % db_name), encoding='utf8', index=None)

df_gen = pd.read_sql(sql=sql_ref, con=mysql, chunksize=step)
res = []
for tmp in df_gen:
    res.append(tmp)
df_ref = pd.concat(res)
df_ref.to_csv(os.path.join(file_path, 'all_ref_%s.csv' % db_name), encoding='utf8', index=None)

df_ms = pd.read_sql(sql=sql_ms, con=mysql)
df_ms.to_csv(os.path.join(file_path, 'ms.csv'), encoding='utf8', index=None)
# #############################################

# #######################
# 查文件
# df_loan = pd.read_csv(os.path.join(file_path, 'all_loan.csv'), encoding='utf8', low_memory=False)
# df_ref = pd.read_csv(os.path.join(file_path, 'all_ref.csv'), encoding='utf8', low_memory=False)
# df_ms = pd.read_csv(os.path.join(file_path, 'ms.csv'), encoding='utf8', low_memory=False)
# df_loan[u'放款日期'] = pd.to_datetime(df_loan[u'放款日期'])
# df_ref[u'repaid_at'] = pd.to_datetime(df_ref[u'repaid_at'])
# df_ms[u'repaid_at'] = pd.to_datetime(df_ms[u'repaid_at'])
# #######################

df_ms.loan_id = df_ms.loan_id.astype(str)
df_loan.loan_id = df_loan.loan_id.astype(str)

sql_ratio = """SELECT class 风险等级, year 年, month 月, bad_debt_ratio 计提风险金比例 FROM test_mzh.service_fee_ratio"""
df_ratio = pd.read_sql(sql=sql_ratio, con=mysql)
df_loan_ratio = pd.merge(df_loan, df_ratio, on=[u'风险等级', u'年', u'月'], how='left')
df_loan_ratio.loc[df_loan_ratio.funding_code.isin([270, 310, 320]), u'计提风险金比例'] = 0


def proc_save(watch_date):
    loan = df_loan_ratio.loc[df_loan_ratio[u'放款日期'] < watch_date]
    loan.loc[~loan.is_active.isin([1, -2]), u'本金债权'] = 0

    loan_other = loan.loc[~loan[u'funding_code'].isin([160, 340])]
    loan_ms = loan.loc[loan[u'funding_code'] == 160]
    loan_yghs = loan.loc[loan[u'funding_code'] == 340]

    loan_other_unique = loan_other[loan_col]
    loan_ms_unique = loan_ms[loan_col]
    loan_yghs_unique = loan_yghs[loan_col]

    ref = df_ref.loc[df_ref.repaid_at < watch_date]
    gp_other = ref.groupby('ref_id')[u'实还服务费（减免后）'].agg(sum).reset_index()

    ms = df_ms.loc[df_ms.repaid_at < watch_date]
    gp_ms = ms.groupby('loan_id')[u'实还服务费（减免后）'].agg(sum).reset_index()

    yghs = df_yghs.loc[df_yghs.repaid_at < watch_date]
    gp_yghs = yghs.groupby('ref_id')[u'实还服务费（减免后）'].agg(sum).reset_index()

    loan_other_result = pd.merge(loan_other_unique, gp_other, how='left')
    loan_other_result.fillna(0, inplace=True)

    loan_ms_result = pd.merge(loan_ms_unique, gp_ms, how='left')
    loan_ms_result.fillna(0, inplace=True)

    loan_yghs_result = pd.merge(loan_yghs_unique, gp_yghs, how='left')
    loan_yghs_result.fillna(0, inplace=True)

    loan_result = pd.concat([loan_other_result, loan_ms_result, loan_yghs_result])
    loan_result[u'计提风险金'] = np.round(loan_result[u'本金债权'] * loan_result[u'计提风险金比例'], 2)
    loan_result.loc[loan_result.funding_code.isin([270, 310, 320]), u'计提风险金'] = 0

    loan_result[u'实还服务费（减免后、含一次性服务费）'] = np.round(loan_result[u'实还服务费（减免后）'] + loan_result[u'qg_one_time_service_fee'],
                                                  2)
    loan_result[u'asset余额'] = np.maximum(np.round(loan_result[u'计提风险金'] - loan_result[u'实还服务费（减免后、含一次性服务费）'], 2), 0)
    loan_result[u'收入确认金额'] = np.minimum(np.round(loan_result[u'计提风险金'] - loan_result[u'实还服务费（减免后、含一次性服务费）'], 2), 0)
    print(loan_result[[u'本金债权', u'实还服务费（减免后）', u'实还服务费（减免后、含一次性服务费）']].sum())
    loan_result = loan_result[res_cols]
    loan_result.to_csv(os.path.join(file_path, '%s(%s-%02d).csv' % (file_name, watch_date.year, watch_date.month - 1)),
                       index=None, encoding='utf8')
    if len(loan_result) > max_limit:
        for i in xrange(0, len(loan_result), max_limit):
            loan_result[i:i + max_limit].to_csv(os.path.join(file_path, '%s(%s-%02d)-%d.csv' % (
            file_name, watch_date.year, watch_date.month - 1, i / max_limit + 1)), index=None, encoding='utf8')
    # if len(loan_result) > max_limit:
    #     excel_file = pd.ExcelWriter(
    #         os.path.join(file_path, '%s(%s-%02d).xlsx' % (file_name, watch_date.year, watch_date.month - 1)))
    #     for i in xrange(0, len(loan_result), max_limit):
    #         loan_result[i:i + max_limit].to_excel(excel_file, str(i / max_limit + 1), index=None)
    #     excel_file.save()
    # else:
    #     loan_result.to_excel(
    #         os.path.join(file_path, '%s(%s-%02d).xlsx' % (file_name, watch_date.year, watch_date.month - 1)),
    #         index=None)


date_report_list = [datetime.date(2016, 4, 1), datetime.date(2016, 7, 1), datetime.date(2016, 10, 1),
                    datetime.date(2017, 2, 1),
                    datetime.date(2017, 3, 1), datetime.date(2017, 4, 1), datetime.date(2017, 5, 1)]
for watch_date in date_report_list:
    print(watch_date + datetime.timedelta(days=-1))
    proc_save(watch_date)

    # date_range = pd.date_range(start='2017-02', end='2017-08', freq='MS')
    # for watch_date in date_range:
    #     print(watch_date,)
    #     proc_save(watch_date.date())
