diff --git a/erpnext/accounts/doctype/journal_entry/journal_entry.py b/erpnext/accounts/doctype/journal_entry/journal_entry.py index 9ff64eb9c67..81fe43660b3 100644 --- a/erpnext/accounts/doctype/journal_entry/journal_entry.py +++ b/erpnext/accounts/doctype/journal_entry/journal_entry.py @@ -525,13 +525,10 @@ class JournalEntry(AccountsController): 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, account=None): +def get_default_bank_cash_account(company, voucher_type=None, 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) - if account.get("account"): - account.update({"balance": get_balance_on(account.get("account"))}) - return account + account = get_bank_cash_account(mode_of_payment, company).get("account") if not account: if voucher_type=="Bank Entry": @@ -549,12 +546,13 @@ def get_default_bank_cash_account(company, voucher_type, mode_of_payment=None, a if account: account_details = frappe.db.get_value("Account", account, ["account_currency", "account_type"], as_dict=1) - return { + + return frappe._dict({ "account": account, "balance": get_balance_on(account), "account_currency": account_details.account_currency, "account_type": account_details.account_type - } + }) @frappe.whitelist() def get_payment_entry_against_order(dt, dn, amount=None, debit_in_account_currency=None, journal_entry=False, bank_account=None): diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.js b/erpnext/accounts/doctype/payment_entry/payment_entry.js index da4f10d4a14..52834d452ed 100644 --- a/erpnext/accounts/doctype/payment_entry/payment_entry.js +++ b/erpnext/accounts/doctype/payment_entry/payment_entry.js @@ -4,8 +4,8 @@ frappe.ui.form.on('Payment Entry', { onload: function(frm) { if(frm.doc.__islocal) { - frm.set_value("paid_from_account_currency", null); - frm.set_value("paid_to_account_currency", null); + if (!frm.doc.paid_from) frm.set_value("paid_from_account_currency", null); + if (!frm.doc.paid_to) frm.set_value("paid_to_account_currency", null); } }, diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.py b/erpnext/accounts/doctype/payment_entry/payment_entry.py index 0e5d8e7aec7..dae7bda742c 100644 --- a/erpnext/accounts/doctype/payment_entry/payment_entry.py +++ b/erpnext/accounts/doctype/payment_entry/payment_entry.py @@ -5,10 +5,11 @@ from __future__ import unicode_literals import frappe, json from frappe import _, scrub -from frappe.utils import flt, comma_or +from frappe.utils import flt, comma_or, nowdate from erpnext.accounts.utils import get_outstanding_invoices, get_account_currency, get_balance_on from erpnext.accounts.party import get_party_account -from erpnext.accounts.doctype.journal_entry.journal_entry import get_average_exchange_rate +from erpnext.accounts.doctype.journal_entry.journal_entry \ + import get_average_exchange_rate, get_default_bank_cash_account from erpnext.setup.utils import get_exchange_rate from erpnext.accounts.general_ledger import make_gl_entries @@ -16,9 +17,7 @@ from erpnext.controllers.accounts_controller import AccountsController class PaymentEntry(AccountsController): - def __init__(self, arg1, arg2=None): - super(PaymentEntry, self).__init__(arg1, arg2) - + def setup_party_account_field(self): self.party_account_field = None self.party_account = None self.party_account_currency = None @@ -32,8 +31,11 @@ class PaymentEntry(AccountsController): self.party_account_field = "paid_to" self.party_account = self.paid_to self.party_account_currency = self.paid_to_account_currency + + print self.payment_type, self.party_account_field def validate(self): + self.setup_party_account_field() self.set_missing_values() self.validate_party_details() self.validate_bank_accounts() @@ -69,11 +71,10 @@ class PaymentEntry(AccountsController): self.party_balance = get_balance_on(party_type=self.party_type, party=self.party, date=self.posting_date) - if not self.get(self.party_account_field): + if not self.party_account: party_account = get_party_account(self.party_type, self.party, self.company) self.set(self.party_account_field, party_account) - - self.party_account = self.get(self.party_account_field) + self.party_account = party_account if self.paid_from and not (self.paid_from_account_currency or self.paid_from_account_balance): acc = get_account_currency_and_balance(self.paid_from, self.posting_date) @@ -187,7 +188,6 @@ class PaymentEntry(AccountsController): self.total_allocated_amount, self.base_total_allocated_amount = 0, 0 for d in self.get("references"): if d.allocated_amount: - print d.reference_name, d.outstanding_amount, d.allocated_amount if d.allocated_amount > d.outstanding_amount: frappe.throw(_("Row #{0}: Allocated amount cannot be greater than outstanding amount") .format(d.idx)) @@ -439,4 +439,59 @@ def get_company_defaults(company): frappe.throw(_("Please set default {0} in Company {1}") .format(frappe.get_meta("Company").get_label(fieldname), company)) - return ret \ No newline at end of file + return ret + +@frappe.whitelist() +def get_payment_entry_against_invoice(dt, dn): + invoice = frappe.get_doc(dt, dn) + + if dt == "Sales Invoice": + party_type = "Customer" + party_account = invoice.debit_to + else: + party_type = "Supplier" + party_account = invoice.credit_to + + + if (dt=="Sales Invoice" and invoice.outstanding_amount > 0) \ + or (dt=="Purchase Invoice" and invoice.outstanding_amount < 0): + payment_type = "Receive" + else: + payment_type = "Pay" + + bank = frappe._dict() + if invoice.mode_of_payment: + bank = get_default_bank_cash_account(invoice.company, mode_of_payment=invoice.mode_of_payment) + + paid_amount = received_amount = 0 + if invoice.party_account_currency == bank.account_currency: + paid_amount = received_amount = invoice.outstanding_amount + elif payment_type == "Receive": + paid_amount = invoice.outstanding_amount + else: + received_amount = invoice.outstanding_amount + + pe = frappe.new_doc("Payment Entry") + pe.payment_type = payment_type + pe.company = invoice.company + pe.posting_date = nowdate() + pe.mode_of_payment = invoice.mode_of_payment + pe.party_type = party_type + pe.party = invoice.get(scrub(party_type)) + pe.paid_from = party_account if payment_type=="Receive" else bank.account + pe.paid_to = party_account if payment_type=="Pay" else bank.account + pe.paid_amount = paid_amount + pe.received_amount = received_amount + + pe.append("references", { + "reference_doctype": dt, + "reference_name": dn, + "allocated_amount": invoice.outstanding_amount + }) + + pe.setup_party_account_field() + pe.set_missing_values() + pe.set_exchange_rate() + pe.set_amounts() + + return pe \ No newline at end of file diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js index 7a83c7b0b2c..e919c4b02e9 100644 --- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js +++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js @@ -35,7 +35,7 @@ erpnext.accounts.PurchaseInvoice = erpnext.buying.BuyingController.extend({ if(!doc.is_return && doc.docstatus==1) { if(doc.outstanding_amount > 0) { - this.frm.add_custom_button(__('Payment'), this.make_bank_entry, __("Make")); + this.frm.add_custom_button(__('Payment'), this.make_payment_entry, __("Make")); cur_frm.page.set_inner_btn_group_as_primary(__("Make")); } @@ -218,21 +218,6 @@ cur_frm.fields_dict.cash_bank_account.get_query = function(doc) { } } -cur_frm.cscript.make_bank_entry = function() { - return frappe.call({ - method: "erpnext.accounts.doctype.journal_entry.journal_entry.get_payment_entry_against_invoice", - args: { - "dt": "Purchase Invoice", - "dn": cur_frm.doc.name - }, - callback: function(r) { - var doclist = frappe.model.sync(r.message); - frappe.set_route("Form", doclist[0].doctype, doclist[0].name); - } - }); -} - - cur_frm.fields_dict['supplier_address'].get_query = function(doc, cdt, cdn) { return{ filters:{'supplier': doc.supplier} diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js index 09ff5b23a25..95ad98a0837 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js @@ -67,7 +67,7 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte if(doc.outstanding_amount>0 && !cint(doc.is_return)) { 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")); + cur_frm.add_custom_button(__('Payment'), this.make_payment_entry, __("Make")); } } @@ -280,20 +280,6 @@ cur_frm.cscript['Make Delivery Note'] = function() { }) } -cur_frm.cscript.make_bank_entry = function() { - return frappe.call({ - method: "erpnext.accounts.doctype.journal_entry.journal_entry.get_payment_entry_against_invoice", - args: { - "dt": "Sales Invoice", - "dn": cur_frm.doc.name - }, - callback: function(r) { - var doclist = frappe.model.sync(r.message); - frappe.set_route("Form", doclist[0].doctype, doclist[0].name); - } - }); -} - cur_frm.fields_dict.cash_bank_account.get_query = function(doc) { return { filters: [ diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py index a6fbff739bb..82cb365145a 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py @@ -704,7 +704,8 @@ def get_bank_cash_account(mode_of_payment, company): account = frappe.db.get_value("Mode of Payment Account", {"parent": mode_of_payment, "company": company}, "default_account") if not account: - frappe.throw(_("Please set default Cash or Bank account in Mode of Payment {0}").format(mode_of_payment)) + frappe.throw(_("Please set default Cash or Bank account in Mode of Payment {0}") + .format(mode_of_payment)) return { "account": account } diff --git a/erpnext/accounts/utils.py b/erpnext/accounts/utils.py index 048a534c29d..b1f55df9f4b 100644 --- a/erpnext/accounts/utils.py +++ b/erpnext/accounts/utils.py @@ -316,6 +316,7 @@ def update_reference_in_payment_entry(d, payment_entry): new_row.update(reference_details) payment_entry.flags.ignore_validate_update_after_submit = True + payment_entry.setup_party_account_field() payment_entry.set_missing_values() payment_entry.set_amounts() payment_entry.save(ignore_permissions=True) diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py index 518561431f4..1c7d032d714 100644 --- a/erpnext/controllers/accounts_controller.py +++ b/erpnext/controllers/accounts_controller.py @@ -312,7 +312,7 @@ class AccountsController(TransactionBase): order_list = list(set([d.get(order_field) for d in self.get("items") if d.get(order_field)])) - + journal_entries = get_advance_journal_entries(party_type, party, party_account, amount_field, order_doctype, order_list, include_unallocated) @@ -324,6 +324,12 @@ class AccountsController(TransactionBase): return res def validate_advance_entries(self): + order_field = "sales_order" if self.doctype == "Sales Invoice" else "purchase_order" + order_list = list(set([d.get(order_field) + for d in self.get("items") if d.get(order_field)])) + + if not order_list: return + advance_entries = self.get_advance_entries(include_unallocated=False) if advance_entries: diff --git a/erpnext/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js index ad6901c8c39..a7f7e2a53ca 100644 --- a/erpnext/public/js/controllers/transaction.js +++ b/erpnext/public/js/controllers/transaction.js @@ -1000,5 +1000,19 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({ } }) } + }, + + make_payment_entry: function() { + return frappe.call({ + method: "erpnext.accounts.doctype.payment_entry.payment_entry.get_payment_entry_against_invoice", + args: { + "dt": cur_frm.doc.doctype, + "dn": cur_frm.doc.name + }, + callback: function(r) { + var doclist = frappe.model.sync(r.message); + frappe.set_route("Form", doclist[0].doctype, doclist[0].name); + } + }); } }); \ No newline at end of file