From 610ad47676dd3a06f41e07b6c7ae14eb43c8a617 Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Fri, 28 Aug 2015 11:40:14 +0530 Subject: [PATCH 01/15] [hotfix] reload Delivery Note, Sales Invoice and Purchase Receipt in return entry patch --- .../patches/v5_8/update_order_reference_in_return_entries.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/erpnext/patches/v5_8/update_order_reference_in_return_entries.py b/erpnext/patches/v5_8/update_order_reference_in_return_entries.py index a875aede28..d7972dc64a 100644 --- a/erpnext/patches/v5_8/update_order_reference_in_return_entries.py +++ b/erpnext/patches/v5_8/update_order_reference_in_return_entries.py @@ -5,6 +5,9 @@ from __future__ import unicode_literals import frappe def execute(): + frappe.reload_doctype("Delivery Note") + frappe.reload_doctype("Sales Invoice") + frappe.reload_doctype("Purchase Receipt") frappe.reload_doctype("Sales Order Item") frappe.reload_doctype("Purchase Order Item") From 8f1391dc96b630b0842ee998750e06dcdce8ea71 Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Mon, 31 Aug 2015 12:42:05 +0530 Subject: [PATCH 02/15] [enhancement] calendar for sales order and other related fixes #3542 --- .../current/calendar_for_sales_order.md | 1 + erpnext/hooks.py | 2 +- .../production_order/production_order.py | 28 ++++++------ .../production_order_calendar.js | 9 ++++ erpnext/projects/doctype/task/task.py | 20 ++++----- erpnext/projects/doctype/time_log/time_log.py | 15 ++----- .../doctype/sales_order/sales_order.py | 21 +++++++++ .../sales_order/sales_order_calendar.js | 45 +++++++++++++++++++ 8 files changed, 101 insertions(+), 40 deletions(-) create mode 100644 erpnext/change_log/current/calendar_for_sales_order.md create mode 100644 erpnext/selling/doctype/sales_order/sales_order_calendar.js diff --git a/erpnext/change_log/current/calendar_for_sales_order.md b/erpnext/change_log/current/calendar_for_sales_order.md new file mode 100644 index 0000000000..0b244c85a8 --- /dev/null +++ b/erpnext/change_log/current/calendar_for_sales_order.md @@ -0,0 +1 @@ +- Added Calendar and Gantt Views for Sales Order based on Delivery Date diff --git a/erpnext/hooks.py b/erpnext/hooks.py index 7a6a535283..80abe0d47b 100644 --- a/erpnext/hooks.py +++ b/erpnext/hooks.py @@ -51,7 +51,7 @@ my_account_context = "erpnext.shopping_cart.utils.update_my_account_context" email_append_to = ["Job Applicant", "Opportunity", "Issue"] -calendars = ["Task", "Production Order", "Time Log", "Leave Application"] +calendars = ["Task", "Production Order", "Time Log", "Leave Application", "Sales Order"] website_generators = ["Item Group", "Item", "Sales Partner"] diff --git a/erpnext/manufacturing/doctype/production_order/production_order.py b/erpnext/manufacturing/doctype/production_order/production_order.py index 6299736d95..19746fc304 100644 --- a/erpnext/manufacturing/doctype/production_order/production_order.py +++ b/erpnext/manufacturing/doctype/production_order/production_order.py @@ -329,15 +329,15 @@ class ProductionOrder(Document): frappe.throw(_("Production Order cannot be raised against a Item Template"), ItemHasVariantError) validate_end_of_life(self.production_item) - + def validate_qty(self): if not self.qty > 0: frappe.throw(_("Quantity to Manufacture must be greater than 0.")) - + def validate_operation_time(self): for d in self.operations: if not d.time_in_mins > 0: - frappe.throw(_("Operation Time must be greater than 0 for Operation {0}".format(d.operation))) + frappe.throw(_("Operation Time must be greater than 0 for Operation {0}".format(d.operation))) @frappe.whitelist() def get_item_details(item): @@ -381,19 +381,17 @@ def make_stock_entry(production_order_id, purpose, qty=None): @frappe.whitelist() def get_events(start, end, filters=None): - from frappe.desk.reportview import build_match_conditions - if not frappe.has_permission("Production Order"): - frappe.msgprint(_("No Permission"), raise_exception=1) + """Returns events for Gantt / Calendar view rendering. - conditions = build_match_conditions("Production Order") - conditions = conditions and (" and " + conditions) or "" - if filters: - filters = json.loads(filters) - for key in filters: - if filters[key]: - conditions += " and " + key + ' = "' + filters[key].replace('"', '\"') + '"' + :param start: Start date-time. + :param end: End date-time. + :param filters: Filters (JSON). + """ + from frappe.desk.calendar import get_event_conditions + conditions = get_event_conditions("Production Order", filters) - data = frappe.db.sql("""select name, production_item, planned_start_date, planned_end_date + data = frappe.db.sql("""select name, production_item, planned_start_date, + planned_end_date, status from `tabProduction Order` where ((ifnull(planned_start_date, '0000-00-00')!= '0000-00-00') \ and (planned_start_date between %(start)s and %(end)s) \ @@ -427,4 +425,4 @@ def make_time_log(name, operation, from_time=None, to_time=None, qty=None, proj def get_default_warehouse(): wip_warehouse = frappe.db.get_single_value("Manufacturing Settings", "default_wip_warehouse") fg_warehouse = frappe.db.get_single_value("Manufacturing Settings", "default_fg_warehouse") - return {"wip_warehouse": wip_warehouse, "fg_warehouse": fg_warehouse} \ No newline at end of file + return {"wip_warehouse": wip_warehouse, "fg_warehouse": fg_warehouse} diff --git a/erpnext/manufacturing/doctype/production_order/production_order_calendar.js b/erpnext/manufacturing/doctype/production_order/production_order_calendar.js index a43b25e344..2832494805 100644 --- a/erpnext/manufacturing/doctype/production_order/production_order_calendar.js +++ b/erpnext/manufacturing/doctype/production_order/production_order_calendar.js @@ -10,6 +10,15 @@ frappe.views.calendar["Production Order"] = { "allDay": "allDay" }, gantt: true, + get_css_class: function(data) { + if(data.status==="Completed") { + return "success"; + } else if(data.status==="In Process") { + return "warning"; + } else { + return "danger"; + } + }, filters: [ { "fieldtype": "Link", diff --git a/erpnext/projects/doctype/task/task.py b/erpnext/projects/doctype/task/task.py index fcd756ba6d..28cfcd3050 100644 --- a/erpnext/projects/doctype/task/task.py +++ b/erpnext/projects/doctype/task/task.py @@ -42,7 +42,7 @@ class Task(Document): for d in self.depends_on: if frappe.db.get_value("Task", d.task, "status") != "Closed": frappe.throw(_("Cannot close task as its dependant task {0} is not closed.").format(d.task)) - + from frappe.desk.form.assign_to import clear clear(self.doctype, self.name) @@ -107,18 +107,14 @@ class Task(Document): @frappe.whitelist() def get_events(start, end, filters=None): - from frappe.desk.reportview import build_match_conditions - if not frappe.has_permission("Task"): - frappe.msgprint(_("No Permission"), raise_exception=1) + """Returns events for Gantt / Calendar view rendering. - conditions = build_match_conditions("Task") - conditions = conditions and (" and " + conditions) or "" - - if filters: - filters = json.loads(filters) - for key in filters: - if filters[key]: - conditions += " and " + key + ' = "' + filters[key].replace('"', '\"') + '"' + :param start: Start date-time. + :param end: End date-time. + :param filters: Filters (JSON). + """ + from frappe.desk.calendar import get_event_conditions + conditions = get_event_conditions("Task", filters) data = frappe.db.sql("""select name, exp_start_date, exp_end_date, subject, status, project from `tabTask` diff --git a/erpnext/projects/doctype/time_log/time_log.py b/erpnext/projects/doctype/time_log/time_log.py index 6e937c09e7..ed8930701b 100644 --- a/erpnext/projects/doctype/time_log/time_log.py +++ b/erpnext/projects/doctype/time_log/time_log.py @@ -2,7 +2,7 @@ # License: GNU General Public License v3. See license.txt from __future__ import unicode_literals -import frappe, json +import frappe from frappe import _ from frappe.utils import cstr, flt, get_datetime, get_time, getdate from dateutil.relativedelta import relativedelta @@ -248,17 +248,8 @@ def get_events(start, end, filters=None): :param end: End date-time. :param filters: Filters like workstation, project etc. """ - from frappe.desk.reportview import build_match_conditions - if not frappe.has_permission("Time Log"): - frappe.msgprint(_("No Permission"), raise_exception=1) - - conditions = build_match_conditions("Time Log") - conditions = conditions and (" and " + conditions) or "" - if filters: - filters = json.loads(filters) - for key in filters: - if filters[key]: - conditions += " and " + key + ' = "' + filters[key].replace('"', '\"') + '"' + from frappe.desk.calendar import get_event_conditions + conditions = get_event_conditions("Time Log", filters) data = frappe.db.sql("""select name, from_time, to_time, activity_type, task, project, production_order, workstation from `tabTime Log` diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py index 0b5eb37589..065d32938f 100644 --- a/erpnext/selling/doctype/sales_order/sales_order.py +++ b/erpnext/selling/doctype/sales_order/sales_order.py @@ -471,3 +471,24 @@ def make_maintenance_visit(source_name, target_doc=None): }, target_doc) return doclist + +@frappe.whitelist() +def get_events(start, end, filters=None): + """Returns events for Gantt / Calendar view rendering. + + :param start: Start date-time. + :param end: End date-time. + :param filters: Filters (JSON). + """ + from frappe.desk.calendar import get_event_conditions + conditions = get_event_conditions("Sales Order", filters) + + data = frappe.db.sql("""select name, customer_name, delivery_status, billing_status, delivery_date + from `tabSales Order` + where (ifnull(delivery_date, '0000-00-00')!= '0000-00-00') \ + and (delivery_date between %(start)s and %(end)s) {conditions} + """.format(conditions=conditions), { + "start": start, + "end": end + }, as_dict=True, update={"allDay": 0}) + return data diff --git a/erpnext/selling/doctype/sales_order/sales_order_calendar.js b/erpnext/selling/doctype/sales_order/sales_order_calendar.js new file mode 100644 index 0000000000..8724daae80 --- /dev/null +++ b/erpnext/selling/doctype/sales_order/sales_order_calendar.js @@ -0,0 +1,45 @@ +// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors +// License: GNU General Public License v3. See license.txt + +frappe.views.calendar["Sales Order"] = { + field_map: { + "start": "delivery_date", + "end": "delivery_date", + "id": "name", + "title": "customer_name", + "allDay": "allDay" + }, + gantt: true, + filters: [ + { + "fieldtype": "Link", + "fieldname": "customer", + "options": "Customer", + "label": __("Customer") + }, + { + "fieldtype": "Select", + "fieldname": "delivery_status", + "options": "Not Delivered\nFully Delivered\nPartly Delivered\nClosed\nNot Applicable", + "label": __("Delivery Status") + }, + { + "fieldtype": "Select", + "fieldname": "billing_status", + "options": "Not Billed\nFully Billed\nPartly Billed\nClosed", + "label": __("Billing Status") + }, + ], + get_events_method: "erpnext.selling.doctype.sales_order.sales_order.get_events", + get_css_class: function(data) { + if(data.status=="Stopped") { + return ""; + } if(data.delivery_status=="Not Delivered") { + return "danger"; + } else if(data.delivery_status=="Partly Delivered") { + return "warning"; + } else if(data.delivery_status=="Fully Delivered") { + return "success"; + } + } +} From 19e560e73fd5855450ea3907462fe16222d9071a Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Tue, 1 Sep 2015 09:57:25 +0530 Subject: [PATCH 03/15] [fix] dropbox backup check not working --- erpnext/setup/doctype/backup_manager/backup_manager.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/erpnext/setup/doctype/backup_manager/backup_manager.py b/erpnext/setup/doctype/backup_manager/backup_manager.py index 8d9d48fbad..4b16330868 100644 --- a/erpnext/setup/doctype/backup_manager/backup_manager.py +++ b/erpnext/setup/doctype/backup_manager/backup_manager.py @@ -4,7 +4,7 @@ # For license information, please see license.txt from __future__ import unicode_literals -from frappe.utils import get_site_path +from frappe.utils import get_site_path, cint from frappe.utils.data import convert_utc_to_user_timezone import os import datetime @@ -42,7 +42,7 @@ def take_backups_weekly(): take_backups_if("Weekly") def take_backups_if(freq): - if frappe.db.get_value("Backup Manager", None, "send_backups_to_dropbox"): + if cint(frappe.db.get_value("Backup Manager", None, "send_backups_to_dropbox")): if frappe.db.get_value("Backup Manager", None, "upload_backups_to_dropbox")==freq: take_backups_dropbox() From 409c1e494be04cb335c221caf11f5bb3fdf4de99 Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Wed, 2 Sep 2015 10:55:25 +0530 Subject: [PATCH 04/15] Updated CONTRIBUTING.md --- CONTRIBUTING.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e0dd29850f..ed2d7c56a6 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -49,6 +49,20 @@ DocTypes are easy to create but hard to maintain. If you find that there is a an Tabs! +#### Release Checklist + +- Describe, in detail, what is in the pull request +- How to use the new feature? +- Test cases +- Change log +- Manual Pull Request Link +- Screencast. Should include: + - New Forms + - Linked Forms + - Linked Reports + - Print Views + ### Copyright Please see README.md + From e52ee553c0b1302db6799901d25ba1b9aa122302 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Wed, 2 Sep 2015 10:55:32 +0530 Subject: [PATCH 05/15] Removed debug flag --- erpnext/controllers/queries.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/controllers/queries.py b/erpnext/controllers/queries.py index 04c12f7803..6c98202826 100644 --- a/erpnext/controllers/queries.py +++ b/erpnext/controllers/queries.py @@ -268,7 +268,7 @@ def get_batch_no(doctype, txt, searchfield, start, page_len, filters): {0} {match_conditions} order by expiry_date, name desc - limit %(start)s, %(page_len)s""".format(cond, match_conditions=get_match_cond(doctype)), args, debug=1) + limit %(start)s, %(page_len)s""".format(cond, match_conditions=get_match_cond(doctype)), args) def get_account_list(doctype, txt, searchfield, start, page_len, filters): filter_list = [] From 906bf64f04446ac5dcac33dfa1bc5d7a260b3740 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Wed, 2 Sep 2015 11:32:07 +0530 Subject: [PATCH 06/15] [fix] Insert Item Price automatically based on Rate in Stock UOM --- erpnext/stock/get_item_details.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/erpnext/stock/get_item_details.py b/erpnext/stock/get_item_details.py index 0cec77b4ef..40c2729028 100644 --- a/erpnext/stock/get_item_details.py +++ b/erpnext/stock/get_item_details.py @@ -212,7 +212,7 @@ def get_price_list_rate(args, item_doc, out): price_list_rate = get_price_list_rate_for(args, item_doc.name) if not price_list_rate and item_doc.variant_of: price_list_rate = get_price_list_rate_for(args, item_doc.variant_of) - + if not price_list_rate: if args.price_list and args.rate: insert_item_price(args) @@ -231,12 +231,16 @@ def insert_item_price(args): if frappe.db.get_value("Price List", args.price_list, "currency") == args.currency \ and cint(frappe.db.get_single_value("Stock Settings", "auto_insert_price_list_rate_if_missing")): if frappe.has_permission("Item Price", "write"): + + price_list_rate = args.rate / args.conversion_factor \ + if args.get("conversion_factor") else args.rate + item_price = frappe.get_doc({ "doctype": "Item Price", "price_list": args.price_list, "item_code": args.item_code, "currency": args.currency, - "price_list_rate": args.rate + "price_list_rate": price_list_rate }) item_price.insert() frappe.msgprint("Item Price added for {0} in Price List {1}".format(args.item_code, From a1fa6594757f4cefa504c020df565902cdc57b25 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Wed, 2 Sep 2015 12:56:29 +0530 Subject: [PATCH 07/15] [fix] Delete Time Logs while deleting company transactions --- .../company/delete_company_transactions.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/erpnext/setup/doctype/company/delete_company_transactions.py b/erpnext/setup/doctype/company/delete_company_transactions.py index 87c13754bf..0253674287 100644 --- a/erpnext/setup/doctype/company/delete_company_transactions.py +++ b/erpnext/setup/doctype/company/delete_company_transactions.py @@ -16,6 +16,8 @@ def delete_company_transactions(company_name): frappe.throw(_("Transactions can only be deleted by the creator of the Company"), frappe.PermissionError) delete_bins(company_name) + + delete_time_logs(company_name) for doctype in frappe.db.sql_list("""select parent from tabDocField where fieldtype='Link' and options='Company'"""): @@ -60,3 +62,20 @@ def delete_for_doctype(doctype, company_name): def delete_bins(company_name): frappe.db.sql("""delete from tabBin where warehouse in (select name from tabWarehouse where company=%s)""", company_name) + +def delete_time_logs(company_name): + # Delete Time Logs as it is linked to Production Order / Project / Task, which are linked to company + frappe.db.sql(""" + delete from `tabTime Log` + where + (ifnull(project, '') != '' + and exists(select name from `tabProject` where name=`tabTime Log`.project and company=%(company)s)) + or (ifnull(task, '') != '' + and exists(select name from `tabTask` where name=`tabTime Log`.task and company=%(company)s)) + or (ifnull(production_order, '') != '' + and exists(select name from `tabProduction Order` + where name=`tabTime Log`.production_order and company=%(company)s)) + or (ifnull(sales_invoice, '') != '' + and exists(select name from `tabSales Invoice` + where name=`tabTime Log`.sales_invoice and company=%(company)s)) + """, {"company": company_name}) \ No newline at end of file From 0ca3e3d89e72a0da14c8438a5076cff25655c4ff Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Wed, 2 Sep 2015 13:09:48 +0530 Subject: [PATCH 08/15] [fix] Clear notification count while deleting company transactions --- erpnext/setup/doctype/company/delete_company_transactions.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/erpnext/setup/doctype/company/delete_company_transactions.py b/erpnext/setup/doctype/company/delete_company_transactions.py index 0253674287..cb735c12bf 100644 --- a/erpnext/setup/doctype/company/delete_company_transactions.py +++ b/erpnext/setup/doctype/company/delete_company_transactions.py @@ -6,6 +6,7 @@ import frappe from frappe.utils import cint from frappe import _ +from frappe.desk.notifications import clear_notifications @frappe.whitelist() def delete_company_transactions(company_name): @@ -23,6 +24,9 @@ def delete_company_transactions(company_name): tabDocField where fieldtype='Link' and options='Company'"""): if doctype not in ("Account", "Cost Center", "Warehouse", "Budget Detail", "Party Account"): delete_for_doctype(doctype, company_name) + + # Clear notification counts + clear_notifications() def delete_for_doctype(doctype, company_name): meta = frappe.get_meta(doctype) From e1d2bef3893127ce8fde18e8b2c250360017786e Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Wed, 2 Sep 2015 14:07:46 +0530 Subject: [PATCH 09/15] [fix] Dont delete Employee while deleting company transactions --- erpnext/setup/doctype/company/delete_company_transactions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/setup/doctype/company/delete_company_transactions.py b/erpnext/setup/doctype/company/delete_company_transactions.py index cb735c12bf..f7334b1e6d 100644 --- a/erpnext/setup/doctype/company/delete_company_transactions.py +++ b/erpnext/setup/doctype/company/delete_company_transactions.py @@ -22,7 +22,7 @@ def delete_company_transactions(company_name): for doctype in frappe.db.sql_list("""select parent from tabDocField where fieldtype='Link' and options='Company'"""): - if doctype not in ("Account", "Cost Center", "Warehouse", "Budget Detail", "Party Account"): + if doctype not in ("Account", "Cost Center", "Warehouse", "Budget Detail", "Party Account", "Employee"): delete_for_doctype(doctype, company_name) # Clear notification counts From c3796d273c2112efe02535f8b5cdded0171ccd9b Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Wed, 2 Sep 2015 15:54:53 +0530 Subject: [PATCH 10/15] [change-log] --- erpnext/change_log/current/calendar_for_sales_order.md | 1 - .../{current/collapsible_sections.md => v6/v6_0_0.md} | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) delete mode 100644 erpnext/change_log/current/calendar_for_sales_order.md rename erpnext/change_log/{current/collapsible_sections.md => v6/v6_0_0.md} (52%) diff --git a/erpnext/change_log/current/calendar_for_sales_order.md b/erpnext/change_log/current/calendar_for_sales_order.md deleted file mode 100644 index 0b244c85a8..0000000000 --- a/erpnext/change_log/current/calendar_for_sales_order.md +++ /dev/null @@ -1 +0,0 @@ -- Added Calendar and Gantt Views for Sales Order based on Delivery Date diff --git a/erpnext/change_log/current/collapsible_sections.md b/erpnext/change_log/v6/v6_0_0.md similarity index 52% rename from erpnext/change_log/current/collapsible_sections.md rename to erpnext/change_log/v6/v6_0_0.md index 9c7fb30df1..bb8cd5d1c3 100644 --- a/erpnext/change_log/current/collapsible_sections.md +++ b/erpnext/change_log/v6/v6_0_0.md @@ -1,2 +1,4 @@ +- Added Calendar and Gantt Views for Sales Order based on Delivery Date - Most transaction forms will now have collapsibe sections so that forms appear to be more organized and you can easily locate parts to be edited. - The document title on most transactions can be edited so that you can set meaningful titles to all transactions like Sales Invoice and also edit it to denote status. +- Allow user to disable warnings for "Multiple Items" and "Multiple Sales Order against a Customer's Purchase Order" via Sales and Purchase Settings. Sponsored by: **[McLean Images](http://www.mcleanimages.com.au/)** From 099bbbded09825209e83889a82c8f6280c7fc4b4 Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Wed, 2 Sep 2015 11:18:32 +0530 Subject: [PATCH 11/15] Attributes in the variant should be in the same order as in the Template - Moved Item Variant code from item.py to controllers/item_variant.py - Use Template Item's order of Attribute for Variant Item --- erpnext/controllers/item_variant.py | 168 +++++++++++++++++ erpnext/stock/doctype/item/item.js | 4 +- erpnext/stock/doctype/item/item.py | 170 +----------------- erpnext/stock/doctype/item/test_item.py | 6 +- .../doctype/item_attribute/item_attribute.py | 4 + .../stock_ledger_entry/stock_ledger_entry.py | 2 +- 6 files changed, 180 insertions(+), 174 deletions(-) create mode 100644 erpnext/controllers/item_variant.py diff --git a/erpnext/controllers/item_variant.py b/erpnext/controllers/item_variant.py new file mode 100644 index 0000000000..4edf52b645 --- /dev/null +++ b/erpnext/controllers/item_variant.py @@ -0,0 +1,168 @@ +# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors +# License: GNU General Public License v3. See license.txt + +from __future__ import unicode_literals +import frappe +from frappe import _ +from frappe.utils import cstr, flt +import json + +class ItemVariantExistsError(frappe.ValidationError): pass +class InvalidItemAttributeValueError(frappe.ValidationError): pass +class ItemTemplateCannotHaveStock(frappe.ValidationError): pass + +@frappe.whitelist() +def get_variant(item, args): + """Validates Attributes and their Values, then looks for an exactly matching Item Variant + + :param item: Template Item + :param args: A dictionary with "Attribute" as key and "Attribute Value" as value + """ + if isinstance(args, basestring): + args = json.loads(args) + + if not args: + frappe.throw(_("Please specify at least one attribute in the Attributes table")) + + validate_item_variant_attributes(item, args) + + return find_variant(item, args) + +def validate_item_variant_attributes(item, args): + attribute_values = {} + for t in frappe.get_all("Item Attribute Value", fields=["parent", "attribute_value"], + filters={"parent": ["in", args.keys()]}): + (attribute_values.setdefault(t.parent, [])).append(t.attribute_value) + + numeric_attributes = frappe._dict((t.attribute, t) for t in \ + frappe.db.sql("""select attribute, from_range, to_range, increment from `tabItem Variant Attribute` + where parent = %s and numeric_values=1""", (item), as_dict=1)) + + for attribute, value in args.items(): + if attribute in numeric_attributes: + numeric_attribute = numeric_attributes[attribute] + + from_range = numeric_attribute.from_range + to_range = numeric_attribute.to_range + increment = numeric_attribute.increment + + if increment == 0: + # defensive validation to prevent ZeroDivisionError + frappe.throw(_("Increment for Attribute {0} cannot be 0").format(attribute)) + + is_in_range = from_range <= flt(value) <= to_range + precision = len(cstr(increment).split(".")[-1].rstrip("0")) + #avoid precision error by rounding the remainder + remainder = flt((flt(value) - from_range) % increment, precision) + + is_incremental = remainder==0 or remainder==0 or remainder==increment + + if not (is_in_range and is_incremental): + frappe.throw(_("Value for Attribute {0} must be within the range of {1} to {2} in the increments of {3}")\ + .format(attribute, from_range, to_range, increment), InvalidItemAttributeValueError) + + elif value not in attribute_values[attribute]: + frappe.throw(_("Value {0} for Attribute {1} does not exist in the list of valid Item Attribute Values").format( + value, attribute)) + +def find_variant(item, args): + conditions = ["""(iv_attribute.attribute="{0}" and iv_attribute.attribute_value="{1}")"""\ + .format(frappe.db.escape(key), frappe.db.escape(cstr(value))) for key, value in args.items()] + + conditions = " or ".join(conditions) + + # use approximate match and shortlist possible variant matches + # it is approximate because we are matching using OR condition + # and it need not be exact match at this stage + # this uses a simpler query instead of using multiple exists conditions + possible_variants = frappe.db.sql_list("""select name from `tabItem` item + where variant_of=%s and exists ( + select name from `tabItem Variant Attribute` iv_attribute + where iv_attribute.parent=item.name + and ({conditions}) + )""".format(conditions=conditions), item) + + for variant in possible_variants: + variant = frappe.get_doc("Item", variant) + + if len(args.keys()) == len(variant.get("attributes")): + # has the same number of attributes and values + # assuming no duplication as per the validation in Item + match_count = 0 + + for attribute, value in args.items(): + for row in variant.attributes: + if row.attribute==attribute and row.attribute_value== cstr(value): + # this row matches + match_count += 1 + break + + if match_count == len(args.keys()): + return variant.name + +@frappe.whitelist() +def create_variant(item, args): + if isinstance(args, basestring): + args = json.loads(args) + + template = frappe.get_doc("Item", item) + variant = frappe.new_doc("Item") + variant_attributes = [] + + for d in template.attributes: + variant_attributes.append({ + "attribute": d.attribute, + "attribute_value": args.get(d.attribute) + }) + + variant.set("attributes", variant_attributes) + copy_attributes_to_variant(template, variant) + make_variant_item_code(template, variant) + + return variant + +def copy_attributes_to_variant(item, variant): + from frappe.model import no_value_fields + for field in item.meta.fields: + if field.fieldtype not in no_value_fields and (not field.no_copy)\ + and field.fieldname not in ("item_code", "item_name"): + if variant.get(field.fieldname) != item.get(field.fieldname): + variant.set(field.fieldname, item.get(field.fieldname)) + variant.variant_of = item.name + variant.has_variants = 0 + variant.show_in_website = 0 + if variant.attributes: + variant.description += "\n" + for d in variant.attributes: + variant.description += "

