Merge pull request #40111 from frappe/mergify/bp/version-15-hotfix/pr-40062
fix: sales person / partner achieved targets in report (backport #40062)
This commit is contained in:
commit
93f64396ac
@ -206,42 +206,36 @@ def prepare_data(
|
||||
|
||||
def get_actual_data(filters, sales_users_or_territory_data, date_field, sales_field):
|
||||
fiscal_year = get_fiscal_year(fiscal_year=filters.get("fiscal_year"), as_dict=1)
|
||||
dates = [fiscal_year.year_start_date, fiscal_year.year_end_date]
|
||||
|
||||
select_field = "`tab{0}`.{1}".format(filters.get("doctype"), sales_field)
|
||||
child_table = "`tab{0}`".format(filters.get("doctype") + " Item")
|
||||
parent_doc = frappe.qb.DocType(filters.get("doctype"))
|
||||
child_doc = frappe.qb.DocType(filters.get("doctype") + " Item")
|
||||
sales_team = frappe.qb.DocType("Sales Team")
|
||||
|
||||
query = (
|
||||
frappe.qb.from_(parent_doc)
|
||||
.inner_join(child_doc)
|
||||
.on(child_doc.parent == parent_doc.name)
|
||||
.inner_join(sales_team)
|
||||
.on(sales_team.parent == parent_doc.name)
|
||||
.select(
|
||||
child_doc.item_group,
|
||||
(child_doc.stock_qty * sales_team.allocated_percentage / 100).as_("stock_qty"),
|
||||
(child_doc.base_net_amount * sales_team.allocated_percentage / 100).as_("base_net_amount"),
|
||||
sales_team.sales_person,
|
||||
parent_doc[date_field],
|
||||
)
|
||||
.where(
|
||||
(parent_doc.docstatus == 1)
|
||||
& (parent_doc[date_field].between(fiscal_year.year_start_date, fiscal_year.year_end_date))
|
||||
)
|
||||
)
|
||||
|
||||
if sales_field == "sales_person":
|
||||
select_field = "`tabSales Team`.sales_person"
|
||||
child_table = "`tab{0}`, `tabSales Team`".format(filters.get("doctype") + " Item")
|
||||
cond = """`tabSales Team`.parent = `tab{0}`.name and
|
||||
`tabSales Team`.sales_person in ({1}) """.format(
|
||||
filters.get("doctype"), ",".join(["%s"] * len(sales_users_or_territory_data))
|
||||
)
|
||||
query = query.where(sales_team.sales_person.isin(sales_users_or_territory_data))
|
||||
else:
|
||||
cond = "`tab{0}`.{1} in ({2})".format(
|
||||
filters.get("doctype"), sales_field, ",".join(["%s"] * len(sales_users_or_territory_data))
|
||||
)
|
||||
query = query.where(parent_doc[sales_field].isin(sales_users_or_territory_data))
|
||||
|
||||
return frappe.db.sql(
|
||||
""" SELECT `tab{child_doc}`.item_group,
|
||||
`tab{child_doc}`.stock_qty, `tab{child_doc}`.base_net_amount,
|
||||
{select_field}, `tab{parent_doc}`.{date_field}
|
||||
FROM `tab{parent_doc}`, {child_table}
|
||||
WHERE
|
||||
`tab{child_doc}`.parent = `tab{parent_doc}`.name
|
||||
and `tab{parent_doc}`.docstatus = 1 and {cond}
|
||||
and `tab{parent_doc}`.{date_field} between %s and %s""".format(
|
||||
cond=cond,
|
||||
date_field=date_field,
|
||||
select_field=select_field,
|
||||
child_table=child_table,
|
||||
parent_doc=filters.get("doctype"),
|
||||
child_doc=filters.get("doctype") + " Item",
|
||||
),
|
||||
tuple(sales_users_or_territory_data + dates),
|
||||
as_dict=1,
|
||||
)
|
||||
return query.run(as_dict=True)
|
||||
|
||||
|
||||
def get_parents_data(filters, partner_doctype):
|
||||
|
@ -0,0 +1,84 @@
|
||||
import frappe
|
||||
from frappe.tests.utils import FrappeTestCase
|
||||
from frappe.utils import flt, nowdate
|
||||
|
||||
from erpnext.accounts.utils import get_fiscal_year
|
||||
from erpnext.selling.doctype.sales_order.test_sales_order import make_sales_order
|
||||
from erpnext.selling.report.sales_person_target_variance_based_on_item_group.sales_person_target_variance_based_on_item_group import (
|
||||
execute,
|
||||
)
|
||||
|
||||
|
||||
class TestSalesPersonTargetVarianceBasedOnItemGroup(FrappeTestCase):
|
||||
def setUp(self):
|
||||
self.fiscal_year = get_fiscal_year(nowdate())[0]
|
||||
|
||||
def tearDown(self):
|
||||
frappe.db.rollback()
|
||||
|
||||
def test_achieved_target_and_variance(self):
|
||||
# Create a Target Distribution
|
||||
distribution = frappe.new_doc("Monthly Distribution")
|
||||
distribution.distribution_id = "Target Report Distribution"
|
||||
distribution.fiscal_year = self.fiscal_year
|
||||
distribution.get_months()
|
||||
distribution.insert()
|
||||
|
||||
# Create sales people with targets
|
||||
person_1 = create_sales_person_with_target("Sales Person 1", self.fiscal_year, distribution.name)
|
||||
person_2 = create_sales_person_with_target("Sales Person 2", self.fiscal_year, distribution.name)
|
||||
|
||||
# Create a Sales Order with 50-50 contribution
|
||||
so = make_sales_order(
|
||||
rate=1000,
|
||||
qty=20,
|
||||
do_not_submit=True,
|
||||
)
|
||||
so.set(
|
||||
"sales_team",
|
||||
[
|
||||
{
|
||||
"sales_person": person_1.name,
|
||||
"allocated_percentage": 50,
|
||||
"allocated_amount": 10000,
|
||||
},
|
||||
{
|
||||
"sales_person": person_2.name,
|
||||
"allocated_percentage": 50,
|
||||
"allocated_amount": 10000,
|
||||
},
|
||||
],
|
||||
)
|
||||
so.submit()
|
||||
|
||||
# Check Achieved Target and Variance
|
||||
result = execute(
|
||||
frappe._dict(
|
||||
{
|
||||
"fiscal_year": self.fiscal_year,
|
||||
"doctype": "Sales Order",
|
||||
"period": "Yearly",
|
||||
"target_on": "Quantity",
|
||||
}
|
||||
)
|
||||
)[1]
|
||||
row = frappe._dict(result[0])
|
||||
self.assertSequenceEqual(
|
||||
[flt(value, 2) for value in (row.total_target, row.total_achieved, row.total_variance)],
|
||||
[50, 10, -40],
|
||||
)
|
||||
|
||||
|
||||
def create_sales_person_with_target(sales_person_name, fiscal_year, distribution_id):
|
||||
sales_person = frappe.new_doc("Sales Person")
|
||||
sales_person.sales_person_name = sales_person_name
|
||||
sales_person.append(
|
||||
"targets",
|
||||
{
|
||||
"fiscal_year": fiscal_year,
|
||||
"target_qty": 50,
|
||||
"target_amount": 30000,
|
||||
"distribution_id": distribution_id,
|
||||
},
|
||||
)
|
||||
return sales_person.insert()
|
@ -36,6 +36,7 @@ def execute(filters=None):
|
||||
d.base_net_amount,
|
||||
d.sales_person,
|
||||
d.allocated_percentage,
|
||||
(d.stock_qty * d.allocated_percentage / 100),
|
||||
d.contribution_amt,
|
||||
company_currency,
|
||||
]
|
||||
@ -103,7 +104,7 @@ def get_columns(filters):
|
||||
"fieldtype": "Link",
|
||||
"width": 140,
|
||||
},
|
||||
{"label": _("Qty"), "fieldname": "qty", "fieldtype": "Float", "width": 140},
|
||||
{"label": _("SO Total Qty"), "fieldname": "qty", "fieldtype": "Float", "width": 140},
|
||||
{
|
||||
"label": _("Amount"),
|
||||
"options": "currency",
|
||||
@ -119,6 +120,12 @@ def get_columns(filters):
|
||||
"width": 140,
|
||||
},
|
||||
{"label": _("Contribution %"), "fieldname": "contribution", "fieldtype": "Float", "width": 140},
|
||||
{
|
||||
"label": _("Contribution Qty"),
|
||||
"fieldname": "contribution_qty",
|
||||
"fieldtype": "Float",
|
||||
"width": 140,
|
||||
},
|
||||
{
|
||||
"label": _("Contribution Amount"),
|
||||
"options": "currency",
|
||||
|
Loading…
x
Reference in New Issue
Block a user