Exemple #1
0
def logout(request):

    # update last login
    cur_usr = sup_fn.get_user(request)
    sess = Session.objects.get(pk=request.COOKIES.get('sessionid'))
    if sess.get_decoded()['type'] == 'ADMIN':
        usr_list = AdminUser.objects.filter(email=cur_usr.email)

        try:
            del request.session['email']
            del request.session['timestamp']
            del request.session['type']
            del request.session['handling_side']
        except KeyError:
            pass
    else:
        usr_list = User.objects.filter(email=cur_usr.email, status='ACTIVE')
        for usr in usr_list:
            usr.last_login = cur_usr.this_login
            usr.save()
        try:
            del request.session['email']
            del request.session['timestamp']
            del request.session['type']
        except KeyError:
            pass

    sess.delete()
    return redirect('/login')
	def get(self, request, format=None):
		usr = sup_fn.get_user(request)
		bor_id = request.GET.get('bor_id')
		
		# check XSS
		if sup_fn.checkHTMLtags([v for k, v in request.GET.iteritems()]):
			return HttpResponse('Invalid input.')
		
		if bor_id == 'all':
			bor_list = BorrowRequest.objects.filter(usr_id = usr.id)
			bor_list = [bor for bor in bor_list if bor.status == 'DISBURSED' or 'PAYBACK' in bor.status]
		else:
			bor_list = BorrowRequest.objects.filter(id = bor_id)
			
		schedule_list = []
		min_start_date = None
		max_end_date = None
		
		for bor in bor_list:
			loan_list = Loan.objects.filter(bor_id = bor.id)
			prod = Product.objects.get(id = bor.prod_id)
			bor.draw_down_date = timezone.localtime(bor.draw_down_date)
			start_date_day = bor.draw_down_date.day
			start_date_month = bor.draw_down_date.month + 1
			start_date_year = bor.draw_down_date.year
			amount_per_month = prod.total_amount / prod.repayment_period
			interest_per_month = prod.total_amount * prod.APR_borrower * 0.01 * (prod.repayment_period / 12) / prod.repayment_period
			for i in range(prod.repayment_period):
				day = start_date_day
				month = (start_date_month + i-1) % 12 + 1
				year = start_date_year + ((start_date_month+i-1) / 12)
				try:
					date = datetime.strptime(str(day)+'/'+str(month)+'/'+str(year), '%d/%m/%Y')
				except ValueError:
					date = datetime.strptime('1/'+str((month%12)+1)+'/'+str(year), '%d/%m/%Y') - dt.timedelta(days=1)
				today = datetime.strptime(timezone.localtime(timezone.now()).strftime('%d/%m/%Y'), '%d/%m/%Y')
				if date < today and bor.repaid_month >= (i+1):
					status = 'PAID'
				elif date < today and bor.repaid_month < (i+1):
					status = 'OVERDUE'
				elif date >= today:
					status = 'OPEN'
				schedule = {
				'date': timezone.localtime(date).strftime('%d/%m/%Y'),
				'os_principal': round(prod.total_amount - amount_per_month * (i+1),1), 
				'os_interest': round(prod.total_amount * prod.APR_borrower * 0.01 * (prod.repayment_period / 12) - interest_per_month * (i+1),1), 
				'os_balance': round(prod.total_amount - amount_per_month * (i+1),1)+round(prod.total_amount * prod.APR_borrower * 0.01 * (prod.repayment_period / 12) - interest_per_month * (i+1),1),
				'paid_principal': round(amount_per_month, 1) if status == 'PAID' else 0,
				'paid_interest': round(interest_per_month, 1) if status == 'PAID' else 0,
				'ref_num': bor.ref_num,
				'prod_name': prod.name_en,
				'installment': round(amount_per_month+interest_per_month, 1),
				'status': status,
				
				}
				schedule_list.append(schedule)
		serialized_table_list = RepayTableSerializer(schedule_list, many=True)
		content = {'data': serialized_table_list.data}
		return Response(content)
	def get(self, request, format=None):
		usr = sup_fn.get_user(request)
		lang = sup_fn.get_lang(request)
		
		prod_id = request.GET.get('prod_id')
		if prod_id == 'all':
			inv_list = Investment.objects.filter(usr_id=usr.id)
		else:
			inv_list = Investment.objects.filter(usr_id=usr.id,prod_id=prod_id)
		
		#color_lib = {'red':['#E08283','#E7505A','#D91E18'],'green':['#36D7B7','#4DB3A2','#26C281'],'yellow':['#F4D03F','#F7CA18','#F3C200']}
		color_lib = ['#E08283','#36D7B7','#F4D03F','#BF55EC','#3598DC']
		i = 0
		data_list = []
		returning_principal = 0
		returning_interest = 0
		returned_principal = 0
		returned_interest = 0
		overdue = 0
		for inv in inv_list:
			prod = Product.objects.get(id=inv.prod_id)
			loan_list = Loan.objects.filter(inv_id=inv.id)
			loan_list = [loan for loan in loan_list if 'DISBURSED' in loan.status or 'PAYBACK' in loan.status]
			returning_principal += sum([loan.remain_principal for loan in loan_list])
			returning_interest += sum([loan.remain_interest_lender for loan in loan_list])
			returned_principal += sum([loan.initial_amount-loan.remain_principal for loan in loan_list])
			returned_interest += sum([loan.initial_amount for loan in loan_list]) * prod.APR_lender * 0.01 * (prod.repayment_period / 12) - sum([loan.remain_interest_lender for loan in loan_list])
			overdue += sum([loan.overdue_principal+loan.overdue_interest for loan in loan_list])
		
		if lang == 'en':
			if prod_id == 'all':
				name = 'All Products'
			else:
				name = Product.objects.get(id = prod_id).name_en
				
			data_list.append({'name': 'Returning Principal', 'amount': returning_principal, 'color': color_lib[0]})
			data_list.append({'name': 'Returning Interest', 'amount': returning_interest, 'color': color_lib[1]})
			data_list.append({'name': 'Returned Principal', 'amount': returned_principal, 'color': color_lib[2]})
			data_list.append({'name': 'Returned Interest', 'amount': returned_interest, 'color': color_lib[3]})
			data_list.append({'name': 'Overdue', 'amount': overdue,'color': color_lib[4]})
		elif lang == 'zh':
			if prod_id == 'all':
				name = '全部產品'
			else:
				name = Product.objects.get(id = prod_id).name_zh.encode('utf8')
				
			data_list.append({'name': '待收本金', 'amount': returning_principal, 'color': color_lib[0]})
			data_list.append({'name': '待收利息', 'amount': returning_interest, 'color': color_lib[1]})
			data_list.append({'name': '已收本金', 'amount': returned_principal, 'color': color_lib[2]})
			data_list.append({'name': '已收利息', 'amount': returned_interest, 'color': color_lib[3]})
			data_list.append({'name': '逾期還款', 'amount': overdue,'color': color_lib[4]})
		
		for data in data_list:
			data['amount'] = round(data['amount'], 2)
			
		#serialized_data_list = RepayPieSerializer(data_list, many=True)
		content = {'data': data_list}
		return Response(content)
Exemple #4
0
def footer(request):
	user = sup_fn.get_user(request)
	lang = sup_fn.get_lang(request)
	if user.type == 'L':
		content = {'lang': lang,}
		return render(request, 'peerloan/lender/footer.html', content)
		
	if user.type == 'B':
		content = {'lang': lang,}
		return render(request, 'peerloan/borrower/footer.html', content)
def trans_records(request):
	usr = sup_fn.get_user(request)
	lang = sup_fn.get_lang(request)
	
	if usr.type == 'B':
		content = {
		'lang': lang,
		'cate': 'trans_records',
		'title': 'Transaction Records',
		}
		if lang == 'zh':
			content['title'] = '交易紀錄'
		return render(request, 'peerloan/borrower/trans_records.html', content)
	def get(self, request, format=None):
		usr = sup_fn.get_user(request)
		bor_id = request.GET.get('bor_id')
		
		# check XSS
		if sup_fn.checkHTMLtags([v for k, v in request.GET.iteritems()]):
			return HttpResponse('Invalid input.')
		
		data_list = []
		if bor_id == 'all':
			bor_list = BorrowRequest.objects.filter(usr_id = usr.id)
			bor_list = [bor for bor in bor_list if bor.status == 'DISBURSED' or 'PAYBACK' in bor.status]
		else:
			bor_list = BorrowRequest.objects.filter(id = bor_id)
		total_principal = 0
		paid_principal = 0
		paid_interest = 0
		outstanding_principal = 0
		outstanding_interest = 0
		overdue_principal = 0
		overdue_amount = 0
		
		for bor in bor_list:
			prod = Product.objects.get(id = bor.prod_id)
			loan_list = Loan.objects.filter(bor_id = bor.id)
			total_principal += sum([loan.initial_amount for loan in loan_list])
			paid_principal += sum([loan.initial_amount - loan.remain_principal for loan in loan_list])
			paid_interest += sum([loan.initial_amount for loan in loan_list]) * prod.APR_borrower * 0.01 * (prod.repayment_period /12) - sum([loan.remain_interest_borrower for loan in loan_list])
			outstanding_principal += sum([loan.remain_principal for loan in loan_list])
			outstanding_interest += sum([loan.remain_interest_borrower for loan in loan_list])
			overdue_principal += sum([loan.overdue_principal for loan in loan_list])
			overdue_amount += sum([loan.overdue_principal+loan.overdue_interest for loan in loan_list])
		total_principal = round(total_principal, 1)
		paid_principal = round(paid_principal, 1)
		paid_interest = round(paid_interest, 1)
		outstanding_principal = round(outstanding_principal, 1)
		outstanding_interest = round(outstanding_interest, 1)
		overdue_principal = round(overdue_principal, 1)
		overdue_amount = round(overdue_amount, 1)
		
		data_list.append({'key': 'Total Principal', 'value':'$'+str(total_principal)})
		data_list.append({'key': 'Paid Principal', 'value':'$'+str(paid_principal)})
		data_list.append({'key': 'Paid Interest', 'value':'$'+str(paid_interest)})
		data_list.append({'key': 'Outstanding Principal', 'value':'$'+str(outstanding_principal)})
		data_list.append({'key': 'Outstanding Interest', 'value':'$'+str(outstanding_interest)})
		data_list.append({'key': 'Overdue Principal', 'value':'$'+str(overdue_principal)})
		data_list.append({'key': 'Overdue Amount (included interest)', 'value':'$'+str(overdue_amount)})
		
		serialized_data_list = KeyValueSerializer(data_list, many=True)
		content = {'data': serialized_data_list.data}
		return Response(content)
	def get(self, request, format=None):
		usr = sup_fn.get_user(request)
		prod_id = request.GET.get('prod_id')
		
		# check XSS
		if sup_fn.checkHTMLtags([v for k, v in request.GET.iteritems()]):
			return HttpResponse('Invalid input.')
		
		if prod_id == 'all':
			inv_list = Investment.objects.filter(usr_id=usr.id)
		else:
			inv_list = Investment.objects.filter(usr_id=usr.id, prod_id=prod_id)
		data_list = []
		total_principal = 0
		returned_principal = 0
		returned_interest = 0
		returning_principal = 0
		returning_interest = 0
		overdue_principal = 0
		overdue_amount = 0
		
		for inv in inv_list:
			loan_list = Loan.objects.filter(inv_id=inv.id)
			total_principal += sum([loan.initial_amount for loan in loan_list])
			returned_principal += sum([loan.initial_amount - loan.remain_principal for loan in loan_list])
			prod = Product.objects.get(id=inv.prod_id)
			returned_interest += sum([loan.initial_amount * prod.APR_lender * 0.01 * (prod.repayment_period/12) - loan.remain_interest_lender for loan in loan_list])
			returning_principal += sum([loan.remain_principal for loan in loan_list])
			returning_interest += sum([loan.remain_interest_lender for loan in loan_list])
			overdue_principal += sum([loan.overdue_principal for loan in loan_list])
			overdue_amount += sum([loan.overdue_principal+loan.overdue_interest for loan in loan_list])
		returned_principal = round(returned_principal, 1)
		returned_interest = round(returned_interest, 1)
		returning_principal = round(returning_principal, 1)
		returning_interest = round(returning_interest, 1)
		overdue_principal = round(overdue_principal, 1)
		overdue_amount = round(overdue_amount, 1)
		
		data_list.append({'key': 'Total Principal', 'value':'$'+str(total_principal)})
		data_list.append({'key': 'Returned Principal', 'value':'$'+str(returned_principal)})
		data_list.append({'key': 'Returned Interest', 'value':'$'+str(returned_interest)})
		data_list.append({'key': 'Returning Principal', 'value':'$'+str(returning_principal)})
		data_list.append({'key': 'Returning Interest', 'value':'$'+str(returning_interest)})
		data_list.append({'key': 'Overdue Principal', 'value':'$'+str(overdue_principal)})
		data_list.append({'key': 'Overdue Amount (included interest)', 'value':'$'+str(overdue_amount)})
		
		serialized_data_list = KeyValueSerializer(data_list, many=True)
		content = {'data': serialized_data_list.data}
		return Response(content)
	def get(self, request, format=None):
		usr = sup_fn.get_user(request)
		prod_id = request.GET.get('prod_id')
		
		# check XSS
		if sup_fn.checkHTMLtags([v for k, v in request.GET.iteritems()]):
			return HttpResponse('Invalid input.')
		
		if prod_id == 'all':
			prod_list = Product.objects.filter(status='ACTIVE')
		else:
			prod_list = Product.objects.filter(id=prod_id)
		rd_loan_list = []
		for prod in prod_list:
			try:
				inv = Investment.objects.get(prod_id=prod.id, usr_id= usr.id)
			except ObjectDoesNotExist:
				continue
			loan_list = Loan.objects.filter(inv_id=inv.id)
			loan_list = [loan for loan in loan_list if loan.status=='DISBURSED' or 'PAYBACK' in loan.status]
			
			for loan in loan_list:
				try:
					bor = BorrowRequest.objects.get(id = loan.bor_id)
				except:
					continue
					
				rd_loan = {
				'shadow_datetime': timezone.localtime(bor.draw_down_date),
				'date': datetime.strftime(timezone.localtime(loan.update_timestamp), '%Y/%m/%d'),
				'ref_num': bor.ref_num,
				'amount': FLOAT_DATA_FORMAT.format(loan.initial_amount),
				'interest': FLOAT_DATA_FORMAT.format(loan.total_repay_amount_lender - loan.initial_amount),
				'installment': FLOAT_DATA_FORMAT.format(loan.instalment_lender),
				'draw_down_date': datetime.strftime(timezone.localtime(bor.draw_down_date), '%Y/%m/%d'),
				'expected_end_date': datetime.strftime(timezone.localtime(bor.expected_end_date), '%Y/%m/%d'),
				'overdue_loan_receivable': FLOAT_DATA_FORMAT.format(loan.overdue_principal + loan.overdue_interest),
				'loan_id': loan.id,
				}
				rd_loan_list.append(rd_loan)
		#serialized_data_list = ActiveInvSerializer(rd_loan_list, many=True)
		content = {'data': rd_loan_list}
		return Response(content)
Exemple #9
0
def invest_now(request):
	user = sup_fn.get_user(request)
	lang = sup_fn.get_lang(request)
	
	if 'start_investing' in request.META.get('PATH_INFO').split('/'):
		rd_prod_list = [['all','All Products']]
		prod_list = Product.objects.filter(status='ACTIVE')
		for prod in prod_list:
			rd_prod_list.append([prod.id,prod.name_en])
		content = {
		'cate': 'invest_now',
		'prod_list': rd_prod_list,
		}
		return render(request, 'peerloan/lender/start_invest.html', content)
	
	prod_list = Product.objects.filter(status='ACTIVE')
	rd_prod_list = []
	
	for prod in prod_list:
		details = {
		'prod_name': prod.name_en,
		'total_amount': prod.total_amount,
		'APR': prod.APR_lender,
		'flat_rate': prod.flat_rate_lender,
		'repayment_period': prod.repayment_period,
		'amount_per_unit': prod.min_amount_per_loan,
		'min_inv_unit_per_loan': 1,
		'max_inv_unit_per_loan': int(prod.total_amount / prod.min_amount_per_loan),
		'prod_id': prod.id,
		}
		rd_prod_list.append(details)
	
	
	content = {
	'cate': 'invest_now',
	'prod_list': rd_prod_list,
	}
	return render(request, 'peerloan/lender/invest_now.html', content)
	def get(self, request, format=None):
		usr = sup_fn.get_user(request)
		bor_id = request.GET.get('bor_id')
		
		# check XSS
		if sup_fn.checkHTMLtags([v for k, v in request.GET.iteritems()]):
			return HttpResponse('Invalid input.')
		
		if bor_id == 'all':
			bor_list = BorrowRequest.objects.filter(usr_id = usr.id)
			bor_list = [bor for bor in bor_list if bor.status == 'DISBURSED' or 'PAYBACK' in bor.status]
		else:
			bor_list = BorrowRequest.objects.filter(id = bor_id)
		
		# assume user applies not more than 3 loans
		color_lib = {'red':['#E08283','#E7505A','#D91E18'],'green':['#36D7B7','#4DB3A2','#26C281'],'yellow':['#F4D03F','#F7CA18','#F3C200']}
		data_list = []
		i = 0
		for bor in bor_list:
			loan_list = Loan.objects.filter(bor_id = bor.id)
			prod = Product.objects.get(id = bor.prod_id)
			
			paid_principal = sum([loan.initial_amount - loan.remain_principal for loan in loan_list])
			outstanding_principal = sum([loan.remain_principal for loan in loan_list])
			overdue_principal = sum([loan.overdue_principal for loan in loan_list])
			
			if paid_principal != 0:
				data_list.append({'name':'Paid Principal ('+prod.name_en+')','amount':paid_principal,'color':color_lib['green'][i]})
			if outstanding_principal != 0:
				data_list.append({'name':'Outstanding Principal ('+prod.name_en+')','amount':outstanding_principal,'color':color_lib['yellow'][i]})
			if overdue_principal != 0:
				data_list.append({'name':'Overdue Principal ('+prod.name_en+')','amount':overdue_principal,'color':color_lib['red'][i]})
			i += 1
			
		serialized_data_list = RepayPieSerializer(data_list, many=True)
		content = {'data': serialized_data_list.data}
		return Response(content)
Exemple #11
0
def switch_role(request):
	usr = sup_fn.get_user(request)
	lang = sup_fn.get_lang(request)
	
	if usr.type == 'L':
		request.session['type'] = 'B'
		
		# upate borrower last login
		b_usr = User.objects.get(email=usr.email,type='B')
		b_usr.this_login = timezone.localtime(timezone.now())
		b_usr.save()
		return redirect('/borrow_now')
	elif usr.type == 'B':
		if len(User.objects.filter(email = usr.email, status = 'ACTIVE')) == 2:
			request.session['type'] = 'L'
			return redirect('/portfolio/portfolio_summary')
		else:
			return redirect('/apply_to_be_investor')
	elif len(AdminUser.objects.filter(email=usr.email)) != 0:
		if request.session['handling_side'] == 'L':
			request.session['handling_side'] = 'B'
		elif request.session['handling_side'] == 'B':
			request.session['handling_side'] = 'L'
		return redirect('/pl_admin/application')
def investment(request):
	usr = sup_fn.get_user(request)
	lang = sup_fn.get_lang(request)
	action = request.META.get('PATH_INFO').split('/')[2]
	
	if action == 'invest_now':
		if 'product_details' in request.META.get('PATH_INFO').split('/'):
			prod_list = Product.objects.filter(status='ACTIVE')
			prod_list = [prod for prod in prod_list if prod.repayment_plan != 'Promotion Balloon Payment']
			
			if lang == 'en':
				thead_list = [
					'Product Name', 'Maximum Amount Per Loan (HK$)', 'Expected Annualised Return (%)', 'Repayment Period (months)',
					'Amount Per Unit (HK$/month)', 'Investment Unit Per Loan',
					'Expected Returning Schedule (Per Unit)'
				]
			elif lang == 'zh':
				thead_list = [
					'產品名稱', '每筆貸款的最高金額 (HK$)', '預期年回報 (%)', '還款期 (月)',
					'每單位金額 (HK$/月)', '每筆貸款的投資單位',
					'預計收回貸款時間表 (每單位)'
				]
				
			tdata_list = []
			
			for prod in prod_list:
				if lang == 'en':
					tdata = [
					prod.name_en, FLOAT_DATA_FORMAT.format(prod.total_amount), FLOAT_DATA_FORMAT.format(prod.APR_lender), 
					prod.repayment_period, FLOAT_DATA_FORMAT.format(prod.min_amount_per_loan), '1-' + str(int(prod.total_amount/prod.min_amount_per_loan)),
					'<a href=\'javascript:window.open("/loan_repay_schedule/?prod_id='+str(prod.id)+'","contestrules", "menubar=0,resizable=0,width=1000,height=800");\'><button class="btn green-jungle">Browse</button></a>'
					]
				elif lang == 'zh':
					tdata = [
					prod.name_zh, FLOAT_DATA_FORMAT.format(prod.total_amount), FLOAT_DATA_FORMAT.format(prod.APR_lender), 
					prod.repayment_period, FLOAT_DATA_FORMAT.format(prod.min_amount_per_loan), '1-' + str(int(prod.total_amount/prod.min_amount_per_loan)),
					'<a href=\'javascript:window.open("/loan_repay_schedule/?prod_id='+str(prod.id).encode('utf8')+'","contestrules", "menubar=0,resizable=0,width=1000,height=800");\'><button class="btn green-jungle">瀏覽</button></a>'
					]
				tdata_list.append(tdata)
			
			content = {
			'lang': lang,
			'caption': 'Product List',
			'thead_list': thead_list,
			'tdata_list': tdata_list
			}
			if lang == 'zh':
				content['caption'] = '產品列表'
			return render(request, 'peerloan/lender/table.html', content)
			
		acc = Account.objects.get(usr_id=usr.id)
		inv_list = Investment.objects.filter(usr_id=usr.id)
		prod_list = Product.objects.filter(status='ACTIVE')
		prod_list = [prod for prod in prod_list if prod.repayment_plan != 'Promotion Balloon Payment']
		
		rd_prod_list = []
		for prod in prod_list:
			try:
				inv = Investment.objects.get(usr_id=usr.id, prod_id=prod.id)
			except ObjectDoesNotExist:
				existed_investment = 0
				on_hold_investment = 0
				max_amt_per_loan = 'Not set'
			else:
				existed_investment = inv.usable_amount
				on_hold_investment = inv.on_hold_amount
				max_amt_per_loan = inv.max_amount_per_loan
			rd_prod_list.append({
				'id': str(prod.id),
				'name_en': str(prod.name_en),
				'name_zh': prod.name_zh.encode('utf8'),
				'min_amount_per_loan': str(prod.min_amount_per_loan),
				'total_amount': str(prod.total_amount),
				'existed_investment': existed_investment,
				'str_existed_investment': FLOAT_DATA_FORMAT.format(existed_investment),
				'on_hold_investment': on_hold_investment,
				'str_on_hold_investment': FLOAT_DATA_FORMAT.format(on_hold_investment),
				'max_amt_per_loan': FLOAT_DATA_FORMAT.format(max_amt_per_loan) if max_amt_per_loan !='Not set' else max_amt_per_loan,
			})
		
		disbursed_amount = 0
		for inv in inv_list:
			loan_list = Loan.objects.filter(inv_id=inv.id)
			disbursed_amount += sum([loan.remain_principal_lender for loan in loan_list if 'PAYBACK' in loan.status])
		
		content = {
		'lang': lang,
		'cate': 'investment',
		'sub_cate': 'invest_now',
		'title': 'Invest Now',
		#'account_balance': '%.2f'%(acc.balance + sum([inv.total_amount for inv in inv_list]) + disbursed_amount),
		'account_balance': '%.2f'%(acc.balance + sum([inv.usable_amount+inv.on_hold_amount for inv in inv_list]) + disbursed_amount),
		'str_account_balance': FLOAT_DATA_FORMAT.format(acc.balance + sum([inv.usable_amount+inv.on_hold_amount for inv in inv_list]) + disbursed_amount),
		'unallocated': '%.2f'%(acc.balance),
		'str_unallocated': FLOAT_DATA_FORMAT.format(acc.balance),
		'prod_list': rd_prod_list
		}
		if lang == 'zh':
			content['title'] = ' 開始投資'
		return render(request, 'peerloan/lender/invest_now.html', content)
	elif action == 'reallocate_fund':
		acc = Account.objects.get(usr_id=usr.id)
		inv_list = Investment.objects.filter(usr_id=usr.id)
		prod_list = Product.objects.filter(status='ACTIVE')
		prod_list = [prod for prod in prod_list if prod.repayment_plan != 'Promotion Balloon Payment']
		
		rd_prod_list = []
		for prod in prod_list:
			try:
				inv = Investment.objects.get(usr_id=usr.id, prod_id=prod.id)
			except ObjectDoesNotExist:
				existed_investment = 0
				on_hold_investment = 0
				investment_setting = '--'
				max_amount_per_loan = 0
			else:
				existed_investment = round(inv.usable_amount, 2)
				on_hold_investment = round(inv.on_hold_amount, 2)
				investment_setting = inv.option
				max_amount_per_loan = round(inv.max_amount_per_loan, 2)
			rd_prod_list.append({
				'id': str(prod.id),
				'name_en': str(prod.name_en),
				'name_zh': prod.name_zh.encode('utf8'),
				'min_amount_per_loan': str(prod.min_amount_per_loan),
				'total_amount': str(prod.total_amount),
				'existed_investment': existed_investment,
				'str_existed_investment': FLOAT_DATA_FORMAT.format(existed_investment),
				'on_hold_investment': on_hold_investment,
				'str_on_hold_investment': FLOAT_DATA_FORMAT.format(on_hold_investment),
				'investment_setting': str(investment_setting),
				'max_amount_per_loan': max_amount_per_loan,
				'str_max_amount_per_loan': FLOAT_DATA_FORMAT.format(max_amount_per_loan)
			})
		
		disbursed_amount = 0
		for inv in inv_list:
			loan_list = Loan.objects.filter(inv_id=inv.id)
			disbursed_amount += sum([loan.remain_principal_lender for loan in loan_list if 'PAYBACK' in loan.status])
		
		content = {
		'lang': lang,
		'cate': 'investment',
		'sub_cate': 'reallocate_fund',
		'title': 'Reallocate Fund',
		#'account_balance': '%.2f'%(acc.balance + sum([inv.total_amount for inv in inv_list]) + disbursed_amount),
		'account_balance': '%.2f'%(acc.balance + sum([inv.usable_amount+inv.on_hold_amount for inv in inv_list]) + disbursed_amount),
		'str_account_balance': FLOAT_DATA_FORMAT.format(acc.balance + sum([inv.usable_amount+inv.on_hold_amount for inv in inv_list]) + disbursed_amount),
		'unallocated': '%.2f'%(acc.balance),
		'str_unallocated': FLOAT_DATA_FORMAT.format(acc.balance),
		'prod_list': rd_prod_list
		}
		if lang == 'zh':
			content['title'] = '調配投資金額'
		return render(request, 'peerloan/lender/reallocate_fund.html', content)
	elif action == 'transfer_fund':
		inv_list = Investment.objects.filter(usr_id=usr.id)
		rd_prod_list = []
		for inv in inv_list:
			prod = Product.objects.get(id=inv.prod_id)
			if lang == 'en':
				rd_prod_list.append({'prod_id':str(prod.id), 'prod_name':str(prod.name_en), 'usable_amount':str(inv.usable_amount)})
			elif lang == 'zh':
				rd_prod_list.append({'prod_id':str(prod.id), 'prod_name':prod.name_zh.encode('utf8'), 'usable_amount':str(inv.usable_amount)})
				
		content = {
		'lang': lang,
		'prod_list': rd_prod_list,
		'cate': 'investment',
		'sub_cate': 'transfer_fund',
		}
		if lang == 'en':
			content['title'] = 'Transfer Fund Between Products'
			content['instruction'] = """Fund Transfer only applicable to the product which have your investment instruction record, 
			if you have not invested in such product before, please click "Invest Now" to set your investment instruction first. Fund Transfer instruction will be executed immediately."""
		if lang == 'zh':
			content['title'] = '調配資金'
			content['instruction'] = """調配資金只適用於已有投資紀錄的產品,如你從未投資於該產品,請即按入"現在投資"以設定該產品的投資指示,你的資金調配指示將會即時執行。"""
		return render(request, 'peerloan/lender/transfer_form.html', content)
Exemple #13
0
def borrow_now(request):
	user = sup_fn.get_user(request)
	lang = sup_fn.get_lang(request)
	
	prod_list = Product.objects.filter(status='ACTIVE')
	rd_prod_list = []
	for prod in prod_list:
		# calculate the installment
		rate_per_month = prod.APR_borrower * 0.01 / 12
		
		if prod.repayment_plan == 'Instalment':
			instalment_borrower = prod.min_amount * (rate_per_month / (1- (1 + rate_per_month)**(-(prod.repayment_period/12)*12)))
		
		if prod.repayment_plan == 'Balloon Payment':
			instalment_borrower = prod.min_amount * rate_per_month
		
		# check num of applied prod
		bor_list = BorrowRequest.objects.filter(usr_id=user.id)
		bor_list = [bor for bor in bor_list if bor.status not in ['PAYBACK COMPLETED', 'REJECTED', 'CANCELLED']]
		num_of_applied_prod = len(bor_list)
		
		# check which step
		if num_of_applied_prod != 0:
			step = 'auto_reject'
		else:
			try:
				bor = BorrowRequest.objects.filter(usr_id=user.id, prod_id=prod.id).latest('update_timestamp')
			except ObjectDoesNotExist:
				if num_of_applied_prod == 0:
					step = 'apply'
				else:
					step = 'auto_reject'
			else:
				if bor.status == 'AUTO APPROVED':
					step = 'upload_docs'
				elif bor.status == 'DOC UPLOADED':
					step = 'confirm_agreement'
				elif bor.status == 'PAYBACK COMPLETED' or bor.status == 'REJECTED' or bor.status == 'CANCELLED':
					step = 'apply'
				elif bor.status == 'FUND MATCHING COMPLETED':
					step = 'confirm_memorandum'
				else: # status = draw down, repay, ...
					step = 'auto_reject'
					
		if lang == 'en':
			prod_name = prod.name_en
		elif lang == 'zh':
			prod_name = prod.name_zh
		
		rd_prod_list.append({
		'id': prod.id,
		'name': prod_name,
		#'min_amount': int(prod.min_amount),
		'min_amount': FLOAT_DATA_FORMAT.format(prod.min_amount),
		
		'total_amount': FLOAT_DATA_FORMAT.format(prod.total_amount),
		'APR_borrower': FLOAT_DATA_FORMAT.format(prod.APR_borrower if prod.fake_APR_borrower == None else prod.fake_APR_borrower),
		'repayment_period': prod.repayment_period if prod.fake_repayment_period == None else prod.fake_repayment_period,
		'instalment_borrower': FLOAT_DATA_FORMAT.format(instalment_borrower),
		'step': step,
		})
	content = {
	'lang': lang,
	'cate': 'borrow_now',
	'prod_list': rd_prod_list,
	}
	return render(request, 'peerloan/borrower/borrow_now.html', content)
