# encoding: utf8
from __future__ import unicode_literals

import datetime

import numpy as np
import pandas as pd
from dateutil.relativedelta import *
from sqlalchemy import create_engine

pd.options.mode.chained_assignment = None
import sys
import multiprocessing as mtp

reload(sys)
sys.setdefaultencoding('utf8')
engine_xyqb = create_engine('mysql+mysqldb://syzhu_data_r:ulk0989742097y43@192.168.4.6:8066/xyqb?charset=utf8',
                            echo=True)
engine_audit = create_engine('mysql+mysqldb://yulong_rw:TouBStYwN8wkdxVt@172.16.3.201:3306/audit?charset=utf8',
                             echo=True)

funding_detail_sql = """ 
 SELECT
	fc.`name` 资金方,
	frr.loan_id 产品编号,
	lm.loan_paid_at 放款日期,
	la.accountName 放款账户,
	lm.contract_loan_amount 放款金额,
	lm.real_loan_amount 本金,
	lm.contract_term 贷款总期数,
	frr.term_no,
	frr.deadline 应还资金方日期,
	IFNULL(plan.principle,0) 应还款本金,
	IFNULL(plan.interest,0) 应还款利息,
	frr.repaid_at 实还资金方日期,
	IFNULL(frr.principle,0) 实际支付本金,
	IFNULL(frr.interest,0) 实际支付利息,
	IFNULL(frr.prepay_fee,0) 提前还款服务费,
	IFNULL(frr.funding_service_fee,0) 资金方服务费,
	IFNULL(frr.punish_fee,0) 逾期罚息,
	frr.AIR 利率,
	lm.contract_term,
	lm.monthly_interest_rate,
	lm.contract_loan_amount,
	frr.funding_code,
	frr.flow_id 流水号

FROM
	funding_repayment_record frr
LEFT JOIN funding_corp fc ON frr.funding_code = fc.funding_code
LEFT JOIN new_transaction.user_repayment_plan plan ON plan.ref_id = frr.ref_id AND frr.term_no = plan.term_no
LEFT JOIN loan_manifest lm ON lm.ref_id =frr.ref_id
LEFT JOIN loan_account la ON la.id = lm.loan_account_id 
WHERE  
frr.repaid_at IS NOT NULL 
AND  frr.funding_code= %s 
AND year(frr.repaid_at)=%s 
AND MONTH(frr.repaid_at)=%s  
ORDER BY lm.loan_paid_at  """

funding_diandi_detail_sql = """ 
 SELECT
	fc.`name` 资金方,
	frr.loan_id 产品编号,
	lm.loan_paid_at 放款日期,
	la.accountName 放款账户,
	lm.contract_loan_amount 放款金额,
	lm.real_loan_amount 本金,
	lm.contract_term 贷款总期数,
	frr.term_no,
	frr.deadline 应还资金方日期,
	IFNULL(plan.principle,0) 应还款本金,
	IFNULL(plan.interest,0) 应还款利息,
	frr.repaid_at 实还资金方日期,
	IFNULL(frr.principle,0) 实际支付本金,
	IFNULL(frr.interest,0) 实际支付利息,
	IFNULL(frr.prepay_fee,0) 提前还款服务费,
	IFNULL(plan.service_fee,0) 资金方服务费,
	IFNULL(frr.punish_fee,0) 逾期罚息,
	frr.AIR 利率,
	lm.contract_term,
	lm.monthly_interest_rate,
	lm.contract_loan_amount,
	frr.funding_code,
	frr.flow_id 流水号

FROM
	funding_repayment_record frr
LEFT JOIN new_transaction.user_repayment_plan plan ON plan.real_loan_id = frr.loan_id AND frr.term_no = plan.term_no
LEFT JOIN funding_corp fc ON frr.funding_code = fc.funding_code
LEFT JOIN loan_manifest lm ON lm.ref_id =frr.ref_id
LEFT JOIN loan_account la ON la.id = lm.loan_account_id 
WHERE  
frr.funding_code= %s 
AND plan.deadline is NOT NULL
AND year(plan.deadline)=%s 
AND MONTH(plan.deadline)=%s  
ORDER BY lm.loan_paid_at  """
# columns_detail = ['资金方', '产品编号',  '放款日期', '放款账户', '放款金额', '本金', '贷款总期数', '应还款期数',
#                   '应还资金方日期', '应还款本金', '应还款利息', '实还资金方日期', '实际支付本金', '实际支付利息',
#                   '提前还款服务费','资金方服务费','逾期罚息', '利率']
# columns = ['打款年份', '打款月份', '打款账户', '资金方', '当期本息和', '当期本金', '当期利息', '提前还款服务费']

