diff --git a/taxes_az/taxes_az/report/mining_resources_stock_report/__init__.py b/taxes_az/taxes_az/report/mining_resources_stock_report/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/taxes_az/taxes_az/report/mining_resources_stock_report/mining_resources_stock_report.js b/taxes_az/taxes_az/report/mining_resources_stock_report/mining_resources_stock_report.js new file mode 100644 index 0000000..1b1bfdd --- /dev/null +++ b/taxes_az/taxes_az/report/mining_resources_stock_report/mining_resources_stock_report.js @@ -0,0 +1,36 @@ +// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors +// License: GNU General Public License v3. See license.txt + +frappe.query_reports["Mining Resources Stock Report"] = { + filters: [ + { + fieldname: "from_date", + label: __("From Date"), + fieldtype: "Date", + default: frappe.datetime.add_months(frappe.datetime.get_today(), -1), + reqd: 1, + }, + { + fieldname: "to_date", + label: __("To Date"), + fieldtype: "Date", + default: frappe.datetime.get_today(), + reqd: 1, + } + ], + formatter: function (value, row, column, data, default_formatter) { + value = default_formatter(value, row, column, data); + + // Format the In Qty column with green color for positive values + if (column.fieldname == "in_qty" && data && data.in_qty > 0) { + value = "" + value + ""; + } + + // Make item names bold + if (column.fieldname == "item_name") { + value = "" + value + ""; + } + + return value; + } +}; \ No newline at end of file diff --git a/taxes_az/taxes_az/report/mining_resources_stock_report/mining_resources_stock_report.json b/taxes_az/taxes_az/report/mining_resources_stock_report/mining_resources_stock_report.json new file mode 100644 index 0000000..6602092 --- /dev/null +++ b/taxes_az/taxes_az/report/mining_resources_stock_report/mining_resources_stock_report.json @@ -0,0 +1,36 @@ +{ + "add_total_row": 0, + "columns": [], + "creation": "2025-08-19 15:11:43.818116", + "disabled": 0, + "docstatus": 0, + "doctype": "Report", + "filters": [], + "idx": 0, + "is_standard": "Yes", + "letterhead": null, + "modified": "2025-08-19 15:11:43.818116", + "modified_by": "Administrator", + "module": "Taxes Az", + "name": "Mining Resources Stock Report", + "owner": "Administrator", + "prepared_report": 0, + "ref_doctype": "Stock Ledger Entry", + "report_name": "Mining Resources Stock Report", + "report_type": "Script Report", + "roles": [ + { + "role": "Accounts User" + }, + { + "role": "Purchase User" + }, + { + "role": "Accounts Manager" + }, + { + "role": "Auditor" + } + ], + "timeout": 0 +} \ No newline at end of file diff --git a/taxes_az/taxes_az/report/mining_resources_stock_report/mining_resources_stock_report.py b/taxes_az/taxes_az/report/mining_resources_stock_report/mining_resources_stock_report.py new file mode 100644 index 0000000..5a6a1db --- /dev/null +++ b/taxes_az/taxes_az/report/mining_resources_stock_report/mining_resources_stock_report.py @@ -0,0 +1,138 @@ + +import frappe +from frappe import _ +from frappe.query_builder.functions import Sum +from frappe.utils import flt + +def execute(filters=None): + columns = get_columns() + data = get_data(filters) + return columns, data + +def get_columns(): + columns = [ + { + "label": _("Item"), + "fieldname": "item_code", + "fieldtype": "Link", + "options": "Item", + "width": 200, + }, + { + "label": _("Item Name"), + "fieldname": "item_name", + "width": 250, + }, + { + "label": _("In Qty"), + "fieldname": "in_qty", + "fieldtype": "Float", + "width": 120, + }, + { + "label": _("UOM"), + "fieldname": "stock_uom", + "fieldtype": "Link", + "options": "UOM", + "width": 80, + } + ] + return columns + +def get_predefined_item_groups(): + """Return the hardcoded list of item groups""" + return [ + "Xam neft - ton", + "Təbii qaz - m³", + "Filiz faydalı qazıntıları: bütün növ metallar - ton", + "Mişar daşları - m³", + "Üzlük daşları - m³", + "Seolit - ton", + "Barit - ton", + "Yüngül doldurucular üçün gillər - m³", + "Vulkan külü və pemza - m³", + "Kvars qumları - ton", + "Sement xammalı - ton", + "Duz - ton", + "Qiymətli və yarımqiymətli bəzək daşları - karat / qram", + "Yodlu bromlu sular - m³", + "Mineral sular - m³", + "Bentonit gillər - ton", + "Kərpic-kirəmit gilləri - m³", + "Tikinti qumları - m³", + "Çınqıl xammalı - m³", + "Gips, gəc - ton" + ] + +def get_data(filters): + item_groups = get_predefined_item_groups() + + # Get items from the predefined item groups + item_table = frappe.qb.DocType("Item") + item_group_table = frappe.qb.DocType("Item Group") + + items_query = ( + frappe.qb.from_(item_table) + .inner_join(item_group_table) + .on(item_table.item_group == item_group_table.name) + .select( + item_table.name.as_("item_code"), + item_table.item_name, + item_table.stock_uom, + item_group_table.name.as_("item_group") + ) + .where(item_group_table.name.isin(item_groups)) + ) + + items = items_query.run(as_dict=True) + + if not items: + return [] + + item_codes = [item.item_code for item in items] + + # Get stock ledger entries for these items + sle_table = frappe.qb.DocType("Stock Ledger Entry") + + sle_query = ( + frappe.qb.from_(sle_table) + .select( + sle_table.item_code, + Sum(sle_table.actual_qty).as_("total_qty") + ) + .where( + (sle_table.item_code.isin(item_codes)) + & (sle_table.docstatus < 2) + & (sle_table.is_cancelled == 0) + & (sle_table.actual_qty > 0) # Only positive quantities (IN) + ) + .groupby(sle_table.item_code) + ) + + # Add date filter if provided + if filters and filters.get("from_date"): + sle_query = sle_query.where(sle_table.posting_date >= filters.from_date) + if filters and filters.get("to_date"): + sle_query = sle_query.where(sle_table.posting_date <= filters.to_date) + + sle_data = sle_query.run(as_dict=True) + + # Create a dictionary for quick lookup + sle_dict = {row.item_code: row.total_qty for row in sle_data} + + # Combine item details with stock data + result = [] + for item in items: + in_qty = flt(sle_dict.get(item.item_code, 0)) + if in_qty > 0: # Only show items with positive quantities + result.append({ + "item_code": item.item_code, + "item_name": item.item_name, + "in_qty": in_qty, + "stock_uom": item.stock_uom + }) + + # Sort by item name + result.sort(key=lambda x: x["item_name"] or "") + + return result \ No newline at end of file