[stock] [feature] added project to stock ledger entry and updated stock balance report
This commit is contained in:
parent
e97ce3475d
commit
06d186ba98
@ -623,7 +623,8 @@ class DocType(SellingController):
|
|||||||
'fiscal_year' : self.doc.fiscal_year,
|
'fiscal_year' : self.doc.fiscal_year,
|
||||||
'is_cancelled' : (update_stock==1) and 'No' or 'Yes',
|
'is_cancelled' : (update_stock==1) and 'No' or 'Yes',
|
||||||
'batch_no' : cstr(d['batch_no']),
|
'batch_no' : cstr(d['batch_no']),
|
||||||
'serial_no' : d['serial_no']
|
'serial_no' : d['serial_no'],
|
||||||
|
"project" : self.doc.project_name
|
||||||
})
|
})
|
||||||
|
|
||||||
def update_stock_ledger(self, update_stock):
|
def update_stock_ledger(self, update_stock):
|
||||||
|
42
patches/march_2013/p07_update_project_in_stock_ledger.py
Normal file
42
patches/march_2013/p07_update_project_in_stock_ledger.py
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
import webnotes
|
||||||
|
|
||||||
|
def execute():
|
||||||
|
webnotes.reload_doc("stock", "doctype", "stock_ledger_entry")
|
||||||
|
|
||||||
|
# from stock entry
|
||||||
|
webnotes.conn.sql("""update
|
||||||
|
`tabStock Ledger Entry` sle,
|
||||||
|
`tabStock Entry` st
|
||||||
|
set sle.project = st.project_name
|
||||||
|
where
|
||||||
|
sle.voucher_type = "Stock Entry"
|
||||||
|
and sle.voucher_no = st.name""")
|
||||||
|
|
||||||
|
# from purchase
|
||||||
|
webnotes.conn.sql("""update
|
||||||
|
`tabStock Ledger Entry` sle,
|
||||||
|
`tabPurchase Receipt Item` pri
|
||||||
|
set sle.project = pri.project_name
|
||||||
|
where
|
||||||
|
sle.voucher_type = "Purchase Receipt"
|
||||||
|
and sle.voucher_detail_no = pri.name""")
|
||||||
|
|
||||||
|
# from delivery note
|
||||||
|
webnotes.conn.sql("""update
|
||||||
|
`tabStock Ledger Entry` sle,
|
||||||
|
`tabDelivery Note` dn
|
||||||
|
set sle.project = dn.project_name
|
||||||
|
where
|
||||||
|
sle.voucher_type = "Delivery Note"
|
||||||
|
and sle.voucher_no = dn.name""")
|
||||||
|
|
||||||
|
# from pos invoice
|
||||||
|
webnotes.conn.sql("""update
|
||||||
|
`tabStock Ledger Entry` sle,
|
||||||
|
`tabSales Invoice` si
|
||||||
|
set sle.project = si.project_name
|
||||||
|
where
|
||||||
|
sle.voucher_type = "Sales Invoice"
|
||||||
|
and sle.voucher_no = si.name""")
|
||||||
|
|
||||||
|
|
@ -214,5 +214,7 @@ patch_list = [
|
|||||||
"patches.march_2013.p04_pos_update_stock_check",
|
"patches.march_2013.p04_pos_update_stock_check",
|
||||||
"patches.march_2013.p05_payment_reconciliation",
|
"patches.march_2013.p05_payment_reconciliation",
|
||||||
"patches.march_2013.p06_remove_sales_purchase_return_tool",
|
"patches.march_2013.p06_remove_sales_purchase_return_tool",
|
||||||
"execute:webnotes.bean('Global Defaults').save()"
|
"execute:webnotes.bean('Global Defaults').save()",
|
||||||
|
"patches.march_2013.p07_update_project_in_stock_ledger",
|
||||||
|
"execute:webnotes.bean('Style Settings').save() #2013-03-25",
|
||||||
]
|
]
|
@ -80,6 +80,11 @@ data_map = {
|
|||||||
"conditions": ["docstatus < 2"],
|
"conditions": ["docstatus < 2"],
|
||||||
"order_by": "name"
|
"order_by": "name"
|
||||||
},
|
},
|
||||||
|
"Project": {
|
||||||
|
"columns": ["name"],
|
||||||
|
"conditions": ["docstatus < 2"],
|
||||||
|
"order_by": "name"
|
||||||
|
},
|
||||||
"Warehouse": {
|
"Warehouse": {
|
||||||
"columns": ["name"],
|
"columns": ["name"],
|
||||||
"conditions": ["docstatus < 2"],
|
"conditions": ["docstatus < 2"],
|
||||||
@ -87,13 +92,14 @@ data_map = {
|
|||||||
},
|
},
|
||||||
"Stock Ledger Entry": {
|
"Stock Ledger Entry": {
|
||||||
"columns": ["name", "posting_date", "posting_time", "item_code", "warehouse",
|
"columns": ["name", "posting_date", "posting_time", "item_code", "warehouse",
|
||||||
"actual_qty as qty", "voucher_type", "voucher_no",
|
"actual_qty as qty", "voucher_type", "voucher_no", "project",
|
||||||
"ifnull(incoming_rate,0) as incoming_rate", "stock_uom", "serial_no"],
|
"ifnull(incoming_rate,0) as incoming_rate", "stock_uom", "serial_no"],
|
||||||
"conditions": ["ifnull(is_cancelled, 'No')='No'"],
|
"conditions": ["ifnull(is_cancelled, 'No')='No'"],
|
||||||
"order_by": "posting_date, posting_time, name",
|
"order_by": "posting_date, posting_time, name",
|
||||||
"links": {
|
"links": {
|
||||||
"item_code": ["Item", "name"],
|
"item_code": ["Item", "name"],
|
||||||
"warehouse": ["Warehouse", "name"]
|
"warehouse": ["Warehouse", "name"],
|
||||||
|
"project": ["Project", "name"]
|
||||||
},
|
},
|
||||||
"force_index": "posting_sort_index"
|
"force_index": "posting_sort_index"
|
||||||
},
|
},
|
||||||
|
@ -387,7 +387,8 @@ class DocType(SellingController):
|
|||||||
'fiscal_year' : self.doc.fiscal_year,
|
'fiscal_year' : self.doc.fiscal_year,
|
||||||
'is_cancelled' : (update_stock==1) and 'No' or 'Yes',
|
'is_cancelled' : (update_stock==1) and 'No' or 'Yes',
|
||||||
'batch_no' : d['batch_no'],
|
'batch_no' : d['batch_no'],
|
||||||
'serial_no' : d['serial_no']
|
'serial_no' : d['serial_no'],
|
||||||
|
"project" : self.doc.project_name
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
@ -210,7 +210,8 @@ class DocType(BuyingController):
|
|||||||
'fiscal_year' : self.doc.fiscal_year,
|
'fiscal_year' : self.doc.fiscal_year,
|
||||||
'is_cancelled' : (is_submit==1) and 'No' or 'Yes',
|
'is_cancelled' : (is_submit==1) and 'No' or 'Yes',
|
||||||
'batch_no' : cstr(d.batch_no).strip(),
|
'batch_no' : cstr(d.batch_no).strip(),
|
||||||
'serial_no' : serial_no
|
'serial_no' : serial_no,
|
||||||
|
"project" : d.project_name
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
@ -604,7 +604,8 @@ class DocType(StockController):
|
|||||||
'company': self.doc.company,
|
'company': self.doc.company,
|
||||||
'is_cancelled': (is_cancelled ==1) and 'Yes' or 'No',
|
'is_cancelled': (is_cancelled ==1) and 'Yes' or 'No',
|
||||||
'batch_no': cstr(d.batch_no).strip(),
|
'batch_no': cstr(d.batch_no).strip(),
|
||||||
'serial_no': cstr(d.serial_no).strip()
|
'serial_no': cstr(d.serial_no).strip(),
|
||||||
|
"project": self.doc.project_name
|
||||||
})
|
})
|
||||||
|
|
||||||
def get_cust_values(self):
|
def get_cust_values(self):
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
[
|
[
|
||||||
{
|
{
|
||||||
"creation": "2013-01-14 16:33:26",
|
"creation": "2013-01-29 19:25:42",
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"modified": "2013-01-29 16:27:57",
|
"modified": "2013-03-25 16:04:59",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"owner": "Administrator"
|
"owner": "Administrator"
|
||||||
},
|
},
|
||||||
@ -24,13 +24,9 @@
|
|||||||
"parent": "Stock Ledger Entry",
|
"parent": "Stock Ledger Entry",
|
||||||
"parentfield": "fields",
|
"parentfield": "fields",
|
||||||
"parenttype": "DocType",
|
"parenttype": "DocType",
|
||||||
"permlevel": 0,
|
"permlevel": 0
|
||||||
"read_only": 1
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"amend": 0,
|
|
||||||
"cancel": 0,
|
|
||||||
"create": 0,
|
|
||||||
"doctype": "DocPerm",
|
"doctype": "DocPerm",
|
||||||
"name": "__common__",
|
"name": "__common__",
|
||||||
"parent": "Stock Ledger Entry",
|
"parent": "Stock Ledger Entry",
|
||||||
@ -39,9 +35,7 @@
|
|||||||
"permlevel": 0,
|
"permlevel": 0,
|
||||||
"read": 1,
|
"read": 1,
|
||||||
"report": 1,
|
"report": 1,
|
||||||
"role": "Material User",
|
"submit": 0
|
||||||
"submit": 0,
|
|
||||||
"write": 0
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"doctype": "DocType",
|
"doctype": "DocType",
|
||||||
@ -57,6 +51,7 @@
|
|||||||
"oldfieldtype": "Link",
|
"oldfieldtype": "Link",
|
||||||
"options": "Item",
|
"options": "Item",
|
||||||
"print_width": "100px",
|
"print_width": "100px",
|
||||||
|
"read_only": 1,
|
||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 1,
|
"search_index": 1,
|
||||||
"width": "100px"
|
"width": "100px"
|
||||||
@ -68,6 +63,7 @@
|
|||||||
"in_filter": 0,
|
"in_filter": 0,
|
||||||
"label": "Serial No",
|
"label": "Serial No",
|
||||||
"print_width": "100px",
|
"print_width": "100px",
|
||||||
|
"read_only": 1,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"width": "100px"
|
"width": "100px"
|
||||||
},
|
},
|
||||||
@ -77,7 +73,8 @@
|
|||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"label": "Batch No",
|
"label": "Batch No",
|
||||||
"oldfieldname": "batch_no",
|
"oldfieldname": "batch_no",
|
||||||
"oldfieldtype": "Data"
|
"oldfieldtype": "Data",
|
||||||
|
"read_only": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"doctype": "DocField",
|
"doctype": "DocField",
|
||||||
@ -89,6 +86,7 @@
|
|||||||
"oldfieldtype": "Link",
|
"oldfieldtype": "Link",
|
||||||
"options": "Warehouse",
|
"options": "Warehouse",
|
||||||
"print_width": "100px",
|
"print_width": "100px",
|
||||||
|
"read_only": 1,
|
||||||
"search_index": 1,
|
"search_index": 1,
|
||||||
"width": "100px"
|
"width": "100px"
|
||||||
},
|
},
|
||||||
@ -101,6 +99,7 @@
|
|||||||
"oldfieldname": "warehouse_type",
|
"oldfieldname": "warehouse_type",
|
||||||
"oldfieldtype": "Select",
|
"oldfieldtype": "Select",
|
||||||
"options": "link:Warehouse Type",
|
"options": "link:Warehouse Type",
|
||||||
|
"read_only": 1,
|
||||||
"search_index": 0
|
"search_index": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -113,6 +112,7 @@
|
|||||||
"oldfieldname": "posting_date",
|
"oldfieldname": "posting_date",
|
||||||
"oldfieldtype": "Date",
|
"oldfieldtype": "Date",
|
||||||
"print_width": "100px",
|
"print_width": "100px",
|
||||||
|
"read_only": 1,
|
||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 1,
|
"search_index": 1,
|
||||||
"width": "100px"
|
"width": "100px"
|
||||||
@ -126,6 +126,7 @@
|
|||||||
"oldfieldname": "posting_time",
|
"oldfieldname": "posting_time",
|
||||||
"oldfieldtype": "Time",
|
"oldfieldtype": "Time",
|
||||||
"print_width": "100px",
|
"print_width": "100px",
|
||||||
|
"read_only": 1,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"width": "100px"
|
"width": "100px"
|
||||||
},
|
},
|
||||||
@ -138,6 +139,7 @@
|
|||||||
"oldfieldname": "voucher_type",
|
"oldfieldname": "voucher_type",
|
||||||
"oldfieldtype": "Data",
|
"oldfieldtype": "Data",
|
||||||
"print_width": "150px",
|
"print_width": "150px",
|
||||||
|
"read_only": 1,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"width": "150px"
|
"width": "150px"
|
||||||
},
|
},
|
||||||
@ -150,6 +152,7 @@
|
|||||||
"oldfieldname": "voucher_no",
|
"oldfieldname": "voucher_no",
|
||||||
"oldfieldtype": "Data",
|
"oldfieldtype": "Data",
|
||||||
"print_width": "150px",
|
"print_width": "150px",
|
||||||
|
"read_only": 1,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"width": "150px"
|
"width": "150px"
|
||||||
},
|
},
|
||||||
@ -161,6 +164,7 @@
|
|||||||
"oldfieldname": "voucher_detail_no",
|
"oldfieldname": "voucher_detail_no",
|
||||||
"oldfieldtype": "Data",
|
"oldfieldtype": "Data",
|
||||||
"print_width": "150px",
|
"print_width": "150px",
|
||||||
|
"read_only": 1,
|
||||||
"width": "150px"
|
"width": "150px"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -172,6 +176,7 @@
|
|||||||
"oldfieldname": "actual_qty",
|
"oldfieldname": "actual_qty",
|
||||||
"oldfieldtype": "Currency",
|
"oldfieldtype": "Currency",
|
||||||
"print_width": "150px",
|
"print_width": "150px",
|
||||||
|
"read_only": 1,
|
||||||
"width": "150px"
|
"width": "150px"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -181,7 +186,8 @@
|
|||||||
"label": "Incoming Rate",
|
"label": "Incoming Rate",
|
||||||
"oldfieldname": "incoming_rate",
|
"oldfieldname": "incoming_rate",
|
||||||
"oldfieldtype": "Currency",
|
"oldfieldtype": "Currency",
|
||||||
"options": "Company:company:default_currency"
|
"options": "Company:company:default_currency",
|
||||||
|
"read_only": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"doctype": "DocField",
|
"doctype": "DocField",
|
||||||
@ -191,6 +197,7 @@
|
|||||||
"oldfieldname": "stock_uom",
|
"oldfieldname": "stock_uom",
|
||||||
"oldfieldtype": "Data",
|
"oldfieldtype": "Data",
|
||||||
"print_width": "150px",
|
"print_width": "150px",
|
||||||
|
"read_only": 1,
|
||||||
"width": "150px"
|
"width": "150px"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -202,6 +209,7 @@
|
|||||||
"oldfieldname": "bin_aqat",
|
"oldfieldname": "bin_aqat",
|
||||||
"oldfieldtype": "Currency",
|
"oldfieldtype": "Currency",
|
||||||
"print_width": "150px",
|
"print_width": "150px",
|
||||||
|
"read_only": 1,
|
||||||
"width": "150px"
|
"width": "150px"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -213,6 +221,7 @@
|
|||||||
"oldfieldtype": "Currency",
|
"oldfieldtype": "Currency",
|
||||||
"options": "Company:company:default_currency",
|
"options": "Company:company:default_currency",
|
||||||
"print_width": "150px",
|
"print_width": "150px",
|
||||||
|
"read_only": 1,
|
||||||
"width": "150px"
|
"width": "150px"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -222,7 +231,8 @@
|
|||||||
"label": "Stock Value",
|
"label": "Stock Value",
|
||||||
"oldfieldname": "stock_value",
|
"oldfieldname": "stock_value",
|
||||||
"oldfieldtype": "Currency",
|
"oldfieldtype": "Currency",
|
||||||
"options": "Company:company:default_currency"
|
"options": "Company:company:default_currency",
|
||||||
|
"read_only": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"doctype": "DocField",
|
"doctype": "DocField",
|
||||||
@ -234,9 +244,17 @@
|
|||||||
"oldfieldname": "fcfs_stack",
|
"oldfieldname": "fcfs_stack",
|
||||||
"oldfieldtype": "Text",
|
"oldfieldtype": "Text",
|
||||||
"print_hide": 1,
|
"print_hide": 1,
|
||||||
|
"read_only": 1,
|
||||||
"report_hide": 1,
|
"report_hide": 1,
|
||||||
"search_index": 0
|
"search_index": 0
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"doctype": "DocField",
|
||||||
|
"fieldname": "project",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"label": "Project",
|
||||||
|
"options": "Project"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"doctype": "DocField",
|
"doctype": "DocField",
|
||||||
"fieldname": "company",
|
"fieldname": "company",
|
||||||
@ -247,6 +265,7 @@
|
|||||||
"oldfieldtype": "Data",
|
"oldfieldtype": "Data",
|
||||||
"options": "link:Company",
|
"options": "link:Company",
|
||||||
"print_width": "150px",
|
"print_width": "150px",
|
||||||
|
"read_only": 1,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"width": "150px"
|
"width": "150px"
|
||||||
},
|
},
|
||||||
@ -259,6 +278,7 @@
|
|||||||
"oldfieldname": "fiscal_year",
|
"oldfieldname": "fiscal_year",
|
||||||
"oldfieldtype": "Data",
|
"oldfieldtype": "Data",
|
||||||
"print_width": "150px",
|
"print_width": "150px",
|
||||||
|
"read_only": 1,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"width": "150px"
|
"width": "150px"
|
||||||
},
|
},
|
||||||
@ -272,10 +292,20 @@
|
|||||||
"oldfieldtype": "Select",
|
"oldfieldtype": "Select",
|
||||||
"options": "\nYes\nNo",
|
"options": "\nYes\nNo",
|
||||||
"print_width": "100px",
|
"print_width": "100px",
|
||||||
|
"read_only": 1,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"width": "100px"
|
"width": "100px"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"doctype": "DocPerm"
|
"amend": 0,
|
||||||
|
"cancel": 0,
|
||||||
|
"create": 0,
|
||||||
|
"doctype": "DocPerm",
|
||||||
|
"role": "Material User",
|
||||||
|
"write": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"doctype": "DocPerm",
|
||||||
|
"role": "Accounts Manager"
|
||||||
}
|
}
|
||||||
]
|
]
|
@ -35,7 +35,7 @@ erpnext.StockBalance = erpnext.StockAnalytics.extend({
|
|||||||
this._super(wrapper, {
|
this._super(wrapper, {
|
||||||
title: "Stock Balance",
|
title: "Stock Balance",
|
||||||
doctypes: ["Item", "Item Group", "Warehouse", "Stock Ledger Entry", "Brand",
|
doctypes: ["Item", "Item Group", "Warehouse", "Stock Ledger Entry", "Brand",
|
||||||
"Stock Entry"],
|
"Stock Entry", "Project"],
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
setup_columns: function() {
|
setup_columns: function() {
|
||||||
@ -76,6 +76,10 @@ erpnext.StockBalance = erpnext.StockAnalytics.extend({
|
|||||||
default_value: "Select Warehouse...", filter: function(val, item, opts, me) {
|
default_value: "Select Warehouse...", filter: function(val, item, opts, me) {
|
||||||
return me.apply_zero_filter(val, item, opts, me);
|
return me.apply_zero_filter(val, item, opts, me);
|
||||||
}},
|
}},
|
||||||
|
{fieldtype:"Select", label: "Project", link:"Project",
|
||||||
|
default_value: "Select Project...", filter: function(val, item, opts, me) {
|
||||||
|
return me.apply_zero_filter(val, item, opts, me);
|
||||||
|
}, link_formatter: {filter_input: "project"}},
|
||||||
{fieldtype:"Date", label: "From Date"},
|
{fieldtype:"Date", label: "From Date"},
|
||||||
{fieldtype:"Label", label: "To"},
|
{fieldtype:"Label", label: "To"},
|
||||||
{fieldtype:"Date", label: "To Date"},
|
{fieldtype:"Date", label: "To Date"},
|
||||||
@ -105,7 +109,8 @@ erpnext.StockBalance = erpnext.StockAnalytics.extend({
|
|||||||
var sl = data[i];
|
var sl = data[i];
|
||||||
var sl_posting_date = dateutil.str_to_obj(sl.posting_date);
|
var sl_posting_date = dateutil.str_to_obj(sl.posting_date);
|
||||||
|
|
||||||
if(me.is_default("warehouse") ? true : me.warehouse == sl.warehouse) {
|
if((me.is_default("warehouse") ? true : me.warehouse == sl.warehouse) &&
|
||||||
|
(me.is_default("project") ? true : me.project == sl.project)) {
|
||||||
var item = me.item_by_name[sl.item_code];
|
var item = me.item_by_name[sl.item_code];
|
||||||
var wh = me.get_item_warehouse(sl.warehouse, sl.item_code);
|
var wh = me.get_item_warehouse(sl.warehouse, sl.item_code);
|
||||||
var valuation_method = item.valuation_method ?
|
var valuation_method = item.valuation_method ?
|
||||||
|
@ -69,7 +69,6 @@ div.web-footer, div.web-footer a {
|
|||||||
.navbar-inverse .navbar-inner {
|
.navbar-inverse .navbar-inner {
|
||||||
background-color: #{{ doc.top_bar_background or "444444"}};
|
background-color: #{{ doc.top_bar_background or "444444"}};
|
||||||
background-repeat: repeat-x;
|
background-repeat: repeat-x;
|
||||||
border-color: transparent;
|
|
||||||
background-image: none;
|
background-image: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,7 +85,7 @@ class DocType:
|
|||||||
"UPPERCASE": "uppercase",
|
"UPPERCASE": "uppercase",
|
||||||
"Title Case":"capitalize",
|
"Title Case":"capitalize",
|
||||||
"lowercase": "lowercase"
|
"lowercase": "lowercase"
|
||||||
}[self.doc.heading_text_as]
|
}.get(self.doc.heading_text_as) or ""
|
||||||
|
|
||||||
self.doc.at_import = ""
|
self.doc.at_import = ""
|
||||||
for f in fonts:
|
for f in fonts:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user