funding_codes = [0, 1, 2, 3, 4, 5, 29, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 135, 140, 141, 150, 160, 170, 180,
                 190, 200, 210, 220, 230, 240, 250, 251, 260, 270, 280, 290, 300, 310, 320, 330, 340, 350]


def cal_prin_inst(x):
    fund_id = int(x['funding_code'])
    a = x['contract_loan_amount']
    c = int(x['contract_term'])
    b = x['monthly_interest_rate'] * 12
    term = int(x['term_no'])
    result = {}
    if fund_id in (170, 190, 230, 260):
        result['total'] = np.pmt(b / 12, c, -a)
        result['prin'] = np.ppmt(b / 12, term, c, -a)
        result['inst'] = np.ipmt(b / 12, term, c, -a)
    elif fund_id == 140:
        result['prin'] = np.ceil(np.ppmt(b / 12, term, c, -a) * 100) / 100
        result['inst'] = np.ceil(np.ipmt(b / 12, term, c, -a) * 100) / 100
        result['total'] = result['prin'] + result['inst']
    elif fund_id == 180:
        # 剩余本金=合同金额
        # 计息天数=第一期还款日期 - 放款日期
        result['total'] = np.round(np.pmt(b / 12, c, -a), 2)
        if term == 1:
            money = a
            term_days = ((datetime.datetime.strptime(x['deadline'], '%Y-%m-%d')).date() - (
                (datetime.datetime.strptime(x['deadline'], '%Y-%m-%d')) + relativedelta(months=-1)).date()).days
            result['inst'] = np.round(b / 360 * money * term_days, 2)
            result['prin'] = result['total'] - result['inst']
        # 合同金额 - 第一期本金
        # 第二期还款日期 - 第一期还款日期
        else:
            money = a
            for i in xrange(1, term):
                term_days = ((
                                 (datetime.datetime.strptime(x['deadline'], '%Y-%m-%d')) + relativedelta(
                                     months=-(term - i))).date() - (
                                 (datetime.datetime.strptime(x['deadline'], '%Y-%m-%d')) + relativedelta(
                                     months=-(term - i + 1))).date()).days
                money -= result['total'] - np.round(b / 360 * money * term_days, 2)

            term_days = ((datetime.datetime.strptime(x['deadline'], '%Y-%m-%d')).date() - (
                (datetime.datetime.strptime(x['deadline'], '%Y-%m-%d')) + relativedelta(months=-1)).date()).days
            result['inst'] = np.round(b / 360 * money * term_days, 2)
            result['prin'] = (term == 3) and money or result['total'] - result['inst']
            result['total'] = (term == 3) and (result['inst'] + result['prin']) or result['total']

    elif fund_id in (150, 240, 290):
        result['inst'] = np.round(np.ipmt(b / 12, term, c, -a), 2)
        if term == c:
            result['prin'] = a
            for i in xrange(1, c):
                result['prin'] -= np.round(np.ppmt(b / 12, i, c, -a), 2)
            result['total'] = result['inst'] + result['prin']
        else:
            result['total'] = np.round(np.pmt(b / 12, c, -a), 2)
            # result['prin'] = np.round(np.ppmt(b / 12, term, c, -a), 2)
            result['prin'] = result['total'] - result['inst']
    elif fund_id == 200:
        result['total'] = np.round(np.pmt(b / 12, c, -a), 2)
        result['inst'] = np.round(np.ipmt(b / 12, term, c, -a), 2)
        if term == c:
            result['prin'] = a
            for i in xrange(1, c):
                result['prin'] -= np.round(np.ppmt(b / 12, i, c, -a), 2)
        else:
            result['prin'] = np.round(np.ppmt(b / 12, term, c, -a), 2)
    elif fund_id == 210:
        result['inst'] = np.round(np.ipmt(b / 12, term, c, -a), 2)
        if term == c:
            result['prin'] = a
            for i in xrange(1, c):
                result['prin'] -= (np.round(np.pmt(b / 12, c, -a), 2) - np.round(np.ipmt(b / 12, i, c, -a), 2))
            result['total'] = result['inst'] + result['prin']
        else:
            result['total'] = np.round(np.pmt(b / 12, c, -a), 2)
            result['prin'] = result['total'] - result['inst']
    elif fund_id == 250:
        result['total'] = np.round(np.pmt(b / 12, c, -a), 2)
        # result['prin'] = np.round(np.ppmt(b / 12, term, c, -a), 2)
        result['inst'] = np.round(np.ipmt(b / 12, term, c, -a), 2)
        result['prin'] = result['total'] - result['inst']
        # result['inst'] = result['total'] - result['prin']
    elif fund_id == 300:
        result['inst'] = 0
        if term == c:
            result['prin'] = a
            for i in xrange(1, c):
                result['prin'] -= np.round(a / c, 2)
            result['total'] = result['prin'] + result['inst']
        else:
            result['prin'] = np.round(a / c, 2)
            result['total'] = result['prin'] + result['inst']
    elif fund_id == 310:
        result['inst'] = np.round(np.ipmt(b / 12, term, c, -a), 2)
        if term == c:
            result['prin'] = a
            for i in xrange(1, c):
                result['prin'] -= np.round(np.ppmt(b / 12, i, c, -a), 2)
            result['total'] = result['inst'] + result['prin']
        else:
            result['total'] = np.round(np.pmt(b / 12, c, -a), 2)
            result['prin'] = np.round(np.ppmt(b / 12, term, c, -a), 2)
    elif fund_id == 270:
        result['inst'] = np.round(np.ipmt(b / 12, term, c, -a), 2)
        if term == c:
            result['prin'] = a
            for i in xrange(1, c):
                result['prin'] -= np.round(np.ppmt(b / 12, i, c, -a), 2)
            result['total'] = result['inst'] + result['prin']
        else:
            result['total'] = np.round(np.pmt(b / 12, c, -a), 2)
            result['prin'] = np.round(np.ppmt(b / 12, term, c, -a), 2)
    return result


