Merge branch 'develop' into mariadb-client-refactor
This commit is contained in:
commit
2a1a2deebf
12 changed files with 158 additions and 30 deletions
6
.github/dependabot.yml
vendored
Normal file
6
.github/dependabot.yml
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: "github-actions"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
|
|
@ -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
|
||||
|
|
|
|||
2
.github/workflows/ui-tests.yml
vendored
2
.github/workflows/ui-tests.yml
vendored
|
|
@ -21,7 +21,7 @@ jobs:
|
|||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
containers: [1, 2]
|
||||
containers: [1, 2, 3]
|
||||
|
||||
name: UI Tests (Cypress)
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
42
cypress/integration/control_date_range.js
Normal file
42
cypress/integration/control_date_range.js
Normal file
|
|
@ -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');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -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" });
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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":
|
||||
|
|
|
|||
|
|
@ -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")},
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
@ -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"""
|
||||
<div style="text-align: {self.align.lower()};">
|
||||
<img src="{self.image}" alt="{self.name}" {dimension}="{dimension_value}" style="{dimension}: {dimension_value}px;">
|
||||
</div>
|
||||
"""
|
||||
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"""<div style="text-align: {self.get(align, "").lower()};">
|
||||
<img src="{self.get(field)}" alt="{self.get("name")}"
|
||||
{dimension}="{dimension_value}" style="{dimension}: {dimension_value}px;">
|
||||
</div>""",
|
||||
)
|
||||
|
||||
frappe.msgprint(success_msg, alert=True)
|
||||
|
||||
def on_update(self):
|
||||
self.set_as_default()
|
||||
|
|
|
|||
|
|
@ -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, ',');
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue