Merge pull request #4595 from saurabh6790/payment_request_vai_cart
Payment request via cart
diff --git a/erpnext/accounts/doctype/accounts_settings/accounts_settings.json b/erpnext/accounts/doctype/accounts_settings/accounts_settings.json
index 1b933ce..1ba9221 100644
--- a/erpnext/accounts/doctype/accounts_settings/accounts_settings.json
+++ b/erpnext/accounts/doctype/accounts_settings/accounts_settings.json
@@ -21,9 +21,11 @@
"in_filter": 0,
"in_list_view": 1,
"label": "Make Accounting Entry For Every Stock Movement",
+ "length": 0,
"no_copy": 0,
"permlevel": 0,
"print_hide": 0,
+ "print_hide_if_no_value": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
@@ -43,9 +45,11 @@
"in_filter": 0,
"in_list_view": 1,
"label": "Accounts Frozen Upto",
+ "length": 0,
"no_copy": 0,
"permlevel": 0,
"print_hide": 0,
+ "print_hide_if_no_value": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
@@ -65,10 +69,12 @@
"in_filter": 0,
"in_list_view": 1,
"label": "Role Allowed to Set Frozen Accounts & Edit Frozen Entries",
+ "length": 0,
"no_copy": 0,
"options": "Role",
"permlevel": 0,
"print_hide": 0,
+ "print_hide_if_no_value": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
@@ -88,10 +94,12 @@
"in_filter": 0,
"in_list_view": 1,
"label": "Credit Controller",
+ "length": 0,
"no_copy": 0,
"options": "Role",
"permlevel": 0,
"print_hide": 0,
+ "print_hide_if_no_value": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
@@ -110,10 +118,12 @@
"in_filter": 0,
"in_list_view": 0,
"label": "Check Supplier Invoice Number Uniqueness",
+ "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,
@@ -131,7 +141,8 @@
"is_submittable": 0,
"issingle": 1,
"istable": 0,
- "modified": "2015-07-14 00:51:48.095525",
+ "max_attachments": 0,
+ "modified": "2015-12-24 21:42:01.274459",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Accounts Settings",
diff --git a/erpnext/accounts/doctype/journal_entry/journal_entry.py b/erpnext/accounts/doctype/journal_entry/journal_entry.py
index 670661c..7deca52 100644
--- a/erpnext/accounts/doctype/journal_entry/journal_entry.py
+++ b/erpnext/accounts/doctype/journal_entry/journal_entry.py
@@ -508,7 +508,7 @@
d.party_balance = party_balance[(d.party_type, d.party)]
@frappe.whitelist()
-def get_default_bank_cash_account(company, voucher_type, mode_of_payment=None):
+def get_default_bank_cash_account(company, voucher_type, mode_of_payment=None, account=None):
from erpnext.accounts.doctype.sales_invoice.sales_invoice import get_bank_cash_account
if mode_of_payment:
account = get_bank_cash_account(mode_of_payment, company)
@@ -516,16 +516,18 @@
account.update({"balance": get_balance_on(account.get("account"))})
return account
- if voucher_type=="Bank Entry":
- account = frappe.db.get_value("Company", company, "default_bank_account")
- if not account:
- account = frappe.db.get_value("Account",
- {"company": company, "account_type": "Bank", "is_group": 0})
- elif voucher_type=="Cash Entry":
- account = frappe.db.get_value("Company", company, "default_cash_account")
- if not account:
- account = frappe.db.get_value("Account",
- {"company": company, "account_type": "Cash", "is_group": 0})
+ if not account:
+ if voucher_type=="Bank Entry":
+ account = frappe.db.get_value("Company", company, "default_bank_account")
+ if not account:
+ account = frappe.db.get_value("Account",
+ {"company": company, "account_type": "Bank", "is_group": 0})
+
+ elif voucher_type=="Cash Entry":
+ account = frappe.db.get_value("Company", company, "default_cash_account")
+ if not account:
+ account = frappe.db.get_value("Account",
+ {"company": company, "account_type": "Cash", "is_group": 0})
if account:
account_details = frappe.db.get_value("Account", account,
@@ -538,7 +540,7 @@
}
@frappe.whitelist()
-def get_payment_entry_against_order(dt, dn):
+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:
@@ -556,10 +558,11 @@
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 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)
+ 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)
return get_payment_entry(ref_doc, {
"party_type": party_type,
@@ -569,11 +572,13 @@
"amount_field_bank": amount_field_bank,
"amount": amount,
"remarks": 'Advance Payment received against {0} {1}'.format(dt, dn),
- "is_advance": "Yes"
+ "is_advance": "Yes",
+ "bank_account": bank_account,
+ "journal_entry": journal_entry
})
@frappe.whitelist()
-def get_payment_entry_against_invoice(dt, dn):
+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"
@@ -597,9 +602,11 @@
"party_account_currency": ref_doc.party_account_currency,
"amount_field_party": amount_field_party,
"amount_field_bank": amount_field_bank,
- "amount": 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"
+ "is_advance": "No",
+ "bank_account": bank_account,
+ "journal_entry": journal_entry
})
def get_payment_entry(ref_doc, args):
@@ -607,14 +614,14 @@
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()),
@@ -631,8 +638,10 @@
"reference_name": ref_doc.name
})
- bank_row = jv.append("accounts")
- bank_account = get_default_bank_cash_account(ref_doc.company, "Bank Entry")
+ 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"))
if bank_account:
bank_row.update(bank_account)
bank_row.exchange_rate = get_exchange_rate(bank_account["account"],
@@ -648,12 +657,12 @@
# 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()
-
- return jv.as_dict()
+ je.set_amounts_in_company_currency()
+ je.set_total_debit_credit()
+
+ 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/__init__.py b/erpnext/accounts/doctype/payment_gateway/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/accounts/doctype/payment_gateway/__init__.py
diff --git a/erpnext/accounts/doctype/payment_gateway/payment_gateway.json b/erpnext/accounts/doctype/payment_gateway/payment_gateway.json
new file mode 100644
index 0000000..9b48066
--- /dev/null
+++ b/erpnext/accounts/doctype/payment_gateway/payment_gateway.json
@@ -0,0 +1,118 @@
+{
+ "allow_copy": 0,
+ "allow_import": 0,
+ "allow_rename": 0,
+ "autoname": "field:gateway",
+ "creation": "2015-12-15 22:26:45.221162",
+ "custom": 0,
+ "docstatus": 0,
+ "doctype": "DocType",
+ "document_type": "",
+ "fields": [
+ {
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "fieldname": "gateway",
+ "fieldtype": "Data",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Gateway",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ }
+ ],
+ "hide_heading": 0,
+ "hide_toolbar": 0,
+ "idx": 0,
+ "in_create": 0,
+ "in_dialog": 0,
+ "is_submittable": 0,
+ "issingle": 0,
+ "istable": 0,
+ "max_attachments": 0,
+ "modified": "2015-12-29 12:04:17.371619",
+ "modified_by": "Administrator",
+ "module": "Accounts",
+ "name": "Payment Gateway",
+ "name_case": "",
+ "owner": "Administrator",
+ "permissions": [
+ {
+ "amend": 0,
+ "apply_user_permissions": 0,
+ "cancel": 0,
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "export": 1,
+ "if_owner": 0,
+ "import": 0,
+ "permlevel": 0,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "Administrator",
+ "set_user_permissions": 0,
+ "share": 1,
+ "submit": 0,
+ "write": 1
+ },
+ {
+ "amend": 0,
+ "apply_user_permissions": 0,
+ "cancel": 0,
+ "create": 0,
+ "delete": 0,
+ "email": 0,
+ "export": 0,
+ "if_owner": 0,
+ "import": 0,
+ "permlevel": 0,
+ "print": 0,
+ "read": 1,
+ "report": 0,
+ "role": "System Manager",
+ "set_user_permissions": 0,
+ "share": 0,
+ "submit": 0,
+ "write": 0
+ },
+ {
+ "amend": 0,
+ "apply_user_permissions": 0,
+ "cancel": 0,
+ "create": 0,
+ "delete": 0,
+ "email": 0,
+ "export": 0,
+ "if_owner": 0,
+ "import": 0,
+ "permlevel": 0,
+ "print": 0,
+ "read": 1,
+ "report": 0,
+ "role": "Accounts Manager",
+ "set_user_permissions": 0,
+ "share": 0,
+ "submit": 0,
+ "write": 0
+ }
+ ],
+ "read_only": 0,
+ "read_only_onload": 0,
+ "sort_field": "modified",
+ "sort_order": "DESC"
+}
\ No newline at end of file
diff --git a/erpnext/accounts/doctype/payment_gateway/payment_gateway.py b/erpnext/accounts/doctype/payment_gateway/payment_gateway.py
new file mode 100644
index 0000000..80799e3
--- /dev/null
+++ b/erpnext/accounts/doctype/payment_gateway/payment_gateway.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe
+from frappe.model.document import Document
+
+class PaymentGateway(Document):
+ pass
\ No newline at end of file
diff --git a/erpnext/accounts/doctype/payment_gateway/test_payment_gateway.py b/erpnext/accounts/doctype/payment_gateway/test_payment_gateway.py
new file mode 100644
index 0000000..2faf1a7
--- /dev/null
+++ b/erpnext/accounts/doctype/payment_gateway/test_payment_gateway.py
@@ -0,0 +1,12 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+import frappe
+import unittest
+
+# test_records = frappe.get_test_records('Payment Gateway')
+
+class TestPaymentGateway(unittest.TestCase):
+ pass
diff --git a/erpnext/accounts/doctype/payment_gateway_account/__init__.py b/erpnext/accounts/doctype/payment_gateway_account/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/accounts/doctype/payment_gateway_account/__init__.py
diff --git a/erpnext/accounts/doctype/payment_gateway_account/payment_gateway_account.js b/erpnext/accounts/doctype/payment_gateway_account/payment_gateway_account.js
new file mode 100644
index 0000000..c9bdc9b
--- /dev/null
+++ b/erpnext/accounts/doctype/payment_gateway_account/payment_gateway_account.js
@@ -0,0 +1,6 @@
+cur_frm.cscript.refresh = function(doc, dt, dn){
+ if(!doc.__islocal){
+ var df = frappe.meta.get_docfield(doc.doctype, "gateway", doc.name);
+ df.read_only = 1;
+ }
+}
\ 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
new file mode 100644
index 0000000..c3a4772
--- /dev/null
+++ b/erpnext/accounts/doctype/payment_gateway_account/payment_gateway_account.json
@@ -0,0 +1,291 @@
+{
+ "allow_copy": 0,
+ "allow_import": 0,
+ "allow_rename": 0,
+ "creation": "2015-12-23 21:31:52.699821",
+ "custom": 0,
+ "docstatus": 0,
+ "doctype": "DocType",
+ "document_type": "",
+ "fields": [
+ {
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "fieldname": "gateway_acount_details",
+ "fieldtype": "Section Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Gateway Acount Details",
+ "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": "is_default",
+ "fieldtype": "Check",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Is Default",
+ "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": "gateway",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Gateway",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Payment Gateway",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "fieldname": "payment_account",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Payment Account",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Account",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "fieldname": "currency",
+ "fieldtype": "Read Only",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Currency",
+ "length": 0,
+ "no_copy": 0,
+ "options": "payment_account.account_currency",
+ "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_request_message",
+ "fieldtype": "Section Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Payment Request 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": "message",
+ "fieldtype": "Text Editor",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "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_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,
+ "hide_toolbar": 0,
+ "idx": 0,
+ "in_create": 0,
+ "in_dialog": 0,
+ "is_submittable": 0,
+ "issingle": 0,
+ "istable": 0,
+ "max_attachments": 0,
+ "modified": "2016-01-11 05:55:41.117089",
+ "modified_by": "Administrator",
+ "module": "Accounts",
+ "name": "Payment Gateway Account",
+ "name_case": "",
+ "owner": "Administrator",
+ "permissions": [
+ {
+ "amend": 0,
+ "apply_user_permissions": 0,
+ "cancel": 0,
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "export": 1,
+ "if_owner": 0,
+ "import": 0,
+ "permlevel": 0,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "Administrator",
+ "set_user_permissions": 0,
+ "share": 1,
+ "submit": 0,
+ "write": 1
+ },
+ {
+ "amend": 0,
+ "apply_user_permissions": 0,
+ "cancel": 0,
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "export": 1,
+ "if_owner": 0,
+ "import": 0,
+ "permlevel": 0,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "Accounts Manager",
+ "set_user_permissions": 0,
+ "share": 1,
+ "submit": 0,
+ "write": 1
+ }
+ ],
+ "read_only": 0,
+ "read_only_onload": 0,
+ "sort_field": "modified",
+ "sort_order": "DESC"
+}
\ No newline at end of file
diff --git a/erpnext/accounts/doctype/payment_gateway_account/payment_gateway_account.py b/erpnext/accounts/doctype/payment_gateway_account/payment_gateway_account.py
new file mode 100644
index 0000000..dd971ad
--- /dev/null
+++ b/erpnext/accounts/doctype/payment_gateway_account/payment_gateway_account.py
@@ -0,0 +1,24 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe
+from frappe.model.document import Document
+
+class PaymentGatewayAccount(Document):
+ def autoname(self):
+ self.name = self.gateway + " - " + self.currency
+
+ def validate(self):
+ self.update_default_payment_gateway()
+ 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_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_gateway_account/test_payment_gateway_account.py b/erpnext/accounts/doctype/payment_gateway_account/test_payment_gateway_account.py
new file mode 100644
index 0000000..84c3bc4
--- /dev/null
+++ b/erpnext/accounts/doctype/payment_gateway_account/test_payment_gateway_account.py
@@ -0,0 +1,12 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+import frappe
+import unittest
+
+# test_records = frappe.get_test_records('Payment Gateway Account')
+
+class TestPaymentGatewayAccount(unittest.TestCase):
+ pass
diff --git a/erpnext/accounts/doctype/payment_request/__init__.py b/erpnext/accounts/doctype/payment_request/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/accounts/doctype/payment_request/__init__.py
diff --git a/erpnext/accounts/doctype/payment_request/payment_request.js b/erpnext/accounts/doctype/payment_request/payment_request.js
new file mode 100644
index 0000000..b28a889
--- /dev/null
+++ b/erpnext/accounts/doctype/payment_request/payment_request.js
@@ -0,0 +1,43 @@
+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) {
+ frappe.call({
+ method:"erpnext.accounts.doctype.payment_request.payment_request.get_print_format_list",
+ args: {"ref_doctype": frm.doc.reference_doctype},
+ callback:function(r){
+ set_field_options("print_format", r.message["print_format"])
+ }
+ })
+ }
+})
+
+frappe.ui.form.on("Payment Request", "refresh", function(frm) {
+ frm.add_custom_button(__('Resend Payment Email'), function(){
+ frappe.call({
+ method:"erpnext.accounts.doctype.payment_request.payment_request.resend_payment_email",
+ args: {"docname": frm.doc.name},
+ freeze: true,
+ freeze_message: __("Sending"),
+ callback:function(r){
+ if(!r.exc) {
+ frappe.msgprint(__("Message Sent"))
+ }
+ }
+ })
+ })
+
+ 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
new file mode 100644
index 0000000..7655b58
--- /dev/null
+++ b/erpnext/accounts/doctype/payment_request/payment_request.json
@@ -0,0 +1,678 @@
+{
+ "allow_copy": 0,
+ "allow_import": 0,
+ "allow_rename": 0,
+ "autoname": "PR.######",
+ "creation": "2015-12-15 22:23:24.745065",
+ "custom": 0,
+ "docstatus": 0,
+ "doctype": "DocType",
+ "document_type": "",
+ "fields": [
+ {
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "fieldname": "payment_details",
+ "fieldtype": "Section Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Payment Details",
+ "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": "amount",
+ "fieldtype": "Currency",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Amount",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "2",
+ "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": "currency",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Currency",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Currency",
+ "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,
+ "depends_on": "eval:doc.reference_doctype==\"Sales Order\"",
+ "fieldname": "make_sales_invoice",
+ "fieldtype": "Check",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Make Sales Invoice",
+ "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": "column_break_5",
+ "fieldtype": "Column Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "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,
+ "default": "Draft",
+ "fieldname": "status",
+ "fieldtype": "Select",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Status",
+ "length": 0,
+ "no_copy": 0,
+ "options": "\nDraft\nInitiated\nPaid\nFailed\nCancelled",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "fieldname": "section_break_7",
+ "fieldtype": "Section Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "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_gateway",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Payment Gateway",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Payment Gateway Account",
+ "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
+ },
+ {
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "fieldname": "column_break_9",
+ "fieldtype": "Column Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "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": "gateway",
+ "fieldtype": "Read Only",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Gateway",
+ "length": 0,
+ "no_copy": 0,
+ "options": "payment_gateway.gateway",
+ "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_account",
+ "fieldtype": "Read Only",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Payment Account",
+ "length": 0,
+ "no_copy": 0,
+ "options": "payment_gateway.payment_account",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "fieldname": "recipient_and_message",
+ "fieldtype": "Section Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Recipient and 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,
+ "default": "",
+ "fieldname": "print_format",
+ "fieldtype": "Select",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Print Format",
+ "length": 0,
+ "no_copy": 0,
+ "options": "",
+ "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": "mute_email",
+ "fieldtype": "Check",
+ "hidden": 1,
+ "ignore_user_permissions": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Mute Email",
+ "length": 0,
+ "no_copy": 1,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 1,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "report_hide": 1,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "fieldname": "email_to",
+ "fieldtype": "Data",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Email To",
+ "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": 1,
+ "bold": 0,
+ "collapsible": 0,
+ "fieldname": "subject",
+ "fieldtype": "Data",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Subject",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "fieldname": "message",
+ "fieldtype": "Text Editor",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "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_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_url",
+ "fieldtype": "Data",
+ "hidden": 1,
+ "ignore_user_permissions": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "payment_url",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "fieldname": "reference_details",
+ "fieldtype": "Section Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Reference Details",
+ "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": "reference_doctype",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Reference Doctype",
+ "length": 0,
+ "no_copy": 1,
+ "options": "DocType",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 1,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "report_hide": 1,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "fieldname": "reference_name",
+ "fieldtype": "Dynamic Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Reference Name",
+ "length": 0,
+ "no_copy": 1,
+ "options": "reference_doctype",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 1,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "report_hide": 1,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "fieldname": "amended_from",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Amended From",
+ "length": 0,
+ "no_copy": 1,
+ "options": "Payment Request",
+ "permlevel": 0,
+ "print_hide": 1,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ }
+ ],
+ "hide_heading": 0,
+ "hide_toolbar": 0,
+ "idx": 0,
+ "in_create": 0,
+ "in_dialog": 0,
+ "is_submittable": 1,
+ "issingle": 0,
+ "istable": 0,
+ "max_attachments": 0,
+ "modified": "2016-01-11 05:49:28.342786",
+ "modified_by": "Administrator",
+ "module": "Accounts",
+ "name": "Payment Request",
+ "name_case": "",
+ "owner": "Administrator",
+ "permissions": [
+ {
+ "amend": 0,
+ "apply_user_permissions": 0,
+ "cancel": 0,
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "export": 1,
+ "if_owner": 0,
+ "import": 0,
+ "permlevel": 0,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "Accounts User",
+ "set_user_permissions": 0,
+ "share": 1,
+ "submit": 0,
+ "write": 1
+ },
+ {
+ "amend": 1,
+ "apply_user_permissions": 0,
+ "cancel": 1,
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "export": 1,
+ "if_owner": 0,
+ "import": 0,
+ "permlevel": 0,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "Accounts Manager",
+ "set_user_permissions": 0,
+ "share": 1,
+ "submit": 1,
+ "write": 1
+ },
+ {
+ "amend": 1,
+ "apply_user_permissions": 0,
+ "cancel": 1,
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "export": 1,
+ "if_owner": 0,
+ "import": 0,
+ "permlevel": 0,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "Administrator",
+ "set_user_permissions": 0,
+ "share": 1,
+ "submit": 1,
+ "write": 1
+ }
+ ],
+ "read_only": 0,
+ "read_only_onload": 0,
+ "sort_field": "modified",
+ "sort_order": "DESC"
+}
\ No newline at end of file
diff --git a/erpnext/accounts/doctype/payment_request/payment_request.py b/erpnext/accounts/doctype/payment_request/payment_request.py
new file mode 100644
index 0000000..23fd5a8
--- /dev/null
+++ b/erpnext/accounts/doctype/payment_request/payment_request.py
@@ -0,0 +1,238 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe
+from frappe import _
+from frappe.model.document import Document
+from frappe.utils import flt, nowdate, get_url, cstr
+from erpnext.accounts.party import get_party_account
+from erpnext.accounts.utils import get_account_currency, get_balance_on
+from erpnext.accounts.doctype.journal_entry.journal_entry import (get_payment_entry_against_invoice,
+get_payment_entry_against_order)
+
+from itertools import chain
+
+class PaymentRequest(Document):
+ def validate(self):
+ self.validate_payment_gateway_account()
+ self.validate_payment_request()
+ self.validate_currency()
+
+ 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 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 must be same as Payment Gateway currency"))
+
+ def validate_payment_gateway_account(self):
+ if not self.payment_gateway:
+ frappe.throw(_("Payment Gateway Account is not configured"))
+
+ def validate_payment_gateway(self):
+ if self.gateway == "PayPal":
+ if not frappe.db.get_value("PayPal Settings", None, "api_username"):
+ if not frappe.conf.paypal_username:
+ frappe.throw(_("PayPal Settings missing"))
+
+
+ def on_submit(self):
+ if not self.mute_email:
+ self.send_payment_request()
+ self.send_email()
+
+ self.make_communication_entry()
+
+ def on_cancel(self):
+ self.set_as_cancelled()
+
+ def on_update_after_submit(self):
+ pass
+
+ 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
+ si = make_sales_invoice(self.reference_name, ignore_permissions=True)
+ si = si.insert(ignore_permissions=True)
+ si.submit()
+
+ def send_payment_request(self):
+ self.payment_url = get_url("/api/method/erpnext.accounts.doctype.payment_request.payment_request.generate_payment_request?name={0}".format(self.name))
+ if self.payment_url:
+ frappe.db.set_value(self.doctype, self.name, "status", "Initiated")
+
+ def set_as_paid(self):
+ if frappe.session.user == "Guest":
+ frappe.set_user("Administrator")
+
+ jv = self.create_journal_entry()
+ self.make_invoice()
+
+ return jv
+
+ def create_journal_entry(self):
+ """create entry"""
+ payment_details = {
+ "amount": self.amount,
+ "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,\
+ 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,\
+ amount=self.amount, journal_entry=True, bank_account=self.payment_account)
+
+ jv.update({
+ "voucher_type": "Journal Entry",
+ "posting_date": nowdate()
+ })
+ jv.insert(ignore_permissions=True)
+ jv.submit()
+
+ #set status as paid for Payment Request
+ frappe.db.set_value(self.doctype, self.name, "status", "Paid")
+
+ return jv
+
+ def send_email(self):
+ """send email with payment link"""
+ frappe.sendmail(recipients=self.email_to, sender=None, subject=self.subject,
+ message=self.get_message(), attachments=[frappe.attach_print(self.reference_doctype,
+ self.reference_name, file_name=self.reference_name, print_format=self.print_format)])
+
+ def get_message(self):
+ """return message with payment gateway link"""
+ return cstr(self.message) + " <a href='{0}'>{1}</a>".format(self.payment_url, \
+ self.payment_url_message or _(" Click here to pay"))
+
+ def set_failed(self):
+ pass
+
+ def set_as_cancelled(self):
+ frappe.db.set_value(self.doctype, self.name, "status", "Cancelled")
+
+ def make_communication_entry(self):
+ """Make communication entry"""
+ 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)
+
+ 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 = frappe.get_doc(args.dt, args.dn)
+ gateway_account = get_gateway_details(args)
+
+ pr = frappe.new_doc("Payment Request")
+ pr.update({
+ "payment_gateway": gateway_account.name,
+ "gateway": gateway_account.gateway,
+ "payment_account": gateway_account.payment_account,
+ "currency": ref_doc.currency,
+ "make_sales_invoice": args.cart or 0,
+ "amount": get_amount(ref_doc, args.dt),
+ "mute_email": args.mute_email or 0,
+ "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
+ })
+
+ if args.return_doc:
+ return pr
+
+ if args.submit_doc:
+ pr.insert(ignore_permissions=True)
+ pr.submit()
+
+ if args.cart:
+ generate_payment_request(pr.name)
+ frappe.db.commit()
+
+ if not args.cart:
+ return pr
+
+ return pr.as_dict()
+
+def get_amount(ref_doc, dt):
+ """get amount based on doctype"""
+ if dt == "Sales Order":
+ amount = flt(ref_doc.base_grand_total) - flt(ref_doc.advance_paid)
+
+ if dt == "Sales Invoice":
+ amount = abs(ref_doc.outstanding_amount)
+
+ if amount > 0:
+ return amount
+ else:
+ frappe.throw(_("Payment Entry is already created"))
+
+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", "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", "payment_url_message", "payment_success_url"],
+ as_dict=1)
+
+ if not gateway_account:
+ frappe.throw(_("Payment Gateway Account is not configured"))
+
+ return gateway_account
+
+@frappe.whitelist()
+def get_print_format_list(ref_doctype):
+ print_format_list = ["Standard"]
+
+ 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):
+ 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
+
+@frappe.whitelist(allow_guest=True)
+def resend_payment_email(docname):
+ return frappe.get_doc("Payment Request", docname).send_email()
+
\ No newline at end of file
diff --git a/erpnext/accounts/doctype/payment_request/payment_request_list.js b/erpnext/accounts/doctype/payment_request/payment_request_list.js
new file mode 100644
index 0000000..0caf1c2
--- /dev/null
+++ b/erpnext/accounts/doctype/payment_request/payment_request_list.js
@@ -0,0 +1,17 @@
+frappe.listview_settings['Payment Request'] = {
+ add_fields: ["status"],
+ get_indicator: function(doc) {
+ if(doc.status == "Draft") {
+ return [__("Draft"), "darkgrey", "status,=,Draft"];
+ }
+ else if(doc.status == "Initiated") {
+ return [__("Initiated"), "green", "status,=,Initiated"];
+ }
+ else if(doc.status == "Paid") {
+ return [__("Paid"), "blue", "status,=,Paid"];
+ }
+ else if(doc.status == "Cancelled") {
+ return [__("Cancelled"), "orange", "status,=,Cancelled"];
+ }
+ }
+}
diff --git a/erpnext/accounts/doctype/payment_request/test_payment_request.py b/erpnext/accounts/doctype/payment_request/test_payment_request.py
new file mode 100644
index 0000000..a1e975a
--- /dev/null
+++ b/erpnext/accounts/doctype/payment_request/test_payment_request.py
@@ -0,0 +1,79 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+import frappe
+import unittest
+from erpnext.selling.doctype.sales_order.test_sales_order import make_sales_order
+from erpnext.accounts.doctype.payment_request.payment_request import make_payment_request
+from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice
+# test_records = frappe.get_test_records('Payment Request')
+
+test_dependencies = ["Currency Exchange", "Journal Entry", "Contact", "Address"]
+
+payment_gateway = {
+ "doctype": "Payment Gateway",
+ "gateway": "_Test Gateway"
+}
+
+payment_method = [
+ {
+ "doctype": "Payment Gateway Account",
+ "is_default": 1,
+ "gateway": "_Test Gateway",
+ "payment_account": "_Test Bank - _TC",
+ "currency": "INR"
+ },
+ {
+ "doctype": "Payment Gateway Account",
+ "gateway": "_Test Gateway",
+ "payment_account": "_Test Bank - _TC",
+ "currency": "USD"
+ }
+]
+
+class TestPaymentRequest(unittest.TestCase):
+ def setUp(self):
+ if not frappe.db.get_value("Payment Gateway", payment_gateway["gateway"], "name"):
+ frappe.get_doc(payment_gateway).insert(ignore_permissions=True)
+
+ for method in payment_method:
+ if not frappe.db.get_value("Payment Gateway Account", {"gateway": method["gateway"],
+ "currency": method["currency"]}, "name"):
+ frappe.get_doc(method).insert(ignore_permissions=True)
+
+ def test_payment_request_linkings(self):
+ SO_INR = make_sales_order(currency="INR")
+ pr = make_payment_request(dt="Sales Order", dn=SO_INR.name, recipient_id="saurabh@erpnext.com")
+
+ self.assertEquals(pr.reference_doctype, "Sales Order")
+ self.assertEquals(pr.reference_name, SO_INR.name)
+ self.assertEquals(pr.currency, "INR")
+
+ SI_USD = create_sales_invoice(currency="USD", conversion_rate=50)
+ pr = make_payment_request(dt="Sales Invoice", dn=SI_USD.name, recipient_id="saurabh@erpnext.com")
+
+ self.assertEquals(pr.reference_doctype, "Sales Invoice")
+ self.assertEquals(pr.reference_name, SI_USD.name)
+ self.assertEquals(pr.currency, "USD")
+
+ def test_payment_entry(self):
+ 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_as_paid()
+
+ SO_INR = frappe.get_doc("Sales Order", SO_INR.name)
+
+ self.assertEquals(SO_INR.advance_paid, jv.total_debit)
+
+ SI_USD = create_sales_invoice(customer="_Test Customer USD", debit_to="_Test Receivable USD - _TC",
+ currency="USD", conversion_rate=50)
+
+ pr = make_payment_request(dt="Sales Invoice", dn=SI_USD.name, recipient_id="saurabh@erpnext.com",
+ mute_email=1, return_doc=1, payemnt_gateway="_Test Gateway - USD")
+
+ self.assertRaises(frappe.ValidationError, pr.save)
+
+
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
index 1b541cf..6b03afa 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
@@ -75,6 +75,7 @@
if(doc.outstanding_amount!=0 && !cint(doc.is_return)) {
cur_frm.add_custom_button(__('Payment'), cur_frm.cscript.make_bank_entry).addClass("btn-primary");
+ cur_frm.add_custom_button(__('Make Payment Request'), this.make_payment_request);
}
}
diff --git a/erpnext/accounts/utils.py b/erpnext/accounts/utils.py
index e7f2b8a..6f02a54 100644
--- a/erpnext/accounts/utils.py
+++ b/erpnext/accounts/utils.py
@@ -247,7 +247,7 @@
# will work as update after submit
jv_obj.flags.ignore_validate_update_after_submit = True
- jv_obj.save()
+ jv_obj.save(ignore_permissions=True)
def remove_against_link_from_jv(ref_type, ref_no):
linked_jv = frappe.db.sql_list("""select parent from `tabJournal Entry Account`
diff --git a/erpnext/config/accounts.py b/erpnext/config/accounts.py
index 8a27394..859764d 100644
--- a/erpnext/config/accounts.py
+++ b/erpnext/config/accounts.py
@@ -33,6 +33,11 @@
"description": _("Supplier database.")
},
{
+ "type": "doctype",
+ "name": "Payment Request",
+ "description": _("Payment Request")
+ },
+ {
"type": "page",
"name": "Accounts Browser",
"icon": "icon-sitemap",
@@ -84,6 +89,11 @@
"description": _("Financial / accounting year.")
},
{
+ "type": "doctype",
+ "name": "Payment Gateway Account",
+ "description": _("Setup Gateway accounts.")
+ },
+ {
"type": "page",
"name": "Accounts Browser",
"icon": "icon-sitemap",
diff --git a/erpnext/docs/assets/img/accounts/pr-details-1.png b/erpnext/docs/assets/img/accounts/pr-details-1.png
new file mode 100644
index 0000000..12e40a6
--- /dev/null
+++ b/erpnext/docs/assets/img/accounts/pr-details-1.png
Binary files differ
diff --git a/erpnext/docs/assets/img/accounts/pr-details-2.png b/erpnext/docs/assets/img/accounts/pr-details-2.png
new file mode 100644
index 0000000..43122e3
--- /dev/null
+++ b/erpnext/docs/assets/img/accounts/pr-details-2.png
Binary files differ
diff --git a/erpnext/docs/assets/img/accounts/pr-email.png b/erpnext/docs/assets/img/accounts/pr-email.png
new file mode 100644
index 0000000..de1a868
--- /dev/null
+++ b/erpnext/docs/assets/img/accounts/pr-email.png
Binary files differ
diff --git a/erpnext/docs/assets/img/accounts/pr-from-si.png b/erpnext/docs/assets/img/accounts/pr-from-si.png
new file mode 100644
index 0000000..c9e654a
--- /dev/null
+++ b/erpnext/docs/assets/img/accounts/pr-from-si.png
Binary files differ
diff --git a/erpnext/docs/assets/img/accounts/pr-from-so.png b/erpnext/docs/assets/img/accounts/pr-from-so.png
new file mode 100644
index 0000000..b41ea4f
--- /dev/null
+++ b/erpnext/docs/assets/img/accounts/pr-from-so.png
Binary files differ
diff --git a/erpnext/docs/user/manual/en/accounts/index.txt b/erpnext/docs/user/manual/en/accounts/index.txt
index 391a185..5f1b5d5 100644
--- a/erpnext/docs/user/manual/en/accounts/index.txt
+++ b/erpnext/docs/user/manual/en/accounts/index.txt
@@ -1,6 +1,7 @@
journal-entry
sales-invoice
purchase-invoice
+payment-request
chart-of-accounts
making-payments
advance-payment-entry
diff --git a/erpnext/docs/user/manual/en/accounts/pyament-request.md b/erpnext/docs/user/manual/en/accounts/pyament-request.md
new file mode 100644
index 0000000..ca696c6
--- /dev/null
+++ b/erpnext/docs/user/manual/en/accounts/pyament-request.md
@@ -0,0 +1,28 @@
+Payment Request will act as mediator between Payment Gateway and ERPNext. You can create payment request via Sales Order or Sales Invoice.
+
+- Create Payment Request via Sales Order
+<img class="screenshot" alt="Payment Request" src="{{docs_base_url}}/assets/img/accounts/pr-from-so.png">
+
+- Create payment Request via Sales Invoice
+<img class="screenshot" alt="Payment Request" src="{{docs_base_url}}/assets/img/accounts/pr-from-si.png">
+
+---
+
+Select appropriate Payment Gateway Account on Payment Request. Account head specified on payment gateway will
+considered to create journal entry.
+
+Note: Invoice/Order Currency and Payment Gateway Account corruncy should be same.
+
+<img class="screenshot" alt="Payment Request" src="{{docs_base_url}}/assets/img/accounts/pr-details-1.png">
+
+---
+
+##### Notify Customer
+You can notify customer from Payment Request with print format. If customer contact email is mentioned, it will automatically fetch email. If not so you can set email id on Payment Request.
+
+<img class="screenshot" alt="Payment Request" src="{{docs_base_url}}/assets/img/accounts/pr-details-2.png">
+
+##### Request Mail
+<img class="screenshot" alt="Payment Request" src="{{docs_base_url}}/assets/img/accounts/pr-email.png">
+
+
diff --git a/erpnext/public/js/shopping_cart.js b/erpnext/public/js/shopping_cart.js
index d437d74..b667177 100644
--- a/erpnext/public/js/shopping_cart.js
+++ b/erpnext/public/js/shopping_cart.js
@@ -4,13 +4,12 @@
// shopping cart
frappe.provide("shopping_cart");
-$(function() {
+frappe.ready(function() {
// update user
if(full_name) {
$('.navbar li[data-label="User"] a')
.html('<i class="icon-fixed-width icon-user"></i> ' + full_name);
}
-
// update login
shopping_cart.set_cart_count();
});
@@ -33,10 +32,9 @@
},
btn: opts.btn,
callback: function(r) {
+ shopping_cart.set_cart_count();
if(opts.callback)
opts.callback(r);
-
- shopping_cart.set_cart_count();
}
});
}
@@ -44,13 +42,29 @@
set_cart_count: function() {
var cart_count = getCookie("cart_count");
- var $cart = $('.dropdown [data-label="Cart"]');
- var $badge = $cart.find(".badge");
+
+ if($(".cart-icon").length == 0) {
+ $('<div class="cart-icon" style="float:right;padding-top:10px;">\
+ <a href="/cart" class="text-muted small">\
+ <div class="btn btn-primary cart"> Cart\
+ <span id="cart-count" class="label" style="padding-left:5px;margin-left:5px;\
+ margin-right:-5px;background-color: #2905E2;">\
+ </span>\
+ </div>\
+ </a></div>').appendTo($('.hidden-xs'))
+ }
+
+ var $cart = $('.cart-icon');
+ var $badge = $cart.find("#cart-count");
+
+ if(parseInt(cart_count) === 0 || cart_count === undefined) {
+ $cart.css("display", "none");
+ }
+ else {
+ $cart.css("display", "inline");
+ }
+
if(cart_count) {
- if($badge.length === 0) {
- var $badge = $('<span class="badge pull-right"></span>')
- .prependTo($cart.find("a").addClass("badge-hover"));
- }
$badge.html(cart_count);
} else {
$badge.remove();
diff --git a/erpnext/selling/doctype/sales_order/sales_order.js b/erpnext/selling/doctype/sales_order/sales_order.js
index 56c8da0..74b5202 100644
--- a/erpnext/selling/doctype/sales_order/sales_order.js
+++ b/erpnext/selling/doctype/sales_order/sales_order.js
@@ -41,45 +41,47 @@
}
}
- // material request
- if(!doc.order_type || ["Sales", "Shopping Cart"].indexOf(doc.order_type)!==-1
- && flt(doc.per_delivered, 2) < 100) {
- cur_frm.add_custom_button(__('Material Request'), this.make_material_request);
- }
-
- // make purchase order
- if(flt(doc.per_delivered, 2) < 100 && allow_purchase) {
- cur_frm.add_custom_button(__('Purchase Order'), cur_frm.cscript.make_purchase_order);
- }
-
- if(flt(doc.per_billed)==0) {
- cur_frm.add_custom_button(__('Payment'), cur_frm.cscript.make_bank_entry);
- }
-
if (this.frm.has_perm("submit")) {
// stop
if(flt(doc.per_delivered, 2) < 100 || flt(doc.per_billed) < 100) {
- cur_frm.add_custom_button(__('Stop'), this.stop_sales_order)
+ cur_frm.add_custom_button(__('Stop'), this.stop_sales_order, __("Status"))
}
- cur_frm.add_custom_button(__('Close'), this.close_sales_order)
- }
-
- // maintenance
- if(flt(doc.per_delivered, 2) < 100 && ["Sales", "Shopping Cart"].indexOf(doc.order_type)===-1) {
- cur_frm.add_custom_button(__('Maint. Visit'), this.make_maintenance_visit);
- cur_frm.add_custom_button(__('Maint. Schedule'), this.make_maintenance_schedule);
+ cur_frm.add_custom_button(__('Close'), this.close_sales_order, __("Status"))
}
// delivery note
if(flt(doc.per_delivered, 2) < 100 && ["Sales", "Shopping Cart"].indexOf(doc.order_type)!==-1 && allow_delivery) {
- cur_frm.add_custom_button(__('Delivery'), this.make_delivery_note).addClass("btn-primary");
+ cur_frm.add_custom_button(__('Delivery'), this.make_delivery_note, __("Make"));
+ // cur_frm.page.set_inner_btn_group_as_primary(__("Make"));
}
// sales invoice
if(flt(doc.per_billed, 2) < 100) {
- cur_frm.add_custom_button(__('Invoice'), this.make_sales_invoice).addClass("btn-primary");
+ cur_frm.add_custom_button(__('Invoice'), this.make_sales_invoice, __("Make"));
+ }
+
+ // material request
+ if(!doc.order_type || ["Sales", "Shopping Cart"].indexOf(doc.order_type)!==-1
+ && flt(doc.per_delivered, 2) < 100) {
+ cur_frm.add_custom_button(__('Material Request'), this.make_material_request, __("Make"));
+ }
+
+ // make purchase order
+ if(flt(doc.per_delivered, 2) < 100 && allow_purchase) {
+ cur_frm.add_custom_button(__('Purchase Order'), cur_frm.cscript.make_purchase_order, __("Make"));
+ }
+
+ if(flt(doc.per_billed)==0) {
+ cur_frm.add_custom_button(__('Payment Request'), this.make_payment_request, __("Make"));
+ cur_frm.add_custom_button(__('Payment'), cur_frm.cscript.make_bank_entry, __("Make"));
+ }
+
+ // maintenance
+ if(flt(doc.per_delivered, 2) < 100 && ["Sales", "Shopping Cart"].indexOf(doc.order_type)===-1) {
+ cur_frm.add_custom_button(__('Maintenance Visit'), this.make_maintenance_visit, __("Make"));
+ cur_frm.add_custom_button(__('Maintenance Schedule'), this.make_maintenance_schedule, __("Make"));
}
diff --git a/erpnext/selling/doctype/sales_order/sales_order.json b/erpnext/selling/doctype/sales_order/sales_order.json
index db8cb81..ee97334 100644
--- a/erpnext/selling/doctype/sales_order/sales_order.json
+++ b/erpnext/selling/doctype/sales_order/sales_order.json
@@ -2802,7 +2802,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
- "modified": "2015-12-17 16:19:40.324514",
+ "modified": "2015-12-29 12:32:45.649349",
"modified_by": "Administrator",
"module": "Selling",
"name": "Sales Order",
diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py
index 99e708d..8bc96e6 100644
--- a/erpnext/selling/doctype/sales_order/sales_order.py
+++ b/erpnext/selling/doctype/sales_order/sales_order.py
@@ -288,11 +288,26 @@
frappe.db.set_value("Sales Order", self.name, "per_delivered", flt(delivered_qty/tot_qty) * 100,
update_modified=False)
+
+ def set_indicator(self):
+ """Set indicator for portal"""
+ if self.per_billed < 100 and self.per_delivered < 100:
+ self.indicator_color = "orange"
+ self.indicator_title = _("Not Paid and Not Delivered")
+
+ elif self.per_billed == 100 and self.per_delivered < 100:
+ self.indicator_color = "orange"
+ self.indicator_title = _("Paid and Not Delivered")
+ else:
+ self.indicator_color = "green"
+ self.indicator_title = _("Paid")
+
def get_list_context(context=None):
from erpnext.controllers.website_list_for_contact import get_list_context
list_context = get_list_context(context)
list_context["title"] = _("My Orders")
+ list_context["parents"] = [{"title": _("My Account"), "name": "me"}]
return list_context
@frappe.whitelist()
@@ -401,7 +416,7 @@
return target_doc
@frappe.whitelist()
-def make_sales_invoice(source_name, target_doc=None):
+def make_sales_invoice(source_name, target_doc=None, ignore_permissions=False):
def postprocess(source, target):
set_missing_values(source, target)
#Get the advance paid Journal Entries in Sales Invoice Advance
@@ -410,6 +425,7 @@
def set_missing_values(source, target):
target.is_pos = 0
target.ignore_pricing_rule = 1
+ target.flags.ignore_permissions = True
target.run_method("set_missing_values")
target.run_method("calculate_taxes_and_totals")
@@ -442,7 +458,7 @@
"doctype": "Sales Team",
"add_if_empty": True
}
- }, target_doc, postprocess)
+ }, target_doc, postprocess, ignore_permissions=ignore_permissions)
return doclist
diff --git a/erpnext/selling/sales_common.js b/erpnext/selling/sales_common.js
index 6a8744a..7f17bd3 100644
--- a/erpnext/selling/sales_common.js
+++ b/erpnext/selling/sales_common.js
@@ -288,6 +288,24 @@
}
}
refresh_field('product_bundle_help');
+ },
+
+ make_payment_request: function() {
+ frappe.call({
+ method:"erpnext.accounts.doctype.payment_request.payment_request.make_payment_request",
+ args: {
+ "dt": cur_frm.doc.doctype,
+ "dn": cur_frm.doc.name,
+ "recipient_id": cur_frm.doc.contact_email
+ },
+ callback: function(r) {
+ if(!r.exc){
+ var doc = frappe.model.sync(r.message);
+ console.log(r.message)
+ frappe.set_route("Form", r.message.doctype, r.message.name);
+ }
+ }
+ })
}
});
diff --git a/erpnext/setup/setup_wizard/setup_wizard.py b/erpnext/setup/setup_wizard/setup_wizard.py
index 9be2880..081afcc 100644
--- a/erpnext/setup/setup_wizard/setup_wizard.py
+++ b/erpnext/setup/setup_wizard/setup_wizard.py
@@ -124,7 +124,7 @@
"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")))
diff --git a/erpnext/shopping_cart/utils.py b/erpnext/shopping_cart/utils.py
index 7794a8f..b8d5054 100644
--- a/erpnext/shopping_cart/utils.py
+++ b/erpnext/shopping_cart/utils.py
@@ -28,17 +28,7 @@
cart_enabled = is_cart_enabled()
context["shopping_cart_enabled"] = cart_enabled
- if cart_enabled:
- post_login = [
- {"label": _("Cart"), "url": "cart", "class": "cart-count"},
- {"class": "divider"}
- ]
- context["post_login"] = post_login + context.get("post_login", [])
-
def update_my_account_context(context):
- if is_cart_enabled():
- context["my_account_list"].append({"label": _("Cart"), "url": "cart"})
-
context["my_account_list"].extend([
{"label": _("Orders"), "url": "orders"},
{"label": _("Invoices"), "url": "invoices"},
diff --git a/erpnext/templates/generators/item.html b/erpnext/templates/generators/item.html
index dc48e0d..34d345f 100644
--- a/erpnext/templates/generators/item.html
+++ b/erpnext/templates/generators/item.html
@@ -71,18 +71,7 @@
style="display: none;
padding-left: 0px; padding-right: 0px;
padding-top: 10px;">
- <div>
- <input class="form-control"
- type="text" style="max-width: 140px;">
- </div>
- <div style="margin-top: 10px;">
- <button class="btn btn-default btn-sm">
- {{ _("Update") }}</button>
- </div>
- <div style="margin-top: 5px;">
- <a href="/cart" class="text-muted small">
- {{ _("View Cart") }}</a>
- </div>
+ <a href="/cart">{{ _("Goto Cart") }}</a>
</div>
</div>
</div>
diff --git a/erpnext/templates/includes/cart.js b/erpnext/templates/includes/cart.js
index e413f0b..0c29569 100644
--- a/erpnext/templates/includes/cart.js
+++ b/erpnext/templates/includes/cart.js
@@ -65,11 +65,11 @@
if(!r.exc) {
$(".cart-items").html(r.message.items);
$(".cart-tax-items").html(r.message.taxes);
+ $(".cart-icon").hide();
}
},
});
});
-
},
render_tax_row: function($cart_taxes, doc, shipping_rules) {
@@ -144,5 +144,6 @@
});
$(document).ready(function() {
+ $(".cart-icon").hide();
shopping_cart.bind_events();
});
diff --git a/erpnext/templates/includes/product_page.js b/erpnext/templates/includes/product_page.js
index 0a38c23..f4d9027 100644
--- a/erpnext/templates/includes/product_page.js
+++ b/erpnext/templates/includes/product_page.js
@@ -49,21 +49,6 @@
});
});
- $("#item-update-cart button").on("click", function() {
- shopping_cart.update_cart({
- item_code: get_item_code(),
- qty: $("#item-update-cart input").val(),
- btn: this,
- callback: function(r) {
- if(r.exc) {
- $("#item-update-cart input").val(qty);
- } else {
- qty = $("#item-update-cart input").val();
- }
- },
- });
- });
-
$("[itemscope] .item-view-attribute .form-control").on("change", function() {
try {
var item_code = encodeURIComponent(get_item_code());
diff --git a/erpnext/templates/pages/order.html b/erpnext/templates/pages/order.html
index 26dbed6..3bd6ad3 100644
--- a/erpnext/templates/pages/order.html
+++ b/erpnext/templates/pages/order.html
@@ -5,6 +5,10 @@
<!-- <h6 class="text-muted">{{ doc._title or doc.doctype }}</h6> -->
{% endblock %}
+{% block breadcrumbs %}
+ {% include "templates/includes/breadcrumbs.html" %}
+{% endblock %}
+
{% block style %}
<style>
{% include "templates/includes/order/order.css" %}
@@ -20,7 +24,7 @@
<span class="indicator {{ doc.indicator_color or "darkgrey" }}">
{{ doc.indicator_title or doc.status or "Submitted" }}
</span>
- </div>
+ </div>
<div class="col-xs-6 text-muted text-right h6">
{{ doc.get_formatted("transaction_date") }}
</div>
@@ -58,7 +62,7 @@
{% endif %}
</div>
<div class="col-sm-2 col-xs-3 text-right">
- {{ d.get_formatted("amount") }}
+ {{ d.get_formatted("amount") }}
{# output of get_formatted("rate") is unicode, to replace unicode use _("text {0}").decode("utf8").format(val) #}
<p class="text-muted small">{{
_("Rate: {0}").decode("utf8").format(d.get_formatted("rate")) }}</p>
@@ -76,4 +80,19 @@
</div>
</div>
+<div class="cart-taxes row small">
+ <div class="col-sm-8"><!-- empty --></div>
+ <div class="col-sm-4">
+ {% if (doc.doctype=="Sales Order" and doc.per_billed <= 0)
+ or (doc.doctype=="Sales Invoice" and doc.outstanding_amount > 0) %}
+ <div class="page-header-actions-block" data-html-block="header-actions">
+ <p>
+ <a href="/api/method/erpnext.accounts.doctype.payment_request.payment_request.make_payment_request?dn={{ doc.name }}&dt={{ doc.doctype }}&submit_doc=1&mute_email=1&cart=1"
+ class="btn btn-primary btn-sm">Pay {{ doc.get_formatted("grand_total") }} </a>
+ </p>
+ </div>
+ {% endif %}
+ </div>
+</div>
+
{% endblock %}
diff --git a/erpnext/templates/pages/order.py b/erpnext/templates/pages/order.py
index 6c36e3c..4824d44 100644
--- a/erpnext/templates/pages/order.py
+++ b/erpnext/templates/pages/order.py
@@ -13,6 +13,8 @@
context.doc.set_indicator()
context.parents = frappe.form_dict.parents
-
+ context.payment_ref = frappe.db.get_value("Payment Request",
+ {"reference_name": frappe.form_dict.name}, "name")
+
if not context.doc.has_website_permission("read"):
frappe.throw(_("Not Permitted"), frappe.PermissionError)