def my_account(request):
    usr = sup_fn.get_user(request)
    lang = sup_fn.get_lang(request)

    sub_cate = request.META.get('PATH_INFO').split('/')[2]
    # borrower side =============================================================================================
    if usr.type == 'B':
        if sub_cate == 'all_application_listing':
            if 'detail' in request.META.get('PATH_INFO').split('/'):
                # bor detail
                bor_id = request.GET.get('bor_id')
                bor = BorrowRequest.objects.get(id=bor_id)
                prod = Product.objects.get(id=bor.prod_id)

                los_list = LoanSchedule.objects.filter(bor_id=bor.id,
                                                       status='OVERDUE')
                basic_info = {
                    'product':
                    prod.name_en,
                    'total_amount':
                    'HK$' + FLOAT_DATA_FORMAT.format(bor.amount),
                    'instalment':
                    'HK$' + FLOAT_DATA_FORMAT.format(bor.instalment_borrower),
                    'draw_down_date':
                    bor.draw_down_date.strftime('%Y/%m/%d'),
                    'expected_end_date':
                    bor.expected_end_date.strftime('%Y/%m/%d'),
                    'overdue_loan_payment':
                    'HK$' + FLOAT_DATA_FORMAT.format(
                        sum([
                            los.overdue_interest_accumulated
                            for los in los_list
                        ])),
                    'tenor':
                    str(prod.repayment_period) + ' months',
                    'status':
                    ''.join([i for i in bor.status if (not i.isdigit())])
                }
                if prod.repayment_plan == 'Promotion Balloon Payment':
                    basic_info['tenor'] = str(9) + ' months'
                if lang == 'zh':
                    basic_info['product'] = prod.name_zh
                    basic_info['tenor'] = str(prod.repayment_period) + ' 月'
                    if prod.repayment_plan == 'Promotion Balloon Payment':
                        basic_info['tenor'] = str(9) + ' 月'

                # create repayment table
                los_list = LoanSchedule.objects.filter(bor_id=bor.id)
                repayment_table = []
                repayment_history = []
                remain_balance = bor.amount
                for i in range(prod.repayment_period):
                    los = los_list[i]
                    remain_balance -= los.principal
                    if remain_balance <= 0.02:
                        remain_balance = 0
                    row = {
                        'tenor':
                        str(i + 1),
                        'due_date':
                        los.due_date,
                        'instalment_amount':
                        FLOAT_DATA_FORMAT.format(los.instalment),
                        'interest':
                        FLOAT_DATA_FORMAT.format(los.interest),
                        'principal':
                        FLOAT_DATA_FORMAT.format(los.principal),
                        'outstanding_principal':
                        FLOAT_DATA_FORMAT.format(remain_balance),
                    }
                    repayment_table.append(row)

                    if 'PAID' in los.status or 'PAYBACK COMPLETED' in los.status:
                        row = {
                            'due_date':
                            los.due_date,
                            'repayment_date':
                            timezone.localtime(
                                los.repayment_date).strftime('%Y/%m/%d'),
                            'overdue_day':
                            los.overdue_days,
                            'overdue_interest':
                            FLOAT_DATA_FORMAT.format(
                                los.overdue_interest_accumulated),
                            'payment_amount':
                            FLOAT_DATA_FORMAT.format(los.received_amount),
                            'repayment_method':
                            los.repayment_method,
                            'repayment_type':
                            los.repayment_type,
                        }
                        repayment_history.append(row)

                # calculate early settle
                loan_list = Loan.objects.filter(bor_id=bor.id)
                if bor.repaid_month == 0:
                    last_pay_date = bor.draw_down_date
                else:
                    los = LoanSchedule.objects.get(bor_id=bor.id,
                                                   tenor=bor.repaid_month)
                    last_pay_date = datetime.strptime(los.due_date, '%Y/%m/%d')
                    last_pay_date = pytz.timezone('Asia/Hong_Kong').localize(
                        last_pay_date)
                days = (timezone.localtime(timezone.now()) -
                        last_pay_date).days
                if days < 0:
                    days = 0
                rate_per_day = prod.APR_borrower * 0.01 / 360
                remain_principal = sum(
                    [loan.remain_principal for loan in loan_list])
                early_settlement_amount = remain_principal * (
                    1 + rate_per_day * days)
                early_settle = {
                    'date':
                    timezone.localtime(timezone.now()).strftime('%Y/%m/%d') +
                    ' (as today)',
                    'amount':
                    'HK$' + FLOAT_DATA_FORMAT.format(early_settlement_amount)
                }
                if lang == 'zh':
                    early_settle['date'] = timezone.localtime(
                        timezone.now()).strftime('%Y/%m/%d') + ' (在今日)'

                content = {
                    'lang':
                    lang,
                    'cate':
                    'my_account',
                    'sub_cate':
                    'all_application_listing',
                    'title':
                    'Loan - ' + bor.ref_num,
                    'form_action':
                    'javascript:;',
                    'basic_info':
                    basic_info,
                    'repayment_table':
                    repayment_table,
                    'repayment_history':
                    repayment_history,
                    'early_settle':
                    early_settle,
                    'bod_list':
                    BorrowRequestDocument.objects.filter(bor_id=bor.id),
                }
                if lang == 'zh':
                    content['title'] = '貸款 - %s' % bor.ref_num.encode("utf8")
                return render(
                    request,
                    'peerloan/borrower/all_application_listing_detail.html',
                    content)
            else:
                # bor table
                status_list = [
                    'All', 'AUTO APPROVED', 'DOC UPLOADED',
                    'AGREEMENT CONFIRMED', 'PENDING DOC/IV', 'DISBURSED',
                    'PAYBACK', 'PAYBACK OVERDUE', 'PAYBACK COMPLETED'
                ]
                content = {
                    'lang': lang,
                    'cate': 'my_account',
                    'sub_cate': 'all_application_listing',
                    'title': 'Application Listing',
                    'status_list': status_list,
                }
                if lang == 'zh':
                    content['title'] = '申請列表'
                return render(
                    request, 'peerloan/borrower/all_application_listing.html',
                    content)
        if sub_cate == 'active_loan':
            if 'repayment_details' in request.META.get('PATH_INFO').split('/'):
                # repay detail page
                bor_list = BorrowRequest.objects.filter(usr_id=usr.id)
                bor_list = [
                    bor for bor in bor_list
                    if bor.status == 'DISBURSED' or 'PAYBACK' in bor.status
                ]
                rd_bor_list = [['all', 'All Active Loan']]
                for bor in bor_list:
                    rd_bor_list.append(
                        [bor.id, 'Loan Ref No.: ' + bor.ref_num])
                content = {
                    'cate': 'my_account',
                    'sub_cate': 'active_loan',
                    'bor_list': rd_bor_list,
                }
                return render(request,
                              'peerloan/borrower/repayment_details.html',
                              content)
            else:
                # active loan page
                bor_list = BorrowRequest.objects.filter(usr_id=usr.id)
                bor_list = [
                    bor for bor in bor_list
                    if bor.status == 'DISBURSED' or 'PAYBACK' in bor.status
                ]
                detail_list = []
                app_list = []
                for bor in bor_list:
                    detail = {}
                    prod = Product.objects.get(id=bor.prod_id)
                    loan_list = Loan.objects.filter(bor_id=bor.id)
                    detail['prod_name'] = prod.name_en
                    detail['total_amount'] = prod.total_amount
                    detail['installment'] = round(bor.instalment_borrower, 2)
                    detail['draw_down_date'] = loan_list[
                        0].draw_down_date.strftime("%d/%m/%Y")
                    detail['expected_end_date'] = loan_list[
                        0].expected_end_date.strftime("%d/%m/%Y")
                    detail['overdue_loan_payment'] = sum([
                        loan.overdue_principal + loan.overdue_interest
                        for loan in loan_list
                    ])

                    detail['bor_ref_num'] = bor.ref_num
                    detail['repayment_period'] = prod.repayment_period
                    detail['APR'] = prod.APR_borrower
                    detail_list.append(detail)

                    bod_list = BorrowRequestDocument.objects.filter(
                        bor_id=bor.id)

                    app_list.append(bod_list)
                content = {
                    'cate': 'my_account',
                    'sub_cate': 'active_loan',
                    'bor_list': bor_list,
                    'detail_list': detail_list,
                    'app_list': app_list,
                }
                return render(request, 'peerloan/borrower/active_loan.html',
                              content)
        if sub_cate == 'loan_status':
            if 'view_detail' in request.META.get('PATH_INFO').split('/'):
                # bor detail
                bor_id = request.GET.get('bor_id')
                bor = BorrowRequest.objects.get(id=bor_id)
                prod = Product.objects.get(id=bor.prod_id)
                if bor.status == 'APPLIED':
                    fields = []
                    fields.append({
                        'name': 'Product Name',
                        'value': prod.name_en
                    })
                    fields.append({
                        'name': 'Total Applied Amount',
                        'value': prod.total_amount
                    })
                    fields.append({'name': 'APR', 'value': prod.APR_borrower})
                    fields.append({
                        'name': 'Upload Supplementary Documents',
                        'type': 'upload_file',
                        'value': 'supply_doc'
                    })
                    fields.append({
                        'name': 'Supplementaty Documents Description',
                        'type': 'input',
                        'value': 'supply_doc_descri'
                    })
                    fields.append({
                        'name':
                        'Applicaton Date',
                        'value':
                        bor.create_timestamp.strftime('%Y-%m-%d')
                    })
                    fields.append({'name': 'Status', 'value': bor.status})

                    buttons = []
                    buttons.append({'name': 'Submit', 'type': 'submit'})
                    buttons.append({
                        'name': 'Close',
                        'type': 'button',
                        'onclick': 'window.close()'
                    })
                elif bor.status == 'VALIDATED' or 'MATCHING' in bor.status:
                    fields = []
                    loan_list = Loan.objects.filter(bor_id=bor.id)
                    if len(loan_list) == 0:
                        fields.append({'name': 'Matched Amount', 'value': 0})
                    else:
                        fields.append({
                            'name':
                            'Matched Amount',
                            'value':
                            sum([loan.initial_amount for loan in loan_list])
                        })
                    fields.append({
                        'name': 'Total Applied Amount',
                        'value': prod.total_amount
                    })
                    fields.append({
                        'name':
                        'Application Date',
                        'value':
                        bor.create_timestamp.strftime('%Y-%m-%d')
                    })
                    fields.append({
                        'name':
                        'Matching Starting Date',
                        'value':
                        bor.update_timestamp.strftime('%Y-%m-%d')
                    })
                    fields.append({
                        'name':
                        'Matching Expiring Date',
                        'value': (bor.update_timestamp +
                                  dt.timedelta(days=7)).strftime('%Y-%m-%d')
                    })
                    fields.append({'name': 'APR', 'value': prod.APR_borrower})
                    fields.append({'name': 'Status', 'value': bor.status})

                    buttons = []
                    buttons.append({
                        'name': 'Close',
                        'type': 'button',
                        'onclick': 'window.close()'
                    })
                elif 'PAYBACK' in bor.status or bor.status == 'DRAWN DOWN':
                    return redirect('/my_account/active_loan')
                elif bor.status == 'COMPLETED':
                    fields = []
                    loan_list = Loan.objects.filter(bor_id=bor.id)
                    fields.append({
                        'name':
                        'Borrowed Principal',
                        'value':
                        sum([loan.remain_principal for loan in loan_list])
                    })
                    fields.append({
                        'name':
                        'Total Interest',
                        'value':
                        sum([
                            loan.remain_interest_borrower for loan in loan_list
                        ])
                    })
                    fields.append({
                        'name':
                        'Total Overdue Interest',
                        'value':
                        sum([loan.overdue_interest for loan in loan_list])
                    })
                    fields.append({'name': 'APR', 'value': prod.APR_borrower})

                    total_interest = prod.total_amount * prod.APR_borrower * 0.01 * prod.repayment_period / 12 + sum(
                        [loan.paid_overdue_interest for loan in loan_list])
                    effective_APR = (total_interest / prod.total_amount) * (
                        12 / prod.repayment_period) * 100
                    fields.append({
                        'name': 'Effective APR',
                        'value': effective_APR
                    })
                    fields.append({
                        'name': 'Effective Flat Rate',
                        'value': 'PENDING'
                    })

                    buttons = []
                    buttons.append({
                        'name': 'Close',
                        'type': 'button',
                        'onclick': 'window.close()'
                    })
                content = {
                    'title': 'Loan Reference Number - ' + bor.ref_num,
                    'cate': 'my_account',
                    'sub_cate': 'loan_status',
                    'form_action': '/ack/',
                    'fields': fields,
                    'buttons': buttons,
                }
                return render(request, 'peerloan/borrower/form.html', content)
            else:
                # bor table
                status_list = [
                    'All', 'AUTO APPROVED', 'DOC UPLOADED',
                    'AGREEMENT CONFIRMED', 'PENDING DOC/IV',
                    'PENDING VERIFIED', 'VALIDATED', 'FUND MATCHING',
                    'FUND MATCHING COMPLETED', 'DISBURSED', 'PAYBACK',
                    'PAYBACK OVERDUE', 'PAYBACK COMPLETED'
                ]
                content = {
                    'cate': 'my_account',
                    'sub_cate': 'loan_status',
                    'status_list': status_list,
                }
                return render(request, 'peerloan/borrower/loan_status.html',
                              content)
        if sub_cate == 'change_acc_info':
            details = json.loads(usr.detail_info)
            usr_info = {
                'usr_id': usr.id,
                'password': '******',
                'mobile': sup_fn.try_KeyError(details, 'Mobile'),
                'address': sup_fn.try_KeyError(details, 'Residential Address'),
            }
            content = {
                'lang': lang,
                'cate': 'my_account',
                'sub_cate': 'change_acc_info',
                'title': 'Change Account Information',
                'form_action': 'javascript:;',
                'usr_info': usr_info,
            }
            if lang == 'zh':
                content['title'] = '更換賬戶資料'
            return render(request, 'peerloan/borrower/change_acc_info.html',
                          content)
        if sub_cate == 'repayment_and_settlement':
            usr = sup_fn.get_user(request)
            bor_list = BorrowRequest.objects.filter(usr_id=usr.id)
            bor_list = [
                bor for bor in bor_list
                if ('PAYBACK' in bor.status or 'DISBURSED' in bor.status)
                and 'COMPLETED' not in bor.status
            ]
            content = {
                'lang': lang,
                'cate': 'my_account',
                'sub_cate': 'repayment_and_settlement',
                'title': 'Repayment and Settlement',
            }
            if lang == 'zh':
                content['title'] = '供款及提早還款'

            if len(bor_list) != 0:
                bor = bor_list[0]

                inputs = {'bor_id': bor.id, 'type': 'instalment'}
                outputs = sup_fn.calculate_repay_amount(inputs)
                content['instalment_month'] = outputs['instalment_month']
                total_amount = max(
                    0, outputs['instalment_amount'] +
                    outputs['overdue_interest'] + outputs['late_charge'] -
                    outputs['overpay_amount'])
                content[
                    'instalment_amount'] = 'HK$%s, included: <br>instalment: HK$%s;<br>overdue interest: HK$%s;<br>late charge: HK$%s;<br>overpay amount: HK$%s.' % (
                        FLOAT_DATA_FORMAT.format(total_amount),
                        FLOAT_DATA_FORMAT.format(outputs['instalment_amount']),
                        FLOAT_DATA_FORMAT.format(outputs['overdue_interest']),
                        FLOAT_DATA_FORMAT.format(outputs['late_charge']),
                        FLOAT_DATA_FORMAT.format(outputs['overpay_amount']))
                if lang == 'zh':
                    content[
                        'instalment_amount'] = 'HK$%s, 包含: <br>分期還款金額: HK$%s;<br>逾期利息: HK$%s;<br>逾期收費: HK$%s;<br>多繳金額: HK$%s。' % (
                            FLOAT_DATA_FORMAT.format(total_amount),
                            FLOAT_DATA_FORMAT.format(
                                outputs['instalment_amount']),
                            FLOAT_DATA_FORMAT.format(
                                outputs['overdue_interest']),
                            FLOAT_DATA_FORMAT.format(outputs['late_charge']),
                            FLOAT_DATA_FORMAT.format(
                                outputs['overpay_amount']))
                # calculate early settlement
                inputs = {'bor_id': bor.id, 'type': 'early_settlement'}
                outputs = sup_fn.calculate_repay_amount(inputs)
                total_amount = max(
                    0, outputs['early_settlement_amount'] +
                    outputs['late_charge'] - outputs['overpay_amount'])
                content[
                    'early_settlement_amount'] = 'HK$%s, included: <br>principal: HK$%s;<br>interest: HK$%s;<br>late charge: HK$%s;<br>overpay amount: HK$%s.' % (
                        FLOAT_DATA_FORMAT.format(total_amount),
                        FLOAT_DATA_FORMAT.format(outputs['principal']),
                        FLOAT_DATA_FORMAT.format(outputs['interest']),
                        FLOAT_DATA_FORMAT.format(outputs['late_charge']),
                        FLOAT_DATA_FORMAT.format(outputs['overpay_amount']))
                if lang == 'zh':
                    content[
                        'early_settlement_amount'] = 'HK$%s, 包含: <br>本金: HK$%s;<br>利息: HK$%s;<br>逾期收費: HK$%s;<br>多繳金額: HK$%s。' % (
                            FLOAT_DATA_FORMAT.format(total_amount),
                            FLOAT_DATA_FORMAT.format(outputs['principal']),
                            FLOAT_DATA_FORMAT.format(outputs['interest']),
                            FLOAT_DATA_FORMAT.format(outputs['late_charge']),
                            FLOAT_DATA_FORMAT.format(
                                outputs['overpay_amount']))

                content['bor_id'] = bor.id
                content['bor_ref_num'] = bor.ref_num

                return render(
                    request, 'peerloan/borrower/repayment_and_settlement.html',
                    content)
            else:
                if lang == 'en':
                    content[
                        'instruction'] = 'No record, you can apply a loan first. Click <a href="/borrow_now" style="color:#fff;"><u>here</u></a>'
                elif lang == 'zh':
                    content[
                        'instruction'] = '沒有找到記錄,請先申請貸款。<a href="/borrow_now" style="color:#fff;">點擊此處</a>'

                return render(request,
                              'peerloan/borrower/acknowledgement.html',
                              content)

    # borrower side end =======================================================================================
    # lender side =============================================================================================
    elif usr.type == 'L':
        if sub_cate == 'deposit_money':
            if lang == 'en':
                fields = []
                fields.append({'name': 'Bank Name', 'value': 'Hang Seng Bank'})
                fields.append({
                    'name': 'Bank Account Number',
                    'value': '239-498-348883'
                })
                fields.append({
                    'name': 'Name of Account Holder',
                    'value': 'P L Technology Limited'
                })
                fields.append({
                    'name': 'Bank Deposit Slip',
                    'value': 'receipt',
                    'type': 'upload_file',
                    'additional_text':
                    'Please keep your original bank slip at least 3 months (from upload date) for record.',
                    'required': 'True'
                })
                fields.append({
                    'name': 'Deposit Amount',
                    'value': 'transfer_amt',
                    'type': 'input',
                    'required': 'True'
                })
                #fields.append({'name': 'Your Reference', 'value': 'ur_ref', 'type': 'input'})

                buttons = []
                buttons.append({'name': 'Submit', 'type': 'submit'})
                buttons.append({
                    'name': 'Cancel',
                    'type': 'button',
                    'onclick': 'window.history.back()'
                })

                content = {
                    'lang': lang,
                    'cate': 'my_account',
                    'sub_cate': 'deposit_money',
                    'title': 'Deposit Money',
                    'instruction':
                    """Zwap only accept cheque deposit or bank transfer from a local bank account under 
				your own name, please upload the deposit slip here, the fund will be ready in your Zwap's account 
				within 1 business day for bank transfer, and 2 business days for cheque deposit.
				""",
                    'form_action': '/ack/',
                    'fields': fields,
                    'buttons': buttons,
                }
            elif lang == 'zh':
                fields = []
                fields.append({'name': '銀行名稱', 'value': '恒生銀行'})
                fields.append({'name': '戶口號碼', 'value': '239-498-348883'})
                fields.append({
                    'name': '戶口持有人名稱',
                    'value': 'P L Technology Limited'
                })
                fields.append({
                    'name': '銀行存款單據',
                    'value': 'receipt',
                    'type': 'upload_file',
                    'additional_text': '請保留你的正本收據三個月(從上傅日起計)以作紀錄。',
                    'required': 'True'
                })
                fields.append({
                    'name': '存入金額',
                    'value': 'transfer_amt',
                    'type': 'input',
                    'required': 'True'
                })
                #fields.append({'name': 'Your Reference', 'value': 'ur_ref', 'type': 'input'})

                buttons = []
                buttons.append({'name': '提交', 'type': 'submit'})
                buttons.append({
                    'name': '取消',
                    'type': 'button',
                    'onclick': 'window.history.back()'
                })

                content = {
                    'lang': lang,
                    'cate': 'my_account',
                    'sub_cate': 'deposit_money',
                    'title': '存入資金',
                    'instruction':
                    """Zwap只接受以你名下之本地銀行戶口發出之支票存款,或銀行轉賬形式存款,請上載你的銀行
				存款收據,經核實後我們將於一個工作天內存入資金至你的Zwap帳戶,如以支票形式存款,則須兩個工作天核實。
				""",
                    'form_action': '/ack/',
                    'fields': fields,
                    'buttons': buttons,
                }
            return render(request, 'peerloan/lender/form.html', content)
        elif sub_cate == 'withdraw_money':
            acc = Account.objects.get(usr_id=usr.id)

            if lang == 'en':
                fields = []
                if acc.balance == 0:
                    fields.append({
                        'name': 'Withdrawal Amount',
                        'value': '/my_account/deposit_money',
                        'text': 'Please deposit money first',
                        'type': 'href',
                        'required': 'True'
                    })
                else:
                    fields.append({
                        'name': 'Withdrawal Amount',
                        'value': 'withdraw_amt',
                        'type': 'ion-slider',
                        'required': 'True'
                    })

                details = json.loads(usr.detail_info)
                bank_acc = sup_fn.try_KeyError(details['Individual'],
                                               'Bank Account')
                if bank_acc == '--':
                    fields.append({
                        'name': 'Bank Account',
                        'value': '/my_account/change_acc_info',
                        'text':
                        'Please input your bank account information first',
                        'type': 'href'
                    })
                else:
                    fields.append({
                        'name': 'Bank Account',
                        'value': 'Bank Account',
                        'hidden_value': bank_acc,
                        'type': 'text_and_hidden'
                    })

                #fields.append({'name': 'Your Reference', 'value': 'Your Reference', 'type': 'input'})
                fields.append({
                    'name': 'One Time Password',
                    'value': 'OTP',
                    'type': 'OTP',
                    'required': 'True'
                })

                buttons = []
                if acc.balance == 0 or bank_acc == '--':
                    buttons.append({
                        'name': 'Submit',
                        'type': 'submit',
                        'disabled': 'disabled'
                    })
                else:
                    buttons.append({'name': 'Submit', 'type': 'submit'})
                buttons.append({
                    'name': 'Cancel',
                    'type': 'button',
                    'onclick': 'window.history.back()'
                })

                content = {
                    'lang': lang,
                    'cate': 'my_account',
                    'sub_cate': 'withdraw_money',
                    'title': 'Withdraw Money',
                    'instruction':
                    """Please specify the amount you would like to withdraw from your Zwap's account. We will deposit 
				the request amount to your registered bank account by cheque within 1 business day after validation.
				""",
                    'form_action': '/ack/',
                    'usr_id': usr.id,
                    'fields': fields,
                    'buttons': buttons,
                    'acc_balance': acc.balance,
                    'OTP_action': 'Withdraw Money',
                    'mobile':
                    json.loads(usr.detail_info)['Individual']['Mobile']
                }
            elif lang == 'zh':
                fields = []
                if acc.balance == 0:
                    fields.append({
                        'name': '提取金額',
                        'value': '/my_account/deposit_money',
                        'text': '請先存入資金',
                        'type': 'href',
                        'required': 'True'
                    })
                else:
                    fields.append({
                        'name': '提取金額',
                        'value': 'withdraw_amt',
                        'type': 'ion-slider',
                        'required': 'True'
                    })

                details = json.loads(usr.detail_info)
                bank_acc = sup_fn.try_KeyError(details['Individual'],
                                               'Bank Account')
                if bank_acc == '--':
                    fields.append({
                        'name': '銀行戶口',
                        'value': '/my_account/change_acc_info',
                        'text': '請先輸入你的銀行戶口資料',
                        'type': 'href'
                    })
                else:
                    fields.append({
                        'name': '銀行戶口',
                        'value': 'Bank Account',
                        'hidden_value': bank_acc,
                        'type': 'text_and_hidden'
                    })

                #fields.append({'name': 'Your Reference', 'value': 'Your Reference', 'type': 'input'})
                fields.append({
                    'name': '一次性密碼',
                    'value': 'OTP',
                    'type': 'OTP',
                    'required': 'True'
                })

                buttons = []
                if acc.balance == 0 or bank_acc == '--':
                    buttons.append({
                        'name': '提交',
                        'type': 'submit',
                        'disabled': 'disabled'
                    })
                else:
                    buttons.append({'name': '提交', 'type': 'submit'})
                buttons.append({
                    'name': '取消',
                    'type': 'button',
                    'onclick': 'window.history.back()'
                })

                content = {
                    'lang': lang,
                    'cate': 'my_account',
                    'sub_cate': 'withdraw_money',
                    'title': '提取資金',
                    'instruction':
                    """請註明你要從你的Zwap帳戶提取的金額,經核實後我們將於一個工作天內以支票形式存入你已登記的銀行戶口內。
				""",
                    'form_action': '/ack/',
                    'usr_id': usr.id,
                    'fields': fields,
                    'buttons': buttons,
                    'acc_balance': acc.balance,
                    'OTP_action': 'Withdraw Money',
                    'mobile':
                    json.loads(usr.detail_info)['Individual']['Mobile']
                }

            error = request.GET.get('error')
            if lang == 'en':
                if error == 'invalid_OTP':
                    content['error_msg'] = 'Please input a valid OTP'
                if error == 'OTP_not_matched':
                    content[
                        'error_msg'] = 'The OTP doesn\'t match to our record, please try again'
                if error == 'OTP_expired':
                    content[
                        'error_msg'] = 'The OTP is expired, please receive a new OTP first'
            elif lang == 'zh':
                if error == 'invalid_OTP':
                    content['error_msg'] = '請輸入一個有效的OTP'
                if error == 'OTP_not_matched':
                    content['error_msg'] = '你輸入的OTP與我們的記錄不符合,請重新操作'
                if error == 'OTP_expired':
                    content['error_msg'] = '你的OTP已經逾期,請重新獲取OTP'

            return render(request, 'peerloan/lender/form.html', content)
        elif sub_cate == 'transaction_records':
            content = {
                'lang': lang,
                'cate': 'my_account',
                'sub_cate': 'transaction_records',
                'title': 'Transaction Records',
            }
            if lang == 'zh':
                content['title'] = '交易記錄'

            return render(request, 'peerloan/lender/trans_records.html',
                          content)
        elif sub_cate == 'change_acc_info':
            details = json.loads(usr.detail_info)
            usr_info = {
                'usr_id':
                usr.id,
                'password':
                '******',
                'mobile':
                sup_fn.try_KeyError(details['Individual'], 'Mobile'),
                'address':
                sup_fn.try_KeyError(details['Individual'],
                                    'Residential Address'),
                'bank_account':
                sup_fn.try_KeyError(details['Individual'], 'Bank Account'),
            }
            if sup_fn.try_KeyError(details, 'Corporate') != '--':
                usr_info['office_address'] = sup_fn.try_KeyError(
                    details['Corporate'], 'Office Address')
            content = {
                'lang': lang,
                'cate': 'my_account',
                'sub_cate': 'change_acc_info',
                'title': 'Change Account Information',
                'form_action': 'javascript:;',
                'usr_info': usr_info,
            }
            if lang == 'zh':
                content['title'] = '更改帳戶資料'
            return render(request, 'peerloan/lender/change_acc_info.html',
                          content)
def settings(request):
	usr = sup_fn.get_user(request)
	lang = sup_fn.get_lang(request)
	
	sub_cate = request.META.get('PATH_INFO').split('/')[2]
	# lender side =============================================================================================
	if usr.type == 'L':
		if sub_cate == 'sms_email_notification':
			if lang == 'en':
				uri_list = UserInformation.objects.filter(info_type='Settings')
			elif lang == 'zh':
				uri_list = UserInformation.objects.filter(info_type='Settings')
				
			notification = json.loads(usr.notification)
			i = 0
			for uri in uri_list:
				uri.details = json.loads(uri.details, object_pairs_hook=OrderedDict)
				for k, v in uri.details.iteritems():
					v['no'] = i
					v['checked'] = notification[k]
					i += 1
			content = {
			'lang': lang,
			'cate': 'settings',
			'sub_cate': 'sms_email_notification',
			'title': 'SMS/Email Notification',
			'uri_list': uri_list,
			}
			if lang == 'zh':
				content['title'] = '手機短訊/電郵提示'
			return render(request, 'peerloan/lender/sms_email_notification.html' ,content)
		if sub_cate == 'account_information':
			# check last change acc info request
			try:
				uor = UserOperationRequest.objects.filter(usr_id=usr.id, type='Change Account Information', status='PENDING APPROVAL').latest('create_timestamp')
			except ObjectDoesNotExist:
				notice = ''
			else:
				if uor != None:
					notice = 'Your request has submitted. You can make another request after the current request is proceeded.'
			
			uri_list = UserInformation.objects.filter(section="Individual", info_type="Account Information")
			details = []
			for uri in uri_list:
				details.append((uri.section, json.loads(uri.details, object_pairs_hook=OrderedDict)))
			details = OrderedDict(details)
			existed_details = OrderedDict()
			
			for section, terms in details.iteritems():
				existed_details[section] = OrderedDict()
				for name, values in terms.iteritems():
					try:
						existed_details[section][name] = json.loads(usr.detail_info)[section][name]
					except KeyError:
						existed_details[section][name] = '--'
			buttons = []
			buttons.append({"name": "Submit", "type":"submit"})
			
			content = {
			'cate': 'settings',
			'sub_cate': sub_cate,
			'title': 'Account Information',
			'notice': notice,
			'details': details,
			'existed_details': existed_details,
			'form_action': '/ack/',
			'buttons': buttons,
			}
			return render(request, 'peerloan/lender/change_acc_info.html', content)
	def get(self, request, format=None):
		usr = sup_fn.get_user(request)
		prod_id = request.GET.get('prod_id')
		
		# check XSS
		if sup_fn.checkHTMLtags([v for k, v in request.GET.iteritems()]):
			return HttpResponse('Invalid input.')
		
		if prod_id == 'all':
			inv_list = Investment.objects.filter(usr_id=usr.id)
		else:
			inv_list = Investment.objects.filter(usr_id=usr.id, prod_id=prod_id)
			
		schedule_list = []
		schedule2_list = []
		min_start_date = None
		max_end_date = None
		
		for inv in inv_list:
			loan_list = Loan.objects.filter(inv_id = inv.id)
			loan_list = [loan for loan in loan_list if 'DISBURSED' in loan.status or 'PAYBACK' in loan.status]
			prod = Product.objects.get(id = inv.prod_id)
			rate_per_month = prod.APR_lender * 0.01 / 12
			for loan in loan_list:
				try:
					bor = BorrowRequest.objects.get(id=loan.bor_id)
				except:
					continue
				bor.draw_down_date = timezone.localtime(bor.draw_down_date)
				start_date_day = bor.draw_down_date.day
				start_date_month = bor.draw_down_date.month + 1
				start_date_year = bor.draw_down_date.year
				
				remain_principal = loan.initial_amount
				#remain_interest = loan.total_repay_amount_lender - loan.initial_amount
				ratio = prod.APR_lender / bor.getBorAPR(prod.APR_borrower)
				remain_interest = (loan.total_repay_amount_lender - loan.initial_amount) * ratio
				
				for i in range(prod.repayment_period):
					day = start_date_day
					month = (start_date_month + i-1) % 12 + 1
					year = start_date_year + ((start_date_month+i-1) / 12)
					
					interest = remain_principal * rate_per_month
					interest_ldr = interest * ratio
					principal = loan.instalment_lender - interest
					remain_interest -= interest_ldr
					remain_principal -= principal
					
					try:
						date = datetime.strptime(str(day)+'/'+str(month)+'/'+str(year), '%d/%m/%Y')
					except ValueError:
						date = datetime.strptime('1/'+str((month%12)+1)+'/'+str(year), '%d/%m/%Y') - dt.timedelta(days=1)
					today = datetime.strptime(timezone.localtime(timezone.now()).strftime('%d/%m/%Y'), '%d/%m/%Y')
					if date < today and bor.repaid_month >= (i+1):
						status = 'PAID'
					elif date < today and bor.repaid_month < (i+1):
						status = 'OVERDUE'
					elif date >= today:
						status = 'OPEN'
					schedule = {
					#'date': timezone.localtime(date).strftime('%d/%m/%Y'),
					'date': date,
					'initial_principal': loan.initial_amount,
					'os_principal': remain_principal,
					'os_interest': remain_interest, 
					'os_balance': remain_principal + remain_interest,
					'paid_principal': principal if status == 'PAID' else 0,
					'paid_interest': interest if status == 'PAID' else 0,
					'ref_num': loan.ref_num,
					'prod_name': prod.name_en,
					'installment': loan.instalment_lender,
					'status': status,
					}
					schedule_list.append(schedule)
				
		# month base view
		date_set = set()
		for schedule in schedule_list:
			date = datetime.strptime(datetime.strftime(schedule['date'], '%m/%Y'), '%m/%Y')
			date_set.add(date)
		for date in date_set:
			schedule_sub_list = [schedule for schedule in schedule_list if schedule['date'].month == date.month and schedule['date'].year == date.year]
			
			schedule = {
			'shadow_datetime': date,
			'date': datetime.strftime(date, '%Y/%m'),
			'initial_principal': FLOAT_DATA_FORMAT.format(sum([s['initial_principal'] for s in schedule_sub_list])),
			'os_principal': FLOAT_DATA_FORMAT.format(abs(sum([s['os_principal'] for s in schedule_sub_list]))),
			'os_interest': FLOAT_DATA_FORMAT.format(abs(sum([s['os_interest'] for s in schedule_sub_list]))),
			'os_balance': FLOAT_DATA_FORMAT.format(abs(sum([s['os_balance'] for s in schedule_sub_list]))),
			'paid_principal': FLOAT_DATA_FORMAT.format(sum([s['paid_principal'] for s in schedule_sub_list])),
			'paid_interest': FLOAT_DATA_FORMAT.format(sum([s['paid_interest'] for s in schedule_sub_list])),
			'ref_num': '',
			'prod_name': '',
			'installment': FLOAT_DATA_FORMAT.format(sum([s['installment'] for s in schedule_sub_list])),
			'status': '',
			}
			schedule2_list.append(schedule)
		
		serialized_table_list = schedule2_list
		content = {'data': serialized_table_list}
		return Response(content)
Exemple #17
0
def auth(request):
    lang = sup_fn.get_lang(request)
    if request.method == 'POST':
        email = request.POST.get('email')
        password = request.POST.get('password')

    # admin login
    if 'pl_admin' in request.META.get('HTTP_REFERER').split('/'):
        if len(AdminUser.objects.filter(email=email)) == 0:
            return HttpResponse('Admin side: account doesn\'t exist.')
        else:
            usr = AdminUser.objects.filter(email=email)[0]
            if usr.password != hashlib.md5(password).hexdigest():
                return HttpResponse('Admin side: wrong password.')
            else:
                request.session['type'] = 'ADMIN'
                request.session['email'] = email
                request.session['handling_side'] = 'B'
                request.session['timestamp'] = datetime.strftime(
                    timezone.localtime(timezone.now()), '%Y-%m-%d %H:%M:%S')
                request.session.save()

                # update last login
                usr = sup_fn.get_user(request)
                usr.this_login = timezone.localtime(timezone.now())
                usr.save()

                return redirect('/pl_admin/application')

    # user login
    if len(
            User.objects.filter(email=email,
                                password=hashlib.md5(password).hexdigest(),
                                status='ACTIVE')) == 0:
        # login failed
        if lang == 'en':
            content = {
                'status': 'Login Failed!',
                'content':
                'You can go back to login page and try to login again.',
            }
            if len(User.objects.filter(email=email, status='ACTIVE')) == 0:
                content['header'] = 'Account doesn\'t exist or is locked.'
            else:
                content['header'] = 'The password is incorrect.'

        if lang == 'zh':
            content = {
                'status': '登入失敗!',
                'content': '你可以返回登入頁面并嘗試重新登入。',
            }
            if len(User.objects.filter(email=email, status='ACTIVE')) == 0:
                content['header'] = '用戶名不存在。'
            else:
                content['header'] = '密碼不正確。'

        usr_list = User.objects.filter(email=email, status='ACTIVE')
        for usr in usr_list:
            # accumulate both lender & borrower account
            usr.account_attempt += 1
            if usr.account_attempt >= ACCOUNT_ATTEMPT_TIMES:
                usr.status = 'LOCKED'
            usr.save()
        if len(usr_list) != 0:
            if usr_list[0].account_attempt >= ACCOUNT_ATTEMPT_TIMES:
                # generate token
                def generate_unique_sequence64(size=64,
                                               chars=string.ascii_uppercase +
                                               string.digits):
                    uor_list = UserOperationRequest.objects.filter(
                        type='Forget Password', status="ACTIVE")
                    token_list = [
                        json.loads(uor.details)['token'] for uor in uor_list
                    ]
                    while 1:
                        rand_seq = ''.join(
                            random.choice(chars) for _ in range(size))
                        if rand_seq not in token_list:
                            return rand_seq

                new_token = generate_unique_sequence64()
                details = {"token": new_token, "email": email}
                new_uor = UserOperationRequest(
                    usr_id=0,
                    type='Forget Password',
                    details=json.dumps(details),
                    status='ACTIVE',
                    create_timestamp=timezone.localtime(timezone.now()),
                    update_timestamp=timezone.localtime(timezone.now()))
                new_uor.save()

                usr_emailing = emailing.GeneralEmail(email_addr=email)
                usr_emailing.unlock_account(token=new_token)
        content['lang'] = lang
        return render(request, 'peerloan/general/general_ack.html', content)
    else:
        # login successfully
        request.session['email'] = email
        request.session['timestamp'] = datetime.strftime(
            timezone.localtime(timezone.now()), '%Y-%m-%d %H:%M:%S')

        # check password case sensitively
        usr = User.objects.filter(email=email, status='ACTIVE')[0]

        if hashlib.md5(password).hexdigest() != usr.password:
            content = {
                'status': 'Login Failed!',
                'header': 'The password is incorrect.',
                'content':
                'You can go back to login page and try to login again.',
            }
            return render(request, 'peerloan/general/general_ack.html',
                          content)
        """
		if len(User.objects.filter(email=email, password__exact=hashlib.md5(password).hexdigest(), status='ACTIVE')) == 1 and User.objects.filter(email=email, password__exact=password, status='ACTIVE')[0].type == 'ADMIN':
			request.session['type'] = 'ADMIN'
			request.session['handling_side'] = 'B'
			request.session.save()
			
			# update last login
			usr = sup_fn.get_user(request)
			usr.this_login = timezone.localtime(timezone.now())
			usr.save()
			
			return redirect('/pl_admin/application')
		"""
        if len(
                User.objects.filter(
                    email=email,
                    password__exact=hashlib.md5(password).hexdigest(),
                    status='ACTIVE')) == 2:
            request.session['type'] = 'L'
            request.session.save()

            # update last login
            usr_list = User.objects.filter(email=email)
            for usr in usr_list:
                usr.account_attempt = 0
                usr.this_login = timezone.localtime(timezone.now())
                usr.save()

            return redirect('/portfolio/portfolio_summary')
        else:
            request.session['type'] = 'B'
            request.session.save()

            # update last login
            usr = sup_fn.get_user(request)
            usr.account_attempt = 0
            usr.this_login = timezone.localtime(timezone.now())
            usr.save()

            return redirect('/borrow_now')
	def get_initial_queryset(self):
		user = sup_fn.get_user(self.request)
		trx_list = UserTransaction.objects.filter(usr_id=user.id)
		return trx_list
	def get(self, request, format=None):
		usr = sup_fn.get_user(request)
		lang = sup_fn.get_lang(request)
		
		prod_id = request.GET.get('prod_id')
		if prod_id == 'all':
			inv_list = Investment.objects.filter(usr_id=usr.id)
		else:
			inv_list = Investment.objects.filter(usr_id=usr.id,prod_id=prod_id)
			
		acc = Account.objects.get(usr_id = usr.id)
		#color_lib = {'red':['#E08283','#E7505A','#D91E18'],'green':['#36D7B7','#4DB3A2','#26C281'],'yellow':['#F4D03F','#F7CA18','#F3C200'],'purple':['#BF55EC']}
		color_lib = ['#E08283','#36D7B7','#F4D03F','#BF55EC','#3598DC']
		data_list = []
		i = 0
		if prod_id == 'all':
			total_balance = acc.balance + sum([inv.on_hold_amount + inv.usable_amount for inv in inv_list])
			if lang == 'en':
				data_list.append({'name': 'Total Account Balance', 'amount': total_balance, 'color': color_lib[i]})
				i += 1
				data_list.append({'name': 'Available Amount', 'amount': acc.balance, 'color': color_lib[i]})
				i += 1
			elif lang == 'zh':
				#data_list.append({'name': '總賬戶結餘', 'amount': total_balance, 'color': color_lib[i]})
				#i += 1
				data_list.append({'name': '可用金額', 'amount': acc.balance, 'color': color_lib[i]})
				i += 1
		
			for inv in inv_list:
				prod = Product.objects.get(id=inv.prod_id)
				if lang == 'en':
					data_list.append({'name': 'Queuing Amount in %s' % (prod.name_en), 'amount': inv.usable_amount + inv.on_hold_amount, 'color': color_lib[i]})
				elif lang == 'zh':
					data_list.append({'name': '分配在' + (prod.name_zh.encode('utf8')), 'amount': inv.usable_amount + inv.on_hold_amount, 'color': color_lib[i]})
					
				i += 1
		else:
			if len(inv_list) == 0:
				prod = Product.objects.get(id=prod_id)
				if lang == 'en':
					data_list.append({'name': 'Total Queuing Amount %s' % (prod.name_en), 'amount': 0, 'color': color_lib[i]})
					i += 1
					data_list.append({'name': 'Queuing Amount %s' % (prod.name_en) + ' (not matched)', 'amount': 0, 'color': color_lib[i]})
					i += 1
					data_list.append({'name': 'Queuing Amount %s' % (prod.name_en) + ' (on hold)', 'amount': 0, 'color': color_lib[i]})
					i += 1
				elif lang == 'zh':
					#data_list.append({'name': '總分配在' + (prod.name_zh.encode('utf8')), 'amount': 0, 'color': color_lib[i]})
					#i += 1
					data_list.append({'name': '分配在' + (prod.name_zh.encode('utf8')) + ' (未匹配)', 'amount': 0, 'color': color_lib[i]})
					i += 1
					data_list.append({'name': '分配在' + (prod.name_zh.encode('utf8')) + ' (未提款)', 'amount': 0, 'color': color_lib[i]})
					i += 1
			else:
				for inv in inv_list:
					prod = Product.objects.get(id=inv.prod_id)
					if lang == 'en':
						data_list.append({'name': 'Total Queuing Amount %s' % (prod.name_en), 'amount': inv.usable_amount + inv.on_hold_amount, 'color': color_lib[i]})
						i += 1
						data_list.append({'name': 'Queuing Amount %s' % (prod.name_en) + ' (not matched)', 'amount': inv.usable_amount, 'color': color_lib[i]})
						i += 1
						data_list.append({'name': 'Queuing Amount %s' % (prod.name_en) + ' (on hold)', 'amount': inv.on_hold_amount, 'color': color_lib[i]})
						i += 1
					elif lang == 'zh':
						#data_list.append({'name': '總分配在' + (prod.name_zh.encode('utf8')), 'amount': inv.usable_amount + inv.on_hold_amount, 'color': color_lib[i]})
						#i += 1
						data_list.append({'name': '分配在' + (prod.name_zh.encode('utf8')) + ' (未匹配)', 'amount': inv.usable_amount, 'color': color_lib[i]})
						i += 1
						data_list.append({'name': '分配在' + (prod.name_zh.encode('utf8')) + ' (未提款)', 'amount': inv.on_hold_amount, 'color': color_lib[i]})
						i += 1
		for data in data_list:
			data['amount'] = round(data['amount'], 2)
			
		#serialized_data_list = RepayPieSerializer(data_list, many=True)
		content = {'data': data_list}
		return Response(content)