def repay_funding_detail_by_code(funding_code, year, month):
    # if funding_code in (2,3):
    #     df = pd.read_sql(funding_diandi_detail_sql % (str(funding_code), int(year), int(month),), con=engine_audit)
    # else:
    #     df = pd.read_sql(funding_detail_sql % (str(funding_code), int(year), int(month),), con=engine_audit)
    df = pd.read_sql(funding_detail_sql % (str(funding_code), int(year), int(month),), con=engine_audit)
    if len(df) > 0:
        df.rename(columns={'term_no': u'应还款期数'}, inplace=True)
        df.drop(['funding_code', 'contract_loan_amount', 'contract_term', 'monthly_interest_rate'], axis=1,
                inplace=True)
        # df.drop(['contract_loan_amount'], axis=1, inplace=True)
        # df.drop(['contract_term'], axis=1, inplace=True)
        # df.drop(['monthly_interest_rate'], axis=1, inplace=True)
        df.to_excel('E:/数据汇总/还资金方明细表/现金贷/资金方明细%s_%s年%s月.xlsx' % (funding_code, year, month,), index=None)


for m in range(1, 13):
    repay_funding_detail_by_code(3, 2015, m)

# if __name__ == '__main__':
#     # years = [2015,]
#     # months = range(6, 13)
#     # import itertools
#     # con = itertools.product(years, months)
#     # for (year, month) in con:
#     #     repay_funding_detail_by_code(3, year, month)
#     years = [2015, 2016, 2017]
#     months = range(1, 13)
#     import itertools
#     con = itertools.product(years, months)
#     pool = mtp.Pool(processes=8)
#     for (year, month) in con:
#         for funding_code in funding_codes:
#             print '------begin---', funding_code
#             pool.apply_async(repay_funding_detail_by_code, (funding_code, year,month))
#     pool.close()
#     pool.join()
