Add fund balance tracking & transactions

This commit is contained in:
meichthys 2025-10-02 05:29:47 +00:00
parent 1bbe21b036
commit 2eae8b9d0e
22 changed files with 527 additions and 23 deletions

View File

@ -0,0 +1,35 @@
{
"chart_name": "Church Fund Balances",
"chart_type": "Report",
"creation": "2025-10-02 01:25:37.459929",
"currency": "USD",
"custom_options": "{\"x_field\": \"fund\", \"chart_type\": \"Bar\", \"y_axis_fields\": [{\"idx\": 1, \"__islocal\": true, \"y_field\": \"balance\", \"color\": \"#29CD42\", \"name\": \"row 1\"}], \"y_fields\": [\"balance\"], \"colors\": [\"#29CD42\"]}",
"docstatus": 0,
"doctype": "Dashboard Chart",
"filters_json": "{}",
"group_by_type": "Count",
"idx": 0,
"is_public": 0,
"is_standard": 1,
"modified": "2025-10-02 01:26:04.007658",
"modified_by": "Administrator",
"module": "Church Finances",
"name": "Church Fund Balances",
"number_of_groups": 0,
"owner": "Administrator",
"report_name": "Church Fund Balances",
"roles": [],
"show_values_over_chart": 1,
"time_interval": "Yearly",
"timeseries": 0,
"timespan": "Last Year",
"type": "Bar",
"use_report_chart": 0,
"x_field": "fund",
"y_axis": [
{
"color": "#29CD42",
"y_field": "balance"
}
]
}

View File

@ -19,20 +19,57 @@ frappe.ui.form.on("Church Collection", {
},
});
// Keep Collection `total_amount` up to date when amounts are changed/added
frappe.ui.form.on("Church Donation", "amount", update_collection_total);
frappe.ui.form.on("Church Donation", "amount", function(frm, cdt, cdn) {
update_collection_total(frm);
update_fund_totals(frm);
});
// Keep Collection `total_amount` up to date when rows are removed from grid
frappe.ui.form.on("Church Donation", {
donations_remove: update_collection_total
donations_remove: function(frm) {
update_collection_total(frm);
update_fund_totals(frm);
}
});
// Also update when fund field changes
frappe.ui.form.on("Church Donation", "fund", function(frm, cdt, cdn) {
update_fund_totals(frm);
});
// Update Collection `total_amount` with sum of donation amounts
function update_collection_total(frm) {
var total = 0;
frm.doc.donations.forEach(function (donation) {
total += donation.amount || 0;
});
frm.set_value("total_amount", total);
var total = 0;
frm.doc.donations.forEach(function (donation) {
total += donation.amount || 0;
});
frm.set_value("total_amount", total);
}
// Update fund_totals table based on donations
function update_fund_totals(frm) {
// Clear existing fund_totals before each update
frm.clear_table("fund_totals");
// Calculate totals by fund
var fund_totals = {};
frm.doc.donations.forEach(function(donation) {
if (donation.fund && donation.amount) {
if (!fund_totals[donation.fund]) {
fund_totals[donation.fund] = 0;
}
fund_totals[donation.fund] += donation.amount;
}
});
// Add rows to fund_totals table
Object.keys(fund_totals).forEach(function(fund) {
var row = frm.add_child("fund_totals");
row.fund = fund;
row.total = fund_totals[fund];
});
// Refresh the fund_totals field to show updated data
frm.refresh_field("fund_totals");
}

View File

@ -11,6 +11,7 @@
"event",
"column_break_ijpy",
"total_amount",
"fund_totals",
"section_break_izta",
"donations"
],
@ -53,14 +54,22 @@
"fieldname": "total_amount",
"fieldtype": "Currency",
"in_list_view": 1,
"in_preview": 1,
"label": "Total Amount",
"read_only": 1
},
{
"fieldname": "fund_totals",
"fieldtype": "Table",
"label": "Fund Totals",
"options": "Church Collection Fund Total",
"read_only": 1
}
],
"grid_page_length": 50,
"index_web_pages_for_search": 1,
"links": [],
"modified": "2025-09-04 23:45:50.511534",
"modified": "2025-10-01 22:52:37.422727",
"modified_by": "Administrator",
"module": "Church Finances",
"name": "Church Collection",
@ -85,4 +94,4 @@
"sort_order": "DESC",
"states": [],
"track_changes": 1
}
}

View File

@ -1,9 +1,35 @@
# Copyright (c) 2025, meichthys and contributors
# For license information, please see license.txt
# import frappe
import frappe
from frappe.model.document import Document
class ChurchCollection(Document):
pass
def after_insert(self):
self.update_church_funds()
def update_church_funds(self):
# Group donations by fund
fund_data = {}
for donation in self.donations:
if donation.fund and donation.amount:
if donation.fund not in fund_data:
fund_data[donation.fund] = 0
fund_data[donation.fund] += donation.amount
# Update each Church Fund
for fund_name, fund_total in fund_data.items():
fund_doc = frappe.get_doc("Church Fund", fund_name)
# Add financial transaction
transaction = fund_doc.append(
"transactions",
{"amount": fund_total, "source_type": "Church Collection", "source": self.name},
)
transaction.creation = frappe.utils.now()
# Update balance (assuming you want to add to existing balance)
current_balance = fund_doc.get("balance") or 0
fund_doc.balance = current_balance + fund_total
fund_doc.save()

View File

@ -0,0 +1,47 @@
{
"actions": [],
"allow_rename": 1,
"creation": "2025-10-01 22:18:39.386224",
"description": "Total donations for specific `Church Fund`s",
"doctype": "DocType",
"engine": "InnoDB",
"field_order": [
"fund",
"total"
],
"fields": [
{
"fieldname": "fund",
"fieldtype": "Link",
"in_filter": 1,
"in_list_view": 1,
"in_standard_filter": 1,
"label": "Fund",
"options": "Church Fund",
"reqd": 1
},
{
"fieldname": "total",
"fieldtype": "Currency",
"in_filter": 1,
"in_list_view": 1,
"in_standard_filter": 1,
"label": "Total",
"reqd": 1
}
],
"grid_page_length": 50,
"index_web_pages_for_search": 1,
"istable": 1,
"links": [],
"modified": "2025-10-02 00:41:27.821263",
"modified_by": "Administrator",
"module": "Church Finances",
"name": "Church Collection Fund Total",
"owner": "Administrator",
"permissions": [],
"row_format": "Dynamic",
"sort_field": "modified",
"sort_order": "DESC",
"states": []
}

View File

@ -0,0 +1,9 @@
# Copyright (c) 2025, meichthys and contributors
# For license information, please see license.txt
# import frappe
from frappe.model.document import Document
class ChurchCollectionFundTotal(Document):
pass

View File

@ -0,0 +1,70 @@
{
"actions": [],
"allow_rename": 1,
"creation": "2025-10-01 23:06:24.774047",
"description": "A financial transaction from a source (i.e. Person, Business, etc)",
"doctype": "DocType",
"editable_grid": 1,
"engine": "InnoDB",
"field_order": [
"amount",
"source_type",
"source",
"notes"
],
"fields": [
{
"fieldname": "amount",
"fieldtype": "Currency",
"in_filter": 1,
"in_list_view": 1,
"in_preview": 1,
"in_standard_filter": 1,
"label": "Amount",
"reqd": 1
},
{
"fieldname": "notes",
"fieldtype": "Small Text",
"in_list_view": 1,
"in_preview": 1,
"label": "Notes"
},
{
"fieldname": "source_type",
"fieldtype": "Link",
"in_filter": 1,
"in_list_view": 1,
"in_preview": 1,
"in_standard_filter": 1,
"label": "Source Type",
"options": "DocType",
"reqd": 1
},
{
"fieldname": "source",
"fieldtype": "Dynamic Link",
"in_filter": 1,
"in_list_view": 1,
"in_preview": 1,
"in_standard_filter": 1,
"label": "Source",
"options": "source_type",
"reqd": 1
}
],
"grid_page_length": 50,
"index_web_pages_for_search": 1,
"istable": 1,
"links": [],
"modified": "2025-10-02 00:50:27.009030",
"modified_by": "Administrator",
"module": "Church Finances",
"name": "Church Financial Transaction",
"owner": "Administrator",
"permissions": [],
"row_format": "Dynamic",
"sort_field": "modified",
"sort_order": "DESC",
"states": []
}

View File

@ -0,0 +1,9 @@
# Copyright (c) 2025, meichthys and contributors
# For license information, please see license.txt
# import frappe
from frappe.model.document import Document
class ChurchFinancialTransaction(Document):
pass

View File

@ -11,7 +11,10 @@
"description",
"column_break_ojjy",
"start_date",
"end_date"
"end_date",
"balance",
"section_break_xcgh",
"transactions"
],
"fields": [
{
@ -42,6 +45,21 @@
"fieldname": "end_date",
"fieldtype": "Date",
"label": "End Date"
},
{
"fieldname": "balance",
"fieldtype": "Currency",
"label": "Balance"
},
{
"fieldname": "section_break_xcgh",
"fieldtype": "Section Break"
},
{
"fieldname": "transactions",
"fieldtype": "Table",
"label": "Transactions",
"options": "Church Financial Transaction"
}
],
"grid_page_length": 50,
@ -53,7 +71,7 @@
"table_fieldname": "donations"
}
],
"modified": "2025-09-08 23:10:00.488734",
"modified": "2025-10-01 23:11:07.400554",
"modified_by": "Administrator",
"module": "Church Finances",
"name": "Church Fund",
@ -79,4 +97,4 @@
"sort_order": "DESC",
"states": [],
"track_changes": 1
}
}

View File

@ -6,4 +6,18 @@ from frappe.model.document import Document
class ChurchFund(Document):
pass
def before_save(self):
# Ensure balance is always current before saving
self.recalculate_balance()
def on_update(self):
self.recalculate_balance()
def recalculate_balance(self):
# Calculate balance from all financial transactions
total_balance = 0
for transaction in self.transactions:
total_balance += transaction.amount or 0
# Update the balance field
self.balance = total_balance

View File

@ -17,10 +17,10 @@
"wildcard_filter": 0
}
],
"idx": 2,
"idx": 3,
"is_standard": "Yes",
"letterhead": null,
"modified": "2025-09-21 22:47:37.094571",
"modified": "2025-10-02 01:07:53.346443",
"modified_by": "Administrator",
"module": "Church Finances",
"name": "Church Collection Bank Reconciliation",
@ -33,6 +33,9 @@
"roles": [
{
"role": "System Manager"
},
{
"role": "Church Manager"
}
],
"timeout": 0

View File

@ -11,7 +11,7 @@
"is_standard": "Yes",
"json": "{\"filters\":[],\"fields\":[[\"name\",\"Church Collection\"],[\"event\",\"Church Collection\"],[\"fund\",\"Church Donation\"],[\"person\",\"Church Donation\"],[\"payment_type\",\"Church Donation\"],[\"check_number\",\"Church Donation\"],[\"amount\",\"Church Donation\"]],\"order_by\":\"`tabChurch Collection`.`modified` desc\",\"page_length\":20,\"column_widths\":{\"name\":120,\"event\":120,\"Church Donation:fund\":120,\"Church Donation:person\":120,\"Church Donation:payment_type\":120,\"Church Donation:check_number\":120,\"Church Donation:amount\":120},\"group_by\":null}",
"letterhead": null,
"modified": "2025-09-21 22:47:37.149849",
"modified": "2025-10-02 01:10:11.876159",
"modified_by": "Administrator",
"module": "Church Finances",
"name": "Church Donations",
@ -23,6 +23,9 @@
"roles": [
{
"role": "System Manager"
},
{
"role": "Church Manager"
}
],
"timeout": 0

View File

@ -11,7 +11,7 @@
"is_standard": "Yes",
"json": "{\"filters\":[[\"Church Collection\",\"date\",\"Timespan\",\"this year\",false]],\"fields\":[[\"person\",\"Church Donation\"],[\"_aggregate_column\",\"Church Donation\"]],\"order_by\":\"`tabChurch Collection`.`modified` desc\",\"add_totals_row\":true,\"page_length\":20,\"column_widths\":{\"Church Donation:person\":120,\"_aggregate_column\":200},\"group_by\":{\"group_by\":\"`tabChurch Donation`.`person`\",\"aggregate_function\":\"sum\",\"aggregate_on\":\"`tabChurch Donation`.`amount`\"}}",
"letterhead": null,
"modified": "2025-09-21 22:47:37.187395",
"modified": "2025-10-02 01:09:55.346449",
"modified_by": "Administrator",
"module": "Church Finances",
"name": "Church Donations by Person",
@ -23,6 +23,9 @@
"roles": [
{
"role": "System Manager"
},
{
"role": "Church Manager"
}
],
"timeout": 0

View File

