Merge branch 'develop' of github.com:frappe/frappe into mariadb-10_6

This commit is contained in:
Gavin D'souza 2021-09-14 22:10:24 +05:30
commit f1d2886328
778 changed files with 4215 additions and 4262 deletions

View file

@ -10,3 +10,6 @@
# Replace use of Class.extend with native JS class
fe20515c23a3ac41f1092bf0eaf0a0a452ec2e85
# Updating license headers
34460265554242a8d05fb09f049033b1117e1a2b

View file

@ -17,6 +17,7 @@ if [ "$TYPE" == "server" ]; then
fi
if [ "$DB" == "mariadb" ];then
sudo apt install mariadb-client-10.3
mysql --host 127.0.0.1 --port 3306 -u root -e "SET GLOBAL character_set_server = 'utf8mb4'";
mysql --host 127.0.0.1 --port 3306 -u root -e "SET GLOBAL collation_server = 'utf8mb4_unicode_ci'";
@ -58,4 +59,4 @@ cd ../..
bench start &
bench --site test_site reinstall --yes
if [ "$TYPE" == "server" ]; then bench --site test_site_producer reinstall --yes; fi
bench build --app frappe
bench build --app frappe

View file

@ -9,7 +9,7 @@ concurrency:
jobs:
test:
runs-on: ubuntu-18.04
runs-on: ubuntu-latest
name: Patch Test

View file

@ -13,7 +13,7 @@ concurrency:
jobs:
test:
runs-on: ubuntu-18.04
runs-on: ubuntu-latest
strategy:
fail-fast: false
@ -121,9 +121,10 @@ jobs:
ORCHESTRATOR_URL: http://test-orchestrator.frappe.io
- name: Upload coverage data
if: ${{ steps.check-build.outputs.build == 'strawberry' }}
uses: codecov/codecov-action@v2
with:
name: MariaDB
fail_ci_if_error: true
files: /home/runner/frappe-bench/sites/coverage.xml
verbose: true
verbose: true

View file

@ -12,7 +12,7 @@ concurrency:
jobs:
test:
runs-on: ubuntu-18.04
runs-on: ubuntu-latest
strategy:
fail-fast: false
@ -124,6 +124,7 @@ jobs:
ORCHESTRATOR_URL: http://test-orchestrator.frappe.io
- name: Upload coverage data
if: ${{ steps.check-build.outputs.build == 'strawberry' }}
uses: codecov/codecov-action@v2
with:
name: Postgres

View file

@ -1,22 +0,0 @@
name: Frappe Linter
on:
pull_request:
branches:
- develop
- version-12-hotfix
- version-11-hotfix
jobs:
check_translation:
name: Translation Syntax Check
runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@v2
- name: Setup python3
uses: actions/setup-python@v1
with:
python-version: 3.6
- name: Validating Translation Syntax
run: |
git fetch origin $GITHUB_BASE_REF:$GITHUB_BASE_REF -q
files=$(git diff --name-only --diff-filter=d $GITHUB_BASE_REF)
python $GITHUB_WORKSPACE/.github/helper/translation.py $files

View file

@ -12,7 +12,7 @@ concurrency:
jobs:
test:
runs-on: ubuntu-18.04
runs-on: ubuntu-latest
strategy:
fail-fast: false

View file

@ -1,6 +1,6 @@
The MIT License
Copyright (c) 2016-2018 Frappe Technologies Pvt. Ltd. <developers@frappe.io>
Copyright (c) 2016-2021 Frappe Technologies Pvt. Ltd. <developers@frappe.io>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View file

@ -1,5 +1,13 @@
codecov:
require_ci_to_pass: yes
coverage:
status:
project:
default:
target: auto
threshold: 0.5%
comment:
layout: "diff, flags, files"
require_changes: true
layout: "diff"
require_changes: true

View file

@ -31,8 +31,13 @@ context('API Resources', () => {
});
it('Removes the Comments', () => {
cy.get_list('Comment').then(body => body.data.forEach(comment => {
cy.remove_doc('Comment', comment.name);
}));
cy.get_list('Comment').then(body => {
let comment_names = [];
body.data.map(comment => comment_names.push(comment.name));
comment_names = [...new Set(comment_names)]; // remove duplicates
comment_names.forEach((comment_name) => {
cy.remove_doc('Comment', comment_name);
});
});
});
});

View file

@ -0,0 +1,93 @@
context("Control Float", () => {
before(() => {
cy.login();
cy.visit("/app/website");
});
function get_dialog_with_float() {
return cy.dialog({
title: "Float Check",
fields: [
{
fieldname: "float_number",
fieldtype: "Float",
Label: "Float"
}
]
});
}
it("check value changes", () => {
get_dialog_with_float().as("dialog");
let data = get_data();
data.forEach(x => {
cy.window()
.its("frappe")
.then(frappe => {
frappe.boot.sysdefaults.number_format = x.number_format;
});
x.values.forEach(d => {
cy.get_field("float_number", "Float").clear();
cy.fill_field("float_number", d.input, "Float").blur();
cy.get_field("float_number", "Float").should(
"have.value",
d.blur_expected
);
cy.get_field("float_number", "Float").focus();
cy.get_field("float_number", "Float").blur();
cy.get_field("float_number", "Float").focus();
cy.get_field("float_number", "Float").should(
"have.value",
d.focus_expected
);
});
});
});
function get_data() {
return [
{
number_format: "#.###,##",
values: [
{
input: "364.87,334",
blur_expected: "36.487,334",
focus_expected: "36487.334"
},
{
input: "36487,334",
blur_expected: "36.487,334",
focus_expected: "36487.334"
},
{
input: "100",
blur_expected: "100,000",
focus_expected: "100"
}
]
},
{
number_format: "#,###.##",
values: [
{
input: "364,87.334",
blur_expected: "36,487.334",
focus_expected: "36487.334"
},
{
input: "36487.334",
blur_expected: "36,487.334",
focus_expected: "36487.334"
},
{
input: "100",
blur_expected: "100.000",
focus_expected: "100"
}
]
}
];
}
});

