diff --git a/erpnext/assets/dashboard_fixtures.py b/erpnext/assets/dashboard_fixtures.py new file mode 100644 index 00000000000..aa4eed2f746 --- /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 03094160e5f..13709e370bb 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 a53ff881777..fba20c0c879 100644 --- a/erpnext/assets/doctype/asset/asset.js +++ b/erpnext/assets/doctype/asset/asset.js @@ -387,7 +387,8 @@ frappe.ui.form.on('Asset', { } 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 505ba4c6b64..2ecabe60f03 100644 --- a/erpnext/assets/doctype/asset/asset.py +++ b/erpnext/assets/doctype/asset/asset.py @@ -127,6 +127,8 @@ class Asset(AccountsController): 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 00000000000..b32a7f2be5b --- /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 00000000000..f5818c091f1 --- /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 00000000000..28d8485f976 --- /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 00000000000..8aceafd7e5f --- /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 00000000000..b6f38decb9e --- /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 00000000000..e69de29bb2d 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 00000000000..aa643efb2df --- /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 00000000000..a6dbce05163 --- /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 00000000000..96131e92605 --- /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 91ce9ce7fe9..d68993c2976 100644 --- a/erpnext/assets/report/fixed_asset_register/fixed_asset_register.js +++ b/erpnext/assets/report/fixed_asset_register/fixed_asset_register.js @@ -30,18 +30,24 @@ frappe.query_reports["Fixed Asset Register"] = { label: __("Available For Use Date"), 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"), 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 fa2fe7b4a3c..64ee6a35037 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 @@ def execute(filters=None): 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 @@ def get_conditions(filters): 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 @@ def get_data(filters): 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 @@ def get_purchase_invoice_supplier_map(): 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 00000000000..e69de29bb2d 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 00000000000..efdafa18c5c --- /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 00000000000..2a554d83d0e --- /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 00000000000..6aade0e27aa --- /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