diff --git a/.github/frappe-bird.png b/.github/frappe-bird.png deleted file mode 100644 index fd19e7bfc4..0000000000 Binary files a/.github/frappe-bird.png and /dev/null differ diff --git a/.github/frappe-framework-logo.png b/.github/frappe-framework-logo.png new file mode 100644 index 0000000000..5049078a46 Binary files /dev/null and b/.github/frappe-framework-logo.png differ diff --git a/.travis/run-tests.sh b/.travis/run-tests.sh index 15ea2370e4..a333e050bb 100755 --- a/.travis/run-tests.sh +++ b/.travis/run-tests.sh @@ -11,17 +11,13 @@ setup_mariadb_env() { if [[ $DB == 'mariadb' ]]; then setup_mariadb_env 'test_frappe' bench --site test_site reinstall --yes - bench --site test_site setup-help - bench setup-global-help --root_password travis bench --site test_site scheduler disable bench --site test_site run-tests --coverage elif [[ $TEST_TYPE == 'ui' ]]; then setup_mariadb_env 'test_site_ui' - bench --site test_site_ui --force restore ./apps/frappe/test_sites/test_site_ui/20181116_225029-test_site_ui-database.sql.gz + bench --site test_site_ui --force restore ./apps/frappe/test_sites/test_site_ui/test_site_ui-database.sql.gz bench --site test_site_ui migrate - bench --site test_site_ui setup-help - bench setup-global-help --root_password travis bench --site test_site_ui scheduler disable cd apps/frappe && yarn && yarn cypress:run @@ -29,8 +25,6 @@ elif [[ $DB == 'postgres' ]]; then psql -c "CREATE DATABASE test_frappe;" -U postgres psql -c "CREATE USER test_frappe WITH PASSWORD 'test_frappe';" -U postgres bench --site test_site_postgres reinstall --yes - bench --site test_site_postgres setup-help - bench setup-global-help --db_type=postgres --root_password travis bench --site test_site_postgres scheduler disable bench --site test_site_postgres run-tests --coverage fi diff --git a/README.md b/README.md index bdb082ccdc..50d715ad72 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@
- +

frappe @@ -22,7 +22,7 @@ - + diff --git a/cypress/fixtures/example.json b/cypress/fixtures/example.json new file mode 100644 index 0000000000..da18d9352a --- /dev/null +++ b/cypress/fixtures/example.json @@ -0,0 +1,5 @@ +{ + "name": "Using fixtures to represent data", + "email": "hello@cypress.io", + "body": "Fixtures are a great way to mock data for responses to routes" +} \ No newline at end of file diff --git a/cypress/integration/login.js b/cypress/integration/login.js index 96b316db24..4da1f39229 100644 --- a/cypress/integration/login.js +++ b/cypress/integration/login.js @@ -1,10 +1,12 @@ context('Login', () => { beforeEach(() => { + cy.request('/api/method/logout'); cy.visit('/login'); + cy.location().should('be', '/login'); }); it('greets with login screen', () => { - cy.get('.page-card-head').contains('Sign In'); + cy.get('.page-card-head').contains('Login'); }); it('validates password', () => { diff --git a/cypress/integration/relative_filters.js b/cypress/integration/relative_filters.js new file mode 100644 index 0000000000..efc6b930b2 --- /dev/null +++ b/cypress/integration/relative_filters.js @@ -0,0 +1,50 @@ +context('Relative Timeframe', () => { + beforeEach(() => { + cy.login('Administrator', 'qwe'); + cy.visit('/desk'); + }); + before(() => { + cy.login('Administrator', 'qwe'); + cy.visit('/desk'); + cy.window().its('frappe').then(frappe => { + frappe.call("frappe.tests.test_utils.create_todo_records"); + }); + }); + it('set relative filter for Previous and check list', () => { + cy.visit('/desk#List/ToDo/List'); + cy.get('.list-row:contains("this is fourth todo")').should('exist'); + cy.get('.tag-filters-area .btn:contains("Add Filter")').click(); + cy.get('.fieldname-select-area').should('exist'); + cy.get('.fieldname-select-area input').type("Due Date{enter}", { delay: 100 }); + cy.get('select.condition.form-control').select("Previous"); + cy.get('.filter-field select.input-with-feedback.form-control').select("1 week"); + cy.server(); + cy.route({ + method: 'POST', + url: '/' + }).as('applyFilter'); + cy.get('.filter-box .btn:contains("Apply")').click(); + cy.wait('@applyFilter'); + cy.get('.list-row-container').its('length').should('eq', 1); + cy.get('.list-row-container').should('contain', 'this is second todo'); + cy.get('.remove-filter.btn').click(); + }); + it('set relative filter for Next and check list', () => { + cy.visit('/desk#List/ToDo/List'); + cy.get('.list-row:contains("this is fourth todo")').should('exist'); + cy.get('.tag-filters-area .btn:contains("Add Filter")').click(); + cy.get('.fieldname-select-area input').type("Due Date{enter}", { delay: 100 }); + cy.get('select.condition.form-control').select("Next"); + cy.get('.filter-field select.input-with-feedback.form-control').select("1 week"); + cy.server(); + cy.route({ + method: 'POST', + url: '/' + }).as('applyFilter'); + cy.get('.filter-box .btn:contains("Apply")').click(); + cy.wait('@applyFilter'); + cy.get('.list-row-container').its('length').should('eq', 1); + cy.get('.list-row').should('contain', 'this is first todo'); + cy.get('.remove-filter.btn').click(); + }); +}); diff --git a/cypress/integration/table_multiselect.js b/cypress/integration/table_multiselect.js new file mode 100644 index 0000000000..67b522c364 --- /dev/null +++ b/cypress/integration/table_multiselect.js @@ -0,0 +1,50 @@ +context('Table MultiSelect', () => { + beforeEach(() => { + cy.login('Administrator', 'qwe'); + }); + + it('select value from multiselect dropdown', () => { + cy.visit('/desk#Form/ToDo/New ToDo 1'); + cy.fill_field('description', 'asdf', 'Text Editor').blur(); + cy.get('input[data-fieldname="assign_to"]').focus().as('input'); + cy.get('input[data-fieldname="assign_to"] + ul').should('be.visible'); + cy.get('@input').type('faris{enter}', { delay: 100 }); + cy.get('.frappe-control[data-fieldname="assign_to"] .form-control .tb-selected-value') + .first().as('selected-value'); + cy.get('@selected-value').should('contain', 'faris@erpnext.com'); + + cy.server(); + cy.route('POST', '/').as('save_form'); + // trigger save + cy.get('.primary-action').click(); + cy.wait('@save_form').its('status').should('eq', 200); + cy.get('@selected-value').should('contain', 'faris@erpnext.com'); + }); + + it('delete value using backspace', () => { + cy.visit('/desk#List/ToDo/List'); + cy.get('.list-row a').should('exist'); + cy.get('.list-subject').last().find('a').click(); + cy.get('input[data-fieldname="assign_to"]').focus().type('{backspace}'); + cy.get('.frappe-control[data-fieldname="assign_to"] .form-control .tb-selected-value') + .should('not.exist'); + }); + + it('delete value using x', () => { + cy.visit('/desk#List/ToDo/List'); + cy.get('.list-row a').should('exist'); + cy.get('.list-subject').last().find('a').click(); + cy.get('.frappe-control[data-fieldname="assign_to"] .form-control .tb-selected-value').as('existing_value'); + cy.get('@existing_value').find('.btn-remove').click(); + cy.get('@existing_value').should('not.exist'); + }); + + it('navigate to selected value', () => { + cy.visit('/desk#List/ToDo/List'); + cy.get('.list-row a').should('exist'); + cy.get('.list-subject').last().find('a').click(); + cy.get('.frappe-control[data-fieldname="assign_to"] .form-control .tb-selected-value').as('existing_value'); + cy.get('@existing_value').find('.btn-link-to-form').click(); + cy.location('hash').should('contain', 'Form/User/faris@erpnext.com'); + }); +}); diff --git a/frappe/__init__.py b/frappe/__init__.py index 2d5ae6352d..f6aa7f9e1d 100644 --- a/frappe/__init__.py +++ b/frappe/__init__.py @@ -17,7 +17,13 @@ from faker import Faker from .exceptions import * from .utils.jinja import (get_jenv, get_template, render_template, get_email_from_template, get_jloader) -__version__ = '10.1.68' +# Hamless for Python 3 +# For Python 2 set default encoding to utf-8 +if sys.version[0] == '2': + reload(sys) + sys.setdefaultencoding("utf-8") + +__version__ = '11.1.3' __title__ = "Frappe Framework" local = Local() diff --git a/frappe/cache_manager.py b/frappe/cache_manager.py index f723e43173..616b0ad03b 100644 --- a/frappe/cache_manager.py +++ b/frappe/cache_manager.py @@ -49,6 +49,10 @@ def clear_defaults_cache(user=None): elif frappe.flags.in_install!="frappe": frappe.cache().delete_key("defaults") +def clear_document_cache(): + frappe.local.document_cache = {} + frappe.cache().delete_key("document_cache") + def clear_doctype_cache(doctype=None): cache = frappe.cache() @@ -70,7 +74,8 @@ def clear_doctype_cache(doctype=None): # clear all parent doctypes - for dt in frappe.db.get_all('DocField', 'parent', dict(fieldtype='Table', options=doctype)): + for dt in frappe.db.get_all('DocField', 'parent', + dict(fieldtype=['in', frappe.model.table_fields], options=doctype)): clear_single(dt.parent) # clear all notifications @@ -81,3 +86,6 @@ def clear_doctype_cache(doctype=None): for name in groups: cache.delete_value(name) + # Clear all document's cache. To clear documents of a specific DocType document_cache should be restructured + clear_document_cache() + diff --git a/frappe/change_log/v11/v11_1_0.md b/frappe/change_log/v11/v11_1_0.md new file mode 100644 index 0000000000..12a214c458 --- /dev/null +++ b/frappe/change_log/v11/v11_1_0.md @@ -0,0 +1,19 @@ +- Dynamic [Frappe Charts](https://github.com/frappe/charts) with Report Builder (built by @pratu16x7) +- New Frappe Chat for easier internal communication (built by @achillesrasquinha) +- [Frappe DataTable](https://github.com/frappe/datatable) for better reports (built by @netchampfaris) +- Google Calendar can now be integrated with Frappe +- Files can now be uploaded using drag-and-drop +- Enhanced List View and Tree View +- Bulk Actions from List View +- Quill editor has been introduced in place of Summernote +- HTML Editor has been introduced +- New User Permissions +- Subscriptions in ERPNext now moved to Auto Repeat in Frappe +- Support for Razorpay and PayPal subscriptions +- Better Social login, Workflow +- Messages for when user goes online/offline +- Logout from all sessions on password change +- Desktop icons can now be selected from a dialog box +- Changes have been made to ensure Frappe is compatible with Python 3 +- Better documentation is now available with support for more languages +- A lot of other fixes have been done to ensure a better overall user experience \ No newline at end of file diff --git a/frappe/change_log/v8/v8_7_0.md b/frappe/change_log/v8/v8_7_0.md index c7b0b4d577..8c982dcbcc 100644 --- a/frappe/change_log/v8/v8_7_0.md +++ b/frappe/change_log/v8/v8_7_0.md @@ -1,2 +1,2 @@ ### User Permissions -- User Permission is now a DocType, a new UX for the existing Role and User Permission managers to make it easy to enter permissions. For more details please check User Permissions \ No newline at end of file +- User Permission is now a DocType, a new UX for the existing Role and User Permission managers to make it easy to enter permissions. For more details please check User Permissions \ No newline at end of file diff --git a/frappe/chat/__init__.py b/frappe/chat/__init__.py index a1a2e9cb36..dea0030839 100644 --- a/frappe/chat/__init__.py +++ b/frappe/chat/__init__.py @@ -1,3 +1,4 @@ +from __future__ import unicode_literals import frappe from frappe import _ diff --git a/frappe/chat/doctype/chat_message/chat_message.py b/frappe/chat/doctype/chat_message/chat_message.py index 06127b3148..657009b2c1 100644 --- a/frappe/chat/doctype/chat_message/chat_message.py +++ b/frappe/chat/doctype/chat_message/chat_message.py @@ -1,3 +1,5 @@ +from __future__ import unicode_literals + # imports - standard imports import json diff --git a/frappe/chat/doctype/chat_message/test_chat_message.py b/frappe/chat/doctype/chat_message/test_chat_message.py index fc4e750719..46dac9858c 100644 --- a/frappe/chat/doctype/chat_message/test_chat_message.py +++ b/frappe/chat/doctype/chat_message/test_chat_message.py @@ -1,3 +1,5 @@ +from __future__ import unicode_literals + # imports - standard imports import unittest diff --git a/frappe/chat/doctype/chat_profile/chat_profile.py b/frappe/chat/doctype/chat_profile/chat_profile.py index a26c76984a..22ce94858d 100644 --- a/frappe/chat/doctype/chat_profile/chat_profile.py +++ b/frappe/chat/doctype/chat_profile/chat_profile.py @@ -1,3 +1,5 @@ +from __future__ import unicode_literals + # imports - module imports from frappe.model.document import Document from frappe import _ diff --git a/frappe/chat/doctype/chat_profile/test_chat_profile.py b/frappe/chat/doctype/chat_profile/test_chat_profile.py index a4f1bf359f..7c12b7179a 100644 --- a/frappe/chat/doctype/chat_profile/test_chat_profile.py +++ b/frappe/chat/doctype/chat_profile/test_chat_profile.py @@ -1,3 +1,5 @@ +from __future__ import unicode_literals + # imports - standard imports import unittest @@ -16,7 +18,7 @@ class TestChatProfile(unittest.TestCase): # def test_create(self): # with self.assertRaises(frappe.ValidationError): # chat_profile.create(test_user) - + # user = get_user_doc(session.user) # if not user.chat_profile: # chat_profile.create(user.name) @@ -47,7 +49,7 @@ class TestChatProfile(unittest.TestCase): # )) # user = get_user_doc(session.user) - # prev = chat_profile.get(user.name) + # prev = chat_profile.get(user.name) # chat_profile.update(user.name, data = dict( # status = 'Offline' diff --git a/frappe/chat/doctype/chat_room/chat_room.py b/frappe/chat/doctype/chat_room/chat_room.py index 4de234f89b..db138ed08b 100644 --- a/frappe/chat/doctype/chat_room/chat_room.py +++ b/frappe/chat/doctype/chat_room/chat_room.py @@ -1,3 +1,5 @@ +from __future__ import unicode_literals + # imports - standard imports import json diff --git a/frappe/chat/doctype/chat_room_user/chat_room_user.py b/frappe/chat/doctype/chat_room_user/chat_room_user.py index f6dbdc7659..f8e13add82 100644 --- a/frappe/chat/doctype/chat_room_user/chat_room_user.py +++ b/frappe/chat/doctype/chat_room_user/chat_room_user.py @@ -1,3 +1,5 @@ +from __future__ import unicode_literals + # imports - module imports from frappe.model.document import Document import frappe diff --git a/frappe/chat/util/__init__.py b/frappe/chat/util/__init__.py index 383df581cd..15977af566 100644 --- a/frappe/chat/util/__init__.py +++ b/frappe/chat/util/__init__.py @@ -1,3 +1,5 @@ +from __future__ import unicode_literals + # imports - module imports from frappe.chat.util.util import ( get_user_doc, diff --git a/frappe/chat/util/test_util.py b/frappe/chat/util/test_util.py index 8b07a1ca08..6d44a63d31 100644 --- a/frappe/chat/util/test_util.py +++ b/frappe/chat/util/test_util.py @@ -1,3 +1,5 @@ +from __future__ import unicode_literals + # imports - standard imports import unittest @@ -7,6 +9,7 @@ from frappe.chat.util import ( safe_json_loads ) import frappe +import six class TestChatUtil(unittest.TestCase): def test_safe_json_loads(self): @@ -15,10 +18,10 @@ class TestChatUtil(unittest.TestCase): number = safe_json_loads("1.0") self.assertEqual(type(number), float) - + string = safe_json_loads("foobar") - self.assertEqual(type(string), str) - + self.assertEqual(type(string), six.text_type) + array = safe_json_loads('[{ "foo": "bar" }]') self.assertEqual(type(array), list) diff --git a/frappe/chat/util/util.py b/frappe/chat/util/util.py index c071cfa17e..5aa80a85ae 100644 --- a/frappe/chat/util/util.py +++ b/frappe/chat/util/util.py @@ -1,3 +1,5 @@ +from __future__ import unicode_literals + # imports - third-party imports import requests @@ -26,7 +28,7 @@ def get_user_doc(user = None): user = user or session.user user = frappe.get_doc('User', user) - + return user def squashify(what): @@ -43,9 +45,9 @@ def safe_json_loads(*args): arg = json.loads(arg) except Exception as e: pass - + results.append(arg) - + return squashify(results) def filter_dict(what, keys, ignore = False): @@ -68,7 +70,7 @@ def get_if_empty(a, b): if not a: a = b return a - + def listify(arg): if not isinstance(arg, list): arg = [arg] @@ -89,7 +91,7 @@ def check_url(what, raise_err = False): raise ValueError('{what} not a valid URL.') else: return False - + return True def create_test_user(module): @@ -110,5 +112,5 @@ def get_emojis(): if resp.ok: emojis = resp.json() redis.hset('frappe_emojis', 'emojis', emojis) - + return dictify(emojis) \ No newline at end of file diff --git a/frappe/chat/website/__init__.py b/frappe/chat/website/__init__.py index 4b8d2283df..f33f531cbf 100644 --- a/frappe/chat/website/__init__.py +++ b/frappe/chat/website/__init__.py @@ -1,3 +1,4 @@ +from __future__ import unicode_literals import frappe from frappe.chat.util import filter_dict, safe_json_loads diff --git a/frappe/commands/scheduler.py b/frappe/commands/scheduler.py index caa0d7ed62..8d1cca286d 100755 --- a/frappe/commands/scheduler.py +++ b/frappe/commands/scheduler.py @@ -1,6 +1,6 @@ from __future__ import unicode_literals, absolute_import, print_function import click -import json, sys +import sys import frappe from frappe.utils import cint from frappe.commands import pass_context, get_site diff --git a/frappe/commands/translate.py b/frappe/commands/translate.py index 1a94210566..5a48e2b409 100644 --- a/frappe/commands/translate.py +++ b/frappe/commands/translate.py @@ -1,6 +1,5 @@ from __future__ import unicode_literals, absolute_import, print_function import click -import frappe from frappe.commands import pass_context, get_site # translation diff --git a/frappe/commands/utils.py b/frappe/commands/utils.py index 984d078dae..bb900590e3 100644 --- a/frappe/commands/utils.py +++ b/frappe/commands/utils.py @@ -343,6 +343,7 @@ def mariadb(context): frappe.conf.db_name, '-h', frappe.conf.db_host or "localhost", '--pager=less -SFX', + '--safe-updates', "-A"]) @click.command('postgres') @@ -600,58 +601,27 @@ def get_version(): @click.option('--db_type') @click.option('--root_password') def setup_global_help(db_type=None, root_password=None): - '''setup help table in a separate database that will be + '''Deprecated: setup help table in a separate database that will be shared by the whole bench and set `global_help_setup` as 1 in common_site_config.json''' - - from frappe.installer import update_site_config - - frappe.local.flags = frappe._dict() - frappe.local.flags.in_setup_help = True - frappe.local.flags.in_install = True - frappe.local.lang = 'en' - frappe.local.conf = frappe.get_site_config(sites_path='.') - - update_site_config('global_help_setup', 1, - site_config_path=os.path.join('.', 'common_site_config.json')) - - if root_password: - frappe.local.conf.root_password = root_password - - if not frappe.local.conf.db_type: - frappe.local.conf.db_type = db_type - - - from frappe.utils.help import sync - sync() + print_in_app_help_deprecation() @click.command('get-docs-app') @click.argument('app') def get_docs_app(app): - '''Get the docs app for given app''' - from frappe.utils.help import setup_apps_for_docs - setup_apps_for_docs(app) + '''Deprecated: Get the docs app for given app''' + print_in_app_help_deprecation() @click.command('get-all-docs-apps') def get_all_docs_apps(): - '''Get docs apps for all apps''' - from frappe.utils.help import setup_apps_for_docs - for app in frappe.get_installed_apps(): - setup_apps_for_docs(app) + '''Deprecated: Get docs apps for all apps''' + print_in_app_help_deprecation() @click.command('setup-help') @pass_context def setup_help(context): - '''Setup help table in the current site (called after migrate)''' - from frappe.utils.help import sync - - for site in context.sites: - try: - frappe.init(site) - frappe.connect() - sync() - finally: - frappe.destroy() + '''Deprecated: Setup help table in the current site (called after migrate)''' + print_in_app_help_deprecation() @click.command('rebuild-global-search') @pass_context @@ -715,6 +685,10 @@ def auto_deploy(context, app, migrate=False, restart=False, remote='upstream'): else: print('No Updates') +def print_in_app_help_deprecation(): + print("In app help has been removed.\nYou can access the documentation on erpnext.com/docs or frappe.io/docs") + return + commands = [ build, clear_cache, @@ -747,6 +721,5 @@ commands = [ add_to_email_queue, setup_global_help, setup_help, - rebuild_global_search, - auto_deploy + rebuild_global_search ] diff --git a/frappe/config/desktop.py b/frappe/config/desktop.py index 863c344d02..b620508c06 100644 --- a/frappe/config/desktop.py +++ b/frappe/config/desktop.py @@ -80,5 +80,12 @@ def get_data(): "color": '#FF4136', 'standard': 1, 'idx': 15 + }, + { + "module_name": 'Settings', + "color": "#bdc3c7", + "reverse": 1, + "icon": "octicon octicon-settings", + "type": "module" } ] diff --git a/frappe/config/settings.py b/frappe/config/settings.py new file mode 100644 index 0000000000..d1c00c2e71 --- /dev/null +++ b/frappe/config/settings.py @@ -0,0 +1,51 @@ +from frappe import _ + +def get_data(): + return [{ + "label": _("Settings"), + "icon": "fa fa-wrench", + "items": [ + { + "type": "doctype", + "name": "System Settings", + "label": _("System Settings"), + "description": _("Language, Date and Time settings"), + "hide_count": True + }, + { + "type": "doctype", + "name": "Domain Settings", + "label": _("Domain Settings"), + "description": _("Enable / Disable Domains"), + "hide_count": True + }, + { + "type": "doctype", + "name": "Print Settings", + "label": _("Print Settings"), + "description": _("Print Style, PDF Size"), + "hide_count": True + }, + { + "type": "doctype", + "name": "Website Settings", + "label": _("Website Settings"), + "description": _("Landing Page, Website Theme, Brand Setup and more"), + "hide_count": True + }, + { + "type": "doctype", + "name": "S3 Backup Settings", + "label": _("S3 Backup Settings"), + "description": _("Enable / Disable Backup, Backup Frequency"), + "hide_count": True + }, + { + "type": "doctype", + "name": "SMS Settings", + "label": _("SMS Settings"), + "description": _("SMS Gateway URL, Message & Receiver Parameter"), + "hide_count": True + } + ] + }] diff --git a/frappe/contacts/report/addresses_and_contacts/addresses_and_contacts.py b/frappe/contacts/report/addresses_and_contacts/addresses_and_contacts.py index 10a1f0f4cd..ce0d91953f 100644 --- a/frappe/contacts/report/addresses_and_contacts/addresses_and_contacts.py +++ b/frappe/contacts/report/addresses_and_contacts/addresses_and_contacts.py @@ -2,7 +2,6 @@ # For license information, please see license.txt from __future__ import unicode_literals -from six.moves import range from six import iteritems import frappe @@ -53,11 +52,11 @@ def get_reference_addresses_and_contact(reference_doctype, reference_name): filters = { "name": reference_name } reference_list = [d[0] for d in frappe.get_list(reference_doctype, filters=filters, fields=["name"], as_list=True)] + for d in reference_list: reference_details.setdefault(d, frappe._dict()) - - reference_details = get_reference_details(reference_doctype, reference_list, "Address", reference_details) - reference_details = get_reference_details(reference_doctype, reference_list, "Contact", reference_details) + reference_details = get_reference_details(reference_doctype, "Address", reference_list, reference_details) + reference_details = get_reference_details(reference_doctype, "Contact", reference_list, reference_details) for reference_name, details in iteritems(reference_details): addresses = details.get("address", []) @@ -68,21 +67,14 @@ def get_reference_addresses_and_contact(reference_doctype, reference_name): result.extend(add_blank_columns_for("Address")) data.append(result) else: - addresses = map(list, addresses) - contacts = map(list, contacts) + result = [reference_name] + result.extend(list(addresses) or add_blank_columns_for("Address")) + result.extend(list(contacts) or add_blank_columns_for("Contact")) + data.append(result) - max_length = max(len(addresses), len(contacts)) - for idx in range(0, max_length): - result = [reference_name] - address = addresses[idx] if idx < len(addresses) else add_blank_columns_for("Address") - contact = contacts[idx] if idx < len(contacts) else add_blank_columns_for("Contact") - result.extend(address) - result.extend(contact) - - data.append(result) return data -def get_reference_details(reference_doctype, reference_list, doctype, reference_details): +def get_reference_details(reference_doctype, doctype, reference_list, reference_details): filters = [ ["Dynamic Link", "link_doctype", "=", reference_doctype], ["Dynamic Link", "link_name", "in", reference_list] @@ -91,9 +83,7 @@ def get_reference_details(reference_doctype, reference_list, doctype, reference_ records = frappe.get_list(doctype, filters=filters, fields=fields, as_list=True) for d in records: - details = reference_details.get(d[0]) or {} - details.setdefault(frappe.scrub(doctype), []).append(d[1:]) - + reference_details[d[0]][frappe.scrub(doctype)] = d[1:] return reference_details def add_blank_columns_for(doctype): diff --git a/frappe/contacts/report/addresses_and_contacts/test_addresses_and_contacts.py b/frappe/contacts/report/addresses_and_contacts/test_addresses_and_contacts.py new file mode 100644 index 0000000000..b375874655 --- /dev/null +++ b/frappe/contacts/report/addresses_and_contacts/test_addresses_and_contacts.py @@ -0,0 +1,107 @@ +from __future__ import unicode_literals +import frappe +import frappe.defaults +import unittest + +from frappe.contacts.report.addresses_and_contacts.addresses_and_contacts import get_data + +def get_custom_linked_doctype(): + if bool(frappe.get_all("DocType", filters={'name':'Test Custom Doctype'})): + return + + doc = frappe.get_doc({ + "doctype": "DocType", + "module": "Core", + "custom": 1, + "fields": [{ + "label": "Test Field", + "fieldname": "test_field", + "fieldtype": "Data" + }, + { + "label": "Contact HTML", + "fieldname": "contact_html", + "fieldtype": "HTML" + }, + { + "label": "Address HTML", + "fieldname": "address_html", + "fieldtype": "HTML" + }], + "permissions": [{ + "role": "System Manager", + "read": 1 + }], + "name": "Test Custom Doctype", + }) + doc.insert() + +def get_custom_doc_for_address_and_contacts(): + get_custom_linked_doctype() + linked_doc = frappe.get_doc({ + "doctype": "Test Custom Doctype", + "test_field": "Hello", + }).insert() + return linked_doc + +def create_linked_address(link_list): + if frappe.flags.test_address_created: + return + + address = frappe.get_doc({ + "doctype": "Address", + "address_title": "_Test Address", + "address_type": "Billing", + "address_line1": "test address line 1", + "address_line2": "test address line 2", + "city": "Milan", + "country": "Italy" + }) + + for name in link_list: + address.append("links",{ + 'link_doctype': 'Test Custom Doctype', + 'link_name': name + }) + + address.insert() + frappe.flags.test_address_created = True + +def create_linked_contact(link_list): + if frappe.flags.test_contact_created: + return + + contact = frappe.get_doc({ + "doctype": "Contact", + "salutation": "Mr", + "email_id": "test_contact@example.com", + "first_name": "_Test First Name", + "last_name": "_Test Last Name", + "is_primary_contact": 1, + "phone": "+91 0000000000", + "status": "Open" + }) + + for name in link_list: + contact.append("links",{ + 'link_doctype': 'Test Custom Doctype', + 'link_name': name + }) + + contact.insert() + frappe.flags.test_contact_created = True + + +class TestAddressesAndContacts(unittest.TestCase): + def test_get_data(self): + linked_docs = [get_custom_doc_for_address_and_contacts(), get_custom_doc_for_address_and_contacts(), get_custom_doc_for_address_and_contacts()] + links_list = [item.name for item in linked_docs] + create_linked_contact(links_list) + create_linked_address(links_list) + report_data = get_data({"reference_doctype": "Test Custom Doctype"}) + for link in links_list: + test_item = [link, 'test address line 1', 'test address line 2', 'Milan', None, None, 'Italy', 0, '_Test First Name', '_Test Last Name', '+91 0000000000', None, 'test_contact@example.com', 1] + self.assertIn(test_item, report_data) + + def tearDown(self): + frappe.db.rollback() \ No newline at end of file diff --git a/frappe/core/doctype/activity_log/feed.py b/frappe/core/doctype/activity_log/feed.py index cc04feef66..b4d46eb5c1 100644 --- a/frappe/core/doctype/activity_log/feed.py +++ b/frappe/core/doctype/activity_log/feed.py @@ -75,8 +75,8 @@ def get_feed_match_conditions(user=None, force=True): if user_permissions: can_read_docs = [] for doctype, obj in user_permissions.items(): - for n in obj.get("docs", []): - can_read_docs.append('{}|{}'.format(doctype, frappe.db.escape(n))) + for n in obj: + can_read_docs.append('{}|{}'.format(doctype, frappe.db.escape(n.get('doc', '')))) if can_read_docs: conditions.append("concat_ws('|', `tabCommunication`.reference_doctype, `tabCommunication`.reference_name) in ({})".format( diff --git a/frappe/core/doctype/communication/comment.py b/frappe/core/doctype/communication/comment.py index 86244ede54..b7a008cd38 100644 --- a/frappe/core/doctype/communication/comment.py +++ b/frappe/core/doctype/communication/comment.py @@ -96,15 +96,17 @@ def notify_mentions(doc): recipients = [frappe.db.get_value("User", {"enabled": 1, "name": name, "user_type": "System User", "allowed_in_mentions": 1}, "email") for name in mentions] + link = get_link_to_form(doc.reference_doctype, doc.reference_name, label=parent_doc_label) + frappe.sendmail( recipients=recipients, sender=frappe.session.user, subject=subject, template="mentioned_in_comment", args={ - "sender_fullname": sender_fullname, + "body_content": _("{0} mentioned you in a comment in {1}").format(sender_fullname, link), "comment": doc, - "link": get_link_to_form(doc.reference_doctype, doc.reference_name, label=parent_doc_label) + "link": link }, header=[_('New Mention'), 'orange'] ) diff --git a/frappe/core/doctype/data_import/data_import.py b/frappe/core/doctype/data_import/data_import.py index 02624cdf65..3ca154c384 100644 --- a/frappe/core/doctype/data_import/data_import.py +++ b/frappe/core/doctype/data_import/data_import.py @@ -34,8 +34,10 @@ def import_data(data_import): frappe.db.set_value("Data Import", data_import, "import_status", "In Progress", update_modified=False) frappe.publish_realtime("data_import_progress", {"progress": "0", "data_import": data_import, "reload": True}, user=frappe.session.user) + from frappe.core.page.background_jobs.background_jobs import get_info enqueued_jobs = [d.get("job_name") for d in get_info()] + if data_import not in enqueued_jobs: enqueue(upload, queue='default', timeout=6000, event='data_import', job_name=data_import, data_import_doc=data_import, from_data_import="Yes", user=frappe.session.user) diff --git a/frappe/core/doctype/data_import/importer.py b/frappe/core/doctype/data_import/importer.py index 3207578363..3681199bca 100644 --- a/frappe/core/doctype/data_import/importer.py +++ b/frappe/core/doctype/data_import/importer.py @@ -434,15 +434,28 @@ def upload(rows = None, submit_after_import=None, ignore_encoding_errors=False, except Exception as e: error_flag = True - err_msg = frappe.local.message_log and "\n".join([json.loads(msg).get('message') for msg in frappe.local.message_log]) or cstr(e) + + # build error message + if frappe.local.message_log: + err_msg = "\n".join(['

{}

'.format(json.loads(msg).get('message')) for msg in frappe.local.message_log]) + else: + err_msg = '

{}

'.format(cstr(e)) + error_trace = frappe.get_traceback() if error_trace: error_log_doc = frappe.log_error(error_trace) error_link = get_url_to_form("Error Log", error_log_doc.name) else: error_link = None - log(**{"row": row_idx + 1, "title":'Error for row %s' % (len(row)>1 and frappe.safe_decode(row[1]) or ""), "message": err_msg, - "indicator": "red", "link":error_link}) + + log(**{ + "row": row_idx + 1, + "title": 'Error for row %s' % (len(row)>1 and frappe.safe_decode(row[1]) or ""), + "message": err_msg, + "indicator": "red", + "link":error_link + }) + # data with error to create a new file # include the errored data in the last row as last_error_row_idx will not be updated for the last row if skip_errors: diff --git a/frappe/core/doctype/data_import/log_details.html b/frappe/core/doctype/data_import/log_details.html index ae6c02ac04..aa160a742b 100644 --- a/frappe/core/doctype/data_import/log_details.html +++ b/frappe/core/doctype/data_import/log_details.html @@ -6,19 +6,19 @@ {{ __("Row Status") }} {{ __("Message") }} - + {% for row in data %} {% if (!show_only_errors) || (show_only_errors && row.indicator == "red") %} - {{ row.row }} + {{ row.row }} {{ row.title }} {% if (import_status != "Failed" || (row.indicator == "red")) { %} - {{ row.message }} +
{{ row.message }}
{% if row.link %} diff --git a/frappe/core/doctype/docfield/docfield.json b/frappe/core/doctype/docfield/docfield.json index e29a6bf8cd..1b8f454838 100644 --- a/frappe/core/doctype/docfield/docfield.json +++ b/frappe/core/doctype/docfield/docfield.json @@ -1,1568 +1,1568 @@ { - "allow_copy": 0, - "allow_events_in_timeline": 0, - "allow_guest_to_view": 0, - "allow_import": 0, - "allow_rename": 0, - "autoname": "hash", - "beta": 0, - "creation": "2013-02-22 01:27:33", - "custom": 0, - "docstatus": 0, - "doctype": "DocType", - "document_type": "Setup", - "editable_grid": 1, - "engine": "InnoDB", + "allow_copy": 0, + "allow_events_in_timeline": 0, + "allow_guest_to_view": 0, + "allow_import": 0, + "allow_rename": 0, + "autoname": "hash", + "beta": 0, + "creation": "2013-02-22 01:27:33", + "custom": 0, + "docstatus": 0, + "doctype": "DocType", + "document_type": "Setup", + "editable_grid": 1, + "engine": "InnoDB", "fields": [ { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "label_and_type", - "fieldtype": "Section Break", - "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": "", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "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, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "label_and_type", + "fieldtype": "Section Break", + "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": "", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "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": 1, - "collapsible": 0, - "columns": 0, - "fieldname": "label", - "fieldtype": "Data", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Label", - "length": 0, - "no_copy": 0, - "oldfieldname": "label", - "oldfieldtype": "Data", - "permlevel": 0, - "print_hide": 0, - "print_hide_if_no_value": 0, - "print_width": "163", - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 1, - "set_only_once": 0, - "translatable": 0, - "unique": 0, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 1, + "collapsible": 0, + "columns": 0, + "fieldname": "label", + "fieldtype": "Data", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 1, + "in_standard_filter": 0, + "label": "Label", + "length": 0, + "no_copy": 0, + "oldfieldname": "label", + "oldfieldtype": "Data", + "permlevel": 0, + "print_hide": 0, + "print_hide_if_no_value": 0, + "print_width": "163", + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 1, + "set_only_once": 0, + "translatable": 0, + "unique": 0, "width": "163" - }, + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 1, - "collapsible": 0, - "columns": 0, - "default": "Data", - "fieldname": "fieldtype", - "fieldtype": "Select", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Type", - "length": 0, - "no_copy": 0, - "oldfieldname": "fieldtype", - "oldfieldtype": "Select", - "options": "Attach\nAttach Image\nBarcode\nButton\nCheck\nCode\nColor\nColumn Break\nCurrency\nData\nDate\nDatetime\nDynamic Link\nFloat\nFold\nGeolocation\nHeading\nHTML\nHTML Editor\nImage\nInt\nLink\nLong Text\nMarkdown Editor\nPassword\nPercent\nRead Only\nSection Break\nSelect\nSmall Text\nTable\nText\nText Editor\nTime\nSignature", - "permlevel": 0, - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 1, - "set_only_once": 0, - "translatable": 0, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 1, + "collapsible": 0, + "columns": 0, + "default": "Data", + "fieldname": "fieldtype", + "fieldtype": "Select", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 1, + "in_standard_filter": 0, + "label": "Type", + "length": 0, + "no_copy": 0, + "oldfieldname": "fieldtype", + "oldfieldtype": "Select", + "options": "Attach\nAttach Image\nBarcode\nButton\nCheck\nCode\nColor\nColumn Break\nCurrency\nData\nDate\nDatetime\nDynamic Link\nFloat\nFold\nGeolocation\nHeading\nHTML\nHTML Editor\nImage\nInt\nLink\nLong Text\nMarkdown Editor\nPassword\nPercent\nRead Only\nSection Break\nSelect\nSmall Text\nTable\nTable MultiSelect\nText\nText Editor\nTime\nSignature", + "permlevel": 0, + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 1, + "set_only_once": 0, + "translatable": 0, "unique": 0 - }, + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 1, - "collapsible": 0, - "columns": 0, - "fieldname": "fieldname", - "fieldtype": "Data", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Name", - "length": 0, - "no_copy": 0, - "oldfieldname": "fieldname", - "oldfieldtype": "Data", - "permlevel": 0, - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 1, - "set_only_once": 0, - "translatable": 0, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 1, + "collapsible": 0, + "columns": 0, + "fieldname": "fieldname", + "fieldtype": "Data", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 1, + "in_standard_filter": 0, + "label": "Name", + "length": 0, + "no_copy": 0, + "oldfieldname": "fieldname", + "oldfieldtype": "Data", + "permlevel": 0, + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 1, + "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, - "fieldname": "reqd", - "fieldtype": "Check", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Mandatory", - "length": 0, - "no_copy": 0, - "oldfieldname": "reqd", - "oldfieldtype": "Check", - "permlevel": 0, - "print_hide": 0, - "print_hide_if_no_value": 0, - "print_width": "50px", - "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, + "fieldname": "reqd", + "fieldtype": "Check", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 1, + "in_standard_filter": 0, + "label": "Mandatory", + "length": 0, + "no_copy": 0, + "oldfieldname": "reqd", + "oldfieldtype": "Check", + "permlevel": 0, + "print_hide": 0, + "print_hide_if_no_value": 0, + "print_width": "50px", + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, + "unique": 0, "width": "50px" - }, + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "eval:in_list([\"Float\", \"Currency\", \"Percent\"], doc.fieldtype)", - "description": "Set non-standard precision for a Float or Currency field", - "fieldname": "precision", - "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": "Precision", - "length": 0, - "no_copy": 0, - "options": "\n1\n2\n3\n4\n5\n6\n7\n8\n9", - "permlevel": 0, - "print_hide": 1, - "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, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "depends_on": "eval:in_list([\"Float\", \"Currency\", \"Percent\"], doc.fieldtype)", + "description": "Set non-standard precision for a Float or Currency field", + "fieldname": "precision", + "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": "Precision", + "length": 0, + "no_copy": 0, + "options": "\n1\n2\n3\n4\n5\n6\n7\n8\n9", + "permlevel": 0, + "print_hide": 1, + "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, - "depends_on": "eval:in_list(['Data', 'Link', 'Dynamic Link', 'Password', 'Select', 'Read Only', 'Attach', 'Attach Image', 'Int'], doc.fieldtype)", - "fieldname": "length", - "fieldtype": "Int", - "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": "Length", - "length": 0, - "no_copy": 0, - "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, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "depends_on": "eval:in_list(['Data', 'Link', 'Dynamic Link', 'Password', 'Select', 'Read Only', 'Attach', 'Attach Image', 'Int'], doc.fieldtype)", + "fieldname": "length", + "fieldtype": "Int", + "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": "Length", + "length": 0, + "no_copy": 0, + "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, - "fieldname": "search_index", - "fieldtype": "Check", - "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": "Index", - "length": 0, - "no_copy": 0, - "oldfieldname": "search_index", - "oldfieldtype": "Check", - "permlevel": 0, - "print_hide": 0, - "print_hide_if_no_value": 0, - "print_width": "50px", - "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, + "fieldname": "search_index", + "fieldtype": "Check", + "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": "Index", + "length": 0, + "no_copy": 0, + "oldfieldname": "search_index", + "oldfieldtype": "Check", + "permlevel": 0, + "print_hide": 0, + "print_hide_if_no_value": 0, + "print_width": "50px", + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, + "unique": 0, "width": "50px" - }, + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "in_list_view", - "fieldtype": "Check", - "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": "In List View", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "print_hide": 0, - "print_hide_if_no_value": 0, - "print_width": "70px", - "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, + "fieldname": "in_list_view", + "fieldtype": "Check", + "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": "In List View", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "print_hide": 0, + "print_hide_if_no_value": 0, + "print_width": "70px", + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, + "unique": 0, "width": "70px" - }, + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "in_standard_filter", - "fieldtype": "Check", - "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": "In Standard Filter", - "length": 0, - "no_copy": 0, - "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, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "in_standard_filter", + "fieldtype": "Check", + "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": "In Standard Filter", + "length": 0, + "no_copy": 0, + "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, - "depends_on": "eval:([\"Data\", \"Select\", \"Table\", \"Text\", \"Text Editor\", \"Link\", \"Small Text\", \"Long Text\", \"Read Only\", \"Heading\", \"Dynamic Link\"].indexOf(doc.fieldtype) !== -1)", - "fieldname": "in_global_search", - "fieldtype": "Check", - "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": "In Global Search", - "length": 0, - "no_copy": 0, - "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, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "depends_on": "eval:([\"Data\", \"Select\", \"Table\", \"Text\", \"Text Editor\", \"Link\", \"Small Text\", \"Long Text\", \"Read Only\", \"Heading\", \"Dynamic Link\"].indexOf(doc.fieldtype) !== -1)", + "fieldname": "in_global_search", + "fieldtype": "Check", + "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": "In Global Search", + "length": 0, + "no_copy": 0, + "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, - "fieldname": "allow_in_quick_entry", - "fieldtype": "Check", - "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": "Allow in Quick Entry", - "length": 0, - "no_copy": 0, - "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, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "allow_in_quick_entry", + "fieldtype": "Check", + "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": "Allow in Quick Entry", + "length": 0, + "no_copy": 0, + "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, - "fieldname": "bold", - "fieldtype": "Check", - "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": "Bold", - "length": 0, - "no_copy": 0, - "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, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "bold", + "fieldtype": "Check", + "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": "Bold", + "length": 0, + "no_copy": 0, + "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": "0", - "depends_on": "eval:['Data', 'Select', 'Text', 'Small Text', 'Text Editor'].includes(doc.fieldtype)", - "fieldname": "translatable", - "fieldtype": "Check", - "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": "Translatable", - "length": 0, - "no_copy": 0, - "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, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "default": "0", + "depends_on": "eval:['Data', 'Select', 'Text', 'Small Text', 'Text Editor'].includes(doc.fieldtype)", + "fieldname": "translatable", + "fieldtype": "Check", + "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": "Translatable", + "length": 0, + "no_copy": 0, + "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, - "depends_on": "eval:doc.fieldtype===\"Section Break\"", - "fieldname": "collapsible", - "fieldtype": "Check", - "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": "Collapsible", - "length": 255, - "no_copy": 0, - "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, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "depends_on": "eval:doc.fieldtype===\"Section Break\"", + "fieldname": "collapsible", + "fieldtype": "Check", + "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": "Collapsible", + "length": 255, + "no_copy": 0, + "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, - "depends_on": "eval:doc.fieldtype==\"Section Break\"", - "fieldname": "collapsible_depends_on", - "fieldtype": "Code", - "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": "Collapsible Depends On", - "length": 0, - "no_copy": 0, - "options": "JS", - "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, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "depends_on": "eval:doc.fieldtype==\"Section Break\"", + "fieldname": "collapsible_depends_on", + "fieldtype": "Code", + "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": "Collapsible Depends On", + "length": 0, + "no_copy": 0, + "options": "JS", + "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, - "fieldname": "column_break_6", - "fieldtype": "Column Break", - "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, - "length": 0, - "no_copy": 0, - "permlevel": 0, - "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, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "column_break_6", + "fieldtype": "Column Break", + "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, + "length": 0, + "no_copy": 0, + "permlevel": 0, + "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, - "description": "For Links, enter the DocType as range.\nFor Select, enter list of Options, each on a new line.", - "fieldname": "options", - "fieldtype": "Small Text", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Options", - "length": 0, - "no_copy": 0, - "oldfieldname": "options", - "oldfieldtype": "Text", - "permlevel": 0, - "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, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "description": "For Links, enter the DocType as range.\nFor Select, enter list of Options, each on a new line.", + "fieldname": "options", + "fieldtype": "Small Text", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 1, + "in_standard_filter": 0, + "label": "Options", + "length": 0, + "no_copy": 0, + "oldfieldname": "options", + "oldfieldtype": "Text", + "permlevel": 0, + "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, - "fieldname": "default", - "fieldtype": "Small Text", - "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": "Default", - "length": 0, - "no_copy": 0, - "oldfieldname": "default", - "oldfieldtype": "Text", - "permlevel": 0, - "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, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "default", + "fieldtype": "Small Text", + "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": "Default", + "length": 0, + "no_copy": 0, + "oldfieldname": "default", + "oldfieldtype": "Text", + "permlevel": 0, + "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, - "fieldname": "fetch_from", - "fieldtype": "Small Text", - "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": "Fetch From", - "length": 0, - "no_copy": 0, - "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, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "fetch_from", + "fieldtype": "Small Text", + "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": "Fetch From", + "length": 0, + "no_copy": 0, + "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, - "fieldname": "permissions", - "fieldtype": "Section Break", - "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": "Permissions", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "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, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "permissions", + "fieldtype": "Section Break", + "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": "Permissions", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "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, - "fieldname": "depends_on", - "fieldtype": "Code", - "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": "Display Depends On", - "length": 255, - "no_copy": 0, - "oldfieldname": "depends_on", - "oldfieldtype": "Data", - "options": "JS", - "permlevel": 0, - "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, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "depends_on", + "fieldtype": "Code", + "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": "Display Depends On", + "length": 255, + "no_copy": 0, + "oldfieldname": "depends_on", + "oldfieldtype": "Data", + "options": "JS", + "permlevel": 0, + "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, - "fieldname": "hidden", - "fieldtype": "Check", - "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": "Hidden", - "length": 0, - "no_copy": 0, - "oldfieldname": "hidden", - "oldfieldtype": "Check", - "permlevel": 0, - "print_hide": 0, - "print_hide_if_no_value": 0, - "print_width": "50px", - "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, + "fieldname": "hidden", + "fieldtype": "Check", + "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": "Hidden", + "length": 0, + "no_copy": 0, + "oldfieldname": "hidden", + "oldfieldtype": "Check", + "permlevel": 0, + "print_hide": 0, + "print_hide_if_no_value": 0, + "print_width": "50px", + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, + "unique": 0, "width": "50px" - }, + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "read_only", - "fieldtype": "Check", - "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": "Read Only", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "print_hide": 0, - "print_hide_if_no_value": 0, - "print_width": "50px", - "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, + "fieldname": "read_only", + "fieldtype": "Check", + "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": "Read Only", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "print_hide": 0, + "print_hide_if_no_value": 0, + "print_width": "50px", + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, + "unique": 0, "width": "50px" - }, + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "unique", - "fieldtype": "Check", - "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": "Unique", - "length": 0, - "no_copy": 0, - "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, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "unique", + "fieldtype": "Check", + "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": "Unique", + "length": 0, + "no_copy": 0, + "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, - "description": "Do not allow user to change after set the first time", - "fieldname": "set_only_once", - "fieldtype": "Check", - "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": "Set Only Once", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "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, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "description": "Do not allow user to change after set the first time", + "fieldname": "set_only_once", + "fieldtype": "Check", + "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": "Set Only Once", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "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, - "depends_on": "eval: doc.fieldtype == \"Table\"", - "fieldname": "allow_bulk_edit", - "fieldtype": "Check", - "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": "Allow Bulk Edit", - "length": 0, - "no_copy": 0, - "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, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "depends_on": "eval: doc.fieldtype == \"Table\"", + "fieldname": "allow_bulk_edit", + "fieldtype": "Check", + "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": "Allow Bulk Edit", + "length": 0, + "no_copy": 0, + "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, - "fieldname": "column_break_13", - "fieldtype": "Column Break", - "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, - "length": 0, - "no_copy": 0, - "permlevel": 0, - "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, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "column_break_13", + "fieldtype": "Column Break", + "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, + "length": 0, + "no_copy": 0, + "permlevel": 0, + "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": "0", - "fieldname": "permlevel", - "fieldtype": "Int", - "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": "Perm Level", - "length": 0, - "no_copy": 0, - "oldfieldname": "permlevel", - "oldfieldtype": "Int", - "permlevel": 0, - "print_hide": 0, - "print_hide_if_no_value": 0, - "print_width": "50px", - "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": "0", + "fieldname": "permlevel", + "fieldtype": "Int", + "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": "Perm Level", + "length": 0, + "no_copy": 0, + "oldfieldname": "permlevel", + "oldfieldtype": "Int", + "permlevel": 0, + "print_hide": 0, + "print_hide_if_no_value": 0, + "print_width": "50px", + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, + "unique": 0, "width": "50px" - }, + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "description": "User permissions should not apply for this Link", - "fieldname": "ignore_user_permissions", - "fieldtype": "Check", - "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": "Ignore User Permissions", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "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, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "description": "User permissions should not apply for this Link", + "fieldname": "ignore_user_permissions", + "fieldtype": "Check", + "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": "Ignore User Permissions", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "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, - "depends_on": "eval: parent.is_submittable", - "fieldname": "allow_on_submit", - "fieldtype": "Check", - "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": "Allow on Submit", - "length": 0, - "no_copy": 0, - "oldfieldname": "allow_on_submit", - "oldfieldtype": "Check", - "permlevel": 0, - "print_hide": 0, - "print_hide_if_no_value": 0, - "print_width": "50px", - "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, + "depends_on": "eval: parent.is_submittable", + "fieldname": "allow_on_submit", + "fieldtype": "Check", + "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": "Allow on Submit", + "length": 0, + "no_copy": 0, + "oldfieldname": "allow_on_submit", + "oldfieldtype": "Check", + "permlevel": 0, + "print_hide": 0, + "print_hide_if_no_value": 0, + "print_width": "50px", + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, + "unique": 0, "width": "50px" - }, + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "report_hide", - "fieldtype": "Check", - "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": "Report Hide", - "length": 0, - "no_copy": 0, - "oldfieldname": "report_hide", - "oldfieldtype": "Check", - "permlevel": 0, - "print_hide": 0, - "print_hide_if_no_value": 0, - "print_width": "50px", - "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, + "fieldname": "report_hide", + "fieldtype": "Check", + "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": "Report Hide", + "length": 0, + "no_copy": 0, + "oldfieldname": "report_hide", + "oldfieldtype": "Check", + "permlevel": 0, + "print_hide": 0, + "print_hide_if_no_value": 0, + "print_width": "50px", + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, + "unique": 0, "width": "50px" - }, + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "eval:(doc.fieldtype == 'Link')", - "fieldname": "remember_last_selected_value", - "fieldtype": "Check", - "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": "Remember Last Selected Value", - "length": 0, - "no_copy": 0, - "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, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "depends_on": "eval:(doc.fieldtype == 'Link')", + "fieldname": "remember_last_selected_value", + "fieldtype": "Check", + "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": "Remember Last Selected Value", + "length": 0, + "no_copy": 0, + "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, - "description": "Don't HTML Encode HTML tags like <script> or just characters like < or >, as they could be intentionally used in this field", - "fieldname": "ignore_xss_filter", - "fieldtype": "Check", - "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": "Ignore XSS Filter", - "length": 0, - "no_copy": 0, - "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, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "description": "Don't HTML Encode HTML tags like <script> or just characters like < or >, as they could be intentionally used in this field", + "fieldname": "ignore_xss_filter", + "fieldtype": "Check", + "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": "Ignore XSS Filter", + "length": 0, + "no_copy": 0, + "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, - "fieldname": "display", - "fieldtype": "Section Break", - "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": "Display", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "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, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "display", + "fieldtype": "Section Break", + "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": "Display", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "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, - "fieldname": "in_filter", - "fieldtype": "Check", - "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": "In Filter", - "length": 0, - "no_copy": 0, - "oldfieldname": "in_filter", - "oldfieldtype": "Check", - "permlevel": 0, - "print_hide": 0, - "print_hide_if_no_value": 0, - "print_width": "50px", - "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, + "fieldname": "in_filter", + "fieldtype": "Check", + "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": "In Filter", + "length": 0, + "no_copy": 0, + "oldfieldname": "in_filter", + "oldfieldtype": "Check", + "permlevel": 0, + "print_hide": 0, + "print_hide_if_no_value": 0, + "print_width": "50px", + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, + "unique": 0, "width": "50px" - }, + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "no_copy", - "fieldtype": "Check", - "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": "No Copy", - "length": 0, - "no_copy": 0, - "oldfieldname": "no_copy", - "oldfieldtype": "Check", - "permlevel": 0, - "print_hide": 0, - "print_hide_if_no_value": 0, - "print_width": "50px", - "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, + "fieldname": "no_copy", + "fieldtype": "Check", + "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": "No Copy", + "length": 0, + "no_copy": 0, + "oldfieldname": "no_copy", + "oldfieldtype": "Check", + "permlevel": 0, + "print_hide": 0, + "print_hide_if_no_value": 0, + "print_width": "50px", + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, + "unique": 0, "width": "50px" - }, + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "print_hide", - "fieldtype": "Check", - "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": "Print Hide", - "length": 0, - "no_copy": 0, - "oldfieldname": "print_hide", - "oldfieldtype": "Check", - "permlevel": 0, - "print_hide": 0, - "print_hide_if_no_value": 0, - "print_width": "50px", - "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, + "fieldname": "print_hide", + "fieldtype": "Check", + "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": "Print Hide", + "length": 0, + "no_copy": 0, + "oldfieldname": "print_hide", + "oldfieldtype": "Check", + "permlevel": 0, + "print_hide": 0, + "print_hide_if_no_value": 0, + "print_width": "50px", + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, + "unique": 0, "width": "50px" - }, + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "eval:[\"Int\", \"Float\", \"Currency\", \"Percent\"].indexOf(doc.fieldtype)!==-1", - "fieldname": "print_hide_if_no_value", - "fieldtype": "Check", - "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": "Print Hide If No Value", - "length": 0, - "no_copy": 0, - "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, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "depends_on": "eval:[\"Int\", \"Float\", \"Currency\", \"Percent\"].indexOf(doc.fieldtype)!==-1", + "fieldname": "print_hide_if_no_value", + "fieldtype": "Check", + "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": "Print Hide If No Value", + "length": 0, + "no_copy": 0, + "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, - "fieldname": "print_width", - "fieldtype": "Data", - "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": "Print Width", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "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, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "print_width", + "fieldtype": "Data", + "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": "Print Width", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "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, - "fieldname": "width", - "fieldtype": "Data", - "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": "Width", - "length": 0, - "no_copy": 0, - "oldfieldname": "width", - "oldfieldtype": "Data", - "permlevel": 0, - "print_hide": 0, - "print_hide_if_no_value": 0, - "print_width": "50px", - "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, + "fieldname": "width", + "fieldtype": "Data", + "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": "Width", + "length": 0, + "no_copy": 0, + "oldfieldname": "width", + "oldfieldtype": "Data", + "permlevel": 0, + "print_hide": 0, + "print_hide_if_no_value": 0, + "print_width": "50px", + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, + "unique": 0, "width": "50px" - }, + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "", - "description": "Number of columns for a field in a List View or a Grid (Total Columns should be less than 11)", - "fieldname": "columns", - "fieldtype": "Int", - "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": "Columns", - "length": 0, - "no_copy": 0, - "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, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "depends_on": "", + "description": "Number of columns for a field in a List View or a Grid (Total Columns should be less than 11)", + "fieldname": "columns", + "fieldtype": "Int", + "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": "Columns", + "length": 0, + "no_copy": 0, + "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, - "fieldname": "column_break_22", - "fieldtype": "Column Break", - "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, - "length": 0, - "no_copy": 0, - "permlevel": 0, - "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, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "column_break_22", + "fieldtype": "Column Break", + "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, + "length": 0, + "no_copy": 0, + "permlevel": 0, + "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, - "fieldname": "description", - "fieldtype": "Small Text", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Description", - "length": 0, - "no_copy": 0, - "oldfieldname": "description", - "oldfieldtype": "Text", - "permlevel": 0, - "print_hide": 0, - "print_hide_if_no_value": 0, - "print_width": "300px", - "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, + "fieldname": "description", + "fieldtype": "Small Text", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 1, + "in_standard_filter": 0, + "label": "Description", + "length": 0, + "no_copy": 0, + "oldfieldname": "description", + "oldfieldtype": "Text", + "permlevel": 0, + "print_hide": 0, + "print_hide_if_no_value": 0, + "print_width": "300px", + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, + "unique": 0, "width": "300px" - }, + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "oldfieldname", - "fieldtype": "Data", - "hidden": 1, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "length": 0, - "no_copy": 0, - "oldfieldname": "oldfieldname", - "oldfieldtype": "Data", - "permlevel": 0, - "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, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "oldfieldname", + "fieldtype": "Data", + "hidden": 1, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "length": 0, + "no_copy": 0, + "oldfieldname": "oldfieldname", + "oldfieldtype": "Data", + "permlevel": 0, + "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, - "fieldname": "oldfieldtype", - "fieldtype": "Data", - "hidden": 1, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "length": 0, - "no_copy": 0, - "oldfieldname": "oldfieldtype", - "oldfieldtype": "Data", - "permlevel": 0, - "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, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "oldfieldtype", + "fieldtype": "Data", + "hidden": 1, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "length": 0, + "no_copy": 0, + "oldfieldname": "oldfieldtype", + "oldfieldtype": "Data", + "permlevel": 0, + "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 } - ], - "has_web_view": 0, - "hide_heading": 0, - "hide_toolbar": 0, - "idx": 1, - "image_view": 0, - "in_create": 0, - "is_submittable": 0, - "issingle": 0, - "istable": 1, - "max_attachments": 0, - "modified": "2018-11-13 11:44:37.455236", - "modified_by": "Administrator", - "module": "Core", - "name": "DocField", - "owner": "Administrator", - "permissions": [], - "quick_entry": 0, - "read_only": 0, - "read_only_onload": 0, - "show_name_in_global_search": 0, - "sort_order": "ASC", - "track_changes": 0, - "track_seen": 0, + ], + "has_web_view": 0, + "hide_heading": 0, + "hide_toolbar": 0, + "idx": 1, + "image_view": 0, + "in_create": 0, + "is_submittable": 0, + "issingle": 0, + "istable": 1, + "max_attachments": 0, + "modified": "2018-12-19 18:31:44.809413", + "modified_by": "Administrator", + "module": "Core", + "name": "DocField", + "owner": "Administrator", + "permissions": [], + "quick_entry": 0, + "read_only": 0, + "read_only_onload": 0, + "show_name_in_global_search": 0, + "sort_order": "ASC", + "track_changes": 0, + "track_seen": 0, "track_views": 0 } \ No newline at end of file diff --git a/frappe/core/doctype/docshare/test_docshare.py b/frappe/core/doctype/docshare/test_docshare.py index 10986d9eae..697930d6b5 100644 --- a/frappe/core/doctype/docshare/test_docshare.py +++ b/frappe/core/doctype/docshare/test_docshare.py @@ -1,6 +1,7 @@ # Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors # See license.txt +from __future__ import unicode_literals import frappe import frappe.share import unittest diff --git a/frappe/core/doctype/doctype/doctype.py b/frappe/core/doctype/doctype/doctype.py index 76af094ecf..ce252c2d70 100644 --- a/frappe/core/doctype/doctype/doctype.py +++ b/frappe/core/doctype/doctype/doctype.py @@ -10,7 +10,7 @@ import frappe from frappe import _ from frappe.utils import now, cint -from frappe.model import no_value_fields, default_fields, data_fieldtypes +from frappe.model import no_value_fields, default_fields, data_fieldtypes, table_fields from frappe.model.document import Document from frappe.custom.doctype.property_setter.property_setter import make_property_setter from frappe.desk.notifications import delete_notification_count_for @@ -82,7 +82,7 @@ class DocType(Document): if not [d.fieldname for d in self.fields if d.in_list_view]: cnt = 0 for d in self.fields: - if d.reqd and not d.hidden and not d.fieldtype == "Table": + if d.reqd and not d.hidden and not d.fieldtype in table_fields: d.in_list_view = 1 cnt += 1 if cnt == 4: break @@ -171,7 +171,8 @@ class DocType(Document): """Change the timestamp of parent DocType if the current one is a child to clear caches.""" if frappe.flags.in_import: return - parent_list = frappe.db.get_all('DocField', 'parent', dict(fieldtype='Table', options=self.name)) + parent_list = frappe.db.get_all('DocField', 'parent', + dict(fieldtype=['in', frappe.model.table_fields], options=self.name)) for p in parent_list: frappe.db.sql('UPDATE `tabDocType` SET modified=%s WHERE `name`=%s', (now(), p.parent)) @@ -511,11 +512,11 @@ def validate_fields(meta): validate_column_length(fieldname) def check_illegal_mandatory(d): - if (d.fieldtype in no_value_fields) and d.fieldtype!="Table" and d.reqd: + if (d.fieldtype in no_value_fields) and d.fieldtype not in table_fields and d.reqd: frappe.throw(_("Field {0} of type {1} cannot be mandatory").format(d.label, d.fieldtype)) def check_link_table_options(d): - if d.fieldtype in ("Link", "Table"): + if d.fieldtype in ("Link",) + table_fields: if not d.options: frappe.throw(_("Options required for Link or Table type field {0} in row {1}").format(d.label, d.idx)) if d.options=="[Select]" or d.options==d.parent: @@ -692,6 +693,19 @@ def validate_fields(meta): re.match("""[\w\.:_]+\s*={1}\s*[\w\.@'"]+""", depends_on): frappe.throw(_("Invalid {0} condition").format(frappe.unscrub(field)), frappe.ValidationError) + def check_table_multiselect_option(docfield): + '''check if the doctype provided in Option has atleast 1 Link field''' + if not docfield.fieldtype == 'Table MultiSelect': return + + doctype = docfield.options + meta = frappe.get_meta(doctype) + link_field = [df for df in meta.fields if df.fieldtype == 'Link'] + + if not link_field: + frappe.throw(_('DocType {0} provided for the field {1} must have atleast one Link field') + .format(doctype, docfield.fieldname), frappe.ValidationError) + + fields = meta.get("fields") fieldname_list = [d.fieldname for d in fields] @@ -702,7 +716,7 @@ def validate_fields(meta): for d in fields: if not d.permlevel: d.permlevel = 0 - if d.fieldtype != "Table": d.allow_bulk_edit = 0 + if d.fieldtype not in table_fields: d.allow_bulk_edit = 0 if d.fieldtype == "Barcode": d.ignore_xss_filter = 1 if not d.fieldname: d.fieldname = d.fieldname.lower() @@ -719,6 +733,7 @@ def validate_fields(meta): check_illegal_default(d) check_unique_and_text(d) check_illegal_depends_on_conditions(d) + check_table_multiselect_option(d) check_fold(fields) check_search_fields(meta, fields) diff --git a/frappe/core/doctype/file/file.py b/frappe/core/doctype/file/file.py index 4e3f07f669..2ab6fcda28 100755 --- a/frappe/core/doctype/file/file.py +++ b/frappe/core/doctype/file/file.py @@ -94,7 +94,7 @@ class File(NestedSet): self.validate_file_name() self.validate_folder() - if not self.flags.ignore_file_validate: + if not self.file_url and not self.flags.ignore_file_validate: if not self.is_folder: self.validate_file() self.generate_content_hash() @@ -386,9 +386,11 @@ class File(NestedSet): elif file_path.startswith("/files/"): file_path = get_files_path(*file_path.split("/files/", 1)[1].split("/")) + elif file_path.startswith("http"): pass - else: + + elif not self.file_url: frappe.throw(_("There is some problem with the file url: {0}").format(file_path)) return file_path @@ -817,12 +819,9 @@ def download_file(file_url): """ file_doc = frappe.get_doc("File", {"file_url": file_url}) file_doc.check_permission("read") - path = os.path.join(get_files_path(), os.path.basename(file_url)) - with open(path, "rb") as fileobj: - filedata = fileobj.read() frappe.local.response.filename = os.path.basename(file_url) - frappe.local.response.filecontent = filedata + frappe.local.response.filecontent = file_doc.get_content() frappe.local.response.type = "download" def extract_images_from_doc(doc, fieldname): diff --git a/frappe/core/doctype/prepared_report/prepared_report.py b/frappe/core/doctype/prepared_report/prepared_report.py index 893e3aec03..1cd106dabd 100644 --- a/frappe/core/doctype/prepared_report/prepared_report.py +++ b/frappe/core/doctype/prepared_report/prepared_report.py @@ -65,8 +65,8 @@ def create_json_gz_file(data, dt, dn): "file_name": json_filename, "attached_to_doctype": dt, "attached_to_name": dn, - "content": compressed_content, - "decode": True}) + "content": compressed_content + }) _file.save() @frappe.whitelist() diff --git a/frappe/core/doctype/report/report.json b/frappe/core/doctype/report/report.json index ce7b4b7d51..4c8b77de5f 100644 --- a/frappe/core/doctype/report/report.json +++ b/frappe/core/doctype/report/report.json @@ -1,5 +1,6 @@ { "allow_copy": 0, + "allow_events_in_timeline": 0, "allow_guest_to_view": 0, "allow_import": 0, "allow_rename": 0, @@ -42,7 +43,7 @@ "search_index": 0, "set_only_once": 0, "translatable": 0, - "unique": 0 + "unique": 1 }, { "allow_bulk_edit": 0, @@ -562,7 +563,7 @@ "bold": 0, "collapsible": 0, "columns": 0, - "fieldname": "prepared_report", + "fieldname": "disable_prepared_report", "fieldtype": "Check", "hidden": 0, "ignore_user_permissions": 0, @@ -571,15 +572,47 @@ "in_global_search": 0, "in_list_view": 0, "in_standard_filter": 0, + "label": "Disable Prepared Report", + "length": 0, + "no_copy": 0, + "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, + "fieldname": "prepared_report", + "fieldtype": "Check", + "hidden": 1, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, "label": "Prepared Report", "length": 0, "no_copy": 0, - "options": "Yes\nNo", + "options": "", "permlevel": 0, "precision": "", "print_hide": 0, "print_hide_if_no_value": 0, - "read_only": 0, + "read_only": 1, "remember_last_selected_value": 0, "report_hide": 0, "reqd": 0, @@ -600,7 +633,7 @@ "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2018-06-27 14:48:49.989952", + "modified": "2019-01-25 12:04:50.833264", "modified_by": "Administrator", "module": "Core", "name": "Report", diff --git a/frappe/core/doctype/report/report.py b/frappe/core/doctype/report/report.py index 11a42fbc2f..87c14c6651 100644 --- a/frappe/core/doctype/report/report.py +++ b/frappe/core/doctype/report/report.py @@ -118,14 +118,16 @@ class Report(Document): if fieldtype and '/' in fieldtype: fieldtype, options = fieldtype.split('/') - columns.append(frappe._dict(label=parts[0], fieldtype=fieldtype, fieldname=parts[0])) + columns.append(frappe._dict(label=parts[0], fieldtype=fieldtype, fieldname=parts[0], options=options)) out += data.get('result') else: # standard report params = json.loads(self.json) - if params.get('columns'): + if params.get('fields'): + columns = params.get('fields') + elif params.get('columns'): columns = params.get('columns') elif params.get('fields'): columns = params.get('fields') @@ -165,6 +167,7 @@ class Report(Document): user=user) _columns = [] + for column in columns: meta = frappe.get_meta(column[1]) field = [meta.get_field(column[0]) or frappe._dict(label=meta.get_label(column[0]), fieldname=column[0])] @@ -192,3 +195,8 @@ class Report(Document): @Document.whitelist def toggle_disable(self, disable): self.db_set("disabled", cint(disable)) + +@frappe.whitelist() +def is_prepared_report_disabled(report): + return frappe.db.get_value('Report', + report, 'disable_prepared_report') or 0 diff --git a/frappe/core/doctype/role_permission_for_page_and_report/role_permission_for_page_and_report.js b/frappe/core/doctype/role_permission_for_page_and_report/role_permission_for_page_and_report.js index 02fcf94a7b..fa807792fa 100644 --- a/frappe/core/doctype/role_permission_for_page_and_report/role_permission_for_page_and_report.js +++ b/frappe/core/doctype/role_permission_for_page_and_report/role_permission_for_page_and_report.js @@ -9,10 +9,14 @@ frappe.ui.form.on('Role Permission for Page and Report', { refresh: function(frm) { frm.disable_save(); frm.role_area.hide(); - frm.add_custom_button(__("Reset to defaults"), - function(){ frm.trigger("reset_roles") }); - frm.add_custom_button(__("Update"), - function(){ frm.trigger("update_roles") }).addClass('btn-primary'); + + frm.add_custom_button(__("Reset to defaults"), function() { + frm.trigger("reset_roles"); + }); + + frm.add_custom_button(__("Update"), function() { + frm.trigger("update_report_page_data"); + }).addClass('btn-primary'); }, onload: function(frm) { @@ -45,22 +49,22 @@ frappe.ui.form.on('Role Permission for Page and Report', { page: function(frm) { if(frm.doc.page) { - frm.trigger("get_roles") + frm.trigger("set_report_page_data"); } }, report: function(frm){ if(frm.doc.report) { - frm.trigger("get_roles") + frm.trigger("set_report_page_data"); } }, - get_roles: function(frm) { + set_report_page_data: function(frm) { frm.toggle_display('roles_html', true) frm.role_area.show(); return frm.call({ - method:"get_custom_roles", + method:"set_report_page_data", doc: frm.doc, callback: function(r) { refresh_field('roles') @@ -69,14 +73,14 @@ frappe.ui.form.on('Role Permission for Page and Report', { }) }, - update_roles: function(frm) { + update_report_page_data: function(frm) { frm.trigger("validate_mandatory_fields") if(frm.roles_editor) { frm.roles_editor.set_roles_in_table() } return frm.call({ - method:"set_custom_roles", + method:"update_report_page_data", doc: frm.doc, callback: function(r) { refresh_field('roles') diff --git a/frappe/core/doctype/role_permission_for_page_and_report/role_permission_for_page_and_report.json b/frappe/core/doctype/role_permission_for_page_and_report/role_permission_for_page_and_report.json index 0c21a5748b..8a5393b872 100644 --- a/frappe/core/doctype/role_permission_for_page_and_report/role_permission_for_page_and_report.json +++ b/frappe/core/doctype/role_permission_for_page_and_report/role_permission_for_page_and_report.json @@ -1,5 +1,6 @@ { "allow_copy": 1, + "allow_events_in_timeline": 0, "allow_guest_to_view": 0, "allow_import": 0, "allow_rename": 0, @@ -13,6 +14,8 @@ "engine": "InnoDB", "fields": [ { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -24,7 +27,7 @@ "ignore_xss_filter": 0, "in_filter": 0, "in_global_search": 0, - "in_list_view": 0, + "in_list_view": 1, "in_standard_filter": 0, "label": "Set Role For", "length": 0, @@ -40,9 +43,12 @@ "reqd": 1, "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, @@ -71,9 +77,12 @@ "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, @@ -102,9 +111,77 @@ "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, + "fieldname": "column_break_4", + "fieldtype": "Column Break", + "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, + "length": 0, + "no_copy": 0, + "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, + "depends_on": "report", + "fetch_from": "", + "fieldname": "disable_prepared_report", + "fieldtype": "Check", + "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": "Disable Prepared Report", + "length": 0, + "no_copy": 0, + "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, @@ -131,9 +208,12 @@ "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, @@ -161,9 +241,12 @@ "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, @@ -191,6 +274,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 } ], @@ -204,7 +288,7 @@ "issingle": 1, "istable": 0, "max_attachments": 0, - "modified": "2017-03-11 02:35:32.369043", + "modified": "2019-01-25 12:08:57.250719", "modified_by": "Administrator", "module": "Core", "name": "Role Permission for Page and Report", @@ -213,7 +297,6 @@ "permissions": [ { "amend": 0, - "apply_user_permissions": 0, "cancel": 0, "create": 1, "delete": 1, @@ -239,5 +322,6 @@ "sort_field": "modified", "sort_order": "DESC", "track_changes": 0, - "track_seen": 0 + "track_seen": 0, + "track_views": 0 } \ No newline at end of file diff --git a/frappe/core/doctype/role_permission_for_page_and_report/role_permission_for_page_and_report.py b/frappe/core/doctype/role_permission_for_page_and_report/role_permission_for_page_and_report.py index f05e187972..d7462d1d95 100644 --- a/frappe/core/doctype/role_permission_for_page_and_report/role_permission_for_page_and_report.py +++ b/frappe/core/doctype/role_permission_for_page_and_report/role_permission_for_page_and_report.py @@ -4,10 +4,15 @@ from __future__ import unicode_literals import frappe +from frappe.core.doctype.report.report import is_prepared_report_disabled from frappe.model.document import Document class RolePermissionforPageandReport(Document): - def get_custom_roles(self): + def set_report_page_data(self): + self.set_custom_roles() + self.check_prepared_report_disabled() + + def set_custom_roles(self): args = self.get_args() self.set('roles', []) @@ -19,7 +24,11 @@ class RolePermissionforPageandReport(Document): roles = self.get_standard_roles() self.set('roles', roles) - + + def check_prepared_report_disabled(self): + if self.report: + self.disable_prepared_report = is_prepared_report_disabled(self.report) + def get_standard_roles(self): doctype = self.set_role_for docname = self.page if self.set_role_for == 'Page' else self.report @@ -29,9 +38,14 @@ class RolePermissionforPageandReport(Document): def reset_roles(self): roles = self.get_standard_roles() self.set('roles', roles) - self.set_custom_roles() + self.update_custom_roles() + self.update_disable_prepared_report() - def set_custom_roles(self): + def update_report_page_data(self): + self.update_custom_roles() + self.update_disable_prepared_report() + + def update_custom_roles(self): args = self.get_args() name = frappe.db.get_value('Custom Role', args, "name") @@ -50,6 +64,10 @@ class RolePermissionforPageandReport(Document): else: frappe.get_doc(args).insert() + def update_disable_prepared_report(self): + if self.report: + frappe.db.set_value('Report', self.report, 'disable_prepared_report', self.disable_prepared_report) + def get_args(self, row=None): name = self.page if self.set_role_for == 'Page' else self.report check_for_field = self.set_role_for.replace(" ","_").lower() diff --git a/frappe/core/doctype/system_settings/system_settings.json b/frappe/core/doctype/system_settings/system_settings.json index 1da13ee88b..cf317edc42 100644 --- a/frappe/core/doctype/system_settings/system_settings.json +++ b/frappe/core/doctype/system_settings/system_settings.json @@ -1624,7 +1624,7 @@ "issingle": 1, "istable": 0, "max_attachments": 0, - "modified": "2018-10-01 17:35:13.043855", + "modified": "2019-01-30 11:02:41.011412", "modified_by": "Administrator", "module": "Core", "name": "System Settings", diff --git a/frappe/core/doctype/transaction_log/readme.md b/frappe/core/doctype/transaction_log/readme.md new file mode 100644 index 0000000000..09162ef4f0 --- /dev/null +++ b/frappe/core/doctype/transaction_log/readme.md @@ -0,0 +1,16 @@ +# Transaction Log Changelog + +## v1.0.0 +Initial version + +The line hash summarizes: +- The index of the row +- The timestamp +- The document raw data + +The chain hash summarizes: +- The previous line hash +- The current line hash + +## v1.0.1 +Modification of the timestamp fieldtype from "Time" to "Datetime" \ No newline at end of file diff --git a/frappe/core/doctype/transaction_log/transaction_log.json b/frappe/core/doctype/transaction_log/transaction_log.json index 55aa73b781..aa4ab4d473 100644 --- a/frappe/core/doctype/transaction_log/transaction_log.json +++ b/frappe/core/doctype/transaction_log/transaction_log.json @@ -1,5 +1,6 @@ { "allow_copy": 0, + "allow_events_in_timeline": 0, "allow_guest_to_view": 0, "allow_import": 0, "allow_rename": 0, @@ -178,7 +179,7 @@ "collapsible": 0, "columns": 0, "fieldname": "timestamp", - "fieldtype": "Time", + "fieldtype": "Datetime", "hidden": 0, "ignore_user_permissions": 0, "ignore_xss_filter": 0, @@ -436,7 +437,7 @@ "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2018-09-21 08:49:07.915376", + "modified": "2018-12-27 15:22:34.533766", "modified_by": "Administrator", "module": "Core", "name": "Transaction Log", diff --git a/frappe/core/doctype/transaction_log/transaction_log.py b/frappe/core/doctype/transaction_log/transaction_log.py index 245b953f73..b7ea6cac60 100644 --- a/frappe/core/doctype/transaction_log/transaction_log.py +++ b/frappe/core/doctype/transaction_log/transaction_log.py @@ -6,14 +6,14 @@ from __future__ import unicode_literals import frappe from frappe import _ from frappe.model.document import Document -from frappe.utils import now, cint +from frappe.utils import cint, now_datetime import hashlib class TransactionLog(Document): def before_insert(self): index = get_current_index() self.row_index = index - self.timestamp = now() + self.timestamp = now_datetime() if index != 1: prev_hash = frappe.db.sql( "SELECT `chaining_hash` FROM `tabTransaction Log` WHERE `row_index` = '{0}'".format(index - 1)) @@ -25,7 +25,7 @@ class TransactionLog(Document): self.previous_hash = self.hash_line() self.transaction_hash = self.hash_line() self.chaining_hash = self.hash_chain() - self.checksum_version = "v1.0.0" + self.checksum_version = "v1.0.1" def hash_line(self): sha = hashlib.sha256() diff --git a/frappe/core/doctype/user/user.py b/frappe/core/doctype/user/user.py index ead7883447..b191496c73 100644 --- a/frappe/core/doctype/user/user.py +++ b/frappe/core/doctype/user/user.py @@ -891,10 +891,9 @@ def get_active_website_users(): def get_permission_query_conditions(user): if user=="Administrator": return "" - else: return """(`tabUser`.name not in ({standard_users}))""".format( - standard_users='"' + '", "'.join(STANDARD_USERS) + '"') + standard_users = ", ".join(frappe.db.escape(user) for user in STANDARD_USERS)) def has_permission(doc, user): if (user != "Administrator") and (doc.name in STANDARD_USERS): @@ -932,7 +931,7 @@ def handle_password_test_fail(result): suggestions = result['feedback']['suggestions'][0] if result['feedback']['suggestions'] else '' warning = result['feedback']['warning'] if 'warning' in result['feedback'] else '' suggestions += "
" + _("Hint: Include symbols, numbers and capital letters in the password") + '
' - frappe.throw(_('Invalid Password: ' + ' '.join([warning, suggestions]))) + frappe.throw(' '.join([_('Invalid Password:'), warning, suggestions])) def update_gravatar(name): gravatar = has_gravatar(name) diff --git a/frappe/core/doctype/user_permission/user_permission.py b/frappe/core/doctype/user_permission/user_permission.py index e82a5c7c35..f8099cac38 100644 --- a/frappe/core/doctype/user_permission/user_permission.py +++ b/frappe/core/doctype/user_permission/user_permission.py @@ -56,10 +56,10 @@ def get_user_permissions(user=None): if not out.get(perm.allow): out[perm.allow] = [] - out[perm.allow].append({ + out[perm.allow].append(frappe._dict({ 'doc': doc_name, 'applicable_for': perm.get('applicable_for') - }) + })) try: for perm in frappe.get_all('User Permission', @@ -74,6 +74,7 @@ def get_user_permissions(user=None): for doc in decendants: add_doc_to_perm(perm, doc) + out = frappe._dict(out) frappe.cache().hset("user_permissions", user, out) except frappe.db.SQLError: if frappe.db.is_table_missing(): @@ -94,6 +95,7 @@ def get_applicable_for_doctype_list(doctype, txt, searchfield, start, page_len, linked_doctypes = get_linked_doctypes(doctype, True).keys() linked_doctypes = list(linked_doctypes) linked_doctypes += [doctype] + if txt: linked_doctypes = [d for d in linked_doctypes if txt in d.lower()] @@ -108,3 +110,13 @@ def get_applicable_for_doctype_list(doctype, txt, searchfield, start, page_len, def get_permitted_documents(doctype): return [d.get('doc') for d in get_user_permissions().get(doctype, []) \ if d.get('doc')] + +@frappe.whitelist() +def clear_user_permissions(user, for_doctype): + frappe.only_for('System Manager') + + total = frappe.db.count('User Permission', filters = dict(user=user, allow=for_doctype)) + if total: + frappe.db.sql('DELETE FROM `tabUser Permission` WHERE `user`=%s AND `allow`=%s', (user, for_doctype)) + frappe.clear_cache() + return total diff --git a/frappe/core/doctype/user_permission/user_permission_list.js b/frappe/core/doctype/user_permission/user_permission_list.js new file mode 100644 index 0000000000..39a4648334 --- /dev/null +++ b/frappe/core/doctype/user_permission/user_permission_list.js @@ -0,0 +1,52 @@ +frappe.listview_settings['User Permission'] = { + onload: function(list_view) { + list_view.page.add_menu_item(__("Clear User Permissions"), () => { + const dialog = new frappe.ui.Dialog({ + title: __('Clear User Permissions'), + fields: [ + { + 'fieldname': 'user', + 'label': __('For User'), + 'fieldtype': 'Link', + 'options': 'User', + 'reqd': 1 + }, + { + 'fieldname': 'for_doctype', + 'label': __('For Document Type'), + 'fieldtype': 'Link', + 'options': 'DocType', + 'reqd': 1 + }, + ], + primary_action: (data) => { + // mandatory not filled + if (!data) return; + + frappe.confirm(__('Are you sure?'), () => { + frappe + .xcall('frappe.core.doctype.user_permission.user_permission.clear_user_permissions', data) + .then(data => { + dialog.hide(); + let message = ''; + if (data === 0) { + message = __('No records deleted'); + } else { + message = __('{0} records deleted', [data]); + } + frappe.show_alert({ + message, + indicator: 'green' + }); + list_view.refresh(); + }); + }); + + }, + primary_action_label: __('Clear') + }); + + dialog.show(); + }); + } +}; diff --git a/frappe/core/doctype/version/version.py b/frappe/core/doctype/version/version.py index 9d945fed11..28f3ea5364 100644 --- a/frappe/core/doctype/version/version.py +++ b/frappe/core/doctype/version/version.py @@ -7,7 +7,7 @@ from __future__ import unicode_literals import frappe, json from frappe.model.document import Document -from frappe.model import no_value_fields +from frappe.model import no_value_fields, table_fields class Version(Document): def set_diff(self, old, new): @@ -42,12 +42,12 @@ def get_diff(old, new, for_child=False): }''' out = frappe._dict(changed = [], added = [], removed = [], row_changed = []) for df in new.meta.fields: - if df.fieldtype in no_value_fields and df.fieldtype != 'Table': + if df.fieldtype in no_value_fields and df.fieldtype not in table_fields: continue old_value, new_value = old.get(df.fieldname), new.get(df.fieldname) - if df.fieldtype=='Table': + if df.fieldtype in table_fields: # make maps old_row_by_name, new_row_by_name = {}, {} for d in old_value: diff --git a/frappe/core/doctype/view_log/test_view_log.js b/frappe/core/doctype/view_log/test_view_log.js index b0694d47c2..b6de94fe56 100644 --- a/frappe/core/doctype/view_log/test_view_log.js +++ b/frappe/core/doctype/view_log/test_view_log.js @@ -2,15 +2,15 @@ // rename this file from _test_[name] to test_[name] to activate // and remove above this line -QUnit.test("test: View log", function (assert) { +QUnit.test("test: View Log", function (assert) { let done = assert.async(); // number of asserts assert.expect(1); frappe.run_serially([ - // insert a new View log - () => frappe.tests.make('View log', [ + // insert a new View Log + () => frappe.tests.make('View Log', [ // values to be set {key: 'value'} ]), diff --git a/frappe/core/doctype/view_log/test_view_log.py b/frappe/core/doctype/view_log/test_view_log.py index 7414c4962d..83967a39a4 100644 --- a/frappe/core/doctype/view_log/test_view_log.py +++ b/frappe/core/doctype/view_log/test_view_log.py @@ -6,7 +6,7 @@ from __future__ import unicode_literals import frappe import unittest -class TestViewlog(unittest.TestCase): +class TestViewLog(unittest.TestCase): def tearDown(self): frappe.set_user('Administrator') @@ -25,7 +25,7 @@ class TestViewlog(unittest.TestCase): # load the form getdoc('Event', ev.name) a = frappe.get_value( - doctype="View log", + doctype="View Log", filters={ "reference_doctype": "Event", "reference_name": ev.name diff --git a/frappe/core/doctype/view_log/view_log.js b/frappe/core/doctype/view_log/view_log.js index 4ec143061e..a8c95b01e8 100644 --- a/frappe/core/doctype/view_log/view_log.js +++ b/frappe/core/doctype/view_log/view_log.js @@ -1,7 +1,7 @@ // Copyright (c) 2018, Frappe Technologies and contributors // For license information, please see license.txt -frappe.ui.form.on('View log', { +frappe.ui.form.on('View Log', { refresh: function(frm) { } diff --git a/frappe/core/doctype/view_log/view_log.json b/frappe/core/doctype/view_log/view_log.json index 570ca07d42..cf9d2eb746 100644 --- a/frappe/core/doctype/view_log/view_log.json +++ b/frappe/core/doctype/view_log/view_log.json @@ -1,160 +1,161 @@ { - "allow_copy": 0, - "allow_guest_to_view": 0, - "allow_import": 0, - "allow_rename": 0, - "beta": 0, - "creation": "2018-05-27 02:20:11.193944", - "custom": 0, - "docstatus": 0, - "doctype": "DocType", - "document_type": "", - "editable_grid": 1, - "engine": "InnoDB", + "allow_copy": 0, + "allow_events_in_timeline": 0, + "allow_guest_to_view": 0, + "allow_import": 0, + "allow_rename": 0, + "beta": 0, + "creation": "2018-05-27 02:20:11.193944", + "custom": 0, + "docstatus": 0, + "doctype": "DocType", + "document_type": "", + "editable_grid": 1, + "engine": "InnoDB", "fields": [ { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "viewed_by", - "fieldtype": "Data", - "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": "Viewed By", - "length": 0, - "no_copy": 0, - "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": 1, - "translatable": 0, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "viewed_by", + "fieldtype": "Data", + "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": "Viewed By", + "length": 0, + "no_copy": 0, + "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": 1, + "translatable": 0, "unique": 0 - }, + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "reference_doctype", - "fieldtype": "Link", - "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": "Reference doctype", - "length": 0, - "no_copy": 0, - "options": "DocType", - "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": 1, - "translatable": 0, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "reference_doctype", + "fieldtype": "Link", + "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": "Reference doctype", + "length": 0, + "no_copy": 0, + "options": "DocType", + "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": 1, + "translatable": 0, "unique": 0 - }, + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "reference_name", - "fieldtype": "Dynamic Link", - "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": "Reference name", - "length": 0, - "no_copy": 0, - "options": "reference_doctype", - "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": 1, - "translatable": 0, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "reference_name", + "fieldtype": "Dynamic Link", + "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": "Reference name", + "length": 0, + "no_copy": 0, + "options": "reference_doctype", + "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": 1, + "translatable": 0, "unique": 0 } - ], - "has_web_view": 0, - "hide_heading": 0, - "hide_toolbar": 0, - "idx": 0, - "image_view": 0, - "in_create": 0, - "is_submittable": 0, - "issingle": 0, - "istable": 0, - "max_attachments": 0, - "modified": "2018-05-30 11:21:35.258019", - "modified_by": "shridhar.p@zerodha.com", - "module": "Core", - "name": "View log", - "name_case": "", - "owner": "shridhar.p@zerodha.com", + ], + "has_web_view": 0, + "hide_heading": 0, + "hide_toolbar": 0, + "idx": 0, + "image_view": 0, + "in_create": 0, + "is_submittable": 0, + "issingle": 0, + "istable": 0, + "max_attachments": 0, + "modified": "2019-01-03 13:04:31.389182", + "modified_by": "Administrator", + "module": "Core", + "name": "View Log", + "name_case": "", + "owner": "Administrator", "permissions": [ { - "amend": 0, - "cancel": 0, - "create": 0, - "delete": 0, - "email": 1, - "export": 1, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "System Manager", - "set_user_permissions": 0, - "share": 1, - "submit": 0, + "amend": 0, + "cancel": 0, + "create": 0, + "delete": 0, + "email": 1, + "export": 1, + "if_owner": 0, + "import": 0, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "System Manager", + "set_user_permissions": 0, + "share": 1, + "submit": 0, "write": 0 } - ], - "quick_entry": 1, - "read_only": 0, - "read_only_onload": 0, - "show_name_in_global_search": 0, - "sort_field": "modified", - "sort_order": "DESC", - "track_changes": 1, - "track_seen": 0, + ], + "quick_entry": 1, + "read_only": 0, + "read_only_onload": 0, + "show_name_in_global_search": 0, + "sort_field": "modified", + "sort_order": "DESC", + "track_changes": 1, + "track_seen": 0, "track_views": 0 } \ No newline at end of file diff --git a/frappe/core/doctype/view_log/view_log.py b/frappe/core/doctype/view_log/view_log.py index 711f5a6cdd..45e98e37c7 100644 --- a/frappe/core/doctype/view_log/view_log.py +++ b/frappe/core/doctype/view_log/view_log.py @@ -6,5 +6,5 @@ from __future__ import unicode_literals import frappe from frappe.model.document import Document -class Viewlog(Document): +class ViewLog(Document): pass diff --git a/frappe/core/report/transaction_log_report/transaction_log_report.js b/frappe/core/report/transaction_log_report/transaction_log_report.js index 8bd37672c8..54ecf3fcf1 100644 --- a/frappe/core/report/transaction_log_report/transaction_log_report.js +++ b/frappe/core/report/transaction_log_report/transaction_log_report.js @@ -1,7 +1,11 @@ -// Copyright (c) 2016, Frappe Technologies and contributors +// Copyright (c) 2019, Frappe Technologies and contributors // For license information, please see license.txt /* eslint-disable */ frappe.query_reports["Transaction Log Report"] = { - + onload: function(query_report) { + query_report.add_make_chart_button = function() { + // + }; + } } diff --git a/frappe/core/report/transaction_log_report/transaction_log_report.json b/frappe/core/report/transaction_log_report/transaction_log_report.json index c858d51427..6d6fb78360 100644 --- a/frappe/core/report/transaction_log_report/transaction_log_report.json +++ b/frappe/core/report/transaction_log_report/transaction_log_report.json @@ -6,7 +6,7 @@ "doctype": "Report", "idx": 0, "is_standard": "Yes", - "modified": "2018-06-29 15:46:46.884862", + "modified": "2018-12-27 18:10:29.785415", "modified_by": "Administrator", "module": "Core", "name": "Transaction Log Report", @@ -18,6 +18,9 @@ "roles": [ { "role": "Administrator" + }, + { + "role": "System Manager" } ] } \ No newline at end of file diff --git a/frappe/core/report/transaction_log_report/transaction_log_report.py b/frappe/core/report/transaction_log_report/transaction_log_report.py index 2a6839d40c..9d84901f22 100644 --- a/frappe/core/report/transaction_log_report/transaction_log_report.py +++ b/frappe/core/report/transaction_log_report/transaction_log_report.py @@ -1,10 +1,11 @@ -# Copyright (c) 2013, Frappe Technologies and contributors +# Copyright (c) 2019, Frappe Technologies and contributors # For license information, please see license.txt from __future__ import unicode_literals import frappe import hashlib from frappe import _ +from frappe.utils import format_datetime def execute(filters=None): columns, data = get_columns(filters), get_data(filters) @@ -24,9 +25,9 @@ def get_data(filters=None): else: integrity = check_data_integrity(l.chaining_hash, l.transaction_hash, l.previous_hash, previous_hash[0][0]) - result.append([str(integrity), l.reference_doctype, l.document_name, l.owner, l.modified_by, l.timestamp]) + result.append([_(str(integrity)), _(l.reference_doctype), l.document_name, l.owner, l.modified_by, format_datetime(l.timestamp, "YYYYMMDDHHmmss")]) else: - result.append([_("First Transaction"), l.reference_doctype, l.document_name, l.owner, l.modified_by, l.timestamp]) + result.append([_("First Transaction"), _(l.reference_doctype), l.document_name, l.owner, l.modified_by, format_datetime(l.timestamp, "YYYYMMDDHHmmss")]) return result diff --git a/frappe/core/utils.py b/frappe/core/utils.py index 89aba20cd8..e4c349da93 100644 --- a/frappe/core/utils.py +++ b/frappe/core/utils.py @@ -1,8 +1,9 @@ # Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors # MIT License. See license.txt +from __future__ import unicode_literals import frappe -from frappe import _ + def get_parent_doc(doc): """Returns document of `reference_doctype`, `reference_doctype`""" diff --git a/frappe/core/web_form/edit_profile/edit_profile.json b/frappe/core/web_form/edit_profile/edit_profile.json index 1752284845..7072584670 100644 --- a/frappe/core/web_form/edit_profile/edit_profile.json +++ b/frappe/core/web_form/edit_profile/edit_profile.json @@ -18,7 +18,7 @@ "is_standard": 1, "login_required": 1, "max_attachment_size": 0, - "modified": "2018-11-01 19:35:43.552429", + "modified": "2019-01-28 12:45:17.158069", "modified_by": "Administrator", "module": "Core", "name": "edit-profile", @@ -129,19 +129,6 @@ "read_only": 0, "reqd": 0, "show_in_filter": 0 - }, - { - "allow_read_on_all_link_options": 0, - "fieldname": "roles", - "fieldtype": "Table", - "hidden": 0, - "label": "Roles Assigned", - "max_length": 0, - "max_value": 0, - "options": "Has Role", - "read_only": 0, - "reqd": 0, - "show_in_filter": 0 } ] } \ No newline at end of file diff --git a/frappe/custom/doctype/custom_field/custom_field.js b/frappe/custom/doctype/custom_field/custom_field.js index c430d12752..c59fabeaa6 100644 --- a/frappe/custom/doctype/custom_field/custom_field.js +++ b/frappe/custom/doctype/custom_field/custom_field.js @@ -9,6 +9,9 @@ frappe.ui.form.on('Custom Field', { frm.set_query('dt', function(doc) { var filters = [ ['DocType', 'issingle', '=', 0], + ['DocType', 'custom', '=', 0], + ['DocType', 'name', 'not in', frappe.model.core_doctypes_list], + ['DocType', 'restrict_to_domain', 'in', frappe.boot.active_domains] ]; if(frappe.session.user!=="Administrator") { filters.push(['DocType', 'module', 'not in', ['Core', 'Custom']]) @@ -32,15 +35,21 @@ frappe.ui.form.on('Custom Field', { return frappe.call({ method: 'frappe.custom.doctype.custom_field.custom_field.get_fields_label', args: { doctype: frm.doc.dt, fieldname: frm.doc.fieldname }, - callback: function(r, rt) { - set_field_options('insert_after', r.message); - var fieldnames = $.map(r.message, function(v) { return v.value; }); + callback: function(r) { + if(r) { + if(r._server_messages && r._server_messages.length) { + frm.set_value("dt", ""); + } else { + set_field_options('insert_after', r.message); + var fieldnames = $.map(r.message, function(v) { return v.value; }); - if(insert_after==null || !in_list(fieldnames, insert_after)) { - insert_after = fieldnames[-1]; + if(insert_after==null || !in_list(fieldnames, insert_after)) { + insert_after = fieldnames[-1]; + } + + frm.set_value('insert_after', insert_after); + } } - - frm.set_value('insert_after', insert_after); } }); diff --git a/frappe/custom/doctype/custom_field/custom_field.json b/frappe/custom/doctype/custom_field/custom_field.json index 75186fe159..11ba382b22 100644 --- a/frappe/custom/doctype/custom_field/custom_field.json +++ b/frappe/custom/doctype/custom_field/custom_field.json @@ -234,7 +234,7 @@ "no_copy": 0, "oldfieldname": "fieldtype", "oldfieldtype": "Select", - "options": "Attach\nAttach Image\nBarcode\nButton\nCheck\nCode\nColor\nColumn Break\nCurrency\nData\nDate\nDatetime\nDynamic Link\nFloat\nGeolocation\nHTML\nImage\nInt\nLink\nLong Text\nMarkdown Editor\nPassword\nPercent\nRead Only\nSection Break\nSelect\nSmall Text\nTable\nText\nText Editor\nTime\nSignature", + "options": "Attach\nAttach Image\nBarcode\nButton\nCheck\nCode\nColor\nColumn Break\nCurrency\nData\nDate\nDatetime\nDynamic Link\nFloat\nGeolocation\nHTML\nImage\nInt\nLink\nLong Text\nMarkdown Editor\nPassword\nPercent\nRead Only\nSection Break\nSelect\nSmall Text\nTable\nTable MultiSelect\nText\nText Editor\nTime\nSignature", "permlevel": 0, "print_hide": 0, "print_hide_if_no_value": 0, @@ -1302,7 +1302,7 @@ "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2018-11-23 19:56:43.328280", + "modified": "2018-12-19 18:34:46.031246", "modified_by": "Administrator", "module": "Custom", "name": "Custom Field", diff --git a/frappe/custom/doctype/custom_field/custom_field.py b/frappe/custom/doctype/custom_field/custom_field.py index 361680af44..356a571adc 100644 --- a/frappe/custom/doctype/custom_field/custom_field.py +++ b/frappe/custom/doctype/custom_field/custom_field.py @@ -8,6 +8,7 @@ from frappe.utils import cstr from frappe import _ from frappe.model.document import Document from frappe.model.docfield import supports_translation +from frappe.model import core_doctypes_list class CustomField(Document): def autoname(self): @@ -85,6 +86,14 @@ class CustomField(Document): @frappe.whitelist() def get_fields_label(doctype=None): + meta = frappe.get_meta(doctype) + + if doctype in core_doctypes_list: + return frappe.msgprint(_("Custom Fields cannot be added to core DocTypes.")) + + if meta.custom: + return frappe.msgprint(_("Custom Fields can only be added to a standard DocType.")) + return [{"value": df.fieldname or "", "label": _(df.label or "")} for df in frappe.get_meta(doctype).get("fields")] diff --git a/frappe/custom/doctype/customize_form/customize_form.js b/frappe/custom/doctype/customize_form/customize_form.js index 227c6de1ee..125db507ea 100644 --- a/frappe/custom/doctype/customize_form/customize_form.js +++ b/frappe/custom/doctype/customize_form/customize_form.js @@ -13,9 +13,7 @@ frappe.ui.form.on("Customize Form", { filters: [ ['DocType', 'issingle', '=', 0], ['DocType', 'custom', '=', 0], - ['DocType', 'name', 'not in', 'DocType, DocField, DocPerm, User, Role, Has Role, \ - Page, Has Role, Module Def, Print Format, Report, Customize Form, \ - Customize Form Field, Property Setter, Custom Field, Custom Script'], + ['DocType', 'name', 'not in', frappe.model.core_doctypes_list], ['DocType', 'restrict_to_domain', 'in', frappe.boot.active_domains] ] }; @@ -39,8 +37,14 @@ frappe.ui.form.on("Customize Form", { doc: frm.doc, freeze: true, callback: function(r) { - frm.refresh(); - frm.trigger("setup_sortable"); + if(r) { + if(r._server_messages && r._server_messages.length) { + frm.set_value("doc_type", ""); + } else { + frm.refresh(); + frm.trigger("setup_sortable"); + } + } } }); } else { diff --git a/frappe/custom/doctype/customize_form/customize_form.py b/frappe/custom/doctype/customize_form/customize_form.py index 3a6b606852..974dd84382 100644 --- a/frappe/custom/doctype/customize_form/customize_form.py +++ b/frappe/custom/doctype/customize_form/customize_form.py @@ -11,7 +11,7 @@ import frappe.translate from frappe import _ from frappe.utils import cint from frappe.model.document import Document -from frappe.model import no_value_fields +from frappe.model import no_value_fields, core_doctypes_list from frappe.core.doctype.doctype.doctype import validate_fields_for_doctype from frappe.model.docfield import supports_translation @@ -69,7 +69,7 @@ docfield_properties = { allowed_fieldtype_change = (('Currency', 'Float', 'Percent'), ('Small Text', 'Data'), ('Text', 'Data'), ('Text', 'Text Editor', 'Code', 'Signature', 'HTML Editor'), ('Data', 'Select'), - ('Text', 'Small Text'), ('Text', 'Data', 'Barcode'), ('Code', 'Geolocation')) + ('Text', 'Small Text'), ('Text', 'Data', 'Barcode'), ('Code', 'Geolocation'), ('Table', 'Table MultiSelect')) allowed_fieldtype_for_options_change = ('Read Only', 'HTML', 'Select', 'Data') @@ -85,6 +85,12 @@ class CustomizeForm(Document): meta = frappe.get_meta(self.doc_type) + if self.doc_type in core_doctypes_list: + return frappe.msgprint(_("Core DocTypes cannot be customized.")) + + if meta.custom: + return frappe.msgprint(_("Only standard DocTypes are allowed to be customized from Customize Form.")) + # doctype properties for property in doctype_properties: self.set(property, meta.get(property)) diff --git a/frappe/custom/doctype/customize_form/test_customize_form.py b/frappe/custom/doctype/customize_form/test_customize_form.py index f76fc52609..7da63f4d5d 100644 --- a/frappe/custom/doctype/customize_form/test_customize_form.py +++ b/frappe/custom/doctype/customize_form/test_customize_form.py @@ -9,28 +9,28 @@ from frappe.core.doctype.doctype.doctype import InvalidFieldNameError test_dependencies = ["Custom Field", "Property Setter"] class TestCustomizeForm(unittest.TestCase): def insert_custom_field(self): - frappe.delete_doc_if_exists("Custom Field", "User-test_custom_field") + frappe.delete_doc_if_exists("Custom Field", "Event-test_custom_field") frappe.get_doc({ "doctype": "Custom Field", - "dt": "User", + "dt": "Event", "label": "Test Custom Field", "description": "A Custom Field for Testing", "fieldtype": "Select", "in_list_view": 1, "options": "\nCustom 1\nCustom 2\nCustom 3", "default": "Custom 3", - "insert_after": frappe.get_meta('User').fields[-1].fieldname + "insert_after": frappe.get_meta('Event').fields[-1].fieldname }).insert() def setUp(self): self.insert_custom_field() frappe.db.commit() - frappe.clear_cache(doctype="User") + frappe.clear_cache(doctype="Event") def tearDown(self): - frappe.delete_doc("Custom Field", "User-test_custom_field") + frappe.delete_doc("Custom Field", "Event-test_custom_field") frappe.db.commit() - frappe.clear_cache(doctype="User") + frappe.clear_cache(doctype="Event") def get_customize_form(self, doctype=None): d = frappe.get_doc("Customize Form") @@ -45,78 +45,67 @@ class TestCustomizeForm(unittest.TestCase): self.assertEqual(len(d.get("fields")), 0) d = self.get_customize_form("Event") - self.assertEqual(d.doc_type, "Event") - self.assertEqual(len(d.get("fields")), 27) + self.assertEquals(d.doc_type, "Event") + self.assertEquals(len(d.get("fields")), 28) - d = self.get_customize_form("User") - self.assertEqual(d.doc_type, "User") + d = self.get_customize_form("Event") + self.assertEquals(d.doc_type, "Event") self.assertEqual(len(d.get("fields")), len(frappe.get_doc("DocType", d.doc_type).fields) + 1) - self.assertEqual(d.get("fields")[-1].fieldname, "test_custom_field") - self.assertEqual(d.get("fields", {"fieldname": "location"})[0].in_list_view, 1) + self.assertEquals(d.get("fields")[-1].fieldname, "test_custom_field") + self.assertEquals(d.get("fields", {"fieldname": "event_type"})[0].in_list_view, 1) return d def test_save_customization_property(self): - d = self.get_customize_form("User") - self.assertEqual(frappe.db.get_value("Property Setter", - {"doc_type": "User", "property": "allow_copy"}, "value"), None) + d = self.get_customize_form("Event") + self.assertEquals(frappe.db.get_value("Property Setter", + {"doc_type": "Event", "property": "allow_copy"}, "value"), None) d.allow_copy = 1 d.run_method("save_customization") - self.assertEqual(frappe.db.get_value("Property Setter", - {"doc_type": "User", "property": "allow_copy"}, "value"), '1') + self.assertEquals(frappe.db.get_value("Property Setter", + {"doc_type": "Event", "property": "allow_copy"}, "value"), '1') d.allow_copy = 0 d.run_method("save_customization") - self.assertEqual(frappe.db.get_value("Property Setter", - {"doc_type": "User", "property": "allow_copy"}, "value"), None) + self.assertEquals(frappe.db.get_value("Property Setter", + {"doc_type": "Event", "property": "allow_copy"}, "value"), None) def test_save_customization_field_property(self): - d = self.get_customize_form("User") - self.assertEqual(frappe.db.get_value("Property Setter", - {"doc_type": "User", "property": "reqd", "field_name": "location"}, "value"), None) + d = self.get_customize_form("Event") + self.assertEquals(frappe.db.get_value("Property Setter", + {"doc_type": "Event", "property": "reqd", "field_name": "repeat_this_event"}, "value"), None) - location_field = d.get("fields", {"fieldname": "location"})[0] - location_field.reqd = 1 + repeat_this_event_field = d.get("fields", {"fieldname": "repeat_this_event"})[0] + repeat_this_event_field.reqd = 1 d.run_method("save_customization") - self.assertEqual(frappe.db.get_value("Property Setter", - {"doc_type": "User", "property": "reqd", "field_name": "location"}, "value"), '1') + self.assertEquals(frappe.db.get_value("Property Setter", + {"doc_type": "Event", "property": "reqd", "field_name": "repeat_this_event"}, "value"), '1') - location_field = d.get("fields", {"fieldname": "location"})[0] - location_field.reqd = 0 + repeat_this_event_field = d.get("fields", {"fieldname": "repeat_this_event"})[0] + repeat_this_event_field.reqd = 0 d.run_method("save_customization") - self.assertEqual(frappe.db.get_value("Property Setter", - {"doc_type": "User", "property": "reqd", "field_name": "location"}, "value"), None) - - # for not allowing to change mandatory property of standard fields - self.assertEqual(frappe.db.get_value("Property Setter", - {"doc_type": "User", "property": "reqd", "field_name": "email"}, "value"), None) - - email_field = d.get("fields", {"fieldname": "email"})[0] - email_field.reqd = 0 - d.run_method("save_customization") - - self.assertEqual(frappe.db.get_value("Property Setter", - {"doc_type": "User", "property": "reqd", "field_name": "email"}, "value"), None) + self.assertEquals(frappe.db.get_value("Property Setter", + {"doc_type": "Event", "property": "reqd", "field_name": "repeat_this_event"}, "value"), None) def test_save_customization_custom_field_property(self): - d = self.get_customize_form("User") - self.assertEqual(frappe.db.get_value("Custom Field", "User-test_custom_field", "reqd"), 0) + d = self.get_customize_form("Event") + self.assertEquals(frappe.db.get_value("Custom Field", "Event-test_custom_field", "reqd"), 0) custom_field = d.get("fields", {"fieldname": "test_custom_field"})[0] custom_field.reqd = 1 d.run_method("save_customization") - self.assertEqual(frappe.db.get_value("Custom Field", "User-test_custom_field", "reqd"), 1) + self.assertEquals(frappe.db.get_value("Custom Field", "Event-test_custom_field", "reqd"), 1) custom_field = d.get("fields", {"is_custom_field": True})[0] custom_field.reqd = 0 d.run_method("save_customization") - self.assertEqual(frappe.db.get_value("Custom Field", "User-test_custom_field", "reqd"), 0) + self.assertEquals(frappe.db.get_value("Custom Field", "Event-test_custom_field", "reqd"), 0) def test_save_customization_new_field(self): - d = self.get_customize_form("User") + d = self.get_customize_form("Event") last_fieldname = d.fields[-1].fieldname d.append("fields", { "label": "Test Add Custom Field Via Customize Form", @@ -124,19 +113,19 @@ class TestCustomizeForm(unittest.TestCase): "is_custom_field": 1 }) d.run_method("save_customization") - self.assertEqual(frappe.db.get_value("Custom Field", - "User-test_add_custom_field_via_customize_form", "fieldtype"), "Data") + self.assertEquals(frappe.db.get_value("Custom Field", + "Event-test_add_custom_field_via_customize_form", "fieldtype"), "Data") - self.assertEqual(frappe.db.get_value("Custom Field", - "User-test_add_custom_field_via_customize_form", 'insert_after'), last_fieldname) + self.assertEquals(frappe.db.get_value("Custom Field", + "Event-test_add_custom_field_via_customize_form", 'insert_after'), last_fieldname) - frappe.delete_doc("Custom Field", "User-test_add_custom_field_via_customize_form") - self.assertEqual(frappe.db.get_value("Custom Field", - "User-test_add_custom_field_via_customize_form"), None) + frappe.delete_doc("Custom Field", "Event-test_add_custom_field_via_customize_form") + self.assertEquals(frappe.db.get_value("Custom Field", + "Event-test_add_custom_field_via_customize_form"), None) def test_save_customization_remove_field(self): - d = self.get_customize_form("User") + d = self.get_customize_form("Event") custom_field = d.get("fields", {"fieldname": "test_custom_field"})[0] d.get("fields").remove(custom_field) d.run_method("save_customization") @@ -148,24 +137,24 @@ class TestCustomizeForm(unittest.TestCase): def test_reset_to_defaults(self): d = frappe.get_doc("Customize Form") - d.doc_type = "User" + d.doc_type = "Event" d.run_method('reset_to_defaults') - self.assertEqual(d.get("fields", {"fieldname": "location"})[0].in_list_view, 0) + self.assertEquals(d.get("fields", {"fieldname": "repeat_this_event"})[0].in_list_view, 0) frappe.local.test_objects["Property Setter"] = [] make_test_records_for_doctype("Property Setter") def test_set_allow_on_submit(self): - d = self.get_customize_form("User") - d.get("fields", {"fieldname": "first_name"})[0].allow_on_submit = 1 + d = self.get_customize_form("Event") + d.get("fields", {"fieldname": "subject"})[0].allow_on_submit = 1 d.get("fields", {"fieldname": "test_custom_field"})[0].allow_on_submit = 1 d.run_method("save_customization") - d = self.get_customize_form("User") + d = self.get_customize_form("Event") # don't allow for standard fields - self.assertEqual(d.get("fields", {"fieldname": "first_name"})[0].allow_on_submit or 0, 0) + self.assertEquals(d.get("fields", {"fieldname": "subject"})[0].allow_on_submit or 0, 0) # allow for custom field self.assertEqual(d.get("fields", {"fieldname": "test_custom_field"})[0].allow_on_submit, 1) @@ -193,4 +182,12 @@ class TestCustomizeForm(unittest.TestCase): # undo df.default = None - d.run_method("save_customization") \ No newline at end of file + d.run_method("save_customization") + + def test_core_doctype_customization(self): + d = self.get_customize_form('User') + e = self.get_customize_form('Custom Field') + + # core doctype is invalid, hence no attributes are set + self.assertEquals(d.get("fields"), []) + self.assertEquals(e.get("fields"), []) diff --git a/frappe/custom/doctype/customize_form_field/customize_form_field.json b/frappe/custom/doctype/customize_form_field/customize_form_field.json index f103b2e47a..eab199f913 100644 --- a/frappe/custom/doctype/customize_form_field/customize_form_field.json +++ b/frappe/custom/doctype/customize_form_field/customize_form_field.json @@ -1,1364 +1,1364 @@ { - "allow_copy": 0, - "allow_events_in_timeline": 0, - "allow_guest_to_view": 0, - "allow_import": 0, - "allow_rename": 0, - "autoname": "hash", - "beta": 0, - "creation": "2013-02-22 01:27:32", - "custom": 0, - "docstatus": 0, - "doctype": "DocType", - "document_type": "Setup", - "editable_grid": 1, + "allow_copy": 0, + "allow_events_in_timeline": 0, + "allow_guest_to_view": 0, + "allow_import": 0, + "allow_rename": 0, + "autoname": "hash", + "beta": 0, + "creation": "2013-02-22 01:27:32", + "custom": 0, + "docstatus": 0, + "doctype": "DocType", + "document_type": "Setup", + "editable_grid": 1, "fields": [ { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "label_and_type", - "fieldtype": "Section Break", - "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": "Label and Type", - "length": 0, - "no_copy": 0, - "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, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "label_and_type", + "fieldtype": "Section Break", + "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": "Label and Type", + "length": 0, + "no_copy": 0, + "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, - "fieldname": "label", - "fieldtype": "Data", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Label", - "length": 0, - "no_copy": 0, - "oldfieldname": "label", - "oldfieldtype": "Data", - "permlevel": 0, - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 1, - "set_only_once": 0, - "translatable": 0, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "label", + "fieldtype": "Data", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 1, + "in_standard_filter": 0, + "label": "Label", + "length": 0, + "no_copy": 0, + "oldfieldname": "label", + "oldfieldtype": "Data", + "permlevel": 0, + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 1, + "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": "Data", - "fieldname": "fieldtype", - "fieldtype": "Select", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Type", - "length": 0, - "no_copy": 0, - "oldfieldname": "fieldtype", - "oldfieldtype": "Select", - "options": "Attach\nAttach Image\nBarcode\nButton\nCheck\nCode\nColor\nColumn Break\nCurrency\nData\nDate\nDatetime\nDynamic Link\nFloat\nFold\nGeolocation\nHeading\nHTML\nHTML Editor\nImage\nInt\nLink\nLong Text\nMarkdown Editor\nPassword\nPercent\nRead Only\nSection Break\nSelect\nSignature\nSmall Text\nTable\nText\nText Editor\nTime", - "permlevel": 0, - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 1, - "set_only_once": 0, - "translatable": 0, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "default": "Data", + "fieldname": "fieldtype", + "fieldtype": "Select", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 1, + "in_standard_filter": 0, + "label": "Type", + "length": 0, + "no_copy": 0, + "oldfieldname": "fieldtype", + "oldfieldtype": "Select", + "options": "Attach\nAttach Image\nBarcode\nButton\nCheck\nCode\nColor\nColumn Break\nCurrency\nData\nDate\nDatetime\nDynamic Link\nFloat\nFold\nGeolocation\nHeading\nHTML\nHTML Editor\nImage\nInt\nLink\nLong Text\nMarkdown Editor\nPassword\nPercent\nRead Only\nSection Break\nSelect\nSignature\nSmall Text\nTable\nTable MultiSelect\nText\nText Editor\nTime", + "permlevel": 0, + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 1, + "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, - "fieldname": "fieldname", - "fieldtype": "Data", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Name", - "length": 0, - "no_copy": 0, - "oldfieldname": "fieldname", - "oldfieldtype": "Data", - "permlevel": 0, - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 1, - "set_only_once": 0, - "translatable": 0, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "fieldname", + "fieldtype": "Data", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 1, + "in_standard_filter": 0, + "label": "Name", + "length": 0, + "no_copy": 0, + "oldfieldname": "fieldname", + "oldfieldtype": "Data", + "permlevel": 0, + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 1, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 1, + "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, - "fieldname": "reqd", - "fieldtype": "Check", - "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": "Mandatory", - "length": 0, - "no_copy": 0, - "oldfieldname": "reqd", - "oldfieldtype": "Check", - "permlevel": 0, - "print_hide": 0, - "print_hide_if_no_value": 0, - "print_width": "50px", - "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, + "fieldname": "reqd", + "fieldtype": "Check", + "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": "Mandatory", + "length": 0, + "no_copy": 0, + "oldfieldname": "reqd", + "oldfieldtype": "Check", + "permlevel": 0, + "print_hide": 0, + "print_hide_if_no_value": 0, + "print_width": "50px", + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, + "unique": 0, "width": "50px" - }, + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "unique", - "fieldtype": "Check", - "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": "Unique", - "length": 0, - "no_copy": 0, - "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, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "unique", + "fieldtype": "Check", + "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": "Unique", + "length": 0, + "no_copy": 0, + "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, - "fieldname": "in_list_view", - "fieldtype": "Check", - "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": "In List View", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "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, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "in_list_view", + "fieldtype": "Check", + "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": "In List View", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "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, - "fieldname": "in_standard_filter", - "fieldtype": "Check", - "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": "In Standard Filter", - "length": 0, - "no_copy": 0, - "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, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "in_standard_filter", + "fieldtype": "Check", + "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": "In Standard Filter", + "length": 0, + "no_copy": 0, + "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, - "depends_on": "eval:([\"Data\", \"Select\", \"Table\", \"Text\", \"Text Editor\", \"Link\", \"Small Text\", \"Long Text\", \"Read Only\", \"Heading\", \"Dynamic Link\"].indexOf(doc.fieldtype) !== -1)", - "fieldname": "in_global_search", - "fieldtype": "Check", - "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": "In Global Search", - "length": 0, - "no_copy": 0, - "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, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "depends_on": "eval:([\"Data\", \"Select\", \"Table\", \"Text\", \"Text Editor\", \"Link\", \"Small Text\", \"Long Text\", \"Read Only\", \"Heading\", \"Dynamic Link\"].indexOf(doc.fieldtype) !== -1)", + "fieldname": "in_global_search", + "fieldtype": "Check", + "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": "In Global Search", + "length": 0, + "no_copy": 0, + "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, - "fieldname": "bold", - "fieldtype": "Check", - "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": "Bold", - "length": 0, - "no_copy": 0, - "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, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "bold", + "fieldtype": "Check", + "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": "Bold", + "length": 0, + "no_copy": 0, + "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", - "depends_on": "eval:['Data', 'Select', 'Text', 'Small Text', 'Text Editor'].includes(doc.fieldtype)", - "fieldname": "translatable", - "fieldtype": "Check", - "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": "Translatable", - "length": 0, - "no_copy": 0, - "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, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "default": "1", + "depends_on": "eval:['Data', 'Select', 'Text', 'Small Text', 'Text Editor'].includes(doc.fieldtype)", + "fieldname": "translatable", + "fieldtype": "Check", + "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": "Translatable", + "length": 0, + "no_copy": 0, + "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, - "fieldname": "column_break_7", - "fieldtype": "Column Break", - "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, - "length": 0, - "no_copy": 0, - "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, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "column_break_7", + "fieldtype": "Column Break", + "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, + "length": 0, + "no_copy": 0, + "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, - "depends_on": "eval:in_list([\"Float\", \"Currency\", \"Percent\"], doc.fieldtype)", - "description": "Set non-standard precision for a Float or Currency field", - "fieldname": "precision", - "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": "Precision", - "length": 0, - "no_copy": 0, - "options": "\n1\n2\n3\n4\n5\n6\n7\n8\n9", - "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, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "depends_on": "eval:in_list([\"Float\", \"Currency\", \"Percent\"], doc.fieldtype)", + "description": "Set non-standard precision for a Float or Currency field", + "fieldname": "precision", + "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": "Precision", + "length": 0, + "no_copy": 0, + "options": "\n1\n2\n3\n4\n5\n6\n7\n8\n9", + "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, - "depends_on": "eval:in_list(['Data', 'Link', 'Dynamic Link', 'Password', 'Select', 'Read Only', 'Attach', 'Attach Image'], doc.fieldtype)", - "fieldname": "length", - "fieldtype": "Int", - "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": "Length", - "length": 0, - "no_copy": 0, - "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, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "depends_on": "eval:in_list(['Data', 'Link', 'Dynamic Link', 'Password', 'Select', 'Read Only', 'Attach', 'Attach Image'], doc.fieldtype)", + "fieldname": "length", + "fieldtype": "Int", + "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": "Length", + "length": 0, + "no_copy": 0, + "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, - "description": "For Links, enter the DocType as range.\nFor Select, enter list of Options, each on a new line.", - "fieldname": "options", - "fieldtype": "Small Text", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Options", - "length": 0, - "no_copy": 0, - "oldfieldname": "options", - "oldfieldtype": "Text", - "permlevel": 0, - "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, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "description": "For Links, enter the DocType as range.\nFor Select, enter list of Options, each on a new line.", + "fieldname": "options", + "fieldtype": "Small Text", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 1, + "in_standard_filter": 0, + "label": "Options", + "length": 0, + "no_copy": 0, + "oldfieldname": "options", + "oldfieldtype": "Text", + "permlevel": 0, + "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, - "fieldname": "fetch_from", - "fieldtype": "Small Text", - "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": "Fetch From", - "length": 0, - "no_copy": 0, - "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, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "fetch_from", + "fieldtype": "Small Text", + "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": "Fetch From", + "length": 0, + "no_copy": 0, + "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, - "fieldname": "permissions", - "fieldtype": "Section Break", - "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": "Permissions", - "length": 0, - "no_copy": 0, - "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, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "permissions", + "fieldtype": "Section Break", + "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": "Permissions", + "length": 0, + "no_copy": 0, + "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, - "description": "This field will appear only if the fieldname defined here has value OR the rules are true (examples): \nmyfield\neval:doc.myfield=='My Value'\neval:doc.age>18", - "fieldname": "depends_on", - "fieldtype": "Code", - "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": "Depends On", - "length": 0, - "no_copy": 0, - "oldfieldname": "depends_on", - "oldfieldtype": "Data", - "options": "JS", - "permlevel": 0, - "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, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "description": "This field will appear only if the fieldname defined here has value OR the rules are true (examples): \nmyfield\neval:doc.myfield=='My Value'\neval:doc.age>18", + "fieldname": "depends_on", + "fieldtype": "Code", + "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": "Depends On", + "length": 0, + "no_copy": 0, + "oldfieldname": "depends_on", + "oldfieldtype": "Data", + "options": "JS", + "permlevel": 0, + "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": "0", - "fieldname": "permlevel", - "fieldtype": "Int", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Perm Level", - "length": 0, - "no_copy": 0, - "oldfieldname": "permlevel", - "oldfieldtype": "Int", - "permlevel": 0, - "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, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "default": "0", + "fieldname": "permlevel", + "fieldtype": "Int", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 1, + "in_standard_filter": 0, + "label": "Perm Level", + "length": 0, + "no_copy": 0, + "oldfieldname": "permlevel", + "oldfieldtype": "Int", + "permlevel": 0, + "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, - "fieldname": "hidden", - "fieldtype": "Check", - "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": "Hidden", - "length": 0, - "no_copy": 0, - "oldfieldname": "hidden", - "oldfieldtype": "Check", - "permlevel": 0, - "print_hide": 0, - "print_hide_if_no_value": 0, - "print_width": "50px", - "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, + "fieldname": "hidden", + "fieldtype": "Check", + "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": "Hidden", + "length": 0, + "no_copy": 0, + "oldfieldname": "hidden", + "oldfieldtype": "Check", + "permlevel": 0, + "print_hide": 0, + "print_hide_if_no_value": 0, + "print_width": "50px", + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, + "unique": 0, "width": "50px" - }, + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "read_only", - "fieldtype": "Check", - "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": "Read Only", - "length": 0, - "no_copy": 0, - "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, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "read_only", + "fieldtype": "Check", + "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": "Read Only", + "length": 0, + "no_copy": 0, + "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, - "depends_on": "eval:doc.fieldtype==\"Section Break\"", - "fieldname": "collapsible", - "fieldtype": "Check", - "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": "Collapsible", - "length": 0, - "no_copy": 0, - "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, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "depends_on": "eval:doc.fieldtype==\"Section Break\"", + "fieldname": "collapsible", + "fieldtype": "Check", + "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": "Collapsible", + "length": 0, + "no_copy": 0, + "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, - "depends_on": "eval: doc.fieldtype == \"Table\"", - "fieldname": "allow_bulk_edit", - "fieldtype": "Check", - "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": "Allow Bulk Edit", - "length": 0, - "no_copy": 0, - "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, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "depends_on": "eval: doc.fieldtype == \"Table\"", + "fieldname": "allow_bulk_edit", + "fieldtype": "Check", + "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": "Allow Bulk Edit", + "length": 0, + "no_copy": 0, + "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, - "depends_on": "eval:doc.fieldtype==\"Section Break\"", - "fieldname": "collapsible_depends_on", - "fieldtype": "Code", - "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": "Collapsible Depends On", - "length": 0, - "no_copy": 0, - "options": "JS", - "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, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "depends_on": "eval:doc.fieldtype==\"Section Break\"", + "fieldname": "collapsible_depends_on", + "fieldtype": "Code", + "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": "Collapsible Depends On", + "length": 0, + "no_copy": 0, + "options": "JS", + "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, - "fieldname": "column_break_14", - "fieldtype": "Column Break", - "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, - "length": 0, - "no_copy": 0, - "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, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "column_break_14", + "fieldtype": "Column Break", + "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, + "length": 0, + "no_copy": 0, + "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, - "fieldname": "ignore_user_permissions", - "fieldtype": "Check", - "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": "Ignore User Permissions", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "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, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "ignore_user_permissions", + "fieldtype": "Check", + "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": "Ignore User Permissions", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "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, - "fieldname": "allow_on_submit", - "fieldtype": "Check", - "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": "Allow on Submit", - "length": 0, - "no_copy": 0, - "oldfieldname": "allow_on_submit", - "oldfieldtype": "Check", - "permlevel": 0, - "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, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "allow_on_submit", + "fieldtype": "Check", + "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": "Allow on Submit", + "length": 0, + "no_copy": 0, + "oldfieldname": "allow_on_submit", + "oldfieldtype": "Check", + "permlevel": 0, + "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, - "fieldname": "report_hide", - "fieldtype": "Check", - "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": "Report Hide", - "length": 0, - "no_copy": 0, - "oldfieldname": "report_hide", - "oldfieldtype": "Check", - "permlevel": 0, - "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, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "report_hide", + "fieldtype": "Check", + "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": "Report Hide", + "length": 0, + "no_copy": 0, + "oldfieldname": "report_hide", + "oldfieldtype": "Check", + "permlevel": 0, + "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, - "depends_on": "eval:(doc.fieldtype == 'Link')", - "fieldname": "remember_last_selected_value", - "fieldtype": "Check", - "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": "Remember Last Selected Value", - "length": 0, - "no_copy": 0, - "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, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "depends_on": "eval:(doc.fieldtype == 'Link')", + "fieldname": "remember_last_selected_value", + "fieldtype": "Check", + "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": "Remember Last Selected Value", + "length": 0, + "no_copy": 0, + "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, - "fieldname": "display", - "fieldtype": "Section Break", - "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": "Display", - "length": 0, - "no_copy": 0, - "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, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "display", + "fieldtype": "Section Break", + "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": "Display", + "length": 0, + "no_copy": 0, + "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, - "fieldname": "default", - "fieldtype": "Text", - "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": "Default", - "length": 0, - "no_copy": 0, - "oldfieldname": "default", - "oldfieldtype": "Text", - "permlevel": 0, - "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, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "default", + "fieldtype": "Text", + "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": "Default", + "length": 0, + "no_copy": 0, + "oldfieldname": "default", + "oldfieldtype": "Text", + "permlevel": 0, + "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, - "fieldname": "in_filter", - "fieldtype": "Check", - "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": "In Filter", - "length": 0, - "no_copy": 0, - "oldfieldname": "in_filter", - "oldfieldtype": "Check", - "permlevel": 0, - "print_hide": 0, - "print_hide_if_no_value": 0, - "print_width": "50px", - "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, + "fieldname": "in_filter", + "fieldtype": "Check", + "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": "In Filter", + "length": 0, + "no_copy": 0, + "oldfieldname": "in_filter", + "oldfieldtype": "Check", + "permlevel": 0, + "print_hide": 0, + "print_hide_if_no_value": 0, + "print_width": "50px", + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, + "unique": 0, "width": "50px" - }, + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "column_break_21", - "fieldtype": "Column Break", - "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, - "length": 0, - "no_copy": 0, - "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, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "column_break_21", + "fieldtype": "Column Break", + "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, + "length": 0, + "no_copy": 0, + "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, - "fieldname": "description", - "fieldtype": "Text", - "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": "Description", - "length": 0, - "no_copy": 0, - "oldfieldname": "description", - "oldfieldtype": "Text", - "permlevel": 0, - "print_hide": 0, - "print_hide_if_no_value": 0, - "print_width": "300px", - "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, + "fieldname": "description", + "fieldtype": "Text", + "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": "Description", + "length": 0, + "no_copy": 0, + "oldfieldname": "description", + "oldfieldtype": "Text", + "permlevel": 0, + "print_hide": 0, + "print_hide_if_no_value": 0, + "print_width": "300px", + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, + "unique": 0, "width": "300px" - }, + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "print_hide", - "fieldtype": "Check", - "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": "Print Hide", - "length": 0, - "no_copy": 0, - "oldfieldname": "print_hide", - "oldfieldtype": "Check", - "permlevel": 0, - "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, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "print_hide", + "fieldtype": "Check", + "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": "Print Hide", + "length": 0, + "no_copy": 0, + "oldfieldname": "print_hide", + "oldfieldtype": "Check", + "permlevel": 0, + "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, - "depends_on": "eval:[\"Int\", \"Float\", \"Currency\", \"Percent\"].indexOf(doc.fieldtype)!==-1", - "fieldname": "print_hide_if_no_value", - "fieldtype": "Check", - "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": "Print Hide If No Value", - "length": 0, - "no_copy": 0, - "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, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "depends_on": "eval:[\"Int\", \"Float\", \"Currency\", \"Percent\"].indexOf(doc.fieldtype)!==-1", + "fieldname": "print_hide_if_no_value", + "fieldtype": "Check", + "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": "Print Hide If No Value", + "length": 0, + "no_copy": 0, + "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, - "description": "Print Width of the field, if the field is a column in a table", - "fieldname": "print_width", - "fieldtype": "Data", - "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": "Print Width", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "print_hide": 0, - "print_hide_if_no_value": 0, - "print_width": "50px", - "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, + "description": "Print Width of the field, if the field is a column in a table", + "fieldname": "print_width", + "fieldtype": "Data", + "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": "Print Width", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "print_hide": 0, + "print_hide_if_no_value": 0, + "print_width": "50px", + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, + "unique": 0, "width": "50px" - }, + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "eval:cur_frm.doc.istable", - "description": "Number of columns for a field in a Grid (Total Columns in a grid should be less than 11)", - "fieldname": "columns", - "fieldtype": "Int", - "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": "Columns", - "length": 0, - "no_copy": 0, - "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, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "depends_on": "eval:cur_frm.doc.istable", + "description": "Number of columns for a field in a Grid (Total Columns in a grid should be less than 11)", + "fieldname": "columns", + "fieldtype": "Int", + "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": "Columns", + "length": 0, + "no_copy": 0, + "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, - "fieldname": "width", - "fieldtype": "Data", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Width", - "length": 0, - "no_copy": 0, - "oldfieldname": "width", - "oldfieldtype": "Data", - "permlevel": 0, - "print_hide": 0, - "print_hide_if_no_value": 0, - "print_width": "50px", - "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, + "fieldname": "width", + "fieldtype": "Data", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 1, + "in_standard_filter": 0, + "label": "Width", + "length": 0, + "no_copy": 0, + "oldfieldname": "width", + "oldfieldtype": "Data", + "permlevel": 0, + "print_hide": 0, + "print_hide_if_no_value": 0, + "print_width": "50px", + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, + "unique": 0, "width": "50px" - }, + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "is_custom_field", - "fieldtype": "Check", - "hidden": 1, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Is Custom Field", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "is_custom_field", + "fieldtype": "Check", + "hidden": 1, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Is Custom Field", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 1, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, "unique": 0 } - ], - "has_web_view": 0, - "hide_heading": 0, - "hide_toolbar": 0, - "idx": 1, - "image_view": 0, - "in_create": 0, - "is_submittable": 0, - "issingle": 0, - "istable": 1, - "max_attachments": 0, - "modified": "2018-11-13 11:46:36.069338", - "modified_by": "Administrator", - "module": "Custom", - "name": "Customize Form Field", - "owner": "Administrator", - "permissions": [], - "quick_entry": 0, - "read_only": 0, - "read_only_onload": 0, - "show_name_in_global_search": 0, - "sort_order": "ASC", - "track_changes": 0, - "track_seen": 0, + ], + "has_web_view": 0, + "hide_heading": 0, + "hide_toolbar": 0, + "idx": 1, + "image_view": 0, + "in_create": 0, + "is_submittable": 0, + "issingle": 0, + "istable": 1, + "max_attachments": 0, + "modified": "2018-12-19 18:32:06.435085", + "modified_by": "Administrator", + "module": "Custom", + "name": "Customize Form Field", + "owner": "Administrator", + "permissions": [], + "quick_entry": 0, + "read_only": 0, + "read_only_onload": 0, + "show_name_in_global_search": 0, + "sort_order": "ASC", + "track_changes": 0, + "track_seen": 0, "track_views": 0 } \ No newline at end of file diff --git a/frappe/custom/doctype/property_setter/property_setter.py b/frappe/custom/doctype/property_setter/property_setter.py index 2343e4bc44..d8ab5ede73 100644 --- a/frappe/custom/doctype/property_setter/property_setter.py +++ b/frappe/custom/doctype/property_setter/property_setter.py @@ -37,12 +37,16 @@ class PropertySetter(Document): and property = %(property)s""", self.get_valid_dict()) def get_property_list(self, dt): - return frappe.db.sql("""select fieldname, label, fieldtype - from tabDocField - where parent=%s - and fieldtype not in ('Section Break', 'Column Break', 'HTML', 'Read Only', 'Table', 'Fold') - and coalesce(fieldname, '') != '' - order by label asc""", dt, as_dict=1) + return frappe.db.get_all('DocField', + fields=['fieldname', 'label', 'fieldtype'], + filters={ + 'parent': dt, + 'fieldtype': ['not in', ('Section Break', 'Column Break', 'HTML', 'Read Only', 'Fold') + frappe.model.table_fields], + 'fieldname': ['!=', ''] + }, + order_by='label asc', + as_dict=1 + ) def get_setup_data(self): return { diff --git a/frappe/data_migration/doctype/data_migration_connector/connectors/base.py b/frappe/data_migration/doctype/data_migration_connector/connectors/base.py index f500b4a7e8..97f9f5f4a3 100644 --- a/frappe/data_migration/doctype/data_migration_connector/connectors/base.py +++ b/frappe/data_migration/doctype/data_migration_connector/connectors/base.py @@ -1,3 +1,4 @@ +from __future__ import unicode_literals from six import with_metaclass from abc import ABCMeta, abstractmethod from frappe.utils.password import get_decrypted_password diff --git a/frappe/database/database.py b/frappe/database/database.py index 54b0af7deb..136e25cd93 100644 --- a/frappe/database/database.py +++ b/frappe/database/database.py @@ -18,6 +18,7 @@ from time import time from frappe.utils import now, getdate, cast_fieldtype from frappe.utils.background_jobs import execute_job, get_queue from frappe.model.utils.link_count import flush_local_link_count +from frappe.utils import cint # imports - compatibility imports from six import ( @@ -538,9 +539,9 @@ class Database(object): `tabSingles` where `doctype`=%s and `field`=%s""", (doctype, fieldname)) val = val[0][0] if val else None - if val=="0" or val=="1": - # check type - val = int(val) + df = frappe.get_meta(doctype).get_field(fieldname) + if df.fieldtype in frappe.model.numeric_fieldtypes: + val = cint(val) self.value_cache[doctype][fieldname] = val diff --git a/frappe/database/mariadb/framework_mariadb.sql b/frappe/database/mariadb/framework_mariadb.sql index 049fcaa2f8..1c2cb84153 100644 --- a/frappe/database/mariadb/framework_mariadb.sql +++ b/frappe/database/mariadb/framework_mariadb.sql @@ -103,7 +103,7 @@ CREATE TABLE `tabDocPerm` ( DROP TABLE IF EXISTS `tabDocType`; CREATE TABLE `tabDocType` ( - `name` varchar(255) NOT NULL DEFAULT '', + `name` varchar(255) NOT NULL, `creation` datetime(6) DEFAULT NULL, `modified` datetime(6) DEFAULT NULL, `modified_by` varchar(255) DEFAULT NULL, diff --git a/frappe/database/postgres/framework_postgres.sql b/frappe/database/postgres/framework_postgres.sql index 1b6cbf0947..abbfab8c8c 100644 --- a/frappe/database/postgres/framework_postgres.sql +++ b/frappe/database/postgres/framework_postgres.sql @@ -104,7 +104,7 @@ create index on "tabDocPerm" ("parent"); DROP TABLE IF EXISTS "tabDocType"; CREATE TABLE "tabDocType" ( - "name" varchar(255) NOT NULL DEFAULT '', + "name" varchar(255) NOT NULL, "creation" timestamp(6) DEFAULT NULL, "modified" timestamp(6) DEFAULT NULL, "modified_by" varchar(255) DEFAULT NULL, diff --git a/frappe/desk/doctype/desktop_icon/desktop_icon.py b/frappe/desk/doctype/desktop_icon/desktop_icon.py index c7b30c39be..175d1ece7d 100644 --- a/frappe/desk/doctype/desktop_icon/desktop_icon.py +++ b/frappe/desk/doctype/desktop_icon/desktop_icon.py @@ -307,7 +307,7 @@ def make_user_copy(module_name, user): 'module_name': module_name }) - for key in ('app', 'label', 'route', 'type', '_doctype', 'idx', 'reverse', 'force_show'): + for key in ('app', 'label', 'route', 'type', '_doctype', 'idx', 'reverse', 'force_show', 'link', 'icon', 'color'): if original.get(key): desktop_icon.set(key, original.get(key)) @@ -410,7 +410,7 @@ def get_user_icons(user): add = False if not icon.custom: - if icon.module_name=='Learn': + if icon.module_name==['Help', 'Settings']: pass elif icon.type=="page" and icon.link not in allowed_pages: diff --git a/frappe/desk/doctype/event/event.py b/frappe/desk/doctype/event/event.py index 7749f71e17..04f7455e2d 100644 --- a/frappe/desk/doctype/event/event.py +++ b/frappe/desk/doctype/event/event.py @@ -92,7 +92,6 @@ def get_permission_query_conditions(user): } def has_permission(doc, user): - frappe.log_error(doc.owner) if doc.event_type=="Public" or doc.owner==user: return True diff --git a/frappe/desk/doctype/kanban_board/kanban_board.py b/frappe/desk/doctype/kanban_board/kanban_board.py index 923ca8aa6b..f1ad41db6c 100644 --- a/frappe/desk/doctype/kanban_board/kanban_board.py +++ b/frappe/desk/doctype/kanban_board/kanban_board.py @@ -8,7 +8,6 @@ import json from frappe import _ from frappe.model.document import Document from six import iteritems -from frappe.custom.doctype.custom_field.custom_field import create_custom_field class KanbanBoard(Document): @@ -130,17 +129,8 @@ def update_order(board_name, order): @frappe.whitelist() def quick_kanban_board(doctype, board_name, field_name, project=None): '''Create new KanbanBoard quickly with default options''' + doc = frappe.new_doc('Kanban Board') - - if field_name == 'kanban_column': - create_custom_field(doctype, { - 'label': 'Kanban Column', - 'fieldname': 'kanban_column', - 'fieldtype': 'Select', - 'hidden': 1, - 'owner': 'Administrator' - }) - meta = frappe.get_meta(doctype) options = '' diff --git a/frappe/desk/doctype/note/test_note.py b/frappe/desk/doctype/note/test_note.py index 865527b5a0..8d46eaf336 100644 --- a/frappe/desk/doctype/note/test_note.py +++ b/frappe/desk/doctype/note/test_note.py @@ -1,6 +1,7 @@ # Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors and Contributors # See license.txt +from __future__ import unicode_literals import frappe import unittest diff --git a/frappe/desk/form/linked_with.py b/frappe/desk/form/linked_with.py index 2a43c9fc4f..734b99a003 100644 --- a/frappe/desk/form/linked_with.py +++ b/frappe/desk/form/linked_with.py @@ -42,9 +42,10 @@ def get_linked_docs(doctype, name, linkinfo=None, for_doctype=None): link_meta_bundle = frappe.desk.form.load.get_meta_bundle(dt) linkmeta = link_meta_bundle[0] if not linkmeta.get("issingle"): - fields = [d.fieldname for d in linkmeta.get("fields", {"in_list_view":1, - "fieldtype": ["not in", ["Image", "HTML", "Button", "Table"]]})] \ - + ["name", "modified", "docstatus"] + fields = [d.fieldname for d in linkmeta.get("fields", { + "in_list_view": 1, + "fieldtype": ["not in", ("Image", "HTML", "Button") + frappe.model.table_fields] + })] + ["name", "modified", "docstatus"] if link.get("add_fields"): fields += link["add_fields"] @@ -116,7 +117,7 @@ def _get_linked_doctypes(doctype, without_ignore_user_permissions_enabled=False) ret.update(get_linked_fields(doctype, without_ignore_user_permissions_enabled)) ret.update(get_dynamic_linked_fields(doctype, without_ignore_user_permissions_enabled)) - filters=[['fieldtype','=','Table'], ['options', '=', doctype]] + filters=[['fieldtype', 'in', frappe.model.table_fields], ['options', '=', doctype]] if without_ignore_user_permissions_enabled: filters.append(['ignore_user_permissions', '!=', 1]) # find links of parents links = frappe.get_all("DocField", fields=["parent as dt"], filters=filters) @@ -159,7 +160,7 @@ def get_linked_fields(doctype, without_ignore_user_permissions_enabled=False): for doctype_name in links_dict: ret[doctype_name] = { "fieldname": links_dict.get(doctype_name) } table_doctypes = frappe.get_all("DocType", filters=[["istable", "=", "1"], ["name", "in", tuple(links_dict)]]) - child_filters = [['fieldtype','=', 'Table'], ['options', 'in', tuple(doctype.name for doctype in table_doctypes)]] + child_filters = [['fieldtype','in', frappe.model.table_fields], ['options', 'in', tuple(doctype.name for doctype in table_doctypes)]] if without_ignore_user_permissions_enabled: child_filters.append(['ignore_user_permissions', '!=', 1]) # find out if linked in a child table diff --git a/frappe/desk/form/load.py b/frappe/desk/form/load.py index 2304eb9d31..0566a4d14b 100644 --- a/frappe/desk/form/load.py +++ b/frappe/desk/form/load.py @@ -80,7 +80,7 @@ def getdoctype(doctype, with_parent=False, cached_timestamp=None): def get_meta_bundle(doctype): bundle = [frappe.desk.form.meta.get_meta(doctype)] for df in bundle[0].fields: - if df.fieldtype=="Table": + if df.fieldtype in frappe.model.table_fields: bundle.append(frappe.desk.form.meta.get_meta(df.options, not frappe.conf.developer_mode)) return bundle @@ -219,11 +219,11 @@ def get_view_logs(doctype, docname): """ get and return the latest view logs if available """ logs = [] if hasattr(frappe.get_meta(doctype), 'track_views') and frappe.get_meta(doctype).track_views: - view_logs = frappe.get_all("View log", filters={ + view_logs = frappe.get_all("View Log", filters={ "reference_doctype": doctype, "reference_name": docname, - }, fields=["name", "creation"], order_by="creation desc") + }, fields=["name", "creation", "owner"], order_by="creation desc") - if view_logs: + if view_logs: logs = view_logs return logs diff --git a/frappe/desk/notifications.py b/frappe/desk/notifications.py index b3100a43da..43b67f2976 100644 --- a/frappe/desk/notifications.py +++ b/frappe/desk/notifications.py @@ -12,8 +12,15 @@ import json @frappe.whitelist() @frappe.read_only() def get_notifications(): - if frappe.flags.in_install: - return + if (frappe.flags.in_install or + not frappe.db.get_single_value('System Settings', 'setup_complete')): + return { + "open_count_doctype": {}, + "open_count_module": {}, + "open_count_other": {}, + "targets": {}, + "new_messages": [] + } config = get_notification_config() @@ -108,7 +115,8 @@ def get_notifications_for_doctypes(config, notification_count): except Exception as e: # OperationalError: (1412, 'Table definition has changed, please retry transaction') - if e.args[0]!=1412: + # InternalError: (1684, 'Table definition is being modified by concurrent DDL statement') + if e.args[0] not in (1412, 1684): raise else: @@ -148,7 +156,7 @@ def get_notifications_for_targets(config, notification_percent): frappe.clear_messages() pass except Exception as e: - if e.args[0]!=1412: + if e.args[0] not in (1412, 1684): raise else: diff --git a/frappe/desk/page/backups/backups.py b/frappe/desk/page/backups/backups.py index 2d493515b7..663ab37cff 100644 --- a/frappe/desk/page/backups/backups.py +++ b/frappe/desk/page/backups/backups.py @@ -1,3 +1,4 @@ +from __future__ import unicode_literals import os import frappe from frappe import _ diff --git a/frappe/desk/query_builder.py b/frappe/desk/query_builder.py index ef6240b8dd..81eba35e05 100644 --- a/frappe/desk/query_builder.py +++ b/frappe/desk/query_builder.py @@ -220,9 +220,6 @@ def runquery(q='', ret=0, from_export=0): def runquery_csv(): global out - # run query - res = runquery(from_export = 1) - q = frappe.form_dict.get('query') rep_name = frappe.form_dict.get('report_name') @@ -234,9 +231,6 @@ def runquery_csv(): if not rep_name: rep_name = 'DataExport' - # Headings - heads = [] - rows = [[rep_name], out['colnames']] + out['values'] from six import StringIO diff --git a/frappe/desk/query_report.py b/frappe/desk/query_report.py index 6d43ae5eb7..8954a9d36c 100644 --- a/frappe/desk/query_report.py +++ b/frappe/desk/query_report.py @@ -57,7 +57,7 @@ def generate_report_result(report, filters=None, user=None): module = report.module or frappe.db.get_value("DocType", report.ref_doctype, "module") if report.is_standard == "Yes": method_name = get_report_module_dotted_path(module, report.name) + ".execute" - threshold = 10 + threshold = 30 res = [] start_time = datetime.datetime.now() @@ -66,9 +66,13 @@ def generate_report_result(report, filters=None, user=None): end_time = datetime.datetime.now() - if (end_time - start_time).seconds > threshold and not report.prepared_report: + execution_time = (end_time - start_time).seconds + + if execution_time > threshold and not report.prepared_report: report.db_set('prepared_report', 1) + frappe.cache().hset('report_execution_time', report.name, execution_time) + columns, result = res[0], res[1] if len(res) > 2: message = res[2] @@ -89,7 +93,8 @@ def generate_report_result(report, filters=None, user=None): "message": message, "chart": chart, "data_to_be_printed": data_to_be_printed, - "status": status + "status": status, + "execution_time": frappe.cache().hget('report_execution_time', report.name) or 0 } @frappe.whitelist() @@ -147,7 +152,8 @@ def get_script(report_name): return { "script": render_include(script), - "html_format": html_format + "html_format": html_format, + "execution_time": frappe.cache().hget('report_execution_time', report_name) or 0 } @@ -164,7 +170,7 @@ def run(report_name, filters=None, user=None): result = None - if report.prepared_report: + if report.prepared_report and not report.disable_prepared_report: if filters: if isinstance(filters, string_types): filters = json.loads(filters) @@ -185,7 +191,9 @@ def run(report_name, filters=None, user=None): def get_prepared_report_result(report, filters, dn="", user=None): latest_report_data = {} # Only look for completed prepared reports with given filters. - doc_list = frappe.get_all("Prepared Report", filters={"status": "Completed", "report_name": report.name, "filters": json.dumps(filters), "owner": user}) + doc_list = frappe.get_all("Prepared Report", + filters={"status": "Completed", "report_name": report.name, "filters": filters, "owner": user}) + doc = None if len(doc_list): if dn: @@ -254,7 +262,7 @@ def export_query(): if row and (i in visible_idx): row_list = [] for idx in range(len(data.columns)): - row_list.append(row.get(columns[idx]["fieldname"],"")) + row_list.append(row.get(columns[idx]["fieldname"], row.get(columns[idx]["label"], ""))) result.append(row_list) elif not row: result.append([]) diff --git a/frappe/desk/reportview.py b/frappe/desk/reportview.py index 727bcc5e98..362f883581 100644 --- a/frappe/desk/reportview.py +++ b/frappe/desk/reportview.py @@ -42,7 +42,6 @@ def get_form_params(): else: data["save_user_settings"] = True - doctype = data["doctype"] fields = data["fields"] for field in fields: @@ -213,7 +212,7 @@ def delete_items(): """delete selected items""" import json - il = sorted(json.loads(frappe.form_dict.get('items')), reverse=True) + il = sorted(json.loads(frappe.form_dict.get('items')), reverse=True, key=frappe.safe_decode) doctype = frappe.form_dict.get('doctype') failed = [] diff --git a/frappe/email/doctype/auto_email_report/auto_email_report.py b/frappe/email/doctype/auto_email_report/auto_email_report.py index 3f09cd3cfb..a6d6ab2e71 100644 --- a/frappe/email/doctype/auto_email_report/auto_email_report.py +++ b/frappe/email/doctype/auto_email_report/auto_email_report.py @@ -74,6 +74,8 @@ class AutoEmailReport(Document): return None if self.format == 'HTML': + columns, data = make_links(columns, data) + return self.get_html_table(columns, data) elif self.format == 'XLSX': @@ -195,3 +197,15 @@ def send_monthly(): '''Check reports to be sent monthly''' for report in frappe.get_all('Auto Email Report', {'enabled': 1, 'frequency': 'Monthly'}): frappe.get_doc('Auto Email Report', report.name).send() + +def make_links(columns, data): + for row in data: + for col in columns: + if col.fieldtype == "Link" and col.options != "Currency": + if col.options and row[col.fieldname]: + row[col.fieldname] = get_link_to_form(col.options, row[col.fieldname]) + elif col.fieldtype == "Dynamic Link": + if col.options and row[col.fieldname]: + row[col.fieldname] = get_link_to_form(row[col.options], row[col.fieldname]) + + return columns, data diff --git a/frappe/email/doctype/auto_email_report/test_auto_email_report.py b/frappe/email/doctype/auto_email_report/test_auto_email_report.py index 70371965de..0595d9a43d 100644 --- a/frappe/email/doctype/auto_email_report/test_auto_email_report.py +++ b/frappe/email/doctype/auto_email_report/test_auto_email_report.py @@ -5,6 +5,7 @@ from __future__ import unicode_literals import frappe import unittest, json +from frappe.utils import get_link_to_form # test_records = frappe.get_test_records('Auto Email Report') @@ -25,8 +26,8 @@ class TestAutoEmailReport(unittest.TestCase): )).insert() data = auto_email_report.get_report_content() - self.assertTrue('DocShare' in data) - self.assertTrue('Core' in data) + + self.assertTrue(''+str(get_link_to_form('Module Def', 'Core'))+'' in data) auto_email_report.format = 'CSV' diff --git a/frappe/email/doctype/email_account/email_account.json b/frappe/email/doctype/email_account/email_account.json index 61167f9f63..5ab3cd1630 100644 --- a/frappe/email/doctype/email_account/email_account.json +++ b/frappe/email/doctype/email_account/email_account.json @@ -1130,6 +1130,39 @@ "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", + "fieldname": "no_smtp_authentication", + "fieldtype": "Check", + "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": "Disable SMTP server authentication", + "length": 0, + "no_copy": 0, + "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, @@ -1530,7 +1563,7 @@ "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2018-08-01 19:37:43.234891", + "modified": "2019-01-30 11:02:41.011412", "modified_by": "Administrator", "module": "Email", "name": "Email Account", @@ -1566,4 +1599,4 @@ "track_changes": 1, "track_seen": 0, "track_views": 0 -} \ No newline at end of file +} diff --git a/frappe/email/doctype/email_account/email_account.py b/frappe/email/doctype/email_account/email_account.py index f61ee02806..34cd3c24ee 100755 --- a/frappe/email/doctype/email_account/email_account.py +++ b/frappe/email/doctype/email_account/email_account.py @@ -72,7 +72,7 @@ class EmailAccount(Document): if self.enable_outgoing: self.check_smtp() else: - if self.enable_incoming or self.enable_outgoing: + if self.enable_incoming or (self.enable_outgoing and not self.no_smtp_authentication): frappe.throw(_("Password is required or select Awaiting Password")) if self.notify_if_unreplied: @@ -134,8 +134,9 @@ class EmailAccount(Document): port = cint(self.smtp_port), use_tls = cint(self.use_tls) ) - if self.password: + if self.password and not self.no_smtp_authentication: server.password = self.get_password() + server.sess def get_incoming_server(self, in_receive=False, email_sync_rule="UNSEEN"): diff --git a/frappe/email/doctype/email_account/test_email_account.py b/frappe/email/doctype/email_account/test_email_account.py index 849cb6b42c..f098a8b205 100644 --- a/frappe/email/doctype/email_account/test_email_account.py +++ b/frappe/email/doctype/email_account/test_email_account.py @@ -1,6 +1,7 @@ # Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors # See license.txt +from __future__ import unicode_literals import frappe, os import unittest, email diff --git a/frappe/email/doctype/email_queue/email_queue.json b/frappe/email/doctype/email_queue/email_queue.json index 15e87c65c9..fd47bb3c39 100644 --- a/frappe/email/doctype/email_queue/email_queue.json +++ b/frappe/email/doctype/email_queue/email_queue.json @@ -559,24 +559,55 @@ "set_only_once": 0, "translatable": 0, "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "default": "0", + "fieldname": "retry", + "fieldtype": "Int", + "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": "Retry", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 1, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 } - ], - "has_web_view": 0, - "hide_heading": 0, - "hide_toolbar": 0, - "icon": "fa fa-envelope", - "idx": 1, - "image_view": 0, - "in_create": 1, - "is_submittable": 0, - "issingle": 0, - "istable": 0, - "max_attachments": 0, - "modified": "2018-11-09 15:34:07.229657", - "modified_by": "Administrator", - "module": "Email", - "name": "Email Queue", - "owner": "Administrator", + ], + "has_web_view": 0, + "hide_heading": 0, + "hide_toolbar": 0, + "icon": "fa fa-envelope", + "idx": 1, + "image_view": 0, + "in_create": 1, + "is_submittable": 0, + "issingle": 0, + "istable": 0, + "max_attachments": 0, + "modified": "2019-01-11 09:05:04.175368", + "modified_by": "Administrator", + "module": "Email", + "name": "Email Queue", + "owner": "Administrator", "permissions": [ { "amend": 0, diff --git a/frappe/email/email_body.py b/frappe/email/email_body.py index aba41e8813..b4af93e61d 100755 --- a/frappe/email/email_body.py +++ b/frappe/email/email_body.py @@ -6,7 +6,7 @@ import frappe, re, os from frappe.utils.pdf import get_pdf from frappe.email.smtp import get_outgoing_email_account from frappe.utils import (get_url, scrub_urls, strip, expand_relative_urls, cint, - split_emails, to_markdown, markdown, encode, random_string, parse_addr) + split_emails, to_markdown, markdown, random_string, parse_addr) import email.utils from six import iteritems, text_type, string_types from email.mime.multipart import MIMEMultipart diff --git a/frappe/email/inbox.py b/frappe/email/inbox.py index 5c8d33793a..6cfcf9f263 100644 --- a/frappe/email/inbox.py +++ b/frappe/email/inbox.py @@ -1,3 +1,4 @@ +from __future__ import unicode_literals import frappe import json diff --git a/frappe/email/queue.py b/frappe/email/queue.py index 56bfbbb7c0..ba66e670dd 100755 --- a/frappe/email/queue.py +++ b/frappe/email/queue.py @@ -382,7 +382,7 @@ def send_one(email, smtpserver=None, auto_commit=True, now=False, from_test=Fals email = frappe.db.sql('''select name, status, communication, message, sender, reference_doctype, reference_name, unsubscribe_param, unsubscribe_method, expose_recipients, - show_as_cc, add_unsubscribe_link, attachments + show_as_cc, add_unsubscribe_link, attachments, retry from `tabEmail Queue` where @@ -464,12 +464,16 @@ def send_one(email, smtpserver=None, auto_commit=True, now=False, from_test=Fals except Exception as e: frappe.db.rollback() - if any("Sent" == s.status for s in recipients_list): - frappe.db.sql("""update `tabEmail Queue` set status='Partially Errored', error=%s where name=%s""", - (text_type(e), email.name), auto_commit=auto_commit) + if email.retry < 3: + frappe.db.sql("""update `tabEmail Queue` set status='Not Sent', modified=%s, retry=retry+1 where name=%s""", + (now_datetime(), email.name), auto_commit=auto_commit) else: - frappe.db.sql("""update `tabEmail Queue` set status='Error', error=%s -where name=%s""", (text_type(e), email.name), auto_commit=auto_commit) + if any("Sent" == s.status for s in recipients_list): + frappe.db.sql("""update `tabEmail Queue` set status='Partially Errored', error=%s where name=%s""", + (text_type(e), email.name), auto_commit=auto_commit) + else: + frappe.db.sql("""update `tabEmail Queue` set status='Error', error=%s + where name=%s""", (text_type(e), email.name), auto_commit=auto_commit) if email.communication: frappe.get_doc('Communication', email.communication).set_delivery_status(commit=auto_commit) diff --git a/frappe/email/receive.py b/frappe/email/receive.py index ffee8dc17a..9bdf3a9ba3 100644 --- a/frappe/email/receive.py +++ b/frappe/email/receive.py @@ -553,6 +553,7 @@ class Email: # fix due to a python bug in poplib that limits it to 2048 poplib._MAXLINE = 20480 +imaplib._MAXLINE = 20480 class TimerMixin(object): def __init__(self, *args, **kwargs): diff --git a/frappe/email/smtp.py b/frappe/email/smtp.py index fa6b92fc33..549b3f1d1e 100644 --- a/frappe/email/smtp.py +++ b/frappe/email/smtp.py @@ -88,7 +88,7 @@ def get_outgoing_email_account(raise_exception_not_set=True, append_to=None, sen if email_account: if email_account.enable_outgoing and not getattr(email_account, 'from_site_config', False): raise_exception = True - if email_account.smtp_server in ['localhost','127.0.0.1']: + if email_account.smtp_server in ['localhost','127.0.0.1'] or email_account.no_smtp_authentication: raise_exception = False email_account.password = email_account.get_password(raise_exception=raise_exception) email_account.default_sender = email.utils.formataddr((email_account.name, email_account.get("email_id"))) @@ -170,11 +170,14 @@ class SMTPServer: self.email_account = get_outgoing_email_account(raise_exception_not_set=False, append_to=append_to, sender=sender) if self.email_account: self.server = self.email_account.smtp_server - self.login = getattr(self.email_account, "login_id", None) or self.email_account.email_id - if self.email_account.ascii_encode_password: - self.password = frappe.safe_encode(self.email_account.password, 'ascii') + self.login = (getattr(self.email_account, "login_id", None) or self.email_account.email_id) + if not self.email_account.no_smtp_authentication: + if self.email_account.ascii_encode_password: + self.password = frappe.safe_encode(self.email_account.password, 'ascii') + else: + self.password = self.email_account.password else: - self.password = self.email_account.password + self.password = None self.port = self.email_account.smtp_port self.use_tls = self.email_account.use_tls self.sender = self.email_account.email_id @@ -210,7 +213,7 @@ class SMTPServer: self._sess.ehlo() if self.login and self.password: - ret = self._sess.login((self.login or ""), (self.password or "")) + ret = self._sess.login(str(self.login or ""), str(self.password or "")) # check if logged correctly if ret[0]!=235: diff --git a/frappe/email/test_email_body.py b/frappe/email/test_email_body.py index 3f6502cdd4..b0bfddd4f0 100644 --- a/frappe/email/test_email_body.py +++ b/frappe/email/test_email_body.py @@ -2,7 +2,7 @@ # License: GNU General Public License v3. See license.txt from __future__ import unicode_literals -import frappe, unittest, os, base64 +import unittest, os, base64 from frappe.email.email_body import (replace_filename_with_cid, get_email, inline_style_in_html, get_header) diff --git a/frappe/frappeclient.py b/frappe/frappeclient.py index f1f57c2fe4..3e11f9d72f 100644 --- a/frappe/frappeclient.py +++ b/frappe/frappeclient.py @@ -1,4 +1,4 @@ -from __future__ import print_function +from __future__ import print_function, unicode_literals import requests import json import frappe diff --git a/frappe/geo/doctype/country/test_country.py b/frappe/geo/doctype/country/test_country.py index 110e38e2b5..81849d6886 100644 --- a/frappe/geo/doctype/country/test_country.py +++ b/frappe/geo/doctype/country/test_country.py @@ -1,6 +1,6 @@ # Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors # License: See license.txt - +from __future__ import unicode_literals import frappe test_records = frappe.get_test_records('Country') \ No newline at end of file diff --git a/frappe/geo/doctype/currency/test_currency.py b/frappe/geo/doctype/currency/test_currency.py index 5552e675ec..7945e193da 100644 --- a/frappe/geo/doctype/currency/test_currency.py +++ b/frappe/geo/doctype/currency/test_currency.py @@ -3,5 +3,6 @@ # pre loaded +from __future__ import unicode_literals import frappe test_records = frappe.get_test_records('Currency') \ No newline at end of file diff --git a/frappe/hooks.py b/frappe/hooks.py index 86e251f9b3..ff63533d1e 100644 --- a/frappe/hooks.py +++ b/frappe/hooks.py @@ -12,7 +12,6 @@ source_link = "https://github.com/frappe/frappe" app_license = "MIT" develop_version = '12.x.x-develop' -staging_version = '11.0.3-beta.42' app_email = "info@frappe.io" @@ -147,7 +146,8 @@ scheduler_events = { "frappe.integrations.doctype.razorpay_settings.razorpay_settings.capture_payment", "frappe.twofactor.delete_all_barcodes_for_users", "frappe.integrations.doctype.gcalendar_settings.gcalendar_settings.sync", - "frappe.website.doctype.web_page.web_page.check_publish_status" + "frappe.website.doctype.web_page.web_page.check_publish_status", + 'frappe.utils.global_search.sync_global_search' ], "hourly": [ "frappe.model.utils.link_count.update_link_count", diff --git a/frappe/integrations/data_migration_mapping/gcalendar_to_event/__init__.py b/frappe/integrations/data_migration_mapping/gcalendar_to_event/__init__.py index 7656173c9b..441d2c3797 100644 --- a/frappe/integrations/data_migration_mapping/gcalendar_to_event/__init__.py +++ b/frappe/integrations/data_migration_mapping/gcalendar_to_event/__init__.py @@ -1,5 +1,6 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- +from __future__ import unicode_literals import frappe from datetime import datetime from dateutil.parser import parse diff --git a/frappe/integrations/doctype/dropbox_settings/dropbox_settings.json b/frappe/integrations/doctype/dropbox_settings/dropbox_settings.json index 091adc967f..33d34e0210 100644 --- a/frappe/integrations/doctype/dropbox_settings/dropbox_settings.json +++ b/frappe/integrations/doctype/dropbox_settings/dropbox_settings.json @@ -448,7 +448,7 @@ "issingle": 1, "istable": 0, "max_attachments": 0, - "modified": "2018-10-25 15:17:17.573134", + "modified": "2019-01-03 05:44:40.520943", "modified_by": "Administrator", "module": "Integrations", "name": "Dropbox Settings", @@ -484,4 +484,4 @@ "track_changes": 1, "track_seen": 0, "track_views": 0 -} \ No newline at end of file +} diff --git a/frappe/integrations/doctype/ldap_settings/ldap_settings.json b/frappe/integrations/doctype/ldap_settings/ldap_settings.json index f317f43070..6eb44a2db8 100644 --- a/frappe/integrations/doctype/ldap_settings/ldap_settings.json +++ b/frappe/integrations/doctype/ldap_settings/ldap_settings.json @@ -397,7 +397,7 @@ "issingle": 1, "istable": 0, "max_attachments": 0, - "modified": "2017-03-08 17:16:01.087365", + "modified": "2019-01-30 11:02:41.011412", "modified_by": "Administrator", "module": "Integrations", "name": "LDAP Settings", diff --git a/frappe/integrations/doctype/social_login_keys/social_login_keys.py b/frappe/integrations/doctype/social_login_keys/social_login_keys.py index da9e21cd8e..bd4cea01af 100644 --- a/frappe/integrations/doctype/social_login_keys/social_login_keys.py +++ b/frappe/integrations/doctype/social_login_keys/social_login_keys.py @@ -1,4 +1,5 @@ # see license +from __future__ import unicode_literals from frappe.model.document import Document class SocialLoginKeys(Document): diff --git a/frappe/integrations/doctype/webhook/__init__.py b/frappe/integrations/doctype/webhook/__init__.py index b72acc0578..75af2b360a 100644 --- a/frappe/integrations/doctype/webhook/__init__.py +++ b/frappe/integrations/doctype/webhook/__init__.py @@ -2,6 +2,7 @@ # Copyright (c) 2017, Frappe Technologies and contributors # For license information, please see license.txt +from __future__ import unicode_literals import frappe def run_webhooks(doc, method): @@ -37,7 +38,7 @@ def run_webhooks(doc, method): def _webhook_request(webhook): if not webhook.name in frappe.flags.webhooks_executed.get(doc.name, []): - frappe.enqueue("frappe.integrations.doctype.webhook.webhook.enqueue_webhook", + frappe.enqueue("frappe.integrations.doctype.webhook.webhook.enqueue_webhook", enqueue_after_commit=True, doc=doc, webhook=webhook) # keep list of webhooks executed for this doc in this request diff --git a/frappe/integrations/doctype/webhook/webhook.js b/frappe/integrations/doctype/webhook/webhook.js index 3fc78e0d2c..0bcb99e5cf 100644 --- a/frappe/integrations/doctype/webhook/webhook.js +++ b/frappe/integrations/doctype/webhook/webhook.js @@ -8,7 +8,7 @@ frappe.webhook = { frappe.model.with_doctype(doc.webhook_doctype, function() { var fields = $.map(frappe.get_doc("DocType", frm.doc.webhook_doctype).fields, function(d) { if (frappe.model.no_value_type.indexOf(d.fieldtype) === -1 || - d.fieldtype === 'Table') { + frappe.model.table_fields.includes(d.fieldtype)) { return { label: d.label + ' (' + d.fieldtype + ')', value: d.fieldname }; } else if (d.fieldtype === 'Currency' || d.fieldtype === 'Float') { diff --git a/frappe/migrate.py b/frappe/migrate.py index d0fc2bf93c..956b4a3c93 100644 --- a/frappe/migrate.py +++ b/frappe/migrate.py @@ -14,7 +14,6 @@ from frappe.website import render, router from frappe.desk.doctype.desktop_icon.desktop_icon import sync_desktop_icons from frappe.core.doctype.language.language import sync_languages from frappe.modules.utils import sync_customizations -import frappe.utils.help def migrate(verbose=True, rebuild_website=False): '''Migrate all apps to the latest version, will: @@ -60,10 +59,6 @@ def migrate(verbose=True, rebuild_website=False): frappe.db.commit() - if not frappe.conf.get('global_help_setup'): - # sync help if not set as global - frappe.utils.help.sync() - clear_notifications() frappe.publish_realtime("version-update") diff --git a/frappe/model/__init__.py b/frappe/model/__init__.py index 2d260d8247..40ab9e3e5b 100644 --- a/frappe/model/__init__.py +++ b/frappe/model/__init__.py @@ -4,7 +4,6 @@ # model __init__.py from __future__ import unicode_literals import frappe -import json data_fieldtypes = ( 'Currency', @@ -37,12 +36,35 @@ data_fieldtypes = ( 'Geolocation' ) -no_value_fields = ('Section Break', 'Column Break', 'HTML', 'Table', 'Button', 'Image', +no_value_fields = ('Section Break', 'Column Break', 'HTML', 'Table', 'Table MultiSelect', 'Button', 'Image', 'Fold', 'Heading') display_fieldtypes = ('Section Break', 'Column Break', 'HTML', 'Button', 'Image', 'Fold', 'Heading') +numeric_fieldtypes = ('Currency', 'Int', 'Long Int', 'Float', 'Percent', 'Check') default_fields = ('doctype','name','owner','creation','modified','modified_by', 'parent','parentfield','parenttype','idx','docstatus') optional_fields = ("_user_tags", "_comments", "_assign", "_liked_by", "_seen") +table_fields = ('Table', 'Table MultiSelect') +core_doctypes_list = ('DocType', 'DocField', 'DocPerm', 'User', 'Role', 'Has Role', + 'Page', 'Module Def', 'Print Format', 'Report', 'Customize Form', + 'Customize Form Field', 'Property Setter', 'Custom Field', 'Custom Script') + +def copytables(srctype, src, srcfield, tartype, tar, tarfield, srcfields, tarfields=[]): + if not tarfields: + tarfields = srcfields + l = [] + data = src.get(srcfield) + for d in data: + newrow = tar.append(tarfield) + newrow.idx = d.idx + + for i in range(len(srcfields)): + newrow.set(tarfields[i], d.get(srcfields[i])) + + l.append(newrow) + return l + +def db_exists(dt, dn): + return frappe.db.exists(dt, dn) def delete_fields(args_dict, delete=0): """ diff --git a/frappe/model/base_document.py b/frappe/model/base_document.py index d5f5a194eb..9364f4403a 100644 --- a/frappe/model/base_document.py +++ b/frappe/model/base_document.py @@ -7,7 +7,7 @@ from six import iteritems, string_types import frappe import datetime from frappe import _ -from frappe.model import default_fields +from frappe.model import default_fields, table_fields from frappe.model.naming import set_new_name from frappe.model.utils.link_count import notify_link_count from frappe.modules import load_doctype_module @@ -222,7 +222,7 @@ class BaseDocument(object): # unique empty field should be set to None d[fieldname] = None - if isinstance(d[fieldname], list) and df.fieldtype != 'Table': + if isinstance(d[fieldname], list) and df.fieldtype not in table_fields: frappe.throw(_('Value for {0} cannot be a list').format(_(df.label))) if convert_dates_to_str and isinstance(d[fieldname], (datetime.datetime, datetime.time, datetime.timedelta)): @@ -398,7 +398,7 @@ class BaseDocument(object): def _get_missing_mandatory_fields(self): """Get mandatory fields that do not have any values""" def get_msg(df): - if df.fieldtype == "Table": + if df.fieldtype in table_fields: return "{}: {}: {}".format(_("Error"), _("Data missing in table"), _(df.label)) elif self.parentfield: @@ -573,7 +573,7 @@ class BaseDocument(object): db_value = db_values.get(key) if df and not df.allow_on_submit and (self.get(key) or db_value): - if df.fieldtype=="Table": + if df.fieldtype in table_fields: # just check if the table size has changed # individual fields will be checked in the loop for children self_value = len(self.get(key)) @@ -756,7 +756,7 @@ class BaseDocument(object): ref_doc = frappe.new_doc(self.doctype) else: # get values from old doc - if self.parent: + if self.get('parent_doc'): self.parent_doc.get_latest() ref_doc = [d for d in self.parent_doc.get(self.parentfield) if d.name == self.name][0] else: diff --git a/frappe/model/create_new.py b/frappe/model/create_new.py index 03bf2ba584..76176e3939 100644 --- a/frappe/model/create_new.py +++ b/frappe/model/create_new.py @@ -133,13 +133,14 @@ def user_permissions_exist(df, user_permissions): def get_default_based_on_another_field(df, user_permissions, parent_doc): # default value based on another document + from frappe.permissions import get_allowed_docs_for_doctype + ref_doctype = df.default[1:] ref_fieldname = ref_doctype.lower().replace(" ", "_") reference_name = parent_doc.get(ref_fieldname) if parent_doc else frappe.db.get_default(ref_fieldname) - default_value = frappe.db.get_value(ref_doctype, reference_name, df.fieldname) is_allowed_default_value = (not user_permissions_exist(df, user_permissions) or - (default_value in user_permissions.get(df.options).get('docs', []))) + (default_value in get_allowed_docs_for_doctype(user_permissions[df.options], df.parent))) # is this allowed as per user permissions if is_allowed_default_value: diff --git a/frappe/model/db_query.py b/frappe/model/db_query.py index 405997b461..178bc427eb 100644 --- a/frappe/model/db_query.py +++ b/frappe/model/db_query.py @@ -16,7 +16,7 @@ import frappe, json, copy, re from frappe.model import optional_fields from frappe.client import check_parent_permission from frappe.model.utils.user_settings import get_user_settings, update_user_settings -from frappe.utils import flt, cint, get_time, make_filter_tuple, get_filter, add_to_date, cstr +from frappe.utils import flt, cint, get_time, make_filter_tuple, get_filter, add_to_date, cstr, nowdate class DatabaseQuery(object): def __init__(self, doctype, user=None): @@ -402,6 +402,33 @@ class DatabaseQuery(object): if df and df.fieldtype in ("Check", "Float", "Int", "Currency", "Percent"): can_be_null = False + if f.operator.lower() in ('previous', 'next'): + if f.operator.lower() == "previous": + if f.value == "1 week": + date_range = [add_to_date(nowdate(), days=-7), nowdate()] + elif f.value == "1 month": + date_range = [add_to_date(nowdate(), months=-1), nowdate()] + elif f.value == "3 months": + date_range = [add_to_date(nowdate(), months=-3), nowdate()] + elif f.value == "6 months": + date_range = [add_to_date(nowdate(), months=-6), nowdate()] + elif f.value == "1 year": + date_range = [add_to_date(nowdate(), years=-1), nowdate()] + elif f.operator.lower() == "next": + if f.value == "1 week": + date_range = [nowdate(), add_to_date(nowdate(), days=7)] + elif f.value == "1 month": + date_range = [nowdate(), add_to_date(nowdate(), months=1)] + elif f.value == "3 months": + date_range = [nowdate(), add_to_date(nowdate(), months=3)] + elif f.value == "6 months": + date_range = [nowdate(), add_to_date(nowdate(), months=6)] + elif f.value == "1 year": + date_range = [nowdate(), add_to_date(nowdate(), years=1)] + f.operator = "Between" + f.value = date_range + fallback = "'0001-01-01 00:00:00'" + if f.operator in ('>', '<') and (f.fieldname in ('creation', 'modified')): value = cstr(f.value) fallback = "NULL" @@ -424,6 +451,19 @@ class DatabaseQuery(object): value = get_time(f.value).strftime("%H:%M:%S.%f") fallback = "'00:00:00'" + elif f.operator.lower() == "is": + if f.value == 'set': + f.operator = '!=' + elif f.value == 'not set': + f.operator = '=' + + value = "" + fallback = '""' + can_be_null = True + + if 'ifnull' not in column_name: + column_name = 'ifnull({}, {})'.format(column_name, fallback) + elif f.operator.lower() in ("like", "not like") or (isinstance(f.value, string_types) and (not df or df.fieldtype not in ["Float", "Int", "Currency", "Percent", "Check"])): value = "" if f.value==None else f.value @@ -573,6 +613,7 @@ class DatabaseQuery(object): ) match_conditions.append("({condition})".format(condition=condition)) + match_filters[df.get('options')] = docs if match_conditions: self.match_conditions.append(" and ".join(match_conditions)) @@ -736,7 +777,7 @@ def is_parent_only_filter(doctype, filters): def has_any_user_permission_for_doctype(doctype, user, applicable_for): user_permissions = frappe.permissions.get_user_permissions(user=user) - doctype_user_permissions = user_permissions.get(doctype) + doctype_user_permissions = user_permissions.get(doctype, []) for permission in doctype_user_permissions: if not permission.applicable_for or permission.applicable_for == applicable_for: diff --git a/frappe/model/delete_doc.py b/frappe/model/delete_doc.py index 2b8a747643..20e0d00199 100644 --- a/frappe/model/delete_doc.py +++ b/frappe/model/delete_doc.py @@ -141,8 +141,14 @@ def delete_from_table(doctype, name, ignore_doctypes, doc): else: def get_table_fields(field_doctype): - return frappe.db.sql_list("""select options from `tab{}` where fieldtype='Table' - and parent=%s""".format(field_doctype), doctype) + return [r[0] for r in frappe.get_all(field_doctype, + fields='options', + filters={ + 'fieldtype': ['in', frappe.model.table_fields], + 'parent': doctype + }, + as_list=1 + )] tables = get_table_fields("DocField") if not frappe.flags.in_install=="frappe": @@ -214,7 +220,7 @@ def check_if_doc_is_linked(doc, method="Delete"): def check_if_doc_is_dynamically_linked(doc, method="Delete"): '''Raise `frappe.LinkExistsError` if the document is dynamically linked''' for df in get_dynamic_link_map().get(doc.doctype, []): - if df.parent in ("Communication", "ToDo", "DocShare", "Email Unsubscribe", "Activity Log", 'File', 'Version'): + if df.parent in ("Communication", "ToDo", "DocShare", "Email Unsubscribe", "Activity Log", 'File', 'Version', 'View Log'): # don't check for communication and todo! continue @@ -280,6 +286,10 @@ def delete_dynamic_links(doctype, name): communication_type = 'Comment' and reference_doctype=%s and reference_name=%s""", (doctype, name)) + # delete view logs + frappe.db.sql("""delete from `tabView Log` + where reference_doctype=%s and reference_name=%s""", (doctype, name)) + # unlink communications frappe.db.sql("""update `tabCommunication` set reference_doctype=null, reference_name=null diff --git a/frappe/model/docfield.py b/frappe/model/docfield.py index 090c26bf9f..19b78e329d 100644 --- a/frappe/model/docfield.py +++ b/frappe/model/docfield.py @@ -36,7 +36,7 @@ def update_table(f, new): def update_parent_field(f, new): """update 'parentfield' in tables""" - if f['fieldtype']=='Table': + if f['fieldtype'] in frappe.model.table_fields: frappe.db.begin() frappe.db.sql("""update `tab%s` set parentfield=%s where parentfield=%s""" \ % (f['options'], '%s', '%s'), (new, f['fieldname'])) diff --git a/frappe/model/document.py b/frappe/model/document.py index 5af72bff44..6bd82ba25a 100644 --- a/frappe/model/document.py +++ b/frappe/model/document.py @@ -12,7 +12,7 @@ from frappe.model.naming import set_new_name from six import iteritems, string_types from werkzeug.exceptions import NotFound, Forbidden import hashlib, json -from frappe.model import optional_fields +from frappe.model import optional_fields, table_fields from frappe.model.workflow import validate_workflow from frappe.utils.global_search import update_global_search from frappe.integrations.doctype.webhook import run_webhooks @@ -489,7 +489,7 @@ class Document(BaseDocument): value = self.get(field.fieldname) original_value = self._doc_before_save.get(field.fieldname) - if field.fieldtype=='Table': + if field.fieldtype in table_fields: fail = not self.is_child_table_same(field.fieldname) elif field.fieldtype in ('Date', 'Datetime', 'Time'): fail = str(value) != str(original_value) @@ -756,7 +756,7 @@ class Document(BaseDocument): def get_all_children(self, parenttype=None): """Returns all children documents from **Table** type field in a list.""" ret = [] - for df in self.meta.get("fields", {"fieldtype": "Table"}): + for df in self.meta.get("fields", {"fieldtype": ['in', table_fields]}): if parenttype: if df.options==parenttype: return self.get(df.fieldname) @@ -1168,7 +1168,7 @@ class Document(BaseDocument): if hasattr(self.meta, 'track_views') and self.meta.track_views: frappe.get_doc({ - "doctype": "View log", + "doctype": "View Log", "viewed_by": frappe.session.user, "reference_doctype": self.doctype, "reference_name": self.name, diff --git a/frappe/model/dynamic_links.py b/frappe/model/dynamic_links.py index fcd0b9234b..e5ce9102e2 100644 --- a/frappe/model/dynamic_links.py +++ b/frappe/model/dynamic_links.py @@ -1,6 +1,7 @@ # Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors # MIT License. See license.txt +from __future__ import unicode_literals import frappe # select doctypes that are accessed by the user (not read_only) first, so that the diff --git a/frappe/model/mapper.py b/frappe/model/mapper.py index 273a3af6fc..967be8384e 100644 --- a/frappe/model/mapper.py +++ b/frappe/model/mapper.py @@ -5,7 +5,7 @@ from __future__ import unicode_literals import frappe, json from frappe import _ from frappe.utils import cstr -from frappe.model import default_fields +from frappe.model import default_fields, table_fields from six import string_types @frappe.whitelist() @@ -129,8 +129,8 @@ def map_doc(source_doc, target_doc, table_map, source_parent=None): table_map["postprocess"](source_doc, target_doc, source_parent) def map_fields(source_doc, target_doc, table_map, source_parent): - no_copy_fields = set([d.fieldname for d in source_doc.meta.get("fields") if (d.no_copy==1 or d.fieldtype=="Table")] - + [d.fieldname for d in target_doc.meta.get("fields") if (d.no_copy==1 or d.fieldtype=="Table")] + no_copy_fields = set([d.fieldname for d in source_doc.meta.get("fields") if (d.no_copy==1 or d.fieldtype in table_fields)] + + [d.fieldname for d in target_doc.meta.get("fields") if (d.no_copy==1 or d.fieldtype in table_fields)] + list(default_fields) + list(table_map.get("field_no_map", []))) diff --git a/frappe/model/meta.py b/frappe/model/meta.py index 1e66d2f045..e53b4f6be4 100644 --- a/frappe/model/meta.py +++ b/frappe/model/meta.py @@ -20,7 +20,7 @@ from datetime import datetime from six.moves import range import frappe, json, os from frappe.utils import cstr, cint -from frappe.model import default_fields, no_value_fields, optional_fields, data_fieldtypes +from frappe.model import default_fields, no_value_fields, optional_fields, data_fieldtypes, table_fields from frappe.model.document import Document from frappe.model.base_document import BaseDocument from frappe.modules import load_doctype_module @@ -150,7 +150,7 @@ class Meta(Document): def get_table_fields(self): if not hasattr(self, "_table_fields"): if self.name!="DocType": - self._table_fields = self.get('fields', {"fieldtype":"Table"}) + self._table_fields = self.get('fields', {"fieldtype": ['in', table_fields]}) else: self._table_fields = doctype_table_fields @@ -451,7 +451,7 @@ def is_single(doctype): raise Exception('Cannot determine whether %s is single' % doctype) def get_parent_dt(dt): - parent_dt = frappe.db.get_all('DocField', 'parent', dict(fieldtype='Table', options=dt), limit=1) + parent_dt = frappe.db.get_all('DocField', 'parent', dict(fieldtype=['in', frappe.model.table_fields], options=dt), limit=1) return parent_dt and parent_dt[0].parent or '' def set_fieldname(field_id, fieldname): diff --git a/frappe/model/rename_doc.py b/frappe/model/rename_doc.py index 83e252bd7a..a373554696 100644 --- a/frappe/model/rename_doc.py +++ b/frappe/model/rename_doc.py @@ -173,9 +173,11 @@ def validate_rename(doctype, new, meta, merge, force, ignore_permissions): return new def rename_doctype(doctype, old, new, force=False): - # change options for fieldtype Table - update_options_for_fieldtype("Table", old, new) - update_options_for_fieldtype("Link", old, new) + # change options for fieldtype Table, Table MultiSelect and Link + fields_with_options = ("Link",) + frappe.model.table_fields + + for fieldtype in fields_with_options: + update_options_for_fieldtype(fieldtype, old, new) # change options where select options are hardcoded i.e. listed select_fields = get_select_fields(old, new) @@ -352,13 +354,21 @@ def update_select_field_values(old, new): .format(frappe.db.escape('%' + '\n' + old + '%'), frappe.db.escape('%' + old + '\n' + '%')), (old, new, new)) def update_parenttype_values(old, new): - child_doctypes = frappe.db.sql("""\ - select options, fieldname from `tabDocField` - where parent=%s and fieldtype='Table'""", (new,), as_dict=1) + child_doctypes = frappe.db.get_all('DocField', + fields=['options', 'fieldname'], + filters={ + 'parent': new, + 'fieldtype': ['in', frappe.model.table_fields] + } + ) - custom_child_doctypes = frappe.db.sql("""\ - select options, fieldname from `tabCustom Field` - where dt=%s and fieldtype='Table'""", (new,), as_dict=1) + custom_child_doctypes = frappe.db.get_all('Custom Field', + fields=['options', 'fieldname'], + filters={ + 'dt': new, + 'fieldtype': ['in', frappe.model.table_fields] + } + ) child_doctypes += custom_child_doctypes fields = [d['fieldname'] for d in child_doctypes] diff --git a/frappe/model/utils/rename_field.py b/frappe/model/utils/rename_field.py index cc635170a5..0cb974df1e 100644 --- a/frappe/model/utils/rename_field.py +++ b/frappe/model/utils/rename_field.py @@ -5,7 +5,7 @@ from __future__ import unicode_literals, print_function import frappe import json -from frappe.model import no_value_fields +from frappe.model import no_value_fields, table_fields from frappe.utils.password import rename_password_field from frappe.model.utils.user_settings import update_user_settings_data, sync_user_settings @@ -19,7 +19,7 @@ def rename_field(doctype, old_fieldname, new_fieldname): print("rename_field: " + (new_fieldname) + " not found in " + doctype) return - if new_field.fieldtype == "Table": + if new_field.fieldtype in table_fields: # change parentfield of table mentioned in options frappe.db.sql("""update `tab%s` set parentfield=%s where parentfield=%s""" % (new_field.options.split("\n")[0], "%s", "%s"), diff --git a/frappe/model/utils/user_settings.py b/frappe/model/utils/user_settings.py index 2cbfa50026..d59bda71a5 100644 --- a/frappe/model/utils/user_settings.py +++ b/frappe/model/utils/user_settings.py @@ -1,3 +1,4 @@ +from __future__ import unicode_literals # Settings saved per user basis # such as page_limit, filters, last_view diff --git a/frappe/modules/__init__.py b/frappe/modules/__init__.py index 90f60fdd89..fef4829bb6 100644 --- a/frappe/modules/__init__.py +++ b/frappe/modules/__init__.py @@ -1 +1,2 @@ +from __future__ import unicode_literals from .utils import * \ No newline at end of file diff --git a/frappe/modules/export_file.py b/frappe/modules/export_file.py index 275db10b13..66a6a9f6b7 100644 --- a/frappe/modules/export_file.py +++ b/frappe/modules/export_file.py @@ -3,7 +3,7 @@ from __future__ import unicode_literals -import frappe, os, json +import frappe, os import frappe.model from frappe.modules import scrub, get_module_path, scrub_dt_dn diff --git a/frappe/oauth.py b/frappe/oauth.py index e89a13cd0e..4dc50366be 100644 --- a/frappe/oauth.py +++ b/frappe/oauth.py @@ -1,11 +1,11 @@ -from __future__ import print_function +from __future__ import print_function, unicode_literals import frappe import pytz from frappe import _ from frappe.auth import LoginManager from oauthlib.oauth2.rfc6749.tokens import BearerToken -from oauthlib.oauth2.rfc6749.grant_types import AuthorizationCodeGrant, ImplicitGrant, ResourceOwnerPasswordCredentialsGrant, ClientCredentialsGrant, RefreshTokenGrant, OpenIDConnectAuthCode +from oauthlib.oauth2.rfc6749.grant_types import AuthorizationCodeGrant, ImplicitGrant, ResourceOwnerPasswordCredentialsGrant, ClientCredentialsGrant, RefreshTokenGrant from oauthlib.oauth2 import RequestValidator from oauthlib.oauth2.rfc6749.endpoints.authorization import AuthorizationEndpoint from oauthlib.oauth2.rfc6749.endpoints.token import TokenEndpoint @@ -40,19 +40,12 @@ class WebApplicationServer(AuthorizationEndpoint, TokenEndpoint, ResourceEndpoin implicit_grant = ImplicitGrant(request_validator) auth_grant = AuthorizationCodeGrant(request_validator) refresh_grant = RefreshTokenGrant(request_validator) - openid_connect_auth = OpenIDConnectAuthCode(request_validator) resource_owner_password_credentials_grant = ResourceOwnerPasswordCredentialsGrant(request_validator) bearer = BearerToken(request_validator, token_generator, token_expires_in, refresh_token_generator) AuthorizationEndpoint.__init__(self, default_response_type='code', response_types={ 'code': auth_grant, - 'code+token': openid_connect_auth, - 'code+id_token': openid_connect_auth, - 'code+token+id_token': openid_connect_auth, - 'code token': openid_connect_auth, - 'code id_token': openid_connect_auth, - 'code token id_token': openid_connect_auth, 'token': implicit_grant }, default_token_type=bearer) diff --git a/frappe/patches.txt b/frappe/patches.txt index 867eeb4af9..c8623b78de 100644 --- a/frappe/patches.txt +++ b/frappe/patches.txt @@ -12,13 +12,14 @@ execute:frappe.reload_doc('core', 'doctype', 'docperm') #2018-05-29 frappe.patches.v8_0.drop_is_custom_from_docperm execute:frappe.reload_doc('core', 'doctype', 'module_def') #2017-09-22 execute:frappe.reload_doc('core', 'doctype', 'version') #2017-04-01 +frappe.patches.v11_0.replicate_old_user_permissions +frappe.patches.v11_0.drop_column_apply_user_permissions +frappe.patches.v11_0.reload_and_rename_view_log #2019-01-03 frappe.patches.v7_1.rename_scheduler_log_to_error_log frappe.patches.v6_1.rename_file_data frappe.patches.v7_0.re_route #2016-06-27 frappe.patches.v8_0.update_records_in_global_search #11-05-2017 frappe.patches.v8_0.update_published_in_global_search -frappe.patches.v11_0.replicate_old_user_permissions -frappe.patches.v11_0.drop_column_apply_user_permissions frappe.patches.v11_0.copy_fetch_data_from_options frappe.patches.v11_0.change_email_signature_fieldtype execute:frappe.reload_doc('core', 'doctype', 'activity_log') @@ -221,7 +222,6 @@ frappe.patches.v11_0.rename_workflow_action_to_workflow_action_master #13-06-201 frappe.patches.v11_0.rename_email_alert_to_notification #13-06-2018 frappe.patches.v11_0.delete_duplicate_user_permissions frappe.patches.v11_0.set_dropbox_file_backup -frappe.patches.v11_0.get_docs_apps_if_not_present frappe.patches.v10_0.set_default_locking_time frappe.patches.v11_0.rename_google_maps_doctype frappe.patches.v10_0.modify_smallest_currency_fraction @@ -229,8 +229,10 @@ frappe.patches.v10_0.modify_naming_series_table frappe.patches.v10_0.enhance_security frappe.patches.v11_0.multiple_references_in_events frappe.patches.v11_0.set_allow_self_approval_in_workflow -execute:frappe.db.sql('ALTER table `tabSeries` ADD PRIMARY KEY IF NOT EXISTS (name)') frappe.patches.v11_0.remove_skip_for_doctype frappe.patches.v11_0.migrate_report_settings_for_new_listview frappe.patches.v11_0.delete_all_prepared_reports frappe.patches.v11_0.fix_order_by_in_reports_json +execute:frappe.delete_doc('Page', 'applications', ignore_missing=True) +frappe.patches.v11_0.set_missing_creation_and_modified_value_for_user_permissions +frappe.patches.v12_0.set_primary_key_in_series diff --git a/frappe/patches/v10_0/enable_chat_by_default_within_system_settings.py b/frappe/patches/v10_0/enable_chat_by_default_within_system_settings.py index 09d7b42ce7..eddca78051 100644 --- a/frappe/patches/v10_0/enable_chat_by_default_within_system_settings.py +++ b/frappe/patches/v10_0/enable_chat_by_default_within_system_settings.py @@ -1,3 +1,4 @@ +from __future__ import unicode_literals import frappe def execute(): diff --git a/frappe/patches/v10_0/enhance_security.py b/frappe/patches/v10_0/enhance_security.py index 6a9c371b51..865d18dcff 100644 --- a/frappe/patches/v10_0/enhance_security.py +++ b/frappe/patches/v10_0/enhance_security.py @@ -1,3 +1,4 @@ +from __future__ import unicode_literals import frappe diff --git a/frappe/patches/v10_0/increase_single_table_column_length.py b/frappe/patches/v10_0/increase_single_table_column_length.py index 3c2a2b3233..18de0cff9e 100644 --- a/frappe/patches/v10_0/increase_single_table_column_length.py +++ b/frappe/patches/v10_0/increase_single_table_column_length.py @@ -1,3 +1,4 @@ +from __future__ import unicode_literals """ Run this after updating country_info.json and or """ diff --git a/frappe/patches/v10_0/migrate_passwords_passlib.py b/frappe/patches/v10_0/migrate_passwords_passlib.py index 47a59f4ef5..22b7a86f85 100644 --- a/frappe/patches/v10_0/migrate_passwords_passlib.py +++ b/frappe/patches/v10_0/migrate_passwords_passlib.py @@ -1,3 +1,4 @@ +from __future__ import unicode_literals import frappe from frappe.utils.password import LegacyPassword diff --git a/frappe/patches/v10_0/modify_naming_series_table.py b/frappe/patches/v10_0/modify_naming_series_table.py index d98ab1edd1..659e247a38 100644 --- a/frappe/patches/v10_0/modify_naming_series_table.py +++ b/frappe/patches/v10_0/modify_naming_series_table.py @@ -1,3 +1,4 @@ +from __future__ import unicode_literals ''' Modify the Integer 10 Digits Value to BigInt 20 Digit value diff --git a/frappe/patches/v10_0/modify_smallest_currency_fraction.py b/frappe/patches/v10_0/modify_smallest_currency_fraction.py index c9ae477359..f875d6b87d 100644 --- a/frappe/patches/v10_0/modify_smallest_currency_fraction.py +++ b/frappe/patches/v10_0/modify_smallest_currency_fraction.py @@ -1,6 +1,7 @@ # Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors # MIT License. See license.txt +from __future__ import unicode_literals import frappe def execute(): diff --git a/frappe/patches/v10_0/refactor_social_login_keys.py b/frappe/patches/v10_0/refactor_social_login_keys.py index da834c763a..07737912df 100644 --- a/frappe/patches/v10_0/refactor_social_login_keys.py +++ b/frappe/patches/v10_0/refactor_social_login_keys.py @@ -1,3 +1,4 @@ +from __future__ import unicode_literals import frappe from frappe.utils import cstr diff --git a/frappe/patches/v10_0/reload_countries_and_currencies.py b/frappe/patches/v10_0/reload_countries_and_currencies.py index 927fb10a7c..f83ed9c3aa 100644 --- a/frappe/patches/v10_0/reload_countries_and_currencies.py +++ b/frappe/patches/v10_0/reload_countries_and_currencies.py @@ -1,3 +1,4 @@ +from __future__ import unicode_literals """ Run this after updating country_info.json and or """ diff --git a/frappe/patches/v10_0/remove_custom_field_for_disabled_domain.py b/frappe/patches/v10_0/remove_custom_field_for_disabled_domain.py index 65e616ea3f..f27639388e 100644 --- a/frappe/patches/v10_0/remove_custom_field_for_disabled_domain.py +++ b/frappe/patches/v10_0/remove_custom_field_for_disabled_domain.py @@ -1,3 +1,4 @@ +from __future__ import unicode_literals import frappe def execute(): diff --git a/frappe/patches/v10_0/set_default_locking_time.py b/frappe/patches/v10_0/set_default_locking_time.py index 045fa0e3fa..1c9797a6cc 100644 --- a/frappe/patches/v10_0/set_default_locking_time.py +++ b/frappe/patches/v10_0/set_default_locking_time.py @@ -1,6 +1,7 @@ # Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors # MIT License. See license.txt +from __future__ import unicode_literals import frappe def execute(): diff --git a/frappe/patches/v10_0/set_no_copy_to_workflow_state.py b/frappe/patches/v10_0/set_no_copy_to_workflow_state.py index 00ca125bf7..800d4a4d1b 100644 --- a/frappe/patches/v10_0/set_no_copy_to_workflow_state.py +++ b/frappe/patches/v10_0/set_no_copy_to_workflow_state.py @@ -1,3 +1,4 @@ +from __future__ import unicode_literals import frappe def execute(): diff --git a/frappe/patches/v11_0/change_email_signature_fieldtype.py b/frappe/patches/v11_0/change_email_signature_fieldtype.py index ccfa8541c3..f6d4bd5dcb 100644 --- a/frappe/patches/v11_0/change_email_signature_fieldtype.py +++ b/frappe/patches/v11_0/change_email_signature_fieldtype.py @@ -1,6 +1,7 @@ # Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors # MIT License. See license.txt +from __future__ import unicode_literals import frappe def execute(): diff --git a/frappe/patches/v11_0/copy_fetch_data_from_options.py b/frappe/patches/v11_0/copy_fetch_data_from_options.py index 4c69a75c55..ae7788450a 100644 --- a/frappe/patches/v11_0/copy_fetch_data_from_options.py +++ b/frappe/patches/v11_0/copy_fetch_data_from_options.py @@ -1,3 +1,4 @@ +from __future__ import unicode_literals import frappe def execute(): diff --git a/frappe/patches/v11_0/delete_all_prepared_reports.py b/frappe/patches/v11_0/delete_all_prepared_reports.py index 2204f90a8d..10bc049895 100644 --- a/frappe/patches/v11_0/delete_all_prepared_reports.py +++ b/frappe/patches/v11_0/delete_all_prepared_reports.py @@ -1,3 +1,4 @@ +from __future__ import unicode_literals import frappe def execute(): diff --git a/frappe/patches/v11_0/delete_duplicate_user_permissions.py b/frappe/patches/v11_0/delete_duplicate_user_permissions.py index 22369fb78e..9795d2dead 100644 --- a/frappe/patches/v11_0/delete_duplicate_user_permissions.py +++ b/frappe/patches/v11_0/delete_duplicate_user_permissions.py @@ -1,3 +1,4 @@ +from __future__ import unicode_literals import frappe def execute(): diff --git a/frappe/patches/v11_0/drop_column_apply_user_permissions.py b/frappe/patches/v11_0/drop_column_apply_user_permissions.py index b1e4ea05f8..ed0a6881af 100644 --- a/frappe/patches/v11_0/drop_column_apply_user_permissions.py +++ b/frappe/patches/v11_0/drop_column_apply_user_permissions.py @@ -1,3 +1,4 @@ +from __future__ import unicode_literals import frappe def execute(): diff --git a/frappe/patches/v11_0/fix_order_by_in_reports_json.py b/frappe/patches/v11_0/fix_order_by_in_reports_json.py index 561efdcee3..2cd82d442d 100644 --- a/frappe/patches/v11_0/fix_order_by_in_reports_json.py +++ b/frappe/patches/v11_0/fix_order_by_in_reports_json.py @@ -1,3 +1,4 @@ +from __future__ import unicode_literals import frappe, json def execute(): diff --git a/frappe/patches/v11_0/get_docs_apps_if_not_present.py b/frappe/patches/v11_0/get_docs_apps_if_not_present.py deleted file mode 100644 index 83f95247bf..0000000000 --- a/frappe/patches/v11_0/get_docs_apps_if_not_present.py +++ /dev/null @@ -1,6 +0,0 @@ -import frappe -from frappe.utils.help import setup_apps_for_docs - -def execute(): - for app in frappe.get_installed_apps(): - setup_apps_for_docs(app) diff --git a/frappe/patches/v11_0/migrate_report_settings_for_new_listview.py b/frappe/patches/v11_0/migrate_report_settings_for_new_listview.py index 9e5ce727c0..5bef52c295 100644 --- a/frappe/patches/v11_0/migrate_report_settings_for_new_listview.py +++ b/frappe/patches/v11_0/migrate_report_settings_for_new_listview.py @@ -1,3 +1,4 @@ +from __future__ import unicode_literals import frappe, json def execute(): diff --git a/frappe/patches/v11_0/multiple_references_in_events.py b/frappe/patches/v11_0/multiple_references_in_events.py index 86dd36f660..57d4787eca 100644 --- a/frappe/patches/v11_0/multiple_references_in_events.py +++ b/frappe/patches/v11_0/multiple_references_in_events.py @@ -1,3 +1,4 @@ +from __future__ import unicode_literals import frappe def execute(): diff --git a/frappe/patches/v11_0/reload_and_rename_view_log.py b/frappe/patches/v11_0/reload_and_rename_view_log.py new file mode 100644 index 0000000000..611de79a3c --- /dev/null +++ b/frappe/patches/v11_0/reload_and_rename_view_log.py @@ -0,0 +1,28 @@ +from __future__ import unicode_literals +import frappe + +def execute(): + if frappe.db.exists('DocType', 'View log'): + # for mac users direct renaming would not work since mysql for mac saves table name in lower case + # so while renaming `tabView log` to `tabView Log` we get "Table 'tabView Log' already exists" error + # more info https://stackoverflow.com/a/44753093/5955589 , + # https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html#sysvar_lower_case_table_names + + # here we are creating a temp table to store view log data + frappe.db.sql("CREATE TABLE `ViewLogTemp` AS SELECT * FROM `tabView log`") + + # deleting old View log table + frappe.db.sql("DROP table `tabView log`") + frappe.delete_doc('DocType', 'View log') + + # reloading view log doctype to create `tabView Log` table + frappe.reload_doc('core', 'doctype', 'view_log') + + # Move the data to newly created `tabView Log` table + frappe.db.sql("INSERT INTO `tabView Log` SELECT * FROM `ViewLogTemp`") + frappe.db.commit() + + # Delete temporary table + frappe.db.sql("DROP table `ViewLogTemp`") + else: + frappe.reload_doc('core', 'doctype', 'view_log') diff --git a/frappe/patches/v11_0/remove_skip_for_doctype.py b/frappe/patches/v11_0/remove_skip_for_doctype.py index 1849cb7bcd..edd385e317 100644 --- a/frappe/patches/v11_0/remove_skip_for_doctype.py +++ b/frappe/patches/v11_0/remove_skip_for_doctype.py @@ -1,3 +1,4 @@ +from __future__ import unicode_literals import frappe from frappe.desk.form.linked_with import get_linked_doctypes from frappe.patches.v11_0.replicate_old_user_permissions import get_doctypes_to_skip @@ -42,9 +43,9 @@ def execute(): # only specific doctypes are selected # split this into multiple records and delete linked_doctypes = get_linked_doctypes(user_permission.allow, True).keys() - + linked_doctypes = list(linked_doctypes) - + # append the doctype for which we have build the user permission linked_doctypes += [user_permission.allow] @@ -55,14 +56,16 @@ def execute(): user_permission.skip_for_doctype = None for doctype in applicable_for_doctypes: if doctype: - # Maintain sequence (name, user, allow, for_value, applicable_for, apply_to_all_doctypes) + # Maintain sequence (name, user, allow, for_value, applicable_for, apply_to_all_doctypes, creation, modified) new_user_permissions_list.append(( frappe.generate_hash("", 10), user_permission.user, user_permission.allow, user_permission.for_value, doctype, - 0 + 0, + user_permission.creation, + user_permission.modified )) else: # No skip_for_doctype found! Just update apply_to_all_doctypes. @@ -71,7 +74,7 @@ def execute(): if new_user_permissions_list: frappe.db.sql(''' INSERT INTO `tabUser Permission` - (`name`, `user`, `allow`, `for_value`, `applicable_for`, `apply_to_all_doctypes`) + (`name`, `user`, `allow`, `for_value`, `applicable_for`, `apply_to_all_doctypes`, `creation`, `modified`) VALUES {} '''.format( # nosec ', '.join(['%s'] * len(new_user_permissions_list)) diff --git a/frappe/patches/v11_0/rename_email_alert_to_notification.py b/frappe/patches/v11_0/rename_email_alert_to_notification.py index fee6fd2f0d..727055fcc4 100644 --- a/frappe/patches/v11_0/rename_email_alert_to_notification.py +++ b/frappe/patches/v11_0/rename_email_alert_to_notification.py @@ -1,3 +1,4 @@ +from __future__ import unicode_literals import frappe from frappe.model.rename_doc import rename_doc diff --git a/frappe/patches/v11_0/rename_google_maps_doctype.py b/frappe/patches/v11_0/rename_google_maps_doctype.py index 1423cd70e4..5420dcfc20 100644 --- a/frappe/patches/v11_0/rename_google_maps_doctype.py +++ b/frappe/patches/v11_0/rename_google_maps_doctype.py @@ -1,7 +1,8 @@ -import frappe -from frappe.model.rename_doc import rename_doc - -def execute(): - if frappe.db.exists("DocType","Google Maps") and not frappe.db.exists("DocType","Google Maps Settings"): - rename_doc('DocType', 'Google Maps', 'Google Maps Settings') +from __future__ import unicode_literals +import frappe +from frappe.model.rename_doc import rename_doc + +def execute(): + if frappe.db.exists("DocType","Google Maps") and not frappe.db.exists("DocType","Google Maps Settings"): + rename_doc('DocType', 'Google Maps', 'Google Maps Settings') frappe.reload_doc('integrations', 'doctype', 'google_maps_settings') \ No newline at end of file diff --git a/frappe/patches/v11_0/rename_standard_reply_to_email_template.py b/frappe/patches/v11_0/rename_standard_reply_to_email_template.py index f5b86b9149..06869530e2 100644 --- a/frappe/patches/v11_0/rename_standard_reply_to_email_template.py +++ b/frappe/patches/v11_0/rename_standard_reply_to_email_template.py @@ -1,3 +1,4 @@ +from __future__ import unicode_literals import frappe from frappe.model.rename_doc import rename_doc diff --git a/frappe/patches/v11_0/rename_workflow_action_to_workflow_action_master.py b/frappe/patches/v11_0/rename_workflow_action_to_workflow_action_master.py index ff7bbcb719..32f17ac2d8 100644 --- a/frappe/patches/v11_0/rename_workflow_action_to_workflow_action_master.py +++ b/frappe/patches/v11_0/rename_workflow_action_to_workflow_action_master.py @@ -1,3 +1,4 @@ +from __future__ import unicode_literals import frappe from frappe.model.rename_doc import rename_doc diff --git a/frappe/patches/v11_0/replicate_old_user_permissions.py b/frappe/patches/v11_0/replicate_old_user_permissions.py index 63b072502d..d1ceae8a7f 100644 --- a/frappe/patches/v11_0/replicate_old_user_permissions.py +++ b/frappe/patches/v11_0/replicate_old_user_permissions.py @@ -1,3 +1,4 @@ +from __future__ import unicode_literals import frappe import json from frappe.utils import cint diff --git a/frappe/patches/v11_0/set_allow_self_approval_in_workflow.py b/frappe/patches/v11_0/set_allow_self_approval_in_workflow.py index 99a2b6f536..24c01e1a58 100644 --- a/frappe/patches/v11_0/set_allow_self_approval_in_workflow.py +++ b/frappe/patches/v11_0/set_allow_self_approval_in_workflow.py @@ -1,3 +1,4 @@ +from __future__ import unicode_literals import frappe def execute(): diff --git a/frappe/patches/v11_0/set_missing_creation_and_modified_value_for_user_permissions.py b/frappe/patches/v11_0/set_missing_creation_and_modified_value_for_user_permissions.py new file mode 100644 index 0000000000..84d6d6c994 --- /dev/null +++ b/frappe/patches/v11_0/set_missing_creation_and_modified_value_for_user_permissions.py @@ -0,0 +1,6 @@ +import frappe + +def execute(): + frappe.db.sql('''UPDATE `tabUser Permission` + SET `modified`=NOW(), `creation`=NOW() + WHERE `creation` IS NULL''') \ No newline at end of file diff --git a/frappe/patches/v11_0/sync_stripe_settings_before_migrate.py b/frappe/patches/v11_0/sync_stripe_settings_before_migrate.py index 211e25fb95..331b0eba32 100644 --- a/frappe/patches/v11_0/sync_stripe_settings_before_migrate.py +++ b/frappe/patches/v11_0/sync_stripe_settings_before_migrate.py @@ -1,3 +1,4 @@ +from __future__ import unicode_literals import frappe from frappe.utils.password import get_decrypted_password diff --git a/frappe/patches/v11_0/sync_user_permission_doctype_before_migrate.py b/frappe/patches/v11_0/sync_user_permission_doctype_before_migrate.py index 612d83bf97..738fea1a48 100644 --- a/frappe/patches/v11_0/sync_user_permission_doctype_before_migrate.py +++ b/frappe/patches/v11_0/sync_user_permission_doctype_before_migrate.py @@ -1,3 +1,4 @@ +from __future__ import unicode_literals import frappe def execute(): diff --git a/frappe/patches/v12_0/create_social_desktop_icon.py b/frappe/patches/v12_0/create_social_desktop_icon.py deleted file mode 100644 index 5c52cbf0d9..0000000000 --- a/frappe/patches/v12_0/create_social_desktop_icon.py +++ /dev/null @@ -1,19 +0,0 @@ -import frappe - -def execute(): - icon_obj = { - 'doctype': 'Desktop Icon', - 'module_name': 'Social', - 'label': 'Social', - 'standard': 1, - 'idx': 15, - 'type': 'link', - 'color': '#FF4136', - 'link': 'social/home', - 'icon': 'octicon octicon-heart' - } - - if not frappe.db.exists(icon_obj): - icon = frappe.get_doc(icon_obj) - icon.insert() - frappe.db.commit() \ No newline at end of file diff --git a/frappe/patches/v12_0/set_primary_key_in_series.py b/frappe/patches/v12_0/set_primary_key_in_series.py new file mode 100644 index 0000000000..e5ed2204ba --- /dev/null +++ b/frappe/patches/v12_0/set_primary_key_in_series.py @@ -0,0 +1,21 @@ +import frappe + +def execute(): + #if current = 0, simply delete the key as it'll be recreated on first entry + frappe.db.sql('delete from `tabSeries` where current = 0') + duplicate_keys = frappe.db.sql(''' + SELECT name, max(current) as current + from + `tabSeries` + group by + name + having count(name) > 1 + ''', as_dict=True) + for row in duplicate_keys: + frappe.db.sql('delete from `tabSeries` where name = %(key)s', { + 'key': row.name + }) + if row.current: + frappe.db.sql('insert into `tabSeries`(`name`, `current`) values (%(name)s, %(current)s)', row) + frappe.db.commit() + frappe.db.sql('ALTER table `tabSeries` ADD PRIMARY KEY IF NOT EXISTS (name)') diff --git a/frappe/patches/v5_0/clear_website_group_and_notifications.py b/frappe/patches/v5_0/clear_website_group_and_notifications.py index 66bd68d5e1..bad50222a3 100644 --- a/frappe/patches/v5_0/clear_website_group_and_notifications.py +++ b/frappe/patches/v5_0/clear_website_group_and_notifications.py @@ -1,3 +1,4 @@ +from __future__ import unicode_literals import frappe def execute(): diff --git a/frappe/patches/v5_0/communication_parent.py b/frappe/patches/v5_0/communication_parent.py index 494c9b218b..2ea3b401c6 100644 --- a/frappe/patches/v5_0/communication_parent.py +++ b/frappe/patches/v5_0/communication_parent.py @@ -1,3 +1,4 @@ +from __future__ import unicode_literals import frappe def execute(): diff --git a/frappe/patches/v5_0/expire_old_scheduler_logs.py b/frappe/patches/v5_0/expire_old_scheduler_logs.py index 2d107d26f6..8b65ed5fb1 100644 --- a/frappe/patches/v5_0/expire_old_scheduler_logs.py +++ b/frappe/patches/v5_0/expire_old_scheduler_logs.py @@ -1,3 +1,4 @@ +from __future__ import unicode_literals import frappe def execute(): diff --git a/frappe/patches/v5_0/modify_session.py b/frappe/patches/v5_0/modify_session.py index 2aaf2da97b..f0e247a633 100644 --- a/frappe/patches/v5_0/modify_session.py +++ b/frappe/patches/v5_0/modify_session.py @@ -1,3 +1,4 @@ +from __future__ import unicode_literals import frappe def execute(): diff --git a/frappe/patches/v5_0/move_scheduler_last_event_to_system_settings.py b/frappe/patches/v5_0/move_scheduler_last_event_to_system_settings.py index 749067612b..0fa1dad1e5 100644 --- a/frappe/patches/v5_0/move_scheduler_last_event_to_system_settings.py +++ b/frappe/patches/v5_0/move_scheduler_last_event_to_system_settings.py @@ -1,3 +1,4 @@ +from __future__ import unicode_literals import frappe def execute(): diff --git a/frappe/patches/v5_0/rename_table_fieldnames.py b/frappe/patches/v5_0/rename_table_fieldnames.py index 79703bbba2..b716599f28 100644 --- a/frappe/patches/v5_0/rename_table_fieldnames.py +++ b/frappe/patches/v5_0/rename_table_fieldnames.py @@ -1,6 +1,7 @@ # 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.model.utils.rename_field import rename_field from frappe.modules import scrub, get_doctype_module diff --git a/frappe/patches/v5_0/update_shared.py b/frappe/patches/v5_0/update_shared.py index 4ba908b334..f2b77895d8 100644 --- a/frappe/patches/v5_0/update_shared.py +++ b/frappe/patches/v5_0/update_shared.py @@ -1,3 +1,4 @@ +from __future__ import unicode_literals import frappe import frappe.share diff --git a/frappe/patches/v6_0/document_type_rename.py b/frappe/patches/v6_0/document_type_rename.py index 0d9ca7da0e..16c7d34286 100644 --- a/frappe/patches/v6_0/document_type_rename.py +++ b/frappe/patches/v6_0/document_type_rename.py @@ -1,3 +1,4 @@ +from __future__ import unicode_literals import frappe def execute(): diff --git a/frappe/patches/v6_0/fix_ghana_currency.py b/frappe/patches/v6_0/fix_ghana_currency.py index 10365148b1..67f740d240 100644 --- a/frappe/patches/v6_0/fix_ghana_currency.py +++ b/frappe/patches/v6_0/fix_ghana_currency.py @@ -1,3 +1,4 @@ +from __future__ import unicode_literals def execute(): from frappe.geo.country_info import get_all diff --git a/frappe/patches/v6_0/make_task_log_folder.py b/frappe/patches/v6_0/make_task_log_folder.py index f557b5c8a1..87d6e4126f 100644 --- a/frappe/patches/v6_0/make_task_log_folder.py +++ b/frappe/patches/v6_0/make_task_log_folder.py @@ -1,3 +1,4 @@ +from __future__ import unicode_literals import frappe.utils, os def execute(): diff --git a/frappe/patches/v6_1/rename_file_data.py b/frappe/patches/v6_1/rename_file_data.py index 079e16cdcd..83152271eb 100644 --- a/frappe/patches/v6_1/rename_file_data.py +++ b/frappe/patches/v6_1/rename_file_data.py @@ -1,4 +1,4 @@ -from __future__ import print_function +from __future__ import print_function, unicode_literals import frappe def execute(): diff --git a/frappe/patches/v6_11/rename_field_in_email_account.py b/frappe/patches/v6_11/rename_field_in_email_account.py index 8462ab66ad..319b569802 100644 --- a/frappe/patches/v6_11/rename_field_in_email_account.py +++ b/frappe/patches/v6_11/rename_field_in_email_account.py @@ -1,3 +1,4 @@ +from __future__ import unicode_literals import frappe def execute(): diff --git a/frappe/patches/v6_15/set_username.py b/frappe/patches/v6_15/set_username.py index 4e62cad178..513ff3301d 100644 --- a/frappe/patches/v6_15/set_username.py +++ b/frappe/patches/v6_15/set_username.py @@ -1,3 +1,4 @@ +from __future__ import unicode_literals import frappe def execute(): diff --git a/frappe/patches/v6_2/rename_backup_manager.py b/frappe/patches/v6_2/rename_backup_manager.py index 974a4fe7d6..af02e55878 100644 --- a/frappe/patches/v6_2/rename_backup_manager.py +++ b/frappe/patches/v6_2/rename_backup_manager.py @@ -1,3 +1,4 @@ +from __future__ import unicode_literals import frappe def execute(): diff --git a/frappe/patches/v6_20x/remove_roles_from_website_user.py b/frappe/patches/v6_20x/remove_roles_from_website_user.py index 499ad5ddf4..a4d579a1f0 100644 --- a/frappe/patches/v6_20x/remove_roles_from_website_user.py +++ b/frappe/patches/v6_20x/remove_roles_from_website_user.py @@ -1,3 +1,4 @@ +from __future__ import unicode_literals import frappe def execute(): diff --git a/frappe/patches/v6_20x/set_allow_draft_for_print.py b/frappe/patches/v6_20x/set_allow_draft_for_print.py index 3c1008496e..90c15e22b2 100644 --- a/frappe/patches/v6_20x/set_allow_draft_for_print.py +++ b/frappe/patches/v6_20x/set_allow_draft_for_print.py @@ -1,3 +1,4 @@ +from __future__ import unicode_literals import frappe def execute(): diff --git a/frappe/patches/v6_20x/update_insert_after.py b/frappe/patches/v6_20x/update_insert_after.py index b7d5166d0b..5ebec52fc9 100644 --- a/frappe/patches/v6_20x/update_insert_after.py +++ b/frappe/patches/v6_20x/update_insert_after.py @@ -1,3 +1,4 @@ +from __future__ import unicode_literals import frappe, json def execute(): diff --git a/frappe/patches/v6_24/set_language_as_code.py b/frappe/patches/v6_24/set_language_as_code.py index 0679459783..d685fd7d0e 100644 --- a/frappe/patches/v6_24/set_language_as_code.py +++ b/frappe/patches/v6_24/set_language_as_code.py @@ -1,3 +1,4 @@ +from __future__ import unicode_literals import frappe from frappe.translate import get_lang_dict diff --git a/frappe/patches/v6_24/sync_desktop_icons.py b/frappe/patches/v6_24/sync_desktop_icons.py index a635990732..74f52e6056 100644 --- a/frappe/patches/v6_24/sync_desktop_icons.py +++ b/frappe/patches/v6_24/sync_desktop_icons.py @@ -1,3 +1,4 @@ +from __future__ import unicode_literals import frappe, json from frappe.desk.doctype.desktop_icon.desktop_icon import sync_from_app, get_user_copy diff --git a/frappe/patches/v7_0/add_communication_in_doc.py b/frappe/patches/v7_0/add_communication_in_doc.py index 1ec31be72d..92120634ef 100644 --- a/frappe/patches/v7_0/add_communication_in_doc.py +++ b/frappe/patches/v7_0/add_communication_in_doc.py @@ -1,3 +1,4 @@ +from __future__ import unicode_literals import frappe from frappe.core.doctype.communication.comment import update_comment_in_doc diff --git a/frappe/patches/v7_0/cleanup_list_settings.py b/frappe/patches/v7_0/cleanup_list_settings.py index dc918afb79..e03ff57406 100644 --- a/frappe/patches/v7_0/cleanup_list_settings.py +++ b/frappe/patches/v7_0/cleanup_list_settings.py @@ -1,3 +1,4 @@ +from __future__ import unicode_literals import frappe, json def execute(): diff --git a/frappe/patches/v7_0/create_private_file_folder.py b/frappe/patches/v7_0/create_private_file_folder.py index 51e3d9f07b..bd26917a78 100644 --- a/frappe/patches/v7_0/create_private_file_folder.py +++ b/frappe/patches/v7_0/create_private_file_folder.py @@ -1,3 +1,4 @@ +from __future__ import unicode_literals import frappe, os def execute(): diff --git a/frappe/patches/v7_0/desktop_icons_hidden_by_admin_as_blocked.py b/frappe/patches/v7_0/desktop_icons_hidden_by_admin_as_blocked.py index 269a8978d4..496af17cd2 100644 --- a/frappe/patches/v7_0/desktop_icons_hidden_by_admin_as_blocked.py +++ b/frappe/patches/v7_0/desktop_icons_hidden_by_admin_as_blocked.py @@ -1,3 +1,4 @@ +from __future__ import unicode_literals import frappe def execute(): diff --git a/frappe/patches/v7_0/re_route.py b/frappe/patches/v7_0/re_route.py index 46e4771855..cc36594ae8 100644 --- a/frappe/patches/v7_0/re_route.py +++ b/frappe/patches/v7_0/re_route.py @@ -1,3 +1,4 @@ +from __future__ import unicode_literals import frappe from frappe.model.base_document import get_controller diff --git a/frappe/patches/v7_0/rename_bulk_email_to_email_queue.py b/frappe/patches/v7_0/rename_bulk_email_to_email_queue.py index 7be9aa6a72..9a7a756144 100644 --- a/frappe/patches/v7_0/rename_bulk_email_to_email_queue.py +++ b/frappe/patches/v7_0/rename_bulk_email_to_email_queue.py @@ -1,3 +1,4 @@ +from __future__ import unicode_literals import frappe def execute(): diff --git a/frappe/patches/v7_0/rename_newsletter_list_to_email_group.py b/frappe/patches/v7_0/rename_newsletter_list_to_email_group.py index 059792d68e..79061d383c 100644 --- a/frappe/patches/v7_0/rename_newsletter_list_to_email_group.py +++ b/frappe/patches/v7_0/rename_newsletter_list_to_email_group.py @@ -1,3 +1,4 @@ +from __future__ import unicode_literals import frappe def execute(): diff --git a/frappe/patches/v7_0/set_user_fullname.py b/frappe/patches/v7_0/set_user_fullname.py index f2ddf43b5a..a7c6670f45 100644 --- a/frappe/patches/v7_0/set_user_fullname.py +++ b/frappe/patches/v7_0/set_user_fullname.py @@ -1,3 +1,4 @@ +from __future__ import unicode_literals import frappe def execute(): diff --git a/frappe/patches/v7_0/update_send_after_in_bulk_email.py b/frappe/patches/v7_0/update_send_after_in_bulk_email.py index 157b084255..1b08309b6a 100644 --- a/frappe/patches/v7_0/update_send_after_in_bulk_email.py +++ b/frappe/patches/v7_0/update_send_after_in_bulk_email.py @@ -1,3 +1,4 @@ +from __future__ import unicode_literals import frappe from frappe.utils import now_datetime diff --git a/frappe/patches/v7_1/rename_chinese_language_codes.py b/frappe/patches/v7_1/rename_chinese_language_codes.py index 858246faa2..1ed25a4959 100644 --- a/frappe/patches/v7_1/rename_chinese_language_codes.py +++ b/frappe/patches/v7_1/rename_chinese_language_codes.py @@ -1,3 +1,4 @@ +from __future__ import unicode_literals import frappe def execute(): diff --git a/frappe/patches/v7_1/rename_scheduler_log_to_error_log.py b/frappe/patches/v7_1/rename_scheduler_log_to_error_log.py index fdc6b0a44f..4d1a39538f 100644 --- a/frappe/patches/v7_1/rename_scheduler_log_to_error_log.py +++ b/frappe/patches/v7_1/rename_scheduler_log_to_error_log.py @@ -1,3 +1,4 @@ +from __future__ import unicode_literals import frappe def execute(): diff --git a/frappe/patches/v7_1/set_backup_limit.py b/frappe/patches/v7_1/set_backup_limit.py index f32c35ce0c..7b0a344305 100644 --- a/frappe/patches/v7_1/set_backup_limit.py +++ b/frappe/patches/v7_1/set_backup_limit.py @@ -3,7 +3,8 @@ from frappe.utils import cint import frappe def execute(): - backup_limit = frappe.db.get_single_value('System Settings', 'backup_limit') - - if cint(backup_limit) == 0: - frappe.db.set_value('System Settings', 'System Settings', 'backup_limit', 3) + frappe.reload_doctype('System Settings') + backup_limit = frappe.db.get_single_value('System Settings', 'backup_limit') + + if cint(backup_limit) == 0: + frappe.db.set_value('System Settings', 'System Settings', 'backup_limit', 3) diff --git a/frappe/patches/v7_1/sync_language_doctype.py b/frappe/patches/v7_1/sync_language_doctype.py index a3eda183b2..83d1a4f5a6 100644 --- a/frappe/patches/v7_1/sync_language_doctype.py +++ b/frappe/patches/v7_1/sync_language_doctype.py @@ -1,3 +1,4 @@ +from __future__ import unicode_literals import frappe from frappe.translate import get_lang_dict diff --git a/frappe/patches/v7_2/fix_email_queue_recipient.py b/frappe/patches/v7_2/fix_email_queue_recipient.py index 89aca69c91..645b17b5c9 100644 --- a/frappe/patches/v7_2/fix_email_queue_recipient.py +++ b/frappe/patches/v7_2/fix_email_queue_recipient.py @@ -1,3 +1,4 @@ +from __future__ import unicode_literals import frappe def execute(): diff --git a/frappe/patches/v7_2/merge_knowledge_base.py b/frappe/patches/v7_2/merge_knowledge_base.py index 2eb52acfd6..81ff98230b 100644 --- a/frappe/patches/v7_2/merge_knowledge_base.py +++ b/frappe/patches/v7_2/merge_knowledge_base.py @@ -1,3 +1,4 @@ +from __future__ import unicode_literals import frappe from frappe.patches.v7_0.re_route import update_routes diff --git a/frappe/patches/v7_2/remove_in_filter.py b/frappe/patches/v7_2/remove_in_filter.py index dcd62a45e7..36556d7c13 100644 --- a/frappe/patches/v7_2/remove_in_filter.py +++ b/frappe/patches/v7_2/remove_in_filter.py @@ -1,3 +1,4 @@ +from __future__ import unicode_literals import frappe def execute(): diff --git a/frappe/patches/v7_2/set_doctype_engine.py b/frappe/patches/v7_2/set_doctype_engine.py index fa914003f3..3a5cc384a2 100644 --- a/frappe/patches/v7_2/set_doctype_engine.py +++ b/frappe/patches/v7_2/set_doctype_engine.py @@ -1,3 +1,4 @@ +from __future__ import unicode_literals import frappe def execute(): diff --git a/frappe/patches/v7_2/set_in_standard_filter_property.py b/frappe/patches/v7_2/set_in_standard_filter_property.py index 9f0de7ebf2..1379ffd431 100644 --- a/frappe/patches/v7_2/set_in_standard_filter_property.py +++ b/frappe/patches/v7_2/set_in_standard_filter_property.py @@ -1,3 +1,4 @@ +from __future__ import unicode_literals import frappe def execute(): diff --git a/frappe/patches/v7_2/setup_custom_perms.py b/frappe/patches/v7_2/setup_custom_perms.py index f057e7aa0d..1b3b86236c 100644 --- a/frappe/patches/v7_2/setup_custom_perms.py +++ b/frappe/patches/v7_2/setup_custom_perms.py @@ -1,3 +1,4 @@ +from __future__ import unicode_literals import frappe from frappe.permissions import setup_custom_perms from frappe.core.page.permission_manager.permission_manager import get_standard_permissions diff --git a/frappe/patches/v7_2/setup_ldap_config.py b/frappe/patches/v7_2/setup_ldap_config.py index 670474dc64..31dd8ca6fe 100644 --- a/frappe/patches/v7_2/setup_ldap_config.py +++ b/frappe/patches/v7_2/setup_ldap_config.py @@ -1,3 +1,4 @@ +from __future__ import unicode_literals import frappe from frappe.utils import cint diff --git a/frappe/patches/v7_2/update_communications.py b/frappe/patches/v7_2/update_communications.py index b7a1b962f8..98c729ae41 100644 --- a/frappe/patches/v7_2/update_communications.py +++ b/frappe/patches/v7_2/update_communications.py @@ -1,3 +1,4 @@ +from __future__ import unicode_literals import frappe def execute(): diff --git a/frappe/patches/v7_2/update_feedback_request.py b/frappe/patches/v7_2/update_feedback_request.py index 37e77d9b15..68814e7a58 100644 --- a/frappe/patches/v7_2/update_feedback_request.py +++ b/frappe/patches/v7_2/update_feedback_request.py @@ -1,3 +1,4 @@ +from __future__ import unicode_literals import frappe def execute(): diff --git a/frappe/patches/v8_0/deprecate_integration_broker.py b/frappe/patches/v8_0/deprecate_integration_broker.py index b8201f1ca1..ad1a7d9571 100644 --- a/frappe/patches/v8_0/deprecate_integration_broker.py +++ b/frappe/patches/v8_0/deprecate_integration_broker.py @@ -1,3 +1,4 @@ +from __future__ import unicode_literals import frappe from frappe.integrations.utils import create_payment_gateway diff --git a/frappe/patches/v8_0/drop_in_dialog.py b/frappe/patches/v8_0/drop_in_dialog.py index b3ba15764f..231d757f26 100644 --- a/frappe/patches/v8_0/drop_in_dialog.py +++ b/frappe/patches/v8_0/drop_in_dialog.py @@ -1,3 +1,4 @@ +from __future__ import unicode_literals import frappe def execute(): diff --git a/frappe/patches/v8_0/drop_is_custom_from_docperm.py b/frappe/patches/v8_0/drop_is_custom_from_docperm.py index c4e457d813..4530dcd2e0 100644 --- a/frappe/patches/v8_0/drop_is_custom_from_docperm.py +++ b/frappe/patches/v8_0/drop_is_custom_from_docperm.py @@ -1,3 +1,4 @@ +from __future__ import unicode_literals import frappe def execute(): diff --git a/frappe/patches/v8_0/install_new_build_system_requirements.py b/frappe/patches/v8_0/install_new_build_system_requirements.py index 3d8843213a..536c2fcfb3 100644 --- a/frappe/patches/v8_0/install_new_build_system_requirements.py +++ b/frappe/patches/v8_0/install_new_build_system_requirements.py @@ -1,4 +1,4 @@ -from __future__ import print_function +from __future__ import print_function, unicode_literals from subprocess import Popen, call, PIPE def execute(): diff --git a/frappe/patches/v8_0/rename_listsettings_to_usersettings.py b/frappe/patches/v8_0/rename_listsettings_to_usersettings.py index f17e925cc3..584e4a1111 100644 --- a/frappe/patches/v8_0/rename_listsettings_to_usersettings.py +++ b/frappe/patches/v8_0/rename_listsettings_to_usersettings.py @@ -1,3 +1,4 @@ +from __future__ import unicode_literals from frappe.model.utils.user_settings import update_user_settings import frappe, json from six import iteritems diff --git a/frappe/patches/v8_0/rename_print_to_printing.py b/frappe/patches/v8_0/rename_print_to_printing.py index 171de9b59b..ecdbc3f7be 100644 --- a/frappe/patches/v8_0/rename_print_to_printing.py +++ b/frappe/patches/v8_0/rename_print_to_printing.py @@ -1,3 +1,4 @@ +from __future__ import unicode_literals import frappe def execute(): diff --git a/frappe/patches/v8_0/set_allow_traceback.py b/frappe/patches/v8_0/set_allow_traceback.py index 2b1e91a7ae..3eceb3e29c 100644 --- a/frappe/patches/v8_0/set_allow_traceback.py +++ b/frappe/patches/v8_0/set_allow_traceback.py @@ -1,3 +1,4 @@ +from __future__ import unicode_literals import frappe def execute(): diff --git a/frappe/patches/v8_0/setup_email_inbox.py b/frappe/patches/v8_0/setup_email_inbox.py index cb4156e935..8cd8b28116 100644 --- a/frappe/patches/v8_0/setup_email_inbox.py +++ b/frappe/patches/v8_0/setup_email_inbox.py @@ -1,3 +1,4 @@ +from __future__ import unicode_literals import frappe, json from frappe.core.doctype.user.user import ask_pass_update, setup_user_email_inbox diff --git a/frappe/patches/v8_0/update_global_search_table.py b/frappe/patches/v8_0/update_global_search_table.py index cb788da1e0..3c0a70155b 100644 --- a/frappe/patches/v8_0/update_global_search_table.py +++ b/frappe/patches/v8_0/update_global_search_table.py @@ -1,3 +1,4 @@ +from __future__ import unicode_literals import frappe def execute(): diff --git a/frappe/patches/v8_0/update_published_in_global_search.py b/frappe/patches/v8_0/update_published_in_global_search.py index 0a6595319a..a378f24732 100644 --- a/frappe/patches/v8_0/update_published_in_global_search.py +++ b/frappe/patches/v8_0/update_published_in_global_search.py @@ -1,3 +1,4 @@ +from __future__ import unicode_literals import frappe def execute(): diff --git a/frappe/patches/v8_0/update_records_in_global_search.py b/frappe/patches/v8_0/update_records_in_global_search.py index 4792ebec5a..dafa1e76d3 100644 --- a/frappe/patches/v8_0/update_records_in_global_search.py +++ b/frappe/patches/v8_0/update_records_in_global_search.py @@ -1,3 +1,4 @@ +from __future__ import unicode_literals import frappe from frappe.utils.global_search import get_doctypes_with_global_search, rebuild_for_doctype from frappe.utils import update_progress_bar diff --git a/frappe/patches/v8_1/delete_custom_docperm_if_doctype_not_exists.py b/frappe/patches/v8_1/delete_custom_docperm_if_doctype_not_exists.py index 6b0b731978..92b54edfd4 100644 --- a/frappe/patches/v8_1/delete_custom_docperm_if_doctype_not_exists.py +++ b/frappe/patches/v8_1/delete_custom_docperm_if_doctype_not_exists.py @@ -1,3 +1,4 @@ +from __future__ import unicode_literals import frappe def execute(): diff --git a/frappe/patches/v8_x/update_user_permission.py b/frappe/patches/v8_x/update_user_permission.py index 0f8045f48d..693b87c974 100644 --- a/frappe/patches/v8_x/update_user_permission.py +++ b/frappe/patches/v8_x/update_user_permission.py @@ -1,3 +1,4 @@ +from __future__ import unicode_literals import frappe def execute(): diff --git a/frappe/patches/v9_1/move_feed_to_activity_log.py b/frappe/patches/v9_1/move_feed_to_activity_log.py index 2d35e1e908..db46b4e419 100644 --- a/frappe/patches/v9_1/move_feed_to_activity_log.py +++ b/frappe/patches/v9_1/move_feed_to_activity_log.py @@ -1,3 +1,4 @@ +from __future__ import unicode_literals import frappe from frappe.utils.background_jobs import enqueue diff --git a/frappe/patches/v9_1/resave_domain_settings.py b/frappe/patches/v9_1/resave_domain_settings.py index 63ad68751d..1e54ad3aa5 100644 --- a/frappe/patches/v9_1/resave_domain_settings.py +++ b/frappe/patches/v9_1/resave_domain_settings.py @@ -1,3 +1,4 @@ +from __future__ import unicode_literals import frappe def execute(): diff --git a/frappe/patches/v9_1/revert_domain_settings.py b/frappe/patches/v9_1/revert_domain_settings.py index 1682651a51..a14b48dae6 100644 --- a/frappe/patches/v9_1/revert_domain_settings.py +++ b/frappe/patches/v9_1/revert_domain_settings.py @@ -1,3 +1,4 @@ +from __future__ import unicode_literals import frappe def execute(): diff --git a/frappe/permissions.py b/frappe/permissions.py index 57e8aa0812..abe5eca84d 100644 --- a/frappe/permissions.py +++ b/frappe/permissions.py @@ -27,7 +27,7 @@ def print_has_permission_check_logs(func): # print only if access denied if not result: msgprint(('
').join(frappe.flags['has_permission_check_logs'])) - del frappe.flags['has_permission_check_logs'] + frappe.flags.pop('has_permission_check_logs', None) return result return inner @@ -187,7 +187,9 @@ def get_role_permissions(doctype_meta, user=None): and ptype != 'create'): perms['if_owner'][ptype] = 1 # has no access if not owner - perms[ptype] = 0 + # only provide read access so that user is able to at-least access list + # (and the documents will be filtered based on owner sin further checks) + perms[ptype] = 1 if ptype == 'read' else 0 frappe.local.role_permissions[cache_key] = perms diff --git a/frappe/printing/doctype/print_settings/print_settings.py b/frappe/printing/doctype/print_settings/print_settings.py index 8043130358..2758f0aa9c 100644 --- a/frappe/printing/doctype/print_settings/print_settings.py +++ b/frappe/printing/doctype/print_settings/print_settings.py @@ -18,7 +18,7 @@ class PrintSettings(Document): printer_list = [] try: import cups - except ModuleNotFoundError: + except ImportError: frappe.throw("You need to install pycups to use this feature!") return try: diff --git a/frappe/printing/page/print_format_builder/print_format_builder_section.html b/frappe/printing/page/print_format_builder/print_format_builder_section.html index f5a96faede..cd173c4b40 100644 --- a/frappe/printing/page/print_format_builder/print_format_builder_section.html +++ b/frappe/printing/page/print_format_builder/print_format_builder_section.html @@ -1,4 +1,4 @@ -