# -*- encoding: utf8 -*-
import sys
import datetime
import pandas as pd
from sqlalchemy import create_engine
from dateutil.relativedelta import relativedelta
import multiprocessing as mtp
from itertools import product

reload(sys)
sys.setdefaultencoding("utf-8")
pd.options.mode.chained_assignment = None

#
# 表名称：
#	白条-去哪儿-核算-放款表：分多种类型，转让保理后的放款表，资金方的放款表，针对用户角度的放款表
#
#


file_path = u'E:/量化派/去哪儿/常规出账/'
file_name = u'核算放款表_%s_%s.xlsx'
engine_qunaer = create_engine('mysql+mysqldb://internal_r:ArbNgtvlJzZHXsEu@172.16.3.201:3306/qunaer_new?charset=utf8',
							  echo=False).connect()
# 债权转让后的保理放款表
def baoli_pay(year, month,plan_table='baoli_repayment_plan'):
	start_time = datetime.datetime(year, month, 1, 0, 0, 0)
	end_time = start_time + relativedelta(months=+1)
	sql_pay = '''
	select '保理' AS '资金方',
		pay.product_no '产品编号',
		date(pay.trans_time) '债转时间',
		date(pay.loan_time) '放款时间',
		pay.loan_amount '合同放款金额',
		pay.new_stages AS '贷款总期数',
		'FALSE' AS '是否退款',
		'FALSE' AS  '是否转分期后订单',
		'FALSE' AS  '是否资金方直投',
		plan.current_stage_no '当期期数',
		date(plan.deadline) '每期应还款日',
		plan.principle+plan.fee_amount '每期应还金额',
		plan.principle '每期应还本金',
		plan.fee_amount AS '每期应还服务费',
		0 AS '每期应还服务费-QG承担'
	from qunaer_new.baoli_pay_detail pay
	join %s plan on pay.product_no = plan.product_no 
	where trans_time >='%s' and trans_time < '%s'
	''' % (plan_table,start_time, end_time)

	# 属于保理的退款--flow_id 提取空的
	sql_refund='''
	select '保理' AS '资金方',
	refund.product_no '产品编号',
	date(pay.trans_time) '债转时间',
	date(pay.loan_time) '放款时间',
	refund.refund_amount '合同放款金额',
	pay.new_stages '贷款总期数',
	'TRUE' AS '是否退款',
	date(refund.refund_time) AS '退款时间',
	month(refund.refund_time) AS '退款月份',
	'FALSE' AS  '是否转分期后订单',
	'FALSE' AS  '是否资金方直投'
	from qunaer_new.refund_detail refund
	JOIN qunaer_new.baoli_pay_detail pay on refund.product_no = pay.product_no and refund.fund_code = 1
	WHERE refund_time >='%s' and refund_time < '%s' and refund.flow_id IS NULL 
	''' % (start_time,end_time)
	# 读取sql语句，2分钟左右
	df_pay = pd.read_sql(sql_pay, engine_qunaer)
    # 含有 flow_id 的退款，在还款表中体现。
	df_refund = pd.read_sql(sql_refund, engine_qunaer)
	# 合并退款记录和放款记录
	df = pd.concat([df_pay, df_refund], ignore_index=True)
	df = df.fillna(0)
	df.ix[df[u'当期期数'] > 1,u'合同放款金额'] = 0
	return df[[u'资金方',u'产品编号',u'债转时间',u'放款时间',u'合同放款金额',u'贷款总期数',u'是否退款',u'退款时间',u'退款月份',u'是否转分期后订单',
			   u'是否资金方直投',u'当期期数',u'每期应还款日',u'每期应还金额',u'每期应还本金',u'每期应还服务费',u'每期应还服务费-QG承担']]

# 资金方放款表
def fund_pay(year,month,plan_table='fund_repayment_plan'):
	start_time = datetime.datetime(year, month, 1, 0, 0, 0)
	end_time = start_time + relativedelta(months=+1)
	# 资金方的放款表
	sql_pay = '''
    	select fc.fund_name '资金方',
    		pay.product_no '产品编号',
    		date(pay.trans_time) '订单时间',
    		date(pay.loan_time) '放款时间',
    		pay.loan_amount '合同放款金额',
    		pay.stages '贷款总期数',
    		'FALSE' AS '是否退款',
    		'FALSE' AS '是否转分期后订单',
    		'TRUE' AS '是否资金方直投',
    		plan.current_stage_no '当期期数',
    		date(plan.deadline) '每期应还款日',
    		plan.principle+plan.fee_amount '每期应还金额',
    		plan.principle '每期应还本金',
    		plan.fee_amount '每期应还服务费',
    		if(pay.stages=1,plan.fee_amount,0) '每期应还服务费-QG承担'
    	from qunaer_new.fund_pay_detail pay
    	join %s plan on pay.product_no = plan.product_no 
    	join qunaer_new.fund_corp fc on pay.fund_code = fc.fund_code
    	where trans_time >='%s' and trans_time < '%s'
    ''' % (plan_table,start_time, end_time)

	# 属于资金方的退款
	sql_refund = '''
    	select fc.fund_name '资金方',
    	refund.product_no '产品编号',
    	date(pay.trans_time) '订单时间',
    	date(pay.loan_time) '放款时间',
    	refund.refund_amount '合同放款金额',
    	pay.stages '贷款总期数',
    	'TRUE' AS '是否退款',
    	DATE(refund.refund_time) AS '退款时间',
    	MONTH(refund.refund_time) AS '退款月份',
    	'FALSE' AS '是否转分期后订单',
    	'TRUE' AS '是否资金方直投'
    	from qunaer_new.refund_detail refund
    	JOIN qunaer_new.fund_pay_detail pay on refund.product_no = pay.product_no and refund.fund_code = pay.fund_code
    	JOIN qunaer_new.fund_corp fc on refund.fund_code = fc.fund_code
    	WHERE refund_time >='%s' and refund_time < '%s' AND refund.flow_id is NULL 
    	''' % (start_time, end_time)
	# 读取sql语句，2分钟左右
	df_pay = pd.read_sql(sql_pay, engine_qunaer)
	# 含有 flow_id 的退款，在还款表中体现。
	df_refund = pd.read_sql(sql_refund, engine_qunaer)
	# 合并退款记录和放款记录
	df = pd.concat([df_pay, df_refund], ignore_index=True)
	df = df.fillna(0)
	df.ix[df[u'当期期数'] > 1, u'合同放款金额'] = 0
	return df[[u'资金方',u'产品编号',u'订单时间',u'放款时间',u'合同放款金额',u'贷款总期数',u'是否退款',u'退款时间',u'退款月份',u'是否转分期后订单',
			   u'是否资金方直投',u'当期期数',u'每期应还款日',u'每期应还金额',u'每期应还本金',u'每期应还服务费',u'每期应还服务费-QG承担']]

