mirror of
https://github.com/frappe/erpnext.git
synced 2026-02-16 16:15:02 +00:00
Merge branch 'version-15-hotfix' into mergify/bp/version-15-hotfix/pr-45987
This commit is contained in:
@@ -50,6 +50,7 @@ def get_group_by_asset_category_data(filters):
|
||||
flt(row.accumulated_depreciation_as_on_from_date)
|
||||
+ flt(row.depreciation_amount_during_the_period)
|
||||
- flt(row.depreciation_eliminated_during_the_period)
|
||||
- flt(row.depreciation_eliminated_via_reversal)
|
||||
)
|
||||
|
||||
row.net_asset_value_as_on_from_date = flt(row.value_as_on_from_date) - flt(
|
||||
@@ -247,6 +248,7 @@ def get_group_by_asset_data(filters):
|
||||
flt(row.accumulated_depreciation_as_on_from_date)
|
||||
+ flt(row.depreciation_amount_during_the_period)
|
||||
- flt(row.depreciation_eliminated_during_the_period)
|
||||
- flt(row.depreciation_eliminated_via_reversal)
|
||||
)
|
||||
|
||||
row.net_asset_value_as_on_from_date = flt(row.value_as_on_from_date) - flt(
|
||||
@@ -276,6 +278,7 @@ def get_assets_for_grouped_by_category(filters):
|
||||
f"""
|
||||
SELECT results.asset_category,
|
||||
sum(results.accumulated_depreciation_as_on_from_date) as accumulated_depreciation_as_on_from_date,
|
||||
sum(results.depreciation_eliminated_via_reversal) as depreciation_eliminated_via_reversal,
|
||||
sum(results.depreciation_eliminated_during_the_period) as depreciation_eliminated_during_the_period,
|
||||
sum(results.depreciation_amount_during_the_period) as depreciation_amount_during_the_period
|
||||
from (SELECT a.asset_category,
|
||||
@@ -284,6 +287,11 @@ def get_assets_for_grouped_by_category(filters):
|
||||
else
|
||||
0
|
||||
end), 0) as accumulated_depreciation_as_on_from_date,
|
||||
ifnull(sum(case when gle.posting_date <= %(to_date)s and ifnull(a.disposal_date, 0) = 0 then
|
||||
gle.credit
|
||||
else
|
||||
0
|
||||
end), 0) as depreciation_eliminated_via_reversal,
|
||||
ifnull(sum(case when ifnull(a.disposal_date, 0) != 0 and a.disposal_date >= %(from_date)s
|
||||
and a.disposal_date <= %(to_date)s and gle.posting_date <= a.disposal_date then
|
||||
gle.debit
|
||||
@@ -307,7 +315,6 @@ def get_assets_for_grouped_by_category(filters):
|
||||
a.docstatus=1
|
||||
and a.company=%(company)s
|
||||
and a.purchase_date <= %(to_date)s
|
||||
and gle.debit != 0
|
||||
and gle.is_cancelled = 0
|
||||
and gle.account = ifnull(aca.depreciation_expense_account, company.depreciation_expense_account)
|
||||
{condition} {finance_book_filter}
|
||||
@@ -319,6 +326,7 @@ def get_assets_for_grouped_by_category(filters):
|
||||
else
|
||||
a.opening_accumulated_depreciation
|
||||
end), 0) as accumulated_depreciation_as_on_from_date,
|
||||
0 as depreciation_eliminated_via_reversal,
|
||||
ifnull(sum(case when a.disposal_date >= %(from_date)s and a.disposal_date <= %(to_date)s then
|
||||
a.opening_accumulated_depreciation
|
||||
else
|
||||
@@ -354,6 +362,7 @@ def get_assets_for_grouped_by_asset(filters):
|
||||
f"""
|
||||
SELECT results.name as asset,
|
||||
sum(results.accumulated_depreciation_as_on_from_date) as accumulated_depreciation_as_on_from_date,
|
||||
sum(results.depreciation_eliminated_via_reversal) as depreciation_eliminated_via_reversal,
|
||||
sum(results.depreciation_eliminated_during_the_period) as depreciation_eliminated_during_the_period,
|
||||
sum(results.depreciation_amount_during_the_period) as depreciation_amount_during_the_period
|
||||
from (SELECT a.name as name,
|
||||
@@ -362,6 +371,11 @@ def get_assets_for_grouped_by_asset(filters):
|
||||
else
|
||||
0
|
||||
end), 0) as accumulated_depreciation_as_on_from_date,
|
||||
ifnull(sum(case when gle.posting_date <= %(to_date)s and ifnull(a.disposal_date, 0) = 0 then
|
||||
gle.credit
|
||||
else
|
||||
0
|
||||
end), 0) as depreciation_eliminated_via_reversal,
|
||||
ifnull(sum(case when ifnull(a.disposal_date, 0) != 0 and a.disposal_date >= %(from_date)s
|
||||
and a.disposal_date <= %(to_date)s and gle.posting_date <= a.disposal_date then
|
||||
gle.debit
|
||||
@@ -385,7 +399,6 @@ def get_assets_for_grouped_by_asset(filters):
|
||||
a.docstatus=1
|
||||
and a.company=%(company)s
|
||||
and a.purchase_date <= %(to_date)s
|
||||
and gle.debit != 0
|
||||
and gle.is_cancelled = 0
|
||||
and gle.account = ifnull(aca.depreciation_expense_account, company.depreciation_expense_account)
|
||||
{finance_book_filter} {condition}
|
||||
@@ -397,6 +410,7 @@ def get_assets_for_grouped_by_asset(filters):
|
||||
else
|
||||
a.opening_accumulated_depreciation
|
||||
end), 0) as accumulated_depreciation_as_on_from_date,
|
||||
0 as depreciation_as_on_from_date_credit,
|
||||
ifnull(sum(case when a.disposal_date >= %(from_date)s and a.disposal_date <= %(to_date)s then
|
||||
a.opening_accumulated_depreciation
|
||||
else
|
||||
@@ -503,6 +517,12 @@ def get_columns(filters):
|
||||
"fieldtype": "Currency",
|
||||
"width": 270,
|
||||
},
|
||||
{
|
||||
"label": _("Depreciation eliminated via reversal"),
|
||||
"fieldname": "depreciation_eliminated_via_reversal",
|
||||
"fieldtype": "Currency",
|
||||
"width": 270,
|
||||
},
|
||||
{
|
||||
"label": _("Net Asset value as on") + " " + formatdate(filters.day_before_from_date),
|
||||
"fieldname": "net_asset_value_as_on_from_date",
|
||||
|
||||
@@ -307,6 +307,7 @@ class Deferred_Revenue_and_Expense_Report:
|
||||
.where(
|
||||
(inv.docstatus == 1)
|
||||
& (deferred_flag_field == 1)
|
||||
& (inv.company == self.filters.company)
|
||||
& (
|
||||
(
|
||||
(self.period_list[0].from_date >= inv_item.service_start_date)
|
||||
|
||||
@@ -2,5 +2,27 @@
|
||||
// For license information, please see license.txt
|
||||
|
||||
frappe.query_reports["Delivered Items To Be Billed"] = {
|
||||
filters: [],
|
||||
filters: [
|
||||
{
|
||||
label: __("Company"),
|
||||
fieldname: "company",
|
||||
fieldtype: "Link",
|
||||
options: "Company",
|
||||
reqd: 1,
|
||||
default: frappe.defaults.get_default("Company"),
|
||||
},
|
||||
{
|
||||
label: __("As on Date"),
|
||||
fieldname: "posting_date",
|
||||
fieldtype: "Date",
|
||||
reqd: 1,
|
||||
default: frappe.datetime.get_today(),
|
||||
},
|
||||
{
|
||||
label: __("Delivery Note"),
|
||||
fieldname: "delivery_note",
|
||||
fieldtype: "Link",
|
||||
options: "Delivery Note",
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
|
||||
from frappe import _
|
||||
from pypika import Order
|
||||
|
||||
from erpnext.accounts.report.non_billed_report import get_ordered_to_be_billed_data
|
||||
|
||||
@@ -10,7 +11,7 @@ from erpnext.accounts.report.non_billed_report import get_ordered_to_be_billed_d
|
||||
def execute(filters=None):
|
||||
columns = get_column()
|
||||
args = get_args()
|
||||
data = get_ordered_to_be_billed_data(args)
|
||||
data = get_ordered_to_be_billed_data(args, filters)
|
||||
return columns, data
|
||||
|
||||
|
||||
@@ -76,13 +77,6 @@ def get_column():
|
||||
"options": "Project",
|
||||
"width": 120,
|
||||
},
|
||||
{
|
||||
"label": _("Company"),
|
||||
"fieldname": "company",
|
||||
"fieldtype": "Link",
|
||||
"options": "Company",
|
||||
"width": 120,
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
@@ -92,5 +86,6 @@ def get_args():
|
||||
"party": "customer",
|
||||
"date": "posting_date",
|
||||
"order": "name",
|
||||
"order_by": "desc",
|
||||
"order_by": Order.desc,
|
||||
"reference_field": "delivery_note",
|
||||
}
|
||||
|
||||
@@ -4,11 +4,12 @@
|
||||
|
||||
import frappe
|
||||
from frappe.model.meta import get_field_precision
|
||||
from frappe.query_builder.functions import IfNull, Round
|
||||
|
||||
from erpnext import get_default_currency
|
||||
|
||||
|
||||
def get_ordered_to_be_billed_data(args):
|
||||
def get_ordered_to_be_billed_data(args, filters=None):
|
||||
doctype, party = args.get("doctype"), args.get("party")
|
||||
child_tab = doctype + " Item"
|
||||
precision = (
|
||||
@@ -18,47 +19,57 @@ def get_ordered_to_be_billed_data(args):
|
||||
or 2
|
||||
)
|
||||
|
||||
project_field = get_project_field(doctype, party)
|
||||
doctype = frappe.qb.DocType(doctype)
|
||||
child_doctype = frappe.qb.DocType(child_tab)
|
||||
|
||||
return frappe.db.sql(
|
||||
"""
|
||||
Select
|
||||
`{parent_tab}`.name, `{parent_tab}`.{date_field},
|
||||
`{parent_tab}`.{party}, `{parent_tab}`.{party}_name,
|
||||
`{child_tab}`.item_code,
|
||||
`{child_tab}`.base_amount,
|
||||
(`{child_tab}`.billed_amt * ifnull(`{parent_tab}`.conversion_rate, 1)),
|
||||
(`{child_tab}`.base_rate * ifnull(`{child_tab}`.returned_qty, 0)),
|
||||
(`{child_tab}`.base_amount -
|
||||
(`{child_tab}`.billed_amt * ifnull(`{parent_tab}`.conversion_rate, 1)) -
|
||||
(`{child_tab}`.base_rate * ifnull(`{child_tab}`.returned_qty, 0))),
|
||||
`{child_tab}`.item_name, `{child_tab}`.description,
|
||||
{project_field}, `{parent_tab}`.company
|
||||
from
|
||||
`{parent_tab}`, `{child_tab}`
|
||||
where
|
||||
`{parent_tab}`.name = `{child_tab}`.parent and `{parent_tab}`.docstatus = 1
|
||||
and `{parent_tab}`.status not in ('Closed', 'Completed')
|
||||
and `{child_tab}`.amount > 0
|
||||
and (`{child_tab}`.base_amount -
|
||||
round(`{child_tab}`.billed_amt * ifnull(`{parent_tab}`.conversion_rate, 1), {precision}) -
|
||||
(`{child_tab}`.base_rate * ifnull(`{child_tab}`.returned_qty, 0))) > 0
|
||||
order by
|
||||
`{parent_tab}`.{order} {order_by}
|
||||
""".format(
|
||||
parent_tab="tab" + doctype,
|
||||
child_tab="tab" + child_tab,
|
||||
precision=precision,
|
||||
party=party,
|
||||
date_field=args.get("date"),
|
||||
project_field=project_field,
|
||||
order=args.get("order"),
|
||||
order_by=args.get("order_by"),
|
||||
docname = filters.get(args.get("reference_field"), None)
|
||||
project_field = get_project_field(doctype, child_doctype, party)
|
||||
|
||||
query = (
|
||||
frappe.qb.from_(doctype)
|
||||
.inner_join(child_doctype)
|
||||
.on(doctype.name == child_doctype.parent)
|
||||
.select(
|
||||
doctype.name,
|
||||
doctype[args.get("date")].as_("date"),
|
||||
doctype[party],
|
||||
doctype[party + "_name"],
|
||||
child_doctype.item_code,
|
||||
child_doctype.base_amount.as_("amount"),
|
||||
(child_doctype.billed_amt * IfNull(doctype.conversion_rate, 1)).as_("billed_amount"),
|
||||
(child_doctype.base_rate * IfNull(child_doctype.returned_qty, 0)).as_("returned_amount"),
|
||||
(
|
||||
child_doctype.base_amount
|
||||
- (child_doctype.billed_amt * IfNull(doctype.conversion_rate, 1))
|
||||
- (child_doctype.base_rate * IfNull(child_doctype.returned_qty, 0))
|
||||
).as_("pending_amount"),
|
||||
child_doctype.item_name,
|
||||
child_doctype.description,
|
||||
project_field,
|
||||
)
|
||||
.where(
|
||||
(doctype.docstatus == 1)
|
||||
& (doctype.status.notin(["Closed", "Completed"]))
|
||||
& (doctype.company == filters.get("company"))
|
||||
& (doctype.posting_date <= filters.get("posting_date"))
|
||||
& (child_doctype.amount > 0)
|
||||
& (
|
||||
child_doctype.base_amount
|
||||
- Round(child_doctype.billed_amt * IfNull(doctype.conversion_rate, 1), precision)
|
||||
- (child_doctype.base_rate * IfNull(child_doctype.returned_qty, 0))
|
||||
)
|
||||
> 0
|
||||
)
|
||||
.orderby(doctype[args.get("order")], order=args.get("order_by"))
|
||||
)
|
||||
|
||||
if docname:
|
||||
query = query.where(doctype.name == docname)
|
||||
|
||||
def get_project_field(doctype, party):
|
||||
return query.run(as_dict=True)
|
||||
|
||||
|
||||
def get_project_field(doctype, child_doctype, party):
|
||||
if party == "supplier":
|
||||
doctype = doctype + " Item"
|
||||
return "`tab%s`.project" % (doctype)
|
||||
return child_doctype.project
|
||||
return doctype.project
|
||||
|
||||
@@ -2,5 +2,27 @@
|
||||
// For license information, please see license.txt
|
||||
|
||||
frappe.query_reports["Received Items To Be Billed"] = {
|
||||
filters: [],
|
||||
filters: [
|
||||
{
|
||||
label: __("Company"),
|
||||
fieldname: "company",
|
||||
fieldtype: "Link",
|
||||
options: "Company",
|
||||
reqd: 1,
|
||||
default: frappe.defaults.get_default("Company"),
|
||||
},
|
||||
{
|
||||
label: __("As on Date"),
|
||||
fieldname: "posting_date",
|
||||
fieldtype: "Date",
|
||||
reqd: 1,
|
||||
default: frappe.datetime.get_today(),
|
||||
},
|
||||
{
|
||||
label: __("Purchase Receipt"),
|
||||
fieldname: "purchase_receipt",
|
||||
fieldtype: "Link",
|
||||
options: "Purchase Receipt",
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
|
||||
from frappe import _
|
||||
from pypika import Order
|
||||
|
||||
from erpnext.accounts.report.non_billed_report import get_ordered_to_be_billed_data
|
||||
|
||||
@@ -10,7 +11,7 @@ from erpnext.accounts.report.non_billed_report import get_ordered_to_be_billed_d
|
||||
def execute(filters=None):
|
||||
columns = get_column()
|
||||
args = get_args()
|
||||
data = get_ordered_to_be_billed_data(args)
|
||||
data = get_ordered_to_be_billed_data(args, filters)
|
||||
return columns, data
|
||||
|
||||
|
||||
@@ -76,13 +77,6 @@ def get_column():
|
||||
"options": "Project",
|
||||
"width": 120,
|
||||
},
|
||||
{
|
||||
"label": _("Company"),
|
||||
"fieldname": "company",
|
||||
"fieldtype": "Link",
|
||||
"options": "Company",
|
||||
"width": 120,
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
@@ -92,5 +86,6 @@ def get_args():
|
||||
"party": "supplier",
|
||||
"date": "posting_date",
|
||||
"order": "name",
|
||||
"order_by": "desc",
|
||||
"order_by": Order.desc,
|
||||
"reference_field": "purchase_receipt",
|
||||
}
|
||||
|
||||
@@ -93,7 +93,7 @@
|
||||
},
|
||||
{
|
||||
"hidden": 0,
|
||||
"is_query_report": 0,
|
||||
"is_query_report": 1,
|
||||
"label": "Accounts Payable",
|
||||
"link_count": 0,
|
||||
"link_to": "Accounts Payable",
|
||||
@@ -103,7 +103,7 @@
|
||||
},
|
||||
{
|
||||
"hidden": 0,
|
||||
"is_query_report": 0,
|
||||
"is_query_report": 1,
|
||||
"label": "Accounts Payable Summary",
|
||||
"link_count": 0,
|
||||
"link_to": "Accounts Payable Summary",
|
||||
@@ -113,7 +113,7 @@
|
||||
},
|
||||
{
|
||||
"hidden": 0,
|
||||
"is_query_report": 0,
|
||||
"is_query_report": 1,
|
||||
"label": "Purchase Register",
|
||||
"link_count": 0,
|
||||
"link_to": "Purchase Register",
|
||||
@@ -123,7 +123,7 @@
|
||||
},
|
||||
{
|
||||
"hidden": 0,
|
||||
"is_query_report": 0,
|
||||
"is_query_report": 1,
|
||||
"label": "Item-wise Purchase Register",
|
||||
"link_count": 0,
|
||||
"link_to": "Item-wise Purchase Register",
|
||||
@@ -133,7 +133,7 @@
|
||||
},
|
||||
{
|
||||
"hidden": 0,
|
||||
"is_query_report": 0,
|
||||
"is_query_report": 1,
|
||||
"label": "Purchase Order Analysis",
|
||||
"link_count": 0,
|
||||
"link_to": "Purchase Order Analysis",
|
||||
@@ -143,7 +143,7 @@
|
||||
},
|
||||
{
|
||||
"hidden": 0,
|
||||
"is_query_report": 0,
|
||||
"is_query_report": 1,
|
||||
"label": "Received Items To Be Billed",
|
||||
"link_count": 0,
|
||||
"link_to": "Received Items To Be Billed",
|
||||
@@ -153,7 +153,7 @@
|
||||
},
|
||||
{
|
||||
"hidden": 0,
|
||||
"is_query_report": 0,
|
||||
"is_query_report": 1,
|
||||
"label": "Supplier Ledger Summary",
|
||||
"link_count": 0,
|
||||
"link_to": "Supplier Ledger Summary",
|
||||
|
||||
@@ -1234,7 +1234,7 @@ class StockController(AccountsController):
|
||||
child_tab.item_code,
|
||||
child_tab.qty,
|
||||
)
|
||||
.where(parent_tab.docstatus < 2)
|
||||
.where(parent_tab.docstatus == 1)
|
||||
)
|
||||
|
||||
if self.doctype == "Purchase Invoice":
|
||||
|
||||
@@ -396,3 +396,4 @@ erpnext.patches.v15_0.set_difference_amount_in_asset_value_adjustment
|
||||
erpnext.patches.v14_0.update_posting_datetime
|
||||
erpnext.stock.doctype.stock_ledger_entry.patches.ensure_sle_indexes
|
||||
erpnext.patches.v15_0.rename_sla_fields
|
||||
erpnext.patches.v15_0.update_query_report
|
||||
|
||||
25
erpnext/patches/v15_0/update_query_report.py
Normal file
25
erpnext/patches/v15_0/update_query_report.py
Normal file
@@ -0,0 +1,25 @@
|
||||
import frappe
|
||||
|
||||
|
||||
def execute():
|
||||
reports = [
|
||||
"Accounts Payable",
|
||||
"Accounts Payable Summary",
|
||||
"Purchase Register",
|
||||
"Item-wise Purchase Register",
|
||||
"Purchase Order Analysis",
|
||||
"Received Items To Be Billed",
|
||||
"Supplier Ledger Summary",
|
||||
]
|
||||
frappe.db.set_value(
|
||||
"Workspace Link",
|
||||
{
|
||||
"parent": "Payables",
|
||||
"link_type": "Report",
|
||||
"type": "Link",
|
||||
"link_to": ["in", reports],
|
||||
"is_query_report": 0,
|
||||
},
|
||||
"is_query_report",
|
||||
1,
|
||||
)
|
||||
@@ -1044,7 +1044,7 @@ def make_delivery_note(source_name, target_doc=None, kwargs=None):
|
||||
ignore_permissions=True,
|
||||
)
|
||||
|
||||
dn_item.qty = flt(sre.reserved_qty) * flt(dn_item.get("conversion_factor", 1))
|
||||
dn_item.qty = flt(sre.reserved_qty) / flt(dn_item.get("conversion_factor", 1))
|
||||
|
||||
if sre.reservation_based_on == "Serial and Batch" and (sre.has_serial_no or sre.has_batch_no):
|
||||
dn_item.serial_and_batch_bundle = get_ssb_bundle_for_voucher(sre)
|
||||
|
||||
@@ -221,7 +221,7 @@ def update_stock(ctx, out, doc=None):
|
||||
else:
|
||||
qty -= batch_qty
|
||||
|
||||
out.update({"batch_no": batch_no, "actual_batch_qty": qty})
|
||||
out.update({"batch_no": batch_no, "actual_batch_qty": batch_qty})
|
||||
if rate:
|
||||
out.update({"rate": rate, "price_list_rate": rate})
|
||||
|
||||
@@ -1051,9 +1051,11 @@ def get_batch_based_item_price(params, item_code) -> float:
|
||||
if not item_price:
|
||||
item_price = get_item_price(params, item_code, ignore_party=True, force_batch_no=True)
|
||||
|
||||
is_free_item = params.get("items", [{}])[0].get("is_free_item")
|
||||
|
||||
if item_price and item_price[0][2] == params.get("uom") and not is_free_item:
|
||||
if (
|
||||
item_price
|
||||
and item_price[0][2] == params.get("uom")
|
||||
and not params.get("items", [{}])[0].get("is_free_item", 0)
|
||||
):
|
||||
return item_price[0][1]
|
||||
|
||||
return 0.0
|
||||
|
||||
Reference in New Issue
Block a user