feat: Selling Desk, Dashboard and Onboarding (#22055)
* feat: Selling Desk, Dashboard and Onboarding * chore: Selling Onboarding and fixes in Other onboardings * chore: Dashboard and Number card Fixtures * fix: Escape filters and Reposition Accounts Dashboard shortcut. Co-authored-by: Nabin Hait <nabinhait@gmail.com>
This commit is contained in:
parent
22d49726d1
commit
383807f72e
@ -13,7 +13,7 @@
|
||||
{
|
||||
"hidden": 0,
|
||||
"label": "Accounts Receivable",
|
||||
"links": "[\n {\n \"description\": \"Bills raised to Customers.\",\n \"label\": \"Sales Invoice\",\n \"name\": \"Sales Invoice\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Customer database.\",\n \"label\": \"Customer\",\n \"name\": \"Customer\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Bank/Cash transactions against party or for internal transfer\",\n \"label\": \"Payment Entry\",\n \"name\": \"Payment Entry\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Payment Request\",\n \"label\": \"Payment Request\",\n \"name\": \"Payment Request\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Accounts Receivable\",\n \"name\": \"Accounts Receivable\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Accounts Receivable Summary\",\n \"name\": \"Accounts Receivable Summary\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Sales Register\",\n \"name\": \"Sales Register\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Item-wise Sales Register\",\n \"name\": \"Item-wise Sales Register\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Ordered Items To Be Billed\",\n \"name\": \"Ordered Items To Be Billed\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Delivered Items To Be Billed\",\n \"name\": \"Delivered Items To Be Billed\",\n \"type\": \"report\"\n }\n]"
|
||||
"links": "[\n {\n \"description\": \"Bills raised to Customers.\",\n \"label\": \"Sales Invoice\",\n \"name\": \"Sales Invoice\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Customer database.\",\n \"label\": \"Customer\",\n \"name\": \"Customer\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Bank/Cash transactions against party or for internal transfer\",\n \"label\": \"Payment Entry\",\n \"name\": \"Payment Entry\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Payment Request\",\n \"label\": \"Payment Request\",\n \"name\": \"Payment Request\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Accounts Receivable\",\n \"name\": \"Accounts Receivable\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Accounts Receivable Summary\",\n \"name\": \"Accounts Receivable Summary\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Sales Register\",\n \"name\": \"Sales Register\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Item-wise Sales Register\",\n \"name\": \"Item-wise Sales Register\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Order\",\n \"is_query_report\": true,\n \"label\": \"Sales Order Analysis\",\n \"name\": \"Sales Order Analysis\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Delivered Items To Be Billed\",\n \"name\": \"Delivered Items To Be Billed\",\n \"type\": \"report\"\n }\n]"
|
||||
},
|
||||
{
|
||||
"hidden": 0,
|
||||
@ -98,7 +98,7 @@
|
||||
"idx": 0,
|
||||
"is_standard": 1,
|
||||
"label": "Accounting",
|
||||
"modified": "2020-05-27 20:34:50.949772",
|
||||
"modified": "2020-06-19 12:42:44.054598",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Accounting",
|
||||
@ -122,11 +122,6 @@
|
||||
"link_to": "Purchase Invoice",
|
||||
"type": "DocType"
|
||||
},
|
||||
{
|
||||
"label": "Dashboard",
|
||||
"link_to": "Accounts",
|
||||
"type": "Dashboard"
|
||||
},
|
||||
{
|
||||
"label": "Journal Entry",
|
||||
"link_to": "Journal Entry",
|
||||
@ -151,6 +146,11 @@
|
||||
"label": "Trial Balance",
|
||||
"link_to": "Trial Balance",
|
||||
"type": "Report"
|
||||
},
|
||||
{
|
||||
"label": "Dashboard",
|
||||
"link_to": "Accounts",
|
||||
"type": "Dashboard"
|
||||
}
|
||||
]
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
frappe.query_reports["Ordered Items To Be Billed"] = {
|
||||
"filters": [
|
||||
|
||||
]
|
||||
}
|
@ -1,27 +0,0 @@
|
||||
{
|
||||
"add_total_row": 1,
|
||||
"apply_user_permissions": 1,
|
||||
"creation": "2013-02-21 14:26:44",
|
||||
"disabled": 0,
|
||||
"docstatus": 0,
|
||||
"doctype": "Report",
|
||||
"idx": 3,
|
||||
"is_standard": "Yes",
|
||||
"modified": "2017-11-06 13:04:51.559061",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Ordered Items To Be Billed",
|
||||
"owner": "Administrator",
|
||||
"query": "select \n `tabSales Order`.`name` as \"Sales Order:Link/Sales Order:120\",\n `tabSales Order`.`customer` as \"Customer:Link/Customer:120\",\n `tabSales Order`.`customer_name` as \"Customer Name:150\",\n`tabSales Order`.`status` as \"Status\",\n `tabSales Order`.`transaction_date` as \"Date:Date\",\n `tabSales Order`.`project` as \"Project\",\n `tabSales Order Item`.item_code as \"Item:Link/Item:120\",\n `tabSales Order Item`.base_amount as \"Amount:Currency:110\",\n (`tabSales Order Item`.billed_amt * ifnull(`tabSales Order`.conversion_rate, 1)) as \"Billed Amount:Currency:110\",\n (`tabSales Order Item`.base_amount - (`tabSales Order Item`.billed_amt * ifnull(`tabSales Order`.conversion_rate, 1))) as \"Pending Amount:Currency:120\",\n `tabSales Order Item`.item_name as \"Item Name::150\",\n `tabSales Order Item`.description as \"Description::200\",\n `tabSales Order`.`company` as \"Company:Link/Company:\"\nfrom\n `tabSales Order`, `tabSales Order Item`\nwhere\n `tabSales Order Item`.`parent` = `tabSales Order`.`name`\n and `tabSales Order`.docstatus = 1\n and `tabSales Order`.status != \"Closed\"\n and `tabSales Order Item`.amount > 0\n and `tabSales Order Item`.billed_amt < `tabSales Order Item`.amount\norder by `tabSales Order`.transaction_date asc",
|
||||
"ref_doctype": "Sales Invoice",
|
||||
"report_name": "Ordered Items To Be Billed",
|
||||
"report_type": "Script Report",
|
||||
"roles": [
|
||||
{
|
||||
"role": "Accounts Manager"
|
||||
},
|
||||
{
|
||||
"role": "Accounts User"
|
||||
}
|
||||
]
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
# Copyright (c) 2013, Frappe Technologies Pvt. Ltd. and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe import _
|
||||
from erpnext.accounts.report.non_billed_report import get_ordered_to_be_billed_data
|
||||
|
||||
def execute(filters=None):
|
||||
columns = get_column()
|
||||
args = get_args()
|
||||
data = get_ordered_to_be_billed_data(args)
|
||||
return columns, data
|
||||
|
||||
def get_column():
|
||||
return [
|
||||
_("Sales Order") + ":Link/Sales Order:120", _("Status") + "::120", _("Date") + ":Date:100",
|
||||
_("Suplier") + ":Link/Customer:120", _("Customer Name") + "::120",
|
||||
_("Project") + ":Link/Project:120", _("Item Code") + ":Link/Item:120",
|
||||
_("Amount") + ":Currency:100", _("Billed Amount") + ":Currency:100", _("Pending Amount") + ":Currency:100",
|
||||
_("Item Name") + "::120", _("Description") + "::120", _("Company") + ":Link/Company:120",
|
||||
]
|
||||
|
||||
def get_args():
|
||||
return {'doctype': 'Sales Order', 'party': 'customer',
|
||||
'date': 'transaction_date', 'order': 'transaction_date', 'order_by': 'asc'}
|
@ -155,8 +155,7 @@ def get_number_cards(company, fiscal_year_name, start_date, end_date):
|
||||
["Purchase Order", "transaction_date", "Between", [start_date, end_date], False],
|
||||
["Purchase Order", "status", "not in", ["Draft", "Cancelled", "Closed", None], False],
|
||||
["Purchase Order", "docstatus", "=", 1, False],
|
||||
["Purchase Order", "company", "=", company.name, False],
|
||||
["Purchase Order", "transaction_date", "Between", [start_date,end_date], False]
|
||||
["Purchase Order", "company", "=", company.name, False]
|
||||
]),
|
||||
"function": "Sum",
|
||||
"is_public": 1,
|
||||
|
@ -11,21 +11,21 @@ frappe.tour['Buying Settings'] = [
|
||||
{
|
||||
fieldname: "supp_master_name",
|
||||
title: "Supplier Naming By",
|
||||
description: __("By default, the Item Name is set as per the Item Code entered. If you want Items to be named by a set ") + "<a href='https://docs.erpnext.com/docs/user/manual/en/setting-up/settings/naming-series' target='_blank'>Naming Series</a>" + __(" choose the 'Naming Series' option."),
|
||||
description: __("By default, the Supplier Name is set as per the Supplier Name entered. If you want Suppliers to be named by a ") + "<a href='https://docs.erpnext.com/docs/user/manual/en/setting-up/settings/naming-series' target='_blank'>Naming Series</a>" + __(" choose the 'Naming Series' option."),
|
||||
},
|
||||
{
|
||||
fieldname: "buying_price_list",
|
||||
title: "Default Buying Price List",
|
||||
description: __("Configure the default Price List when creating a new Buying transaction, the default is set as 'Standard Buying'. Item prices will be fetched from this Price List.")
|
||||
description: __("Configure the default Price List when creating a new Purchase transaction. Item prices will be fetched from this Price List.")
|
||||
},
|
||||
{
|
||||
fieldname: "po_required",
|
||||
title: "Purchase Order Required for Purchase Invoice & Receipt Creation",
|
||||
description: __("If this option is configured 'Yes', ERPNext will prevent you from creating a Purchase Invoice or Receipt without creating a Purchase Order first. This configuration can be overridden for a particular supplier by enabling the 'Allow Purchase Invoice Creation Without Purchase Order' checkbox in supplier master.")
|
||||
description: __("If this option is configured 'Yes', ERPNext will prevent you from creating a Purchase Invoice or Receipt without creating a Purchase Order first. This configuration can be overridden for a particular supplier by enabling the 'Allow Purchase Invoice Creation Without Purchase Order' checkbox in the Supplier master.")
|
||||
},
|
||||
{
|
||||
fieldname: "pr_required",
|
||||
title: "Purchase Receipt Required for Purchase Invoice Creation",
|
||||
description: __("If this option is configured 'Yes', ERPNext will prevent you from creating a Purchase Invoice without creating a Purchase Receipt first. This configuration can be overridden for a particular supplier by enabling the 'Allow Purchase Invoice Creation Without Purchase Receipt' checkbox in supplier master.")
|
||||
description: __("If this option is configured 'Yes', ERPNext will prevent you from creating a Purchase Invoice without creating a Purchase Receipt first. This configuration can be overridden for a particular supplier by enabling the 'Allow Purchase Invoice Creation Without Purchase Receipt' checkbox in the Supplier master.")
|
||||
}
|
||||
];
|
@ -19,7 +19,7 @@
|
||||
"documentation_url": "https://docs.erpnext.com/docs/user/manual/en/buying",
|
||||
"idx": 0,
|
||||
"is_complete": 0,
|
||||
"modified": "2020-05-27 17:17:52.075947",
|
||||
"modified": "2020-06-01 12:55:09.234944",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Buying",
|
||||
"name": "Buying",
|
||||
|
@ -1,19 +1,19 @@
|
||||
{
|
||||
"action": "Update Settings",
|
||||
"action": "Show Form Tour",
|
||||
"creation": "2020-05-06 15:53:44.667414",
|
||||
"docstatus": 0,
|
||||
"doctype": "Onboarding Step",
|
||||
"idx": 0,
|
||||
"is_complete": 0,
|
||||
"is_mandatory": 0,
|
||||
"is_single": 0,
|
||||
"is_mandatory": 1,
|
||||
"is_single": 1,
|
||||
"is_skipped": 0,
|
||||
"modified": "2020-05-12 18:30:06.323797",
|
||||
"modified": "2020-06-01 12:52:57.668870",
|
||||
"modified_by": "Administrator",
|
||||
"name": "Buying Settings",
|
||||
"owner": "Administrator",
|
||||
"reference_document": "Buying Settings",
|
||||
"show_full_form": 0,
|
||||
"title": "Configure Buying Settings.",
|
||||
"validate_action": 1
|
||||
"validate_action": 0
|
||||
}
|
@ -700,4 +700,5 @@ erpnext.patches.v12_0.set_italian_import_supplier_invoice_permissions
|
||||
erpnext.patches.v13_0.update_sla_enhancements
|
||||
erpnext.patches.v12_0.update_address_template_for_india
|
||||
erpnext.patches.v12_0.set_multi_uom_in_rfq
|
||||
execute:frappe.delete_doc_if_exists("DocType", "Bank Reconciliation")
|
||||
erpnext.patches.v13_0.delete_old_sales_reports
|
||||
execute:frappe.delete_doc_if_exists("DocType", "Bank Reconciliation")
|
21
erpnext/patches/v13_0/delete_old_sales_reports.py
Normal file
21
erpnext/patches/v13_0/delete_old_sales_reports.py
Normal file
@ -0,0 +1,21 @@
|
||||
# Copyright (c) 2019, Frappe and Contributors
|
||||
# License: GNU General Public License v3. See license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import frappe
|
||||
|
||||
def execute():
|
||||
reports_to_delete = ["Ordered Items To Be Delivered", "Ordered Items To Be Billed"]
|
||||
|
||||
for report in reports_to_delete:
|
||||
if frappe.db.exists("Report", report):
|
||||
delete_auto_email_reports(report)
|
||||
|
||||
frappe.delete_doc("Report", report)
|
||||
|
||||
def delete_auto_email_reports(report):
|
||||
""" Check for one or multiple Auto Email Reports and delete """
|
||||
auto_email_reports = frappe.db.get_values("Auto Email Report", {"report": report}, ["name"])
|
||||
for auto_email_report in auto_email_reports:
|
||||
frappe.delete_doc("Auto Email Report", auto_email_report[0])
|
198
erpnext/selling/dashboard_fixtures.py
Normal file
198
erpnext/selling/dashboard_fixtures.py
Normal file
@ -0,0 +1,198 @@
|
||||
# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# License: GNU General Public License v3. See license.txt
|
||||
|
||||
import frappe
|
||||
import json
|
||||
from frappe import _
|
||||
from frappe.utils import nowdate
|
||||
from erpnext.accounts.utils import get_fiscal_year
|
||||
|
||||
def get_data():
|
||||
return frappe._dict({
|
||||
"dashboards": get_dashboards(),
|
||||
"charts": get_charts(),
|
||||
"number_cards": get_number_cards(),
|
||||
})
|
||||
|
||||
def get_company_for_dashboards():
|
||||
company = frappe.defaults.get_defaults().company
|
||||
if company:
|
||||
return company
|
||||
else:
|
||||
company_list = frappe.get_list("Company")
|
||||
if company_list:
|
||||
return company_list[0].name
|
||||
return None
|
||||
|
||||
company = frappe.get_doc("Company", get_company_for_dashboards())
|
||||
fiscal_year = get_fiscal_year(nowdate(), as_dict=1)
|
||||
fiscal_year_name = fiscal_year.get("name")
|
||||
start_date = str(fiscal_year.get("year_start_date"))
|
||||
end_date = str(fiscal_year.get("year_end_date"))
|
||||
|
||||
def get_dashboards():
|
||||
return [{
|
||||
"name": "Selling",
|
||||
"dashboard_name": "Selling",
|
||||
"charts": [
|
||||
{ "chart": "Sales Order Trends", "width": "Full"},
|
||||
{ "chart": "Top Customers", "width": "Half"},
|
||||
{ "chart": "Sales Order Analysis", "width": "Half"},
|
||||
{ "chart": "Item-wise Annual Sales", "width": "Full"}
|
||||
],
|
||||
"cards": [
|
||||
{ "card": "Annual Sales"},
|
||||
{ "card": "Sales Orders to Deliver"},
|
||||
{ "card": "Sales Orders to Bill"},
|
||||
{ "card": "Active Customers"}
|
||||
]
|
||||
}]
|
||||
|
||||
def get_charts():
|
||||
return [
|
||||
{
|
||||
"name": "Sales Order Analysis",
|
||||
"chart_name": _("Sales Order Analysis"),
|
||||
"chart_type": "Report",
|
||||
"custom_options": json.dumps({
|
||||
"type": "donut",
|
||||
"height": 300,
|
||||
"axisOptions": {"shortenYAxisNumbers": 1}
|
||||
}),
|
||||
"doctype": "Dashboard Chart",
|
||||
"filters_json": json.dumps({
|
||||
"company": company.name,
|
||||
"from_date": start_date,
|
||||
"to_date": end_date
|
||||
}),
|
||||
"is_custom": 1,
|
||||
"is_public": 1,
|
||||
"owner": "Administrator",
|
||||
"report_name": "Sales Order Analysis",
|
||||
"type": "Donut"
|
||||
},
|
||||
{
|
||||
"name": "Item-wise Annual Sales",
|
||||
"chart_name": _("Item-wise Annual Sales"),
|
||||
"chart_type": "Report",
|
||||
"doctype": "Dashboard Chart",
|
||||
"filters_json": json.dumps({
|
||||
"company": company.name,
|
||||
"from_date": start_date,
|
||||
"to_date": end_date
|
||||
}),
|
||||
"is_custom": 1,
|
||||
"is_public": 1,
|
||||
"owner": "Administrator",
|
||||
"report_name": "Item-wise Sales History",
|
||||
"type": "Bar"
|
||||
},
|
||||
{
|
||||
"name": "Sales Order Trends",
|
||||
"chart_name": _("Sales Order Trends"),
|
||||
"chart_type": "Report",
|
||||
"custom_options": json.dumps({
|
||||
"type": "line",
|
||||
"axisOptions": {"shortenYAxisNumbers": 1},
|
||||
"tooltipOptions": {},
|
||||
"lineOptions": {
|
||||
"regionFill": 1
|
||||
}
|
||||
}),
|
||||
"doctype": "Dashboard Chart",
|
||||
"filters_json": json.dumps({
|
||||
"company": company.name,
|
||||
"period": "Monthly",
|
||||
"fiscal_year": fiscal_year_name,
|
||||
"based_on": "Item"
|
||||
}),
|
||||
"is_custom": 1,
|
||||
"is_public": 1,
|
||||
"owner": "Administrator",
|
||||
"report_name": "Sales Order Trends",
|
||||
"type": "Line"
|
||||
},
|
||||
{
|
||||
"name": "Top Customers",
|
||||
"chart_name": _("Top Customers"),
|
||||
"chart_type": "Report",
|
||||
"doctype": "Dashboard Chart",
|
||||
"filters_json": json.dumps({
|
||||
"company": company.name,
|
||||
"period": "Monthly",
|
||||
"fiscal_year": fiscal_year_name,
|
||||
"based_on": "Customer"
|
||||
}),
|
||||
"is_custom": 1,
|
||||
"is_public": 1,
|
||||
"owner": "Administrator",
|
||||
"report_name": "Delivery Note Trends",
|
||||
"type": "Bar"
|
||||
}
|
||||
]
|
||||
|
||||
def get_number_cards():
|
||||
return [
|
||||
{
|
||||
"name": "Annual Sales",
|
||||
"aggregate_function_based_on": "base_net_total",
|
||||
"doctype": "Number Card",
|
||||
"document_type": "Sales Order",
|
||||
"filters_json": json.dumps([
|
||||
["Sales Order", "transaction_date", "Between", [start_date, end_date], False],
|
||||
["Sales Order", "status", "not in", ["Draft", "Cancelled", "Closed", None], False],
|
||||
["Sales Order", "docstatus", "=", 1, False],
|
||||
["Sales Order", "company", "=", company.name, False]
|
||||
]),
|
||||
"function": "Sum",
|
||||
"is_public": 1,
|
||||
"label": _("Annual Sales"),
|
||||
"owner": "Administrator",
|
||||
"show_percentage_stats": 1,
|
||||
"stats_time_interval": "Monthly"
|
||||
},
|
||||
{
|
||||
"name": "Sales Orders to Deliver",
|
||||
"doctype": "Number Card",
|
||||
"document_type": "Sales Order",
|
||||
"filters_json": json.dumps([
|
||||
["Sales Order", "status", "in", ["To Deliver and Bill", "To Deliver", None], False],
|
||||
["Sales Order", "docstatus", "=", 1, False],
|
||||
["Sales Order", "company", "=", company.name, False]
|
||||
]),
|
||||
"function": "Count",
|
||||
"is_public": 1,
|
||||
"label": _("Sales Orders to Deliver"),
|
||||
"owner": "Administrator",
|
||||
"show_percentage_stats": 1,
|
||||
"stats_time_interval": "Weekly"
|
||||
},
|
||||
{
|
||||
"name": "Sales Orders to Bill",
|
||||
"doctype": "Number Card",
|
||||
"document_type": "Sales Order",
|
||||
"filters_json": json.dumps([
|
||||
["Sales Order", "status", "in", ["To Deliver and Bill", "To Bill", None], False],
|
||||
["Sales Order", "docstatus", "=", 1, False],
|
||||
["Sales Order", "company", "=", company.name, False]
|
||||
]),
|
||||
"function": "Count",
|
||||
"is_public": 1,
|
||||
"label": _("Sales Orders to Bill"),
|
||||
"owner": "Administrator",
|
||||
"show_percentage_stats": 1,
|
||||
"stats_time_interval": "Weekly"
|
||||
},
|
||||
{
|
||||
"name": "Active Customers",
|
||||
"doctype": "Number Card",
|
||||
"document_type": "Customer",
|
||||
"filters_json": json.dumps([["Customer", "disabled", "=", "0"]]),
|
||||
"function": "Count",
|
||||
"is_public": 1,
|
||||
"label": "Active Customers",
|
||||
"owner": "Administrator",
|
||||
"show_percentage_stats": 1,
|
||||
"stats_time_interval": "Monthly"
|
||||
}
|
||||
]
|
@ -1,5 +1,10 @@
|
||||
{
|
||||
"cards": [
|
||||
{
|
||||
"hidden": 0,
|
||||
"label": "Selling",
|
||||
"links": "[\n {\n \"description\": \"Customer Database.\",\n \"label\": \"Customer\",\n \"name\": \"Customer\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\",\n \"Customer\"\n ],\n \"description\": \"Quotes to Leads or Customers.\",\n \"label\": \"Quotation\",\n \"name\": \"Quotation\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\",\n \"Customer\"\n ],\n \"description\": \"Confirmed orders from Customers.\",\n \"label\": \"Sales Order\",\n \"name\": \"Sales Order\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\",\n \"Customer\"\n ],\n \"label\": \"Sales Invoice\",\n \"name\": \"Sales Invoice\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\",\n \"Customer\"\n ],\n \"description\": \"Blanket Orders from Costumers.\",\n \"label\": \"Blanket Order\",\n \"name\": \"Blanket Order\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"description\": \"Manage Sales Partners.\",\n \"label\": \"Sales Partner\",\n \"name\": \"Sales Partner\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\",\n \"Customer\"\n ],\n \"description\": \"Manage Sales Person Tree.\",\n \"icon\": \"fa fa-sitemap\",\n \"label\": \"Sales Person\",\n \"link\": \"Tree/Sales Person\",\n \"name\": \"Sales Person\",\n \"type\": \"doctype\"\n }\n]"
|
||||
},
|
||||
{
|
||||
"hidden": 0,
|
||||
"label": "Items and Pricing",
|
||||
@ -10,29 +15,25 @@
|
||||
"label": "Settings",
|
||||
"links": "[\n {\n \"description\": \"Default settings for selling transactions.\",\n \"label\": \"Selling Settings\",\n \"name\": \"Selling Settings\",\n \"settings\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Template of terms or contract.\",\n \"label\": \"Terms and Conditions Template\",\n \"name\": \"Terms and Conditions\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Tax template for selling transactions.\",\n \"label\": \"Sales Taxes and Charges Template\",\n \"name\": \"Sales Taxes and Charges Template\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Track Leads by Lead Source.\",\n \"label\": \"Lead Source\",\n \"name\": \"Lead Source\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Manage Customer Group Tree.\",\n \"icon\": \"fa fa-sitemap\",\n \"label\": \"Customer Group\",\n \"link\": \"Tree/Customer Group\",\n \"name\": \"Customer Group\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"All Contacts.\",\n \"label\": \"Contact\",\n \"name\": \"Contact\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"All Addresses.\",\n \"label\": \"Address\",\n \"name\": \"Address\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Manage Territory Tree.\",\n \"icon\": \"fa fa-sitemap\",\n \"label\": \"Territory\",\n \"link\": \"Tree/Territory\",\n \"name\": \"Territory\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Sales campaigns.\",\n \"label\": \"Campaign\",\n \"name\": \"Campaign\",\n \"type\": \"doctype\"\n }\n]"
|
||||
},
|
||||
{
|
||||
"hidden": 0,
|
||||
"label": "Other Reports",
|
||||
"links": "[\n {\n \"dependencies\": [\n \"Lead\"\n ],\n \"doctype\": \"Lead\",\n \"is_query_report\": true,\n \"label\": \"Lead Details\",\n \"name\": \"Lead Details\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Address\"\n ],\n \"doctype\": \"Address\",\n \"is_query_report\": true,\n \"label\": \"Customer Addresses And Contacts\",\n \"name\": \"Address And Contacts\",\n \"route_options\": {\n \"party_type\": \"Customer\"\n },\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"BOM\"\n ],\n \"doctype\": \"BOM\",\n \"is_query_report\": true,\n \"label\": \"BOM Search\",\n \"name\": \"BOM Search\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"doctype\": \"Item\",\n \"is_query_report\": true,\n \"label\": \"Available Stock for Packing Items\",\n \"name\": \"Available Stock for Packing Items\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Order\"\n ],\n \"doctype\": \"Sales Order\",\n \"is_query_report\": true,\n \"label\": \"Pending SO Items For Purchase Request\",\n \"name\": \"Pending SO Items For Purchase Request\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Customer\"\n ],\n \"doctype\": \"Customer\",\n \"is_query_report\": true,\n \"label\": \"Customer Credit Balance\",\n \"name\": \"Customer Credit Balance\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Customer\"\n ],\n \"doctype\": \"Customer\",\n \"is_query_report\": true,\n \"label\": \"Customers Without Any Sales Transactions\",\n \"name\": \"Customers Without Any Sales Transactions\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Customer\"\n ],\n \"doctype\": \"Customer\",\n \"is_query_report\": true,\n \"label\": \"Sales Partners Commission\",\n \"name\": \"Sales Partners Commission\",\n \"type\": \"report\"\n }\n]"
|
||||
},
|
||||
{
|
||||
"hidden": 0,
|
||||
"label": "Sales",
|
||||
"links": "[\n {\n \"description\": \"Customer Database.\",\n \"label\": \"Customer\",\n \"name\": \"Customer\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\",\n \"Customer\"\n ],\n \"description\": \"Quotes to Leads or Customers.\",\n \"label\": \"Quotation\",\n \"name\": \"Quotation\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\",\n \"Customer\"\n ],\n \"description\": \"Confirmed orders from Customers.\",\n \"label\": \"Sales Order\",\n \"name\": \"Sales Order\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\",\n \"Customer\"\n ],\n \"description\": \"Invoices for Costumers.\",\n \"label\": \"Sales Invoice\",\n \"name\": \"Sales Invoice\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\",\n \"Customer\"\n ],\n \"description\": \"Blanket Orders from Costumers.\",\n \"label\": \"Blanket Order\",\n \"name\": \"Blanket Order\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"description\": \"Manage Sales Partners.\",\n \"label\": \"Sales Partner\",\n \"name\": \"Sales Partner\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\",\n \"Customer\"\n ],\n \"description\": \"Manage Sales Person Tree.\",\n \"icon\": \"fa fa-sitemap\",\n \"label\": \"Sales Person\",\n \"link\": \"Tree/Sales Person\",\n \"name\": \"Sales Person\",\n \"type\": \"doctype\"\n }\n]"
|
||||
},
|
||||
{
|
||||
"hidden": 0,
|
||||
"label": "Key Reports",
|
||||
"links": "[\n {\n \"dependencies\": [\n \"Sales Order\"\n ],\n \"doctype\": \"Sales Order\",\n \"is_query_report\": true,\n \"label\": \"Sales Analytics\",\n \"name\": \"Sales Analytics\",\n \"onboard\": 1,\n \"type\": \"report\"\n },\n {\n \"icon\": \"fa fa-bar-chart\",\n \"label\": \"Sales Funnel\",\n \"name\": \"sales-funnel\",\n \"onboard\": 1,\n \"type\": \"page\"\n },\n {\n \"dependencies\": [\n \"Customer\"\n ],\n \"doctype\": \"Customer\",\n \"icon\": \"fa fa-bar-chart\",\n \"is_query_report\": true,\n \"label\": \"Customer Acquisition and Loyalty\",\n \"name\": \"Customer Acquisition and Loyalty\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Order\"\n ],\n \"doctype\": \"Sales Order\",\n \"is_query_report\": true,\n \"label\": \"Inactive Customers\",\n \"name\": \"Inactive Customers\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Order\"\n ],\n \"doctype\": \"Sales Order\",\n \"is_query_report\": true,\n \"label\": \"Ordered Items To Be Delivered\",\n \"name\": \"Ordered Items To Be Delivered\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Order\"\n ],\n \"doctype\": \"Sales Order\",\n \"is_query_report\": true,\n \"label\": \"Sales Person-wise Transaction Summary\",\n \"name\": \"Sales Person-wise Transaction Summary\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"doctype\": \"Item\",\n \"is_query_report\": true,\n \"label\": \"Item-wise Sales History\",\n \"name\": \"Item-wise Sales History\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Quotation\"\n ],\n \"doctype\": \"Quotation\",\n \"is_query_report\": true,\n \"label\": \"Quotation Trends\",\n \"name\": \"Quotation Trends\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Order\"\n ],\n \"doctype\": \"Sales Order\",\n \"is_query_report\": true,\n \"label\": \"Sales Order Trends\",\n \"name\": \"Sales Order Trends\",\n \"type\": \"report\"\n }\n]"
|
||||
"links": "[\n {\n \"dependencies\": [\n \"Sales Order\"\n ],\n \"doctype\": \"Sales Order\",\n \"is_query_report\": true,\n \"label\": \"Sales Analytics\",\n \"name\": \"Sales Analytics\",\n \"onboard\": 1,\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Order\"\n ],\n \"doctype\": \"Sales Order\",\n \"is_query_report\": true,\n \"label\": \"Sales Order Analysis\",\n \"name\": \"Sales Order Analysis\",\n \"onboard\": 1,\n \"type\": \"report\"\n },\n {\n \"icon\": \"fa fa-bar-chart\",\n \"label\": \"Sales Funnel\",\n \"name\": \"sales-funnel\",\n \"onboard\": 1,\n \"type\": \"page\"\n },\n {\n \"dependencies\": [\n \"Sales Order\"\n ],\n \"doctype\": \"Sales Order\",\n \"is_query_report\": true,\n \"label\": \"Sales Order Trends\",\n \"name\": \"Sales Order Trends\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Quotation\"\n ],\n \"doctype\": \"Quotation\",\n \"is_query_report\": true,\n \"label\": \"Quotation Trends\",\n \"name\": \"Quotation Trends\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Customer\"\n ],\n \"doctype\": \"Customer\",\n \"icon\": \"fa fa-bar-chart\",\n \"is_query_report\": true,\n \"label\": \"Customer Acquisition and Loyalty\",\n \"name\": \"Customer Acquisition and Loyalty\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Order\"\n ],\n \"doctype\": \"Sales Order\",\n \"is_query_report\": true,\n \"label\": \"Inactive Customers\",\n \"name\": \"Inactive Customers\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Order\"\n ],\n \"doctype\": \"Sales Order\",\n \"is_query_report\": true,\n \"label\": \"Sales Person-wise Transaction Summary\",\n \"name\": \"Sales Person-wise Transaction Summary\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"doctype\": \"Item\",\n \"is_query_report\": true,\n \"label\": \"Item-wise Sales History\",\n \"name\": \"Item-wise Sales History\",\n \"type\": \"report\"\n }\n]"
|
||||
},
|
||||
{
|
||||
"hidden": 0,
|
||||
"label": "Other Reports",
|
||||
"links": "[\n {\n \"dependencies\": [\n \"Lead\"\n ],\n \"doctype\": \"Lead\",\n \"is_query_report\": true,\n \"label\": \"Lead Details\",\n \"name\": \"Lead Details\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Address\"\n ],\n \"doctype\": \"Address\",\n \"is_query_report\": true,\n \"label\": \"Customer Addresses And Contacts\",\n \"name\": \"Address And Contacts\",\n \"route_options\": {\n \"party_type\": \"Customer\"\n },\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"doctype\": \"Item\",\n \"is_query_report\": true,\n \"label\": \"Available Stock for Packing Items\",\n \"name\": \"Available Stock for Packing Items\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Order\"\n ],\n \"doctype\": \"Sales Order\",\n \"is_query_report\": true,\n \"label\": \"Pending SO Items For Purchase Request\",\n \"name\": \"Pending SO Items For Purchase Request\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Customer\"\n ],\n \"doctype\": \"Customer\",\n \"is_query_report\": true,\n \"label\": \"Customer Credit Balance\",\n \"name\": \"Customer Credit Balance\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Customer\"\n ],\n \"doctype\": \"Customer\",\n \"is_query_report\": true,\n \"label\": \"Customers Without Any Sales Transactions\",\n \"name\": \"Customers Without Any Sales Transactions\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Customer\"\n ],\n \"doctype\": \"Customer\",\n \"is_query_report\": true,\n \"label\": \"Sales Partners Commission\",\n \"name\": \"Sales Partners Commission\",\n \"type\": \"report\"\n }\n]"
|
||||
}
|
||||
],
|
||||
"category": "Modules",
|
||||
"charts": [
|
||||
{
|
||||
"chart_name": "Incoming Bills (Purchase Invoice)",
|
||||
"label": "Income"
|
||||
"chart_name": "Sales Order Trends",
|
||||
"label": "Sales Order Trends"
|
||||
}
|
||||
],
|
||||
"charts_label": "Selling ",
|
||||
"creation": "2020-01-28 11:49:12.092882",
|
||||
"developer_mode_only": 0,
|
||||
"disable_user_customization": 0,
|
||||
@ -43,52 +44,49 @@
|
||||
"idx": 0,
|
||||
"is_standard": 1,
|
||||
"label": "Selling",
|
||||
"modified": "2020-06-03 13:23:24.861706",
|
||||
"modified": "2020-06-19 13:23:24.861706",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Selling",
|
||||
"name": "Selling",
|
||||
"onboarding": "Selling",
|
||||
"owner": "Administrator",
|
||||
"pin_to_bottom": 0,
|
||||
"pin_to_top": 0,
|
||||
"shortcuts": [
|
||||
{
|
||||
"color": "#ffe8cd",
|
||||
"format": "{} Draft",
|
||||
"label": "Sales Invoice",
|
||||
"link_to": "Sales Invoice",
|
||||
"stats_filter": "{ \"status\": \"Draft\" }",
|
||||
"color": "#cef6d1",
|
||||
"format": "{} Available",
|
||||
"label": "Item",
|
||||
"link_to": "Item",
|
||||
"stats_filter": "{\n \"disabled\":0\n}",
|
||||
"type": "DocType"
|
||||
},
|
||||
{
|
||||
"color": "#ffe8cd",
|
||||
"format": "{} To Deliver",
|
||||
"format": "{} To Deliver",
|
||||
"label": "Sales Order",
|
||||
"link_to": "Sales Order",
|
||||
"stats_filter": "{\"Status\": \"To Deliver and Bill\"}",
|
||||
"stats_filter": "{\n \"company\": [\"like\", '%' + frappe.defaults.get_global_default(\"company\") + '%'],\n \"status\":[\"in\", [\"To Deliver\", \"To Deliver and Bill\"]]\n}",
|
||||
"type": "DocType"
|
||||
},
|
||||
{
|
||||
"color": "#cef6d1",
|
||||
"format": "{} Open",
|
||||
"label": "Quotation",
|
||||
"link_to": "Quotation",
|
||||
"label": "Sales Analytics",
|
||||
"link_to": "Sales Analytics",
|
||||
"stats_filter": "{ \"Status\": \"Open\" }",
|
||||
"type": "DocType"
|
||||
},
|
||||
{
|
||||
"label": "Delivery Note",
|
||||
"link_to": "Delivery Note",
|
||||
"type": "DocType"
|
||||
},
|
||||
{
|
||||
"label": "Accounts Receivable",
|
||||
"link_to": "Accounts Receivable",
|
||||
"type": "Report"
|
||||
},
|
||||
{
|
||||
"label": "Sales Register",
|
||||
"link_to": "Sales Register",
|
||||
"label": "Sales Order Analysis",
|
||||
"link_to": "Sales Order Analysis",
|
||||
"type": "Report"
|
||||
},
|
||||
{
|
||||
"label": "Dashboard",
|
||||
"link_to": "Selling",
|
||||
"type": "Dashboard"
|
||||
}
|
||||
]
|
||||
],
|
||||
"shortcuts_label": "Quick Access"
|
||||
}
|
@ -6,3 +6,26 @@ frappe.ui.form.on('Selling Settings', {
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
frappe.tour['Selling Settings'] = [
|
||||
{
|
||||
fieldname: "cust_master_name",
|
||||
title: "Customer Naming By",
|
||||
description: __("By default, the Customer Name is set as per the Full Name entered. If you want Customers to be named by a ") + "<a href='https://docs.erpnext.com/docs/user/manual/en/setting-up/settings/naming-series' target='_blank'>Naming Series</a>" + __(" choose the 'Naming Series' option."),
|
||||
},
|
||||
{
|
||||
fieldname: "selling_price_list",
|
||||
title: "Default Selling Price List",
|
||||
description: __("Configure the default Price List when creating a new Sales transaction. Item prices will be fetched from this Price List.")
|
||||
},
|
||||
{
|
||||
fieldname: "so_required",
|
||||
title: "Sales Order Required for Sales Invoice & Delivery Note Creation",
|
||||
description: __("If this option is configured 'Yes', ERPNext will prevent you from creating a Sales Invoice or Delivery Note without creating a Sales Order first. This configuration can be overridden for a particular Customer by enabling the 'Allow Sales Invoice Creation Without Sales Order' checkbox in the Customer master.")
|
||||
},
|
||||
{
|
||||
fieldname: "dn_required",
|
||||
title: "Delivery Note Required for Sales Invoice Creation",
|
||||
description: __("If this option is configured 'Yes', ERPNext will prevent you from creating a Sales Invoice without creating a Delivery Note first. This configuration can be overridden for a particular Customer by enabling the 'Allow Sales Invoice Creation Without Delivery Note' checkbox in the Customer master.")
|
||||
}
|
||||
];
|
@ -1,4 +1,5 @@
|
||||
{
|
||||
"actions": [],
|
||||
"creation": "2013-06-25 10:25:16",
|
||||
"description": "Settings for Selling Module",
|
||||
"doctype": "DocType",
|
||||
@ -79,13 +80,13 @@
|
||||
{
|
||||
"fieldname": "so_required",
|
||||
"fieldtype": "Select",
|
||||
"label": "Sales Order Required",
|
||||
"label": "Sales Order Required for Sales Invoice & Delivery Note Creation",
|
||||
"options": "No\nYes"
|
||||
},
|
||||
{
|
||||
"fieldname": "dn_required",
|
||||
"fieldtype": "Select",
|
||||
"label": "Delivery Note Required",
|
||||
"label": "Delivery Note Required for Sales Invoice Creation",
|
||||
"options": "No\nYes"
|
||||
},
|
||||
{
|
||||
@ -137,7 +138,8 @@
|
||||
"icon": "fa fa-cog",
|
||||
"idx": 1,
|
||||
"issingle": 1,
|
||||
"modified": "2019-12-09 13:38:36.486298",
|
||||
"links": [],
|
||||
"modified": "2020-06-01 13:58:35.637858",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Selling",
|
||||
"name": "Selling Settings",
|
||||
|
54
erpnext/selling/module_onboarding/selling/selling.json
Normal file
54
erpnext/selling/module_onboarding/selling/selling.json
Normal file
@ -0,0 +1,54 @@
|
||||
{
|
||||
"allow_roles": [
|
||||
{
|
||||
"role": "Sales Manager"
|
||||
},
|
||||
{
|
||||
"role": "Sales User"
|
||||
},
|
||||
{
|
||||
"role": "Stock Manager"
|
||||
},
|
||||
{
|
||||
"role": "Stock User"
|
||||
}
|
||||
],
|
||||
"creation": "2020-06-01 12:44:42.589930",
|
||||
"docstatus": 0,
|
||||
"doctype": "Module Onboarding",
|
||||
"documentation_url": "https://docs.erpnext.com/docs/user/manual/en/selling",
|
||||
"idx": 0,
|
||||
"is_complete": 0,
|
||||
"modified": "2020-06-01 13:35:16.100512",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Selling",
|
||||
"name": "Selling",
|
||||
"owner": "Administrator",
|
||||
"steps": [
|
||||
{
|
||||
"step": "Introduction to Selling"
|
||||
},
|
||||
{
|
||||
"step": "Create a Customer"
|
||||
},
|
||||
{
|
||||
"step": "Setup your Warehouse"
|
||||
},
|
||||
{
|
||||
"step": "Create a Product"
|
||||
},
|
||||
{
|
||||
"step": "Create a Quotation"
|
||||
},
|
||||
{
|
||||
"step": "Create your first Sales Order"
|
||||
},
|
||||
{
|
||||
"step": "Selling Settings"
|
||||
}
|
||||
],
|
||||
"subtitle": "Products, Sales, Analysis and more.",
|
||||
"success_message": "The Selling Module is all set up!",
|
||||
"title": "Let's Set Up the Selling Module.",
|
||||
"user_can_dismiss": 1
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
{
|
||||
"action": "Create Entry",
|
||||
"creation": "2020-05-14 17:46:41.831517",
|
||||
"docstatus": 0,
|
||||
"doctype": "Onboarding Step",
|
||||
"idx": 0,
|
||||
"is_complete": 0,
|
||||
"is_mandatory": 0,
|
||||
"is_single": 0,
|
||||
"is_skipped": 0,
|
||||
"modified": "2020-06-01 13:16:19.731719",
|
||||
"modified_by": "Administrator",
|
||||
"name": "Create a Customer",
|
||||
"owner": "Administrator",
|
||||
"reference_document": "Customer",
|
||||
"show_full_form": 0,
|
||||
"title": "Create a Customer",
|
||||
"validate_action": 1
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
{
|
||||
"action": "Create Entry",
|
||||
"creation": "2020-05-12 18:16:06.624554",
|
||||
"docstatus": 0,
|
||||
"doctype": "Onboarding Step",
|
||||
"idx": 0,
|
||||
"is_complete": 0,
|
||||
"is_mandatory": 0,
|
||||
"is_single": 0,
|
||||
"is_skipped": 0,
|
||||
"modified": "2020-05-12 18:30:02.489949",
|
||||
"modified_by": "Administrator",
|
||||
"name": "Create a Product",
|
||||
"owner": "Administrator",
|
||||
"reference_document": "Item",
|
||||
"show_full_form": 0,
|
||||
"title": "Create a Product",
|
||||
"validate_action": 1
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
{
|
||||
"action": "Create Entry",
|
||||
"creation": "2020-06-01 13:34:58.958641",
|
||||
"docstatus": 0,
|
||||
"doctype": "Onboarding Step",
|
||||
"idx": 0,
|
||||
"is_complete": 0,
|
||||
"is_mandatory": 0,
|
||||
"is_single": 0,
|
||||
"is_skipped": 0,
|
||||
"modified": "2020-06-01 13:34:58.958641",
|
||||
"modified_by": "Administrator",
|
||||
"name": "Create a Quotation",
|
||||
"owner": "Administrator",
|
||||
"reference_document": "Quotation",
|
||||
"show_full_form": 1,
|
||||
"title": "Create a Quotation",
|
||||
"validate_action": 1
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
{
|
||||
"action": "Create Entry",
|
||||
"creation": "2020-05-05 16:42:31.476275",
|
||||
"docstatus": 0,
|
||||
"doctype": "Onboarding Step",
|
||||
"idx": 0,
|
||||
"is_complete": 0,
|
||||
"is_mandatory": 1,
|
||||
"is_single": 0,
|
||||
"is_skipped": 0,
|
||||
"modified": "2020-05-19 12:50:59.010439",
|
||||
"modified_by": "Administrator",
|
||||
"name": "Create Product",
|
||||
"owner": "Administrator",
|
||||
"reference_document": "Item",
|
||||
"show_full_form": 0,
|
||||
"title": "Create a Finished Good",
|
||||
"validate_action": 1
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
{
|
||||
"action": "Create Entry",
|
||||
"creation": "2020-06-01 12:52:27.181841",
|
||||
"docstatus": 0,
|
||||
"doctype": "Onboarding Step",
|
||||
"idx": 0,
|
||||
"is_complete": 0,
|
||||
"is_mandatory": 1,
|
||||
"is_single": 0,
|
||||
"is_skipped": 0,
|
||||
"modified": "2020-06-01 12:52:27.181841",
|
||||
"modified_by": "Administrator",
|
||||
"name": "Create your first Sales Order",
|
||||
"owner": "Administrator",
|
||||
"reference_document": "Sales Order",
|
||||
"show_full_form": 1,
|
||||
"title": "Create your first Sales Order",
|
||||
"validate_action": 1
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
{
|
||||
"action": "Watch Video",
|
||||
"creation": "2020-06-01 12:44:32.089234",
|
||||
"docstatus": 0,
|
||||
"doctype": "Onboarding Step",
|
||||
"idx": 0,
|
||||
"is_complete": 0,
|
||||
"is_mandatory": 0,
|
||||
"is_single": 0,
|
||||
"is_skipped": 0,
|
||||
"modified": "2020-06-01 13:29:13.703177",
|
||||
"modified_by": "Administrator",
|
||||
"name": "Introduction to Selling",
|
||||
"owner": "Administrator",
|
||||
"show_full_form": 0,
|
||||
"title": "Introduction to Selling",
|
||||
"validate_action": 1,
|
||||
"video_url": "https://youtu.be/1eP90MWoDQM"
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
{
|
||||
"action": "Show Form Tour",
|
||||
"creation": "2020-06-01 13:01:45.615189",
|
||||
"docstatus": 0,
|
||||
"doctype": "Onboarding Step",
|
||||
"idx": 0,
|
||||
"is_complete": 0,
|
||||
"is_mandatory": 0,
|
||||
"is_single": 1,
|
||||
"is_skipped": 0,
|
||||
"modified": "2020-06-01 13:04:14.980743",
|
||||
"modified_by": "Administrator",
|
||||
"name": "Selling Settings",
|
||||
"owner": "Administrator",
|
||||
"reference_document": "Selling Settings",
|
||||
"show_full_form": 0,
|
||||
"title": "Configure Selling Settings.",
|
||||
"validate_action": 0
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
{
|
||||
"action": "Go to Page",
|
||||
"creation": "2020-05-19 18:54:19.383397",
|
||||
"docstatus": 0,
|
||||
"doctype": "Onboarding Step",
|
||||
"idx": 0,
|
||||
"is_complete": 0,
|
||||
"is_mandatory": 0,
|
||||
"is_single": 0,
|
||||
"is_skipped": 0,
|
||||
"modified": "2020-05-19 18:54:19.383397",
|
||||
"modified_by": "Administrator",
|
||||
"name": "Setup your Warehouse",
|
||||
"owner": "Administrator",
|
||||
"path": "Tree/Warehouse",
|
||||
"reference_document": "Warehouse",
|
||||
"show_full_form": 0,
|
||||
"title": "Setup your Warehouse",
|
||||
"validate_action": 1
|
||||
}
|
@ -12,12 +12,6 @@ frappe.query_reports["Item-wise Sales History"] = {
|
||||
default: frappe.defaults.get_user_default("Company"),
|
||||
reqd: 1
|
||||
},
|
||||
{
|
||||
fieldname:"item_group",
|
||||
label: __("Item Group"),
|
||||
fieldtype: "Link",
|
||||
options: "Item Group"
|
||||
},
|
||||
{
|
||||
fieldname:"from_date",
|
||||
reqd: 1,
|
||||
@ -32,6 +26,38 @@ frappe.query_reports["Item-wise Sales History"] = {
|
||||
label: __("To Date"),
|
||||
fieldtype: "Date",
|
||||
},
|
||||
{
|
||||
fieldname:"item_group",
|
||||
label: __("Item Group"),
|
||||
fieldtype: "Link",
|
||||
options: "Item Group"
|
||||
},
|
||||
{
|
||||
fieldname:"item_code",
|
||||
label: __("Item"),
|
||||
fieldtype: "Link",
|
||||
options: "Item",
|
||||
get_query: () => {
|
||||
return {
|
||||
query: "erpnext.controllers.queries.item_query"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
fieldname:"customer",
|
||||
label: __("Customer"),
|
||||
fieldtype: "Link",
|
||||
options: "Customer"
|
||||
}
|
||||
],
|
||||
|
||||
]
|
||||
"formatter": function (value, row, column, data, default_formatter) {
|
||||
value = default_formatter(value, row, column, data);
|
||||
let format_fields = ["delivered_quantity", "billed_amount"];
|
||||
|
||||
if (in_list(format_fields, column.fieldname) && data && data[column.fieldname] > 0) {
|
||||
value = "<span style='color:green;'>" + value + "</span>";
|
||||
}
|
||||
return value;
|
||||
}
|
||||
};
|
@ -11,7 +11,10 @@ def execute(filters=None):
|
||||
filters = frappe._dict(filters or {})
|
||||
columns = get_columns(filters)
|
||||
data = get_data(filters)
|
||||
return columns, data
|
||||
|
||||
chart_data = get_chart_data(data)
|
||||
|
||||
return columns, data, None, chart_data
|
||||
|
||||
def get_columns(filters):
|
||||
return [
|
||||
@ -181,6 +184,12 @@ def get_conditions(filters):
|
||||
if filters.get('to_date'):
|
||||
conditions += "AND so.transaction_date <= '%s'" %filters.to_date
|
||||
|
||||
if filters.get("item_code"):
|
||||
conditions += "AND so_item.item_code = '%s'" %frappe.db.escape(filters.item_code)
|
||||
|
||||
if filters.get("customer"):
|
||||
conditions += "AND so.customer = '%s'" %frappe.db.escape(filters.customer)
|
||||
|
||||
return conditions
|
||||
|
||||
def get_customer_details():
|
||||
@ -212,3 +221,34 @@ def get_sales_order_details(company_list, filters):
|
||||
AND so.company in ({0})
|
||||
AND so.docstatus = 1 {1}
|
||||
""".format(','.join(["%s"] * len(company_list)), conditions), tuple(company_list), as_dict=1)
|
||||
|
||||
def get_chart_data(data):
|
||||
item_wise_sales_map = {}
|
||||
labels, datapoints = [], []
|
||||
|
||||
for row in data:
|
||||
item_key = row.get("item_code")
|
||||
|
||||
if not item_key in item_wise_sales_map:
|
||||
item_wise_sales_map[item_key] = 0
|
||||
|
||||
item_wise_sales_map[item_key] = flt(item_wise_sales_map[item_key]) + flt(row.get("amount"))
|
||||
|
||||
item_wise_sales_map = { item: value for item, value in (sorted(item_wise_sales_map.items(), key = lambda i: i[1], reverse=True))}
|
||||
|
||||
for key in item_wise_sales_map:
|
||||
labels.append(key)
|
||||
datapoints.append(item_wise_sales_map[key])
|
||||
|
||||
return {
|
||||
"data" : {
|
||||
"labels" : labels[:30], # show max of 30 items in chart
|
||||
"datasets" : [
|
||||
{
|
||||
"name" : _(" Total Sales Amount"),
|
||||
"values" : datapoints[:30]
|
||||
}
|
||||
]
|
||||
},
|
||||
"type" : "bar"
|
||||
}
|
@ -3,6 +3,7 @@
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe import _
|
||||
from erpnext.controllers.trends import get_columns, get_data
|
||||
|
||||
def execute(filters=None):
|
||||
@ -11,4 +12,48 @@ def execute(filters=None):
|
||||
conditions = get_columns(filters, "Quotation")
|
||||
data = get_data(filters, conditions)
|
||||
|
||||
return conditions["columns"], data
|
||||
chart_data = get_chart_data(data, conditions, filters)
|
||||
|
||||
return conditions["columns"], data, None, chart_data
|
||||
|
||||
def get_chart_data(data, conditions, filters):
|
||||
if not (data and conditions):
|
||||
return []
|
||||
|
||||
datapoints = []
|
||||
|
||||
start = 2 if filters.get("based_on") in ["Item", "Customer"] else 1
|
||||
if filters.get("group_by"):
|
||||
start += 1
|
||||
|
||||
# fetch only periodic columns as labels
|
||||
columns = conditions.get("columns")[start:-2][1::2]
|
||||
labels = [column.split(':')[0] for column in columns]
|
||||
datapoints = [0] * len(labels)
|
||||
|
||||
for row in data:
|
||||
# If group by filter, don't add first row of group (it's already summed)
|
||||
if not row[start-1]:
|
||||
continue
|
||||
# Remove None values and compute only periodic data
|
||||
row = [x if x else 0 for x in row[start:-2]]
|
||||
row = row[1::2]
|
||||
|
||||
for i in range(len(row)):
|
||||
datapoints[i] += row[i]
|
||||
|
||||
return {
|
||||
"data" : {
|
||||
"labels" : labels,
|
||||
"datasets" : [
|
||||
{
|
||||
"name" : _("{0}").format(filters.get("period")) + _(" Quoted Amount"),
|
||||
"values" : datapoints
|
||||
}
|
||||
]
|
||||
},
|
||||
"type" : "line",
|
||||
"lineOptions": {
|
||||
"regionFill": 1
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,85 @@
|
||||
// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
|
||||
// For license information, please see license.txt
|
||||
/* eslint-disable */
|
||||
|
||||
frappe.query_reports["Sales Order Analysis"] = {
|
||||
"filters": [
|
||||
{
|
||||
"fieldname": "company",
|
||||
"label": __("Company"),
|
||||
"fieldtype": "Link",
|
||||
"width": "80",
|
||||
"options": "Company",
|
||||
"reqd": 1,
|
||||
"default": frappe.defaults.get_default("company")
|
||||
},
|
||||
{
|
||||
"fieldname":"from_date",
|
||||
"label": __("From Date"),
|
||||
"fieldtype": "Date",
|
||||
"width": "80",
|
||||
"reqd": 1,
|
||||
"default": frappe.datetime.add_months(frappe.datetime.get_today(), -1),
|
||||
},
|
||||
{
|
||||
"fieldname":"to_date",
|
||||
"label": __("To Date"),
|
||||
"fieldtype": "Date",
|
||||
"width": "80",
|
||||
"reqd": 1,
|
||||
"default": frappe.datetime.get_today()
|
||||
},
|
||||
{
|
||||
"fieldname": "sales_order",
|
||||
"label": __("Sales Order"),
|
||||
"fieldtype": "MultiSelectList",
|
||||
"width": "80",
|
||||
"options": "Sales Order",
|
||||
"get_data": function(txt) {
|
||||
return frappe.db.get_link_options("Sales Order", txt);
|
||||
},
|
||||
"get_query": () =>{
|
||||
return {
|
||||
filters: { "docstatus": 1 }
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"fieldname": "status",
|
||||
"label": __("Status"),
|
||||
"fieldtype": "MultiSelectList",
|
||||
"width": "80",
|
||||
get_data: function(txt) {
|
||||
let status = ["To Bill", "To Deliver", "To Deliver and Bill", "Completed"]
|
||||
let options = []
|
||||
for (let option of status){
|
||||
options.push({
|
||||
"value": option,
|
||||
"description": ""
|
||||
})
|
||||
}
|
||||
return options
|
||||
}
|
||||
},
|
||||
{
|
||||
"fieldname": "group_by_so",
|
||||
"label": __("Group by Sales Order"),
|
||||
"fieldtype": "Check",
|
||||
"default": 0
|
||||
}
|
||||
],
|
||||
|
||||
"formatter": function (value, row, column, data, default_formatter) {
|
||||
value = default_formatter(value, row, column, data);
|
||||
let format_fields = ["delivered_qty", "billed_amount"];
|
||||
|
||||
if (in_list(format_fields, column.fieldname) && data && data[column.fieldname] > 0) {
|
||||
value = "<span style='color:green;'>" + value + "</span>";
|
||||
}
|
||||
|
||||
if (column.fieldname == "delay" && data && data[column.fieldname] > 0) {
|
||||
value = "<span style='color:red;'>" + value + "</span>";
|
||||
}
|
||||
return value;
|
||||
}
|
||||
};
|
@ -0,0 +1,36 @@
|
||||
{
|
||||
"add_total_row": 1,
|
||||
"creation": "2020-05-29 14:54:53.591445",
|
||||
"disable_prepared_report": 0,
|
||||
"disabled": 0,
|
||||
"docstatus": 0,
|
||||
"doctype": "Report",
|
||||
"idx": 0,
|
||||
"is_standard": "Yes",
|
||||
"modified": "2020-05-29 14:54:53.591445",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Selling",
|
||||
"name": "Sales Order Analysis",
|
||||
"owner": "Administrator",
|
||||
"prepared_report": 0,
|
||||
"ref_doctype": "Sales Order",
|
||||
"report_name": "Sales Order Analysis",
|
||||
"report_type": "Script Report",
|
||||
"roles": [
|
||||
{
|
||||
"role": "Sales User"
|
||||
},
|
||||
{
|
||||
"role": "Sales Manager"
|
||||
},
|
||||
{
|
||||
"role": "Maintenance User"
|
||||
},
|
||||
{
|
||||
"role": "Accounts User"
|
||||
},
|
||||
{
|
||||
"role": "Stock User"
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,279 @@
|
||||
# Copyright (c) 2013, Frappe Technologies Pvt. Ltd. and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
import copy
|
||||
from frappe import _
|
||||
from frappe.utils import flt, date_diff, getdate
|
||||
|
||||
def execute(filters=None):
|
||||
if not filters:
|
||||
return [], [], None, []
|
||||
|
||||
validate_filters(filters)
|
||||
|
||||
columns = get_columns(filters)
|
||||
conditions = get_conditions(filters)
|
||||
data = get_data(conditions, filters)
|
||||
|
||||
if not data:
|
||||
return [], [], None, []
|
||||
|
||||
data, chart_data = prepare_data(data, filters)
|
||||
|
||||
return columns, data, None, chart_data
|
||||
|
||||
def validate_filters(filters):
|
||||
from_date, to_date = filters.get("from_date"), filters.get("to_date")
|
||||
|
||||
if not from_date and to_date:
|
||||
frappe.throw(_("From and To Dates are required."))
|
||||
elif date_diff(to_date, from_date) < 0:
|
||||
frappe.throw(_("To Date cannot be before From Date."))
|
||||
|
||||
def get_conditions(filters):
|
||||
conditions = ""
|
||||
if filters.get("from_date") and filters.get("to_date"):
|
||||
conditions += " and so.transaction_date between %(from_date)s and %(to_date)s"
|
||||
|
||||
if filters.get("company"):
|
||||
conditions += " and so.company = %(company)s"
|
||||
|
||||
if filters.get("sales_order"):
|
||||
conditions += " and so.name in %(sales_order)s"
|
||||
|
||||
if filters.get("status"):
|
||||
conditions += " and so.status in %(status)s"
|
||||
|
||||
return conditions
|
||||
|
||||
def get_data(conditions, filters):
|
||||
data = frappe.db.sql("""
|
||||
SELECT
|
||||
so.transaction_date as date,
|
||||
soi.delivery_date as delivery_date,
|
||||
so.name as sales_order,
|
||||
so.status, so.customer, soi.item_code,
|
||||
DATEDIFF(CURDATE(), soi.delivery_date) as delay_days,
|
||||
IF(so.status in ('Completed','To Bill'), 0, (SELECT delay_days)) as delay,
|
||||
soi.qty, soi.delivered_qty,
|
||||
(soi.qty - soi.delivered_qty) AS pending_qty,
|
||||
IFNULL(sii.qty, 0) as billed_qty,
|
||||
soi.base_amount as amount,
|
||||
(soi.delivered_qty * soi.base_rate) as delivered_qty_amount,
|
||||
(soi.billed_amt * IFNULL(so.conversion_rate, 1)) as billed_amount,
|
||||
(soi.base_amount - (soi.billed_amt * IFNULL(so.conversion_rate, 1))) as pending_amount,
|
||||
soi.warehouse as warehouse,
|
||||
so.company, soi.name
|
||||
FROM
|
||||
`tabSales Order` so,
|
||||
`tabSales Order Item` soi
|
||||
LEFT JOIN `tabSales Invoice Item` sii
|
||||
ON sii.so_detail = soi.name
|
||||
WHERE
|
||||
soi.parent = so.name
|
||||
and so.status not in ('Stopped', 'Closed', 'On Hold')
|
||||
and so.docstatus = 1
|
||||
{conditions}
|
||||
GROUP BY soi.name
|
||||
ORDER BY so.transaction_date ASC
|
||||
""".format(conditions=conditions), filters, as_dict=1)
|
||||
|
||||
return data
|
||||
|
||||
def prepare_data(data, filters):
|
||||
completed, pending = 0, 0
|
||||
|
||||
if filters.get("group_by_so"):
|
||||
sales_order_map = {}
|
||||
|
||||
for row in data:
|
||||
# sum data for chart
|
||||
completed += row["billed_amount"]
|
||||
pending += row["pending_amount"]
|
||||
|
||||
# prepare data for report view
|
||||
row["qty_to_bill"] = flt(row["qty"]) - flt(row["billed_qty"])
|
||||
|
||||
row["delay"] = 0 if row["delay"] < 0 else row["delay"]
|
||||
if filters.get("group_by_so"):
|
||||
so_name = row["sales_order"]
|
||||
|
||||
if not so_name in sales_order_map:
|
||||
# create an entry
|
||||
row_copy = copy.deepcopy(row)
|
||||
sales_order_map[so_name] = row_copy
|
||||
else:
|
||||
# update existing entry
|
||||
so_row = sales_order_map[so_name]
|
||||
so_row["required_date"] = max(getdate(so_row["delivery_date"]), getdate(row["delivery_date"]))
|
||||
so_row["delay"] = min(so_row["delay"], row["delay"])
|
||||
|
||||
# sum numeric columns
|
||||
fields = ["qty", "delivered_qty", "pending_qty", "billed_qty", "qty_to_bill", "amount",
|
||||
"delivered_qty_amount", "billed_amount", "pending_amount"]
|
||||
for field in fields:
|
||||
so_row[field] = flt(row[field]) + flt(so_row[field])
|
||||
|
||||
chart_data = prepare_chart_data(pending, completed)
|
||||
|
||||
if filters.get("group_by_so"):
|
||||
data = []
|
||||
for so in sales_order_map:
|
||||
data.append(sales_order_map[so])
|
||||
return data, chart_data
|
||||
|
||||
return data, chart_data
|
||||
|
||||
def prepare_chart_data(pending, completed):
|
||||
labels = ["Amount to Bill", "Billed Amount"]
|
||||
|
||||
return {
|
||||
"data" : {
|
||||
"labels": labels,
|
||||
"datasets": [
|
||||
{"values": [pending, completed]}
|
||||
]
|
||||
},
|
||||
"type": 'donut',
|
||||
"height": 300
|
||||
}
|
||||
|
||||
def get_columns(filters):
|
||||
columns = [
|
||||
{
|
||||
"label":_("Date"),
|
||||
"fieldname": "date",
|
||||
"fieldtype": "Date",
|
||||
"width": 90
|
||||
},
|
||||
{
|
||||
"label": _("Sales Order"),
|
||||
"fieldname": "sales_order",
|
||||
"fieldtype": "Link",
|
||||
"options": "Sales Order",
|
||||
"width": 160
|
||||
},
|
||||
{
|
||||
"label":_("Status"),
|
||||
"fieldname": "status",
|
||||
"fieldtype": "Data",
|
||||
"width": 130
|
||||
},
|
||||
{
|
||||
"label": _("Customer"),
|
||||
"fieldname": "customer",
|
||||
"fieldtype": "Link",
|
||||
"options": "Customer",
|
||||
"width": 130
|
||||
}]
|
||||
|
||||
if not filters.get("group_by_so"):
|
||||
columns.append({
|
||||
"label":_("Item Code"),
|
||||
"fieldname": "item_code",
|
||||
"fieldtype": "Link",
|
||||
"options": "Item",
|
||||
"width": 100
|
||||
})
|
||||
|
||||
columns.extend([
|
||||
{
|
||||
"label": _("Qty"),
|
||||
"fieldname": "qty",
|
||||
"fieldtype": "Float",
|
||||
"width": 120,
|
||||
"convertible": "qty"
|
||||
},
|
||||
{
|
||||
"label": _("Delivered Qty"),
|
||||
"fieldname": "delivered_qty",
|
||||
"fieldtype": "Float",
|
||||
"width": 120,
|
||||
"convertible": "qty"
|
||||
},
|
||||
{
|
||||
"label": _("Qty to Deliver"),
|
||||
"fieldname": "pending_qty",
|
||||
"fieldtype": "Float",
|
||||
"width": 120,
|
||||
"convertible": "qty"
|
||||
},
|
||||
{
|
||||
"label": _("Billed Qty"),
|
||||
"fieldname": "billed_qty",
|
||||
"fieldtype": "Float",
|
||||
"width": 80,
|
||||
"convertible": "qty"
|
||||
},
|
||||
{
|
||||
"label": _("Qty to Bill"),
|
||||
"fieldname": "qty_to_bill",
|
||||
"fieldtype": "Float",
|
||||
"width": 80,
|
||||
"convertible": "qty"
|
||||
},
|
||||
{
|
||||
"label": _("Amount"),
|
||||
"fieldname": "amount",
|
||||
"fieldtype": "Currency",
|
||||
"width": 110,
|
||||
"options": "Company:company:default_currency",
|
||||
"convertible": "rate"
|
||||
},
|
||||
{
|
||||
"label": _("Billed Amount"),
|
||||
"fieldname": "billed_amount",
|
||||
"fieldtype": "Currency",
|
||||
"width": 110,
|
||||
"options": "Company:company:default_currency",
|
||||
"convertible": "rate"
|
||||
},
|
||||
{
|
||||
"label": _("Pending Amount"),
|
||||
"fieldname": "pending_amount",
|
||||
"fieldtype": "Currency",
|
||||
"width": 130,
|
||||
"options": "Company:company:default_currency",
|
||||
"convertible": "rate"
|
||||
},
|
||||
{
|
||||
"label": _("Amount Delivered"),
|
||||
"fieldname": "delivered_qty_amount",
|
||||
"fieldtype": "Currency",
|
||||
"width": 100,
|
||||
"options": "Company:company:default_currency",
|
||||
"convertible": "rate"
|
||||
},
|
||||
{
|
||||
"label":_("Delivery Date"),
|
||||
"fieldname": "delivery_date",
|
||||
"fieldtype": "Date",
|
||||
"width": 120
|
||||
},
|
||||
{
|
||||
"label": _("Delay (in Days)"),
|
||||
"fieldname": "delay",
|
||||
"fieldtype": "Data",
|
||||
"width": 100
|
||||
}
|
||||
])
|
||||
if not filters.get("group_by_so"):
|
||||
columns.append({
|
||||
"label": _("Warehouse"),
|
||||
"fieldname": "warehouse",
|
||||
"fieldtype": "Link",
|
||||
"options": "Warehouse",
|
||||
"width": 100
|
||||
})
|
||||
columns.append({
|
||||
"label": _("Company"),
|
||||
"fieldname": "company",
|
||||
"fieldtype": "Link",
|
||||
"options": "Company",
|
||||
"width": 100
|
||||
})
|
||||
|
||||
|
||||
return columns
|
@ -3,6 +3,7 @@
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe import _
|
||||
from erpnext.controllers.trends import get_columns,get_data
|
||||
|
||||
def execute(filters=None):
|
||||
@ -10,4 +11,48 @@ def execute(filters=None):
|
||||
data = []
|
||||
conditions = get_columns(filters, "Sales Order")
|
||||
data = get_data(filters, conditions)
|
||||
return conditions["columns"], data
|
||||
chart_data = get_chart_data(data, conditions, filters)
|
||||
|
||||
return conditions["columns"], data, None, chart_data
|
||||
|
||||
def get_chart_data(data, conditions, filters):
|
||||
if not (data and conditions):
|
||||
return []
|
||||
|
||||
datapoints = []
|
||||
|
||||
start = 2 if filters.get("based_on") in ["Item", "Customer"] else 1
|
||||
if filters.get("group_by"):
|
||||
start += 1
|
||||
|
||||
# fetch only periodic columns as labels
|
||||
columns = conditions.get("columns")[start:-2][1::2]
|
||||
labels = [column.split(':')[0] for column in columns]
|
||||
datapoints = [0] * len(labels)
|
||||
|
||||
for row in data:
|
||||
# If group by filter, don't add first row of group (it's already summed)
|
||||
if not row[start-1]:
|
||||
continue
|
||||
# Remove None values and compute only periodic data
|
||||
row = [x if x else 0 for x in row[start:-2]]
|
||||
row = row[1::2]
|
||||
|
||||
for i in range(len(row)):
|
||||
datapoints[i] += row[i]
|
||||
|
||||
return {
|
||||
"data" : {
|
||||
"labels" : labels,
|
||||
"datasets" : [
|
||||
{
|
||||
"name" : _("{0}").format(filters.get("period")) + _(" Sales Value"),
|
||||
"values" : datapoints
|
||||
}
|
||||
]
|
||||
},
|
||||
"type" : "line",
|
||||
"lineOptions": {
|
||||
"regionFill": 1
|
||||
}
|
||||
}
|
||||
|
@ -33,7 +33,7 @@
|
||||
{
|
||||
"hidden": 0,
|
||||
"label": "Key Reports",
|
||||
"links": "[\n {\n \"dependencies\": [\n \"Item Price\"\n ],\n \"doctype\": \"Item Price\",\n \"is_query_report\": false,\n \"label\": \"Item-wise Price List Rate\",\n \"name\": \"Item-wise Price List Rate\",\n \"onboard\": 1,\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Stock Entry\"\n ],\n \"doctype\": \"Stock Entry\",\n \"is_query_report\": true,\n \"label\": \"Stock Analytics\",\n \"name\": \"Stock Analytics\",\n \"onboard\": 1,\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Delivery Note\"\n ],\n \"doctype\": \"Delivery Note\",\n \"is_query_report\": true,\n \"label\": \"Delivery Note Trends\",\n \"name\": \"Delivery Note Trends\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Purchase Receipt\"\n ],\n \"doctype\": \"Purchase Receipt\",\n \"is_query_report\": true,\n \"label\": \"Purchase Receipt Trends\",\n \"name\": \"Purchase Receipt Trends\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Delivery Note\"\n ],\n \"doctype\": \"Delivery Note\",\n \"is_query_report\": true,\n \"label\": \"Ordered Items To Be Delivered\",\n \"name\": \"Ordered Items To Be Delivered\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Purchase Order\"\n ],\n \"doctype\": \"Purchase Order\",\n \"is_query_report\": true,\n \"label\": \"Purchase Order Analysis\",\n \"name\": \"Purchase Order Analysis\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Bin\"\n ],\n \"doctype\": \"Bin\",\n \"is_query_report\": true,\n \"label\": \"Item Shortage Report\",\n \"name\": \"Item Shortage Report\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Batch\"\n ],\n \"doctype\": \"Batch\",\n \"is_query_report\": true,\n \"label\": \"Batch-Wise Balance History\",\n \"name\": \"Batch-Wise Balance History\",\n \"type\": \"report\"\n }\n]"
|
||||
"links": "[\n {\n \"dependencies\": [\n \"Item Price\"\n ],\n \"doctype\": \"Item Price\",\n \"is_query_report\": false,\n \"label\": \"Item-wise Price List Rate\",\n \"name\": \"Item-wise Price List Rate\",\n \"onboard\": 1,\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Stock Entry\"\n ],\n \"doctype\": \"Stock Entry\",\n \"is_query_report\": true,\n \"label\": \"Stock Analytics\",\n \"name\": \"Stock Analytics\",\n \"onboard\": 1,\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Delivery Note\"\n ],\n \"doctype\": \"Delivery Note\",\n \"is_query_report\": true,\n \"label\": \"Delivery Note Trends\",\n \"name\": \"Delivery Note Trends\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Purchase Receipt\"\n ],\n \"doctype\": \"Purchase Receipt\",\n \"is_query_report\": true,\n \"label\": \"Purchase Receipt Trends\",\n \"name\": \"Purchase Receipt Trends\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Order\"\n ],\n \"doctype\": \"Sales Order\",\n \"is_query_report\": true,\n \"label\": \"Sales Order Analysis\",\n \"name\": \"Sales Order Analysis\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Purchase Order\"\n ],\n \"doctype\": \"Purchase Order\",\n \"is_query_report\": true,\n \"label\": \"Purchase Order Analysis\",\n \"name\": \"Purchase Order Analysis\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Bin\"\n ],\n \"doctype\": \"Bin\",\n \"is_query_report\": true,\n \"label\": \"Item Shortage Report\",\n \"name\": \"Item Shortage Report\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Batch\"\n ],\n \"doctype\": \"Batch\",\n \"is_query_report\": true,\n \"label\": \"Batch-Wise Balance History\",\n \"name\": \"Batch-Wise Balance History\",\n \"type\": \"report\"\n }\n]"
|
||||
},
|
||||
{
|
||||
"hidden": 0,
|
||||
@ -58,7 +58,7 @@
|
||||
"idx": 0,
|
||||
"is_standard": 1,
|
||||
"label": "Stock",
|
||||
"modified": "2020-05-27 20:38:25.255323",
|
||||
"modified": "2020-05-30 17:32:11.062681",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Stock",
|
||||
"name": "Stock",
|
||||
|
@ -20,7 +20,7 @@ frappe.tour['Stock Settings'] = [
|
||||
{
|
||||
fieldname: "item_naming_by",
|
||||
title: __("Item Naming By"),
|
||||
description: __("By default, the Item Name is set as per the Item Code entered. If you want Items to be named by a set Naming Series choose the 'Naming Series' option.")
|
||||
description: __("By default, the Item Name is set as per the Item Code entered. If you want Items to be named by a") + "<a href='https://docs.erpnext.com/docs/user/manual/en/setting-up/settings/naming-series' target='_blank'>Naming Series</a>" + __(" choose the 'Naming Series' option."),
|
||||
},
|
||||
{
|
||||
fieldname: "default_warehouse",
|
||||
|
@ -26,9 +26,10 @@ def get_chart_data(data, filters):
|
||||
# consider only consolidated row
|
||||
data = [row for row in data if row[0]]
|
||||
|
||||
data = sorted(data, key = lambda i: i[-1],reverse=True)
|
||||
|
||||
if len(data) > 10:
|
||||
# get top 10 if data too long
|
||||
data = sorted(data, key = lambda i: i[-1],reverse=True)
|
||||
data = data[:10]
|
||||
|
||||
for row in data:
|
||||
|
@ -1,34 +0,0 @@
|
||||
{
|
||||
"add_total_row": 1,
|
||||
"creation": "2018-01-09 18:38:23.540100",
|
||||
"disable_prepared_report": 0,
|
||||
"disabled": 0,
|
||||
"docstatus": 0,
|
||||
"doctype": "Report",
|
||||
"idx": 0,
|
||||
"is_standard": "Yes",
|
||||
"modified": "2019-04-01 22:10:09.829361",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Stock",
|
||||
"name": "Ordered Items To Be Delivered",
|
||||
"owner": "Administrator",
|
||||
"prepared_report": 0,
|
||||
"query": "select \n `tabSales Order`.`name` as \"Sales Order:Link/Sales Order:120\",\n `tabSales Order`.`status` as \"Status:Data:120\",\n `tabSales Order`.`customer` as \"Customer:Link/Customer:120\",\n `tabSales Order`.`customer_name` as \"Customer Name::150\",\n `tabSales Order`.`transaction_date` as \"Date:Date\",\n `tabSales Order`.`project` as \"Project:Link/Project:120\",\n `tabSales Order Item`.item_code as \"Item:Link/Item:120\",\n `tabSales Order Item`.qty as \"Qty:Float:140\",\n `tabSales Order Item`.delivered_qty as \"Delivered Qty:Float:140\",\n (`tabSales Order Item`.qty - ifnull(`tabSales Order Item`.delivered_qty, 0)) as \"Qty to Deliver:Float:140\",\n `tabSales Order Item`.base_rate as \"Rate:Float:140\",\n `tabSales Order Item`.base_amount as \"Amount:Float:140\",\n ((`tabSales Order Item`.qty - ifnull(`tabSales Order Item`.delivered_qty, 0))*`tabSales Order Item`.base_rate) as \"Amount to Deliver:Float:140\",\n `tabBin`.actual_qty as \"Available Qty:Float:120\",\n `tabBin`.projected_qty as \"Projected Qty:Float:120\",\n `tabSales Order Item`.`delivery_date` as \"Item Delivery Date:Date:120\",\n DATEDIFF(CURDATE(),`tabSales Order Item`.`delivery_date`) as \"Delay Days:Int:120\",\n `tabSales Order Item`.item_name as \"Item Name::150\",\n `tabSales Order Item`.description as \"Description::200\",\n `tabSales Order Item`.item_group as \"Item Group:Link/Item Group:120\",\n `tabSales Order Item`.warehouse as \"Warehouse:Link/Warehouse:200\"\nfrom\n `tabSales Order` JOIN `tabSales Order Item` \n LEFT JOIN `tabBin` ON (`tabBin`.item_code = `tabSales Order Item`.item_code\n and `tabBin`.warehouse = `tabSales Order Item`.warehouse)\nwhere\n `tabSales Order Item`.`parent` = `tabSales Order`.`name`\n and `tabSales Order`.docstatus = 1\n and `tabSales Order`.status not in (\"Stopped\", \"Closed\")\n and ifnull(`tabSales Order Item`.delivered_qty,0) < ifnull(`tabSales Order Item`.qty,0)\norder by `tabSales Order`.transaction_date asc",
|
||||
"ref_doctype": "Delivery Note",
|
||||
"report_name": "Ordered Items To Be Delivered",
|
||||
"report_type": "Query Report",
|
||||
"roles": [
|
||||
{
|
||||
"role": "Stock User"
|
||||
},
|
||||
{
|
||||
"role": "Stock Manager"
|
||||
},
|
||||
{
|
||||
"role": "Sales User"
|
||||
},
|
||||
{
|
||||
"role": "Accounts User"
|
||||
}
|
||||
]
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user