mirror of
https://github.com/frappe/erpnext.git
synced 2026-05-18 20:49:19 +00:00
feat: fixed asset register based on fiscal year
*asset value chart
This commit is contained in:
@@ -3,12 +3,13 @@
|
|||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
import json
|
import json
|
||||||
|
from frappe.utils import nowdate, add_months
|
||||||
|
|
||||||
def get_data():
|
def get_data():
|
||||||
return frappe._dict({
|
return frappe._dict({
|
||||||
"dashboards": get_dashboards(),
|
"dashboards": get_dashboards(),
|
||||||
"charts": get_charts()
|
"charts": get_charts(),
|
||||||
|
"number_cards": get_number_cards(),
|
||||||
})
|
})
|
||||||
|
|
||||||
def get_dashboards():
|
def get_dashboards():
|
||||||
@@ -16,22 +17,63 @@ def get_dashboards():
|
|||||||
"name": "Asset",
|
"name": "Asset",
|
||||||
"dashboard_name": "Asset",
|
"dashboard_name": "Asset",
|
||||||
"charts": [
|
"charts": [
|
||||||
{ "chart": "Category-wise Asset Value" },
|
{ "chart": "Asset Value Analytics", "width": "Full" },
|
||||||
{ "chart": "Location-wise Asset Value" },
|
{ "chart": "Category-wise Asset Value", "width": "Half" },
|
||||||
|
{ "chart": "Location-wise Asset Value", "width": "Half" },
|
||||||
]
|
]
|
||||||
}]
|
}]
|
||||||
|
|
||||||
def get_charts():
|
def get_charts():
|
||||||
|
company = get_company_for_dashboards()
|
||||||
|
fiscal_year = get_fiscal_year()
|
||||||
|
|
||||||
return [
|
return [
|
||||||
|
{
|
||||||
|
"name": "Asset Value Analytics",
|
||||||
|
"chart_name": "Asset Value Analytics",
|
||||||
|
"chart_type": "Report",
|
||||||
|
"report_name": "Fixed Asset Register",
|
||||||
|
"is_custom": 1,
|
||||||
|
"group_by_type": "Count",
|
||||||
|
"number_of_groups": 0,
|
||||||
|
"is_public": 0,
|
||||||
|
"timespan": "Last Year",
|
||||||
|
"time_interval": "Yearly",
|
||||||
|
"timeseries": 0,
|
||||||
|
"filters_json": json.dumps({
|
||||||
|
"company": company,
|
||||||
|
"status": "In Location",
|
||||||
|
"filter_based_on": "Fiscal Year",
|
||||||
|
"from_fiscal_year": fiscal_year,
|
||||||
|
"to_fiscal_year": fiscal_year,
|
||||||
|
"period_start_date": add_months(nowdate(), -12),
|
||||||
|
"period_end_date": nowdate(),
|
||||||
|
"date_based_on": "Purchase Date",
|
||||||
|
"group_by": "--Select a group--"
|
||||||
|
}),
|
||||||
|
"type": "Bar",
|
||||||
|
"custom_options": json.dumps({
|
||||||
|
"type": "bar",
|
||||||
|
"barOptions": { "stacked": 1 },
|
||||||
|
"axisOptions": { "shortenYAxisNumbers": 1 },
|
||||||
|
"tooltipOptions": {}
|
||||||
|
}),
|
||||||
|
"doctype": "Dashboard Chart",
|
||||||
|
"y_axis": []
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "Category-wise Asset Value",
|
"name": "Category-wise Asset Value",
|
||||||
"chart_name": "Category-wise Asset Value",
|
"chart_name": "Category-wise Asset Value",
|
||||||
"chart_type": "Report",
|
"chart_type": "Report",
|
||||||
"report_name": "Fixed Asset Report",
|
"report_name": "Fixed Asset Register",
|
||||||
"is_custom": 1,
|
|
||||||
"x_field": "asset_category",
|
"x_field": "asset_category",
|
||||||
"timeseries": 0,
|
"timeseries": 0,
|
||||||
"filters_json": json.dumps("""{"status":"In Location","group_by":"Asset Category","is_existing_asset":0}"""),
|
"filters_json": json.dumps({
|
||||||
|
"company": company,
|
||||||
|
"status":"In Location",
|
||||||
|
"group_by":"Asset Category",
|
||||||
|
"is_existing_asset":0
|
||||||
|
}),
|
||||||
"type": "Donut",
|
"type": "Donut",
|
||||||
"doctype": "Dashboard Chart",
|
"doctype": "Dashboard Chart",
|
||||||
"y_axis": [
|
"y_axis": [
|
||||||
@@ -53,11 +95,15 @@ def get_charts():
|
|||||||
"name": "Location-wise Asset Value",
|
"name": "Location-wise Asset Value",
|
||||||
"chart_name": "Location-wise Asset Value",
|
"chart_name": "Location-wise Asset Value",
|
||||||
"chart_type": "Report",
|
"chart_type": "Report",
|
||||||
"report_name": "Fixed Asset Report",
|
"report_name": "Fixed Asset Register",
|
||||||
"is_custom": 1,
|
|
||||||
"x_field": "location",
|
"x_field": "location",
|
||||||
"timeseries": 0,
|
"timeseries": 0,
|
||||||
"filters_json": json.dumps("""{"status":"In Location","group_by":"Location","is_existing_asset":0}"""),
|
"filters_json": json.dumps({
|
||||||
|
"company": company,
|
||||||
|
"status":"In Location",
|
||||||
|
"group_by":"Location",
|
||||||
|
"is_existing_asset":0
|
||||||
|
}),
|
||||||
"type": "Donut",
|
"type": "Donut",
|
||||||
"doctype": "Dashboard Chart",
|
"doctype": "Dashboard Chart",
|
||||||
"y_axis": [
|
"y_axis": [
|
||||||
@@ -74,4 +120,41 @@ def get_charts():
|
|||||||
"height": 300,
|
"height": 300,
|
||||||
"axisOptions": {"shortenYAxisNumbers": 1}
|
"axisOptions": {"shortenYAxisNumbers": 1}
|
||||||
})
|
})
|
||||||
}]
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
def get_number_cards():
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
"name": "Asset Value",
|
||||||
|
"label": "Asset Value",
|
||||||
|
"function": "Sum",
|
||||||
|
"aggregate_function_based_on": "value_after_depreciation",
|
||||||
|
"document_type": "Asset",
|
||||||
|
"is_public": 1,
|
||||||
|
"show_percentage_stats": 1,
|
||||||
|
"stats_time_interval": "Monthly",
|
||||||
|
"filters_json": "[]",
|
||||||
|
"doctype": "Number Card",
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
def get_company_for_dashboards():
|
||||||
|
company = frappe.defaults.get_defaults().company
|
||||||
|
if company:
|
||||||
|
return company
|
||||||
|
else:
|
||||||
|
company_list = frappe.get_list("Company")
|
||||||
|
if company_list:
|
||||||
|
return company_list[0].name
|
||||||
|
return None
|
||||||
|
|
||||||
|
def get_fiscal_year():
|
||||||
|
fiscal_year = frappe.defaults.get_defaults().fiscal_year
|
||||||
|
if fiscal_year:
|
||||||
|
return fiscal_year
|
||||||
|
else:
|
||||||
|
fiscal_year_list = frappe.get_list("Fiscal Year")
|
||||||
|
if fiscal_year_list:
|
||||||
|
return fiscal_year_list[0].name
|
||||||
|
return None
|
||||||
@@ -17,7 +17,12 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"category": "Modules",
|
"category": "Modules",
|
||||||
"charts": [],
|
"charts": [
|
||||||
|
{
|
||||||
|
"chart_name": "Asset Value Analytics",
|
||||||
|
"label": "Asset Value Analytics"
|
||||||
|
}
|
||||||
|
],
|
||||||
"creation": "2020-03-02 15:43:27.634865",
|
"creation": "2020-03-02 15:43:27.634865",
|
||||||
"developer_mode_only": 0,
|
"developer_mode_only": 0,
|
||||||
"disable_user_customization": 0,
|
"disable_user_customization": 0,
|
||||||
@@ -27,7 +32,7 @@
|
|||||||
"idx": 0,
|
"idx": 0,
|
||||||
"is_standard": 1,
|
"is_standard": 1,
|
||||||
"label": "Assets",
|
"label": "Assets",
|
||||||
"modified": "2020-05-08 16:07:04.671296",
|
"modified": "2020-05-12 17:35:14.770662",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Assets",
|
"module": "Assets",
|
||||||
"name": "Assets",
|
"name": "Assets",
|
||||||
@@ -42,8 +47,8 @@
|
|||||||
"type": "DocType"
|
"type": "DocType"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"label": "Asset Movement",
|
"label": "Asset Category",
|
||||||
"link_to": "Asset Movement",
|
"link_to": "Asset Category",
|
||||||
"type": "DocType"
|
"type": "DocType"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -21,14 +21,61 @@ frappe.query_reports["Fixed Asset Register"] = {
|
|||||||
reqd: 1
|
reqd: 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
fieldname:"purchase_date",
|
"fieldname":"filter_based_on",
|
||||||
label: __("Purchase Date"),
|
"label": __("Period Based On"),
|
||||||
fieldtype: "Date"
|
"fieldtype": "Select",
|
||||||
|
"options": ["Fiscal Year", "Date Range"],
|
||||||
|
"default": ["Fiscal Year"],
|
||||||
|
"reqd": 1,
|
||||||
|
on_change: function() {
|
||||||
|
let filter_based_on = frappe.query_report.get_filter_value('filter_based_on');
|
||||||
|
frappe.query_report.toggle_filter_display('from_fiscal_year', filter_based_on === 'Date Range');
|
||||||
|
frappe.query_report.toggle_filter_display('to_fiscal_year', filter_based_on === 'Date Range');
|
||||||
|
frappe.query_report.toggle_filter_display('from_date', filter_based_on === 'Fiscal Year');
|
||||||
|
frappe.query_report.toggle_filter_display('to_date', filter_based_on === 'Fiscal Year');
|
||||||
|
|
||||||
|
frappe.query_report.refresh();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
fieldname:"available_for_use_date",
|
"fieldname":"from_date",
|
||||||
label: __("Available For Use Date"),
|
"label": __("Start Date"),
|
||||||
fieldtype: "Date"
|
"fieldtype": "Date",
|
||||||
|
"default": frappe.datetime.nowdate(),
|
||||||
|
"hidden": 1,
|
||||||
|
"reqd": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname":"to_date",
|
||||||
|
"label": __("End Date"),
|
||||||
|
"fieldtype": "Date",
|
||||||
|
"default": frappe.datetime.add_months(frappe.datetime.nowdate(), 12),
|
||||||
|
"hidden": 1,
|
||||||
|
"reqd": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname":"from_fiscal_year",
|
||||||
|
"label": __("Start Year"),
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"options": "Fiscal Year",
|
||||||
|
"default": frappe.defaults.get_user_default("fiscal_year"),
|
||||||
|
"reqd": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname":"to_fiscal_year",
|
||||||
|
"label": __("End Year"),
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"options": "Fiscal Year",
|
||||||
|
"default": frappe.defaults.get_user_default("fiscal_year"),
|
||||||
|
"reqd": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname":"date_based_on",
|
||||||
|
"label": __("Date Based On"),
|
||||||
|
"fieldtype": "Select",
|
||||||
|
"options": ["Purchase Date", "Available For Use Date"],
|
||||||
|
"default": "Purchase Date",
|
||||||
|
"reqd": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
fieldname:"asset_category",
|
fieldname:"asset_category",
|
||||||
@@ -48,18 +95,13 @@ frappe.query_reports["Fixed Asset Register"] = {
|
|||||||
fieldtype: "Link",
|
fieldtype: "Link",
|
||||||
options: "Cost Center"
|
options: "Cost Center"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
fieldname:"finance_book",
|
|
||||||
label: __("Finance Book"),
|
|
||||||
fieldtype: "Link",
|
|
||||||
options: "Finance Book"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
fieldname:"group_by",
|
fieldname:"group_by",
|
||||||
label: __("Group By"),
|
label: __("Group By"),
|
||||||
fieldtype: "Select",
|
fieldtype: "Select",
|
||||||
options: " \nAsset Category\nLocation",
|
options: ["--Select a group--", "Asset Category", "Location"],
|
||||||
default: '',
|
default: "--Select a group--",
|
||||||
|
reqd: 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
fieldname:"is_existing_asset",
|
fieldname:"is_existing_asset",
|
||||||
|
|||||||
@@ -4,26 +4,33 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
import frappe
|
import frappe
|
||||||
from frappe import _
|
from frappe import _
|
||||||
from frappe.utils import cstr, today, flt
|
from frappe.utils import cstr, today, flt, add_years, formatdate, getdate
|
||||||
|
from erpnext.accounts.report.financial_statements import get_period_list, get_fiscal_year_data, validate_fiscal_year
|
||||||
|
|
||||||
def execute(filters=None):
|
def execute(filters=None):
|
||||||
filters = frappe._dict(filters or {})
|
filters = frappe._dict(filters or {})
|
||||||
columns = get_columns(filters)
|
columns = get_columns(filters)
|
||||||
data = get_data(filters)
|
data = get_data(filters)
|
||||||
chart = prepare_chart_data(data) if not filters.get("group_by") else {}
|
chart = prepare_chart_data(data, filters) if filters.get("group_by") not in ("Asset Category", "Location") else {}
|
||||||
|
|
||||||
return columns, data, None, chart
|
return columns, data, None, chart
|
||||||
|
|
||||||
def get_conditions(filters):
|
def get_conditions(filters):
|
||||||
conditions = { 'docstatus': 1 }
|
conditions = { 'docstatus': 1 }
|
||||||
status = filters.status
|
status = filters.status
|
||||||
|
date_field = frappe.scrub(filters.date_based_on or "Purchase Date")
|
||||||
|
|
||||||
if filters.get('company'):
|
if filters.get('company'):
|
||||||
conditions["company"] = filters.company
|
conditions["company"] = filters.company
|
||||||
if filters.get('purchase_date'):
|
if filters.filter_based_on == "Date Range":
|
||||||
conditions["purchase_date"] = ('<=', filters.get('purchase_date'))
|
conditions[date_field] = ["between", [filters.from_date, filters.to_date]]
|
||||||
if filters.get('available_for_use_date'):
|
if filters.filter_based_on == "Fiscal Year":
|
||||||
conditions["available_for_use_date"] = ('<=', filters.get('available_for_use_date'))
|
fiscal_year = get_fiscal_year_data(filters.from_fiscal_year, filters.to_fiscal_year)
|
||||||
|
validate_fiscal_year(fiscal_year, filters.from_fiscal_year, filters.to_fiscal_year)
|
||||||
|
year_start_date = getdate(fiscal_year.year_start_date)
|
||||||
|
year_end_date = getdate(fiscal_year.year_end_date)
|
||||||
|
|
||||||
|
conditions[date_field] = ["between", [year_start_date, year_end_date]]
|
||||||
if filters.get('is_existing_asset'):
|
if filters.get('is_existing_asset'):
|
||||||
conditions["is_existing_asset"] = filters.get('is_existing_asset')
|
conditions["is_existing_asset"] = filters.get('is_existing_asset')
|
||||||
if filters.get('asset_category'):
|
if filters.get('asset_category'):
|
||||||
@@ -49,16 +56,17 @@ def get_data(filters):
|
|||||||
pi_supplier_map = get_purchase_invoice_supplier_map()
|
pi_supplier_map = get_purchase_invoice_supplier_map()
|
||||||
|
|
||||||
conditions = get_conditions(filters)
|
conditions = get_conditions(filters)
|
||||||
group_by = frappe.scrub(filters.get("group_by") or "")
|
|
||||||
|
|
||||||
if group_by:
|
group_by = frappe.scrub(filters.get("group_by"))
|
||||||
if group_by == "asset_category":
|
|
||||||
fields = ["asset_category", "gross_purchase_amount", "opening_accumulated_depreciation"]
|
|
||||||
else:
|
|
||||||
fields = ["location", "gross_purchase_amount", "opening_accumulated_depreciation"]
|
|
||||||
|
|
||||||
|
if group_by == "asset_category":
|
||||||
|
fields = ["asset_category", "gross_purchase_amount", "opening_accumulated_depreciation"]
|
||||||
assets_record = frappe.db.get_all("Asset", filters=conditions, fields=fields, group_by=group_by)
|
assets_record = frappe.db.get_all("Asset", filters=conditions, fields=fields, group_by=group_by)
|
||||||
print(assets_record)
|
|
||||||
|
elif group_by == "location":
|
||||||
|
fields = ["location", "gross_purchase_amount", "opening_accumulated_depreciation"]
|
||||||
|
assets_record = frappe.db.get_all("Asset", filters=conditions, fields=fields, group_by=group_by)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
fields = ["name as asset_id", "asset_name", "status", "department", "cost_center", "purchase_receipt",
|
fields = ["name as asset_id", "asset_name", "status", "department", "cost_center", "purchase_receipt",
|
||||||
"asset_category", "purchase_date", "gross_purchase_amount", "location",
|
"asset_category", "purchase_date", "gross_purchase_amount", "location",
|
||||||
@@ -89,19 +97,29 @@ def get_data(filters):
|
|||||||
|
|
||||||
return data
|
return data
|
||||||
|
|
||||||
def prepare_chart_data(data):
|
def prepare_chart_data(data, filters):
|
||||||
labels, asset_values, depreciated_amounts = [], [], []
|
labels_values_map = {}
|
||||||
|
date_field = frappe.scrub(filters.date_based_on)
|
||||||
|
|
||||||
|
period_list = get_period_list(filters.from_fiscal_year, filters.to_fiscal_year,
|
||||||
|
filters.from_date, filters.to_date, filters.filter_based_on, "Monthly", company=filters.company)
|
||||||
|
|
||||||
|
for d in period_list:
|
||||||
|
labels_values_map.setdefault(d.get('label'), frappe._dict({'asset_value': 0, 'depreciated_amount': 0}))
|
||||||
|
|
||||||
for d in data:
|
for d in data:
|
||||||
labels.append(d.get("asset_id"))
|
date = d.get(date_field)
|
||||||
asset_values.append(d.get("asset_value"))
|
belongs_to_month = formatdate(date, "MMM YYYY")
|
||||||
depreciated_amounts.append(d.get("depreciated_amount"))
|
|
||||||
|
labels_values_map[belongs_to_month].asset_value += d.get("asset_value")
|
||||||
|
labels_values_map[belongs_to_month].depreciated_amount += d.get("depreciated_amount")
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"data" : {
|
"data" : {
|
||||||
"labels": labels,
|
"labels": labels_values_map.keys(),
|
||||||
"datasets": [
|
"datasets": [
|
||||||
{ 'name': _('Asset Value'), 'values': asset_values },
|
{ 'name': _('Asset Value'), 'values': [d.get("asset_value") for d in labels_values_map.values()] },
|
||||||
{ 'name': _('Depreciatied Amount'), 'values': depreciated_amounts}
|
{ 'name': _('Depreciatied Amount'), 'values': [d.get("depreciated_amount") for d in labels_values_map.values()] }
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"type": "bar",
|
"type": "bar",
|
||||||
@@ -144,7 +162,7 @@ def get_purchase_invoice_supplier_map():
|
|||||||
AND pi.is_return=0'''))
|
AND pi.is_return=0'''))
|
||||||
|
|
||||||
def get_columns(filters):
|
def get_columns(filters):
|
||||||
if filters.get("group_by"):
|
if filters.get("group_by") in ["Asset Category", "Location"]:
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
"label": _("{}").format(filters.get("group_by")),
|
"label": _("{}").format(filters.get("group_by")),
|
||||||
|
|||||||
Reference in New Issue
Block a user