[enhancement] modify payment request to get payment url (#6097)
* [enhancement] modify payment request to get payment url * redirect to payment url if payment initiated via shopping cart
This commit is contained in:
parent
e5d13f3156
commit
b835fef8ac
@ -6,10 +6,11 @@ from __future__ import unicode_literals
|
|||||||
import frappe
|
import frappe
|
||||||
from frappe import _
|
from frappe import _
|
||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
from frappe.utils import flt, get_url, nowdate
|
from frappe.utils import flt, nowdate, get_url
|
||||||
from erpnext.accounts.party import get_party_account
|
from erpnext.accounts.party import get_party_account
|
||||||
from erpnext.accounts.utils import get_account_currency
|
from erpnext.accounts.utils import get_account_currency
|
||||||
from erpnext.accounts.doctype.payment_entry.payment_entry import get_payment_entry, get_company_defaults
|
from erpnext.accounts.doctype.payment_entry.payment_entry import get_payment_entry, get_company_defaults
|
||||||
|
from frappe.integration_broker.doctype.integration_service.integration_service import get_integration_controller
|
||||||
|
|
||||||
class PaymentRequest(Document):
|
class PaymentRequest(Document):
|
||||||
def validate(self):
|
def validate(self):
|
||||||
@ -25,7 +26,7 @@ class PaymentRequest(Document):
|
|||||||
ref_doc = frappe.get_doc(self.reference_doctype, self.reference_name)
|
ref_doc = frappe.get_doc(self.reference_doctype, self.reference_name)
|
||||||
if self.payment_account and ref_doc.currency != frappe.db.get_value("Account", self.payment_account, "account_currency"):
|
if self.payment_account and ref_doc.currency != frappe.db.get_value("Account", self.payment_account, "account_currency"):
|
||||||
frappe.throw(_("Transaction currency must be same as Payment Gateway currency"))
|
frappe.throw(_("Transaction currency must be same as Payment Gateway currency"))
|
||||||
|
|
||||||
def on_submit(self):
|
def on_submit(self):
|
||||||
send_mail = True
|
send_mail = True
|
||||||
self.make_communication_entry()
|
self.make_communication_entry()
|
||||||
@ -35,17 +36,13 @@ class PaymentRequest(Document):
|
|||||||
send_mail = False
|
send_mail = False
|
||||||
|
|
||||||
if send_mail and not self.flags.mute_email:
|
if send_mail and not self.flags.mute_email:
|
||||||
self.send_payment_request()
|
self.set_payment_request_url()
|
||||||
self.send_email()
|
self.send_email()
|
||||||
|
|
||||||
def on_cancel(self):
|
def on_cancel(self):
|
||||||
|
self.check_if_payment_entry_exists()
|
||||||
self.set_as_cancelled()
|
self.set_as_cancelled()
|
||||||
|
|
||||||
def get_payment_url(self):
|
|
||||||
""" This is blanck method to trigger hooks call from individual payment gateway app
|
|
||||||
which will return respective payment gateway"""
|
|
||||||
pass
|
|
||||||
|
|
||||||
def make_invoice(self):
|
def make_invoice(self):
|
||||||
ref_doc = frappe.get_doc(self.reference_doctype, self.reference_name)
|
ref_doc = frappe.get_doc(self.reference_doctype, self.reference_name)
|
||||||
if hasattr(ref_doc, "order_type") and getattr(ref_doc, "order_type") == "Shopping Cart":
|
if hasattr(ref_doc, "order_type") and getattr(ref_doc, "order_type") == "Shopping Cart":
|
||||||
@ -54,20 +51,39 @@ class PaymentRequest(Document):
|
|||||||
si = si.insert(ignore_permissions=True)
|
si = si.insert(ignore_permissions=True)
|
||||||
si.submit()
|
si.submit()
|
||||||
|
|
||||||
def send_payment_request(self):
|
def set_payment_request_url(self):
|
||||||
if self.payment_account:
|
if self.payment_account:
|
||||||
self.payment_url = get_url("/api/method/erpnext.accounts.doctype.payment_request.payment_request.generate_payment_request?name={0}".format(self.name))
|
self.payment_url = self.get_payment_url()
|
||||||
|
|
||||||
if self.payment_url:
|
if self.payment_url:
|
||||||
self.db_set('payment_url', self.payment_url)
|
self.db_set('payment_url', self.payment_url)
|
||||||
|
|
||||||
if self.payment_url or not self.payment_gateway_account:
|
if self.payment_url or not self.payment_gateway_account:
|
||||||
self.db_set('status', 'Initiated')
|
self.db_set('status', 'Initiated')
|
||||||
|
|
||||||
|
def get_payment_url(self):
|
||||||
|
data = frappe.db.get_value(self.reference_doctype, self.reference_name,
|
||||||
|
["company", "customer_name"], as_dict=1)
|
||||||
|
|
||||||
|
controller = get_integration_controller(self.payment_gateway, setup=False)
|
||||||
|
controller.validate_transaction_currency(self.currency)
|
||||||
|
|
||||||
|
return controller.get_payment_url(**{
|
||||||
|
"amount": self.grand_total,
|
||||||
|
"title": data.company,
|
||||||
|
"description": self.subject,
|
||||||
|
"reference_doctype": "Payment Request",
|
||||||
|
"reference_docname": self.name,
|
||||||
|
"payer_email": self.email_to or frappe.session.user,
|
||||||
|
"payer_name": data.customer_name,
|
||||||
|
"order_id": self.name,
|
||||||
|
"currency": self.currency
|
||||||
|
})
|
||||||
|
|
||||||
def set_as_paid(self):
|
def set_as_paid(self):
|
||||||
if frappe.session.user == "Guest":
|
if frappe.session.user == "Guest":
|
||||||
frappe.set_user("Administrator")
|
frappe.set_user("Administrator")
|
||||||
|
|
||||||
payment_entry = self.create_payment_entry()
|
payment_entry = self.create_payment_entry()
|
||||||
self.make_invoice()
|
self.make_invoice()
|
||||||
|
|
||||||
@ -141,6 +157,13 @@ class PaymentRequest(Document):
|
|||||||
|
|
||||||
def set_as_cancelled(self):
|
def set_as_cancelled(self):
|
||||||
self.db_set("status", "Cancelled")
|
self.db_set("status", "Cancelled")
|
||||||
|
|
||||||
|
def check_if_payment_entry_exists(self):
|
||||||
|
if self.status == "Paid":
|
||||||
|
payment_entry = frappe.db.sql_list("""select parent from `tabPayment Entry Reference`
|
||||||
|
where reference_name=%s""", self.reference_name)
|
||||||
|
if payment_entry:
|
||||||
|
frappe.throw(_("Payment Entry already exists"), title=_('Error'))
|
||||||
|
|
||||||
def make_communication_entry(self):
|
def make_communication_entry(self):
|
||||||
"""Make communication entry"""
|
"""Make communication entry"""
|
||||||
@ -156,7 +179,33 @@ class PaymentRequest(Document):
|
|||||||
|
|
||||||
def get_payment_success_url(self):
|
def get_payment_success_url(self):
|
||||||
return self.payment_success_url
|
return self.payment_success_url
|
||||||
|
|
||||||
|
def on_payment_authorized(self, status=None):
|
||||||
|
if not status:
|
||||||
|
return
|
||||||
|
|
||||||
|
shopping_cart_settings = frappe.get_doc("Shopping Cart Settings")
|
||||||
|
|
||||||
|
if status in ["Authorized", "Completed"]:
|
||||||
|
redirect_to = None
|
||||||
|
self.run_method("set_as_paid")
|
||||||
|
|
||||||
|
# if shopping cart enabled and in session
|
||||||
|
if (shopping_cart_settings.enabled and hasattr(frappe.local, "session")
|
||||||
|
and frappe.local.session.user != "Guest"):
|
||||||
|
|
||||||
|
success_url = shopping_cart_settings.payment_success_url
|
||||||
|
if success_url:
|
||||||
|
redirect_to = ({
|
||||||
|
"Orders": "orders",
|
||||||
|
"Invoices": "invoices",
|
||||||
|
"My Account": "me"
|
||||||
|
}).get(success_url, "me")
|
||||||
|
else:
|
||||||
|
redirect_to = get_url("/orders/{0}".format(self.reference_name))
|
||||||
|
|
||||||
|
return redirect_to
|
||||||
|
|
||||||
@frappe.whitelist(allow_guest=True)
|
@frappe.whitelist(allow_guest=True)
|
||||||
def make_payment_request(**args):
|
def make_payment_request(**args):
|
||||||
"""Make payment request"""
|
"""Make payment request"""
|
||||||
@ -201,8 +250,9 @@ def make_payment_request(**args):
|
|||||||
pr.submit()
|
pr.submit()
|
||||||
|
|
||||||
if hasattr(ref_doc, "order_type") and getattr(ref_doc, "order_type") == "Shopping Cart":
|
if hasattr(ref_doc, "order_type") and getattr(ref_doc, "order_type") == "Shopping Cart":
|
||||||
generate_payment_request(pr.name)
|
|
||||||
frappe.db.commit()
|
frappe.db.commit()
|
||||||
|
frappe.local.response["type"] = "redirect"
|
||||||
|
frappe.local.response["location"] = pr.get_payment_url()
|
||||||
|
|
||||||
if not args.cart:
|
if not args.cart:
|
||||||
return pr
|
return pr
|
||||||
@ -255,10 +305,6 @@ def get_print_format_list(ref_doctype):
|
|||||||
"print_format": print_format_list
|
"print_format": print_format_list
|
||||||
}
|
}
|
||||||
|
|
||||||
@frappe.whitelist(allow_guest=True)
|
|
||||||
def generate_payment_request(name):
|
|
||||||
frappe.get_doc("Payment Request", name).run_method("get_payment_url")
|
|
||||||
|
|
||||||
@frappe.whitelist(allow_guest=True)
|
@frappe.whitelist(allow_guest=True)
|
||||||
def resend_payment_email(docname):
|
def resend_payment_email(docname):
|
||||||
return frappe.get_doc("Payment Request", docname).send_email()
|
return frappe.get_doc("Payment Request", docname).send_email()
|
||||||
@ -278,6 +324,7 @@ def make_status_as_paid(doc, method):
|
|||||||
doc = frappe.get_doc("Payment Request", payment_request_name)
|
doc = frappe.get_doc("Payment Request", payment_request_name)
|
||||||
if doc.status != "Paid":
|
if doc.status != "Paid":
|
||||||
doc.db_set('status', 'Paid')
|
doc.db_set('status', 'Paid')
|
||||||
|
frappe.db.commit()
|
||||||
|
|
||||||
def get_dummy_message(use_dummy_message=True):
|
def get_dummy_message(use_dummy_message=True):
|
||||||
return """
|
return """
|
||||||
|
@ -570,3 +570,58 @@ def get_children():
|
|||||||
each["balance_in_account_currency"] = flt(get_balance_on(each.get("value")))
|
each["balance_in_account_currency"] = flt(get_balance_on(each.get("value")))
|
||||||
|
|
||||||
return acc
|
return acc
|
||||||
|
|
||||||
|
def create_payment_gateway_and_account(gateway):
|
||||||
|
create_payment_gateway(gateway)
|
||||||
|
create_payment_gateway_account(gateway)
|
||||||
|
|
||||||
|
def create_payment_gateway(gateway):
|
||||||
|
# NOTE: we don't translate Payment Gateway name because it is an internal doctype
|
||||||
|
if not frappe.db.exists("Payment Gateway", gateway):
|
||||||
|
payment_gateway = frappe.get_doc({
|
||||||
|
"doctype": "Payment Gateway",
|
||||||
|
"gateway": gateway
|
||||||
|
})
|
||||||
|
payment_gateway.insert(ignore_permissions=True)
|
||||||
|
|
||||||
|
def create_payment_gateway_account(gateway):
|
||||||
|
from erpnext.setup.setup_wizard.setup_wizard import create_bank_account
|
||||||
|
|
||||||
|
company = frappe.db.get_value("Global Defaults", None, "default_company")
|
||||||
|
if not company:
|
||||||
|
return
|
||||||
|
|
||||||
|
# NOTE: we translate Payment Gateway account name because that is going to be used by the end user
|
||||||
|
bank_account = frappe.db.get_value("Account", {"account_name": _(gateway), "company": company},
|
||||||
|
["name", 'account_currency'], as_dict=1)
|
||||||
|
|
||||||
|
if not bank_account:
|
||||||
|
# check for untranslated one
|
||||||
|
bank_account = frappe.db.get_value("Account", {"account_name": gateway, "company": company},
|
||||||
|
["name", 'account_currency'], as_dict=1)
|
||||||
|
|
||||||
|
if not bank_account:
|
||||||
|
# try creating one
|
||||||
|
bank_account = create_bank_account({"company_name": company, "bank_account": _(gateway)})
|
||||||
|
|
||||||
|
if not bank_account:
|
||||||
|
frappe.msgprint(_("Payment Gateway Account not created, please create one manually."))
|
||||||
|
return
|
||||||
|
|
||||||
|
# if payment gateway account exists, return
|
||||||
|
if frappe.db.exists("Payment Gateway Account",
|
||||||
|
{"payment_gateway": gateway, "currency": bank_account.account_currency}):
|
||||||
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
frappe.get_doc({
|
||||||
|
"doctype": "Payment Gateway Account",
|
||||||
|
"is_default": 1,
|
||||||
|
"payment_gateway": gateway,
|
||||||
|
"payment_account": bank_account.name,
|
||||||
|
"currency": bank_account.account_currency
|
||||||
|
}).insert(ignore_permissions=True)
|
||||||
|
|
||||||
|
except frappe.DuplicateEntryError:
|
||||||
|
# already exists, due to a reinstall?
|
||||||
|
pass
|
||||||
|
Loading…
x
Reference in New Issue
Block a user