@ -0,0 +1,46 @@
{
"add_total_row": 1,
"add_translate_data": 0,
"columns": [
{
"fieldname": "fund",
"fieldtype": "Link",
"label": "Fund",
"options": "Church Fund",
"width": 0
},
{
"fieldname": "balance",
"fieldtype": "Currency",
"label": "Balance",
"width": 0
}
],
"creation": "2025-10-01 23:58:31.335720",
"disabled": 0,
"docstatus": 0,
"doctype": "Report",
"filters": [],
"idx": 0,
"is_standard": "Yes",
"letterhead": null,
"modified": "2025-10-02 00:14:58.822835",
"modified_by": "Administrator",
"module": "Church Finances",
"name": "Church Fund Balances",
"owner": "Administrator",
"prepared_report": 0,
"query": "SELECT fund, balance\nFROM `tabChurch Fund`;",
"ref_doctype": "Church Fund",
"report_name": "Church Fund Balances",
"report_type": "Query Report",
"roles": [
{
"role": "Church User"
},
{
"role": "Church Manager"
}
],
"timeout": 0
}

View File

@ -0,0 +1,76 @@
{
"add_total_row": 1,
"add_translate_data": 0,
"columns": [
{
"fieldname": "fund",
"fieldtype": "Link",
"label": "Fund",
"options": "Church Fund",
"width": 0
},
{
"fieldname": "amount",
"fieldtype": "Currency",
"label": "Amount",
"width": 0
},
{
"fieldname": "notes",
"fieldtype": "Data",
"label": "Notes",
"width": 0
},
{
"fieldname": "creation",
"fieldtype": "Datetime",
"label": "Date",
"width": 0
}
],
"creation": "2025-10-02 00:08:03.097873",
"disabled": 0,
"docstatus": 0,
"doctype": "Report",
"filters": [
{
"default": "",
"fieldname": "from_date",
"fieldtype": "Date",
"label": "From Date",
"mandatory": 1,
"options": "",
"wildcard_filter": 0
},
{
"default": "",
"fieldname": "to_date",
"fieldtype": "Date",
"label": "To Date",
"mandatory": 1,
"wildcard_filter": 0
}
],
"idx": 0,
"is_standard": "Yes",
"letterhead": null,
"modified": "2025-10-02 00:37:51.943094",
"modified_by": "Administrator",
"module": "Church Finances",
"name": "Church Fund Transactions",
"owner": "Administrator",
"prepared_report": 0,
"query": "SELECT \n cf.fund, \n ft.amount, \n ft.notes, \n ft.creation\nFROM \n `tabChurch Fund` cf \nINNER JOIN \n `tabChurch Financial Transaction` ft ON ft.parent = cf.name \nWHERE \n ft.parenttype = 'Church Fund'\n AND (%(from_date)s IS NULL OR DATE(ft.creation) >= %(from_date)s) \n AND (%(to_date)s IS NULL OR DATE(ft.creation) <= %(to_date)s) \nORDER BY\n cf.fund, ft.creation DESC",
"ref_doctype": "Church Fund",
"report_name": "Church Fund Transactions",
"report_type": "Query Report",
"roles": [
{
"role": "Church User"
},
{
"role": "Church Manager"
}
],
"timeout": 0
}

View File

@ -0,0 +1,76 @@
{
"add_total_row": 1,
"add_translate_data": 0,
"columns": [
{
"fieldname": "fund",
"fieldtype": "Link",
"label": "Fund",
"options": "Church Fund",
"width": 0
},
{
"fieldname": "amount",
"fieldtype": "Currency",
"label": "Amount",
"width": 0
},
{
"fieldname": "notes",
"fieldtype": "Data",
"label": "Notes",
"width": 0
},
{
"fieldname": "creation",
"fieldtype": "Datetime",
"label": "Date",
"width": 0
}
],
"creation": "2025-10-02 00:47:04.809206",
"disabled": 0,
"docstatus": 0,
"doctype": "Report",
"filters": [
{
"default": "",
"fieldname": "from_date",
"fieldtype": "Date",
"label": "From Date",
"mandatory": 1,
"options": "",
"wildcard_filter": 0
},
{
"default": "",
"fieldname": "to_date",
"fieldtype": "Date",
"label": "To Date",
"mandatory": 1,
"wildcard_filter": 0
}
],
"idx": 0,
"is_standard": "Yes",
"letterhead": null,
"modified": "2025-10-02 00:47:04.809206",
"modified_by": "Administrator",
"module": "Church Finances",
"name": "Church Fund Transactions By Date",
"owner": "Administrator",
"prepared_report": 0,
"query": "SELECT \n cf.fund, \n ft.amount, \n ft.notes, \n ft.creation\nFROM \n `tabChurch Fund` cf \nINNER JOIN \n `tabChurch Financial Transaction` ft ON ft.parent = cf.name \nWHERE \n ft.parenttype = 'Church Fund'\n AND (%(from_date)s IS NULL OR DATE(ft.creation) >= %(from_date)s) \n AND (%(to_date)s IS NULL OR DATE(ft.creation) <= %(to_date)s) \nORDER BY\n cf.fund, ft.creation DESC",
"ref_doctype": "Church Fund",
"report_name": "Church Fund Transactions By Date",
"report_type": "Query Report",
"roles": [
{
"role": "Church User"
},
{
"role": "Church Manager"
}
],
"timeout": 0
}

View File

@ -1,11 +1,15 @@
{
"charts": [
{
"chart_name": "Church Fund Balances",
"label": "Church Fund Balances"
},
{
"chart_name": "Church Collections Sum",
"label": "Collections"
}
],
"content": "[{\"id\":\"mncYXd3Fp_\",\"type\":\"paragraph\",\"data\":{\"text\":\"<i>\\\"Which of you, wishing to build a tower, does not first sit down and \\ncount the cost to see if he has the resources to complete it?\\\"</i>\",\"col\":12}},{\"id\":\"MmG7zVkZbr\",\"type\":\"chart\",\"data\":{\"chart_name\":\"Collections\",\"col\":12}},{\"id\":\"nN5R0rrK8W\",\"type\":\"spacer\",\"data\":{\"col\":12}},{\"id\":\"Xwvf2HyJiA\",\"type\":\"card\",\"data\":{\"card_name\":\"Collection Documents\",\"col\":4}},{\"id\":\"m34hRRgTkK\",\"type\":\"card\",\"data\":{\"card_name\":\"Collection Reports\",\"col\":4}},{\"id\":\"l_H4g7YzJQ\",\"type\":\"spacer\",\"data\":{\"col\":12}}]",
"content": "[{\"id\":\"mncYXd3Fp_\",\"type\":\"paragraph\",\"data\":{\"text\":\"<i>\\\"Which of you, wishing to build a tower, does not first sit down and \\ncount the cost to see if he has the resources to complete it?\\\"</i>\",\"col\":12}},{\"id\":\"MmG7zVkZbr\",\"type\":\"chart\",\"data\":{\"chart_name\":\"Collections\",\"col\":6}},{\"id\":\"K7pkEdUhpZ\",\"type\":\"chart\",\"data\":{\"chart_name\":\"Church Fund Balances\",\"col\":6}},{\"id\":\"nN5R0rrK8W\",\"type\":\"spacer\",\"data\":{\"col\":12}},{\"id\":\"Xwvf2HyJiA\",\"type\":\"card\",\"data\":{\"card_name\":\"Collection Documents\",\"col\":4}},{\"id\":\"m34hRRgTkK\",\"type\":\"card\",\"data\":{\"card_name\":\"Collection Reports\",\"col\":4}},{\"id\":\"lFJ3k1PnBW\",\"type\":\"card\",\"data\":{\"card_name\":\"Fund Reports\",\"col\":4}},{\"id\":\"l_H4g7YzJQ\",\"type\":\"spacer\",\"data\":{\"col\":12}}]",
"creation": "2025-09-14 22:29:59.428671",
"custom_blocks": [],
"docstatus": 0,
@ -97,9 +101,28 @@
"link_type": "DocType",
"onboard": 0,
"type": "Link"
},
{
"hidden": 0,
"is_query_report": 0,
"label": "Fund Reports",
"link_count": 1,
"link_type": "DocType",
"onboard": 0,
"type": "Card Break"
},
{
"hidden": 0,
"is_query_report": 1,
"label": "Church Fund Balances",
"link_count": 0,
"link_to": "Church Fund Balances",
"link_type": "Report",
"onboard": 0,
"type": "Link"
}
],
"modified": "2025-09-28 23:15:54.369943",
"modified": "2025-10-02 01:26:46.381167",
"modified_by": "Administrator",
"module": "Church Finances",
"name": "Finances",