From 7b1fb7240f0f585331d2e9e2d56170bb984ab1cb Mon Sep 17 00:00:00 2001 From: mudux Date: Wed, 20 Dec 2023 17:34:15 +0300 Subject: [PATCH 01/31] update non profit qr_code --- .../non_profit/doctype/member/member.json | 17 +- .../non_profit/doctype/member/member.py | 57 +++++ .../grant_application/grant_application.json | 214 ++++++++++-------- 3 files changed, 190 insertions(+), 98 deletions(-) diff --git a/non_profit/non_profit/doctype/member/member.json b/non_profit/non_profit/doctype/member/member.json index 7c1baf1a..8e0e0029 100644 --- a/non_profit/non_profit/doctype/member/member.json +++ b/non_profit/non_profit/doctype/member/member.json @@ -10,6 +10,8 @@ "naming_series", "member_name", "membership_expiry_date", + "member_pin", + "qr_code", "column_break_5", "membership_type", "email_id", @@ -166,14 +168,26 @@ "fieldtype": "Select", "label": "Subscription Status", "options": "\nActive\nHalted" + }, + { + "fieldname": "member_pin", + "fieldtype": "Data", + "label": "Member Security Pin" + }, + { + "fieldname": "qr_code", + "fieldtype": "Attach Image", + "label": "QR Code", + "read_only": 1 } ], "image_field": "image", "links": [], - "modified": "2021-07-11 14:27:26.368039", + "modified": "2023-12-20 17:33:28.264837", "modified_by": "Administrator", "module": "Non Profit", "name": "Member", + "naming_rule": "By \"Naming Series\" field", "owner": "Administrator", "permissions": [ { @@ -205,6 +219,7 @@ "restrict_to_domain": "Non Profit", "sort_field": "modified", "sort_order": "DESC", + "states": [], "title_field": "member_name", "track_changes": 1 } \ No newline at end of file diff --git a/non_profit/non_profit/doctype/member/member.py b/non_profit/non_profit/doctype/member/member.py index 1470efd1..a7ffb556 100644 --- a/non_profit/non_profit/doctype/member/member.py +++ b/non_profit/non_profit/doctype/member/member.py @@ -22,6 +22,8 @@ def onload(self): def validate(self): if self.email_id: self.validate_email_type(self.email_id) + self.generate_qr_code() + self.send_email_to_member() def validate_email_type(self, email): from frappe.utils import validate_email_address @@ -55,6 +57,61 @@ def setup_subscription(self): return subscription + + def generate_qr_code(self): + if not self.qr_code: + if self.name and self.member_name and email_id: + from print_designer.print_designer.page.print_designer.print_designer import get_barcode + arguments = { + "barcode_format": "qrcode", + "barcode_value": doc.member_name + " - " + doc.name, + "options": {"background":"#ffffff","quiet_zone":1,"foreground":"#142b91"} + } + try: + self.qr_code = get_barcode(arguments)["value"] + except Exception as e: + frappe.log_error(frappe.get_traceback(), _("QR Code Generation Failed")) + else: + frappe.throw("Please provide all the details") + + + def send_email_to_member(self): + from frappe.core.doctype.communication.email import make + args = { + "doctype" : "Member", + "name" : self.name, + "content" : f"

Your Personal certified NHIF Notice has been generated.

Please Click Here to Download.

", + "subject" : "NHIF Notice", + "sent_or_received" : "Sent", + "sender" : "RUPHA", + "recipients" : [self.email_id], + "communication_medium" : "Email", + "print_html" : None, + "print_format" : "RUPHA-NOTICE" + } + # :param doctype: Reference DocType. + # :param name: Reference Document name. + # :param content: Communication body. + # :param subject: Communication subject. + # :param sent_or_received: Sent or Received (default **Sent**). + # :param sender: Communcation sender (default current user). + # :param recipients: Communication recipients as list. + # :param communication_medium: Medium of communication (default **Email**). + # :param send_email: Send via email (default **False**). + # :param print_html: HTML Print format to be sent as attachment. + # :param print_format: Print Format name of parent document to be sent as attachment. + # :param attachments: List of File names or dicts with keys "fname" and "fcontent" + # :param send_me_a_copy: Send a copy to the sender (default **False**). + # :param email_template: Template which is used to compose mail . + # :param send_after: Send after the given datetime. + try: + make(args) + except Exception as e: + frappe.log_error(frappe.get_traceback(), _("Member Email Sending Failed")) + + + + @frappe.whitelist() def make_customer_and_link(self): if self.customer: diff --git a/non_profit/non_profit/web_form/grant_application/grant_application.json b/non_profit/non_profit/web_form/grant_application/grant_application.json index 73c94455..75529160 100644 --- a/non_profit/non_profit/web_form/grant_application/grant_application.json +++ b/non_profit/non_profit/web_form/grant_application/grant_application.json @@ -1,108 +1,128 @@ { - "accept_payment": 0, - "allow_comments": 0, - "allow_delete": 1, - "allow_edit": 1, - "allow_incomplete": 0, - "allow_multiple": 1, - "allow_print": 0, - "amount": 0.0, - "amount_based_on_field": 0, - "creation": "2017-10-30 15:57:10.825188", - "currency": "INR", - "doc_type": "Grant Application", - "docstatus": 0, - "doctype": "Web Form", - "idx": 0, - "introduction_text": "Share as many details as you can to get quick response from organization", - "is_standard": 1, - "login_required": 1, - "max_attachment_size": 0, - "modified": "2017-12-06 12:32:16.893289", - "modified_by": "Administrator", - "module": "Non Profit", - "name": "grant-application", - "owner": "Administrator", - "payment_button_label": "Buy Now", - "published": 1, - "route": "my-grant", - "show_sidebar": 1, - "sidebar_items": [], - "success_url": "/grant-application", - "title": "Grant Application", + "accept_payment": 0, + "allow_comments": 0, + "allow_delete": 1, + "allow_edit": 1, + "allow_incomplete": 0, + "allow_multiple": 1, + "allow_print": 0, + "amount": 0.0, + "amount_based_on_field": 0, + "anonymous": 0, + "apply_document_permissions": 0, + "condition_json": "[]", + "creation": "2017-10-30 15:57:10.825188", + "currency": "INR", + "doc_type": "Grant Application", + "docstatus": 0, + "doctype": "Web Form", + "idx": 0, + "introduction_text": "Share as many details as you can to get quick response from organization", + "is_standard": 1, + "list_columns": [], + "login_required": 1, + "max_attachment_size": 0, + "modified": "2023-12-19 14:15:58.250035", + "modified_by": "mohamud@rupha.co.ke", + "module": "Non Profit", + "name": "grant-application", + "owner": "Administrator", + "payment_button_label": "Buy Now", + "published": 1, + "route": "my-grant", + "show_attachments": 0, + "show_list": 1, + "show_sidebar": 1, + "success_url": "/grant-application", + "title": "Grant Application", "web_form_fields": [ { - "fieldname": "applicant_type", - "fieldtype": "Select", - "hidden": 0, - "label": "Applicant Type", - "max_length": 0, - "max_value": 0, - "options": "Individual\nOrganization", - "read_only": 0, - "reqd": 1 - }, + "allow_read_on_all_link_options": 0, + "fieldname": "applicant_type", + "fieldtype": "Select", + "hidden": 0, + "label": "Applicant Type", + "max_length": 0, + "max_value": 0, + "options": "Individual\nOrganization", + "read_only": 0, + "reqd": 1, + "show_in_filter": 0 + }, { - "fieldname": "applicant_name", - "fieldtype": "Data", - "hidden": 0, - "label": "Name", - "max_length": 0, - "max_value": 0, - "read_only": 0, - "reqd": 1 - }, + "allow_read_on_all_link_options": 0, + "fieldname": "applicant_name", + "fieldtype": "Data", + "hidden": 0, + "label": "Name", + "max_length": 0, + "max_value": 0, + "read_only": 0, + "reqd": 1, + "show_in_filter": 0 + }, { - "fieldname": "email", - "fieldtype": "Data", - "hidden": 0, - "label": "Email Address", - "max_length": 0, - "max_value": 0, - "read_only": 0, - "reqd": 1 - }, + "allow_read_on_all_link_options": 0, + "fieldname": "email", + "fieldtype": "Data", + "hidden": 0, + "label": "Email Address", + "max_length": 0, + "max_value": 0, + "read_only": 0, + "reqd": 1, + "show_in_filter": 0 + }, { - "description": "", - "fieldname": "grant_description", - "fieldtype": "Text", - "hidden": 0, - "label": "Please outline your current situation and why you are applying for a grant?", - "max_length": 0, - "max_value": 0, - "read_only": 0, - "reqd": 1 - }, + "allow_read_on_all_link_options": 0, + "description": "", + "fieldname": "grant_description", + "fieldtype": "Text", + "hidden": 0, + "label": "Please outline your current situation and why you are applying for a grant?", + "max_length": 0, + "max_value": 0, + "read_only": 0, + "reqd": 1, + "show_in_filter": 0 + }, { - "fieldname": "amount", - "fieldtype": "Float", - "hidden": 0, - "label": "Requested Amount", - "max_length": 0, - "max_value": 0, - "read_only": 0, - "reqd": 0 - }, + "allow_read_on_all_link_options": 0, + "fieldname": "amount", + "fieldtype": "Float", + "hidden": 0, + "label": "Requested Amount", + "max_length": 0, + "max_value": 0, + "read_only": 0, + "reqd": 0, + "show_in_filter": 0 + }, { - "fieldname": "has_any_past_grant_record", - "fieldtype": "Check", - "hidden": 0, - "label": "Have you received any grant from us before?", - "max_length": 0, - "max_value": 0, - "options": "", - "read_only": 0, - "reqd": 0 - }, + "allow_read_on_all_link_options": 0, + "fieldname": "has_any_past_grant_record", + "fieldtype": "Check", + "hidden": 0, + "label": "Have you received any grant from us before?", + "max_length": 0, + "max_value": 0, + "options": "", + "read_only": 0, + "reqd": 0, + "show_in_filter": 0 + }, { - "fieldname": "published", - "fieldtype": "Check", - "hidden": 0, - "label": "Show on Website", - "max_length": 0, - "max_value": 0, - "read_only": 0, - "reqd": 0 + "allow_read_on_all_link_options": 0, + "fieldname": "published", + "fieldtype": "Check", + "hidden": 0, + "label": "Show on Website", + "max_length": 0, + "max_value": 0, + "read_only": 0, + "reqd": 0, + "show_in_filter": 0 } - ] + ], + "website_sidebar": "Guest Side Bar" } \ No newline at end of file From c8197b116ff5b5bce061caec856b895b5bbba585 Mon Sep 17 00:00:00 2001 From: mudux Date: Wed, 20 Dec 2023 18:57:18 +0300 Subject: [PATCH 02/31] update emailid --- non_profit/non_profit/doctype/member/member.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/non_profit/non_profit/doctype/member/member.py b/non_profit/non_profit/doctype/member/member.py index a7ffb556..731f3b1f 100644 --- a/non_profit/non_profit/doctype/member/member.py +++ b/non_profit/non_profit/doctype/member/member.py @@ -60,7 +60,7 @@ def setup_subscription(self): def generate_qr_code(self): if not self.qr_code: - if self.name and self.member_name and email_id: + if self.name and self.member_name and self.email_id: from print_designer.print_designer.page.print_designer.print_designer import get_barcode arguments = { "barcode_format": "qrcode", From 9ab1c2ccd53e5548b50f189e1e04f42873822509 Mon Sep 17 00:00:00 2001 From: mudux Date: Wed, 20 Dec 2023 19:14:13 +0300 Subject: [PATCH 03/31] self forgot --- non_profit/non_profit/doctype/member/member.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/non_profit/non_profit/doctype/member/member.py b/non_profit/non_profit/doctype/member/member.py index 731f3b1f..80b2cbe5 100644 --- a/non_profit/non_profit/doctype/member/member.py +++ b/non_profit/non_profit/doctype/member/member.py @@ -64,7 +64,7 @@ def generate_qr_code(self): from print_designer.print_designer.page.print_designer.print_designer import get_barcode arguments = { "barcode_format": "qrcode", - "barcode_value": doc.member_name + " - " + doc.name, + "barcode_value": self.member_name + " - " + self.name, "options": {"background":"#ffffff","quiet_zone":1,"foreground":"#142b91"} } try: From 02b17c5ce7b51fc44f504ca6a284357ca7ef6cef Mon Sep 17 00:00:00 2001 From: mudux Date: Wed, 20 Dec 2023 19:45:02 +0300 Subject: [PATCH 04/31] self.is_new() --- non_profit/non_profit/doctype/member/member.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/non_profit/non_profit/doctype/member/member.py b/non_profit/non_profit/doctype/member/member.py index 80b2cbe5..2f3d7f25 100644 --- a/non_profit/non_profit/doctype/member/member.py +++ b/non_profit/non_profit/doctype/member/member.py @@ -18,6 +18,10 @@ def onload(self): """Load address and contacts in `__onload`""" load_address_and_contact(self) + def before_insert(self): + self.generate_qr_code() + self.send_email_to_member() + def validate(self): if self.email_id: @@ -104,10 +108,11 @@ def send_email_to_member(self): # :param send_me_a_copy: Send a copy to the sender (default **False**). # :param email_template: Template which is used to compose mail . # :param send_after: Send after the given datetime. - try: - make(args) - except Exception as e: - frappe.log_error(frappe.get_traceback(), _("Member Email Sending Failed")) + if self.is_new(): + try: + make(args) + except Exception as e: + frappe.log_error(frappe.get_traceback(), _("Member Email Sending Failed")) From dc443e8f2327a8ea39fae4b0ae4b396f0d9515b0 Mon Sep 17 00:00:00 2001 From: mudux Date: Wed, 20 Dec 2023 20:05:51 +0300 Subject: [PATCH 05/31] fix --- non_profit/non_profit/doctype/member/member.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/non_profit/non_profit/doctype/member/member.py b/non_profit/non_profit/doctype/member/member.py index 2f3d7f25..7b1a98ea 100644 --- a/non_profit/non_profit/doctype/member/member.py +++ b/non_profit/non_profit/doctype/member/member.py @@ -18,7 +18,7 @@ def onload(self): """Load address and contacts in `__onload`""" load_address_and_contact(self) - def before_insert(self): + def on_update(self): self.generate_qr_code() self.send_email_to_member() From ad9d1128fd1e873cefebb9c0219099c12b4ec119 Mon Sep 17 00:00:00 2001 From: mudux Date: Thu, 21 Dec 2023 13:11:57 +0300 Subject: [PATCH 06/31] update member nhif notices --- .../non_profit/doctype/member/member.json | 5 +- .../non_profit/doctype/member/member.py | 46 +++++---- .../non_profit/print_format/__init__.py | 0 .../print_format/rupha_notice/__init__.py | 0 .../rupha_notice/rupha_notice.json | 35 +++++++ .../web_form/nhif_notice/__init__.py | 0 .../web_form/nhif_notice/nhif_notice.js | 3 + .../web_form/nhif_notice/nhif_notice.json | 97 +++++++++++++++++++ .../web_form/nhif_notice/nhif_notice.py | 5 + 9 files changed, 170 insertions(+), 21 deletions(-) create mode 100644 non_profit/non_profit/print_format/__init__.py create mode 100644 non_profit/non_profit/print_format/rupha_notice/__init__.py create mode 100644 non_profit/non_profit/print_format/rupha_notice/rupha_notice.json create mode 100644 non_profit/non_profit/web_form/nhif_notice/__init__.py create mode 100644 non_profit/non_profit/web_form/nhif_notice/nhif_notice.js create mode 100644 non_profit/non_profit/web_form/nhif_notice/nhif_notice.json create mode 100644 non_profit/non_profit/web_form/nhif_notice/nhif_notice.py diff --git a/non_profit/non_profit/doctype/member/member.json b/non_profit/non_profit/doctype/member/member.json index 8e0e0029..f1b626f1 100644 --- a/non_profit/non_profit/doctype/member/member.json +++ b/non_profit/non_profit/doctype/member/member.json @@ -177,13 +177,12 @@ { "fieldname": "qr_code", "fieldtype": "Attach Image", - "label": "QR Code", - "read_only": 1 + "label": "QR Code" } ], "image_field": "image", "links": [], - "modified": "2023-12-20 17:33:28.264837", + "modified": "2023-12-21 11:06:13.074135", "modified_by": "Administrator", "module": "Non Profit", "name": "Member", diff --git a/non_profit/non_profit/doctype/member/member.py b/non_profit/non_profit/doctype/member/member.py index 7b1a98ea..5847d744 100644 --- a/non_profit/non_profit/doctype/member/member.py +++ b/non_profit/non_profit/doctype/member/member.py @@ -18,16 +18,14 @@ def onload(self): """Load address and contacts in `__onload`""" load_address_and_contact(self) - def on_update(self): + def after_insert(self): self.generate_qr_code() self.send_email_to_member() - def validate(self): if self.email_id: self.validate_email_type(self.email_id) - self.generate_qr_code() - self.send_email_to_member() + def validate_email_type(self, email): from frappe.utils import validate_email_address @@ -63,16 +61,19 @@ def setup_subscription(self): def generate_qr_code(self): - if not self.qr_code: + if not self.qr_code or self.qr_code == "": if self.name and self.member_name and self.email_id: + frappe.msgprint("Generating QR Code") from print_designer.print_designer.page.print_designer.print_designer import get_barcode arguments = { - "barcode_format": "qrcode", - "barcode_value": self.member_name + " - " + self.name, - "options": {"background":"#ffffff","quiet_zone":1,"foreground":"#142b91"} + "scale": 3, + "background": "#ffffff", + "module_color": "#142b91", + "quiet_zone":1, } try: - self.qr_code = get_barcode(arguments)["value"] + self.qr_code = get_barcode(barcode_value = self.member_name + " - " + self.name,options=arguments,barcode_format="qrcode")["value"] + frappe.msgprint(self.qr_code) except Exception as e: frappe.log_error(frappe.get_traceback(), _("QR Code Generation Failed")) else: @@ -84,10 +85,10 @@ def send_email_to_member(self): args = { "doctype" : "Member", "name" : self.name, - "content" : f"

Your Personal certified NHIF Notice has been generated.

Please Click Here to Download.

", + "content" : f"Dear Member,

Your institution's unique NHIF Notice has been auto generated.



Please Click Here to Download.", "subject" : "NHIF Notice", "sent_or_received" : "Sent", - "sender" : "RUPHA", + "sender" : "noreply@rupha.co.ke", "recipients" : [self.email_id], "communication_medium" : "Email", "print_html" : None, @@ -108,13 +109,22 @@ def send_email_to_member(self): # :param send_me_a_copy: Send a copy to the sender (default **False**). # :param email_template: Template which is used to compose mail . # :param send_after: Send after the given datetime. - if self.is_new(): - try: - make(args) - except Exception as e: - frappe.log_error(frappe.get_traceback(), _("Member Email Sending Failed")) - - + + try: + make( + doctype = args["doctype"], + name = args["name"], + content = args["content"], + subject = args["subject"], + sent_or_received = args["sent_or_received"], + sender = args["sender"], + recipients = args["recipients"], + communication_medium = args["communication_medium"], + print_html = args["print_html"], + print_format = args["print_format"] + ) + except Exception as e: + frappe.log_error(frappe.get_traceback(), _("Member Email Sending Failed")) @frappe.whitelist() diff --git a/non_profit/non_profit/print_format/__init__.py b/non_profit/non_profit/print_format/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/non_profit/non_profit/print_format/rupha_notice/__init__.py b/non_profit/non_profit/print_format/rupha_notice/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/non_profit/non_profit/print_format/rupha_notice/rupha_notice.json b/non_profit/non_profit/print_format/rupha_notice/rupha_notice.json new file mode 100644 index 00000000..e4e7f340 --- /dev/null +++ b/non_profit/non_profit/print_format/rupha_notice/rupha_notice.json @@ -0,0 +1,35 @@ +{ + "absolute_value": 0, + "align_labels_right": 0, + "creation": "2023-12-20 04:03:38.182801", + "css": "body {\r\n margin: 0;\r\n font-family: Montserrat;\r\n font-size:13px;\r\n position: relative;\r\n max-height: 200%;\r\n max-width: 200%;\r\n border: 2px solid #00008B;\r\n border-radius: 10px;\r\n}\r\n\r\n.page {\r\n /*width: 297mm;*/\r\n /*height: 210mm;*/\r\n margin: 3 auto;\r\n max-height: 100%;\r\n}\r\n\r\n.center {\r\n display: block;\r\n text-align: center;\r\n margin-left: auto;\r\n margin-right: auto;\r\n}\r\n\r\n.header-column {\r\n display: inline-block;\r\n /*height: 35%;*/\r\n /*width: 150px;*/\r\n width: 32%;\r\n /*column: 3*/\r\n}\r\n\r\n.header-logo {\r\n /*max-width: 100%;*/\r\n /*height: 50%;*/\r\n font-size:13px;\r\n display: block;\r\n /*vertical-align: middle;*/\r\n /*margin-top: 10mm;*/\r\n}\r\n\r\nheader {\r\n/* text-align: center;*/\r\n/* display: inline-block;*/\r\n /*position: absolute;*/\r\n /*top: 10mm;*/\r\n /*bottom: 10mm;*/\r\n margin-top: 10mm;\r\n margin-bottom: 10mm;\r\n /*width: 100%;*/\r\n/* display: flex;*/\r\n/* justify-content: space-between;*/\r\n}\r\n\r\n\r\nol {\r\n /*background: #ff9999;*/\r\n padding: 5px;\r\n font-size:18px;\r\n}\r\n\r\nol li {\r\n /*background: #ffe5e5;*/\r\n /*color: darkred;*/\r\n padding: 5px;\r\n margin-left: 10px;\r\n margin-right: 10px;\r\n}\r\n\r\n/*.logodiv {*/\r\n/* text-align: center;*/\r\n /*display: inline-block;*/\r\n/*}*/\r\n\r\n/*header img {*/\r\n/* max-width: 100%;*/\r\n/* height: auto;*/\r\n/*}*/\r\n\r\n/*.qrcode img {*/\r\n/* max-width: 100%;*/\r\n/* height: auto;*/\r\n/*}*/\r\n\r\n\r\n/*.logo {*/\r\n/* display: inline-block;*/\r\n/* vertical-align: middle;*/\r\n/* position: absolute;*/\r\n /*text-align: center;*/\r\n \r\n/*}*/\r\n\r\n/*.qrcode {*/\r\n/* vertical-align: middle;*/\r\n /*margin-left: 50px;*/\r\n /*display: inline-block;*/\r\n/* position: absolute;*/\r\n /*right: 10mm;*/\r\n/* width: 30mm;*/\r\n/* height: 30mm;*/\r\n/*}*/\r\n\r\nhr {\r\n margin-top: 2mm;\r\n margin-bottom: 3mm;\r\n width: 80%;\r\n}\r\n\r\n/*.member-name {*/\r\n /*display: inline-block;*/\r\n/* vertical-align: middle;*/\r\n /*margin-right: 50px;*/\r\n/* position: absolute;*/\r\n /*left: 10mm;*/\r\n/*}*/\r\n\r\n.foreword {\r\n font-size:12px;\r\n text-align: center;\r\n margin-top: 3mm;\r\n margin-bottom: 3mm;\r\n margin-left: 5px;\r\n margin-right: 5px;\r\n}\r\n\r\n.content-columns {\r\n /*margin-top: 3mm;*/\r\n /*margin-bottom: 3mm;*/\r\n font-size:12px;\r\n columns: 2;\r\n}\r\n\r\n.main-title {\r\n text-align: center;\r\n margin-top: 5mm;\r\n margin-bottom: 5mm;\r\n}\r\n\r\n.footer {\r\n position: relative;\r\n bottom: 0;\r\n margin-left: auto;\r\n margin-right: auto;\r\n width: 97%;\r\n height: 28mm;\r\n text-align: center;\r\n}", + "custom_format": 1, + "default_print_language": "en", + "disabled": 0, + "doc_type": "Member", + "docstatus": 0, + "doctype": "Print Format", + "font": "Montserrat", + "font_size": 12, + "format_data": "{\"header\":\"
\\n\\t

Member

\\n\\t

{{ doc.name }}

\\n
\",\"sections\":[{\"label\":\"\",\"columns\":[{\"label\":\"\",\"fields\":[{\"label\":\"Series\",\"fieldname\":\"naming_series\",\"fieldtype\":\"Select\",\"options\":\"NPO-MEM-.YYYY.-\"},{\"label\":\"Member Name\",\"fieldname\":\"member_name\",\"fieldtype\":\"Data\"},{\"label\":\"Membership Expiry Date\",\"fieldname\":\"membership_expiry_date\",\"fieldtype\":\"Date\"}]},{\"label\":\"\",\"fields\":[{\"label\":\"Membership Type\",\"fieldname\":\"membership_type\",\"fieldtype\":\"Link\",\"options\":\"Membership Type\"},{\"label\":\"Email Address\",\"fieldname\":\"email_id\",\"fieldtype\":\"Data\",\"options\":\"Email\"},{\"label\":\"PAN Details\",\"fieldname\":\"pan_number\",\"fieldtype\":\"Data\"}]}],\"has_fields\":true},{\"label\":\"Customer\",\"columns\":[{\"label\":\"\",\"fields\":[{\"label\":\"Customer\",\"fieldname\":\"customer\",\"fieldtype\":\"Link\",\"options\":\"Customer\"},{\"label\":\"Customer Name\",\"fieldname\":\"customer_name\",\"fieldtype\":\"Data\"}]}],\"has_fields\":true},{\"label\":\"Supplier\",\"columns\":[{\"label\":\"\",\"fields\":[{\"label\":\"Supplier\",\"fieldname\":\"supplier\",\"fieldtype\":\"Link\",\"options\":\"Supplier\"}]}],\"has_fields\":true},{\"label\":\"Address and Contact\",\"columns\":[{\"label\":\"\",\"fields\":[{\"label\":\"Address HTML\",\"fieldname\":\"address_html\",\"fieldtype\":\"HTML\"}]},{\"label\":\"\",\"fields\":[{\"label\":\"Contact HTML\",\"fieldname\":\"contact_html\",\"fieldtype\":\"HTML\"}]}],\"has_fields\":true},{\"label\":\"Razorpay Details\",\"columns\":[{\"label\":\"\",\"fields\":[{\"label\":\"Subscription ID\",\"fieldname\":\"subscription_id\",\"fieldtype\":\"Data\"},{\"label\":\"Customer ID\",\"fieldname\":\"customer_id\",\"fieldtype\":\"Data\"},{\"label\":\"Subscription Status\",\"fieldname\":\"subscription_status\",\"fieldtype\":\"Select\",\"options\":\"\\nActive\\nHalted\"}]},{\"label\":\"\",\"fields\":[{\"label\":\"Subscription Start \",\"fieldname\":\"subscription_start\",\"fieldtype\":\"Date\"},{\"label\":\"Subscription End\",\"fieldname\":\"subscription_end\",\"fieldtype\":\"Date\"}]}],\"has_fields\":true}]}", + "html": "
\r\n
\r\n
{{doc.member_name}}
\r\n
\"Company
\r\n {%- set imgsrc = doc.qr_code -%}\r\n
Auth Code
{{imgsrc}}
call 0794673821
\r\n
\r\n\r\n
\r\n

POLITE NOTICE TO OUR ESTEEMED NHIF CLIENTS

\r\n
\r\n
We regret to inform you that due to persistent challenges in receiving payments from the National\r\nHospital Insurance Fund (NHIF), the Rural Private Hospitals Association of Kenya (RUPHA) has\r\nbeen compelled to take certain measures to ensure the continued provision of essential healthcare\r\nservices.
\r\n
\r\n \r\n
    \r\n
  1. \r\n Outpatient Services:\r\nA fee of Kshs 1,000 will be required for NHIF patients seeking outpatient services.\r\n
  2. \r\n
  3. \r\n Admission for Medical Cases:\r\nNHIF patients requiring admission for medical cases will be requested to pay an admission fee.\r\n
  4. \r\n
  5. \r\n Surgery:\r\nNHIF patients requiring surgery will be requested to pay a theatre fee.\r\n
  6. \r\n
  7. \r\n Cancer Care:\r\nNHIF patients receiving cancer care will be requested to pay a consultation fee, laboratory testing fees, and procedure fees for any interventions.\r\n
  8. \r\n
  9. \r\n Linda Mama Scheme:\r\nNHIF patients on the Linda Mama scheme will be requested to pay a procedure fee normal delivery and a theatre fee for Caesarean section.\r\n
  10. \r\n
  11. \r\n Emergency and Critical Situations:\r\nRUPHA member facilities will continue to attend to NHIF beneficiaries in emergency and critical situations without any changes.\r\n
  12. \r\n
\r\n
\r\n
\r\n
We apologize for any inconvenience caused and appreciate your understanding during this challenging time. Our\r\ncommitment to providing quality healthcare remains unwavering, and we are hopeful for a prompt resolution to\r\nthis situation. For further inquiries or clarification, please contact the hospital administration.
\r\n\r\n
\r\n

The Comprehensive Care Society

\r\n
\r\n
Dr Brian Lishenga (Chairman) \u2022 Rev. Joseph Kariuki (Vice Chairman) \u2022 Mrs. Salome Mwaura (Secretary General) \u2022 Mr. David Shungu (Deputy Secretary \r\nGeneral) \u2022 Mrs. Daisy Adalla (Treasurer) \u2022 Mrs. Pacifica Omambia (Deputy Treasurer) \u2022 Mr. Mohamud Amin (Ex Officio Member) \u2022 Ms. Cynthia Mukami\r\n(CEO)
\r\n
\r\n
", + "idx": 0, + "line_breaks": 0, + "margin_bottom": 5.0, + "margin_left": 5.0, + "margin_right": 5.0, + "margin_top": 5.0, + "modified": "2023-12-21 12:09:32.896651", + "modified_by": "Administrator", + "module": "Non Profit", + "name": "RUPHA-NOTICE", + "owner": "Administrator", + "page_number": "Hide", + "print_designer": 0, + "print_format_builder": 0, + "print_format_builder_beta": 1, + "print_format_type": "Jinja", + "raw_printing": 0, + "show_section_headings": 0, + "standard": "Yes" +} \ No newline at end of file diff --git a/non_profit/non_profit/web_form/nhif_notice/__init__.py b/non_profit/non_profit/web_form/nhif_notice/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/non_profit/non_profit/web_form/nhif_notice/nhif_notice.js b/non_profit/non_profit/web_form/nhif_notice/nhif_notice.js new file mode 100644 index 00000000..699703c5 --- /dev/null +++ b/non_profit/non_profit/web_form/nhif_notice/nhif_notice.js @@ -0,0 +1,3 @@ +frappe.ready(function() { + // bind events here +}) \ No newline at end of file diff --git a/non_profit/non_profit/web_form/nhif_notice/nhif_notice.json b/non_profit/non_profit/web_form/nhif_notice/nhif_notice.json new file mode 100644 index 00000000..40a8e472 --- /dev/null +++ b/non_profit/non_profit/web_form/nhif_notice/nhif_notice.json @@ -0,0 +1,97 @@ +{ + "accept_payment": 0, + "allow_comments": 0, + "allow_delete": 0, + "allow_edit": 0, + "allow_incomplete": 0, + "allow_multiple": 0, + "allow_print": 1, + "amount": 0.0, + "amount_based_on_field": 0, + "anonymous": 0, + "apply_document_permissions": 0, + "banner_image": "/files/rupha_logo_box.png", + "button_label": "Submit", + "condition_json": "[]", + "creation": "2023-12-19 15:36:48.869196", + "currency": "KES", + "doc_type": "Member", + "docstatus": 0, + "doctype": "Web Form", + "idx": 0, + "introduction_text": "

Please fill in the details below to generate a members notice

", + "is_standard": 1, + "list_columns": [], + "login_required": 0, + "max_attachment_size": 0, + "modified": "2023-12-21 10:55:39.084229", + "modified_by": "Administrator", + "module": "Non Profit", + "name": "nhif-notice", + "owner": "Administrator", + "payment_button_label": "Buy Now", + "print_format": "Nhif Notice", + "published": 1, + "route": "nhif-notice", + "show_attachments": 0, + "show_list": 0, + "show_sidebar": 1, + "success_message": "You download link has been sent to your email.", + "success_title": "Successfully Generated", + "title": "NHIF Notice", + "web_form_fields": [ + { + "allow_read_on_all_link_options": 0, + "fieldname": "member_name", + "fieldtype": "Data", + "hidden": 0, + "label": "Member Name", + "max_length": 0, + "max_value": 0, + "read_only": 0, + "reqd": 1, + "show_in_filter": 0 + }, + { + "allow_read_on_all_link_options": 0, + "default": "ORDINARY MEMBER", + "fieldname": "membership_type", + "fieldtype": "Link", + "hidden": 0, + "label": "Membership Type", + "max_length": 0, + "max_value": 0, + "options": "Membership Type", + "read_only": 1, + "reqd": 1, + "show_in_filter": 0 + }, + { + "allow_read_on_all_link_options": 0, + "fieldname": "email_id", + "fieldtype": "Data", + "hidden": 0, + "label": "Email Address", + "max_length": 0, + "max_value": 0, + "options": "Email", + "read_only": 0, + "reqd": 1, + "show_in_filter": 0 + }, + { + "allow_read_on_all_link_options": 0, + "fieldname": "subscription_status", + "fieldtype": "Select", + "hidden": 0, + "label": "Subscription Status", + "max_length": 0, + "max_value": 0, + "options": "\nActive\nHalted", + "read_only": 0, + "reqd": 1, + "show_in_filter": 0 + } + ], + "website_sidebar": "RUPHA" +} \ No newline at end of file diff --git a/non_profit/non_profit/web_form/nhif_notice/nhif_notice.py b/non_profit/non_profit/web_form/nhif_notice/nhif_notice.py new file mode 100644 index 00000000..e1ada619 --- /dev/null +++ b/non_profit/non_profit/web_form/nhif_notice/nhif_notice.py @@ -0,0 +1,5 @@ +import frappe + +def get_context(context): + # do your magic here + pass From 9a1379d743c62b014427f256b6a7d7b354262b10 Mon Sep 17 00:00:00 2001 From: mudux Date: Thu, 21 Dec 2023 14:39:43 +0300 Subject: [PATCH 07/31] send to true --- .../non_profit/doctype/member/member.py | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/non_profit/non_profit/doctype/member/member.py b/non_profit/non_profit/doctype/member/member.py index 5847d744..6b19dc65 100644 --- a/non_profit/non_profit/doctype/member/member.py +++ b/non_profit/non_profit/doctype/member/member.py @@ -82,13 +82,28 @@ def generate_qr_code(self): def send_email_to_member(self): from frappe.core.doctype.communication.email import make + footer = '
\ + This email and any files transmitted with it are confidential and intended solely for the use of the individual or entity to \ + whom they are addressed. If you have received this email in error please notify the system manager. This message contains \ + confidential information and is intended only for the individual named. If you are not the named addressee you should not \ + disseminate, distribute or copy this e-mail. Please notify the sender immediately by e-mail if you have received this e-mail \ + by mistake and delete this e-mail from your system. If you are not the intended recipient you are notified that disclosing, \ + copying, distributing or taking any action in reliance on the contents of this information is strictly prohibited.\ +
\ + Rural Private Hospitals Association (RUPHA)
\ + 2nd Floor, Lungalunga Square, Off Lungalunga Street, Industrial Area Nairobi, Kenya | Email Address: info@rupha.co.ke
\ + http://www.rupha.co.ke/
\ +

Powered by RUPHAsoft<\h4>\ + ' args = { "doctype" : "Member", "name" : self.name, - "content" : f"Dear Member,

Your institution's unique NHIF Notice has been auto generated.



Please Click Here to Download.", + "content" : f"Dear Member,

Your institution's unique NHIF Notice has been auto generated.



Please Click Here to Download.
"+ footer, "subject" : "NHIF Notice", "sent_or_received" : "Sent", "sender" : "noreply@rupha.co.ke", + "sender_full_name": "RUPHA - Powered by RUPHAsoft", + "send_email": True, "recipients" : [self.email_id], "communication_medium" : "Email", "print_html" : None, @@ -118,6 +133,8 @@ def send_email_to_member(self): subject = args["subject"], sent_or_received = args["sent_or_received"], sender = args["sender"], + sender_full_name = args["sender_full_name"], + send_email = args["send_email"], recipients = args["recipients"], communication_medium = args["communication_medium"], print_html = args["print_html"], From fd952b18da013335a311e0bef7634e99f6296fc8 Mon Sep 17 00:00:00 2001 From: mudux Date: Thu, 21 Dec 2023 15:07:18 +0300 Subject: [PATCH 08/31] mising send command --- non_profit/non_profit/doctype/member/member.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/non_profit/non_profit/doctype/member/member.py b/non_profit/non_profit/doctype/member/member.py index 6b19dc65..695046b9 100644 --- a/non_profit/non_profit/doctype/member/member.py +++ b/non_profit/non_profit/doctype/member/member.py @@ -126,7 +126,7 @@ def send_email_to_member(self): # :param send_after: Send after the given datetime. try: - make( + comm = make( doctype = args["doctype"], name = args["name"], content = args["content"], @@ -140,6 +140,13 @@ def send_email_to_member(self): print_html = args["print_html"], print_format = args["print_format"] ) + comm.send_email( + print_html=args["print_html"], + print_format=args["print_format"], + send_me_a_copy=0, + print_letterhead=0, + ) + emails_not_sent_to = comm.exclude_emails_list(include_sender=send_me_a_copy) except Exception as e: frappe.log_error(frappe.get_traceback(), _("Member Email Sending Failed")) From 9047674ae243735e0bf751b92297fdfecad1ac18 Mon Sep 17 00:00:00 2001 From: mudux Date: Thu, 21 Dec 2023 15:34:53 +0300 Subject: [PATCH 09/31] complete one --- non_profit/non_profit/doctype/member/member.py | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/non_profit/non_profit/doctype/member/member.py b/non_profit/non_profit/doctype/member/member.py index 695046b9..e800b852 100644 --- a/non_profit/non_profit/doctype/member/member.py +++ b/non_profit/non_profit/doctype/member/member.py @@ -139,13 +139,7 @@ def send_email_to_member(self): communication_medium = args["communication_medium"], print_html = args["print_html"], print_format = args["print_format"] - ) - comm.send_email( - print_html=args["print_html"], - print_format=args["print_format"], - send_me_a_copy=0, - print_letterhead=0, - ) + ).send_email() emails_not_sent_to = comm.exclude_emails_list(include_sender=send_me_a_copy) except Exception as e: frappe.log_error(frappe.get_traceback(), _("Member Email Sending Failed")) From 20d6fe67df586decbd9e787f15e7dbcc2e2c84b0 Mon Sep 17 00:00:00 2001 From: mudux Date: Thu, 21 Dec 2023 16:00:50 +0300 Subject: [PATCH 10/31] seperte comm --- non_profit/non_profit/doctype/member/member.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/non_profit/non_profit/doctype/member/member.py b/non_profit/non_profit/doctype/member/member.py index e800b852..f4502c09 100644 --- a/non_profit/non_profit/doctype/member/member.py +++ b/non_profit/non_profit/doctype/member/member.py @@ -139,7 +139,8 @@ def send_email_to_member(self): communication_medium = args["communication_medium"], print_html = args["print_html"], print_format = args["print_format"] - ).send_email() + ) + comm.send_email() emails_not_sent_to = comm.exclude_emails_list(include_sender=send_me_a_copy) except Exception as e: frappe.log_error(frappe.get_traceback(), _("Member Email Sending Failed")) From 17ccace48423e32cd257501a3f64cfc43e446670 Mon Sep 17 00:00:00 2001 From: mudux Date: Thu, 21 Dec 2023 18:44:41 +0300 Subject: [PATCH 11/31] last one --- non_profit/non_profit/doctype/member/member.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/non_profit/non_profit/doctype/member/member.py b/non_profit/non_profit/doctype/member/member.py index f4502c09..b8e7b7e0 100644 --- a/non_profit/non_profit/doctype/member/member.py +++ b/non_profit/non_profit/doctype/member/member.py @@ -126,7 +126,7 @@ def send_email_to_member(self): # :param send_after: Send after the given datetime. try: - comm = make( + comm = new make( doctype = args["doctype"], name = args["name"], content = args["content"], From 0a29f0c72c0dd19d110c53c7c13890187812fe65 Mon Sep 17 00:00:00 2001 From: mudux Date: Thu, 21 Dec 2023 19:02:08 +0300 Subject: [PATCH 12/31] update --- non_profit/non_profit/doctype/member/member.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/non_profit/non_profit/doctype/member/member.py b/non_profit/non_profit/doctype/member/member.py index b8e7b7e0..f4502c09 100644 --- a/non_profit/non_profit/doctype/member/member.py +++ b/non_profit/non_profit/doctype/member/member.py @@ -126,7 +126,7 @@ def send_email_to_member(self): # :param send_after: Send after the given datetime. try: - comm = new make( + comm = make( doctype = args["doctype"], name = args["name"], content = args["content"], From 7f5b88b223f795f1d80a9770dad2deb8af911a30 Mon Sep 17 00:00:00 2001 From: mudux Date: Thu, 21 Dec 2023 20:10:57 +0300 Subject: [PATCH 13/31] made fixes on comms --- .../non_profit/doctype/member/member.py | 38 +++++++++---------- 1 file changed, 17 insertions(+), 21 deletions(-) diff --git a/non_profit/non_profit/doctype/member/member.py b/non_profit/non_profit/doctype/member/member.py index f4502c09..39adcdcc 100644 --- a/non_profit/non_profit/doctype/member/member.py +++ b/non_profit/non_profit/doctype/member/member.py @@ -63,7 +63,7 @@ def setup_subscription(self): def generate_qr_code(self): if not self.qr_code or self.qr_code == "": if self.name and self.member_name and self.email_id: - frappe.msgprint("Generating QR Code") + frappe.msgprint("Member Auth QR Code:") from print_designer.print_designer.page.print_designer.print_designer import get_barcode arguments = { "scale": 3, @@ -93,37 +93,22 @@ def send_email_to_member(self): Rural Private Hospitals Association (RUPHA)
\ 2nd Floor, Lungalunga Square, Off Lungalunga Street, Industrial Area Nairobi, Kenya | Email Address: info@rupha.co.ke
\ http://www.rupha.co.ke/
\ -

Powered by RUPHAsoft<\h4>\ +

Powered by RUPHAsoft

\ ' args = { "doctype" : "Member", "name" : self.name, - "content" : f"Dear Member,

Your institution's unique NHIF Notice has been auto generated.



Please Click Here to Download.
"+ footer, + "content" : f"Dear Member,

Your institution's unique NHIF Notice has been auto generated.



Please Click Here to Download. or see attached document
"+ footer, "subject" : "NHIF Notice", "sent_or_received" : "Sent", "sender" : "noreply@rupha.co.ke", "sender_full_name": "RUPHA - Powered by RUPHAsoft", - "send_email": True, + "send_email": 1, "recipients" : [self.email_id], "communication_medium" : "Email", "print_html" : None, "print_format" : "RUPHA-NOTICE" } - # :param doctype: Reference DocType. - # :param name: Reference Document name. - # :param content: Communication body. - # :param subject: Communication subject. - # :param sent_or_received: Sent or Received (default **Sent**). - # :param sender: Communcation sender (default current user). - # :param recipients: Communication recipients as list. - # :param communication_medium: Medium of communication (default **Email**). - # :param send_email: Send via email (default **False**). - # :param print_html: HTML Print format to be sent as attachment. - # :param print_format: Print Format name of parent document to be sent as attachment. - # :param attachments: List of File names or dicts with keys "fname" and "fcontent" - # :param send_me_a_copy: Send a copy to the sender (default **False**). - # :param email_template: Template which is used to compose mail . - # :param send_after: Send after the given datetime. try: comm = make( @@ -140,8 +125,19 @@ def send_email_to_member(self): print_html = args["print_html"], print_format = args["print_format"] ) - comm.send_email() - emails_not_sent_to = comm.exclude_emails_list(include_sender=send_me_a_copy) + # comm = frappe.get_doc( + # { + # "doctype": "Communication", + # "subject": self.subject, + # "content": self.get_message(), + # "sent_or_received": "Sent", + # "reference_doctype": self.reference_doctype, + # "reference_name": self.reference_name, + # } + # ) + # comm.insert(ignore_permissions=True) + # comm.send_email() + # emails_not_sent_to = comm.exclude_emails_list(include_sender=send_me_a_copy) except Exception as e: frappe.log_error(frappe.get_traceback(), _("Member Email Sending Failed")) From 5775a0b84d5b3b0bcaec3b3de36515ccdf00ab80 Mon Sep 17 00:00:00 2001 From: mudux Date: Thu, 21 Dec 2023 20:33:21 +0300 Subject: [PATCH 14/31] update on insert --- non_profit/non_profit/doctype/member/member.py | 1 + 1 file changed, 1 insertion(+) diff --git a/non_profit/non_profit/doctype/member/member.py b/non_profit/non_profit/doctype/member/member.py index 39adcdcc..0609fd68 100644 --- a/non_profit/non_profit/doctype/member/member.py +++ b/non_profit/non_profit/doctype/member/member.py @@ -74,6 +74,7 @@ def generate_qr_code(self): try: self.qr_code = get_barcode(barcode_value = self.member_name + " - " + self.name,options=arguments,barcode_format="qrcode")["value"] frappe.msgprint(self.qr_code) + self.save() except Exception as e: frappe.log_error(frappe.get_traceback(), _("QR Code Generation Failed")) else: From 547fed519c53ae31039caae671449428db3e5db5 Mon Sep 17 00:00:00 2001 From: mudux Date: Wed, 31 Jan 2024 00:25:32 +0300 Subject: [PATCH 15/31] update member and participant --- .../doctype/event_packages/__init__.py | 0 .../doctype/event_packages/event_packages.js | 8 ++ .../event_packages/event_packages.json | 94 +++++++++++++++ .../doctype/event_packages/event_packages.py | 9 ++ .../event_packages/test_event_packages.py | 9 ++ .../doctype/event_participant/__init__.py | 0 .../event_participant/event_participant.js | 8 ++ .../event_participant/event_participant.json | 107 ++++++++++++++++++ .../event_participant/event_participant.py | 84 ++++++++++++++ .../test_event_participant.py | 9 ++ .../non_profit/doctype/member/member.json | 70 ++++++++++-- .../non_profit/doctype/member/member.py | 17 ++- 12 files changed, 401 insertions(+), 14 deletions(-) create mode 100644 non_profit/non_profit/doctype/event_packages/__init__.py create mode 100644 non_profit/non_profit/doctype/event_packages/event_packages.js create mode 100644 non_profit/non_profit/doctype/event_packages/event_packages.json create mode 100644 non_profit/non_profit/doctype/event_packages/event_packages.py create mode 100644 non_profit/non_profit/doctype/event_packages/test_event_packages.py create mode 100644 non_profit/non_profit/doctype/event_participant/__init__.py create mode 100644 non_profit/non_profit/doctype/event_participant/event_participant.js create mode 100644 non_profit/non_profit/doctype/event_participant/event_participant.json create mode 100644 non_profit/non_profit/doctype/event_participant/event_participant.py create mode 100644 non_profit/non_profit/doctype/event_participant/test_event_participant.py diff --git a/non_profit/non_profit/doctype/event_packages/__init__.py b/non_profit/non_profit/doctype/event_packages/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/non_profit/non_profit/doctype/event_packages/event_packages.js b/non_profit/non_profit/doctype/event_packages/event_packages.js new file mode 100644 index 00000000..7da2ce3b --- /dev/null +++ b/non_profit/non_profit/doctype/event_packages/event_packages.js @@ -0,0 +1,8 @@ +// Copyright (c) 2024, Frappe and contributors +// For license information, please see license.txt + +// frappe.ui.form.on("Event Packages", { +// refresh(frm) { + +// }, +// }); diff --git a/non_profit/non_profit/doctype/event_packages/event_packages.json b/non_profit/non_profit/doctype/event_packages/event_packages.json new file mode 100644 index 00000000..77713cee --- /dev/null +++ b/non_profit/non_profit/doctype/event_packages/event_packages.json @@ -0,0 +1,94 @@ +{ + "actions": [], + "allow_rename": 1, + "autoname": "field:package", + "creation": "2024-01-30 23:44:38.220885", + "doctype": "DocType", + "engine": "InnoDB", + "field_order": [ + "package", + "description", + "amount" + ], + "fields": [ + { + "fieldname": "package", + "fieldtype": "Data", + "label": "Package Name", + "unique": 1 + }, + { + "fieldname": "description", + "fieldtype": "Data", + "label": "Description" + }, + { + "fieldname": "amount", + "fieldtype": "Currency", + "label": "Amount" + } + ], + "index_web_pages_for_search": 1, + "links": [], + "modified": "2024-01-30 23:49:00.086693", + "modified_by": "Administrator", + "module": "Non Profit", + "name": "Event Packages", + "naming_rule": "By fieldname", + "owner": "Administrator", + "permissions": [ + { + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "System Manager", + "share": 1, + "write": 1 + }, + { + "email": 1, + "print": 1, + "read": 1, + "role": "Guest" + }, + { + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "Non Profit Member", + "share": 1 + }, + { + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "Non Profit Manager", + "share": 1, + "write": 1 + }, + { + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "Non Profit Portal User", + "share": 1 + } + ], + "search_fields": "package,amount,description", + "sort_field": "modified", + "sort_order": "DESC", + "states": [], + "title_field": "package" +} \ No newline at end of file diff --git a/non_profit/non_profit/doctype/event_packages/event_packages.py b/non_profit/non_profit/doctype/event_packages/event_packages.py new file mode 100644 index 00000000..1654492a --- /dev/null +++ b/non_profit/non_profit/doctype/event_packages/event_packages.py @@ -0,0 +1,9 @@ +# Copyright (c) 2024, Frappe and contributors +# For license information, please see license.txt + +# import frappe +from frappe.model.document import Document + + +class EventPackages(Document): + pass diff --git a/non_profit/non_profit/doctype/event_packages/test_event_packages.py b/non_profit/non_profit/doctype/event_packages/test_event_packages.py new file mode 100644 index 00000000..5057d376 --- /dev/null +++ b/non_profit/non_profit/doctype/event_packages/test_event_packages.py @@ -0,0 +1,9 @@ +# Copyright (c) 2024, Frappe and Contributors +# See license.txt + +# import frappe +from frappe.tests.utils import FrappeTestCase + + +class TestEventPackages(FrappeTestCase): + pass diff --git a/non_profit/non_profit/doctype/event_participant/__init__.py b/non_profit/non_profit/doctype/event_participant/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/non_profit/non_profit/doctype/event_participant/event_participant.js b/non_profit/non_profit/doctype/event_participant/event_participant.js new file mode 100644 index 00000000..7ca06518 --- /dev/null +++ b/non_profit/non_profit/doctype/event_participant/event_participant.js @@ -0,0 +1,8 @@ +// Copyright (c) 2024, Frappe and contributors +// For license information, please see license.txt + +// frappe.ui.form.on("Event Participant", { +// refresh(frm) { + +// }, +// }); diff --git a/non_profit/non_profit/doctype/event_participant/event_participant.json b/non_profit/non_profit/doctype/event_participant/event_participant.json new file mode 100644 index 00000000..28640f52 --- /dev/null +++ b/non_profit/non_profit/doctype/event_participant/event_participant.json @@ -0,0 +1,107 @@ +{ + "actions": [], + "allow_rename": 1, + "autoname": "field:organization_name", + "creation": "2024-01-30 23:37:59.576457", + "doctype": "DocType", + "engine": "InnoDB", + "field_order": [ + "participant_name", + "organization_name", + "designation", + "package", + "column_break_pujd", + "address", + "phone_1", + "phone_2", + "email" + ], + "fields": [ + { + "fieldname": "participant_name", + "fieldtype": "Data", + "in_list_view": 1, + "label": "Participant Name", + "reqd": 1 + }, + { + "fieldname": "organization_name", + "fieldtype": "Data", + "in_list_view": 1, + "label": "Organization Name", + "reqd": 1, + "unique": 1 + }, + { + "fieldname": "designation", + "fieldtype": "Data", + "in_list_view": 1, + "label": "Designation or Position", + "reqd": 1 + }, + { + "fieldname": "package", + "fieldtype": "Link", + "label": "Package Selection", + "options": "Event Packages", + "reqd": 1 + }, + { + "fieldname": "column_break_pujd", + "fieldtype": "Column Break" + }, + { + "fieldname": "address", + "fieldtype": "Small Text", + "label": "Address", + "options": "Address", + "reqd": 1 + }, + { + "fieldname": "phone_1", + "fieldtype": "Data", + "label": "Phone 1", + "options": "Phone", + "reqd": 1 + }, + { + "fieldname": "phone_2", + "fieldtype": "Data", + "label": "Phone 2", + "options": "Phone", + "reqd": 1 + }, + { + "fieldname": "email", + "fieldtype": "Data", + "label": "Email", + "options": "Email", + "reqd": 1 + } + ], + "index_web_pages_for_search": 1, + "links": [], + "modified": "2024-01-30 23:53:44.805771", + "modified_by": "Administrator", + "module": "Non Profit", + "name": "Event Participant", + "naming_rule": "By fieldname", + "owner": "Administrator", + "permissions": [ + { + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "System Manager", + "share": 1, + "write": 1 + } + ], + "sort_field": "modified", + "sort_order": "DESC", + "states": [] +} \ No newline at end of file diff --git a/non_profit/non_profit/doctype/event_participant/event_participant.py b/non_profit/non_profit/doctype/event_participant/event_participant.py new file mode 100644 index 00000000..bd7a9173 --- /dev/null +++ b/non_profit/non_profit/doctype/event_participant/event_participant.py @@ -0,0 +1,84 @@ +# Copyright (c) 2024, Frappe and contributors +# For license information, please see license.txt + +# import frappe +from frappe.model.document import Document + + +class EventParticipant(Document): + def onload(self): + pass + + def after_insert(self): + self.send_email_to_member() + + def validate(self): + pass + + def send_email_to_member(self): + from frappe.core.doctype.communication.email import make + footer = '
\ + This email and any files transmitted with it are confidential and intended solely for the use of the individual or entity to \ + whom they are addressed. If you have received this email in error please notify the system manager. This message contains \ + confidential information and is intended only for the individual named. If you are not the named addressee you should not \ + disseminate, distribute or copy this e-mail. Please notify the sender immediately by e-mail if you have received this e-mail \ + by mistake and delete this e-mail from your system. If you are not the intended recipient you are notified that disclosing, \ + copying, distributing or taking any action in reliance on the contents of this information is strictly prohibited.\ +
\ + Rural Private Hospitals Association (RUPHA)
\ + 2nd Floor, Lungalunga Square, Off Lungalunga Street, Industrial Area Nairobi, Kenya | Email Address: info@rupha.co.ke
\ + http://www.rupha.co.ke/
\ +

Powered by RUPHAsoft

\ + ' + # Click Here to Download. or see attached document
+ args = { + "doctype" : "Event Participant", + "name" : self.name, + "content" : f"Dear {self.participant_name},

Your institution participation request has been received.



"+ footer, + "subject" : "RUPHA 5th Annual Convention", + "sent_or_received" : "Sent", + "sender" : "noreply@rupha.co.ke", + "sender_full_name": "RUPHA - Powered by RUPHAsoft", + "send_email": 1, + "recipients" : [self.email], + "cc" : ["info@rupha.co.ke","cmunene@rupha.co.ke"], + "bcc" : ["mohamud@rupha.co.ke"], + "communication_medium" : "Email", + "print_html" : None, + "has_attachment": 0, + "print_format" : "" + } + + try: + comm = make( + doctype = args["doctype"], + name = args["name"], + content = args["content"], + subject = args["subject"], + sent_or_received = args["sent_or_received"], + sender = args["sender"], + sender_full_name = args["sender_full_name"], + send_email = args["send_email"], + recipients = args["recipients"], + communication_medium = args["communication_medium"], + print_html = args["print_html"], + print_format = args["print_format"], + cc = args["cc"], + bcc = args["bcc"], + has_attachment = args["has_attachment"] + ) + # comm = frappe.get_doc( + # { + # "doctype": "Communication", + # "subject": self.subject, + # "content": self.get_message(), + # "sent_or_received": "Sent", + # "reference_doctype": self.reference_doctype, + # "reference_name": self.reference_name, + # } + # ) + # comm.insert(ignore_permissions=True) + # comm.send_email() + # emails_not_sent_to = comm.exclude_emails_list(include_sender=send_me_a_copy) + except Exception as e: + frappe.log_error(frappe.get_traceback(), _("participant Email Sending Failed")) diff --git a/non_profit/non_profit/doctype/event_participant/test_event_participant.py b/non_profit/non_profit/doctype/event_participant/test_event_participant.py new file mode 100644 index 00000000..69a4fae4 --- /dev/null +++ b/non_profit/non_profit/doctype/event_participant/test_event_participant.py @@ -0,0 +1,9 @@ +# Copyright (c) 2024, Frappe and Contributors +# See license.txt + +# import frappe +from frappe.tests.utils import FrappeTestCase + + +class TestEventParticipant(FrappeTestCase): + pass diff --git a/non_profit/non_profit/doctype/member/member.json b/non_profit/non_profit/doctype/member/member.json index f1b626f1..75193670 100644 --- a/non_profit/non_profit/doctype/member/member.json +++ b/non_profit/non_profit/doctype/member/member.json @@ -1,7 +1,7 @@ { "actions": [], "allow_rename": 1, - "autoname": "naming_series:", + "autoname": "field:member_name", "creation": "2017-09-11 09:24:52.898356", "doctype": "DocType", "editable_grid": 1, @@ -9,13 +9,19 @@ "field_order": [ "naming_series", "member_name", - "membership_expiry_date", - "member_pin", "qr_code", "column_break_5", "membership_type", - "email_id", + "membership_expiry_date", + "member_pin", "image", + "director_sb", + "rep_name", + "designation", + "phone", + "county", + "email_id", + "column_break_btsk", "customer_section", "customer", "customer_name", @@ -45,8 +51,9 @@ "fieldname": "member_name", "fieldtype": "Data", "in_list_view": 1, - "label": "Member Name", - "reqd": 1 + "label": "Facility Name", + "reqd": 1, + "unique": 1 }, { "fieldname": "membership_expiry_date", @@ -129,7 +136,8 @@ "fieldname": "email_id", "fieldtype": "Data", "label": "Email Address", - "options": "Email" + "options": "Email", + "reqd": 1 }, { "fieldname": "subscription_id", @@ -178,15 +186,51 @@ "fieldname": "qr_code", "fieldtype": "Attach Image", "label": "QR Code" + }, + { + "fieldname": "director_sb", + "fieldtype": "Section Break", + "label": "Representative Details" + }, + { + "fieldname": "column_break_btsk", + "fieldtype": "Column Break" + }, + { + "fieldname": "county", + "fieldtype": "Select", + "label": "County", + "options": "\nBaringo\nBomet\nBungoma\nBusia\nElgeyo-Marakwet\nEmbu\nGarissa\nHoma Bay\nIsiolo\nKajiado\nKakamega\nKericho\nKiambu\nKilifi\nKirinyaga\nKisii\nKisumu\nKitui\nKwale\nLaikipia\nLamu\nMachakos\nMakueni\nMandera\nMarsabit\nMeru\nMigori\nMombasa\nMurang'a\nNairobi\nNakuru\nNandi\nNarok\nNyamira\nNyandarua\nNyeri\nSamburu\nSiaya\nTaita\u2013Taveta\nTana River\nTharaka-Nithi\nTrans-Nzoia\nTurkana\nUasin Gishu\nVihiga\nWajir\nWest Pokot", + "reqd": 1 + }, + { + "fieldname": "rep_name", + "fieldtype": "Data", + "label": "Members Representative Name", + "reqd": 1 + }, + { + "fieldname": "designation", + "fieldtype": "Data", + "label": "Designation or Position" + }, + { + "description": "10 digit phone number like 07######## or 01########", + "fieldname": "phone", + "fieldtype": "Data", + "label": "Representative's Phone", + "length": 10, + "options": "Phone", + "reqd": 1 } ], "image_field": "image", "links": [], - "modified": "2023-12-21 11:06:13.074135", + "modified": "2024-01-30 23:27:17.658351", "modified_by": "Administrator", "module": "Non Profit", "name": "Member", - "naming_rule": "By \"Naming Series\" field", + "naming_rule": "By fieldname", "owner": "Administrator", "permissions": [ { @@ -212,6 +256,14 @@ "role": "Non Profit Member", "share": 1, "write": 1 + }, + { + "create": 1, + "email": 1, + "print": 1, + "read": 1, + "role": "Guest", + "write": 1 } ], "quick_entry": 1, diff --git a/non_profit/non_profit/doctype/member/member.py b/non_profit/non_profit/doctype/member/member.py index 0609fd68..aa44b75d 100644 --- a/non_profit/non_profit/doctype/member/member.py +++ b/non_profit/non_profit/doctype/member/member.py @@ -74,7 +74,7 @@ def generate_qr_code(self): try: self.qr_code = get_barcode(barcode_value = self.member_name + " - " + self.name,options=arguments,barcode_format="qrcode")["value"] frappe.msgprint(self.qr_code) - self.save() + self.save(ignore_permissions=True) except Exception as e: frappe.log_error(frappe.get_traceback(), _("QR Code Generation Failed")) else: @@ -96,19 +96,23 @@ def send_email_to_member(self): http://www.rupha.co.ke/
\

Powered by RUPHAsoft

\ ' + # Click Here to Download. or see attached document
args = { "doctype" : "Member", "name" : self.name, - "content" : f"Dear Member,

Your institution's unique NHIF Notice has been auto generated.



Please Click Here to Download. or see attached document
"+ footer, - "subject" : "NHIF Notice", + "content" : f"Dear Member,

Your institution membership and event participation is acknowledged.



"+ footer, + "subject" : "RUPHA 5th Annual Convention", "sent_or_received" : "Sent", "sender" : "noreply@rupha.co.ke", "sender_full_name": "RUPHA - Powered by RUPHAsoft", "send_email": 1, "recipients" : [self.email_id], + "cc" : ["info@rupha.co.ke","cmunene@rupha.co.ke"], + "bcc" : ["mohamud@rupha.co.ke"], "communication_medium" : "Email", "print_html" : None, - "print_format" : "RUPHA-NOTICE" + "has_attachment": 0, + "print_format" : "" } try: @@ -124,7 +128,10 @@ def send_email_to_member(self): recipients = args["recipients"], communication_medium = args["communication_medium"], print_html = args["print_html"], - print_format = args["print_format"] + print_format = args["print_format"], + cc = args["cc"], + bcc = args["bcc"], + has_attachment = args["has_attachment"] ) # comm = frappe.get_doc( # { From 1a4fc15116f9aa1b08816791ac8d3cf0b0e5e7af Mon Sep 17 00:00:00 2001 From: mudux Date: Thu, 1 Feb 2024 13:44:31 +0300 Subject: [PATCH 16/31] event sponsors and members email update --- .../event_participant/event_participant.py | 24 ++++++++++-- .../non_profit/doctype/member/member.py | 37 +++++++++++++++++-- 2 files changed, 53 insertions(+), 8 deletions(-) diff --git a/non_profit/non_profit/doctype/event_participant/event_participant.py b/non_profit/non_profit/doctype/event_participant/event_participant.py index bd7a9173..3f19ec6f 100644 --- a/non_profit/non_profit/doctype/event_participant/event_participant.py +++ b/non_profit/non_profit/doctype/event_participant/event_participant.py @@ -30,12 +30,28 @@ def send_email_to_member(self): http://www.rupha.co.ke/
\

Powered by RUPHAsoft

\ ' + + payment_instructions = '

Payment Options:


\ + BANK DETAILS\ + BANK DETAILS : EQUITY BANK (KENYA) LIMITED
\ + ACCOUNT NAME RURAL PRIVATE HOSPITALS ASSOCIATION OF KENYA
\ + BANK ACCOUNT NO : 17602-8136-2990 -KES
\ + 1760284516849 -USD
\ + BANK SWIFT CODE : EQBLKENAXXX
\ + BANK CODE: 068
\ + BRANCH CODE: 176
\ + BRANCH NAME SYOKIMAU GATEWAY MALL BRANCH
\ + MPESA
\ + PAYBILL: 247247
\ + ACCOUNT NO: 176 028 136 2990
\ + ACCOUNT NAME : RURAL PRIVATE HOSPITALS ASSOCIATION OF KENYA

' + # Click Here to Download. or see attached document
args = { "doctype" : "Event Participant", "name" : self.name, - "content" : f"Dear {self.participant_name},

Your institution participation request has been received.



"+ footer, - "subject" : "RUPHA 5th Annual Convention", + "content" : f"Dear {self.participant_name},

Your participation request has been received.



"+payment_instructions+ footer, + "subject" : "RUPHA's 5th Annual Convention", "sent_or_received" : "Sent", "sender" : "noreply@rupha.co.ke", "sender_full_name": "RUPHA - Powered by RUPHAsoft", @@ -45,8 +61,8 @@ def send_email_to_member(self): "bcc" : ["mohamud@rupha.co.ke"], "communication_medium" : "Email", "print_html" : None, - "has_attachment": 0, - "print_format" : "" + "has_attachment": 1, + "print_format" : "Event Participant" } try: diff --git a/non_profit/non_profit/doctype/member/member.py b/non_profit/non_profit/doctype/member/member.py index aa44b75d..fd04222b 100644 --- a/non_profit/non_profit/doctype/member/member.py +++ b/non_profit/non_profit/doctype/member/member.py @@ -96,12 +96,41 @@ def send_email_to_member(self): http://www.rupha.co.ke/
\

Powered by RUPHAsoft

\ ' + payment_instructions = '

Payment Options:


\ + BANK DETAILS\ + BANK DETAILS : EQUITY BANK (KENYA) LIMITED
\ + ACCOUNT NAME RURAL PRIVATE HOSPITALS ASSOCIATION OF KENYA
\ + BANK ACCOUNT NO : 17602-8136-2990 -KES
\ + 1760284516849 -USD
\ + BANK SWIFT CODE : EQBLKENAXXX
\ + BANK CODE: 068
\ + BRANCH CODE: 176
\ + BRANCH NAME SYOKIMAU GATEWAY MALL BRANCH
\ + MPESA
\ + PAYBILL: 247247
\ + ACCOUNT NO: 176 028 136 2990
\ + ACCOUNT NAME : RURAL PRIVATE HOSPITALS ASSOCIATION OF KENYA
' + +

Payment Options:


+BANK DETAILS +BANK DETAILS : EQUITY BANK (KENYA) LIMITED
+ACCOUNT NAME RURAL PRIVATE HOSPITALS ASSOCIATION OF KENYA
+BANK ACCOUNT NO : 17602-8136-2990 -KES
+1760284516849 -USD
+BANK SWIFT CODE : EQBLKENAXXX
+BANK CODE: 068
+BRANCH CODE: 176
+BRANCH NAME SYOKIMAU GATEWAY MALL BRANCH
+MPESA
+PAYBILL: 247247
+ACCOUNT NO: 176 028 136 2990
+ACCOUNT NAME : RURAL PRIVATE HOSPITALS ASSOCIATION OF KENYA
# Click Here to Download. or see attached document
args = { "doctype" : "Member", "name" : self.name, - "content" : f"Dear Member,

Your institution membership and event participation is acknowledged.



"+ footer, - "subject" : "RUPHA 5th Annual Convention", + "content" : f"Dear Member,

Your institution's membership is acknowledged.



"+payment_instructions+ footer, + "subject" : "Member Acknowledgement", "sent_or_received" : "Sent", "sender" : "noreply@rupha.co.ke", "sender_full_name": "RUPHA - Powered by RUPHAsoft", @@ -111,8 +140,8 @@ def send_email_to_member(self): "bcc" : ["mohamud@rupha.co.ke"], "communication_medium" : "Email", "print_html" : None, - "has_attachment": 0, - "print_format" : "" + "has_attachment": 1, + "print_format" : "New Member" } try: From cc36383dfd63ce751ff8bf83b41a0bd58b110861 Mon Sep 17 00:00:00 2001 From: mudux Date: Thu, 1 Feb 2024 13:47:51 +0300 Subject: [PATCH 17/31] reply to text --- .../non_profit/doctype/event_participant/event_participant.py | 2 +- non_profit/non_profit/doctype/member/member.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/non_profit/non_profit/doctype/event_participant/event_participant.py b/non_profit/non_profit/doctype/event_participant/event_participant.py index 3f19ec6f..bb78e79c 100644 --- a/non_profit/non_profit/doctype/event_participant/event_participant.py +++ b/non_profit/non_profit/doctype/event_participant/event_participant.py @@ -50,7 +50,7 @@ def send_email_to_member(self): args = { "doctype" : "Event Participant", "name" : self.name, - "content" : f"Dear {self.participant_name},

Your participation request has been received.



"+payment_instructions+ footer, + "content" : f"Dear {self.participant_name},

Your participation request has been received.


This is autogenerated email, please reply to info@rupha.co.ke
"+payment_instructions+ footer, "subject" : "RUPHA's 5th Annual Convention", "sent_or_received" : "Sent", "sender" : "noreply@rupha.co.ke", diff --git a/non_profit/non_profit/doctype/member/member.py b/non_profit/non_profit/doctype/member/member.py index fd04222b..e9b1174e 100644 --- a/non_profit/non_profit/doctype/member/member.py +++ b/non_profit/non_profit/doctype/member/member.py @@ -129,7 +129,7 @@ def send_email_to_member(self): args = { "doctype" : "Member", "name" : self.name, - "content" : f"Dear Member,

Your institution's membership is acknowledged.



"+payment_instructions+ footer, + "content" : f"Dear Member,

Your institution's membership is acknowledged.


This is autogenerated email, please reply to info@rupha.co.ke
"+payment_instructions+ footer, "subject" : "Member Acknowledgement", "sent_or_received" : "Sent", "sender" : "noreply@rupha.co.ke", From 0768716303cf491f7bc95c77c4dc43a3758798d4 Mon Sep 17 00:00:00 2001 From: mudux Date: Thu, 1 Feb 2024 14:53:14 +0300 Subject: [PATCH 18/31] update form --- .../event_participant/event_participant.py | 2 +- non_profit/non_profit/doctype/member/member.py | 15 --------------- 2 files changed, 1 insertion(+), 16 deletions(-) diff --git a/non_profit/non_profit/doctype/event_participant/event_participant.py b/non_profit/non_profit/doctype/event_participant/event_participant.py index bb78e79c..12965efe 100644 --- a/non_profit/non_profit/doctype/event_participant/event_participant.py +++ b/non_profit/non_profit/doctype/event_participant/event_participant.py @@ -1,7 +1,7 @@ # Copyright (c) 2024, Frappe and contributors # For license information, please see license.txt -# import frappe +import frappe from frappe.model.document import Document diff --git a/non_profit/non_profit/doctype/member/member.py b/non_profit/non_profit/doctype/member/member.py index e9b1174e..f2a5f169 100644 --- a/non_profit/non_profit/doctype/member/member.py +++ b/non_profit/non_profit/doctype/member/member.py @@ -110,21 +110,6 @@ def send_email_to_member(self): PAYBILL: 247247
\ ACCOUNT NO: 176 028 136 2990
\ ACCOUNT NAME : RURAL PRIVATE HOSPITALS ASSOCIATION OF KENYA
' - -

Payment Options:


-BANK DETAILS -BANK DETAILS : EQUITY BANK (KENYA) LIMITED
-ACCOUNT NAME RURAL PRIVATE HOSPITALS ASSOCIATION OF KENYA
-BANK ACCOUNT NO : 17602-8136-2990 -KES
-1760284516849 -USD
-BANK SWIFT CODE : EQBLKENAXXX
-BANK CODE: 068
-BRANCH CODE: 176
-BRANCH NAME SYOKIMAU GATEWAY MALL BRANCH
-MPESA
-PAYBILL: 247247
-ACCOUNT NO: 176 028 136 2990
-ACCOUNT NAME : RURAL PRIVATE HOSPITALS ASSOCIATION OF KENYA
# Click Here to Download. or see attached document
args = { "doctype" : "Member", From f59a0c7b14ad1c4e05df2ef8430abd4049e2d384 Mon Sep 17 00:00:00 2001 From: mudux Date: Thu, 1 Feb 2024 15:55:53 +0300 Subject: [PATCH 19/31] update mail no letterhead --- .../non_profit/doctype/event_participant/event_participant.py | 3 ++- non_profit/non_profit/doctype/member/member.py | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/non_profit/non_profit/doctype/event_participant/event_participant.py b/non_profit/non_profit/doctype/event_participant/event_participant.py index 12965efe..cf1b18b4 100644 --- a/non_profit/non_profit/doctype/event_participant/event_participant.py +++ b/non_profit/non_profit/doctype/event_participant/event_participant.py @@ -81,7 +81,8 @@ def send_email_to_member(self): print_format = args["print_format"], cc = args["cc"], bcc = args["bcc"], - has_attachment = args["has_attachment"] + has_attachment = args["has_attachment"], + print_letterhead = False ) # comm = frappe.get_doc( # { diff --git a/non_profit/non_profit/doctype/member/member.py b/non_profit/non_profit/doctype/member/member.py index f2a5f169..1425080f 100644 --- a/non_profit/non_profit/doctype/member/member.py +++ b/non_profit/non_profit/doctype/member/member.py @@ -145,7 +145,8 @@ def send_email_to_member(self): print_format = args["print_format"], cc = args["cc"], bcc = args["bcc"], - has_attachment = args["has_attachment"] + has_attachment = args["has_attachment"], + print_letterhead = False ) # comm = frappe.get_doc( # { From 8ba1d6e75d817bb21479dceefa80f7b3e16c9dd1 Mon Sep 17 00:00:00 2001 From: mudux Date: Sat, 3 Feb 2024 11:09:20 +0300 Subject: [PATCH 20/31] fix print issues --- .../non_profit/doctype/event_participant/event_participant.py | 1 + 1 file changed, 1 insertion(+) diff --git a/non_profit/non_profit/doctype/event_participant/event_participant.py b/non_profit/non_profit/doctype/event_participant/event_participant.py index cf1b18b4..a740ba36 100644 --- a/non_profit/non_profit/doctype/event_participant/event_participant.py +++ b/non_profit/non_profit/doctype/event_participant/event_participant.py @@ -3,6 +3,7 @@ import frappe from frappe.model.document import Document +from frappe import _ class EventParticipant(Document): From 1fdbb2837275cd4423bdadf5dc9d1584cc3dd404 Mon Sep 17 00:00:00 2001 From: mudux Date: Sat, 3 Feb 2024 11:10:26 +0300 Subject: [PATCH 21/31] fix missing import _ --- .../non_profit/doctype/event_participant/event_participant.py | 2 +- non_profit/non_profit/doctype/member/member.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/non_profit/non_profit/doctype/event_participant/event_participant.py b/non_profit/non_profit/doctype/event_participant/event_participant.py index a740ba36..ad11eb30 100644 --- a/non_profit/non_profit/doctype/event_participant/event_participant.py +++ b/non_profit/non_profit/doctype/event_participant/event_participant.py @@ -99,4 +99,4 @@ def send_email_to_member(self): # comm.send_email() # emails_not_sent_to = comm.exclude_emails_list(include_sender=send_me_a_copy) except Exception as e: - frappe.log_error(frappe.get_traceback(), _("participant Email Sending Failed")) + frappe.log_error(frappe.get_traceback(), "participant Email Sending Failed") diff --git a/non_profit/non_profit/doctype/member/member.py b/non_profit/non_profit/doctype/member/member.py index 1425080f..24532130 100644 --- a/non_profit/non_profit/doctype/member/member.py +++ b/non_profit/non_profit/doctype/member/member.py @@ -162,7 +162,7 @@ def send_email_to_member(self): # comm.send_email() # emails_not_sent_to = comm.exclude_emails_list(include_sender=send_me_a_copy) except Exception as e: - frappe.log_error(frappe.get_traceback(), _("Member Email Sending Failed")) + frappe.log_error(frappe.get_traceback(), "Member Email Sending Failed") @frappe.whitelist() From 8896ee952d626317322f51694e518e46a35c371a Mon Sep 17 00:00:00 2001 From: FrankDickenz Date: Sun, 30 Jun 2024 14:42:09 +0300 Subject: [PATCH 22/31] Member Automation - Contact Address, Membership etc --- .../non_profit/doctype/member/member.js | 92 ++- .../non_profit/doctype/member/member.json | 225 +++++++- .../non_profit/doctype/member/member.py | 542 ++++++++++-------- .../member_application_form/__init__.py | 0 .../member_application_form.js | 3 + .../member_application_form.json | 344 +++++++++++ .../member_application_form.py | 5 + 7 files changed, 940 insertions(+), 271 deletions(-) create mode 100644 non_profit/non_profit/web_form/member_application_form/__init__.py create mode 100644 non_profit/non_profit/web_form/member_application_form/member_application_form.js create mode 100644 non_profit/non_profit/web_form/member_application_form/member_application_form.json create mode 100644 non_profit/non_profit/web_form/member_application_form/member_application_form.py diff --git a/non_profit/non_profit/doctype/member/member.js b/non_profit/non_profit/doctype/member/member.js index 22e9cca8..1821448a 100644 --- a/non_profit/non_profit/doctype/member/member.js +++ b/non_profit/non_profit/doctype/member/member.js @@ -2,34 +2,33 @@ // For license information, please see license.txt frappe.ui.form.on('Member', { - setup: function(frm) { + setup: function (frm) { frappe.db.get_single_value('Non Profit Settings', 'enable_razorpay_for_memberships').then(val => { if (val && (frm.doc.subscription_id || frm.doc.customer_id)) { frm.set_df_property('razorpay_details_section', 'hidden', false); } }) }, + refresh: function (frm) { - refresh: function(frm) { + frappe.dynamic_link = { doc: frm.doc, fieldname: 'name', doctype: 'Member' }; - frappe.dynamic_link = {doc: frm.doc, fieldname: 'name', doctype: 'Member'}; + frm.toggle_display(['address_html', 'contact_html'], !frm.doc.__islocal); - frm.toggle_display(['address_html','contact_html'], !frm.doc.__islocal); - - if(!frm.doc.__islocal) { + if (!frm.doc.__islocal) { frappe.contacts.render_address_and_contact(frm); // custom buttons - frm.add_custom_button(__('Accounting Ledger'), function() { + frm.add_custom_button(__('Accounting Ledger'), function () { if (frm.doc.customer) { - frappe.set_route('query-report', 'General Ledger', {party_type: 'Customer', party: frm.doc.customer}); + frappe.set_route('query-report', 'General Ledger', { party_type: 'Customer', party: frm.doc.customer }); } else { - frappe.set_route('query-report', 'General Ledger', {party_type: 'Member', party: frm.doc.name}); + frappe.set_route('query-report', 'General Ledger', { party_type: 'Member', party: frm.doc.name }); } }); - frm.add_custom_button(__('Accounts Receivable'), function() { - frappe.set_route('query-report', 'Accounts Receivable', {customer: frm.doc.customer}); + frm.add_custom_button(__('Accounts Receivable'), function () { + frappe.set_route('query-report', 'Accounts Receivable', { customer: frm.doc.customer }); }); if (!frm.doc.customer) { @@ -48,20 +47,77 @@ frappe.ui.form.on('Member', { } frappe.call({ - method:"frappe.client.get_value", - args:{ - 'doctype':"Membership", - 'filters':{'member': frm.doc.name}, - 'fieldname':[ + method: "frappe.client.get_value", + args: { + 'doctype': "Membership", + 'filters': { 'member': frm.doc.name }, + 'fieldname': [ 'to_date' ] }, callback: function (data) { - if(data.message) { - frappe.model.set_value(frm.doctype,frm.docname, + if (data.message) { + frappe.model.set_value(frm.doctype, frm.docname, "membership_expiry_date", data.message.to_date); } } }); } }); + +// function create_contact_and_address(frm) { +// // Create Contact +// frappe.call({ +// method: "frappe.client.insert", +// args: { +// doc: { +// doctype: "Contact", +// first_name: frm.doc.rep_name, +// email_id: frm.doc.email_id, +// phone: frm.doc.phone, +// links: [{ +// link_doctype: "Member", +// link_name: frm.doc.name +// }] +// } +// }, +// callback: function (response) { +// frappe.msgprint(__('Contact created successfully')); + +// // Create Address after Contact is created +// frappe.call({ +// method: "frappe.client.insert", +// args: { +// doc: { +// doctype: "Address", +// address_title: frm.doc.rep_name, +// county: frm.doc.county, +// address_line1: "Address Line 1", +// city: "City", +// links: [{ +// link_doctype: "Member", +// link_name: frm.doc.name +// }] +// } +// }, +// callback: function (response) { +// frappe.msgprint(__('Address created successfully')); + +// // Update HTML fields and set flag +// var contact_html = "Email: " + frm.doc.email_id + "
Representative Email: " + frm.doc.representative_email_id + "
Phone: " + frm.doc.phone; +// var address_html = "County: " + frm.doc.county; + +// frappe.db.set_value('Member', frm.doc.name, { +// 'contact_html': contact_html, +// 'address_html': address_html, +// 'contact_and_address_created': 1 +// }).then(() => { +// frappe.msgprint(__('HTML fields updated and flag set.')); +// frm.reload_doc(); +// frm.save() +// }); +// } +// }); +// } +// }); +// } \ No newline at end of file diff --git a/non_profit/non_profit/doctype/member/member.json b/non_profit/non_profit/doctype/member/member.json index 75193670..4c147443 100644 --- a/non_profit/non_profit/doctype/member/member.json +++ b/non_profit/non_profit/doctype/member/member.json @@ -8,19 +8,47 @@ "engine": "InnoDB", "field_order": [ "naming_series", + "select_facility", + "enter_facility_name", "member_name", + "membership_expiry_date", + "member_pin", + "qr_code_data", "qr_code", + "member_approval_status", + "membership_status", + "url", "column_break_5", "membership_type", - "membership_expiry_date", - "member_pin", + "initial_membership", + "email_id", + "theatre", + "nhif_contract", + "nhif_contract_type", + "nhif_scope", + "makl_contract", + "makl_scope", + "column_break_siil", + "kmpdc_registration", + "kmpdc_current_license", + "directors_id", + "kra_pin", + "keph_level", + "bed_capacity", + "nhif_hospital_code", + "mfl_code", + "services_offered", + "pan_details", "image", + "exhibition_stand_optin", + "costs", + "number_of_complementary_passes", "director_sb", "rep_name", "designation", "phone", "county", - "email_id", + "representative_email_id", "column_break_btsk", "customer_section", "customer", @@ -121,7 +149,8 @@ { "fieldname": "address_html", "fieldtype": "HTML", - "label": "Address HTML" + "label": "Address HTML", + "read_only": 1 }, { "fieldname": "column_break_9", @@ -130,14 +159,8 @@ { "fieldname": "contact_html", "fieldtype": "HTML", - "label": "Contact HTML" - }, - { - "fieldname": "email_id", - "fieldtype": "Data", - "label": "Email Address", - "options": "Email", - "reqd": 1 + "label": "Contact HTML", + "read_only": 1 }, { "fieldname": "subscription_id", @@ -222,11 +245,187 @@ "length": 10, "options": "Phone", "reqd": 1 + }, + { + "fieldname": "select_facility", + "fieldtype": "Select", + "label": "Select Facility", + "options": "\nAfya Bora Nursing Home\nAhadi Health And Maternity Services\nAhava Medical Centre\nAkemo Medical Clinic And Pharmacy\nAkshar Healthcare Ltd\nAlexandria General Hospital\nAlfombiu Medical Clinic\nAlice Nursing Home\nAlpha Hill Medical Centre Ltd\nAlphond Medical Centre\nAmbercare Medical Centre\nAndicare Dental Services Ltd\nAnsari Medical Clinic\nAppex Hospitals Malaba\nAroha Cancer Centre\nAthi River Medical Services\nAtimiros Hospital\nBamba Maternity Nursing Home\nBangal Nursing Home\nBaraka Smiles Dental Ltd\nBatian Medical Centre\nBenmac Hospital\nBlessed Comm. Medical Center\nBliss Medical Clinic Mumias\nBlue Turtle Nursing Home\nBrantly Medical Centre\nBreetons Medical Centre\nBrook Of Cherith Medical And Nutrition Centre\nBunyore Medical Centre\nBura Springs Family Medical Centre Limited\nBura Tana Nursing Home Limited\nBuruburu Health Centre\nBuxton Hospital\nBwana Ni Mwema Medical Centre\nCana Family Nursing Home\nCedar Medical Centre\nCentre View Medical Healthcare\nCentres For Community Healthcare Accesd\nChaani Medical Clinic\nChamalo Medical Centre\nCharity Medical Hospital\nChebunyo Medical Clinic\nCherengany Hospital\nCity Eye Hospital\nClastan Medical Services\nCounty Medical And Diagnostic Limited\nCounty Medical Centre\nCovenant Medical Centre\nCriterion Hospital\nDanid Care Services\nDaraja Medical Centre\nDencare Medical Clinic\nDeteni Maternity & Nursing Home\nDinome Medical Centre\nDomiline Medical Centre\nDrive Inn Nursing Home\nDunga Nursing Home\nEastlife Hospital\nElburgon Maternity Home\nEldama Ravine Nursing Home\nEldo Eye Center\nEliss Medical Centre\nEmmaus Medical Centre\nEsther Memorial Maternity & N.H.\nEvans Health Care\nFairmont Hospital\nFairview Medical Centre\nFaraja Family Care Hospital\nFavour Medical Services\nFavoured Medical Clinic\nFig Tree Health Options\nFina Nursing Home\nFirst Community Hospital\nFuraha Medical Care\nGacal Budget Hospital\nGakira Family Healthcare Ltd\nGetembe Annex Frankston Hospital Ltd\nGlory Medical Reproductive Health & Youth Friendly Centre\nGolgotha Medical Centre Limited\nGrace Home Clinic\nGraceheal Hospital\nGracepark Medical Centre\nGracimed Healthcare\nGranton & Dolly N.H.\nGreenspan Medical Centre\nGreenwood Cottage Community Hospital\nGuardian Hospital\nGynocare Womens And Fistula Hospital\nHalisi Family Hospital\nHaven Hospital\nHavilah Healthcare\nHawi Family Hospital-Oyugis\nHealth Charge Medical Centre-Kutus\nHolani Medical Centre\nHolsoms Annex Keumbu\nHolsoms Nursing Home\nHomeground Medical Centre\nHopkins Crescent Hospital Limited\nHoplan Medical Centre\nHuduma Nursing Home\nHunter Medical Centre Runyenjes\nHuruma Nursing Home\nIkutha Faith N.H.\nImara Mediplus Hospital\nImpact Healthcare\nInnovation Eye Centre Ltd - (Kisii Eye Hospital)\nItarc Hospital\nIvory Health Solutions Ltd\nJahmii Kipawa Medicl\nJakaba Medical Clinic\nJambo Healthcare Ltd\nJamii Hospital- Karatina\nJoyride Medical Centre\nJuja Modern Hospital\nJuja Road Hospital\nJumuia Hospital\nKabete Medical & Eye Care Centre\nKagio Hospital Ltd\nKannex Medical Ckinic\nKapsabet Supreme Surgical And Outpatient\nKasarani Maternity & Nursing Home\nKeflo Medical Clinic\nKenlands Health Services\nKenol Hospital Ltd\nKerio Hospital Limited\nKerugoya Fortis Medical Centre\nKerugoya Medical Centre\nKhalaba Medical Services Ltd\nKianjokoma Muungano Community Cottage Hospital\nKijanaheri Medical Centre\nKimathi Medical Services-Main Hospital\nKing David Hospital\nKingscare Medical\nKinondo Kwetu Health Services\nKirinyaga Treatment Centre\nKiritiri Medical Healthcare\nKisumu Comprehensive Medical Centre\nKisumu Heart Centre\nKitengela Medical Services\nKory Family Hospital\nKpn Pearl Health Limited\nKwa Lydia Medical Centre\nKwa Ng'ang'a Medicare Centre\nLadorphama Medical Centre Ltd\nLakeside Intergrated Medical Service\nLakeview Maternity & Nursing Home\nLane Care Medical Centre -Mlolongo\nLang'ata Hospital\nLenmek Hospital\nLessos Heathcare Clinic\nLiberty Maternity & Nursing Home\nLifepoint Hospital\nLifetime Wellness Centre\nLimuru Nursing Home Ltd\nLimuru Cottage Hospital\nMaai Mahiu Maternity & Hospital\nMabera Maternity & N.H.\nMaida Healthcare Limited\nMainland Health Centre\nMakdavie Medical Clinic\nMalvick Medical Centre\nMamlaka Medical Centre\nManguo Medical Centre\nMao-Aweys International Hospital\nMarble Healthcare Limited\nMargaret Wambui\nMariakani Community Health Centre\nMariakani Cottage Hospital\nMark Tumaini Medical Centre -Kirura\nMasii Medical Centre\nMathingira Medical Centre\nMatunda Maternity Home\nMatungulu Medical Centre\nMaua Medical Cottage Hospital Limited\nMawepi Medical Services\nMaxicare Sunrise Limited Hospital\nMedicure Medical Centre\nMedistar Hospital Kericho Ltd\nMeditrust Healthcare Services\nMedlife Healthcare Ltd\nMedstops Healthcare Nursing Home\nMephi Health Services\nMeru Doctors Plaza Hospital\nMikindani Medical Center\nMillenium Medical Centre\nMina Nursing Home Rhamu Ltd\nMiritini Medical Centre\nMitunguu Medical Services\nModesty Health Services\nMombasa Cancer Centre\nMombasa West Hospital\nMontagna Medical Clinic\nMontana Hospital\nMother And Child Hospital\nMt Kenya Kangema Hospital Ltd\nMtwapa Medical Clinic And Nursing Home\nMulatya Memorial Hospital (Mikindu)\nMulemi Nursing Home\nMumbuni Maternity And Nursing Home\nMumbuni Roadside Medical Centre\nMumoni Nursing Home\nMundika Maternity & N.H.\nMungoma Hospital\nMutethia Kiraone Nursing Home\nMwatate Medical Centre\nMwea Medical Centre\nMwingi Medicare Centre Ltd\nMwingi Specialist Hospital\nMwirigi Healthcare Services\nNairobi Homes Nursing Home\nNaivasha Quality Healthcare\nNaj Hospital Ltd\nNakuru Maternity & N. H.\nNala Maternity Hospital\nNamunyak Medical Centre\nNamuya Shalom Medical Services\nNanyuki Hospital Limited\nNarok Cottage Hospital\nNasha Lengot Medical Centre\nNeema Hospital\nNeon Rapha Healthcare Clinin\nNew Busia Maternity & Nursing Home\nNew Degree Medical Center\nNew Elgon View Medical Cottage\nNew Hope Hospital\nNew Ikonge Medical Centre\nNew Kilifi Wananchi Maternity & Nursing Home\nNewlight Medical Centre & N.H.\nNgurubani Medical Services\nNightingale Medical Centre\nNkubu Highway Medicare\nNuru Ambusely Medical Centre\nNyamira Jamii Med & Diagn.Centre\nNyamusi Medical Centre\nNyatieko Gesusu Health Services\nNzoia Medical Centre\nOaktree Centre For Kidney\nOkitta Nursing Home\nOlchobosei Medical Centre\nOlivelink Healthcare Ltd\nOljabet Hospital\nOlympus Medical Centre\nOptex Opticals\nPalm Care Sinai Hospital\nParkerra Medical Centre\nPatanisho Nursing Home\nPenda Health (Umoja Med Centre)\nPhadam Hospital\nPlainsview Hospitals And Nursing Home\nPolani Medical Centre\nPolyclinic Hospital\nPonacare Medical Centre\nPotter's Family Hospital\nPrecious Hospital\nPrecious Life Medical Centre\nPremiercare Diagnostic Centre Loitokitok\nPremiercare Diagnostics\nPremiercare Diagnostics (Narok)\nProact Services Health Center\nProgress Medical Centre\nPrudent Cottage Hospital\nQasims Hospital Ltd\nQatar Medical Clinic\nQueens & Kings Health Centre\nRadiant Hospitals (Kiambu)\nRakedenn Medical Centre\nRavine Glory Healthcare\nRavine Specialists Hospital Limited\nRehoboth Maternity And Nursing Home\nRiochand Nursing Home\nRobins Heath Care Ltd\nRoman Annex Med Centre\nRopheka Medical Services\nRopment Medical Centre\nRoyal Dental Clinic\nRoyal Garden Hospital\nRoyal Star Family Hospital\nSalama Cancer Centre\nSamjomen Hospital\nSanitas Family Hospital\nSantamore Specialized Surgical Hospital\nScanlab Kitengela\nScharts Medical Centre\nSerena Umoja Medical Centre\nShammah Nursing Home\nShelly Beach Hospital\nShibale Medical Centre\nSigma Medical Centre\nSikhendu Medical Center\nSilvad Calvary Hill Specialist Hospital\nSilvercrest Medcare\nSoin Medical Center Limited\nSouth Lake Med Centre\nSpringcrest Medical Center Ltd\nSprings Heritage Nursing Home-Juja\nSt Andrew's Medical Clinic\nSt Anne Medical Centre\nSt Clare Medical Centre\nSt James Amenity Hospital\nSt John Divine Nursing Home\nSt Joseph's Hospital\nSt Jude Nursing Home\nSt Luke's Afya Clinic\nSt Mary Health Services\nSt Mary's Mother & Child Hospital\nSt Paul Dawa Medical Centre\nSt. Crispin Afya Hospital\nST.Akidiva Memorial Hospital\nStarheal Medical Clinic\nStirling Medical Centre\nSubukia Integrated Med. Centre\nSummit Medicare Nyansiongo\nSynergy Clinics Limited\nTamani Medical Centre\nThagana County Medical Centre\nThe Athi River Shalom Hospital.\nThe Fairhaven Medicare\nThe Green Park Healthcare\nThe Greenview Nursing Home\nThe Hopkins Crescent Hospitals Limited\nThe Kitui Hospital Maternity And Nursing Home\nThe Kitui Royal Diognastics Centre\nThe Tana Hospital\nThuti Medical Clinic\nTimeless Medical Spa\nTop Care Limited\nTrue Life Medical Centre\nTrust Doctors Centre\nTsunza Medical Care Limited\nTudor Healthcare\nTulah Medical Centre\nTuwan Highway\nUltramed Healthcare Ltd\nUnited Health Group Medical Centre\nUpendo Medical Clinic\nUwezo Healthcare Ltd\nUzima Uhai Health Centre\nVantage Hospital Syokimau\nVelma Memorial Medical Centre\nVenoma Medical Centre\nVichabem Nursing Home\nVision Medical Center\nVisiongate Eye Care Consultants\nVostrum Medical Services\nWatamu Community Healthcare\nWatamu Hospital\nWatamu Maternity & Nursing Home\nWayside Medical Clinic\nWells Women Hospital\nWest Inland Hospital Ltd Changamwe\nWest Side Cottage Hospital\nWestlands Medical Centre\nWhite Health Medical Centre\nWhiterose Medical Centre\nYunasi Medical Centre\nZawena Treatment Centre" + }, + { + "default": "0", + "fieldname": "enter_facility_name", + "fieldtype": "Check", + "label": "Enter Facility Name" + }, + { + "fieldname": "column_break_siil", + "fieldtype": "Column Break" + }, + { + "fieldname": "qr_code_data", + "fieldtype": "HTML", + "label": "QR Code Data" + }, + { + "default": "Pending", + "fieldname": "member_approval_status", + "fieldtype": "Select", + "in_filter": 1, + "in_list_view": 1, + "label": "Member Approval Status", + "options": "\nPending\nApproved" + }, + { + "fieldname": "membership_status", + "fieldtype": "Select", + "in_filter": 1, + "in_list_view": 1, + "label": "Membership Status", + "options": "\nCurrent\nDue\nOverdue" + }, + { + "default": "https://rupha.ruphasoft.com/5th-convention", + "fieldname": "url", + "fieldtype": "Data", + "label": "Url" + }, + { + "fieldname": "initial_membership", + "fieldtype": "Date", + "label": "Member Since", + "reqd": 1 + }, + { + "fieldname": "theatre", + "fieldtype": "Select", + "label": "Theatre", + "options": "\nYes\nNo" + }, + { + "fieldname": "nhif_contract", + "fieldtype": "Select", + "label": "NHIF Contract", + "options": "\nYes\nNo" + }, + { + "fieldname": "nhif_contract_type", + "fieldtype": "Select", + "label": "NHIF Contract Type", + "options": "\nComprehensive\nNon-Comprehensive" + }, + { + "fieldname": "nhif_scope", + "fieldtype": "Select", + "label": "NHIF Scope", + "options": "\nINPATIENT/OUTPATIENT\nOUTPATIENT\nINPATIENT" + }, + { + "fieldname": "makl_contract", + "fieldtype": "Select", + "label": "MAKL Contract", + "options": "\nYes\nNo" + }, + { + "fieldname": "makl_scope", + "fieldtype": "Select", + "label": "MAKL Scope", + "options": "\nINPATIENT/OUTPATIENT\nOUTPATIENT\nINPATIENT" + }, + { + "fieldname": "kmpdc_registration", + "fieldtype": "Attach", + "ignore_user_permissions": 1, + "label": "KMPDC Registration" + }, + { + "fieldname": "kmpdc_current_license", + "fieldtype": "Attach", + "ignore_user_permissions": 1, + "label": "KMPDC Current License" + }, + { + "fieldname": "directors_id", + "fieldtype": "Attach", + "ignore_user_permissions": 1, + "label": "Directors ID" + }, + { + "fieldname": "kra_pin", + "fieldtype": "Attach", + "ignore_user_permissions": 1, + "label": "KRA PIN" + }, + { + "fieldname": "keph_level", + "fieldtype": "Select", + "label": "KEPH Level", + "options": "\n1\n2\n3A\n3B\n4\n5\n6" + }, + { + "fieldname": "bed_capacity", + "fieldtype": "Int", + "label": "Bed Capacity" + }, + { + "fieldname": "nhif_hospital_code", + "fieldtype": "Int", + "label": "NHIF Hospital Code", + "non_negative": 1 + }, + { + "fieldname": "mfl_code", + "fieldtype": "Int", + "label": "MFL CODE", + "non_negative": 1 + }, + { + "fieldname": "services_offered", + "fieldtype": "Small Text", + "label": "Services Offered" + }, + { + "fieldname": "pan_details", + "fieldtype": "Data", + "label": "PAN Details", + "translatable": 1 + }, + { + "fieldname": "exhibition_stand_optin", + "fieldtype": "Select", + "label": "Exhibition Stand Optin", + "options": "\nExhibition stand 2 days\nNot interested" + }, + { + "fieldname": "costs", + "fieldtype": "HTML", + "label": "Costs", + "options": "COSTS:\n
    \n \t
  • Exhibition stand 2 days: Ksh 20,000
  • \n
" + }, + { + "description": "Members can bring their co-directors/representatives. This has to be shared and approved in advanced for planning purposes.", + "fieldname": "number_of_complementary_passes", + "fieldtype": "Int", + "label": "Number of Complementary Passes", + "non_negative": 1 + }, + { + "fieldname": "representative_email_id", + "fieldtype": "Data", + "label": "Representative's Email Address", + "options": "Email", + "reqd": 1 + }, + { + "fieldname": "email_id", + "fieldtype": "Data", + "label": "Facility Email Address", + "reqd": 1 } ], "image_field": "image", "links": [], - "modified": "2024-01-30 23:27:17.658351", + "modified": "2024-06-30 10:39:37.346543", "modified_by": "Administrator", "module": "Non Profit", "name": "Member", diff --git a/non_profit/non_profit/doctype/member/member.py b/non_profit/non_profit/doctype/member/member.py index 24532130..81108485 100644 --- a/non_profit/non_profit/doctype/member/member.py +++ b/non_profit/non_profit/doctype/member/member.py @@ -14,76 +14,128 @@ class Member(Document): - def onload(self): - """Load address and contacts in `__onload`""" - load_address_and_contact(self) - - def after_insert(self): - self.generate_qr_code() - self.send_email_to_member() - - def validate(self): - if self.email_id: - self.validate_email_type(self.email_id) - - - def validate_email_type(self, email): - from frappe.utils import validate_email_address - validate_email_address(email.strip(), True) - - def setup_subscription(self): - non_profit_settings = frappe.get_doc('Non Profit Settings') - if not non_profit_settings.enable_razorpay_for_memberships: - frappe.throw(_('Please check Enable Razorpay for Memberships in {0} to setup subscription')).format( - get_link_to_form('Non Profit Settings', 'Non Profit Settings')) - - controller = get_payment_gateway_controller("Razorpay") - settings = controller.get_settings({}) - - plan_id = frappe.get_value("Membership Type", self.membership_type, "razorpay_plan_id") - - if not plan_id: - frappe.throw(_("Please setup Razorpay Plan ID")) - - subscription_details = { - "plan_id": plan_id, - "billing_frequency": cint(non_profit_settings.billing_frequency), - "customer_notify": 1 - } - - args = { - 'subscription_details': subscription_details - } - - subscription = controller.setup_subscription(settings, **args) - - return subscription - - - def generate_qr_code(self): - if not self.qr_code or self.qr_code == "": - if self.name and self.member_name and self.email_id: - frappe.msgprint("Member Auth QR Code:") - from print_designer.print_designer.page.print_designer.print_designer import get_barcode - arguments = { - "scale": 3, - "background": "#ffffff", - "module_color": "#142b91", - "quiet_zone":1, - } - try: - self.qr_code = get_barcode(barcode_value = self.member_name + " - " + self.name,options=arguments,barcode_format="qrcode")["value"] - frappe.msgprint(self.qr_code) - self.save(ignore_permissions=True) - except Exception as e: - frappe.log_error(frappe.get_traceback(), _("QR Code Generation Failed")) - else: - frappe.throw("Please provide all the details") - - - def send_email_to_member(self): - from frappe.core.doctype.communication.email import make - footer = '
\ + + def create_contact_and_address(self): + try: + # Create Contact + contact = frappe.get_doc({ + 'doctype': 'Contact', + 'first_name': self.rep_name, + 'email_ids': [{ + 'email_id': self.representative_email_id, + 'is_primary': 1 + }], + 'phone_nos': [{ + 'phone': self.phone, + 'is_primary_phone': 1 + }], + 'links': [{ + 'link_doctype': 'Member', + 'link_name': self.name + }] + }) + contact.insert(ignore_permissions=True) + frappe.logger().info( + f"Contact {contact.name} created for Member {self.name}.") + + # Create Address + address = frappe.get_doc({ + 'doctype': 'Address', + 'address_title': self.member_name, + 'address_type': 'Current', + 'city': self.county, + 'address_line1': "", + 'links': [{ + 'link_doctype': 'Member', + 'link_name': self.name + }] + }) + address.insert(ignore_permissions=True, ignore_mandatory=True) + frappe.logger().info(f"Address {address.name} created for Member {self.name}.") + + frappe.logger().info( f"HTML fields updated for Member {self.name}.") + + # self.contact_html + + except Exception as e: + frappe.logger().error( + f"Error in creating contact and address for Member {self.name}: {frappe.get_traceback()}") + + def onload(self): + """Load address and contacts in `__onload`""" + load_address_and_contact(self) + + def after_insert(self): + self.generate_qr_code() + self.send_email_to_member() + self.create_contact_and_address() + frappe.logger().info( + f"Member {self.name} inserted, creating contact and address.") + + def validate(self): + if self.member_approval_status == "Approved" and not self.customer: + self.make_customer_and_link() + if self.email_id: + self.validate_email_type(self.email_id) + + def validate_email_type(self, email): + from frappe.utils import validate_email_address + validate_email_address(email.strip(), True) + + def setup_subscription(self): + non_profit_settings = frappe.get_doc('Non Profit Settings') + if not non_profit_settings.enable_razorpay_for_memberships: + frappe.throw(_('Please check Enable Razorpay for Memberships in {0} to setup subscription')).format( + get_link_to_form('Non Profit Settings', 'Non Profit Settings')) + + controller = get_payment_gateway_controller("Razorpay") + settings = controller.get_settings({}) + + plan_id = frappe.get_value( + "Membership Type", self.membership_type, "razorpay_plan_id") + + if not plan_id: + frappe.throw(_("Please setup Razorpay Plan ID")) + + subscription_details = { + "plan_id": plan_id, + "billing_frequency": cint(non_profit_settings.billing_frequency), + "customer_notify": 1 + } + + args = { + 'subscription_details': subscription_details + } + + subscription = controller.setup_subscription(settings, **args) + + return subscription + + def generate_qr_code(self): + if not self.qr_code or self.qr_code == "": + if self.name and self.member_name and self.email_id: + frappe.msgprint("Member Auth QR Code:") + from print_designer.print_designer.page.print_designer.print_designer import get_barcode + arguments = { + "scale": 3, + "background": "#ffffff", + "module_color": "#142b91", + "quiet_zone": 1, + } + try: + self.qr_code = get_barcode( + barcode_value=self.member_name + " - " + self.name, options=arguments, barcode_format="qrcode")["value"] + frappe.msgprint(self.qr_code) + self.save(ignore_permissions=True) + except Exception as e: + frappe.log_error(frappe.get_traceback(), + _("QR Code Generation Failed")) + else: + frappe.throw("Please provide all the details") + + def send_email_to_member(self): + from frappe.core.doctype.communication.email import make + footer = '
\ This email and any files transmitted with it are confidential and intended solely for the use of the individual or entity to \ whom they are addressed. If you have received this email in error please notify the system manager. This message contains \ confidential information and is intended only for the individual named. If you are not the named addressee you should not \ @@ -96,7 +148,7 @@ def send_email_to_member(self): http://www.rupha.co.ke/
\

Powered by RUPHAsoft

\ ' - payment_instructions = '

Payment Options:


\ + payment_instructions = '

Payment Options:


\ BANK DETAILS\ BANK DETAILS : EQUITY BANK (KENYA) LIMITED
\ ACCOUNT NAME RURAL PRIVATE HOSPITALS ASSOCIATION OF KENYA
\ @@ -110,191 +162,201 @@ def send_email_to_member(self): PAYBILL: 247247
\ ACCOUNT NO: 176 028 136 2990
\ ACCOUNT NAME : RURAL PRIVATE HOSPITALS ASSOCIATION OF KENYA
' - # Click Here to Download. or see attached document
- args = { - "doctype" : "Member", - "name" : self.name, - "content" : f"Dear Member,

Your institution's membership is acknowledged.


This is autogenerated email, please reply to info@rupha.co.ke
"+payment_instructions+ footer, - "subject" : "Member Acknowledgement", - "sent_or_received" : "Sent", - "sender" : "noreply@rupha.co.ke", - "sender_full_name": "RUPHA - Powered by RUPHAsoft", - "send_email": 1, - "recipients" : [self.email_id], - "cc" : ["info@rupha.co.ke","cmunene@rupha.co.ke"], - "bcc" : ["mohamud@rupha.co.ke"], - "communication_medium" : "Email", - "print_html" : None, - "has_attachment": 1, - "print_format" : "New Member" - } - - try: - comm = make( - doctype = args["doctype"], - name = args["name"], - content = args["content"], - subject = args["subject"], - sent_or_received = args["sent_or_received"], - sender = args["sender"], - sender_full_name = args["sender_full_name"], - send_email = args["send_email"], - recipients = args["recipients"], - communication_medium = args["communication_medium"], - print_html = args["print_html"], - print_format = args["print_format"], - cc = args["cc"], - bcc = args["bcc"], - has_attachment = args["has_attachment"], - print_letterhead = False - ) - # comm = frappe.get_doc( - # { - # "doctype": "Communication", - # "subject": self.subject, - # "content": self.get_message(), - # "sent_or_received": "Sent", - # "reference_doctype": self.reference_doctype, - # "reference_name": self.reference_name, - # } - # ) - # comm.insert(ignore_permissions=True) - # comm.send_email() - # emails_not_sent_to = comm.exclude_emails_list(include_sender=send_me_a_copy) - except Exception as e: - frappe.log_error(frappe.get_traceback(), "Member Email Sending Failed") - - - @frappe.whitelist() - def make_customer_and_link(self): - if self.customer: - frappe.msgprint(_("A customer is already linked to this Member")) - - customer = create_customer(frappe._dict({ - 'fullname': self.member_name, - 'email': self.email_id, - 'phone': None - })) - - self.customer = customer - self.save() - frappe.msgprint(_("Customer {0} has been created succesfully.").format(self.customer)) + # Click Here to Download. or see attached document
+ args = { + "doctype": "Member", + "name": self.name, + "content": f"Dear Member,

Your institution's membership is acknowledged.


This is autogenerated email, please reply to info@rupha.co.ke
"+payment_instructions + footer, + "subject": "Member Acknowledgement", + "sent_or_received": "Sent", + "sender": "noreply@rupha.co.ke", + "sender_full_name": "RUPHA - Powered by RUPHAsoft", + "send_email": 1, + "recipients": [self.email_id], + "cc": ["info@rupha.co.ke", "cmunene@rupha.co.ke"], + "bcc": ["mohamud@rupha.co.ke"], + "communication_medium": "Email", + "print_html": None, + "has_attachment": 1, + "print_format": "New Member" + } + + try: + comm = make( + doctype=args["doctype"], + name=args["name"], + content=args["content"], + subject=args["subject"], + sent_or_received=args["sent_or_received"], + sender=args["sender"], + sender_full_name=args["sender_full_name"], + send_email=args["send_email"], + recipients=args["recipients"], + communication_medium=args["communication_medium"], + print_html=args["print_html"], + print_format=args["print_format"], + cc=args["cc"], + bcc=args["bcc"], + has_attachment=args["has_attachment"], + print_letterhead=False + ) + # comm = frappe.get_doc( + # { + # "doctype": "Communication", + # "subject": self.subject, + # "content": self.get_message(), + # "sent_or_received": "Sent", + # "reference_doctype": self.reference_doctype, + # "reference_name": self.reference_name, + # } + # ) + # comm.insert(ignore_permissions=True) + # comm.send_email() + # emails_not_sent_to = comm.exclude_emails_list(include_sender=send_me_a_copy) + except Exception as e: + frappe.log_error(frappe.get_traceback(), + "Member Email Sending Failed") + + @frappe.whitelist() + def make_customer_and_link(self): + if self.customer: + frappe.msgprint(_("A customer is already linked to this Member")) + + customer = create_customer(frappe._dict({ + 'fullname': self.member_name, + 'email': self.email_id, + 'phone': None + })) + + self.customer = customer + # self.save() + frappe.msgprint( + _("Customer {0} has been created succesfully.").format(self.customer)) def get_or_create_member(user_details): - member_list = frappe.get_all("Member", filters={'email': user_details.email, 'membership_type': user_details.plan_id}) - if member_list and member_list[0]: - return member_list[0]['name'] - else: - return create_member(user_details) + member_list = frappe.get_all("Member", filters={ + 'email': user_details.email, 'membership_type': user_details.plan_id}) + if member_list and member_list[0]: + return member_list[0]['name'] + else: + return create_member(user_details) + def create_member(user_details): - user_details = frappe._dict(user_details) - member = frappe.new_doc("Member") - member.update({ - "member_name": user_details.fullname, - "email_id": user_details.email, - "pan_number": user_details.pan or None, - "membership_type": user_details.plan_id, - "customer_id": user_details.customer_id or None, - "subscription_id": user_details.subscription_id or None, - "subscription_status": user_details.subscription_status or "" - }) - - member.insert(ignore_permissions=True) - member.customer = create_customer(user_details, member.name) - member.save(ignore_permissions=True) - - return member + user_details = frappe._dict(user_details) + member = frappe.new_doc("Member") + member.update({ + "member_name": user_details.fullname, + "email_id": user_details.email, + "pan_number": user_details.pan or None, + "membership_type": user_details.plan_id, + "customer_id": user_details.customer_id or None, + "subscription_id": user_details.subscription_id or None, + "subscription_status": user_details.subscription_status or "" + }) + + member.insert(ignore_permissions=True) + member.customer = create_customer(user_details, member.name) + member.save(ignore_permissions=True) + + return member + def create_customer(user_details, member=None): - customer = frappe.new_doc("Customer") - customer.customer_name = user_details.fullname - customer.customer_type = "Individual" - customer.customer_group = frappe.db.get_single_value("Selling Settings", "customer_group") - customer.territory = frappe.db.get_single_value("Selling Settings", "territory") - customer.flags.ignore_mandatory = True - customer.insert(ignore_permissions=True) - - try: - frappe.db.savepoint("contact_creation") - contact = frappe.new_doc("Contact") - contact.first_name = user_details.fullname - if user_details.mobile: - contact.add_phone(user_details.mobile, is_primary_phone=1, is_primary_mobile_no=1) - if user_details.email: - contact.add_email(user_details.email, is_primary=1) - contact.insert(ignore_permissions=True) - - contact.append("links", { - "link_doctype": "Customer", - "link_name": customer.name - }) - - if member: - contact.append("links", { - "link_doctype": "Member", - "link_name": member - }) - - contact.save(ignore_permissions=True) - - except frappe.DuplicateEntryError: - return customer.name - - except Exception as e: - frappe.db.rollback(save_point="contact_creation") - frappe.log_error(frappe.get_traceback(), _("Contact Creation Failed")) - pass - - return customer.name + customer = frappe.new_doc("Customer") + customer.customer_name = user_details.fullname + customer.customer_type = "Individual" + customer.customer_group = frappe.db.get_single_value( + "Selling Settings", "customer_group") + customer.territory = frappe.db.get_single_value( + "Selling Settings", "territory") + customer.flags.ignore_mandatory = True + customer.insert(ignore_permissions=True) + + try: + frappe.db.savepoint("contact_creation") + contact = frappe.new_doc("Contact") + contact.first_name = user_details.fullname + if user_details.mobile: + contact.add_phone(user_details.mobile, + is_primary_phone=1, is_primary_mobile_no=1) + if user_details.email: + contact.add_email(user_details.email, is_primary=1) + contact.insert(ignore_permissions=True) + + contact.append("links", { + "link_doctype": "Customer", + "link_name": customer.name + }) + + if member: + contact.append("links", { + "link_doctype": "Member", + "link_name": member + }) + + contact.save(ignore_permissions=True) + + except frappe.DuplicateEntryError: + return customer.name + + except Exception as e: + frappe.db.rollback(save_point="contact_creation") + frappe.log_error(frappe.get_traceback(), _("Contact Creation Failed")) + pass + + return customer.name + @frappe.whitelist(allow_guest=True) def create_member_subscription_order(user_details): - """Create Member subscription and order for payment + """Create Member subscription and order for payment + + Args: + user_details (TYPE): Description - Args: - user_details (TYPE): Description + Returns: + Dictionary: Dictionary with subscription details + { + 'subscription_details': { + 'plan_id': 'plan_EXwyxDYDCj3X4v', + 'billing_frequency': 24, + 'customer_notify': 1 + }, + 'subscription_id': 'sub_EZycCvXFvqnC6p' + } + """ - Returns: - Dictionary: Dictionary with subscription details - { - 'subscription_details': { - 'plan_id': 'plan_EXwyxDYDCj3X4v', - 'billing_frequency': 24, - 'customer_notify': 1 - }, - 'subscription_id': 'sub_EZycCvXFvqnC6p' - } - """ + user_details = frappe._dict(user_details) + member = get_or_create_member(user_details) - user_details = frappe._dict(user_details) - member = get_or_create_member(user_details) + subscription = member.setup_subscription() - subscription = member.setup_subscription() + member.subscription_id = subscription.get('subscription_id') + member.save(ignore_permissions=True) - member.subscription_id = subscription.get('subscription_id') - member.save(ignore_permissions=True) + return subscription - return subscription @frappe.whitelist() def register_member(fullname, email, rzpay_plan_id, subscription_id, pan=None, mobile=None): - plan = get_membership_type(rzpay_plan_id) - if not plan: - raise frappe.DoesNotExistError - - member = frappe.db.exists("Member", {'email': email, 'subscription_id': subscription_id }) - if member: - return member - else: - member = create_member(dict( - fullname=fullname, - email=email, - plan_id=plan, - subscription_id=subscription_id, - pan=pan, - mobile=mobile - )) - - return member.name + plan = get_membership_type(rzpay_plan_id) + if not plan: + raise frappe.DoesNotExistError + + member = frappe.db.exists( + "Member", {'email': email, 'subscription_id': subscription_id}) + if member: + return member + else: + member = create_member(dict( + fullname=fullname, + email=email, + plan_id=plan, + subscription_id=subscription_id, + pan=pan, + mobile=mobile + )) + + return member.name diff --git a/non_profit/non_profit/web_form/member_application_form/__init__.py b/non_profit/non_profit/web_form/member_application_form/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/non_profit/non_profit/web_form/member_application_form/member_application_form.js b/non_profit/non_profit/web_form/member_application_form/member_application_form.js new file mode 100644 index 00000000..699703c5 --- /dev/null +++ b/non_profit/non_profit/web_form/member_application_form/member_application_form.js @@ -0,0 +1,3 @@ +frappe.ready(function() { + // bind events here +}) \ No newline at end of file diff --git a/non_profit/non_profit/web_form/member_application_form/member_application_form.json b/non_profit/non_profit/web_form/member_application_form/member_application_form.json new file mode 100644 index 00000000..312f13f2 --- /dev/null +++ b/non_profit/non_profit/web_form/member_application_form/member_application_form.json @@ -0,0 +1,344 @@ +{ + "allow_comments": 0, + "allow_delete": 0, + "allow_edit": 0, + "allow_incomplete": 0, + "allow_multiple": 0, + "allow_print": 0, + "anonymous": 0, + "apply_document_permissions": 0, + "banner_image": "/files/rupha_logo_box.png", + "button_label": "Apply", + "condition_json": "[]", + "creation": "2024-06-26 21:59:57.898945", + "doc_type": "Member", + "docstatus": 0, + "doctype": "Web Form", + "idx": 0, + "introduction_text": "

Please fill the form below to apply for Membership:

", + "is_standard": 1, + "list_columns": [], + "login_required": 0, + "max_attachment_size": 10, + "modified": "2024-06-27 12:49:14.444102", + "modified_by": "Administrator", + "module": "Non Profit", + "name": "member-application-form", + "owner": "Administrator", + "published": 1, + "route": "member", + "show_attachments": 0, + "show_list": 0, + "show_sidebar": 0, + "success_message": "Please wait as you application is verified and the office will respond.\n

Payment Options:


\nBANK DETAILS\nBANK DETAILS : EQUITY BANK (KENYA) LIMITED
\nACCOUNT NAME RURAL PRIVATE HOSPITALS ASSOCIATION OF KENYA
\nBANK ACCOUNT NO : 17602-8136-2990 -KES
\n1760284516849 -USD
\nBANK SWIFT CODE : EQBLKENAXXX
\nBANK CODE: 068
\nBRANCH CODE: 176
\nBRANCH NAME SYOKIMAU GATEWAY MALL BRANCH
\nMPESA
\nPAYBILL: 247247
\nACCOUNT NO: 176 028 136 2990
\nACCOUNT NAME : RURAL PRIVATE HOSPITALS ASSOCIATION OF KENYA
", + "success_title": "Submission Successful", + "title": "Member Application Form", + "web_form_fields": [ + { + "allow_read_on_all_link_options": 0, + "fieldname": "member_name", + "fieldtype": "Data", + "hidden": 0, + "label": "Facility Name", + "max_length": 0, + "max_value": 0, + "precision": "", + "read_only": 0, + "reqd": 1, + "show_in_filter": 0 + }, + { + "allow_read_on_all_link_options": 0, + "fieldname": "qr_code", + "fieldtype": "Attach Image", + "hidden": 1, + "label": "QR Code", + "max_length": 0, + "max_value": 0, + "precision": "", + "read_only": 0, + "reqd": 0, + "show_in_filter": 0 + }, + { + "allow_read_on_all_link_options": 0, + "fieldname": "initial_membership", + "fieldtype": "Date", + "hidden": 0, + "label": "Member Since", + "max_length": 0, + "max_value": 0, + "precision": "", + "read_only": 0, + "reqd": 1, + "show_in_filter": 0 + }, + { + "allow_read_on_all_link_options": 0, + "fieldname": "membership_type", + "fieldtype": "Link", + "hidden": 0, + "label": "Membership Type", + "max_length": 0, + "max_value": 0, + "options": "Membership Type", + "precision": "", + "read_only": 0, + "reqd": 1, + "show_in_filter": 0 + }, + { + "allow_read_on_all_link_options": 0, + "fieldname": "email_id", + "fieldtype": "Data", + "hidden": 0, + "label": "Facility Email Address", + "max_length": 0, + "max_value": 0, + "precision": "", + "read_only": 0, + "reqd": 1, + "show_in_filter": 0 + }, + { + "allow_read_on_all_link_options": 0, + "fieldname": "director_sb", + "fieldtype": "Section Break", + "hidden": 0, + "label": "Representative Details", + "max_length": 0, + "max_value": 0, + "precision": "", + "read_only": 0, + "reqd": 0, + "show_in_filter": 0 + }, + { + "allow_read_on_all_link_options": 0, + "fieldname": "rep_name", + "fieldtype": "Data", + "hidden": 0, + "label": "Members Representative Name", + "max_length": 0, + "max_value": 0, + "precision": "", + "read_only": 0, + "reqd": 1, + "show_in_filter": 0 + }, + { + "allow_read_on_all_link_options": 0, + "fieldname": "designation", + "fieldtype": "Data", + "hidden": 0, + "label": "Designation or Position", + "max_length": 0, + "max_value": 0, + "precision": "", + "read_only": 0, + "reqd": 0, + "show_in_filter": 0 + }, + { + "allow_read_on_all_link_options": 0, + "fieldname": "phone", + "fieldtype": "Data", + "hidden": 0, + "label": "Representative's Phone", + "max_length": 0, + "max_value": 0, + "options": "Phone", + "precision": "", + "read_only": 0, + "reqd": 1, + "show_in_filter": 0 + }, + { + "allow_read_on_all_link_options": 0, + "fieldname": "representative_email_id", + "fieldtype": "Data", + "hidden": 0, + "label": "Representative's Email Address", + "max_length": 0, + "max_value": 0, + "options": "Email", + "precision": "", + "read_only": 0, + "reqd": 1, + "show_in_filter": 0 + }, + { + "allow_read_on_all_link_options": 0, + "fieldname": "county", + "fieldtype": "Select", + "hidden": 0, + "label": "County", + "max_length": 0, + "max_value": 0, + "options": "\nBaringo\nBomet\nBungoma\nBusia\nElgeyo-Marakwet\nEmbu\nGarissa\nHoma Bay\nIsiolo\nKajiado\nKakamega\nKericho\nKiambu\nKilifi\nKirinyaga\nKisii\nKisumu\nKitui\nKwale\nLaikipia\nLamu\nMachakos\nMakueni\nMandera\nMarsabit\nMeru\nMigori\nMombasa\nMurang'a\nNairobi\nNakuru\nNandi\nNarok\nNyamira\nNyandarua\nNyeri\nSamburu\nSiaya\nTaita\u2013Taveta\nTana River\nTharaka-Nithi\nTrans-Nzoia\nTurkana\nUasin Gishu\nVihiga\nWajir\nWest Pokot", + "precision": "", + "read_only": 0, + "reqd": 1, + "show_in_filter": 0 + }, + { + "allow_read_on_all_link_options": 0, + "default": "Pending", + "fieldname": "member_approval_status", + "fieldtype": "Select", + "hidden": 1, + "label": "Member Approval Status", + "max_length": 0, + "max_value": 0, + "options": "\nPending\nApproved", + "precision": "", + "read_only": 0, + "reqd": 0, + "show_in_filter": 0 + }, + { + "allow_read_on_all_link_options": 0, + "fieldname": "column_break_5", + "fieldtype": "Column Break", + "hidden": 0, + "max_length": 0, + "max_value": 0, + "precision": "", + "read_only": 0, + "reqd": 0, + "show_in_filter": 0 + }, + { + "allow_read_on_all_link_options": 0, + "fieldname": "kmpdc_registration", + "fieldtype": "Attach", + "hidden": 0, + "label": "KMPDC Registration", + "max_length": 0, + "max_value": 0, + "precision": "", + "read_only": 0, + "reqd": 0, + "show_in_filter": 0 + }, + { + "allow_read_on_all_link_options": 0, + "fieldname": "kmpdc_current_license", + "fieldtype": "Attach", + "hidden": 0, + "label": "KMPDC Current License", + "max_length": 0, + "max_value": 0, + "precision": "", + "read_only": 0, + "reqd": 0, + "show_in_filter": 0 + }, + { + "allow_read_on_all_link_options": 0, + "fieldname": "nhif_hospital_code", + "fieldtype": "Int", + "hidden": 0, + "label": "NHIF Hospital Code", + "max_length": 0, + "max_value": 0, + "precision": "", + "read_only": 0, + "reqd": 0, + "show_in_filter": 0 + }, + { + "allow_read_on_all_link_options": 0, + "fieldname": "mfl_code", + "fieldtype": "Int", + "hidden": 0, + "label": "MFL CODE", + "max_length": 0, + "max_value": 0, + "precision": "", + "read_only": 0, + "reqd": 0, + "show_in_filter": 0 + }, + { + "allow_read_on_all_link_options": 0, + "fieldname": "directors_id", + "fieldtype": "Attach", + "hidden": 0, + "label": "Directors ID", + "max_length": 0, + "max_value": 0, + "precision": "", + "read_only": 0, + "reqd": 0, + "show_in_filter": 0 + }, + { + "allow_read_on_all_link_options": 0, + "fieldname": "kra_pin", + "fieldtype": "Attach", + "hidden": 0, + "label": "KRA PIN", + "max_length": 0, + "max_value": 0, + "precision": "", + "read_only": 0, + "reqd": 0, + "show_in_filter": 0 + }, + { + "allow_read_on_all_link_options": 0, + "fieldname": "keph_level", + "fieldtype": "Select", + "hidden": 0, + "label": "KEPH Level", + "max_length": 0, + "max_value": 0, + "options": "\n1\n2\n3A\n3B\n4\n5\n6", + "precision": "", + "read_only": 0, + "reqd": 0, + "show_in_filter": 0 + }, + { + "allow_read_on_all_link_options": 0, + "fieldname": "bed_capacity", + "fieldtype": "Int", + "hidden": 0, + "label": "Bed Capacity", + "max_length": 0, + "max_value": 0, + "precision": "", + "read_only": 0, + "reqd": 0, + "show_in_filter": 0 + }, + { + "allow_read_on_all_link_options": 0, + "fieldname": "services_offered", + "fieldtype": "Small Text", + "hidden": 0, + "label": "Services Offered", + "max_length": 0, + "max_value": 0, + "precision": "", + "read_only": 0, + "reqd": 0, + "show_in_filter": 0 + }, + { + "allow_read_on_all_link_options": 0, + "fieldname": "exhibition_stand_optin", + "fieldtype": "Select", + "hidden": 0, + "label": "Exhibition Stand Optin", + "max_length": 0, + "max_value": 0, + "options": "\nExhibition stand 2 days\nNot interested", + "precision": "", + "read_only": 0, + "reqd": 0, + "show_in_filter": 0 + } + ] +} \ No newline at end of file diff --git a/non_profit/non_profit/web_form/member_application_form/member_application_form.py b/non_profit/non_profit/web_form/member_application_form/member_application_form.py new file mode 100644 index 00000000..e1ada619 --- /dev/null +++ b/non_profit/non_profit/web_form/member_application_form/member_application_form.py @@ -0,0 +1,5 @@ +import frappe + +def get_context(context): + # do your magic here + pass From e1aca723925da4a4956969fee81d0bb9b52246d2 Mon Sep 17 00:00:00 2001 From: FrankDickenz Date: Thu, 4 Jul 2024 12:35:34 +0300 Subject: [PATCH 23/31] Subscription --- .../non_profit/doctype/member/member.py | 85 ++++++++++++++++++- .../doctype/subscription_period/__init__.py | 0 .../subscription_period.json | 49 +++++++++++ .../subscription_period.py | 9 ++ 4 files changed, 139 insertions(+), 4 deletions(-) create mode 100644 non_profit/non_profit/doctype/subscription_period/__init__.py create mode 100644 non_profit/non_profit/doctype/subscription_period/subscription_period.json create mode 100644 non_profit/non_profit/doctype/subscription_period/subscription_period.py diff --git a/non_profit/non_profit/doctype/member/member.py b/non_profit/non_profit/doctype/member/member.py index 81108485..7faf0017 100644 --- a/non_profit/non_profit/doctype/member/member.py +++ b/non_profit/non_profit/doctype/member/member.py @@ -14,6 +14,42 @@ class Member(Document): + @frappe.whitelist() + def create_membership_and_link(self): + if self.member_approval_status != "Approved": + frappe.msgprint(_("Member is not approved yet")) + return + + existing_membership = frappe.get_all( + "Membership", filters={"member": self.name}) + if existing_membership: + frappe.msgprint(_("Membership already exists for this Member")) + return + + membership = create_membership(frappe._dict({ + 'member': self.name, + 'membership_type': self.membership_type, + 'from_date': self.initial_membership, + 'to_date': self.membership_expiry_date + })) + + frappe.msgprint( + _("Membership {0} has been created successfully.").format(membership)) + + # Create subscription after membership is successfully created + subscription = create_subscription(frappe._dict({ + 'party': self.customer, + 'self.name': membership, + 'start_date': self.initial_membership, + 'end_date': self.membership_expiry_date, + 'plans': [{ + 'plan': "Ordinary Member", + 'qty': '1' + }] + })) + + frappe.msgprint( + _("Subscription {0} has been created successfully.").format(subscription)) def create_contact_and_address(self): try: @@ -51,9 +87,11 @@ def create_contact_and_address(self): }] }) address.insert(ignore_permissions=True, ignore_mandatory=True) - frappe.logger().info(f"Address {address.name} created for Member {self.name}.") + frappe.logger().info( + f"Address {address.name} created for Member {self.name}.") - frappe.logger().info( f"HTML fields updated for Member {self.name}.") + frappe.logger().info( + f"HTML fields updated for Member {self.name}.") # self.contact_html @@ -69,14 +107,13 @@ def after_insert(self): self.generate_qr_code() self.send_email_to_member() self.create_contact_and_address() - frappe.logger().info( - f"Member {self.name} inserted, creating contact and address.") def validate(self): if self.member_approval_status == "Approved" and not self.customer: self.make_customer_and_link() if self.email_id: self.validate_email_type(self.email_id) + self.create_membership_and_link() def validate_email_type(self, email): from frappe.utils import validate_email_address @@ -360,3 +397,43 @@ def register_member(fullname, email, rzpay_plan_id, subscription_id, pan=None, m )) return member.name + + +def create_membership(details): + membership = frappe.new_doc("Membership") + membership.member = details.member + membership.membership_type = details.membership_type + membership.from_date = details.from_date + membership.to_date = details.to_date + membership.membership_status = 'New' + membership.insert(ignore_permissions=True) + + try: + frappe.db.savepoint("membership_creation") + + except frappe.DuplicateEntryError: + return membership.name + + except Exception as e: + frappe.db.rollback(save_point="membership_creation") + frappe.log_error(frappe.get_traceback(), + _("Membership Creation Failed")) + pass + + return membership.name + + +def create_subscription(details): + subscription = frappe.new_doc("Subscription") + subscription.membership = details.membership # Link to the created membership + subscription.party_type = "Customer" + subscription.party = details.party + subscription.start_date = details.start_date + subscription.end_date = details.end_date + + plans = details.get('plans', []) + if plans: + for plan_detail in plans: + subscription.append("plans", plan_detail) + subscription.insert(ignore_permissions=True) + return subscription.name diff --git a/non_profit/non_profit/doctype/subscription_period/__init__.py b/non_profit/non_profit/doctype/subscription_period/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/non_profit/non_profit/doctype/subscription_period/subscription_period.json b/non_profit/non_profit/doctype/subscription_period/subscription_period.json new file mode 100644 index 00000000..a92b6050 --- /dev/null +++ b/non_profit/non_profit/doctype/subscription_period/subscription_period.json @@ -0,0 +1,49 @@ +{ + "actions": [], + "allow_rename": 1, + "creation": "2024-07-03 12:16:15.018339", + "doctype": "DocType", + "editable_grid": 1, + "engine": "InnoDB", + "field_order": [ + "item", + "rate", + "is_registration" + ], + "fields": [ + { + "fieldname": "item", + "fieldtype": "Link", + "in_list_view": 1, + "label": "Item", + "options": "Item", + "reqd": 1 + }, + { + "fieldname": "rate", + "fieldtype": "Currency", + "in_list_view": 1, + "label": "Rate", + "reqd": 1 + }, + { + "default": "0", + "fieldname": "is_registration", + "fieldtype": "Check", + "in_list_view": 1, + "label": "Is Registration" + } + ], + "index_web_pages_for_search": 1, + "istable": 1, + "links": [], + "modified": "2024-07-03 12:24:37.494090", + "modified_by": "Administrator", + "module": "Non Profit", + "name": "Subscription Period", + "owner": "Administrator", + "permissions": [], + "sort_field": "modified", + "sort_order": "DESC", + "states": [] +} \ No newline at end of file diff --git a/non_profit/non_profit/doctype/subscription_period/subscription_period.py b/non_profit/non_profit/doctype/subscription_period/subscription_period.py new file mode 100644 index 00000000..c0981031 --- /dev/null +++ b/non_profit/non_profit/doctype/subscription_period/subscription_period.py @@ -0,0 +1,9 @@ +# Copyright (c) 2024, Frappe and contributors +# For license information, please see license.txt + +# import frappe +from frappe.model.document import Document + + +class SubscriptionPeriod(Document): + pass From e251888e0a3c0ef2deef95e59cb2aa57f9b07d1a Mon Sep 17 00:00:00 2001 From: FrankDickenz Date: Tue, 9 Jul 2024 14:11:25 +0300 Subject: [PATCH 24/31] Invoice Generation --- non_profit/non_profit/doctype/member/member.py | 15 +++++++++++++++ .../non_profit/doctype/membership/membership.py | 1 + 2 files changed, 16 insertions(+) diff --git a/non_profit/non_profit/doctype/member/member.py b/non_profit/non_profit/doctype/member/member.py index 7faf0017..ffc49976 100644 --- a/non_profit/non_profit/doctype/member/member.py +++ b/non_profit/non_profit/doctype/member/member.py @@ -11,6 +11,8 @@ from payments.utils import get_payment_gateway_controller from non_profit.non_profit.doctype.membership_type.membership_type import get_membership_type +from erpnext.accounts.doctype.subscription.subscription import Subscription +from erpnext.accounts.doctype.subscription.subscription import is_prorate, get_prorata_factor, process_all class Member(Document): @@ -51,6 +53,16 @@ def create_membership_and_link(self): frappe.msgprint( _("Subscription {0} has been created successfully.").format(subscription)) + # Check if subscription was successfully created before creating invoice + if subscription: + subscription_doc = frappe.get_doc("Subscription", subscription) + invoicing = subscription_doc.create_invoice() + invoicing.submit() + frappe.msgprint(_("Invoice created and submitted successfully.")) + else: + frappe.msgprint( + _("Failed to create subscription. Invoice creation aborted.")) + def create_contact_and_address(self): try: # Create Contact @@ -430,6 +442,9 @@ def create_subscription(details): subscription.party = details.party subscription.start_date = details.start_date subscription.end_date = details.end_date + subscription.generate_new_invoices_past_due_date = 1 + subscription.submit_invoice = 1 + subscription.generate_invoice_at = 'Beginning of the current subscription period' plans = details.get('plans', []) if plans: diff --git a/non_profit/non_profit/doctype/membership/membership.py b/non_profit/non_profit/doctype/membership/membership.py index 8ab86910..c43ff143 100644 --- a/non_profit/non_profit/doctype/membership/membership.py +++ b/non_profit/non_profit/doctype/membership/membership.py @@ -14,6 +14,7 @@ from non_profit.non_profit.doctype.member.member import create_member + class Membership(Document): def validate(self): if not self.member or not frappe.db.exists("Member", self.member): From 750d6f9c58777cc5ff666a99e6a920d131a2219c Mon Sep 17 00:00:00 2001 From: FrankDickenz Date: Fri, 12 Jul 2024 02:05:57 +0300 Subject: [PATCH 25/31] Subscription Period --- non_profit/hooks.py | 49 +++++++++-------- .../non_profit/doctype/member/member.js | 32 +++++------ .../non_profit/doctype/member/member.py | 51 +++++++++++++++++- .../member_subscription_settings/__init__.py | 0 .../member_subscription_settings.js | 8 +++ .../member_subscription_settings.json | 46 ++++++++++++++++ .../member_subscription_settings.py | 9 ++++ .../test_member_subscription_settings.py | 9 ++++ .../subscription_period.js | 8 +++ .../subscription_period.json | 53 +++++++++++-------- .../test_subscription_period.py | 9 ++++ 11 files changed, 212 insertions(+), 62 deletions(-) create mode 100644 non_profit/non_profit/doctype/member_subscription_settings/__init__.py create mode 100644 non_profit/non_profit/doctype/member_subscription_settings/member_subscription_settings.js create mode 100644 non_profit/non_profit/doctype/member_subscription_settings/member_subscription_settings.json create mode 100644 non_profit/non_profit/doctype/member_subscription_settings/member_subscription_settings.py create mode 100644 non_profit/non_profit/doctype/member_subscription_settings/test_member_subscription_settings.py create mode 100644 non_profit/non_profit/doctype/subscription_period/subscription_period.js create mode 100644 non_profit/non_profit/doctype/subscription_period/test_subscription_period.py diff --git a/non_profit/hooks.py b/non_profit/hooks.py index 28d4c2eb..c8cadfbf 100644 --- a/non_profit/hooks.py +++ b/non_profit/hooks.py @@ -36,7 +36,7 @@ # include js in doctype views # doctype_js = {"doctype" : "public/js/doctype.js"} doctype_js = { - "Sales Invoice": "public/js/payment_entry.js" + "Sales Invoice": "public/js/payment_entry.js" } # doctype_list_js = {"doctype" : "public/js/doctype_list.js"} # doctype_tree_js = {"doctype" : "public/js/doctype_tree.js"} @@ -50,7 +50,7 @@ # website user home page (by Role) # role_home_page = { -# "Role": "home_page" +# "Role": "home_page" # } # Generators @@ -103,28 +103,33 @@ # Override standard doctype classes override_doctype_class = { - "Payment Entry": "non_profit.non_profit.custom_doctype.payment_entry.NonProfitPaymentEntry", + "Payment Entry": "non_profit.non_profit.custom_doctype.payment_entry.NonProfitPaymentEntry", } # Document Events # --------------- # Hook on document methods and events +doc_events = { + "Subscription": { + "before_validate": "non_profit.non_profit.doctype.member.member.extend_subscription" + } +} # doc_events = { # "*": { # "on_update": "method", # "on_cancel": "method", # "on_trash": "method" -# } +# } # } # Scheduled Tasks # --------------- scheduler_events = { - "daily": [ - "non_profit.non_profit.doctype.membership.membership.set_expired_status", - ], + "daily": [ + "non_profit.non_profit.doctype.membership.membership.set_expired_status", + ], } # Testing @@ -184,22 +189,22 @@ global_search_doctypes = { - "Non Profit": [ - {'doctype': 'Certified Consultant', 'index': 1}, - {'doctype': 'Certification Application', 'index': 2}, - {'doctype': 'Volunteer', 'index': 3}, - {'doctype': 'Membership', 'index': 4}, - {'doctype': 'Member', 'index': 5}, - {'doctype': 'Donor', 'index': 6}, - {'doctype': 'Chapter', 'index': 7}, - {'doctype': 'Grant Application', 'index': 8}, - {'doctype': 'Volunteer Type', 'index': 9}, - {'doctype': 'Donor Type', 'index': 10}, - {'doctype': 'Membership Type', 'index': 11} - ] + "Non Profit": [ + {'doctype': 'Certified Consultant', 'index': 1}, + {'doctype': 'Certification Application', 'index': 2}, + {'doctype': 'Volunteer', 'index': 3}, + {'doctype': 'Membership', 'index': 4}, + {'doctype': 'Member', 'index': 5}, + {'doctype': 'Donor', 'index': 6}, + {'doctype': 'Chapter', 'index': 7}, + {'doctype': 'Grant Application', 'index': 8}, + {'doctype': 'Volunteer Type', 'index': 9}, + {'doctype': 'Donor Type', 'index': 10}, + {'doctype': 'Membership Type', 'index': 11} + ] } standard_portal_menu_items = [ - {"title": _("Certification"), "route": "/certification", - "reference_doctype": "Certification Application", "role": "Non Profit Portal User"}, + {"title": _("Certification"), "route": "/certification", + "reference_doctype": "Certification Application", "role": "Non Profit Portal User"}, ] diff --git a/non_profit/non_profit/doctype/member/member.js b/non_profit/non_profit/doctype/member/member.js index 1821448a..0a7151f7 100644 --- a/non_profit/non_profit/doctype/member/member.js +++ b/non_profit/non_profit/doctype/member/member.js @@ -46,22 +46,22 @@ frappe.ui.form.on('Member', { frappe.contacts.clear_address_and_contact(frm); } - frappe.call({ - method: "frappe.client.get_value", - args: { - 'doctype': "Membership", - 'filters': { 'member': frm.doc.name }, - 'fieldname': [ - 'to_date' - ] - }, - callback: function (data) { - if (data.message) { - frappe.model.set_value(frm.doctype, frm.docname, - "membership_expiry_date", data.message.to_date); - } - } - }); + // frappe.call({ + // method: "frappe.client.get_value", + // args: { + // 'doctype': "Membership", + // 'filters': { 'member': frm.doc.name }, + // 'fieldname': [ + // 'to_date' + // ] + // }, + // callback: function (data) { + // if (data.message) { + // frappe.model.set_value(frm.doctype, frm.docname, + // "membership_expiry_date", data.message.to_date); + // } + // } + // }); } }); diff --git a/non_profit/non_profit/doctype/member/member.py b/non_profit/non_profit/doctype/member/member.py index ffc49976..432e43d5 100644 --- a/non_profit/non_profit/doctype/member/member.py +++ b/non_profit/non_profit/doctype/member/member.py @@ -8,6 +8,7 @@ from frappe.model.document import Document from frappe.utils import cint, get_link_to_form +from frappe.utils.data import add_to_date, getdate from payments.utils import get_payment_gateway_controller from non_profit.non_profit.doctype.membership_type.membership_type import get_membership_type @@ -16,6 +17,14 @@ class Member(Document): + def validate_membership_expiry_date(self): + period = get_subscription_period(self.initial_membership) + + if period: + self.membership_expiry_date = period['end_date'] + else: + frappe.throw("Subscription period not found for the given initial membership date.") + @frappe.whitelist() def create_membership_and_link(self): if self.member_approval_status != "Approved": @@ -27,7 +36,8 @@ def create_membership_and_link(self): if existing_membership: frappe.msgprint(_("Membership already exists for this Member")) return - + period = get_subscription_period(self.initial_membership) + membership = create_membership(frappe._dict({ 'member': self.name, 'membership_type': self.membership_type, @@ -121,6 +131,7 @@ def after_insert(self): self.create_contact_and_address() def validate(self): + self.validate_membership_expiry_date() if self.member_approval_status == "Approved" and not self.customer: self.make_customer_and_link() if self.email_id: @@ -452,3 +463,41 @@ def create_subscription(details): subscription.append("plans", plan_detail) subscription.insert(ignore_permissions=True) return subscription.name + + +def get_subscription_period(start_date): + start_date = getdate(start_date) + subscription_period = frappe.db.sql(""" + SELECT name, start_date, end_date + FROM `tabSubscription Period` + WHERE start_date <= %s AND end_date >= %s + LIMIT 1 + """, (start_date, start_date), as_dict=True) + + if subscription_period: + return subscription_period[0] + else: + return None + +def validate_end_date(self): + period = get_subscription_period(self.start_date) + if period: + self.end_date = period.end_date + + billing_cycle_info = self.get_billing_cycle_data() + end_date = add_to_date(self.start_date, **billing_cycle_info) + + # if self.end_date and getdate(self.end_date) <= getdate(end_date): + # frappe.throw( + # _("Subscription End Date must be after {0} as per the subscription plan").format(end_date) + # ) + +# Override the original validate method +def override_subscription_validate(): + from erpnext.accounts.doctype.subscription.subscription import Subscription + + Subscription.validate_end_date = validate_end_date + +# Hook to extend the Subscription doctype +def extend_subscription(doc, method): + override_subscription_validate() \ No newline at end of file diff --git a/non_profit/non_profit/doctype/member_subscription_settings/__init__.py b/non_profit/non_profit/doctype/member_subscription_settings/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/non_profit/non_profit/doctype/member_subscription_settings/member_subscription_settings.js b/non_profit/non_profit/doctype/member_subscription_settings/member_subscription_settings.js new file mode 100644 index 00000000..9a2f5ea6 --- /dev/null +++ b/non_profit/non_profit/doctype/member_subscription_settings/member_subscription_settings.js @@ -0,0 +1,8 @@ +// Copyright (c) 2024, Frappe and contributors +// For license information, please see license.txt + +// frappe.ui.form.on("Member Subscription Settings", { +// refresh(frm) { + +// }, +// }); diff --git a/non_profit/non_profit/doctype/member_subscription_settings/member_subscription_settings.json b/non_profit/non_profit/doctype/member_subscription_settings/member_subscription_settings.json new file mode 100644 index 00000000..7affb293 --- /dev/null +++ b/non_profit/non_profit/doctype/member_subscription_settings/member_subscription_settings.json @@ -0,0 +1,46 @@ +{ + "actions": [], + "allow_rename": 1, + "creation": "2024-07-11 12:07:12.522539", + "doctype": "DocType", + "engine": "InnoDB", + "field_order": [ + "start_month", + "end_month" + ], + "fields": [ + { + "fieldname": "start_month", + "fieldtype": "Select", + "label": "Start Month" + }, + { + "fieldname": "end_month", + "fieldtype": "Select", + "label": "End Month" + } + ], + "index_web_pages_for_search": 1, + "issingle": 1, + "links": [], + "modified": "2024-07-11 12:08:35.772761", + "modified_by": "Administrator", + "module": "Non Profit", + "name": "Member Subscription 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/non_profit/non_profit/doctype/member_subscription_settings/member_subscription_settings.py b/non_profit/non_profit/doctype/member_subscription_settings/member_subscription_settings.py new file mode 100644 index 00000000..d27beddd --- /dev/null +++ b/non_profit/non_profit/doctype/member_subscription_settings/member_subscription_settings.py @@ -0,0 +1,9 @@ +# Copyright (c) 2024, Frappe and contributors +# For license information, please see license.txt + +# import frappe +from frappe.model.document import Document + + +class MemberSubscriptionSettings(Document): + pass diff --git a/non_profit/non_profit/doctype/member_subscription_settings/test_member_subscription_settings.py b/non_profit/non_profit/doctype/member_subscription_settings/test_member_subscription_settings.py new file mode 100644 index 00000000..4e865807 --- /dev/null +++ b/non_profit/non_profit/doctype/member_subscription_settings/test_member_subscription_settings.py @@ -0,0 +1,9 @@ +# Copyright (c) 2024, Frappe and Contributors +# See license.txt + +# import frappe +from frappe.tests.utils import FrappeTestCase + + +class TestMemberSubscriptionSettings(FrappeTestCase): + pass diff --git a/non_profit/non_profit/doctype/subscription_period/subscription_period.js b/non_profit/non_profit/doctype/subscription_period/subscription_period.js new file mode 100644 index 00000000..4a7a407a --- /dev/null +++ b/non_profit/non_profit/doctype/subscription_period/subscription_period.js @@ -0,0 +1,8 @@ +// Copyright (c) 2024, Frappe and contributors +// For license information, please see license.txt + +// frappe.ui.form.on("Subscription Period", { +// refresh(frm) { + +// }, +// }); diff --git a/non_profit/non_profit/doctype/subscription_period/subscription_period.json b/non_profit/non_profit/doctype/subscription_period/subscription_period.json index a92b6050..980236c8 100644 --- a/non_profit/non_profit/doctype/subscription_period/subscription_period.json +++ b/non_profit/non_profit/doctype/subscription_period/subscription_period.json @@ -1,48 +1,55 @@ { "actions": [], - "allow_rename": 1, + "autoname": "field:period", "creation": "2024-07-03 12:16:15.018339", "doctype": "DocType", "editable_grid": 1, "engine": "InnoDB", "field_order": [ - "item", - "rate", - "is_registration" + "period", + "start_date", + "end_date" ], "fields": [ { - "fieldname": "item", - "fieldtype": "Link", - "in_list_view": 1, - "label": "Item", - "options": "Item", - "reqd": 1 + "fieldname": "period", + "fieldtype": "Data", + "label": "Period", + "unique": 1 }, { - "fieldname": "rate", - "fieldtype": "Currency", - "in_list_view": 1, - "label": "Rate", - "reqd": 1 + "fieldname": "start_date", + "fieldtype": "Date", + "label": "Start Date" }, { - "default": "0", - "fieldname": "is_registration", - "fieldtype": "Check", - "in_list_view": 1, - "label": "Is Registration" + "fieldname": "end_date", + "fieldtype": "Date", + "label": "End Date" } ], "index_web_pages_for_search": 1, - "istable": 1, "links": [], - "modified": "2024-07-03 12:24:37.494090", + "modified": "2024-07-11 12:04:22.047205", "modified_by": "Administrator", "module": "Non Profit", "name": "Subscription Period", + "naming_rule": "By fieldname", "owner": "Administrator", - "permissions": [], + "permissions": [ + { + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "System Manager", + "share": 1, + "write": 1 + } + ], "sort_field": "modified", "sort_order": "DESC", "states": [] diff --git a/non_profit/non_profit/doctype/subscription_period/test_subscription_period.py b/non_profit/non_profit/doctype/subscription_period/test_subscription_period.py new file mode 100644 index 00000000..3dbf9cb8 --- /dev/null +++ b/non_profit/non_profit/doctype/subscription_period/test_subscription_period.py @@ -0,0 +1,9 @@ +# Copyright (c) 2024, Frappe and Contributors +# See license.txt + +# import frappe +from frappe.tests.utils import FrappeTestCase + + +class TestSubscriptionPeriod(FrappeTestCase): + pass From bff885ebf4b17ee4b0fb163e57cfbf2bf792d6e3 Mon Sep 17 00:00:00 2001 From: FrankDickenz Date: Fri, 12 Jul 2024 10:25:06 +0300 Subject: [PATCH 26/31] Membership Type Edits --- non_profit/non_profit/doctype/member/member.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/non_profit/non_profit/doctype/member/member.py b/non_profit/non_profit/doctype/member/member.py index 432e43d5..adeb24ea 100644 --- a/non_profit/non_profit/doctype/member/member.py +++ b/non_profit/non_profit/doctype/member/member.py @@ -47,6 +47,11 @@ def create_membership_and_link(self): frappe.msgprint( _("Membership {0} has been created successfully.").format(membership)) + + if self.membership_type.lower() == "ordinary member": + plan = "Membership Annual Sub" + else: + plan = "Ordinary Member" # Create subscription after membership is successfully created subscription = create_subscription(frappe._dict({ @@ -55,7 +60,7 @@ def create_membership_and_link(self): 'start_date': self.initial_membership, 'end_date': self.membership_expiry_date, 'plans': [{ - 'plan': "Ordinary Member", + 'plan': plan, 'qty': '1' }] })) From 39009b63d0b1a51a01caff0fa6df64afaf24f14a Mon Sep 17 00:00:00 2001 From: Mohamud Amin Ali Date: Thu, 7 May 2026 12:56:36 +0300 Subject: [PATCH 27/31] add pyproject.toml file Signed-off-by: Mohamud Amin Ali --- pyproject.toml | 1 + 1 file changed, 1 insertion(+) create mode 100644 pyproject.toml diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1 @@ + From 137264f753d7779e3b1f7687c4da3d97676e4387 Mon Sep 17 00:00:00 2001 From: Mohamud Amin Ali Date: Thu, 7 May 2026 12:58:26 +0300 Subject: [PATCH 28/31] Scaffold minimal pyproject.toml --- pyproject.toml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index 8b137891..b9e3b31a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1 +1,19 @@ +[build-system] +requires = ["setuptools>=68", "wheel"] +build-backend = "setuptools.build_meta" +[project] +name = "non-profit" +version = "0.1.0" +description = "Minimum viable Python project scaffold for the non_profit application." +readme = "README.md" +requires-python = ">=3.10" +license = { text = "Proprietary" } +authors = [{ name = "RUPHAsoft" }] + +# Keep dependencies empty for now since requirements.txt is empty and +# the repo appears to have no declared runtime deps. +dependencies = [] + +[tool.setuptools] +# No packaging layout assumptions; keep minimal. From 5946247df63e95aca9d06d1f4132c88264bae71c Mon Sep 17 00:00:00 2001 From: Mohamud Amin Ali Date: Fri, 8 May 2026 09:24:13 +0300 Subject: [PATCH 29/31] Comment out setup function and requirements Comment out the setup configuration in setup.py Signed-off-by: Mohamud Amin Ali --- setup.py | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/setup.py b/setup.py index d969ed16..ff4e799f 100644 --- a/setup.py +++ b/setup.py @@ -1,19 +1,19 @@ -from setuptools import setup, find_packages +# from setuptools import setup, find_packages -with open("requirements.txt") as f: - install_requires = f.read().strip().split("\n") +# with open("requirements.txt") as f: +# install_requires = f.read().strip().split("\n") -# get version from __version__ variable in non_profit/__init__.py -from non_profit import __version__ as version +# # get version from __version__ variable in non_profit/__init__.py +# from non_profit import __version__ as version -setup( - name="non_profit", - version=version, - description="Non Profit", - author="Frappe", - author_email="pandikunta@frappe.io", - packages=find_packages(), - zip_safe=False, - include_package_data=True, - install_requires=install_requires -) +# setup( +# name="non_profit", +# version=version, +# description="Non Profit", +# author="Frappe", +# author_email="pandikunta@frappe.io", +# packages=find_packages(), +# zip_safe=False, +# include_package_data=True, +# install_requires=install_requires +# ) From 4d539d7a41feca09b4866297619dceae9b2a6779 Mon Sep 17 00:00:00 2001 From: Mohamud Amin Ali Date: Sat, 9 May 2026 06:55:07 +0300 Subject: [PATCH 30/31] Uncomment setup configuration in setup.py Signed-off-by: Mohamud Amin Ali --- setup.py | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/setup.py b/setup.py index ff4e799f..3b6d9fc3 100644 --- a/setup.py +++ b/setup.py @@ -1,19 +1,19 @@ -# from setuptools import setup, find_packages +from setuptools import setup, find_packages -# with open("requirements.txt") as f: -# install_requires = f.read().strip().split("\n") +with open("requirements.txt") as f: + install_requires = f.read().strip().split("\n") -# # get version from __version__ variable in non_profit/__init__.py +# get version from __version__ variable in non_profit/__init__.py # from non_profit import __version__ as version -# setup( -# name="non_profit", -# version=version, -# description="Non Profit", -# author="Frappe", -# author_email="pandikunta@frappe.io", -# packages=find_packages(), -# zip_safe=False, -# include_package_data=True, -# install_requires=install_requires -# ) +setup( + name="non_profit", + version="0.0.1", + description="Non Profit", + author="Frappe", + author_email="pandikunta@frappe.io", + packages=find_packages(), + zip_safe=False, + include_package_data=True, + install_requires=install_requires +) From 16dd11116b049c67f090a50495277ddb40678978 Mon Sep 17 00:00:00 2001 From: Mohamud Amin Ali Date: Sat, 9 May 2026 07:03:38 +0300 Subject: [PATCH 31/31] Rename project from 'non-profit' to 'non_profit' Signed-off-by: Mohamud Amin Ali --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index b9e3b31a..f9fd5671 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,7 +3,7 @@ requires = ["setuptools>=68", "wheel"] build-backend = "setuptools.build_meta" [project] -name = "non-profit" +name = "non_profit" version = "0.1.0" description = "Minimum viable Python project scaffold for the non_profit application." readme = "README.md"