mirror of
https://github.com/meichthys/church.git
synced 2026-05-01 00:11:30 +00:00
implement fund transfers
This commit is contained in:
parent
e1dc187fad
commit
0ebed26b06
@ -0,0 +1,19 @@
|
||||
// Copyright (c) 2025, meichthys and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
frappe.ui.form.on('Church Fund Transfer', {
|
||||
from_fund: function(frm) {
|
||||
// Dynamically filter 'to_fund' to exclude the selected 'from_fund'
|
||||
frm.set_query('to_fund', () => ({
|
||||
filters: [
|
||||
['name', '!=', frm.doc.from_fund]
|
||||
]
|
||||
}));
|
||||
|
||||
// Clear to_fund if it's the same as from_fund
|
||||
if (frm.doc.to_fund === frm.doc.from_fund) {
|
||||
frm.set_value('to_fund', null);
|
||||
}
|
||||
},
|
||||
|
||||
});
|
||||
@ -0,0 +1,122 @@
|
||||
{
|
||||
"actions": [],
|
||||
"allow_rename": 1,
|
||||
"autoname": "format:{from_fund} to {to_fund} - {date}",
|
||||
"creation": "2025-10-09 23:26:05.829776",
|
||||
"description": "A financial currency transfer between two `Church Fund`s",
|
||||
"doctype": "DocType",
|
||||
"engine": "InnoDB",
|
||||
"field_order": [
|
||||
"section_break_ev5b",
|
||||
"from_fund",
|
||||
"to_fund",
|
||||
"column_break_qjba",
|
||||
"amount",
|
||||
"date",
|
||||
"amended_from",
|
||||
"section_break_wqbf",
|
||||
"notes"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
"fieldname": "section_break_ev5b",
|
||||
"fieldtype": "Section Break"
|
||||
},
|
||||
{
|
||||
"allow_in_quick_entry": 1,
|
||||
"fieldname": "from_fund",
|
||||
"fieldtype": "Link",
|
||||
"in_filter": 1,
|
||||
"in_list_view": 1,
|
||||
"in_preview": 1,
|
||||
"in_standard_filter": 1,
|
||||
"label": "From Fund",
|
||||
"options": "Church Fund",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"allow_in_quick_entry": 1,
|
||||
"fieldname": "to_fund",
|
||||
"fieldtype": "Link",
|
||||
"in_filter": 1,
|
||||
"in_list_view": 1,
|
||||
"in_preview": 1,
|
||||
"in_standard_filter": 1,
|
||||
"label": "To Fund",
|
||||
"options": "Church Fund",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"allow_in_quick_entry": 1,
|
||||
"fieldname": "amount",
|
||||
"fieldtype": "Currency",
|
||||
"in_list_view": 1,
|
||||
"in_preview": 1,
|
||||
"label": "Amount",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "notes",
|
||||
"fieldtype": "Small Text",
|
||||
"in_list_view": 1,
|
||||
"in_preview": 1,
|
||||
"label": "Notes"
|
||||
},
|
||||
{
|
||||
"fieldname": "amended_from",
|
||||
"fieldtype": "Link",
|
||||
"label": "Amended From",
|
||||
"no_copy": 1,
|
||||
"options": "Church Fund Transfer",
|
||||
"print_hide": 1,
|
||||
"read_only": 1,
|
||||
"search_index": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_qjba",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "section_break_wqbf",
|
||||
"fieldtype": "Section Break"
|
||||
},
|
||||
{
|
||||
"default": "Now",
|
||||
"fieldname": "date",
|
||||
"fieldtype": "Datetime",
|
||||
"in_list_view": 1,
|
||||
"in_preview": 1,
|
||||
"label": "Date",
|
||||
"reqd": 1
|
||||
}
|
||||
],
|
||||
"grid_page_length": 50,
|
||||
"index_web_pages_for_search": 1,
|
||||
"is_submittable": 1,
|
||||
"links": [],
|
||||
"modified": "2025-10-10 00:09:27.051847",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Church Finances",
|
||||
"name": "Church Fund Transfer",
|
||||
"naming_rule": "Expression",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "System Manager",
|
||||
"share": 1,
|
||||
"submit": 1,
|
||||
"write": 1
|
||||
}
|
||||
],
|
||||
"row_format": "Dynamic",
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"states": []
|
||||
}
|
||||
@ -0,0 +1,82 @@
|
||||
import frappe
|
||||
from frappe.model.document import Document
|
||||
from frappe.utils import get_link_to_form, nowdate
|
||||
|
||||
|
||||
class ChurchFundTransfer(Document):
|
||||
def validate(self):
|
||||
if self.from_fund == self.to_fund:
|
||||
frappe.throw("Source and destination funds must be different.")
|
||||
if self.amount <= 0:
|
||||
frappe.throw("Transfer amount must be greater than zero.")
|
||||
|
||||
def on_submit(self):
|
||||
self.transfer_funds()
|
||||
|
||||
def on_cancel(self):
|
||||
self.remove_fund_transfer_transactions()
|
||||
|
||||
def transfer_funds(self):
|
||||
from_fund = frappe.get_doc("Church Fund", self.from_fund)
|
||||
to_fund = frappe.get_doc("Church Fund", self.to_fund)
|
||||
|
||||
transfer_note = self.notes or ""
|
||||
from_note = f"Transfer to {self.to_fund}"
|
||||
to_note = f"Transfer from {self.from_fund}"
|
||||
if transfer_note:
|
||||
from_note += f" — {transfer_note}"
|
||||
to_note += f" — {transfer_note}"
|
||||
|
||||
# Add transactions (no manual balance updates needed)
|
||||
from_fund.append(
|
||||
"transactions",
|
||||
{
|
||||
"amount": -self.amount,
|
||||
"source_type": "Church Fund Transfer",
|
||||
"source": self.name,
|
||||
"date": self.date or nowdate(),
|
||||
"notes": from_note,
|
||||
},
|
||||
)
|
||||
|
||||
to_fund.append(
|
||||
"transactions",
|
||||
{
|
||||
"amount": self.amount,
|
||||
"source_type": "Church Fund Transfer",
|
||||
"source": self.name,
|
||||
"date": self.date or nowdate(),
|
||||
"notes": to_note,
|
||||
},
|
||||
)
|
||||
|
||||
from_fund.save(ignore_permissions=True)
|
||||
to_fund.save(ignore_permissions=True)
|
||||
|
||||
frappe.msgprint(
|
||||
f"✅ Transferred ${self.amount} from "
|
||||
f"{get_link_to_form('Church Fund', self.from_fund)} to "
|
||||
f"{get_link_to_form('Church Fund', self.to_fund)}."
|
||||
)
|
||||
|
||||
def remove_fund_transfer_transactions(self):
|
||||
# Remove matching transactions from both funds
|
||||
for fund_name in [self.from_fund, self.to_fund]:
|
||||
fund_doc = frappe.get_doc("Church Fund", fund_name)
|
||||
# Keep only transactions not from this transfer
|
||||
fund_doc.set(
|
||||
"transactions",
|
||||
[
|
||||
tx
|
||||
for tx in fund_doc.transactions
|
||||
if not (tx.source_type == "Church Fund Transfer" and tx.source == self.name)
|
||||
],
|
||||
)
|
||||
fund_doc.save(ignore_permissions=True)
|
||||
fund_doc.reload()
|
||||
|
||||
frappe.msgprint(
|
||||
f"⏪ Reverted transfer of ${self.amount} from "
|
||||
f"{get_link_to_form('Church Fund', self.from_fund)} to "
|
||||
f"{get_link_to_form('Church Fund', self.to_fund)}."
|
||||
)
|
||||
@ -0,0 +1,9 @@
|
||||
# Copyright (c) 2025, meichthys and Contributors
|
||||
# See license.txt
|
||||
|
||||
# import frappe
|
||||
from frappe.tests.utils import FrappeTestCase
|
||||
|
||||
|
||||
class TestChurchFundTransfer(FrappeTestCase):
|
||||
pass
|
||||
Loading…
x
Reference in New Issue
Block a user