From e150d99ff02e1a000d2a5737b07b10b63b2d33b0 Mon Sep 17 00:00:00 2001 From: naveen <172697+naveensrinivasan@users.noreply.github.com> Date: Thu, 9 Jun 2022 01:29:31 +0000 Subject: [PATCH 01/10] chore: Included githubactions in the dependabot config This should help with keeping the GitHub actions updated on new releases. This will also help with keeping it secure. Dependabot helps in keeping the supply chain secure https://docs.github.com/en/code-security/dependabot GitHub actions up to date https://docs.github.com/en/code-security/dependabot/working-with-dependabot/keeping-your-actions-up-to-date-with-dependabot https://github.com/ossf/scorecard/blob/main/docs/checks.md#dependency-update-tool Signed-off-by: naveen <172697+naveensrinivasan@users.noreply.github.com> --- .github/dependabot.yml | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .github/dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000000..5ace4600a1 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,6 @@ +version: 2 +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" From 42f3013699d5cf1cb61021937a11d2b14ed365e6 Mon Sep 17 00:00:00 2001 From: Shariq Ansari Date: Thu, 16 Jun 2022 11:35:58 +0530 Subject: [PATCH 02/10] fix: daterange value not updating --- frappe/public/js/frappe/form/controls/date_range.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/frappe/public/js/frappe/form/controls/date_range.js b/frappe/public/js/frappe/form/controls/date_range.js index 02cac1cf28..a1e796604f 100644 --- a/frappe/public/js/frappe/form/controls/date_range.js +++ b/frappe/public/js/frappe/form/controls/date_range.js @@ -41,7 +41,8 @@ frappe.ui.form.ControlDateRange = class ControlDateRange extends frappe.ui.form. this.set_mandatory && this.set_mandatory(value); } parse(value) { - if (!value || (value && !value.includes('to'))) return value; + if (value == undefined || typeof value == 'object') return value; + // replace the separator (which can be in user language) with comma const to = __('{0} to {1}').replace('{0}', '').replace('{1}', ''); value = value && value.replace(to, ','); From 1298b39bb3877c72b5dbbcf30041ad724bac56a9 Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Thu, 16 Jun 2022 12:07:19 +0530 Subject: [PATCH 03/10] ci: Add one more instance for faster UI tests execution --- .github/workflows/ui-tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ui-tests.yml b/.github/workflows/ui-tests.yml index 06ad921a6a..3850f33627 100644 --- a/.github/workflows/ui-tests.yml +++ b/.github/workflows/ui-tests.yml @@ -21,7 +21,7 @@ jobs: strategy: fail-fast: false matrix: - containers: [1, 2] + containers: [1, 2, 3] name: UI Tests (Cypress) From 6cebacaf6fad3a534484884ae3e35192b42d29ad Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Thu, 16 Jun 2022 12:07:55 +0530 Subject: [PATCH 04/10] ci: Update mergify.yml --- .mergify.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.mergify.yml b/.mergify.yml index 97df91a927..d9896df921 100644 --- a/.mergify.yml +++ b/.mergify.yml @@ -21,13 +21,13 @@ pull_request_rules: - name: Automatic merge on CI success and review conditions: - status-success=Sider - - status-success=Semantic Pull Request - status-success=Python Unit Tests (MariaDB) (1) - status-success=Python Unit Tests (MariaDB) (2) - status-success=Python Unit Tests (Postgres) (1) - status-success=Python Unit Tests (Postgres) (2) - status-success=UI Tests (Cypress) (1) - status-success=UI Tests (Cypress) (2) + - status-success=UI Tests (Cypress) (3) - status-success=security/snyk (frappe) - label!=dont-merge - label!=squash @@ -44,6 +44,7 @@ pull_request_rules: - status-success=Python Unit Tests (Postgres) (2) - status-success=UI Tests (Cypress) (1) - status-success=UI Tests (Cypress) (2) + - status-success=UI Tests (Cypress) (3) - status-success=security/snyk (frappe) - label!=dont-merge - label=squash From d9e848ef882721427466601b8768f1a2bbb295fe Mon Sep 17 00:00:00 2001 From: Shariq Ansari Date: Thu, 16 Jun 2022 13:00:34 +0530 Subject: [PATCH 05/10] test: added UI test for date range control --- cypress/integration/control_date_range.js | 42 +++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 cypress/integration/control_date_range.js diff --git a/cypress/integration/control_date_range.js b/cypress/integration/control_date_range.js new file mode 100644 index 0000000000..6f26b35f84 --- /dev/null +++ b/cypress/integration/control_date_range.js @@ -0,0 +1,42 @@ +context('Date Range Control', () => { + before(() => { + cy.login(); + cy.visit('/app'); + }); + + function get_dialog() { + return cy.dialog({ + title: 'Date Range', + fields: [{ + "label": "Date Range", + "fieldname": "date_range", + "fieldtype": "Date Range", + }] + }); + } + + it('Selecting a date range from the datepicker', () => { + cy.clear_dialogs(); + cy.clear_datepickers(); + + get_dialog().as('dialog'); + cy.get_field('date_range', 'Date Range').click(); + cy.get('.datepicker--nav-title').click(); + cy.get('.datepicker--nav-title').click({force: true}); + + //Inputing date range values in the date range field + cy.get('.datepicker--years > .datepicker--cells > .datepicker--cell[data-year=2020]').click(); + cy.get('.datepicker--months > .datepicker--cells > .datepicker--cell[data-month=0]').click(); + cy.get('.datepicker--cell[data-date=1]:first').click({force: true}); + cy.get('.datepicker--cell[data-date=15]:first').click({force: true}); + + // Verify if the selected date range values is set in the date range field + cy.window() + .its('cur_dialog') + .then(dialog => { + let date_range = dialog.get_value("date_range"); + expect(date_range[0]).to.equal('2020-01-01'); + expect(date_range[1]).to.equal('2020-01-15'); + }); + }); +}); \ No newline at end of file From 782fb801ecf63bef43b886968c131463a9ca0f1c Mon Sep 17 00:00:00 2001 From: phot0n Date: Thu, 16 Jun 2022 14:28:04 +0530 Subject: [PATCH 06/10] fix: ignore if integration_type column doesn't exist (for direct v14 installations) for integration request patch --- frappe/patches/v14_0/update_integration_request.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/frappe/patches/v14_0/update_integration_request.py b/frappe/patches/v14_0/update_integration_request.py index 7d491461e3..d067411166 100644 --- a/frappe/patches/v14_0/update_integration_request.py +++ b/frappe/patches/v14_0/update_integration_request.py @@ -3,6 +3,10 @@ import frappe def execute(): doctype = "Integration Request" + + if not frappe.db.has_column(doctype, "integration_type"): + return + frappe.db.set_value( doctype, {"integration_type": "Remote", "integration_request_service": ("!=", "PayPal")}, From 27b0b3669dd6e786a4eb1d026a811bdf04720b3e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 16 Jun 2022 10:24:59 +0000 Subject: [PATCH 07/10] build(deps): bump bruceadams/get-release from 1.2.0 to 1.2.3 Bumps [bruceadams/get-release](https://github.com/bruceadams/get-release) from 1.2.0 to 1.2.3. - [Release notes](https://github.com/bruceadams/get-release/releases) - [Commits](https://github.com/bruceadams/get-release/compare/v1.2.0...v1.2.3) --- updated-dependencies: - dependency-name: bruceadams/get-release dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/publish-assets-releases.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish-assets-releases.yml b/.github/workflows/publish-assets-releases.yml index 2582632fa0..faf41ed23e 100644 --- a/.github/workflows/publish-assets-releases.yml +++ b/.github/workflows/publish-assets-releases.yml @@ -36,7 +36,7 @@ jobs: - name: Get release id: get_release - uses: bruceadams/get-release@v1.2.0 + uses: bruceadams/get-release@v1.2.3 - name: Upload built Assets to Release uses: actions/upload-release-asset@v1.0.2 From 86f94654325874aa2ed22d09ec208cb74fb4b403 Mon Sep 17 00:00:00 2001 From: Michelle Alva <50285544+michellealva@users.noreply.github.com> Date: Thu, 16 Jun 2022 16:16:00 +0530 Subject: [PATCH 08/10] chore: typo --- frappe/core/page/permission_manager/permission_manager.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frappe/core/page/permission_manager/permission_manager.js b/frappe/core/page/permission_manager/permission_manager.js index cb218b2eae..8a06a9aac5 100644 --- a/frappe/core/page/permission_manager/permission_manager.js +++ b/frappe/core/page/permission_manager/permission_manager.js @@ -284,7 +284,7 @@ frappe.PermissionEngine = class PermissionEngine { } setup_if_owner(d, role_cell) { - this.add_check(role_cell, d, "if_owner", "Only If Creator") + this.add_check(role_cell, d, "if_owner", "Only if Creator") .removeClass("col-md-4") .css({ "margin-top": "15px" }); } From 335edc14f3b66cd34c97deab0e0f807d71afe723 Mon Sep 17 00:00:00 2001 From: Ritwik Puri Date: Thu, 16 Jun 2022 20:25:01 +0530 Subject: [PATCH 09/10] fix: number card ui inconsistencies (#17160) --- frappe/desk/doctype/number_card/number_card.json | 5 +++-- frappe/desk/doctype/number_card/number_card.py | 9 ++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/frappe/desk/doctype/number_card/number_card.json b/frappe/desk/doctype/number_card/number_card.json index 7975d878ba..ab33715d12 100644 --- a/frappe/desk/doctype/number_card/number_card.json +++ b/frappe/desk/doctype/number_card/number_card.json @@ -51,7 +51,7 @@ "options": "Count\nSum\nAverage\nMinimum\nMaximum" }, { - "depends_on": "eval: doc.function !== 'Count'", + "depends_on": "eval: doc.type === 'Document Type' && doc.function !== 'Count'", "fieldname": "aggregate_function_based_on", "fieldtype": "Select", "label": "Aggregate Function Based On", @@ -192,6 +192,7 @@ }, { "description": "The document type selected is a child table, so the parent document type is required.", + "depends_on": "eval: doc.type === 'Document Type'", "fieldname": "parent_document_type", "fieldtype": "Link", "label": "Parent Document Type", @@ -199,7 +200,7 @@ } ], "links": [], - "modified": "2022-03-10 15:34:38.210910", + "modified": "2022-06-12 15:34:38.210910", "modified_by": "Administrator", "module": "Desk", "name": "Number Card", diff --git a/frappe/desk/doctype/number_card/number_card.py b/frappe/desk/doctype/number_card/number_card.py index d6d4f00b69..2290e49656 100644 --- a/frappe/desk/doctype/number_card/number_card.py +++ b/frappe/desk/doctype/number_card/number_card.py @@ -26,11 +26,10 @@ class NumberCard(Document): if not (self.document_type and self.function): frappe.throw(_("Document Type and Function are required to create a number card")) - if ( - self.document_type - and frappe.get_meta(self.document_type).istable - and not self.parent_document_type - ): + if self.function != "Count" and not self.aggregate_function_based_on: + frappe.throw(_("Aggregate Field is required to create a number card")) + + if frappe.get_meta(self.document_type).istable and not self.parent_document_type: frappe.throw(_("Parent Document Type is required to create a number card")) elif self.type == "Report": From 6d6a67e9e322abd831d9669dc93c54c0b14dd833 Mon Sep 17 00:00:00 2001 From: Himanshu Date: Fri, 17 Jun 2022 12:07:07 +0530 Subject: [PATCH 10/10] feat: set image as footer in letter head (#17119) * feat: set image as footer in letter head * fix: do not hide footer section * fix: hide footer source * style: black * fix: reduce code for setting image as html * fix: Force system admin role only if active * fix(ui): tab refresh was not implemented * fix(minor): Onboarding: add option to view list view in create action * fix(minor): js lint * fix: allow All to select a User * test: user permissions affecting User * refactor: filter_dynamic_link_doctypes API * Added typing, better variable naming * Remove unnecessary re-iterations * Optimize queries and membership processing * perf: Check query type via is_query_type * chore: Drop duplicate get_frontmatter definition * perf: Login Page Improves performance 3x - from 0.047s to 0.017s * Use frappe.get_*_settings to query table once * Use cached LDAP Settings' document via get_ldap_client_settings * Use single get_all to query all Social Login providers and related data * Skip provider if client_secret doesn't exist * perf: About Us Settings Use cached document for building /about page * perf: App Page Reduced time taken for get_context to execute from 0.035s to 0.02s (75% reduction) * perf: Patch qb only once - not on every init * perf: Fetch and cache entire settings' dicts * refactor!: frappe.db.get_singles_dict * Cast single's values as their fieldtypes before returning * Support previously dead debug parameter * Consider single with no meta as non-existent; skip query Decided to go ahead with the breaking change given the nature of the existing usages of get_singles_dict :crie: * ci: Run tests bypassing roulette with labels "Run UI Tests", "Run Server Tests" * test: Scheduler tests cleanup * chore: linter changes * chore: linter changes * chore: linter changes * fix: set HTML as default to keep existing formats working * refactor: no **kwargs Co-authored-by: Raffael Meyer <14891507+barredterra@users.noreply.github.com> Co-authored-by: Deepesh Garg Co-authored-by: Rushabh Mehta Co-authored-by: Gavin D'souza --- .../doctype/letter_head/letter_head.json | 48 +++++++++++++- .../doctype/letter_head/letter_head.py | 62 ++++++++++++++----- 2 files changed, 92 insertions(+), 18 deletions(-) diff --git a/frappe/printing/doctype/letter_head/letter_head.json b/frappe/printing/doctype/letter_head/letter_head.json index f723a6b489..d49b65ab36 100644 --- a/frappe/printing/doctype/letter_head/letter_head.json +++ b/frappe/printing/doctype/letter_head/letter_head.json @@ -9,6 +9,7 @@ "field_order": [ "letter_head_name", "source", + "footer_source", "column_break_3", "disabled", "is_default", @@ -20,7 +21,12 @@ "header_section", "content", "footer_section", - "footer" + "footer", + "footer_image_section", + "footer_image", + "footer_image_height", + "footer_image_width", + "footer_align" ], "fields": [ { @@ -93,7 +99,7 @@ "oldfieldtype": "Text Editor" }, { - "collapsible": 1, + "depends_on": "eval:doc.footer_source==='HTML' && doc.letter_head_name", "fieldname": "footer_section", "fieldtype": "Section Break", "label": "Footer" @@ -121,13 +127,48 @@ "fieldname": "image_width", "fieldtype": "Float", "label": "Image Width" + }, + { + "depends_on": "eval:doc.footer_source==='Image' && doc.letter_head_name", + "fieldname": "footer_image_section", + "fieldtype": "Section Break", + "label": "Footer Image" + }, + { + "fieldname": "footer_image", + "fieldtype": "Attach Image", + "label": "Image" + }, + { + "fieldname": "footer_image_height", + "fieldtype": "Float", + "label": "Image Height" + }, + { + "fieldname": "footer_image_width", + "fieldtype": "Float", + "label": "Image Width" + }, + { + "fieldname": "footer_align", + "fieldtype": "Select", + "label": "Align", + "options": "Left\nRight\nCenter" + }, + { + "default": "HTML", + "depends_on": "letter_head_name", + "fieldname": "footer_source", + "fieldtype": "Select", + "label": "Footer Based On", + "options": "Image\nHTML" } ], "icon": "fa fa-font", "idx": 1, "links": [], "max_attachments": 3, - "modified": "2021-10-03 14:37:58.314696", + "modified": "2022-06-16 23:10:46.852116", "modified_by": "Administrator", "module": "Printing", "name": "Letter Head", @@ -152,5 +193,6 @@ ], "sort_field": "modified", "sort_order": "ASC", + "states": [], "track_changes": 1 } \ No newline at end of file diff --git a/frappe/printing/doctype/letter_head/letter_head.py b/frappe/printing/doctype/letter_head/letter_head.py index 98c2fc7c2b..9edd84a425 100644 --- a/frappe/printing/doctype/letter_head/letter_head.py +++ b/frappe/printing/doctype/letter_head/letter_head.py @@ -26,21 +26,53 @@ class LetterHead(Document): def set_image(self): if self.source == "Image": - if self.image and is_image(self.image): - self.image_width = flt(self.image_width) - self.image_height = flt(self.image_height) - dimension = "width" if self.image_width > self.image_height else "height" - dimension_value = self.get("image_" + dimension) - self.content = f""" -
- {self.name} -
- """ - frappe.msgprint(frappe._("Header HTML set from attachment {0}").format(self.image), alert=True) - else: - frappe.msgprint( - frappe._("Please attach an image file to set HTML"), alert=True, indicator="orange" - ) + self.set_image_as_html( + field="image", + width="image_width", + height="image_height", + align="align", + html_field="content", + dimension_prefix="image_", + success_msg=_("Header HTML set from attachment {0}").format(self.image), + failure_msg=_("Please attach an image file to set HTML for Letter Head."), + ) + + if self.footer_source == "Image": + self.set_image_as_html( + field="footer_image", + width="footer_image_width", + height="footer_image_height", + align="footer_align", + html_field="footer", + dimension_prefix="footer_image_", + success_msg=_("Footer HTML set from attachment {0}").format(self.footer_image), + failure_msg=_("Please attach an image file to set HTML for Footer."), + ) + + def set_image_as_html( + self, field, width, height, dimension_prefix, align, html_field, success_msg, failure_msg + ): + if not self.get(field) or not is_image(self.get(field)): + frappe.msgprint(failure_msg, alert=True, indicator="orange") + return + + self.set(width, flt(self.get(width))) + self.set(height, flt(self.get(height))) + + # To preserve the aspect ratio of the image, apply constraints only on + # the greater dimension and allow the other to scale accordingly + dimension = "width" if width > height else "height" + dimension_value = self.get(f"{dimension_prefix}{dimension}") + + self.set( + html_field, + f"""
+{self.get( +
""", + ) + + frappe.msgprint(success_msg, alert=True) def on_update(self): self.set_as_default()