Payment Entry from invoice

This commit is contained in:
Nabin Hait 2016-06-28 19:42:19 +05:30
parent 221fa98b51
commit 05aefbbf5d
9 changed files with 98 additions and 52 deletions

View File

@ -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):

View File

@ -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);
}
},

View File

@ -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
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

View File

@ -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}

View File

@ -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: [

View File

@ -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
}

View File

@ -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)

View File

@ -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:

View File

@ -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);
}
});
}
});