Implement banking system features and enhancements
- Added banking mode with checking, savings, and charity accounts, including auto-split options for income. - Introduced banking transaction management, including transfers and charity outflows. - Updated family settings to allow configuration of banking features and interest rates. - Enhanced data export functionality to include bank transactions. - Improved user interface to display banking information and donation goals. - Updated documentation to reflect new banking features and settings.
This commit is contained in:
+132
-15
@@ -188,6 +188,12 @@
|
||||
currency_symbol: $('#currency_symbol').val(),
|
||||
currency_name: $('#currency_name').val(),
|
||||
currency_permanence: $('#currency_permanence').val(),
|
||||
banking_enabled: $('#banking_enabled').is(':checked'),
|
||||
banking_auto_split_enabled: $('#banking_auto_split_enabled').is(':checked'),
|
||||
banking_auto_split_savings_pct: Number($('#banking_auto_split_savings_pct').val()) || 0,
|
||||
banking_auto_split_charity_pct: Number($('#banking_auto_split_charity_pct').val()) || 0,
|
||||
banking_savings_monthly_interest_rate: Number($('#banking_savings_monthly_interest_rate').val()) || 0,
|
||||
banking_roundup_destination: $('#banking_roundup_destination').val() || 'off',
|
||||
week_starts_on: parseInt($('#week_starts_on').val(), 10),
|
||||
nfc_base_url: ($('#nfc_base_url').val() || '').trim(),
|
||||
nfc_show_confirmation: $('#nfc_show_confirmation').is(':checked'),
|
||||
@@ -1014,32 +1020,143 @@
|
||||
}
|
||||
|
||||
function bindCurrencyPage() {
|
||||
var $form = $('#expenseForm');
|
||||
if (!$form.length) {
|
||||
var hasLegacyExpense = $('#expenseForm').length > 0;
|
||||
var hasBanking = $('#bankTransferForm').length > 0
|
||||
|| $('#bankAdjustForm').length > 0
|
||||
|| $('#charityOutflowForm').length > 0;
|
||||
if (!hasLegacyExpense && !hasBanking) {
|
||||
return;
|
||||
}
|
||||
$form.on('submit', function (e) {
|
||||
if (hasLegacyExpense) {
|
||||
$('#expenseForm').on('submit', function (e) {
|
||||
e.preventDefault();
|
||||
var payload = {
|
||||
title: $('#expense_title').val(),
|
||||
description: $('#expense_description').val(),
|
||||
date: $('#expense_date').val(),
|
||||
value: Number($('#expense_value').val()),
|
||||
assignee_id: $('#expense_assignee').val()
|
||||
};
|
||||
postJson('/expense_create.php', payload)
|
||||
.then(function () {
|
||||
var $fb = $('#expenseFormFeedback');
|
||||
showAlert($fb, 'success', 'Expense recorded. Reloading…');
|
||||
$fb.removeClass('d-none');
|
||||
window.location.reload();
|
||||
})
|
||||
.catch(function (err) {
|
||||
var $fb = $('#expenseFormFeedback');
|
||||
showAlert($fb, 'danger', err.message || 'Could not record expense');
|
||||
$fb.removeClass('d-none');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
$('#bankTransferForm').on('submit', function (e) {
|
||||
e.preventDefault();
|
||||
var payload = {
|
||||
title: $('#expense_title').val(),
|
||||
description: $('#expense_description').val(),
|
||||
date: $('#expense_date').val(),
|
||||
value: Number($('#expense_value').val()),
|
||||
assignee_id: $('#expense_assignee').val()
|
||||
};
|
||||
postJson('/expense_create.php', payload)
|
||||
var from = $('#transfer_from_account').val();
|
||||
var to = $('#transfer_to_account').val();
|
||||
if (to === 'charity' && !window.confirm('Transfers into charity cannot be moved back out. Continue?')) {
|
||||
return;
|
||||
}
|
||||
postJson('/bank_transfer.php', {
|
||||
from_account: from,
|
||||
to_account: to,
|
||||
amount: Number($('#transfer_amount').val()) || 0,
|
||||
category: $('#transfer_category').val(),
|
||||
note: $('#transfer_note').val()
|
||||
})
|
||||
.then(function () {
|
||||
var $fb = $('#expenseFormFeedback');
|
||||
showAlert($fb, 'success', 'Expense recorded. Reloading…');
|
||||
var $fb = $('#bankTransferFeedback');
|
||||
showAlert($fb, 'success', 'Transfer saved. Reloading…');
|
||||
$fb.removeClass('d-none');
|
||||
window.location.reload();
|
||||
})
|
||||
.catch(function (err) {
|
||||
var $fb = $('#expenseFormFeedback');
|
||||
showAlert($fb, 'danger', err.message || 'Could not record expense');
|
||||
var $fb = $('#bankTransferFeedback');
|
||||
showAlert($fb, 'danger', err.message || 'Could not transfer');
|
||||
$fb.removeClass('d-none');
|
||||
});
|
||||
});
|
||||
|
||||
$('#bankAdjustForm').on('submit', function (e) {
|
||||
e.preventDefault();
|
||||
postJson('/bank_adjust_checking.php', {
|
||||
person_id: $('#bank_adjust_person').val(),
|
||||
type: $('#bank_adjust_type').val(),
|
||||
amount: Number($('#bank_adjust_amount').val()) || 0,
|
||||
category: $('#bank_adjust_category').val(),
|
||||
note: $('#bank_adjust_note').val()
|
||||
})
|
||||
.then(function () {
|
||||
var $fb = $('#bankAdjustFeedback');
|
||||
showAlert($fb, 'success', 'Checking transaction saved. Reloading…');
|
||||
$fb.removeClass('d-none');
|
||||
window.location.reload();
|
||||
})
|
||||
.catch(function (err) {
|
||||
var $fb = $('#bankAdjustFeedback');
|
||||
showAlert($fb, 'danger', err.message || 'Could not save transaction');
|
||||
$fb.removeClass('d-none');
|
||||
});
|
||||
});
|
||||
|
||||
$('#charityOutflowForm').on('submit', function (e) {
|
||||
e.preventDefault();
|
||||
postJson('/bank_charity_outflow.php', {
|
||||
person_id: $('#charity_outflow_person').val(),
|
||||
amount: Number($('#charity_outflow_amount').val()) || 0,
|
||||
category: $('#charity_outflow_category').val(),
|
||||
note: $('#charity_outflow_note').val()
|
||||
})
|
||||
.then(function () {
|
||||
var $fb = $('#charityOutflowFeedback');
|
||||
showAlert($fb, 'success', 'Charity outflow logged. Reloading…');
|
||||
$fb.removeClass('d-none');
|
||||
window.location.reload();
|
||||
})
|
||||
.catch(function (err) {
|
||||
var $fb = $('#charityOutflowFeedback');
|
||||
showAlert($fb, 'danger', err.message || 'Could not log outflow');
|
||||
$fb.removeClass('d-none');
|
||||
});
|
||||
});
|
||||
|
||||
$('#donationGoalForm').on('submit', function (e) {
|
||||
e.preventDefault();
|
||||
postJson('/bank_set_donation_goal.php', {
|
||||
person_id: $('#donation_goal_person').val(),
|
||||
goal_monthly: Number($('#donation_goal_monthly').val()) || 0
|
||||
})
|
||||
.then(function () {
|
||||
var $fb = $('#donationGoalFeedback');
|
||||
showAlert($fb, 'success', 'Donation goal saved. Reloading…');
|
||||
$fb.removeClass('d-none');
|
||||
window.location.reload();
|
||||
})
|
||||
.catch(function (err) {
|
||||
var $fb = $('#donationGoalFeedback');
|
||||
showAlert($fb, 'danger', err.message || 'Could not save goal');
|
||||
$fb.removeClass('d-none');
|
||||
});
|
||||
});
|
||||
|
||||
$(document).on('click', '.btn-bank-reverse', function () {
|
||||
var txid = $(this).data('id');
|
||||
if (!txid) {
|
||||
return;
|
||||
}
|
||||
if (!window.confirm('Create a reversal entry for this transaction? This keeps audit history intact.')) {
|
||||
return;
|
||||
}
|
||||
postJson('/bank_reverse_transaction.php', { transaction_id: txid, note: 'Reversed by HoH' })
|
||||
.then(function () {
|
||||
window.location.reload();
|
||||
})
|
||||
.catch(function (err) {
|
||||
window.alert(err.message || 'Could not reverse transaction');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function bindPeopleTable() {
|
||||
|
||||
Reference in New Issue
Block a user