mirror of
https://github.com/frappe/erpnext.git
synced 2026-06-08 23:52:57 +00:00
[Enhancement] Pending SO Items for Purchase Request Report (#16188)
* deleted old purchase request query report * [Enhancement] pending so items for purchase request report refactor * comments and format fix * test and minor fixes * test fixes
This commit is contained in:
committed by
Rushabh Mehta
parent
083f1c5370
commit
70c5aa5f5d
@@ -0,0 +1,6 @@
|
|||||||
|
// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
|
// For license information, please see license.txt
|
||||||
|
/* eslint-disable */
|
||||||
|
|
||||||
|
frappe.query_reports["Pending SO Items For Purchase Request"] = {
|
||||||
|
}
|
||||||
@@ -1,24 +1,23 @@
|
|||||||
{
|
{
|
||||||
"add_total_row": 0,
|
"add_total_row": 0,
|
||||||
"apply_user_permissions": 1,
|
"creation": "2018-11-12 14:08:27.241332",
|
||||||
"creation": "2013-06-21 16:46:45",
|
|
||||||
"disabled": 0,
|
"disabled": 0,
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"doctype": "Report",
|
"doctype": "Report",
|
||||||
"idx": 3,
|
"idx": 0,
|
||||||
"is_standard": "Yes",
|
"is_standard": "Yes",
|
||||||
"modified": "2017-02-24 20:08:11.744036",
|
"modified": "2018-11-12 14:08:27.241332",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Selling",
|
"module": "Selling",
|
||||||
"name": "Pending SO Items For Purchase Request",
|
"name": "Pending SO Items For Purchase Request",
|
||||||
"owner": "Administrator",
|
"owner": "Administrator",
|
||||||
"query": "select so_item.item_code as \"Item Code:Link/Item:120\",\n so_item.item_name as \"Item Name::120\",\n so_item.description as \"Description::120\",\n so.`name` as \"S.O. No.:Link/Sales Order:120\",\n so.`transaction_date` as \"Date:Date:120\",\n mr.name as \"Material Request:Link/Material Request:120\",\n so.customer as \"Customer:Link/Customer:120\",\n so.territory as \"Terretory:Link/Territory:120\",\n sum(so_item.qty) as \"SO Qty:Float:100 \",\n sum(mr_item.qty) as \"Requested Qty:Float:100\",\n sum(so_item.qty) - sum(mr_item.qty) as \"Pending Qty:Float:100 \", \n so.company as \"Company:Link/Company:\"\nfrom\n `tabSales Order` so, `tabSales Order Item` so_item, \n `tabMaterial Request` mr, `tabMaterial Request Item` mr_item\nwhere \n so_item.`parent` = so.`name` \n and mr_item.parent = mr.name\n and mr_item.sales_order = so.name\n and mr_item.item_code = so_item.item_code\n and so.docstatus = 1 and so.status != \"Closed\" \n and mr.docstatus = 1 and mr.status != \"Stopped\"\ngroup by so.name, so_item.item_code\nhaving sum(so_item.qty) > sum(mr_item.qty)\norder by so.name desc, so_item.item_code asc",
|
"prepared_report": 0,
|
||||||
"ref_doctype": "Sales Order",
|
"ref_doctype": "Sales Order",
|
||||||
"report_name": "Pending SO Items For Purchase Request",
|
"report_name": "Pending SO Items For Purchase Request",
|
||||||
"report_type": "Query Report",
|
"report_type": "Script Report",
|
||||||
"roles": [
|
"roles": [
|
||||||
{
|
{
|
||||||
"role": "Sales User"
|
"role": "Stock User"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"role": "Sales Manager"
|
"role": "Sales Manager"
|
||||||
@@ -30,7 +29,7 @@
|
|||||||
"role": "Accounts User"
|
"role": "Accounts User"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"role": "Stock User"
|
"role": "Sales User"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,148 @@
|
|||||||
|
# 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 cint,cstr
|
||||||
|
|
||||||
|
def execute(filters=None):
|
||||||
|
columns = get_columns()
|
||||||
|
data = get_data()
|
||||||
|
return columns, data
|
||||||
|
|
||||||
|
def get_columns():
|
||||||
|
columns = [
|
||||||
|
{
|
||||||
|
"label": _("Item Code"),
|
||||||
|
"options": "Item",
|
||||||
|
"fieldname": "item_code",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"width": 200
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": _("Item Name"),
|
||||||
|
"fieldname": "item_name",
|
||||||
|
"fieldtype": "Data",
|
||||||
|
"width": 200
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": _("Description"),
|
||||||
|
"fieldname": "description",
|
||||||
|
"fieldtype": "Data",
|
||||||
|
"width": 140
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": _("S.O. No."),
|
||||||
|
"options": "Sales Order",
|
||||||
|
"fieldname": "sales_order_no",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"width": 140
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": _("Date"),
|
||||||
|
"fieldname": "date",
|
||||||
|
"fieldtype": "Date",
|
||||||
|
"width": 140
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": _("Material Request"),
|
||||||
|
"options": "Material Request",
|
||||||
|
"fieldname": "material_request",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"width": 140
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": _("Customer"),
|
||||||
|
"fieldname": "customer",
|
||||||
|
"fieldtype": "Data",
|
||||||
|
"width": 140
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": _("Territory"),
|
||||||
|
"fieldname": "territory",
|
||||||
|
"fieldtype": "Data",
|
||||||
|
"width": 140
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": _("SO Qty"),
|
||||||
|
"fieldname": "so_qty",
|
||||||
|
"fieldtype": "Float",
|
||||||
|
"width": 140
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": _("Requested Qty"),
|
||||||
|
"fieldname": "requested_qty",
|
||||||
|
"fieldtype": "Float",
|
||||||
|
"width": 140
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": _("Pending Qty"),
|
||||||
|
"fieldname": "pending_qty",
|
||||||
|
"fieldtype": "Float",
|
||||||
|
"width": 140
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": _("Company"),
|
||||||
|
"fieldname": "company",
|
||||||
|
"fieldtype": "Data",
|
||||||
|
"width": 140
|
||||||
|
}
|
||||||
|
]
|
||||||
|
return columns
|
||||||
|
|
||||||
|
def get_data():
|
||||||
|
sales_order_entry = frappe.db.sql("""
|
||||||
|
SELECT
|
||||||
|
so_item.item_code,
|
||||||
|
so_item.item_name,
|
||||||
|
so_item.description,
|
||||||
|
so.name,
|
||||||
|
so.transaction_date,
|
||||||
|
so.customer,
|
||||||
|
so.territory,
|
||||||
|
sum(so_item.qty) as net_qty,
|
||||||
|
so.company
|
||||||
|
FROM `tabSales Order` so, `tabSales Order Item` so_item
|
||||||
|
WHERE
|
||||||
|
so.docstatus = 1
|
||||||
|
and so.name = so_item.parent
|
||||||
|
and so.status not in ("Closed","Completed","Cancelled")
|
||||||
|
GROUP BY
|
||||||
|
so.name,so_item.item_code
|
||||||
|
""", as_dict = 1)
|
||||||
|
|
||||||
|
mr_records = frappe.get_all("Material Request Item",
|
||||||
|
{"sales_order_item": ("!=",""), "docstatus": 1},
|
||||||
|
["parent", "qty", "sales_order", "item_code"])
|
||||||
|
|
||||||
|
grouped_records = {}
|
||||||
|
|
||||||
|
for record in mr_records:
|
||||||
|
grouped_records.setdefault(record.sales_order, []).append(record)
|
||||||
|
|
||||||
|
pending_so=[]
|
||||||
|
for so in sales_order_entry:
|
||||||
|
# fetch all the material request records for a sales order item
|
||||||
|
mr_list = grouped_records.get(so.name) or [{}]
|
||||||
|
mr_item_record = ([mr for mr in mr_list if mr.get('item_code') == so.item_code] or [{}])
|
||||||
|
|
||||||
|
for mr in mr_item_record:
|
||||||
|
# check for pending sales order
|
||||||
|
if cint(so.net_qty) > cint(mr.get('qty')):
|
||||||
|
so_record = {
|
||||||
|
"item_code": so.item_code,
|
||||||
|
"item_name": so.item_name,
|
||||||
|
"description": so.description,
|
||||||
|
"sales_order_no": so.name,
|
||||||
|
"date": so.transaction_date,
|
||||||
|
"material_request": cstr(mr.get('parent')),
|
||||||
|
"customer": so.customer,
|
||||||
|
"territory": so.territory,
|
||||||
|
"so_qty": so.net_qty,
|
||||||
|
"requested_qty": cint(mr.get('qty')),
|
||||||
|
"pending_qty": so.net_qty - cint(mr.get('qty')),
|
||||||
|
"company": so.company
|
||||||
|
}
|
||||||
|
pending_so.append(so_record)
|
||||||
|
return pending_so
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
# Copyright (c) 2013, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
|
# For license information, please see license.txt
|
||||||
|
|
||||||
|
import unittest
|
||||||
|
from frappe.utils import nowdate, add_months
|
||||||
|
from erpnext.selling.report.pending_so_items_for_purchase_request.pending_so_items_for_purchase_request\
|
||||||
|
import execute
|
||||||
|
from erpnext.selling.doctype.sales_order.sales_order import make_material_request
|
||||||
|
from erpnext.selling.doctype.sales_order.test_sales_order import make_sales_order
|
||||||
|
|
||||||
|
|
||||||
|
class TestPendingSOItemsForPurchaseRequest(unittest.TestCase):
|
||||||
|
def test_result_for_partial_material_request(self):
|
||||||
|
so = make_sales_order()
|
||||||
|
mr=make_material_request(so.name)
|
||||||
|
mr.items[0].qty = 4
|
||||||
|
mr.schedule_date = add_months(nowdate(),1)
|
||||||
|
mr.submit()
|
||||||
|
report = execute()
|
||||||
|
l = len(report[1])
|
||||||
|
self.assertEqual((so.items[0].qty - mr.items[0].qty), report[1][l-1]['pending_qty'])
|
||||||
|
|
||||||
|
def test_result_for_so_item(self):
|
||||||
|
so = make_sales_order()
|
||||||
|
report = execute()
|
||||||
|
l = len(report[1])
|
||||||
|
self.assertEqual(so.items[0].qty, report[1][l-1]['pending_qty'])
|
||||||
Reference in New Issue
Block a user