-
Notifications
You must be signed in to change notification settings - Fork 7.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #30969 from ankush/fifo_queue_report
chore: fifo queue vs qty after transaction comparison report
- Loading branch information
Showing
5 changed files
with
294 additions
and
0 deletions.
There are no files selected for viewing
Empty file.
53 changes: 53 additions & 0 deletions
53
...eue_vs_qty_after_transaction_comparison/fifo_queue_vs_qty_after_transaction_comparison.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
// Copyright (c) 2022, Frappe Technologies Pvt. Ltd. and contributors | ||
// For license information, please see license.txt | ||
/* eslint-disable */ | ||
|
||
const DIFFERNCE_FIELD_NAMES = [ | ||
"fifo_qty_diff", | ||
"fifo_value_diff", | ||
]; | ||
|
||
frappe.query_reports["FIFO Queue vs Qty After Transaction Comparison"] = { | ||
"filters": [ | ||
{ | ||
"fieldname": "item_code", | ||
"fieldtype": "Link", | ||
"label": "Item", | ||
"options": "Item", | ||
get_query: function() { | ||
return { | ||
filters: {is_stock_item: 1, has_serial_no: 0} | ||
} | ||
} | ||
}, | ||
{ | ||
"fieldname": "item_group", | ||
"fieldtype": "Link", | ||
"label": "Item Group", | ||
"options": "Item Group", | ||
}, | ||
{ | ||
"fieldname": "warehouse", | ||
"fieldtype": "Link", | ||
"label": "Warehouse", | ||
"options": "Warehouse", | ||
}, | ||
{ | ||
"fieldname": "from_date", | ||
"fieldtype": "Date", | ||
"label": "From Posting Date", | ||
}, | ||
{ | ||
"fieldname": "to_date", | ||
"fieldtype": "Date", | ||
"label": "From Posting Date", | ||
} | ||
], | ||
formatter (value, row, column, data, default_formatter) { | ||
value = default_formatter(value, row, column, data); | ||
if (DIFFERNCE_FIELD_NAMES.includes(column.fieldname) && Math.abs(data[column.fieldname]) > 0.001) { | ||
value = "<span style='color:red'>" + value + "</span>"; | ||
} | ||
return value; | ||
}, | ||
}; |
27 changes: 27 additions & 0 deletions
27
...e_vs_qty_after_transaction_comparison/fifo_queue_vs_qty_after_transaction_comparison.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
{ | ||
"add_total_row": 0, | ||
"columns": [], | ||
"creation": "2022-05-11 04:09:13.460652", | ||
"disable_prepared_report": 0, | ||
"disabled": 0, | ||
"docstatus": 0, | ||
"doctype": "Report", | ||
"filters": [], | ||
"idx": 0, | ||
"is_standard": "Yes", | ||
"letter_head": "abc", | ||
"modified": "2022-05-11 04:09:20.232177", | ||
"modified_by": "Administrator", | ||
"module": "Stock", | ||
"name": "FIFO Queue vs Qty After Transaction Comparison", | ||
"owner": "Administrator", | ||
"prepared_report": 0, | ||
"ref_doctype": "Stock Ledger Entry", | ||
"report_name": "FIFO Queue vs Qty After Transaction Comparison", | ||
"report_type": "Script Report", | ||
"roles": [ | ||
{ | ||
"role": "Administrator" | ||
} | ||
] | ||
} |
212 changes: 212 additions & 0 deletions
212
...eue_vs_qty_after_transaction_comparison/fifo_queue_vs_qty_after_transaction_comparison.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,212 @@ | ||
# Copyright (c) 2022, Frappe Technologies Pvt. Ltd. and contributors | ||
# For license information, please see license.txt | ||
|
||
import json | ||
|
||
import frappe | ||
from frappe import _ | ||
from frappe.utils import flt | ||
from frappe.utils.nestedset import get_descendants_of | ||
|
||
SLE_FIELDS = ( | ||
"name", | ||
"item_code", | ||
"warehouse", | ||
"posting_date", | ||
"posting_time", | ||
"creation", | ||
"voucher_type", | ||
"voucher_no", | ||
"actual_qty", | ||
"qty_after_transaction", | ||
"stock_queue", | ||
"batch_no", | ||
"stock_value", | ||
"valuation_rate", | ||
) | ||
|
||
|
||
def execute(filters=None): | ||
columns = get_columns() | ||
data = get_data(filters) | ||
return columns, data | ||
|
||
|
||
def get_data(filters): | ||
if not any([filters.warehouse, filters.item_code, filters.item_group]): | ||
frappe.throw(_("Any one of following filters required: warehouse, Item Code, Item Group")) | ||
sles = get_stock_ledger_entries(filters) | ||
return find_first_bad_queue(sles) | ||
|
||
|
||
def get_stock_ledger_entries(filters): | ||
|
||
sle_filters = {"is_cancelled": 0} | ||
|
||
if filters.warehouse: | ||
children = get_descendants_of("Warehouse", filters.warehouse) | ||
sle_filters["warehouse"] = ("in", children + [filters.warehouse]) | ||
|
||
if filters.item_code: | ||
sle_filters["item_code"] = filters.item_code | ||
elif filters.get("item_group"): | ||
item_group = filters.get("item_group") | ||
children = get_descendants_of("Item Group", item_group) | ||
item_group_filter = {"item_group": ("in", children + [item_group])} | ||
sle_filters["item_code"] = ( | ||
"in", | ||
frappe.get_all("Item", filters=item_group_filter, pluck="name", order_by=None), | ||
) | ||
|
||
if filters.from_date: | ||
sle_filters["posting_date"] = (">=", filters.from_date) | ||
if filters.to_date: | ||
sle_filters["posting_date"] = ("<=", filters.to_date) | ||
|
||
return frappe.get_all( | ||
"Stock Ledger Entry", | ||
fields=SLE_FIELDS, | ||
filters=sle_filters, | ||
order_by="timestamp(posting_date, posting_time), creation", | ||
) | ||
|
||
|
||
def find_first_bad_queue(sles): | ||
item_warehouse_sles = {} | ||
for sle in sles: | ||
item_warehouse_sles.setdefault((sle.item_code, sle.warehouse), []).append(sle) | ||
|
||
data = [] | ||
|
||
for _item_wh, sles in item_warehouse_sles.items(): | ||
for idx, sle in enumerate(sles): | ||
queue = json.loads(sle.stock_queue or "[]") | ||
|
||
sle.fifo_queue_qty = 0.0 | ||
sle.fifo_stock_value = 0.0 | ||
for qty, rate in queue: | ||
sle.fifo_queue_qty += flt(qty) | ||
sle.fifo_stock_value += flt(qty) * flt(rate) | ||
|
||
sle.fifo_qty_diff = sle.qty_after_transaction - sle.fifo_queue_qty | ||
sle.fifo_value_diff = sle.stock_value - sle.fifo_stock_value | ||
|
||
if sle.batch_no: | ||
sle.use_batchwise_valuation = frappe.db.get_value( | ||
"Batch", sle.batch_no, "use_batchwise_valuation", cache=True | ||
) | ||
|
||
if abs(sle.fifo_qty_diff) > 0.001 or abs(sle.fifo_value_diff) > 0.1: | ||
if idx: | ||
data.append(sles[idx - 1]) | ||
data.append(sle) | ||
data.append({}) | ||
break | ||
|
||
return data | ||
|
||
|
||
def get_columns(): | ||
return [ | ||
{ | ||
"fieldname": "name", | ||
"fieldtype": "Link", | ||
"label": _("Stock Ledger Entry"), | ||
"options": "Stock Ledger Entry", | ||
}, | ||
{ | ||
"fieldname": "item_code", | ||
"fieldtype": "Link", | ||
"label": _("Item Code"), | ||
"options": "Item", | ||
}, | ||
{ | ||
"fieldname": "warehouse", | ||
"fieldtype": "Link", | ||
"label": _("Warehouse"), | ||
"options": "Warehouse", | ||
}, | ||
{ | ||
"fieldname": "posting_date", | ||
"fieldtype": "Data", | ||
"label": _("Posting Date"), | ||
}, | ||
{ | ||
"fieldname": "posting_time", | ||
"fieldtype": "Data", | ||
"label": _("Posting Time"), | ||
}, | ||
{ | ||
"fieldname": "creation", | ||
"fieldtype": "Data", | ||
"label": _("Creation"), | ||
}, | ||
{ | ||
"fieldname": "voucher_type", | ||
"fieldtype": "Link", | ||
"label": _("Voucher Type"), | ||
"options": "DocType", | ||
}, | ||
{ | ||
"fieldname": "voucher_no", | ||
"fieldtype": "Dynamic Link", | ||
"label": _("Voucher No"), | ||
"options": "voucher_type", | ||
}, | ||
{ | ||
"fieldname": "batch_no", | ||
"fieldtype": "Link", | ||
"label": _("Batch"), | ||
"options": "Batch", | ||
}, | ||
{ | ||
"fieldname": "use_batchwise_valuation", | ||
"fieldtype": "Check", | ||
"label": _("Batchwise Valuation"), | ||
}, | ||
{ | ||
"fieldname": "actual_qty", | ||
"fieldtype": "Float", | ||
"label": _("Qty Change"), | ||
}, | ||
{ | ||
"fieldname": "qty_after_transaction", | ||
"fieldtype": "Float", | ||
"label": _("(A) Qty After Transaction"), | ||
}, | ||
{ | ||
"fieldname": "stock_queue", | ||
"fieldtype": "Data", | ||
"label": _("FIFO/LIFO Queue"), | ||
}, | ||
{ | ||
"fieldname": "fifo_queue_qty", | ||
"fieldtype": "Float", | ||
"label": _("(C) Total qty in queue"), | ||
}, | ||
{ | ||
"fieldname": "fifo_qty_diff", | ||
"fieldtype": "Float", | ||
"label": _("A - C"), | ||
}, | ||
{ | ||
"fieldname": "stock_value", | ||
"fieldtype": "Float", | ||
"label": _("(D) Balance Stock Value"), | ||
}, | ||
{ | ||
"fieldname": "fifo_stock_value", | ||
"fieldtype": "Float", | ||
"label": _("(E) Balance Stock Value in Queue"), | ||
}, | ||
{ | ||
"fieldname": "fifo_value_diff", | ||
"fieldtype": "Float", | ||
"label": _("D - E"), | ||
}, | ||
{ | ||
"fieldname": "valuation_rate", | ||
"fieldtype": "Float", | ||
"label": _("(H) Valuation Rate"), | ||
}, | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters