diff --git a/erpnext/accounts/doctype/journal_entry/journal_entry.py b/erpnext/accounts/doctype/journal_entry/journal_entry.py index afb9b85fb9..ca7cb7edc4 100644 --- a/erpnext/accounts/doctype/journal_entry/journal_entry.py +++ b/erpnext/accounts/doctype/journal_entry/journal_entry.py @@ -551,7 +551,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, amount=None, journal_entry=False, bank_account=None): +def get_payment_entry_against_order(dt, dn, amount=None, debit_in_account_currency=None, journal_entry=False, bank_account=None): ref_doc = frappe.get_doc(dt, dn) if flt(ref_doc.per_billed, 2) > 0: @@ -582,6 +582,7 @@ def get_payment_entry_against_order(dt, dn, amount=None, journal_entry=False, ba "amount_field_party": amount_field_party, "amount_field_bank": amount_field_bank, "amount": amount, + "debit_in_account_currency": debit_in_account_currency, "remarks": 'Advance Payment received against {0} {1}'.format(dt, dn), "is_advance": "Yes", "bank_account": bank_account, @@ -589,7 +590,7 @@ def get_payment_entry_against_order(dt, dn, amount=None, journal_entry=False, ba }) @frappe.whitelist() -def get_payment_entry_against_invoice(dt, dn, amount=None, journal_entry=False, bank_account=None): +def get_payment_entry_against_invoice(dt, dn, amount=None, debit_in_account_currency=None, journal_entry=False, bank_account=None): ref_doc = frappe.get_doc(dt, dn) if dt == "Sales Invoice": party_type = "Customer" @@ -614,6 +615,7 @@ def get_payment_entry_against_invoice(dt, dn, amount=None, journal_entry=False, "amount_field_party": amount_field_party, "amount_field_bank": amount_field_bank, "amount": amount if amount else abs(ref_doc.outstanding_amount), + "debit_in_account_currency": debit_in_account_currency, "remarks": 'Payment received against {0} {1}. {2}'.format(dt, dn, ref_doc.remarks), "is_advance": "No", "bank_account": bank_account, @@ -662,10 +664,12 @@ def get_payment_entry(ref_doc, args): bank_row.cost_center = cost_center + amount = args.get("debit_in_account_currency") or args.get("amount") + if bank_row.account_currency == args.get("party_account_currency"): - bank_row.set(args.get("amount_field_bank"), args.get("amount")) + bank_row.set(args.get("amount_field_bank"), amount) else: - bank_row.set(args.get("amount_field_bank"), args.get("amount") * exchange_rate) + bank_row.set(args.get("amount_field_bank"), amount * exchange_rate) # set multi currency check if party_row.account_currency != ref_doc.company_currency \ diff --git a/erpnext/accounts/doctype/payment_gateway_account/payment_gateway_account.js b/erpnext/accounts/doctype/payment_gateway_account/payment_gateway_account.js index c9bdc9b80a..e1fe5a16a3 100644 --- a/erpnext/accounts/doctype/payment_gateway_account/payment_gateway_account.js +++ b/erpnext/accounts/doctype/payment_gateway_account/payment_gateway_account.js @@ -1,6 +1,6 @@ cur_frm.cscript.refresh = function(doc, dt, dn){ if(!doc.__islocal){ - var df = frappe.meta.get_docfield(doc.doctype, "gateway", doc.name); + var df = frappe.meta.get_docfield(doc.doctype, "payment_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 index 579c2c29b3..df8eaebed5 100644 --- a/erpnext/accounts/doctype/payment_gateway_account/payment_gateway_account.json +++ b/erpnext/accounts/doctype/payment_gateway_account/payment_gateway_account.json @@ -12,7 +12,7 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, - "fieldname": "gateway", + "fieldname": "payment_gateway", "fieldtype": "Link", "hidden": 0, "ignore_user_permissions": 0, @@ -203,30 +203,6 @@ "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, @@ -238,7 +214,7 @@ "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2016-01-18 03:53:50.534673", + "modified": "2016-01-21 11:32:10.311015", "modified_by": "Administrator", "module": "Accounts", "name": "Payment Gateway Account", 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 468f8778c4..fd213a47a1 100644 --- a/erpnext/accounts/doctype/payment_gateway_account/payment_gateway_account.py +++ b/erpnext/accounts/doctype/payment_gateway_account/payment_gateway_account.py @@ -8,7 +8,7 @@ from frappe.model.document import Document class PaymentGatewayAccount(Document): def autoname(self): - self.name = self.gateway + " - " + self.currency + self.name = self.payment_gateway + " - " + self.currency def validate(self): self.currency = frappe.db.get_value("Account", self.payment_account, "account_currency") @@ -24,4 +24,4 @@ class PaymentGatewayAccount(Document): 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 + 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 b519dee734..1f0e9bc9a1 100644 --- a/erpnext/accounts/doctype/payment_request/payment_request.js +++ b/erpnext/accounts/doctype/payment_request/payment_request.js @@ -1,8 +1,7 @@ cur_frm.add_fetch("payment_gateway", "payment_account", "payment_account") -cur_frm.add_fetch("payment_gateway", "gateway", "gateway") +cur_frm.add_fetch("payment_gateway", "payment_gateway", "payment_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) { @@ -17,18 +16,20 @@ frappe.ui.form.on("Payment Request", "onload", function(frm, dt, dn){ }) 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")); + if(!in_list(["Initiated", "Paid"], frm.doc.status) && !frm.doc.__islocal){ + 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")); + } } - } + }); }); - }); + } }); diff --git a/erpnext/accounts/doctype/payment_request/payment_request.json b/erpnext/accounts/doctype/payment_request/payment_request.json index 7655b5872e..e916034d29 100644 --- a/erpnext/accounts/doctype/payment_request/payment_request.json +++ b/erpnext/accounts/doctype/payment_request/payment_request.json @@ -17,6 +17,7 @@ "fieldtype": "Section Break", "hidden": 0, "ignore_user_permissions": 0, + "ignore_xss_filter": 0, "in_filter": 0, "in_list_view": 0, "label": "Payment Details", @@ -33,30 +34,6 @@ "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, @@ -65,9 +42,10 @@ "fieldtype": "Link", "hidden": 0, "ignore_user_permissions": 0, + "ignore_xss_filter": 0, "in_filter": 0, "in_list_view": 0, - "label": "Currency", + "label": "Transaction Currency", "length": 0, "no_copy": 0, "options": "Currency", @@ -86,18 +64,20 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, - "depends_on": "eval:doc.reference_doctype==\"Sales Order\"", - "fieldname": "make_sales_invoice", - "fieldtype": "Check", + "description": "Amount in customer's currency", + "fieldname": "grand_total", + "fieldtype": "Currency", "hidden": 0, "ignore_user_permissions": 0, + "ignore_xss_filter": 0, "in_filter": 0, "in_list_view": 0, - "label": "Make Sales Invoice", + "label": "Grand Total", "length": 0, "no_copy": 0, + "options": "currency", "permlevel": 0, - "precision": "", + "precision": "2", "print_hide": 0, "print_hide_if_no_value": 0, "read_only": 0, @@ -115,6 +95,7 @@ "fieldtype": "Column Break", "hidden": 0, "ignore_user_permissions": 0, + "ignore_xss_filter": 0, "in_filter": 0, "in_list_view": 0, "length": 0, @@ -139,6 +120,7 @@ "fieldtype": "Select", "hidden": 0, "ignore_user_permissions": 0, + "ignore_xss_filter": 0, "in_filter": 0, "in_list_view": 0, "label": "Status", @@ -156,6 +138,32 @@ "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, + "ignore_xss_filter": 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, @@ -164,6 +172,57 @@ "fieldtype": "Section Break", "hidden": 0, "ignore_user_permissions": 0, + "ignore_xss_filter": 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_account", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Payment Gateway Account", + "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": "column_break_9", + "fieldtype": "Column Break", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, "in_filter": 0, "in_list_view": 0, "length": 0, @@ -184,87 +243,16 @@ "bold": 0, "collapsible": 0, "fieldname": "payment_gateway", - "fieldtype": "Link", + "fieldtype": "Read Only", "hidden": 0, "ignore_user_permissions": 0, + "ignore_xss_filter": 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", + "options": "payment_gateway_account.payment_gateway", "permlevel": 0, "precision": "", "print_hide": 0, @@ -284,12 +272,13 @@ "fieldtype": "Read Only", "hidden": 0, "ignore_user_permissions": 0, + "ignore_xss_filter": 0, "in_filter": 0, "in_list_view": 0, "label": "Payment Account", "length": 0, "no_copy": 0, - "options": "payment_gateway.payment_account", + "options": "payment_gateway_account.payment_account", "permlevel": 0, "precision": "", "print_hide": 0, @@ -309,6 +298,7 @@ "fieldtype": "Section Break", "hidden": 0, "ignore_user_permissions": 0, + "ignore_xss_filter": 0, "in_filter": 0, "in_list_view": 0, "label": "Recipient and Message", @@ -334,6 +324,7 @@ "fieldtype": "Select", "hidden": 0, "ignore_user_permissions": 0, + "ignore_xss_filter": 0, "in_filter": 0, "in_list_view": 0, "label": "Print Format", @@ -359,6 +350,7 @@ "fieldtype": "Check", "hidden": 1, "ignore_user_permissions": 0, + "ignore_xss_filter": 0, "in_filter": 0, "in_list_view": 0, "label": "Mute Email", @@ -383,6 +375,7 @@ "fieldtype": "Data", "hidden": 0, "ignore_user_permissions": 0, + "ignore_xss_filter": 0, "in_filter": 0, "in_list_view": 0, "label": "Email To", @@ -407,6 +400,7 @@ "fieldtype": "Data", "hidden": 0, "ignore_user_permissions": 0, + "ignore_xss_filter": 0, "in_filter": 0, "in_list_view": 0, "label": "Subject", @@ -431,6 +425,7 @@ "fieldtype": "Text Editor", "hidden": 0, "ignore_user_permissions": 0, + "ignore_xss_filter": 0, "in_filter": 0, "in_list_view": 0, "label": "Message", @@ -455,6 +450,7 @@ "fieldtype": "Data", "hidden": 0, "ignore_user_permissions": 0, + "ignore_xss_filter": 0, "in_filter": 0, "in_list_view": 0, "label": "Payment URL Message", @@ -479,6 +475,7 @@ "fieldtype": "Data", "hidden": 1, "ignore_user_permissions": 0, + "ignore_xss_filter": 0, "in_filter": 0, "in_list_view": 0, "label": "payment_url", @@ -503,6 +500,7 @@ "fieldtype": "Section Break", "hidden": 0, "ignore_user_permissions": 0, + "ignore_xss_filter": 0, "in_filter": 0, "in_list_view": 0, "label": "Reference Details", @@ -527,6 +525,7 @@ "fieldtype": "Link", "hidden": 0, "ignore_user_permissions": 0, + "ignore_xss_filter": 0, "in_filter": 0, "in_list_view": 0, "label": "Reference Doctype", @@ -552,6 +551,7 @@ "fieldtype": "Dynamic Link", "hidden": 0, "ignore_user_permissions": 0, + "ignore_xss_filter": 0, "in_filter": 0, "in_list_view": 0, "label": "Reference Name", @@ -577,6 +577,7 @@ "fieldtype": "Link", "hidden": 0, "ignore_user_permissions": 0, + "ignore_xss_filter": 0, "in_filter": 0, "in_list_view": 0, "label": "Amended From", @@ -603,7 +604,7 @@ "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2016-01-11 05:49:28.342786", + "modified": "2016-02-24 16:49:46.832403", "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 ba7413d886..bd4cc4d622 100644 --- a/erpnext/accounts/doctype/payment_request/payment_request.py +++ b/erpnext/accounts/doctype/payment_request/payment_request.py @@ -8,12 +8,10 @@ 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.utils import get_account_currency 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() @@ -35,7 +33,7 @@ class PaymentRequest(Document): frappe.throw(_("Payment Gateway Account is not configured")) def validate_payment_gateway(self): - if self.gateway == "PayPal": + if self.payment_gateway == "PayPal": if not frappe.db.get_value("PayPal Settings", None, "api_username"): if not frappe.conf.paypal_username: frappe.throw(_("PayPal Settings missing")) @@ -49,14 +47,10 @@ class PaymentRequest(Document): 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): + """ This is blanck method to trigger hooks call from individual payment gateway app + which will return respective payment gateway""" pass def make_invoice(self): @@ -69,6 +63,7 @@ class PaymentRequest(Document): 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, "payment_url", self.payment_url) frappe.db.set_value(self.doctype, self.name, "status", "Initiated") def set_as_paid(self): @@ -82,29 +77,44 @@ class PaymentRequest(Document): 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 + + ref_doc = frappe.get_doc(self.reference_doctype, self.reference_name) + + party_account = get_party_account("Customer", ref_doc.get("customer"), ref_doc.company) + party_account_currency = get_account_currency(party_account) + + debit_in_account_currency = 0.0 + + if party_account_currency == ref_doc.company_currency: + amount = flt(flt(self.grand_total) * \ + flt(ref_doc.conversion_rate, ref_doc.precision("conversion_rate")), \ + ref_doc.precision("base_grand_total")) + + if self.currency != ref_doc.company_currency: + debit_in_account_currency = self.grand_total + + else: + amount = debit_in_account_currency = self.grand_total 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) + jv = get_payment_entry_against_order(self.reference_doctype, self.reference_name, + amount=amount, debit_in_account_currency=debit_in_account_currency , 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) + if self.reference_doctype == "Sales Invoice": + jv = get_payment_entry_against_invoice(self.reference_doctype, self.reference_name, + amount=amount, debit_in_account_currency=debit_in_account_currency, 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") @@ -148,22 +158,26 @@ def make_payment_request(**args): args = frappe._dict(args) ref_doc = frappe.get_doc(args.dt, args.dn) + gateway_account = get_gateway_details(args) + grand_total = get_amount(ref_doc, args.dt) + existing_payment_request = frappe.db.get_value("Payment Request", {"reference_doctype": args.dt, "reference_name": args.dn}) + if existing_payment_request: pr = frappe.get_doc("Payment Request", existing_payment_request) - else: + + else: pr = frappe.new_doc("Payment Request") - pr.update({ - "payment_gateway": gateway_account.name, - "gateway": gateway_account.gateway, + "payment_gateway_account": gateway_account.name, + "payment_gateway": gateway_account.payment_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), + "grand_total": grand_total, "mute_email": args.mute_email or 0, "email_to": args.recipient_id or "", "subject": "Payment Request for %s"%args.dn, @@ -180,11 +194,12 @@ def make_payment_request(**args): 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 @@ -193,31 +208,37 @@ def make_payment_request(**args): 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) - + grand_total = flt(ref_doc.grand_total) - flt(ref_doc.advance_paid) + if dt == "Sales Invoice": - amount = abs(ref_doc.outstanding_amount) - - if amount > 0: - return amount + grand_total = flt(ref_doc.outstanding_amount) + + if grand_total > 0 : + return grand_total + 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) + if args.get("payment_gateway"): + return get_payment_gateway_account(args.get("payment_gateway")) + + if args.cart: + payment_gateway_account = frappe.get_doc("Shopping Cart Settings").payment_gateway_account + return get_payment_gateway_account(payment_gateway_account) - 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) + gateway_account = get_payment_gateway_account({"is_default": 1}) if not gateway_account: frappe.throw(_("Payment Gateway Account is not configured")) return gateway_account + +def get_payment_gateway_account(args): + return frappe.db.get_value("Payment Gateway Account", args, + ["name", "payment_gateway", "payment_account", "message", "payment_url_message"], + as_dict=1) @frappe.whitelist() def get_print_format_list(ref_doctype): diff --git a/erpnext/accounts/doctype/payment_request/test_payment_request.py b/erpnext/accounts/doctype/payment_request/test_payment_request.py index 49c604a8c2..eb8e55875c 100644 --- a/erpnext/accounts/doctype/payment_request/test_payment_request.py +++ b/erpnext/accounts/doctype/payment_request/test_payment_request.py @@ -6,8 +6,9 @@ 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.payment_request.payment_request import make_payment_request, get_gateway_details from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice +from erpnext.setup.utils import get_exchange_rate # test_records = frappe.get_test_records('Payment Request') test_dependencies = ["Currency Exchange", "Journal Entry", "Contact", "Address"] @@ -21,13 +22,13 @@ payment_method = [ { "doctype": "Payment Gateway Account", "is_default": 1, - "gateway": "_Test Gateway", + "payment_gateway": "_Test Gateway", "payment_account": "_Test Bank - _TC", "currency": "INR" }, { "doctype": "Payment Gateway Account", - "gateway": "_Test Gateway", + "payment_gateway": "_Test Gateway", "payment_account": "_Test Bank USD - _TC", "currency": "USD" } @@ -39,41 +40,49 @@ class TestPaymentRequest(unittest.TestCase): 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"], + if not frappe.db.get_value("Payment Gateway Account", {"payment_gateway": method["payment_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") - + 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.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") + + conversion_rate = get_exchange_rate("USD", "INR") + + si_usd = create_sales_invoice(currency="USD", conversion_rate=conversion_rate) + 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.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) - - + 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) + + conversion_rate = get_exchange_rate("USD", "INR") + + si_usd = create_sales_invoice(customer="_Test Customer USD", debit_to="_Test Receivable USD - _TC", + currency="USD", conversion_rate=conversion_rate) + + pr = make_payment_request(dt="Sales Invoice", dn=si_usd.name, recipient_id="saurabh@erpnext.com", + mute_email=1, return_doc=1, payment_gateway="_Test Gateway - USD") + + jv = pr.set_as_paid() + + payment_gateway_details = get_gateway_details({"payment_gateway": "_Test Gateway - USD"}) + + self.assertEquals(jv.accounts[0].account, "_Test Receivable USD - _TC") + self.assertEquals(jv.accounts[1].account, payment_gateway_details.payment_account) + \ No newline at end of file diff --git a/erpnext/accounts/utils.py b/erpnext/accounts/utils.py index d59b179fd4..36ff1ab72c 100644 --- a/erpnext/accounts/utils.py +++ b/erpnext/accounts/utils.py @@ -477,3 +477,15 @@ def get_outstanding_invoices(party_type, party, account, condition=None): }) return outstanding_invoices + + +def get_account(account_type=None, root_type=None, is_group=None, account_currency=None, company=None): + """return account based on matching conditions""" + return frappe.db.get_value("Account", { + "account_type": account_type or '', + "root_type": root_type or '', + "is_group": is_group or 0, + "account_currency": account_currency or frappe.defaults.get_defaults().currency, + "company": company or frappe.defaults.get_defaults().company + }, "name") + \ No newline at end of file diff --git a/erpnext/patches.txt b/erpnext/patches.txt index e5ec4548d0..76bffc2de9 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -246,6 +246,6 @@ erpnext.patches.v6_16.update_billing_status_in_dn_and_pr erpnext.patches.v6_16.create_manufacturer_records execute:frappe.db.sql("update `tabPricing Rule` set title=name where title='' or title is null") #2016-01-27 erpnext.patches.v6_20.set_party_account_currency_in_orders -erpnext.patches.v6_19.comment_feed_communication +#erpnext.patches.v6_19.comment_feed_communication erpnext.patches.v6_21.fix_reorder_level erpnext.patches.v6_21.rename_material_request_fields diff --git a/erpnext/shopping_cart/cart.py b/erpnext/shopping_cart/cart.py index 561a50cd72..012aaf7750 100644 --- a/erpnext/shopping_cart/cart.py +++ b/erpnext/shopping_cart/cart.py @@ -9,6 +9,7 @@ from frappe.utils import cint, flt, get_fullname, cstr from erpnext.utilities.doctype.address.address import get_address_display from erpnext.shopping_cart.doctype.shopping_cart_settings.shopping_cart_settings import get_shopping_cart_settings from frappe.utils.nestedset import get_root_of +from erpnext.accounts.utils import get_account class WebsitePriceListMissingError(frappe.ValidationError): pass @@ -280,7 +281,13 @@ def get_customer(user=None): user = frappe.session.user customer = frappe.db.get_value("Contact", {"email_id": user}, "customer") - + cart_settings = frappe.get_doc("Shopping Cart Settings") + + debtors_account = '' + + if cart_settings.enable_checkout: + debtors_account = get_debtors_account(cart_settings) + if customer: return frappe.get_doc("Customer", customer) @@ -293,6 +300,15 @@ def get_customer(user=None): "customer_group": get_shopping_cart_settings().default_customer_group, "territory": get_root_of("Territory") }) + + if debtors_account: + customer.update({ + "accounts": [{ + "company": cart_settings.company, + "account": debtors_account.name + }] + }) + customer.flags.ignore_mandatory = True customer.insert(ignore_permissions=True) @@ -307,6 +323,32 @@ def get_customer(user=None): return customer +def get_debtors_account(cart_settings): + payment_gateway_account_currency = \ + frappe.get_doc("Payment Gateway Account", cart_settings.payment_gateway_account).currency + + account_name = _("Debtors ({0})".format(payment_gateway_account_currency)) + + debtors_account = get_account("Receivable", "Asset", is_group=0,\ + account_currency=payment_gateway_account_currency, company=cart_settings.company) + + if not debtors_account: + debtors_account = frappe.get_doc({ + "doctype": "Account", + "account_type": "Receivable", + "root_type": "Asset", + "is_group": 0, + "parent_account": get_account(root_type="Asset", is_group=1, company=cart_settings.company), + "account_name": account_name, + "currency": payment_gateway_account_currency + }).insert(ignore_permissions=True) + + return debtors_account + + else: + return debtors_account + + def get_address_docs(doctype=None, txt=None, filters=None, limit_start=0, limit_page_length=20, party=None): if not party: party = get_customer() diff --git a/erpnext/shopping_cart/doctype/shopping_cart_settings/shopping_cart_settings.js b/erpnext/shopping_cart/doctype/shopping_cart_settings/shopping_cart_settings.js index 550e34d504..3219d7a5cd 100644 --- a/erpnext/shopping_cart/doctype/shopping_cart_settings/shopping_cart_settings.js +++ b/erpnext/shopping_cart/doctype/shopping_cart_settings/shopping_cart_settings.js @@ -6,5 +6,19 @@ $.extend(cur_frm.cscript, { if(cur_frm.doc.__onload && cur_frm.doc.__onload.quotation_series) { cur_frm.fields_dict.quotation_series.df.options = cur_frm.doc.__onload.quotation_series; } + }, + refresh: function(){ + toggle_mandatory(cur_frm) + }, + enable_checkout: function(){ + toggle_mandatory(cur_frm) } }); + + +function toggle_mandatory (cur_frm){ + cur_frm.toggle_reqd("payment_gateway_account", false); + if(cur_frm.doc.enabled && cur_frm.doc.enable_checkout) { + cur_frm.toggle_reqd("payment_gateway_account", true); + } +} diff --git a/erpnext/shopping_cart/doctype/shopping_cart_settings/shopping_cart_settings.json b/erpnext/shopping_cart/doctype/shopping_cart_settings/shopping_cart_settings.json index fbc9ba0220..4c462c28db 100644 --- a/erpnext/shopping_cart/doctype/shopping_cart_settings/shopping_cart_settings.json +++ b/erpnext/shopping_cart/doctype/shopping_cart_settings/shopping_cart_settings.json @@ -19,9 +19,11 @@ "in_filter": 0, "in_list_view": 1, "label": "Enable Shopping Cart", + "length": 0, "no_copy": 0, "permlevel": 0, "print_hide": 0, + "print_hide_if_no_value": 0, "read_only": 0, "report_hide": 0, "reqd": 0, @@ -39,9 +41,11 @@ "ignore_user_permissions": 0, "in_filter": 0, "in_list_view": 0, + "length": 0, "no_copy": 0, "permlevel": 0, "print_hide": 0, + "print_hide_if_no_value": 0, "read_only": 0, "report_hide": 0, "reqd": 0, @@ -60,10 +64,12 @@ "in_filter": 0, "in_list_view": 1, "label": "Company", + "length": 0, "no_copy": 0, "options": "Company", "permlevel": 0, "print_hide": 0, + "print_hide_if_no_value": 0, "read_only": 0, "report_hide": 0, "reqd": 1, @@ -82,11 +88,13 @@ "in_filter": 0, "in_list_view": 0, "label": "Price List", + "length": 0, "no_copy": 0, "options": "Price List", "permlevel": 0, "precision": "", "print_hide": 0, + "print_hide_if_no_value": 0, "read_only": 0, "report_hide": 0, "reqd": 1, @@ -104,9 +112,11 @@ "ignore_user_permissions": 0, "in_filter": 0, "in_list_view": 0, + "length": 0, "no_copy": 0, "permlevel": 0, "print_hide": 0, + "print_hide_if_no_value": 0, "read_only": 0, "report_hide": 0, "reqd": 0, @@ -126,10 +136,12 @@ "in_filter": 0, "in_list_view": 0, "label": "Default Customer Group", + "length": 0, "no_copy": 0, "options": "Customer Group", "permlevel": 0, "print_hide": 0, + "print_hide_if_no_value": 0, "read_only": 0, "report_hide": 0, "reqd": 1, @@ -148,15 +160,141 @@ "in_filter": 0, "in_list_view": 0, "label": "Quotation Series", + "length": 0, "no_copy": 0, "permlevel": 0, "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": 1, + "collapsible_depends_on": "eval:doc.enable_checkout", + "fieldname": "section_break_8", + "fieldtype": "Section Break", + "hidden": 0, + "ignore_user_permissions": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Checkout Settings", + "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": "enable_checkout", + "fieldtype": "Check", + "hidden": 0, + "ignore_user_permissions": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Enable Checkout", + "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": "Orders", + "description": "After payment completion redirect user to selected page.", + "fieldname": "payment_success_url", + "fieldtype": "Select", + "hidden": 0, + "ignore_user_permissions": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Payment Success Url", + "length": 0, + "no_copy": 0, + "options": "\nOrders\nInvoices\nMy 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": "column_break_11", + "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": "payment_gateway_account", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Payment Gateway Account", + "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 } ], "hide_heading": 0, @@ -168,7 +306,8 @@ "is_submittable": 0, "issingle": 1, "istable": 0, - "modified": "2015-09-17 07:56:09.176098", + "max_attachments": 0, + "modified": "2016-02-09 15:45:03.389220", "modified_by": "Administrator", "module": "Shopping Cart", "name": "Shopping Cart Settings", @@ -196,5 +335,6 @@ } ], "read_only": 0, - "read_only_onload": 0 + "read_only_onload": 0, + "sort_order": "ASC" } \ No newline at end of file diff --git a/erpnext/templates/includes/cart/cart_address.html b/erpnext/templates/includes/cart/cart_address.html index 44964da47c..1af8f0bb48 100644 --- a/erpnext/templates/includes/cart/cart_address.html +++ b/erpnext/templates/includes/cart/cart_address.html @@ -1,12 +1,15 @@ {% from "erpnext/templates/includes/cart/cart_macros.html" import show_address %}
+ {% if addresses|length == 1%} + {% set select_address = True %} + {% endif %}

{{ _("Shipping Address") }}

{% for address in addresses %} - {{ show_address(address, doc, "shipping_address_name") }} + {{ show_address(address, doc, "shipping_address_name", select_address) }} {% endfor %}
@@ -17,7 +20,7 @@
{% for address in addresses %} - {{ show_address(address, doc, "customer_address") }} + {{ show_address(address, doc, "customer_address", select_address) }} {% endfor %}
diff --git a/erpnext/templates/includes/cart/cart_macros.html b/erpnext/templates/includes/cart/cart_macros.html index 250b487920..fd95dba424 100644 --- a/erpnext/templates/includes/cart/cart_macros.html +++ b/erpnext/templates/includes/cart/cart_macros.html @@ -1,5 +1,6 @@ -{% macro show_address(address, doc, fieldname) %} +{% macro show_address(address, doc, fieldname, select_address=False) %} {% set selected=address.name==doc.get(fieldname) %} +
diff --git a/erpnext/templates/pages/order.html b/erpnext/templates/pages/order.html index fae55f3264..03e625da1f 100644 --- a/erpnext/templates/pages/order.html +++ b/erpnext/templates/pages/order.html @@ -1,4 +1,4 @@ -{% extends "templates/web.html" %} +t{% extends "templates/web.html" %} {% block header %}

{{ doc.name }}

@@ -82,14 +82,16 @@
- {% if (doc.doctype=="Sales Order" and doc.per_billed <= 0) - or (doc.doctype=="Sales Invoice" and doc.outstanding_amount > 0) %} -
-

- Pay {{ doc.get_formatted("grand_total") }} -

+ {% if enabled_checkout %} + {% if (doc.doctype=="Sales Order" and doc.per_billed <= 0) + or (doc.doctype=="Sales Invoice" and doc.outstanding_amount > 0) %} + + {% endif %} {% endif %}
diff --git a/erpnext/templates/pages/order.py b/erpnext/templates/pages/order.py index 4824d4403f..bf1514ac2b 100644 --- a/erpnext/templates/pages/order.py +++ b/erpnext/templates/pages/order.py @@ -15,6 +15,8 @@ def get_context(context): context.parents = frappe.form_dict.parents context.payment_ref = frappe.db.get_value("Payment Request", {"reference_name": frappe.form_dict.name}, "name") - + + context.enabled_checkout = frappe.get_doc("Shopping Cart Settings").enable_checkout + if not context.doc.has_website_permission("read"): frappe.throw(_("Not Permitted"), frappe.PermissionError)