Update outstanding amt based on party
Party mandatory if account is receivable/payable Fetch advance based on party Reconciliation splitting logic based on party
This commit is contained in:
parent
cc582bd774
commit
3225102eb9
@ -27,7 +27,7 @@ class GLEntry(Document):
|
||||
# Update outstanding amt on against voucher
|
||||
if self.against_voucher_type in ['Journal Voucher', 'Sales Invoice', 'Purchase Invoice'] \
|
||||
and self.against_voucher and update_outstanding == 'Yes':
|
||||
update_outstanding_amt(self.account, self.against_voucher_type,
|
||||
update_outstanding_amt(self.account, self.party_type, self.party, self.against_voucher_type,
|
||||
self.against_voucher)
|
||||
|
||||
def check_mandatory(self):
|
||||
@ -36,6 +36,10 @@ class GLEntry(Document):
|
||||
if not self.get(k):
|
||||
frappe.throw(_("{0} is required").format(self.meta.get_label(k)))
|
||||
|
||||
account_type = frappe.db.get_value("Account", self.account, "account_type")
|
||||
if account_type in ["Receivable", "Payable"] and not (self.party_type and self.party):
|
||||
frappe.throw(_("Party Type and Party is required for Receivable / Payable account {0}").format(self.account))
|
||||
|
||||
# Zero value transaction is not allowed
|
||||
if not (flt(self.debit) or flt(self.credit)):
|
||||
frappe.throw(_("Either debit or credit amount is required for {0}").format(self.account))
|
||||
@ -109,12 +113,13 @@ def check_freezing_date(posting_date, adv_adj=False):
|
||||
and not frozen_accounts_modifier in frappe.user.get_roles():
|
||||
frappe.throw(_("You are not authorized to add or update entries before {0}").format(formatdate(acc_frozen_upto)))
|
||||
|
||||
def update_outstanding_amt(account, against_voucher_type, against_voucher, on_cancel=False):
|
||||
def update_outstanding_amt(account, party_type, party, against_voucher_type, against_voucher, on_cancel=False):
|
||||
# get final outstanding amt
|
||||
bal = flt(frappe.db.sql("""select sum(ifnull(debit, 0)) - sum(ifnull(credit, 0))
|
||||
from `tabGL Entry`
|
||||
where against_voucher_type=%s and against_voucher=%s and account = %s""",
|
||||
(against_voucher_type, against_voucher, account))[0][0] or 0.0)
|
||||
where against_voucher_type=%s and against_voucher=%s
|
||||
and account = %s and party_type=%s and party=%s""",
|
||||
(against_voucher_type, against_voucher, account, party_type, party))[0][0] or 0.0)
|
||||
|
||||
if against_voucher_type == 'Purchase Invoice':
|
||||
bal = -bal
|
||||
@ -122,8 +127,8 @@ def update_outstanding_amt(account, against_voucher_type, against_voucher, on_ca
|
||||
against_voucher_amount = flt(frappe.db.sql("""
|
||||
select sum(ifnull(debit, 0)) - sum(ifnull(credit, 0))
|
||||
from `tabGL Entry` where voucher_type = 'Journal Voucher' and voucher_no = %s
|
||||
and account = %s and ifnull(against_voucher, '') = ''""",
|
||||
(against_voucher, account))[0][0])
|
||||
and account = %s and party_type=%s and party=%s and ifnull(against_voucher, '') = ''""",
|
||||
(against_voucher, account, party_type, party))[0][0])
|
||||
bal = against_voucher_amount + bal
|
||||
if against_voucher_amount < 0:
|
||||
bal = -bal
|
||||
|
@ -21,7 +21,7 @@ class JournalVoucher(AccountsController):
|
||||
self.clearance_date = None
|
||||
|
||||
super(JournalVoucher, self).validate_date_with_fiscal_year()
|
||||
|
||||
self.validate_party()
|
||||
self.validate_cheque_info()
|
||||
self.validate_entries_for_advance()
|
||||
self.validate_debit_and_credit()
|
||||
@ -61,6 +61,13 @@ class JournalVoucher(AccountsController):
|
||||
self.make_gl_entries(1)
|
||||
self.update_advance_paid()
|
||||
|
||||
def validate_party(self):
|
||||
for d in self.get("entries"):
|
||||
account_type = frappe.db.get_value("Account", d.account, "account_type")
|
||||
if account_type in ["Receivable", "Payable"] and not (d.party_type and d.party):
|
||||
frappe.throw(_("Row{0}: Party Type and Party is required for Receivable / Payable account {1}").format(d.idx, d.account))
|
||||
|
||||
|
||||
def check_credit_limit(self):
|
||||
customers = list(set([d.party for d in self.get("entries") if d.party_type=="Customer"]))
|
||||
if customers:
|
||||
@ -247,6 +254,7 @@ class JournalVoucher(AccountsController):
|
||||
for d in self.get('entries'):
|
||||
if d.against_invoice and d.credit:
|
||||
currency = frappe.db.get_value("Sales Invoice", d.against_invoice, "currency")
|
||||
|
||||
r.append(_("{0} against Sales Invoice {1}").format(fmt_money(flt(d.credit), currency = currency), \
|
||||
d.against_invoice))
|
||||
|
||||
@ -260,7 +268,7 @@ class JournalVoucher(AccountsController):
|
||||
from `tabPurchase Invoice` where name=%s""", d.against_voucher)
|
||||
if bill_no and bill_no[0][0] and bill_no[0][0].lower().strip() \
|
||||
not in ['na', 'not applicable', 'none']:
|
||||
r.append(_('{0} against Bill {1} dated {2}').format(fmt_money(flt(d.debit), bill_no[0][2]), bill_no[0][0],
|
||||
r.append(_('{0} against Bill {1} dated {2}').format(fmt_money(flt(d.debit), currency=bill_no[0][2]), bill_no[0][0],
|
||||
bill_no[0][1] and formatdate(bill_no[0][1].strftime('%Y-%m-%d'))))
|
||||
|
||||
if d.against_purchase_order and d.debit:
|
||||
@ -294,7 +302,7 @@ class JournalVoucher(AccountsController):
|
||||
self.pay_to_recd_from = frappe.db.get_value(d.party_type, d.party,
|
||||
"customer_name" if d.party_type=="Customer" else "supplier_name")
|
||||
elif frappe.db.get_value("Account", d.account, "account_type") in ["Bank", "Cash"]:
|
||||
self.total_amount = fmt_money(d.debit or d.credit, currency)
|
||||
self.total_amount = fmt_money(d.debit or d.credit, currency=currency)
|
||||
self.total_amount_in_words = money_in_words(self.total_amount, currency)
|
||||
|
||||
def make_gl_entries(self, cancel=0, adv_adj=0):
|
||||
|
@ -3,9 +3,7 @@
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
|
||||
|
||||
from frappe.utils import cint, cstr, formatdate, flt
|
||||
from frappe.utils import cint, formatdate, flt
|
||||
from frappe import msgprint, _, throw
|
||||
from erpnext.setup.utils import get_company_currency
|
||||
import frappe.defaults
|
||||
@ -76,7 +74,7 @@ class PurchaseInvoice(BuyingController):
|
||||
super(PurchaseInvoice, self).set_missing_values(for_validate)
|
||||
|
||||
def get_advances(self):
|
||||
super(PurchaseInvoice, self).get_advances(self.credit_to,
|
||||
super(PurchaseInvoice, self).get_advances(self.credit_to, "Supplier", self.supplier,
|
||||
"Purchase Invoice Advance", "advance_allocation_details", "debit", "purchase_order")
|
||||
|
||||
def check_active_purchase_items(self):
|
||||
@ -226,6 +224,8 @@ class PurchaseInvoice(BuyingController):
|
||||
'against_voucher_type' : 'Purchase Invoice',
|
||||
'against_voucher' : self.name,
|
||||
'account' : self.credit_to,
|
||||
'party_type': 'Supplier',
|
||||
'party': self.supplier,
|
||||
'is_advance' : 'Yes',
|
||||
'dr_or_cr' : 'debit',
|
||||
'unadjusted_amt' : flt(d.advance_amount),
|
||||
|
@ -202,7 +202,7 @@ class SalesInvoice(SellingController):
|
||||
self.set_taxes("other_charges", "taxes_and_charges")
|
||||
|
||||
def get_advances(self):
|
||||
super(SalesInvoice, self).get_advances(self.debit_to,
|
||||
super(SalesInvoice, self).get_advances(self.debit_to, "Customer", self.customer,
|
||||
"Sales Invoice Advance", "advance_adjustment_details", "credit", "sales_order")
|
||||
|
||||
def get_company_abbr(self):
|
||||
@ -225,6 +225,8 @@ class SalesInvoice(SellingController):
|
||||
'against_voucher_type' : 'Sales Invoice',
|
||||
'against_voucher' : self.name,
|
||||
'account' : self.debit_to,
|
||||
'party_type': 'Customer',
|
||||
'party': self.customer,
|
||||
'is_advance' : 'Yes',
|
||||
'dr_or_cr' : 'credit',
|
||||
'unadjusted_amt' : flt(d.advance_amount),
|
||||
@ -455,7 +457,7 @@ class SalesInvoice(SellingController):
|
||||
|
||||
if update_outstanding == "No":
|
||||
from erpnext.accounts.doctype.gl_entry.gl_entry import update_outstanding_amt
|
||||
update_outstanding_amt(self.debit_to, self.doctype, self.name)
|
||||
update_outstanding_amt(self.debit_to, "Customer", self.customer, self.doctype, self.name)
|
||||
|
||||
if repost_future_gle and cint(self.update_stock) \
|
||||
and cint(frappe.defaults.get_global_default("auto_accounting_for_stock")):
|
||||
|
@ -122,5 +122,5 @@ def delete_gl_entries(gl_entries=None, voucher_type=None, voucher_no=None,
|
||||
validate_expense_against_budget(entry)
|
||||
|
||||
if entry.get("against_voucher") and update_outstanding == 'Yes':
|
||||
update_outstanding_amt(entry["account"], entry.get("against_voucher_type"),
|
||||
update_outstanding_amt(entry["account"], entry.get("party_type"), entry.get("party"), entry.get("against_voucher_type"),
|
||||
entry.get("against_voucher"), on_cancel=True)
|
||||
|
@ -152,6 +152,7 @@ def check_if_jv_modified(args):
|
||||
ret = frappe.db.sql("""
|
||||
select t2.{dr_or_cr} from `tabJournal Voucher` t1, `tabJournal Voucher Detail` t2
|
||||
where t1.name = t2.parent and t2.account = %(account)s
|
||||
and t2.party_type = %(party_type)s and t2.party = %(party)s
|
||||
and ifnull(t2.against_voucher, '')=''
|
||||
and ifnull(t2.against_invoice, '')='' and ifnull(t2.against_jv, '')=''
|
||||
and t1.name = %(voucher_no)s and t2.name = %(voucher_detail_no)s
|
||||
@ -180,6 +181,8 @@ def update_against_doc(d, jv_obj):
|
||||
# new entry with balance amount
|
||||
ch = jv_obj.append("entries")
|
||||
ch.account = d['account']
|
||||
ch.party_type = d["party_type"]
|
||||
ch.party = d["party"]
|
||||
ch.cost_center = cstr(jvd[0][0])
|
||||
ch.balance = flt(jvd[0][1])
|
||||
ch.set(d['dr_or_cr'], flt(d['unadjusted_amt']) - flt(d['allocated_amt']))
|
||||
|
@ -364,6 +364,8 @@ class AccountsController(TransactionBase):
|
||||
'debit': 0,
|
||||
'credit': 0,
|
||||
'is_opening': self.get("is_opening") or "No",
|
||||
'party_type': None,
|
||||
'party': None
|
||||
})
|
||||
gl_dict.update(args)
|
||||
return gl_dict
|
||||
@ -374,7 +376,7 @@ class AccountsController(TransactionBase):
|
||||
frappe.db.sql("""delete from `tab%s` where parentfield=%s and parent = %s
|
||||
and ifnull(allocated_amount, 0) = 0""" % (childtype, '%s', '%s'), (parentfield, self.name))
|
||||
|
||||
def get_advances(self, account_head, child_doctype, parentfield, dr_or_cr, against_order_field):
|
||||
def get_advances(self, account_head, party_type, party, child_doctype, parentfield, dr_or_cr, against_order_field):
|
||||
so_list = list(set([d.get(against_order_field) for d in self.get("entries") if d.get(against_order_field)]))
|
||||
cond = ""
|
||||
if so_list:
|
||||
@ -386,17 +388,18 @@ class AccountsController(TransactionBase):
|
||||
from
|
||||
`tabJournal Voucher` t1, `tabJournal Voucher Detail` t2
|
||||
where
|
||||
t1.name = t2.parent and t2.account = %s and t2.is_advance = 'Yes' and t1.docstatus = 1
|
||||
t1.name = t2.parent and t2.account = %s
|
||||
and t2.party_type=%s and t2.party=%s
|
||||
and t2.is_advance = 'Yes' and t1.docstatus = 1
|
||||
and ((
|
||||
ifnull(t2.against_voucher, '') = ''
|
||||
and ifnull(t2.against_invoice, '') = ''
|
||||
and ifnull(t2.against_jv, '') = ''
|
||||
and ifnull(t2.against_sales_order, '') = ''
|
||||
and ifnull(t2.against_purchase_order, '') = ''
|
||||
) %s)
|
||||
) %s)
|
||||
order by t1.posting_date""" %
|
||||
(dr_or_cr, '%s', cond),
|
||||
tuple([account_head] + so_list), as_dict= True)
|
||||
(dr_or_cr, '%s', '%s', '%s', cond), tuple([account_head, party_type, party] + so_list), as_dict=1)
|
||||
|
||||
self.set(parentfield, [])
|
||||
for d in res:
|
||||
|
Loading…
x
Reference in New Issue
Block a user