View file

@ -1,19 +1,19 @@
context('Datetime Field Validation', () => {
before(() => {
cy.login();
cy.visit('/app/communication');
cy.window().its('frappe').then(frappe => {
frappe.call("frappe.tests.ui_test_helpers.create_communication_records");
});
});
// TODO: Enable this again
// currently this is flaky possibly because of different timezone in CI
// validating datetime field value when value is set from backend and get validated on form load.
it('datetime field form validation', () => {
cy.visit('/app/communication');
cy.get('a[title="Test Form Communication 1"]').invoke('attr', 'data-name')
.then((name) => {
cy.visit(`/app/communication/${name}`);
cy.get('.indicator-pill').should('contain', 'Open').should('have.class', 'red');
});
});
});
// context('Datetime Field Validation', () => {
// before(() => {
// cy.login();
// cy.visit('/app/communication');
// });
// it('datetime field form validation', () => {
// // validating datetime field value when value is set from backend and get validated on form load.
// cy.window().its('frappe').then(frappe => {
// return frappe.xcall("frappe.tests.ui_test_helpers.create_communication_record");
// }).then(doc => {
// cy.visit(`/app/communication/${doc.name}`);
// cy.get('.indicator-pill').should('contain', 'Open').should('have.class', 'red');
// });
// });
// });

View file

