diff --git a/pdc_management/hooks.py b/pdc_management/hooks.py index d59f43d..99ab066 100644 --- a/pdc_management/hooks.py +++ b/pdc_management/hooks.py @@ -148,23 +148,22 @@ # Scheduled Tasks # --------------- -# scheduler_events = { -# "all": [ -# "pdc_management.tasks.all" -# ], -# "daily": [ -# "pdc_management.tasks.daily" -# ], -# "hourly": [ -# "pdc_management.tasks.hourly" -# ], -# "weekly": [ -# "pdc_management.tasks.weekly" -# ], -# "monthly": [ -# "pdc_management.tasks.monthly" -# ], -# } +scheduler_events = { + "daily": [ + "pdc_management.pdc_management.doctype.pdc_management_settings.pdc_management_settings.send_maturity_notifications" + ], + # "all": [ + # ], + # "hourly": [ + # "pdc_management.tasks.hourly" + # ], + # "weekly": [ + # "pdc_management.tasks.weekly" + # ], + # "monthly": [ + # "pdc_management.tasks.monthly" + # ], +} # Testing # ------- diff --git a/pdc_management/pdc_management/doctype/pdc_management_settings/__init__.py b/pdc_management/pdc_management/doctype/pdc_management_settings/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/pdc_management/pdc_management/doctype/pdc_management_settings/pdc_management_settings.js b/pdc_management/pdc_management/doctype/pdc_management_settings/pdc_management_settings.js new file mode 100644 index 0000000..3ad681e --- /dev/null +++ b/pdc_management/pdc_management/doctype/pdc_management_settings/pdc_management_settings.js @@ -0,0 +1,8 @@ +// Copyright (c) 2025, efeone and contributors +// For license information, please see license.txt + +// frappe.ui.form.on("PDC Management Settings", { +// refresh(frm) { + +// }, +// }); diff --git a/pdc_management/pdc_management/doctype/pdc_management_settings/pdc_management_settings.json b/pdc_management/pdc_management/doctype/pdc_management_settings/pdc_management_settings.json new file mode 100644 index 0000000..96bdc4b --- /dev/null +++ b/pdc_management/pdc_management/doctype/pdc_management_settings/pdc_management_settings.json @@ -0,0 +1,56 @@ +{ + "actions": [], + "allow_rename": 1, + "creation": "2025-05-30 14:32:22.979470", + "doctype": "DocType", + "engine": "InnoDB", + "field_order": [ + "maturity_notification_before", + "maturity_notification_template", + "notification_role" + ], + "fields": [ + { + "description": "(In Days)", + "fieldname": "maturity_notification_before", + "fieldtype": "Int", + "label": "Maturity Notification Before" + }, + { + "fieldname": "maturity_notification_template", + "fieldtype": "Link", + "label": "Maturity Notification Template", + "options": "Email Template" + }, + { + "fieldname": "notification_role", + "fieldtype": "Link", + "label": "Notification Role", + "options": "Role" + } + ], + "grid_page_length": 50, + "index_web_pages_for_search": 1, + "issingle": 1, + "links": [], + "modified": "2025-06-11 11:57:51.388741", + "modified_by": "Administrator", + "module": "PDC Management", + "name": "PDC Management Settings", + "owner": "Administrator", + "permissions": [ + { + "create": 1, + "delete": 1, + "email": 1, + "print": 1, + "read": 1, + "role": "System Manager", + "share": 1, + "write": 1 + } + ], + "sort_field": "modified", + "sort_order": "DESC", + "states": [] +} \ No newline at end of file diff --git a/pdc_management/pdc_management/doctype/pdc_management_settings/pdc_management_settings.py b/pdc_management/pdc_management/doctype/pdc_management_settings/pdc_management_settings.py new file mode 100644 index 0000000..3520a25 --- /dev/null +++ b/pdc_management/pdc_management/doctype/pdc_management_settings/pdc_management_settings.py @@ -0,0 +1,90 @@ + +import frappe +from frappe.model.document import Document +from frappe.utils import add_days, nowdate +from frappe.utils.user import get_users_with_role + + +class PDCManagementSettings(Document): + pass + + +@frappe.whitelist() +def send_maturity_notifications(): + settings = frappe.get_single("PDC Management Settings") + email_template_name = settings.maturity_notification_template + role_to_notify = settings.notification_role + days_before = settings.maturity_notification_before or 0 + + if not email_template_name: + return + + template_doc = frappe.get_doc("Email Template", email_template_name) + subject = template_doc.subject or "PDC Maturity Reminder" + template = template_doc.response or "" + + target_date = add_days(nowdate(), days_before) + + # Fetch PDCs due on the target date + pdc_list = frappe.get_all( + "Post Dated Cheque", + filters={ + "maturity_date": target_date, + "docstatus": 1 + }, + fields=["name", "maturity_date", "party_type", "party"] + ) + + # Get internal user emails with the specified role + internal_emails = [] + if role_to_notify: + for user in get_users_with_role(role_to_notify): + email = frappe.db.get_value("User", user, "email") + enabled = frappe.db.get_value("User", user, "enabled") + if enabled and email: + internal_emails.append(email) + + for pdc in pdc_list: + party_email = get_party_email(pdc.party_type, pdc.party) + + recipients = list(set(internal_emails)) + if party_email: + recipients.append(party_email) + + if not recipients: + continue + + message = frappe.render_template(template, { + "doc": pdc, + "party_name": pdc.party, + "pdc_name": pdc.name, + "maturity_date": pdc.maturity_date + }) + + # Send email to all recipients + frappe.sendmail( + recipients=recipients, + subject=subject, + message=message, + reference_doctype="Post Dated Cheque", + reference_name=pdc.name + ) + + +def get_party_email(party_type, party): + if not party_type or not party: + return None + + result = frappe.db.sql(""" + SELECT ce.email_id + FROM `tabDynamic Link` dl + JOIN `tabContact Email` ce ON ce.parent = dl.parent + WHERE dl.link_doctype = %s AND dl.link_name = %s + ORDER BY ce.is_primary DESC + LIMIT 1 + """, (party_type, party), as_dict=True) + + if result: + return result[0]["email_id"] + + return frappe.db.get_value(party_type, party, "email_id") diff --git a/pdc_management/pdc_management/doctype/pdc_management_settings/test_pdc_management_settings.py b/pdc_management/pdc_management/doctype/pdc_management_settings/test_pdc_management_settings.py new file mode 100644 index 0000000..568e4e2 --- /dev/null +++ b/pdc_management/pdc_management/doctype/pdc_management_settings/test_pdc_management_settings.py @@ -0,0 +1,9 @@ +# Copyright (c) 2025, efeone and Contributors +# See license.txt + +# import frappe +from frappe.tests.utils import FrappeTestCase + + +class TestPDCManagementSettings(FrappeTestCase): + pass diff --git a/pdc_management/pdc_management/doctype/pdc_payment_reference/__init__.py b/pdc_management/pdc_management/doctype/pdc_payment_reference/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/pdc_management/pdc_management/doctype/pdc_payment_reference/pdc_payment_reference.json b/pdc_management/pdc_management/doctype/pdc_payment_reference/pdc_payment_reference.json new file mode 100644 index 0000000..b334f33 --- /dev/null +++ b/pdc_management/pdc_management/doctype/pdc_payment_reference/pdc_payment_reference.json @@ -0,0 +1,73 @@ +{ + "actions": [], + "allow_rename": 1, + "creation": "2025-05-30 10:47:28.110415", + "doctype": "DocType", + "editable_grid": 1, + "engine": "InnoDB", + "field_order": [ + "reference_type", + "reference_name", + "amount", + "outstanding_amount", + "allocated_amount", + "pdc_clearance_date" + ], + "fields": [ + { + "fieldname": "amount", + "fieldtype": "Currency", + "in_list_view": 1, + "label": "Amount", + "reqd": 1 + }, + { + "fieldname": "outstanding_amount", + "fieldtype": "Currency", + "in_list_view": 1, + "label": "Outstanding Amount" + }, + { + "fieldname": "allocated_amount", + "fieldtype": "Currency", + "in_list_view": 1, + "label": "Allocated Amount" + }, + { + "fieldname": "pdc_clearance_date", + "fieldtype": "Date", + "in_list_view": 1, + "label": "PDC Clearance Date", + "reqd": 1 + }, + { + "fieldname": "reference_type", + "fieldtype": "Link", + "in_list_view": 1, + "label": "Type", + "options": "DocType", + "reqd": 1 + }, + { + "fieldname": "reference_name", + "fieldtype": "Dynamic Link", + "in_list_view": 1, + "label": "Name", + "options": "reference_type", + "reqd": 1 + } + ], + "grid_page_length": 50, + "index_web_pages_for_search": 1, + "istable": 1, + "links": [], + "modified": "2025-06-11 13:24:39.141405", + "modified_by": "Administrator", + "module": "PDC Management", + "name": "PDC Payment Reference", + "owner": "Administrator", + "permissions": [], + "sort_field": "modified", + "sort_order": "DESC", + "states": [] +} \ No newline at end of file diff --git a/pdc_management/pdc_management/doctype/pdc_payment_reference/pdc_payment_reference.py b/pdc_management/pdc_management/doctype/pdc_payment_reference/pdc_payment_reference.py new file mode 100644 index 0000000..306347d --- /dev/null +++ b/pdc_management/pdc_management/doctype/pdc_payment_reference/pdc_payment_reference.py @@ -0,0 +1,9 @@ +# Copyright (c) 2025, efeone and contributors +# For license information, please see license.txt + +# import frappe +from frappe.model.document import Document + + +class PDCPaymentReference(Document): + pass diff --git a/pdc_management/pdc_management/doctype/post_dated_cheque/post_dated_cheque.json b/pdc_management/pdc_management/doctype/post_dated_cheque/post_dated_cheque.json index baa5973..78dd547 100644 --- a/pdc_management/pdc_management/doctype/post_dated_cheque/post_dated_cheque.json +++ b/pdc_management/pdc_management/doctype/post_dated_cheque/post_dated_cheque.json @@ -1,6 +1,7 @@ { "actions": [], "allow_rename": 1, + "autoname": "format:{PDC}-{####}", "creation": "2025-05-24 20:17:20.615000", "doctype": "DocType", "engine": "InnoDB", @@ -17,7 +18,10 @@ "amended_from", "party_details_section", "party_type", + "column_break_cmvm", "party", + "section_break_himj", + "payment_reference", "references_section", "payment_entry" ], @@ -118,16 +122,31 @@ "label": "Payment Entry", "options": "Payment Entry", "read_only": 1 + }, + { + "fieldname": "section_break_himj", + "fieldtype": "Section Break" + }, + { + "fieldname": "payment_reference", + "fieldtype": "Table", + "label": "Payment Reference", + "options": "PDC Payment Reference" + }, + { + "fieldname": "column_break_cmvm", + "fieldtype": "Column Break" } ], "grid_page_length": 50, "index_web_pages_for_search": 1, "is_submittable": 1, "links": [], - "modified": "2025-05-24 20:41:18.451758", + "modified": "2025-05-31 09:25:16.274405", "modified_by": "Administrator", "module": "PDC Management", "name": "Post Dated Cheque", + "naming_rule": "Expression", "owner": "Administrator", "permissions": [ { @@ -144,7 +163,6 @@ "write": 1 } ], - "row_format": "Dynamic", "sort_field": "modified", "sort_order": "DESC", "states": []