chore: enhance fixed asset report and remove redundant reports
This commit is contained in:
parent
03007de4d7
commit
1dcf103398
@ -1,43 +0,0 @@
|
|||||||
// 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"
|
|
||||||
},
|
|
||||||
]
|
|
||||||
};
|
|
||||||
@ -1,29 +0,0 @@
|
|||||||
{
|
|
||||||
"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"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@ -1,137 +0,0 @@
|
|||||||
# 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
|
|
||||||
}
|
|
||||||
]
|
|
||||||
@ -54,6 +54,13 @@ frappe.query_reports["Fixed Asset Register"] = {
|
|||||||
fieldtype: "Link",
|
fieldtype: "Link",
|
||||||
options: "Finance Book"
|
options: "Finance Book"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
fieldname:"group_by",
|
||||||
|
label: __("Group By"),
|
||||||
|
fieldtype: "Select",
|
||||||
|
options: " \nAsset Category\nLocation",
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
fieldname:"is_existing_asset",
|
fieldname:"is_existing_asset",
|
||||||
label: __("Is Existing Asset"),
|
label: __("Is Existing Asset"),
|
||||||
|
|||||||
@ -44,23 +44,33 @@ def get_data(filters):
|
|||||||
|
|
||||||
data = []
|
data = []
|
||||||
|
|
||||||
conditions = get_conditions(filters)
|
|
||||||
depreciation_amount_map = get_finance_book_value_map(filters)
|
depreciation_amount_map = get_finance_book_value_map(filters)
|
||||||
pr_supplier_map = get_purchase_receipt_supplier_map()
|
pr_supplier_map = get_purchase_receipt_supplier_map()
|
||||||
pi_supplier_map = get_purchase_invoice_supplier_map()
|
pi_supplier_map = get_purchase_invoice_supplier_map()
|
||||||
|
|
||||||
assets_record = frappe.db.get_all("Asset",
|
conditions = get_conditions(filters)
|
||||||
filters=conditions,
|
group_by = frappe.scrub(filters.get("group_by") or "")
|
||||||
fields=["name", "asset_name", "department", "cost_center", "purchase_receipt",
|
|
||||||
|
if 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"]
|
||||||
|
|
||||||
|
assets_record = frappe.db.get_all("Asset", filters=conditions, fields=fields, group_by=group_by)
|
||||||
|
print(assets_record)
|
||||||
|
else:
|
||||||
|
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",
|
||||||
"available_for_use_date", "status", "purchase_invoice", "opening_accumulated_depreciation"])
|
"available_for_use_date", "purchase_invoice", "opening_accumulated_depreciation"]
|
||||||
|
assets_record = frappe.db.get_all("Asset", filters=conditions, fields=fields)
|
||||||
|
|
||||||
for asset in assets_record:
|
for asset in assets_record:
|
||||||
asset_value = asset.gross_purchase_amount - flt(asset.opening_accumulated_depreciation) \
|
asset_value = asset.gross_purchase_amount - flt(asset.opening_accumulated_depreciation) \
|
||||||
- flt(depreciation_amount_map.get(asset.name))
|
- flt(depreciation_amount_map.get(asset.name))
|
||||||
if asset_value:
|
if asset_value:
|
||||||
row = {
|
row = {
|
||||||
"asset_id": asset.name,
|
"asset_id": asset.asset_id,
|
||||||
"asset_name": asset.asset_name,
|
"asset_name": asset.asset_name,
|
||||||
"status": asset.status,
|
"status": asset.status,
|
||||||
"department": asset.department,
|
"department": asset.department,
|
||||||
@ -129,6 +139,45 @@ 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"):
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
"label": _("{}").format(filters.get("group_by")),
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"fieldname": frappe.scrub(filters.get("group_by")),
|
||||||
|
"options": filters.get("group_by"),
|
||||||
|
"width": 120
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"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
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
"label": _("Asset Id"),
|
"label": _("Asset Id"),
|
||||||
|
|||||||
@ -1,43 +0,0 @@
|
|||||||
// 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"
|
|
||||||
},
|
|
||||||
]
|
|
||||||
};
|
|
||||||
@ -1,29 +0,0 @@
|
|||||||
{
|
|
||||||
"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"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@ -1,137 +0,0 @@
|
|||||||
# 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
|
|
||||||
}
|
|
||||||
]
|
|
||||||
Loading…
x
Reference in New Issue
Block a user