コード例 #1
0
    def get(self, request, format=None):
        prod_id = request.GET.get('prod_id')
        usr_list = User.objects.filter(type='L', status='ACTIVE')
        data_list = []
        for usr in usr_list:
            acc = Account.objects.get(usr_id=usr.id)
            inv_list = Investment.objects.filter(usr_id=usr.id)
            if prod_id != 'all':
                inv_list = [
                    inv for inv in inv_list if inv.prod_id == int(prod_id)
                ]
            loan_list = []
            for inv in inv_list:
                loans = Loan.objects.filter(inv_id=inv.id)
                loans = [
                    loan for loan in loan_list
                    if 'DISBURSED' in loan.status or 'PAYBACK' in loan.status
                ]
                for loan in loans:
                    loan_list.append(loan)
            details = json.loads(usr.detail_info)
            try:
                name = details['Individual']['Surname'] + ' ' + details[
                    'Individual']['Given Name']
            except KeyError:
                name = '--'
            allocated_amount = sum([
                inv.usable_amount + inv.on_hold_amount for inv in inv_list
            ]) + sum([loan.remain_principal for loan in loan_list])

            try:
                fund_matching_percentage = round(
                    (sum([inv.on_hold_amount for inv in inv_list]) +
                     sum([loan.remain_principal
                          for loan in loan_list])) / allocated_amount, 2)
            except ZeroDivisionError:
                fund_matching_percentage = 0
            try:
                delinquent_percentage = round(
                    sum([
                        loan.remain_principal
                        for loan in loan_list if 'OVERDUE' in loan.status
                    ]) / sum([loan.remain_principal for loan in loan_list]), 2)
            except ZeroDivisionError:
                delinquent_percentage = 0
            data_list.append({
                'account_no':
                sup_fn.try_KeyError(details, 'Lender No'),
                'usr_id':
                usr.id,
                'name':
                name,
                'allocated_amount':
                round(allocated_amount, 2),
                'account_balance':
                round(acc.balance + acc.on_hold_amt, 2),
                'fund_matching_percentage':
                str(fund_matching_percentage) + '%',
                'delinquent_percentage':
                str(delinquent_percentage) + '%',
                'ledger':
                '--',
            })
        content = {'data': data_list}
        return Response(content)
