mirror of
https://github.com/frappe/erpnext.git
synced 2026-05-25 16:04:46 +00:00
Merge branch 'version-11-hotfix' into version-11
This commit is contained in:
@@ -5,7 +5,7 @@ import frappe
|
|||||||
from erpnext.hooks import regional_overrides
|
from erpnext.hooks import regional_overrides
|
||||||
from frappe.utils import getdate
|
from frappe.utils import getdate
|
||||||
|
|
||||||
__version__ = '11.1.55'
|
__version__ = '11.1.56'
|
||||||
|
|
||||||
def get_default_company(user=None):
|
def get_default_company(user=None):
|
||||||
'''Get default company for user'''
|
'''Get default company for user'''
|
||||||
|
|||||||
@@ -450,7 +450,9 @@ def get_timeline_data(doctype, name):
|
|||||||
# fetch and append data from Activity Log
|
# fetch and append data from Activity Log
|
||||||
data += frappe.db.sql("""select {fields}
|
data += frappe.db.sql("""select {fields}
|
||||||
from `tabActivity Log`
|
from `tabActivity Log`
|
||||||
where reference_doctype="{doctype}" and reference_name="{name}"
|
where (reference_doctype="{doctype}" and reference_name="{name}")
|
||||||
|
or (timeline_doctype in ("{doctype}") and timeline_name="{name}")
|
||||||
|
or (reference_doctype in ("Quotation", "Opportunity") and timeline_name="{name}")
|
||||||
and status!='Success' and creation > {after}
|
and status!='Success' and creation > {after}
|
||||||
{group_by} order by creation desc
|
{group_by} order by creation desc
|
||||||
""".format(doctype=frappe.db.escape(doctype), name=frappe.db.escape(name), fields=fields,
|
""".format(doctype=frappe.db.escape(doctype), name=frappe.db.escape(name), fields=fields,
|
||||||
|
|||||||
@@ -407,9 +407,12 @@ def get_cost_centers_with_children(cost_centers):
|
|||||||
|
|
||||||
all_cost_centers = []
|
all_cost_centers = []
|
||||||
for d in cost_centers:
|
for d in cost_centers:
|
||||||
lft, rgt = frappe.db.get_value("Cost Center", d, ["lft", "rgt"])
|
if frappe.db.exists("Cost Center", d):
|
||||||
children = frappe.get_all("Cost Center", filters={"lft": [">=", lft], "rgt": ["<=", rgt]})
|
lft, rgt = frappe.db.get_value("Cost Center", d, ["lft", "rgt"])
|
||||||
all_cost_centers += [c.name for c in children]
|
children = frappe.get_all("Cost Center", filters={"lft": [">=", lft], "rgt": ["<=", rgt]})
|
||||||
|
all_cost_centers += [c.name for c in children]
|
||||||
|
else:
|
||||||
|
frappe.throw(_("Cost Center: {0} does not exist".format(d)))
|
||||||
|
|
||||||
return list(set(all_cost_centers))
|
return list(set(all_cost_centers))
|
||||||
|
|
||||||
|
|||||||
@@ -121,19 +121,11 @@ def get_gl_entries(filters):
|
|||||||
select_fields = """, debit, credit, debit_in_account_currency,
|
select_fields = """, debit, credit, debit_in_account_currency,
|
||||||
credit_in_account_currency """
|
credit_in_account_currency """
|
||||||
|
|
||||||
group_by_statement = ''
|
|
||||||
order_by_statement = "order by posting_date, account"
|
order_by_statement = "order by posting_date, account"
|
||||||
|
|
||||||
if filters.get("group_by") == _("Group by Voucher"):
|
if filters.get("group_by") == _("Group by Voucher"):
|
||||||
order_by_statement = "order by posting_date, voucher_type, voucher_no"
|
order_by_statement = "order by posting_date, voucher_type, voucher_no"
|
||||||
|
|
||||||
if filters.get("group_by") == _("Group by Voucher (Consolidated)"):
|
|
||||||
group_by_statement = "group by voucher_type, voucher_no, account, cost_center"
|
|
||||||
|
|
||||||
select_fields = """, sum(debit) as debit, sum(credit) as credit,
|
|
||||||
sum(debit_in_account_currency) as debit_in_account_currency,
|
|
||||||
sum(credit_in_account_currency) as credit_in_account_currency"""
|
|
||||||
|
|
||||||
if filters.get("include_default_book_entries"):
|
if filters.get("include_default_book_entries"):
|
||||||
filters['company_fb'] = frappe.db.get_value("Company",
|
filters['company_fb'] = frappe.db.get_value("Company",
|
||||||
filters.get("company"), 'default_finance_book')
|
filters.get("company"), 'default_finance_book')
|
||||||
@@ -146,11 +138,10 @@ def get_gl_entries(filters):
|
|||||||
against_voucher_type, against_voucher, account_currency,
|
against_voucher_type, against_voucher, account_currency,
|
||||||
remarks, against, is_opening {select_fields}
|
remarks, against, is_opening {select_fields}
|
||||||
from `tabGL Entry`
|
from `tabGL Entry`
|
||||||
where company=%(company)s {conditions} {group_by_statement}
|
where company=%(company)s {conditions}
|
||||||
{order_by_statement}
|
{order_by_statement}
|
||||||
""".format(
|
""".format(
|
||||||
select_fields=select_fields, conditions=get_conditions(filters),
|
select_fields=select_fields, conditions=get_conditions(filters),
|
||||||
group_by_statement=group_by_statement,
|
|
||||||
order_by_statement=order_by_statement
|
order_by_statement=order_by_statement
|
||||||
),
|
),
|
||||||
filters, as_dict=1)
|
filters, as_dict=1)
|
||||||
@@ -187,7 +178,8 @@ def get_conditions(filters):
|
|||||||
if not (filters.get("account") or filters.get("party") or
|
if not (filters.get("account") or filters.get("party") or
|
||||||
filters.get("group_by") in ["Group by Account", "Group by Party"]):
|
filters.get("group_by") in ["Group by Account", "Group by Party"]):
|
||||||
conditions.append("posting_date >=%(from_date)s")
|
conditions.append("posting_date >=%(from_date)s")
|
||||||
conditions.append("posting_date <=%(to_date)s")
|
|
||||||
|
conditions.append("(posting_date <=%(to_date)s or is_opening = 'Yes')")
|
||||||
|
|
||||||
if filters.get("project"):
|
if filters.get("project"):
|
||||||
conditions.append("project in %(project)s")
|
conditions.append("project in %(project)s")
|
||||||
@@ -281,6 +273,7 @@ def initialize_gle_map(gl_entries, filters):
|
|||||||
def get_accountwise_gle(filters, gl_entries, gle_map):
|
def get_accountwise_gle(filters, gl_entries, gle_map):
|
||||||
totals = get_totals_dict()
|
totals = get_totals_dict()
|
||||||
entries = []
|
entries = []
|
||||||
|
consolidated_gle = OrderedDict()
|
||||||
group_by = group_by_field(filters.get('group_by'))
|
group_by = group_by_field(filters.get('group_by'))
|
||||||
|
|
||||||
def update_value_in_dict(data, key, gle):
|
def update_value_in_dict(data, key, gle):
|
||||||
@@ -306,11 +299,19 @@ def get_accountwise_gle(filters, gl_entries, gle_map):
|
|||||||
if filters.get("group_by") != _('Group by Voucher (Consolidated)'):
|
if filters.get("group_by") != _('Group by Voucher (Consolidated)'):
|
||||||
gle_map[gle.get(group_by)].entries.append(gle)
|
gle_map[gle.get(group_by)].entries.append(gle)
|
||||||
else:
|
else:
|
||||||
entries.append(gle)
|
key = (gle.get("voucher_type"), gle.get("voucher_no"),
|
||||||
|
gle.get("account"), gle.get("cost_center"))
|
||||||
|
if key not in consolidated_gle:
|
||||||
|
consolidated_gle.setdefault(key, gle)
|
||||||
|
else:
|
||||||
|
update_value_in_dict(consolidated_gle, key, gle)
|
||||||
|
|
||||||
update_value_in_dict(gle_map[gle.get(group_by)].totals, 'closing', gle)
|
update_value_in_dict(gle_map[gle.get(group_by)].totals, 'closing', gle)
|
||||||
update_value_in_dict(totals, 'closing', gle)
|
update_value_in_dict(totals, 'closing', gle)
|
||||||
|
|
||||||
|
for key, value in consolidated_gle.items():
|
||||||
|
entries.append(value)
|
||||||
|
|
||||||
return totals, entries
|
return totals, entries
|
||||||
|
|
||||||
def get_result_as_list(data, filters):
|
def get_result_as_list(data, filters):
|
||||||
|
|||||||
@@ -18,34 +18,31 @@ def validate_return(doc):
|
|||||||
validate_returned_items(doc)
|
validate_returned_items(doc)
|
||||||
|
|
||||||
def validate_return_against(doc):
|
def validate_return_against(doc):
|
||||||
filters = {"doctype": doc.doctype, "docstatus": 1, "company": doc.company}
|
if not frappe.db.exists(doc.doctype, doc.return_against):
|
||||||
if doc.meta.get_field("customer") and doc.customer:
|
|
||||||
filters["customer"] = doc.customer
|
|
||||||
elif doc.meta.get_field("supplier") and doc.supplier:
|
|
||||||
filters["supplier"] = doc.supplier
|
|
||||||
|
|
||||||
if not frappe.db.exists(filters):
|
|
||||||
frappe.throw(_("Invalid {0}: {1}")
|
frappe.throw(_("Invalid {0}: {1}")
|
||||||
.format(doc.meta.get_label("return_against"), doc.return_against))
|
.format(doc.meta.get_label("return_against"), doc.return_against))
|
||||||
else:
|
else:
|
||||||
ref_doc = frappe.get_doc(doc.doctype, doc.return_against)
|
ref_doc = frappe.get_doc(doc.doctype, doc.return_against)
|
||||||
|
|
||||||
# validate posting date time
|
party_type = "customer" if doc.doctype in ("Sales Invoice", "Delivery Note") else "supplier"
|
||||||
return_posting_datetime = "%s %s" % (doc.posting_date, doc.get("posting_time") or "00:00:00")
|
|
||||||
ref_posting_datetime = "%s %s" % (ref_doc.posting_date, ref_doc.get("posting_time") or "00:00:00")
|
|
||||||
|
|
||||||
if get_datetime(return_posting_datetime) < get_datetime(ref_posting_datetime):
|
if ref_doc.company == doc.company and ref_doc.get(party_type) == doc.get(party_type) and ref_doc.docstatus == 1:
|
||||||
frappe.throw(_("Posting timestamp must be after {0}").format(format_datetime(ref_posting_datetime)))
|
# validate posting date time
|
||||||
|
return_posting_datetime = "%s %s" % (doc.posting_date, doc.get("posting_time") or "00:00:00")
|
||||||
|
ref_posting_datetime = "%s %s" % (ref_doc.posting_date, ref_doc.get("posting_time") or "00:00:00")
|
||||||
|
|
||||||
# validate same exchange rate
|
if get_datetime(return_posting_datetime) < get_datetime(ref_posting_datetime):
|
||||||
if doc.conversion_rate != ref_doc.conversion_rate:
|
frappe.throw(_("Posting timestamp must be after {0}").format(format_datetime(ref_posting_datetime)))
|
||||||
frappe.throw(_("Exchange Rate must be same as {0} {1} ({2})")
|
|
||||||
.format(doc.doctype, doc.return_against, ref_doc.conversion_rate))
|
|
||||||
|
|
||||||
# validate update stock
|
# validate same exchange rate
|
||||||
if doc.doctype == "Sales Invoice" and doc.update_stock and not ref_doc.update_stock:
|
if doc.conversion_rate != ref_doc.conversion_rate:
|
||||||
frappe.throw(_("'Update Stock' can not be checked because items are not delivered via {0}")
|
frappe.throw(_("Exchange Rate must be same as {0} {1} ({2})")
|
||||||
.format(doc.return_against))
|
.format(doc.doctype, doc.return_against, ref_doc.conversion_rate))
|
||||||
|
|
||||||
|
# validate update stock
|
||||||
|
if doc.doctype == "Sales Invoice" and doc.update_stock and not ref_doc.update_stock:
|
||||||
|
frappe.throw(_("'Update Stock' can not be checked because items are not delivered via {0}")
|
||||||
|
.format(doc.return_against))
|
||||||
|
|
||||||
def validate_returned_items(doc):
|
def validate_returned_items(doc):
|
||||||
from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos
|
from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos
|
||||||
|
|||||||
@@ -165,6 +165,7 @@ class Project(Document):
|
|||||||
|
|
||||||
task.run_method("validate")
|
task.run_method("validate")
|
||||||
task.db_update()
|
task.db_update()
|
||||||
|
task.notify_update()
|
||||||
else:
|
else:
|
||||||
task.save(ignore_permissions = True)
|
task.save(ignore_permissions = True)
|
||||||
task_names.append(task.name)
|
task_names.append(task.name)
|
||||||
|
|||||||
@@ -701,6 +701,7 @@ def create_delivery_note(**args):
|
|||||||
"qty": args.qty or 1,
|
"qty": args.qty or 1,
|
||||||
"rate": args.rate or 100,
|
"rate": args.rate or 100,
|
||||||
"conversion_factor": 1.0,
|
"conversion_factor": 1.0,
|
||||||
|
"allow_zero_valuation_rate": args.allow_zero_valuation_rate or 1,
|
||||||
"expense_account": "Cost of Goods Sold - _TC",
|
"expense_account": "Cost of Goods Sold - _TC",
|
||||||
"cost_center": args.cost_center or "_Test Cost Center - _TC",
|
"cost_center": args.cost_center or "_Test Cost Center - _TC",
|
||||||
"serial_no": args.serial_no,
|
"serial_no": args.serial_no,
|
||||||
|
|||||||
@@ -457,16 +457,22 @@ def get_valuation_rate(item_code, warehouse, voucher_type, voucher_no,
|
|||||||
|
|
||||||
last_valuation_rate = frappe.db.sql("""select valuation_rate
|
last_valuation_rate = frappe.db.sql("""select valuation_rate
|
||||||
from `tabStock Ledger Entry`
|
from `tabStock Ledger Entry`
|
||||||
where item_code = %s and warehouse = %s
|
where
|
||||||
and valuation_rate >= 0
|
item_code = %s
|
||||||
order by posting_date desc, posting_time desc, name desc limit 1""", (item_code, warehouse))
|
AND warehouse = %s
|
||||||
|
AND valuation_rate >= 0
|
||||||
|
AND NOT (voucher_no = %s AND voucher_type = %s)
|
||||||
|
order by posting_date desc, posting_time desc, name desc limit 1""", (item_code, warehouse, voucher_no, voucher_type))
|
||||||
|
|
||||||
if not last_valuation_rate:
|
if not last_valuation_rate:
|
||||||
# Get valuation rate from last sle for the item against any warehouse
|
# Get valuation rate from last sle for the item against any warehouse
|
||||||
last_valuation_rate = frappe.db.sql("""select valuation_rate
|
last_valuation_rate = frappe.db.sql("""select valuation_rate
|
||||||
from `tabStock Ledger Entry`
|
from `tabStock Ledger Entry`
|
||||||
where item_code = %s and valuation_rate > 0
|
where
|
||||||
order by posting_date desc, posting_time desc, name desc limit 1""", item_code)
|
item_code = %s
|
||||||
|
AND valuation_rate > 0
|
||||||
|
AND NOT(voucher_no = %s AND voucher_type = %s)
|
||||||
|
order by posting_date desc, posting_time desc, name desc limit 1""", (item_code, voucher_no, voucher_type))
|
||||||
|
|
||||||
if last_valuation_rate:
|
if last_valuation_rate:
|
||||||
return flt(last_valuation_rate[0][0]) # as there is previous records, it might come with zero rate
|
return flt(last_valuation_rate[0][0]) # as there is previous records, it might come with zero rate
|
||||||
|
|||||||
Reference in New Issue
Block a user