From c5c9ae46e605977101ee6d5f53552d621306ded1 Mon Sep 17 00:00:00 2001 From: prssanna Date: Fri, 6 Mar 2020 19:46:20 +0530 Subject: [PATCH 1/5] feat: change fieldtype in db with customize form --- .../doctype/customize_form/customize_form.py | 32 +++++++++++++++++-- frappe/database/schema.py | 8 +++-- 2 files changed, 36 insertions(+), 4 deletions(-) diff --git a/frappe/custom/doctype/customize_form/customize_form.py b/frappe/custom/doctype/customize_form/customize_form.py index 8d47a075ba..b35bfddf76 100644 --- a/frappe/custom/doctype/customize_form/customize_form.py +++ b/frappe/custom/doctype/customize_form/customize_form.py @@ -166,11 +166,10 @@ class CustomizeForm(Document): self.flags.update_db = False self.flags.rebuild_doctype_for_global_search = False - + validate_fields_for_doctype(self.doc_type) self.set_property_setters() self.update_custom_fields() self.set_name_translation() - validate_fields_for_doctype(self.doc_type) if self.flags.update_db: frappe.db.updatedb(self.doc_type) @@ -362,13 +361,42 @@ class CustomizeForm(Document): def validate_fieldtype_change(self, df, old_value, new_value): allowed = False + self.check_length_for_fieldtypes = [] for allowed_changes in allowed_fieldtype_change: if (old_value in allowed_changes and new_value in allowed_changes): allowed = True + self.flags.update_db = True + if frappe.db.type_map.get(old_value)[1] > frappe.db.type_map.get(new_value)[1]: + + self.check_length_for_fieldtypes.append({'df': df, 'old_value': old_value}) + self.validate_fieldtype_length() break if not allowed: frappe.throw(_("Fieldtype cannot be changed from {0} to {1} in row {2}").format(old_value, new_value, df.idx)) + def validate_fieldtype_length(self): + for field in self.check_length_for_fieldtypes: + df = field.get('df') + max_length = frappe.db.type_map.get(df.fieldtype)[1] + fieldname = df.fieldname + docs = frappe.db.sql('''select name, {fieldname}, length({fieldname}) as len + from `tab{doctype}` + where length({fieldname}) > {max_length} + '''.format( + fieldname = fieldname, + doctype = self.doc_type, + max_length = max_length + ), as_dict = True) + links = [] + label = df.label + for doc in docs: + links.append(frappe.utils.get_link_to_form(self.doc_type, doc.name)) + links_str = ', '.join(links) + + if len(docs): + frappe.throw(_('Value for field {label} is too long in {links_str}. Length should be lesser than {max_length}') + .format(label=label, max_length=max_length, links_str=links_str), title='Data Too Long') + def reset_to_defaults(self): if not self.doc_type: return diff --git a/frappe/database/schema.py b/frappe/database/schema.py index 88cda9340b..73bdf32761 100644 --- a/frappe/database/schema.py +++ b/frappe/database/schema.py @@ -69,6 +69,7 @@ class DBTable: lengths = {} precisions = {} uniques = {} + fieldtype = '' # optional fields like _comments if not self.meta.istable: @@ -100,7 +101,7 @@ class DBTable: filters={ "doc_type": self.doctype, "doctype_or_field": "DocField", - "property": ["in", ["precision", "length", "unique"]] + "property": ["in", ["precision", "length", "unique", "fieldtype"]] }): if ps.property=="length": @@ -112,10 +113,13 @@ class DBTable: elif ps.property=="unique": uniques[ps.field_name] = cint(ps.value) + if ps.property=="fieldtype": + fieldtype = ps.value + for f in fl: self.columns[f['fieldname']] = DbColumn(self, f['fieldname'], - f['fieldtype'], + fieldtype or f['fieldtype'], lengths.get(f["fieldname"]) or f.get('length'), f.get('default'), f.get('search_index'), From 7bb014ee9a4a7b61c8ccf13ab5e84b8b5c5fe5a1 Mon Sep 17 00:00:00 2001 From: prssanna Date: Sat, 7 Mar 2020 15:15:12 +0530 Subject: [PATCH 2/5] fix: update db type map --- frappe/custom/doctype/customize_form/customize_form.py | 10 ++++++---- frappe/database/mariadb/database.py | 4 ++-- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/frappe/custom/doctype/customize_form/customize_form.py b/frappe/custom/doctype/customize_form/customize_form.py index b35bfddf76..a38e8f4fa7 100644 --- a/frappe/custom/doctype/customize_form/customize_form.py +++ b/frappe/custom/doctype/customize_form/customize_form.py @@ -166,10 +166,10 @@ class CustomizeForm(Document): self.flags.update_db = False self.flags.rebuild_doctype_for_global_search = False - validate_fields_for_doctype(self.doc_type) self.set_property_setters() self.update_custom_fields() self.set_name_translation() + validate_fields_for_doctype(self.doc_type) if self.flags.update_db: frappe.db.updatedb(self.doc_type) @@ -365,11 +365,11 @@ class CustomizeForm(Document): for allowed_changes in allowed_fieldtype_change: if (old_value in allowed_changes and new_value in allowed_changes): allowed = True - self.flags.update_db = True if frappe.db.type_map.get(old_value)[1] > frappe.db.type_map.get(new_value)[1]: - self.check_length_for_fieldtypes.append({'df': df, 'old_value': old_value}) self.validate_fieldtype_length() + else: + self.flags.update_db = True break if not allowed: frappe.throw(_("Fieldtype cannot be changed from {0} to {1} in row {2}").format(old_value, new_value, df.idx)) @@ -394,8 +394,10 @@ class CustomizeForm(Document): links_str = ', '.join(links) if len(docs): - frappe.throw(_('Value for field {label} is too long in {links_str}. Length should be lesser than {max_length}') + frappe.throw(_('Value for field {label} is too long in {links_str}. Length should be lesser than {max_length} characters') .format(label=label, max_length=max_length, links_str=links_str), title='Data Too Long') + else: + self.flags.update_db = True def reset_to_defaults(self): if not self.doc_type: diff --git a/frappe/database/mariadb/database.py b/frappe/database/mariadb/database.py index cd053569f0..926425f857 100644 --- a/frappe/database/mariadb/database.py +++ b/frappe/database/mariadb/database.py @@ -33,7 +33,7 @@ class MariaDBDatabase(Database): 'Float': ('decimal', '18,6'), 'Percent': ('decimal', '18,6'), 'Check': ('int', '1'), - 'Small Text': ('text', ''), + 'Small Text': ('text', 65535), 'Long Text': ('longtext', ''), 'Code': ('longtext', ''), 'Text Editor': ('longtext', ''), @@ -42,7 +42,7 @@ class MariaDBDatabase(Database): 'Date': ('date', ''), 'Datetime': ('datetime', '6'), 'Time': ('time', '6'), - 'Text': ('text', ''), + 'Text': ('text', 65535), 'Data': ('varchar', self.VARCHAR_LEN), 'Link': ('varchar', self.VARCHAR_LEN), 'Dynamic Link': ('varchar', self.VARCHAR_LEN), From a8861c8ed40a07f2136aa564954ad17967bbc543 Mon Sep 17 00:00:00 2001 From: prssanna Date: Fri, 13 Mar 2020 15:14:54 +0530 Subject: [PATCH 3/5] fix: code formatting --- .../custom/doctype/customize_form/customize_form.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/frappe/custom/doctype/customize_form/customize_form.py b/frappe/custom/doctype/customize_form/customize_form.py index a38e8f4fa7..61d00984fd 100644 --- a/frappe/custom/doctype/customize_form/customize_form.py +++ b/frappe/custom/doctype/customize_form/customize_form.py @@ -379,9 +379,10 @@ class CustomizeForm(Document): df = field.get('df') max_length = frappe.db.type_map.get(df.fieldtype)[1] fieldname = df.fieldname - docs = frappe.db.sql('''select name, {fieldname}, length({fieldname}) as len - from `tab{doctype}` - where length({fieldname}) > {max_length} + docs = frappe.db.sql(''' + SELECT name, {fieldname}, LENGTH({fieldname}) AS len + FROM `tab{doctype}` + WHERE LENGTH({fieldname}) > {max_length} '''.format( fieldname = fieldname, doctype = self.doc_type, @@ -394,8 +395,8 @@ class CustomizeForm(Document): links_str = ', '.join(links) if len(docs): - frappe.throw(_('Value for field {label} is too long in {links_str}. Length should be lesser than {max_length} characters') - .format(label=label, max_length=max_length, links_str=links_str), title='Data Too Long') + frappe.throw(_('Value for field {0} is too long in {1}. Length should be lesser than {2} characters') + .format(frappe.bold(label), links_str, frappe.bold(max_length)), title='Data Too Long') else: self.flags.update_db = True From 83677236f55cc0b58a0ab42b7e87d1a0257e09f3 Mon Sep 17 00:00:00 2001 From: prssanna Date: Fri, 13 Mar 2020 15:23:17 +0530 Subject: [PATCH 4/5] fix: set is_minimizable as true for error dialog --- frappe/custom/doctype/customize_form/customize_form.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frappe/custom/doctype/customize_form/customize_form.py b/frappe/custom/doctype/customize_form/customize_form.py index 61d00984fd..0cef12fd7e 100644 --- a/frappe/custom/doctype/customize_form/customize_form.py +++ b/frappe/custom/doctype/customize_form/customize_form.py @@ -396,7 +396,7 @@ class CustomizeForm(Document): if len(docs): frappe.throw(_('Value for field {0} is too long in {1}. Length should be lesser than {2} characters') - .format(frappe.bold(label), links_str, frappe.bold(max_length)), title='Data Too Long') + .format(frappe.bold(label), links_str, frappe.bold(max_length)), title='Data Too Long', is_minimizable=True) else: self.flags.update_db = True From 35ae0244ae7c38388b188b05d5758ff683e2c5b1 Mon Sep 17 00:00:00 2001 From: Prssanna Desai Date: Fri, 13 Mar 2020 17:18:02 +0530 Subject: [PATCH 5/5] fix: translate dialog title Co-Authored-By: Suraj Shetty <13928957+surajshetty3416@users.noreply.github.com> --- frappe/custom/doctype/customize_form/customize_form.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/frappe/custom/doctype/customize_form/customize_form.py b/frappe/custom/doctype/customize_form/customize_form.py index 0cef12fd7e..c8d1bb18b4 100644 --- a/frappe/custom/doctype/customize_form/customize_form.py +++ b/frappe/custom/doctype/customize_form/customize_form.py @@ -394,11 +394,11 @@ class CustomizeForm(Document): links.append(frappe.utils.get_link_to_form(self.doc_type, doc.name)) links_str = ', '.join(links) - if len(docs): - frappe.throw(_('Value for field {0} is too long in {1}. Length should be lesser than {2} characters') - .format(frappe.bold(label), links_str, frappe.bold(max_length)), title='Data Too Long', is_minimizable=True) - else: - self.flags.update_db = True + if docs: + frappe.throw(_('Value for field {0} is too long in {1}. Length should be lesser than {2} characters') + .format(frappe.bold(label), links_str, frappe.bold(max_length)), title=_('Data Too Long'), is_minimizable=len(docs) > 1) + + self.flags.update_db = True def reset_to_defaults(self): if not self.doc_type: