diff --git a/erpnext/__init__.py b/erpnext/__init__.py index d8357f82170..92d7435ebd0 100644 --- a/erpnext/__init__.py +++ b/erpnext/__init__.py @@ -5,7 +5,7 @@ import frappe from erpnext.hooks import regional_overrides from frappe.utils import getdate -__version__ = '11.1.25' +__version__ = '11.1.28' def get_default_company(user=None): '''Get default company for user''' diff --git a/erpnext/accounts/party.py b/erpnext/accounts/party.py index 67bd0bd8c70..240dc4255b9 100644 --- a/erpnext/accounts/party.py +++ b/erpnext/accounts/party.py @@ -44,7 +44,7 @@ def _get_party_details(party=None, account=None, party_type="Customer", company= frappe.throw(_("Not permitted for {0}").format(party), frappe.PermissionError) party = frappe.get_doc(party_type, party) - currency = party.default_currency if party.default_currency else get_company_currency(company) + currency = party.default_currency if party.get("default_currency") else get_company_currency(company) out["taxes_and_charges"] = set_taxes(party.name, party_type, posting_date, company, out.customer_group, out.supplier_group) out["payment_terms_template"] = get_pyt_term_template(party.name, party_type, company) @@ -140,7 +140,7 @@ def set_other_values(out, party, party_type): def get_default_price_list(party): """Return default price list for party (Document object)""" - if party.default_price_list: + if party.get("default_price_list"): return party.default_price_list if party.doctype == "Customer": diff --git a/erpnext/accounts/report/gross_profit/gross_profit.py b/erpnext/accounts/report/gross_profit/gross_profit.py index ee5a4d28e37..4137555d957 100644 --- a/erpnext/accounts/report/gross_profit/gross_profit.py +++ b/erpnext/accounts/report/gross_profit/gross_profit.py @@ -65,7 +65,7 @@ def get_columns(group_wise_columns, filters): "warehouse": _("Warehouse") + ":Link/Warehouse", "qty": _("Qty") + ":Float", "base_rate": _("Avg. Selling Rate") + ":Currency/currency", - "buying_rate": _("Avg. Buying Rate") + ":Currency/currency", + "buying_rate": _("Valuation Rate") + ":Currency/currency", "base_amount": _("Selling Amount") + ":Currency/currency", "buying_amount": _("Buying Amount") + ":Currency/currency", "gross_profit": _("Gross Profit") + ":Currency/currency", diff --git a/erpnext/accounts/report/utils.py b/erpnext/accounts/report/utils.py index 0b17c8f964a..4a9af490cfc 100644 --- a/erpnext/accounts/report/utils.py +++ b/erpnext/accounts/report/utils.py @@ -137,7 +137,7 @@ def get_appropriate_company(filters): return company @frappe.whitelist() -def get_invoiced_item_gross_margin(sales_invoice=None, item_code=None, company=None): +def get_invoiced_item_gross_margin(sales_invoice=None, item_code=None, company=None, with_item_data=False): from erpnext.accounts.report.gross_profit.gross_profit import GrossProfitGenerator sales_invoice = sales_invoice or frappe.form_dict.get('sales_invoice') @@ -152,5 +152,8 @@ def get_invoiced_item_gross_margin(sales_invoice=None, item_code=None, company=N } gross_profit_data = GrossProfitGenerator(filters) + result = gross_profit_data.grouped_data + if not with_item_data: + result = sum([d.gross_profit for d in result]) - return gross_profit_data.grouped_data + return result diff --git a/erpnext/controllers/stock_controller.py b/erpnext/controllers/stock_controller.py index d1ffd7db66d..af689808c07 100644 --- a/erpnext/controllers/stock_controller.py +++ b/erpnext/controllers/stock_controller.py @@ -351,10 +351,12 @@ class StockController(AccountsController): frappe.throw(_("Row {0}: Quality Inspection rejected for item {1}") .format(d.idx, d.item_code), QualityInspectionRejectedError) elif qa_required : - frappe.msgprint(_("Quality Inspection required for Item {0}").format(d.item_code)) - if self.docstatus==1: - raise QualityInspectionRequiredError - + action = frappe.get_doc('Stock Settings').action_if_quality_inspection_is_not_submitted + if self.docstatus==1 and action == 'Stop': + frappe.throw(_("Quality Inspection required for Item {0} to submit").format(frappe.bold(d.item_code)), + exc=QualityInspectionRequiredError) + else: + frappe.msgprint(_("Create Quality Inspection for Item {0}").format(frappe.bold(d.item_code))) def update_blanket_order(self): blanket_orders = list(set([d.blanket_order for d in self.items if d.blanket_order])) diff --git a/erpnext/crm/doctype/lead/lead_dashboard.py b/erpnext/crm/doctype/lead/lead_dashboard.py index e8472aafc2e..d58527e00cd 100644 --- a/erpnext/crm/doctype/lead/lead_dashboard.py +++ b/erpnext/crm/doctype/lead/lead_dashboard.py @@ -4,6 +4,10 @@ from frappe import _ def get_data(): return { 'fieldname': 'lead', + 'non_standard_fieldnames': { + 'Quotation': 'party_name', + 'Opportunity': 'party_name' + }, 'transactions': [ { 'items': ['Opportunity', 'Quotation'] diff --git a/erpnext/hr/doctype/salary_slip/salary_slip.json b/erpnext/hr/doctype/salary_slip/salary_slip.json index c9a5d87281a..dd4451028eb 100644 --- a/erpnext/hr/doctype/salary_slip/salary_slip.json +++ b/erpnext/hr/doctype/salary_slip/salary_slip.json @@ -2,7 +2,7 @@ "allow_copy": 0, "allow_events_in_timeline": 0, "allow_guest_to_view": 0, - "allow_import": 0, + "allow_import": 1, "allow_rename": 0, "beta": 0, "creation": "2013-01-10 16:34:15", @@ -21,6 +21,7 @@ "collapsible": 0, "columns": 0, "default": "Today", + "fetch_if_empty": 0, "fieldname": "posting_date", "fieldtype": "Date", "hidden": 0, @@ -53,6 +54,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "employee", "fieldtype": "Link", "hidden": 0, @@ -88,6 +90,7 @@ "collapsible": 0, "columns": 0, "fetch_from": "employee.employee_name", + "fetch_if_empty": 0, "fieldname": "employee_name", "fieldtype": "Read Only", "hidden": 0, @@ -123,6 +126,7 @@ "collapsible": 0, "columns": 0, "fetch_from": "employee.department", + "fetch_if_empty": 0, "fieldname": "department", "fieldtype": "Link", "hidden": 0, @@ -159,6 +163,7 @@ "columns": 0, "depends_on": "eval:doc.designation", "fetch_from": "employee.designation", + "fetch_if_empty": 0, "fieldname": "designation", "fieldtype": "Read Only", "hidden": 0, @@ -194,6 +199,7 @@ "collapsible": 0, "columns": 0, "fetch_from": "employee.branch", + "fetch_if_empty": 0, "fieldname": "branch", "fieldtype": "Link", "hidden": 0, @@ -228,6 +234,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "column_break1", "fieldtype": "Column Break", "hidden": 0, @@ -260,6 +267,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "status", "fieldtype": "Select", "hidden": 0, @@ -293,6 +301,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "journal_entry", "fieldtype": "Link", "hidden": 0, @@ -326,6 +335,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "payroll_entry", "fieldtype": "Link", "hidden": 0, @@ -359,6 +369,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "company", "fieldtype": "Link", "hidden": 0, @@ -391,6 +402,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "letter_head", "fieldtype": "Link", "hidden": 0, @@ -423,6 +435,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "section_break_10", "fieldtype": "Section Break", "hidden": 0, @@ -455,6 +468,7 @@ "collapsible": 0, "columns": 0, "depends_on": "", + "fetch_if_empty": 0, "fieldname": "salary_slip_based_on_timesheet", "fieldtype": "Check", "hidden": 0, @@ -489,6 +503,7 @@ "collapsible": 0, "columns": 0, "default": "", + "fetch_if_empty": 0, "fieldname": "start_date", "fieldtype": "Date", "hidden": 0, @@ -523,6 +538,7 @@ "columns": 0, "default": "", "depends_on": "", + "fetch_if_empty": 0, "fieldname": "end_date", "fieldtype": "Date", "hidden": 0, @@ -555,6 +571,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "column_break_15", "fieldtype": "Column Break", "hidden": 0, @@ -587,6 +604,7 @@ "collapsible": 0, "columns": 0, "depends_on": "", + "fetch_if_empty": 0, "fieldname": "salary_structure", "fieldtype": "Link", "hidden": 0, @@ -622,6 +640,7 @@ "columns": 0, "default": "", "depends_on": "eval:(!doc.salary_slip_based_on_timesheet)", + "fetch_if_empty": 0, "fieldname": "payroll_frequency", "fieldtype": "Select", "hidden": 0, @@ -656,6 +675,7 @@ "collapsible": 0, "columns": 0, "depends_on": "", + "fetch_if_empty": 0, "fieldname": "total_working_days", "fieldtype": "Float", "hidden": 0, @@ -690,6 +710,7 @@ "collapsible": 0, "columns": 0, "depends_on": "", + "fetch_if_empty": 0, "fieldname": "leave_without_pay", "fieldtype": "Float", "hidden": 0, @@ -724,6 +745,7 @@ "collapsible": 0, "columns": 0, "depends_on": "", + "fetch_if_empty": 0, "fieldname": "payment_days", "fieldtype": "Float", "hidden": 0, @@ -758,6 +780,7 @@ "collapsible": 0, "columns": 0, "depends_on": "", + "fetch_if_empty": 0, "fieldname": "hourly_wages", "fieldtype": "Section Break", "hidden": 0, @@ -791,6 +814,7 @@ "collapsible": 0, "columns": 0, "depends_on": "", + "fetch_if_empty": 0, "fieldname": "timesheets", "fieldtype": "Table", "hidden": 0, @@ -824,6 +848,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "column_break_20", "fieldtype": "Column Break", "hidden": 0, @@ -855,6 +880,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "total_working_hours", "fieldtype": "Float", "hidden": 0, @@ -887,6 +913,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "hour_rate", "fieldtype": "Currency", "hidden": 0, @@ -921,6 +948,7 @@ "collapsible": 0, "columns": 0, "depends_on": "", + "fetch_if_empty": 0, "fieldname": "section_break_26", "fieldtype": "Section Break", "hidden": 0, @@ -953,6 +981,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "bank_name", "fieldtype": "Data", "hidden": 0, @@ -986,6 +1015,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "bank_account_no", "fieldtype": "Data", "hidden": 0, @@ -1019,6 +1049,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "column_break_01", "fieldtype": "Column Break", "hidden": 0, @@ -1050,6 +1081,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "amended_from", "fieldtype": "Link", "hidden": 0, @@ -1084,6 +1116,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "section_break_32", "fieldtype": "Section Break", "hidden": 0, @@ -1115,6 +1148,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "deduct_tax_for_unclaimed_employee_benefits", "fieldtype": "Check", "hidden": 0, @@ -1147,6 +1181,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "deduct_tax_for_unsubmitted_tax_exemption_proof", "fieldtype": "Check", "hidden": 0, @@ -1179,6 +1214,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "earning_deduction", "fieldtype": "Section Break", "hidden": 0, @@ -1211,6 +1247,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "earning", "fieldtype": "Column Break", "hidden": 0, @@ -1245,6 +1282,7 @@ "collapsible": 0, "columns": 0, "depends_on": "", + "fetch_if_empty": 0, "fieldname": "earnings", "fieldtype": "Table", "hidden": 0, @@ -1279,6 +1317,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "deduction", "fieldtype": "Column Break", "hidden": 0, @@ -1312,6 +1351,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "deductions", "fieldtype": "Table", "hidden": 0, @@ -1346,6 +1386,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "totals", "fieldtype": "Section Break", "hidden": 0, @@ -1378,6 +1419,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "gross_pay", "fieldtype": "Currency", "hidden": 0, @@ -1412,6 +1454,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "column_break_25", "fieldtype": "Column Break", "hidden": 0, @@ -1442,6 +1485,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "total_deduction", "fieldtype": "Currency", "hidden": 0, @@ -1477,6 +1521,7 @@ "collapsible": 0, "columns": 0, "depends_on": "total_loan_repayment", + "fetch_if_empty": 0, "fieldname": "loan_repayment", "fieldtype": "Section Break", "hidden": 0, @@ -1509,6 +1554,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "loans", "fieldtype": "Table", "hidden": 0, @@ -1542,6 +1588,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "section_break_43", "fieldtype": "Section Break", "hidden": 0, @@ -1574,6 +1621,7 @@ "collapsible": 0, "columns": 0, "default": "0", + "fetch_if_empty": 0, "fieldname": "total_principal_amount", "fieldtype": "Currency", "hidden": 0, @@ -1608,6 +1656,7 @@ "collapsible": 0, "columns": 0, "default": "0", + "fetch_if_empty": 0, "fieldname": "total_interest_amount", "fieldtype": "Currency", "hidden": 0, @@ -1641,6 +1690,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "column_break_45", "fieldtype": "Column Break", "hidden": 0, @@ -1673,6 +1723,7 @@ "collapsible": 0, "columns": 0, "default": "0", + "fetch_if_empty": 0, "fieldname": "total_loan_repayment", "fieldtype": "Currency", "hidden": 0, @@ -1706,6 +1757,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "net_pay_info", "fieldtype": "Section Break", "hidden": 0, @@ -1739,6 +1791,7 @@ "collapsible": 0, "columns": 0, "description": "Gross Pay - Total Deduction - Loan Repayment", + "fetch_if_empty": 0, "fieldname": "net_pay", "fieldtype": "Currency", "hidden": 0, @@ -1773,6 +1826,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "column_break_53", "fieldtype": "Column Break", "hidden": 0, @@ -1804,6 +1858,7 @@ "bold": 1, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "rounded_total", "fieldtype": "Currency", "hidden": 0, @@ -1836,6 +1891,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "section_break_55", "fieldtype": "Section Break", "hidden": 0, @@ -1868,6 +1924,7 @@ "collapsible": 0, "columns": 0, "description": "Net Pay (in words) will be visible once you save the Salary Slip.", + "fetch_if_empty": 0, "fieldname": "total_in_words", "fieldtype": "Data", "hidden": 0, @@ -1906,7 +1963,7 @@ "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2019-02-18 18:54:36.161027", + "modified": "2019-05-08 20:16:21.549386", "modified_by": "Administrator", "module": "HR", "name": "Salary Slip", diff --git a/erpnext/patches.txt b/erpnext/patches.txt index a57070b13a6..c060264a937 100755 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -592,8 +592,10 @@ erpnext.patches.v11_1.make_job_card_time_logs erpnext.patches.v11_1.set_variant_based_on erpnext.patches.v11_1.move_customer_lead_to_dynamic_column erpnext.patches.v11_1.woocommerce_set_creation_user +erpnext.patches.v11_1.set_default_action_for_quality_inspection erpnext.patches.v11_1.delete_bom_browser erpnext.patches.v11_1.set_salary_details_submittable erpnext.patches.v11_1.rename_depends_on_lwp erpnext.patches.v11_1.set_missing_title_for_quotation -execute:frappe.delete_doc("Report", "Inactive Items") \ No newline at end of file +execute:frappe.delete_doc("Report", "Inactive Items") +erpnext.patches.v11_1.delete_scheduling_tool \ No newline at end of file diff --git a/erpnext/patches/v11_1/delete_scheduling_tool.py b/erpnext/patches/v11_1/delete_scheduling_tool.py new file mode 100644 index 00000000000..b7ad28a3fd6 --- /dev/null +++ b/erpnext/patches/v11_1/delete_scheduling_tool.py @@ -0,0 +1,9 @@ +# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors +# License: GNU General Public License v3. See license.txt + +from __future__ import unicode_literals +import frappe + +def execute(): + if frappe.db.exists("DocType", "Scheduling Tool"): + frappe.delete_doc("DocType", "Scheduling Tool", ignore_permissions=True) diff --git a/erpnext/patches/v11_1/set_default_action_for_quality_inspection.py b/erpnext/patches/v11_1/set_default_action_for_quality_inspection.py new file mode 100644 index 00000000000..82d43b05206 --- /dev/null +++ b/erpnext/patches/v11_1/set_default_action_for_quality_inspection.py @@ -0,0 +1,10 @@ +# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors +# License: GNU General Public License v3. See license.txt + +from __future__ import unicode_literals +import frappe + +def execute(): + stock_settings = frappe.get_doc('Stock Settings') + stock_settings.action_if_quality_inspection_is_not_submitted = "Stop" + stock_settings.save() \ No newline at end of file diff --git a/erpnext/projects/doctype/project/project.py b/erpnext/projects/doctype/project/project.py index fc58df0ffc5..b328f56ccd8 100644 --- a/erpnext/projects/doctype/project/project.py +++ b/erpnext/projects/doctype/project/project.py @@ -318,7 +318,8 @@ class Project(Document): if not self.get('deleted_task_list'): return for d in self.get('deleted_task_list'): - frappe.delete_doc("Task", d) + # unlink project + frappe.db.set_value('Task', d, 'project', '') self.deleted_task_list = [] diff --git a/erpnext/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js index 75b09fb8f4a..8c74f736eab 100644 --- a/erpnext/public/js/controllers/transaction.js +++ b/erpnext/public/js/controllers/transaction.js @@ -428,7 +428,7 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({ serial_no: item.serial_no, set_warehouse: me.frm.doc.set_warehouse, warehouse: item.warehouse, - customer: me.frm.doc.customer, + customer: me.frm.doc.customer || me.frm.doc.party_name, supplier: me.frm.doc.supplier, currency: me.frm.doc.currency, update_stock: update_stock, @@ -1118,7 +1118,7 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({ var me = this; return { "items": this._get_item_list(item), - "customer": me.frm.doc.customer, + "customer": me.frm.doc.customer || me.frm.doc.party_name, "customer_group": me.frm.doc.customer_group, "territory": me.frm.doc.territory, "supplier": me.frm.doc.supplier, diff --git a/erpnext/public/js/utils/party.js b/erpnext/public/js/utils/party.js index 5869c4da4c2..52657edd173 100644 --- a/erpnext/public/js/utils/party.js +++ b/erpnext/public/js/utils/party.js @@ -8,10 +8,17 @@ erpnext.utils.get_party_details = function(frm, method, args, callback) { method = "erpnext.accounts.party.get_party_details"; } if(!args) { - if(frm.doctype != "Purchase Order" && frm.doc.customer) { + if((frm.doctype != "Purchase Order" && frm.doc.customer) + || (frm.doc.party_name && in_list(['Quotation', 'Opportunity'], frm.doc.doctype))) { + + let party_type = "Customer"; + if(frm.doc.quotation_to && frm.doc.quotation_to === "Lead") { + party_type = "Lead"; + } + args = { - party: frm.doc.customer, - party_type: "Customer", + party: frm.doc.customer || frm.doc.party_name, + party_type: party_type, price_list: frm.doc.selling_price_list }; } else if(frm.doc.supplier) { diff --git a/erpnext/regional/india/utils.py b/erpnext/regional/india/utils.py index 82bff0f4238..c6100cf5fcf 100644 --- a/erpnext/regional/india/utils.py +++ b/erpnext/regional/india/utils.py @@ -387,6 +387,7 @@ def get_address_details(data, doc, company_address, billing_address): data.transType = 2 shipping_address = frappe.get_doc('Address', doc.shipping_address_name) set_gst_state_and_state_number(shipping_address) + data.toPincode = validate_pincode(shipping_address.pincode, 'Shipping Address') data.actualToStateCode = validate_state_code(shipping_address.gst_state_number, 'Shipping Address') else: data.transType = 1 @@ -430,6 +431,10 @@ def get_item_list(data, doc): data.itemList.append(item_data) + # Tax amounts rounded to 2 decimals to avoid exceeding max character limit + for attr in ['sgstValue', 'cgstValue', 'igstValue', 'cessValue']: + data[attr] = flt(data[attr], 2) + return data def validate_sales_invoice(doc): @@ -458,7 +463,7 @@ def get_transport_details(data, doc): if doc.distance > 4000: frappe.throw(_('Distance cannot be greater than 4000 kms')) - data.transDistance = round(doc.distance) + data.transDistance = int(round(doc.distance)) transport_modes = { 'Road': 1, diff --git a/erpnext/selling/doctype/customer/customer.js b/erpnext/selling/doctype/customer/customer.js index 89811656eed..8d590a0c9d0 100644 --- a/erpnext/selling/doctype/customer/customer.js +++ b/erpnext/selling/doctype/customer/customer.js @@ -124,10 +124,5 @@ frappe.ui.form.on("Customer", { validate: function(frm) { if(frm.doc.lead_name) frappe.model.clear_doc("Lead", frm.doc.lead_name); - var total = 0; - for (var idx in frm.doc.sales_team) { - total += frm.doc.sales_team[idx].allocated_percentage; - if (total > 100) frappe.throw(__("Total contribution percentage can't exceed 100")); - } }, }); \ No newline at end of file diff --git a/erpnext/selling/doctype/customer/customer.py b/erpnext/selling/doctype/customer/customer.py index f815e5f97cb..295f34d0c55 100644 --- a/erpnext/selling/doctype/customer/customer.py +++ b/erpnext/selling/doctype/customer/customer.py @@ -60,6 +60,10 @@ class Customer(TransactionBase): if self.loyalty_program == customer.loyalty_program and not self.loyalty_program_tier: self.loyalty_program_tier = customer.loyalty_program_tier + if self.sales_team: + if sum([member.allocated_percentage or 0 for member in self.sales_team]) != 100: + frappe.throw(_("Total contribution percentage should be equal to 100")) + def check_customer_group_change(self): frappe.flags.customer_group_changed = False diff --git a/erpnext/selling/doctype/quotation/quotation.js b/erpnext/selling/doctype/quotation/quotation.js index 397c853097b..5d4b8a0116f 100644 --- a/erpnext/selling/doctype/quotation/quotation.js +++ b/erpnext/selling/doctype/quotation/quotation.js @@ -42,10 +42,16 @@ erpnext.selling.QuotationController = erpnext.selling.SellingController.extend({ this._super(doc, dt, dn); }, + party_name: function() { + var me = this; + erpnext.utils.get_party_details(this.frm, null, null, function() { + me.apply_price_list(); + }); + }, refresh: function(doc, dt, dn) { this._super(doc, dt, dn); doctype = doc.quotation_to == 'Customer' ? 'Customer':'Lead'; - frappe.dynamic_link = {doc: this.frm.doc, fieldname: doctype.toLowerCase(), doctype: doctype} + frappe.dynamic_link = {doc: this.frm.doc, fieldname: 'party_name', doctype: doctype} var me = this; diff --git a/erpnext/selling/doctype/quotation/quotation.json b/erpnext/selling/doctype/quotation/quotation.json index abafbbf6a16..4083b8e6d0b 100644 --- a/erpnext/selling/doctype/quotation/quotation.json +++ b/erpnext/selling/doctype/quotation/quotation.json @@ -169,8 +169,8 @@ "in_filter": 0, "in_global_search": 1, "in_list_view": 0, - "in_standard_filter": 1, - "label": "Customer/Lead", + "in_standard_filter": 0, + "label": "Party", "length": 0, "no_copy": 0, "oldfieldname": "customer", @@ -542,7 +542,7 @@ "bold": 0, "collapsible": 0, "columns": 0, - "depends_on": "eval:doc.quotaion_to=='Customer' && doc.party_name", + "depends_on": "", "fetch_if_empty": 0, "fieldname": "contact_person", "fieldtype": "Link", @@ -3224,7 +3224,7 @@ "istable": 0, "max_attachments": 1, "menu_index": 0, - "modified": "2019-05-02 15:16:37.394455", + "modified": "2019-05-07 14:29:22.565474", "modified_by": "Administrator", "module": "Selling", "name": "Quotation", diff --git a/erpnext/selling/doctype/quotation/quotation.py b/erpnext/selling/doctype/quotation/quotation.py index 833ef1d606c..8b339ba82f2 100644 --- a/erpnext/selling/doctype/quotation/quotation.py +++ b/erpnext/selling/doctype/quotation/quotation.py @@ -216,35 +216,38 @@ def _make_sales_invoice(source_name, target_doc=None, ignore_permissions=False): return doclist def _make_customer(source_name, ignore_permissions=False): - quotation = frappe.db.get_value("Quotation", source_name, ["order_type", "party_name", "customer_name"]) - if quotation and quotation[1] and not quotation[2]: - lead_name = quotation[1] - customer_name = frappe.db.get_value("Customer", {"lead_name": lead_name}, - ["name", "customer_name"], as_dict=True) - if not customer_name: - from erpnext.crm.doctype.lead.lead import _make_customer - customer_doclist = _make_customer(lead_name, ignore_permissions=ignore_permissions) - customer = frappe.get_doc(customer_doclist) - customer.flags.ignore_permissions = ignore_permissions - if quotation[1] == "Shopping Cart": - customer.customer_group = frappe.db.get_value("Shopping Cart Settings", None, - "default_customer_group") + quotation = frappe.db.get_value("Quotation", + source_name, ["order_type", "party_name", "customer_name"], as_dict=1) - try: - customer.insert() - return customer - except frappe.NameError: - if frappe.defaults.get_global_default('cust_master_name') == "Customer Name": - customer.run_method("autoname") - customer.name += "-" + lead_name + if quotation and quotation.get('party_name'): + if not frappe.db.exists("Customer", quotation.get("party_name")): + lead_name = quotation.get("party_name") + customer_name = frappe.db.get_value("Customer", {"lead_name": lead_name}, + ["name", "customer_name"], as_dict=True) + if not customer_name: + from erpnext.crm.doctype.lead.lead import _make_customer + customer_doclist = _make_customer(lead_name, ignore_permissions=ignore_permissions) + customer = frappe.get_doc(customer_doclist) + customer.flags.ignore_permissions = ignore_permissions + if quotation.get("party_name") == "Shopping Cart": + customer.customer_group = frappe.db.get_value("Shopping Cart Settings", None, + "default_customer_group") + + try: customer.insert() return customer - else: - raise - except frappe.MandatoryError: - frappe.local.message_log = [] - frappe.throw(_("Please create Customer from Lead {0}").format(lead_name)) + except frappe.NameError: + if frappe.defaults.get_global_default('cust_master_name') == "Customer Name": + customer.run_method("autoname") + customer.name += "-" + lead_name + customer.insert() + return customer + else: + raise + except frappe.MandatoryError: + frappe.local.message_log = [] + frappe.throw(_("Please create Customer from Lead {0}").format(lead_name)) + else: + return customer_name else: - return customer_name - elif quotation and quotation[1]: - return frappe.get_doc("Customer",quotation[1]) + return frappe.get_doc("Customer", quotation.get("party_name")) diff --git a/erpnext/stock/doctype/batch/batch.py b/erpnext/stock/doctype/batch/batch.py index ef0a317d657..8ea7c44c07f 100644 --- a/erpnext/stock/doctype/batch/batch.py +++ b/erpnext/stock/doctype/batch/batch.py @@ -9,6 +9,7 @@ from frappe.model.naming import make_autoname, revert_series_if_last from frappe.utils import flt, cint from frappe.utils.jinja import render_template from frappe.utils.data import add_days +from six import string_types class UnableToSelectBatchError(frappe.ValidationError): pass @@ -60,7 +61,7 @@ def _make_naming_series_key(prefix): :param prefix: Naming series prefix gotten from Stock Settings :return: The derived key. If no prefix is given, an empty string is returned """ - if not unicode(prefix): + if not isinstance(prefix, string_types): return '' else: return prefix.upper() + '.#####' @@ -86,7 +87,7 @@ class Batch(Document): def autoname(self): """Generate random ID for batch if not specified""" if not self.batch_id: - create_new_batch, batch_number_series = frappe.db.get_value('Item', self.item, + create_new_batch, batch_number_series = frappe.db.get_value('Item', self.item, ['create_new_batch', 'batch_number_series']) if create_new_batch: diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py index dc9c4fc3fe8..bae9ea72e51 100644 --- a/erpnext/stock/doctype/stock_entry/stock_entry.py +++ b/erpnext/stock/doctype/stock_entry/stock_entry.py @@ -122,6 +122,10 @@ class StockEntry(StockController): if self.purpose not in valid_purposes: frappe.throw(_("Purpose must be one of {0}").format(comma_or(valid_purposes))) + if self.job_card and self.purpose != 'Material Transfer for Manufacture': + frappe.throw(_("For job card {0}, you can only make the 'Material Transfer for Manufacture' type stock entry") + .format(self.job_card)) + def set_transfer_qty(self): for item in self.get("items"): if not flt(item.qty): @@ -1068,7 +1072,7 @@ class StockEntry(StockController): frappe.MappingMismatchError) def validate_batch(self): - if self.purpose in ["Material Transfer for Manufacture", "Manufacture", "Repack", "Subcontract", "Material Issue"]: + if self.purpose in ["Material Transfer for Manufacture", "Manufacture", "Repack", "Subcontract"]: for item in self.get("items"): if item.batch_no: disabled = frappe.db.get_value("Batch", item.batch_no, "disabled") diff --git a/erpnext/stock/doctype/stock_settings/stock_settings.json b/erpnext/stock/doctype/stock_settings/stock_settings.json index 4d5423e5476..3f7bf959dd5 100644 --- a/erpnext/stock/doctype/stock_settings/stock_settings.json +++ b/erpnext/stock/doctype/stock_settings/stock_settings.json @@ -1,5 +1,6 @@ { "allow_copy": 0, + "allow_events_in_timeline": 0, "allow_guest_to_view": 0, "allow_import": 0, "allow_rename": 0, @@ -14,11 +15,13 @@ "fields": [ { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, "columns": 0, "default": "Item Code", + "fetch_if_empty": 0, "fieldname": "item_naming_by", "fieldtype": "Select", "hidden": 0, @@ -41,15 +44,18 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, "columns": 0, "description": "", + "fetch_if_empty": 0, "fieldname": "item_group", "fieldtype": "Link", "hidden": 0, @@ -72,14 +78,17 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "stock_uom", "fieldtype": "Link", "hidden": 0, @@ -102,14 +111,17 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "default_warehouse", "fieldtype": "Link", "hidden": 0, @@ -133,14 +145,17 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "sample_retention_warehouse", "fieldtype": "Link", "hidden": 0, @@ -164,14 +179,17 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "column_break_4", "fieldtype": "Column Break", "hidden": 0, @@ -192,14 +210,17 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "valuation_method", "fieldtype": "Select", "hidden": 0, @@ -222,15 +243,18 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, "columns": 0, "description": "Percentage you are allowed to receive or deliver more against the quantity ordered. For example: If you have ordered 100 units. and your Allowance is 10% then you are allowed to receive 110 units.", + "fetch_if_empty": 0, "fieldname": "tolerance", "fieldtype": "Float", "hidden": 0, @@ -252,15 +276,53 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "default": "Stop", + "fetch_if_empty": 0, + "fieldname": "action_if_quality_inspection_is_not_submitted", + "fieldtype": "Select", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Action if Quality inspection is not submitted", + "length": 0, + "no_copy": 0, + "options": "Stop\nWarn", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, "columns": 0, "default": "1", + "fetch_if_empty": 0, "fieldname": "show_barcode_field", "fieldtype": "Check", "hidden": 0, @@ -283,15 +345,18 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, "columns": 0, "default": "1", + "fetch_if_empty": 0, "fieldname": "clean_description_html", "fieldtype": "Check", "hidden": 0, @@ -314,14 +379,17 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "section_break_7", "fieldtype": "Section Break", "hidden": 0, @@ -343,14 +411,17 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "auto_insert_price_list_rate_if_missing", "fieldtype": "Check", "hidden": 0, @@ -373,14 +444,17 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "allow_negative_stock", "fieldtype": "Check", "hidden": 0, @@ -402,14 +476,17 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "column_break_10", "fieldtype": "Column Break", "hidden": 0, @@ -431,15 +508,18 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, "columns": 0, "default": "1", + "fetch_if_empty": 0, "fieldname": "automatically_set_serial_nos_based_on_fifo", "fieldtype": "Check", "hidden": 0, @@ -462,15 +542,18 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, "columns": 0, "default": "1", + "fetch_if_empty": 0, "fieldname": "set_qty_in_transactions_based_on_serial_no_input", "fieldtype": "Check", "hidden": 0, @@ -493,14 +576,17 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "auto_material_request", "fieldtype": "Section Break", "hidden": 0, @@ -522,14 +608,17 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "auto_indent", "fieldtype": "Check", "hidden": 0, @@ -551,14 +640,17 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "reorder_email_notify", "fieldtype": "Check", "hidden": 0, @@ -580,14 +672,17 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "freeze_stock_entries", "fieldtype": "Section Break", "hidden": 0, @@ -609,14 +704,17 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "stock_frozen_upto", "fieldtype": "Date", "hidden": 0, @@ -638,14 +736,17 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "stock_frozen_upto_days", "fieldtype": "Int", "hidden": 0, @@ -667,14 +768,17 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "stock_auth_role", "fieldtype": "Link", "hidden": 0, @@ -697,14 +801,17 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "batch_id_sb", "fieldtype": "Section Break", "hidden": 0, @@ -727,15 +834,18 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, "columns": 0, "default": "0", + "fetch_if_empty": 0, "fieldname": "use_naming_series", "fieldtype": "Check", "hidden": 0, @@ -758,16 +868,19 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, "columns": 0, "default": "BATCH-", "depends_on": "eval:doc.use_naming_series==1", + "fetch_if_empty": 0, "fieldname": "naming_series_prefix", "fieldtype": "Data", "hidden": 0, @@ -790,6 +903,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 } ], @@ -804,7 +918,7 @@ "issingle": 1, "istable": 0, "max_attachments": 0, - "modified": "2018-05-03 12:38:12.905394", + "modified": "2019-04-18 12:33:08.040078", "modified_by": "Administrator", "module": "Stock", "name": "Stock Settings", @@ -812,7 +926,6 @@ "permissions": [ { "amend": 0, - "apply_user_permissions": 0, "cancel": 0, "create": 1, "delete": 0, @@ -837,5 +950,6 @@ "show_name_in_global_search": 0, "sort_order": "ASC", "track_changes": 0, - "track_seen": 0 + "track_seen": 0, + "track_views": 0 } \ No newline at end of file