" + d.attribute + ": " + cstr(d.attribute_value) + "

" + +def make_variant_item_code(template, variant): + """Uses template's item code and abbreviations to make variant's item code""" + if variant.item_code: + return + + abbreviations = [] + for attr in variant.attributes: + item_attribute = frappe.db.sql("""select i.numeric_values, v.abbr + from `tabItem Attribute` i left join `tabItem Attribute Value` v + on (i.name=v.parent) + where i.name=%(attribute)s and v.attribute_value=%(attribute_value)s""", { + "attribute": attr.attribute, + "attribute_value": attr.attribute_value + }, as_dict=True) + + if not item_attribute: + # somehow an invalid item attribute got used + return + + if item_attribute[0].numeric_values: + # don't generate item code if one of the attributes is numeric + return + + abbreviations.append(item_attribute[0].abbr) + + if abbreviations: + variant.item_code = "{0}-{1}".format(template.item_code, "-".join(abbreviations)) + + if variant.item_code: + variant.item_name = variant.item_code diff --git a/erpnext/stock/doctype/item/item.js b/erpnext/stock/doctype/item/item.js index 7aa5a03897..06a115fa8d 100644 --- a/erpnext/stock/doctype/item/item.js +++ b/erpnext/stock/doctype/item/item.js @@ -231,7 +231,7 @@ $.extend(erpnext.item, { args = d.get_values(); if(!args) return; frappe.call({ - method:"erpnext.stock.doctype.item.item.get_variant", + method:"erpnext.controllers.item_variant.get_variant", args: { "item": cur_frm.doc.name, "args": d.get_values() @@ -253,7 +253,7 @@ $.extend(erpnext.item, { } else { d.hide(); frappe.call({ - method:"erpnext.stock.doctype.item.item.create_variant", + method:"erpnext.controllers.item_variant.create_variant", args: { "item": cur_frm.doc.name, "args": d.get_values() diff --git a/erpnext/stock/doctype/item/item.py b/erpnext/stock/doctype/item/item.py index d445582f72..d8d21ff09f 100644 --- a/erpnext/stock/doctype/item/item.py +++ b/erpnext/stock/doctype/item/item.py @@ -3,18 +3,15 @@ from __future__ import unicode_literals import frappe -import json from frappe import msgprint, _ from frappe.utils import cstr, flt, cint, getdate, now_datetime, formatdate from frappe.website.website_generator import WebsiteGenerator from erpnext.setup.doctype.item_group.item_group import invalidate_cache_for, get_parent_item_groups from frappe.website.render import clear_cache from frappe.website.doctype.website_slideshow.website_slideshow import get_slideshow +from erpnext.controllers.item_variant import get_variant, copy_attributes_to_variant, ItemVariantExistsError class WarehouseNotSet(frappe.ValidationError): pass -class ItemTemplateCannotHaveStock(frappe.ValidationError): pass -class ItemVariantExistsError(frappe.ValidationError): pass -class InvalidItemAttributeValueError(frappe.ValidationError): pass class Item(WebsiteGenerator): website = frappe._dict( @@ -63,8 +60,8 @@ class Item(WebsiteGenerator): self.validate_warehouse_for_reorder() self.update_item_desc() self.synced_with_hub = 0 + self.validate_has_variants() - # self.validate_stock_for_template_must_be_zero() self.validate_attributes() self.validate_variant_attributes() @@ -314,14 +311,6 @@ class Item(WebsiteGenerator): if frappe.db.exists("Item", {"variant_of": self.name}): frappe.throw(_("Item has variants.")) - def validate_stock_for_template_must_be_zero(self): - if self.has_variants: - stock_in = frappe.db.sql_list("""select warehouse from tabBin - where item_code=%s and (ifnull(actual_qty, 0) > 0 or ifnull(ordered_qty, 0) > 0 - or ifnull(reserved_qty, 0) > 0 or ifnull(indented_qty, 0) > 0 or ifnull(planned_qty, 0) > 0)""", self.name) - if stock_in: - frappe.throw(_("Item Template cannot have stock or Open Sales/Purchase/Production Orders."), ItemTemplateCannotHaveStock) - def validate_uom(self): if not self.get("__islocal"): check_stock_uom_with_bin(self.name, self.stock_uom) @@ -490,158 +479,3 @@ def check_stock_uom_with_bin(item, stock_uom): you have already made some transaction(s) with another UOM. To change default UOM, \ use 'UOM Replace Utility' tool under Stock module.").format(item)) -@frappe.whitelist() -def get_variant(item, args): - """Validates Attributes and their Values, then looks for an exactly matching Item Variant - - :param item: Template Item - :param args: A dictionary with "Attribute" as key and "Attribute Value" as value - """ - if isinstance(args, basestring): - args = json.loads(args) - - if not args: - frappe.throw(_("Please specify at least one attribute in the Attributes table")) - - validate_item_variant_attributes(item, args) - - return find_variant(item, args) - -def validate_item_variant_attributes(item, args): - attribute_values = {} - for t in frappe.get_all("Item Attribute Value", fields=["parent", "attribute_value"], - filters={"parent": ["in", args.keys()]}): - (attribute_values.setdefault(t.parent, [])).append(t.attribute_value) - - numeric_attributes = frappe._dict((t.attribute, t) for t in \ - frappe.db.sql("""select attribute, from_range, to_range, increment from `tabItem Variant Attribute` - where parent = %s and numeric_values=1""", (item), as_dict=1)) - - for attribute, value in args.items(): - - if attribute in numeric_attributes: - numeric_attribute = numeric_attributes[attribute] - - from_range = numeric_attribute.from_range - to_range = numeric_attribute.to_range - increment = numeric_attribute.increment - - if increment == 0: - # defensive validation to prevent ZeroDivisionError - frappe.throw(_("Increment for Attribute {0} cannot be 0").format(attribute)) - - is_in_range = from_range <= flt(value) <= to_range - precision = len(cstr(increment).split(".")[-1].rstrip("0")) - #avoid precision error by rounding the remainder - remainder = flt((flt(value) - from_range) % increment, precision) - - is_incremental = remainder==0 or remainder==0 or remainder==increment - - if not (is_in_range and is_incremental): - frappe.throw(_("Value for Attribute {0} must be within the range of {1} to {2} in the increments of {3}")\ - .format(attribute, from_range, to_range, increment), InvalidItemAttributeValueError) - - elif value not in attribute_values[attribute]: - frappe.throw(_("Value {0} for Attribute {1} does not exist in the list of valid Item Attribute Values").format( - value, attribute)) - -def find_variant(item, args): - conditions = ["""(iv_attribute.attribute="{0}" and iv_attribute.attribute_value="{1}")"""\ - .format(frappe.db.escape(key), frappe.db.escape(cstr(value))) for key, value in args.items()] - - conditions = " or ".join(conditions) - - # use approximate match and shortlist possible variant matches - # it is approximate because we are matching using OR condition - # and it need not be exact match at this stage - # this uses a simpler query instead of using multiple exists conditions - possible_variants = frappe.db.sql_list("""select name from `tabItem` item - where variant_of=%s and exists ( - select name from `tabItem Variant Attribute` iv_attribute - where iv_attribute.parent=item.name - and ({conditions}) - )""".format(conditions=conditions), item) - - for variant in possible_variants: - variant = frappe.get_doc("Item", variant) - - if len(args.keys()) == len(variant.get("attributes")): - # has the same number of attributes and values - # assuming no duplication as per the validation in Item - match_count = 0 - - for attribute, value in args.items(): - for row in variant.attributes: - if row.attribute==attribute and row.attribute_value== cstr(value): - # this row matches - match_count += 1 - break - - if match_count == len(args.keys()): - return variant.name - -@frappe.whitelist() -def create_variant(item, args): - if isinstance(args, basestring): - args = json.loads(args) - - variant = frappe.new_doc("Item") - variant_attributes = [] - for d in args: - variant_attributes.append({ - "attribute": d, - "attribute_value": args[d] - }) - - variant.set("attributes", variant_attributes) - template = frappe.get_doc("Item", item) - copy_attributes_to_variant(template, variant) - make_variant_item_code(template, variant) - - return variant - -def copy_attributes_to_variant(item, variant): - from frappe.model import no_value_fields - for field in item.meta.fields: - if field.fieldtype not in no_value_fields and (not field.no_copy)\ - and field.fieldname not in ("item_code", "item_name"): - if variant.get(field.fieldname) != item.get(field.fieldname): - variant.set(field.fieldname, item.get(field.fieldname)) - variant.variant_of = item.name - variant.has_variants = 0 - variant.show_in_website = 0 - if variant.attributes: - variant.description += "\n" - for d in variant.attributes: - variant.description += "

" + d.attribute + ": " + cstr(d.attribute_value) + "

" - -def make_variant_item_code(template, variant): - """Uses template's item code and abbreviations to make variant's item code""" - if variant.item_code: - return - - abbreviations = [] - for attr in variant.attributes: - item_attribute = frappe.db.sql("""select i.numeric_values, v.abbr - from `tabItem Attribute` i left join `tabItem Attribute Value` v - on (i.name=v.parent) - where i.name=%(attribute)s and v.attribute_value=%(attribute_value)s""", { - "attribute": attr.attribute, - "attribute_value": attr.attribute_value - }, as_dict=True) - - if not item_attribute: - # somehow an invalid item attribute got used - return - - if item_attribute[0].numeric_values: - # don't generate item code if one of the attributes is numeric - return - - abbreviations.append(item_attribute[0].abbr) - - if abbreviations: - variant.item_code = "{0}-{1}".format(template.item_code, "-".join(abbreviations)) - - if variant.item_code: - variant.item_name = variant.item_code diff --git a/erpnext/stock/doctype/item/test_item.py b/erpnext/stock/doctype/item/test_item.py index 916101516f..bd6fe285a1 100644 --- a/erpnext/stock/doctype/item/test_item.py +++ b/erpnext/stock/doctype/item/test_item.py @@ -6,8 +6,8 @@ import unittest import frappe from frappe.test_runner import make_test_records -from erpnext.stock.doctype.item.item import (WarehouseNotSet, create_variant, - ItemVariantExistsError, InvalidItemAttributeValueError) +from erpnext.stock.doctype.item.item import WarehouseNotSet +from erpnext.controllers.item_variant import create_variant, ItemVariantExistsError, InvalidItemAttributeValueError test_ignore = ["BOM"] test_dependencies = ["Warehouse"] @@ -132,7 +132,7 @@ class TestItem(unittest.TestCase): "attribute": "Test Size" }, { - "attribute": "Test Item Length", + "attribute": "Test Item Length", "numeric_values": 1, "from_range": 0.0, "to_range": 100.0, diff --git a/erpnext/stock/doctype/item_attribute/item_attribute.py b/erpnext/stock/doctype/item_attribute/item_attribute.py index 8310288e47..f2d53451d0 100644 --- a/erpnext/stock/doctype/item_attribute/item_attribute.py +++ b/erpnext/stock/doctype/item_attribute/item_attribute.py @@ -41,6 +41,10 @@ class ItemAttribute(Document): abbrs.append(d.abbr) def validate_attribute_values(self): + # don't validate numeric values + if self.numeric_values: + return + attribute_values = [] for d in self.item_attribute_values: attribute_values.append(d.attribute_value) diff --git a/erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.py b/erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.py index 797b2a0a89..33fc6586a2 100644 --- a/erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.py +++ b/erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.py @@ -8,7 +8,7 @@ from frappe import _ from frappe.utils import flt, getdate, add_days, formatdate from frappe.model.document import Document from datetime import date -from erpnext.stock.doctype.item.item import ItemTemplateCannotHaveStock +from erpnext.controllers.item_variant import ItemTemplateCannotHaveStock class StockFreezeError(frappe.ValidationError): pass From a6130dc918cb57078687fddf9aabc183c5263a4c Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Wed, 2 Sep 2015 16:32:45 +0600 Subject: [PATCH 12/15] bumped to version 6.0.0 --- erpnext/__version__.py | 2 +- erpnext/hooks.py | 2 +- setup.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/erpnext/__version__.py b/erpnext/__version__.py index 889fbef84b..7a61e5f6dd 100644 --- a/erpnext/__version__.py +++ b/erpnext/__version__.py @@ -1,2 +1,2 @@ from __future__ import unicode_literals -__version__ = '5.8.2' +__version__ = '6.0.0' diff --git a/erpnext/hooks.py b/erpnext/hooks.py index 80abe0d47b..f7f9197398 100644 --- a/erpnext/hooks.py +++ b/erpnext/hooks.py @@ -27,7 +27,7 @@ blogs. """ app_icon = "icon-th" app_color = "#e74c3c" -app_version = "5.8.2" +app_version = "6.0.0" github_link = "https://github.com/frappe/erpnext" error_report_email = "support@erpnext.com" diff --git a/setup.py b/setup.py index 6a420c3c05..bfa2fa7ab7 100644 --- a/setup.py +++ b/setup.py @@ -1,6 +1,6 @@ from setuptools import setup, find_packages -version = "5.8.2" +version = "6.0.0" with open("requirements.txt", "r") as f: install_requires = f.readlines() From c2283ca3041fb42acfadc0d1954a00e013cc7aa0 Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Wed, 2 Sep 2015 18:56:19 +0530 Subject: [PATCH 13/15] [hot] [fix] remove test options in Opportunity --- .../crm/doctype/opportunity/opportunity.json | 1723 ++++++++--------- 1 file changed, 861 insertions(+), 862 deletions(-) diff --git a/erpnext/crm/doctype/opportunity/opportunity.json b/erpnext/crm/doctype/opportunity/opportunity.json index f3291f2324..77e4e5dca7 100644 --- a/erpnext/crm/doctype/opportunity/opportunity.json +++ b/erpnext/crm/doctype/opportunity/opportunity.json @@ -1,946 +1,945 @@ { - "allow_copy": 0, - "allow_import": 1, - "allow_rename": 0, - "autoname": "naming_series:", - "creation": "2013-03-07 18:50:30", - "custom": 0, - "description": "Potential Sales Deal", - "docstatus": 0, - "doctype": "DocType", - "document_type": "Document", + "allow_copy": 0, + "allow_import": 1, + "allow_rename": 0, + "autoname": "naming_series:", + "creation": "2013-03-07 18:50:30", + "custom": 0, + "description": "Potential Sales Deal", + "docstatus": 0, + "doctype": "DocType", + "document_type": "Document", "fields": [ { - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "fieldname": "from_section", - "fieldtype": "Section Break", - "hidden": 0, - "ignore_user_permissions": 0, - "in_filter": 0, - "in_list_view": 0, - "label": "", - "no_copy": 0, - "options": "icon-user", - "permlevel": 0, - "print_hide": 0, - "read_only": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "from_section", + "fieldtype": "Section Break", + "hidden": 0, + "ignore_user_permissions": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "", + "no_copy": 0, + "options": "icon-user", + "permlevel": 0, + "print_hide": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, "unique": 0 - }, + }, { - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "fieldname": "naming_series", - "fieldtype": "Select", - "hidden": 0, - "ignore_user_permissions": 0, - "in_filter": 0, - "in_list_view": 0, - "label": "Series", - "no_copy": 1, - "oldfieldname": "naming_series", - "oldfieldtype": "Select", - "options": "OPTY-", - "permlevel": 0, - "print_hide": 0, - "read_only": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "naming_series", + "fieldtype": "Select", + "hidden": 0, + "ignore_user_permissions": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Series", + "no_copy": 1, + "oldfieldname": "naming_series", + "oldfieldtype": "Select", + "options": "OPTY-", + "permlevel": 0, + "print_hide": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "set_only_once": 0, "unique": 0 - }, + }, { - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "fieldname": "enquiry_from", - "fieldtype": "Select", - "hidden": 0, - "ignore_user_permissions": 0, - "in_filter": 0, - "in_list_view": 0, - "label": "Opportunity From", - "no_copy": 0, - "oldfieldname": "enquiry_from", - "oldfieldtype": "Select", - "options": "\nLead\nCustomer", - "permlevel": 0, - "print_hide": 1, - "read_only": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "enquiry_from", + "fieldtype": "Select", + "hidden": 0, + "ignore_user_permissions": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Opportunity From", + "no_copy": 0, + "oldfieldname": "enquiry_from", + "oldfieldtype": "Select", + "options": "\nLead\nCustomer", + "permlevel": 0, + "print_hide": 1, + "read_only": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "set_only_once": 0, "unique": 0 - }, + }, { - "allow_on_submit": 0, - "bold": 1, - "collapsible": 0, - "depends_on": "eval:doc.enquiry_from===\"Customer\"", - "fieldname": "customer", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "in_filter": 1, - "in_list_view": 0, - "label": "Customer", - "no_copy": 0, - "oldfieldname": "customer", - "oldfieldtype": "Link", - "options": "Customer", - "permlevel": 0, - "print_hide": 1, - "read_only": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, + "allow_on_submit": 0, + "bold": 1, + "collapsible": 0, + "depends_on": "eval:doc.enquiry_from===\"Customer\"", + "fieldname": "customer", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 0, + "in_filter": 1, + "in_list_view": 0, + "label": "Customer", + "no_copy": 0, + "oldfieldname": "customer", + "oldfieldtype": "Link", + "options": "Customer", + "permlevel": 0, + "print_hide": 1, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, "unique": 0 - }, + }, { - "allow_on_submit": 0, - "bold": 1, - "collapsible": 0, - "depends_on": "eval:doc.enquiry_from===\"Lead\"", - "fieldname": "lead", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "in_filter": 1, - "in_list_view": 0, - "label": "Lead", - "no_copy": 0, - "oldfieldname": "lead", - "oldfieldtype": "Link", - "options": "Lead", - "permlevel": 0, - "print_hide": 1, - "read_only": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, + "allow_on_submit": 0, + "bold": 1, + "collapsible": 0, + "depends_on": "eval:doc.enquiry_from===\"Lead\"", + "fieldname": "lead", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 0, + "in_filter": 1, + "in_list_view": 0, + "label": "Lead", + "no_copy": 0, + "oldfieldname": "lead", + "oldfieldtype": "Link", + "options": "Lead", + "permlevel": 0, + "print_hide": 1, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, "unique": 0 - }, + }, { - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "depends_on": "", - "fieldname": "customer_name", - "fieldtype": "Data", - "hidden": 0, - "ignore_user_permissions": 0, - "in_filter": 0, - "in_list_view": 0, - "label": "Customer / Lead Name", - "no_copy": 0, - "permlevel": 0, - "print_hide": 0, - "read_only": 1, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "depends_on": "", + "fieldname": "customer_name", + "fieldtype": "Data", + "hidden": 0, + "ignore_user_permissions": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Customer / Lead Name", + "no_copy": 0, + "permlevel": 0, + "print_hide": 0, + "read_only": 1, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, "unique": 0 - }, + }, { - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "fieldname": "column_break0", - "fieldtype": "Column Break", - "hidden": 0, - "ignore_user_permissions": 0, - "in_filter": 0, - "in_list_view": 0, - "no_copy": 0, - "oldfieldtype": "Column Break", - "permlevel": 0, - "print_hide": 0, - "read_only": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "column_break0", + "fieldtype": "Column Break", + "hidden": 0, + "ignore_user_permissions": 0, + "in_filter": 0, + "in_list_view": 0, + "no_copy": 0, + "oldfieldtype": "Column Break", + "permlevel": 0, + "print_hide": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0, "width": "50%" - }, + }, { - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "fieldname": "title", - "fieldtype": "Data", - "hidden": 1, - "ignore_user_permissions": 0, - "in_filter": 0, - "in_list_view": 0, - "label": "Title", - "no_copy": 0, - "options": "[{status}] {enquiry_type} from {customer}", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "read_only": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "title", + "fieldtype": "Data", + "hidden": 1, + "ignore_user_permissions": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Title", + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, "unique": 0 - }, + }, { - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "default": "Sales", - "fieldname": "enquiry_type", - "fieldtype": "Select", - "hidden": 0, - "ignore_user_permissions": 0, - "in_filter": 0, - "in_list_view": 0, - "label": "Opportunity Type", - "no_copy": 0, - "oldfieldname": "enquiry_type", - "oldfieldtype": "Select", - "options": "Sales\nMaintenance", - "permlevel": 0, - "print_hide": 0, - "read_only": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "default": "Sales", + "fieldname": "enquiry_type", + "fieldtype": "Select", + "hidden": 0, + "ignore_user_permissions": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Opportunity Type", + "no_copy": 0, + "oldfieldname": "enquiry_type", + "oldfieldtype": "Select", + "options": "Sales\nMaintenance", + "permlevel": 0, + "print_hide": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "set_only_once": 0, "unique": 0 - }, + }, { - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "default": "Open", - "fieldname": "status", - "fieldtype": "Select", - "hidden": 0, - "ignore_user_permissions": 0, - "in_filter": 0, - "in_list_view": 0, - "label": "Status", - "no_copy": 1, - "oldfieldname": "status", - "oldfieldtype": "Select", - "options": "Open\nQuotation\nLost\nReplied\nClosed", - "permlevel": 0, - "print_hide": 1, - "read_only": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "default": "Open", + "fieldname": "status", + "fieldtype": "Select", + "hidden": 0, + "ignore_user_permissions": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Status", + "no_copy": 1, + "oldfieldname": "status", + "oldfieldtype": "Select", + "options": "Open\nQuotation\nLost\nReplied\nClosed", + "permlevel": 0, + "print_hide": 1, + "read_only": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "set_only_once": 0, "unique": 0 - }, + }, { - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "depends_on": "eval:doc.status===\"Lost\"", - "fieldname": "order_lost_reason", - "fieldtype": "Small Text", - "hidden": 0, - "ignore_user_permissions": 0, - "in_filter": 0, - "in_list_view": 0, - "label": "Lost Reason", - "no_copy": 1, - "permlevel": 0, - "print_hide": 0, - "read_only": 1, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "depends_on": "eval:doc.status===\"Lost\"", + "fieldname": "order_lost_reason", + "fieldtype": "Small Text", + "hidden": 0, + "ignore_user_permissions": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Lost Reason", + "no_copy": 1, + "permlevel": 0, + "print_hide": 0, + "read_only": 1, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, "unique": 0 - }, + }, { - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "fieldname": "with_items", - "fieldtype": "Check", - "hidden": 0, - "ignore_user_permissions": 0, - "in_filter": 0, - "in_list_view": 0, - "label": "With Items", - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "read_only": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "with_items", + "fieldtype": "Check", + "hidden": 0, + "ignore_user_permissions": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "With Items", + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, "unique": 0 - }, + }, { - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "depends_on": "with_items", - "fieldname": "items_section", - "fieldtype": "Section Break", - "hidden": 0, - "ignore_user_permissions": 0, - "in_filter": 0, - "in_list_view": 0, - "label": "", - "no_copy": 0, - "oldfieldtype": "Section Break", - "options": "icon-shopping-cart", - "permlevel": 0, - "print_hide": 0, - "read_only": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "depends_on": "with_items", + "fieldname": "items_section", + "fieldtype": "Section Break", + "hidden": 0, + "ignore_user_permissions": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "", + "no_copy": 0, + "oldfieldtype": "Section Break", + "options": "icon-shopping-cart", + "permlevel": 0, + "print_hide": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, "unique": 0 - }, + }, { - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "description": "", - "fieldname": "items", - "fieldtype": "Table", - "hidden": 0, - "ignore_user_permissions": 0, - "in_filter": 0, - "in_list_view": 0, - "label": "Items", - "no_copy": 0, - "oldfieldname": "enquiry_details", - "oldfieldtype": "Table", - "options": "Opportunity Item", - "permlevel": 0, - "print_hide": 0, - "read_only": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "description": "", + "fieldname": "items", + "fieldtype": "Table", + "hidden": 0, + "ignore_user_permissions": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Items", + "no_copy": 0, + "oldfieldname": "enquiry_details", + "oldfieldtype": "Table", + "options": "Opportunity Item", + "permlevel": 0, + "print_hide": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, "unique": 0 - }, + }, { - "allow_on_submit": 0, - "bold": 0, - "collapsible": 1, - "collapsible_depends_on": "next_contact_by", - "depends_on": "eval:doc.lead || doc.customer", - "fieldname": "contact_info", - "fieldtype": "Section Break", - "hidden": 0, - "ignore_user_permissions": 0, - "in_filter": 0, - "in_list_view": 0, - "label": "Contact Info", - "no_copy": 0, - "options": "icon-bullhorn", - "permlevel": 0, - "print_hide": 0, - "read_only": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 1, + "collapsible_depends_on": "next_contact_by", + "depends_on": "eval:doc.lead || doc.customer", + "fieldname": "contact_info", + "fieldtype": "Section Break", + "hidden": 0, + "ignore_user_permissions": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Contact Info", + "no_copy": 0, + "options": "icon-bullhorn", + "permlevel": 0, + "print_hide": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, "unique": 0 - }, + }, { - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "depends_on": "eval:doc.customer || doc.lead", - "fieldname": "customer_address", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "in_filter": 1, - "in_list_view": 0, - "label": "Customer / Lead Address", - "no_copy": 0, - "options": "Address", - "permlevel": 0, - "print_hide": 1, - "read_only": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "depends_on": "eval:doc.customer || doc.lead", + "fieldname": "customer_address", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 0, + "in_filter": 1, + "in_list_view": 0, + "label": "Customer / Lead Address", + "no_copy": 0, + "options": "Address", + "permlevel": 0, + "print_hide": 1, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, "unique": 0 - }, + }, { - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "fieldname": "address_display", - "fieldtype": "Small Text", - "hidden": 1, - "ignore_user_permissions": 0, - "in_filter": 0, - "in_list_view": 0, - "label": "Address", - "no_copy": 0, - "oldfieldname": "address", - "oldfieldtype": "Small Text", - "permlevel": 0, - "print_hide": 0, - "read_only": 1, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "address_display", + "fieldtype": "Small Text", + "hidden": 1, + "ignore_user_permissions": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Address", + "no_copy": 0, + "oldfieldname": "address", + "oldfieldtype": "Small Text", + "permlevel": 0, + "print_hide": 0, + "read_only": 1, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, "unique": 0 - }, + }, { - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "depends_on": "customer", - "description": "", - "fieldname": "territory", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "in_filter": 1, - "in_list_view": 1, - "label": "Territory", - "no_copy": 0, - "options": "Territory", - "permlevel": 0, - "print_hide": 1, - "read_only": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 1, - "set_only_once": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "depends_on": "customer", + "description": "", + "fieldname": "territory", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 0, + "in_filter": 1, + "in_list_view": 1, + "label": "Territory", + "no_copy": 0, + "options": "Territory", + "permlevel": 0, + "print_hide": 1, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 1, + "set_only_once": 0, "unique": 0 - }, + }, { - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "depends_on": "customer", - "description": "", - "fieldname": "customer_group", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "in_filter": 1, - "in_list_view": 0, - "label": "Customer Group", - "no_copy": 0, - "oldfieldname": "customer_group", - "oldfieldtype": "Link", - "options": "Customer Group", - "permlevel": 0, - "print_hide": 1, - "read_only": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 1, - "set_only_once": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "depends_on": "customer", + "description": "", + "fieldname": "customer_group", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 0, + "in_filter": 1, + "in_list_view": 0, + "label": "Customer Group", + "no_copy": 0, + "oldfieldname": "customer_group", + "oldfieldtype": "Link", + "options": "Customer Group", + "permlevel": 0, + "print_hide": 1, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 1, + "set_only_once": 0, "unique": 0 - }, + }, { - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "fieldname": "column_break3", - "fieldtype": "Column Break", - "hidden": 0, - "ignore_user_permissions": 0, - "in_filter": 0, - "in_list_view": 0, - "no_copy": 0, - "permlevel": 0, - "print_hide": 0, - "read_only": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "column_break3", + "fieldtype": "Column Break", + "hidden": 0, + "ignore_user_permissions": 0, + "in_filter": 0, + "in_list_view": 0, + "no_copy": 0, + "permlevel": 0, + "print_hide": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, "unique": 0 - }, + }, { - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "depends_on": "eval:doc.lead || doc.customer", - "fieldname": "contact_person", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "in_filter": 1, - "in_list_view": 0, - "label": "Contact Person", - "no_copy": 0, - "options": "Contact", - "permlevel": 0, - "print_hide": 1, - "read_only": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "depends_on": "eval:doc.lead || doc.customer", + "fieldname": "contact_person", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 0, + "in_filter": 1, + "in_list_view": 0, + "label": "Contact Person", + "no_copy": 0, + "options": "Contact", + "permlevel": 0, + "print_hide": 1, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, "unique": 0 - }, + }, { - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "depends_on": "customer", - "fieldname": "contact_display", - "fieldtype": "Small Text", - "hidden": 0, - "ignore_user_permissions": 0, - "in_filter": 0, - "in_list_view": 0, - "label": "Contact", - "no_copy": 0, - "permlevel": 0, - "print_hide": 0, - "read_only": 1, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "depends_on": "customer", + "fieldname": "contact_display", + "fieldtype": "Small Text", + "hidden": 0, + "ignore_user_permissions": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Contact", + "no_copy": 0, + "permlevel": 0, + "print_hide": 0, + "read_only": 1, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, "unique": 0 - }, + }, { - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "depends_on": "eval:doc.lead || doc.customer", - "fieldname": "contact_email", - "fieldtype": "Small Text", - "hidden": 0, - "ignore_user_permissions": 0, - "in_filter": 0, - "in_list_view": 0, - "label": "Contact Email", - "no_copy": 0, - "permlevel": 0, - "print_hide": 0, - "read_only": 1, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "depends_on": "eval:doc.lead || doc.customer", + "fieldname": "contact_email", + "fieldtype": "Small Text", + "hidden": 0, + "ignore_user_permissions": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Contact Email", + "no_copy": 0, + "permlevel": 0, + "print_hide": 0, + "read_only": 1, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, "unique": 0 - }, + }, { - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "depends_on": "eval:doc.lead || doc.customer", - "fieldname": "contact_mobile", - "fieldtype": "Small Text", - "hidden": 0, - "ignore_user_permissions": 0, - "in_filter": 0, - "in_list_view": 0, - "label": "Contact Mobile No", - "no_copy": 0, - "permlevel": 0, - "print_hide": 0, - "read_only": 1, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "depends_on": "eval:doc.lead || doc.customer", + "fieldname": "contact_mobile", + "fieldtype": "Small Text", + "hidden": 0, + "ignore_user_permissions": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Contact Mobile No", + "no_copy": 0, + "permlevel": 0, + "print_hide": 0, + "read_only": 1, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, "unique": 0 - }, + }, { - "allow_on_submit": 0, - "bold": 0, - "collapsible": 1, - "collapsible_depends_on": "", - "fieldname": "more_info", - "fieldtype": "Section Break", - "hidden": 0, - "ignore_user_permissions": 0, - "in_filter": 0, - "in_list_view": 0, - "label": "Source", - "no_copy": 0, - "oldfieldtype": "Section Break", - "options": "icon-file-text", - "permlevel": 0, - "print_hide": 0, - "read_only": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 1, + "collapsible_depends_on": "", + "fieldname": "more_info", + "fieldtype": "Section Break", + "hidden": 0, + "ignore_user_permissions": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Source", + "no_copy": 0, + "oldfieldtype": "Section Break", + "options": "icon-file-text", + "permlevel": 0, + "print_hide": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, "unique": 0 - }, + }, { - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "fieldname": "source", - "fieldtype": "Select", - "hidden": 0, - "ignore_user_permissions": 0, - "in_filter": 0, - "in_list_view": 0, - "label": "Source", - "no_copy": 0, - "oldfieldname": "source", - "oldfieldtype": "Select", - "options": "\nExisting Customer\nReference\nAdvertisement\nCold Calling\nExhibition\nSupplier Reference\nMass Mailing\nCustomer's Vendor\nCampaign\nWalk In", - "permlevel": 0, - "print_hide": 0, - "read_only": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "source", + "fieldtype": "Select", + "hidden": 0, + "ignore_user_permissions": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Source", + "no_copy": 0, + "oldfieldname": "source", + "oldfieldtype": "Select", + "options": "\nExisting Customer\nReference\nAdvertisement\nCold Calling\nExhibition\nSupplier Reference\nMass Mailing\nCustomer's Vendor\nCampaign\nWalk In", + "permlevel": 0, + "print_hide": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, "unique": 0 - }, + }, { - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "description": "Enter name of campaign if source of enquiry is campaign", - "fieldname": "campaign", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "in_filter": 0, - "in_list_view": 0, - "label": "Campaign", - "no_copy": 0, - "oldfieldname": "campaign", - "oldfieldtype": "Link", - "options": "Campaign", - "permlevel": 0, - "print_hide": 0, - "read_only": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "description": "Enter name of campaign if source of enquiry is campaign", + "fieldname": "campaign", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Campaign", + "no_copy": 0, + "oldfieldname": "campaign", + "oldfieldtype": "Link", + "options": "Campaign", + "permlevel": 0, + "print_hide": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, "unique": 0 - }, + }, { - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "fieldname": "column_break1", - "fieldtype": "Column Break", - "hidden": 0, - "ignore_user_permissions": 0, - "in_filter": 0, - "in_list_view": 0, - "no_copy": 0, - "oldfieldtype": "Column Break", - "permlevel": 0, - "print_hide": 0, - "read_only": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "column_break1", + "fieldtype": "Column Break", + "hidden": 0, + "ignore_user_permissions": 0, + "in_filter": 0, + "in_list_view": 0, + "no_copy": 0, + "oldfieldtype": "Column Break", + "permlevel": 0, + "print_hide": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0, "width": "50%" - }, + }, { - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "fieldname": "company", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "in_filter": 1, - "in_list_view": 0, - "label": "Company", - "no_copy": 0, - "oldfieldname": "company", - "oldfieldtype": "Link", - "options": "Company", - "permlevel": 0, - "print_hide": 1, - "read_only": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 1, - "set_only_once": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "company", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 0, + "in_filter": 1, + "in_list_view": 0, + "label": "Company", + "no_copy": 0, + "oldfieldname": "company", + "oldfieldtype": "Link", + "options": "Company", + "permlevel": 0, + "print_hide": 1, + "read_only": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 1, + "set_only_once": 0, "unique": 0 - }, + }, { - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "default": "Today", - "fieldname": "transaction_date", - "fieldtype": "Date", - "hidden": 0, - "ignore_user_permissions": 0, - "in_filter": 0, - "in_list_view": 0, - "label": "Opportunity Date", - "no_copy": 0, - "oldfieldname": "transaction_date", - "oldfieldtype": "Date", - "permlevel": 0, - "print_hide": 0, - "read_only": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "unique": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "default": "Today", + "fieldname": "transaction_date", + "fieldtype": "Date", + "hidden": 0, + "ignore_user_permissions": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Opportunity Date", + "no_copy": 0, + "oldfieldname": "transaction_date", + "oldfieldtype": "Date", + "permlevel": 0, + "print_hide": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "set_only_once": 0, + "unique": 0, "width": "50px" - }, + }, { - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "fieldname": "fiscal_year", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "in_filter": 1, - "in_list_view": 0, - "label": "Fiscal Year", - "no_copy": 0, - "oldfieldname": "fiscal_year", - "oldfieldtype": "Select", - "options": "Fiscal Year", - "permlevel": 0, - "print_hide": 1, - "read_only": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 1, - "set_only_once": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "fiscal_year", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 0, + "in_filter": 1, + "in_list_view": 0, + "label": "Fiscal Year", + "no_copy": 0, + "oldfieldname": "fiscal_year", + "oldfieldtype": "Select", + "options": "Fiscal Year", + "permlevel": 0, + "print_hide": 1, + "read_only": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 1, + "set_only_once": 0, "unique": 0 - }, + }, { - "allow_on_submit": 0, - "bold": 0, - "collapsible": 1, - "collapsible_depends_on": "contact_by", - "fieldname": "next_contact", - "fieldtype": "Section Break", - "hidden": 0, - "ignore_user_permissions": 0, - "in_filter": 0, - "in_list_view": 0, - "label": "Next Contact", - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "read_only": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 1, + "collapsible_depends_on": "contact_by", + "fieldname": "next_contact", + "fieldtype": "Section Break", + "hidden": 0, + "ignore_user_permissions": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Next Contact", + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, "unique": 0 - }, + }, { - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "description": "Your sales person who will contact the customer in future", - "fieldname": "contact_by", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "in_filter": 1, - "in_list_view": 0, - "label": "Next Contact By", - "no_copy": 0, - "oldfieldname": "contact_by", - "oldfieldtype": "Link", - "options": "User", - "permlevel": 0, - "print_hide": 0, - "read_only": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "description": "Your sales person who will contact the customer in future", + "fieldname": "contact_by", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 0, + "in_filter": 1, + "in_list_view": 0, + "label": "Next Contact By", + "no_copy": 0, + "oldfieldname": "contact_by", + "oldfieldtype": "Link", + "options": "User", + "permlevel": 0, + "print_hide": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0, "width": "75px" - }, + }, { - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "description": "Your sales person will get a reminder on this date to contact the customer", - "fieldname": "contact_date", - "fieldtype": "Datetime", - "hidden": 0, - "ignore_user_permissions": 0, - "in_filter": 0, - "in_list_view": 0, - "label": "Next Contact Date", - "no_copy": 0, - "oldfieldname": "contact_date", - "oldfieldtype": "Date", - "permlevel": 0, - "print_hide": 0, - "read_only": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "description": "Your sales person will get a reminder on this date to contact the customer", + "fieldname": "contact_date", + "fieldtype": "Datetime", + "hidden": 0, + "ignore_user_permissions": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Next Contact Date", + "no_copy": 0, + "oldfieldname": "contact_date", + "oldfieldtype": "Date", + "permlevel": 0, + "print_hide": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, "unique": 0 - }, + }, { - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "fieldname": "column_break2", - "fieldtype": "Column Break", - "hidden": 0, - "ignore_user_permissions": 0, - "in_filter": 0, - "in_list_view": 0, - "no_copy": 0, - "oldfieldtype": "Column Break", - "permlevel": 0, - "print_hide": 0, - "read_only": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "column_break2", + "fieldtype": "Column Break", + "hidden": 0, + "ignore_user_permissions": 0, + "in_filter": 0, + "in_list_view": 0, + "no_copy": 0, + "oldfieldtype": "Column Break", + "permlevel": 0, + "print_hide": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0, "width": "50%" - }, + }, { - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "fieldname": "to_discuss", - "fieldtype": "Small Text", - "hidden": 0, - "ignore_user_permissions": 0, - "in_filter": 0, - "in_list_view": 0, - "label": "To Discuss", - "no_copy": 1, - "oldfieldname": "to_discuss", - "oldfieldtype": "Small Text", - "permlevel": 0, - "print_hide": 0, - "read_only": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "to_discuss", + "fieldtype": "Small Text", + "hidden": 0, + "ignore_user_permissions": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "To Discuss", + "no_copy": 1, + "oldfieldname": "to_discuss", + "oldfieldtype": "Small Text", + "permlevel": 0, + "print_hide": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, "unique": 0 - }, + }, { - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "fieldname": "amended_from", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 1, - "in_filter": 0, - "in_list_view": 0, - "label": "Amended From", - "no_copy": 1, - "oldfieldname": "amended_from", - "oldfieldtype": "Data", - "options": "Opportunity", - "permlevel": 0, - "print_hide": 1, - "read_only": 1, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "amended_from", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 1, + "in_filter": 0, + "in_list_view": 0, + "label": "Amended From", + "no_copy": 1, + "oldfieldname": "amended_from", + "oldfieldtype": "Data", + "options": "Opportunity", + "permlevel": 0, + "print_hide": 1, + "read_only": 1, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0, "width": "150px" } - ], - "hide_heading": 0, - "hide_toolbar": 0, - "icon": "icon-info-sign", - "idx": 1, - "in_create": 0, - "in_dialog": 0, - "is_submittable": 0, - "issingle": 0, - "istable": 0, - "modified": "2015-08-26 06:56:09.914606", - "modified_by": "Administrator", - "module": "CRM", - "name": "Opportunity", - "owner": "Administrator", + ], + "hide_heading": 0, + "hide_toolbar": 0, + "icon": "icon-info-sign", + "idx": 1, + "in_create": 0, + "in_dialog": 0, + "is_submittable": 0, + "issingle": 0, + "istable": 0, + "modified": "2015-08-26 06:56:09.914607", + "modified_by": "Administrator", + "module": "CRM", + "name": "Opportunity", + "owner": "Administrator", "permissions": [ { - "amend": 0, - "apply_user_permissions": 1, - "cancel": 0, - "create": 1, - "delete": 1, - "email": 1, - "export": 0, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "Sales User", - "set_user_permissions": 0, - "share": 1, - "submit": 0, + "amend": 0, + "apply_user_permissions": 1, + "cancel": 0, + "create": 1, + "delete": 1, + "email": 1, + "export": 0, + "if_owner": 0, + "import": 0, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "Sales User", + "set_user_permissions": 0, + "share": 1, + "submit": 0, "write": 1 - }, + }, { - "amend": 0, - "apply_user_permissions": 0, - "cancel": 0, - "create": 1, - "delete": 1, - "email": 1, - "export": 0, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "Sales Manager", - "set_user_permissions": 0, - "share": 1, - "submit": 0, + "amend": 0, + "apply_user_permissions": 0, + "cancel": 0, + "create": 1, + "delete": 1, + "email": 1, + "export": 0, + "if_owner": 0, + "import": 0, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "Sales Manager", + "set_user_permissions": 0, + "share": 1, + "submit": 0, "write": 1 } - ], - "read_only": 0, - "read_only_onload": 0, - "search_fields": "status,transaction_date,customer,lead,enquiry_type,territory,company", - "sort_field": "modified", - "sort_order": "DESC", + ], + "read_only": 0, + "read_only_onload": 0, + "search_fields": "status,transaction_date,customer,lead,enquiry_type,territory,company", + "sort_field": "modified", + "sort_order": "DESC", "title_field": "title" -} \ No newline at end of file +} From be090fa512122e4a4deabb6c250c48746011a5c1 Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Wed, 2 Sep 2015 19:28:14 +0600 Subject: [PATCH 14/15] bumped to version 6.0.1 --- erpnext/__version__.py | 2 +- erpnext/hooks.py | 2 +- setup.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/erpnext/__version__.py b/erpnext/__version__.py index 7a61e5f6dd..928ce49652 100644 --- a/erpnext/__version__.py +++ b/erpnext/__version__.py @@ -1,2 +1,2 @@ from __future__ import unicode_literals -__version__ = '6.0.0' +__version__ = '6.0.1' diff --git a/erpnext/hooks.py b/erpnext/hooks.py index f7f9197398..ed1e74a47f 100644 --- a/erpnext/hooks.py +++ b/erpnext/hooks.py @@ -27,7 +27,7 @@ blogs. """ app_icon = "icon-th" app_color = "#e74c3c" -app_version = "6.0.0" +app_version = "6.0.1" github_link = "https://github.com/frappe/erpnext" error_report_email = "support@erpnext.com" diff --git a/setup.py b/setup.py index bfa2fa7ab7..b3a16ce85a 100644 --- a/setup.py +++ b/setup.py @@ -1,6 +1,6 @@ from setuptools import setup, find_packages -version = "6.0.0" +version = "6.0.1" with open("requirements.txt", "r") as f: install_requires = f.readlines() From 59c4ae5a463e3b450f7c9ee64ff18e0a5edf8878 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Thu, 3 Sep 2015 10:46:48 +0530 Subject: [PATCH 15/15] [patch] Re-run the 'default_title' patch --- erpnext/patches.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/patches.txt b/erpnext/patches.txt index 2a16ef3824..5f7dd91a50 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -200,4 +200,4 @@ erpnext.patches.v5_8.add_credit_note_print_heading execute:frappe.delete_doc_if_exists("Print Format", "Credit Note - Negative Invoice") # V6.0 -erpnext.patches.v6_0.set_default_title +erpnext.patches.v6_0.set_default_title # 2015-09-03