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)
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): 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)
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)
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 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)
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)