Report : Batch Item Expiry Status
Select From Date and To Date Lists Items about to expire or already expired Expiry Status column shows number of days in which item/batch will expire
This commit is contained in:
parent
2b8aafb08d
commit
0766d3e67e
@ -261,6 +261,12 @@ def get_data():
|
||||
"name": "Batch-Wise Balance History",
|
||||
"doctype": "Batch"
|
||||
},
|
||||
{
|
||||
"type": "report",
|
||||
"is_query_report": True,
|
||||
"name": "Batch Item Expiry Status",
|
||||
"doctype": "Stock Ledger Entry"
|
||||
},
|
||||
{
|
||||
"type": "report",
|
||||
"is_query_report": True,
|
||||
|
@ -0,0 +1,21 @@
|
||||
// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
frappe.query_reports["Batch Item Expiry Status"] = {
|
||||
"filters": [
|
||||
{
|
||||
"fieldname":"from_date",
|
||||
"label": __("From Date"),
|
||||
"fieldtype": "Date",
|
||||
"width": "80",
|
||||
"default": sys_defaults.year_start_date,
|
||||
},
|
||||
{
|
||||
"fieldname":"to_date",
|
||||
"label": __("To Date"),
|
||||
"fieldtype": "Date",
|
||||
"width": "80",
|
||||
"default": frappe.datetime.get_today()
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
{
|
||||
"add_total_row": 0,
|
||||
"apply_user_permissions": 1,
|
||||
"creation": "2016-12-21 11:29:01.884436",
|
||||
"disabled": 0,
|
||||
"docstatus": 0,
|
||||
"doctype": "Report",
|
||||
"idx": 0,
|
||||
"is_standard": "Yes",
|
||||
"modified": "2016-12-21 11:29:01.884436",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Stock",
|
||||
"name": "Batch Item Expiry Status",
|
||||
"owner": "Administrator",
|
||||
"ref_doctype": "Stock Ledger Entry",
|
||||
"report_name": "Batch Item Expiry Status",
|
||||
"report_type": "Script Report"
|
||||
}
|
@ -0,0 +1,94 @@
|
||||
# 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 flt, cint, getdate
|
||||
|
||||
def execute(filters=None):
|
||||
if not filters: filters = {}
|
||||
|
||||
float_precision = cint(frappe.db.get_default("float_precision")) or 3
|
||||
|
||||
columns = get_columns(filters)
|
||||
item_map = get_item_details(filters)
|
||||
iwb_map = get_item_warehouse_batch_map(filters, float_precision)
|
||||
|
||||
data = []
|
||||
for item in sorted(iwb_map):
|
||||
for wh in sorted(iwb_map[item]):
|
||||
for batch in sorted(iwb_map[item][wh]):
|
||||
qty_dict = iwb_map[item][wh][batch]
|
||||
|
||||
data.append([item, item_map[item]["item_name"], item_map[item]["description"], wh, batch,
|
||||
frappe.db.get_value('Batch', batch, 'expiry_date'), qty_dict.expiry_status
|
||||
])
|
||||
|
||||
|
||||
return columns, data
|
||||
|
||||
def get_columns(filters):
|
||||
"""return columns based on filters"""
|
||||
|
||||
columns = [_("Item") + ":Link/Item:100"] + [_("Item Name") + "::150"] + [_("Description") + "::150"] + \
|
||||
[_("Warehouse") + ":Link/Warehouse:100"] + [_("Batch") + ":Link/Batch:100"] + [_("Expires On") + ":Date:90"] + \
|
||||
[_("Expiry Status") + ":Data:120"]
|
||||
|
||||
return columns
|
||||
|
||||
def get_conditions(filters):
|
||||
conditions = ""
|
||||
if not filters.get("from_date"):
|
||||
frappe.throw(_("'From Date' is required"))
|
||||
|
||||
if filters.get("to_date"):
|
||||
conditions += " and posting_date <= '%s'" % filters["to_date"]
|
||||
else:
|
||||
frappe.throw(_("'To Date' is required"))
|
||||
|
||||
return conditions
|
||||
|
||||
def get_stock_ledger_entries(filters):
|
||||
conditions = get_conditions(filters)
|
||||
return frappe.db.sql("""select item_code, batch_no, warehouse,
|
||||
posting_date, actual_qty
|
||||
from `tabStock Ledger Entry`
|
||||
where docstatus < 2 and ifnull(batch_no, '') != '' %s order by item_code, warehouse""" %
|
||||
conditions, as_dict=1)
|
||||
|
||||
def get_item_warehouse_batch_map(filters, float_precision):
|
||||
sle = get_stock_ledger_entries(filters)
|
||||
iwb_map = {}
|
||||
|
||||
from_date = getdate(filters["from_date"])
|
||||
to_date = getdate(filters["to_date"])
|
||||
|
||||
for d in sle:
|
||||
iwb_map.setdefault(d.item_code, {}).setdefault(d.warehouse, {})\
|
||||
.setdefault(d.batch_no, frappe._dict({
|
||||
"expires_on": None, "expiry_status": None}))
|
||||
|
||||
qty_dict = iwb_map[d.item_code][d.warehouse][d.batch_no]
|
||||
|
||||
expiry_date_unicode = frappe.db.get_value('Batch', d.batch_no, 'expiry_date')
|
||||
qty_dict.expires_on = expiry_date_unicode
|
||||
|
||||
exp_date = frappe.utils.data.getdate(expiry_date_unicode)
|
||||
qty_dict.expires_on = exp_date
|
||||
|
||||
expires_in_days = (exp_date - frappe.utils.datetime.date.today()).days
|
||||
|
||||
if expires_in_days > 0:
|
||||
qty_dict.expiry_status = "Expires in {} day(s)".format(expires_in_days)
|
||||
else:
|
||||
qty_dict.expiry_status = 'Expired'
|
||||
|
||||
return iwb_map
|
||||
|
||||
def get_item_details(filters):
|
||||
item_map = {}
|
||||
for d in frappe.db.sql("select name, item_name, description from tabItem", as_dict=1):
|
||||
item_map.setdefault(d.name, d)
|
||||
|
||||
return item_map
|
Loading…
x
Reference in New Issue
Block a user