Make payment entry aginst order, payment request and patch to rename advance table fields
This commit is contained in:
parent
05aefbbf5d
commit
13093b4b68
@ -283,7 +283,8 @@ cur_frm.cscript.voucher_type = function(doc, cdt, cdn) {
|
|||||||
type: "GET",
|
type: "GET",
|
||||||
method: "erpnext.accounts.doctype.journal_entry.journal_entry.get_default_bank_cash_account",
|
method: "erpnext.accounts.doctype.journal_entry.journal_entry.get_default_bank_cash_account",
|
||||||
args: {
|
args: {
|
||||||
"voucher_type": doc.voucher_type,
|
"account_type": (doc.voucher_type=="Bank Entry" ?
|
||||||
|
"Bank" : (doc.voucher_type=="Cash" ? "Cash" : null)),
|
||||||
"company": doc.company
|
"company": doc.company
|
||||||
},
|
},
|
||||||
callback: function(r) {
|
callback: function(r) {
|
||||||
|
@ -525,19 +525,19 @@ class JournalEntry(AccountsController):
|
|||||||
d.party_balance = party_balance[(d.party_type, d.party)]
|
d.party_balance = party_balance[(d.party_type, d.party)]
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_default_bank_cash_account(company, voucher_type=None, mode_of_payment=None, account=None):
|
def get_default_bank_cash_account(company, account_type=None, mode_of_payment=None, account=None):
|
||||||
from erpnext.accounts.doctype.sales_invoice.sales_invoice import get_bank_cash_account
|
from erpnext.accounts.doctype.sales_invoice.sales_invoice import get_bank_cash_account
|
||||||
if mode_of_payment:
|
if mode_of_payment:
|
||||||
account = get_bank_cash_account(mode_of_payment, company).get("account")
|
account = get_bank_cash_account(mode_of_payment, company).get("account")
|
||||||
|
|
||||||
if not account:
|
if not account:
|
||||||
if voucher_type=="Bank Entry":
|
if account_type=="Bank":
|
||||||
account = frappe.db.get_value("Company", company, "default_bank_account")
|
account = frappe.db.get_value("Company", company, "default_bank_account")
|
||||||
if not account:
|
if not account:
|
||||||
account = frappe.db.get_value("Account",
|
account = frappe.db.get_value("Account",
|
||||||
{"company": company, "account_type": "Bank", "is_group": 0})
|
{"company": company, "account_type": "Bank", "is_group": 0})
|
||||||
|
|
||||||
elif voucher_type=="Cash Entry":
|
elif account_type=="Cash":
|
||||||
account = frappe.db.get_value("Company", company, "default_cash_account")
|
account = frappe.db.get_value("Company", company, "default_cash_account")
|
||||||
if not account:
|
if not account:
|
||||||
account = frappe.db.get_value("Account",
|
account = frappe.db.get_value("Account",
|
||||||
@ -660,7 +660,7 @@ def get_payment_entry(ref_doc, args):
|
|||||||
bank_row = je.append("accounts")
|
bank_row = je.append("accounts")
|
||||||
|
|
||||||
#make it bank_details
|
#make it bank_details
|
||||||
bank_account = get_default_bank_cash_account(ref_doc.company, "Bank Entry", account=args.get("bank_account"))
|
bank_account = get_default_bank_cash_account(ref_doc.company, "Bank", account=args.get("bank_account"))
|
||||||
if bank_account:
|
if bank_account:
|
||||||
bank_row.update(bank_account)
|
bank_row.update(bank_account)
|
||||||
bank_row.exchange_rate = get_exchange_rate(bank_account["account"],
|
bank_row.exchange_rate = get_exchange_rate(bank_account["account"],
|
||||||
|
@ -94,11 +94,9 @@ frappe.ui.form.on('Payment Entry', {
|
|||||||
frm.doc.paid_to_account_currency != company_currency &&
|
frm.doc.paid_to_account_currency != company_currency &&
|
||||||
frm.doc.paid_from_account_currency != frm.doc.paid_to_account_currency));
|
frm.doc.paid_from_account_currency != frm.doc.paid_to_account_currency));
|
||||||
|
|
||||||
frm.toggle_display("base_paid_amount",
|
frm.toggle_display("base_paid_amount", frm.doc.paid_from_account_currency != company_currency);
|
||||||
(!frm.doc.party && frm.doc.paid_from_account_currency != company_currency));
|
|
||||||
|
|
||||||
frm.toggle_display("base_received_amount", (!frm.doc.party &&
|
frm.toggle_display("base_received_amount", (frm.doc.paid_to_account_currency != company_currency &&
|
||||||
frm.doc.paid_to_account_currency != company_currency &&
|
|
||||||
frm.doc.paid_from_account_currency != frm.doc.paid_to_account_currency));
|
frm.doc.paid_from_account_currency != frm.doc.paid_to_account_currency));
|
||||||
|
|
||||||
frm.toggle_display("received_amount",
|
frm.toggle_display("received_amount",
|
||||||
|
@ -456,17 +456,17 @@
|
|||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"depends_on": "paid_to",
|
"depends_on": "paid_to",
|
||||||
"fieldname": "paid_to_account_balance",
|
"fieldname": "paid_to_account_currency",
|
||||||
"fieldtype": "Currency",
|
"fieldtype": "Link",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
"ignore_user_permissions": 0,
|
"ignore_user_permissions": 0,
|
||||||
"ignore_xss_filter": 0,
|
"ignore_xss_filter": 0,
|
||||||
"in_filter": 0,
|
"in_filter": 0,
|
||||||
"in_list_view": 0,
|
"in_list_view": 0,
|
||||||
"label": "Account Balance",
|
"label": "Account Currency",
|
||||||
"length": 0,
|
"length": 0,
|
||||||
"no_copy": 0,
|
"no_copy": 0,
|
||||||
"options": "paid_to_account_currency",
|
"options": "Currency",
|
||||||
"permlevel": 0,
|
"permlevel": 0,
|
||||||
"precision": "",
|
"precision": "",
|
||||||
"print_hide": 1,
|
"print_hide": 1,
|
||||||
@ -483,17 +483,17 @@
|
|||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"depends_on": "paid_to",
|
"depends_on": "paid_to",
|
||||||
"fieldname": "paid_to_account_currency",
|
"fieldname": "paid_to_account_balance",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Currency",
|
||||||
"hidden": 1,
|
"hidden": 0,
|
||||||
"ignore_user_permissions": 0,
|
"ignore_user_permissions": 0,
|
||||||
"ignore_xss_filter": 0,
|
"ignore_xss_filter": 0,
|
||||||
"in_filter": 0,
|
"in_filter": 0,
|
||||||
"in_list_view": 0,
|
"in_list_view": 0,
|
||||||
"label": "Account Currency",
|
"label": "Account Balance",
|
||||||
"length": 0,
|
"length": 0,
|
||||||
"no_copy": 0,
|
"no_copy": 0,
|
||||||
"options": "Currency",
|
"options": "paid_to_account_currency",
|
||||||
"permlevel": 0,
|
"permlevel": 0,
|
||||||
"precision": "",
|
"precision": "",
|
||||||
"print_hide": 1,
|
"print_hide": 1,
|
||||||
@ -762,7 +762,7 @@
|
|||||||
"print_hide_if_no_value": 0,
|
"print_hide_if_no_value": 0,
|
||||||
"read_only": 0,
|
"read_only": 0,
|
||||||
"report_hide": 0,
|
"report_hide": 0,
|
||||||
"reqd": 1,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
@ -812,7 +812,7 @@
|
|||||||
"print_hide_if_no_value": 0,
|
"print_hide_if_no_value": 0,
|
||||||
"read_only": 0,
|
"read_only": 0,
|
||||||
"report_hide": 0,
|
"report_hide": 0,
|
||||||
"reqd": 1,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
@ -1372,7 +1372,7 @@
|
|||||||
"issingle": 0,
|
"issingle": 0,
|
||||||
"istable": 0,
|
"istable": 0,
|
||||||
"max_attachments": 0,
|
"max_attachments": 0,
|
||||||
"modified": "2016-06-28 12:45:59.162749",
|
"modified": "2016-06-29 17:30:20.840249",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Payment Entry",
|
"name": "Payment Entry",
|
||||||
|
@ -31,19 +31,20 @@ class PaymentEntry(AccountsController):
|
|||||||
self.party_account_field = "paid_to"
|
self.party_account_field = "paid_to"
|
||||||
self.party_account = self.paid_to
|
self.party_account = self.paid_to
|
||||||
self.party_account_currency = self.paid_to_account_currency
|
self.party_account_currency = self.paid_to_account_currency
|
||||||
|
|
||||||
print self.payment_type, self.party_account_field
|
|
||||||
|
|
||||||
def validate(self):
|
def validate(self):
|
||||||
self.setup_party_account_field()
|
self.setup_party_account_field()
|
||||||
self.set_missing_values()
|
self.set_missing_values()
|
||||||
self.validate_party_details()
|
self.validate_party_details()
|
||||||
self.validate_bank_accounts()
|
self.validate_bank_accounts()
|
||||||
self.set_exchange_rate()
|
self.set_exchange_rate()
|
||||||
|
self.validate_mandatory()
|
||||||
self.validate_reference_documents()
|
self.validate_reference_documents()
|
||||||
self.set_amounts()
|
self.set_amounts()
|
||||||
self.clear_unallocated_reference_document_rows()
|
self.clear_unallocated_reference_document_rows()
|
||||||
self.set_title()
|
self.set_title()
|
||||||
|
self.validate_transaction_reference()
|
||||||
|
|
||||||
|
|
||||||
def on_submit(self):
|
def on_submit(self):
|
||||||
self.make_gl_entries()
|
self.make_gl_entries()
|
||||||
@ -89,20 +90,30 @@ class PaymentEntry(AccountsController):
|
|||||||
self.party_account_currency = self.paid_from_account_currency \
|
self.party_account_currency = self.paid_from_account_currency \
|
||||||
if self.payment_type=="Receive" else self.paid_to_account_currency
|
if self.payment_type=="Receive" else self.paid_to_account_currency
|
||||||
|
|
||||||
|
self.set_missing_ref_details()
|
||||||
|
|
||||||
|
|
||||||
|
def set_missing_ref_details(self):
|
||||||
for d in self.get("references"):
|
for d in self.get("references"):
|
||||||
if d.allocated_amount and d.reference_doctype in ("Sales Invoice", "Purchase Invoice"):
|
if d.allocated_amount:
|
||||||
ref_doc = frappe.db.get_value(d.reference_doctype, d.reference_name, ["grand_total",
|
if d.reference_doctype != "Journal Entry":
|
||||||
"base_grand_total", "outstanding_amount", "conversion_rate", "due_date"], as_dict=1)
|
ref_doc = frappe.get_doc(d.reference_doctype, d.reference_name)
|
||||||
|
|
||||||
d.outstanding_amount = ref_doc.outstanding_amount
|
d.due_date = ref_doc.get("due_date")
|
||||||
d.due_date = ref_doc.due_date
|
|
||||||
|
|
||||||
if self.party_account_currency == self.company_currency:
|
if self.party_account_currency == self.company_currency:
|
||||||
d.total_amount = ref_doc.base_grand_total
|
d.total_amount = ref_doc.base_grand_total
|
||||||
d.exchange_rate = 1
|
d.exchange_rate = 1
|
||||||
else:
|
else:
|
||||||
d.total_amount = ref_doc.grand_total
|
d.total_amount = ref_doc.grand_total
|
||||||
d.exchange_rate = ref_doc.conversion_rate
|
d.exchange_rate = ref_doc.get("conversion_rate") or \
|
||||||
|
get_exchange_rate(self.party_account_currency, self.company_currency)
|
||||||
|
|
||||||
|
d.outstanding_amount = ref_doc.get("outstanding_amount") \
|
||||||
|
if d.reference_doctype in ("Sales Invoice", "Purchase Invoice") \
|
||||||
|
else flt(d.total_amount) - flt(ref_doc.advance_paid)
|
||||||
|
elif not d.exchange_rate:
|
||||||
|
d.exchange_rate = get_exchange_rate(self.party_account_currency, self.company_currency)
|
||||||
|
|
||||||
def validate_party_details(self):
|
def validate_party_details(self):
|
||||||
if self.party:
|
if self.party:
|
||||||
@ -139,6 +150,11 @@ class PaymentEntry(AccountsController):
|
|||||||
self.target_exchange_rate = get_exchange_rate(self.paid_to_account_currency,
|
self.target_exchange_rate = get_exchange_rate(self.paid_to_account_currency,
|
||||||
self.company_currency)
|
self.company_currency)
|
||||||
|
|
||||||
|
def validate_mandatory(self):
|
||||||
|
for field in ("paid_amount", "received_amount", "source_exchange_rate", "target_exchange_rate"):
|
||||||
|
if not self.get(field):
|
||||||
|
frappe.throw(_("{0} is mandatory").format(self.meta.get_label(field)))
|
||||||
|
|
||||||
def validate_reference_documents(self):
|
def validate_reference_documents(self):
|
||||||
if self.party_type == "Customer":
|
if self.party_type == "Customer":
|
||||||
valid_reference_doctypes = ("Sales Order", "Sales Invoice", "Journal Entry")
|
valid_reference_doctypes = ("Sales Order", "Sales Invoice", "Journal Entry")
|
||||||
@ -188,9 +204,11 @@ class PaymentEntry(AccountsController):
|
|||||||
self.total_allocated_amount, self.base_total_allocated_amount = 0, 0
|
self.total_allocated_amount, self.base_total_allocated_amount = 0, 0
|
||||||
for d in self.get("references"):
|
for d in self.get("references"):
|
||||||
if d.allocated_amount:
|
if d.allocated_amount:
|
||||||
if d.allocated_amount > d.outstanding_amount:
|
print d.allocated_amount, d.outstanding_amount
|
||||||
frappe.throw(_("Row #{0}: Allocated amount cannot be greater than outstanding amount")
|
if d.reference_doctype not in ("Sales Order", "Purchase Order") \
|
||||||
.format(d.idx))
|
and d.allocated_amount > d.outstanding_amount:
|
||||||
|
frappe.throw(_("Row #{0}: Allocated amount cannot be greater than outstanding amount")
|
||||||
|
.format(d.idx))
|
||||||
|
|
||||||
self.total_allocated_amount += flt(d.allocated_amount)
|
self.total_allocated_amount += flt(d.allocated_amount)
|
||||||
self.base_total_allocated_amount += flt(flt(d.allocated_amount) * flt(d.exchange_rate),
|
self.base_total_allocated_amount += flt(flt(d.allocated_amount) * flt(d.exchange_rate),
|
||||||
@ -232,6 +250,14 @@ class PaymentEntry(AccountsController):
|
|||||||
self.title = self.party
|
self.title = self.party
|
||||||
else:
|
else:
|
||||||
self.title = self.paid_from + " - " + self.paid_to
|
self.title = self.paid_from + " - " + self.paid_to
|
||||||
|
|
||||||
|
def validate_transaction_reference(self):
|
||||||
|
bank_account = self.paid_to if self.payment_type == "Receive" else self.paid_from
|
||||||
|
bank_account_type = frappe.db.get_value("Account", bank_account, "account_type")
|
||||||
|
|
||||||
|
if bank_account_type == "Bank":
|
||||||
|
if not self.reference_no or not self.reference_date:
|
||||||
|
frappe.throw(_("Reference No and Reference Date is mandatory for Bank transaction"))
|
||||||
|
|
||||||
def make_gl_entries(self, cancel=0, adv_adj=0):
|
def make_gl_entries(self, cancel=0, adv_adj=0):
|
||||||
gl_entries = []
|
gl_entries = []
|
||||||
@ -442,56 +468,85 @@ def get_company_defaults(company):
|
|||||||
return ret
|
return ret
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_payment_entry_against_invoice(dt, dn):
|
def get_payment_entry(dt, dn, party_amount=None, bank_account=None, bank_amount=None):
|
||||||
invoice = frappe.get_doc(dt, dn)
|
doc = frappe.get_doc(dt, dn)
|
||||||
|
|
||||||
|
if dt in ("Sales Order", "Purchase Order") and flt(doc.per_billed, 2) > 0:
|
||||||
|
frappe.throw(_("Can only make payment against unbilled {0}").format(dt))
|
||||||
|
|
||||||
|
party_type = "Customer" if dt in ("Sales Invoice", "Sales Order") else "Supplier"
|
||||||
|
|
||||||
|
# party account
|
||||||
if dt == "Sales Invoice":
|
if dt == "Sales Invoice":
|
||||||
party_type = "Customer"
|
party_account = doc.debit_to
|
||||||
party_account = invoice.debit_to
|
elif dt == "Purchase Invoice":
|
||||||
|
party_account = doc.credit_to
|
||||||
else:
|
else:
|
||||||
party_type = "Supplier"
|
party_account = get_party_account(party_type, doc.get(party_type.lower()), doc.company)
|
||||||
party_account = invoice.credit_to
|
|
||||||
|
party_account_currency = doc.get("party_account_currency") or get_account_currency(party_account)
|
||||||
|
|
||||||
if (dt=="Sales Invoice" and invoice.outstanding_amount > 0) \
|
# payment type
|
||||||
or (dt=="Purchase Invoice" and invoice.outstanding_amount < 0):
|
if (dt == "Sales Order" or (dt=="Sales Invoice" and doc.outstanding_amount > 0)) \
|
||||||
|
or (dt=="Purchase Invoice" and doc.outstanding_amount < 0):
|
||||||
payment_type = "Receive"
|
payment_type = "Receive"
|
||||||
else:
|
else:
|
||||||
payment_type = "Pay"
|
payment_type = "Pay"
|
||||||
|
|
||||||
bank = frappe._dict()
|
# amounts
|
||||||
if invoice.mode_of_payment:
|
grand_total = outstanding_amount = 0
|
||||||
bank = get_default_bank_cash_account(invoice.company, mode_of_payment=invoice.mode_of_payment)
|
if party_amount:
|
||||||
|
grand_total = outstanding_amount = party_amount
|
||||||
|
elif dt in ("Sales Invoice", "Purchase Invoice"):
|
||||||
|
grand_total = doc.grand_total
|
||||||
|
outstanding_amount = doc.outstanding_amount
|
||||||
|
else:
|
||||||
|
total_field = "base_grand_total" if party_account_currency == doc.company_currency else "grand_total"
|
||||||
|
grand_total = flt(doc.get(total_field))
|
||||||
|
outstanding_amount = grand_total - flt(doc.advance_paid)
|
||||||
|
|
||||||
|
# bank or cash
|
||||||
|
bank = get_default_bank_cash_account(doc.company, "Bank", mode_of_payment=doc.get("mode_of_payment"),
|
||||||
|
account=bank_account)
|
||||||
|
|
||||||
paid_amount = received_amount = 0
|
paid_amount = received_amount = 0
|
||||||
if invoice.party_account_currency == bank.account_currency:
|
if party_account_currency == bank.account_currency:
|
||||||
paid_amount = received_amount = invoice.outstanding_amount
|
paid_amount = received_amount = outstanding_amount
|
||||||
elif payment_type == "Receive":
|
elif payment_type == "Receive":
|
||||||
paid_amount = invoice.outstanding_amount
|
paid_amount = outstanding_amount
|
||||||
|
if bank_amount:
|
||||||
|
received_amount = bank_amount
|
||||||
else:
|
else:
|
||||||
received_amount = invoice.outstanding_amount
|
received_amount = outstanding_amount
|
||||||
|
if bank_amount:
|
||||||
|
paid_amount = bank_amount
|
||||||
|
|
||||||
pe = frappe.new_doc("Payment Entry")
|
pe = frappe.new_doc("Payment Entry")
|
||||||
pe.payment_type = payment_type
|
pe.payment_type = payment_type
|
||||||
pe.company = invoice.company
|
pe.company = doc.company
|
||||||
pe.posting_date = nowdate()
|
pe.posting_date = nowdate()
|
||||||
pe.mode_of_payment = invoice.mode_of_payment
|
pe.mode_of_payment = doc.get("mode_of_payment")
|
||||||
pe.party_type = party_type
|
pe.party_type = party_type
|
||||||
pe.party = invoice.get(scrub(party_type))
|
pe.party = doc.get(scrub(party_type))
|
||||||
pe.paid_from = party_account if payment_type=="Receive" else bank.account
|
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_to = party_account if payment_type=="Pay" else bank.account
|
||||||
|
pe.paid_from_account_currency = party_account_currency \
|
||||||
|
if payment_type=="Receive" else bank.account_currency
|
||||||
|
pe.paid_to_account_currency = party_account_currency if payment_type=="Pay" else bank.account_currency
|
||||||
pe.paid_amount = paid_amount
|
pe.paid_amount = paid_amount
|
||||||
pe.received_amount = received_amount
|
pe.received_amount = received_amount
|
||||||
|
|
||||||
pe.append("references", {
|
pe.append("references", {
|
||||||
"reference_doctype": dt,
|
"reference_doctype": dt,
|
||||||
"reference_name": dn,
|
"reference_name": dn,
|
||||||
"allocated_amount": invoice.outstanding_amount
|
"due_date": doc.get("due_date"),
|
||||||
|
"total_amount": grand_total,
|
||||||
|
"outstanding_amount": outstanding_amount,
|
||||||
|
"allocated_amount": outstanding_amount
|
||||||
})
|
})
|
||||||
|
|
||||||
pe.setup_party_account_field()
|
pe.setup_party_account_field()
|
||||||
pe.set_missing_values()
|
pe.set_missing_values()
|
||||||
pe.set_exchange_rate()
|
pe.set_exchange_rate()
|
||||||
pe.set_amounts()
|
pe.set_amounts()
|
||||||
|
|
||||||
return pe
|
return pe
|
@ -5,8 +5,50 @@ from __future__ import unicode_literals
|
|||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
import unittest
|
import unittest
|
||||||
|
from erpnext.accounts.doctype.sales_order.test_sales_order import make_sales_order
|
||||||
# test_records = frappe.get_test_records('Payment Entry')
|
from erpnext.accounts.doctype.payment_entry.payment_entry import make_payment_entry
|
||||||
|
|
||||||
class TestPaymentEntry(unittest.TestCase):
|
class TestPaymentEntry(unittest.TestCase):
|
||||||
pass
|
def test_payment_entry_against_order(self):
|
||||||
|
so = make_sales_order()
|
||||||
|
pe = make_payment_entry("Sales Order", so.name)
|
||||||
|
pe.paid_to = "_Test Bank - _TC"
|
||||||
|
pe.insert()
|
||||||
|
pe.submit()
|
||||||
|
|
||||||
|
expected_gle = {
|
||||||
|
"_Test Bank - _TC": {
|
||||||
|
"account_currency": "INR",
|
||||||
|
"debit": 1000,
|
||||||
|
"debit_in_account_currency": 1000,
|
||||||
|
"credit": 0,
|
||||||
|
"credit_in_account_currency": 0,
|
||||||
|
"against_voucher": None
|
||||||
|
},
|
||||||
|
"_Test Receivable - _TC": {
|
||||||
|
"account_currency": "INR",
|
||||||
|
"debit": 0,
|
||||||
|
"debit_in_account_currency": 0,
|
||||||
|
"credit": 1000,
|
||||||
|
"credit_in_account_currency": 1000,
|
||||||
|
"against_voucher": so.name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.validate_gl_entries(pe.name, expected_gle)
|
||||||
|
|
||||||
|
so.load_from_db()
|
||||||
|
|
||||||
|
def validate_gl_entries(self, voucher_no, expected_gle):
|
||||||
|
gl_entries = frappe.db.sql("""select account, account_currency, debit, credit,
|
||||||
|
debit_in_account_currency, credit_in_account_currency, against_voucher
|
||||||
|
from `tabGL Entry` where voucher_type='Payment Entry' and voucher_no=%s
|
||||||
|
order by account asc""", voucher_no, as_dict=1)
|
||||||
|
|
||||||
|
self.assertTrue(gl_entries)
|
||||||
|
|
||||||
|
for field in ("account_currency", "debit", "debit_in_account_currency",
|
||||||
|
"credit", "credit_in_account_currency"):
|
||||||
|
for i, gle in enumerate(gl_entries):
|
||||||
|
self.assertEquals(expected_gle[gle.account][field], gle[field])
|
||||||
|
|
||||||
|
@ -6,11 +6,11 @@ from __future__ import unicode_literals
|
|||||||
import frappe
|
import frappe
|
||||||
from frappe import _
|
from frappe import _
|
||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
from frappe.utils import flt, nowdate, get_url, cstr
|
from frappe.utils import flt, get_url, nowdate, getdate
|
||||||
from erpnext.accounts.party import get_party_account
|
from erpnext.accounts.party import get_party_account
|
||||||
from erpnext.accounts.utils import get_account_currency
|
from erpnext.accounts.utils import get_account_currency
|
||||||
from erpnext.accounts.doctype.journal_entry.journal_entry import (get_payment_entry_against_invoice,
|
from erpnext.setup.utils import get_exchange_rate
|
||||||
get_payment_entry_against_order)
|
from erpnext.accounts.doctype.payment_entry.payment_entry import get_payment_entry
|
||||||
|
|
||||||
class PaymentRequest(Document):
|
class PaymentRequest(Document):
|
||||||
def validate(self):
|
def validate(self):
|
||||||
@ -77,12 +77,12 @@ class PaymentRequest(Document):
|
|||||||
if frappe.session.user == "Guest":
|
if frappe.session.user == "Guest":
|
||||||
frappe.set_user("Administrator")
|
frappe.set_user("Administrator")
|
||||||
|
|
||||||
jv = self.create_journal_entry()
|
payment_entry = self.create_payment_entry()
|
||||||
self.make_invoice()
|
self.make_invoice()
|
||||||
|
|
||||||
return jv
|
return payment_entry
|
||||||
|
|
||||||
def create_journal_entry(self):
|
def create_payment_entry(self):
|
||||||
"""create entry"""
|
"""create entry"""
|
||||||
frappe.flags.ignore_account_permission = True
|
frappe.flags.ignore_account_permission = True
|
||||||
|
|
||||||
@ -90,42 +90,31 @@ class PaymentRequest(Document):
|
|||||||
|
|
||||||
party_account = get_party_account("Customer", ref_doc.get("customer"), ref_doc.company)
|
party_account = get_party_account("Customer", ref_doc.get("customer"), ref_doc.company)
|
||||||
party_account_currency = get_account_currency(party_account)
|
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=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=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)
|
bank_amount = self.grand_total
|
||||||
jv.submit()
|
if party_account_currency == ref_doc.company_currency and party_account_currency != self.currency:
|
||||||
|
party_amount = flt(flt(self.grand_total) *
|
||||||
|
get_exchange_rate(self.currency, party_account_currency),
|
||||||
|
ref_doc.precision("base_grand_total"))
|
||||||
|
else:
|
||||||
|
party_amount = self.grand_total
|
||||||
|
|
||||||
|
payment_entry = get_payment_entry(self.reference_doctype, self.reference_name,
|
||||||
|
party_amount=party_amount, bank_account=self.payment_account, bank_amount=bank_amount)
|
||||||
|
|
||||||
|
payment_entry.update({
|
||||||
|
"reference_no": self.name,
|
||||||
|
"reference_date": nowdate(),
|
||||||
|
"remarks": "Payment Entry against {0} {1} via Payment Request {2}".format(self.reference_doctype,
|
||||||
|
self.reference_name, self.name)
|
||||||
|
})
|
||||||
|
payment_entry.insert(ignore_permissions=True)
|
||||||
|
payment_entry.submit()
|
||||||
|
|
||||||
#set status as paid for Payment Request
|
#set status as paid for Payment Request
|
||||||
frappe.db.set_value(self.doctype, self.name, "status", "Paid")
|
frappe.db.set_value(self.doctype, self.name, "status", "Paid")
|
||||||
|
|
||||||
return jv
|
return payment_entry
|
||||||
|
|
||||||
def send_email(self):
|
def send_email(self):
|
||||||
"""send email with payment link"""
|
"""send email with payment link"""
|
||||||
@ -177,7 +166,7 @@ def make_payment_request(**args):
|
|||||||
grand_total = get_amount(ref_doc, args.dt)
|
grand_total = get_amount(ref_doc, args.dt)
|
||||||
|
|
||||||
existing_payment_request = frappe.db.get_value("Payment Request",
|
existing_payment_request = frappe.db.get_value("Payment Request",
|
||||||
{"reference_doctype": args.dt, "reference_name": args.dn})
|
{"reference_doctype": args.dt, "reference_name": args.dn, "docstatus": ["!=", 2]})
|
||||||
|
|
||||||
if existing_payment_request:
|
if existing_payment_request:
|
||||||
pr = frappe.get_doc("Payment Request", existing_payment_request)
|
pr = frappe.get_doc("Payment Request", existing_payment_request)
|
||||||
|
@ -471,9 +471,10 @@ def get_outstanding_invoices(party_type, party, account, condition=None):
|
|||||||
"party_type": party_type,
|
"party_type": party_type,
|
||||||
"party": party,
|
"party": party,
|
||||||
"account": account,
|
"account": account,
|
||||||
}, as_dict=True)
|
}, as_dict=True, debug=1)
|
||||||
|
|
||||||
for d in invoice_list:
|
for d in invoice_list:
|
||||||
|
print d.voucher_no, d.invoice_amount, d.payment_amount
|
||||||
outstanding_invoices.append(frappe._dict({
|
outstanding_invoices.append(frappe._dict({
|
||||||
'voucher_no': d.voucher_no,
|
'voucher_no': d.voucher_no,
|
||||||
'voucher_type': d.voucher_type,
|
'voucher_type': d.voucher_type,
|
||||||
|
@ -76,7 +76,7 @@ erpnext.buying.PurchaseOrderController = erpnext.buying.BuyingController.extend(
|
|||||||
this.make_purchase_invoice, __("Make"));
|
this.make_purchase_invoice, __("Make"));
|
||||||
|
|
||||||
if(flt(doc.per_billed)==0 && doc.status != "Delivered") {
|
if(flt(doc.per_billed)==0 && doc.status != "Delivered") {
|
||||||
cur_frm.add_custom_button(__('Payment'), cur_frm.cscript.make_bank_entry, __("Make"));
|
cur_frm.add_custom_button(__('Payment'), cur_frm.cscript.make_payment_entry, __("Make"));
|
||||||
}
|
}
|
||||||
cur_frm.page.set_inner_btn_group_as_primary(__("Make"));
|
cur_frm.page.set_inner_btn_group_as_primary(__("Make"));
|
||||||
|
|
||||||
@ -184,20 +184,6 @@ erpnext.buying.PurchaseOrderController = erpnext.buying.BuyingController.extend(
|
|||||||
this.frm.script_manager.copy_from_first_row("items", row, ["schedule_date"]);
|
this.frm.script_manager.copy_from_first_row("items", row, ["schedule_date"]);
|
||||||
},
|
},
|
||||||
|
|
||||||
make_bank_entry: function() {
|
|
||||||
return frappe.call({
|
|
||||||
method: "erpnext.accounts.doctype.journal_entry.journal_entry.get_payment_entry_against_order",
|
|
||||||
args: {
|
|
||||||
"dt": "Purchase Order",
|
|
||||||
"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);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
unclose_purchase_order: function(){
|
unclose_purchase_order: function(){
|
||||||
cur_frm.cscript.update_status('Re-open', 'Submitted')
|
cur_frm.cscript.update_status('Re-open', 'Submitted')
|
||||||
},
|
},
|
||||||
|
@ -462,11 +462,11 @@ class AccountsController(TransactionBase):
|
|||||||
formatted_order_total = fmt_money(order_total, precision=self.precision("base_grand_total"),
|
formatted_order_total = fmt_money(order_total, precision=self.precision("base_grand_total"),
|
||||||
currency=advance.account_currency)
|
currency=advance.account_currency)
|
||||||
|
|
||||||
if order_total >= advance_paid:
|
if self.currency == self.company_currency:
|
||||||
frappe.db.set_value(self.doctype, self.name, "advance_paid", advance_paid)
|
|
||||||
else:
|
|
||||||
frappe.throw(_("Total advance ({0}) against Order {1} cannot be greater than the Grand Total ({2})")
|
frappe.throw(_("Total advance ({0}) against Order {1} cannot be greater than the Grand Total ({2})")
|
||||||
.format(formatted_advance_paid, self.name, formatted_order_total))
|
.format(formatted_advance_paid, self.name, formatted_order_total))
|
||||||
|
|
||||||
|
frappe.db.set_value(self.doctype, self.name, "advance_paid", advance_paid)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def company_abbr(self):
|
def company_abbr(self):
|
||||||
|
@ -10,7 +10,7 @@ erpnext.hr.ExpenseClaimController = frappe.ui.form.Controller.extend({
|
|||||||
method: "erpnext.accounts.doctype.journal_entry.journal_entry.get_default_bank_cash_account",
|
method: "erpnext.accounts.doctype.journal_entry.journal_entry.get_default_bank_cash_account",
|
||||||
args: {
|
args: {
|
||||||
"company": cur_frm.doc.company,
|
"company": cur_frm.doc.company,
|
||||||
"voucher_type": "Bank Entry"
|
"account_type": "Bank"
|
||||||
},
|
},
|
||||||
callback: function(r) {
|
callback: function(r) {
|
||||||
var jv = frappe.model.make_new_doc_and_get_name('Journal Entry');
|
var jv = frappe.model.make_new_doc_and_get_name('Journal Entry');
|
||||||
|
15
erpnext/patches/v7_0/rename_advance_table_fields.py
Normal file
15
erpnext/patches/v7_0/rename_advance_table_fields.py
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
|
||||||
|
# License: GNU General Public License v3. See license.txt
|
||||||
|
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
import frappe
|
||||||
|
from frappe.model.utils.rename_field import rename_field
|
||||||
|
|
||||||
|
def execute():
|
||||||
|
for dt in ("Sales Invoice Advance", "Purchase Invoice Advance"):
|
||||||
|
frappe.reload_doctype(dt)
|
||||||
|
|
||||||
|
frappe.db.sql("update `tab{0}` set reference_type = 'Journal Entry'".format(dt))
|
||||||
|
|
||||||
|
rename_field(dt, "journal_entry", "reference_name")
|
||||||
|
rename_field(dt, "jv_detail_no", "reference_row")
|
@ -169,7 +169,6 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
|
|||||||
this.show_item_wise_taxes();
|
this.show_item_wise_taxes();
|
||||||
this.set_dynamic_labels();
|
this.set_dynamic_labels();
|
||||||
this.setup_sms();
|
this.setup_sms();
|
||||||
this.make_show_payments_btn();
|
|
||||||
},
|
},
|
||||||
|
|
||||||
apply_default_taxes: function() {
|
apply_default_taxes: function() {
|
||||||
@ -205,22 +204,6 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
|
|||||||
var sms_man = new SMSManager(this.frm.doc);
|
var sms_man = new SMSManager(this.frm.doc);
|
||||||
},
|
},
|
||||||
|
|
||||||
make_show_payments_btn: function() {
|
|
||||||
var me = this;
|
|
||||||
if (in_list(["Purchase Invoice", "Sales Invoice"], this.frm.doctype)) {
|
|
||||||
if(this.frm.doc.outstanding_amount !== this.frm.doc.base_grand_total) {
|
|
||||||
this.frm.add_custom_button(__("Payments"), function() {
|
|
||||||
frappe.route_options = {
|
|
||||||
"Journal Entry Account.reference_type": me.frm.doc.doctype,
|
|
||||||
"Journal Entry Account.reference_name": me.frm.doc.name
|
|
||||||
};
|
|
||||||
|
|
||||||
frappe.set_route("List", "Journal Entry");
|
|
||||||
}, __("View"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
barcode: function(doc, cdt, cdn) {
|
barcode: function(doc, cdt, cdn) {
|
||||||
var d = locals[cdt][cdn];
|
var d = locals[cdt][cdn];
|
||||||
if(d.barcode=="" || d.barcode==null) {
|
if(d.barcode=="" || d.barcode==null) {
|
||||||
@ -1004,7 +987,7 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
|
|||||||
|
|
||||||
make_payment_entry: function() {
|
make_payment_entry: function() {
|
||||||
return frappe.call({
|
return frappe.call({
|
||||||
method: "erpnext.accounts.doctype.payment_entry.payment_entry.get_payment_entry_against_invoice",
|
method: "erpnext.accounts.doctype.payment_entry.payment_entry.get_payment_entry",
|
||||||
args: {
|
args: {
|
||||||
"dt": cur_frm.doc.doctype,
|
"dt": cur_frm.doc.doctype,
|
||||||
"dn": cur_frm.doc.name
|
"dn": cur_frm.doc.name
|
||||||
|
@ -76,11 +76,12 @@ erpnext.selling.SalesOrderController = erpnext.selling.SellingController.extend(
|
|||||||
|
|
||||||
if(flt(doc.per_billed)==0) {
|
if(flt(doc.per_billed)==0) {
|
||||||
cur_frm.add_custom_button(__('Payment Request'), this.make_payment_request, __("Make"));
|
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'), cur_frm.cscript.make_payment_entry, __("Make"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// maintenance
|
// maintenance
|
||||||
if(flt(doc.per_delivered, 2) < 100 && ["Sales", "Shopping Cart"].indexOf(doc.order_type)===-1) {
|
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 Visit'), this.make_maintenance_visit, __("Make"));
|
||||||
cur_frm.add_custom_button(__('Maintenance Schedule'), this.make_maintenance_schedule, __("Make"));
|
cur_frm.add_custom_button(__('Maintenance Schedule'), this.make_maintenance_schedule, __("Make"));
|
||||||
}
|
}
|
||||||
@ -157,19 +158,6 @@ erpnext.selling.SalesOrderController = erpnext.selling.SellingController.extend(
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
make_bank_entry: function() {
|
|
||||||
return frappe.call({
|
|
||||||
method: "erpnext.accounts.doctype.journal_entry.journal_entry.get_payment_entry_against_order",
|
|
||||||
args: {
|
|
||||||
"dt": "Sales Order",
|
|
||||||
"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);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
make_purchase_order: function(){
|
make_purchase_order: function(){
|
||||||
var dialog = new frappe.ui.Dialog({
|
var dialog = new frappe.ui.Dialog({
|
||||||
title: __("For Supplier"),
|
title: __("For Supplier"),
|
||||||
|
Loading…
Reference in New Issue
Block a user