feat: asset onboarding, dashboards
diff --git a/erpnext/assets/dashboard_fixtures.py b/erpnext/assets/dashboard_fixtures.py
new file mode 100644
index 0000000..aa4eed2
--- /dev/null
+++ b/erpnext/assets/dashboard_fixtures.py
@@ -0,0 +1,96 @@
+# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors
+# License: GNU General Public License v3. See license.txt
+
+import frappe
+import json
+
+
+def get_data():
+ return frappe._dict({
+ "dashboards": get_dashboards(),
+ "charts": get_charts(),
+ "number_cards": get_number_cards(),
+ })
+
+def get_dashboards():
+ return [{
+ "name": "Asset",
+ "dashboard_name": "Asset",
+ "charts": [
+ { "chart": "Category-wise Asset Value" },
+ { "chart": "Location-wise Asset Value" },
+ ]
+ }]
+
+def get_charts():
+ return [
+ {
+ "name": "Category-wise Asset Value",
+ "chart_name": "Category-wise Asset Value",
+ "chart_type": "Report",
+ "report_name": "Category-wise Asset Value",
+ "is_custom": 1,
+ "x_field": "asset_category",
+ "timeseries": 0,
+ "filters_json": "{}",
+ "type": "Donut",
+ "doctype": "Dashboard Chart",
+ "y_axis": [
+ {
+ "parent": "Category-wise Asset Value",
+ "parentfield": "y_axis",
+ "parenttype": "Dashboard Chart",
+ "y_field": "asset_value",
+ "doctype": "Dashboard Chart Field"
+ }
+ ],
+ "custom_options": json.dumps({
+ "type": "donut",
+ "height": 300,
+ "axisOptions": {"shortenYAxisNumbers": 1}
+ })
+ },
+ {
+ "name": "Location-wise Asset Value",
+ "chart_name": "Location-wise Asset Value",
+ "chart_type": "Report",
+ "report_name": "Location-wise Asset Value",
+ "is_custom": 1,
+ "x_field": "location",
+ "timeseries": 0,
+ "filters_json": "{}",
+ "type": "Donut",
+ "doctype": "Dashboard Chart",
+ "y_axis": [
+ {
+ "parent": "Location-wise Asset Value",
+ "parentfield": "y_axis",
+ "parenttype": "Dashboard Chart",
+ "y_field": "asset_value",
+ "doctype": "Dashboard Chart Field"
+ }
+ ],
+ "custom_options": json.dumps({
+ "type": "donut",
+ "height": 300,
+ "axisOptions": {"shortenYAxisNumbers": 1}
+ })
+ }
+ ]
+
+
+def get_number_cards():
+ return [
+ {
+ "name": "Asset Value",
+ "label": "Asset Value ",
+ "function": "Sum",
+ "aggregate_function_based_on": "gross_purchase_amount",
+ "document_type": "Asset",
+ "is_public": 0,
+ "show_percentage_stats": 1,
+ "stats_time_interval": "Monthly",
+ "filters_json": "[]",
+ "doctype": "Number Card"
+ }
+ ]
\ No newline at end of file
diff --git a/erpnext/assets/desk_page/assets/assets.json b/erpnext/assets/desk_page/assets/assets.json
index 0309416..13709e3 100644
--- a/erpnext/assets/desk_page/assets/assets.json
+++ b/erpnext/assets/desk_page/assets/assets.json
@@ -24,14 +24,14 @@
"docstatus": 0,
"doctype": "Desk Page",
"extends_another_page": 0,
- "icon": "",
"idx": 0,
"is_standard": 1,
"label": "Assets",
- "modified": "2020-04-01 11:28:51.072198",
+ "modified": "2020-05-08 16:07:04.671296",
"modified_by": "Administrator",
"module": "Assets",
"name": "Assets",
+ "onboarding": "Assets",
"owner": "Administrator",
"pin_to_bottom": 0,
"pin_to_top": 0,
diff --git a/erpnext/assets/doctype/asset/asset.js b/erpnext/assets/doctype/asset/asset.js
index a53ff88..fba20c0 100644
--- a/erpnext/assets/doctype/asset/asset.js
+++ b/erpnext/assets/doctype/asset/asset.js
@@ -387,7 +387,8 @@
}
frm.set_value('gross_purchase_amount', item.base_net_rate + item.item_tax_amount);
frm.set_value('purchase_receipt_amount', item.base_net_rate + item.item_tax_amount);
- frm.set_value('location', item.asset_location);
+ item.asset_location && frm.set_value('location', item.asset_location);
+ frm.set_value('cost_center', item.cost_center || purchase_doc.cost_center);
},
set_depreciation_rate: function(frm, row) {
diff --git a/erpnext/assets/doctype/asset/asset.py b/erpnext/assets/doctype/asset/asset.py
index 505ba4c..2ecabe6 100644
--- a/erpnext/assets/doctype/asset/asset.py
+++ b/erpnext/assets/doctype/asset/asset.py
@@ -127,6 +127,8 @@
frappe.throw(_("Available-for-use Date should be after purchase date"))
def validate_gross_and_purchase_amount(self):
+ if self.is_existing_asset: return
+
if self.gross_purchase_amount and self.gross_purchase_amount != self.purchase_receipt_amount:
frappe.throw(_("Gross Purchase Amount should be {} to purchase amount of one single Asset. {}\
Please do not book expense of multiple assets against one single Asset.")
diff --git a/erpnext/assets/onboarding/assets/assets.json b/erpnext/assets/onboarding/assets/assets.json
new file mode 100644
index 0000000..b32a7f2
--- /dev/null
+++ b/erpnext/assets/onboarding/assets/assets.json
@@ -0,0 +1,39 @@
+{
+ "allow_roles": [
+ {
+ "role": "Accounts User"
+ },
+ {
+ "role": "Maintenance User"
+ }
+ ],
+ "creation": "2020-05-08 15:10:45.571457",
+ "docstatus": 0,
+ "doctype": "Onboarding",
+ "documentation_url": "https://docs.erpnext.com/docs/user/manual/en/asset",
+ "idx": 0,
+ "is_complete": 0,
+ "modified": "2020-05-08 16:17:31.685943",
+ "modified_by": "Administrator",
+ "module": "Assets",
+ "name": "Assets",
+ "owner": "Administrator",
+ "steps": [
+ {
+ "step": "Introduction to Assets"
+ },
+ {
+ "step": "Create a Fixed Asset Item"
+ },
+ {
+ "step": "Purchase the Asset Item"
+ },
+ {
+ "step": "Create the Asset"
+ }
+ ],
+ "subtitle": "Assets, Depreciations, Repairs and more",
+ "success_message": "The Asset Module is all set up!",
+ "title": "Let's Setup Asset Management",
+ "user_can_dismiss": 1
+}
\ No newline at end of file
diff --git a/erpnext/assets/onboarding_step/create_a_fixed_asset_item/create_a_fixed_asset_item.json b/erpnext/assets/onboarding_step/create_a_fixed_asset_item/create_a_fixed_asset_item.json
new file mode 100644
index 0000000..f5818c0
--- /dev/null
+++ b/erpnext/assets/onboarding_step/create_a_fixed_asset_item/create_a_fixed_asset_item.json
@@ -0,0 +1,16 @@
+{
+ "action": "Create Entry",
+ "creation": "2020-05-08 13:20:00.259985",
+ "docstatus": 0,
+ "doctype": "Onboarding Step",
+ "idx": 0,
+ "is_complete": 0,
+ "is_mandatory": 0,
+ "is_skipped": 0,
+ "modified": "2020-05-08 13:20:00.259985",
+ "modified_by": "Administrator",
+ "name": "Create a Fixed Asset Item",
+ "owner": "Administrator",
+ "reference_document": "Item",
+ "title": "Create a Fixed Asset Item"
+}
\ No newline at end of file
diff --git a/erpnext/assets/onboarding_step/create_the_asset/create_the_asset.json b/erpnext/assets/onboarding_step/create_the_asset/create_the_asset.json
new file mode 100644
index 0000000..28d8485
--- /dev/null
+++ b/erpnext/assets/onboarding_step/create_the_asset/create_the_asset.json
@@ -0,0 +1,16 @@
+{
+ "action": "Create Entry",
+ "creation": "2020-05-08 13:21:53.332538",
+ "docstatus": 0,
+ "doctype": "Onboarding Step",
+ "idx": 0,
+ "is_complete": 0,
+ "is_mandatory": 0,
+ "is_skipped": 0,
+ "modified": "2020-05-08 13:21:53.332538",
+ "modified_by": "Administrator",
+ "name": "Create the Asset",
+ "owner": "Administrator",
+ "reference_document": "Asset",
+ "title": "Create the Asset"
+}
\ No newline at end of file
diff --git a/erpnext/assets/onboarding_step/introduction_to_assets/introduction_to_assets.json b/erpnext/assets/onboarding_step/introduction_to_assets/introduction_to_assets.json
new file mode 100644
index 0000000..8aceafd
--- /dev/null
+++ b/erpnext/assets/onboarding_step/introduction_to_assets/introduction_to_assets.json
@@ -0,0 +1,16 @@
+{
+ "action": "Watch Video",
+ "creation": "2020-05-08 13:18:25.424715",
+ "docstatus": 0,
+ "doctype": "Onboarding Step",
+ "idx": 0,
+ "is_complete": 0,
+ "is_mandatory": 0,
+ "is_skipped": 0,
+ "modified": "2020-05-08 16:06:16.625646",
+ "modified_by": "Administrator",
+ "name": "Introduction to Assets",
+ "owner": "Administrator",
+ "title": "Introduction to Fixed Asset Management",
+ "video_url": "https://www.youtube.com/watch?v=I-K8pLRmvSo"
+}
\ No newline at end of file
diff --git a/erpnext/assets/onboarding_step/purchase_the_asset_item/purchase_the_asset_item.json b/erpnext/assets/onboarding_step/purchase_the_asset_item/purchase_the_asset_item.json
new file mode 100644
index 0000000..b6f38de
--- /dev/null
+++ b/erpnext/assets/onboarding_step/purchase_the_asset_item/purchase_the_asset_item.json
@@ -0,0 +1,16 @@
+{
+ "action": "Create Entry",
+ "creation": "2020-05-08 13:21:28.208059",
+ "docstatus": 0,
+ "doctype": "Onboarding Step",
+ "idx": 0,
+ "is_complete": 0,
+ "is_mandatory": 0,
+ "is_skipped": 0,
+ "modified": "2020-05-08 13:21:28.208059",
+ "modified_by": "Administrator",
+ "name": "Purchase the Asset Item",
+ "owner": "Administrator",
+ "reference_document": "Purchase Receipt",
+ "title": "Purchase the Asset Item"
+}
\ No newline at end of file
diff --git a/erpnext/assets/report/category_wise_asset_value/__init__.py b/erpnext/assets/report/category_wise_asset_value/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/assets/report/category_wise_asset_value/__init__.py
diff --git a/erpnext/assets/report/category_wise_asset_value/category_wise_asset_value.js b/erpnext/assets/report/category_wise_asset_value/category_wise_asset_value.js
new file mode 100644
index 0000000..aa643ef
--- /dev/null
+++ b/erpnext/assets/report/category_wise_asset_value/category_wise_asset_value.js
@@ -0,0 +1,43 @@
+// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+/* eslint-disable */
+
+frappe.query_reports["Category-wise Asset Value"] = {
+ "filters": [
+ {
+ fieldname:"company",
+ label: __("Company"),
+ fieldtype: "Link",
+ options: "Company",
+ default: frappe.defaults.get_user_default("Company"),
+ reqd: 1
+ },
+ {
+ fieldname:"purchase_date",
+ label: __("Purchase Date"),
+ fieldtype: "Date"
+ },
+ {
+ fieldname:"available_for_use_date",
+ label: __("Available For Use Date"),
+ fieldtype: "Date"
+ },
+ {
+ fieldname:"cost_center",
+ label: __("Cost Center"),
+ fieldtype: "Link",
+ options: "Cost Center"
+ },
+ {
+ fieldname:"finance_book",
+ label: __("Finance Book"),
+ fieldtype: "Link",
+ options: "Finance Book"
+ },
+ {
+ fieldname:"is_existing_asset",
+ label: __("Is Existing Asset"),
+ fieldtype: "Check"
+ },
+ ]
+};
diff --git a/erpnext/assets/report/category_wise_asset_value/category_wise_asset_value.json b/erpnext/assets/report/category_wise_asset_value/category_wise_asset_value.json
new file mode 100644
index 0000000..a6dbce0
--- /dev/null
+++ b/erpnext/assets/report/category_wise_asset_value/category_wise_asset_value.json
@@ -0,0 +1,29 @@
+{
+ "add_total_row": 0,
+ "creation": "2020-05-08 15:36:02.116096",
+ "disable_prepared_report": 1,
+ "disabled": 0,
+ "docstatus": 0,
+ "doctype": "Report",
+ "idx": 0,
+ "is_standard": "Yes",
+ "javascript": "",
+ "modified": "2020-05-08 15:36:02.116096",
+ "modified_by": "Administrator",
+ "module": "Assets",
+ "name": "Category-wise Asset Value",
+ "owner": "Administrator",
+ "prepared_report": 0,
+ "query": "",
+ "ref_doctype": "Asset",
+ "report_name": "Category-wise Asset Value",
+ "report_type": "Script Report",
+ "roles": [
+ {
+ "role": "Accounts User"
+ },
+ {
+ "role": "Quality Manager"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/erpnext/assets/report/category_wise_asset_value/category_wise_asset_value.py b/erpnext/assets/report/category_wise_asset_value/category_wise_asset_value.py
new file mode 100644
index 0000000..96131e9
--- /dev/null
+++ b/erpnext/assets/report/category_wise_asset_value/category_wise_asset_value.py
@@ -0,0 +1,137 @@
+# Copyright (c) 2013, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe
+from frappe import _
+from frappe.utils import cstr, today, flt
+
+def execute(filters=None):
+ filters = frappe._dict(filters or {})
+ columns = get_columns(filters)
+ data = get_data(filters)
+
+ return columns, data
+
+def get_conditions(filters):
+ conditions = { 'docstatus': 1 }
+
+ if filters.get('company'):
+ conditions["company"] = filters.company
+ if filters.get('purchase_date'):
+ conditions["purchase_date"] = ('<=', filters.get('purchase_date'))
+ if filters.get('available_for_use_date'):
+ conditions["available_for_use_date"] = ('<=', filters.get('available_for_use_date'))
+ if filters.get('is_existing_asset'):
+ conditions["is_existing_asset"] = filters.get('is_existing_asset')
+ if filters.get('cost_center'):
+ conditions["cost_center"] = filters.get('cost_center')
+
+ return conditions
+
+def get_data(filters):
+
+ data = []
+ depreciation_amount_map = get_finance_book_value_map(filters)
+
+ assets_record = frappe.db.get_all("Asset",
+ filters=get_conditions(filters),
+ fields=["name", "asset_name", "asset_category", "gross_purchase_amount",
+ "opening_accumulated_depreciation", "available_for_use_date", "purchase_date"],
+ group_by="asset_category")
+
+ for asset in assets_record:
+ asset_value = asset.gross_purchase_amount - flt(asset.opening_accumulated_depreciation) \
+ - flt(depreciation_amount_map.get(asset.name))
+ if asset_value:
+ row = {
+ "asset_category": asset.asset_category,
+ "asset_id": asset.name,
+ "asset_name": asset.asset_name,
+ "purchase_date": asset.purchase_date,
+ "available_for_use_date": asset.available_for_use_date,
+ "gross_purchase_amount": asset.gross_purchase_amount,
+ "opening_accumulated_depreciation": asset.opening_accumulated_depreciation,
+ "depreciated_amount": depreciation_amount_map.get(asset.name) or 0.0,
+ "asset_value": asset_value
+ }
+ data.append(row)
+
+ return data
+
+def get_finance_book_value_map(filters):
+ date = filters.get('purchase_date') or filters.get('available_for_use_date') or today()
+
+ return frappe._dict(frappe.db.sql(''' Select
+ parent, SUM(depreciation_amount)
+ FROM `tabDepreciation Schedule`
+ WHERE
+ parentfield='schedules'
+ AND schedule_date<=%s
+ AND journal_entry IS NOT NULL
+ AND ifnull(finance_book, '')=%s
+ GROUP BY parent''', (date, cstr(filters.finance_book or ''))))
+
+def get_columns(filters):
+ return [
+ {
+ "label": _("Asset Category"),
+ "fieldtype": "Link",
+ "fieldname": "asset_category",
+ "options": "Asset Category",
+ "width": 120
+ },
+ {
+ "label": _("Asset Id"),
+ "fieldtype": "Link",
+ "fieldname": "asset_id",
+ "options": "Asset",
+ "width": 100
+ },
+ {
+ "label": _("Asset Name"),
+ "fieldtype": "Data",
+ "fieldname": "asset_name",
+ "width": 140
+ },
+ {
+ "label": _("Purchase Date"),
+ "fieldtype": "Date",
+ "fieldname": "purchase_date",
+ "width": 90
+ },
+ {
+ "label": _("Available For Use Date"),
+ "fieldtype": "Date",
+ "fieldname": "available_for_use_date",
+ "width": 90
+ },
+ {
+ "label": _("Gross Purchase Amount"),
+ "fieldname": "gross_purchase_amount",
+ "fieldtype": "Currency",
+ "options": "company:currency",
+ "width": 100
+ },
+ {
+ "label": _("Opening Accumulated Depreciation"),
+ "fieldname": "opening_accumulated_depreciation",
+ "fieldtype": "Currency",
+ "options": "company:currency",
+ "width": 90
+ },
+ {
+ "label": _("Depreciated Amount"),
+ "fieldname": "depreciated_amount",
+ "fieldtype": "Currency",
+ "options": "company:currency",
+ "width": 100
+ },
+ {
+ "label": _("Asset Value"),
+ "fieldname": "asset_value",
+ "fieldtype": "Currency",
+ "options": "company:currency",
+ "width": 100
+ }
+ ]
\ No newline at end of file
diff --git a/erpnext/assets/report/fixed_asset_register/fixed_asset_register.js b/erpnext/assets/report/fixed_asset_register/fixed_asset_register.js
index 91ce9ce..d68993c 100644
--- a/erpnext/assets/report/fixed_asset_register/fixed_asset_register.js
+++ b/erpnext/assets/report/fixed_asset_register/fixed_asset_register.js
@@ -31,18 +31,24 @@
fieldtype: "Date"
},
{
- fieldname:"finance_book",
- label: __("Finance Book"),
- fieldtype: "Link",
- options: "Finance Book"
- },
- {
fieldname:"asset_category",
label: __("Asset Category"),
fieldtype: "Link",
options: "Asset Category"
},
{
+ fieldname:"cost_center",
+ label: __("Cost Center"),
+ fieldtype: "Link",
+ options: "Cost Center"
+ },
+ {
+ fieldname:"finance_book",
+ label: __("Finance Book"),
+ fieldtype: "Link",
+ options: "Finance Book"
+ },
+ {
fieldname:"is_existing_asset",
label: __("Is Existing Asset"),
fieldtype: "Check"
diff --git a/erpnext/assets/report/fixed_asset_register/fixed_asset_register.py b/erpnext/assets/report/fixed_asset_register/fixed_asset_register.py
index fa2fe7b..64ee6a3 100644
--- a/erpnext/assets/report/fixed_asset_register/fixed_asset_register.py
+++ b/erpnext/assets/report/fixed_asset_register/fixed_asset_register.py
@@ -10,105 +10,13 @@
filters = frappe._dict(filters or {})
columns = get_columns(filters)
data = get_data(filters)
- return columns, data
+ chart = prepare_chart_data(data, columns)
-def get_columns(filters):
- return [
- {
- "label": _("Asset Id"),
- "fieldtype": "Link",
- "fieldname": "asset_id",
- "options": "Asset",
- "width": 100
- },
- {
- "label": _("Asset Name"),
- "fieldtype": "Data",
- "fieldname": "asset_name",
- "width": 140
- },
- {
- "label": _("Asset Category"),
- "fieldtype": "Link",
- "fieldname": "asset_category",
- "options": "Asset Category",
- "width": 100
- },
- {
- "label": _("Status"),
- "fieldtype": "Data",
- "fieldname": "status",
- "width": 90
- },
- {
- "label": _("Purchase Date"),
- "fieldtype": "Date",
- "fieldname": "purchase_date",
- "width": 90
- },
- {
- "label": _("Available For Use Date"),
- "fieldtype": "Date",
- "fieldname": "available_for_use_date",
- "width": 90
- },
- {
- "label": _("Gross Purchase Amount"),
- "fieldname": "gross_purchase_amount",
- "options": "Currency",
- "width": 90
- },
- {
- "label": _("Asset Value"),
- "fieldname": "asset_value",
- "options": "Currency",
- "width": 90
- },
- {
- "label": _("Opening Accumulated Depreciation"),
- "fieldname": "opening_accumulated_depreciation",
- "options": "Currency",
- "width": 90
- },
- {
- "label": _("Depreciated Amount"),
- "fieldname": "depreciated_amount",
- "options": "Currency",
- "width": 90
- },
- {
- "label": _("Cost Center"),
- "fieldtype": "Link",
- "fieldname": "cost_center",
- "options": "Cost Center",
- "width": 100
- },
- {
- "label": _("Department"),
- "fieldtype": "Link",
- "fieldname": "department",
- "options": "Department",
- "width": 100
- },
- {
- "label": _("Vendor Name"),
- "fieldtype": "Data",
- "fieldname": "vendor_name",
- "width": 100
- },
- {
- "label": _("Location"),
- "fieldtype": "Link",
- "fieldname": "location",
- "options": "Location",
- "width": 100
- },
- ]
+ return columns, data, None, chart
def get_conditions(filters):
conditions = { 'docstatus': 1 }
status = filters.status
- date = filters.date
if filters.get('company'):
conditions["company"] = filters.company
@@ -120,6 +28,8 @@
conditions["is_existing_asset"] = filters.get('is_existing_asset')
if filters.get('asset_category'):
conditions["asset_category"] = filters.get('asset_category')
+ if filters.get('cost_center'):
+ conditions["cost_center"] = filters.get('cost_center')
# In Store assets are those that are not sold or scrapped
operand = 'not in'
@@ -169,6 +79,22 @@
return data
+def prepare_chart_data(data, columns):
+ label_values_map = {}
+ for d in data:
+ if not label_values_map.get(d.get('asset_category')):
+ label_values_map[d.get('asset_category')] = 0
+ label_values_map[d.get('asset_category')] += d.get('asset_value')
+
+ return {
+ "data" : {
+ "labels": label_values_map.keys(),
+ "datasets": [{ "values": label_values_map.values() }]
+ },
+ "type": 'donut',
+ "height": 250
+ }
+
def get_finance_book_value_map(filters):
date = filters.get('purchase_date') or filters.get('available_for_use_date') or today()
@@ -201,3 +127,100 @@
AND pii.is_fixed_asset=1
AND pi.docstatus=1
AND pi.is_return=0'''))
+
+def get_columns(filters):
+ return [
+ {
+ "label": _("Asset Id"),
+ "fieldtype": "Link",
+ "fieldname": "asset_id",
+ "options": "Asset",
+ "width": 60
+ },
+ {
+ "label": _("Asset Name"),
+ "fieldtype": "Data",
+ "fieldname": "asset_name",
+ "width": 140
+ },
+ {
+ "label": _("Asset Category"),
+ "fieldtype": "Link",
+ "fieldname": "asset_category",
+ "options": "Asset Category",
+ "width": 100
+ },
+ {
+ "label": _("Status"),
+ "fieldtype": "Data",
+ "fieldname": "status",
+ "width": 80
+ },
+ {
+ "label": _("Purchase Date"),
+ "fieldtype": "Date",
+ "fieldname": "purchase_date",
+ "width": 90
+ },
+ {
+ "label": _("Available For Use Date"),
+ "fieldtype": "Date",
+ "fieldname": "available_for_use_date",
+ "width": 90
+ },
+ {
+ "label": _("Gross Purchase Amount"),
+ "fieldname": "gross_purchase_amount",
+ "fieldtype": "Currency",
+ "options": "company:currency",
+ "width": 100
+ },
+ {
+ "label": _("Asset Value"),
+ "fieldname": "asset_value",
+ "fieldtype": "Currency",
+ "options": "company:currency",
+ "width": 100
+ },
+ {
+ "label": _("Opening Accumulated Depreciation"),
+ "fieldname": "opening_accumulated_depreciation",
+ "fieldtype": "Currency",
+ "options": "company:currency",
+ "width": 90
+ },
+ {
+ "label": _("Depreciated Amount"),
+ "fieldname": "depreciated_amount",
+ "fieldtype": "Currency",
+ "options": "company:currency",
+ "width": 100
+ },
+ {
+ "label": _("Cost Center"),
+ "fieldtype": "Link",
+ "fieldname": "cost_center",
+ "options": "Cost Center",
+ "width": 100
+ },
+ {
+ "label": _("Department"),
+ "fieldtype": "Link",
+ "fieldname": "department",
+ "options": "Department",
+ "width": 100
+ },
+ {
+ "label": _("Vendor Name"),
+ "fieldtype": "Data",
+ "fieldname": "vendor_name",
+ "width": 100
+ },
+ {
+ "label": _("Location"),
+ "fieldtype": "Link",
+ "fieldname": "location",
+ "options": "Location",
+ "width": 100
+ },
+ ]
\ No newline at end of file
diff --git a/erpnext/assets/report/location_wise_asset_value/__init__.py b/erpnext/assets/report/location_wise_asset_value/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/assets/report/location_wise_asset_value/__init__.py
diff --git a/erpnext/assets/report/location_wise_asset_value/location_wise_asset_value.js b/erpnext/assets/report/location_wise_asset_value/location_wise_asset_value.js
new file mode 100644
index 0000000..efdafa1
--- /dev/null
+++ b/erpnext/assets/report/location_wise_asset_value/location_wise_asset_value.js
@@ -0,0 +1,43 @@
+// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+/* eslint-disable */
+
+frappe.query_reports["Location-wise Asset Value"] = {
+ "filters": [
+ {
+ fieldname:"company",
+ label: __("Company"),
+ fieldtype: "Link",
+ options: "Company",
+ default: frappe.defaults.get_user_default("Company"),
+ reqd: 1
+ },
+ {
+ fieldname:"purchase_date",
+ label: __("Purchase Date"),
+ fieldtype: "Date"
+ },
+ {
+ fieldname:"available_for_use_date",
+ label: __("Available For Use Date"),
+ fieldtype: "Date"
+ },
+ {
+ fieldname:"cost_center",
+ label: __("Cost Center"),
+ fieldtype: "Link",
+ options: "Cost Center"
+ },
+ {
+ fieldname:"finance_book",
+ label: __("Finance Book"),
+ fieldtype: "Link",
+ options: "Finance Book"
+ },
+ {
+ fieldname:"is_existing_asset",
+ label: __("Is Existing Asset"),
+ fieldtype: "Check"
+ },
+ ]
+};
diff --git a/erpnext/assets/report/location_wise_asset_value/location_wise_asset_value.json b/erpnext/assets/report/location_wise_asset_value/location_wise_asset_value.json
new file mode 100644
index 0000000..2a554d8
--- /dev/null
+++ b/erpnext/assets/report/location_wise_asset_value/location_wise_asset_value.json
@@ -0,0 +1,29 @@
+{
+ "add_total_row": 0,
+ "creation": "2020-05-08 15:47:55.036143",
+ "disable_prepared_report": 1,
+ "disabled": 0,
+ "docstatus": 0,
+ "doctype": "Report",
+ "idx": 0,
+ "is_standard": "Yes",
+ "javascript": "",
+ "modified": "2020-05-08 15:47:55.036143",
+ "modified_by": "Administrator",
+ "module": "Assets",
+ "name": "Location-wise Asset Value",
+ "owner": "Administrator",
+ "prepared_report": 0,
+ "query": "",
+ "ref_doctype": "Asset",
+ "report_name": "Location-wise Asset Value",
+ "report_type": "Script Report",
+ "roles": [
+ {
+ "role": "Accounts User"
+ },
+ {
+ "role": "Quality Manager"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/erpnext/assets/report/location_wise_asset_value/location_wise_asset_value.py b/erpnext/assets/report/location_wise_asset_value/location_wise_asset_value.py
new file mode 100644
index 0000000..6aade0e
--- /dev/null
+++ b/erpnext/assets/report/location_wise_asset_value/location_wise_asset_value.py
@@ -0,0 +1,137 @@
+# Copyright (c) 2013, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe
+from frappe import _
+from frappe.utils import cstr, today, flt
+
+def execute(filters=None):
+ filters = frappe._dict(filters or {})
+ columns = get_columns(filters)
+ data = get_data(filters)
+
+ return columns, data
+
+def get_conditions(filters):
+ conditions = { 'docstatus': 1 }
+
+ if filters.get('company'):
+ conditions["company"] = filters.company
+ if filters.get('purchase_date'):
+ conditions["purchase_date"] = ('<=', filters.get('purchase_date'))
+ if filters.get('available_for_use_date'):
+ conditions["available_for_use_date"] = ('<=', filters.get('available_for_use_date'))
+ if filters.get('is_existing_asset'):
+ conditions["is_existing_asset"] = filters.get('is_existing_asset')
+ if filters.get('cost_center'):
+ conditions["cost_center"] = filters.get('cost_center')
+
+ return conditions
+
+def get_data(filters):
+
+ data = []
+ depreciation_amount_map = get_finance_book_value_map(filters)
+
+ assets_record = frappe.db.get_all("Asset",
+ filters=get_conditions(filters),
+ fields=["name", "asset_name", "location", "gross_purchase_amount",
+ "opening_accumulated_depreciation", "available_for_use_date", "purchase_date"],
+ group_by="location")
+
+ for asset in assets_record:
+ asset_value = asset.gross_purchase_amount - flt(asset.opening_accumulated_depreciation) \
+ - flt(depreciation_amount_map.get(asset.name))
+ if asset_value:
+ row = {
+ "location": asset.location,
+ "asset_id": asset.name,
+ "asset_name": asset.asset_name,
+ "purchase_date": asset.purchase_date,
+ "available_for_use_date": asset.available_for_use_date,
+ "gross_purchase_amount": asset.gross_purchase_amount,
+ "opening_accumulated_depreciation": asset.opening_accumulated_depreciation,
+ "depreciated_amount": depreciation_amount_map.get(asset.name) or 0.0,
+ "asset_value": asset_value
+ }
+ data.append(row)
+
+ return data
+
+def get_finance_book_value_map(filters):
+ date = filters.get('purchase_date') or filters.get('available_for_use_date') or today()
+
+ return frappe._dict(frappe.db.sql(''' Select
+ parent, SUM(depreciation_amount)
+ FROM `tabDepreciation Schedule`
+ WHERE
+ parentfield='schedules'
+ AND schedule_date<=%s
+ AND journal_entry IS NOT NULL
+ AND ifnull(finance_book, '')=%s
+ GROUP BY parent''', (date, cstr(filters.finance_book or ''))))
+
+def get_columns(filters):
+ return [
+ {
+ "label": _("Location"),
+ "fieldtype": "Link",
+ "fieldname": "location",
+ "options": "Location",
+ "width": 120
+ },
+ {
+ "label": _("Asset Id"),
+ "fieldtype": "Link",
+ "fieldname": "asset_id",
+ "options": "Asset",
+ "width": 100
+ },
+ {
+ "label": _("Asset Name"),
+ "fieldtype": "Data",
+ "fieldname": "asset_name",
+ "width": 140
+ },
+ {
+ "label": _("Purchase Date"),
+ "fieldtype": "Date",
+ "fieldname": "purchase_date",
+ "width": 90
+ },
+ {
+ "label": _("Available For Use Date"),
+ "fieldtype": "Date",
+ "fieldname": "available_for_use_date",
+ "width": 90
+ },
+ {
+ "label": _("Gross Purchase Amount"),
+ "fieldname": "gross_purchase_amount",
+ "fieldtype": "Currency",
+ "options": "company:currency",
+ "width": 100
+ },
+ {
+ "label": _("Opening Accumulated Depreciation"),
+ "fieldname": "opening_accumulated_depreciation",
+ "fieldtype": "Currency",
+ "options": "company:currency",
+ "width": 90
+ },
+ {
+ "label": _("Depreciated Amount"),
+ "fieldname": "depreciated_amount",
+ "fieldtype": "Currency",
+ "options": "company:currency",
+ "width": 100
+ },
+ {
+ "label": _("Asset Value"),
+ "fieldname": "asset_value",
+ "fieldtype": "Currency",
+ "options": "company:currency",
+ "width": 100
+ }
+ ]
\ No newline at end of file