From 8bbca6fa2eda10afe05efe1436d7e2801afb3bf1 Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Tue, 12 Apr 2016 19:16:33 +0530 Subject: [PATCH] [enhancement] links menu in customer, supplier, item --- erpnext/accounts/party_status.py | 24 ------------- erpnext/buying/doctype/supplier/supplier.js | 2 +- erpnext/buying/doctype/supplier/supplier.py | 31 ++-------------- .../buying/doctype/supplier/supplier_links.py | 15 ++++++++ erpnext/public/js/utils/party.js | 31 ++-------------- erpnext/selling/doctype/customer/customer.js | 2 +- erpnext/selling/doctype/customer/customer.py | 31 ++-------------- .../doctype/customer/customer_links.py | 19 ++++++++++ erpnext/stock/doctype/item/item.js | 3 ++ erpnext/stock/doctype/item/item.json | 3 +- erpnext/stock/doctype/item/item.py | 7 ++-- erpnext/stock/doctype/item/item_links.py | 36 +++++++++++++++++++ 12 files changed, 87 insertions(+), 117 deletions(-) create mode 100644 erpnext/buying/doctype/supplier/supplier_links.py create mode 100644 erpnext/selling/doctype/customer/customer_links.py create mode 100644 erpnext/stock/doctype/item/item_links.py diff --git a/erpnext/accounts/party_status.py b/erpnext/accounts/party_status.py index 0c5d4c50e26..53810b7bdc1 100644 --- a/erpnext/accounts/party_status.py +++ b/erpnext/accounts/party_status.py @@ -5,7 +5,6 @@ from __future__ import unicode_literals import frappe -from frappe import _ from frappe.utils import evaluate_filters from frappe.desk.notifications import get_filters_for @@ -77,26 +76,3 @@ def update_status(doc): status = get_party_status(doc) if doc.status != status: doc.db_set('status', status) - -def get_transaction_count(doc): - '''Return list of open documents given party doc''' - out = [] - for doctype in status_depends_on[doc.doctype]: - filters = get_filters_for(doctype) - filters[doc.doctype.lower()] = doc.name - if filters: - open_count = frappe.get_all(doctype, fields='count(*) as count', filters=filters)[0].count - out.append({'name': doctype, 'count': open_count}) - - return out - -@frappe.whitelist() -def get_transaction_info(party_type, party_name): - doc = frappe.get_doc(party_type, party_name) - if not doc.has_permission('read'): - frappe.msgprint(_("Not permitted"), raise_exception=True) - - out = {} - out['transaction_count'] = get_transaction_count(doc) - - return out \ No newline at end of file diff --git a/erpnext/buying/doctype/supplier/supplier.js b/erpnext/buying/doctype/supplier/supplier.js index 0ad60b83270..a4896f1f0eb 100644 --- a/erpnext/buying/doctype/supplier/supplier.js +++ b/erpnext/buying/doctype/supplier/supplier.js @@ -6,7 +6,7 @@ frappe.ui.form.on("Supplier", { frappe.setup_language_field(frm); }, refresh: function(frm) { - erpnext.party.setup_dashboard(frm); + frm.dashboard.show_documents(); if(frappe.defaults.get_default("supp_master_name")!="Naming Series") { frm.toggle_display("naming_series", false); diff --git a/erpnext/buying/doctype/supplier/supplier.py b/erpnext/buying/doctype/supplier/supplier.py index dc82b4edf9c..4b384faed40 100644 --- a/erpnext/buying/doctype/supplier/supplier.py +++ b/erpnext/buying/doctype/supplier/supplier.py @@ -9,7 +9,7 @@ from frappe.model.naming import make_autoname from erpnext.utilities.address_and_contact import load_address_and_contact from erpnext.utilities.transaction_base import TransactionBase from erpnext.accounts.party import validate_party_accounts -from erpnext.accounts.party_status import get_transaction_count, get_party_status, status_depends_on +from erpnext.accounts.party_status import get_party_status class Supplier(TransactionBase): def get_feed(self): @@ -18,7 +18,7 @@ class Supplier(TransactionBase): def onload(self): """Load address and contacts in `__onload`""" load_address_and_contact(self, "supplier") - self.set_onload('transactions', status_depends_on[self.doctype]) + self.set_onload('links', self.meta.get_links_setup()) def autoname(self): supp_master_name = frappe.defaults.get_global_default('supp_master_name') @@ -84,30 +84,3 @@ class Supplier(TransactionBase): frappe.db.sql("""update `tabAddress` set address_title=%(newdn)s {set_field} where supplier=%(newdn)s"""\ .format(set_field=set_field), ({"newdn": newdn})) - -# @frappe.whitelist() -# def get_dashboard_info(supplier): -# doc = frappe.get_doc('Supplier', supplier) -# if not doc.has_permission('read'): -# frappe.msgprint(_("Not permitted"), raise_exception=True) -# -# out = {} -# out['transaction_count'] = get_transaction_count(doc) -# -# billing_this_year = frappe.db.sql(""" -# select sum(credit_in_account_currency) - sum(debit_in_account_currency) -# from `tabGL Entry` -# where voucher_type='Purchase Invoice' and party_type = 'Supplier' -# and party=%s and fiscal_year = %s""", -# (supplier, frappe.db.get_default("fiscal_year"))) -# -# total_unpaid = frappe.db.sql("""select sum(outstanding_amount) -# from `tabPurchase Invoice` -# where supplier=%s and docstatus = 1""", supplier) -# -# -# out["billing_this_year"] = billing_this_year[0][0] if billing_this_year else 0 -# out["total_unpaid"] = total_unpaid[0][0] if total_unpaid else 0 -# out["company_currency"] = frappe.db.sql_list("select distinct default_currency from tabCompany") -# -# return out diff --git a/erpnext/buying/doctype/supplier/supplier_links.py b/erpnext/buying/doctype/supplier/supplier_links.py new file mode 100644 index 00000000000..8986eca2b9b --- /dev/null +++ b/erpnext/buying/doctype/supplier/supplier_links.py @@ -0,0 +1,15 @@ +from frappe import _ + +links = { + 'fieldname': 'supplier', + 'transactions': [ + { + 'label': _('Procurement'), + 'items': ['Material Request', 'Request for Quotation', 'Supplier Quotation'] + }, + { + 'label': _('Orders'), + 'items': ['Purchase Order', 'Purchase Receipt', 'Purchase Invoice'] + } + ] +} \ No newline at end of file diff --git a/erpnext/public/js/utils/party.js b/erpnext/public/js/utils/party.js index 2f45a355574..5f9a2769a03 100644 --- a/erpnext/public/js/utils/party.js +++ b/erpnext/public/js/utils/party.js @@ -2,7 +2,7 @@ // License: GNU General Public License v3. See license.txt frappe.provide("erpnext.utils"); -frappe.provide('erpnext.party'); + erpnext.utils.get_party_details = function(frm, method, args, callback) { if(!method) { method = "erpnext.accounts.party.get_party_details"; @@ -139,31 +139,4 @@ erpnext.utils.get_shipping_address = function(frm){ } } }); -} - -erpnext.party.setup_dashboard = function(frm) { - frm.dashboard.reset(frm.doc); - if(frm.doc.__islocal) - return; - - $.each(frm.doc.__onload.transactions, function(i, doctype) { - frm.dashboard.add_doctype_badge(doctype, frm.doc.doctype.toLowerCase()); - }) - - return frappe.call({ - type: "GET", - method: "erpnext.accounts.party_status.get_transaction_info", - args: { - party_type: frm.doc.doctype, - party_name: frm.doc.name - }, - callback: function(r) { - $.each(r.message.transaction_count, function(i, d) { - if(d.count) { - frm.dashboard.set_badge_count(d.name, d.count) - } - }) - } - }); - -} +} \ No newline at end of file diff --git a/erpnext/selling/doctype/customer/customer.js b/erpnext/selling/doctype/customer/customer.js index 0adb0c54c7f..3f6ab24844f 100644 --- a/erpnext/selling/doctype/customer/customer.js +++ b/erpnext/selling/doctype/customer/customer.js @@ -6,7 +6,7 @@ frappe.ui.form.on("Customer", { frappe.setup_language_field(frm); }, refresh: function(frm) { - erpnext.party.setup_dashboard(frm); + frm.dashboard.show_documents(); if(frappe.defaults.get_default("cust_master_name")!="Naming Series") { frm.toggle_display("naming_series", false); diff --git a/erpnext/selling/doctype/customer/customer.py b/erpnext/selling/doctype/customer/customer.py index 82003b0177f..51aedef1aba 100644 --- a/erpnext/selling/doctype/customer/customer.py +++ b/erpnext/selling/doctype/customer/customer.py @@ -11,7 +11,7 @@ from frappe.desk.reportview import build_match_conditions from erpnext.utilities.transaction_base import TransactionBase from erpnext.utilities.address_and_contact import load_address_and_contact from erpnext.accounts.party import validate_party_accounts -from erpnext.accounts.party_status import get_transaction_count, get_party_status, status_depends_on +from erpnext.accounts.party_status import get_party_status class Customer(TransactionBase): def get_feed(self): @@ -20,7 +20,7 @@ class Customer(TransactionBase): def onload(self): """Load address and contacts in `__onload`""" load_address_and_contact(self, "customer") - self.set_onload('transactions', status_depends_on[self.doctype]) + self.set_onload('links', self.meta.get_links_setup()) def autoname(self): cust_master_name = frappe.defaults.get_global_default('cust_master_name') @@ -128,33 +128,6 @@ class Customer(TransactionBase): {set_field} where customer=%(newdn)s"""\ .format(set_field=set_field), ({"newdn": newdn})) -# @frappe.whitelist() -# def get_dashboard_info(customer): -# doc = frappe.get_doc('Customer', customer) -# if not doc.has_permission('read'): -# frappe.msgprint(_("Not permitted"), raise_exception=True) -# -# -# out = {} -# out['transaction_count'] = get_transaction_count(doc) -# -# billing_this_year = frappe.db.sql(""" -# select sum(debit_in_account_currency) - sum(credit_in_account_currency) -# from `tabGL Entry` -# where voucher_type='Sales Invoice' and party_type = 'Customer' -# and party=%s and fiscal_year = %s""", -# (customer, frappe.db.get_default("fiscal_year"))) -# -# total_unpaid = frappe.db.sql("""select sum(outstanding_amount) -# from `tabSales Invoice` -# where customer=%s and docstatus = 1""", customer) -# -# out["billing_this_year"] = billing_this_year[0][0] if billing_this_year else 0 -# out["total_unpaid"] = total_unpaid[0][0] if total_unpaid else 0 -# -# return out - - def get_customer_list(doctype, txt, searchfield, start, page_len, filters): if frappe.db.get_default("cust_master_name") == "Customer Name": fields = ["name", "customer_group", "territory"] diff --git a/erpnext/selling/doctype/customer/customer_links.py b/erpnext/selling/doctype/customer/customer_links.py new file mode 100644 index 00000000000..9410dbe7201 --- /dev/null +++ b/erpnext/selling/doctype/customer/customer_links.py @@ -0,0 +1,19 @@ +from frappe import _ + +links = { + 'fieldname': 'customer', + 'transactions': [ + { + 'label': _('Pre Sales'), + 'items': ['Lead', 'Opportunity', 'Quotation'] + }, + { + 'label': _('Orders'), + 'items': ['Sales Order', 'Delivery Note', 'Sales Invoice'] + }, + { + 'label': _('Projects'), + 'items': ['Project'] + } + ] +} \ No newline at end of file diff --git a/erpnext/stock/doctype/item/item.js b/erpnext/stock/doctype/item/item.js index 213050c3482..4df7128a6f0 100644 --- a/erpnext/stock/doctype/item/item.js +++ b/erpnext/stock/doctype/item/item.js @@ -16,6 +16,7 @@ frappe.ui.form.on("Item", { }, refresh: function(frm) { + if(frm.doc.is_stock_item) { frm.add_custom_button(__("Balance"), function() { frappe.route_options = { @@ -73,6 +74,8 @@ frappe.ui.form.on("Item", { } erpnext.item.toggle_attributes(frm); + + frm.dashboard.show_documents(); }, validate: function(frm){ diff --git a/erpnext/stock/doctype/item/item.json b/erpnext/stock/doctype/item/item.json index fab43a9c934..94d2e8d6aff 100644 --- a/erpnext/stock/doctype/item/item.json +++ b/erpnext/stock/doctype/item/item.json @@ -2298,7 +2298,7 @@ "issingle": 0, "istable": 0, "max_attachments": 1, - "modified": "2016-04-04 06:45:30.554933", + "modified": "2016-04-11 09:15:30.911215", "modified_by": "Administrator", "module": "Stock", "name": "Item", @@ -2468,6 +2468,7 @@ "read_only": 0, "read_only_onload": 0, "search_fields": "item_name,description,item_group,customer_code", + "sort_field": "idx desc, modified desc", "sort_order": "DESC", "title_field": "item_name", "track_seen": 0 diff --git a/erpnext/stock/doctype/item/item.py b/erpnext/stock/doctype/item/item.py index cc8886b50f3..14bdb414e3c 100644 --- a/erpnext/stock/doctype/item/item.py +++ b/erpnext/stock/doctype/item/item.py @@ -27,7 +27,8 @@ class Item(WebsiteGenerator): def onload(self): super(Item, self).onload() - self.get("__onload").sle_exists = self.check_if_sle_exists() + self.set_onload('sle_exists', self.check_if_sle_exists()) + self.set_onload('links', self.meta.get_links_setup()) def autoname(self): if frappe.db.get_default("item_naming_by")=="Naming Series": @@ -84,7 +85,7 @@ class Item(WebsiteGenerator): if not self.get("__islocal"): self.old_item_group = frappe.db.get_value(self.doctype, self.name, "item_group") - self.old_website_item_groups = frappe.db.sql_list("""select item_group + self.old_website_item_groups = frappe.db.sql_list("""select item_group from `tabWebsite Item Group` where parentfield='website_item_groups' and parenttype='Item' and parent=%s""", self.name) @@ -568,7 +569,7 @@ class Item(WebsiteGenerator): if variant: frappe.throw(_("Item variant {0} exists with same attributes") .format(variant), ItemVariantExistsError) - + def validate_fixed_asset_item(self): if self.is_fixed_asset and self.is_stock_item: frappe.throw(_("Fixed Asset Item must be a non-stock item")) diff --git a/erpnext/stock/doctype/item/item_links.py b/erpnext/stock/doctype/item/item_links.py new file mode 100644 index 00000000000..5f76a4cf97d --- /dev/null +++ b/erpnext/stock/doctype/item/item_links.py @@ -0,0 +1,36 @@ +from frappe import _ + +links = { + 'fieldname': 'item_code', + 'non_standard_fieldnames': { + 'Production Order': 'production_item', + 'Product Bundle': 'new_item_code' + }, + 'transactions': [ + { + 'label': _('Related'), + 'items': ['BOM', 'Product Bundle', 'Serial No', 'Batch'] + }, + { + 'label': _('Pricing'), + 'items': ['Item Price', 'Pricing Rule'] + }, + { + 'label': _('Sell'), + 'items': ['Quotation', 'Sales Order', 'Delivery Note', 'Sales Invoice'] + }, + { + 'label': _('Buy'), + 'items': ['Material Request', 'Supplier Quotation', 'Request for Quotation', + 'Purchase Order', 'Purchase Invoice'] + }, + { + 'label': _('Move'), + 'items': ['Stock Entry'] + }, + { + 'label': _('Manufacture'), + 'items': ['Production Order'] + } + ] +} \ No newline at end of file