コード例 #2
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)
コード例 #3
0
    def get(self, request, format=None):
        data_src = request.GET.get('data_src')

        def try_KeyError(dict, key):
            try:
                return dict[key]
            except KeyError:
                return ''

        if data_src == 'deposit_money':
            uor_list = UserOperationRequest.objects.filter(
                type="Deposit Money")
            data_list = []
            for item in uor_list:
                details = json.loads(item.details)

                # check is pending task or not
                try:
                    ptn = PendingTaskNotification.objects.get(
                        ref_id=item.id, model='UserOperationRequest')
                except ObjectDoesNotExist:
                    ptn_status = 'READ'
                else:
                    ptn_status = ptn.status

                usr = User.objects.get(id=item.usr_id)
                usr_detail = json.loads(usr.detail_info)
                data_list.append({
                    'acc_no':
                    usr_detail['Lender No'],
                    'date':
                    datetime.strftime(
                        timezone.localtime(item.create_timestamp), "%d/%m/%Y"),
                    'amount':
                    details['transferred_amount'],
                    'bank_in_slip':
                    details['file'],
                    'bank_in_date':
                    try_KeyError(details, 'bank_in_date'),
                    'bank_in_time':
                    try_KeyError(details, 'bank_in_time'),
                    'ref_num':
                    details['ref_num'],
                    'uor_id':
                    item.id,
                    'status':
                    item.status,
                    'ptn_status':
                    ptn_status,
                })
            #serialized_data_list = DepositSerializer(data_list, many=True)
            serialized_data_list = data_list
        if data_src == 'withdraw_money':
            uor_list = UserOperationRequest.objects.filter(
                type="Withdraw Money")
            data_list = []
            for item in uor_list:
                acc = Account.objects.get(usr_id=item.usr_id)
                details = json.loads(item.details)

                # check is pending task or not
                try:
                    ptn = PendingTaskNotification.objects.get(
                        ref_id=item.id, model='UserOperationRequest')
                except ObjectDoesNotExist:
                    ptn_status = 'READ'
                else:
                    ptn_status = ptn.status

                usr = User.objects.get(id=item.usr_id)
                usr_detail = json.loads(usr.detail_info)
                data_list.append({
                    'acc_no':
                    usr_detail['Lender No'],
                    'date':
                    datetime.strftime(
                        timezone.localtime(item.create_timestamp), "%d/%m/%Y"),
                    'amount':
                    details['withdraw_amt'],
                    'acc_balance':
                    round(acc.balance + acc.on_hold_amt, 2),
                    'bank':
                    try_KeyError(details, 'bank_acc_proof'),
                    'bank_acc_no':
                    try_KeyError(details, 'bank_acc_no'),
                    'chq_no':
                    try_KeyError(details, 'chq_no'),
                    'bank_in_date':
                    try_KeyError(details, 'bank_in_date'),
                    'bank_in_time':
                    try_KeyError(details, 'bank_in_time'),
                    'ref_num':
                    details['ref_num'],
                    'bank_in_slip':
                    '/upload_file/?uor_id=' + str(item.id),
                    'confirm_date':
                    try_KeyError(details, 'confirm_date'),
                    'uor_id':
                    item.id,
                    'status':
                    item.status,
                    'ptn_status':
                    ptn_status,
                })
            #serialized_data_list = WithdrawSerializer(data_list, many=True)
            serialized_data_list = data_list
        if data_src == 'apply_to_be_investor':
            status = request.GET.get('status')
            uor_list = UserOperationRequest.objects.filter(
                type="Apply To Be Investor")

            if status != 'all':
                uor_list = [uor for uor in uor_list if status in uor.status]
            data_list = []
            for uor in uor_list:
                details = json.loads(uor.details)
                try:
                    name = details['Corporate']['Company Name']
                except KeyError:
                    name = details['Individual']['Surname'] + ' ' + details[
                        'Individual']['Given Name']

                # check is pending task or not
                try:
                    ptn = PendingTaskNotification.objects.get(
                        ref_id=uor.id, model='UserOperationRequest')
                except ObjectDoesNotExist:
                    ptn_status = 'READ'
                else:
                    ptn_status = ptn.status

                data_list.append({
                    'application_no':
                    sup_fn.try_KeyError(details['Individual'],
                                        'Application No'),
                    'name':
                    name,
                    'last_updated_time':
                    datetime.strftime(timezone.localtime(uor.create_timestamp),
                                      '%Y/%m/%d %H:%M'),
                    'last_updated_by':
                    '--',
                    'state':
                    uor.status,
                    'source':
                    details['Individual']['Source of Fund'],
                    'uor_id':
                    uor.id,
                    'hkid':
                    details['Individual']['HKID'],
                    'mobile_no':
                    details['Individual']['Mobile'],
                    'ptn_status':
                    ptn_status,
                })
            #serialized_data_list = ApplyInvestorSerializer(data_list, many=True)
            serialized_data_list = data_list
        if data_src == 'repayment':
            bor_ref_num = request.GET.get('bor_ref_num')
            bor = BorrowRequest.objects.get(ref_num=bor_ref_num)
            uor_list = UserOperationRequest.objects.filter(type='Repayment',
                                                           usr_id=bor.usr_id)
            data_list = []
            for uor in uor_list:
                details = json.loads(uor.details)

                if int(details['bor_id']) != bor.id:
                    continue
                row = {
                    'method': details['Deposit Method'],
                    'type': details['Repayment Type'],
                    'deposit_date': details['Deposit Date'],
                    'amount': details['Deposit Amount'],
                    'uploaded_doc': details['fname'],
                    'submit_date': uor.create_timestamp.strftime('%Y/%m/%d'),
                    'status': uor.status,
                    'uor_id': uor.id
                }
                data_list.append(row)
            serialized_data_list = data_list

        content = {'data': serialized_data_list}
        return Response(content)
