From 4e40b9bdbe364ea19efb665ddc80daf159f853f7 Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Wed, 24 Jun 2020 15:41:19 +0530 Subject: [PATCH 1/4] feat: log everything --- .../doctype/membership/membership.py | 65 +++++++++++-------- 1 file changed, 37 insertions(+), 28 deletions(-) diff --git a/erpnext/non_profit/doctype/membership/membership.py b/erpnext/non_profit/doctype/membership/membership.py index 7a0caed621..a2c63afa86 100644 --- a/erpnext/non_profit/doctype/membership/membership.py +++ b/erpnext/non_profit/doctype/membership/membership.py @@ -81,17 +81,24 @@ def verify_signature(data): @frappe.whitelist(allow_guest=True) def trigger_razorpay_subscription(*args, **kwargs): data = frappe.request.get_data(as_text=True) - verify_signature(data) + try: + verify_signature(data) + except Exception as e: + frappe.log_error(e, "Webhook Verification Error") if isinstance(data, six.string_types): data = json.loads(data) data = frappe._dict(data) - subscription = data.payload.get("subscription", {}).get('entity', {}) - subscription = frappe._dict(subscription) + try: + subscription = data.payload.get("subscription", {}).get('entity', {}) + subscription = frappe._dict(subscription) - payment = data.payload.get("payment", {}).get('entity', {}) - payment = frappe._dict(payment) + payment = data.payload.get("payment", {}).get('entity', {}) + payment = frappe._dict(payment) + except Exception as e: + frappe.log_error(e, "Webhook Data Parsing Error") + return False try: data_json = json.dumps(data, indent=4, sort_keys=True) @@ -103,30 +110,32 @@ def trigger_razorpay_subscription(*args, **kwargs): if not member: return False + try: + if data.event == "subscription.activated": + member.customer_id = payment.customer_id + elif data.event == "subscription.charged": + membership = frappe.new_doc("Membership") + membership.update({ + "member": member.name, + "membership_status": "Current", + "membership_type": member.membership_type, + "currency": "INR", + "paid": 1, + "payment_id": payment.id, + "webhook_payload": data_json, + "from_date": datetime.fromtimestamp(subscription.current_start), + "to_date": datetime.fromtimestamp(subscription.current_end), + "amount": payment.amount / 100 # Convert to rupees from paise + }) + membership.insert(ignore_permissions=True) - if data.event == "subscription.activated": - member.customer_id = payment.customer_id - elif data.event == "subscription.charged": - membership = frappe.new_doc("Membership") - membership.update({ - "member": member.name, - "membership_status": "Current", - "membership_type": member.membership_type, - "currency": "INR", - "paid": 1, - "payment_id": payment.id, - "webhook_payload": data_json, - "from_date": datetime.fromtimestamp(subscription.current_start), - "to_date": datetime.fromtimestamp(subscription.current_end), - "amount": payment.amount / 100 # Convert to rupees from paise - }) - membership.insert(ignore_permissions=True) - - # Update these values anyway - member.subscription_start = datetime.fromtimestamp(subscription.start_at) - member.subscription_end = datetime.fromtimestamp(subscription.end_at) - member.subscription_activated = 1 - member.save(ignore_permissions=True) + # Update these values anyway + member.subscription_start = datetime.fromtimestamp(subscription.start_at) + member.subscription_end = datetime.fromtimestamp(subscription.end_at) + member.subscription_activated = 1 + member.save(ignore_permissions=True) + except Exception as e: + frappe.log_error(e, "Error creating membership entry") return True From e43d362d53df7972b705c30268d4c590eacec059 Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Tue, 14 Jul 2020 19:45:29 +0530 Subject: [PATCH 2/4] feat: verbose logging for verification --- erpnext/non_profit/doctype/membership/membership.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/erpnext/non_profit/doctype/membership/membership.py b/erpnext/non_profit/doctype/membership/membership.py index a2c63afa86..eb393ec361 100644 --- a/erpnext/non_profit/doctype/membership/membership.py +++ b/erpnext/non_profit/doctype/membership/membership.py @@ -84,6 +84,8 @@ def trigger_razorpay_subscription(*args, **kwargs): try: verify_signature(data) except Exception as e: + signature = frappe.request.headers.get('X-Razorpay-Signature') + log = "{0} \n\n {1} \n\n {2} \n\n {3}".format(e, frappe.get_traceback(), signature, data) frappe.log_error(e, "Webhook Verification Error") if isinstance(data, six.string_types): From 9e3776e001d0bc0506356ebf352068bb5a9cd162 Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Mon, 27 Jul 2020 14:26:37 +0530 Subject: [PATCH 3/4] feat: improve webhook logging --- erpnext/non_profit/doctype/member/member.py | 2 +- .../doctype/membership/membership.py | 22 +++++++++---------- 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/erpnext/non_profit/doctype/member/member.py b/erpnext/non_profit/doctype/member/member.py index d1294ccc08..7818c99fbe 100644 --- a/erpnext/non_profit/doctype/member/member.py +++ b/erpnext/non_profit/doctype/member/member.py @@ -121,7 +121,7 @@ def create_member_subscription_order(user_details): 'subscription_id': 'sub_EZycCvXFvqnC6p' } """ - # {"plan_id":"IFF Starter","fullname":"Shivam Mishra","mobile":"7506056962","email":"shivam@shivam.dev","pan":"Testing123"} + user_details = frappe._dict(user_details) member = get_or_create_member(user_details) if not member: diff --git a/erpnext/non_profit/doctype/membership/membership.py b/erpnext/non_profit/doctype/membership/membership.py index eb393ec361..729e111e57 100644 --- a/erpnext/non_profit/doctype/membership/membership.py +++ b/erpnext/non_profit/doctype/membership/membership.py @@ -92,15 +92,11 @@ def trigger_razorpay_subscription(*args, **kwargs): data = json.loads(data) data = frappe._dict(data) - try: - subscription = data.payload.get("subscription", {}).get('entity', {}) - subscription = frappe._dict(subscription) + subscription = data.payload.get("subscription", {}).get('entity', {}) + subscription = frappe._dict(subscription) - payment = data.payload.get("payment", {}).get('entity', {}) - payment = frappe._dict(payment) - except Exception as e: - frappe.log_error(e, "Webhook Data Parsing Error") - return False + payment = data.payload.get("payment", {}).get('entity', {}) + payment = frappe._dict(payment) try: data_json = json.dumps(data, indent=4, sort_keys=True) @@ -108,10 +104,10 @@ def trigger_razorpay_subscription(*args, **kwargs): except Exception as e: error_log = frappe.log_error(frappe.get_traceback() + '\n' + data_json , _("Membership Webhook Failed")) notify_failure(error_log) - return False + return { status: 'Failed' } if not member: - return False + return { status: 'Failed' } try: if data.event == "subscription.activated": member.customer_id = payment.customer_id @@ -137,9 +133,11 @@ def trigger_razorpay_subscription(*args, **kwargs): member.subscription_activated = 1 member.save(ignore_permissions=True) except Exception as e: - frappe.log_error(e, "Error creating membership entry") + log = frappe.log_error(e, "Error creating membership entry") + notify_failure(log) + return { status: 'Failed' } - return True + return { status: 'Success' } def notify_failure(log): From 97a316c09ac48b70c09bae494b4a70e364aa0d79 Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Mon, 27 Jul 2020 15:24:50 +0530 Subject: [PATCH 4/4] feat: add create customer button to member --- erpnext/non_profit/doctype/member/member.js | 8 ++++++++ erpnext/non_profit/doctype/member/member.py | 19 +++++++++++++++++-- .../doctype/membership/membership.json | 4 +++- 3 files changed, 28 insertions(+), 3 deletions(-) diff --git a/erpnext/non_profit/doctype/member/member.js b/erpnext/non_profit/doctype/member/member.js index 3e9d0baba5..199dcfc04f 100644 --- a/erpnext/non_profit/doctype/member/member.js +++ b/erpnext/non_profit/doctype/member/member.js @@ -29,6 +29,14 @@ frappe.ui.form.on('Member', { frappe.set_route('query-report', 'Accounts Receivable', {member:frm.doc.name}); }); + if (!frm.doc.customer) { + frm.add_custom_button(__('Create Customer'), () => { + frm.call('make_customer_and_link').then(() => { + frm.reload_doc(); + }); + }); + } + // indicator erpnext.utils.set_party_dashboard_indicators(frm); diff --git a/erpnext/non_profit/doctype/member/member.py b/erpnext/non_profit/doctype/member/member.py index 7818c99fbe..c52082ca23 100644 --- a/erpnext/non_profit/doctype/member/member.py +++ b/erpnext/non_profit/doctype/member/member.py @@ -53,6 +53,19 @@ class Member(Document): return subscription + def make_customer_and_link(self): + if self.customer: + frappe.msgprint(_("A customer is already linked to this Member")) + cust = create_customer(frappe._dict({ + 'fullname': self.member_name, + 'email': self.email_id or self.user, + 'phone': None + })) + + self.customer = cust + self.save() + + 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]: @@ -83,8 +96,10 @@ def create_customer(user_details): try: contact = frappe.new_doc("Contact") contact.first_name = user_details.fullname - contact.add_phone(user_details.mobile, is_primary_phone=1, is_primary_mobile_no=1) - contact.add_email(user_details.email, is_primary=1) + 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", { diff --git a/erpnext/non_profit/doctype/membership/membership.json b/erpnext/non_profit/doctype/membership/membership.json index 9f10d0cfc7..238f4c31fd 100644 --- a/erpnext/non_profit/doctype/membership/membership.json +++ b/erpnext/non_profit/doctype/membership/membership.json @@ -120,13 +120,15 @@ { "fieldname": "webhook_payload", "fieldtype": "Code", + "hidden": 1, "label": "Webhook Payload", "options": "JSON", "read_only": 1 } ], + "index_web_pages_for_search": 1, "links": [], - "modified": "2020-04-06 14:29:33.856060", + "modified": "2020-07-27 14:28:11.532696", "modified_by": "Administrator", "module": "Non Profit", "name": "Membership",