Merge pull request #45267 from frappe/mergify/bp/version-15-hotfix/pr-45211
refactor: allow users to configure interval for Semi-Auto payment reconciliation (backport #45211)
This commit is contained in:
@@ -40,9 +40,13 @@
|
||||
"show_payment_schedule_in_print",
|
||||
"currency_exchange_section",
|
||||
"allow_stale",
|
||||
"column_break_yuug",
|
||||
"stale_days",
|
||||
"section_break_jpd0",
|
||||
"auto_reconcile_payments",
|
||||
"stale_days",
|
||||
"auto_reconciliation_job_trigger",
|
||||
"reconciliation_queue_size",
|
||||
"column_break_resa",
|
||||
"invoicing_settings_tab",
|
||||
"accounts_transactions_settings_section",
|
||||
"over_billing_allowance",
|
||||
@@ -489,6 +493,28 @@
|
||||
"fieldname": "create_pr_in_draft_status",
|
||||
"fieldtype": "Check",
|
||||
"label": "Create in Draft Status"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_yuug",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_resa",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"default": "15",
|
||||
"description": "Interval should be between 1 to 59 MInutes",
|
||||
"fieldname": "auto_reconciliation_job_trigger",
|
||||
"fieldtype": "Int",
|
||||
"label": "Auto Reconciliation Job Trigger"
|
||||
},
|
||||
{
|
||||
"default": "5",
|
||||
"description": "Documents Processed on each trigger. Queue Size should be between 5 and 100",
|
||||
"fieldname": "reconciliation_queue_size",
|
||||
"fieldtype": "Int",
|
||||
"label": "Reconciliation Queue Size"
|
||||
}
|
||||
],
|
||||
"icon": "icon-cog",
|
||||
@@ -496,7 +522,7 @@
|
||||
"index_web_pages_for_search": 1,
|
||||
"issingle": 1,
|
||||
"links": [],
|
||||
"modified": "2024-07-26 06:48:52.714630",
|
||||
"modified": "2025-01-13 17:38:39.661320",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Accounts Settings",
|
||||
|
||||
@@ -10,6 +10,7 @@ from frappe.custom.doctype.property_setter.property_setter import make_property_
|
||||
from frappe.model.document import Document
|
||||
from frappe.utils import cint
|
||||
|
||||
from erpnext.accounts.utils import sync_auto_reconcile_config
|
||||
from erpnext.stock.utils import check_pending_reposting
|
||||
|
||||
|
||||
@@ -27,6 +28,7 @@ class AccountsSettings(Document):
|
||||
allow_multi_currency_invoices_against_single_party_account: DF.Check
|
||||
allow_stale: DF.Check
|
||||
auto_reconcile_payments: DF.Check
|
||||
auto_reconciliation_job_trigger: DF.Int
|
||||
automatically_fetch_payment_terms: DF.Check
|
||||
automatically_process_deferred_accounting_entry: DF.Check
|
||||
book_asset_depreciation_entry_automatically: DF.Check
|
||||
@@ -51,6 +53,7 @@ class AccountsSettings(Document):
|
||||
over_billing_allowance: DF.Currency
|
||||
post_change_gl_entries: DF.Check
|
||||
receivable_payable_remarks_length: DF.Int
|
||||
reconciliation_queue_size: DF.Int
|
||||
role_allowed_to_over_bill: DF.Link | None
|
||||
round_row_wise_tax: DF.Check
|
||||
show_balance_in_coa: DF.Check
|
||||
@@ -90,6 +93,8 @@ class AccountsSettings(Document):
|
||||
if clear_cache:
|
||||
frappe.clear_cache()
|
||||
|
||||
self.validate_and_sync_auto_reconcile_config()
|
||||
|
||||
def validate_stale_days(self):
|
||||
if not self.allow_stale and cint(self.stale_days) <= 0:
|
||||
frappe.msgprint(
|
||||
@@ -114,3 +119,17 @@ class AccountsSettings(Document):
|
||||
def validate_pending_reposts(self):
|
||||
if self.acc_frozen_upto:
|
||||
check_pending_reposting(self.acc_frozen_upto)
|
||||
|
||||
def validate_and_sync_auto_reconcile_config(self):
|
||||
if self.has_value_changed("auto_reconciliation_job_trigger"):
|
||||
if (
|
||||
cint(self.auto_reconciliation_job_trigger) > 0
|
||||
and cint(self.auto_reconciliation_job_trigger) < 60
|
||||
):
|
||||
sync_auto_reconcile_config(self.auto_reconciliation_job_trigger)
|
||||
else:
|
||||
frappe.throw(_("Cron Interval should be between 1 and 59 Min"))
|
||||
|
||||
if self.has_value_changed("reconciliation_queue_size"):
|
||||
if cint(self.reconciliation_queue_size) < 5 or cint(self.reconciliation_queue_size) > 100:
|
||||
frappe.throw(_("Queue Size should be between 5 and 100"))
|
||||
|
||||
@@ -210,7 +210,7 @@ def trigger_reconciliation_for_queued_docs():
|
||||
|
||||
docs_to_trigger = []
|
||||
unique_filters = set()
|
||||
queue_size = 5
|
||||
queue_size = frappe.db.get_single_value("Accounts Settings", "reconciliation_queue_size") or 5
|
||||
|
||||
fields = ["company", "party_type", "party", "receivable_payable_account", "default_advance_account"]
|
||||
|
||||
|
||||
@@ -2250,3 +2250,38 @@ def run_ledger_health_checks():
|
||||
doc.general_and_payment_ledger_mismatch = True
|
||||
doc.checked_on = run_date
|
||||
doc.save()
|
||||
|
||||
|
||||
def sync_auto_reconcile_config(auto_reconciliation_job_trigger: int = 15):
|
||||
auto_reconciliation_job_trigger = auto_reconciliation_job_trigger or frappe.db.get_single_value(
|
||||
"Accounts Settings", "auto_reconciliation_job_trigger"
|
||||
)
|
||||
method = "erpnext.accounts.doctype.process_payment_reconciliation.process_payment_reconciliation.trigger_reconciliation_for_queued_docs"
|
||||
|
||||
sch_event = frappe.get_doc(
|
||||
"Scheduler Event", {"scheduled_against": "Process Payment Reconciliation", "method": method}
|
||||
)
|
||||
if frappe.db.get_value("Scheduled Job Type", {"method": method}):
|
||||
frappe.get_doc(
|
||||
"Scheduled Job Type",
|
||||
{
|
||||
"method": method,
|
||||
},
|
||||
).update(
|
||||
{
|
||||
"cron_format": f"0/{auto_reconciliation_job_trigger} * * * *",
|
||||
"scheduler_event": sch_event.name,
|
||||
}
|
||||
).save()
|
||||
else:
|
||||
frappe.get_doc(
|
||||
{
|
||||
"doctype": "Scheduled Job Type",
|
||||
"method": method,
|
||||
"scheduler_event": sch_event.name,
|
||||
"cron_format": f"0/{auto_reconciliation_job_trigger} * * * *",
|
||||
"create_log": True,
|
||||
"stopped": False,
|
||||
"frequency": "Cron",
|
||||
}
|
||||
).save()
|
||||
|
||||
@@ -412,7 +412,6 @@ scheduler_events = {
|
||||
"cron": {
|
||||
"0/15 * * * *": [
|
||||
"erpnext.manufacturing.doctype.bom_update_log.bom_update_log.resume_bom_cost_update_jobs",
|
||||
"erpnext.accounts.doctype.process_payment_reconciliation.process_payment_reconciliation.trigger_reconciliation_for_queued_docs",
|
||||
],
|
||||
"0/30 * * * *": [
|
||||
"erpnext.utilities.doctype.video.video.update_youtube_data",
|
||||
|
||||
@@ -388,3 +388,4 @@ erpnext.patches.v15_0.enable_allow_existing_serial_no
|
||||
erpnext.patches.v15_0.update_cc_in_process_statement_of_accounts
|
||||
erpnext.patches.v15_0.update_asset_status_to_work_in_progress
|
||||
erpnext.patches.v15_0.migrate_checkbox_to_select_for_reconciliation_effect
|
||||
erpnext.patches.v15_0.sync_auto_reconcile_config
|
||||
|
||||
26
erpnext/patches/v15_0/sync_auto_reconcile_config.py
Normal file
26
erpnext/patches/v15_0/sync_auto_reconcile_config.py
Normal file
@@ -0,0 +1,26 @@
|
||||
import frappe
|
||||
|
||||
from erpnext.accounts.utils import sync_auto_reconcile_config
|
||||
|
||||
|
||||
def execute():
|
||||
"""
|
||||
Set default Cron Interval and Queue size
|
||||
"""
|
||||
frappe.db.set_single_value("Accounts Settings", "auto_reconciliation_job_trigger", 15)
|
||||
frappe.db.set_single_value("Accounts Settings", "reconciliation_queue_size", 5)
|
||||
|
||||
# Create Scheduler Event record if it doesn't exist
|
||||
method = "erpnext.accounts.doctype.process_payment_reconciliation.process_payment_reconciliation.trigger_reconciliation_for_queued_docs"
|
||||
if not frappe.db.get_all(
|
||||
"Scheduler Event", {"scheduled_against": "Process Payment Reconciliation", "method": method}
|
||||
):
|
||||
frappe.get_doc(
|
||||
{
|
||||
"doctype": "Scheduler Event",
|
||||
"scheduled_against": "Process Payment Reconciliation",
|
||||
"method": method,
|
||||
}
|
||||
).save()
|
||||
|
||||
sync_auto_reconcile_config(15)
|
||||
Reference in New Issue
Block a user