diff --git a/erpnext/accounts/doctype/journal_entry/journal_entry.py b/erpnext/accounts/doctype/journal_entry/journal_entry.py index 670661c01f..1a8b645f8b 100644 --- a/erpnext/accounts/doctype/journal_entry/journal_entry.py +++ b/erpnext/accounts/doctype/journal_entry/journal_entry.py @@ -632,7 +632,8 @@ def get_payment_entry(ref_doc, args): }) bank_row = jv.append("accounts") - bank_account = get_default_bank_cash_account(ref_doc.company, "Bank Entry") + + bank_account = args.get("bank_account", get_default_bank_cash_account(ref_doc.company, "Bank Entry")) if bank_account: bank_row.update(bank_account) bank_row.exchange_rate = get_exchange_rate(bank_account["account"], @@ -653,7 +654,7 @@ def get_payment_entry(ref_doc, args): jv.set_amounts_in_company_currency() jv.set_total_debit_credit() - return jv.as_dict() + return jv if args.get("return_obj") else jv.as_dict() @frappe.whitelist() def get_opening_accounts(company): diff --git a/erpnext/accounts/doctype/payment_gateway/payment_gateway.json b/erpnext/accounts/doctype/payment_gateway/payment_gateway.json index 69befe3bfa..ccee2bbf9b 100644 --- a/erpnext/accounts/doctype/payment_gateway/payment_gateway.json +++ b/erpnext/accounts/doctype/payment_gateway/payment_gateway.json @@ -2,7 +2,7 @@ "allow_copy": 0, "allow_import": 0, "allow_rename": 0, - "autoname": "field:gateway_title", + "autoname": "field:gateway", "creation": "2015-12-15 22:26:45.221162", "custom": 0, "docstatus": 0, @@ -13,13 +13,37 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, - "fieldname": "gatewaty_title", + "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": "Data", "hidden": 0, "ignore_user_permissions": 0, "in_filter": 0, "in_list_view": 0, - "label": "Gatewaty Title", + "label": "Gateway", "length": 0, "no_copy": 0, "permlevel": 0, @@ -38,7 +62,7 @@ "bold": 0, "collapsible": 0, "fieldname": "payment_account", - "fieldtype": "Data", + "fieldtype": "Link", "hidden": 0, "ignore_user_permissions": 0, "in_filter": 0, @@ -46,6 +70,7 @@ "label": "Payment Account", "length": 0, "no_copy": 0, + "options": "Account", "permlevel": 0, "precision": "", "print_hide": 0, @@ -67,7 +92,7 @@ "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2015-12-15 22:26:57.027571", + "modified": "2015-12-16 13:20:49.584949", "modified_by": "Administrator", "module": "Accounts", "name": "Payment Gateway", diff --git a/erpnext/accounts/doctype/payment_gateway/payment_gateway.py b/erpnext/accounts/doctype/payment_gateway/payment_gateway.py index 79101ccfc1..a0b8944735 100644 --- a/erpnext/accounts/doctype/payment_gateway/payment_gateway.py +++ b/erpnext/accounts/doctype/payment_gateway/payment_gateway.py @@ -7,4 +7,11 @@ import frappe from frappe.model.document import Document class PaymentGateway(Document): - pass + def validate(self): + self.update_default_payment_gateway() + + def update_default_payment_gateway(self): + frappe.db.sql("""update `tabPayment Gateway` set is_default = 0 + where is_default = 1 """) + + diff --git a/erpnext/accounts/doctype/payment_request/payment_request.json b/erpnext/accounts/doctype/payment_request/payment_request.json index 473b463a62..add555e314 100644 --- a/erpnext/accounts/doctype/payment_request/payment_request.json +++ b/erpnext/accounts/doctype/payment_request/payment_request.json @@ -209,6 +209,31 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "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": "Standard\nPOS Invoice", + "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": "email_to", "fieldtype": "Data", "hidden": 0, @@ -230,7 +255,7 @@ "unique": 0 }, { - "allow_on_submit": 0, + "allow_on_submit": 1, "bold": 0, "collapsible": 0, "fieldname": "subject", @@ -254,7 +279,7 @@ "unique": 0 }, { - "allow_on_submit": 0, + "allow_on_submit": 1, "bold": 0, "collapsible": 0, "fieldname": "message", @@ -313,14 +338,14 @@ "in_list_view": 0, "label": "Reference Doctype", "length": 0, - "no_copy": 0, + "no_copy": 1, "options": "DocType", "permlevel": 0, "precision": "", - "print_hide": 0, + "print_hide": 1, "print_hide_if_no_value": 0, - "read_only": 0, - "report_hide": 0, + "read_only": 1, + "report_hide": 1, "reqd": 0, "search_index": 0, "set_only_once": 0, @@ -338,14 +363,14 @@ "in_list_view": 0, "label": "Reference Name", "length": 0, - "no_copy": 0, + "no_copy": 1, "options": "reference_doctype", "permlevel": 0, "precision": "", - "print_hide": 0, + "print_hide": 1, "print_hide_if_no_value": 0, - "read_only": 0, - "report_hide": 0, + "read_only": 1, + "report_hide": 1, "reqd": 0, "search_index": 0, "set_only_once": 0, @@ -385,7 +410,7 @@ "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2015-12-16 09:02:03.786403", + "modified": "2015-12-16 17:31:37.319394", "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 05b318e32a..e8c824a718 100644 --- a/erpnext/accounts/doctype/payment_request/payment_request.py +++ b/erpnext/accounts/doctype/payment_request/payment_request.py @@ -5,31 +5,130 @@ from __future__ import unicode_literals import frappe from frappe.model.document import Document -from frappe.utils import flt +from frappe.utils import flt, today +from frappe import _ +from erpnext.accounts.doctype.journal_entry.journal_entry import (get_payment_entry_against_order, +get_payment_entry_against_invoice, get_payment_entry) +from erpnext.accounts.party import get_party_account +from erpnext.accounts.utils import get_account_currency, get_balance_on -class PaymentRequest(Document): +class PaymentRequest(Document): + def validate(self): + self.validate_payment_request() + + def validate_payment_request(self): + if frappe.db.get_value("Payment Request", {"reference_name": self.reference_name, + "name": ("!=", self.name), "status": "Paid", "docstatus": 1}, "name"): + frappe.throw(_("Payment Request already exist")) + def on_submit(self): + if self.status == "Paid": + self.set_paid() + + self.send_email() self.send_payment_request() + self.make_communication_entry() + + def on_cancel(self): + pass + + def on_update_after_submit(self): + pass + + def set_status(self): + pass def send_payment_request(self): pass - - def set_paid(self): + + def make_communication_log_entry(self): pass + def set_paid(self): + self.create_journal_voucher_entry() + + def create_journal_voucher_entry(self): + """create voucher entry""" + payment_details = { + "party_type": "Customer", + "amount_field_party": "credit_in_account_currency", + "amount_field_bank": "debit_in_account_currency", + "amount": self.amount, + "return_obj": True + } + ref_doc = frappe.get_doc(self.reference_doctype, self.reference_name) + + if self.reference_doctype == "Sales Order": + party_account = get_party_account("Customer", ref_doc.get('customer'), ref_doc.company) + payment_details.update({ + "party_account": party_account, + "party_account_currency": get_account_currency(party_account), + "remarks": 'Advance Payment received against {0} {1}'.format(self.reference_doctype, self.reference_name), + "is_advance": "Yes" + }) + if self.reference_doctype == "Sales Invoice": + payment_details.update({ + "party_account": ref_doc.debit_to, + "party_account_currency": ref_doc.party_account_currency, + "remarks": 'Payment received against {0} {1}. {2}'.format(self.reference_doctype, self.reference_name, ref_doc.remarks), + "is_advance": "No" + }) + + account_details = frappe.db.get_value("Account", self.payment_account, + ["account_currency", "account_type"], as_dict=1) + + payment_details["bank_account"] = { + "account": self.payment_account, + "balance": get_balance_on(self.payment_account), + "account_currency": account_details.account_currency, + "account_type": account_details.account_type + } + + jv = get_payment_entry(ref_doc, payment_details) + jv.update({ + "voucher_type": "Journal Entry", + "posting_date": today() + }) + jv.submit() + + 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 self.message + "
Payment Link link for payment gateway " + def set_failed(self): pass def set_cancelled(self): pass + + 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) @frappe.whitelist() -def make_payment_request(dt, dn, recipient_id): +def make_payment_request(dt, dn, recipient_id=None): """Make payment request""" ref_doc = get_reference_doc_details(dt, dn) + payment_gateway, payment_account = get_gateway_details() pr = frappe.get_doc({ "doctype": "Payment Request", + "payment_gateway": payment_gateway, + "payment_account": payment_account, "currency": ref_doc.currency, "amount": get_amount(ref_doc, dt), "email_to": recipient_id, @@ -37,12 +136,23 @@ def make_payment_request(dt, dn, recipient_id): "reference_name": dn }).insert() - pr.submit() - def get_reference_doc_details(dt, dn): """ return reference doc Sales Order/Sales Invoice""" return frappe.get_doc(dt, dn) def get_amount(ref_doc, dt): + """get amount based on doctype""" if dt == "Sales Order": - return flt(ref_doc.grand_total) - flt(ref_doc.advance_paid) \ No newline at end of file + amount = 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 + else: + frappe.throw(_("Payment Entry is already created")) + +def get_gateway_details(): + """return gateway and payment account of default payment gateway""" + return frappe.db.get_value("Payment Gateway", {"is_default": 1}, ["gateway", "payment_account"]) \ No newline at end of file diff --git a/erpnext/selling/sales_common.js b/erpnext/selling/sales_common.js index 374526719f..044638223f 100644 --- a/erpnext/selling/sales_common.js +++ b/erpnext/selling/sales_common.js @@ -291,42 +291,12 @@ erpnext.selling.SellingController = erpnext.TransactionController.extend({ }, make_payment_request: function() { - if (!cur_frm.doc.contact_email){ - cur_frm.cscript.get_customer_email(); - } - else { - cur_frm.cscript.create_payment_request(cur_frm.doc.contact_email) - } - }, - - get_customer_email: function() { - var dialog = new frappe.ui.Dialog({ - title: __("Recipient Details"), - fields: [ - {"fieldtype": "Data", "label": __("Recipient Email Id"), "fieldname": "recipient_id", - "reqd": 1}, - {"fieldtype": "Button", "label": __("Make Payment Request"), - "fieldname": "make_pr", "cssClass": "btn-primary"} - ] - }); - - dialog.fields_dict.make_pr.$input.click(function() { - args = dialog.get_values(); - if(!args) return; - dialog.hide(); - cur_frm.cscript.create_payment_request(args.recipient_id) - - }); - dialog.show(); - }, - - create_payment_request: function(recipient_id){ 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": recipient_id + "recipient_id": cur_frm.doc.contact_email }, callback: function(r) {