feat: asset onboarding, dashboards

This commit is contained in:
Saqib Ansari
2020-05-08 16:39:17 +05:30
committed by Nabin Hait
parent e091789332
commit 22aec57beb
19 changed files with 752 additions and 103 deletions

View File

@@ -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"
},
]
};

View File

@@ -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"
}
]
}

View File

@@ -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
}
]

View File

@@ -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"),

View File

@@ -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
},
]

View File

@@ -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"
},
]
};

View File

@@ -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"
}
]
}

View File

@@ -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
}
]