Merge pull request #16977 from rohitwaghchaure/moved_distribution_from_parent_to_child

feat: Added item group variance report for sales partner, commonified item group wise target variance report
This commit is contained in:
rohitwaghchaure 2019-03-26 12:41:47 +05:30 committed by GitHub
commit 392bc54a34
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
29 changed files with 1008 additions and 909 deletions

View File

@ -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

View File

@ -590,4 +590,5 @@ erpnext.patches.v11_0.make_italian_localization_fields # 01-03-2019
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.rename_pricing_rule_child_doctypes
erpnext.patches.v12_0.move_target_distribution_from_parent_to_child #wmnfb

View File

@ -0,0 +1,22 @@
# 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"))
frappe.delete_doc("Report", "Sales Partner-wise Transaction Summary")
frappe.delete_doc("Report", "Sales Person Target Variance Item Group-Wise")
frappe.delete_doc("Report", "Territory Target Variance Item Group-Wise")

View File

@ -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)
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"])

View File

@ -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 based on Item Group"] = {
"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"
},
]
}

View File

@ -0,0 +1,37 @@
{
"add_total_row": 0,
"creation": "2019-03-25 18:22:37.323995",
"disable_prepared_report": 0,
"disabled": 0,
"docstatus": 0,
"doctype": "Report",
"idx": 0,
"is_standard": "Yes",
"letter_head": "Gadgets International",
"modified": "2019-03-25 18:22:37.323995",
"modified_by": "Administrator",
"module": "Selling",
"name": "Sales Partner Target Variance based on Item Group",
"owner": "Administrator",
"prepared_report": 0,
"ref_doctype": "Sales Order",
"report_name": "Sales Partner Target Variance based on Item Group",
"report_type": "Script Report",
"roles": [
{
"role": "Sales User"
},
{
"role": "Sales Manager"
},
{
"role": "Maintenance User"
},
{
"role": "Accounts User"
},
{
"role": "Stock User"
}
]
}

View File

@ -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_based_on_item_group.item_group_wise_sales_target_variance import get_data_column
def execute(filters=None):
data = []
return get_data_column(filters, "Sales Partner")

View File

