Merge pull request #2212 from nabinhait/hotfix
Fetch and validate advance entries in sales/purchase invoice
This commit is contained in:
commit
6a92d51383
@ -49,6 +49,7 @@ class PurchaseInvoice(BuyingController):
|
|||||||
self.check_conversion_rate()
|
self.check_conversion_rate()
|
||||||
self.validate_credit_acc()
|
self.validate_credit_acc()
|
||||||
self.clear_unallocated_advances("Purchase Invoice Advance", "advance_allocation_details")
|
self.clear_unallocated_advances("Purchase Invoice Advance", "advance_allocation_details")
|
||||||
|
self.validate_advance_jv("advance_allocation_details", "purchase_order")
|
||||||
self.check_for_acc_head_of_supplier()
|
self.check_for_acc_head_of_supplier()
|
||||||
self.check_for_stopped_status()
|
self.check_for_stopped_status()
|
||||||
self.validate_with_previous_doc()
|
self.validate_with_previous_doc()
|
||||||
@ -80,7 +81,7 @@ class PurchaseInvoice(BuyingController):
|
|||||||
|
|
||||||
def get_advances(self):
|
def get_advances(self):
|
||||||
super(PurchaseInvoice, self).get_advances(self.credit_to,
|
super(PurchaseInvoice, self).get_advances(self.credit_to,
|
||||||
"Purchase Invoice Advance", "advance_allocation_details", "debit")
|
"Purchase Invoice Advance", "advance_allocation_details", "debit", "purchase_order")
|
||||||
|
|
||||||
def check_active_purchase_items(self):
|
def check_active_purchase_items(self):
|
||||||
for d in self.get('entries'):
|
for d in self.get('entries'):
|
||||||
|
@ -56,6 +56,7 @@ class SalesInvoice(SellingController):
|
|||||||
self.validate_debit_acc()
|
self.validate_debit_acc()
|
||||||
self.validate_fixed_asset_account()
|
self.validate_fixed_asset_account()
|
||||||
self.clear_unallocated_advances("Sales Invoice Advance", "advance_adjustment_details")
|
self.clear_unallocated_advances("Sales Invoice Advance", "advance_adjustment_details")
|
||||||
|
self.validate_advance_jv("advance_adjustment_details", "sales_order")
|
||||||
self.add_remarks()
|
self.add_remarks()
|
||||||
|
|
||||||
if cint(self.is_pos):
|
if cint(self.is_pos):
|
||||||
@ -222,7 +223,7 @@ class SalesInvoice(SellingController):
|
|||||||
|
|
||||||
def get_advances(self):
|
def get_advances(self):
|
||||||
super(SalesInvoice, self).get_advances(self.debit_to,
|
super(SalesInvoice, self).get_advances(self.debit_to,
|
||||||
"Sales Invoice Advance", "advance_adjustment_details", "credit")
|
"Sales Invoice Advance", "advance_adjustment_details", "credit", "sales_order")
|
||||||
|
|
||||||
def get_company_abbr(self):
|
def get_company_abbr(self):
|
||||||
return frappe.db.sql("select abbr from tabCompany where name=%s", self.company)[0][0]
|
return frappe.db.sql("select abbr from tabCompany where name=%s", self.company)[0][0]
|
||||||
|
@ -4,9 +4,7 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
import frappe
|
import frappe
|
||||||
from frappe import _, throw
|
from frappe import _, throw
|
||||||
from frappe.utils import add_days, cint, cstr, today, date_diff, flt, getdate, nowdate, \
|
from frappe.utils import cint, today, flt
|
||||||
get_first_day, get_last_day
|
|
||||||
from frappe.model.naming import make_autoname
|
|
||||||
from erpnext.setup.utils import get_company_currency, get_exchange_rate
|
from erpnext.setup.utils import get_company_currency, get_exchange_rate
|
||||||
from erpnext.accounts.utils import get_fiscal_year, validate_fiscal_year
|
from erpnext.accounts.utils import get_fiscal_year, validate_fiscal_year
|
||||||
from erpnext.utilities.transaction_base import TransactionBase
|
from erpnext.utilities.transaction_base import TransactionBase
|
||||||
@ -362,30 +360,32 @@ class AccountsController(TransactionBase):
|
|||||||
frappe.db.sql("""delete from `tab%s` where parentfield=%s and parent = %s
|
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))
|
and ifnull(allocated_amount, 0) = 0""" % (childtype, '%s', '%s'), (parentfield, self.name))
|
||||||
|
|
||||||
def get_advances(self, account_head, child_doctype, parentfield, dr_or_cr):
|
def get_advances(self, account_head, child_doctype, parentfield, dr_or_cr, against_order_field):
|
||||||
against_order_list = []
|
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:
|
||||||
|
cond = "or (ifnull(t2.%s, '') in (%s))" % ("against_" + against_order_field, ', '.join(['%s']*len(so_list)))
|
||||||
|
|
||||||
res = frappe.db.sql("""
|
res = frappe.db.sql("""
|
||||||
select
|
select
|
||||||
t1.name as jv_no, t1.remark, t2.%s as amount, t2.name as jv_detail_no, t2.%s as order_no
|
t1.name as jv_no, t1.remark, t2.%s as amount, t2.name as jv_detail_no
|
||||||
from
|
from
|
||||||
`tabJournal Voucher` t1, `tabJournal Voucher Detail` t2
|
`tabJournal Voucher` t1, `tabJournal Voucher Detail` t2
|
||||||
where
|
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.is_advance = 'Yes' and t1.docstatus = 1
|
||||||
and ifnull(t2.against_voucher, '') = ''
|
and ((
|
||||||
|
ifnull(t2.against_voucher, '') = ''
|
||||||
and ifnull(t2.against_invoice, '') = ''
|
and ifnull(t2.against_invoice, '') = ''
|
||||||
and ifnull(t2.against_jv, '') = ''
|
and ifnull(t2.against_jv, '') = ''
|
||||||
|
and ifnull(t2.against_sales_order, '') = ''
|
||||||
|
and ifnull(t2.against_purchase_order, '') = ''
|
||||||
|
) %s)
|
||||||
order by t1.posting_date""" %
|
order by t1.posting_date""" %
|
||||||
(dr_or_cr, "against_sales_order" if dr_or_cr == "credit" \
|
(dr_or_cr, '%s', cond),
|
||||||
else "against_purchase_order", '%s'),
|
tuple([account_head] + so_list), as_dict= True)
|
||||||
account_head, as_dict= True)
|
|
||||||
|
|
||||||
if self.get("entries"):
|
|
||||||
for i in self.get("entries"):
|
|
||||||
against_order_list.append(i.sales_order if dr_or_cr == "credit" else i.purchase_order)
|
|
||||||
|
|
||||||
self.set(parentfield, [])
|
self.set(parentfield, [])
|
||||||
for d in res:
|
for d in res:
|
||||||
if not against_order_list or d.order_no in against_order_list:
|
|
||||||
self.append(parentfield, {
|
self.append(parentfield, {
|
||||||
"doctype": child_doctype,
|
"doctype": child_doctype,
|
||||||
"journal_voucher": d.jv_no,
|
"journal_voucher": d.jv_no,
|
||||||
@ -395,6 +395,33 @@ class AccountsController(TransactionBase):
|
|||||||
"allocate_amount": 0
|
"allocate_amount": 0
|
||||||
})
|
})
|
||||||
|
|
||||||
|
def validate_advance_jv(self, advance_table_fieldname, against_order_field):
|
||||||
|
order_list = list(set([d.get(against_order_field) for d in self.get("entries") if d.get(against_order_field)]))
|
||||||
|
if order_list:
|
||||||
|
account = self.get("debit_to" if self.doctype=="Sales Invoice" else "credit_to")
|
||||||
|
|
||||||
|
jv_against_order = frappe.db.sql("""select parent, %s as against_order
|
||||||
|
from `tabJournal Voucher Detail`
|
||||||
|
where docstatus=1 and account=%s and ifnull(is_advance, 'No') = 'Yes'
|
||||||
|
and ifnull(against_sales_order, '') in (%s)
|
||||||
|
group by parent, against_sales_order""" %
|
||||||
|
("against_" + against_order_field, '%s', ', '.join(['%s']*len(order_list))),
|
||||||
|
tuple([account] + order_list), as_dict=1)
|
||||||
|
|
||||||
|
if jv_against_order:
|
||||||
|
order_jv_map = {}
|
||||||
|
for d in jv_against_order:
|
||||||
|
order_jv_map.setdefault(d.against_order, []).append(d.parent)
|
||||||
|
|
||||||
|
advance_jv_against_si = [d.journal_voucher for d in self.get(advance_table_fieldname)]
|
||||||
|
|
||||||
|
for order, jv_list in order_jv_map.items():
|
||||||
|
for jv in jv_list:
|
||||||
|
if not advance_jv_against_si or jv not in advance_jv_against_si:
|
||||||
|
frappe.throw(_("Journal Voucher {0} is linked against Order {1}, hence it must be fetched as advance in Invoice as well.")
|
||||||
|
.format(jv, order))
|
||||||
|
|
||||||
|
|
||||||
def validate_multiple_billing(self, ref_dt, item_ref_dn, based_on, parentfield):
|
def validate_multiple_billing(self, ref_dt, item_ref_dn, based_on, parentfield):
|
||||||
from erpnext.controllers.status_updater import get_tolerance_for
|
from erpnext.controllers.status_updater import get_tolerance_for
|
||||||
item_tolerance = {}
|
item_tolerance = {}
|
||||||
@ -421,7 +448,6 @@ class AccountsController(TransactionBase):
|
|||||||
max_allowed_amt = flt(ref_amt * (100 + tolerance) / 100)
|
max_allowed_amt = flt(ref_amt * (100 + tolerance) / 100)
|
||||||
|
|
||||||
if total_billed_amt - max_allowed_amt > 0.01:
|
if total_billed_amt - max_allowed_amt > 0.01:
|
||||||
reduce_by = total_billed_amt - max_allowed_amt
|
|
||||||
frappe.throw(_("Cannot overbill for Item {0} in row {0} more than {1}. To allow overbilling, please set in Stock Settings").format(item.item_code, item.idx, max_allowed_amt))
|
frappe.throw(_("Cannot overbill for Item {0} in row {0} more than {1}. To allow overbilling, please set in Stock Settings").format(item.item_code, item.idx, max_allowed_amt))
|
||||||
|
|
||||||
def get_company_default(self, fieldname):
|
def get_company_default(self, fieldname):
|
||||||
|
@ -6,7 +6,7 @@ frappe.views.calendar["Task"] = {
|
|||||||
"start": "exp_start_date",
|
"start": "exp_start_date",
|
||||||
"end": "exp_end_date",
|
"end": "exp_end_date",
|
||||||
"id": "name",
|
"id": "name",
|
||||||
"title": __("subject"),
|
"title": "subject",
|
||||||
"allDay": "allDay"
|
"allDay": "allDay"
|
||||||
},
|
},
|
||||||
gantt: true,
|
gantt: true,
|
||||||
|
@ -40,7 +40,7 @@ class AuthorizationControl(TransactionBase):
|
|||||||
chk = 1
|
chk = 1
|
||||||
add_cond1,add_cond2 = '',''
|
add_cond1,add_cond2 = '',''
|
||||||
if based_on == 'Itemwise Discount':
|
if based_on == 'Itemwise Discount':
|
||||||
add_cond1 += " and master_name = '"+cstr(item).replace("'", "\'")+"'"
|
add_cond1 += " and master_name = '"+cstr(item).replace("'", "\\'")+"'"
|
||||||
itemwise_exists = frappe.db.sql("""select value from `tabAuthorization Rule`
|
itemwise_exists = frappe.db.sql("""select value from `tabAuthorization Rule`
|
||||||
where transaction = %s and value <= %s
|
where transaction = %s and value <= %s
|
||||||
and based_on = %s and company = %s and docstatus != 2 %s %s""" %
|
and based_on = %s and company = %s and docstatus != 2 %s %s""" %
|
||||||
@ -76,7 +76,7 @@ class AuthorizationControl(TransactionBase):
|
|||||||
add_cond = ''
|
add_cond = ''
|
||||||
auth_value = av_dis
|
auth_value = av_dis
|
||||||
|
|
||||||
if val == 1: add_cond += " and system_user = '"+session['user'].replace("'", "\'")+"'"
|
if val == 1: add_cond += " and system_user = '"+session['user'].replace("'", "\\'")+"'"
|
||||||
elif val == 2: add_cond += " and system_role IN %s" % ("('"+"','".join(frappe.user.get_roles())+"')")
|
elif val == 2: add_cond += " and system_role IN %s" % ("('"+"','".join(frappe.user.get_roles())+"')")
|
||||||
else: add_cond += " and ifnull(system_user,'') = '' and ifnull(system_role,'') = ''"
|
else: add_cond += " and ifnull(system_user,'') = '' and ifnull(system_role,'') = ''"
|
||||||
|
|
||||||
@ -85,7 +85,7 @@ class AuthorizationControl(TransactionBase):
|
|||||||
if doc_obj:
|
if doc_obj:
|
||||||
if doc_obj.doctype == 'Sales Invoice': customer = doc_obj.customer
|
if doc_obj.doctype == 'Sales Invoice': customer = doc_obj.customer
|
||||||
else: customer = doc_obj.customer_name
|
else: customer = doc_obj.customer_name
|
||||||
add_cond = " and master_name = '"+cstr(customer).replace("'", "\'")+"'"
|
add_cond = " and master_name = '"+cstr(customer).replace("'", "\\'")+"'"
|
||||||
if based_on == 'Itemwise Discount':
|
if based_on == 'Itemwise Discount':
|
||||||
if doc_obj:
|
if doc_obj:
|
||||||
for t in doc_obj.get(doc_obj.fname):
|
for t in doc_obj.get(doc_obj.fname):
|
||||||
|
Loading…
Reference in New Issue
Block a user