コード例 #4
0
    def get(self, request, format=None):
        # check XSS
        if sup_fn.checkHTMLtags([v for k, v in request.GET.iteritems()]):
            return HttpResponse('Invalid input.')

        data_src = request.GET.get('data_src')
        prod_id = request.GET.get('prod_id')
        status = request.GET.get('status')
        cate = request.GET.get('cate')

        bor_list = BorrowRequest.objects.all()

        if data_src == 'fund_matching_bor':
            bor_list = [
                bor for bor in bor_list if bor.status in
                ['VALIDATED', 'FUND MATCHING', 'FUND MATCHING COMPLETED']
            ]
            if prod_id != 'all':
                bor_list = [
                    bor for bor in bor_list if int(bor.prod_id) == int(prod_id)
                ]
            data_list = []
            for bor in bor_list:
                details = json.loads(bor.detail_info)
                prod = Product.objects.get(id=bor.prod_id)
                loan_list = Loan.objects.filter(bor_id=bor.id)
                matched_percentage = float(
                    sum([loan.initial_amount
                         for loan in loan_list])) / float(bor.amount)
                data_list.append({
                    'loan_no':
                    bor.ref_num,
                    'amount_to_collect':
                    bor.amount,
                    'matched_percentage':
                    str(round(matched_percentage * 100, 2)) + '%',
                    'prod_name':
                    prod.name_en,
                    'application_date':
                    datetime.strftime(timezone.localtime(bor.create_timestamp),
                                      '%Y/%m/%d %H:%M'),
                    'agreement_date':
                    details['Confirm Loan Agreement Date'],
                    'no_of_investors':
                    len(loan_list),
                })
            serialized_data_list = FundMatchBorSerializer(data_list, many=True)
            content = {'data': serialized_data_list.data}
            return Response(content)
        if cate == 'application':
            apply_state_list = [
                'AUTO APPROVED', 'DOC UPLOADED', 'AGREEMENT CONFIRMED',
                'PENDING DOC/IV', 'VALIDATED', 'CANCELLED', 'REJECTED'
            ]
            bor_list = [
                bor for bor in bor_list if bor.status in apply_state_list
            ]
        elif cate == 'disbursement':
            disburse_state_list = [
                'FUND MATCHING', 'FUND MATCHING COMPLETED',
                'MEMORANDUM CONFIRMED'
            ]
            bor_list = [
                bor for bor in bor_list if bor.status in disburse_state_list
            ]

        if prod_id != 'all':
            bor_list = [
                bor for bor in bor_list if int(bor.prod_id) == int(prod_id)
            ]
        if status != 'all':
            bor_list = [bor for bor in bor_list if status in bor.status]

        data_list = []
        for bor in bor_list:
            details = json.loads(bor.detail_info)
            name = details['Surname'] + ' ' + details['Given Name']

            # check is pending task or not
            try:
                ptn = PendingTaskNotification.objects.get(
                    ref_id=bor.id, model='BorrowRequest')
            except ObjectDoesNotExist:
                ptn_status = 'READ'
            else:
                ptn_status = ptn.status

            data_list.append({
                'application_no':
                bor.ref_num,
                'name':
                name,
                'application_time':
                datetime.strftime(timezone.localtime(bor.create_timestamp),
                                  '%Y/%m/%d %H:%M'),
                'amount':
                bor.amount,
                'prod_type':
                Product.objects.get(id=bor.prod_id).name_en,
                'follow_by':
                '--',
                'confirmed_identity':
                'Y' if sup_fn.try_KeyError(details, 'Confirmed Identity')
                == 'Y' else 'N',
                'last_updated_time':
                datetime.strftime(timezone.localtime(bor.update_timestamp),
                                  '%Y/%m/%d %H:%M'),
                'last_updated_by':
                '--',
                'disbursement_method':
                sup_fn.try_KeyError(details, 'Disbursement Method'),
                'state':
                bor.status,
                'bor_id':
                bor.id,
                'hkid':
                details['HKID'],
                'mobile_no':
                details['Mobile'],
                'ptn_status':
                ptn_status
            })
        #serialized_data_list = AdminApplicationSerializer(data_list, many=True)
        content = {'data': data_list}
        return Response(content)
