diff --git a/cypress/integration/control_rating.js b/cypress/integration/control_rating.js index 592ed87004..b98e1d0845 100644 --- a/cypress/integration/control_rating.js +++ b/cypress/integration/control_rating.js @@ -10,6 +10,7 @@ context('Control Rating', () => { fields: [{ 'fieldname': 'rate', 'fieldtype': 'Rating', + 'options': 7 }] }); } @@ -40,4 +41,14 @@ context('Control Rating', () => { .invoke('trigger', 'mouseleave') .should('not.have.class', 'star-hover'); }); + + it('check number of stars in rating', () => { + get_dialog_with_rating(); + + cy.get('div.rating') + .first() + .children('svg') + .should('have.length', 7); + }); + }); diff --git a/frappe/core/doctype/doctype/doctype.py b/frappe/core/doctype/doctype/doctype.py index a6a81cb195..3b8dcc8277 100644 --- a/frappe/core/doctype/doctype/doctype.py +++ b/frappe/core/doctype/doctype/doctype.py @@ -1074,6 +1074,11 @@ def validate_fields(meta): if getattr(docfield, 'max_height', None) and (docfield.max_height[-2:] not in ('px', 'em')): frappe.throw('Max for {} height must be in px, em, rem'.format(frappe.bold(docfield.fieldname))) + def check_no_of_ratings(docfield): + if docfield.fieldtype == "Rating": + if docfield.options and (int(docfield.options) > 10 or int(docfield.options) < 3): + frappe.throw(_('Options for Rating field can range from 3 to 10')) + fields = meta.get("fields") fieldname_list = [d.fieldname for d in fields] @@ -1107,6 +1112,7 @@ def validate_fields(meta): scrub_fetch_from(d) validate_data_field_type(d) check_max_height(d) + check_no_of_ratings(d) check_fold(fields) check_search_fields(meta, fields) diff --git a/frappe/database/mariadb/database.py b/frappe/database/mariadb/database.py index 2f6d640743..afd912bc6b 100644 --- a/frappe/database/mariadb/database.py +++ b/frappe/database/mariadb/database.py @@ -43,7 +43,7 @@ class MariaDBDatabase(Database): 'Dynamic Link': ('varchar', self.VARCHAR_LEN), 'Password': ('text', ''), 'Select': ('varchar', self.VARCHAR_LEN), - 'Rating': ('int', '1'), + 'Rating': ('decimal', '3,2'), 'Read Only': ('varchar', self.VARCHAR_LEN), 'Attach': ('text', ''), 'Attach Image': ('text', ''), diff --git a/frappe/database/postgres/database.py b/frappe/database/postgres/database.py index bfa5515111..3cea1440cf 100644 --- a/frappe/database/postgres/database.py +++ b/frappe/database/postgres/database.py @@ -53,7 +53,7 @@ class PostgresDatabase(Database): 'Dynamic Link': ('varchar', self.VARCHAR_LEN), 'Password': ('text', ''), 'Select': ('varchar', self.VARCHAR_LEN), - 'Rating': ('smallint', None), + 'Rating': ('decimal', '3,2'), 'Read Only': ('varchar', self.VARCHAR_LEN), 'Attach': ('text', ''), 'Attach Image': ('text', ''), diff --git a/frappe/patches.txt b/frappe/patches.txt index 3078159c3d..f2f13b0b15 100644 --- a/frappe/patches.txt +++ b/frappe/patches.txt @@ -187,3 +187,4 @@ frappe.patches.v14_0.copy_mail_data #08.03.21 frappe.patches.v14_0.update_workspace2 # 20.09.2021 frappe.patches.v14_0.update_github_endpoints #08-11-2021 frappe.patches.v14_0.remove_db_aggregation +frappe.patches.v14_0.save_ratings_in_fraction diff --git a/frappe/patches/v14_0/save_ratings_in_fraction.py b/frappe/patches/v14_0/save_ratings_in_fraction.py new file mode 100644 index 0000000000..bdc5dfee3d --- /dev/null +++ b/frappe/patches/v14_0/save_ratings_in_fraction.py @@ -0,0 +1,12 @@ +import frappe + +def execute(): + rating_fields = frappe.get_all("DocField", fields=["parent", "fieldname"], filters={"fieldtype": "Rating"}) + + custom_rating_fields = frappe.get_all("Custom Field", fields=["dt", "fieldname"], filters={"fieldtype": "Rating"}) + + for field in rating_fields + custom_rating_fields: + doctype_name = field.get("parent") or field.get("dt") + doctype = frappe.qb.DocType(doctype_name) + field = field.fieldname + (frappe.qb.update(doctype_name).set(doctype[field], doctype[field]/5)).run() diff --git a/frappe/public/js/frappe/form/controls/base_control.js b/frappe/public/js/frappe/form/controls/base_control.js index 58442ec371..7af0705e78 100644 --- a/frappe/public/js/frappe/form/controls/base_control.js +++ b/frappe/public/js/frappe/form/controls/base_control.js @@ -186,7 +186,6 @@ frappe.ui.form.Control = class BaseControl { } ]); }; - value = this.validate(value); if (value && value.then) { // got a promise diff --git a/frappe/public/js/frappe/form/controls/rating.js b/frappe/public/js/frappe/form/controls/rating.js index 1198d33995..fa7b65f67b 100644 --- a/frappe/public/js/frappe/form/controls/rating.js +++ b/frappe/public/js/frappe/form/controls/rating.js @@ -2,11 +2,13 @@ frappe.ui.form.ControlRating = class ControlRating extends frappe.ui.form.Contro make_input() { super.make_input(); let stars = ''; - [1, 2, 3, 4, 5].forEach(i => { + let number_of_stars = this.df.options || 5; + Array.from({length: cint(number_of_stars)}, (_, i) => i + 1).forEach(i => { stars += ``; }); + const star_template = `