Exemple #20
0
def apply_to_be_investor(request):
	usr = sup_fn.get_user(request)
	lang = sup_fn.get_lang(request)
	
	try:
		uor = UserOperationRequest.objects.filter(usr_id=usr.id, type="Apply To Be Investor").latest('create_timestamp')
	except ObjectDoesNotExist:
		# the first time apply
		
		nationality_list = []
		f = open('/home/ubuntu/project_peerloan/peerloan/peerloan_src/nationality.csv', 'r')
		for row in csv.DictReader(f):
			nationality_list.append(row['Nationality'])
		f.close()
		
		country_list = []
		f = open('/home/ubuntu/project_peerloan/peerloan/peerloan_src/countries_of_the_world.csv', 'r')
		for row in csv.DictReader(f):
			country_list.append(row['Country'])
		f.close()
		"""
		buttons = []
		buttons.append({"name": "Submit", "type":"submit"})
		buttons.append({"name": "Back", "type":"button", "onclick":"window.history.back()"})
		"""
		
		content = {
		'lang': lang,
		'title': 'Lender Application Form',
		'form_action': '/ack/',
		'nationality_list': nationality_list,
		'country_list': country_list,
		'usr_details': sup_fn.sync_from_usr(usr.id),
		'gender_list': OrderedDict(
			(
				('Male', 'Male'),
				('Female', 'Female')
			)
		),
		#'buttons': buttons,
		}
		if lang == 'zh':
			content['title'] = '貸方申請表'
			additional_content = {
				'gender_list':OrderedDict(
					(
						('Male', '男性'), 
						('Female', '女性')
					)
				),
			}
			content.update(additional_content)
		return render(request, 'peerloan/borrower/investor_application_form.html', content)
	else:
		# approved
		if uor.status == 'APPROVED':
			details = json.loads(uor.details)
			content = {
			'lang': lang,
			'title': 'Agreement',
			'form_action': '/ack/',
			'mobile': details['Individual']['Mobile'],
			'uor_id': uor.id,
			}
			if lang == 'zh':
				content['title'] = '合約'
			
			error = request.GET.get('error')
			if lang == 'en':
				if error == 'invalid_OTP':
					content['error_msg'] = 'Please input a valid OTP'
				if error == 'OTP_not_matched':
					content['error_msg'] = 'The OTP doesn\'t match to our record, please receive a new OTP and try again'
				if error == 'OTP_expired':
					content['error_msg'] = 'The OTP is expired, please receive a new OTP first'
			elif lang == 'zh':
				if error == 'invalid_OTP':
					content['error_msg'] = '請輸入一個有效的OTP'
				if error == 'OTP_not_matched':
					content['error_msg'] = '你輸入的OTP與我們的記錄不符合,請重新操作'
				if error == 'OTP_expired':
					content['error_msg'] = '你的OTP已經逾期,請重新獲取OTP'
			
			return render(request, 'peerloan/borrower/investor_agreement_form.html', content)
			
		# wait for approval
		elif uor.status == 'DOC UPLOADED' or uor.status == 'PENDING DOC/IV':
			if lang == 'en':
				details = json.loads(uor.details, object_pairs_hook=OrderedDict)
				for k, v in details['File Uploaded'].iteritems():
					details['File Uploaded'][k] = '<a href="/file/'+v+'" target="_blank">View</a>'
				buttons = []
				buttons.append({"name": "Print Acknowledgement", "type":"button", "onclick":"javascript:window.print()"})
				
				content = {
				'lang': lang,
				'title': 'Lender Application - Acknowledgement',
				'form_action': 'javascript:;',
				'instruction': """Thank you for your application. We will process your application within 1 business day and notice you the application result by SMS and email.""",
				'details': details,
				'buttons': buttons,
				}
			elif lang == 'zh':
				en2zh_dict = {
					'Account Type': '戶口類型',
					'Individual': '個人',
					'Corporate': '企業',
					'File Uploaded': '上載文件',
					
					'Company Name': '公司名稱',
					'Established at': '成立日期',
					'CR NO.': '公司註冊號碼',
					'Office Address': '公司地址',
					'Company Size': '公司規模',
					'more than 500': '多於 500',
					'Office Tel': '公司電話',
					'Industry': '行業',
					
					'Surname': '姓氏',
					'Given Name': '名',
					'Gender': '性別',
					'Male': '男性',
					'Female': '女性',
					
					'Education Level': '教育程度',
					'Primary School': '小學',
					'Secondary School': '中學',
					'Tertiary': '專上學院',
					'Bachelors': '大學',
					'Masters or above': '碩士或以上',
					
					'HKID': '香港身份證號碼',
					'Nationality': '國籍',
					'Date of Birth': '出生日期',
					'Occupation': '職業',
					'Type of Employment': '受僱類型',
					'Full Time Employed': '全職',
					'Part Time Employed': '兼職',
					'Self-Employed': '自僱',
					'Unemployed': '待業',
					'Housewife': '家庭主婦',
					'Retired': '退休',
					
					'Annual Income': '年收入',
					'Residential Address': '住宅地址',
					'Home Phone No.': '住宅電話',
					'Mobile': '手提電話',
					'Source of Fund': '資金來源',
					'Salary': '薪金',
					'Business': '生意',
					'Investment': '投資',
					'Others': '其他',
					
					'Other Source of Fund': '其他資金來源',
					'Customer Declaration': '顧客聲明',
					'Application No': '申請編號',
					
					'HKID Proof': '香港身份證證明',
					'Address Proof': '住址證明',
					'BR/CR': '商業登記證/公司註冊證明書',
				}
				details = json.loads(uor.details, object_pairs_hook=OrderedDict)
				for k, v in details['File Uploaded'].iteritems():
					details['File Uploaded'][k] = '<a href="/file/'+v.encode('utf8')+'" target="_blank">瀏覽</a>'
				
				zh_details = OrderedDict()
				for section, fields in details.iteritems():
					zh_details[en2zh_dict[section]] = OrderedDict()
					for k, v in details[section].iteritems():
						zh_v = sup_fn.try_KeyError(en2zh_dict, v)
						if zh_v != '--':
							zh_details[en2zh_dict[section]][en2zh_dict[k]] = zh_v
						else:
							zh_details[en2zh_dict[section]][en2zh_dict[k]] = v
							
				
				buttons = []
				buttons.append({"name": "列印通知", "type":"button", "onclick":"javascript:window.print()"})
				
				content = {
				'lang': lang,
				'title': '確認通知 - 貸方申請已收到',
				'form_action': 'javascript:;',
				'instruction': """感謝你的申請,我們會於一個工作天內處理你的申請,並以手機短訊及電郵通知你申請結果。""",
				'details': zh_details,
				'buttons': buttons,
				}
			return render(request, 'peerloan/borrower/form_with_section.html', content)
		elif uor.status == 'REJECTED' or uor.status == 'CANCELLED':
			content = {
			'lang': lang,
			'title': 'Application State Changed - Acknowledgement',
			'instruction': """Thank you for your application. Unfortunately, we are sorry to inform you that your application have been %s. Please contact
			admin for more information.""" % (uor.status),
			}
			if lang == 'zh':
				content = {
				'lang': lang,
				'title': '確認通知 - 申請狀態更變',
				'instruction': """感謝你的申請, 我們很遺憾地通知你,你的申請未能成功批核。""",
				}
			return render(request, 'peerloan/borrower/acknowledgement.html', content)
	def get(self, request, format=None):
		if request.method == 'GET':
			usr = sup_fn.get_user(request)
			lang = sup_fn.get_lang(request)
			status = request.GET.get('status')
			start_date = request.GET.get('start_date')
			
			# check XSS
			if sup_fn.checkHTMLtags([v for k, v in request.GET.iteritems()]):
				return HttpResponse('Invalid input.')
				
			if usr.type == 'B':
				bor_list = BorrowRequest.objects.filter(usr_id=usr.id)
				if status != 'All':
					if status == 'AGREEMENT CONFIRMED':
						bor_list = [bor for bor in bor_list if 'AGREEMENT CONFIRMED' in bor.status or 'VALIDATED' in bor.status or 'FUND MATCHING' in bor.status]
					else:
						bor_list = [bor for bor in bor_list if status.upper() in bor.status]
				if start_date != 'All':
					start_date = datetime.strptime(start_date, '%m/%d/%Y')
					bor_list = [bor for bor in bor_list if datetime.strptime(timezone.localtime(bor.create_timestamp).strftime('%m/%d/%Y'), '%m/%d/%Y')>= start_date]
					
				data_list = []
				for bor in bor_list:
					details = {}
					prod = Product.objects.get(id=bor.prod_id)
					details['shadow_datetime'] = timezone.localtime(bor.update_timestamp)
					details['updated_date'] = datetime.strftime(timezone.localtime(bor.update_timestamp), '%Y/%m/%d')
					details['prod_name'] = prod.name_en
					if lang == 'zh':
						details['prod_name'] = prod.name_zh
					details['ref_num'] = bor.ref_num
					details['amount'] = FLOAT_DATA_FORMAT.format(bor.amount)
					details['APR'] = FLOAT_DATA_FORMAT.format(bor.getBorAPR(prod.APR_borrower if prod.fake_APR_borrower == None else prod.fake_APR_borrower))
					details['apply_date'] = datetime.strftime(timezone.localtime(bor.create_timestamp), '%Y/%m/%d')
					details['repayment_progress'] = str(bor.repaid_month)+'/'+str(prod.repayment_period)
					details['status'] = ''.join([i for i in bor.status if (not i.isdigit())])
					details['bor_id'] = bor.id
					
					if bor.status == 'AUTO APPROVED':
						details['href'] = '/product/upload_docs/?prod_id='+str(prod.id)
					elif bor.status == 'DOC UPLOADED':
						details['href'] = '/product/confirm_agreement/?prod_id='+str(prod.id)
					elif bor.status == 'AGREEMENT CONFIRMED' or bor.status == 'VALIDATED' or bor.status == 'FUND MATCHING':
						details['href'] = '/ack_page/?action=confirm_agreement'
					elif bor.status == 'DISBURSED' or 'PAYBACK' in bor.status:
						details['href'] = '/my_account/all_application_listing/detail/?bor_id='+str(bor.id)
					elif bor.status == 'FUND MATCHING COMPLETED':
						details['href'] = '/product/confirm_memorandum/?prod_id='+str(prod.id)
					else:
						details['href'] = 'javascript:;'
						
					data_list.append(details)
				#serialized_data_list = LaasSerializer(data_list, many=True)
				content = {'data': data_list}
				return Response(content)
			if usr.type == 'L':
				inv_list = Investment.objects.filter(usr_id = usr.id)
				loan_list = []
				for inv in inv_list:
					loans = Loan.objects.filter(inv_id = inv.id)
					for loan in loans:
						loan_list.append(loan)
				if status != 'All':
					loan_list = [loan for loan in loan_list if status.upper() in loan.status]
				if start_date != 'All':
					start_date = datetime.strptime(start_date, '%m/%d/%Y')
					loan_list = [loan for loan in loan_list if datetime.strptime(timezone.localtime(loan.create_timestamp).strftime('%m/%d/%Y'), '%m/%d/%Y')>= start_date]
				data_list = []
				for loan in loan_list:
					details = {}
					bor = BorrowRequest.objects.get(id=loan.bor_id)
					prod = Product.objects.get(id=bor.prod_id)
					details['updated_date'] = datetime.strftime(timezone.localtime(loan.update_timestamp), '%d/%m/%Y')
					details['prod_name'] = prod.name_en
					details['ref_num'] = bor.ref_num
					details['amount'] = loan.initial_amount
					details['APR'] = prod.APR_lender
					details['draw_down_date'] = datetime.strftime(timezone.localtime(loan.draw_down_date), '%d/%m/%Y')
					details['status'] = bor.status
					data_list.append(details)
				serialized_data_list = LoanLenderSerializer(data_list, many=True)
			content = {'data': serialized_data_list.data}
			return Response(content)
		else:
			return HttpResponse('Wrong request method.')
	def get(self, request, format=None):
		usr = sup_fn.get_user(request)
		lang = sup_fn.get_lang(request)
		
		this_month = datetime.strptime(request.GET.get('date'), '%m/%Y')
		this_month = pytz.timezone('Asia/Hong_Kong').localize(this_month)
		
		if datetime.now().month == this_month.month and datetime.now().year == this_month.year:
			period = datetime.strftime(this_month, '%Y/%m/%d')+' - '+datetime.strftime(datetime.now(), '%Y/%m/%d')
		else:
			month = this_month.month
			year = this_month.year
			month += 1
			if month == 13:
				year += 1
				month = 1
			next_month = datetime.strptime(str(year)+'/'+str(month), '%Y/%m')
			period = datetime.strftime(this_month, '%Y/%m/%d')+' - '+datetime.strftime(next_month - dt.timedelta(days=1), '%Y/%m/%d')
		
		if datetime.now().month == this_month.month and datetime.now().year == this_month.year:
			res_details = sup_fn.generate_portfolio_summary(usr_id=usr.id, date=this_month)
		else:
			try:
				mps = MonthlyPortfolioSummary.objects.get(usr_id=usr.id, month=this_month.month, year=this_month.year)
			except ObjectDoesNotExist:
				content = {}
				# data 1
				content['account_summary'] = {
					'Account Amount': FLOAT_DATA_FORMAT.format(0),
					'Unallocated Amount': FLOAT_DATA_FORMAT.format(0),
					'Un-matched Amount': FLOAT_DATA_FORMAT.format(0),
					'Matched Amount': FLOAT_DATA_FORMAT.format(0)
				}
				
				# data 2 & 3
				data_list = []
				if lang == 'en':
					data_list.append({'name': 'Normal Repayment', 'amount': FLOAT_DATA_FORMAT.format(0), 'color': ''})
					data_list.append({'name': 'Normal Settlement', 'amount': FLOAT_DATA_FORMAT.format(0), 'color': ''})
					data_list.append({'name': 'Early Settlement', 'amount': FLOAT_DATA_FORMAT.format(0), 'color': ''})
				elif lang == 'zh':
					data_list.append({'name': '正常供款', 'amount': FLOAT_DATA_FORMAT.format(0), 'color': ''})
					data_list.append({'name': '最後一期供款', 'amount': FLOAT_DATA_FORMAT.format(0), 'color': ''})
					data_list.append({'name': '提早還款', 'amount': FLOAT_DATA_FORMAT.format(0), 'color': ''})
				
				#serialized_data_list = RepayPieSerializer(data_list, many=True)
				content['data_2'] = data_list
				content['title_2'] = 'HK$'+FLOAT_DATA_FORMAT.format(0)
				
				data_list = []
				if lang == 'en':
					data_list.append({'name': 'Overdue 0 day', 'amount': FLOAT_DATA_FORMAT.format(0), 'color': ''})
					data_list.append({'name': 'Overdue 1-29 days', 'amount': FLOAT_DATA_FORMAT.format(0), 'color': ''})
					data_list.append({'name': 'Overdue 30-59 days', 'amount': FLOAT_DATA_FORMAT.format(0), 'color': ''})
					data_list.append({'name': 'Overdue 60-89 days', 'amount': FLOAT_DATA_FORMAT.format(0), 'color': ''})
					data_list.append({'name': 'Overdue 90-120 days', 'amount': FLOAT_DATA_FORMAT.format(0), 'color': ''})
				elif lang == 'zh':
					data_list.append({'name': '逾期0日', 'amount': FLOAT_DATA_FORMAT.format(0), 'color': ''})
					data_list.append({'name': '逾期1-29日', 'amount': FLOAT_DATA_FORMAT.format(0), 'color': ''})
					data_list.append({'name': '逾期30-59日', 'amount': FLOAT_DATA_FORMAT.format(0), 'color': ''})
					data_list.append({'name': '逾期60-89日', 'amount': FLOAT_DATA_FORMAT.format(0), 'color': ''})
					data_list.append({'name': '逾期90-120日', 'amount': FLOAT_DATA_FORMAT.format(0), 'color': ''})
				
				#serialized_data_list = RepayPieSerializer(data_list, many=True)
				content['data_3'] = data_list
				
				content['title_3'] = 'Repayment Status'
				
				content['basic_info'] = {
					'Accrued Interest': FLOAT_DATA_FORMAT.format(0),
					'Weighted Annual Interest Rate': FLOAT_DATA_FORMAT.format(0)+'%',
					'Active Account': 0,
					'New Account': FLOAT_DATA_FORMAT.format(0)+' (included '+FLOAT_DATA_FORMAT.format(0)+' borrowers)',
					'Period': period,
				}
				if lang == 'zh':
					content['basic_info']['New Account'] = FLOAT_DATA_FORMAT.format(0)+' (包含'+FLOAT_DATA_FORMAT.format(0)+'個借款人)'
					
				return Response(content)
			else:
				res_details = json.loads(mps.details)
				
		content = {}
		# data 1
		dict = res_details['Portfolio Summary ($)']
		content['account_summary'] = {
			'Account Amount': FLOAT_DATA_FORMAT.format(dict['Unallocated Amount']+dict['Unmatched Amount']+dict['Matched Amount']),
			'Unallocated Amount': FLOAT_DATA_FORMAT.format(dict['Unallocated Amount']),
			'Un-matched Amount': FLOAT_DATA_FORMAT.format(dict['Unmatched Amount']),
			'Matched Amount': FLOAT_DATA_FORMAT.format(dict['Matched Amount'])
		}
			
		# data 2 & 3
		dict = res_details['Portfolio Summary ($)']
		data_list = []
		if lang == 'en':
			data_list.append({'name': 'Normal Repayment', 'amount': FLOAT_DATA_FORMAT.format(dict['Normal Run-Down']), 'color': ''})
			data_list.append({'name': 'Normal Settlement', 'amount': FLOAT_DATA_FORMAT.format(dict['Normal Settlement']), 'color': ''})
			data_list.append({'name': 'Early Settlement', 'amount': FLOAT_DATA_FORMAT.format(dict['Early Settlement']), 'color': ''})
		elif lang == 'zh':
			data_list.append({'name': '正常供款', 'amount': FLOAT_DATA_FORMAT.format(dict['Normal Run-Down']), 'color': ''})
			data_list.append({'name': '最後一期供款', 'amount': FLOAT_DATA_FORMAT.format(dict['Normal Settlement']), 'color': ''})
			data_list.append({'name': '提早還款', 'amount': FLOAT_DATA_FORMAT.format(dict['Early Settlement']), 'color': ''})
		
		#serialized_data_list = RepayPieSerializer(data_list, many=True)
		#content['data_2'] = serialized_data_list.data
		content['data_2'] = data_list
		content['title_2'] = 'HK$'+FLOAT_DATA_FORMAT.format(dict['Normal Run-Down']+dict['Normal Settlement']+dict['Early Settlement'])
		
		dict = res_details['Net Flow and Delinquency ($)']
		data_list = []
		if lang == 'en':
			data_list.append({'name': 'Overdue 0 day', 'amount': FLOAT_DATA_FORMAT.format(dict['0 DPD (Current)']), 'color': ''})
			data_list.append({'name': 'Overdue 1-29 day', 'amount': FLOAT_DATA_FORMAT.format(dict['1-29 DPD (Cycle 1)']), 'color': ''})
			data_list.append({'name': 'Overdue 30-59 day', 'amount': FLOAT_DATA_FORMAT.format(dict['30-59 DPD (Cycle 2)']), 'color': ''})
			data_list.append({'name': 'Overdue 60-89 day', 'amount': FLOAT_DATA_FORMAT.format(dict['60-89 DPD (Cycle 3)']), 'color': ''})
			data_list.append({'name': 'Overdue 90-120 day', 'amount': FLOAT_DATA_FORMAT.format(dict['90-120 DPD (Cycle 4)']), 'color': ''})
			data_list.append({'name': 'Overdue 120+ day', 'amount': FLOAT_DATA_FORMAT.format(res_details['Portfolio Summary ($)']['Gross Charge Off']), 'color': ''})
		elif lang == 'zh':
			data_list.append({'name': '逾期0日', 'amount': FLOAT_DATA_FORMAT.format(dict['0 DPD (Current)']), 'color': ''})
			data_list.append({'name': '逾期1-29日', 'amount': FLOAT_DATA_FORMAT.format(dict['1-29 DPD (Cycle 1)']), 'color': ''})
			data_list.append({'name': '逾期30-59日', 'amount': FLOAT_DATA_FORMAT.format(dict['30-59 DPD (Cycle 2)']), 'color': ''})
			data_list.append({'name': '逾期60-89日', 'amount': FLOAT_DATA_FORMAT.format(dict['60-89 DPD (Cycle 3)']), 'color': ''})
			data_list.append({'name': '逾期90-120日', 'amount': FLOAT_DATA_FORMAT.format(dict['90-120 DPD (Cycle 4)']), 'color': ''})
			data_list.append({'name': '逾期120+日', 'amount': FLOAT_DATA_FORMAT.format(res_details['Portfolio Summary ($)']['Gross Charge Off']), 'color': ''})
		
		#serialized_data_list = RepayPieSerializer(data_list, many=True)
		#content['data_3'] = serialized_data_list.data
		content['data_3'] = data_list
		content['title_3'] = 'Repayment Status'
		
		content['basic_info'] = {
			'Accrued Interest': FLOAT_DATA_FORMAT.format(res_details['Portfolio Summary ($)']['Accrued Interest']),
			'Weighted Annual Interest Rate': FLOAT_DATA_FORMAT.format(res_details['Return']['Weighted Annual Interest Rate'])+'%',
			'Active Account': res_details['Portfolio Summary (#)']['Active Account'],
			'New Account': FLOAT_DATA_FORMAT.format(res_details['Portfolio Summary ($)']['New Account'])+' (included '+str(res_details['Portfolio Summary (#)']['New Account'])+' borrowers)',
			'Period': period,
		}
		if lang == 'zh':
			content['basic_info']['New Account'] = FLOAT_DATA_FORMAT.format(res_details['Portfolio Summary ($)']['New Account'])+' (包含'+str(res_details['Portfolio Summary (#)']['New Account'])+'個借款人)'
			
		return Response(content)
Exemple #23
0
def header(request):
	user = sup_fn.get_user(request)
	lang = sup_fn.get_lang(request)
	http_referer = request.META.get('PATH_INFO')
	# get category and sub-category to active the button
	if len(http_referer.split('/')) > 2:
		cate = http_referer.split('/')[2]
		if len(http_referer.split('/')) > 3:
			sub_cate = http_referer.split('/')[3]
		else:
			sub_cate = ''
	else:
		cate, sub_cate = '', ''
	
	last_login = user.last_login
	if last_login == None:
		last_login = user.this_login
	last_login = timezone.localtime(last_login)
	
	content = {
	'usr':user,
	'cate': cate,
	'sub_cate': sub_cate,
	'lang':lang,
	'last_login': last_login.strftime('%Y/%m/%d %H:%M'),
	}
	if user.type == 'L':
		return render(request, 'peerloan/lender/header.html', content)
	elif user.type == 'B':
		return render(request, 'peerloan/borrower/header.html', content)
	elif len(AdminUser.objects.filter(email=user.email)) != 0:
		side = request.session['handling_side']
		
		ptn_list = PendingTaskNotification.objects.filter(status='UNREAD')
		
		if side == 'B':
			application_ptn_no = 0
			disburse_ptn_no = 0
			repayment_ptn_no = 0
			for ptn in ptn_list:
				if ptn.type == 'Application':
					application_ptn_no += 1
				elif ptn.type == 'Disburse':
					disburse_ptn_no += 1
				elif ptn.type == 'Repayment':
					repayment_ptn_no += 1
					
			ptn_cnt = {
			'application': application_ptn_no,
			'disbursement': disburse_ptn_no,
			'repayment': repayment_ptn_no
			}
			for k, v in ptn_cnt.iteritems():
				if v == 0:
					ptn_cnt[k] = ''
			content['ptn_cnt'] = ptn_cnt
			return render(request, 'peerloan/admin/borrower/header.html', content)
		if side == 'L':
			ptn_cnt = {
			'application': len([ptn for ptn in ptn_list if ptn.type == 'Apply To Be Investor']),
			'deposit': len([ptn for ptn in ptn_list if ptn.type == 'Deposit Money']),
			'cash_out': len([ptn for ptn in ptn_list if ptn.type == 'Withdraw Money']),
			}
			for k, v in ptn_cnt.iteritems():
				if v == 0:
					ptn_cnt[k] = ''
			content['ptn_cnt'] = ptn_cnt
			return render(request, 'peerloan/admin/lender/header.html', content)
	def get(self, request, format=None):
		usr = sup_fn.get_user(request)
		lang = sup_fn.get_lang(request)
		
		trend = request.GET.get('trend')
		year = int(request.GET.get('year'))
		"""
		if lang == 'en':
			num_to_month = {
				1: 'Jan', 2: 'Feb', 3: 'Mar', 4: 'Apr', 5: 'May', 6: 'Jun',
				7: 'July', 8: 'Aug', 9: 'Sept', 10: 'Oct', 11: 'Nov', 12: 'Dec'
			}
		elif lang == 'zh':
			num_to_month = {
				1: '1月', 2: '2月', 3: '3月', 4: '4月', 5: '5月', 6: '6月',
				7: '7月', 8: '8月', 9: '9月', 10: '10月', 11: '11月', 12: '12月'
			}
		"""
		num_to_month = {
			1: 'Jan', 2: 'Feb', 3: 'Mar', 4: 'Apr', 5: 'May', 6: 'Jun',
			7: 'July', 8: 'Aug', 9: 'Sept', 10: 'Oct', 11: 'Nov', 12: 'Dec'
		}
			
		mps_list = MonthlyPortfolioSummary.objects.filter(usr_id=usr.id, year=year)
		data_list = []
		content = {}
		if year == datetime.now().year:
			months = datetime.now().month - 1
		else:
			months = 12
		for i in range(months):
			filtered_mps_list = [mps for mps in mps_list if mps.month==(i+1)]
			if len(filtered_mps_list) != 0:
				mps = filtered_mps_list[0]
				details = json.loads(mps.details)
				if trend == 'Outstanding Balance':
					data_list.append({'x': num_to_month[mps.month].encode('utf8'), 'y': details['Portfolio Summary ($)']['Matched Amount']})
				elif trend == 'No. of Active Account':
					data_list.append({'x': num_to_month[mps.month].encode('utf8'), 'y': details['Portfolio Summary (#)']['Active Account']})
				elif trend == 'Accrued Interest':
					data_list.append({'x': num_to_month[mps.month].encode('utf8'), 'y': details['Portfolio Summary ($)']['Accrued Interest']})
				elif trend == 'New Account':
					data_list.append({'x': num_to_month[mps.month].encode('utf8'), 'y': details['Portfolio Summary ($)']['New Account']})
				elif trend == 'No. of New Account':
					data_list.append({'x': num_to_month[mps.month].encode('utf8'), 'y': details['Portfolio Summary (#)']['New Account']})
			else:
				data_list.append({'x': num_to_month[i+1].encode('utf8'), 'y': 0})
			
		content['data'] = data_list
		content['title'] = trend
		if trend == 'Outstanding Balance':
			content['formatter'] = 'HK${value}'
		elif trend == 'No. of Active Account':
			content['formatter'] = '{value}'
		elif trend == 'Accrued Interest':
			content['formatter'] = 'HK${value}'
		elif trend == 'New Account':
			content['formatter'] = 'HK${value}'
		elif trend == 'No. of New Account':
			content['formatter'] = '{value}'
		return Response(content)
