From 44c15961c77134de82dd37ac9ff88876143917b6 Mon Sep 17 00:00:00 2001 From: rocketdebris Date: Fri, 23 Jan 2026 13:55:28 -0500 Subject: [PATCH] Added an email template for Customer Invoice to be filled with copywriting and customized payment links. --- custom_ui/fixtures/custom_field.json | 60 ++++++++++++- custom_ui/fixtures/doctype.json | 92 ++++++++++---------- custom_ui/fixtures/email_template.json | 12 +++ custom_ui/hooks.py | 114 +++++++++++++------------ 4 files changed, 177 insertions(+), 101 deletions(-) create mode 100644 custom_ui/fixtures/email_template.json diff --git a/custom_ui/fixtures/custom_field.json b/custom_ui/fixtures/custom_field.json index 0637a08..cfcc5ed 100644 --- a/custom_ui/fixtures/custom_field.json +++ b/custom_ui/fixtures/custom_field.json @@ -1 +1,59 @@ -[] \ No newline at end of file +[ + { + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "collapsible_depends_on": null, + "columns": 0, + "default": null, + "depends_on": null, + "description": "The company associated with this project template.", + "docstatus": 0, + "doctype": "Custom Field", + "dt": "Project Template", + "fetch_from": null, + "fetch_if_empty": 0, + "fieldname": "company", + "fieldtype": "Link", + "hidden": 0, + "hide_border": 0, + "hide_days": 0, + "hide_seconds": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_preview": 0, + "in_standard_filter": 0, + "insert_after": "project_type", + "is_system_generated": 1, + "is_virtual": 0, + "label": "Company", + "length": 0, + "link_filters": null, + "mandatory_depends_on": null, + "modified": "2026-01-08 10:32:07.535286", + "module": null, + "name": "Project Template-company", + "no_copy": 0, + "non_negative": 0, + "options": "Company", + "permlevel": 0, + "placeholder": null, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "print_width": null, + "read_only": 0, + "read_only_depends_on": null, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "show_dashboard": 0, + "sort_options": 0, + "translatable": 0, + "unique": 0, + "width": null + } +] \ No newline at end of file diff --git a/custom_ui/fixtures/doctype.json b/custom_ui/fixtures/doctype.json index db8c42d..ec218e4 100644 --- a/custom_ui/fixtures/doctype.json +++ b/custom_ui/fixtures/doctype.json @@ -178,8 +178,8 @@ "make_attachments_public": 0, "max_attachments": 0, "menu_index": null, - "migration_hash": "9792f2dfc070efd283d24244c612c2d4", - "modified": "2026-01-20 12:56:39.681180", + "migration_hash": "5a00edceb2f575ccfc93ed99c01bc0b7", + "modified": "2026-01-22 11:05:23.661458", "module": "Custom UI", "name": "Customer Task Link", "naming_rule": "", @@ -396,8 +396,8 @@ "make_attachments_public": 0, "max_attachments": 0, "menu_index": null, - "migration_hash": "9792f2dfc070efd283d24244c612c2d4", - "modified": "2026-01-20 12:56:39.752798", + "migration_hash": "5a00edceb2f575ccfc93ed99c01bc0b7", + "modified": "2026-01-22 11:05:23.730085", "module": "Custom UI", "name": "Address Task Link", "naming_rule": "", @@ -550,8 +550,8 @@ "make_attachments_public": 0, "max_attachments": 0, "menu_index": null, - "migration_hash": "9792f2dfc070efd283d24244c612c2d4", - "modified": "2026-01-20 12:56:39.827207", + "migration_hash": "5a00edceb2f575ccfc93ed99c01bc0b7", + "modified": "2026-01-22 11:05:23.799282", "module": "Custom", "name": "Lead Companies Link", "naming_rule": "", @@ -768,8 +768,8 @@ "make_attachments_public": 0, "max_attachments": 0, "menu_index": null, - "migration_hash": "9792f2dfc070efd283d24244c612c2d4", - "modified": "2026-01-20 12:56:39.914772", + "migration_hash": "5a00edceb2f575ccfc93ed99c01bc0b7", + "modified": "2026-01-22 11:05:23.867486", "module": "Custom", "name": "Address Project Link", "naming_rule": "", @@ -986,8 +986,8 @@ "make_attachments_public": 0, "max_attachments": 0, "menu_index": null, - "migration_hash": "9792f2dfc070efd283d24244c612c2d4", - "modified": "2026-01-20 12:56:40.049882", + "migration_hash": "5a00edceb2f575ccfc93ed99c01bc0b7", + "modified": "2026-01-22 11:05:23.934979", "module": "Custom", "name": "Address Quotation Link", "naming_rule": "", @@ -1204,8 +1204,8 @@ "make_attachments_public": 0, "max_attachments": 0, "menu_index": null, - "migration_hash": "9792f2dfc070efd283d24244c612c2d4", - "modified": "2026-01-20 12:56:40.145083", + "migration_hash": "5a00edceb2f575ccfc93ed99c01bc0b7", + "modified": "2026-01-22 11:05:24.001835", "module": "Custom", "name": "Address On-Site Meeting Link", "naming_rule": "", @@ -1422,8 +1422,8 @@ "make_attachments_public": 0, "max_attachments": 0, "menu_index": null, - "migration_hash": "9792f2dfc070efd283d24244c612c2d4", - "modified": "2026-01-20 12:56:40.270888", + "migration_hash": "5a00edceb2f575ccfc93ed99c01bc0b7", + "modified": "2026-01-22 11:05:24.069255", "module": "Custom", "name": "Address Sales Order Link", "naming_rule": "", @@ -1576,8 +1576,8 @@ "make_attachments_public": 0, "max_attachments": 0, "menu_index": null, - "migration_hash": "9792f2dfc070efd283d24244c612c2d4", - "modified": "2026-01-20 12:56:40.346187", + "migration_hash": "5a00edceb2f575ccfc93ed99c01bc0b7", + "modified": "2026-01-22 11:05:24.137117", "module": "Custom", "name": "Contact Address Link", "naming_rule": "", @@ -1730,8 +1730,8 @@ "make_attachments_public": 0, "max_attachments": 0, "menu_index": null, - "migration_hash": "9792f2dfc070efd283d24244c612c2d4", - "modified": "2026-01-20 12:56:40.418889", + "migration_hash": "5a00edceb2f575ccfc93ed99c01bc0b7", + "modified": "2026-01-22 11:05:24.201857", "module": "Custom", "name": "Lead On-Site Meeting Link", "naming_rule": "", @@ -2332,8 +2332,8 @@ "make_attachments_public": 0, "max_attachments": 0, "menu_index": null, - "migration_hash": "9792f2dfc070efd283d24244c612c2d4", - "modified": "2026-01-20 12:56:40.507246", + "migration_hash": "5a00edceb2f575ccfc93ed99c01bc0b7", + "modified": "2026-01-22 11:05:24.288443", "module": "Selling", "name": "Quotation Template", "naming_rule": "", @@ -2830,8 +2830,8 @@ "make_attachments_public": 0, "max_attachments": 0, "menu_index": null, - "migration_hash": "9792f2dfc070efd283d24244c612c2d4", - "modified": "2026-01-20 12:56:40.595751", + "migration_hash": "5a00edceb2f575ccfc93ed99c01bc0b7", + "modified": "2026-01-22 11:05:24.372116", "module": "Selling", "name": "Quotation Template Item", "naming_rule": "", @@ -2984,8 +2984,8 @@ "make_attachments_public": 0, "max_attachments": 0, "menu_index": null, - "migration_hash": "9792f2dfc070efd283d24244c612c2d4", - "modified": "2026-01-20 12:56:40.676141", + "migration_hash": "5a00edceb2f575ccfc93ed99c01bc0b7", + "modified": "2026-01-22 11:05:24.439961", "module": "Custom UI", "name": "Customer Company Link", "naming_rule": "", @@ -3138,8 +3138,8 @@ "make_attachments_public": 0, "max_attachments": 0, "menu_index": null, - "migration_hash": "9792f2dfc070efd283d24244c612c2d4", - "modified": "2026-01-20 12:56:40.749303", + "migration_hash": "5a00edceb2f575ccfc93ed99c01bc0b7", + "modified": "2026-01-22 11:05:24.506463", "module": "Custom UI", "name": "Customer Address Link", "naming_rule": "", @@ -3292,8 +3292,8 @@ "make_attachments_public": 0, "max_attachments": 0, "menu_index": null, - "migration_hash": "9792f2dfc070efd283d24244c612c2d4", - "modified": "2026-01-20 12:56:40.836296", + "migration_hash": "5a00edceb2f575ccfc93ed99c01bc0b7", + "modified": "2026-01-22 11:05:24.575135", "module": "Custom UI", "name": "Customer Contact Link", "naming_rule": "", @@ -3446,8 +3446,8 @@ "make_attachments_public": 0, "max_attachments": 0, "menu_index": null, - "migration_hash": "9792f2dfc070efd283d24244c612c2d4", - "modified": "2026-01-20 12:56:40.900156", + "migration_hash": "5a00edceb2f575ccfc93ed99c01bc0b7", + "modified": "2026-01-22 11:05:24.644548", "module": "Custom", "name": "Address Contact Link", "naming_rule": "", @@ -3600,8 +3600,8 @@ "make_attachments_public": 0, "max_attachments": 0, "menu_index": null, - "migration_hash": "9792f2dfc070efd283d24244c612c2d4", - "modified": "2026-01-20 12:56:40.986399", + "migration_hash": "5a00edceb2f575ccfc93ed99c01bc0b7", + "modified": "2026-01-22 11:05:24.712407", "module": "Custom", "name": "Customer On-Site Meeting Link", "naming_rule": "", @@ -3754,8 +3754,8 @@ "make_attachments_public": 0, "max_attachments": 0, "menu_index": null, - "migration_hash": "9792f2dfc070efd283d24244c612c2d4", - "modified": "2026-01-20 12:56:41.054749", + "migration_hash": "5a00edceb2f575ccfc93ed99c01bc0b7", + "modified": "2026-01-22 11:05:24.786735", "module": "Custom", "name": "Customer Project Link", "naming_rule": "", @@ -3908,8 +3908,8 @@ "make_attachments_public": 0, "max_attachments": 0, "menu_index": null, - "migration_hash": "9792f2dfc070efd283d24244c612c2d4", - "modified": "2026-01-20 12:56:41.114144", + "migration_hash": "5a00edceb2f575ccfc93ed99c01bc0b7", + "modified": "2026-01-22 11:05:24.856324", "module": "Custom", "name": "Customer Quotation Link", "naming_rule": "", @@ -4062,8 +4062,8 @@ "make_attachments_public": 0, "max_attachments": 0, "menu_index": null, - "migration_hash": "9792f2dfc070efd283d24244c612c2d4", - "modified": "2026-01-20 12:56:41.170115", + "migration_hash": "5a00edceb2f575ccfc93ed99c01bc0b7", + "modified": "2026-01-22 11:05:24.924254", "module": "Custom", "name": "Customer Sales Order Link", "naming_rule": "", @@ -4216,8 +4216,8 @@ "make_attachments_public": 0, "max_attachments": 0, "menu_index": null, - "migration_hash": "9792f2dfc070efd283d24244c612c2d4", - "modified": "2026-01-20 12:56:41.226997", + "migration_hash": "5a00edceb2f575ccfc93ed99c01bc0b7", + "modified": "2026-01-22 11:05:24.990458", "module": "Custom", "name": "Lead Address Link", "naming_rule": "", @@ -4370,8 +4370,8 @@ "make_attachments_public": 0, "max_attachments": 0, "menu_index": null, - "migration_hash": "9792f2dfc070efd283d24244c612c2d4", - "modified": "2026-01-20 12:56:41.283969", + "migration_hash": "5a00edceb2f575ccfc93ed99c01bc0b7", + "modified": "2026-01-22 11:05:25.058368", "module": "Custom", "name": "Lead Contact Link", "naming_rule": "", @@ -4524,8 +4524,8 @@ "make_attachments_public": 0, "max_attachments": 0, "menu_index": null, - "migration_hash": "9792f2dfc070efd283d24244c612c2d4", - "modified": "2026-01-20 12:56:41.344731", + "migration_hash": "5a00edceb2f575ccfc93ed99c01bc0b7", + "modified": "2026-01-22 11:05:25.124946", "module": "Custom", "name": "Lead Quotation Link", "naming_rule": "", @@ -4678,8 +4678,8 @@ "make_attachments_public": 0, "max_attachments": 0, "menu_index": null, - "migration_hash": "9792f2dfc070efd283d24244c612c2d4", - "modified": "2026-01-20 12:56:41.401007", + "migration_hash": "5a00edceb2f575ccfc93ed99c01bc0b7", + "modified": "2026-01-22 11:05:25.193024", "module": "Custom", "name": "Address Company Link", "naming_rule": "", diff --git a/custom_ui/fixtures/email_template.json b/custom_ui/fixtures/email_template.json new file mode 100644 index 0000000..da3baf4 --- /dev/null +++ b/custom_ui/fixtures/email_template.json @@ -0,0 +1,12 @@ +[ + { + "docstatus": 0, + "doctype": "Email Template", + "modified": "2026-01-23 08:44:37.346188", + "name": "Customer Invoice", + "response": "

-- Copywriting goes here --

-- Customized Payment Link goes here --

", + "response_html": null, + "subject": "Your Invoice is Ready", + "use_html": 0 + } +] \ No newline at end of file diff --git a/custom_ui/hooks.py b/custom_ui/hooks.py index 0f5911b..85b3ecc 100644 --- a/custom_ui/hooks.py +++ b/custom_ui/hooks.py @@ -37,13 +37,13 @@ requires = [ # Each item in the list will be shown as an app in the apps page # add_to_apps_screen = [ -# { -# "name": "custom_ui", -# "logo": "/assets/custom_ui/logo.png", -# "title": "Custom Ui", -# "route": "/custom_ui", -# "has_permission": "custom_ui.api.permission.has_app_permission" -# } +# { +# "name": "custom_ui", +# "logo": "/assets/custom_ui/logo.png", +# "title": "Custom Ui", +# "route": "/custom_ui", +# "has_permission": "custom_ui.api.permission.has_app_permission" +# } # ] # Includes in @@ -86,7 +86,7 @@ requires = [ # website user home page (by Role) # role_home_page = { -# "Role": "home_page" +# "Role": "home_page" # } # Generators @@ -100,8 +100,8 @@ requires = [ # add methods and filters to jinja environment # jinja = { -# "methods": "custom_ui.utils.jinja_methods", -# "filters": "custom_ui.utils.jinja_filters" +# "methods": "custom_ui.utils.jinja_methods", +# "filters": "custom_ui.utils.jinja_filters" # } # Installation @@ -143,11 +143,11 @@ requires = [ # Permissions evaluated in scripted ways # permission_query_conditions = { -# "Event": "frappe.desk.doctype.event.event.get_permission_query_conditions", +# "Event": "frappe.desk.doctype.event.event.get_permission_query_conditions", # } # # has_permission = { -# "Event": "frappe.desk.doctype.event.event.has_permission", +# "Event": "frappe.desk.doctype.event.event.has_permission", # } # DocType Class @@ -155,7 +155,7 @@ requires = [ # Override standard doctype classes # override_doctype_class = { -# "ToDo": "custom_app.overrides.CustomToDo" +# "ToDo": "custom_app.overrides.CustomToDo" # } # Document Events @@ -163,11 +163,11 @@ requires = [ # Hook on document methods and events doc_events = { - "On-Site Meeting": { - "after_insert": "custom_ui.events.onsite_meeting.after_insert", + "On-Site Meeting": { + "after_insert": "custom_ui.events.onsite_meeting.after_insert", "before_save": "custom_ui.events.onsite_meeting.before_save", "before_insert": "custom_ui.events.onsite_meeting.before_insert" - }, + }, "Address": { "before_insert": "custom_ui.events.address.before_insert" }, @@ -196,6 +196,12 @@ doc_events = { } fixtures = [ + { + "dt": "Email Template", + "filters": [ + ["name", "in", ["Customer Invoice"]] + ] + }, { "dt": "DocType", "filters": [ @@ -267,7 +273,7 @@ fixtures = [ ["doc_type", "=", "Address"] ] } - + ] @@ -276,21 +282,21 @@ fixtures = [ # --------------- # scheduler_events = { -# "all": [ -# "custom_ui.tasks.all" -# ], -# "daily": [ -# "custom_ui.tasks.daily" -# ], -# "hourly": [ -# "custom_ui.tasks.hourly" -# ], -# "weekly": [ -# "custom_ui.tasks.weekly" -# ], -# "monthly": [ -# "custom_ui.tasks.monthly" -# ], +# "all": [ +# "custom_ui.tasks.all" +# ], +# "daily": [ +# "custom_ui.tasks.daily" +# ], +# "hourly": [ +# "custom_ui.tasks.hourly" +# ], +# "weekly": [ +# "custom_ui.tasks.weekly" +# ], +# "monthly": [ +# "custom_ui.tasks.monthly" +# ], # } # Testing @@ -302,14 +308,14 @@ fixtures = [ # ------------------------------ # # override_whitelisted_methods = { -# "frappe.desk.doctype.event.event.get_events": "custom_ui.event.get_events" +# "frappe.desk.doctype.event.event.get_events": "custom_ui.event.get_events" # } # # each overriding function accepts a `data` argument; # generated from the base implementation of the doctype dashboard, # along with any modifications made in other Frappe apps # override_doctype_dashboards = { -# "Task": "custom_ui.task.get_dashboard_data" +# "Task": "custom_ui.task.get_dashboard_data" # } # exempt linked doctypes from being automatically cancelled @@ -335,37 +341,37 @@ fixtures = [ # -------------------- # user_data_fields = [ -# { -# "doctype": "{doctype_1}", -# "filter_by": "{filter_by}", -# "redact_fields": ["{field_1}", "{field_2}"], -# "partial": 1, -# }, -# { -# "doctype": "{doctype_2}", -# "filter_by": "{filter_by}", -# "partial": 1, -# }, -# { -# "doctype": "{doctype_3}", -# "strict": False, -# }, -# { -# "doctype": "{doctype_4}" -# } +# { +# "doctype": "{doctype_1}", +# "filter_by": "{filter_by}", +# "redact_fields": ["{field_1}", "{field_2}"], +# "partial": 1, +# }, +# { +# "doctype": "{doctype_2}", +# "filter_by": "{filter_by}", +# "partial": 1, +# }, +# { +# "doctype": "{doctype_3}", +# "strict": False, +# }, +# { +# "doctype": "{doctype_4}" +# } # ] # Authentication and authorization # -------------------------------- # auth_hooks = [ -# "custom_ui.auth.validate" +# "custom_ui.auth.validate" # ] # Automatically update python controller files with type annotations for this app. # export_python_type_annotations = True # default_log_clearing_doctypes = { -# "Logging DocType Name": 30 # days to retain logs +# "Logging DocType Name": 30 # days to retain logs # }