コード例 #5
0
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)
コード例 #6
0
def update_pay_los_loan(inputs):
    """
	inputs:
	los
	repayment_method
	payment_status: '(Pending confirm)' or ''
	"""
    los = inputs['los']
    repayment_method = inputs['repayment_method']
    payment_status = inputs['payment_status']

    los.status = 'PAID'
    los.received_amount = los.instalment
    los.paid_interest = los.interest
    los.paid_principal = los.principal
    los.paid_interest_l = los.interest_l
    los.paid_principal_l = los.principal_l
    los.repayment_method = repayment_method
    los.repayment_type = 'Instalment'
    los.repayment_date = timezone.localtime(timezone.now())
    los.save()

    # update bor
    bor = BorrowRequest.objects.get(id=los.bor_id)
    prev_status = bor.status
    prod = Product.objects.get(id=bor.prod_id)
    bor.repaid_month += 1
    if bor.repaid_month == prod.repayment_period:
        bor.status = 'PAYBACK COMPLETED'
    else:
        bor.status = 'PAYBACK ' + str(bor.repaid_month)
    #print bor.status
    bor.save()

    # update aut
    inputs = {
        'usr_id': bor.usr_id,
        'description': 'State "%s changed to "%s"' % (prev_status, bor.status),
        'ref_id': bor.id,
        'model': 'BorrowRequest',
        'by': 'System',
        'datetime': timezone.localtime(timezone.now()),
    }
    sup_fn.update_aut(inputs)

    # update ledger
    inputs = {
        'bor_id':
        bor.id,
        'description':
        payment_status +
        ' Pay auto-pay %s%s repayment by Borrower: Amount $%.2f' %
        (bor.repaid_month, sup_fn.date_postfix(
            bor.repaid_month), los.instalment),
        'reference':
        bor.ref_num,
        'status':
        'Pending Confirm' if payment_status == '(Pending confirm)' else None,
        'debit':
        round(los.instalment, 2),
        'credit':
        0,
        'datetime':
        timezone.localtime(timezone.now())
    }
    sup_fn.update_ledger(inputs)

    # update loan list

    rate_per_month_b = bor.getBorAPR(prod.APR_borrower) * 0.01 / 12
    #rate_per_month_l = prod.APR_lender * 0.01 / 12

    loan_list = Loan.objects.filter(bor_id=bor.id)
    for loan in loan_list:
        return_interest_b = loan.remain_principal * rate_per_month_b
        #return_interest_l = loan.remain_principal_lender * rate_per_month_l

        ratio = (prod.APR_lender / bor.getBorAPR(prod.APR_borrower))
        return_interest_l = return_interest_b * ratio
        return_principal_b = loan.instalment_borrower - return_interest_b
        #return_principal_l = loan.instalment_lender - return_interest_l
        return_principal_l = return_principal_b

        if (prod.repayment_plan == 'Balloon Payment'
                or prod.repayment_plan == 'Promotion Balloon Payment'
            ) and bor.repaid_month != prod.repayment_period:
            return_principal_b = 0
            return_principal_l = 0
        elif (prod.repayment_plan == 'Balloon Payment'
              or prod.repayment_plan == 'Promotion Balloon Payment'
              ) and bor.repaid_month == prod.repayment_period:
            return_principal_b = loan.remain_principal
            return_principal_l = loan.remain_principal_lender

        if prod.repayment_plan == 'Promotion Ballon Payment' and bor.repaid_month < 4:
            return_interest_b = 0
            #return_interest_l = 0

        loan.remain_principal -= return_principal_b
        loan.remain_principal_lender -= return_principal_l
        loan.remain_interest_borrower -= return_interest_b
        loan.remain_interest_lender -= return_interest_l
        loan.status = 'PAYBACK ' + str(bor.repaid_month)
        loan.save()
        #print return_principal_b,loan.remain_principal

        # update ledger
        inv = Investment.objects.get(id=loan.inv_id)
        inv_usr = User.objects.get(id=inv.usr_id)
        lender_no = sup_fn.try_KeyError(json.loads(inv_usr.detail_info),
                                        'Lender No')
        inputs = {
            'usr_id':
            inv.usr_id,
            'description':
            payment_status +
            ' Receive auto-pay %s%s repayment by Lender <a href="/pl_admin/account/ledger/?usr_id=%s" target="_blank">%s</a>: Amount $%.2f'
            % (str(bor.repaid_month), sup_fn.date_postfix(bor.repaid_month),
               inv_usr.id, lender_no, return_principal_l + return_interest_l),
            'reference':
            bor.ref_num,
            'status':
            'Pending Confirm'
            if payment_status == '(Pending confirm)' else None,
            'debit':
            0,
            #'credit': round(loan.instalment_lender,2),
            'credit':
            round(return_principal_l + return_interest_l, 2),
            'datetime':
            timezone.localtime(timezone.now())
        }

        sup_fn.update_ledger(inputs)

    # update pl ledger
    pl_interest = los.interest - los.interest_l
    inputs = {
        'usr_id':
        0,
        'description':
        payment_status +
        ' Receive auto-pay %s%s repayment by P L Account: Amount $%.2f' %
        (str(bor.repaid_month), sup_fn.date_postfix(
            bor.repaid_month), pl_interest),
        'reference':
        bor.ref_num,
        'status':
        'Pending Confirm' if payment_status == '(Pending confirm)' else None,
        'debit':
        0,
        #'credit': round(bor.instalment_borrower - bor.instalment_lender,2),
        'credit':
        round(pl_interest, 2),
        'datetime':
        timezone.localtime(timezone.now())
    }
    sup_fn.update_ledger(inputs)
コード例 #7
0
ファイル: admin.py プロジェクト: Calvin66der/project_peerloan
def application(request):
    if request.session['handling_side'] == 'B':

        # view details
        if 'detail' in request.META.get('PATH_INFO').split('/'):
            bor_ref_num = request.GET.get('bor_ref_num')
            try:
                bor = BorrowRequest.objects.get(ref_num=bor_ref_num)
            except:
                HttpResponse('Loan application doesn\'t exist.')
            usr = User.objects.get(id=bor.usr_id)
            bor_detail = json.loads(bor.detail_info)

            borrower_name = bor_detail['Surname'] + ' ' + bor_detail[
                'Given Name']
            date_of_birth = pytz.timezone('Asia/Hong_Kong').localize(
                datetime.strptime(bor_detail['Date of Birth'], '%Y-%m-%d'))
            borrower_age = int(
                (timezone.localtime(timezone.now()) - date_of_birth).days /
                float(365))

            prod = Product.objects.get(id=bor.prod_id)

            # check re-sign agreement required or not
            re_sign_agreement_required = False
            if bor.status == 'AGREEMENT CONFIRMED' or bor.status == 'PENDING DOC/IV':
                details = json.loads(bor.detail_info)
                agreement_info = details['Agreement Info']
                for k, v in agreement_info.iteritems():
                    if k == 'Amount':
                        if v != bor.amount:
                            re_sign_agreement_required = True
                    else:
                        if v != details[k]:
                            re_sign_agreement_required = True

            preface = {
                'application_amount':
                sup_fn.try_KeyError(bor_detail, 'Applied Amount'),
                'application_tenor':
                prod.repayment_period,
                'application_product':
                prod.name_en,
                'approve_loan_amount':
                bor.amount,
                'annual_interest_rate':
                prod.APR_borrower * (1 - bor.discount_rate),
                'name':
                borrower_name,
                'age':
                borrower_age,
                'loan_purpose':
                sup_fn.try_KeyError(bor_detail, 'Loan Purpose'),
                'loan_purpose_list':
                ['Tuition', 'Investment', 'Travel', 'Debt payment', 'Others'],
                'subject':
                sup_fn.try_KeyError(bor_detail, 'Subject'),
                'school':
                sup_fn.try_KeyError(bor_detail, 'Studying University'),
                'application_state':
                bor.status,
                'approval_records':
                sup_fn.try_KeyError(bor_detail, 'Approval Records'),
                'addit_condit_decla':
                sup_fn.try_KeyError(bor_detail,
                                    'Additional Condition Declaration'),
            }

            memos = AdminMemo.objects.filter(model="BorrowRequest",
                                             identifier=bor_ref_num)

            summary = {
                'disbursement':
                sup_fn.try_KeyError(bor_detail, 'Disbursement Method'),
                'identity_verification':
                bor.verify_identity,
                'identity_verification_list': ['Upload Photo', 'Face To Face'],
                'confirmed_identity':
                sup_fn.try_KeyError(bor_detail, 'Confirmed Identity'),
                'confirmed_identity_list': ['N', 'Y'],
                'disbursement_method':
                sup_fn.try_KeyError(bor_detail, 'Disbursement Method'),
                'disbursement_method_list': ['Cheque', 'Transfer'],
                'bank_code':
                sup_fn.try_KeyError(bor_detail, 'Bank Code').zfill(3),
                'bank_account_no':
                sup_fn.try_KeyError(bor_detail, 'Account Number'),
                'memos':
                memos,
            }

            information = {
                'surname':
                sup_fn.try_KeyError(bor_detail, 'Surname'),
                'given_name':
                sup_fn.try_KeyError(bor_detail, 'Given Name'),
                #'name': borrower_name,
                'date_of_birth':
                sup_fn.try_KeyError(bor_detail, 'Date of Birth'),
                'email':
                usr.email,
                'HKID':
                sup_fn.try_KeyError(bor_detail, 'HKID'),
                'gender':
                sup_fn.try_KeyError(bor_detail, 'Gender'),
                'gender_list': ['Male', 'Female'],
                'mobile':
                sup_fn.try_KeyError(bor_detail, 'Mobile'),
                'home_tel':
                sup_fn.try_KeyError(bor_detail, 'Home Phone No.'),
                'home_address':
                sup_fn.try_KeyError(bor_detail, 'Residential Address'),
                'home_status':
                sup_fn.try_KeyError(bor_detail, 'Living Status'),
                'home_status_list': [
                    'Public Housing', 'Owned by Family', 'Rent', 'Quarter',
                    'Student Hall of Residence'
                ],
                'living_with':
                sup_fn.try_KeyError(bor_detail, 'Living with'),
                'living_with_list':
                ['Parents', 'Relatives', 'Friends or Classmates', 'Others'],
                'school':
                sup_fn.try_KeyError(bor_detail, 'Studying University'),
                'subject':
                sup_fn.try_KeyError(bor_detail, 'Subject'),
                'subject_list': [
                    'Medical/Health', 'Law', 'Accounting',
                    'Construction and Environment', 'Engineering', 'Design',
                    'Business/Finance/Economic', 'Education and Language',
                    'Information Technology/Computing', 'Social Sciences',
                    'Hotel and Tourism', 'Others'
                ],
                'GPA':
                sup_fn.try_KeyError(bor_detail, 'Overall GPA'),
                'year_of_study':
                sup_fn.try_KeyError(bor_detail, 'Currently Studying'),
                'year_of_study_list': ['Year 1', 'Year 2', 'Year 3', 'Year 4'],
                'facebook':
                '--',
                'website':
                '--',
            }

            #bor.usr_id = '*****@*****.**'
            fs = classes.FriendlyScore()
            fs.getToken()
            code, main_score_detail = fs.get(endpoint='users/partner-id/' +
                                             str(bor.usr_id) + '/show')
            code, network_score_detail = fs.get(endpoint='users/partner-id/' +
                                                str(bor.usr_id) +
                                                '/show/social-network-data')
            code, ip_address_detail = fs.get(endpoint='users/partner-id/' +
                                             str(bor.usr_id) +
                                             '/show/ip-address-data')
            social_score = {
                'main_score_detail':
                main_score_detail,
                'network_score_detail':
                network_score_detail,
                'ip_address_detail':
                ip_address_detail,
                'friendlyscore_href':
                'https://friendlyscore.com/company/user/application/user/show/'
                + sup_fn.try_KeyError(main_score_detail, 'id')
            }

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

            check_list = OrderedDict()

            if len(bod_list) != 0:
                check_list[1] = {
                    'fields': {
                        'Surname':
                        sup_fn.try_KeyError(bor_detail, 'Surname'),
                        'Given Name':
                        sup_fn.try_KeyError(bor_detail, 'Given Name'),
                        'HKID':
                        sup_fn.try_KeyError(bor_detail, 'HKID'),
                        'Date of Birth':
                        sup_fn.try_KeyError(bor_detail, 'Date of Birth'),
                    },
                    'rowspan':
                    4,
                    'doc':
                    'HKID',
                    'fname':
                    BorrowRequestDocument.objects.get(bor_id=bor.id,
                                                      type='HKID').detail,
                    'confirm':
                    BorrowRequestDocument.objects.get(bor_id=bor.id,
                                                      type='HKID').confirm,
                }
                check_list[2] = {
                    'fields': {
                        'Studying University':
                        sup_fn.try_KeyError(bor_detail, 'Studying University'),
                        'Subject':
                        sup_fn.try_KeyError(bor_detail, 'Subject'),
                    },
                    'rowspan':
                    2,
                    'doc':
                    'Student Card',
                    'fname':
                    BorrowRequestDocument.objects.get(
                        bor_id=bor.id, type='Student Card').detail,
                    'confirm':
                    BorrowRequestDocument.objects.get(
                        bor_id=bor.id, type='Student Card').confirm,
                }
                check_list[3] = {
                    'fields': {
                        'Overall GPA':
                        sup_fn.try_KeyError(bor_detail, 'Overall GPA'),
                    },
                    'rowspan':
                    1,
                    'doc':
                    'GPA',
                    'fname':
                    BorrowRequestDocument.objects.get(bor_id=bor.id,
                                                      type='GPA').detail,
                    'confirm':
                    BorrowRequestDocument.objects.get(bor_id=bor.id,
                                                      type='GPA').confirm,
                }
                check_list[4] = {
                    'fields': {
                        'Residential Address':
                        sup_fn.try_KeyError(bor_detail, 'Residential Address'),
                        'Living Status':
                        sup_fn.try_KeyError(bor_detail, 'Living Status'),
                    },
                    'rowspan':
                    2,
                    'doc':
                    'Address Proof',
                    'fname':
                    BorrowRequestDocument.objects.get(
                        bor_id=bor.id, type='Address Proof').detail,
                    'confirm':
                    BorrowRequestDocument.objects.get(
                        bor_id=bor.id, type='Address Proof').confirm,
                }
                check_list[5] = {
                    'fields': {
                        'Account Number':
                        sup_fn.try_KeyError(bor_detail, 'Account Number'),
                        'Bank Code':
                        sup_fn.try_KeyError(bor_detail, 'Bank Code'),
                    },
                    'rowspan':
                    2,
                    'doc':
                    'Bank Account Proof',
                    'fname':
                    BorrowRequestDocument.objects.get(
                        bor_id=bor.id, type='Bank Account Proof').detail,
                    'confirm':
                    BorrowRequestDocument.objects.get(
                        bor_id=bor.id, type='Bank Account Proof').confirm,
                }

            status_list = [
                'PENDING DOC/IV', 'VALIDATED', 'REJECTED', 'CANCELLED'
            ]

            # print acknowledgement href link
            reject_print_status_list = [
                'AUTO APPROVED', 'DOC UPLOADED', 'CANCELLED'
            ]
            if bor.status not in reject_print_status_list:
                print_loan_agreement = '/generate_pdf_file/?bor_id=%s&doc_type=Loan Agreement' % (
                    bor.id)
            else:
                print_loan_agreement = 'about:blank'

            content = {
                'cate':
                'application',
                'title':
                'Application Information - ' + bor_ref_num,
                'usr_id':
                usr.id,
                'bor_ref_num':
                bor_ref_num,
                'bor_id':
                bor.id,
                'model':
                'BorrowRequest',
                'preface':
                preface,
                'status_list':
                status_list,
                'summary':
                summary,
                'information':
                information,
                'social_score':
                social_score,
                'bod_list':
                bod_list,
                'check_list':
                check_list,
                're_sign_agreement_required':
                re_sign_agreement_required,
                'require_tick_all_checklist':
                request.GET.get('require_tick_all_checklist'),
                'print_loan_agreement':
                print_loan_agreement,
            }
            return render(
                request,
                'peerloan/admin/borrower/loan_application_detail.html',
                content)
        # view table
        prod_list = Product.objects.all()
        status_list = [
            'AUTO APPROVED', 'DOC UPLOADED', 'AGREEMENT CONFIRMED',
            'PENDING DOC/IV', 'VALIDATED', 'CANCELLED', 'REJECTED'
        ]

        content = {
            'cate': 'application',
            'sub_cate': '',
            'title': 'Borrower Loan Application',
            'prod_list': prod_list,
            'status_list': status_list,
        }
        if 'all_application' in request.META.get('PATH_INFO').split('/'):
            content['sub_cate'] = 'all_application'
            content['title'] = 'All Application'
            status_list = [
                'AUTO APPROVED', 'DOC UPLOADED', 'AGREEMENT CONFIRMED',
                'PENDING DOC/IV', 'VALIDATED', 'CANCELLED', 'REJECTED',
                'FUND MATCHING', 'FUND MATCHING COMPLETED', 'DISBURSED',
                'PAYBACK', 'PAYBACK OVERDUE', 'PAYBACK COMPLETED'
            ]
            content['status_list'] = status_list
            return render(request,
                          'peerloan/admin/borrower/all_application.html',
                          content)
        return render(request, 'peerloan/admin/borrower/application.html',
                      content)
    if request.session['handling_side'] == 'L':
        # view details
        if 'detail' in request.META.get('PATH_INFO').split('/'):

            uor_id = request.GET.get('uor_id')
            uor = UserOperationRequest.objects.get(id=uor_id)
            usr = User.objects.get(id=uor.usr_id)
            uor_details = json.loads(uor.details)
            try:
                uor_details['Corporate']
            except KeyError:
                uor_details['Corporate'] = {}
                # is individual
                account_type = 'Individual'
                name = uor_details['Individual'][
                    'Surname'] + ' ' + uor_details['Individual']['Given Name']
                age = int((timezone.localtime(timezone.now()) -
                           pytz.timezone('Asia/Hong_Kong').localize(
                               datetime.strptime(
                                   uor_details['Individual']['Date of Birth'],
                                   '%Y-%m-%d'))).days / float(365))
                occupation = uor_details['Individual']['Occupation']
            else:
                # is corporate
                account_type = 'Corporate'
                name = uor_details['Corporate']['Company Name']
                age = int((timezone.localtime(timezone.now()) -
                           pytz.timezone('Asia/Hong_Kong').localize(
                               datetime.strptime(
                                   uor_details['Corporate']['Established at'],
                                   '%Y-%m-%d'))).days / float(365))
                occupation = uor_details['Corporate']['Industry']
            preface = {
                'source_of_fund':
                uor_details['Individual']['Source of Fund'],
                'source_of_fund_list':
                ['Salary', 'Business', 'Investment', 'Others'],
                'other_source_of_fund':
                sup_fn.try_KeyError(uor_details['Individual'],
                                    'Other Source of Fund'),
                'account_type':
                account_type,
                'account_type_list': ['Individual', 'Corporate'],
                'name':
                name,
                'age':
                age,
                'occupation':
                occupation,
                'customer_declaration':
                uor_details['Individual']['Customer Declaration'],
                'customer_declaration_list': ['1', '2', '3', '4'],
                'application_state':
                uor.status,
            }

            summary = {}

            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()
            information = {
                'company_name':
                sup_fn.try_KeyError(uor_details['Corporate'], 'Company Name'),
                'established_at':
                sup_fn.try_KeyError(uor_details['Corporate'],
                                    'Established at'),
                'CR_no':
                sup_fn.try_KeyError(uor_details['Corporate'], 'CR NO.'),
                'country':
                sup_fn.try_KeyError(uor_details['Corporate'], 'Country'),
                'country_list':
                country_list,
                'office_address':
                sup_fn.try_KeyError(uor_details['Corporate'],
                                    'Office Address'),
                'office_tel':
                sup_fn.try_KeyError(uor_details['Corporate'], 'Office Tel'),
                'surname':
                sup_fn.try_KeyError(uor_details['Individual'], 'Surname'),
                'given_name':
                sup_fn.try_KeyError(uor_details['Individual'], 'Given Name'),
                'date_of_birth':
                sup_fn.try_KeyError(uor_details['Individual'],
                                    'Date of Birth'),
                'email':
                usr.email,
                'id_passport':
                sup_fn.try_KeyError(uor_details['Individual'], 'HKID'),
                'gender':
                sup_fn.try_KeyError(uor_details['Individual'], 'Gender'),
                'gender_list': ['Male', 'Female'],
                'occupation':
                sup_fn.try_KeyError(uor_details['Individual'], 'Occupation'),
                'nationality':
                sup_fn.try_KeyError(uor_details['Individual'], 'Nationality'),
                'nationality_list':
                nationality_list,
                'mobile':
                sup_fn.try_KeyError(uor_details['Individual'], 'Mobile'),
                'home_tel':
                sup_fn.try_KeyError(uor_details['Individual'],
                                    'Home Phone No.'),
                'home_address':
                sup_fn.try_KeyError(uor_details['Individual'],
                                    'Residential Address'),
                'education_level':
                sup_fn.try_KeyError(uor_details['Individual'],
                                    'Education Level'),
                'annual_income':
                sup_fn.try_KeyError(uor_details['Individual'],
                                    'Annual Income'),
                'type_of_employment':
                sup_fn.try_KeyError(uor_details['Individual'],
                                    'Type of Employment'),
                'type_of_employment_list': [
                    'Full Time Employed', 'Part Time Employed',
                    'Self-Employed', 'Unemployed', 'Housewife', 'Retired'
                ],
                'company_name':
                sup_fn.try_KeyError(uor_details['Individual'], 'Company Name'),
                'office_address':
                sup_fn.try_KeyError(uor_details['Individual'],
                                    'Office Address'),
                'office_tel':
                sup_fn.try_KeyError(uor_details['Individual'], 'Office Tel'),
                'source_of_fund':
                sup_fn.try_KeyError(uor_details['Individual'],
                                    'Source of Fund'),
                'other_source_of_fund':
                sup_fn.try_KeyError(uor_details['Individual'],
                                    'Other Source of Fund'),
                'memos':
                AdminMemo.objects.filter(model="UserOperationRequest",
                                         identifier=uor.id)
            }

            try:
                lender_usr = User.objects.get(email=usr.email, type='L')
            except ObjectDoesNotExist:
                setting = {}
            else:
                setting = {}
                uri_list = UserInformation.objects.filter(info_type='Settings')
                notification = json.loads(lender_usr.notification)
                for uri in uri_list:
                    uri.details = json.loads(uri.details,
                                             object_pairs_hook=OrderedDict)
                    setting[uri.section] = OrderedDict()
                    for k, v in uri.details.iteritems():
                        setting[uri.section][k] = notification[k]

            check_list = OrderedDict()

            if len(uor_details['File Uploaded']) != 0:
                file_details = uor_details['File Uploaded']
                try:
                    confirm_file_details = uor_details['Confirm File Uploaded']
                except:
                    confirm_file_details = {}
                check_list[1] = {
                    'fields': {
                        'Surname':
                        sup_fn.try_KeyError(uor_details['Individual'],
                                            'Surname'),
                        'Given Name':
                        sup_fn.try_KeyError(uor_details['Individual'],
                                            'Given Name'),
                        'HKID':
                        sup_fn.try_KeyError(uor_details['Individual'], 'HKID'),
                        'Date of Birth':
                        sup_fn.try_KeyError(uor_details['Individual'],
                                            'Date of Birth'),
                    },
                    'rowspan':
                    4,
                    'doc':
                    'HKID Proof',
                    'fname':
                    file_details['HKID Proof'],
                    'confirm':
                    sup_fn.try_KeyError(confirm_file_details, 'HKID Proof'),
                }
                check_list[2] = {
                    'fields': {
                        'Residential Address':
                        sup_fn.try_KeyError(uor_details['Individual'],
                                            'Residential Address'),
                    },
                    'rowspan':
                    1,
                    'doc':
                    'Address Proof',
                    'fname':
                    file_details['Address Proof'],
                    'confirm':
                    sup_fn.try_KeyError(confirm_file_details, 'Address Proof'),
                }
                if account_type == 'Corporate':
                    check_list[3] = {
                        'fields': {
                            'Company Name':
                            sup_fn.try_KeyError(uor_details['Corporate'],
                                                'Company Name'),
                            'Established at':
                            sup_fn.try_KeyError(uor_details['Corporate'],
                                                'Established at'),
                            'CR NO.':
                            sup_fn.try_KeyError(uor_details['Corporate'],
                                                'CR NO.'),
                            'Office Address':
                            sup_fn.try_KeyError(uor_details['Corporate'],
                                                'Office Address'),
                            'Company Size':
                            sup_fn.try_KeyError(uor_details['Corporate'],
                                                'Company Size'),
                            'Office Tel':
                            sup_fn.try_KeyError(uor_details['Corporate'],
                                                'Office Tel'),
                            'Industry':
                            sup_fn.try_KeyError(uor_details['Corporate'],
                                                'Industry'),
                        },
                        'rowspan':
                        7,
                        'doc':
                        'BR/CR',
                        'fname':
                        file_details['BR/CR'],
                        'confirm':
                        sup_fn.try_KeyError(confirm_file_details, 'BR/CR'),
                    }

            status_list = [
                'PENDING DOC/IV', 'APPROVED', 'REJECTED', 'CANCELLED'
            ]

            # print acknowledgement href link
            reject_print_status_list = [
                'DOC UPLOADED', 'PENDING DOC/IV', 'APPROVED', 'REJECTED',
                'CANCELLED'
            ]
            if uor.status not in reject_print_status_list:
                print_lender_agreement = '/generate_pdf_file/?uor_id=%s&doc_type=Lender Agreement' % (
                    uor.id)
            else:
                print_lender_agreement = 'about:blank'

            content = {
                'cate':
                'application',
                'sub_cate':
                '',
                'title':
                'Investor Application Information',
                'usr_id':
                usr.id,
                'ref_id':
                uor.id,
                'model':
                'UserOperationRequest',
                'status_list':
                status_list,
                'preface':
                preface,
                'information':
                information,
                'document':
                uor_details['File Uploaded'],
                'setting':
                setting,
                'check_list':
                check_list,
                'print_lender_agreement':
                print_lender_agreement,
                'require_tick_all_checklist':
                request.GET.get('require_tick_all_checklist'),
            }
            return render(
                request,
                'peerloan/admin/lender/investor_application_detail.html',
                content)
        # view table
        status_list = [
            'DOC UPLOADED',
            'PENDING DOC/IV',
            'APPROVED',
            'AGREEMENT CONFIRMED',
            'REJECTED',
            'CANCELLED',
        ]
        content = {
            'cate': 'application',
            'sub_cate': '',
            'title': 'Application',
            'status_list': status_list,
        }
        return render(request, 'peerloan/admin/lender/application.html',
                      content)