def product(request):
    usr = sup_fn.get_user(request)
    lang = sup_fn.get_lang(request)
    action = request.META.get('PATH_INFO').split('/')[2]
    if action == 'apply':
        bor_list = BorrowRequest.objects.filter(usr_id=usr.id)
        bor_list = [
            bor for bor in bor_list if bor.status not in
            ['PAYBACK COMPLETED', 'REJECTED', 'CANCELLED']
        ]
        num_of_applied_prod = len(bor_list)

        # check which step
        if num_of_applied_prod != 0:
            return redirect('/borrow_now')

        prod_id = request.GET.get('prod_id')
        prod = Product.objects.get(id=prod_id)

        if request.method == 'POST':
            form = CaptchaForm(request.POST)
            if form.is_valid():
                # check hkid cannot repeat from other loan application
                simplified_hkid = request.POST.get('HKID').replace(
                    '(', '').replace(')', '').lower()
                other_bor_list = BorrowRequest.objects.filter(
                    (~Q(usr_id=usr.id)) & Q(simplified_hkid=simplified_hkid))
                if len(other_bor_list) != 0:
                    return redirect(
                        '/ack_page/?action=apply_loan_rejected&reason=repeated_hkid'
                    )

                # check hkid should be consistent with the one on he's lender account
                try:
                    ldr_usr = User.objects.get(email=usr.email, type='L')
                except ObjectDoesNotExist:
                    ''
                else:
                    ldr_details = json.loads(ldr_usr.detail_info)
                    ldr_simplified_hkid = ldr_details['Individual'][
                        'HKID'].replace('(', '').replace(')', '').lower()
                    if simplified_hkid != ldr_simplified_hkid:
                        return redirect(
                            '/ack_page/?action=apply_loan_rejected&reason=hkid_not_matched'
                        )

                # check social score
                fs = classes.FriendlyScore()
                fs.getToken()
                code, fs_usr_details = fs.get(
                    endpoint='users/partner-id/%s/show' % (usr.id), params={})

                social_total_score = 0
                social_fraud_risk_score = 0
                if code == 200:
                    social_total_score = float(fs_usr_details['score_points'])
                    social_fraud_risk_score = float(
                        fs_usr_details['risk_score'])

                prod_id = int(
                    request.META.get('HTTP_REFERER').split('/?prod_id=')[-1])
                prod = Product.objects.get(id=prod_id)

                inputs = {
                    'major':
                    request.POST.get('Subject'),
                    'resident':
                    request.POST.get('Living Status'),
                    'living_with':
                    request.POST.get('Living with'),
                    'university':
                    request.POST.get('Studying University'),
                    'GPA':
                    float(request.POST.get('Overall GPA')),
                    'date_of_birth':
                    request.POST.get('Date of Birth'),
                    'year':
                    request.POST.get('Currently Studying'),
                    'social_total_score':
                    '>400' if social_total_score > 400 else '0-400',
                    'social_fraud_risk_score':
                    '>1' if social_fraud_risk_score > 1 else '0-1',
                    'repayment_plan':
                    prod.repayment_plan,
                }

                result = sup_fn.calculate_loan_amount(inputs)

                discount_rate = 0
                if code == 200:
                    if float(fs_usr_details['score_points']) > 431:
                        discount_rate = 0.1

                ref_num = sup_fn.generate_ref_num('borrow_request', 'LOA')
                amount = min(result['amount'],
                             float(request.POST.get('Applied Amount')))

                if prod.repayment_plan == 'Instalment':
                    rate_per_month = prod.APR_borrower * (
                        1 - discount_rate) * 0.01 / 12
                    instalment_borrower = amount * (
                        rate_per_month /
                        (1 -
                         (1 + rate_per_month)**(-12 *
                                                (prod.repayment_period / 12))))
                    rate_per_month = prod.APR_lender * 0.01 / 12
                    instalment_lender = amount * (
                        rate_per_month /
                        (1 -
                         (1 + rate_per_month)**(-12 *
                                                (prod.repayment_period / 12))))
                elif prod.repayment_plan == 'Balloon Payment' or prod.repayment_plan == 'Promotion Balloon Payment':
                    rate_per_month = prod.APR_borrower * (
                        1 - discount_rate) * 0.01 / 12
                    instalment_borrower = amount * rate_per_month
                    rate_per_month = prod.APR_lender * 0.01 / 12
                    instalment_lender = amount * rate_per_month

                bor_detail_info = OrderedDict()
                for name, value in request.POST.iteritems():
                    if len(name) != 0:
                        if str(name)[0].isupper() and value != '':
                            bor_detail_info[name] = value

                approval_records = {
                    1: {
                        'approval_amount': amount,
                        'APR': prod.APR_borrower * (1 - discount_rate),
                        'tenor': prod.repayment_period,
                    }
                }
                bor_detail_info['Approval Records'] = approval_records

                # if year 1 hasn't GPA
                if request.POST.get('No GPA') == 'on':
                    bor_detail_info['Overall GPA'] = 2

                if result['status'] == 'REJECT':
                    status = 'REJECTED'
                else:
                    status = 'AUTO APPROVED'
                new_bor = BorrowRequest(
                    amount=amount,
                    prod_id=prod_id,
                    usr_id=usr.id,
                    ref_num=ref_num,
                    repaid_month=0,
                    instalment_lender=instalment_lender,
                    instalment_borrower=instalment_borrower,
                    simplified_hkid=simplified_hkid,
                    detail_info=json.dumps(bor_detail_info),
                    discount_rate=discount_rate,
                    status=status,
                    create_timestamp=timezone.localtime(timezone.now()),
                    update_timestamp=timezone.localtime(timezone.now()))
                new_bor.save()

                # update aut
                inputs = {
                    'usr_id':
                    usr.id,
                    'description':
                    'Submitted "%s" application, apply amount $%s' %
                    (prod.name_en, request.POST.get('Applied Amount')),
                    'ref_id':
                    new_bor.id,
                    'model':
                    'BorrowRequest',
                    'by':
                    'Borrower: ' + usr.email,
                    'datetime':
                    timezone.localtime(timezone.now()),
                    'action':
                    'create',
                    'type':
                    'Application',
                    'status':
                    'UNREAD',
                }
                sup_fn.update_aut(inputs)

                inputs = {
                    'usr_id':
                    usr.id,
                    'description':
                    'Auto approved $%s, tenor %s, interest rate %s%s' %
                    (amount, prod.repayment_period, prod.APR_borrower *
                     (1 - discount_rate), '%'),
                    'ref_id':
                    new_bor.id,
                    'model':
                    'BorrowRequest',
                    'by':
                    'Borrower: ' + usr.email,
                    'datetime':
                    timezone.localtime(timezone.now()),
                    'details': {
                        'usr_ip': request.META.get('REMOTE_ADDR')
                    },
                    'action':
                    'create',
                    'type':
                    'Application',
                    'status':
                    'UNREAD',
                }
                sup_fn.update_aut(inputs)
                sup_fn.update_ptn(inputs)

                # sync to usr
                sync_list = [
                    'Home Phone No.', 'Surname', 'Given Name',
                    'Account Number', 'Mobile', 'Gender',
                    'Residential Address', 'Bank Code', 'Living Status',
                    'Living with', 'Date of Birth', 'HKID',
                    'Studying University', 'Subject'
                ]
                sync_dict = {}
                for name in sync_list:
                    try:
                        sync_dict[name] = bor_detail_info[name]
                    except KeyError:
                        continue
                sup_fn.sync_to_usr(usr_id=usr.id, dict=sync_dict)

                if result['status'] == 'REJECT':
                    return redirect('/ack_page/?action=apply_loan_rejected')
                return redirect('/product/upload_docs/?prod_id=' +
                                str(prod_id))
            # if form is not valid
            hashkey = CaptchaStore.generate_key()
            image_url = captcha_image_url(hashkey)

            usr_details = {}
            for k, v in request.POST.iteritems():
                usr_details[k] = v
        else:
            # Captcha
            form = ''
            hashkey = CaptchaStore.generate_key()
            image_url = captcha_image_url(hashkey)
            usr_details = sup_fn.sync_from_usr(usr.id)

        #if lang == 'en':
        content = {
            'lang':
            lang,
            'cate':
            'borrow_now',
            'title':
            prod.name_en + ' - Application Form',
            'form_action':
            '?prod_id=' + str(prod_id),
            'prod':
            prod,
            'usr_id':
            usr.id,
            'usr_details':
            usr_details,
            #'applied_amount_list': ['5000', '10000', '15000', '20000', '25000', '30000', '35000', '40000'],
            'applied_amount_list':
            OrderedDict((
                ('5000', FLOAT_DATA_FORMAT.format(5000)),
                ('10000', FLOAT_DATA_FORMAT.format(10000)),
                ('15000', FLOAT_DATA_FORMAT.format(15000)),
                ('20000', FLOAT_DATA_FORMAT.format(20000)),
                ('25000', FLOAT_DATA_FORMAT.format(25000)),
                ('30000', FLOAT_DATA_FORMAT.format(30000)),
                ('35000', FLOAT_DATA_FORMAT.format(35000)),
                ('40000', FLOAT_DATA_FORMAT.format(40000)),
            )),
            'loan_purpose_list':
            OrderedDict(
                (('Tuition', 'Tuition'), ('Investment',
                                          'Investment'), ('Travel', 'Travel'),
                 ('Debt payment', 'Debt payment'), ('Others', 'Others'))),
            'gender_list':
            OrderedDict((('Male', 'Male'), ('Female', 'Female'))),
            'living_status_list':
            OrderedDict(
                (('Public Housing', 'Public Housing'),
                 ('Owned by Family', 'Owned by Family'), ('Rent', 'Rent'),
                 ('Quarter', 'Quarter'), ('Student Hall of Residence',
                                          'Student Hall of Residence'))),
            'living_with_list':
            OrderedDict((('Parents', 'Parents'), ('Relatives', 'Relatives'),
                         ('Friends or Classmates',
                          'Friends or Classmates'), ('Others', 'Others'))),
            'university_list':
            OrderedDict(
                (('The University of Hong Kong',
                  'The University of Hong Kong'),
                 ('The Chinese University of Hong Kong',
                  'The Chinese University of Hong Kong'),
                 ('The Hong Kong University of Science and Technology',
                  'The Hong Kong University of Science and Technology'),
                 ('The Hong Kong Polytechnic University',
                  'The Hong Kong Polytechnic University'),
                 ('City University of Hong Kong',
                  'City University of Hong Kong'),
                 ('Hong Kong Baptist University',
                  'Hong Kong Baptist University'),
                 ('The Hong Kong Institute of Education',
                  'The Hong Kong Institute of Education'),
                 ('Lingnan University', 'Lingnan University'),
                 ('The Open University of Hong Kong',
                  'The Open University of Hong Kong'))),
            'study_year_list': ['Year 1', 'Year 2', 'Year 3', 'Year 4'],
            'subject_list':
            OrderedDict(
                (('Medical/Health', 'Medical/Health'), ('Law', 'Law'),
                 ('Accounting',
                  'Accounting'), ('Construction and Environment',
                                  'Construction and Environment'),
                 ('Engineering', 'Engineering'), ('Design', 'Design'),
                 ('Business/Finance/Economic', 'Business/Finance/Economic'),
                 ('Education and Language', 'Education and Language'),
                 ('Information Technology/Computing',
                  'Information Technology/Computing'), ('Social Sciences',
                                                        'Social Sciences'),
                 ('Hotel and Tourism', 'Hotel and Tourism'), ('Others',
                                                              'Others'))),
            'form':
            form,
            'hashkey':
            hashkey,
            'image_url':
            image_url,
        }

        # if prod is promotion, only allow to apply $10000
        if prod.repayment_plan == 'Promotion Balloon Payment':
            content['applied_amount_list'] = OrderedDict(
                (('10000', FLOAT_DATA_FORMAT.format(10000)), ))
        if lang == 'zh':
            additional_content = {
                #'cate': 'borrow_now',
                'title':
                prod.name_zh.encode("utf8") + ' - 申請表',
                #'form_action': '?prod_id='+str(prod_id),
                #'prod': prod,
                #'usr_id': usr.id,
                #'usr_details': usr_details,
                #'applied_amount_list': ['5000', '10000', '15000', '20000', '25000', '30000', '35000', '40000'],
                'loan_purpose_list':
                OrderedDict(
                    (('Tuition', '學費'), ('Investment', '投資'), ('Travel', '旅遊'),
                     ('Debt payment', '還款'), ('Others', '其他'))),
                'gender_list':
                OrderedDict((('Male', '男性'), ('Female', '女性'))),
                'living_status_list':
                OrderedDict(
                    (('Public Housing', '公共房屋'), ('Owned by Family', '私人住宅'),
                     ('Rent', '租住'), ('Quarter', '宿舍'),
                     ('Student Hall of Residence', '學生宿舍'))),
                'living_with_list':
                OrderedDict(
                    (('Parents', '父母'), ('Relatives', '親戚'),
                     ('Friends or Classmates', '朋友/同學'), ('Others', '其他'))),
                'university_list':
                OrderedDict(
                    (('The University of Hong Kong', '香港大學'),
                     ('The Chinese University of Hong Kong', '香港中文大學'),
                     ('The Hong Kong University of Science and Technology',
                      '香港科技大學'), ('The Hong Kong Polytechnic University',
                                  '香港理工大學'), ('City University of Hong Kong',
                                              '香港城市大學'),
                     ('Hong Kong Baptist University',
                      '香港浸會大學'), ('The Hong Kong Institute of Education',
                                  '香港教育大學'), ('Lingnan University', '嶺南大學'),
                     ('The Open University of Hong Kong', '香港公開大學'))),
                'study_year_list': ['Year 1', 'Year 2', 'Year 3', 'Year 4'],
                'subject_list':
                OrderedDict(
                    (('Medical/Health', '醫療/健康'), ('Law', '法律'),
                     ('Accounting', '會計'), ('Construction and Environment',
                                            '建築及環境'), ('Engineering', '工程'),
                     ('Design', '設計'), ('Business/Finance/Economic',
                                        '商業/財務/經濟'), ('Education and Language',
                                                      '教育及語言'),
                     ('Information Technology/Computing',
                      '資訊科技/電子計算'), ('Social Sciences', '社會科學'),
                     ('Hotel and Tourism', '酒店及旅遊'), ('Others', '其他'))),
                #'form': form,
                #'hashkey': hashkey,
                #'image_url': image_url,
            }
            content.update(additional_content)

        return render(request, 'peerloan/borrower/loan_application_form.html',
                      content)
    if action == 'upload_docs':
        prod_id = request.GET.get('prod_id')
        prod = Product.objects.get(id=prod_id)
        bor = BorrowRequest.objects.filter(
            usr_id=usr.id, prod_id=prod_id,
            status="AUTO APPROVED").latest('update_timestamp')

        # get repayment table
        inputs = {
            'date_type': 'month only',
            'start_balance': bor.amount,
            'rate_per_month': bor.getBorAPR(prod.APR_borrower) * 0.01 / 12,
            'instalment': bor.instalment_borrower,
            'repayment_plan': prod.repayment_plan,
            'repayment_period': prod.repayment_period,
        }

        repayment_table = sup_fn.generate_repayment_schedule(inputs)

        bank_code_list = {}
        f = open(
            '/home/ubuntu/project_peerloan/peerloan/peerloan_src/bank_code_list.csv',
            'r')
        for row in csv.DictReader(f):
            bank_code_list[str(
                row['Bank_Code']).zfill(3)] = row['Bank_Name_in_English']
        f.close()
        bank_code_list = OrderedDict(
            sorted(bank_code_list.items(), key=lambda kv: kv[1]))

        content = {
            'lang':
            lang,
            'cate':
            'borrow_now',
            'title':
            prod.name_en + ' - Upload Supporting Documents',
            'form_action':
            '/ack/',
            'prod':
            prod,
            'usr_details':
            sup_fn.sync_from_usr(usr.id),
            'bor':
            bor,
            'bor_amount':
            FLOAT_DATA_FORMAT.format(bor.amount),
            'APR':
            FLOAT_DATA_FORMAT.format(
                bor.getBorAPR(prod.APR_borrower if prod.fake_APR_borrower ==
                              None else prod.fake_APR_borrower)),
            'monthly_repayment_amount':
            FLOAT_DATA_FORMAT.format(bor.instalment_borrower),
            'repayment_table':
            repayment_table,
            'bank_code_list':
            bank_code_list,
        }
        if lang == 'zh':
            content['title'] = prod.name_zh.encode("utf8") + ' - 上載申請文件'
        return render(request, 'peerloan/borrower/loan_upload_docs_form.html',
                      content)
    if action == 'confirm_agreement':
        prod_id = request.GET.get('prod_id')
        prod = Product.objects.get(id=prod_id)
        bor = BorrowRequest.objects.filter(
            prod_id=prod_id, usr_id=usr.id,
            status='DOC UPLOADED').latest('update_timestamp')
        details = json.loads(bor.detail_info)

        if prod.repayment_plan == 'Promotion Balloon Payment':
            start_month = 4
        else:
            start_month = 1

        end_month = prod.repayment_period
        start_date = sup_fn.check_future_date_exists(timezone.localtime(
            timezone.now()),
                                                     months=start_month)
        end_date = sup_fn.check_future_date_exists(timezone.localtime(
            timezone.now()),
                                                   months=end_month)

        if prod.repayment_plan == 'Instalment':
            last_instalment_amount = round(bor.instalment_borrower, 2)
        elif prod.repayment_plan == 'Balloon Payment' or prod.repayment_plan == 'Promotion Balloon Payment':
            last_instalment_amount = round(
                bor.instalment_borrower + bor.amount, 2)

        info = {
            'loan_agreement_date':
            datetime.strftime(bor.create_timestamp, '%d/%m/%Y'),
            'loan_drawdown_date':
            datetime.strftime(timezone.localtime(timezone.now()), '%d/%m/%Y'),
            'lender':
            'P L Technology Limited',
            'lender_licence_no':
            '0741/2016',
            'address':
            'Unit 1306, Lucky Centre, 165-171 Wanchai Road, Wanchai',
            'borrower':
            '%s %s' % (details['Surname'], details['Given Name']),
            'HKID':
            details['HKID'],
            'residential_address':
            details['Residential Address'],
            'loan_principal_amount':
            FLOAT_DATA_FORMAT.format(bor.amount),
            'interest_rate':
            FLOAT_DATA_FORMAT.format(
                bor.getBorAPR(prod.APR_borrower if prod.fake_APR_borrower ==
                              None else prod.fake_APR_borrower)),
            'instalment_amount':
            FLOAT_DATA_FORMAT.format(bor.instalment_borrower),
            'due_date':
            str(timezone.localtime(timezone.now()).day) +
            sup_fn.date_postfix(timezone.localtime(timezone.now()).day) +
            ' day of each calendar',
            'first_instalment':
            start_date.strftime('%Y/%m/%d'),
            'first_instalment_amount':
            FLOAT_DATA_FORMAT.format(bor.instalment_borrower),
            'last_instalment':
            end_date.strftime('%Y/%m/%d'),
            'last_instalment_amount':
            FLOAT_DATA_FORMAT.format(last_instalment_amount),
            'bank_name':
            details['Bank Code'] + ' ' +
            sup_fn.bank_code_name_converter(details['Bank Code']),
            'account_number':
            details['Account Number'],
            'account_holder':
            '%s %s' % (details['Surname'], details['Given Name']),
            'mobile':
            details['Mobile'],
        }
        if lang == 'zh':
            info['due_date'] = '每月的第' + str(
                timezone.localtime(timezone.now()).day).encode("utf8") + '天'

        content = {
            'lang': lang,
            'cate': 'borrow_now',
            'title': 'Key Terms of Personal Loan Agreement',
            'form_action': '/ack/',
            'info': info,
            'bor_id': bor.id,
            'bor_ref_num': bor.ref_num
        }
        if lang == 'zh':
            content['title'] = '私人貸款協議之主要條款'

        error = request.GET.get('error')
        if lang == 'en':
            if error == 'invalid_OTP':
                content['error_msg'] = 'Please input a valid OTP'
            if error == 'OTP_not_matched':
                content[
                    'error_msg'] = 'The OTP doesn\'t match to our record, please receive a new OTP and try again'
            if error == 'OTP_expired':
                content[
                    'error_msg'] = 'The OTP is expired, please receive a new OTP first'
        elif lang == 'zh':
            if error == 'invalid_OTP':
                content['error_msg'] = '請輸入一個有效的OTP'
            if error == 'OTP_not_matched':
                content['error_msg'] = '你輸入的OTP與我們的記錄不符合,請重新操作'
            if error == 'OTP_expired':
                content['error_msg'] = '你的OTP已經逾期,請重新獲取OTP'

        return render(request, 'peerloan/borrower/loan_agreement_form.html',
                      content)
    if action == 'confirm_memorandum':
        prod_id = request.GET.get('prod_id')
        prod = Product.objects.get(id=prod_id)
        bor = BorrowRequest.objects.filter(
            prod_id=prod_id, usr_id=usr.id,
            status='FUND MATCHING COMPLETED').latest('update_timestamp')
        if request.method == 'POST':
            form = CaptchaForm(request.POST)
            if form.is_valid():
                draw_down_date = sup_fn.find_earliest_business_day(
                    date=timezone.localtime(timezone.now()), cut_off=16)
                details = json.loads(bor.detail_info)
                details['Confirm Memorandum Date'] = datetime.strftime(
                    draw_down_date, '%Y/%m/%d %H:%M:%S')
                details['Memorandum Captcha'] = str(
                    request.POST.get('captcha_1'))
                bor.detail_info = json.dumps(details)
                bor.status = 'MEMORANDUM CONFIRMED'
                bor.update_timestamp = timezone.localtime(timezone.now())
                bor.save()

                # update aut
                inputs = {
                    'usr_id':
                    usr.id,
                    'description':
                    'Confirmed memorandum with Captcha%s' %
                    (request.POST.get('captcha_1')),
                    'ref_id':
                    bor.id,
                    'model':
                    'BorrowRequest',
                    'by':
                    'Borrower: ' + usr.email,
                    'datetime':
                    timezone.localtime(timezone.now()),
                    'action':
                    'modify',
                    'type':
                    'Disburse',
                    'status':
                    'UNREAD',
                }
                sup_fn.update_aut(inputs)
                sup_fn.update_ptn(inputs)
                action = 'confirm_memorandum'

                return redirect('/ack_page/?action=' + action)

            hashkey = CaptchaStore.generate_key()
            image_url = captcha_image_url(hashkey)
        else:
            # Captcha
            form = ''
            hashkey = CaptchaStore.generate_key()
            image_url = captcha_image_url(hashkey)

        details = json.loads(bor.detail_info)

        draw_down_date = sup_fn.find_earliest_business_day(
            date=timezone.localtime(timezone.now()), cut_off=16)

        if prod.repayment_plan == 'Promotion Balloon Payment':
            start_month = 4
        else:
            start_month = 1

        end_month = prod.repayment_period
        start_date = sup_fn.check_future_date_exists(draw_down_date,
                                                     months=start_month)
        end_date = sup_fn.check_future_date_exists(draw_down_date,
                                                   months=end_month)

        if prod.repayment_plan == 'Instalment':
            last_instalment_amount = round(bor.instalment_borrower, 2)
        elif prod.repayment_plan == 'Balloon Payment' or prod.repayment_plan == 'Promotion Balloon Payment':
            last_instalment_amount = round(
                bor.instalment_borrower + bor.amount, 2)

        info = {
            'loan_agreement_date':
            datetime.strftime(bor.create_timestamp, '%d/%m/%Y'),
            'loan_drawdown_date':
            datetime.strftime(draw_down_date, '%d/%m/%Y'),
            'lender':
            'P L Technology Limited',
            'lender_licence_no':
            '0741/2016',
            'address':
            'Unit 1306, Lucky Centre, 165-171 Wanchai Road, Wanchai',
            'borrower':
            '%s %s' % (details['Surname'], details['Given Name']),
            'HKID':
            details['HKID'],
            'residential_address':
            details['Residential Address'],
            'loan_principal_amount':
            FLOAT_DATA_FORMAT.format(bor.amount),
            'interest_rate':
            FLOAT_DATA_FORMAT.format(
                bor.getBorAPR(prod.APR_borrower if prod.fake_APR_borrower ==
                              None else prod.fake_APR_borrower)),
            'instalment_amount':
            FLOAT_DATA_FORMAT.format(bor.instalment_borrower),
            'due_date':
            str(draw_down_date.day) + sup_fn.date_postfix(draw_down_date.day) +
            ' day of each calendar',
            'first_instalment':
            start_date.strftime('%Y/%m/%d'),
            'first_instalment_amount':
            FLOAT_DATA_FORMAT.format(bor.instalment_borrower),
            'last_instalment':
            end_date.strftime('%Y/%m/%d'),
            'last_instalment_amount':
            FLOAT_DATA_FORMAT.format(last_instalment_amount),
            'bank_name':
            details['Bank Code'] + ' ' +
            sup_fn.bank_code_name_converter(details['Bank Code']),
            'account_number':
            details['Account Number'],
            'account_holder':
            '%s %s' % (details['Surname'], details['Given Name']),
            'mobile':
            details['Mobile'],
        }
        if lang == 'zh':
            info['due_date'] = '每月的第' + str(
                draw_down_date.day).encode("utf8") + '天'

        content = {
            'lang': lang,
            'cate': 'borrow_now',
            'title': 'Memorandum of Agreement',
            'form_action': '?prod_id=' + str(prod_id),
            'info': info,
            'form': form,
            'hashkey': hashkey,
            'image_url': image_url,
        }
        if lang == 'zh':
            content['title'] = '協議備忘錄'
        return render(request, 'peerloan/borrower/loan_memorandum_form.html',
                      content)
    if action == 'invest':
        prod_id = request.GET.get('prod_id')
        prod = Product.objects.get(id=prod_id)
        acc = Account.objects.get(usr_id=usr.id)
        total_usable_amount = acc.balance
        try:
            inv = Investment.objects.get(usr_id=usr.id, prod_id=prod_id)
        except ObjectDoesNotExist:
            # set up new inv
            inv = {'total_amount': total_usable_amount, 'used_amount': 0}
            content = {
                'prod': prod,
                'total_usable_amount': total_usable_amount,
                'inv': inv,
                'sub_cate': prod_id,
                'used_percentage': 0,
                'lang': lang,
            }
            if lang == 'en':
                content[
                    'title'] = 'Setting Up Your Investment - ' + prod.name_en
                content[
                    'instruction'] = """The below investment settings define how you invest the money in this product. After 
				you filled up the below form, Peerloan will allocate your investment fund to the selected product automatically."""
            if lang == 'zh':
                content['title'] = '設置你的投資 - ' + prod.name_zh_hk
                content[
                    'instruction'] = """以下投資設置詳述你將如何投資該產品。在你完成以下表格之後,點點眾貸將會自動地分配你的投資資金到該產品。"""
        else:
            # change inv settings
            total_usable_amount += inv.usable_amount + inv.on_hold_amount

            try:
                used_percentage = round(
                    ((inv.on_hold_amount / prod.min_amount_per_loan) /
                     int(total_usable_amount / prod.min_amount_per_loan)) * 100
                    + 1, 1)
            except ZeroDivisionError:
                used_percentage = 0
            content = {
                'prod': prod,
                'total_usable_amount': total_usable_amount,
                'inv': inv,
                'used_percentage': used_percentage,
                'lang': lang,
            }
            if lang == 'en':
                content[
                    'title'] = 'Change Your Investment Setting - ' + prod.name_en
                content[
                    'instruction'] = """The below investment settings define how you invest the money in this product. After 
				you filled up the below form, Peerloan will allocate your investment fund to the selected product automatically."""
            if lang == 'zh':
                content['title'] = '更換你的投資設置 - ' + prod.name_zh_hk
                content[
                    'instruction'] = """以下投資設置詳述你將如何投資該產品。在你完成以下表格之後,點點眾貸將會自動地分配你的投資資金到該產品。"""
        return render(request, 'peerloan/lender/invest_form.html', content)
    if action == 'transfer':
        inv_list = Investment.objects.filter(usr_id=usr.id)
        rd_prod_list = []
        for inv in inv_list:
            prod = Product.objects.get(id=inv.prod_id)
            rd_prod_list.append({
                'prod_id': str(prod.id),
                'prod_name': str(prod.name_en),
                'usable_amount': str(inv.usable_amount)
            })
        content = {
            'prod_list': rd_prod_list,
        }
        if lang == 'en':
            content['title'] = 'Transfer Fund Between Products'
            content[
                'instruction'] = """Please specify the amount of fund you would like to switch from this portfolio to another portfolio. 
			The instruction will be executed immediately."""
        if lang == 'zh':
            content['title'] = '資金轉賬'
            content['instruction'] = """請說明你希望的轉賬金額及收賬的投資組合。該指示將會被立即執行。"""
        return render(request, 'peerloan/lender/transfer_form.html', content)
