diff --git a/blocnote/apps/financialInputs/forms.py b/blocnote/apps/financialInputs/forms.py index ce532fc9d92b616b208f37d3c80da30493b1a4d9..65c2e36a1cd17c54ba454e0706bf3398f21e0931 100644 --- a/blocnote/apps/financialInputs/forms.py +++ b/blocnote/apps/financialInputs/forms.py @@ -1,6 +1,6 @@ """Forms to render and validate for financial-inputs endpoint.""" from django.forms import ModelForm -from blocnote.apps.financialInputs.models import FinancingOverview, CustomerPreference +from blocnote.apps.financialInputs.models import FinancingOverview, CustomerPreference, CashBalance class ProformaInputsForm(ModelForm): @@ -33,3 +33,11 @@ class CustomerPreferenceForm(ModelForm): 'expected_payback', 'expected_net_noi_dscr', ] + + +class CashBalanceForm(ModelForm): + """Define the form to validate cash balance entries.""" + + class Meta: + model = CashBalance + fields = '__all__' diff --git a/blocnote/apps/financialInputs/old_views.py b/blocnote/apps/financialInputs/old_views.py index f3d921086dae8a226896360c7312182d998ce3bd..2f568740e684022e5a49f862414079af34535790 100644 --- a/blocnote/apps/financialInputs/old_views.py +++ b/blocnote/apps/financialInputs/old_views.py @@ -1,10 +1,8 @@ import json -from datetime import date import datetime from django.shortcuts import render from django.http import JsonResponse -from django.db import connections from django.views import View from bpfin.back_end_call.back_end_inputs import monthly_bill, form_prior_income_table as prior_income_statement_table @@ -12,7 +10,7 @@ from bpfin.back_end_call.back_end_inputs import monthly_bill, form_prior_income_ from blocnote.lib.fetch_data import get_building_data from .models import ( - FinancingOverview, Bills, BillsOverview, EstimationAlgorithm, Liabilities, CashBalance, IncomeStatement, + FinancingOverview, Bills, BillsOverview, EstimationAlgorithm, Liabilities, IncomeStatement, LoanOptions, DefaultLoan, Lender, GrowthRate ) @@ -544,59 +542,6 @@ class LiabilitiesTable(View): return JsonResponse({}) -class CashBalanceView(View): - """Display, store and use cash balance data.""" - - model = CashBalance - - def get(self, request, building_id): - """Handle HTTP GET request. - - Fetch cash balance data from database if present. If not, return false status. - - Args: - request: HTTP GET request. - building_id: id of the building. - """ - objs = self.model.objects.filter(building_id=building_id) - instance = {} - if objs: - instance['result'] = [] - for obj in objs: - temp = {} - temp['date'] = obj.statement_date - temp['is_from_balance_sheet'] = obj.is_from_balance_sheet - temp['balance_amount'] = obj.balance_amount - instance['result'].append(temp) - return JsonResponse({'instance': instance}) - return JsonResponse({}) - - def put(self, request, building_id): - """Handle HTTP PUT request. - - Retrieve the list of records from the request. Delete existing records and create new records. - - Args: - request: HTTP PUT request. - building_id: id of the building. - - Returns: - JsonResponse: An instance with OK. - """ - put = json.loads(request.body.decode()) - self.model.objects.filter( - building_id=building_id, - ).delete() - for record in put: - self.model.objects.create( - building_id=building_id, - statement_date=record['statement-date'], - is_from_balance_sheet=record['is-from-balance-sheet'], - balance_amount=record['balance'], - ) - return JsonResponse({}) - - class IncomeStatementTable(View): """Income Statement table. diff --git a/blocnote/apps/financialInputs/static/financialInputs/scripts/app.js b/blocnote/apps/financialInputs/static/financialInputs/scripts/app.js index 416d0b5c4ec60e827876cb18f74e08f7ef81c529..5cc9ab2503ebf4452b915e75fe2ac490f1ca644f 100644 --- a/blocnote/apps/financialInputs/static/financialInputs/scripts/app.js +++ b/blocnote/apps/financialInputs/static/financialInputs/scripts/app.js @@ -12,7 +12,6 @@ loadBillsOverview(); getIncomeStatementTable(); getLiabilitiesTable(); -getCashBalanceForm(); getLoanOptionsTable(); /** Validate that commissioning date is after the construction start date. */ @@ -545,154 +544,6 @@ function getLiabilitiesTable() { }); } -/**Send HTTP GET request to obtain all cash balance records. */ -function getCashBalanceForm() { - request(`cash-balance/`, { - method: 'GET', - credentials: 'same-origin', - headers: { - 'Content-Type': 'application/json' - }, - }).then(res => { - loadCashBalanceTable(res.payload.instance); - }); -} - -/**Load cash balance table with initial values. Takes response from GET request to construct the table. */ -function loadCashBalanceTable(instance) { - table = document.querySelector('#cash-balance-table'); - if (instance) { - for (var record=0; record < instance.result.length; record++) { - balanceAmount = Number(instance.result[record].balance_amount); - date = instance.result[record].date; - isFromBalanceSheet = instance.result[record]['is_from_balance_sheet'] - addCashBalanceRow(balanceAmount, date, isFromBalanceSheet); - } - } - else { - addCashBalanceRow('', '', false); - } -} - -/** - * Return check box to indicate if a record is from balance sheet or not. Takes a boolean as argument which - * is true if the record is from balance, else not. This function returns a checked checkbox if it is from balance - * sheet, else an unchecked checkbox. - */ -function getCashBalanceCheckBox(isFromBalanceSheet) { - var check = ""; - if (isFromBalanceSheet) { - check = "checked"; - } - var text = ` - - `; - return text; -} - -/**Delete a given row in the cash balance table. Takes in the row index as argument. */ -function deleteCashBalanceRow(row) { - var result = confirm('ARE YOU SURE YOU WANT TO DELETE THIS ROW?'); - if (result) { - table = document.querySelector('#cash-balance-table'); - var rowCount = table.rows.length; - if (rowCount === 2) { - alert('YOU MUST HAVE ATLEAST ONE CASH BALANCE ENTRY!'); - return false; - } - table.deleteRow(row); - for (rowInd = 1; rowInd < table.rows.length; rowInd++) { - row = table.rows.item(rowInd).cells; - row.item(0).innerHTML = rowInd; - } - } - return false; -} - -/** - * Add a row to the cash balance table. Take balance amount, date and boolean that represents if a record is from - * balance sheet or not. - */ -function addCashBalanceRow(balance, date, isFromBalanceSheet) { - table = document.querySelector('#cash-balance-table tbody'); - var rowCount = table.rows.length; - var row = table.insertRow(rowCount); - var cell = row.insertCell(0); - cell.innerHTML = `${rowCount + 1}`; - cell = row.insertCell(1); - cell.innerHTML = ` - - `; - cell = row.insertCell(2); - cell.innerHTML = ` - - `; - cell = row.insertCell(3); - cell.innerHTML = getCashBalanceCheckBox(isFromBalanceSheet); - cell = row.insertCell(4) - cell.innerHTML = ` - - `; - return false; -} - -// Watch cash balance to display/erase error/success messages. -var cashBalanceForm = document.querySelector('#cash-balance-form'); -cashBalanceForm.onchange = function() { - document.querySelector('#cash-balance-warning-message').innerHTML = ''; -} - -/**Make PUT request with data from the cash balance table. */ -function submitCashBalanceForm(form) { - var myResult = []; - table = document.querySelector('#cash-balance-table'); - var rowCount = table.rows.length; - for (rowIndex = 1; rowIndex < rowCount; rowIndex++) { - record = {}; - record['balance'] = table.rows[rowIndex].cells[1].children[0].value; - date = table.rows[rowIndex].cells[2].children[0].value; - dateSplit = date.split('-'); - dateDict = { - 'day': Number(dateSplit[2]), - 'month': Number(dateSplit[1]), - 'year': Number(dateSplit[0]), - } - if (!validateDate(dateDict, todaysDate)) { - document.querySelector('#cash-balance-warning-message').innerHTML = ` - Statement date cannot be in the future! - `; - return false; - } - record['statement-date'] = date; - checkBox = table.rows[rowIndex].querySelectorAll('input[type="checkbox"]:checked'); - if (checkBox.length > 0) { - record['is-from-balance-sheet'] = true; - } - else { - record['is-from-balance-sheet'] = false; - } - myResult.push(record); - } - request('cash-balance/', { - method: 'PUT', - credentials: 'same-origin', - body: JSON.stringify(myResult), - headers: new Headers({ - 'Content-Type': 'application/json', - 'X-CSRFToken': Cookies.get('csrftoken') - }) - }).then(res => { - if (!res.payload.err) { - document.querySelector('#cash-balance-warning-message').innerHTML = ` - Saved - `; - } - }); - return false; -} - /** * Load income statement table. The column heading are displayed first along with the table body. The growth rate * drop down box is displayed as well. diff --git a/blocnote/apps/financialInputs/static/financialInputs/scripts/cashBalance.js b/blocnote/apps/financialInputs/static/financialInputs/scripts/cashBalance.js new file mode 100644 index 0000000000000000000000000000000000000000..524f2274752d4e24fff77799b15ecbc5f469f48a --- /dev/null +++ b/blocnote/apps/financialInputs/static/financialInputs/scripts/cashBalance.js @@ -0,0 +1,150 @@ +/**Send HTTP GET request to obtain all cash balance records. */ +function getCashBalanceForm() { + request('cash-balance/', { + method: 'GET', + credentials: 'same-origin', + headers: { + 'Content-Type': 'application/json' + }, + }).then(res => { + loadCashBalanceTable(res.payload.instance); + }); +} + +/**Load cash balance table with initial values. Takes response from GET request to construct the table. */ +function loadCashBalanceTable(instance) { + if (instance) { + for (let record = 0; record < instance.result.length; record++) { + let balanceAmount = Number(instance.result[record].balance_amount); + let date = instance.result[record].statement_date; + let isFromBalanceSheet = instance.result[record]['is_from_balance_sheet']; + addCashBalanceRow(balanceAmount, date, isFromBalanceSheet); + } + } + else { + addCashBalanceRow('', '', false); + } +} + +/** + * Return check box to indicate if a record is from balance sheet or not. Takes a boolean as argument which + * is true if the record is from balance, else not. This function returns a checked checkbox if it is from balance + * sheet, else an unchecked checkbox. + */ +function getCashBalanceCheckBox(isFromBalanceSheet) { + let check = ''; + if (isFromBalanceSheet) { + check = 'checked'; + } + const text = ` + + `; + return text; +} + +/**Delete a given row in the cash balance table. Takes in the row index as argument. */ +function deleteCashBalanceRow(row) { + const result = confirm('ARE YOU SURE YOU WANT TO DELETE THIS ROW?'); + if (result) { + const table = document.querySelector('#cash-balance-table'); + const rowCount = table.rows.length; + if (rowCount === 2) { + alert('YOU MUST HAVE ATLEAST ONE CASH BALANCE ENTRY!'); + return false; + } + table.deleteRow(row); + for (let rowInd = 1; rowInd < table.rows.length; rowInd++) { + row = table.rows.item(rowInd).cells; + row.item(0).innerHTML = rowInd; + } + } + return false; +} + +/** + * Add a row to the cash balance table. Take balance amount, date and boolean that represents if a record is from + * balance sheet or not. + */ +function addCashBalanceRow(balance, date, isFromBalanceSheet) { + const table = document.querySelector('#cash-balance-table tbody'); + const rowCount = table.rows.length; + const row = table.insertRow(rowCount); + let cell = row.insertCell(0); + cell.innerHTML = `${rowCount + 1}`; + cell = row.insertCell(1); + cell.innerHTML = ` + + `; + cell = row.insertCell(2); + cell.innerHTML = ` + + `; + cell = row.insertCell(3); + cell.innerHTML = getCashBalanceCheckBox(isFromBalanceSheet); + cell = row.insertCell(4); + cell.innerHTML = ` + + `; + return false; +} + +// Watch cash balance to display/erase error/success messages. +const cashBalanceForm = document.querySelector('#cash-balance-form'); +cashBalanceForm.onchange = function() { + document.querySelector('#cash-balance-warning-message').innerHTML = ''; +}; + +/**Make PUT request with data from the cash balance table. */ +function submitCashBalanceForm() { + let myResult = []; + const table = document.querySelector('#cash-balance-table'); + const rowCount = table.rows.length; + for (let rowIndex = 1; rowIndex < rowCount; rowIndex++) { + let record = {}; + record['balance_amount'] = table.rows[rowIndex].cells[1].children[0].value; + const todaysDate = new Date(); + const date = table.rows[rowIndex].cells[2].children[0].value; + let currentDate = new Date(date); + if (currentDate > todaysDate) { + document.querySelector('#cash-balance-warning-message').innerHTML = ` + Statement date cannot be in the future! + `; + return false; + } + record['statement_date'] = date; + const checkBox = table.rows[rowIndex].querySelectorAll('input[type="checkbox"]:checked'); + record['is_from_balance_sheet'] = (checkBox.length > 0) + myResult.push(record); + } + request('cash-balance/', { + method: 'PUT', + credentials: 'same-origin', + body: JSON.stringify(myResult), + headers: new Headers({ + 'Content-Type': 'application/json', + 'X-CSRFToken': Cookies.get('csrftoken') + }) + }).then(res => { + if (!res.err) { + document.querySelector('#cash-balance-warning-message').innerHTML = ` + Saved + `; + } + else { + res.err.responseBody.then((error) => { + let errorMsg = ''; + Object.keys(error).forEach((key) => { + errorMsg += `${key}: ${error[key]}.\n`; + }); + document.querySelector('#cash-balance-warning-message').innerHTML = ` + ${errorMsg} + `; + }); + } + }); + return false; +} + +getCashBalanceForm(); diff --git a/blocnote/apps/financialInputs/templates/financialInputs/cashBalance.html b/blocnote/apps/financialInputs/templates/financialInputs/cashBalance.html index e383f8b9ac5721bb0a5246a25db06d6d59e5aed9..2f2af77cc4fe0581616024a711f13ab145041f12 100644 --- a/blocnote/apps/financialInputs/templates/financialInputs/cashBalance.html +++ b/blocnote/apps/financialInputs/templates/financialInputs/cashBalance.html @@ -1,7 +1,7 @@