@ -7,11 +7,11 @@ context('List View', () => {
});
});
it('enables "Actions" button', () => {
const actions = ['Approve', 'Reject', 'Edit', 'Assign To', 'Apply Assignment Rule', 'Add Tags', 'Print', 'Delete'];
const actions = ['Approve', 'Reject', 'Edit', 'Export', 'Assign To', 'Apply Assignment Rule', 'Add Tags', 'Print', 'Delete'];
cy.go_to_list('ToDo');
cy.get('.list-row-container:contains("Pending") .list-row-checkbox').click({ multiple: true, force: true });
cy.get('.actions-btn-group button').contains('Actions').should('be.visible').click();
cy.get('.dropdown-menu li:visible .dropdown-item').should('have.length', 8).each((el, index) => {
cy.get('.dropdown-menu li:visible .dropdown-item').should('have.length', 9).each((el, index) => {
cy.wrap(el).contains(actions[index]);
}).then((elements) => {
cy.intercept({

View file

@ -0,0 +1,58 @@
context('MultiSelectDialog', () => {
before(() => {
cy.login();
cy.visit('/app');
});
function open_multi_select_dialog() {
cy.window().its('frappe').then(frappe => {
new frappe.ui.form.MultiSelectDialog({
doctype: "Assignment Rule",
target: {},
setters: {
document_type: null,
priority: null
},
add_filters_group: 1,
allow_child_item_selection: 1,
child_fieldname: "assignment_days",
child_columns: ["day"]
});
});
}
it('multi select dialog api works', () => {
open_multi_select_dialog();
cy.get_open_dialog().should('contain', 'Select Assignment Rules');
});
it('checks for filters', () => {
['search_term', 'document_type', 'priority'].forEach(fieldname => {
cy.get_open_dialog().get(`.frappe-control[data-fieldname="${fieldname}"]`).should('exist');
});
// add_filters_group: 1 should add a filter group
cy.get_open_dialog().get(`.frappe-control[data-fieldname="filter_area"]`).should('exist');
});
it('checks for child item selection', () => {
cy.get_open_dialog()
.get(`.dt-row-header`).should('not.exist');
cy.get_open_dialog()
.get(`.frappe-control[data-fieldname="allow_child_item_selection"]`)
.should('exist')
.click();
cy.get_open_dialog()
.get(`.frappe-control[data-fieldname="child_selection_area"]`)
.should('exist');
cy.get_open_dialog()
.get(`.dt-row-header`).should('contain', 'Assignment Rule');
cy.get_open_dialog()
.get(`.dt-row-header`).should('contain', 'Day');
});
});

View file

@ -1,7 +1,6 @@
context('Navigation', () => {
before(() => {
cy.login();
cy.visit('/app/website');
});
it('Navigate to route with hash in document name', () => {
cy.insert_doc('ToDo', {'__newname': 'ABC#123', 'description': 'Test this', 'ignore_duplicate': true});
@ -11,4 +10,15 @@ context('Navigation', () => {
cy.go('back');
cy.title().should('eq', 'Website');
});
it.only('Navigate to previous page after login', () => {
cy.visit('/app/todo');
cy.request('/api/method/logout');
cy.reload();
cy.get('.btn-primary').contains('Login').click();
cy.location('pathname').should('eq', '/login');
cy.login();
cy.visit('/app');
cy.location('pathname').should('eq', '/app/todo');
});
});

View file

@ -6,12 +6,12 @@ context('Sidebar', () => {
});
it('Test for checking "Assigned To" counter value, adding filter and adding & removing an assignment', () => {
cy.click_sidebar_button(0);
cy.click_sidebar_button("Assigned To");
//To check if no filter is available in "Assigned To" dropdown
cy.get('.empty-state').should('contain', 'No filters found');
cy.click_sidebar_button(1);
cy.click_sidebar_button("Created By");
//To check if "Created By" dropdown contains filter
cy.get('.group-by-item > .dropdown-item').should('contain', 'Me');
@ -22,7 +22,7 @@ context('Sidebar', () => {
cy.get_field('assign_to_me', 'Check').click();
cy.get('.modal-footer > .standard-actions > .btn-primary').click();
cy.visit('/app/doctype');
cy.click_sidebar_button(0);
cy.click_sidebar_button("Assigned To");
//To check if filter is added in "Assigned To" dropdown after assignment
cy.get('.group-by-field.show > .dropdown-menu > .group-by-item > .dropdown-item').should('contain', '1');
@ -38,20 +38,19 @@ context('Sidebar', () => {
cy.get('.fieldname-select-area > .awesomplete > .form-control').should('have.value', 'Assigned To');
cy.get('.condition').should('have.value', 'like');
cy.get('.filter-field > .form-group > .input-with-feedback').should('have.value', '%Administrator%');
cy.click_filter_button();
//To remove the applied filter
cy.get('.filter-action-buttons > div > .btn-secondary').contains('Clear Filters').click();
cy.click_filter_button();
cy.get('.filter-selector > .btn').should('contain', 'Filter');
cy.clear_filters();
//To remove the assignment
cy.visit('/app/doctype');
cy.click_listview_row_item(0);
cy.get('.assignments > .avatar-group > .avatar > .avatar-frame').click();
cy.get('.remove-btn').click({force: true});
cy.get('.modal.show > .modal-dialog > .modal-content > .modal-header > .modal-actions > .btn-modal-close').click();
cy.hide_dialog();
cy.visit('/app/doctype');
cy.click_sidebar_button(0);
cy.click_sidebar_button("Assigned To");
cy.get('.empty-state').should('contain', 'No filters found');
});
});

View file

@ -4,11 +4,11 @@ context('Timeline', () => {
before(() => {
cy.visit('/login');
cy.login();
cy.visit('/app/todo');
});
it('Adding new ToDo, adding new comment, verifying comment addition & deletion and deleting ToDo', () => {
//Adding new ToDo
cy.visit('/app/todo');
cy.click_listview_primary_button('Add ToDo');
cy.findByRole('button', {name: 'Edit in full page'}).click();
cy.get('[data-fieldname="description"] .ql-editor').eq(0).type('Test ToDo', {force: true});
@ -28,15 +28,15 @@ context('Timeline', () => {
cy.get('.timeline-content').should('contain', 'Testing Timeline');
//Editing comment
cy.click_timeline_action_btn(0);
cy.click_timeline_action_btn("Edit");
cy.get('.timeline-content [data-fieldname="comment"] .ql-editor').first().type(' 123');
cy.click_timeline_action_btn(0);
cy.click_timeline_action_btn("Save");
//To check if the edited comment text is visible in timeline content
cy.get('.timeline-content').should('contain', 'Testing Timeline 123');
//Discarding comment
cy.click_timeline_action_btn(0);
cy.click_timeline_action_btn("Edit");
cy.findByRole('button', {name: 'Dismiss'}).click();
//To check if after discarding the timeline content is same as previous
@ -81,7 +81,7 @@ context('Timeline', () => {
cy.visit('/app/custom-submittable-doctype');
cy.get('.list-subject > .select-like > .list-row-checkbox').eq(0).click();
cy.findByRole('button', {name: 'Actions'}).click();
cy.get('.actions-btn-group > .dropdown-menu > li > .grey-link').eq(7).click();
cy.get('.actions-btn-group > .dropdown-menu > li > .dropdown-item').contains("Delete").click();
cy.click_modal_primary_button('Yes', {force: true, delay: 700});
//Deleting the custom doctype

View file

@ -187,7 +187,7 @@ Cypress.Commands.add('fill_field', (fieldname, value, fieldtype = 'Data') => {
if (fieldtype === 'Select') {
cy.get('@input').select(value);
} else {
cy.get('@input').type(value, {waitForAnimations: false, force: true});
cy.get('@input').type(value, {waitForAnimations: false, force: true, delay: 100});
}
return cy.get('@input');
});
@ -252,7 +252,8 @@ Cypress.Commands.add('new_form', doctype => {
});
Cypress.Commands.add('go_to_list', doctype => {
cy.visit(`/app/list/${doctype}/list`);
let dt_in_route = doctype.toLowerCase().replace(/ /g, '-');
cy.visit(`/app/${dt_in_route}`);
});
Cypress.Commands.add('clear_cache', () => {
@ -316,7 +317,11 @@ Cypress.Commands.add('add_filter', () => {
});
Cypress.Commands.add('clear_filters', () => {
cy.get('.filter-section .filter-button').click();
cy.intercept({
method: 'POST',
url: 'api/method/frappe.model.utils.user_settings.save'
}).as('filter-saved');
cy.get('.filter-section .filter-button').click({force: true});
cy.wait(300);
cy.get('.filter-popover').should('exist');
cy.get('.filter-popover').find('.clear-filters').click();
@ -324,16 +329,15 @@ Cypress.Commands.add('clear_filters', () => {
cy.window().its('cur_list').then(cur_list => {
cur_list && cur_list.filter_area && cur_list.filter_area.clear();
});
cy.wait('@filter-saved');
});
Cypress.Commands.add('click_modal_primary_button', (btn_name) => {
cy.get('.modal-footer > .standard-actions > .btn-primary').contains(btn_name).trigger('click', {force: true});
});
Cypress.Commands.add('click_sidebar_button', (btn_no) => {
cy.get('.list-group-by-fields > .group-by-field > .btn').eq(btn_no).click();
Cypress.Commands.add('click_sidebar_button', (btn_name) => {
cy.get('.list-group-by-fields .list-link > a').contains(btn_name).click({force: true});
});
Cypress.Commands.add('click_listview_row_item', (row_no) => {
@ -348,6 +352,6 @@ Cypress.Commands.add('click_listview_primary_button', (btn_name) => {
cy.get('.primary-action').contains(btn_name).click({force: true});
});
Cypress.Commands.add('click_timeline_action_btn', (btn_no) => {
cy.get('.timeline-content > .timeline-message-box > .justify-between > .actions > .btn').eq(btn_no).first().click();
Cypress.Commands.add('click_timeline_action_btn', (btn_name) => {
cy.get('.timeline-content > .timeline-message-box > .justify-between > .actions > .btn').contains(btn_name).click();
});

View file

@ -1,5 +1,5 @@
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
# MIT License. See license.txt
# License: MIT. See LICENSE
"""
Frappe - Low Code Open Source Framework in Python and JS
@ -618,8 +618,6 @@ def read_only():
try:
retval = fn(*args, **get_newargs(fn, kwargs))
except:
raise
finally:
if local and hasattr(local, 'primary_db'):
local.db.close()
@ -629,6 +627,29 @@ def read_only():
return wrapper_fn
return innfn
def write_only():
# if replica connection exists, we have to replace it momentarily with the primary connection
def innfn(fn):
def wrapper_fn(*args, **kwargs):
primary_db = getattr(local, "primary_db", None)
replica_db = getattr(local, "replica_db", None)
in_read_only = getattr(local, "db", None) != primary_db
# switch to primary connection
if in_read_only and primary_db:
local.db = local.primary_db
try:
retval = fn(*args, **get_newargs(fn, kwargs))
finally:
# switch back to replica connection
if in_read_only and replica_db:
local.db = replica_db
return retval
return wrapper_fn
return innfn
def only_for(roles, message=False):
"""Raise `frappe.PermissionError` if the user does not have any of the given **Roles**.

View file

@ -1,5 +1,5 @@
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
# MIT License. See license.txt
# License: MIT. See LICENSE
import base64
import binascii
import json

View file

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
# MIT License. See license.txt
# License: MIT. See LICENSE
import os
import logging

View file

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2019, Frappe Technologies and contributors
# For license information, please see license.txt
# License: MIT. See LICENSE
import frappe
from frappe.model.document import Document

View file

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2019, Frappe Technologies and Contributors
# See license.txt
# License: MIT. See LICENSE
import frappe
import unittest
from frappe.utils import random_string

View file

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2019, Frappe Technologies and contributors
# For license information, please see license.txt
# License: MIT. See LICENSE
# import frappe
from frappe.model.document import Document

View file

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2019, Frappe Technologies and contributors
# For license information, please see license.txt
# License: MIT. See LICENSE
# import frappe
from frappe.model.document import Document

View file

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
# For license information, please see license.txt
# License: MIT. See LICENSE
import frappe
from frappe import _

View file

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2018, Frappe Technologies and Contributors
# See license.txt
# License: MIT. See LICENSE
import unittest
import frappe

View file

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2020, Frappe Technologies and contributors
# For license information, please see license.txt
# License: MIT. See LICENSE
# import frappe
from frappe.model.document import Document

View file

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2019, Frappe Technologies and contributors
# For license information, please see license.txt
# License: MIT. See LICENSE
import frappe
from frappe.model.document import Document

View file

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2019, Frappe Technologies and Contributors
# See license.txt
# License: MIT. See LICENSE
#import frappe
import unittest

View file

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2019, Frappe Technologies and contributors
# For license information, please see license.txt
# License: MIT. See LICENSE
import frappe
from frappe.model.document import Document

View file

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2019, Frappe Technologies and Contributors
# See license.txt
# License: MIT. See LICENSE
import frappe
import frappe.cache_manager
import unittest

View file

@ -1,5 +1,5 @@
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
# MIT License. See license.txt
# License: MIT. See LICENSE
"""
bootstrap client session
"""

View file

@ -1,5 +1,5 @@
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
# MIT License. See license.txt
# License: MIT. See LICENSE
import os
import re
import json

View file

@ -1,5 +1,5 @@
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
# MIT License. See license.txt
# License: MIT. See LICENSE
import frappe, json
from frappe.model.document import Document

View file

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2018, Frappe Technologies and contributors
# For license information, please see license.txt
# License: MIT. See LICENSE
import frappe
from frappe.model.document import Document

View file

@ -1,5 +1,5 @@
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
# MIT License. See license.txt
# License: MIT. See LICENSE
import frappe
from frappe import _
import frappe.model

View file

@ -1,5 +1,5 @@
# Copyright (c) 2015, Web Notes Technologies Pvt. Ltd. and Contributors
# MIT License. See license.txt
# License: MIT. See LICENSE
import sys
import click

View file

@ -1,5 +1,5 @@
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
# License: GNU General Public License v3. See license.txt
# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and Contributors
# License: MIT. See LICENSE
import frappe

View file

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2015, Frappe Technologies and contributors
# For license information, please see license.txt
# License: MIT. See LICENSE
import frappe
@ -65,7 +65,7 @@ class Address(Document):
def has_link(self, doctype, name):
for link in self.links:
if link.link_doctype==doctype and link.link_name== name:
if link.link_doctype == doctype and link.link_name == name:
return True
def has_common_link(self, doc):

View file

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2015, Frappe Technologies and Contributors
# See license.txt
# License: MIT. See LICENSE
import frappe, unittest
from frappe.contacts.doctype.address.address import get_address_display

View file

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2015, Frappe Technologies and contributors
# For license information, please see license.txt
# License: MIT. See LICENSE
import frappe
from frappe.model.document import Document

View file

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2015, Frappe Technologies and Contributors
# See license.txt
# License: MIT. See LICENSE
import frappe, unittest
class TestAddressTemplate(unittest.TestCase):

View file

@ -1,5 +1,5 @@
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
# License: GNU General Public License v3. See license.txt
# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and Contributors
# License: MIT. See LICENSE
import frappe
from frappe.utils import cstr, has_gravatar
from frappe import _
@ -47,14 +47,14 @@ class Contact(Document):
def get_link_for(self, link_doctype):
'''Return the link name, if exists for the given link DocType'''
for link in self.links:
if link.link_doctype==link_doctype:
if link.link_doctype == link_doctype:
return link.link_name
return None
def has_link(self, doctype, name):
for link in self.links:
if link.link_doctype==doctype and link.link_name== name:
if link.link_doctype == doctype and link.link_name == name:
return True
def has_common_link(self, doc):

View file

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2017, Frappe Technologies and Contributors
# See license.txt
# License: MIT. See LICENSE
import frappe
import unittest

View file

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2019, Frappe Technologies and contributors
# For license information, please see license.txt
# License: MIT. See LICENSE
# import frappe
from frappe.model.document import Document

View file

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2019, Frappe Technologies and contributors
# For license information, please see license.txt
# License: MIT. See LICENSE
# import frappe
from frappe.model.document import Document

View file

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2017, Frappe Technologies and contributors
# For license information, please see license.txt
# License: MIT. See LICENSE
from frappe.model.document import Document

View file

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2017, Frappe Technologies and Contributors
# See license.txt
# License: MIT. See LICENSE
import unittest
class TestGender(unittest.TestCase):

View file

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2017, Frappe Technologies and contributors
# For license information, please see license.txt
# License: MIT. See LICENSE
from frappe.model.document import Document

View file

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2017, Frappe Technologies and Contributors
# See license.txt
# License: MIT. See LICENSE
import unittest
class TestSalutation(unittest.TestCase):

View file

@ -1,5 +1,5 @@
# Copyright (c) 2013, Frappe Technologies Pvt. Ltd. and contributors
# For license information, please see license.txt
# License: MIT. See LICENSE
import frappe
from frappe import _

View file

@ -1,2 +1,2 @@
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
# MIT License. See license.txt
# License: MIT. See LICENSE

View file

@ -1,3 +1,3 @@
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
# MIT License. See license.txt
# License: MIT. See LICENSE

View file

@ -1,5 +1,5 @@
# Copyright (c) 2019, Frappe Technologies and contributors
# For license information, please see license.txt
# License: MIT. See LICENSE
import frappe
from frappe.model.document import Document
@ -9,6 +9,7 @@ class AccessLog(Document):
@frappe.whitelist()
@frappe.write_only()
def make_access_log(doctype=None, document=None, method=None, file_type=None,
report_name=None, filters=None, page=None, columns=None):

View file

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2019, Frappe Technologies and Contributors
# See license.txt
# License: MIT. See LICENSE
# imports - standard imports
import unittest

View file

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2017, Frappe Technologies and contributors
# For license information, please see license.txt
# License: MIT. See LICENSE
from frappe import _
from frappe.utils import get_fullname, now

View file

@ -1,5 +1,5 @@
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
# License: See license.txt
# License: MIT. See LICENSE
import frappe
import frappe.permissions

View file

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2015, Frappe Technologies and Contributors
# See license.txt
# License: MIT. See LICENSE
import frappe
import unittest
import time

View file

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors
# For license information, please see license.txt
# License: MIT. See LICENSE
import frappe
from frappe.model.document import Document

View file

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2019, Frappe Technologies and contributors
# For license information, please see license.txt
# License: MIT. See LICENSE
import frappe
from frappe import _
import json

View file

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2019, Frappe Technologies and Contributors
# See license.txt
# License: MIT. See LICENSE
import frappe, json
import unittest

View file

@ -1,3 +1,3 @@
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
# MIT License. See license.txt
# License: MIT. See LICENSE

View file

@ -1,5 +1,5 @@
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
# MIT License. See license.txt
# License: MIT. See LICENSE
from collections import Counter
import frappe

View file

@ -1,5 +1,5 @@
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
# MIT License. See license.txt
# License: MIT. See LICENSE
import frappe
import json

View file

@ -1,5 +1,5 @@
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
# See license.txt
# License: MIT. See LICENSE
import unittest
from urllib.parse import quote

View file

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2019, Frappe Technologies and contributors
# For license information, please see license.txt
# License: MIT. See LICENSE
import frappe
from frappe.model.document import Document

View file

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2015, Frappe Technologies and contributors
# For license information, please see license.txt
# License: MIT. See LICENSE
import frappe
from frappe.model.document import Document

View file

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2015, Frappe Technologies and Contributors
# See license.txt
# License: MIT. See LICENSE
import frappe
import unittest

View file

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2015, Frappe Technologies and contributors
# For license information, please see license.txt
# License: MIT. See LICENSE
import frappe
from frappe.model.document import Document

View file

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2015, Frappe Technologies and Contributors
# See license.txt
# License: MIT. See LICENSE
import frappe
import unittest

View file

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors
# For license information, please see license.txt
# License: MIT. See LICENSE
from frappe.model.document import Document

View file

@ -1,5 +1,5 @@
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
# MIT License. See license.txt
# License: MIT. See LICENSE
import frappe
from frappe import _

View file

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2019, Frappe Technologies and contributors
# For license information, please see license.txt
# License: MIT. See LICENSE
import os

View file

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2019, Frappe Technologies Pvt. Ltd. and Contributors
# MIT License. See license.txt
# License: MIT. See LICENSE
import typing

View file

@ -1,5 +1,5 @@
# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors
# MIT License. See license.txt
# License: MIT. See LICENSE
import os
import io

View file

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2020, Frappe Technologies and Contributors
# See license.txt
# License: MIT. See LICENSE
# import frappe
import unittest

View file

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2019, Frappe Technologies and Contributors
# See license.txt
# License: MIT. See LICENSE
import unittest
import frappe
from frappe.core.doctype.data_import.exporter import Exporter

View file

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2019, Frappe Technologies and Contributors
# See license.txt
# License: MIT. See LICENSE
import unittest
import frappe
from frappe.core.doctype.data_import.importer import Importer

View file

@ -1,3 +1,3 @@
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
# MIT License. See license.txt
# License: MIT. See LICENSE

View file

@ -1,5 +1,5 @@
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
# MIT License. See license.txt
# License: MIT. See LICENSE
import frappe

View file

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2015, Frappe Technologies and contributors
# For license information, please see license.txt
# License: MIT. See LICENSE
import frappe
import json

View file

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2015, Frappe Technologies and Contributors
# See license.txt
# License: MIT. See LICENSE
import frappe
import unittest

View file

@ -1,3 +1,3 @@
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
# MIT License. See license.txt
# License: MIT. See LICENSE

View file

@ -18,46 +18,53 @@
"hide_seconds",
"reqd",
"search_index",
"in_list_view",
"in_standard_filter",
"in_global_search",
"in_preview",
"allow_in_quick_entry",
"bold",
"translatable",
"collapsible",
"collapsible_depends_on",
"column_break_6",
"column_break_18",
"options",
"defaults_section",
"default",
"column_break_6",
"fetch_from",
"fetch_if_empty",
"permissions",
"depends_on",
"visibility_section",
"hidden",
"bold",
"allow_in_quick_entry",
"translatable",
"print_hide",
"print_hide_if_no_value",
"report_hide",
"column_break_28",
"depends_on",
"collapsible",
"collapsible_depends_on",
"hide_border",
"list__search_settings_section",
"in_list_view",
"in_standard_filter",
"in_preview",
"column_break_35",
"in_filter",
"in_global_search",
"permissions",
"read_only",
"unique",
"set_only_once",
"allow_on_submit",
"ignore_user_permissions",
"allow_bulk_edit",
"column_break_13",
"permlevel",
"ignore_user_permissions",
"allow_on_submit",
"report_hide",
"remember_last_selected_value",
"ignore_xss_filter",
"hide_border",
"property_depends_on_section",
"mandatory_depends_on",
"constraints_section",
"unique",
"no_copy",
"set_only_once",
"remember_last_selected_value",
"column_break_38",
"mandatory_depends_on",
"read_only_depends_on",
"display",
"in_filter",
"no_copy",
"print_hide",
"print_hide_if_no_value",
"print_width",
"width",
"max_height",
"columns",
"column_break_22",
"description",
@ -153,7 +160,7 @@
"default": "0",
"fieldname": "in_standard_filter",
"fieldtype": "Check",
"label": "In Standard Filter"
"label": "In List Filter"
},
{
"default": "0",
@ -197,10 +204,11 @@
"length": 255
},
{
"depends_on": "eval:doc.fieldtype==\"Section Break\"",
"depends_on": "eval:doc.fieldtype==\"Section Break\" && doc.collapsible",
"fieldname": "collapsible_depends_on",
"fieldtype": "Code",
"label": "Collapsible Depends On",
"label": "Collapsible Depends On (JS)",
"max_height": "3rem",
"options": "JS"
},
{
@ -220,6 +228,7 @@
"fieldname": "default",
"fieldtype": "Small Text",
"label": "Default",
"max_height": "3rem",
"oldfieldname": "default",
"oldfieldtype": "Text"
},
@ -230,10 +239,9 @@
},
{
"default": "0",
"description": "If checked, this field will be not overwritten based on Fetch From if a value already exists.",
"fieldname": "fetch_if_empty",
"fieldtype": "Check",
"label": "Fetch If Empty"
"label": "Fetch only if value is not set"
},
{
"fieldname": "permissions",
@ -243,8 +251,9 @@
{
"fieldname": "depends_on",
"fieldtype": "Code",
"label": "Display Depends On",
"label": "Display Depends On (JS)",
"length": 255,
"max_height": "3rem",
"oldfieldname": "depends_on",
"oldfieldtype": "Data",
"options": "JS"
@ -275,10 +284,9 @@
},
{
"default": "0",
"description": "Do not allow user to change after set the first time",
"fieldname": "set_only_once",
"fieldtype": "Check",
"label": "Set Only Once"
"label": "Set only once"
},
{
"default": "0",
@ -303,7 +311,6 @@
},
{
"default": "0",
"description": "User permissions should not apply for this Link",
"fieldname": "ignore_user_permissions",
"fieldtype": "Check",
"label": "Ignore User Permissions"
@ -388,12 +395,14 @@
{
"fieldname": "print_width",
"fieldtype": "Data",
"label": "Print Width"
"label": "Print Width",
"length": 10
},
{
"fieldname": "width",
"fieldtype": "Data",
"label": "Width",
"length": 10,
"oldfieldname": "width",
"oldfieldtype": "Data",
"print_width": "50px",
@ -436,20 +445,17 @@
{
"fieldname": "mandatory_depends_on",
"fieldtype": "Code",
"label": "Mandatory Depends On",
"label": "Mandatory Depends On (JS)",
"max_height": "3rem",
"options": "JS"
},
{
"fieldname": "read_only_depends_on",
"fieldtype": "Code",
"label": "Read Only Depends On",
"label": "Read Only Depends On (JS)",
"max_height": "3rem",
"options": "JS"
},
{
"fieldname": "property_depends_on_section",
"fieldtype": "Section Break",
"label": "Property Depends On"
},
{
"fieldname": "column_break_38",
"fieldtype": "Column Break"
@ -481,16 +487,56 @@
"fieldname": "non_negative",
"fieldtype": "Check",
"label": "Non Negative"
},
{
"fieldname": "column_break_18",
"fieldtype": "Column Break"
},
{
"fieldname": "defaults_section",
"fieldtype": "Section Break",
"label": "Defaults",
"max_height": "2rem"
},
{
"fieldname": "visibility_section",
"fieldtype": "Section Break",
"label": "Visibility"
},
{
"fieldname": "column_break_28",
"fieldtype": "Column Break"
},
{
"fieldname": "constraints_section",
"fieldtype": "Section Break",
"label": "Constraints"
},
{
"fieldname": "max_height",
"fieldtype": "Data",
"label": "Max Height",
"length": 10
},
{
"fieldname": "list__search_settings_section",
"fieldtype": "Section Break",
"label": "List / Search Settings"
},
{
"fieldname": "column_break_35",
"fieldtype": "Column Break"
}
],
"idx": 1,
"index_web_pages_for_search": 1,
"istable": 1,
"links": [],
"modified": "2021-07-10 21:56:04.167745",
"modified": "2021-09-04 19:41:53.684094",
"modified_by": "Administrator",
"module": "Core",
"name": "DocField",
"naming_rule": "Random",
"owner": "Administrator",
"permissions": [],
"sort_field": "modified",

View file

@ -1,5 +1,5 @@
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
# MIT License. See license.txt
# License: MIT. See LICENSE
import frappe
from frappe.model.document import Document

View file

@ -1,3 +1,3 @@
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
# MIT License. See license.txt
# License: MIT. See LICENSE

View file

@ -1,5 +1,5 @@
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
# MIT License. See license.txt
# License: MIT. See LICENSE
import frappe

View file

@ -1,5 +1,5 @@
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors
# For license information, please see license.txt
# License: MIT. See LICENSE
import frappe
from frappe.model.document import Document

View file

@ -1,5 +1,5 @@
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
# See license.txt
# License: MIT. See LICENSE
import frappe
import frappe.share

View file

@ -1,3 +1,3 @@
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
# MIT License. See license.txt
# License: MIT. See LICENSE

View file

@ -61,9 +61,73 @@ frappe.ui.form.on('DocType', {
__('In Grid View') : __('In List View');
frm.events.autoname(frm);
frm.events.set_naming_rule_description(frm);
},
naming_rule: function(frm) {
// set the "autoname" property based on naming_rule
if (frm.doc.naming_rule && !frm.__from_autoname) {
// flag to avoid recursion
frm.__from_naming_rule = true;
if (frm.doc.naming_rule=='Set by user') {
frm.set_value('autoname', 'Prompt');
} else if (frm.doc.naming_rule=='By fieldname') {
frm.set_value('autoname', 'field:');
} else if (frm.doc.naming_rule=='By "Naming Series" field') {
frm.set_value('autoname', 'naming_series:');
} else if (frm.doc.naming_rule=='Expression') {
frm.set_value('autoname', 'format:');
} else if (frm.doc.naming_rule=='Expression (old style)') {
// pass
} else if (frm.doc.naming_rule=='Random') {
frm.set_value('autoname', 'hash');
}
setTimeout(() =>frm.__from_naming_rule = false, 500);
frm.events.set_naming_rule_description(frm);
}
},
set_naming_rule_description(frm) {
let naming_rule_description = {
'Set by user': '',
'By fieldname': 'Format: <code>field:[fieldname]</code>. Valid fieldname must exist',
'By "Naming Series" field': 'Format: <code>naming_series:[fieldname]</code>. Fieldname called <code>naming_series</code> must exist',
'Expression': 'Format: <code>format:EXAMPLE-{MM}morewords{fieldname1}-{fieldname2}-{#####}</code> - Replace all braced words (fieldnames, date words (DD, MM, YY), series) with their value. Outside braces, any characters can be used.',
'Expression (old style)': 'Format: <code>EXAMPLE-.#####</code> Series by prefix (separated by a dot)',
'Random': '',
'By script': ''
};
if (frm.doc.naming_rule) {
frm.get_field('autoname').set_description(naming_rule_description[frm.doc.naming_rule]);
}
},
autoname: function(frm) {
// set naming_rule based on autoname (for old doctypes where its not been set)
if (frm.doc.autoname && !frm.doc.naming_rule && !frm.__from_naming_rule) {
// flag to avoid recursion
frm.__from_autoname = true;
if (frm.doc.autoname.toLowerCase() === 'prompt') {
frm.set_value('naming_rule', 'Set by user');
} else if (frm.doc.autoname.startsWith('field:')) {
frm.set_value('naming_rule', 'By fieldname');
} else if (frm.doc.autoname.startsWith('naming_series:')) {
frm.set_value('naming_rule', 'By "Naming Series" field');
} else if (frm.doc.autoname.startsWith('format:')) {
frm.set_value('naming_rule', 'Expression');
} else if (frm.doc.autoname.toLowerCase() === 'hash') {
frm.set_value('naming_rule', 'Random');
} else {
frm.set_value('naming_rule', 'Expression (old style)');
}
setTimeout(() => frm.__from_autoname = false, 500);
}
frm.set_df_property('fields', 'reqd', frm.doc.autoname !== 'Prompt');
}
});

View file

@ -26,6 +26,7 @@
"fields_section_break",
"fields",
"sb1",
"naming_rule",
"autoname",
"name_case",
"allow_rename",
@ -554,6 +555,13 @@
"fieldname": "website_search_field",
"fieldtype": "Data",
"label": "Website Search Field"
},
{
"fieldname": "naming_rule",
"fieldtype": "Select",
"label": "Naming Rule",
"length": 40,
"options": "\nSet by user\nBy fieldname\nBy \"Naming Series\" field\nExpression\nExpression (old style)\nRandom\nBy script"
}
],
"icon": "fa fa-bolt",
@ -635,7 +643,7 @@
"link_fieldname": "reference_doctype"
}
],
"modified": "2021-08-31 15:26:19.077164",
"modified": "2021-09-05 15:39:13.233403",
"modified_by": "Administrator",
"module": "Core",
"name": "DocType",

View file

@ -1,5 +1,5 @@
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
# MIT License. See license.txt
# License: MIT. See LICENSE
# imports - standard imports
import re, copy, os, shutil
@ -493,6 +493,9 @@ class DocType(Document):
# retain order of 'fields' table and change order in 'field_order'
docdict["field_order"] = [f.fieldname for f in self.fields]
if self.custom:
return
path = get_file_path(self.module, "DocType", self.name)
if os.path.exists(path):
try:
@ -719,20 +722,20 @@ def validate_links_table_fieldnames(meta):
for index, link in enumerate(meta.links):
link_meta = frappe.get_meta(link.link_doctype)
if not link_meta.get_field(link.link_fieldname):
message = _("Row #{0}: Could not find field {1} in {2} DocType").format(index+1, frappe.bold(link.link_fieldname), frappe.bold(link.link_doctype))
message = _("Document Links Row #{0}: Could not find field {1} in {2} DocType").format(index+1, frappe.bold(link.link_fieldname), frappe.bold(link.link_doctype))
frappe.throw(message, InvalidFieldNameError, _("Invalid Fieldname"))
if link.is_child_table and not meta.get_field(link.table_fieldname):
message = _("Row #{0}: Could not find field {1} in {2} DocType").format(index+1, frappe.bold(link.table_fieldname), frappe.bold(meta.name))
message = _("Document Links Row #{0}: Could not find field {1} in {2} DocType").format(index+1, frappe.bold(link.table_fieldname), frappe.bold(meta.name))
frappe.throw(message, frappe.ValidationError, _("Invalid Table Fieldname"))
if link.is_child_table:
if not link.parent_doctype:
message = _("Row #{0}: Parent DocType is mandatory for internal links").format(index+1)
message = _("Document Links Row #{0}: Parent DocType is mandatory for internal links").format(index+1)
frappe.throw(message, frappe.ValidationError, _("Parent Missing"))
if not link.table_fieldname:
message = _("Row #{0}: Table Fieldname is mandatory for internal links").format(index+1)
message = _("Document Links Row #{0}: Table Fieldname is mandatory for internal links").format(index+1)
frappe.throw(message, frappe.ValidationError, _("Table Fieldname Missing"))
def validate_fields_for_doctype(doctype):
@ -1027,6 +1030,9 @@ def validate_fields(meta):
frappe.throw(_('Option {0} for field {1} is not a child table')
.format(frappe.bold(doctype), frappe.bold(docfield.fieldname)), title=_("Invalid Option"))
def check_max_height(docfield):
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)))
fields = meta.get("fields")
fieldname_list = [d.fieldname for d in fields]
@ -1060,6 +1066,7 @@ def validate_fields(meta):
scrub_options_in_select(d)
scrub_fetch_from(d)
validate_data_field_type(d)
check_max_height(d)
check_fold(fields)
check_search_fields(meta, fields)
@ -1216,8 +1223,14 @@ def make_module_and_roles(doc, perm_fieldname="permissions"):
if ("tabModule Def" in frappe.db.get_tables()
and not frappe.db.exists("Module Def", doc.module)):
m = frappe.get_doc({"doctype": "Module Def", "module_name": doc.module})
m.app_name = frappe.local.module_app[frappe.scrub(doc.module)]
if frappe.scrub(doc.module) in frappe.local.module_app:
m.app_name = frappe.local.module_app[frappe.scrub(doc.module)]
else:
m.app_name = 'frappe'
m.flags.ignore_mandatory = m.flags.ignore_permissions = True
if frappe.flags.package:
m.package = frappe.flags.package.name
m.custom = 1
m.insert()
default_roles = ["Administrator", "Guest", "All"]

View file

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
# See license.txt
# License: MIT. See LICENSE
import frappe
import unittest
from frappe.core.doctype.doctype.doctype import (UniqueFieldnameError,

View file

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2019, Frappe Technologies and contributors
# For license information, please see license.txt
# License: MIT. See LICENSE
# import frappe
from frappe.model.document import Document

View file

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2019, Frappe Technologies and contributors
# For license information, please see license.txt
# License: MIT. See LICENSE
# import frappe
from frappe.model.document import Document

View file

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2020, Frappe Technologies and contributors
# For license information, please see license.txt
# License: MIT. See LICENSE
import frappe
from frappe.model.document import Document

View file

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2020, Frappe Technologies and Contributors
# See license.txt
# License: MIT. See LICENSE
import frappe
import unittest

View file

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2020, Frappe Technologies and contributors
# For license information, please see license.txt
# License: MIT. See LICENSE
# import frappe
from frappe.model.document import Document

Some files were not shown because too many files have changed in this diff Show more