Merge pull request #6397 from neilLasrado/develop
Added ability to Import Data via Data Import Tool in Instructor Doctype
diff --git a/erpnext/buying/doctype/supplier/supplier.js b/erpnext/buying/doctype/supplier/supplier.js
index cd13a72..b176e00 100644
--- a/erpnext/buying/doctype/supplier/supplier.js
+++ b/erpnext/buying/doctype/supplier/supplier.js
@@ -2,6 +2,19 @@
// License: GNU General Public License v3. See license.txt
frappe.ui.form.on("Supplier", {
+ setup: function(frm) {
+ frm.set_query('default_price_list', { 'buying': 1});
+ frm.set_query('account', 'accounts', function(doc, cdt, cdn) {
+ var d = locals[cdt][cdn];
+ return {
+ filters: {
+ 'account_type': 'Payable',
+ 'company': d.company,
+ "is_group": 0
+ }
+ }
+ });
+ },
refresh: function(frm) {
if(frappe.defaults.get_default("supp_master_name")!="Naming Series") {
frm.toggle_display("naming_series", false);
@@ -16,23 +29,18 @@
else {
unhide_field(['address_html','contact_html']);
erpnext.utils.render_address_and_contact(frm);
+
+ // custom buttons
+ frm.add_custom_button(__('Accounting Ledger'), function() {
+ frappe.set_route('query-report', 'General Ledger',
+ {party_type:'Supplier', party:frm.doc.name});
+ });
+ frm.add_custom_button(__('Accounts Payable'), function() {
+ frappe.set_route('query-report', 'Accounts Payable', {supplier:frm.doc.name});
+ });
+
+ // indicators
+ erpnext.utils.set_party_dashboard_indicators(frm);
}
},
});
-
-cur_frm.fields_dict['default_price_list'].get_query = function(doc, cdt, cdn) {
- return{
- filters:{'buying': 1}
- }
-}
-
-cur_frm.fields_dict['accounts'].grid.get_field('account').get_query = function(doc, cdt, cdn) {
- var d = locals[cdt][cdn];
- return {
- filters: {
- 'account_type': 'Payable',
- 'company': d.company,
- "is_group": 0
- }
- }
-}
diff --git a/erpnext/buying/doctype/supplier/supplier.py b/erpnext/buying/doctype/supplier/supplier.py
index a4ee326..3677ee2 100644
--- a/erpnext/buying/doctype/supplier/supplier.py
+++ b/erpnext/buying/doctype/supplier/supplier.py
@@ -18,6 +18,26 @@
def onload(self):
"""Load address and contacts in `__onload`"""
load_address_and_contact(self, "supplier")
+ self.load_dashboard_info()
+
+ def load_dashboard_info(self):
+ 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""",
+ (self.name, frappe.db.get_default("fiscal_year")))
+
+ total_unpaid = frappe.db.sql("""select sum(outstanding_amount)
+ from `tabPurchase Invoice`
+ where supplier=%s and docstatus = 1""", self.name)
+
+
+ info = {}
+ info["billing_this_year"] = billing_this_year[0][0] if billing_this_year else 0
+ info["total_unpaid"] = total_unpaid[0][0] if total_unpaid else 0
+
+ self.set_onload('dashboard_info', info)
def autoname(self):
supp_master_name = frappe.defaults.get_global_default('supp_master_name')
diff --git a/erpnext/crm/doctype/opportunity/opportunity_dashboard.py b/erpnext/crm/doctype/opportunity/opportunity_dashboard.py
index 08d5657..782acfd 100644
--- a/erpnext/crm/doctype/opportunity/opportunity_dashboard.py
+++ b/erpnext/crm/doctype/opportunity/opportunity_dashboard.py
@@ -1,11 +1,14 @@
from frappe import _
data = {
- 'fieldname': 'prevdoc_docname',
+ 'fieldname': 'opportunity',
+ 'non_standard_fieldnames': {
+ 'Quotation': 'prevdoc_docname'
+ },
'transactions': [
{
'label': _('Related'),
- 'items': ['Quotation']
+ 'items': ['Quotation', 'Supplier Quotation']
},
]
}
\ No newline at end of file
diff --git a/erpnext/manufacturing/doctype/production_order/production_order.json b/erpnext/manufacturing/doctype/production_order/production_order.json
index d1dc0c2..28c1176 100644
--- a/erpnext/manufacturing/doctype/production_order/production_order.json
+++ b/erpnext/manufacturing/doctype/production_order/production_order.json
@@ -15,6 +15,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "item",
"fieldtype": "Section Break",
"hidden": 0,
@@ -40,6 +41,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"default": "PRO-",
"fieldname": "naming_series",
"fieldtype": "Select",
@@ -66,6 +68,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"default": "Draft",
"depends_on": "eval:!doc.__islocal",
"fieldname": "status",
@@ -80,7 +83,7 @@
"no_copy": 1,
"oldfieldname": "status",
"oldfieldtype": "Select",
- "options": "\nDraft\nSubmitted\nNot Started\nStopped\nIn Process\nCompleted\nCancelled",
+ "options": "\nDraft\nSubmitted\nNot Started\nStopped\nUnstopped\nIn Process\nCompleted\nCancelled",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
@@ -95,6 +98,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "production_item",
"fieldtype": "Link",
"hidden": 0,
@@ -122,6 +126,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"depends_on": "",
"description": "",
"fieldname": "bom_no",
@@ -151,6 +156,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"default": "1",
"description": "Plan material for sub-assemblies",
"fieldname": "use_multi_level_bom",
@@ -177,6 +183,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "column_break1",
"fieldtype": "Column Break",
"hidden": 0,
@@ -202,6 +209,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"description": "",
"fieldname": "sales_order",
"fieldtype": "Link",
@@ -228,6 +236,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"depends_on": "",
"fieldname": "qty",
"fieldtype": "Float",
@@ -255,6 +264,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"default": "0",
"depends_on": "eval:doc.docstatus==1",
"description": "",
@@ -283,6 +293,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"default": "0",
"depends_on": "eval:doc.docstatus==1",
"description": "",
@@ -312,6 +323,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "warehouses",
"fieldtype": "Section Break",
"hidden": 0,
@@ -337,6 +349,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"description": "Warehouse for reserving items",
"fieldname": "source_warehouse",
"fieldtype": "Link",
@@ -364,6 +377,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "wip_warehouse",
"fieldtype": "Link",
"hidden": 0,
@@ -389,6 +403,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "column_break_12",
"fieldtype": "Column Break",
"hidden": 0,
@@ -412,6 +427,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"depends_on": "",
"description": "",
"fieldname": "fg_warehouse",
@@ -439,6 +455,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "time",
"fieldtype": "Section Break",
"hidden": 0,
@@ -465,6 +482,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"depends_on": "",
"fieldname": "expected_delivery_date",
"fieldtype": "Date",
@@ -490,6 +508,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"default": "now",
"fieldname": "planned_start_date",
"fieldtype": "Datetime",
@@ -516,6 +535,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "planned_end_date",
"fieldtype": "Datetime",
"hidden": 0,
@@ -541,6 +561,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "column_break_13",
"fieldtype": "Column Break",
"hidden": 0,
@@ -565,6 +586,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "actual_start_date",
"fieldtype": "Datetime",
"hidden": 0,
@@ -590,6 +612,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "actual_end_date",
"fieldtype": "Datetime",
"hidden": 0,
@@ -615,6 +638,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"depends_on": "",
"fieldname": "operations_section",
"fieldtype": "Section Break",
@@ -642,6 +666,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"depends_on": "",
"fieldname": "operations",
"fieldtype": "Table",
@@ -669,6 +694,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"depends_on": "operations",
"fieldname": "section_break_22",
"fieldtype": "Section Break",
@@ -696,6 +722,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "planned_operating_cost",
"fieldtype": "Currency",
"hidden": 0,
@@ -722,6 +749,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "actual_operating_cost",
"fieldtype": "Currency",
"hidden": 0,
@@ -748,6 +776,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "additional_operating_cost",
"fieldtype": "Currency",
"hidden": 0,
@@ -774,6 +803,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "column_break_24",
"fieldtype": "Column Break",
"hidden": 0,
@@ -798,6 +828,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "total_operating_cost",
"fieldtype": "Currency",
"hidden": 0,
@@ -824,6 +855,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "more_info",
"fieldtype": "Section Break",
"hidden": 0,
@@ -849,6 +881,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "description",
"fieldtype": "Small Text",
"hidden": 0,
@@ -873,6 +906,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"depends_on": "",
"fieldname": "stock_uom",
"fieldtype": "Link",
@@ -901,6 +935,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "company",
"fieldtype": "Link",
"hidden": 0,
@@ -928,6 +963,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "column_break2",
"fieldtype": "Column Break",
"hidden": 0,
@@ -952,6 +988,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "project",
"fieldtype": "Link",
"hidden": 0,
@@ -979,6 +1016,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"description": "Manufacture against Material Request",
"fieldname": "material_request",
"fieldtype": "Link",
@@ -1006,6 +1044,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "material_request_item",
"fieldtype": "Data",
"hidden": 1,
@@ -1031,6 +1070,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "amended_from",
"fieldtype": "Link",
"hidden": 0,
@@ -1058,6 +1098,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "required_items",
"fieldtype": "Table",
"hidden": 1,
@@ -1092,7 +1133,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
- "modified": "2016-07-08 07:09:06.847763",
+ "modified": "2016-09-19 02:48:09.412858",
"modified_by": "Administrator",
"module": "Manufacturing",
"name": "Production Order",
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index 40441c8..8ab34de 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -328,3 +328,4 @@
erpnext.patches.v7_1.move_sales_invoice_from_parent_to_child_timesheet
execute:frappe.db.sql("update `tabTimesheet` ts, `tabEmployee` emp set ts.employee_name = emp.employee_name where emp.name = ts.employee and ts.employee_name is null and ts.employee is not null")
erpnext.patches.v7_1.update_lead_source
+erpnext.patches.v7_1.fix_link_for_customer_from_lead
\ No newline at end of file
diff --git a/erpnext/patches/v7_1/fix_link_for_customer_from_lead.py b/erpnext/patches/v7_1/fix_link_for_customer_from_lead.py
new file mode 100644
index 0000000..cbb3ea4
--- /dev/null
+++ b/erpnext/patches/v7_1/fix_link_for_customer_from_lead.py
@@ -0,0 +1,6 @@
+import frappe
+
+def execute():
+ for c in frappe.db.sql('select name from tabCustomer where ifnull(lead_name,"")!=""'):
+ customer = frappe.get_doc('Customer', c[0])
+ customer.update_lead_status()
\ No newline at end of file
diff --git a/erpnext/public/js/utils.js b/erpnext/public/js/utils.js
index 7330889..6c8898d 100644
--- a/erpnext/public/js/utils.js
+++ b/erpnext/public/js/utils.js
@@ -108,6 +108,17 @@
}
},
+ set_party_dashboard_indicators: function(frm) {
+ if(frm.doc.__onload && frm.doc.__onload.dashboard_info) {
+ var info = frm.doc.__onload.dashboard_info;
+ frm.dashboard.add_indicator(__('Annual Billing: {0}',
+ [format_currency(info.billing_this_year, frm.doc.default_currency)]), 'blue');
+ frm.dashboard.add_indicator(__('Total Unpaid: {0}',
+ [format_currency(info.total_unpaid, frm.doc.default_currency)]),
+ info.total_unpaid ? 'orange' : 'green');
+ }
+ },
+
copy_value_in_all_row: function(doc, dt, dn, table_fieldname, fieldname) {
var d = locals[dt][dn];
if(d[fieldname]){
diff --git a/erpnext/selling/doctype/customer/customer.js b/erpnext/selling/doctype/customer/customer.js
index 20ecc7b..ea88e8b 100644
--- a/erpnext/selling/doctype/customer/customer.js
+++ b/erpnext/selling/doctype/customer/customer.js
@@ -2,6 +2,29 @@
// License: GNU General Public License v3. See license.txt
frappe.ui.form.on("Customer", {
+ setup: function(frm) {
+ frm.add_fetch('lead_name', 'company_name', 'customer_name');
+ frm.add_fetch('default_sales_partner','commission_rate','default_commission_rate');
+
+ frm.set_query('customer_group', {'is_group': 0});
+ frm.set_query('default_price_list', { 'selling': 1});
+ frm.set_query('account', 'accounts', function(doc, cdt, cdn) {
+ var d = locals[cdt][cdn];
+ var filters = {
+ 'account_type': 'Receivable',
+ 'company': d.company,
+ "is_group": 0
+ };
+
+ if(doc.party_account_currency) {
+ $.extend(filters, {"account_currency": doc.party_account_currency});
+ }
+
+ return {
+ filters: filters
+ }
+ });
+ },
refresh: function(frm) {
if(frappe.defaults.get_default("cust_master_name")!="Naming Series") {
frm.toggle_display("naming_series", false);
@@ -13,6 +36,20 @@
if(!frm.doc.__islocal) {
erpnext.utils.render_address_and_contact(frm);
+
+ // custom buttons
+ frm.add_custom_button(__('Accounting Ledger'), function() {
+ frappe.set_route('query-report', 'General Ledger',
+ {party_type:'Customer', party:frm.doc.name});
+ });
+
+ frm.add_custom_button(__('Accounts Receivable'), function() {
+ frappe.set_route('query-report', 'Accounts Receivable', {customer:frm.doc.name});
+ });
+
+ // indicator
+ erpnext.utils.set_party_dashboard_indicators(frm);
+
} else {
erpnext.utils.clear_address_and_contact(frm);
}
@@ -23,55 +60,5 @@
},
validate: function(frm) {
if(frm.doc.lead_name) frappe.model.clear_doc("Lead", frm.doc.lead_name);
- }
+ },
});
-
-cur_frm.cscript.onload = function(doc, dt, dn) {
- cur_frm.cscript.load_defaults(doc, dt, dn);
-}
-
-cur_frm.cscript.load_defaults = function(doc, dt, dn) {
- doc = locals[doc.doctype][doc.name];
- if(!(doc.__islocal && doc.lead_name)) { return; }
-
- var fields_to_refresh = frappe.model.set_default_values(doc);
- if(fields_to_refresh) { refresh_many(fields_to_refresh); }
-}
-
-cur_frm.add_fetch('lead_name', 'company_name', 'customer_name');
-cur_frm.add_fetch('default_sales_partner','commission_rate','default_commission_rate');
-
-cur_frm.fields_dict['customer_group'].get_query = function(doc, dt, dn) {
- return{
- filters:{'is_group': 0}
- }
-}
-
-cur_frm.fields_dict.lead_name.get_query = function(doc, cdt, cdn) {
- return{
- query: "erpnext.controllers.queries.lead_query"
- }
-}
-
-cur_frm.fields_dict['default_price_list'].get_query = function(doc, cdt, cdn) {
- return{
- filters:{'selling': 1}
- }
-}
-
-cur_frm.fields_dict['accounts'].grid.get_field('account').get_query = function(doc, cdt, cdn) {
- var d = locals[cdt][cdn];
- var filters = {
- 'account_type': 'Receivable',
- 'company': d.company,
- "is_group": 0
- };
-
- if(doc.party_account_currency) {
- $.extend(filters, {"account_currency": doc.party_account_currency});
- }
-
- return {
- filters: filters
- }
-}
diff --git a/erpnext/selling/doctype/customer/customer.py b/erpnext/selling/doctype/customer/customer.py
index ee3f6e6..82dbba7 100644
--- a/erpnext/selling/doctype/customer/customer.py
+++ b/erpnext/selling/doctype/customer/customer.py
@@ -20,6 +20,26 @@
def onload(self):
"""Load address and contacts in `__onload`"""
load_address_and_contact(self, "customer")
+ self.load_dashboard_info()
+
+ def load_dashboard_info(self):
+ 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""",
+ (self.name, frappe.db.get_default("fiscal_year")))
+
+ total_unpaid = frappe.db.sql("""select sum(outstanding_amount)
+ from `tabSales Invoice`
+ where customer=%s and docstatus = 1""", self.name)
+
+ info = {}
+ info["billing_this_year"] = billing_this_year[0][0] if billing_this_year else 0
+ info["total_unpaid"] = total_unpaid[0][0] if total_unpaid else 0
+
+ self.set_onload('dashboard_info', info)
+
def autoname(self):
cust_master_name = frappe.defaults.get_global_default('cust_master_name')
@@ -40,14 +60,37 @@
return self.customer_name
+ def after_insert(self):
+ '''If customer created from Lead, update customer id in quotations, opportunities'''
+ self.update_lead_status()
+
def validate(self):
self.flags.is_new_doc = self.is_new()
+ self.flags.old_lead = self.lead_name
validate_party_accounts(self)
self.status = get_party_status(self)
+ def on_update(self):
+ self.validate_name_with_customer_group()
+
+ if self.flags.old_lead != self.lead_name:
+ self.update_lead_status()
+
+ self.update_address()
+ self.update_contact()
+
+ if self.flags.is_new_doc:
+ self.create_lead_address_contact()
+
def update_lead_status(self):
+ '''If Customer created from Lead, update lead status to "Converted"
+ update Customer link in Quotation, Opportunity'''
if self.lead_name:
- frappe.db.sql("update `tabLead` set status='Converted' where name = %s", self.lead_name)
+ frappe.db.set_value('Lead', self.lead_name, 'status', 'Converted', update_modified=False)
+
+ for doctype in ('Opportunity', 'Quotation'):
+ for d in frappe.get_all(doctype, {'lead': self.lead_name}):
+ frappe.db.set_value(doctype, d.name, 'customer', self.name, update_modified=False)
def update_address(self):
frappe.db.sql("""update `tabAddress` set customer_name=%s, modified=NOW()
@@ -78,16 +121,6 @@
if not frappe.db.exists("Contact", c.name):
c.insert()
- def on_update(self):
- self.validate_name_with_customer_group()
-
- self.update_lead_status()
- self.update_address()
- self.update_contact()
-
- if self.flags.is_new_doc:
- self.create_lead_address_contact()
-
def validate_name_with_customer_group(self):
if frappe.db.exists("Customer Group", self.name):
frappe.throw(_("A Customer Group exists with same name please change the Customer name or rename the Customer Group"), frappe.NameError)
diff --git a/erpnext/stock/doctype/material_request/material_request_dashboard.py b/erpnext/stock/doctype/material_request/material_request_dashboard.py
index 8547df1..eab38b2 100644
--- a/erpnext/stock/doctype/material_request/material_request_dashboard.py
+++ b/erpnext/stock/doctype/material_request/material_request_dashboard.py
@@ -7,5 +7,9 @@
'label': _('Related'),
'items': ['Request for Quotation', 'Supplier Quotation', 'Purchase Order']
},
+ {
+ 'label': _('Manufacturing'),
+ 'items': ['Production Order']
+ },
]
}
\ No newline at end of file