def portfolio(request):
    usr = sup_fn.get_user(request)
    lang = sup_fn.get_lang(request)

    # return schedule
    if 'active_investment' in request.META.get('PATH_INFO').split('/'):
        # active investment page
        prod_list = Product.objects.filter(status='ACTIVE')
        if lang == 'en':
            rd_prod_list = [['all', 'All Products']]
        elif lang == 'zh':
            rd_prod_list = [['all', '全部產品']]

        for prod in prod_list:
            if lang == 'en':
                rd_prod_list.append([prod.id, prod.name_en])
            elif lang == 'zh':
                rd_prod_list.append([prod.id, prod.name_zh.encode('utf8')])

        content = {
            'lang': lang,
            'cate': 'portfolio',
            'sub_cate': 'active_investment',
            'prod_list': rd_prod_list,
        }
        return render(request, 'peerloan/lender/active_inv.html', content)
    elif 'estimated_returning_schedule' in request.META.get('PATH_INFO').split(
            '/'):
        content = {
            'lang': lang,
            'prod_list': Product.objects.filter(status='ACTIVE')
        }
        return render(request,
                      'peerloan/lender/estimated_returning_schedule.html',
                      content)

    this_month = datetime.strftime(timezone.localtime(timezone.now()), '%m/%Y')
    search_month_list = []
    search_start_date = {'year': 2016, 'month': 06}
    for i in range(12):
        month = (search_start_date['month'] + i) % 12
        if month == 0:
            month = 12
        year = search_start_date['year'] + (search_start_date['month'] + i -
                                            1) / 12
        date = datetime.strptime(str(month) + '/' + str(year), '%m/%Y')
        search_month_list.append({
            'name': date.strftime('%B %Y'),
            'value': date.strftime('%m/%Y')
        })

    content = {
        'lang': lang,
        'cate': 'portfolio',
        'sub_cate': 'portfolio_summary',
        'title': 'Portfolio Summary',
        'this_month': this_month,
        'search_month_list': search_month_list,
        'today': datetime.strftime(timezone.localtime(timezone.now()),
                                   '%Y/%m/%d')
    }
    if lang == 'zh':
        content['title'] = '投資總覽'

    return render(request, 'peerloan/lender/portfolio_summary.html', content)