@ -2,7 +2,7 @@
// For license information, please see license.txt
/* eslint-disable */
frappe.query_reports["Sales Partner-wise Transaction Summary"] = {
frappe.query_reports["Sales Partner Transaction Summary"] = {
"filters": [
{
fieldname: "sales_partner",

View File

@ -1,6 +1,6 @@
{
"add_total_row": 1,
"creation": "2019-03-15 16:21:16.088831",
"creation": "2019-03-25 18:15:09.920739",
"disable_prepared_report": 0,
"disabled": 0,
"docstatus": 0,
@ -8,14 +8,14 @@
"idx": 0,
"is_standard": "Yes",
"letter_head": "Gadgets International",
"modified": "2019-03-15 16:21:16.088831",
"modified": "2019-03-25 18:15:09.920739",
"modified_by": "Administrator",
"module": "Selling",
"name": "Sales Partner-wise Transaction Summary",
"name": "Sales Partner Transaction Summary",
"owner": "Administrator",
"prepared_report": 0,
"ref_doctype": "Sales Order",
"report_name": "Sales Partner-wise Transaction Summary",
"report_name": "Sales Partner Transaction Summary",
"report_type": "Script Report",
"roles": [
{

View File

@ -1,8 +1,16 @@
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
// License: GNU General Public License v3. See license.txt
// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
// For license information, please see license.txt
/* eslint-disable */
frappe.query_reports["Sales Person Target Variance Item Group-Wise"] = {
frappe.query_reports["Sales Person Target Variance Based On Item Group"] = {
"filters": [
{
fieldname:"company",
label: __("Company"),
fieldtype: "Link",
options: "Company",
default: frappe.defaults.get_user_default("Company")
},
{
fieldname: "fiscal_year",
label: __("Fiscal Year"),
@ -10,6 +18,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"),

View File

@ -1,19 +1,21 @@
{
"add_total_row": 0,
"apply_user_permissions": 1,
"creation": "2013-06-21 12:14:15",
"creation": "2019-03-25 22:16:49.040998",
"disable_prepared_report": 0,
"disabled": 0,
"docstatus": 0,
"doctype": "Report",
"idx": 3,
"idx": 0,
"is_standard": "Yes",
"modified": "2017-02-24 20:14:50.589149",
"letter_head": "Gadgets International",
"modified": "2019-03-25 22:16:49.040998",
"modified_by": "Administrator",
"module": "Selling",
"name": "Sales Person Target Variance Item Group-Wise",
"name": "Sales Person Target Variance Based On Item Group",
"owner": "Administrator",
"prepared_report": 0,
"ref_doctype": "Sales Order",
"report_name": "Sales Person Target Variance Item Group-Wise",
"report_name": "Sales Person Target Variance Based On Item Group",
"report_type": "Script Report",
"roles": [
{

View File

@ -0,0 +1,11 @@
# 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_based_on_item_group.item_group_wise_sales_target_variance import get_data_column
def execute(filters=None):
data = []
return get_data_column(filters, "Sales Person")

View File

@ -1,178 +0,0 @@
# 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 _, 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
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

View File

@ -1,8 +1,16 @@
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
// License: GNU General Public License v3. See license.txt
// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
// For license information, please see license.txt
/* eslint-disable */
frappe.query_reports["Territory Target Variance Item Group-Wise"] = {
frappe.query_reports["Territory Target Variance Based On Item Group"] = {
"filters": [
{
fieldname:"company",
label: __("Company"),
fieldtype: "Link",
options: "Company",
default: frappe.defaults.get_user_default("Company")
},
{
fieldname: "fiscal_year",
label: __("Fiscal Year"),
@ -10,6 +18,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"),

View File

@ -1,19 +1,21 @@
{
"add_total_row": 0,
"apply_user_permissions": 1,
"creation": "2013-06-21 12:15:00",
"creation": "2019-03-25 22:20:59.033199",
"disable_prepared_report": 0,
"disabled": 0,
"docstatus": 0,
"doctype": "Report",
"idx": 3,
"idx": 0,
"is_standard": "Yes",
"modified": "2017-02-24 20:13:29.705321",
"letter_head": "Gadgets International",
"modified": "2019-03-25 22:20:59.033199",
"modified_by": "Administrator",
"module": "Selling",
"name": "Territory Target Variance Item Group-Wise",
"name": "Territory Target Variance Based On Item Group",
"owner": "Administrator",
"prepared_report": 0,
"ref_doctype": "Sales Order",
"report_name": "Territory Target Variance Item Group-Wise",
"report_name": "Territory Target Variance Based On Item Group",
"report_type": "Script Report",
"roles": [
{

View File

@ -0,0 +1,11 @@
# 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_based_on_item_group.item_group_wise_sales_target_variance import get_data_column
def execute(filters=None):
data = []
return get_data_column(filters, "Territory")

View File

@ -1,157 +0,0 @@
# 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 _, 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
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]))
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))

View File

@ -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
}
}
};
}
});

View File

@ -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
}

View File

@ -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
}
}
};
}
});

View File

@ -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",

View File

@ -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",

View File

@ -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);

View File

@ -1,511 +1,487 @@
{
"allow_copy": 0,
"allow_guest_to_view": 0,
"allow_import": 1,
"allow_rename": 1,
"autoname": "field:territory_name",
"beta": 0,
"creation": "2013-01-10 16:34:24",
"custom": 0,
"description": "Classification of Customers by region",
"docstatus": 0,
"doctype": "DocType",
"document_type": "Setup",
"editable_grid": 0,
"allow_copy": 0,
"allow_events_in_timeline": 0,
"allow_guest_to_view": 0,
"allow_import": 1,
"allow_rename": 1,
"autoname": "field:territory_name",
"beta": 0,
"creation": "2013-01-10 16:34:24",
"custom": 0,
"description": "Classification of Customers by region",
"docstatus": 0,
"doctype": "DocType",
"document_type": "Setup",
"editable_grid": 0,
"fields": [
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "territory_name",
"fieldtype": "Data",
"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": "Territory Name",
"length": 0,
"no_copy": 1,
"oldfieldname": "territory_name",
"oldfieldtype": "Data",
"permlevel": 0,
"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,
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "territory_name",
"fieldtype": "Data",
"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": "Territory Name",
"length": 0,
"no_copy": 1,
"oldfieldname": "territory_name",
"oldfieldtype": "Data",
"permlevel": 0,
"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": 1
},
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 1,
"collapsible": 0,
"columns": 0,
"description": "",
"fieldname": "parent_territory",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 1,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Parent Territory",
"length": 0,
"no_copy": 0,
"oldfieldname": "parent_territory",
"oldfieldtype": "Link",
"options": "Territory",
"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,
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 1,
"collapsible": 0,
"columns": 0,
"description": "",
"fetch_if_empty": 0,
"fieldname": "parent_territory",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 1,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Parent Territory",
"length": 0,
"no_copy": 0,
"oldfieldname": "parent_territory",
"oldfieldtype": "Link",
"options": "Territory",
"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": 1,
"collapsible": 0,
"columns": 0,
"description": "",
"fieldname": "is_group",
"fieldtype": "Check",
"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": "Is Group",
"length": 0,
"no_copy": 0,
"oldfieldname": "is_group",
"oldfieldtype": "Select",
"options": "",
"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,
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 1,
"collapsible": 0,
"columns": 0,
"description": "",
"fetch_if_empty": 0,
"fieldname": "is_group",
"fieldtype": "Check",
"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": "Is Group",
"length": 0,
"no_copy": 0,
"oldfieldname": "is_group",
"oldfieldtype": "Select",
"options": "",
"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,
"fieldname": "cb0",
"fieldtype": "Column Break",
"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,
"length": 0,
"no_copy": 0,
"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,
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "cb0",
"fieldtype": "Column Break",
"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,
"length": 0,
"no_copy": 0,
"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,
"description": "For reference",
"fieldname": "territory_manager",
"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": "Territory Manager",
"length": 0,
"no_copy": 0,
"oldfieldname": "territory_manager",
"oldfieldtype": "Link",
"options": "Sales Person",
"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": 1,
"set_only_once": 0,
"translatable": 0,
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"description": "For reference",
"fetch_if_empty": 0,
"fieldname": "territory_manager",
"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": "Territory Manager",
"length": 0,
"no_copy": 0,
"oldfieldname": "territory_manager",
"oldfieldtype": "Link",
"options": "Sales Person",
"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": 1,
"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,
"fieldname": "lft",
"fieldtype": "Int",
"hidden": 1,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "lft",
"length": 0,
"no_copy": 1,
"oldfieldname": "lft",
"oldfieldtype": "Int",
"permlevel": 0,
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 1,
"set_only_once": 0,
"translatable": 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": "lft",
"fieldtype": "Int",
"hidden": 1,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "lft",
"length": 0,
"no_copy": 1,
"oldfieldname": "lft",
"oldfieldtype": "Int",
"permlevel": 0,
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 1,
"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,
"fieldname": "rgt",
"fieldtype": "Int",
"hidden": 1,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "rgt",
"length": 0,
"no_copy": 1,
"oldfieldname": "rgt",
"oldfieldtype": "Int",
"permlevel": 0,
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 1,
"set_only_once": 0,
"translatable": 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": "rgt",
"fieldtype": "Int",
"hidden": 1,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "rgt",
"length": 0,
"no_copy": 1,
"oldfieldname": "rgt",
"oldfieldtype": "Int",
"permlevel": 0,
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 1,
"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": "",
"fieldname": "old_parent",
"fieldtype": "Link",
"hidden": 1,
"ignore_user_permissions": 1,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "old_parent",
"length": 0,
"no_copy": 1,
"oldfieldname": "old_parent",
"oldfieldtype": "Data",
"options": "Territory",
"permlevel": 0,
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 1,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"description": "",
"fetch_if_empty": 0,
"fieldname": "old_parent",
"fieldtype": "Link",
"hidden": 1,
"ignore_user_permissions": 1,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "old_parent",
"length": 0,
"no_copy": 1,
"oldfieldname": "old_parent",
"oldfieldtype": "Data",
"options": "Territory",
"permlevel": 0,
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 1,
"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,
"description": "Set Item Group-wise budgets on this Territory. You can also include seasonality by setting the Distribution.",
"fieldname": "target_details_section_break",
"fieldtype": "Section Break",
"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": "Territory Targets",
"length": 0,
"no_copy": 0,
"oldfieldtype": "Section Break",
"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,
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"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,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Territory Targets",
"length": 0,
"no_copy": 0,
"oldfieldtype": "Section Break",
"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,
"fieldname": "targets",
"fieldtype": "Table",
"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": "Targets",
"length": 0,
"no_copy": 0,
"oldfieldname": "target_details",
"oldfieldtype": "Table",
"options": "Target Detail",
"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,
"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,
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "targets",
"fieldtype": "Table",
"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": "Targets",
"length": 0,
"no_copy": 0,
"oldfieldname": "target_details",
"oldfieldtype": "Table",
"options": "Target Detail",
"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,
"hide_heading": 0,
"hide_toolbar": 0,
"icon": "fa fa-map-marker",
"idx": 1,
"image_view": 0,
"in_create": 0,
"is_submittable": 0,
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2018-08-29 06:26:38.918259",
"modified_by": "Administrator",
"module": "Setup",
"name": "Territory",
"name_case": "Title Case",
"owner": "Administrator",
],
"has_web_view": 0,
"hide_heading": 0,
"hide_toolbar": 0,
"icon": "fa fa-map-marker",
"idx": 1,
"image_view": 0,
"in_create": 0,
"is_submittable": 0,
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2019-03-21 16:26:58.581431",
"modified_by": "Administrator",
"module": "Setup",
"name": "Territory",
"name_case": "Title Case",
"owner": "Administrator",
"permissions": [
{
"amend": 0,
"cancel": 0,
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
"if_owner": 0,
"import": 1,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "Sales Master Manager",
"set_user_permissions": 1,
"share": 1,
"submit": 0,
"amend": 0,
"cancel": 0,
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
"if_owner": 0,
"import": 1,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "Sales Master Manager",
"set_user_permissions": 1,
"share": 1,
"submit": 0,
"write": 1
},
},
{
"amend": 0,
"cancel": 0,
"create": 0,
"delete": 0,
"email": 1,
"export": 0,
"if_owner": 0,
"import": 0,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "Sales Manager",
"set_user_permissions": 0,
"share": 0,
"submit": 0,
"amend": 0,
"cancel": 0,
"create": 0,
"delete": 0,
"email": 1,
"export": 0,
"if_owner": 0,
"import": 0,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "Sales Manager",
"set_user_permissions": 0,
"share": 0,
"submit": 0,
"write": 0
},
},
{
"amend": 0,
"cancel": 0,
"create": 0,
"delete": 0,
"email": 1,
"export": 0,
"if_owner": 0,
"import": 0,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "Sales User",
"set_user_permissions": 0,
"share": 0,
"submit": 0,
"amend": 0,
"cancel": 0,
"create": 0,
"delete": 0,
"email": 1,
"export": 0,
"if_owner": 0,
"import": 0,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "Sales User",
"set_user_permissions": 0,
"share": 0,
"submit": 0,
"write": 0
},
},
{
"amend": 0,
"cancel": 0,
"create": 0,
"delete": 0,
"email": 0,
"export": 0,
"if_owner": 0,
"import": 0,
"permlevel": 0,
"print": 0,
"read": 1,
"report": 0,
"role": "Stock User",
"set_user_permissions": 0,
"share": 0,
"submit": 0,
"amend": 0,
"cancel": 0,
"create": 0,
"delete": 0,
"email": 0,
"export": 0,
"if_owner": 0,
"import": 0,
"permlevel": 0,
"print": 0,
"read": 1,
"report": 0,
"role": "Stock User",
"set_user_permissions": 0,
"share": 0,
"submit": 0,
"write": 0
},
},
{
"amend": 0,
"cancel": 0,
"create": 0,
"delete": 0,
"email": 0,
"export": 0,
"if_owner": 0,
"import": 0,
"permlevel": 0,
"print": 0,
"read": 1,
"report": 0,
"role": "Maintenance User",
"set_user_permissions": 0,
"share": 0,
"submit": 0,
"amend": 0,
"cancel": 0,
"create": 0,
"delete": 0,
"email": 0,
"export": 0,
"if_owner": 0,
"import": 0,
"permlevel": 0,
"print": 0,
"read": 1,
"report": 0,
"role": "Maintenance User",
"set_user_permissions": 0,
"share": 0,
"submit": 0,
"write": 0
}
],
"quick_entry": 1,
"read_only": 0,
"read_only_onload": 0,
"search_fields": "parent_territory,territory_manager",
"show_name_in_global_search": 1,
"sort_order": "DESC",
"track_changes": 0,
"track_seen": 0,
],
"quick_entry": 1,
"read_only": 0,
"read_only_onload": 0,
"search_fields": "parent_territory,territory_manager",
"show_name_in_global_search": 1,
"sort_order": "DESC",
"track_changes": 0,
"track_seen": 0,
"track_views": 0
}