#保理的放款表，注意，非债权转让后的放款表
def user_pay(year,month,plan_table='repayment_plan_2017'):
	start_time = datetime.datetime(year, month, 1, 0, 0, 0)
	end_time = start_time + relativedelta(months=+1)
	# 用户的放款表
	sql_pay = '''
        select '保理' AS '资金方',
        	pay.product_no '产品编号',
        	date(pay.trans_time) '订单时间',
        	date(pay.loan_time) '放款时间',
        	pay.loan_amount '合同放款金额',
        	pay.stages '贷款总期数',
        	'FALSE' AS '是否退款',
        	if(pay.is_ptf = 0,'FALSE','TRUE') '是否转分期后订单',
        	'FALSE' AS '是否资金方直投',
        	plan.current_stage_no '当期期数',
        	date(plan.deadline) '每期应还款日',
        	plan.principle+plan.fee_amount '每期应还金额',
        	plan.principle '每期应还本金',
        	plan.fee_amount '每期应还服务费',
        	0 '每期应还服务费-QG承担'
        from qunaer_new.pay_detail pay
        join %s plan on pay.product_no = plan.product_no 
        where pay.fund_code = 1 and trans_time >='%s' and trans_time < '%s'
    ''' % (plan_table,start_time, end_time)

	# 属于保理的退款
	sql_refund = '''
        select '保理' AS '资金方',
        refund.product_no '产品编号',
        date(pay.trans_time) '订单时间',
        date(pay.loan_time) '放款时间',
        refund.refund_amount '合同放款金额',
        pay.stages '贷款总期数',
        'TRUE' AS '是否退款',
        date(refund.refund_time) '退款时间',
        MONTH(refund.refund_time) '退款月份',
        refund.refund_principle '退款本金',
        refund.refund_fee_amount '退款服务费',
        refund.refund_due_amount '退款罚息',
        if(pay.is_ptf = 0,'FALSE','TRUE') '是否转分期后订单'
        from qunaer_new.refund_detail refund
        JOIN qunaer_new.pay_detail pay on refund.product_no = pay.product_no and refund.fund_code = pay.fund_code
        WHERE pay.fund_code = 1 and refund_time >='%s' and refund_time < '%s' AND refund.flow_id is NULL 
    ''' % (start_time, end_time)
	# 读取sql语句，2分钟左右
	df_pay = pd.read_sql(sql_pay, engine_qunaer)
	# 如果期数 > 1 的，放款为0
	df_pay.ix[df_pay[u'当期期数'] > 1,u'合同放款金额'] = 0
	# 含有 flow_id 的退款，在还款表中体现。
	df_refund = pd.read_sql(sql_refund, engine_qunaer)
	# 合并退款记录和放款记录
	df = pd.concat([df_pay, df_refund], ignore_index=True)
	df = df.fillna(0)
	return df[[u'资金方',u'产品编号',u'订单时间',u'放款时间',u'合同放款金额',u'贷款总期数',u'是否退款',u'退款时间',u'退款月份',u'退款本金',u'退款服务费',u'退款罚息',u'是否转分期后订单',
			   u'是否资金方直投',u'当期期数',u'每期应还款日',u'每期应还金额',u'每期应还本金',u'每期应还服务费',u'每期应还服务费-QG承担']]


if __name__ == '__main__':
	years = [2017]
	months = range(8,9)
	for year, month in product(years, months):
		df_baoli=baoli_pay(year,month,plan_table='baoli_repayment_plan_201708')
		df_fund=fund_pay(year,month,plan_table='fund_repayment_plan_201708')
		df_user=user_pay(year,month,plan_table='repayment_plan_201708')
		writer=pd.ExcelWriter(file_path+file_name%(year,month))
		# 后续就没有内保了，只有债转后的内保。
		if len(df_user) > 0:
			df_user.to_excel(writer,sheet_name=u'保理放款表',encoding='UTF-8',index=None)
		df_fund.to_excel(writer,sheet_name=u'资金方放款表',encoding='UTF-8',index=None)
		df_baoli.to_excel(writer, sheet_name=u'债转后的保理放款表', encoding='UTF-8', index=None)
		writer.save()
		writer.close()


print '-----------------------main done---------------------------------------'