feat: commonified item group wise target variance report
This commit is contained in:
parent
7779bb3839
commit
1c1d0bb1c7
@ -3,8 +3,8 @@
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe.utils import flt
|
||||
from frappe import _
|
||||
from frappe.utils import (flt, add_months)
|
||||
from frappe.model.document import Document
|
||||
|
||||
class MonthlyDistribution(Document):
|
||||
@ -25,3 +25,33 @@ class MonthlyDistribution(Document):
|
||||
if flt(total, 2) != 100.0:
|
||||
frappe.throw(_("Percentage Allocation should be equal to 100%") + \
|
||||
" ({0}%)".format(str(flt(total, 2))))
|
||||
|
||||
def get_periodwise_distribution_data(distribution_id, period_list, periodicity):
|
||||
doc = frappe.get_doc('Monthly Distribution', distribution_id)
|
||||
|
||||
months_to_add = {
|
||||
"Yearly": 12,
|
||||
"Half-Yearly": 6,
|
||||
"Quarterly": 3,
|
||||
"Monthly": 1
|
||||
}[periodicity]
|
||||
|
||||
period_dict = {}
|
||||
|
||||
for d in period_list:
|
||||
period_dict[d.key] = get_percentage(doc, d.from_date, months_to_add)
|
||||
|
||||
return period_dict
|
||||
|
||||
def get_percentage(doc, start_date, period):
|
||||
percentage = 0
|
||||
months = [start_date.strftime("%B").title()]
|
||||
|
||||
for r in range(1, period):
|
||||
months.append(add_months(start_date, r).strftime("%B").title())
|
||||
|
||||
for d in doc.percentages:
|
||||
if d.month in months:
|
||||
percentage += d.percentage_allocation
|
||||
|
||||
return percentage
|
@ -591,3 +591,4 @@ erpnext.patches.v12_0.add_item_name_in_work_orders
|
||||
erpnext.patches.v12_0.update_pricing_rule_fields
|
||||
erpnext.patches.v11_1.make_job_card_time_logs
|
||||
erpnext.patches.v12_0.rename_pricing_rule_child_doctypes
|
||||
erpnext.patches.v12_0.move_target_distribution_from_parent_to_child
|
||||
|
@ -0,0 +1,18 @@
|
||||
# Copyright (c) 2017, Frappe and Contributors
|
||||
# License: GNU General Public License v3. See license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
|
||||
def execute():
|
||||
frappe.reload_doc("setup", "doctype", "target_detail")
|
||||
|
||||
for d in ['Sales Person', 'Sales Partner', 'Territory']:
|
||||
frappe.db.sql("""
|
||||
UPDATE `tab{child_doc}`, `tab{parent_doc}`
|
||||
SET
|
||||
`tab{child_doc}`.distribution_id = `tab{parent_doc}`.distribution_id
|
||||
WHERE
|
||||
`tab{child_doc}`.parent = `tab{parent_doc}`.name
|
||||
and `tab{parent_doc}`.distribution_id is not null and `tab{parent_doc}`.distribution_id != ''
|
||||
""".format(parent_doc = d, child_doc = "Target Detail"))
|
@ -0,0 +1,211 @@
|
||||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# License: GNU General Public License v3. See license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe import _
|
||||
from frappe.utils import flt
|
||||
from erpnext.accounts.utils import get_fiscal_year
|
||||
from erpnext.accounts.report.financial_statements import get_period_list
|
||||
from erpnext.accounts.doctype.monthly_distribution.monthly_distribution import get_periodwise_distribution_data
|
||||
|
||||
def get_data_column(filters, partner_doctype):
|
||||
data = []
|
||||
period_list = get_period_list(filters.fiscal_year, filters.fiscal_year,
|
||||
filters.period, company=filters.company)
|
||||
|
||||
rows = get_data(filters, period_list, partner_doctype)
|
||||
columns = get_columns(filters, period_list, partner_doctype)
|
||||
|
||||
if not rows:
|
||||
return columns, data
|
||||
|
||||
for key, value in rows.items():
|
||||
value.update({
|
||||
frappe.scrub(partner_doctype): key[0],
|
||||
'item_group': key[1]
|
||||
})
|
||||
|
||||
data.append(value)
|
||||
|
||||
return columns, data
|
||||
|
||||
def get_data(filters, period_list, partner_doctype):
|
||||
sales_field = frappe.scrub(partner_doctype)
|
||||
sales_users_data = get_parents_data(filters, partner_doctype)
|
||||
|
||||
if not sales_users_data: return
|
||||
sales_users, item_groups = [], []
|
||||
|
||||
for d in sales_users_data:
|
||||
if d.parent not in sales_users:
|
||||
sales_users.append(d.parent)
|
||||
|
||||
if d.item_group not in item_groups:
|
||||
item_groups.append(d.item_group)
|
||||
|
||||
date_field = ("transaction_date"
|
||||
if filters.get('doctype') == "Sales Order" else "posting_date")
|
||||
|
||||
actual_data = get_actual_data(filters, item_groups, sales_users, date_field, sales_field)
|
||||
|
||||
return prepare_data(filters, sales_users_data,
|
||||
actual_data, date_field, period_list, sales_field)
|
||||
|
||||
def get_columns(filters, period_list, partner_doctype):
|
||||
fieldtype, options = "Currency", "currency"
|
||||
|
||||
if filters.get("target_on") == 'Quantity':
|
||||
fieldtype, options = "Float", ""
|
||||
|
||||
columns = [{
|
||||
"fieldname": frappe.scrub(partner_doctype),
|
||||
"label": _(partner_doctype),
|
||||
"fieldtype": "Link",
|
||||
"options": partner_doctype,
|
||||
"width": 100
|
||||
}, {
|
||||
"fieldname": "item_group",
|
||||
"label": _("Item Group"),
|
||||
"fieldtype": "Link",
|
||||
"options": "Item Group",
|
||||
"width": 100
|
||||
}]
|
||||
|
||||
for period in period_list:
|
||||
target_key = 'target_{}'.format(period.key)
|
||||
variance_key = 'variance_{}'.format(period.key)
|
||||
|
||||
columns.extend([{
|
||||
"fieldname": target_key,
|
||||
"label": _("Target ({})".format(period.label)),
|
||||
"fieldtype": fieldtype,
|
||||
"options": options,
|
||||
"width": 100
|
||||
}, {
|
||||
"fieldname": period.key,
|
||||
"label": _("Achieved ({})".format(period.label)),
|
||||
"fieldtype": fieldtype,
|
||||
"options": options,
|
||||
"width": 100
|
||||
}, {
|
||||
"fieldname": variance_key,
|
||||
"label": _("Variance ({})".format(period.label)),
|
||||
"fieldtype": fieldtype,
|
||||
"options": options,
|
||||
"width": 100
|
||||
}])
|
||||
|
||||
columns.extend([{
|
||||
"fieldname": "total_target",
|
||||
"label": _("Total Target"),
|
||||
"fieldtype": fieldtype,
|
||||
"options": options,
|
||||
"width": 100
|
||||
}, {
|
||||
"fieldname": "total_achieved",
|
||||
"label": _("Total Achieved"),
|
||||
"fieldtype": fieldtype,
|
||||
"options": options,
|
||||
"width": 100
|
||||
}, {
|
||||
"fieldname": "total_variance",
|
||||
"label": _("Total Variance"),
|
||||
"fieldtype": fieldtype,
|
||||
"options": options,
|
||||
"width": 100
|
||||
}])
|
||||
|
||||
return columns
|
||||
|
||||
def prepare_data(filters, sales_users_data, actual_data, date_field, period_list, sales_field):
|
||||
rows = {}
|
||||
|
||||
target_qty_amt_field = ("target_qty"
|
||||
if filters.get("target_on") == 'Quantity' else "target_amount")
|
||||
|
||||
qty_or_amount_field = ("stock_qty"
|
||||
if filters.get("target_on") == 'Quantity' else "base_net_amount")
|
||||
|
||||
for d in sales_users_data:
|
||||
key = (d.parent, d.item_group)
|
||||
dist_data = get_periodwise_distribution_data(d.distribution_id, period_list, filters.get("period"))
|
||||
|
||||
if key not in rows:
|
||||
rows.setdefault(key,{
|
||||
'total_target': 0,
|
||||
'total_achieved': 0,
|
||||
'total_variance': 0
|
||||
})
|
||||
|
||||
details = rows[key]
|
||||
for period in period_list:
|
||||
p_key = period.key
|
||||
if p_key not in details:
|
||||
details[p_key] = 0
|
||||
|
||||
target_key = 'target_{}'.format(p_key)
|
||||
variance_key = 'variance_{}'.format(p_key)
|
||||
details[target_key] = (d.get(target_qty_amt_field) * dist_data.get(p_key)) / 100
|
||||
details[variance_key] = 0
|
||||
details["total_target"] += details[target_key]
|
||||
|
||||
for r in actual_data:
|
||||
if (r.get(sales_field) == d.parent and r.item_group == d.item_group and
|
||||
period.from_date <= r.get(date_field) and r.get(date_field) <= period.to_date):
|
||||
details[p_key] += r.get(qty_or_amount_field, 0)
|
||||
details[variance_key] = details.get(target_key) - details.get(p_key)
|
||||
|
||||
details["total_achieved"] += details.get(p_key)
|
||||
details["total_variance"] = details.get("total_target") - details.get("total_achieved")
|
||||
|
||||
return rows
|
||||
|
||||
def get_actual_data(filters, item_groups, 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')
|
||||
|
||||
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)))
|
||||
else:
|
||||
cond = "`tab{0}`.{1} in ({2})".format(filters.get("doctype"), sales_field,
|
||||
','.join(['%s'] * len(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{child_doc}`.item_group in ({item_groups})
|
||||
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',
|
||||
item_groups = ','.join(['%s'] * len(item_groups))
|
||||
), tuple(sales_users_or_territory_data + item_groups + dates), as_dict=1, debug=1)
|
||||
|
||||
def get_parents_data(filters, partner_doctype):
|
||||
filters_dict = {'parenttype': partner_doctype}
|
||||
|
||||
target_qty_amt_field = ("target_qty"
|
||||
if filters.get("target_on") == 'Quantity' else "target_amount")
|
||||
|
||||
if filters.get("fiscal_year"):
|
||||
filters_dict["fiscal_year"] = filters.get("fiscal_year")
|
||||
|
||||
return frappe.get_all('Target Detail',
|
||||
filters = filters_dict,
|
||||
fields = ["parent", "item_group", target_qty_amt_field, "fiscal_year", "distribution_id"])
|
@ -0,0 +1,48 @@
|
||||
// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
|
||||
// For license information, please see license.txt
|
||||
/* eslint-disable */
|
||||
|
||||
frappe.query_reports["Sales Partner Target Variance Item Group-Wise"] = {
|
||||
"filters": [
|
||||
{
|
||||
fieldname:"company",
|
||||
label: __("Company"),
|
||||
fieldtype: "Link",
|
||||
options: "Company",
|
||||
default: frappe.defaults.get_user_default("Company")
|
||||
},
|
||||
{
|
||||
fieldname: "fiscal_year",
|
||||
label: __("Fiscal Year"),
|
||||
fieldtype: "Link",
|
||||
options: "Fiscal Year",
|
||||
default: frappe.sys_defaults.fiscal_year
|
||||
},
|
||||
{
|
||||
fieldname: "doctype",
|
||||
label: __("Document Type"),
|
||||
fieldtype: "Select",
|
||||
options: "Sales Order\nDelivery Note\nSales Invoice",
|
||||
default: "Sales Order"
|
||||
},
|
||||
{
|
||||
fieldname: "period",
|
||||
label: __("Period"),
|
||||
fieldtype: "Select",
|
||||
options: [
|
||||
{ "value": "Monthly", "label": __("Monthly") },
|
||||
{ "value": "Quarterly", "label": __("Quarterly") },
|
||||
{ "value": "Half-Yearly", "label": __("Half-Yearly") },
|
||||
{ "value": "Yearly", "label": __("Yearly") }
|
||||
],
|
||||
default: "Monthly"
|
||||
},
|
||||
{
|
||||
fieldname: "target_on",
|
||||
label: __("Target On"),
|
||||
fieldtype: "Select",
|
||||
options: "Quantity\nAmount",
|
||||
default: "Quantity"
|
||||
},
|
||||
]
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
{
|
||||
"add_total_row": 0,
|
||||
"creation": "2019-03-15 17:42:00.631020",
|
||||
"disable_prepared_report": 0,
|
||||
"disabled": 0,
|
||||
"docstatus": 0,
|
||||
"doctype": "Report",
|
||||
"idx": 0,
|
||||
"is_standard": "Yes",
|
||||
"letter_head": "Gadgets International",
|
||||
"modified": "2019-03-15 17:42:00.631020",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Selling",
|
||||
"name": "Sales Partner Target Variance Item Group-Wise",
|
||||
"owner": "Administrator",
|
||||
"prepared_report": 0,
|
||||
"ref_doctype": "Sales Order",
|
||||
"report_name": "Sales Partner Target Variance Item Group-Wise",
|
||||
"report_type": "Script Report",
|
||||
"roles": [
|
||||
{
|
||||
"role": "Sales User"
|
||||
},
|
||||
{
|
||||
"role": "Sales Manager"
|
||||
},
|
||||
{
|
||||
"role": "Maintenance User"
|
||||
},
|
||||
{
|
||||
"role": "Accounts User"
|
||||
},
|
||||
{
|
||||
"role": "Stock User"
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# License: GNU General Public License v3. See license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
from erpnext.selling.report.sales_partner_target_variance_item_group_wise.item_group_wise_sales_target_variance import get_data_column
|
||||
|
||||
def execute(filters=None):
|
||||
data = []
|
||||
|
||||
return get_data_column(filters, "Sales Partner")
|
||||
|
@ -3,6 +3,13 @@
|
||||
|
||||
frappe.query_reports["Sales Person Target Variance Item Group-Wise"] = {
|
||||
"filters": [
|
||||
{
|
||||
fieldname:"company",
|
||||
label: __("Company"),
|
||||
fieldtype: "Link",
|
||||
options: "Company",
|
||||
default: frappe.defaults.get_user_default("Company")
|
||||
},
|
||||
{
|
||||
fieldname: "fiscal_year",
|
||||
label: __("Fiscal Year"),
|
||||
@ -10,6 +17,13 @@ frappe.query_reports["Sales Person Target Variance Item Group-Wise"] = {
|
||||
options: "Fiscal Year",
|
||||
default: frappe.sys_defaults.fiscal_year
|
||||
},
|
||||
{
|
||||
fieldname: "doctype",
|
||||
label: __("Document Type"),
|
||||
fieldtype: "Select",
|
||||
options: "Sales Order\nDelivery Note\nSales Invoice",
|
||||
default: "Sales Order"
|
||||
},
|
||||
{
|
||||
fieldname: "period",
|
||||
label: __("Period"),
|
||||
|
@ -3,176 +3,10 @@
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe import _, msgprint
|
||||
from frappe.utils import flt
|
||||
from erpnext.accounts.utils import get_fiscal_year
|
||||
from erpnext.controllers.trends import get_period_date_ranges, get_period_month_ranges
|
||||
from erpnext.selling.report.sales_partner_target_variance_item_group_wise.item_group_wise_sales_target_variance import get_data_column
|
||||
|
||||
def execute(filters=None):
|
||||
if not filters: filters = {}
|
||||
|
||||
columns = get_columns(filters)
|
||||
period_month_ranges = get_period_month_ranges(filters["period"], filters["fiscal_year"])
|
||||
sim_map = get_salesperson_item_month_map(filters)
|
||||
|
||||
data = []
|
||||
for salesperson, salesperson_items in sim_map.items():
|
||||
for item_group, monthwise_data in salesperson_items.items():
|
||||
row = [salesperson, item_group]
|
||||
totals = [0, 0, 0]
|
||||
for relevant_months in period_month_ranges:
|
||||
period_data = [0, 0, 0]
|
||||
for month in relevant_months:
|
||||
month_data = monthwise_data.get(month, {})
|
||||
for i, fieldname in enumerate(["target", "achieved", "variance"]):
|
||||
value = flt(month_data.get(fieldname))
|
||||
period_data[i] += value
|
||||
totals[i] += value
|
||||
period_data[2] = period_data[0] - period_data[1]
|
||||
row += period_data
|
||||
totals[2] = totals[0] - totals[1]
|
||||
row += totals
|
||||
data.append(row)
|
||||
|
||||
return columns, sorted(data, key=lambda x: (x[0], x[1]))
|
||||
|
||||
def get_columns(filters):
|
||||
for fieldname in ["fiscal_year", "period", "target_on"]:
|
||||
if not filters.get(fieldname):
|
||||
label = (" ".join(fieldname.split("_"))).title()
|
||||
msgprint(_("Please specify") + ": " + label,
|
||||
raise_exception=True)
|
||||
|
||||
columns = [_("Sales Person") + ":Link/Sales Person:120", _("Item Group") + ":Link/Item Group:120"]
|
||||
|
||||
group_months = False if filters["period"] == "Monthly" else True
|
||||
|
||||
for from_date, to_date in get_period_date_ranges(filters["period"], filters["fiscal_year"]):
|
||||
for label in [_("Target") + " (%s)", _("Achieved") + " (%s)", _("Variance") + " (%s)"]:
|
||||
if group_months:
|
||||
label = label % (_(from_date.strftime("%b")) + " - " + _(to_date.strftime("%b")))
|
||||
else:
|
||||
label = label % _(from_date.strftime("%b"))
|
||||
|
||||
columns.append(label+":Float:120")
|
||||
|
||||
return columns + [_("Total Target") + ":Float:120", _("Total Achieved") + ":Float:120",
|
||||
_("Total Variance") + ":Float:120"]
|
||||
|
||||
#Get sales person & item group details
|
||||
def get_salesperson_details(filters):
|
||||
return frappe.db.sql("""
|
||||
select
|
||||
sp.name, td.item_group, td.target_qty, td.target_amount, sp.distribution_id
|
||||
from
|
||||
`tabSales Person` sp, `tabTarget Detail` td
|
||||
where
|
||||
td.parent=sp.name and td.fiscal_year=%s order by sp.name
|
||||
""", (filters["fiscal_year"]), as_dict=1)
|
||||
|
||||
#Get target distribution details of item group
|
||||
def get_target_distribution_details(filters):
|
||||
target_details = {}
|
||||
|
||||
for d in frappe.db.sql("""
|
||||
select
|
||||
md.name, mdp.month, mdp.percentage_allocation
|
||||
from
|
||||
`tabMonthly Distribution Percentage` mdp, `tabMonthly Distribution` md
|
||||
where
|
||||
mdp.parent=md.name and md.fiscal_year=%s
|
||||
""", (filters["fiscal_year"]), as_dict=1):
|
||||
target_details.setdefault(d.name, {}).setdefault(d.month, flt(d.percentage_allocation))
|
||||
|
||||
return target_details
|
||||
|
||||
#Get achieved details from sales order
|
||||
def get_achieved_details(filters, sales_person, all_sales_persons, target_item_group, item_groups):
|
||||
start_date, end_date = get_fiscal_year(fiscal_year = filters["fiscal_year"])[1:]
|
||||
|
||||
item_details = frappe.db.sql("""
|
||||
SELECT st.sales_person, MONTHNAME(so.transaction_date) as month_name,
|
||||
CASE
|
||||
WHEN so.status = "Closed" THEN sum(soi.delivered_qty * soi.conversion_factor * (st.allocated_percentage/100))
|
||||
ELSE sum(soi.stock_qty * (st.allocated_percentage/100))
|
||||
END as qty,
|
||||
CASE
|
||||
WHEN so.status = "Closed" THEN sum(soi.delivered_qty * soi.conversion_factor * soi.base_net_rate * (st.allocated_percentage/100))
|
||||
ELSE sum(soi.base_net_amount * (st.allocated_percentage/100))
|
||||
END as amount
|
||||
from
|
||||
`tabSales Order Item` soi, `tabSales Order` so, `tabSales Team` st
|
||||
where
|
||||
soi.parent=so.name and so.docstatus=1 and st.parent=so.name
|
||||
and so.transaction_date>=%s and so.transaction_date<=%s
|
||||
and exists(SELECT name from `tabSales Person` where lft >= %s and rgt <= %s and name=st.sales_person)
|
||||
and exists(SELECT name from `tabItem Group` where lft >= %s and rgt <= %s and name=soi.item_group)
|
||||
group by
|
||||
sales_person, month_name
|
||||
""",
|
||||
(start_date, end_date, all_sales_persons[sales_person].lft, all_sales_persons[sales_person].rgt,
|
||||
item_groups[target_item_group].lft, item_groups[target_item_group].rgt), as_dict=1)
|
||||
|
||||
actual_details = {}
|
||||
for d in item_details:
|
||||
actual_details.setdefault(d.month_name, frappe._dict({
|
||||
"quantity" : 0,
|
||||
"amount" : 0
|
||||
}))
|
||||
|
||||
value_dict = actual_details[d.month_name]
|
||||
value_dict.quantity += flt(d.qty)
|
||||
value_dict.amount += flt(d.amount)
|
||||
|
||||
return actual_details
|
||||
|
||||
def get_salesperson_item_month_map(filters):
|
||||
import datetime
|
||||
salesperson_details = get_salesperson_details(filters)
|
||||
tdd = get_target_distribution_details(filters)
|
||||
item_groups = get_item_groups()
|
||||
sales_persons = get_sales_persons()
|
||||
|
||||
sales_person_achievement_dict = {}
|
||||
for sd in salesperson_details:
|
||||
achieved_details = get_achieved_details(filters, sd.name, sales_persons, sd.item_group, item_groups)
|
||||
|
||||
for month_id in range(1, 13):
|
||||
month = datetime.date(2013, month_id, 1).strftime('%B')
|
||||
sales_person_achievement_dict.setdefault(sd.name, {}).setdefault(sd.item_group, {})\
|
||||
.setdefault(month, frappe._dict({
|
||||
"target": 0.0, "achieved": 0.0
|
||||
}))
|
||||
|
||||
sales_target_achieved = sales_person_achievement_dict[sd.name][sd.item_group][month]
|
||||
month_percentage = tdd.get(sd.distribution_id, {}).get(month, 0) \
|
||||
if sd.distribution_id else 100.0/12
|
||||
|
||||
if (filters["target_on"] == "Quantity"):
|
||||
sales_target_achieved.target = flt(sd.target_qty) * month_percentage / 100
|
||||
else:
|
||||
sales_target_achieved.target = flt(sd.target_amount) * month_percentage / 100
|
||||
|
||||
sales_target_achieved.achieved = achieved_details.get(month, frappe._dict())\
|
||||
.get(filters["target_on"].lower())
|
||||
|
||||
return sales_person_achievement_dict
|
||||
|
||||
def get_item_groups():
|
||||
item_groups = frappe._dict()
|
||||
for d in frappe.get_all("Item Group", fields=["name", "lft", "rgt"]):
|
||||
item_groups.setdefault(d.name, frappe._dict({
|
||||
"lft": d.lft,
|
||||
"rgt": d.rgt
|
||||
}))
|
||||
return item_groups
|
||||
|
||||
def get_sales_persons():
|
||||
sales_persons = frappe._dict()
|
||||
for d in frappe.get_all("Sales Person", fields=["name", "lft", "rgt"]):
|
||||
sales_persons.setdefault(d.name, frappe._dict({
|
||||
"lft": d.lft,
|
||||
"rgt": d.rgt
|
||||
}))
|
||||
return sales_persons
|
||||
return get_data_column(filters, "Sales Person")
|
||||
|
@ -3,6 +3,13 @@
|
||||
|
||||
frappe.query_reports["Territory Target Variance Item Group-Wise"] = {
|
||||
"filters": [
|
||||
{
|
||||
fieldname:"company",
|
||||
label: __("Company"),
|
||||
fieldtype: "Link",
|
||||
options: "Company",
|
||||
default: frappe.defaults.get_user_default("Company")
|
||||
},
|
||||
{
|
||||
fieldname: "fiscal_year",
|
||||
label: __("Fiscal Year"),
|
||||
@ -10,6 +17,13 @@ frappe.query_reports["Territory Target Variance Item Group-Wise"] = {
|
||||
options: "Fiscal Year",
|
||||
default: frappe.sys_defaults.fiscal_year
|
||||
},
|
||||
{
|
||||
fieldname: "doctype",
|
||||
label: __("Document Type"),
|
||||
fieldtype: "Select",
|
||||
options: "Sales Order\nDelivery Note\nSales Invoice",
|
||||
default: "Sales Order"
|
||||
},
|
||||
{
|
||||
fieldname: "period",
|
||||
label: __("Period"),
|
||||
|
@ -3,155 +3,10 @@
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe import _, msgprint
|
||||
from frappe.utils import flt
|
||||
from erpnext.accounts.utils import get_fiscal_year
|
||||
from erpnext.controllers.trends import get_period_date_ranges, get_period_month_ranges
|
||||
from erpnext.selling.report.sales_partner_target_variance_item_group_wise.item_group_wise_sales_target_variance import get_data_column
|
||||
|
||||
def execute(filters=None):
|
||||
if not filters: filters = {}
|
||||
|
||||
columns = get_columns(filters)
|
||||
period_month_ranges = get_period_month_ranges(filters["period"], filters["fiscal_year"])
|
||||
territory_item_group_dict = get_territory_item_month_map(filters)
|
||||
|
||||
data = []
|
||||
for territory, territory_items in territory_item_group_dict.items():
|
||||
for item_group, monthwise_data in territory_items.items():
|
||||
row = [territory, item_group]
|
||||
totals = [0, 0, 0]
|
||||
for relevant_months in period_month_ranges:
|
||||
period_data = [0, 0, 0]
|
||||
for month in relevant_months:
|
||||
month_data = monthwise_data.get(month, {})
|
||||
for i, fieldname in enumerate(["target", "achieved", "variance"]):
|
||||
value = flt(month_data.get(fieldname))
|
||||
period_data[i] += value
|
||||
totals[i] += value
|
||||
period_data[2] = period_data[0] - period_data[1]
|
||||
row += period_data
|
||||
totals[2] = totals[0] - totals[1]
|
||||
row += totals
|
||||
data.append(row)
|
||||
|
||||
return columns, sorted(data, key=lambda x: (x[0], x[1]))
|
||||
return get_data_column(filters, "Territory")
|
||||
|
||||
def get_columns(filters):
|
||||
for fieldname in ["fiscal_year", "period", "target_on"]:
|
||||
if not filters.get(fieldname):
|
||||
label = (" ".join(fieldname.split("_"))).title()
|
||||
msgprint(_("Please specify") + ": " + label, raise_exception=True)
|
||||
|
||||
columns = [_("Territory") + ":Link/Territory:120", _("Item Group") + ":Link/Item Group:120"]
|
||||
|
||||
group_months = False if filters["period"] == "Monthly" else True
|
||||
|
||||
for from_date, to_date in get_period_date_ranges(filters["period"], filters["fiscal_year"]):
|
||||
for label in [_("Target") +" (%s)", _("Achieved") + " (%s)", _("Variance") + " (%s)"]:
|
||||
if group_months:
|
||||
label = label % (_(from_date.strftime("%b")) + " - " + _(to_date.strftime("%b")))
|
||||
else:
|
||||
label = label % _(from_date.strftime("%b"))
|
||||
columns.append(label+":Float:120")
|
||||
|
||||
return columns + [_("Total Target") + ":Float:120", _("Total Achieved") + ":Float:120",
|
||||
_("Total Variance") + ":Float:120"]
|
||||
|
||||
#Get territory & item group details
|
||||
def get_territory_details(filters):
|
||||
return frappe.db.sql("""
|
||||
select
|
||||
t.name, td.item_group, td.target_qty, td.target_amount, t.distribution_id
|
||||
from
|
||||
`tabTerritory` t, `tabTarget Detail` td
|
||||
where
|
||||
td.parent=t.name and td.fiscal_year=%s order by t.name
|
||||
""", (filters["fiscal_year"]), as_dict=1)
|
||||
|
||||
#Get target distribution details of item group
|
||||
def get_target_distribution_details(filters):
|
||||
target_details = {}
|
||||
|
||||
for d in frappe.db.sql("""
|
||||
select
|
||||
md.name, mdp.month, mdp.percentage_allocation
|
||||
from
|
||||
`tabMonthly Distribution Percentage` mdp, `tabMonthly Distribution` md
|
||||
where
|
||||
mdp.parent=md.name and md.fiscal_year=%s
|
||||
""", (filters["fiscal_year"]), as_dict=1):
|
||||
target_details.setdefault(d.name, {}).setdefault(d.month, flt(d.percentage_allocation))
|
||||
|
||||
return target_details
|
||||
|
||||
#Get achieved details from sales order
|
||||
def get_achieved_details(filters, territory, item_groups):
|
||||
start_date, end_date = get_fiscal_year(fiscal_year = filters["fiscal_year"])[1:]
|
||||
|
||||
lft, rgt = frappe.db.get_value("Territory", territory, ["lft", "rgt"])
|
||||
|
||||
item_details = frappe.db.sql("""
|
||||
select
|
||||
soi.item_code, sum(soi.stock_qty) as qty, sum(soi.base_net_amount) as amount,
|
||||
MONTHNAME(so.transaction_date) as month_name
|
||||
from
|
||||
`tabSales Order Item` soi, `tabSales Order` so
|
||||
where
|
||||
soi.parent=so.name and so.docstatus=1
|
||||
and so.transaction_date>=%s and so.transaction_date<=%s
|
||||
and exists(select name from `tabTerritory` where lft >=%s and rgt <= %s and name=so.territory)
|
||||
group by
|
||||
month_name, item_code
|
||||
""", (start_date, end_date, lft, rgt), as_dict=1)
|
||||
|
||||
item_actual_details = {}
|
||||
for d in item_details:
|
||||
item_group = item_groups[d.item_code]
|
||||
item_actual_details.setdefault(item_group, frappe._dict())\
|
||||
.setdefault(d.month_name, frappe._dict({
|
||||
"quantity": 0,
|
||||
"amount": 0
|
||||
}))
|
||||
|
||||
value_dict = item_actual_details[item_group][d.month_name]
|
||||
value_dict.quantity += flt(d.qty)
|
||||
value_dict.amount += flt(d.amount)
|
||||
|
||||
return item_actual_details
|
||||
|
||||
def get_territory_item_month_map(filters):
|
||||
import datetime
|
||||
territory_details = get_territory_details(filters)
|
||||
tdd = get_target_distribution_details(filters)
|
||||
item_groups = get_item_groups()
|
||||
|
||||
territory_item_group_dict = {}
|
||||
|
||||
for td in territory_details:
|
||||
achieved_details = get_achieved_details(filters, td.name, item_groups)
|
||||
|
||||
for month_id in range(1, 13):
|
||||
month = datetime.date(2013, month_id, 1).strftime('%B')
|
||||
|
||||
territory_item_group_dict.setdefault(td.name, {}).setdefault(td.item_group, {})\
|
||||
.setdefault(month, frappe._dict({
|
||||
"target": 0.0, "achieved": 0.0
|
||||
}))
|
||||
|
||||
target_achieved = territory_item_group_dict[td.name][td.item_group][month]
|
||||
month_percentage = tdd.get(td.distribution_id, {}).get(month, 0) \
|
||||
if td.distribution_id else 100.0/12
|
||||
|
||||
|
||||
if (filters["target_on"] == "Quantity"):
|
||||
target_achieved.target = flt(td.target_qty) * month_percentage / 100
|
||||
else:
|
||||
target_achieved.target = flt(td.target_amount) * month_percentage / 100
|
||||
|
||||
target_achieved.achieved = achieved_details.get(td.item_group, {}).get(month, {})\
|
||||
.get(filters["target_on"].lower())
|
||||
|
||||
return territory_item_group_dict
|
||||
|
||||
def get_item_groups():
|
||||
return dict(frappe.get_all("Item", fields=["name", "item_group"], as_list=1))
|
||||
|
@ -13,5 +13,16 @@ frappe.ui.form.on('Sales Partner', {
|
||||
unhide_field(['address_html', 'contact_html', 'address_contacts']);
|
||||
frappe.contacts.render_address_and_contact(frm);
|
||||
}
|
||||
},
|
||||
|
||||
setup: function(frm) {
|
||||
frm.fields_dict["targets"].grid.get_field("distribution_id").get_query = function(doc, cdt, cdn){
|
||||
var row = locals[cdt][cdn];
|
||||
return {
|
||||
filters: {
|
||||
'fiscal_year': row.fiscal_year
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -1,5 +1,6 @@
|
||||
{
|
||||
"allow_copy": 0,
|
||||
"allow_events_in_timeline": 0,
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 1,
|
||||
"allow_rename": 1,
|
||||
@ -21,6 +22,7 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "partner_name",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
@ -45,7 +47,7 @@
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
"unique": 1
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
@ -54,6 +56,7 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "partner_type",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
@ -89,6 +92,7 @@
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"description": "",
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "territory",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
@ -121,6 +125,7 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "column_break0",
|
||||
"fieldtype": "Column Break",
|
||||
"hidden": 0,
|
||||
@ -153,6 +158,7 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "commission_rate",
|
||||
"fieldtype": "Float",
|
||||
"hidden": 0,
|
||||
@ -186,6 +192,7 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "address_contacts",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
@ -218,6 +225,7 @@
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "eval:doc.__islocal",
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "address_desc",
|
||||
"fieldtype": "HTML",
|
||||
"hidden": 0,
|
||||
@ -249,6 +257,7 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "address_html",
|
||||
"fieldtype": "HTML",
|
||||
"hidden": 0,
|
||||
@ -280,6 +289,7 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "column_break1",
|
||||
"fieldtype": "Column Break",
|
||||
"hidden": 0,
|
||||
@ -311,6 +321,7 @@
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "eval:doc.__islocal",
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "contact_desc",
|
||||
"fieldtype": "HTML",
|
||||
"hidden": 0,
|
||||
@ -342,6 +353,7 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "contact_html",
|
||||
"fieldtype": "HTML",
|
||||
"hidden": 0,
|
||||
@ -373,6 +385,7 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "partner_target_details_section_break",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
@ -405,6 +418,7 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "targets",
|
||||
"fieldtype": "Table",
|
||||
"hidden": 0,
|
||||
@ -439,41 +453,7 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"description": "Select Monthly Distribution to unevenly distribute targets across months.",
|
||||
"fieldname": "distribution_id",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Target Distribution",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"oldfieldname": "distribution_id",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "Monthly Distribution",
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "website",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
@ -505,6 +485,7 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "show_in_website",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
@ -537,6 +518,7 @@
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "show_in_website",
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "section_break_17",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
@ -567,6 +549,7 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "route",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
@ -599,6 +582,7 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "column_break_20",
|
||||
"fieldtype": "Column Break",
|
||||
"hidden": 0,
|
||||
@ -629,6 +613,7 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "logo",
|
||||
"fieldtype": "Attach",
|
||||
"hidden": 0,
|
||||
@ -661,6 +646,7 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "partner_website",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
@ -693,6 +679,7 @@
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "show_in_website",
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "section_break_22",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
@ -723,6 +710,7 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "introduction",
|
||||
"fieldtype": "Text",
|
||||
"hidden": 0,
|
||||
@ -754,6 +742,7 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "description",
|
||||
"fieldtype": "Text Editor",
|
||||
"hidden": 0,
|
||||
@ -790,7 +779,7 @@
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2018-06-11 13:47:04.182339",
|
||||
"modified": "2019-03-21 16:26:45.447265",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Setup",
|
||||
"name": "Sales Partner",
|
||||
@ -860,5 +849,6 @@
|
||||
"show_name_in_global_search": 1,
|
||||
"sort_order": "ASC",
|
||||
"track_changes": 0,
|
||||
"track_seen": 0
|
||||
"track_seen": 0,
|
||||
"track_views": 0
|
||||
}
|
@ -8,6 +8,17 @@ frappe.ui.form.on('Sales Person', {
|
||||
frm.dashboard.add_indicator(__('Total Contribution Amount: {0}',
|
||||
[format_currency(info.allocated_amount, info.currency)]), 'blue');
|
||||
}
|
||||
},
|
||||
|
||||
setup: function(frm) {
|
||||
frm.fields_dict["targets"].grid.get_field("distribution_id").get_query = function(doc, cdt, cdn){
|
||||
var row = locals[cdt][cdn];
|
||||
return {
|
||||
filters: {
|
||||
'fiscal_year': row.fiscal_year
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -22,6 +22,7 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "name_and_employee_id",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
@ -54,6 +55,7 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "sales_person_name",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
@ -88,6 +90,7 @@
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"description": "Select company name first.",
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "parent_sales_person",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
@ -122,6 +125,7 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "commission_rate",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
@ -154,6 +158,7 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "is_group",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
@ -189,6 +194,7 @@
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"default": "1",
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "enabled",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
@ -221,6 +227,7 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "cb0",
|
||||
"fieldtype": "Column Break",
|
||||
"hidden": 0,
|
||||
@ -251,6 +258,7 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "employee",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
@ -284,6 +292,7 @@
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_from": "employee.department",
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "department",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
@ -317,6 +326,7 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "lft",
|
||||
"fieldtype": "Int",
|
||||
"hidden": 1,
|
||||
@ -350,6 +360,7 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "rgt",
|
||||
"fieldtype": "Int",
|
||||
"hidden": 1,
|
||||
@ -383,6 +394,7 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "old_parent",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 1,
|
||||
@ -417,6 +429,7 @@
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"description": "Set targets Item Group-wise for this Sales Person.",
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "target_details_section_break",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
@ -450,6 +463,7 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "targets",
|
||||
"fieldtype": "Table",
|
||||
"hidden": 0,
|
||||
@ -476,41 +490,6 @@
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"description": "Select Monthly Distribution to unevenly distribute targets across months.",
|
||||
"fieldname": "distribution_id",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Target Distribution",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"oldfieldname": "distribution_id",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "Monthly Distribution",
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
}
|
||||
],
|
||||
"has_web_view": 0,
|
||||
@ -524,7 +503,7 @@
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2019-01-30 11:28:16.966735",
|
||||
"modified": "2019-03-21 16:26:01.706129",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Setup",
|
||||
"name": "Sales Person",
|
||||
|
@ -19,6 +19,7 @@
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"description": "",
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "item_group",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
@ -53,6 +54,7 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "fiscal_year",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
@ -87,6 +89,7 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "target_qty",
|
||||
"fieldtype": "Float",
|
||||
"hidden": 0,
|
||||
@ -120,6 +123,7 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "target_amount",
|
||||
"fieldtype": "Float",
|
||||
"hidden": 0,
|
||||
@ -145,6 +149,40 @@
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "distribution_id",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Target Distribution",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Monthly Distribution",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
}
|
||||
],
|
||||
"has_web_view": 0,
|
||||
@ -157,7 +195,7 @@
|
||||
"issingle": 0,
|
||||
"istable": 1,
|
||||
"max_attachments": 0,
|
||||
"modified": "2019-01-07 16:56:48.179709",
|
||||
"modified": "2019-03-20 16:59:03.578274",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Setup",
|
||||
"name": "Target Detail",
|
||||
|
@ -1,6 +1,18 @@
|
||||
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
// License: GNU General Public License v3. See license.txt
|
||||
|
||||
frappe.ui.form.on("Territory", {
|
||||
setup: function(frm) {
|
||||
frm.fields_dict["targets"].grid.get_field("distribution_id").get_query = function(doc, cdt, cdn){
|
||||
var row = locals[cdt][cdn];
|
||||
return {
|
||||
filters: {
|
||||
'fiscal_year': row.fiscal_year
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
cur_frm.cscript.refresh = function(doc, cdt, cdn) {
|
||||
cur_frm.cscript.set_root_readonly(doc);
|
||||
|
@ -1,5 +1,6 @@
|
||||
{
|
||||
"allow_copy": 0,
|
||||
"allow_events_in_timeline": 0,
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 1,
|
||||
"allow_rename": 1,
|
||||
@ -20,6 +21,7 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "territory_name",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
@ -54,6 +56,7 @@
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"description": "",
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "parent_territory",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
@ -89,6 +92,7 @@
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"description": "",
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "is_group",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
@ -123,6 +127,7 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "cb0",
|
||||
"fieldtype": "Column Break",
|
||||
"hidden": 0,
|
||||
@ -154,6 +159,7 @@
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"description": "For reference",
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "territory_manager",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
@ -188,6 +194,7 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "lft",
|
||||
"fieldtype": "Int",
|
||||
"hidden": 1,
|
||||
@ -221,6 +228,7 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "rgt",
|
||||
"fieldtype": "Int",
|
||||
"hidden": 1,
|
||||
@ -255,6 +263,7 @@
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"description": "",
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "old_parent",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 1,
|
||||
@ -290,6 +299,7 @@
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"description": "Set Item Group-wise budgets on this Territory. You can also include seasonality by setting the Distribution.",
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "target_details_section_break",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
@ -322,6 +332,7 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "targets",
|
||||
"fieldtype": "Table",
|
||||
"hidden": 0,
|
||||
@ -348,41 +359,6 @@
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"description": "Select Monthly Distribution to unevenly distribute targets across months.",
|
||||
"fieldname": "distribution_id",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Target Distribution",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"oldfieldname": "distribution_id",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "Monthly Distribution",
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
}
|
||||
],
|
||||
"has_web_view": 0,
|
||||
@ -396,7 +372,7 @@
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2018-08-29 06:26:38.918259",
|
||||
"modified": "2019-03-21 16:26:58.581431",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Setup",
|
||||
"name": "Territory",
|
||||
|
Loading…
x
Reference in New Issue
Block a user