diff --git a/erpnext/accounts/doctype/journal_entry/journal_entry.py b/erpnext/accounts/doctype/journal_entry/journal_entry.py index 5d1c3f226a2..7deca523c99 100644 --- a/erpnext/accounts/doctype/journal_entry/journal_entry.py +++ b/erpnext/accounts/doctype/journal_entry/journal_entry.py @@ -540,7 +540,7 @@ def get_default_bank_cash_account(company, voucher_type, mode_of_payment=None, a } @frappe.whitelist() -def get_payment_entry_against_order(dt, dn, args=None): +def get_payment_entry_against_order(dt, dn, amount=None, journal_entry=False, bank_account=None): ref_doc = frappe.get_doc(dt, dn) if flt(ref_doc.per_billed, 2) > 0: @@ -558,13 +558,11 @@ def get_payment_entry_against_order(dt, dn, args=None): party_account = get_party_account(party_type, ref_doc.get(party_type.lower()), ref_doc.company) party_account_currency = get_account_currency(party_account) - if not args or not args["amount"]: + if not amount: if party_account_currency == ref_doc.company_currency: amount = flt(ref_doc.base_grand_total) - flt(ref_doc.advance_paid) else: amount = flt(ref_doc.grand_total) - flt(ref_doc.advance_paid) - else: - amount = args["amount"] return get_payment_entry(ref_doc, { "party_type": party_type, @@ -575,12 +573,12 @@ def get_payment_entry_against_order(dt, dn, args=None): "amount": amount, "remarks": 'Advance Payment received against {0} {1}'.format(dt, dn), "is_advance": "Yes", - "bank_account": args["bank_account"] if args else None, - "return_obj": args["return_obj"] if args else None + "bank_account": bank_account, + "journal_entry": journal_entry }) @frappe.whitelist() -def get_payment_entry_against_invoice(dt, dn, args=None): +def get_payment_entry_against_invoice(dt, dn, amount=None, journal_entry=False, bank_account=None): ref_doc = frappe.get_doc(dt, dn) if dt == "Sales Invoice": party_type = "Customer" @@ -604,11 +602,11 @@ def get_payment_entry_against_invoice(dt, dn, args=None): "party_account_currency": ref_doc.party_account_currency, "amount_field_party": amount_field_party, "amount_field_bank": amount_field_bank, - "amount": args["amount"] if args else abs(ref_doc.outstanding_amount), + "amount": amount if amount else abs(ref_doc.outstanding_amount), "remarks": 'Payment received against {0} {1}. {2}'.format(dt, dn, ref_doc.remarks), "is_advance": "No", - "bank_account": args["bank_account"] if args else None, - "return_obj": args["return_obj"] if args else None + "bank_account": bank_account, + "journal_entry": journal_entry }) def get_payment_entry(ref_doc, args): @@ -616,14 +614,14 @@ def get_payment_entry(ref_doc, args): exchange_rate = get_exchange_rate(args.get("party_account"), args.get("party_account_currency"), ref_doc.company, ref_doc.doctype, ref_doc.name) - jv = frappe.new_doc("Journal Entry") - jv.update({ + je = frappe.new_doc("Journal Entry") + je.update({ "voucher_type": "Bank Entry", "company": ref_doc.company, "remark": args.get("remarks") }) - party_row = jv.append("accounts", { + party_row = je.append("accounts", { "account": args.get("party_account"), "party_type": args.get("party_type"), "party": ref_doc.get(args.get("party_type").lower()), @@ -640,7 +638,7 @@ def get_payment_entry(ref_doc, args): "reference_name": ref_doc.name }) - bank_row = jv.append("accounts") + bank_row = je.append("accounts") #make it bank_details bank_account = get_default_bank_cash_account(ref_doc.company, "Bank Entry", account=args.get("bank_account")) @@ -659,12 +657,12 @@ def get_payment_entry(ref_doc, args): # set multi currency check if party_row.account_currency != ref_doc.company_currency \ or (bank_row.account_currency and bank_row.account_currency != ref_doc.company_currency): - jv.multi_currency = 1 + je.multi_currency = 1 - jv.set_amounts_in_company_currency() - jv.set_total_debit_credit() + je.set_amounts_in_company_currency() + je.set_total_debit_credit() - return jv if args.get("return_obj") else jv.as_dict() + return je if args.get("journal_entry") else je.as_dict() @frappe.whitelist() def get_opening_accounts(company): diff --git a/erpnext/accounts/doctype/payment_gateway/payment_gateway.py b/erpnext/accounts/doctype/payment_gateway/payment_gateway.py index 569a0412a1c..80799e311b9 100644 --- a/erpnext/accounts/doctype/payment_gateway/payment_gateway.py +++ b/erpnext/accounts/doctype/payment_gateway/payment_gateway.py @@ -7,5 +7,4 @@ import frappe from frappe.model.document import Document class PaymentGateway(Document): - pass - \ No newline at end of file + pass \ No newline at end of file diff --git a/erpnext/accounts/doctype/payment_gateway_account/payment_gateway_account.json b/erpnext/accounts/doctype/payment_gateway_account/payment_gateway_account.json index d0950647841..c3a47724fb4 100644 --- a/erpnext/accounts/doctype/payment_gateway_account/payment_gateway_account.json +++ b/erpnext/accounts/doctype/payment_gateway_account/payment_gateway_account.json @@ -177,6 +177,54 @@ "search_index": 0, "set_only_once": 0, "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "payment_url_message", + "fieldtype": "Data", + "hidden": 0, + "ignore_user_permissions": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Payment URL Message", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "payment_success_url", + "fieldtype": "Data", + "hidden": 0, + "ignore_user_permissions": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Payment Success URL", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 } ], "hide_heading": 0, @@ -188,8 +236,8 @@ "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2015-12-30 15:08:47.042197", - "modified_by": "saurabh6790@gmail.com", + "modified": "2016-01-11 05:55:41.117089", + "modified_by": "Administrator", "module": "Accounts", "name": "Payment Gateway Account", "name_case": "", diff --git a/erpnext/accounts/doctype/payment_gateway_account/payment_gateway_account.py b/erpnext/accounts/doctype/payment_gateway_account/payment_gateway_account.py index 8cee085e39b..dd971ad5d2f 100644 --- a/erpnext/accounts/doctype/payment_gateway_account/payment_gateway_account.py +++ b/erpnext/accounts/doctype/payment_gateway_account/payment_gateway_account.py @@ -12,13 +12,13 @@ class PaymentGatewayAccount(Document): def validate(self): self.update_default_payment_gateway() - self.set_as_default() + self.set_as_default_if_not_set() def update_default_payment_gateway(self): if self.is_default: frappe.db.sql("""update `tabPayment Gateway Account` set is_default = 0 where is_default = 1 """) - def set_as_default(self): + def set_as_default_if_not_set(self): if not frappe.db.get_value("Payment Gateway Account", {"is_default": 1, "name": ("!=", self.name)}, "name"): self.is_default = 1 diff --git a/erpnext/accounts/doctype/payment_request/payment_request.js b/erpnext/accounts/doctype/payment_request/payment_request.js index 2665a13c0bf..b28a889be86 100644 --- a/erpnext/accounts/doctype/payment_request/payment_request.js +++ b/erpnext/accounts/doctype/payment_request/payment_request.js @@ -1,6 +1,8 @@ cur_frm.add_fetch("payment_gateway", "payment_account", "payment_account") cur_frm.add_fetch("payment_gateway", "gateway", "gateway") cur_frm.add_fetch("payment_gateway", "message", "message") +cur_frm.add_fetch("payment_gateway", "payment_url_message", "payment_url_message") +cur_frm.add_fetch("payment_gateway", "payment_success_url", "payment_success_url") frappe.ui.form.on("Payment Request", "onload", function(frm, dt, dn){ if (frm.doc.reference_doctype) { @@ -28,5 +30,14 @@ frappe.ui.form.on("Payment Request", "refresh", function(frm) { } }) }) + + frm.add_custom_button(__("Show Paypal Express Payment"), function() { + frappe.route_options = { + "Paypal Express Payment.reference_doctype": frm.doc.doctype, + "Paypal Express Payment.reference_docname": frm.doc.name + }; + + frappe.set_route("List", "Paypal Express Payment"); + }); }) diff --git a/erpnext/accounts/doctype/payment_request/payment_request.json b/erpnext/accounts/doctype/payment_request/payment_request.json index 360ff90dda9..7655b5872e0 100644 --- a/erpnext/accounts/doctype/payment_request/payment_request.json +++ b/erpnext/accounts/doctype/payment_request/payment_request.json @@ -204,6 +204,30 @@ "set_only_once": 0, "unique": 0 }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "payment_success_url", + "fieldtype": "Data", + "hidden": 0, + "ignore_user_permissions": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Payment Success URL", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, { "allow_on_submit": 0, "bold": 0, @@ -423,6 +447,30 @@ "set_only_once": 0, "unique": 0 }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "payment_url_message", + "fieldtype": "Data", + "hidden": 0, + "ignore_user_permissions": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Payment URL Message", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, { "allow_on_submit": 0, "bold": 0, @@ -555,7 +603,7 @@ "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2016-01-08 05:25:06.056398", + "modified": "2016-01-11 05:49:28.342786", "modified_by": "Administrator", "module": "Accounts", "name": "Payment Request", diff --git a/erpnext/accounts/doctype/payment_request/payment_request.py b/erpnext/accounts/doctype/payment_request/payment_request.py index 4df64b257b7..23fd5a8952e 100644 --- a/erpnext/accounts/doctype/payment_request/payment_request.py +++ b/erpnext/accounts/doctype/payment_request/payment_request.py @@ -23,12 +23,12 @@ class PaymentRequest(Document): def validate_payment_request(self): if frappe.db.get_value("Payment Request", {"reference_name": self.reference_name, "name": ("!=", self.name), "status": ("not in", ["Initiated", "Paid"]), "docstatus": 1}, "name"): - frappe.throw(_("Payment Request already exist")) + frappe.throw(_("Payment Request already exists {0}".fomart(self.reference_name))) def validate_currency(self): ref_doc = frappe.get_doc(self.reference_doctype, self.reference_name) if ref_doc.currency != frappe.db.get_value("Account", self.payment_account, "account_currency"): - frappe.throw(_("Transaction currency is not similar to Gateway Currency")) + frappe.throw(_("Transaction currency must be same as Payment Gateway currency")) def validate_payment_gateway_account(self): if not self.payment_gateway: @@ -49,7 +49,7 @@ class PaymentRequest(Document): self.make_communication_entry() def on_cancel(self): - self.set_cancelled() + self.set_as_cancelled() def on_update_after_submit(self): pass @@ -57,6 +57,9 @@ class PaymentRequest(Document): def set_status(self): pass + def get_payment_url(self): + pass + def make_invoice(self): if self.make_sales_invoice: from erpnext.selling.doctype.sales_order.sales_order import make_sales_invoice @@ -69,7 +72,7 @@ class PaymentRequest(Document): if self.payment_url: frappe.db.set_value(self.doctype, self.name, "status", "Initiated") - def set_paid(self): + def set_as_paid(self): if frappe.session.user == "Guest": frappe.set_user("Administrator") @@ -82,17 +85,19 @@ class PaymentRequest(Document): """create entry""" payment_details = { "amount": self.amount, - "return_obj": True, + "journal_entry": True, "bank_account": self.payment_account } frappe.flags.ignore_account_permission = True if self.reference_doctype == "Sales Order": - jv = get_payment_entry_against_order(self.reference_doctype, self.reference_name, payment_details) + jv = get_payment_entry_against_order(self.reference_doctype, self.reference_name,\ + amount=self.amount, journal_entry=True, bank_account=self.payment_account) if self.reference_doctype == "Sales Invoice": - jv = get_payment_entry_against_invoice(self.reference_doctype, self.reference_name, payment_details) + jv = get_payment_entry_against_invoice(self.reference_doctype, self.reference_name,\ + amount=self.amount, journal_entry=True, bank_account=self.payment_account) jv.update({ "voucher_type": "Journal Entry", @@ -114,12 +119,13 @@ class PaymentRequest(Document): def get_message(self): """return message with payment gateway link""" - return cstr(self.message) + """ Click here to pay """%self.payment_url + return cstr(self.message) + " {1}".format(self.payment_url, \ + self.payment_url_message or _(" Click here to pay")) def set_failed(self): pass - def set_cancelled(self): + def set_as_cancelled(self): frappe.db.set_value(self.doctype, self.name, "status", "Cancelled") def make_communication_entry(self): @@ -133,13 +139,16 @@ class PaymentRequest(Document): "reference_name": self.reference_name }) comm.insert(ignore_permissions=True) + + def get_payment_success_url(self): + return self.payment_success_url @frappe.whitelist(allow_guest=True) def make_payment_request(**args): """Make payment request""" args = frappe._dict(args) - ref_doc = get_reference_doc_details(args.dt, args.dn) + ref_doc = frappe.get_doc(args.dt, args.dn) gateway_account = get_gateway_details(args) pr = frappe.new_doc("Payment Request") @@ -154,6 +163,8 @@ def make_payment_request(**args): "email_to": args.recipient_id or "", "subject": "Payment Request for %s"%args.dn, "message": gateway_account.message, + "payment_url_message": gateway_account.payment_url_message, + "payment_success_url": gateway_account.payment_success_url, "reference_doctype": args.dt, "reference_name": args.dn }) @@ -174,10 +185,6 @@ def make_payment_request(**args): return pr.as_dict() -def get_reference_doc_details(dt, dn): - """ return reference doc Sales Order/Sales Invoice""" - return frappe.get_doc(dt, dn) - def get_amount(ref_doc, dt): """get amount based on doctype""" if dt == "Sales Order": @@ -195,10 +202,12 @@ def get_gateway_details(args): """return gateway and payment account of default payment gateway""" if args.payemnt_gateway: gateway_account = frappe.db.get_value("Payment Gateway Account", args.payemnt_gateway, - ["name", "gateway", "payment_account", "message"], as_dict=1) + ["name", "gateway", "payment_account", "message", "payment_url_message", "payment_success_url"], + as_dict=1) gateway_account = frappe.db.get_value("Payment Gateway Account", {"is_default": 1}, - ["name", "gateway", "payment_account", "message"], as_dict=1) + ["name", "gateway", "payment_account", "message", "payment_url_message", "payment_success_url"], + as_dict=1) if not gateway_account: frappe.throw(_("Payment Gateway Account is not configured")) @@ -209,29 +218,20 @@ def get_gateway_details(args): def get_print_format_list(ref_doctype): print_format_list = ["Standard"] - print_format_list.extend(list(chain.from_iterable(frappe.db.sql("""select name from `tabPrint Format` - where doc_type=%s""", ref_doctype, as_list=1)))) + print_format_list.extend([p.name for p in frappe.get_all("Print Format", + filters={"doc_type": ref_doctype})]) return { "print_format": print_format_list } - + @frappe.whitelist(allow_guest=True) def generate_payment_request(name): - doc = frappe.get_doc("Payment Request", name) - if doc.docstatus not in [0, 2]: - if doc.gateway == "PayPal": - from paypal_integration.express_checkout import set_express_checkout - payment_url = set_express_checkout(doc.amount, doc.currency, {"doctype": doc.doctype, - "docname": doc.name}) - + payment_url = frappe.get_doc("Payment Request", name).run_method("get_payment_url") + if payment_url: frappe.local.response["type"] = "redirect" frappe.local.response["location"] = payment_url - else: - frappe.respond_as_web_page(_("Invalid Payment Request"), - _("Payment Request has been canceled by vendor"), success=False, - http_status_code=frappe.ValidationError.http_status_code) - + @frappe.whitelist(allow_guest=True) def resend_payment_email(docname): return frappe.get_doc("Payment Request", docname).send_email() diff --git a/erpnext/accounts/doctype/payment_request/test_payment_request.py b/erpnext/accounts/doctype/payment_request/test_payment_request.py index c9d1705a0c8..a1e975a984f 100644 --- a/erpnext/accounts/doctype/payment_request/test_payment_request.py +++ b/erpnext/accounts/doctype/payment_request/test_payment_request.py @@ -62,7 +62,7 @@ class TestPaymentRequest(unittest.TestCase): SO_INR = make_sales_order(currency="INR") pr = make_payment_request(dt="Sales Order", dn=SO_INR.name, recipient_id="saurabh@erpnext.com", mute_email=1, submit_doc=1) - jv = pr.set_paid() + jv = pr.set_as_paid() SO_INR = frappe.get_doc("Sales Order", SO_INR.name) diff --git a/erpnext/setup/setup_wizard/setup_wizard.py b/erpnext/setup/setup_wizard/setup_wizard.py index 9be2880eb03..081afcc7c39 100644 --- a/erpnext/setup/setup_wizard/setup_wizard.py +++ b/erpnext/setup/setup_wizard/setup_wizard.py @@ -124,7 +124,7 @@ def create_bank_account(args): "account_type": "Bank", }) try: - bank_account.insert() + return bank_account.insert() except RootNotEditable: frappe.throw(_("Bank account cannot be named as {0}").format(args.get("bank_account")))