Merge pull request #23038 from scmmishra/iff-invoicing
This commit is contained in:
commit
e91a5437bd
@ -133,7 +133,8 @@
|
|||||||
{
|
{
|
||||||
"fieldname": "email_id",
|
"fieldname": "email_id",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"label": "Email Address"
|
"label": "Email Address",
|
||||||
|
"options": "Email"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "subscription_id",
|
"fieldname": "subscription_id",
|
||||||
@ -176,7 +177,7 @@
|
|||||||
],
|
],
|
||||||
"image_field": "image",
|
"image_field": "image",
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2020-04-07 14:20:33.215700",
|
"modified": "2020-08-06 10:06:01.153564",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Non Profit",
|
"module": "Non Profit",
|
||||||
"name": "Member",
|
"name": "Member",
|
||||||
|
|||||||
@ -9,6 +9,7 @@ from frappe.model.document import Document
|
|||||||
from frappe.contacts.address_and_contact import load_address_and_contact
|
from frappe.contacts.address_and_contact import load_address_and_contact
|
||||||
from frappe.utils import cint
|
from frappe.utils import cint
|
||||||
from frappe.integrations.utils import get_payment_gateway_controller
|
from frappe.integrations.utils import get_payment_gateway_controller
|
||||||
|
from erpnext.non_profit.doctype.membership_type.membership_type import get_membership_type
|
||||||
|
|
||||||
class Member(Document):
|
class Member(Document):
|
||||||
def onload(self):
|
def onload(self):
|
||||||
@ -74,19 +75,23 @@ def get_or_create_member(user_details):
|
|||||||
return create_member(user_details)
|
return create_member(user_details)
|
||||||
|
|
||||||
def create_member(user_details):
|
def create_member(user_details):
|
||||||
|
user_details = frappe._dict(user_details)
|
||||||
member = frappe.new_doc("Member")
|
member = frappe.new_doc("Member")
|
||||||
member.update({
|
member.update({
|
||||||
"member_name": user_details.fullname,
|
"member_name": user_details.fullname,
|
||||||
"email_id": user_details.email,
|
"email_id": user_details.email,
|
||||||
"pan_number": user_details.pan,
|
"pan_number": user_details.pan or None,
|
||||||
"membership_type": user_details.plan_id,
|
"membership_type": user_details.plan_id,
|
||||||
"customer": create_customer(user_details)
|
"subscription_id": user_details.subscription_id or None
|
||||||
})
|
})
|
||||||
|
|
||||||
member.insert(ignore_permissions=True)
|
member.insert(ignore_permissions=True)
|
||||||
|
member.customer = create_customer(user_details, member.name)
|
||||||
|
member.save(ignore_permissions=True)
|
||||||
|
|
||||||
return member
|
return member
|
||||||
|
|
||||||
def create_customer(user_details):
|
def create_customer(user_details, member=None):
|
||||||
customer = frappe.new_doc("Customer")
|
customer = frappe.new_doc("Customer")
|
||||||
customer.customer_name = user_details.fullname
|
customer.customer_name = user_details.fullname
|
||||||
customer.customer_type = "Individual"
|
customer.customer_type = "Individual"
|
||||||
@ -107,7 +112,13 @@ def create_customer(user_details):
|
|||||||
"link_name": customer.name
|
"link_name": customer.name
|
||||||
})
|
})
|
||||||
|
|
||||||
contact.save()
|
if member:
|
||||||
|
contact.append("links", {
|
||||||
|
"link_doctype": "Member",
|
||||||
|
"link_name": member
|
||||||
|
})
|
||||||
|
|
||||||
|
contact.save(ignore_permissions=True)
|
||||||
|
|
||||||
except frappe.DuplicateEntryError:
|
except frappe.DuplicateEntryError:
|
||||||
return customer.name
|
return customer.name
|
||||||
@ -139,12 +150,31 @@ def create_member_subscription_order(user_details):
|
|||||||
|
|
||||||
user_details = frappe._dict(user_details)
|
user_details = frappe._dict(user_details)
|
||||||
member = get_or_create_member(user_details)
|
member = get_or_create_member(user_details)
|
||||||
if not member:
|
|
||||||
member = create_member(user_details)
|
|
||||||
|
|
||||||
subscription = member.setup_subscription()
|
subscription = member.setup_subscription()
|
||||||
|
|
||||||
member.subscription_id = subscription.get('subscription_id')
|
member.subscription_id = subscription.get('subscription_id')
|
||||||
member.save(ignore_permissions=True)
|
member.save(ignore_permissions=True)
|
||||||
|
|
||||||
return subscription
|
return subscription
|
||||||
|
|
||||||
|
@frappe.whitelist(allow_guest=True)
|
||||||
|
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
|
||||||
@ -8,6 +8,24 @@ frappe.ui.form.on('Membership', {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
|
refresh: function(frm) {
|
||||||
|
!frm.doc.invoice && frm.add_custom_button("Generate Invoice", () => {
|
||||||
|
frm.call("generate_invoice", {
|
||||||
|
save: true
|
||||||
|
}).then(() => {
|
||||||
|
frm.reload_doc();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
frappe.db.get_single_value("Membership Settings", "send_email").then(val => {
|
||||||
|
if (val) frm.add_custom_button("Send Acknowledgement", () => {
|
||||||
|
frm.call("send_acknowlement").then(() => {
|
||||||
|
frm.reload_doc();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
onload: function(frm) {
|
onload: function(frm) {
|
||||||
frm.add_fetch('membership_type', 'amount', 'amount');
|
frm.add_fetch('membership_type', 'amount', 'amount');
|
||||||
}
|
}
|
||||||
|
|||||||
@ -19,10 +19,10 @@
|
|||||||
"paid",
|
"paid",
|
||||||
"currency",
|
"currency",
|
||||||
"amount",
|
"amount",
|
||||||
|
"invoice",
|
||||||
"razorpay_details_section",
|
"razorpay_details_section",
|
||||||
"subscription_id",
|
"subscription_id",
|
||||||
"payment_id",
|
"payment_id"
|
||||||
"webhook_payload"
|
|
||||||
],
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
@ -118,17 +118,15 @@
|
|||||||
"read_only": 1
|
"read_only": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "webhook_payload",
|
"fieldname": "invoice",
|
||||||
"fieldtype": "Code",
|
"fieldtype": "Link",
|
||||||
"hidden": 1,
|
"label": "Invoice",
|
||||||
"label": "Webhook Payload",
|
"options": "Sales Invoice"
|
||||||
"options": "JSON",
|
|
||||||
"read_only": 1
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2020-07-27 14:28:11.532696",
|
"modified": "2020-07-31 13:57:02.328995",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Non Profit",
|
"module": "Non Profit",
|
||||||
"name": "Membership",
|
"name": "Membership",
|
||||||
|
|||||||
@ -10,6 +10,7 @@ from datetime import datetime
|
|||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
from frappe.email import sendmail_to_system_managers
|
from frappe.email import sendmail_to_system_managers
|
||||||
from frappe.utils import add_days, add_years, nowdate, getdate, add_months, get_link_to_form
|
from frappe.utils import add_days, add_years, nowdate, getdate, add_months, get_link_to_form
|
||||||
|
from erpnext.non_profit.doctype.member.member import create_member
|
||||||
from frappe import _
|
from frappe import _
|
||||||
import erpnext
|
import erpnext
|
||||||
|
|
||||||
@ -57,11 +58,95 @@ class Membership(Document):
|
|||||||
self.load_from_db()
|
self.load_from_db()
|
||||||
self.db_set('paid', 1)
|
self.db_set('paid', 1)
|
||||||
|
|
||||||
|
def generate_invoice(self, save=True):
|
||||||
|
if not (self.paid or self.currency or self.amount):
|
||||||
|
frappe.throw(_("The payment for this membership is not paid. To generate invoice fill the payment details"))
|
||||||
|
|
||||||
|
if self.invoice:
|
||||||
|
frappe.throw(_("An invoice is already linked to this document"))
|
||||||
|
|
||||||
|
member = frappe.get_doc("Member", self.member)
|
||||||
|
plan = frappe.get_doc("Membership Type", self.membership_type)
|
||||||
|
settings = frappe.get_doc("Membership Settings")
|
||||||
|
|
||||||
|
if not member.customer:
|
||||||
|
frappe.throw(_("No customer linked to member {}", [member.name]))
|
||||||
|
|
||||||
|
if not settings.debit_account:
|
||||||
|
frappe.throw(_("You need to set <b>Debit Account</b> in Membership Settings"))
|
||||||
|
|
||||||
|
if not settings.company:
|
||||||
|
frappe.throw(_("You need to set <b>Default Company</b> for invoicing in Membership Settings"))
|
||||||
|
|
||||||
|
invoice = make_invoice(self, member, plan, settings)
|
||||||
|
self.invoice = invoice.name
|
||||||
|
|
||||||
|
if save:
|
||||||
|
self.save()
|
||||||
|
|
||||||
|
return invoice
|
||||||
|
|
||||||
|
def send_acknowlement(self):
|
||||||
|
settings = frappe.get_doc("Membership Settings")
|
||||||
|
if not settings.send_email:
|
||||||
|
frappe.throw(_("You need to enable <b>Send Acknowledge Email</b> in Membership Settings"))
|
||||||
|
|
||||||
|
member = frappe.get_doc("Member", self.member)
|
||||||
|
plan = frappe.get_doc("Membership Type", self.membership_type)
|
||||||
|
email = member.email_id if member.email_id else member.email
|
||||||
|
attachments = [frappe.attach_print("Membership", self.name, print_format=settings.membership_print_format)]
|
||||||
|
|
||||||
|
if self.invoice and settings.send_invoice:
|
||||||
|
attachments.append(frappe.attach_print("Sales Invoice", self.invoice, print_format=settings.inv_print_format))
|
||||||
|
|
||||||
|
email_template = frappe.get_doc("Email Template", settings.email_template)
|
||||||
|
context = { "doc": self, "member": member}
|
||||||
|
|
||||||
|
email_args = {
|
||||||
|
"recipients": [email],
|
||||||
|
"message": frappe.render_template(email_template.get("response"), context),
|
||||||
|
"subject": frappe.render_template(email_template.get("subject"), context),
|
||||||
|
"attachments": attachments,
|
||||||
|
"reference_doctype": self.doctype,
|
||||||
|
"reference_name": self.name
|
||||||
|
}
|
||||||
|
|
||||||
|
if not frappe.flags.in_test:
|
||||||
|
frappe.enqueue(method=frappe.sendmail, queue='short', timeout=300, is_async=True, **email_args)
|
||||||
|
else:
|
||||||
|
frappe.sendmail(**email_args)
|
||||||
|
|
||||||
|
def generate_and_send_invoice(self):
|
||||||
|
invoice = self.generate_invoice(False)
|
||||||
|
self.send_acknowlement()
|
||||||
|
|
||||||
|
def make_invoice(membership, member, plan, settings):
|
||||||
|
invoice = frappe.get_doc({
|
||||||
|
'doctype': 'Sales Invoice',
|
||||||
|
'customer': member.customer,
|
||||||
|
'debit_to': settings.debit_account,
|
||||||
|
'currency': membership.currency,
|
||||||
|
'is_pos': 0,
|
||||||
|
'items': [
|
||||||
|
{
|
||||||
|
'item_code': plan.linked_item,
|
||||||
|
'rate': membership.amount,
|
||||||
|
'qty': 1
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
|
||||||
|
invoice.insert(ignore_permissions=True)
|
||||||
|
invoice.submit()
|
||||||
|
|
||||||
|
return invoice
|
||||||
|
|
||||||
def get_member_based_on_subscription(subscription_id, email):
|
def get_member_based_on_subscription(subscription_id, email):
|
||||||
members = frappe.get_all("Member", filters={
|
members = frappe.get_all("Member", filters={
|
||||||
'subscription_id': subscription_id,
|
'subscription_id': subscription_id,
|
||||||
'email_id': email
|
'email_id': email
|
||||||
}, order_by="creation desc")
|
}, order_by="creation desc")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
return frappe.get_doc("Member", members[0]['name'])
|
return frappe.get_doc("Member", members[0]['name'])
|
||||||
except:
|
except:
|
||||||
@ -77,16 +162,15 @@ def verify_signature(data):
|
|||||||
|
|
||||||
controller.verify_signature(data, signature, key)
|
controller.verify_signature(data, signature, key)
|
||||||
|
|
||||||
|
|
||||||
@frappe.whitelist(allow_guest=True)
|
@frappe.whitelist(allow_guest=True)
|
||||||
def trigger_razorpay_subscription(*args, **kwargs):
|
def trigger_razorpay_subscription(*args, **kwargs):
|
||||||
data = frappe.request.get_data(as_text=True)
|
data = frappe.request.get_data(as_text=True)
|
||||||
try:
|
try:
|
||||||
verify_signature(data)
|
verify_signature(data)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
signature = frappe.request.headers.get('X-Razorpay-Signature')
|
log = frappe.log_error(e, "Webhook Verification Error")
|
||||||
log = "{0} \n\n {1} \n\n {2} \n\n {3}".format(e, frappe.get_traceback(), signature, data)
|
notify_failure(log)
|
||||||
frappe.log_error(e, "Webhook Verification Error")
|
return { 'status': 'Failed', 'reason': e}
|
||||||
|
|
||||||
if isinstance(data, six.string_types):
|
if isinstance(data, six.string_types):
|
||||||
data = json.loads(data)
|
data = json.loads(data)
|
||||||
@ -99,35 +183,42 @@ def trigger_razorpay_subscription(*args, **kwargs):
|
|||||||
payment = frappe._dict(payment)
|
payment = frappe._dict(payment)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
data_json = json.dumps(data, indent=4, sort_keys=True)
|
if not data.event == "subscription.charged":
|
||||||
|
return
|
||||||
|
|
||||||
member = get_member_based_on_subscription(subscription.id, payment.email)
|
member = get_member_based_on_subscription(subscription.id, payment.email)
|
||||||
except Exception as e:
|
if not member:
|
||||||
error_log = frappe.log_error(frappe.get_traceback() + '\n' + data_json , _("Membership Webhook Failed"))
|
member = create_member(frappe._dict({
|
||||||
notify_failure(error_log)
|
'fullname': payment.email,
|
||||||
return { status: 'Failed' }
|
'email': payment.email,
|
||||||
|
'plan_id': get_plan_from_razorpay_id(subscription.plan_id)
|
||||||
|
}))
|
||||||
|
|
||||||
if not member:
|
member.subscription_id = subscription.id
|
||||||
return { status: 'Failed' }
|
|
||||||
try:
|
|
||||||
if data.event == "subscription.activated":
|
|
||||||
member.customer_id = payment.customer_id
|
member.customer_id = payment.customer_id
|
||||||
elif data.event == "subscription.charged":
|
if subscription.notes and type(subscription.notes) == dict:
|
||||||
membership = frappe.new_doc("Membership")
|
notes = '\n'.join("{}: {}".format(k, v) for k, v in subscription.notes.items())
|
||||||
membership.update({
|
member.add_comment("Comment", notes)
|
||||||
"member": member.name,
|
elif subscription.notes and type(subscription.notes) == str:
|
||||||
"membership_status": "Current",
|
member.add_comment("Comment", subscription.notes)
|
||||||
"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
|
|
||||||
|
# Update Membership
|
||||||
|
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,
|
||||||
|
"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 membership values
|
||||||
member.subscription_start = datetime.fromtimestamp(subscription.start_at)
|
member.subscription_start = datetime.fromtimestamp(subscription.start_at)
|
||||||
member.subscription_end = datetime.fromtimestamp(subscription.end_at)
|
member.subscription_end = datetime.fromtimestamp(subscription.end_at)
|
||||||
member.subscription_activated = 1
|
member.subscription_activated = 1
|
||||||
@ -135,9 +226,9 @@ def trigger_razorpay_subscription(*args, **kwargs):
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
log = frappe.log_error(e, "Error creating membership entry")
|
log = frappe.log_error(e, "Error creating membership entry")
|
||||||
notify_failure(log)
|
notify_failure(log)
|
||||||
return { status: 'Failed' }
|
return { 'status': 'Failed', 'reason': e}
|
||||||
|
|
||||||
return { status: 'Success' }
|
return { 'status': 'Success' }
|
||||||
|
|
||||||
|
|
||||||
def notify_failure(log):
|
def notify_failure(log):
|
||||||
@ -152,3 +243,11 @@ Administrator""".format(get_link_to_form("Error Log", log.name))
|
|||||||
sendmail_to_system_managers("[Important] [ERPNext] Razorpay membership webhook failed , please check.", content)
|
sendmail_to_system_managers("[Important] [ERPNext] Razorpay membership webhook failed , please check.", content)
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def get_plan_from_razorpay_id(plan_id):
|
||||||
|
plan = frappe.get_all("Membership Type", filters={'razorpay_plan_id': plan_id}, order_by="creation desc")
|
||||||
|
|
||||||
|
try:
|
||||||
|
return plan[0]['name']
|
||||||
|
except:
|
||||||
|
return None
|
||||||
@ -10,7 +10,39 @@ frappe.ui.form.on("Membership Settings", {
|
|||||||
})
|
})
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
frm.set_query('inv_print_format', function(doc) {
|
||||||
|
return {
|
||||||
|
filters: {
|
||||||
|
"doc_type": "Sales Invoice"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
frm.set_query('membership_print_format', function(doc) {
|
||||||
|
return {
|
||||||
|
filters: {
|
||||||
|
"doc_type": "Membership"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
frm.set_query('debit_account', function(doc) {
|
||||||
|
return {
|
||||||
|
filters: {
|
||||||
|
'account_type': 'Receivable',
|
||||||
|
'is_group': 0,
|
||||||
|
'company': frm.doc.company
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
let docs_url = "https://docs.erpnext.com/docs/user/manual/en/non_profit/membership";
|
||||||
|
|
||||||
|
frm.set_intro(__("You can learn more about memberships in the manual. ") + `<a href='${docs_url}'>${__('ERPNext Docs')}</a>`, true);
|
||||||
|
|
||||||
frm.trigger("add_generate_button");
|
frm.trigger("add_generate_button");
|
||||||
|
frm.trigger("add_copy_buttonn");
|
||||||
},
|
},
|
||||||
|
|
||||||
add_generate_button: function(frm) {
|
add_generate_button: function(frm) {
|
||||||
@ -27,4 +59,12 @@ frappe.ui.form.on("Membership Settings", {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
add_copy_buttonn: function(frm) {
|
||||||
|
if (frm.doc.webhook_secret) {
|
||||||
|
frm.add_custom_button(__("Copy Webhook URL"), () => {
|
||||||
|
frappe.utils.copy_to_clipboard(`https://${frappe.boot.sitename}/api/method/erpnext.non_profit.doctype.membership.membership.trigger_razorpay_subscription`);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@ -9,7 +9,17 @@
|
|||||||
"razorpay_settings_section",
|
"razorpay_settings_section",
|
||||||
"billing_cycle",
|
"billing_cycle",
|
||||||
"billing_frequency",
|
"billing_frequency",
|
||||||
"webhook_secret"
|
"webhook_secret",
|
||||||
|
"column_break_6",
|
||||||
|
"enable_auto_invoicing",
|
||||||
|
"company",
|
||||||
|
"debit_account",
|
||||||
|
"column_break_9",
|
||||||
|
"send_email",
|
||||||
|
"send_invoice",
|
||||||
|
"membership_print_format",
|
||||||
|
"inv_print_format",
|
||||||
|
"email_template"
|
||||||
],
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
@ -41,11 +51,79 @@
|
|||||||
"fieldtype": "Password",
|
"fieldtype": "Password",
|
||||||
"label": "Webhook Secret",
|
"label": "Webhook Secret",
|
||||||
"read_only": 1
|
"read_only": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "column_break_6",
|
||||||
|
"fieldtype": "Section Break",
|
||||||
|
"label": "Invoicing"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": "0",
|
||||||
|
"fieldname": "enable_auto_invoicing",
|
||||||
|
"fieldtype": "Check",
|
||||||
|
"label": "Enable Auto Invoicing",
|
||||||
|
"mandatory_depends_on": "eval:doc.send_invoice"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"depends_on": "eval:doc.enable_auto_invoicing",
|
||||||
|
"fieldname": "debit_account",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"label": "Debit Account",
|
||||||
|
"mandatory_depends_on": "eval:doc.enable_auto_invoicing",
|
||||||
|
"options": "Account"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "column_break_9",
|
||||||
|
"fieldtype": "Column Break"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"depends_on": "eval:doc.enable_auto_invoicing",
|
||||||
|
"fieldname": "company",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"label": "Company",
|
||||||
|
"mandatory_depends_on": "eval:doc.enable_auto_invoicing",
|
||||||
|
"options": "Company"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": "0",
|
||||||
|
"depends_on": "eval:doc.enable_auto_invoicing && doc.send_email",
|
||||||
|
"fieldname": "send_invoice",
|
||||||
|
"fieldtype": "Check",
|
||||||
|
"label": "Send Invoice with Email"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": "0",
|
||||||
|
"fieldname": "send_email",
|
||||||
|
"fieldtype": "Check",
|
||||||
|
"label": "Send Membership Acknowledgement"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"depends_on": "eval: doc.send_invoice",
|
||||||
|
"fieldname": "inv_print_format",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"label": "Invoice Print Format",
|
||||||
|
"mandatory_depends_on": "eval: doc.send_invoice",
|
||||||
|
"options": "Print Format"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"depends_on": "eval:doc.send_email",
|
||||||
|
"fieldname": "membership_print_format",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"label": "Membership Print Format",
|
||||||
|
"options": "Print Format"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"depends_on": "eval:doc.send_email",
|
||||||
|
"fieldname": "email_template",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"label": "Email Template",
|
||||||
|
"mandatory_depends_on": "eval:doc.send_email",
|
||||||
|
"options": "Email Template"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"issingle": 1,
|
"issingle": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2020-05-22 12:38:27.103759",
|
"modified": "2020-08-05 17:26:37.287395",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Non Profit",
|
"module": "Non Profit",
|
||||||
"name": "Membership Settings",
|
"name": "Membership Settings",
|
||||||
@ -60,6 +138,23 @@
|
|||||||
"role": "System Manager",
|
"role": "System Manager",
|
||||||
"share": 1,
|
"share": 1,
|
||||||
"write": 1
|
"write": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"create": 1,
|
||||||
|
"delete": 1,
|
||||||
|
"email": 1,
|
||||||
|
"print": 1,
|
||||||
|
"read": 1,
|
||||||
|
"role": "Non Profit Manager",
|
||||||
|
"share": 1,
|
||||||
|
"write": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"email": 1,
|
||||||
|
"print": 1,
|
||||||
|
"read": 1,
|
||||||
|
"role": "Non Profit Member",
|
||||||
|
"share": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"quick_entry": 1,
|
"quick_entry": 1,
|
||||||
|
|||||||
@ -5,6 +5,10 @@ frappe.ui.form.on('Membership Type', {
|
|||||||
refresh: function(frm) {
|
refresh: function(frm) {
|
||||||
frappe.db.get_single_value("Membership Settings", "enable_razorpay").then(val => {
|
frappe.db.get_single_value("Membership Settings", "enable_razorpay").then(val => {
|
||||||
if (val) frm.set_df_property('razorpay_plan_id', 'hidden', false);
|
if (val) frm.set_df_property('razorpay_plan_id', 'hidden', false);
|
||||||
})
|
});
|
||||||
|
|
||||||
|
frappe.db.get_single_value("Membership Settings", "enable_auto_invoicing").then(val => {
|
||||||
|
if (val) frm.set_df_property('linked_item', 'hidden', false);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@ -8,7 +8,8 @@
|
|||||||
"field_order": [
|
"field_order": [
|
||||||
"membership_type",
|
"membership_type",
|
||||||
"amount",
|
"amount",
|
||||||
"razorpay_plan_id"
|
"razorpay_plan_id",
|
||||||
|
"linked_item"
|
||||||
],
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
@ -33,10 +34,17 @@
|
|||||||
"hidden": 1,
|
"hidden": 1,
|
||||||
"label": "Razorpay Plan ID",
|
"label": "Razorpay Plan ID",
|
||||||
"unique": 1
|
"unique": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "linked_item",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"label": "Linked Item",
|
||||||
|
"options": "Item",
|
||||||
|
"unique": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2020-03-30 12:54:07.850857",
|
"modified": "2020-08-05 15:21:43.595745",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Non Profit",
|
"module": "Non Profit",
|
||||||
"name": "Membership Type",
|
"name": "Membership Type",
|
||||||
|
|||||||
@ -4,6 +4,10 @@
|
|||||||
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
|
import frappe
|
||||||
|
|
||||||
class MembershipType(Document):
|
class MembershipType(Document):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def get_membership_type(razorpay_id):
|
||||||
|
return frappe.db.exists("Membership Type", {"razorpay_plan_id": razorpay_id})
|
||||||
@ -722,4 +722,5 @@ erpnext.patches.v13_0.add_standard_navbar_items #4
|
|||||||
erpnext.patches.v13_0.stock_entry_enhancements
|
erpnext.patches.v13_0.stock_entry_enhancements
|
||||||
erpnext.patches.v12_0.update_state_code_for_daman_and_diu
|
erpnext.patches.v12_0.update_state_code_for_daman_and_diu
|
||||||
erpnext.patches.v12_0.rename_lost_reason_detail
|
erpnext.patches.v12_0.rename_lost_reason_detail
|
||||||
|
erpnext.patches.v13_0.drop_razorpay_payload_column
|
||||||
erpnext.patches.v13_0.update_start_end_date_for_old_shift_assignment
|
erpnext.patches.v13_0.update_start_end_date_for_old_shift_assignment
|
||||||
|
|||||||
7
erpnext/patches/v13_0/drop_razorpay_payload_column.py
Normal file
7
erpnext/patches/v13_0/drop_razorpay_payload_column.py
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
from __future__ import unicode_literals
|
||||||
|
import frappe
|
||||||
|
|
||||||
|
def execute():
|
||||||
|
if frappe.db.exists("DocType", "Membership"):
|
||||||
|
if 'webhook_payload' in frappe.db.get_table_columns("Membership"):
|
||||||
|
frappe.db.sql("alter table `tabMembership` drop column webhook_payload")
|
||||||
Loading…
x
Reference in New Issue
Block a user